xkb.c revision 52397711
105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <X11/X.h> 3305b261ecSmrg#define NEED_EVENTS 3405b261ecSmrg#define NEED_REPLIES 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 3905b261ecSmrg#include <xkbsrv.h> 4005b261ecSmrg#include "extnsionst.h" 414642e01fSmrg#include "xace.h" 4205b261ecSmrg#include "xkb.h" 4305b261ecSmrg 4405b261ecSmrg#include <X11/extensions/XI.h> 4505b261ecSmrg 4605b261ecSmrg int XkbEventBase; 4705b261ecSmrgstatic int XkbErrorBase; 4805b261ecSmrg int XkbReqCode; 494642e01fSmrg int XkbKeyboardErrorCode; 5005b261ecSmrgCARD32 xkbDebugFlags = 0; 5105b261ecSmrgstatic CARD32 xkbDebugCtrls = 0; 5205b261ecSmrg 5305b261ecSmrgstatic RESTYPE RT_XKBCLIENT; 5405b261ecSmrg 5505b261ecSmrg/***====================================================================***/ 5605b261ecSmrg 574642e01fSmrg#define CHK_DEVICE(dev, id, client, access_mode, lf) {\ 5805b261ecSmrg int why;\ 594642e01fSmrg int rc = lf(&(dev), id, client, access_mode, &why);\ 604642e01fSmrg if (rc != Success) {\ 614642e01fSmrg client->errorValue = _XkbErrCode2(why, id);\ 624642e01fSmrg return rc;\ 6305b261ecSmrg }\ 6405b261ecSmrg} 6505b261ecSmrg 664642e01fSmrg#define CHK_KBD_DEVICE(dev, id, client, mode) \ 674642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard) 684642e01fSmrg#define CHK_LED_DEVICE(dev, id, client, mode) \ 694642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice) 704642e01fSmrg#define CHK_BELL_DEVICE(dev, id, client, mode) \ 714642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice) 724642e01fSmrg#define CHK_ANY_DEVICE(dev, id, client, mode) \ 734642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice) 7405b261ecSmrg 7505b261ecSmrg#define CHK_ATOM_ONLY2(a,ev,er) {\ 7605b261ecSmrg if (((a)==None)||(!ValidAtom((a)))) {\ 7705b261ecSmrg (ev)= (XID)(a);\ 7805b261ecSmrg return er;\ 7905b261ecSmrg }\ 8005b261ecSmrg} 8105b261ecSmrg#define CHK_ATOM_ONLY(a) \ 8205b261ecSmrg CHK_ATOM_ONLY2(a,client->errorValue,BadAtom) 8305b261ecSmrg 8405b261ecSmrg#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\ 8505b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 8605b261ecSmrg (ev)= (XID)(a);\ 8705b261ecSmrg (er)= BadAtom;\ 8805b261ecSmrg return ret;\ 8905b261ecSmrg }\ 9005b261ecSmrg} 9105b261ecSmrg#define CHK_ATOM_OR_NONE2(a,ev,er) {\ 9205b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 9305b261ecSmrg (ev)= (XID)(a);\ 9405b261ecSmrg return er;\ 9505b261ecSmrg }\ 9605b261ecSmrg} 9705b261ecSmrg#define CHK_ATOM_OR_NONE(a) \ 9805b261ecSmrg CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom) 9905b261ecSmrg 10005b261ecSmrg#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\ 10105b261ecSmrg if ((mask)&(~(legal))) { \ 10205b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 10305b261ecSmrg (er)= BadValue;\ 10405b261ecSmrg return ret;\ 10505b261ecSmrg }\ 10605b261ecSmrg} 10705b261ecSmrg#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\ 10805b261ecSmrg if ((mask)&(~(legal))) { \ 10905b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 11005b261ecSmrg return er;\ 11105b261ecSmrg }\ 11205b261ecSmrg} 11305b261ecSmrg#define CHK_MASK_LEGAL(err,mask,legal) \ 11405b261ecSmrg CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue) 11505b261ecSmrg 11605b261ecSmrg#define CHK_MASK_MATCH(err,affect,value) {\ 11705b261ecSmrg if ((value)&(~(affect))) { \ 11805b261ecSmrg client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\ 11905b261ecSmrg return BadMatch;\ 12005b261ecSmrg }\ 12105b261ecSmrg} 12205b261ecSmrg#define CHK_MASK_OVERLAP(err,m1,m2) {\ 12305b261ecSmrg if ((m1)&(m2)) { \ 12405b261ecSmrg client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\ 12505b261ecSmrg return BadMatch;\ 12605b261ecSmrg }\ 12705b261ecSmrg} 12805b261ecSmrg#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\ 12905b261ecSmrg if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\ 13005b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\ 13105b261ecSmrg return er;\ 13205b261ecSmrg }\ 13305b261ecSmrg else if ( (first)<(x)->min_key_code ) {\ 13405b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\ 13505b261ecSmrg return er;\ 13605b261ecSmrg }\ 13705b261ecSmrg} 13805b261ecSmrg#define CHK_KEY_RANGE(err,first,num,x) \ 13905b261ecSmrg CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue) 14005b261ecSmrg 14105b261ecSmrg#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\ 14205b261ecSmrg if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\ 14305b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\ 14405b261ecSmrg return er;\ 14505b261ecSmrg }\ 14605b261ecSmrg else if ( (first)<(r)->minKeyCode ) {\ 14705b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\ 14805b261ecSmrg return er;\ 14905b261ecSmrg }\ 15005b261ecSmrg} 15105b261ecSmrg#define CHK_REQ_KEY_RANGE(err,first,num,r) \ 15205b261ecSmrg CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) 15305b261ecSmrg 15405b261ecSmrg/***====================================================================***/ 15505b261ecSmrg 15605b261ecSmrgint 15705b261ecSmrgProcXkbUseExtension(ClientPtr client) 15805b261ecSmrg{ 15905b261ecSmrg REQUEST(xkbUseExtensionReq); 16005b261ecSmrg xkbUseExtensionReply rep; 16105b261ecSmrg register int n; 16205b261ecSmrg int supported; 16305b261ecSmrg 16405b261ecSmrg REQUEST_SIZE_MATCH(xkbUseExtensionReq); 16505b261ecSmrg if (stuff->wantedMajor != XkbMajorVersion) { 16605b261ecSmrg /* pre-release version 0.65 is compatible with 1.00 */ 16705b261ecSmrg supported= ((XkbMajorVersion==1)&& 16805b261ecSmrg (stuff->wantedMajor==0)&&(stuff->wantedMinor==65)); 16905b261ecSmrg } 17005b261ecSmrg else supported = 1; 17105b261ecSmrg 17205b261ecSmrg if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) { 17305b261ecSmrg client->xkbClientFlags= _XkbClientInitialized; 17405b261ecSmrg client->vMajor= stuff->wantedMajor; 17505b261ecSmrg client->vMinor= stuff->wantedMinor; 17605b261ecSmrg } 17705b261ecSmrg else if (xkbDebugFlags&0x1) { 1784642e01fSmrg ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", 17905b261ecSmrg client->index, 18005b261ecSmrg (long)client->clientAsMask, 18105b261ecSmrg stuff->wantedMajor,stuff->wantedMinor, 18205b261ecSmrg XkbMajorVersion,XkbMinorVersion); 18305b261ecSmrg } 18405b261ecSmrg rep.type = X_Reply; 18505b261ecSmrg rep.supported = supported; 18605b261ecSmrg rep.length = 0; 18705b261ecSmrg rep.sequenceNumber = client->sequence; 18805b261ecSmrg rep.serverMajor = XkbMajorVersion; 18905b261ecSmrg rep.serverMinor = XkbMinorVersion; 19005b261ecSmrg if ( client->swapped ) { 19105b261ecSmrg swaps(&rep.sequenceNumber, n); 19205b261ecSmrg swaps(&rep.serverMajor, n); 19305b261ecSmrg swaps(&rep.serverMinor, n); 19405b261ecSmrg } 19505b261ecSmrg WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep); 19605b261ecSmrg return client->noClientException; 19705b261ecSmrg} 19805b261ecSmrg 19905b261ecSmrg/***====================================================================***/ 20005b261ecSmrg 20105b261ecSmrgint 20205b261ecSmrgProcXkbSelectEvents(ClientPtr client) 20305b261ecSmrg{ 20405b261ecSmrg unsigned legal; 20505b261ecSmrg DeviceIntPtr dev; 20605b261ecSmrg XkbInterestPtr masks; 20705b261ecSmrg REQUEST(xkbSelectEventsReq); 20805b261ecSmrg 20905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); 21005b261ecSmrg 21105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 21205b261ecSmrg return BadAccess; 21305b261ecSmrg 2144642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess); 21505b261ecSmrg 21605b261ecSmrg if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) { 21705b261ecSmrg client->mapNotifyMask&= ~stuff->affectMap; 21805b261ecSmrg client->mapNotifyMask|= (stuff->affectMap&stuff->map); 21905b261ecSmrg } 22005b261ecSmrg if ((stuff->affectWhich&(~XkbMapNotifyMask))==0) 22105b261ecSmrg return client->noClientException; 22205b261ecSmrg 22305b261ecSmrg masks = XkbFindClientResource((DevicePtr)dev,client); 22405b261ecSmrg if (!masks){ 22505b261ecSmrg XID id = FakeClientID(client->index); 22605b261ecSmrg AddResource(id,RT_XKBCLIENT,dev); 22705b261ecSmrg masks= XkbAddClientResource((DevicePtr)dev,client,id); 22805b261ecSmrg } 22905b261ecSmrg if (masks) { 23005b261ecSmrg union { 23105b261ecSmrg CARD8 *c8; 23205b261ecSmrg CARD16 *c16; 23305b261ecSmrg CARD32 *c32; 23405b261ecSmrg } from,to; 23505b261ecSmrg register unsigned bit,ndx,maskLeft,dataLeft,size; 23605b261ecSmrg 23705b261ecSmrg from.c8= (CARD8 *)&stuff[1]; 23805b261ecSmrg dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq); 23905b261ecSmrg maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask)); 24005b261ecSmrg for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) { 24105b261ecSmrg if ((bit&maskLeft)==0) 24205b261ecSmrg continue; 24305b261ecSmrg maskLeft&= ~bit; 24405b261ecSmrg switch (ndx) { 24505b261ecSmrg case XkbNewKeyboardNotify: 24605b261ecSmrg to.c16= &client->newKeyboardNotifyMask; 24705b261ecSmrg legal= XkbAllNewKeyboardEventsMask; 24805b261ecSmrg size= 2; 24905b261ecSmrg break; 25005b261ecSmrg case XkbStateNotify: 25105b261ecSmrg to.c16= &masks->stateNotifyMask; 25205b261ecSmrg legal= XkbAllStateEventsMask; 25305b261ecSmrg size= 2; 25405b261ecSmrg break; 25505b261ecSmrg case XkbControlsNotify: 25605b261ecSmrg to.c32= &masks->ctrlsNotifyMask; 25705b261ecSmrg legal= XkbAllControlEventsMask; 25805b261ecSmrg size= 4; 25905b261ecSmrg break; 26005b261ecSmrg case XkbIndicatorStateNotify: 26105b261ecSmrg to.c32= &masks->iStateNotifyMask; 26205b261ecSmrg legal= XkbAllIndicatorEventsMask; 26305b261ecSmrg size= 4; 26405b261ecSmrg break; 26505b261ecSmrg case XkbIndicatorMapNotify: 26605b261ecSmrg to.c32= &masks->iMapNotifyMask; 26705b261ecSmrg legal= XkbAllIndicatorEventsMask; 26805b261ecSmrg size= 4; 26905b261ecSmrg break; 27005b261ecSmrg case XkbNamesNotify: 27105b261ecSmrg to.c16= &masks->namesNotifyMask; 27205b261ecSmrg legal= XkbAllNameEventsMask; 27305b261ecSmrg size= 2; 27405b261ecSmrg break; 27505b261ecSmrg case XkbCompatMapNotify: 27605b261ecSmrg to.c8= &masks->compatNotifyMask; 27705b261ecSmrg legal= XkbAllCompatMapEventsMask; 27805b261ecSmrg size= 1; 27905b261ecSmrg break; 28005b261ecSmrg case XkbBellNotify: 28105b261ecSmrg to.c8= &masks->bellNotifyMask; 28205b261ecSmrg legal= XkbAllBellEventsMask; 28305b261ecSmrg size= 1; 28405b261ecSmrg break; 28505b261ecSmrg case XkbActionMessage: 28605b261ecSmrg to.c8= &masks->actionMessageMask; 28705b261ecSmrg legal= XkbAllActionMessagesMask; 28805b261ecSmrg size= 1; 28905b261ecSmrg break; 29005b261ecSmrg case XkbAccessXNotify: 29105b261ecSmrg to.c16= &masks->accessXNotifyMask; 29205b261ecSmrg legal= XkbAllAccessXEventsMask; 29305b261ecSmrg size= 2; 29405b261ecSmrg break; 29505b261ecSmrg case XkbExtensionDeviceNotify: 29605b261ecSmrg to.c16= &masks->extDevNotifyMask; 29705b261ecSmrg legal= XkbAllExtensionDeviceEventsMask; 29805b261ecSmrg size= 2; 29905b261ecSmrg break; 30005b261ecSmrg default: 30105b261ecSmrg client->errorValue = _XkbErrCode2(33,bit); 30205b261ecSmrg return BadValue; 30305b261ecSmrg } 30405b261ecSmrg 30505b261ecSmrg if (stuff->clear&bit) { 30605b261ecSmrg if (size==2) to.c16[0]= 0; 30705b261ecSmrg else if (size==4) to.c32[0]= 0; 30805b261ecSmrg else to.c8[0]= 0; 30905b261ecSmrg } 31005b261ecSmrg else if (stuff->selectAll&bit) { 31105b261ecSmrg if (size==2) to.c16[0]= ~0; 31205b261ecSmrg else if (size==4) to.c32[0]= ~0; 31305b261ecSmrg else to.c8[0]= ~0; 31405b261ecSmrg } 31505b261ecSmrg else { 31605b261ecSmrg if (dataLeft<(size*2)) 31705b261ecSmrg return BadLength; 31805b261ecSmrg if (size==2) { 31905b261ecSmrg CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]); 32005b261ecSmrg CHK_MASK_LEGAL(ndx,from.c16[0],legal); 32105b261ecSmrg to.c16[0]&= ~from.c16[0]; 32205b261ecSmrg to.c16[0]|= (from.c16[0]&from.c16[1]); 32305b261ecSmrg } 32405b261ecSmrg else if (size==4) { 32505b261ecSmrg CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]); 32605b261ecSmrg CHK_MASK_LEGAL(ndx,from.c32[0],legal); 32705b261ecSmrg to.c32[0]&= ~from.c32[0]; 32805b261ecSmrg to.c32[0]|= (from.c32[0]&from.c32[1]); 32905b261ecSmrg } 33005b261ecSmrg else { 33105b261ecSmrg CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]); 33205b261ecSmrg CHK_MASK_LEGAL(ndx,from.c8[0],legal); 33305b261ecSmrg to.c8[0]&= ~from.c8[0]; 33405b261ecSmrg to.c8[0]|= (from.c8[0]&from.c8[1]); 33505b261ecSmrg size= 2; 33605b261ecSmrg } 33705b261ecSmrg from.c8+= (size*2); 33805b261ecSmrg dataLeft-= (size*2); 33905b261ecSmrg } 34005b261ecSmrg } 34105b261ecSmrg if (dataLeft>2) { 3424642e01fSmrg ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft); 34305b261ecSmrg return BadLength; 34405b261ecSmrg } 34505b261ecSmrg return client->noClientException; 34605b261ecSmrg } 34705b261ecSmrg return BadAlloc; 34805b261ecSmrg} 34905b261ecSmrg 35005b261ecSmrg/***====================================================================***/ 3514642e01fSmrg/** 3524642e01fSmrg * Ring a bell on the given device for the given client. 3534642e01fSmrg */ 3544642e01fSmrgstatic int 3554642e01fSmrg_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, 3564642e01fSmrg int bellClass, int bellID, int pitch, int duration, 3574642e01fSmrg int percent, int forceSound, int eventOnly, Atom name) 3584642e01fSmrg{ 3594642e01fSmrg int base; 3604642e01fSmrg pointer ctrl; 3614642e01fSmrg int oldPitch, oldDuration; 3624642e01fSmrg int newPercent; 3634642e01fSmrg 3644642e01fSmrg if (bellClass == KbdFeedbackClass) { 3654642e01fSmrg KbdFeedbackPtr k; 3664642e01fSmrg if (bellID==XkbDfltXIId) 3674642e01fSmrg k= dev->kbdfeed; 3684642e01fSmrg else { 3694642e01fSmrg for (k=dev->kbdfeed; k; k=k->next) { 3704642e01fSmrg if (k->ctrl.id == bellID) 3714642e01fSmrg break; 3724642e01fSmrg } 3734642e01fSmrg } 3744642e01fSmrg if (!k) { 3754642e01fSmrg client->errorValue = _XkbErrCode2(0x5,bellID); 3764642e01fSmrg return BadValue; 3774642e01fSmrg } 3784642e01fSmrg base = k->ctrl.bell; 3794642e01fSmrg ctrl = (pointer) &(k->ctrl); 3804642e01fSmrg oldPitch= k->ctrl.bell_pitch; 3814642e01fSmrg oldDuration= k->ctrl.bell_duration; 3824642e01fSmrg if (pitch!=0) { 3834642e01fSmrg if (pitch==-1) 3844642e01fSmrg k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; 3854642e01fSmrg else k->ctrl.bell_pitch= pitch; 3864642e01fSmrg } 3874642e01fSmrg if (duration!=0) { 3884642e01fSmrg if (duration==-1) 3894642e01fSmrg k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; 3904642e01fSmrg else k->ctrl.bell_duration= duration; 3914642e01fSmrg } 3924642e01fSmrg } 3934642e01fSmrg else if (bellClass == BellFeedbackClass) { 3944642e01fSmrg BellFeedbackPtr b; 3954642e01fSmrg if (bellID==XkbDfltXIId) 3964642e01fSmrg b= dev->bell; 3974642e01fSmrg else { 3984642e01fSmrg for (b=dev->bell; b; b=b->next) { 3994642e01fSmrg if (b->ctrl.id == bellID) 4004642e01fSmrg break; 4014642e01fSmrg } 4024642e01fSmrg } 4034642e01fSmrg if (!b) { 4044642e01fSmrg client->errorValue = _XkbErrCode2(0x6,bellID); 4054642e01fSmrg return BadValue; 4064642e01fSmrg } 4074642e01fSmrg base = b->ctrl.percent; 4084642e01fSmrg ctrl = (pointer) &(b->ctrl); 4094642e01fSmrg oldPitch= b->ctrl.pitch; 4104642e01fSmrg oldDuration= b->ctrl.duration; 4114642e01fSmrg if (pitch!=0) { 4124642e01fSmrg if (pitch==-1) 4134642e01fSmrg b->ctrl.pitch= defaultKeyboardControl.bell_pitch; 4144642e01fSmrg else b->ctrl.pitch= pitch; 4154642e01fSmrg } 4164642e01fSmrg if (duration!=0) { 4174642e01fSmrg if (duration==-1) 4184642e01fSmrg b->ctrl.duration= defaultKeyboardControl.bell_duration; 4194642e01fSmrg else b->ctrl.duration= duration; 4204642e01fSmrg } 4214642e01fSmrg } 4224642e01fSmrg else { 4234642e01fSmrg client->errorValue = _XkbErrCode2(0x7, bellClass); 4244642e01fSmrg return BadValue; 4254642e01fSmrg } 4264642e01fSmrg 4274642e01fSmrg newPercent = (base * percent)/100; 4284642e01fSmrg if (percent < 0) 4294642e01fSmrg newPercent = base + newPercent; 4304642e01fSmrg else newPercent = base - newPercent + percent; 4314642e01fSmrg 4324642e01fSmrg XkbHandleBell(forceSound, eventOnly, 4334642e01fSmrg dev, newPercent, ctrl, bellClass, 4344642e01fSmrg name, pWin, client); 4354642e01fSmrg if ((pitch!=0)||(duration!=0)) { 4364642e01fSmrg if (bellClass == KbdFeedbackClass) { 4374642e01fSmrg KbdFeedbackPtr k; 4384642e01fSmrg k= (KbdFeedbackPtr)ctrl; 4394642e01fSmrg if (pitch!=0) 4404642e01fSmrg k->ctrl.bell_pitch= oldPitch; 4414642e01fSmrg if (duration!=0) 4424642e01fSmrg k->ctrl.bell_duration= oldDuration; 4434642e01fSmrg } 4444642e01fSmrg else { 4454642e01fSmrg BellFeedbackPtr b; 4464642e01fSmrg b= (BellFeedbackPtr)ctrl; 4474642e01fSmrg if (pitch!=0) 4484642e01fSmrg b->ctrl.pitch= oldPitch; 4494642e01fSmrg if (duration!=0) 4504642e01fSmrg b->ctrl.duration= oldDuration; 4514642e01fSmrg } 4524642e01fSmrg } 4534642e01fSmrg 4544642e01fSmrg return Success; 4554642e01fSmrg} 45605b261ecSmrg 45705b261ecSmrgint 45805b261ecSmrgProcXkbBell(ClientPtr client) 45905b261ecSmrg{ 46005b261ecSmrg REQUEST(xkbBellReq); 46105b261ecSmrg DeviceIntPtr dev; 46205b261ecSmrg WindowPtr pWin; 4634642e01fSmrg int rc; 46405b261ecSmrg 46505b261ecSmrg REQUEST_SIZE_MATCH(xkbBellReq); 46605b261ecSmrg 46705b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 46805b261ecSmrg return BadAccess; 46905b261ecSmrg 4704642e01fSmrg CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); 47105b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 47205b261ecSmrg 4734642e01fSmrg /* device-independent checks request for sane values */ 47405b261ecSmrg if ((stuff->forceSound)&&(stuff->eventOnly)) { 47505b261ecSmrg client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); 47605b261ecSmrg return BadMatch; 47705b261ecSmrg } 47805b261ecSmrg if (stuff->percent < -100 || stuff->percent > 100) { 47905b261ecSmrg client->errorValue = _XkbErrCode2(0x2,stuff->percent); 48005b261ecSmrg return BadValue; 48105b261ecSmrg } 48205b261ecSmrg if (stuff->duration<-1) { 48305b261ecSmrg client->errorValue = _XkbErrCode2(0x3,stuff->duration); 48405b261ecSmrg return BadValue; 48505b261ecSmrg } 48605b261ecSmrg if (stuff->pitch<-1) { 48705b261ecSmrg client->errorValue = _XkbErrCode2(0x4,stuff->pitch); 48805b261ecSmrg return BadValue; 48905b261ecSmrg } 49005b261ecSmrg 49105b261ecSmrg if (stuff->bellClass == XkbDfltXIClass) { 49205b261ecSmrg if (dev->kbdfeed!=NULL) 49305b261ecSmrg stuff->bellClass= KbdFeedbackClass; 49405b261ecSmrg else stuff->bellClass= BellFeedbackClass; 49505b261ecSmrg } 4964642e01fSmrg 49705b261ecSmrg if (stuff->window!=None) { 4984642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 4994642e01fSmrg if (rc != Success) { 50005b261ecSmrg client->errorValue= stuff->window; 5014642e01fSmrg return rc; 50205b261ecSmrg } 50305b261ecSmrg } 50405b261ecSmrg else pWin= NULL; 50505b261ecSmrg 5064642e01fSmrg /* Client wants to ring a bell on the core keyboard? 5074642e01fSmrg Ring the bell on the core keyboard (which does nothing, but if that 5084642e01fSmrg fails the client is screwed anyway), and then on all extension devices. 5094642e01fSmrg Fail if the core keyboard fails but not the extension devices. this 5104642e01fSmrg may cause some keyboards to ding and others to stay silent. Fix 5114642e01fSmrg your client to use explicit keyboards to avoid this. 5124642e01fSmrg 5134642e01fSmrg dev is the device the client requested. 5144642e01fSmrg */ 5154642e01fSmrg rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, 5164642e01fSmrg stuff->pitch, stuff->duration, stuff->percent, 5174642e01fSmrg stuff->forceSound, stuff->eventOnly, stuff->name); 5184642e01fSmrg 5194642e01fSmrg if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || 5204642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr))) 5214642e01fSmrg { 5224642e01fSmrg DeviceIntPtr other; 5234642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 5244642e01fSmrg { 5254642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 5264642e01fSmrg { 5274642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); 5284642e01fSmrg if (rc == Success) 5294642e01fSmrg _XkbBell(client, other, pWin, stuff->bellClass, 5304642e01fSmrg stuff->bellID, stuff->pitch, stuff->duration, 5314642e01fSmrg stuff->percent, stuff->forceSound, 5324642e01fSmrg stuff->eventOnly, stuff->name); 5334642e01fSmrg } 5344642e01fSmrg } 5354642e01fSmrg rc = Success; /* reset to success, that's what we got for the VCK */ 53605b261ecSmrg } 5374642e01fSmrg 5384642e01fSmrg return rc; 53905b261ecSmrg} 54005b261ecSmrg 54105b261ecSmrg/***====================================================================***/ 54205b261ecSmrg 54305b261ecSmrgint 54405b261ecSmrgProcXkbGetState(ClientPtr client) 54505b261ecSmrg{ 54605b261ecSmrg REQUEST(xkbGetStateReq); 54705b261ecSmrg DeviceIntPtr dev; 54805b261ecSmrg xkbGetStateReply rep; 54905b261ecSmrg XkbStateRec *xkb; 55005b261ecSmrg 55105b261ecSmrg REQUEST_SIZE_MATCH(xkbGetStateReq); 55205b261ecSmrg 55305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 55405b261ecSmrg return BadAccess; 55505b261ecSmrg 5564642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 55705b261ecSmrg 55805b261ecSmrg xkb= &dev->key->xkbInfo->state; 55905b261ecSmrg bzero(&rep,sizeof(xkbGetStateReply)); 56005b261ecSmrg rep.type= X_Reply; 56105b261ecSmrg rep.sequenceNumber= client->sequence; 56205b261ecSmrg rep.length = 0; 56305b261ecSmrg rep.deviceID = dev->id; 56405b261ecSmrg rep.mods = dev->key->state&0xff; 56505b261ecSmrg rep.baseMods = xkb->base_mods; 56605b261ecSmrg rep.lockedMods = xkb->locked_mods; 56705b261ecSmrg rep.latchedMods = xkb->latched_mods; 56805b261ecSmrg rep.group = xkb->group; 56905b261ecSmrg rep.baseGroup = xkb->base_group; 57005b261ecSmrg rep.latchedGroup = xkb->latched_group; 57105b261ecSmrg rep.lockedGroup = xkb->locked_group; 57205b261ecSmrg rep.compatState = xkb->compat_state; 57305b261ecSmrg rep.ptrBtnState = xkb->ptr_buttons; 57405b261ecSmrg if (client->swapped) { 57505b261ecSmrg register int n; 57605b261ecSmrg swaps(&rep.sequenceNumber,n); 57705b261ecSmrg swaps(&rep.ptrBtnState,n); 57805b261ecSmrg } 57905b261ecSmrg WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep); 58005b261ecSmrg return client->noClientException; 58105b261ecSmrg} 58205b261ecSmrg 58305b261ecSmrg/***====================================================================***/ 58405b261ecSmrg 58505b261ecSmrgint 58605b261ecSmrgProcXkbLatchLockState(ClientPtr client) 58705b261ecSmrg{ 58805b261ecSmrg int status; 58905b261ecSmrg DeviceIntPtr dev, tmpd; 59005b261ecSmrg XkbStateRec oldState,*newState; 59105b261ecSmrg CARD16 changed; 59205b261ecSmrg xkbStateNotify sn; 59305b261ecSmrg XkbEventCauseRec cause; 59405b261ecSmrg 59505b261ecSmrg REQUEST(xkbLatchLockStateReq); 59605b261ecSmrg REQUEST_SIZE_MATCH(xkbLatchLockStateReq); 59705b261ecSmrg 59805b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 59905b261ecSmrg return BadAccess; 60005b261ecSmrg 6014642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 60205b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); 60305b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); 60405b261ecSmrg 60505b261ecSmrg status = Success; 60605b261ecSmrg 60705b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 60805b261ecSmrg if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) || 60905b261ecSmrg tmpd == dev) { 61005b261ecSmrg if (!tmpd->key->xkbInfo) 61105b261ecSmrg continue; 61205b261ecSmrg 61305b261ecSmrg oldState = tmpd->key->xkbInfo->state; 61405b261ecSmrg newState = &tmpd->key->xkbInfo->state; 61505b261ecSmrg if (stuff->affectModLocks) { 61605b261ecSmrg newState->locked_mods &= ~stuff->affectModLocks; 61705b261ecSmrg newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks); 61805b261ecSmrg } 61905b261ecSmrg if (status == Success && stuff->lockGroup) 62005b261ecSmrg newState->locked_group = stuff->groupLock; 62105b261ecSmrg if (status == Success && stuff->affectModLatches) 62205b261ecSmrg status = XkbLatchModifiers(tmpd, stuff->affectModLatches, 62305b261ecSmrg stuff->modLatches); 62405b261ecSmrg if (status == Success && stuff->latchGroup) 62505b261ecSmrg status = XkbLatchGroup(tmpd, stuff->groupLatch); 62605b261ecSmrg 62705b261ecSmrg if (status != Success) 62805b261ecSmrg return status; 62905b261ecSmrg 63005b261ecSmrg XkbComputeDerivedState(tmpd->key->xkbInfo); 63105b261ecSmrg tmpd->key->state = XkbStateFieldFromRec(newState); 63205b261ecSmrg 63305b261ecSmrg changed = XkbStateChangedFlags(&oldState, newState); 63405b261ecSmrg if (changed) { 63505b261ecSmrg sn.keycode = 0; 63605b261ecSmrg sn.eventType = 0; 63705b261ecSmrg sn.requestMajor = XkbReqCode; 63805b261ecSmrg sn.requestMinor = X_kbLatchLockState; 63905b261ecSmrg sn.changed = changed; 64005b261ecSmrg XkbSendStateNotify(tmpd, &sn); 64105b261ecSmrg changed = XkbIndicatorsToUpdate(tmpd, changed, False); 64205b261ecSmrg if (changed) { 64305b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); 64405b261ecSmrg XkbUpdateIndicators(tmpd, changed, True, NULL, &cause); 64505b261ecSmrg } 64605b261ecSmrg } 64705b261ecSmrg } 64805b261ecSmrg } 64905b261ecSmrg 65005b261ecSmrg return client->noClientException; 65105b261ecSmrg} 65205b261ecSmrg 65305b261ecSmrg/***====================================================================***/ 65405b261ecSmrg 65505b261ecSmrgint 65605b261ecSmrgProcXkbGetControls(ClientPtr client) 65705b261ecSmrg{ 65805b261ecSmrg xkbGetControlsReply rep; 65905b261ecSmrg XkbControlsPtr xkb; 66005b261ecSmrg DeviceIntPtr dev; 66105b261ecSmrg register int n; 66205b261ecSmrg 66305b261ecSmrg REQUEST(xkbGetControlsReq); 66405b261ecSmrg REQUEST_SIZE_MATCH(xkbGetControlsReq); 66505b261ecSmrg 66605b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 66705b261ecSmrg return BadAccess; 66805b261ecSmrg 6694642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 67005b261ecSmrg 67105b261ecSmrg xkb = dev->key->xkbInfo->desc->ctrls; 67205b261ecSmrg rep.type = X_Reply; 67305b261ecSmrg rep.length = (SIZEOF(xkbGetControlsReply)- 67405b261ecSmrg SIZEOF(xGenericReply)) >> 2; 67505b261ecSmrg rep.sequenceNumber = client->sequence; 67605b261ecSmrg rep.deviceID = ((DeviceIntPtr)dev)->id; 67705b261ecSmrg rep.numGroups = xkb->num_groups; 67805b261ecSmrg rep.groupsWrap = xkb->groups_wrap; 67905b261ecSmrg rep.internalMods = xkb->internal.mask; 68005b261ecSmrg rep.ignoreLockMods = xkb->ignore_lock.mask; 68105b261ecSmrg rep.internalRealMods = xkb->internal.real_mods; 68205b261ecSmrg rep.ignoreLockRealMods = xkb->ignore_lock.real_mods; 68305b261ecSmrg rep.internalVMods = xkb->internal.vmods; 68405b261ecSmrg rep.ignoreLockVMods = xkb->ignore_lock.vmods; 68505b261ecSmrg rep.enabledCtrls = xkb->enabled_ctrls; 68605b261ecSmrg rep.repeatDelay = xkb->repeat_delay; 68705b261ecSmrg rep.repeatInterval = xkb->repeat_interval; 68805b261ecSmrg rep.slowKeysDelay = xkb->slow_keys_delay; 68905b261ecSmrg rep.debounceDelay = xkb->debounce_delay; 69005b261ecSmrg rep.mkDelay = xkb->mk_delay; 69105b261ecSmrg rep.mkInterval = xkb->mk_interval; 69205b261ecSmrg rep.mkTimeToMax = xkb->mk_time_to_max; 69305b261ecSmrg rep.mkMaxSpeed = xkb->mk_max_speed; 69405b261ecSmrg rep.mkCurve = xkb->mk_curve; 69505b261ecSmrg rep.mkDfltBtn = xkb->mk_dflt_btn; 69605b261ecSmrg rep.axTimeout = xkb->ax_timeout; 69705b261ecSmrg rep.axtCtrlsMask = xkb->axt_ctrls_mask; 69805b261ecSmrg rep.axtCtrlsValues = xkb->axt_ctrls_values; 69905b261ecSmrg rep.axtOptsMask = xkb->axt_opts_mask; 70005b261ecSmrg rep.axtOptsValues = xkb->axt_opts_values; 70105b261ecSmrg rep.axOptions = xkb->ax_options; 70205b261ecSmrg memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize); 70305b261ecSmrg if (client->swapped) { 70405b261ecSmrg swaps(&rep.sequenceNumber, n); 70505b261ecSmrg swapl(&rep.length,n); 70605b261ecSmrg swaps(&rep.internalVMods, n); 70705b261ecSmrg swaps(&rep.ignoreLockVMods, n); 70805b261ecSmrg swapl(&rep.enabledCtrls, n); 70905b261ecSmrg swaps(&rep.repeatDelay, n); 71005b261ecSmrg swaps(&rep.repeatInterval, n); 71105b261ecSmrg swaps(&rep.slowKeysDelay, n); 71205b261ecSmrg swaps(&rep.debounceDelay, n); 71305b261ecSmrg swaps(&rep.mkDelay, n); 71405b261ecSmrg swaps(&rep.mkInterval, n); 71505b261ecSmrg swaps(&rep.mkTimeToMax, n); 71605b261ecSmrg swaps(&rep.mkMaxSpeed, n); 71705b261ecSmrg swaps(&rep.mkCurve, n); 71805b261ecSmrg swaps(&rep.axTimeout, n); 71905b261ecSmrg swapl(&rep.axtCtrlsMask, n); 72005b261ecSmrg swapl(&rep.axtCtrlsValues, n); 72105b261ecSmrg swaps(&rep.axtOptsMask, n); 72205b261ecSmrg swaps(&rep.axtOptsValues, n); 72305b261ecSmrg swaps(&rep.axOptions, n); 72405b261ecSmrg } 72505b261ecSmrg WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep); 72605b261ecSmrg return(client->noClientException); 72705b261ecSmrg} 72805b261ecSmrg 72905b261ecSmrgint 73005b261ecSmrgProcXkbSetControls(ClientPtr client) 73105b261ecSmrg{ 73205b261ecSmrg DeviceIntPtr dev, tmpd; 73305b261ecSmrg XkbSrvInfoPtr xkbi; 73405b261ecSmrg XkbControlsPtr ctrl; 73505b261ecSmrg XkbControlsRec new,old; 73605b261ecSmrg xkbControlsNotify cn; 73705b261ecSmrg XkbEventCauseRec cause; 73805b261ecSmrg XkbSrvLedInfoPtr sli; 73905b261ecSmrg 74005b261ecSmrg REQUEST(xkbSetControlsReq); 74105b261ecSmrg REQUEST_SIZE_MATCH(xkbSetControlsReq); 74205b261ecSmrg 74305b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 74405b261ecSmrg return BadAccess; 74505b261ecSmrg 7464642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 74705b261ecSmrg CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask); 74805b261ecSmrg 74905b261ecSmrg for (tmpd = inputInfo.keyboard; tmpd; tmpd = tmpd->next) { 75005b261ecSmrg if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) || 75105b261ecSmrg tmpd == dev) { 75205b261ecSmrg 75305b261ecSmrg xkbi = tmpd->key->xkbInfo; 75405b261ecSmrg ctrl = xkbi->desc->ctrls; 75505b261ecSmrg new = *ctrl; 75605b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbSetControls, client); 75705b261ecSmrg 75805b261ecSmrg if (stuff->changeCtrls & XkbInternalModsMask) { 75905b261ecSmrg CHK_MASK_MATCH(0x02, stuff->affectInternalMods, 76005b261ecSmrg stuff->internalMods); 76105b261ecSmrg CHK_MASK_MATCH(0x03, stuff->affectInternalVMods, 76205b261ecSmrg stuff->internalVMods); 76305b261ecSmrg 76405b261ecSmrg new.internal.real_mods &= ~(stuff->affectInternalMods); 76505b261ecSmrg new.internal.real_mods |= (stuff->affectInternalMods & 76605b261ecSmrg stuff->internalMods); 76705b261ecSmrg new.internal.vmods &= ~(stuff->affectInternalVMods); 76805b261ecSmrg new.internal.vmods |= (stuff->affectInternalVMods & 76905b261ecSmrg stuff->internalVMods); 77005b261ecSmrg new.internal.mask = new.internal.real_mods | 77105b261ecSmrg XkbMaskForVMask(xkbi->desc, 77205b261ecSmrg new.internal.vmods); 77305b261ecSmrg } 77405b261ecSmrg 77505b261ecSmrg if (stuff->changeCtrls & XkbIgnoreLockModsMask) { 77605b261ecSmrg CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods, 77705b261ecSmrg stuff->ignoreLockMods); 77805b261ecSmrg CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods, 77905b261ecSmrg stuff->ignoreLockVMods); 78005b261ecSmrg 78105b261ecSmrg new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods); 78205b261ecSmrg new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods & 78305b261ecSmrg stuff->ignoreLockMods); 78405b261ecSmrg new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods); 78505b261ecSmrg new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods & 78605b261ecSmrg stuff->ignoreLockVMods); 78705b261ecSmrg new.ignore_lock.mask = new.ignore_lock.real_mods | 78805b261ecSmrg XkbMaskForVMask(xkbi->desc, 78905b261ecSmrg new.ignore_lock.vmods); 79005b261ecSmrg } 79105b261ecSmrg 79205b261ecSmrg CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls, 79305b261ecSmrg stuff->enabledCtrls); 79405b261ecSmrg if (stuff->affectEnabledCtrls) { 79505b261ecSmrg CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls, 79605b261ecSmrg XkbAllBooleanCtrlsMask); 79705b261ecSmrg 79805b261ecSmrg new.enabled_ctrls &= ~(stuff->affectEnabledCtrls); 79905b261ecSmrg new.enabled_ctrls |= (stuff->affectEnabledCtrls & 80005b261ecSmrg stuff->enabledCtrls); 80105b261ecSmrg } 80205b261ecSmrg 80305b261ecSmrg if (stuff->changeCtrls & XkbRepeatKeysMask) { 80405b261ecSmrg if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) { 80505b261ecSmrg client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay, 80605b261ecSmrg stuff->repeatInterval); 80705b261ecSmrg return BadValue; 80805b261ecSmrg } 80905b261ecSmrg 81005b261ecSmrg new.repeat_delay = stuff->repeatDelay; 81105b261ecSmrg new.repeat_interval = stuff->repeatInterval; 81205b261ecSmrg } 81305b261ecSmrg 81405b261ecSmrg if (stuff->changeCtrls & XkbSlowKeysMask) { 81505b261ecSmrg if (stuff->slowKeysDelay < 1) { 81605b261ecSmrg client->errorValue = _XkbErrCode2(0x09, 81705b261ecSmrg stuff->slowKeysDelay); 81805b261ecSmrg return BadValue; 81905b261ecSmrg } 82005b261ecSmrg 82105b261ecSmrg new.slow_keys_delay = stuff->slowKeysDelay; 82205b261ecSmrg } 82305b261ecSmrg 82405b261ecSmrg if (stuff->changeCtrls & XkbBounceKeysMask) { 82505b261ecSmrg if (stuff->debounceDelay < 1) { 82605b261ecSmrg client->errorValue = _XkbErrCode2(0x0A, 82705b261ecSmrg stuff->debounceDelay); 82805b261ecSmrg return BadValue; 82905b261ecSmrg } 83005b261ecSmrg 83105b261ecSmrg new.debounce_delay = stuff->debounceDelay; 83205b261ecSmrg } 83305b261ecSmrg 83405b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysMask) { 83505b261ecSmrg if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) { 83605b261ecSmrg client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn); 83705b261ecSmrg return BadValue; 83805b261ecSmrg } 83905b261ecSmrg 84005b261ecSmrg new.mk_dflt_btn = stuff->mkDfltBtn; 84105b261ecSmrg } 84205b261ecSmrg 84305b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysAccelMask) { 84405b261ecSmrg if (stuff->mkDelay < 1 || stuff->mkInterval < 1 || 84505b261ecSmrg stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 || 84605b261ecSmrg stuff->mkCurve < -1000) { 84705b261ecSmrg client->errorValue = _XkbErrCode2(0x0C,0); 84805b261ecSmrg return BadValue; 84905b261ecSmrg } 85005b261ecSmrg 85105b261ecSmrg new.mk_delay = stuff->mkDelay; 85205b261ecSmrg new.mk_interval = stuff->mkInterval; 85305b261ecSmrg new.mk_time_to_max = stuff->mkTimeToMax; 85405b261ecSmrg new.mk_max_speed = stuff->mkMaxSpeed; 85505b261ecSmrg new.mk_curve = stuff->mkCurve; 85605b261ecSmrg AccessXComputeCurveFactor(xkbi, &new); 85705b261ecSmrg } 85805b261ecSmrg 85905b261ecSmrg if (stuff->changeCtrls & XkbGroupsWrapMask) { 86005b261ecSmrg unsigned act, num; 86105b261ecSmrg 86205b261ecSmrg act = XkbOutOfRangeGroupAction(stuff->groupsWrap); 86305b261ecSmrg switch (act) { 86405b261ecSmrg case XkbRedirectIntoRange: 86505b261ecSmrg num = XkbOutOfRangeGroupNumber(stuff->groupsWrap); 86605b261ecSmrg if (num >= new.num_groups) { 86705b261ecSmrg client->errorValue = _XkbErrCode3(0x0D, new.num_groups, 86805b261ecSmrg num); 86905b261ecSmrg return BadValue; 87005b261ecSmrg } 87105b261ecSmrg case XkbWrapIntoRange: 87205b261ecSmrg case XkbClampIntoRange: 87305b261ecSmrg break; 87405b261ecSmrg default: 87505b261ecSmrg client->errorValue = _XkbErrCode2(0x0E, act); 87605b261ecSmrg return BadValue; 87705b261ecSmrg } 87805b261ecSmrg 87905b261ecSmrg new.groups_wrap= stuff->groupsWrap; 88005b261ecSmrg } 88105b261ecSmrg 88205b261ecSmrg CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask); 88305b261ecSmrg if (stuff->changeCtrls & XkbAccessXKeysMask) { 88405b261ecSmrg new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask; 88505b261ecSmrg } 88605b261ecSmrg else { 88705b261ecSmrg if (stuff->changeCtrls & XkbStickyKeysMask) { 88805b261ecSmrg new.ax_options &= ~(XkbAX_SKOptionsMask); 88905b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask); 89005b261ecSmrg } 89105b261ecSmrg 89205b261ecSmrg if (stuff->changeCtrls & XkbAccessXFeedbackMask) { 89305b261ecSmrg new.ax_options &= ~(XkbAX_FBOptionsMask); 89405b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask); 89505b261ecSmrg } 89605b261ecSmrg } 89705b261ecSmrg 89805b261ecSmrg if (stuff->changeCtrls & XkbAccessXTimeoutMask) { 89905b261ecSmrg if (stuff->axTimeout < 1) { 90005b261ecSmrg client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout); 90105b261ecSmrg return BadValue; 90205b261ecSmrg } 90305b261ecSmrg CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask, 90405b261ecSmrg stuff->axtCtrlsValues); 90505b261ecSmrg CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask, 90605b261ecSmrg XkbAllBooleanCtrlsMask); 90705b261ecSmrg CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues); 90805b261ecSmrg CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask); 90905b261ecSmrg new.ax_timeout = stuff->axTimeout; 91005b261ecSmrg new.axt_ctrls_mask = stuff->axtCtrlsMask; 91105b261ecSmrg new.axt_ctrls_values = (stuff->axtCtrlsValues & 91205b261ecSmrg stuff->axtCtrlsMask); 91305b261ecSmrg new.axt_opts_mask = stuff->axtOptsMask; 91405b261ecSmrg new.axt_opts_values = (stuff->axtOptsValues & 91505b261ecSmrg stuff->axtOptsMask); 91605b261ecSmrg } 91705b261ecSmrg 91805b261ecSmrg if (stuff->changeCtrls & XkbPerKeyRepeatMask) 91905b261ecSmrg memcpy(new.per_key_repeat, stuff->perKeyRepeat, 92005b261ecSmrg XkbPerKeyBitArraySize); 92105b261ecSmrg 92205b261ecSmrg old= *ctrl; 92305b261ecSmrg *ctrl= new; 92405b261ecSmrg XkbDDXChangeControls(tmpd, &old, ctrl); 92505b261ecSmrg 92605b261ecSmrg if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, False)) { 92705b261ecSmrg cn.keycode = 0; 92805b261ecSmrg cn.eventType = 0; 92905b261ecSmrg cn.requestMajor = XkbReqCode; 93005b261ecSmrg cn.requestMinor = X_kbSetControls; 93105b261ecSmrg XkbSendControlsNotify(tmpd, &cn); 93205b261ecSmrg } 93305b261ecSmrg 93405b261ecSmrg sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); 93505b261ecSmrg if (sli) 93605b261ecSmrg XkbUpdateIndicators(tmpd, sli->usesControls, True, NULL, 93705b261ecSmrg &cause); 93805b261ecSmrg 93905b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 94005b261ecSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 94105b261ecSmrg !(ctrl->enabled_ctrls & XkbStickyKeysMask)) 94205b261ecSmrg XkbClearAllLatchesAndLocks(tmpd, xkbi, True, &cause); 94305b261ecSmrg } 94405b261ecSmrg } 94505b261ecSmrg 94605b261ecSmrg return client->noClientException; 94705b261ecSmrg} 94805b261ecSmrg 94905b261ecSmrg/***====================================================================***/ 95005b261ecSmrg 95105b261ecSmrgstatic int 95205b261ecSmrgXkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep) 95305b261ecSmrg{ 95405b261ecSmrg XkbKeyTypeRec *type; 95505b261ecSmrg unsigned i,len; 95605b261ecSmrg 95705b261ecSmrg len= 0; 95805b261ecSmrg if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)|| 95905b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->types)) { 96005b261ecSmrg rep->present&= ~XkbKeyTypesMask; 96105b261ecSmrg rep->firstType= rep->nTypes= 0; 96205b261ecSmrg return 0; 96305b261ecSmrg } 96405b261ecSmrg type= &xkb->map->types[rep->firstType]; 96505b261ecSmrg for (i=0;i<rep->nTypes;i++,type++){ 96605b261ecSmrg len+= SIZEOF(xkbKeyTypeWireDesc); 96705b261ecSmrg if (type->map_count>0) { 96805b261ecSmrg len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc)); 96905b261ecSmrg if (type->preserve) 97005b261ecSmrg len+= (type->map_count*SIZEOF(xkbModsWireDesc)); 97105b261ecSmrg } 97205b261ecSmrg } 97305b261ecSmrg return len; 97405b261ecSmrg} 97505b261ecSmrg 97605b261ecSmrgstatic char * 97705b261ecSmrgXkbWriteKeyTypes( XkbDescPtr xkb, 97805b261ecSmrg xkbGetMapReply * rep, 97905b261ecSmrg char * buf, 98005b261ecSmrg ClientPtr client) 98105b261ecSmrg{ 98205b261ecSmrg XkbKeyTypePtr type; 98305b261ecSmrg unsigned i; 98405b261ecSmrg xkbKeyTypeWireDesc *wire; 98505b261ecSmrg 98605b261ecSmrg type= &xkb->map->types[rep->firstType]; 98705b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 98805b261ecSmrg register unsigned n; 98905b261ecSmrg wire= (xkbKeyTypeWireDesc *)buf; 99005b261ecSmrg wire->mask = type->mods.mask; 99105b261ecSmrg wire->realMods = type->mods.real_mods; 99205b261ecSmrg wire->virtualMods = type->mods.vmods; 99305b261ecSmrg wire->numLevels = type->num_levels; 99405b261ecSmrg wire->nMapEntries = type->map_count; 99505b261ecSmrg wire->preserve = (type->preserve!=NULL); 99605b261ecSmrg if (client->swapped) { 99705b261ecSmrg register int n; 99805b261ecSmrg swaps(&wire->virtualMods,n); 99905b261ecSmrg } 100005b261ecSmrg 100105b261ecSmrg buf= (char *)&wire[1]; 100205b261ecSmrg if (wire->nMapEntries>0) { 100305b261ecSmrg xkbKTMapEntryWireDesc * wire; 100405b261ecSmrg XkbKTMapEntryPtr entry; 100505b261ecSmrg wire= (xkbKTMapEntryWireDesc *)buf; 100605b261ecSmrg entry= type->map; 100705b261ecSmrg for (n=0;n<type->map_count;n++,wire++,entry++) { 100805b261ecSmrg wire->active= entry->active; 100905b261ecSmrg wire->mask= entry->mods.mask; 101005b261ecSmrg wire->level= entry->level; 101105b261ecSmrg wire->realMods= entry->mods.real_mods; 101205b261ecSmrg wire->virtualMods= entry->mods.vmods; 101305b261ecSmrg if (client->swapped) { 101405b261ecSmrg register int n; 101505b261ecSmrg swaps(&wire->virtualMods,n); 101605b261ecSmrg } 101705b261ecSmrg } 101805b261ecSmrg buf= (char *)wire; 101905b261ecSmrg if (type->preserve!=NULL) { 102005b261ecSmrg xkbModsWireDesc * pwire; 102105b261ecSmrg XkbModsPtr preserve; 102205b261ecSmrg pwire= (xkbModsWireDesc *)buf; 102305b261ecSmrg preserve= type->preserve; 102405b261ecSmrg for (n=0;n<type->map_count;n++,pwire++,preserve++) { 102505b261ecSmrg pwire->mask= preserve->mask; 102605b261ecSmrg pwire->realMods= preserve->real_mods; 102705b261ecSmrg pwire->virtualMods= preserve->vmods; 102805b261ecSmrg if (client->swapped) { 102905b261ecSmrg register int n; 103005b261ecSmrg swaps(&pwire->virtualMods,n); 103105b261ecSmrg } 103205b261ecSmrg } 103305b261ecSmrg buf= (char *)pwire; 103405b261ecSmrg } 103505b261ecSmrg } 103605b261ecSmrg } 103705b261ecSmrg return buf; 103805b261ecSmrg} 103905b261ecSmrg 104005b261ecSmrgstatic int 104105b261ecSmrgXkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep) 104205b261ecSmrg{ 104305b261ecSmrg XkbSymMapPtr symMap; 104405b261ecSmrg unsigned i,len; 104505b261ecSmrg unsigned nSyms,nSymsThisKey; 104605b261ecSmrg 104705b261ecSmrg if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)|| 104805b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) { 104905b261ecSmrg rep->present&= ~XkbKeySymsMask; 105005b261ecSmrg rep->firstKeySym= rep->nKeySyms= 0; 105105b261ecSmrg rep->totalSyms= 0; 105205b261ecSmrg return 0; 105305b261ecSmrg } 105405b261ecSmrg len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc); 105505b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 105605b261ecSmrg for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) { 105705b261ecSmrg if (symMap->offset!=0) { 105805b261ecSmrg nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width; 105905b261ecSmrg nSyms+= nSymsThisKey; 106005b261ecSmrg } 106105b261ecSmrg } 106205b261ecSmrg len+= nSyms*4; 106305b261ecSmrg rep->totalSyms= nSyms; 106405b261ecSmrg return len; 106505b261ecSmrg} 106605b261ecSmrg 106705b261ecSmrgstatic int 106805b261ecSmrgXkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep) 106905b261ecSmrg{ 107005b261ecSmrgregister unsigned i,nMods,bit; 107105b261ecSmrg 107205b261ecSmrg if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)|| 107305b261ecSmrg (!xkb)||(!xkb->server)) { 107405b261ecSmrg rep->present&= ~XkbVirtualModsMask; 107505b261ecSmrg rep->virtualMods= 0; 107605b261ecSmrg return 0; 107705b261ecSmrg } 107805b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 107905b261ecSmrg if (rep->virtualMods&bit) 108005b261ecSmrg nMods++; 108105b261ecSmrg } 108205b261ecSmrg return XkbPaddedSize(nMods); 108305b261ecSmrg} 108405b261ecSmrg 108505b261ecSmrgstatic char * 108605b261ecSmrgXkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 108705b261ecSmrg{ 108805b261ecSmrgregister KeySym * pSym; 108905b261ecSmrgXkbSymMapPtr symMap; 109005b261ecSmrgxkbSymMapWireDesc * outMap; 109105b261ecSmrgregister unsigned i; 109205b261ecSmrg 109305b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 109405b261ecSmrg for (i=0;i<rep->nKeySyms;i++,symMap++) { 109505b261ecSmrg outMap = (xkbSymMapWireDesc *)buf; 109605b261ecSmrg outMap->ktIndex[0] = symMap->kt_index[0]; 109705b261ecSmrg outMap->ktIndex[1] = symMap->kt_index[1]; 109805b261ecSmrg outMap->ktIndex[2] = symMap->kt_index[2]; 109905b261ecSmrg outMap->ktIndex[3] = symMap->kt_index[3]; 110005b261ecSmrg outMap->groupInfo = symMap->group_info; 110105b261ecSmrg outMap->width= symMap->width; 110205b261ecSmrg outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info); 110305b261ecSmrg buf= (char *)&outMap[1]; 110405b261ecSmrg if (outMap->nSyms==0) 110505b261ecSmrg continue; 110605b261ecSmrg 110705b261ecSmrg pSym = &xkb->map->syms[symMap->offset]; 110805b261ecSmrg memcpy((char *)buf,(char *)pSym,outMap->nSyms*4); 110905b261ecSmrg if (client->swapped) { 111005b261ecSmrg register int n,nSyms= outMap->nSyms; 111105b261ecSmrg swaps(&outMap->nSyms,n); 111205b261ecSmrg while (nSyms-->0) { 111305b261ecSmrg swapl(buf,n); 111405b261ecSmrg buf+= 4; 111505b261ecSmrg } 111605b261ecSmrg } 111705b261ecSmrg else buf+= outMap->nSyms*4; 111805b261ecSmrg } 111905b261ecSmrg return buf; 112005b261ecSmrg} 112105b261ecSmrg 112205b261ecSmrgstatic int 112305b261ecSmrgXkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep) 112405b261ecSmrg{ 112505b261ecSmrg unsigned i,len,nActs; 112605b261ecSmrg register KeyCode firstKey; 112705b261ecSmrg 112805b261ecSmrg if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)|| 112905b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) { 113005b261ecSmrg rep->present&= ~XkbKeyActionsMask; 113105b261ecSmrg rep->firstKeyAct= rep->nKeyActs= 0; 113205b261ecSmrg rep->totalActs= 0; 113305b261ecSmrg return 0; 113405b261ecSmrg } 113505b261ecSmrg firstKey= rep->firstKeyAct; 113605b261ecSmrg for (nActs=i=0;i<rep->nKeyActs;i++) { 113705b261ecSmrg if (xkb->server->key_acts[i+firstKey]!=0) 113805b261ecSmrg nActs+= XkbKeyNumActions(xkb,i+firstKey); 113905b261ecSmrg } 114005b261ecSmrg len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); 114105b261ecSmrg rep->totalActs= nActs; 114205b261ecSmrg return len; 114305b261ecSmrg} 114405b261ecSmrg 114505b261ecSmrgstatic char * 114605b261ecSmrgXkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 114705b261ecSmrg ClientPtr client) 114805b261ecSmrg{ 114905b261ecSmrg unsigned i; 115005b261ecSmrg CARD8 * numDesc; 115105b261ecSmrg XkbAnyAction * actDesc; 115205b261ecSmrg 115305b261ecSmrg numDesc = (CARD8 *)buf; 115405b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 115505b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]==0) 115605b261ecSmrg numDesc[i] = 0; 115705b261ecSmrg else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 115805b261ecSmrg } 115905b261ecSmrg buf+= XkbPaddedSize(rep->nKeyActs); 116005b261ecSmrg 116105b261ecSmrg actDesc = (XkbAnyAction *)buf; 116205b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 116305b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) { 116405b261ecSmrg unsigned int num; 116505b261ecSmrg num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 116605b261ecSmrg memcpy((char *)actDesc, 116705b261ecSmrg (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)), 116805b261ecSmrg num*SIZEOF(xkbActionWireDesc)); 116905b261ecSmrg actDesc+= num; 117005b261ecSmrg } 117105b261ecSmrg } 117205b261ecSmrg buf = (char *)actDesc; 117305b261ecSmrg return buf; 117405b261ecSmrg} 117505b261ecSmrg 117605b261ecSmrgstatic int 117705b261ecSmrgXkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep) 117805b261ecSmrg{ 117905b261ecSmrg unsigned i,len,nBhvr; 118005b261ecSmrg XkbBehavior * bhv; 118105b261ecSmrg 118205b261ecSmrg if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)|| 118305b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) { 118405b261ecSmrg rep->present&= ~XkbKeyBehaviorsMask; 118505b261ecSmrg rep->firstKeyBehavior= rep->nKeyBehaviors= 0; 118605b261ecSmrg rep->totalKeyBehaviors= 0; 118705b261ecSmrg return 0; 118805b261ecSmrg } 118905b261ecSmrg bhv= &xkb->server->behaviors[rep->firstKeyBehavior]; 119005b261ecSmrg for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) { 119105b261ecSmrg if (bhv->type!=XkbKB_Default) 119205b261ecSmrg nBhvr++; 119305b261ecSmrg } 119405b261ecSmrg len= nBhvr*SIZEOF(xkbBehaviorWireDesc); 119505b261ecSmrg rep->totalKeyBehaviors= nBhvr; 119605b261ecSmrg return len; 119705b261ecSmrg} 119805b261ecSmrg 119905b261ecSmrgstatic char * 120005b261ecSmrgXkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 120105b261ecSmrg ClientPtr client) 120205b261ecSmrg{ 120305b261ecSmrg unsigned i; 120405b261ecSmrg xkbBehaviorWireDesc *wire; 120505b261ecSmrg XkbBehavior *pBhvr; 120605b261ecSmrg 120705b261ecSmrg wire = (xkbBehaviorWireDesc *)buf; 120805b261ecSmrg pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior]; 120905b261ecSmrg for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) { 121005b261ecSmrg if (pBhvr->type!=XkbKB_Default) { 121105b261ecSmrg wire->key= i+rep->firstKeyBehavior; 121205b261ecSmrg wire->type= pBhvr->type; 121305b261ecSmrg wire->data= pBhvr->data; 121405b261ecSmrg wire++; 121505b261ecSmrg } 121605b261ecSmrg } 121705b261ecSmrg buf = (char *)wire; 121805b261ecSmrg return buf; 121905b261ecSmrg} 122005b261ecSmrg 122105b261ecSmrgstatic int 122205b261ecSmrgXkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep) 122305b261ecSmrg{ 122405b261ecSmrg unsigned i,len,nRtrn; 122505b261ecSmrg 122605b261ecSmrg if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)|| 122705b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->explicit)) { 122805b261ecSmrg rep->present&= ~XkbExplicitComponentsMask; 122905b261ecSmrg rep->firstKeyExplicit= rep->nKeyExplicit= 0; 123005b261ecSmrg rep->totalKeyExplicit= 0; 123105b261ecSmrg return 0; 123205b261ecSmrg } 123305b261ecSmrg for (nRtrn=i=0;i<rep->nKeyExplicit;i++) { 123405b261ecSmrg if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0) 123505b261ecSmrg nRtrn++; 123605b261ecSmrg } 123705b261ecSmrg rep->totalKeyExplicit= nRtrn; 123805b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */ 123905b261ecSmrg return len; 124005b261ecSmrg} 124105b261ecSmrg 124205b261ecSmrgstatic char * 124305b261ecSmrgXkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 124405b261ecSmrg{ 124505b261ecSmrgunsigned i; 124605b261ecSmrgchar * start; 124705b261ecSmrgunsigned char * pExp; 124805b261ecSmrg 124905b261ecSmrg start= buf; 125005b261ecSmrg pExp= &xkb->server->explicit[rep->firstKeyExplicit]; 125105b261ecSmrg for (i=0;i<rep->nKeyExplicit;i++,pExp++) { 125205b261ecSmrg if (*pExp!=0) { 125305b261ecSmrg *buf++= i+rep->firstKeyExplicit; 125405b261ecSmrg *buf++= *pExp; 125505b261ecSmrg } 125605b261ecSmrg } 125705b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 125805b261ecSmrg return buf+i; 125905b261ecSmrg} 126005b261ecSmrg 126105b261ecSmrgstatic int 126205b261ecSmrgXkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep) 126305b261ecSmrg{ 126405b261ecSmrg unsigned i,len,nRtrn; 126505b261ecSmrg 126605b261ecSmrg if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)|| 126705b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->modmap)) { 126805b261ecSmrg rep->present&= ~XkbModifierMapMask; 126905b261ecSmrg rep->firstModMapKey= rep->nModMapKeys= 0; 127005b261ecSmrg rep->totalModMapKeys= 0; 127105b261ecSmrg return 0; 127205b261ecSmrg } 127305b261ecSmrg for (nRtrn=i=0;i<rep->nModMapKeys;i++) { 127405b261ecSmrg if (xkb->map->modmap[i+rep->firstModMapKey]!=0) 127505b261ecSmrg nRtrn++; 127605b261ecSmrg } 127705b261ecSmrg rep->totalModMapKeys= nRtrn; 127805b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */ 127905b261ecSmrg return len; 128005b261ecSmrg} 128105b261ecSmrg 128205b261ecSmrgstatic char * 128305b261ecSmrgXkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 128405b261ecSmrg ClientPtr client) 128505b261ecSmrg{ 128605b261ecSmrgunsigned i; 128705b261ecSmrgchar * start; 128805b261ecSmrgunsigned char * pMap; 128905b261ecSmrg 129005b261ecSmrg start= buf; 129105b261ecSmrg pMap= &xkb->map->modmap[rep->firstModMapKey]; 129205b261ecSmrg for (i=0;i<rep->nModMapKeys;i++,pMap++) { 129305b261ecSmrg if (*pMap!=0) { 129405b261ecSmrg *buf++= i+rep->firstModMapKey; 129505b261ecSmrg *buf++= *pMap; 129605b261ecSmrg } 129705b261ecSmrg } 129805b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 129905b261ecSmrg return buf+i; 130005b261ecSmrg} 130105b261ecSmrg 130205b261ecSmrgstatic int 130305b261ecSmrgXkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep) 130405b261ecSmrg{ 130505b261ecSmrg unsigned i,len,nRtrn; 130605b261ecSmrg 130705b261ecSmrg if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)|| 130805b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) { 130905b261ecSmrg rep->present&= ~XkbVirtualModMapMask; 131005b261ecSmrg rep->firstVModMapKey= rep->nVModMapKeys= 0; 131105b261ecSmrg rep->totalVModMapKeys= 0; 131205b261ecSmrg return 0; 131305b261ecSmrg } 131452397711Smrg for (nRtrn=i=0;i<rep->nVModMapKeys;i++) { 131505b261ecSmrg if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0) 131605b261ecSmrg nRtrn++; 131705b261ecSmrg } 131805b261ecSmrg rep->totalVModMapKeys= nRtrn; 131905b261ecSmrg len= nRtrn*SIZEOF(xkbVModMapWireDesc); 132005b261ecSmrg return len; 132105b261ecSmrg} 132205b261ecSmrg 132305b261ecSmrgstatic char * 132405b261ecSmrgXkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 132505b261ecSmrg ClientPtr client) 132605b261ecSmrg{ 132705b261ecSmrgunsigned i; 132805b261ecSmrgxkbVModMapWireDesc * wire; 132905b261ecSmrgunsigned short * pMap; 133005b261ecSmrg 133105b261ecSmrg wire= (xkbVModMapWireDesc *)buf; 133205b261ecSmrg pMap= &xkb->server->vmodmap[rep->firstVModMapKey]; 133352397711Smrg for (i=0;i<rep->nVModMapKeys;i++,pMap++) { 133405b261ecSmrg if (*pMap!=0) { 133505b261ecSmrg wire->key= i+rep->firstVModMapKey; 133605b261ecSmrg wire->vmods= *pMap; 133705b261ecSmrg wire++; 133805b261ecSmrg } 133905b261ecSmrg } 134005b261ecSmrg return (char *)wire; 134105b261ecSmrg} 134205b261ecSmrg 134305b261ecSmrgstatic Status 134405b261ecSmrgXkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep) 134505b261ecSmrg{ 134605b261ecSmrgint len; 134705b261ecSmrg 134805b261ecSmrg rep->minKeyCode= xkb->min_key_code; 134905b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 135005b261ecSmrg len= XkbSizeKeyTypes(xkb,rep); 135105b261ecSmrg len+= XkbSizeKeySyms(xkb,rep); 135205b261ecSmrg len+= XkbSizeKeyActions(xkb,rep); 135305b261ecSmrg len+= XkbSizeKeyBehaviors(xkb,rep); 135405b261ecSmrg len+= XkbSizeVirtualMods(xkb,rep); 135505b261ecSmrg len+= XkbSizeExplicit(xkb,rep); 135605b261ecSmrg len+= XkbSizeModifierMap(xkb,rep); 135705b261ecSmrg len+= XkbSizeVirtualModMap(xkb,rep); 135805b261ecSmrg rep->length+= (len/4); 135905b261ecSmrg return Success; 136005b261ecSmrg} 136105b261ecSmrg 136205b261ecSmrgstatic int 136305b261ecSmrgXkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep) 136405b261ecSmrg{ 136505b261ecSmrgunsigned i,len; 136605b261ecSmrgchar *desc,*start; 136705b261ecSmrg 136805b261ecSmrg len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)); 13694642e01fSmrg start= desc= (char *)xalloc(len); 137005b261ecSmrg if (!start) 137105b261ecSmrg return BadAlloc; 137205b261ecSmrg if ( rep->nTypes>0 ) 137305b261ecSmrg desc = XkbWriteKeyTypes(xkb,rep,desc,client); 137405b261ecSmrg if ( rep->nKeySyms>0 ) 137505b261ecSmrg desc = XkbWriteKeySyms(xkb,rep,desc,client); 137605b261ecSmrg if ( rep->nKeyActs>0 ) 137705b261ecSmrg desc = XkbWriteKeyActions(xkb,rep,desc,client); 137805b261ecSmrg if ( rep->totalKeyBehaviors>0 ) 137905b261ecSmrg desc = XkbWriteKeyBehaviors(xkb,rep,desc,client); 138005b261ecSmrg if ( rep->virtualMods ) { 138105b261ecSmrg register int sz,bit; 138205b261ecSmrg for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 138305b261ecSmrg if (rep->virtualMods&bit) { 138405b261ecSmrg desc[sz++]= xkb->server->vmods[i]; 138505b261ecSmrg } 138605b261ecSmrg } 138705b261ecSmrg desc+= XkbPaddedSize(sz); 138805b261ecSmrg } 138905b261ecSmrg if ( rep->totalKeyExplicit>0 ) 139005b261ecSmrg desc= XkbWriteExplicit(xkb,rep,desc,client); 139105b261ecSmrg if ( rep->totalModMapKeys>0 ) 139205b261ecSmrg desc= XkbWriteModifierMap(xkb,rep,desc,client); 139305b261ecSmrg if ( rep->totalVModMapKeys>0 ) 139405b261ecSmrg desc= XkbWriteVirtualModMap(xkb,rep,desc,client); 139505b261ecSmrg if ((desc-start)!=(len)) { 13964642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", 139705b261ecSmrg len, (unsigned long)(desc-start)); 139805b261ecSmrg } 139905b261ecSmrg if (client->swapped) { 140005b261ecSmrg register int n; 140105b261ecSmrg swaps(&rep->sequenceNumber,n); 140205b261ecSmrg swapl(&rep->length,n); 140305b261ecSmrg swaps(&rep->present,n); 140405b261ecSmrg swaps(&rep->totalSyms,n); 140505b261ecSmrg swaps(&rep->totalActs,n); 140605b261ecSmrg } 140705b261ecSmrg WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep); 140805b261ecSmrg WriteToClient(client, len, start); 14094642e01fSmrg xfree((char *)start); 141005b261ecSmrg return client->noClientException; 141105b261ecSmrg} 141205b261ecSmrg 141305b261ecSmrgint 141405b261ecSmrgProcXkbGetMap(ClientPtr client) 141505b261ecSmrg{ 141605b261ecSmrg DeviceIntPtr dev; 141705b261ecSmrg xkbGetMapReply rep; 141805b261ecSmrg XkbDescRec *xkb; 141905b261ecSmrg int n,status; 142005b261ecSmrg 142105b261ecSmrg REQUEST(xkbGetMapReq); 142205b261ecSmrg REQUEST_SIZE_MATCH(xkbGetMapReq); 142305b261ecSmrg 142405b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 142505b261ecSmrg return BadAccess; 142605b261ecSmrg 14274642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 142805b261ecSmrg CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial); 142905b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask); 143005b261ecSmrg CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask); 143105b261ecSmrg 143205b261ecSmrg xkb= dev->key->xkbInfo->desc; 143305b261ecSmrg bzero(&rep,sizeof(xkbGetMapReply)); 143405b261ecSmrg rep.type= X_Reply; 143505b261ecSmrg rep.sequenceNumber= client->sequence; 143605b261ecSmrg rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2; 143705b261ecSmrg rep.deviceID = dev->id; 143805b261ecSmrg rep.present = stuff->partial|stuff->full; 143905b261ecSmrg rep.minKeyCode = xkb->min_key_code; 144005b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 144105b261ecSmrg if ( stuff->full&XkbKeyTypesMask ) { 144205b261ecSmrg rep.firstType = 0; 144305b261ecSmrg rep.nTypes = xkb->map->num_types; 144405b261ecSmrg } 144505b261ecSmrg else if (stuff->partial&XkbKeyTypesMask) { 144605b261ecSmrg if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) { 144705b261ecSmrg client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types, 144805b261ecSmrg stuff->firstType,stuff->nTypes); 144905b261ecSmrg return BadValue; 145005b261ecSmrg } 145105b261ecSmrg rep.firstType = stuff->firstType; 145205b261ecSmrg rep.nTypes = stuff->nTypes; 145305b261ecSmrg } 145405b261ecSmrg else rep.nTypes = 0; 145505b261ecSmrg rep.totalTypes = xkb->map->num_types; 145605b261ecSmrg 145705b261ecSmrg n= XkbNumKeys(xkb); 145805b261ecSmrg if ( stuff->full&XkbKeySymsMask ) { 145905b261ecSmrg rep.firstKeySym = xkb->min_key_code; 146005b261ecSmrg rep.nKeySyms = n; 146105b261ecSmrg } 146205b261ecSmrg else if (stuff->partial&XkbKeySymsMask) { 146305b261ecSmrg CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb); 146405b261ecSmrg rep.firstKeySym = stuff->firstKeySym; 146505b261ecSmrg rep.nKeySyms = stuff->nKeySyms; 146605b261ecSmrg } 146705b261ecSmrg else rep.nKeySyms = 0; 146805b261ecSmrg rep.totalSyms= 0; 146905b261ecSmrg 147005b261ecSmrg if ( stuff->full&XkbKeyActionsMask ) { 147105b261ecSmrg rep.firstKeyAct= xkb->min_key_code; 147205b261ecSmrg rep.nKeyActs= n; 147305b261ecSmrg } 147405b261ecSmrg else if (stuff->partial&XkbKeyActionsMask) { 147505b261ecSmrg CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb); 147605b261ecSmrg rep.firstKeyAct= stuff->firstKeyAct; 147705b261ecSmrg rep.nKeyActs= stuff->nKeyActs; 147805b261ecSmrg } 147905b261ecSmrg else rep.nKeyActs= 0; 148005b261ecSmrg rep.totalActs= 0; 148105b261ecSmrg 148205b261ecSmrg if ( stuff->full&XkbKeyBehaviorsMask ) { 148305b261ecSmrg rep.firstKeyBehavior = xkb->min_key_code; 148405b261ecSmrg rep.nKeyBehaviors = n; 148505b261ecSmrg } 148605b261ecSmrg else if (stuff->partial&XkbKeyBehaviorsMask) { 148705b261ecSmrg CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb); 148805b261ecSmrg rep.firstKeyBehavior= stuff->firstKeyBehavior; 148905b261ecSmrg rep.nKeyBehaviors= stuff->nKeyBehaviors; 149005b261ecSmrg } 149105b261ecSmrg else rep.nKeyBehaviors = 0; 149205b261ecSmrg rep.totalKeyBehaviors= 0; 149305b261ecSmrg 149405b261ecSmrg if (stuff->full&XkbVirtualModsMask) 149505b261ecSmrg rep.virtualMods= ~0; 149605b261ecSmrg else if (stuff->partial&XkbVirtualModsMask) 149705b261ecSmrg rep.virtualMods= stuff->virtualMods; 149805b261ecSmrg 149905b261ecSmrg if (stuff->full&XkbExplicitComponentsMask) { 150005b261ecSmrg rep.firstKeyExplicit= xkb->min_key_code; 150105b261ecSmrg rep.nKeyExplicit= n; 150205b261ecSmrg } 150305b261ecSmrg else if (stuff->partial&XkbExplicitComponentsMask) { 150405b261ecSmrg CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb); 150505b261ecSmrg rep.firstKeyExplicit= stuff->firstKeyExplicit; 150605b261ecSmrg rep.nKeyExplicit= stuff->nKeyExplicit; 150705b261ecSmrg } 150805b261ecSmrg else rep.nKeyExplicit = 0; 150905b261ecSmrg rep.totalKeyExplicit= 0; 151005b261ecSmrg 151105b261ecSmrg if (stuff->full&XkbModifierMapMask) { 151205b261ecSmrg rep.firstModMapKey= xkb->min_key_code; 151305b261ecSmrg rep.nModMapKeys= n; 151405b261ecSmrg } 151505b261ecSmrg else if (stuff->partial&XkbModifierMapMask) { 151605b261ecSmrg CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb); 151705b261ecSmrg rep.firstModMapKey= stuff->firstModMapKey; 151805b261ecSmrg rep.nModMapKeys= stuff->nModMapKeys; 151905b261ecSmrg } 152005b261ecSmrg else rep.nModMapKeys = 0; 152105b261ecSmrg rep.totalModMapKeys= 0; 152205b261ecSmrg 152305b261ecSmrg if (stuff->full&XkbVirtualModMapMask) { 152405b261ecSmrg rep.firstVModMapKey= xkb->min_key_code; 152505b261ecSmrg rep.nVModMapKeys= n; 152605b261ecSmrg } 152705b261ecSmrg else if (stuff->partial&XkbVirtualModMapMask) { 152805b261ecSmrg CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb); 152905b261ecSmrg rep.firstVModMapKey= stuff->firstVModMapKey; 153005b261ecSmrg rep.nVModMapKeys= stuff->nVModMapKeys; 153105b261ecSmrg } 153205b261ecSmrg else rep.nVModMapKeys = 0; 153305b261ecSmrg rep.totalVModMapKeys= 0; 153405b261ecSmrg 153505b261ecSmrg if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success) 153605b261ecSmrg return status; 153705b261ecSmrg return XkbSendMap(client,xkb,&rep); 153805b261ecSmrg} 153905b261ecSmrg 154005b261ecSmrg/***====================================================================***/ 154105b261ecSmrg 154205b261ecSmrgstatic int 154305b261ecSmrgCheckKeyTypes( ClientPtr client, 154405b261ecSmrg XkbDescPtr xkb, 154505b261ecSmrg xkbSetMapReq * req, 154605b261ecSmrg xkbKeyTypeWireDesc **wireRtrn, 154705b261ecSmrg int * nMapsRtrn, 154805b261ecSmrg CARD8 * mapWidthRtrn) 154905b261ecSmrg{ 155005b261ecSmrgunsigned nMaps; 155105b261ecSmrgregister unsigned i,n; 155205b261ecSmrgregister CARD8 * map; 155305b261ecSmrgregister xkbKeyTypeWireDesc *wire = *wireRtrn; 155405b261ecSmrg 155505b261ecSmrg if (req->firstType>((unsigned)xkb->map->num_types)) { 155605b261ecSmrg *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types); 155705b261ecSmrg return 0; 155805b261ecSmrg } 155905b261ecSmrg if (req->flags&XkbSetMapResizeTypes) { 156005b261ecSmrg nMaps = req->firstType+req->nTypes; 156105b261ecSmrg if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */ 156205b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4); 156305b261ecSmrg return 0; 156405b261ecSmrg } 156505b261ecSmrg } 156605b261ecSmrg else if (req->present&XkbKeyTypesMask) { 156705b261ecSmrg nMaps = xkb->map->num_types; 156805b261ecSmrg if ((req->firstType+req->nTypes)>nMaps) { 156905b261ecSmrg *nMapsRtrn = req->firstType+req->nTypes; 157005b261ecSmrg return 0; 157105b261ecSmrg } 157205b261ecSmrg } 157305b261ecSmrg else { 157405b261ecSmrg *nMapsRtrn = xkb->map->num_types; 157505b261ecSmrg for (i=0;i<xkb->map->num_types;i++) { 157605b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 157705b261ecSmrg } 157805b261ecSmrg return 1; 157905b261ecSmrg } 158005b261ecSmrg 158105b261ecSmrg for (i=0;i<req->firstType;i++) { 158205b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 158305b261ecSmrg } 158405b261ecSmrg for (i=0;i<req->nTypes;i++) { 158505b261ecSmrg unsigned width; 158605b261ecSmrg if (client->swapped) { 158705b261ecSmrg register int s; 158805b261ecSmrg swaps(&wire->virtualMods,s); 158905b261ecSmrg } 159005b261ecSmrg n= i+req->firstType; 159105b261ecSmrg width= wire->numLevels; 159205b261ecSmrg if (width<1) { 159305b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x04,n,width); 159405b261ecSmrg return 0; 159505b261ecSmrg } 159605b261ecSmrg else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */ 159705b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 159805b261ecSmrg return 0; 159905b261ecSmrg } 160005b261ecSmrg else if ((width!=2)&& 160105b261ecSmrg ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)|| 160205b261ecSmrg (n==XkbAlphabeticIndex))) { 160305b261ecSmrg /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ 160405b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 160505b261ecSmrg return 0; 160605b261ecSmrg } 160705b261ecSmrg if (wire->nMapEntries>0) { 160805b261ecSmrg xkbKTSetMapEntryWireDesc * mapWire; 160905b261ecSmrg xkbModsWireDesc * preWire; 161005b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1]; 161105b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 161205b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 161305b261ecSmrg if (client->swapped) { 161405b261ecSmrg register int s; 161505b261ecSmrg swaps(&mapWire[n].virtualMods,s); 161605b261ecSmrg } 161705b261ecSmrg if (mapWire[n].realMods&(~wire->realMods)) { 161805b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods, 161905b261ecSmrg wire->realMods); 162005b261ecSmrg return 0; 162105b261ecSmrg } 162205b261ecSmrg if (mapWire[n].virtualMods&(~wire->virtualMods)) { 162305b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods); 162405b261ecSmrg return 0; 162505b261ecSmrg } 162605b261ecSmrg if (mapWire[n].level>=wire->numLevels) { 162705b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels, 162805b261ecSmrg mapWire[n].level); 162905b261ecSmrg return 0; 163005b261ecSmrg } 163105b261ecSmrg if (wire->preserve) { 163205b261ecSmrg if (client->swapped) { 163305b261ecSmrg register int s; 163405b261ecSmrg swaps(&preWire[n].virtualMods,s); 163505b261ecSmrg } 163605b261ecSmrg if (preWire[n].realMods&(~mapWire[n].realMods)) { 163705b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods, 163805b261ecSmrg mapWire[n].realMods); 163905b261ecSmrg return 0; 164005b261ecSmrg } 164105b261ecSmrg if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) { 164205b261ecSmrg *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods); 164305b261ecSmrg return 0; 164405b261ecSmrg } 164505b261ecSmrg } 164605b261ecSmrg } 164705b261ecSmrg if (wire->preserve) 164805b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 164905b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 165005b261ecSmrg } 165105b261ecSmrg else map= (CARD8 *)&wire[1]; 165205b261ecSmrg mapWidthRtrn[i+req->firstType] = wire->numLevels; 165305b261ecSmrg wire= (xkbKeyTypeWireDesc *)map; 165405b261ecSmrg } 165505b261ecSmrg for (i=req->firstType+req->nTypes;i<nMaps;i++) { 165605b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 165705b261ecSmrg } 165805b261ecSmrg *nMapsRtrn = nMaps; 165905b261ecSmrg *wireRtrn = wire; 166005b261ecSmrg return 1; 166105b261ecSmrg} 166205b261ecSmrg 166305b261ecSmrgstatic int 166405b261ecSmrgCheckKeySyms( ClientPtr client, 166505b261ecSmrg XkbDescPtr xkb, 166605b261ecSmrg xkbSetMapReq * req, 166705b261ecSmrg int nTypes, 166805b261ecSmrg CARD8 * mapWidths, 166905b261ecSmrg CARD16 * symsPerKey, 167005b261ecSmrg xkbSymMapWireDesc ** wireRtrn, 167105b261ecSmrg int * errorRtrn) 167205b261ecSmrg{ 167305b261ecSmrgregister unsigned i; 167405b261ecSmrgXkbSymMapPtr map; 167505b261ecSmrgxkbSymMapWireDesc* wire = *wireRtrn; 167605b261ecSmrg 167705b261ecSmrg if (!(XkbKeySymsMask&req->present)) 167805b261ecSmrg return 1; 167905b261ecSmrg CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0); 168005b261ecSmrg map = &xkb->map->key_sym_map[xkb->min_key_code]; 168105b261ecSmrg for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) { 168205b261ecSmrg register int g,ng,w; 168305b261ecSmrg ng= XkbNumGroups(map->group_info); 168405b261ecSmrg for (w=g=0;g<ng;g++) { 168505b261ecSmrg if (map->kt_index[g]>=(unsigned)nTypes) { 168605b261ecSmrg *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]); 168705b261ecSmrg return 0; 168805b261ecSmrg } 168905b261ecSmrg if (mapWidths[map->kt_index[g]]>w) 169005b261ecSmrg w= mapWidths[map->kt_index[g]]; 169105b261ecSmrg } 169205b261ecSmrg symsPerKey[i] = w*ng; 169305b261ecSmrg } 169405b261ecSmrg for (i=0;i<req->nKeySyms;i++) { 169505b261ecSmrg KeySym *pSyms; 169605b261ecSmrg register unsigned nG; 169705b261ecSmrg if (client->swapped) { 169805b261ecSmrg swaps(&wire->nSyms,nG); 169905b261ecSmrg } 170005b261ecSmrg nG = XkbNumGroups(wire->groupInfo); 170105b261ecSmrg if (nG>XkbNumKbdGroups) { 170205b261ecSmrg *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG); 170305b261ecSmrg return 0; 170405b261ecSmrg } 170505b261ecSmrg if (nG>0) { 170605b261ecSmrg register int g,w; 170705b261ecSmrg for (g=w=0;g<nG;g++) { 170805b261ecSmrg if (wire->ktIndex[g]>=(unsigned)nTypes) { 170905b261ecSmrg *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g, 171005b261ecSmrg wire->ktIndex[g]); 171105b261ecSmrg return 0; 171205b261ecSmrg } 171305b261ecSmrg if (mapWidths[wire->ktIndex[g]]>w) 171405b261ecSmrg w= mapWidths[wire->ktIndex[g]]; 171505b261ecSmrg } 171605b261ecSmrg if (wire->width!=w) { 171705b261ecSmrg *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width); 171805b261ecSmrg return 0; 171905b261ecSmrg } 172005b261ecSmrg w*= nG; 172105b261ecSmrg symsPerKey[i+req->firstKeySym] = w; 172205b261ecSmrg if (w!=wire->nSyms) { 172305b261ecSmrg *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w); 172405b261ecSmrg return 0; 172505b261ecSmrg } 172605b261ecSmrg } 172705b261ecSmrg else if (wire->nSyms!=0) { 172805b261ecSmrg *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms); 172905b261ecSmrg return 0; 173005b261ecSmrg } 173105b261ecSmrg pSyms = (KeySym *)&wire[1]; 173205b261ecSmrg wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 173305b261ecSmrg } 173405b261ecSmrg 173505b261ecSmrg map = &xkb->map->key_sym_map[i]; 173605b261ecSmrg for (;i<=(unsigned)xkb->max_key_code;i++,map++) { 173705b261ecSmrg register int g,nG,w; 173805b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 173905b261ecSmrg for (w=g=0;g<nG;g++) { 174005b261ecSmrg if (map->kt_index[g]>=(unsigned)nTypes) { 174105b261ecSmrg *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]); 174205b261ecSmrg return 0; 174305b261ecSmrg } 174405b261ecSmrg if (mapWidths[map->kt_index[g]]>w) 174505b261ecSmrg w= mapWidths[map->kt_index[g]]; 174605b261ecSmrg } 174705b261ecSmrg symsPerKey[i] = w*nG; 174805b261ecSmrg } 174905b261ecSmrg *wireRtrn = wire; 175005b261ecSmrg return 1; 175105b261ecSmrg} 175205b261ecSmrg 175305b261ecSmrgstatic int 175405b261ecSmrgCheckKeyActions( XkbDescPtr xkb, 175505b261ecSmrg xkbSetMapReq * req, 175605b261ecSmrg int nTypes, 175705b261ecSmrg CARD8 * mapWidths, 175805b261ecSmrg CARD16 * symsPerKey, 175905b261ecSmrg CARD8 ** wireRtrn, 176005b261ecSmrg int * nActsRtrn) 176105b261ecSmrg{ 176205b261ecSmrgint nActs; 176305b261ecSmrgCARD8 * wire = *wireRtrn; 176405b261ecSmrgregister unsigned i; 176505b261ecSmrg 176605b261ecSmrg if (!(XkbKeyActionsMask&req->present)) 176705b261ecSmrg return 1; 176805b261ecSmrg CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0); 176905b261ecSmrg for (nActs=i=0;i<req->nKeyActs;i++) { 177005b261ecSmrg if (wire[0]!=0) { 177105b261ecSmrg if (wire[0]==symsPerKey[i+req->firstKeyAct]) 177205b261ecSmrg nActs+= wire[0]; 177305b261ecSmrg else { 177405b261ecSmrg *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]); 177505b261ecSmrg return 0; 177605b261ecSmrg } 177705b261ecSmrg } 177805b261ecSmrg wire++; 177905b261ecSmrg } 178005b261ecSmrg if (req->nKeyActs%4) 178105b261ecSmrg wire+= 4-(req->nKeyActs%4); 178205b261ecSmrg *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs); 178305b261ecSmrg *nActsRtrn = nActs; 178405b261ecSmrg return 1; 178505b261ecSmrg} 178605b261ecSmrg 178705b261ecSmrgstatic int 178805b261ecSmrgCheckKeyBehaviors( XkbDescPtr xkb, 178905b261ecSmrg xkbSetMapReq * req, 179005b261ecSmrg xkbBehaviorWireDesc ** wireRtrn, 179105b261ecSmrg int * errorRtrn) 179205b261ecSmrg{ 179305b261ecSmrgregister xkbBehaviorWireDesc * wire = *wireRtrn; 179405b261ecSmrgregister XkbServerMapPtr server = xkb->server; 179505b261ecSmrgregister unsigned i; 179605b261ecSmrgunsigned first,last; 179705b261ecSmrg 179805b261ecSmrg if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { 179905b261ecSmrg req->present&= ~XkbKeyBehaviorsMask; 180005b261ecSmrg req->nKeyBehaviors= 0; 180105b261ecSmrg return 1; 180205b261ecSmrg } 180305b261ecSmrg first= req->firstKeyBehavior; 180405b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 180505b261ecSmrg if (first<req->minKeyCode) { 180605b261ecSmrg *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode); 180705b261ecSmrg return 0; 180805b261ecSmrg } 180905b261ecSmrg if (last>req->maxKeyCode) { 181005b261ecSmrg *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode); 181105b261ecSmrg return 0; 181205b261ecSmrg } 181305b261ecSmrg 181405b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++,wire++) { 181505b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 181605b261ecSmrg *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key); 181705b261ecSmrg return 0; 181805b261ecSmrg } 181905b261ecSmrg if ((wire->type&XkbKB_Permanent)&& 182005b261ecSmrg ((server->behaviors[wire->key].type!=wire->type)|| 182105b261ecSmrg (server->behaviors[wire->key].data!=wire->data))) { 182205b261ecSmrg *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type); 182305b261ecSmrg return 0; 182405b261ecSmrg } 182505b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&& 182605b261ecSmrg ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) { 182705b261ecSmrg *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data, 182805b261ecSmrg XkbMaxRadioGroups); 182905b261ecSmrg return 0; 183005b261ecSmrg } 183105b261ecSmrg if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) { 183205b261ecSmrg CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0); 183305b261ecSmrg } 183405b261ecSmrg } 183505b261ecSmrg *wireRtrn = wire; 183605b261ecSmrg return 1; 183705b261ecSmrg} 183805b261ecSmrg 183905b261ecSmrgstatic int 184005b261ecSmrgCheckVirtualMods( XkbDescRec * xkb, 184105b261ecSmrg xkbSetMapReq * req, 184205b261ecSmrg CARD8 ** wireRtrn, 184305b261ecSmrg int * errorRtrn) 184405b261ecSmrg{ 184505b261ecSmrgregister CARD8 *wire = *wireRtrn; 184605b261ecSmrgregister unsigned i,nMods,bit; 184705b261ecSmrg 184805b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 184905b261ecSmrg return 1; 185005b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 185105b261ecSmrg if (req->virtualMods&bit) 185205b261ecSmrg nMods++; 185305b261ecSmrg } 185405b261ecSmrg *wireRtrn= (wire+XkbPaddedSize(nMods)); 185505b261ecSmrg return 1; 185605b261ecSmrg} 185705b261ecSmrg 185805b261ecSmrgstatic int 185905b261ecSmrgCheckKeyExplicit( XkbDescPtr xkb, 186005b261ecSmrg xkbSetMapReq * req, 186105b261ecSmrg CARD8 ** wireRtrn, 186205b261ecSmrg int * errorRtrn) 186305b261ecSmrg{ 186405b261ecSmrgregister CARD8 * wire = *wireRtrn; 186505b261ecSmrgCARD8 * start; 186605b261ecSmrgregister unsigned i; 186705b261ecSmrgint first,last; 186805b261ecSmrg 186905b261ecSmrg if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) { 187005b261ecSmrg req->present&= ~XkbExplicitComponentsMask; 187105b261ecSmrg req->nKeyExplicit= 0; 187205b261ecSmrg return 1; 187305b261ecSmrg } 187405b261ecSmrg first= req->firstKeyExplicit; 187505b261ecSmrg last= first+req->nKeyExplicit-1; 187605b261ecSmrg if (first<req->minKeyCode) { 187705b261ecSmrg *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode); 187805b261ecSmrg return 0; 187905b261ecSmrg } 188005b261ecSmrg if (last>req->maxKeyCode) { 188105b261ecSmrg *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode); 188205b261ecSmrg return 0; 188305b261ecSmrg } 188405b261ecSmrg start= wire; 188505b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+=2) { 188605b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 188705b261ecSmrg *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]); 188805b261ecSmrg return 0; 188905b261ecSmrg } 189005b261ecSmrg if (wire[1]&(~XkbAllExplicitMask)) { 189105b261ecSmrg *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]); 189205b261ecSmrg return 0; 189305b261ecSmrg } 189405b261ecSmrg } 189505b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 189605b261ecSmrg *wireRtrn= wire; 189705b261ecSmrg return 1; 189805b261ecSmrg} 189905b261ecSmrg 190005b261ecSmrgstatic int 190105b261ecSmrgCheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn) 190205b261ecSmrg{ 190305b261ecSmrgregister CARD8 * wire = *wireRtrn; 190405b261ecSmrgCARD8 * start; 190505b261ecSmrgregister unsigned i; 190605b261ecSmrgint first,last; 190705b261ecSmrg 190805b261ecSmrg if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) { 190905b261ecSmrg req->present&= ~XkbModifierMapMask; 191005b261ecSmrg req->nModMapKeys= 0; 191105b261ecSmrg return 1; 191205b261ecSmrg } 191305b261ecSmrg first= req->firstModMapKey; 191405b261ecSmrg last= first+req->nModMapKeys-1; 191505b261ecSmrg if (first<req->minKeyCode) { 191605b261ecSmrg *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode); 191705b261ecSmrg return 0; 191805b261ecSmrg } 191905b261ecSmrg if (last>req->maxKeyCode) { 192005b261ecSmrg *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode); 192105b261ecSmrg return 0; 192205b261ecSmrg } 192305b261ecSmrg start= wire; 192405b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+=2) { 192505b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 192605b261ecSmrg *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]); 192705b261ecSmrg return 0; 192805b261ecSmrg } 192905b261ecSmrg } 193005b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 193105b261ecSmrg *wireRtrn= wire; 193205b261ecSmrg return 1; 193305b261ecSmrg} 193405b261ecSmrg 193505b261ecSmrgstatic int 193605b261ecSmrgCheckVirtualModMap( XkbDescPtr xkb, 193705b261ecSmrg xkbSetMapReq *req, 193805b261ecSmrg xkbVModMapWireDesc **wireRtrn, 193905b261ecSmrg int *errRtrn) 194005b261ecSmrg{ 194105b261ecSmrgregister xkbVModMapWireDesc * wire = *wireRtrn; 194205b261ecSmrgregister unsigned i; 194305b261ecSmrgint first,last; 194405b261ecSmrg 194505b261ecSmrg if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) { 194605b261ecSmrg req->present&= ~XkbVirtualModMapMask; 194705b261ecSmrg req->nVModMapKeys= 0; 194805b261ecSmrg return 1; 194905b261ecSmrg } 195005b261ecSmrg first= req->firstVModMapKey; 195105b261ecSmrg last= first+req->nVModMapKeys-1; 195205b261ecSmrg if (first<req->minKeyCode) { 195305b261ecSmrg *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode); 195405b261ecSmrg return 0; 195505b261ecSmrg } 195605b261ecSmrg if (last>req->maxKeyCode) { 195705b261ecSmrg *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode); 195805b261ecSmrg return 0; 195905b261ecSmrg } 196005b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 196105b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 196205b261ecSmrg *errRtrn = _XkbErrCode4(0x73,first,last,wire->key); 196305b261ecSmrg return 0; 196405b261ecSmrg } 196505b261ecSmrg } 196605b261ecSmrg *wireRtrn= wire; 196705b261ecSmrg return 1; 196805b261ecSmrg} 196905b261ecSmrg 197005b261ecSmrgstatic char * 197105b261ecSmrgSetKeyTypes( XkbDescPtr xkb, 197205b261ecSmrg xkbSetMapReq * req, 197305b261ecSmrg xkbKeyTypeWireDesc * wire, 197405b261ecSmrg XkbChangesPtr changes) 197505b261ecSmrg{ 197605b261ecSmrgregister unsigned i; 197705b261ecSmrgunsigned first,last; 197805b261ecSmrgCARD8 *map; 197905b261ecSmrg 198005b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) { 198105b261ecSmrg i= req->firstType+req->nTypes; 198205b261ecSmrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) { 198305b261ecSmrg return NULL; 198405b261ecSmrg } 198505b261ecSmrg } 198605b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types) 198705b261ecSmrg xkb->map->num_types= req->firstType+req->nTypes; 198805b261ecSmrg 198905b261ecSmrg for (i=0;i<req->nTypes;i++) { 199005b261ecSmrg XkbKeyTypePtr pOld; 199105b261ecSmrg register unsigned n; 199205b261ecSmrg 199305b261ecSmrg if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries, 199405b261ecSmrg wire->preserve,wire->numLevels)!=Success) { 199505b261ecSmrg return NULL; 199605b261ecSmrg } 199705b261ecSmrg pOld = &xkb->map->types[i+req->firstType]; 199805b261ecSmrg map = (CARD8 *)&wire[1]; 199905b261ecSmrg 200005b261ecSmrg pOld->mods.real_mods = wire->realMods; 200105b261ecSmrg pOld->mods.vmods= wire->virtualMods; 200205b261ecSmrg pOld->num_levels = wire->numLevels; 200305b261ecSmrg pOld->map_count= wire->nMapEntries; 200405b261ecSmrg 200505b261ecSmrg pOld->mods.mask= pOld->mods.real_mods| 200605b261ecSmrg XkbMaskForVMask(xkb,pOld->mods.vmods); 200705b261ecSmrg 200805b261ecSmrg if (wire->nMapEntries) { 200905b261ecSmrg xkbKTSetMapEntryWireDesc *mapWire; 201005b261ecSmrg xkbModsWireDesc *preWire; 201105b261ecSmrg unsigned tmp; 201205b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)map; 201305b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 201405b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 201505b261ecSmrg pOld->map[n].active= 1; 201605b261ecSmrg pOld->map[n].mods.mask= mapWire[n].realMods; 201705b261ecSmrg pOld->map[n].mods.real_mods= mapWire[n].realMods; 201805b261ecSmrg pOld->map[n].mods.vmods= mapWire[n].virtualMods; 201905b261ecSmrg pOld->map[n].level= mapWire[n].level; 202005b261ecSmrg if (mapWire[n].virtualMods!=0) { 202105b261ecSmrg tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods); 202205b261ecSmrg pOld->map[n].active= (tmp!=0); 202305b261ecSmrg pOld->map[n].mods.mask|= tmp; 202405b261ecSmrg } 202505b261ecSmrg if (wire->preserve) { 202605b261ecSmrg pOld->preserve[n].real_mods= preWire[n].realMods; 202705b261ecSmrg pOld->preserve[n].vmods= preWire[n].virtualMods; 202805b261ecSmrg tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods); 202905b261ecSmrg pOld->preserve[n].mask= preWire[n].realMods|tmp; 203005b261ecSmrg } 203105b261ecSmrg } 203205b261ecSmrg if (wire->preserve) 203305b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 203405b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 203505b261ecSmrg } 203605b261ecSmrg else map= (CARD8 *)&wire[1]; 203705b261ecSmrg wire = (xkbKeyTypeWireDesc *)map; 203805b261ecSmrg } 203905b261ecSmrg first= req->firstType; 204005b261ecSmrg last= first+req->nTypes-1; /* last changed type */ 204105b261ecSmrg if (changes->map.changed&XkbKeyTypesMask) { 204205b261ecSmrg int oldLast; 204305b261ecSmrg oldLast= changes->map.first_type+changes->map.num_types-1; 204405b261ecSmrg if (changes->map.first_type<first) 204505b261ecSmrg first= changes->map.first_type; 204605b261ecSmrg if (oldLast>last) 204705b261ecSmrg last= oldLast; 204805b261ecSmrg } 204905b261ecSmrg changes->map.changed|= XkbKeyTypesMask; 205005b261ecSmrg changes->map.first_type = first; 205105b261ecSmrg changes->map.num_types = (last-first)+1; 205205b261ecSmrg return (char *)wire; 205305b261ecSmrg} 205405b261ecSmrg 205505b261ecSmrgstatic char * 205605b261ecSmrgSetKeySyms( ClientPtr client, 205705b261ecSmrg XkbDescPtr xkb, 205805b261ecSmrg xkbSetMapReq * req, 205905b261ecSmrg xkbSymMapWireDesc * wire, 206005b261ecSmrg XkbChangesPtr changes, 206105b261ecSmrg DeviceIntPtr dev) 206205b261ecSmrg{ 206305b261ecSmrgregister unsigned i,s; 206405b261ecSmrgXkbSymMapPtr oldMap; 206505b261ecSmrgKeySym * newSyms; 206605b261ecSmrgKeySym * pSyms; 206705b261ecSmrgunsigned first,last; 206805b261ecSmrg 206905b261ecSmrg oldMap = &xkb->map->key_sym_map[req->firstKeySym]; 207005b261ecSmrg for (i=0;i<req->nKeySyms;i++,oldMap++) { 207105b261ecSmrg pSyms = (KeySym *)&wire[1]; 207205b261ecSmrg if (wire->nSyms>0) { 207305b261ecSmrg newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms); 207405b261ecSmrg for (s=0;s<wire->nSyms;s++) { 207505b261ecSmrg newSyms[s]= pSyms[s]; 207605b261ecSmrg } 207705b261ecSmrg if (client->swapped) { 207805b261ecSmrg int n; 207905b261ecSmrg for (s=0;s<wire->nSyms;s++) { 208005b261ecSmrg swapl(&newSyms[s],n); 208105b261ecSmrg } 208205b261ecSmrg } 208305b261ecSmrg } 208405b261ecSmrg oldMap->kt_index[0] = wire->ktIndex[0]; 208505b261ecSmrg oldMap->kt_index[1] = wire->ktIndex[1]; 208605b261ecSmrg oldMap->kt_index[2] = wire->ktIndex[2]; 208705b261ecSmrg oldMap->kt_index[3] = wire->ktIndex[3]; 208805b261ecSmrg oldMap->group_info = wire->groupInfo; 208905b261ecSmrg oldMap->width = wire->width; 209005b261ecSmrg wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 209105b261ecSmrg } 209205b261ecSmrg first= req->firstKeySym; 209305b261ecSmrg last= first+req->nKeySyms-1; 209405b261ecSmrg if (changes->map.changed&XkbKeySymsMask) { 209505b261ecSmrg int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1); 209605b261ecSmrg if (changes->map.first_key_sym<first) 209705b261ecSmrg first= changes->map.first_key_sym; 209805b261ecSmrg if (oldLast>last) 209905b261ecSmrg last= oldLast; 210005b261ecSmrg } 210105b261ecSmrg changes->map.changed|= XkbKeySymsMask; 210205b261ecSmrg changes->map.first_key_sym = first; 210305b261ecSmrg changes->map.num_key_syms = (last-first+1); 210405b261ecSmrg 210505b261ecSmrg s= 0; 210605b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 210705b261ecSmrg if (XkbKeyNumGroups(xkb,i)>s) 210805b261ecSmrg s= XkbKeyNumGroups(xkb,i); 210905b261ecSmrg } 211005b261ecSmrg if (s!=xkb->ctrls->num_groups) { 211105b261ecSmrg xkbControlsNotify cn; 211205b261ecSmrg XkbControlsRec old; 211305b261ecSmrg cn.keycode= 0; 211405b261ecSmrg cn.eventType= 0; 211505b261ecSmrg cn.requestMajor= XkbReqCode; 211605b261ecSmrg cn.requestMinor= X_kbSetMap; 211705b261ecSmrg old= *xkb->ctrls; 211805b261ecSmrg xkb->ctrls->num_groups= s; 211905b261ecSmrg if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,False)) 212005b261ecSmrg XkbSendControlsNotify(dev,&cn); 212105b261ecSmrg } 212205b261ecSmrg return (char *)wire; 212305b261ecSmrg} 212405b261ecSmrg 212505b261ecSmrgstatic char * 212605b261ecSmrgSetKeyActions( XkbDescPtr xkb, 212705b261ecSmrg xkbSetMapReq * req, 212805b261ecSmrg CARD8 * wire, 212905b261ecSmrg XkbChangesPtr changes) 213005b261ecSmrg{ 213105b261ecSmrgregister unsigned i,first,last; 213205b261ecSmrgCARD8 * nActs = wire; 213305b261ecSmrgXkbAction * newActs; 213405b261ecSmrg 213505b261ecSmrg wire+= XkbPaddedSize(req->nKeyActs); 213605b261ecSmrg for (i=0;i<req->nKeyActs;i++) { 213705b261ecSmrg if (nActs[i]==0) 213805b261ecSmrg xkb->server->key_acts[i+req->firstKeyAct]= 0; 213905b261ecSmrg else { 214005b261ecSmrg newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]); 214105b261ecSmrg memcpy((char *)newActs,(char *)wire, 214205b261ecSmrg nActs[i]*SIZEOF(xkbActionWireDesc)); 214305b261ecSmrg wire+= nActs[i]*SIZEOF(xkbActionWireDesc); 214405b261ecSmrg } 214505b261ecSmrg } 214605b261ecSmrg first= req->firstKeyAct; 214705b261ecSmrg last= (first+req->nKeyActs-1); 214805b261ecSmrg if (changes->map.changed&XkbKeyActionsMask) { 214905b261ecSmrg int oldLast; 215005b261ecSmrg oldLast= changes->map.first_key_act+changes->map.num_key_acts-1; 215105b261ecSmrg if (changes->map.first_key_act<first) 215205b261ecSmrg first= changes->map.first_key_act; 215305b261ecSmrg if (oldLast>last) 215405b261ecSmrg last= oldLast; 215505b261ecSmrg } 215605b261ecSmrg changes->map.changed|= XkbKeyActionsMask; 215705b261ecSmrg changes->map.first_key_act= first; 215805b261ecSmrg changes->map.num_key_acts= (last-first+1); 215905b261ecSmrg return (char *)wire; 216005b261ecSmrg} 216105b261ecSmrg 216205b261ecSmrgstatic char * 216305b261ecSmrgSetKeyBehaviors( XkbSrvInfoPtr xkbi, 216405b261ecSmrg xkbSetMapReq *req, 216505b261ecSmrg xkbBehaviorWireDesc *wire, 216605b261ecSmrg XkbChangesPtr changes) 216705b261ecSmrg{ 216805b261ecSmrgregister unsigned i; 216905b261ecSmrgint maxRG = -1; 217005b261ecSmrgXkbDescPtr xkb = xkbi->desc; 217105b261ecSmrgXkbServerMapPtr server = xkb->server; 217205b261ecSmrgunsigned first,last; 217305b261ecSmrg 217405b261ecSmrg first= req->firstKeyBehavior; 217505b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 217605b261ecSmrg bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior)); 217705b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++) { 217805b261ecSmrg if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) { 217905b261ecSmrg server->behaviors[wire->key].type= wire->type; 218005b261ecSmrg server->behaviors[wire->key].data= wire->data; 218105b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG)) 218205b261ecSmrg maxRG= wire->data + 1; 218305b261ecSmrg } 218405b261ecSmrg wire++; 218505b261ecSmrg } 218605b261ecSmrg 218705b261ecSmrg if (maxRG>(int)xkbi->nRadioGroups) { 218805b261ecSmrg int sz = maxRG*sizeof(XkbRadioGroupRec); 218905b261ecSmrg if (xkbi->radioGroups) 219005b261ecSmrg xkbi->radioGroups=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz); 219105b261ecSmrg else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(1, sz); 219205b261ecSmrg if (xkbi->radioGroups) { 219305b261ecSmrg if (xkbi->nRadioGroups) 219405b261ecSmrg bzero(&xkbi->radioGroups[xkbi->nRadioGroups], 219505b261ecSmrg (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec)); 219605b261ecSmrg xkbi->nRadioGroups= maxRG; 219705b261ecSmrg } 219805b261ecSmrg else xkbi->nRadioGroups= 0; 219905b261ecSmrg /* should compute members here */ 220005b261ecSmrg } 220105b261ecSmrg if (changes->map.changed&XkbKeyBehaviorsMask) { 220205b261ecSmrg unsigned oldLast; 220305b261ecSmrg oldLast= changes->map.first_key_behavior+ 220405b261ecSmrg changes->map.num_key_behaviors-1; 220505b261ecSmrg if (changes->map.first_key_behavior<req->firstKeyBehavior) 220605b261ecSmrg first= changes->map.first_key_behavior; 220705b261ecSmrg if (oldLast>last) 220805b261ecSmrg last= oldLast; 220905b261ecSmrg } 221005b261ecSmrg changes->map.changed|= XkbKeyBehaviorsMask; 221105b261ecSmrg changes->map.first_key_behavior = first; 221205b261ecSmrg changes->map.num_key_behaviors = (last-first+1); 221305b261ecSmrg return (char *)wire; 221405b261ecSmrg} 221505b261ecSmrg 221605b261ecSmrgstatic char * 221705b261ecSmrgSetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 221805b261ecSmrg XkbChangesPtr changes) 221905b261ecSmrg{ 222005b261ecSmrgregister int i,bit,nMods; 222105b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 222205b261ecSmrg 222305b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 222405b261ecSmrg return (char *)wire; 222505b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 222605b261ecSmrg if (req->virtualMods&bit) { 222705b261ecSmrg if (srv->vmods[i]!=wire[nMods]) { 222805b261ecSmrg changes->map.changed|= XkbVirtualModsMask; 222905b261ecSmrg changes->map.vmods|= bit; 223005b261ecSmrg srv->vmods[i]= wire[nMods]; 223105b261ecSmrg } 223205b261ecSmrg nMods++; 223305b261ecSmrg } 223405b261ecSmrg } 223505b261ecSmrg return (char *)(wire+XkbPaddedSize(nMods)); 223605b261ecSmrg} 223705b261ecSmrg 223805b261ecSmrgstatic char * 223905b261ecSmrgSetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 224005b261ecSmrg XkbChangesPtr changes) 224105b261ecSmrg{ 224205b261ecSmrgregister unsigned i,first,last; 224305b261ecSmrgXkbServerMapPtr xkb = xkbi->desc->server; 224405b261ecSmrgCARD8 * start; 224505b261ecSmrg 224605b261ecSmrg start= wire; 224705b261ecSmrg first= req->firstKeyExplicit; 224805b261ecSmrg last= req->firstKeyExplicit+req->nKeyExplicit-1; 224905b261ecSmrg bzero(&xkb->explicit[first],req->nKeyExplicit); 225005b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) { 225105b261ecSmrg xkb->explicit[wire[0]]= wire[1]; 225205b261ecSmrg } 225305b261ecSmrg if (first>0) { 225405b261ecSmrg if (changes->map.changed&XkbExplicitComponentsMask) { 225505b261ecSmrg int oldLast; 225605b261ecSmrg oldLast= changes->map.first_key_explicit+ 225705b261ecSmrg changes->map.num_key_explicit-1; 225805b261ecSmrg if (changes->map.first_key_explicit<first) 225905b261ecSmrg first= changes->map.first_key_explicit; 226005b261ecSmrg if (oldLast>last) 226105b261ecSmrg last= oldLast; 226205b261ecSmrg } 226305b261ecSmrg changes->map.first_key_explicit= first; 226405b261ecSmrg changes->map.num_key_explicit= (last-first)+1; 226505b261ecSmrg } 226605b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 226705b261ecSmrg return (char *)wire; 226805b261ecSmrg} 226905b261ecSmrg 227005b261ecSmrgstatic char * 227105b261ecSmrgSetModifierMap( XkbSrvInfoPtr xkbi, 227205b261ecSmrg xkbSetMapReq * req, 227305b261ecSmrg CARD8 * wire, 227405b261ecSmrg XkbChangesPtr changes) 227505b261ecSmrg{ 227605b261ecSmrgregister unsigned i,first,last; 227705b261ecSmrgXkbClientMapPtr xkb = xkbi->desc->map; 227805b261ecSmrgCARD8 * start; 227905b261ecSmrg 228005b261ecSmrg start= wire; 228105b261ecSmrg first= req->firstModMapKey; 228205b261ecSmrg last= req->firstModMapKey+req->nModMapKeys-1; 228305b261ecSmrg bzero(&xkb->modmap[first],req->nModMapKeys); 228405b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+= 2) { 228505b261ecSmrg xkb->modmap[wire[0]]= wire[1]; 228605b261ecSmrg } 228705b261ecSmrg if (first>0) { 228805b261ecSmrg if (changes->map.changed&XkbModifierMapMask) { 228905b261ecSmrg int oldLast; 229005b261ecSmrg oldLast= changes->map.first_modmap_key+ 229105b261ecSmrg changes->map.num_modmap_keys-1; 229205b261ecSmrg if (changes->map.first_modmap_key<first) 229305b261ecSmrg first= changes->map.first_modmap_key; 229405b261ecSmrg if (oldLast>last) 229505b261ecSmrg last= oldLast; 229605b261ecSmrg } 229705b261ecSmrg changes->map.first_modmap_key= first; 229805b261ecSmrg changes->map.num_modmap_keys= (last-first)+1; 229905b261ecSmrg } 230005b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 230105b261ecSmrg return (char *)wire; 230205b261ecSmrg} 230305b261ecSmrg 230405b261ecSmrgstatic char * 230505b261ecSmrgSetVirtualModMap( XkbSrvInfoPtr xkbi, 230605b261ecSmrg xkbSetMapReq * req, 230705b261ecSmrg xkbVModMapWireDesc * wire, 230805b261ecSmrg XkbChangesPtr changes) 230905b261ecSmrg{ 231005b261ecSmrgregister unsigned i,first,last; 231105b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 231205b261ecSmrg 231305b261ecSmrg first= req->firstVModMapKey; 231405b261ecSmrg last= req->firstVModMapKey+req->nVModMapKeys-1; 231505b261ecSmrg bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short)); 231605b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 231705b261ecSmrg srv->vmodmap[wire->key]= wire->vmods; 231805b261ecSmrg } 231905b261ecSmrg if (first>0) { 232005b261ecSmrg if (changes->map.changed&XkbVirtualModMapMask) { 232105b261ecSmrg int oldLast; 232205b261ecSmrg oldLast= changes->map.first_vmodmap_key+ 232305b261ecSmrg changes->map.num_vmodmap_keys-1; 232405b261ecSmrg if (changes->map.first_vmodmap_key<first) 232505b261ecSmrg first= changes->map.first_vmodmap_key; 232605b261ecSmrg if (oldLast>last) 232705b261ecSmrg last= oldLast; 232805b261ecSmrg } 232905b261ecSmrg changes->map.first_vmodmap_key= first; 233005b261ecSmrg changes->map.num_vmodmap_keys= (last-first)+1; 233105b261ecSmrg } 233205b261ecSmrg return (char *)wire; 233305b261ecSmrg} 233405b261ecSmrg 23354642e01fSmrg/** 23364642e01fSmrg * Check if the given request can be applied to the given device but don't 23374642e01fSmrg * actually do anything.. 23384642e01fSmrg */ 23394642e01fSmrgstatic int 23404642e01fSmrg_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values) 234105b261ecSmrg{ 23424642e01fSmrg XkbSrvInfoPtr xkbi; 23434642e01fSmrg XkbDescPtr xkb; 23444642e01fSmrg int error; 23454642e01fSmrg int nTypes = 0, nActions; 23464642e01fSmrg CARD8 mapWidths[XkbMaxLegalKeyCode + 1]; 23474642e01fSmrg CARD16 symsPerKey[XkbMaxLegalKeyCode + 1]; 234805b261ecSmrg 234905b261ecSmrg xkbi= dev->key->xkbInfo; 235005b261ecSmrg xkb = xkbi->desc; 235105b261ecSmrg 23524642e01fSmrg if ((xkb->min_key_code != req->minKeyCode)|| 23534642e01fSmrg (xkb->max_key_code != req->maxKeyCode)) { 235405b261ecSmrg if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ 23554642e01fSmrg req->minKeyCode= xkb->min_key_code; 23564642e01fSmrg req->maxKeyCode= xkb->max_key_code; 235705b261ecSmrg } 235805b261ecSmrg else { 23594642e01fSmrg if (!XkbIsLegalKeycode(req->minKeyCode)) { 23604642e01fSmrg client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); 236105b261ecSmrg return BadValue; 236205b261ecSmrg } 23634642e01fSmrg if (req->minKeyCode > req->maxKeyCode) { 23644642e01fSmrg client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); 236505b261ecSmrg return BadMatch; 236605b261ecSmrg } 236705b261ecSmrg } 236805b261ecSmrg } 236905b261ecSmrg 23704642e01fSmrg if ((req->present & XkbKeyTypesMask) && 23714642e01fSmrg (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values, 237205b261ecSmrg &nTypes,mapWidths))) { 237305b261ecSmrg client->errorValue = nTypes; 237405b261ecSmrg return BadValue; 237505b261ecSmrg } 23764642e01fSmrg if ((req->present & XkbKeySymsMask) && 23774642e01fSmrg (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey, 23784642e01fSmrg (xkbSymMapWireDesc **)&values,&error))) { 237905b261ecSmrg client->errorValue = error; 238005b261ecSmrg return BadValue; 238105b261ecSmrg } 238205b261ecSmrg 23834642e01fSmrg if ((req->present & XkbKeyActionsMask) && 23844642e01fSmrg (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey, 23854642e01fSmrg (CARD8 **)&values,&nActions))) { 238605b261ecSmrg client->errorValue = nActions; 238705b261ecSmrg return BadValue; 238805b261ecSmrg } 238905b261ecSmrg 23904642e01fSmrg if ((req->present & XkbKeyBehaviorsMask) && 23914642e01fSmrg (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) { 239205b261ecSmrg client->errorValue = error; 239305b261ecSmrg return BadValue; 239405b261ecSmrg } 239505b261ecSmrg 23964642e01fSmrg if ((req->present & XkbVirtualModsMask) && 23974642e01fSmrg (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) { 239805b261ecSmrg client->errorValue= error; 239905b261ecSmrg return BadValue; 240005b261ecSmrg } 24014642e01fSmrg if ((req->present&XkbExplicitComponentsMask) && 24024642e01fSmrg (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) { 240305b261ecSmrg client->errorValue= error; 240405b261ecSmrg return BadValue; 240505b261ecSmrg } 24064642e01fSmrg if ((req->present&XkbModifierMapMask) && 24074642e01fSmrg (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) { 240805b261ecSmrg client->errorValue= error; 240905b261ecSmrg return BadValue; 241005b261ecSmrg } 24114642e01fSmrg if ((req->present&XkbVirtualModMapMask) && 24124642e01fSmrg (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) { 241305b261ecSmrg client->errorValue= error; 241405b261ecSmrg return BadValue; 241505b261ecSmrg } 24164642e01fSmrg 24174642e01fSmrg if (((values-((char *)req))/4)!= req->length) { 24184642e01fSmrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); 24194642e01fSmrg client->errorValue = values-((char *)&req[1]); 242005b261ecSmrg return BadLength; 242105b261ecSmrg } 24224642e01fSmrg 24234642e01fSmrg return Success; 24244642e01fSmrg} 24254642e01fSmrg 24264642e01fSmrg/** 24274642e01fSmrg * Apply the given request on the given device. 24284642e01fSmrg */ 24294642e01fSmrgstatic int 24304642e01fSmrg_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values) 24314642e01fSmrg{ 24324642e01fSmrg XkbEventCauseRec cause; 24334642e01fSmrg XkbChangesRec change; 24344642e01fSmrg Bool sentNKN; 24354642e01fSmrg XkbSrvInfoPtr xkbi; 24364642e01fSmrg XkbDescPtr xkb; 24374642e01fSmrg 24384642e01fSmrg xkbi= dev->key->xkbInfo; 24394642e01fSmrg xkb = xkbi->desc; 24404642e01fSmrg 24414642e01fSmrg XkbSetCauseXkbReq(&cause,X_kbSetMap,client); 24424642e01fSmrg bzero(&change, sizeof(change)); 24434642e01fSmrg sentNKN = False; 24444642e01fSmrg if ((xkb->min_key_code!=req->minKeyCode)|| 24454642e01fSmrg (xkb->max_key_code!=req->maxKeyCode)) { 244605b261ecSmrg Status status; 244705b261ecSmrg xkbNewKeyboardNotify nkn; 24484642e01fSmrg nkn.deviceID = nkn.oldDeviceID = dev->id; 24494642e01fSmrg nkn.oldMinKeyCode = xkb->min_key_code; 24504642e01fSmrg nkn.oldMaxKeyCode = xkb->max_key_code; 24514642e01fSmrg status= XkbChangeKeycodeRange(xkb, req->minKeyCode, 24524642e01fSmrg req->maxKeyCode, &change); 24534642e01fSmrg if (status != Success) 24544642e01fSmrg return status; /* oh-oh. what about the other keyboards? */ 24554642e01fSmrg nkn.minKeyCode = xkb->min_key_code; 24564642e01fSmrg nkn.maxKeyCode = xkb->max_key_code; 24574642e01fSmrg nkn.requestMajor = XkbReqCode; 24584642e01fSmrg nkn.requestMinor = X_kbSetMap; 24594642e01fSmrg nkn.changed = XkbNKN_KeycodesMask; 246005b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 24614642e01fSmrg sentNKN = True; 24624642e01fSmrg } 24634642e01fSmrg 24644642e01fSmrg if (req->present&XkbKeyTypesMask) { 24654642e01fSmrg values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change); 24664642e01fSmrg if (!values) goto allocFailure; 24674642e01fSmrg } 24684642e01fSmrg if (req->present&XkbKeySymsMask) { 24694642e01fSmrg values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev); 24704642e01fSmrg if (!values) goto allocFailure; 24714642e01fSmrg } 24724642e01fSmrg if (req->present&XkbKeyActionsMask) { 24734642e01fSmrg values = SetKeyActions(xkb,req,(CARD8 *)values,&change); 24744642e01fSmrg if (!values) goto allocFailure; 24754642e01fSmrg } 24764642e01fSmrg if (req->present&XkbKeyBehaviorsMask) { 24774642e01fSmrg values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change); 24784642e01fSmrg if (!values) goto allocFailure; 24794642e01fSmrg } 24804642e01fSmrg if (req->present&XkbVirtualModsMask) 24814642e01fSmrg values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change); 24824642e01fSmrg if (req->present&XkbExplicitComponentsMask) 24834642e01fSmrg values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change); 24844642e01fSmrg if (req->present&XkbModifierMapMask) 24854642e01fSmrg values= SetModifierMap(xkbi,req,(CARD8 *)values,&change); 24864642e01fSmrg if (req->present&XkbVirtualModMapMask) 24874642e01fSmrg values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change); 24884642e01fSmrg if (((values-((char *)req))/4)!=req->length) { 24894642e01fSmrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); 24904642e01fSmrg client->errorValue = values-((char *)&req[1]); 249105b261ecSmrg return BadLength; 249205b261ecSmrg } 24934642e01fSmrg if (req->flags&XkbSetMapRecomputeActions) { 249405b261ecSmrg KeyCode first,last,firstMM,lastMM; 249505b261ecSmrg if (change.map.num_key_syms>0) { 249605b261ecSmrg first= change.map.first_key_sym; 249705b261ecSmrg last= first+change.map.num_key_syms-1; 249805b261ecSmrg } 249905b261ecSmrg else first= last= 0; 250005b261ecSmrg if (change.map.num_modmap_keys>0) { 250105b261ecSmrg firstMM= change.map.first_modmap_key; 250205b261ecSmrg lastMM= first+change.map.num_modmap_keys-1; 250305b261ecSmrg } 250405b261ecSmrg else firstMM= lastMM= 0; 250505b261ecSmrg if ((last>0) && (lastMM>0)) { 250605b261ecSmrg if (firstMM<first) 250705b261ecSmrg first= firstMM; 250805b261ecSmrg if (lastMM>last) 250905b261ecSmrg last= lastMM; 251005b261ecSmrg } 251105b261ecSmrg else if (lastMM>0) { 251205b261ecSmrg first= firstMM; 251305b261ecSmrg last= lastMM; 251405b261ecSmrg } 251505b261ecSmrg if (last>0) { 251605b261ecSmrg unsigned check= 0; 251705b261ecSmrg XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause); 251805b261ecSmrg if (check) 251905b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 252005b261ecSmrg } 252105b261ecSmrg } 252205b261ecSmrg if (!sentNKN) 252305b261ecSmrg XkbSendNotification(dev,&change,&cause); 252405b261ecSmrg 252505b261ecSmrg XkbUpdateCoreDescription(dev,False); 25264642e01fSmrg return Success; 252705b261ecSmrgallocFailure: 252805b261ecSmrg return BadAlloc; 252905b261ecSmrg} 253005b261ecSmrg 25314642e01fSmrg 25324642e01fSmrgint 25334642e01fSmrgProcXkbSetMap(ClientPtr client) 25344642e01fSmrg{ 25354642e01fSmrg DeviceIntPtr dev; 25364642e01fSmrg char * tmp; 25374642e01fSmrg int rc; 25384642e01fSmrg 25394642e01fSmrg REQUEST(xkbSetMapReq); 25404642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 25414642e01fSmrg 25424642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 25434642e01fSmrg return BadAccess; 25444642e01fSmrg 25454642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 25464642e01fSmrg CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); 25474642e01fSmrg 25484642e01fSmrg tmp = (char *)&stuff[1]; 25494642e01fSmrg 25504642e01fSmrg /* Check if we can to the SetMap on the requested device. If this 25514642e01fSmrg succeeds, do the same thing for all extension devices (if needed). 25524642e01fSmrg If any of them fails, fail. */ 25534642e01fSmrg rc = _XkbSetMapChecks(client, dev, stuff, tmp); 25544642e01fSmrg 25554642e01fSmrg if (rc != Success) 25564642e01fSmrg return rc; 25574642e01fSmrg 25584642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 25594642e01fSmrg { 25604642e01fSmrg DeviceIntPtr other; 25614642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 25624642e01fSmrg { 25634642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 25644642e01fSmrg { 25654642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 25664642e01fSmrg if (rc == Success) 25674642e01fSmrg { 25684642e01fSmrg rc = _XkbSetMapChecks(client, other, stuff, tmp); 25694642e01fSmrg if (rc != Success) 25704642e01fSmrg return rc; 25714642e01fSmrg } 25724642e01fSmrg } 25734642e01fSmrg } 25744642e01fSmrg } 25754642e01fSmrg 25764642e01fSmrg /* We know now that we will succed with the SetMap. In theory anyway. */ 25774642e01fSmrg rc = _XkbSetMap(client, dev, stuff, tmp); 25784642e01fSmrg if (rc != Success) 25794642e01fSmrg return rc; 25804642e01fSmrg 25814642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 25824642e01fSmrg { 25834642e01fSmrg DeviceIntPtr other; 25844642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 25854642e01fSmrg { 25864642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 25874642e01fSmrg { 25884642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 25894642e01fSmrg if (rc == Success) 25904642e01fSmrg _XkbSetMap(client, other, stuff, tmp); 25914642e01fSmrg /* ignore rc. if the SetMap failed although the check above 25924642e01fSmrg reported true there isn't much we can do. we still need to 25934642e01fSmrg set all other devices, hoping that at least they stay in 25944642e01fSmrg sync. */ 25954642e01fSmrg } 25964642e01fSmrg } 25974642e01fSmrg } 25984642e01fSmrg 25994642e01fSmrg return client->noClientException; 26004642e01fSmrg} 26014642e01fSmrg 260205b261ecSmrg/***====================================================================***/ 260305b261ecSmrg 260405b261ecSmrgstatic Status 260505b261ecSmrgXkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat, 260605b261ecSmrg xkbGetCompatMapReply * rep) 260705b261ecSmrg{ 260805b261ecSmrgunsigned size,nGroups; 260905b261ecSmrg 261005b261ecSmrg nGroups= 0; 261105b261ecSmrg if (rep->groups!=0) { 261205b261ecSmrg register int i,bit; 261305b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 261405b261ecSmrg if (rep->groups&bit) 261505b261ecSmrg nGroups++; 261605b261ecSmrg } 261705b261ecSmrg } 261805b261ecSmrg size= nGroups*SIZEOF(xkbModsWireDesc); 261905b261ecSmrg size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); 262005b261ecSmrg rep->length= size/4; 262105b261ecSmrg return Success; 262205b261ecSmrg} 262305b261ecSmrg 262405b261ecSmrgstatic int 262505b261ecSmrgXkbSendCompatMap( ClientPtr client, 262605b261ecSmrg XkbCompatMapPtr compat, 262705b261ecSmrg xkbGetCompatMapReply * rep) 262805b261ecSmrg{ 262905b261ecSmrgchar * data; 263005b261ecSmrgint size; 263105b261ecSmrg 263205b261ecSmrg size= rep->length*4; 263305b261ecSmrg if (size>0) { 26344642e01fSmrg data = (char *)xalloc(size); 263505b261ecSmrg if (data) { 263605b261ecSmrg register unsigned i,bit; 263705b261ecSmrg xkbModsWireDesc * grp; 263805b261ecSmrg XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI]; 263905b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 264005b261ecSmrg for (i=0;i<rep->nSI;i++,sym++,wire++) { 264105b261ecSmrg wire->sym= sym->sym; 264205b261ecSmrg wire->mods= sym->mods; 264305b261ecSmrg wire->match= sym->match; 264405b261ecSmrg wire->virtualMod= sym->virtual_mod; 264505b261ecSmrg wire->flags= sym->flags; 264605b261ecSmrg memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc); 264705b261ecSmrg if (client->swapped) { 264805b261ecSmrg register int n; 264905b261ecSmrg swapl(&wire->sym,n); 265005b261ecSmrg } 265105b261ecSmrg } 265205b261ecSmrg if (rep->groups) { 265305b261ecSmrg grp = (xkbModsWireDesc *)wire; 265405b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 265505b261ecSmrg if (rep->groups&bit) { 265605b261ecSmrg grp->mask= compat->groups[i].mask; 265705b261ecSmrg grp->realMods= compat->groups[i].real_mods; 265805b261ecSmrg grp->virtualMods= compat->groups[i].vmods; 265905b261ecSmrg if (client->swapped) { 266005b261ecSmrg register int n; 266105b261ecSmrg swaps(&grp->virtualMods,n); 266205b261ecSmrg } 266305b261ecSmrg grp++; 266405b261ecSmrg } 266505b261ecSmrg } 266605b261ecSmrg wire= (xkbSymInterpretWireDesc*)grp; 266705b261ecSmrg } 266805b261ecSmrg } 266905b261ecSmrg else return BadAlloc; 267005b261ecSmrg } 267105b261ecSmrg else data= NULL; 267205b261ecSmrg 267305b261ecSmrg if (client->swapped) { 267405b261ecSmrg register int n; 267505b261ecSmrg swaps(&rep->sequenceNumber,n); 267605b261ecSmrg swapl(&rep->length,n); 267705b261ecSmrg swaps(&rep->firstSI,n); 267805b261ecSmrg swaps(&rep->nSI,n); 267905b261ecSmrg swaps(&rep->nTotalSI,n); 268005b261ecSmrg } 268105b261ecSmrg 268205b261ecSmrg WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep); 268305b261ecSmrg if (data) { 268405b261ecSmrg WriteToClient(client, size, data); 26854642e01fSmrg xfree((char *)data); 268605b261ecSmrg } 268705b261ecSmrg return client->noClientException; 268805b261ecSmrg} 268905b261ecSmrg 269005b261ecSmrgint 269105b261ecSmrgProcXkbGetCompatMap(ClientPtr client) 269205b261ecSmrg{ 269305b261ecSmrg xkbGetCompatMapReply rep; 269405b261ecSmrg DeviceIntPtr dev; 269505b261ecSmrg XkbDescPtr xkb; 269605b261ecSmrg XkbCompatMapPtr compat; 269705b261ecSmrg 269805b261ecSmrg REQUEST(xkbGetCompatMapReq); 269905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 270005b261ecSmrg 270105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 270205b261ecSmrg return BadAccess; 270305b261ecSmrg 27044642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 270505b261ecSmrg 270605b261ecSmrg xkb = dev->key->xkbInfo->desc; 270705b261ecSmrg compat= xkb->compat; 270805b261ecSmrg 270905b261ecSmrg rep.type = X_Reply; 271005b261ecSmrg rep.deviceID = dev->id; 271105b261ecSmrg rep.sequenceNumber = client->sequence; 271205b261ecSmrg rep.length = 0; 271305b261ecSmrg rep.firstSI = stuff->firstSI; 271405b261ecSmrg rep.nSI = stuff->nSI; 271505b261ecSmrg if (stuff->getAllSI) { 271605b261ecSmrg rep.firstSI = 0; 271705b261ecSmrg rep.nSI = compat->num_si; 271805b261ecSmrg } 271905b261ecSmrg else if ((((unsigned)stuff->nSI)>0)&& 272005b261ecSmrg ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) { 272105b261ecSmrg client->errorValue = _XkbErrCode2(0x05,compat->num_si); 272205b261ecSmrg return BadValue; 272305b261ecSmrg } 272405b261ecSmrg rep.nTotalSI = compat->num_si; 272505b261ecSmrg rep.groups= stuff->groups; 272605b261ecSmrg XkbComputeGetCompatMapReplySize(compat,&rep); 272705b261ecSmrg return XkbSendCompatMap(client,compat,&rep); 272805b261ecSmrg} 272905b261ecSmrg 27304642e01fSmrg/** 27314642e01fSmrg * Apply the given request on the given device. 27324642e01fSmrg * If dryRun is True, then value checks are performed, but the device isn't 27334642e01fSmrg * modified. 27344642e01fSmrg */ 27354642e01fSmrgstatic int 27364642e01fSmrg_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, 27374642e01fSmrg xkbSetCompatMapReq *req, char* data, BOOL dryRun) 273805b261ecSmrg{ 27394642e01fSmrg XkbSrvInfoPtr xkbi; 27404642e01fSmrg XkbDescPtr xkb; 27414642e01fSmrg XkbCompatMapPtr compat; 27424642e01fSmrg int nGroups; 27434642e01fSmrg unsigned i,bit; 274405b261ecSmrg 274505b261ecSmrg xkbi = dev->key->xkbInfo; 27464642e01fSmrg xkb = xkbi->desc; 27474642e01fSmrg compat = xkb->compat; 27484642e01fSmrg 27494642e01fSmrg if ((req->nSI>0)||(req->truncateSI)) { 275005b261ecSmrg xkbSymInterpretWireDesc *wire; 27514642e01fSmrg if (req->firstSI>compat->num_si) { 275205b261ecSmrg client->errorValue = _XkbErrCode2(0x02,compat->num_si); 275305b261ecSmrg return BadValue; 275405b261ecSmrg } 275505b261ecSmrg wire= (xkbSymInterpretWireDesc *)data; 27564642e01fSmrg wire+= req->nSI; 275705b261ecSmrg data = (char *)wire; 275805b261ecSmrg } 27594642e01fSmrg 276005b261ecSmrg nGroups= 0; 27614642e01fSmrg if (req->groups!=0) { 276205b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 27634642e01fSmrg if ( req->groups&bit ) 276405b261ecSmrg nGroups++; 276505b261ecSmrg } 276605b261ecSmrg } 276705b261ecSmrg data+= nGroups*SIZEOF(xkbModsWireDesc); 27684642e01fSmrg if (((data-((char *)req))/4)!=req->length) { 276905b261ecSmrg return BadLength; 277005b261ecSmrg } 27714642e01fSmrg 27724642e01fSmrg /* Done all the checks we can do */ 27734642e01fSmrg if (dryRun) 27744642e01fSmrg return Success; 27754642e01fSmrg 27764642e01fSmrg data = (char *)&req[1]; 27774642e01fSmrg if (req->nSI>0) { 277805b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 277905b261ecSmrg XkbSymInterpretPtr sym; 27804642e01fSmrg if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) { 27814642e01fSmrg compat->num_si= req->firstSI+req->nSI; 278205b261ecSmrg compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, 278305b261ecSmrg compat->num_si, 278405b261ecSmrg XkbSymInterpretRec); 278505b261ecSmrg if (!compat->sym_interpret) { 278605b261ecSmrg compat->num_si= 0; 278705b261ecSmrg return BadAlloc; 278805b261ecSmrg } 278905b261ecSmrg } 27904642e01fSmrg else if (req->truncateSI) { 27914642e01fSmrg compat->num_si = req->firstSI+req->nSI; 279205b261ecSmrg } 27934642e01fSmrg sym = &compat->sym_interpret[req->firstSI]; 27944642e01fSmrg for (i=0;i<req->nSI;i++,wire++,sym++) { 279505b261ecSmrg if (client->swapped) { 27964642e01fSmrg int n; 279705b261ecSmrg swapl(&wire->sym,n); 279805b261ecSmrg } 279905b261ecSmrg sym->sym= wire->sym; 280005b261ecSmrg sym->mods= wire->mods; 280105b261ecSmrg sym->match= wire->match; 280205b261ecSmrg sym->flags= wire->flags; 280305b261ecSmrg sym->virtual_mod= wire->virtualMod; 280405b261ecSmrg memcpy((char *)&sym->act,(char *)&wire->act, 28054642e01fSmrg SIZEOF(xkbActionWireDesc)); 280605b261ecSmrg } 280705b261ecSmrg data = (char *)wire; 280805b261ecSmrg } 28094642e01fSmrg else if (req->truncateSI) { 28104642e01fSmrg compat->num_si = req->firstSI; 281105b261ecSmrg } 281205b261ecSmrg 28134642e01fSmrg if (req->groups!=0) { 28144642e01fSmrg unsigned i, bit; 281505b261ecSmrg xkbModsWireDesc *wire = (xkbModsWireDesc *)data; 28164642e01fSmrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 28174642e01fSmrg if (req->groups & bit) { 281805b261ecSmrg if (client->swapped) { 28194642e01fSmrg int n; 282005b261ecSmrg swaps(&wire->virtualMods,n); 282105b261ecSmrg } 282205b261ecSmrg compat->groups[i].mask= wire->realMods; 282305b261ecSmrg compat->groups[i].real_mods= wire->realMods; 282405b261ecSmrg compat->groups[i].vmods= wire->virtualMods; 282505b261ecSmrg if (wire->virtualMods!=0) { 282605b261ecSmrg unsigned tmp; 282705b261ecSmrg tmp= XkbMaskForVMask(xkb,wire->virtualMods); 282805b261ecSmrg compat->groups[i].mask|= tmp; 282905b261ecSmrg } 283005b261ecSmrg data+= SIZEOF(xkbModsWireDesc); 283105b261ecSmrg wire= (xkbModsWireDesc *)data; 283205b261ecSmrg } 283305b261ecSmrg } 283405b261ecSmrg } 28354642e01fSmrg i= XkbPaddedSize((data-((char *)req))); 28364642e01fSmrg if ((i/4)!=req->length) { 28374642e01fSmrg ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); 283805b261ecSmrg return BadLength; 283905b261ecSmrg } 28404642e01fSmrg 284105b261ecSmrg if (dev->xkb_interest) { 284205b261ecSmrg xkbCompatMapNotify ev; 284305b261ecSmrg ev.deviceID = dev->id; 28444642e01fSmrg ev.changedGroups = req->groups; 28454642e01fSmrg ev.firstSI = req->firstSI; 28464642e01fSmrg ev.nSI = req->nSI; 284705b261ecSmrg ev.nTotalSI = compat->num_si; 284805b261ecSmrg XkbSendCompatMapNotify(dev,&ev); 284905b261ecSmrg } 285005b261ecSmrg 28514642e01fSmrg if (req->recomputeActions) { 285205b261ecSmrg XkbChangesRec change; 285305b261ecSmrg unsigned check; 285405b261ecSmrg XkbEventCauseRec cause; 285505b261ecSmrg 285605b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client); 285705b261ecSmrg bzero(&change,sizeof(XkbChangesRec)); 285805b261ecSmrg XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check, 285905b261ecSmrg &cause); 286005b261ecSmrg if (check) 286105b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 286205b261ecSmrg XkbUpdateCoreDescription(dev,False); 286305b261ecSmrg XkbSendNotification(dev,&change,&cause); 286405b261ecSmrg } 28654642e01fSmrg return Success; 28664642e01fSmrg} 28674642e01fSmrg 28684642e01fSmrgint 28694642e01fSmrgProcXkbSetCompatMap(ClientPtr client) 28704642e01fSmrg{ 28714642e01fSmrg DeviceIntPtr dev; 28724642e01fSmrg char *data; 28734642e01fSmrg int rc; 28744642e01fSmrg 28754642e01fSmrg REQUEST(xkbSetCompatMapReq); 28764642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 28774642e01fSmrg 28784642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 28794642e01fSmrg return BadAccess; 28804642e01fSmrg 28814642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 28824642e01fSmrg 28834642e01fSmrg data = (char *)&stuff[1]; 28844642e01fSmrg 28854642e01fSmrg /* check first using a dry-run */ 28864642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); 28874642e01fSmrg if (rc != Success) 28884642e01fSmrg return rc; 28894642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 28904642e01fSmrg { 28914642e01fSmrg DeviceIntPtr other; 28924642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 28934642e01fSmrg { 28944642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 28954642e01fSmrg { 28964642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 28974642e01fSmrg if (rc == Success) 28984642e01fSmrg { 28994642e01fSmrg /* dry-run */ 29004642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); 29014642e01fSmrg if (rc != Success) 29024642e01fSmrg return rc; 29034642e01fSmrg } 29044642e01fSmrg } 29054642e01fSmrg } 29064642e01fSmrg } 29074642e01fSmrg 29084642e01fSmrg /* Yay, the dry-runs succeed. Let's apply */ 29094642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); 29104642e01fSmrg if (rc != Success) 29114642e01fSmrg return rc; 29124642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 29134642e01fSmrg { 29144642e01fSmrg DeviceIntPtr other; 29154642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 29164642e01fSmrg { 29174642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 29184642e01fSmrg { 29194642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 29204642e01fSmrg if (rc == Success) 29214642e01fSmrg { 29224642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); 29234642e01fSmrg if (rc != Success) 29244642e01fSmrg return rc; 29254642e01fSmrg } 29264642e01fSmrg } 29274642e01fSmrg } 29284642e01fSmrg } 29294642e01fSmrg 293005b261ecSmrg return client->noClientException; 293105b261ecSmrg} 293205b261ecSmrg 293305b261ecSmrg/***====================================================================***/ 293405b261ecSmrg 293505b261ecSmrgint 293605b261ecSmrgProcXkbGetIndicatorState(ClientPtr client) 293705b261ecSmrg{ 293805b261ecSmrg xkbGetIndicatorStateReply rep; 293905b261ecSmrg XkbSrvLedInfoPtr sli; 294005b261ecSmrg DeviceIntPtr dev; 294105b261ecSmrg register int i; 294205b261ecSmrg 294305b261ecSmrg REQUEST(xkbGetIndicatorStateReq); 294405b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 294505b261ecSmrg 294605b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 294705b261ecSmrg return BadAccess; 294805b261ecSmrg 29494642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 295005b261ecSmrg 295105b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 295205b261ecSmrg XkbXI_IndicatorStateMask); 295305b261ecSmrg if (!sli) 295405b261ecSmrg return BadAlloc; 295505b261ecSmrg 295605b261ecSmrg rep.type = X_Reply; 295705b261ecSmrg rep.sequenceNumber = client->sequence; 295805b261ecSmrg rep.length = 0; 295905b261ecSmrg rep.deviceID = dev->id; 296005b261ecSmrg rep.state = sli->effectiveState; 296105b261ecSmrg 296205b261ecSmrg if (client->swapped) { 296305b261ecSmrg swaps(&rep.sequenceNumber,i); 296405b261ecSmrg swapl(&rep.state,i); 296505b261ecSmrg } 296605b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep); 296705b261ecSmrg return client->noClientException; 296805b261ecSmrg} 296905b261ecSmrg 297005b261ecSmrg/***====================================================================***/ 297105b261ecSmrg 297205b261ecSmrgstatic Status 297305b261ecSmrgXkbComputeGetIndicatorMapReplySize( 297405b261ecSmrg XkbIndicatorPtr indicators, 297505b261ecSmrg xkbGetIndicatorMapReply *rep) 297605b261ecSmrg{ 297705b261ecSmrgregister int i,bit; 297805b261ecSmrgint nIndicators; 297905b261ecSmrg 298005b261ecSmrg rep->realIndicators = indicators->phys_indicators; 298105b261ecSmrg for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 298205b261ecSmrg if (rep->which&bit) 298305b261ecSmrg nIndicators++; 298405b261ecSmrg } 298505b261ecSmrg rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4; 298605b261ecSmrg return Success; 298705b261ecSmrg} 298805b261ecSmrg 298905b261ecSmrgstatic int 299005b261ecSmrgXkbSendIndicatorMap( ClientPtr client, 299105b261ecSmrg XkbIndicatorPtr indicators, 299205b261ecSmrg xkbGetIndicatorMapReply * rep) 299305b261ecSmrg{ 299405b261ecSmrgint length; 299505b261ecSmrgCARD8 * map; 299605b261ecSmrgregister int i; 299705b261ecSmrgregister unsigned bit; 299805b261ecSmrg 299905b261ecSmrg length = rep->length*4; 300005b261ecSmrg if (length>0) { 300105b261ecSmrg CARD8 *to; 30024642e01fSmrg to= map= (CARD8 *)xalloc(length); 300305b261ecSmrg if (map) { 300405b261ecSmrg xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to; 300505b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 300605b261ecSmrg if (rep->which&bit) { 300705b261ecSmrg wire->flags= indicators->maps[i].flags; 300805b261ecSmrg wire->whichGroups= indicators->maps[i].which_groups; 300905b261ecSmrg wire->groups= indicators->maps[i].groups; 301005b261ecSmrg wire->whichMods= indicators->maps[i].which_mods; 301105b261ecSmrg wire->mods= indicators->maps[i].mods.mask; 301205b261ecSmrg wire->realMods= indicators->maps[i].mods.real_mods; 301305b261ecSmrg wire->virtualMods= indicators->maps[i].mods.vmods; 301405b261ecSmrg wire->ctrls= indicators->maps[i].ctrls; 301505b261ecSmrg if (client->swapped) { 301605b261ecSmrg register int n; 301705b261ecSmrg swaps(&wire->virtualMods,n); 301805b261ecSmrg swapl(&wire->ctrls,n); 301905b261ecSmrg } 302005b261ecSmrg wire++; 302105b261ecSmrg } 302205b261ecSmrg } 302305b261ecSmrg to = (CARD8 *)wire; 302405b261ecSmrg if ((to-map)!=length) { 302505b261ecSmrg client->errorValue = _XkbErrCode2(0xff,length); 302605b261ecSmrg return BadLength; 302705b261ecSmrg } 302805b261ecSmrg } 302905b261ecSmrg else return BadAlloc; 303005b261ecSmrg } 303105b261ecSmrg else map = NULL; 303205b261ecSmrg if (client->swapped) { 303305b261ecSmrg swaps(&rep->sequenceNumber,i); 303405b261ecSmrg swapl(&rep->length,i); 303505b261ecSmrg swapl(&rep->which,i); 303605b261ecSmrg swapl(&rep->realIndicators,i); 303705b261ecSmrg } 303805b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep); 303905b261ecSmrg if (map) { 304005b261ecSmrg WriteToClient(client, length, (char *)map); 30414642e01fSmrg xfree((char *)map); 304205b261ecSmrg } 304305b261ecSmrg return client->noClientException; 304405b261ecSmrg} 304505b261ecSmrg 304605b261ecSmrgint 304705b261ecSmrgProcXkbGetIndicatorMap(ClientPtr client) 304805b261ecSmrg{ 304905b261ecSmrgxkbGetIndicatorMapReply rep; 305005b261ecSmrgDeviceIntPtr dev; 305105b261ecSmrgXkbDescPtr xkb; 305205b261ecSmrgXkbIndicatorPtr leds; 305305b261ecSmrg 305405b261ecSmrg REQUEST(xkbGetIndicatorMapReq); 305505b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 305605b261ecSmrg 305705b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 305805b261ecSmrg return BadAccess; 305905b261ecSmrg 30604642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 306105b261ecSmrg 306205b261ecSmrg xkb= dev->key->xkbInfo->desc; 306305b261ecSmrg leds= xkb->indicators; 306405b261ecSmrg 306505b261ecSmrg rep.type = X_Reply; 306605b261ecSmrg rep.sequenceNumber = client->sequence; 306705b261ecSmrg rep.length = 0; 306805b261ecSmrg rep.deviceID = dev->id; 306905b261ecSmrg rep.which = stuff->which; 307005b261ecSmrg XkbComputeGetIndicatorMapReplySize(leds,&rep); 307105b261ecSmrg return XkbSendIndicatorMap(client,leds,&rep); 307205b261ecSmrg} 307305b261ecSmrg 30744642e01fSmrg/** 30754642e01fSmrg * Apply the given map to the given device. Which specifies which components 30764642e01fSmrg * to apply. 30774642e01fSmrg */ 30784642e01fSmrgstatic int 30794642e01fSmrg_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, 30804642e01fSmrg int which, xkbIndicatorMapWireDesc *desc) 30814642e01fSmrg{ 30824642e01fSmrg XkbSrvInfoPtr xkbi; 30834642e01fSmrg XkbSrvLedInfoPtr sli; 30844642e01fSmrg XkbEventCauseRec cause; 30854642e01fSmrg int i, bit; 30864642e01fSmrg 30874642e01fSmrg xkbi = dev->key->xkbInfo; 30884642e01fSmrg 30894642e01fSmrg sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 30904642e01fSmrg XkbXI_IndicatorMapsMask); 30914642e01fSmrg if (!sli) 30924642e01fSmrg return BadAlloc; 30934642e01fSmrg 30944642e01fSmrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 30954642e01fSmrg if (which & bit) { 30964642e01fSmrg sli->maps[i].flags = desc->flags; 30974642e01fSmrg sli->maps[i].which_groups = desc->whichGroups; 30984642e01fSmrg sli->maps[i].groups = desc->groups; 30994642e01fSmrg sli->maps[i].which_mods = desc->whichMods; 31004642e01fSmrg sli->maps[i].mods.mask = desc->mods; 31014642e01fSmrg sli->maps[i].mods.real_mods = desc->mods; 31024642e01fSmrg sli->maps[i].mods.vmods= desc->virtualMods; 31034642e01fSmrg sli->maps[i].ctrls = desc->ctrls; 31044642e01fSmrg if (desc->virtualMods!=0) { 31054642e01fSmrg unsigned tmp; 31064642e01fSmrg tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods); 31074642e01fSmrg sli->maps[i].mods.mask= desc->mods|tmp; 31084642e01fSmrg } 31094642e01fSmrg desc++; 31104642e01fSmrg } 31114642e01fSmrg } 31124642e01fSmrg 31134642e01fSmrg XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); 31144642e01fSmrg XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause); 31154642e01fSmrg 31164642e01fSmrg return Success; 31174642e01fSmrg} 31184642e01fSmrg 311905b261ecSmrgint 312005b261ecSmrgProcXkbSetIndicatorMap(ClientPtr client) 312105b261ecSmrg{ 31224642e01fSmrg int i, bit; 31234642e01fSmrg int nIndicators; 31244642e01fSmrg DeviceIntPtr dev; 31254642e01fSmrg xkbIndicatorMapWireDesc *from; 31264642e01fSmrg int rc; 312705b261ecSmrg 312805b261ecSmrg REQUEST(xkbSetIndicatorMapReq); 312905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 313005b261ecSmrg 313105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 313205b261ecSmrg return BadAccess; 313305b261ecSmrg 31344642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 313505b261ecSmrg 313605b261ecSmrg if (stuff->which==0) 313705b261ecSmrg return client->noClientException; 313805b261ecSmrg 313905b261ecSmrg for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 314005b261ecSmrg if (stuff->which&bit) 314105b261ecSmrg nIndicators++; 314205b261ecSmrg } 314305b261ecSmrg if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+ 314405b261ecSmrg (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) { 314505b261ecSmrg return BadLength; 314605b261ecSmrg } 314705b261ecSmrg 314805b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 314905b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 315005b261ecSmrg if (stuff->which&bit) { 315105b261ecSmrg if (client->swapped) { 31524642e01fSmrg int n; 315305b261ecSmrg swaps(&from->virtualMods,n); 315405b261ecSmrg swapl(&from->ctrls,n); 315505b261ecSmrg } 315605b261ecSmrg CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup); 315705b261ecSmrg CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods); 315805b261ecSmrg from++; 315905b261ecSmrg } 316005b261ecSmrg } 316105b261ecSmrg 316205b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 31634642e01fSmrg rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); 31644642e01fSmrg if (rc != Success) 31654642e01fSmrg return rc; 31664642e01fSmrg 31674642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 31684642e01fSmrg { 31694642e01fSmrg DeviceIntPtr other; 31704642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 31714642e01fSmrg { 31724642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 31734642e01fSmrg { 31744642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess); 31754642e01fSmrg if (rc == Success) 31764642e01fSmrg _XkbSetIndicatorMap(client, other, stuff->which, from); 31774642e01fSmrg } 31784642e01fSmrg } 317905b261ecSmrg } 318005b261ecSmrg 31814642e01fSmrg return Success; 318205b261ecSmrg} 318305b261ecSmrg 318405b261ecSmrg/***====================================================================***/ 318505b261ecSmrg 318605b261ecSmrgint 318705b261ecSmrgProcXkbGetNamedIndicator(ClientPtr client) 318805b261ecSmrg{ 318905b261ecSmrg DeviceIntPtr dev; 319005b261ecSmrg xkbGetNamedIndicatorReply rep; 319105b261ecSmrg register int i = 0; 319205b261ecSmrg XkbSrvLedInfoPtr sli; 319305b261ecSmrg XkbIndicatorMapPtr map = NULL; 319405b261ecSmrg 319505b261ecSmrg REQUEST(xkbGetNamedIndicatorReq); 319605b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 319705b261ecSmrg 319805b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 319905b261ecSmrg return BadAccess; 320005b261ecSmrg 32014642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 320205b261ecSmrg CHK_ATOM_ONLY(stuff->indicator); 320305b261ecSmrg 320405b261ecSmrg sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0); 320505b261ecSmrg if (!sli) 320605b261ecSmrg return BadAlloc; 320705b261ecSmrg 320805b261ecSmrg i= 0; 320905b261ecSmrg map= NULL; 321005b261ecSmrg if ((sli->names)&&(sli->maps)) { 321105b261ecSmrg for (i=0;i<XkbNumIndicators;i++) { 321205b261ecSmrg if (stuff->indicator==sli->names[i]) { 321305b261ecSmrg map= &sli->maps[i]; 321405b261ecSmrg break; 321505b261ecSmrg } 321605b261ecSmrg } 321705b261ecSmrg } 321805b261ecSmrg 321905b261ecSmrg rep.type= X_Reply; 322005b261ecSmrg rep.length = 0; 322105b261ecSmrg rep.sequenceNumber = client->sequence; 322205b261ecSmrg rep.deviceID = dev->id; 322305b261ecSmrg rep.indicator= stuff->indicator; 322405b261ecSmrg if (map!=NULL) { 322505b261ecSmrg rep.found= True; 322605b261ecSmrg rep.on= ((sli->effectiveState&(1<<i))!=0); 322705b261ecSmrg rep.realIndicator= ((sli->physIndicators&(1<<i))!=0); 322805b261ecSmrg rep.ndx= i; 322905b261ecSmrg rep.flags= map->flags; 323005b261ecSmrg rep.whichGroups= map->which_groups; 323105b261ecSmrg rep.groups= map->groups; 323205b261ecSmrg rep.whichMods= map->which_mods; 323305b261ecSmrg rep.mods= map->mods.mask; 323405b261ecSmrg rep.realMods= map->mods.real_mods; 323505b261ecSmrg rep.virtualMods= map->mods.vmods; 323605b261ecSmrg rep.ctrls= map->ctrls; 323705b261ecSmrg rep.supported= True; 323805b261ecSmrg } 323905b261ecSmrg else { 324005b261ecSmrg rep.found= False; 324105b261ecSmrg rep.on= False; 324205b261ecSmrg rep.realIndicator= False; 324305b261ecSmrg rep.ndx= XkbNoIndicator; 324405b261ecSmrg rep.flags= 0; 324505b261ecSmrg rep.whichGroups= 0; 324605b261ecSmrg rep.groups= 0; 324705b261ecSmrg rep.whichMods= 0; 324805b261ecSmrg rep.mods= 0; 324905b261ecSmrg rep.realMods= 0; 325005b261ecSmrg rep.virtualMods= 0; 325105b261ecSmrg rep.ctrls= 0; 325205b261ecSmrg rep.supported= True; 325305b261ecSmrg } 325405b261ecSmrg if ( client->swapped ) { 325505b261ecSmrg register int n; 325605b261ecSmrg swapl(&rep.length,n); 325705b261ecSmrg swaps(&rep.sequenceNumber,n); 325805b261ecSmrg swapl(&rep.indicator,n); 325905b261ecSmrg swaps(&rep.virtualMods,n); 326005b261ecSmrg swapl(&rep.ctrls,n); 326105b261ecSmrg } 326205b261ecSmrg 326305b261ecSmrg WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep); 326405b261ecSmrg return client->noClientException; 326505b261ecSmrg} 326605b261ecSmrg 326705b261ecSmrg 32684642e01fSmrg/** 32694642e01fSmrg * Find the IM on the device. 32704642e01fSmrg * Returns the map, or NULL if the map doesn't exist. 32714642e01fSmrg * If the return value is NULL, led_return is undefined. Otherwise, led_return 32724642e01fSmrg * is set to the led index of the map. 32734642e01fSmrg */ 32744642e01fSmrgstatic XkbIndicatorMapPtr 32754642e01fSmrg_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, 32764642e01fSmrg int *led_return) 32774642e01fSmrg{ 32784642e01fSmrg XkbIndicatorMapPtr map; 32794642e01fSmrg int led; 328005b261ecSmrg 32814642e01fSmrg /* search for the right indicator */ 32824642e01fSmrg map = NULL; 328305b261ecSmrg if (sli->names && sli->maps) { 32844642e01fSmrg for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { 32854642e01fSmrg if (sli->names[led] == indicator) { 328605b261ecSmrg map= &sli->maps[led]; 328705b261ecSmrg break; 328805b261ecSmrg } 328905b261ecSmrg } 329005b261ecSmrg } 329105b261ecSmrg 32924642e01fSmrg *led_return = led; 32934642e01fSmrg return map; 32944642e01fSmrg} 32954642e01fSmrg 32964642e01fSmrg/** 32974642e01fSmrg * Creates an indicator map on the device. If dryRun is True, it only checks 32984642e01fSmrg * if creation is possible, but doesn't actually create it. 32994642e01fSmrg */ 33004642e01fSmrgstatic int 33014642e01fSmrg_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, 33024642e01fSmrg int ledClass, int ledID, 33034642e01fSmrg XkbIndicatorMapPtr *map_return, int *led_return, 33044642e01fSmrg Bool dryRun) 33054642e01fSmrg{ 33064642e01fSmrg XkbSrvLedInfoPtr sli; 33074642e01fSmrg XkbIndicatorMapPtr map; 33084642e01fSmrg int led; 33094642e01fSmrg 33104642e01fSmrg sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); 33114642e01fSmrg if (!sli) 33124642e01fSmrg return BadAlloc; 33134642e01fSmrg 33144642e01fSmrg map = _XkbFindNamedIndicatorMap(sli, indicator, &led); 33154642e01fSmrg 33164642e01fSmrg if (!map) 33174642e01fSmrg { 33184642e01fSmrg /* find first unused indicator maps and assign the name to it */ 33194642e01fSmrg for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) { 33204642e01fSmrg if ((sli->names) && (sli->maps) && (sli->names[led] == None) && 33214642e01fSmrg (!XkbIM_InUse(&sli->maps[led]))) 33224642e01fSmrg { 33234642e01fSmrg map = &sli->maps[led]; 33244642e01fSmrg if (!dryRun) 33254642e01fSmrg sli->names[led] = indicator; 33264642e01fSmrg break; 33274642e01fSmrg } 33284642e01fSmrg } 33294642e01fSmrg } 33304642e01fSmrg 33314642e01fSmrg if (!map) 33324642e01fSmrg return BadAlloc; 33334642e01fSmrg 33344642e01fSmrg *led_return = led; 33354642e01fSmrg *map_return = map; 33364642e01fSmrg return Success; 33374642e01fSmrg} 33384642e01fSmrg 33394642e01fSmrgstatic int 33404642e01fSmrg_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, 33414642e01fSmrg xkbSetNamedIndicatorReq *stuff) 33424642e01fSmrg{ 33434642e01fSmrg unsigned int extDevReason; 33444642e01fSmrg unsigned int statec, namec, mapc; 33454642e01fSmrg XkbSrvLedInfoPtr sli; 33464642e01fSmrg int led = 0; 33474642e01fSmrg XkbIndicatorMapPtr map; 33484642e01fSmrg DeviceIntPtr kbd; 33494642e01fSmrg XkbEventCauseRec cause; 33504642e01fSmrg xkbExtensionDeviceNotify ed; 33514642e01fSmrg XkbChangesRec changes; 33524642e01fSmrg int rc; 33534642e01fSmrg 33544642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, 33554642e01fSmrg stuff->ledID, &map, &led, FALSE); 33564642e01fSmrg if (rc != Success || !map) /* oh-oh */ 33574642e01fSmrg return rc; 33584642e01fSmrg 33594642e01fSmrg sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 33604642e01fSmrg XkbXI_IndicatorsMask); 33614642e01fSmrg if (!sli) 33624642e01fSmrg return BadAlloc; 33634642e01fSmrg 33644642e01fSmrg namec = mapc = statec = 0; 33654642e01fSmrg extDevReason = 0; 33664642e01fSmrg 33674642e01fSmrg namec |= (1<<led); 33684642e01fSmrg sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); 33694642e01fSmrg extDevReason |= XkbXI_IndicatorNamesMask; 33704642e01fSmrg 33714642e01fSmrg if (stuff->setMap) { 33724642e01fSmrg map->flags = stuff->flags; 33734642e01fSmrg map->which_groups = stuff->whichGroups; 33744642e01fSmrg map->groups = stuff->groups; 33754642e01fSmrg map->which_mods = stuff->whichMods; 33764642e01fSmrg map->mods.mask = stuff->realMods; 33774642e01fSmrg map->mods.real_mods = stuff->realMods; 33784642e01fSmrg map->mods.vmods= stuff->virtualMods; 33794642e01fSmrg map->ctrls = stuff->ctrls; 33804642e01fSmrg mapc|= (1<<led); 33814642e01fSmrg } 33824642e01fSmrg 33834642e01fSmrg if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) 33844642e01fSmrg { 33854642e01fSmrg if (stuff->on) sli->explicitState |= (1<<led); 33864642e01fSmrg else sli->explicitState &= ~(1<<led); 33874642e01fSmrg statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); 338805b261ecSmrg } 33894642e01fSmrg 339005b261ecSmrg bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 339105b261ecSmrg bzero((char *)&changes,sizeof(XkbChangesRec)); 339205b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client); 339305b261ecSmrg if (namec) 33944642e01fSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 339505b261ecSmrg if (mapc) 33964642e01fSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 339705b261ecSmrg if (statec) 33984642e01fSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 339905b261ecSmrg 34004642e01fSmrg kbd = dev; 340105b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 34024642e01fSmrg kbd = inputInfo.keyboard; 34034642e01fSmrg XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 34044642e01fSmrg 34054642e01fSmrg return Success; 34064642e01fSmrg} 34074642e01fSmrg 34084642e01fSmrgint 34094642e01fSmrgProcXkbSetNamedIndicator(ClientPtr client) 34104642e01fSmrg{ 34114642e01fSmrg int rc; 34124642e01fSmrg DeviceIntPtr dev; 34134642e01fSmrg int led = 0; 34144642e01fSmrg XkbIndicatorMapPtr map; 34154642e01fSmrg 34164642e01fSmrg REQUEST(xkbSetNamedIndicatorReq); 34174642e01fSmrg REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 34184642e01fSmrg 34194642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 34204642e01fSmrg return BadAccess; 34214642e01fSmrg 34224642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 34234642e01fSmrg CHK_ATOM_ONLY(stuff->indicator); 34244642e01fSmrg CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); 34254642e01fSmrg CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); 34264642e01fSmrg 34274642e01fSmrg /* Dry-run for checks */ 34284642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, 34294642e01fSmrg stuff->ledClass, stuff->ledID, 34304642e01fSmrg &map, &led, TRUE); 34314642e01fSmrg if (rc != Success || !map) /* couldn't be created or didn't exist */ 34324642e01fSmrg return rc; 34334642e01fSmrg 34344642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 34354642e01fSmrg stuff->deviceSpec == XkbUseCorePtr) 34364642e01fSmrg { 34374642e01fSmrg DeviceIntPtr other; 34384642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 34394642e01fSmrg { 34404642e01fSmrg if ((other != dev) && !other->isMaster && (other->u.master == dev) && 344152397711Smrg (other->kbdfeed || other->leds) && 34424642e01fSmrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 34434642e01fSmrg { 34444642e01fSmrg rc = _XkbCreateIndicatorMap(other, stuff->indicator, 34454642e01fSmrg stuff->ledClass, stuff->ledID, 34464642e01fSmrg &map, &led, TRUE); 34474642e01fSmrg if (rc != Success || !map) 34484642e01fSmrg return rc; 34494642e01fSmrg } 34504642e01fSmrg } 34514642e01fSmrg } 34524642e01fSmrg 34534642e01fSmrg /* All checks passed, let's do it */ 34544642e01fSmrg rc = _XkbSetNamedIndicator(client, dev, stuff); 34554642e01fSmrg if (rc != Success) 34564642e01fSmrg return rc; 34574642e01fSmrg 34584642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 34594642e01fSmrg stuff->deviceSpec == XkbUseCorePtr) 34604642e01fSmrg { 34614642e01fSmrg DeviceIntPtr other; 34624642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 34634642e01fSmrg { 34644642e01fSmrg if ((other != dev) && !other->isMaster && (other->u.master == dev) && 346552397711Smrg (other->kbdfeed || other->leds) && 34664642e01fSmrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 34674642e01fSmrg { 34684642e01fSmrg _XkbSetNamedIndicator(client, other, stuff); 34694642e01fSmrg } 34704642e01fSmrg } 34714642e01fSmrg } 34724642e01fSmrg 347305b261ecSmrg return client->noClientException; 347405b261ecSmrg} 347505b261ecSmrg 347605b261ecSmrg/***====================================================================***/ 347705b261ecSmrg 347805b261ecSmrgstatic CARD32 347905b261ecSmrg_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) 348005b261ecSmrg{ 348105b261ecSmrgregister unsigned int i,bit,nAtoms; 348205b261ecSmrgregister CARD32 atomsPresent; 348305b261ecSmrg 348405b261ecSmrg for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { 348505b261ecSmrg if (atoms[i]!=None) { 348605b261ecSmrg atomsPresent|= bit; 348705b261ecSmrg nAtoms++; 348805b261ecSmrg } 348905b261ecSmrg } 349005b261ecSmrg if (count) 349105b261ecSmrg *count= nAtoms; 349205b261ecSmrg return atomsPresent; 349305b261ecSmrg} 349405b261ecSmrg 349505b261ecSmrgstatic char * 349605b261ecSmrg_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap) 349705b261ecSmrg{ 349805b261ecSmrgregister unsigned int i; 349905b261ecSmrgAtom *atm; 350005b261ecSmrg 350105b261ecSmrg atm = (Atom *)wire; 350205b261ecSmrg for (i=0;i<maxAtoms;i++) { 350305b261ecSmrg if (atoms[i]!=None) { 350405b261ecSmrg *atm= atoms[i]; 350505b261ecSmrg if (swap) { 350605b261ecSmrg register int n; 350705b261ecSmrg swapl(atm,n); 350805b261ecSmrg } 350905b261ecSmrg atm++; 351005b261ecSmrg } 351105b261ecSmrg } 351205b261ecSmrg return (char *)atm; 351305b261ecSmrg} 351405b261ecSmrg 351505b261ecSmrgstatic Status 351605b261ecSmrgXkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep) 351705b261ecSmrg{ 351805b261ecSmrgregister unsigned which,length; 351905b261ecSmrgregister int i; 352005b261ecSmrg 352105b261ecSmrg rep->minKeyCode= xkb->min_key_code; 352205b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 352305b261ecSmrg which= rep->which; 352405b261ecSmrg length= 0; 352505b261ecSmrg if (xkb->names!=NULL) { 352605b261ecSmrg if (which&XkbKeycodesNameMask) length++; 352705b261ecSmrg if (which&XkbGeometryNameMask) length++; 352805b261ecSmrg if (which&XkbSymbolsNameMask) length++; 352905b261ecSmrg if (which&XkbPhysSymbolsNameMask) length++; 353005b261ecSmrg if (which&XkbTypesNameMask) length++; 353105b261ecSmrg if (which&XkbCompatNameMask) length++; 353205b261ecSmrg } 353305b261ecSmrg else which&= ~XkbComponentNamesMask; 353405b261ecSmrg 353505b261ecSmrg if (xkb->map!=NULL) { 353605b261ecSmrg if (which&XkbKeyTypeNamesMask) 353705b261ecSmrg length+= xkb->map->num_types; 353805b261ecSmrg rep->nTypes= xkb->map->num_types; 353905b261ecSmrg if (which&XkbKTLevelNamesMask) { 354005b261ecSmrg XkbKeyTypePtr pType = xkb->map->types; 354105b261ecSmrg int nKTLevels = 0; 354205b261ecSmrg 354305b261ecSmrg length+= XkbPaddedSize(xkb->map->num_types)/4; 354405b261ecSmrg for (i=0;i<xkb->map->num_types;i++,pType++) { 354505b261ecSmrg if (pType->level_names!=NULL) 354605b261ecSmrg nKTLevels+= pType->num_levels; 354705b261ecSmrg } 354805b261ecSmrg rep->nKTLevels= nKTLevels; 354905b261ecSmrg length+= nKTLevels; 355005b261ecSmrg } 355105b261ecSmrg } 355205b261ecSmrg else { 355305b261ecSmrg rep->nTypes= 0; 355405b261ecSmrg rep->nKTLevels= 0; 355505b261ecSmrg which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask); 355605b261ecSmrg } 355705b261ecSmrg 355805b261ecSmrg rep->minKeyCode= xkb->min_key_code; 355905b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 356005b261ecSmrg rep->indicators= 0; 356105b261ecSmrg rep->virtualMods= 0; 356205b261ecSmrg rep->groupNames= 0; 356305b261ecSmrg if (xkb->names!=NULL) { 356405b261ecSmrg if (which&XkbIndicatorNamesMask) { 356505b261ecSmrg int nLeds; 356605b261ecSmrg rep->indicators= 356705b261ecSmrg _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds); 356805b261ecSmrg length+= nLeds; 356905b261ecSmrg if (nLeds==0) 357005b261ecSmrg which&= ~XkbIndicatorNamesMask; 357105b261ecSmrg } 357205b261ecSmrg 357305b261ecSmrg if (which&XkbVirtualModNamesMask) { 357405b261ecSmrg int nVMods; 357505b261ecSmrg rep->virtualMods= 357605b261ecSmrg _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods); 357705b261ecSmrg length+= nVMods; 357805b261ecSmrg if (nVMods==0) 357905b261ecSmrg which&= ~XkbVirtualModNamesMask; 358005b261ecSmrg } 358105b261ecSmrg 358205b261ecSmrg if (which&XkbGroupNamesMask) { 358305b261ecSmrg int nGroups; 358405b261ecSmrg rep->groupNames= 358505b261ecSmrg _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups); 358605b261ecSmrg length+= nGroups; 358705b261ecSmrg if (nGroups==0) 358805b261ecSmrg which&= ~XkbGroupNamesMask; 358905b261ecSmrg } 359005b261ecSmrg 359105b261ecSmrg if ((which&XkbKeyNamesMask)&&(xkb->names->keys)) 359205b261ecSmrg length+= rep->nKeys; 359305b261ecSmrg else which&= ~XkbKeyNamesMask; 359405b261ecSmrg 359505b261ecSmrg if ((which&XkbKeyAliasesMask)&& 359605b261ecSmrg (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) { 359705b261ecSmrg rep->nKeyAliases= xkb->names->num_key_aliases; 359805b261ecSmrg length+= rep->nKeyAliases*2; 359905b261ecSmrg } 360005b261ecSmrg else { 360105b261ecSmrg which&= ~XkbKeyAliasesMask; 360205b261ecSmrg rep->nKeyAliases= 0; 360305b261ecSmrg } 360405b261ecSmrg 360505b261ecSmrg if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0)) 360605b261ecSmrg length+= xkb->names->num_rg; 360705b261ecSmrg else which&= ~XkbRGNamesMask; 360805b261ecSmrg } 360905b261ecSmrg else { 361005b261ecSmrg which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask); 361105b261ecSmrg which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask); 361205b261ecSmrg which&= ~XkbRGNamesMask; 361305b261ecSmrg } 361405b261ecSmrg 361505b261ecSmrg rep->length= length; 361605b261ecSmrg rep->which= which; 361705b261ecSmrg return Success; 361805b261ecSmrg} 361905b261ecSmrg 362005b261ecSmrgstatic int 362105b261ecSmrgXkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep) 362205b261ecSmrg{ 362305b261ecSmrgregister unsigned i,length,which; 362405b261ecSmrgchar * start; 362505b261ecSmrgchar * desc; 362605b261ecSmrgregister int n; 362705b261ecSmrg 362805b261ecSmrg length= rep->length*4; 362905b261ecSmrg which= rep->which; 363005b261ecSmrg if (client->swapped) { 363105b261ecSmrg swaps(&rep->sequenceNumber,n); 363205b261ecSmrg swapl(&rep->length,n); 363305b261ecSmrg swapl(&rep->which,n); 363405b261ecSmrg swaps(&rep->virtualMods,n); 363505b261ecSmrg swapl(&rep->indicators,n); 363605b261ecSmrg } 363705b261ecSmrg 36384642e01fSmrg start = desc = (char *)xalloc(length); 363905b261ecSmrg if ( !start ) 364005b261ecSmrg return BadAlloc; 364105b261ecSmrg if (xkb->names) { 364205b261ecSmrg if (which&XkbKeycodesNameMask) { 364305b261ecSmrg *((CARD32 *)desc)= xkb->names->keycodes; 364405b261ecSmrg if (client->swapped) { 364505b261ecSmrg swapl(desc,n); 364605b261ecSmrg } 364705b261ecSmrg desc+= 4; 364805b261ecSmrg } 364905b261ecSmrg if (which&XkbGeometryNameMask) { 365005b261ecSmrg *((CARD32 *)desc)= xkb->names->geometry; 365105b261ecSmrg if (client->swapped) { 365205b261ecSmrg swapl(desc,n); 365305b261ecSmrg } 365405b261ecSmrg desc+= 4; 365505b261ecSmrg } 365605b261ecSmrg if (which&XkbSymbolsNameMask) { 365705b261ecSmrg *((CARD32 *)desc)= xkb->names->symbols; 365805b261ecSmrg if (client->swapped) { 365905b261ecSmrg swapl(desc,n); 366005b261ecSmrg } 366105b261ecSmrg desc+= 4; 366205b261ecSmrg } 366305b261ecSmrg if (which&XkbPhysSymbolsNameMask) { 366405b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 366505b261ecSmrg atm[0]= (CARD32)xkb->names->phys_symbols; 366605b261ecSmrg if (client->swapped) { 366705b261ecSmrg swapl(&atm[0],n); 366805b261ecSmrg } 366905b261ecSmrg desc+= 4; 367005b261ecSmrg } 367105b261ecSmrg if (which&XkbTypesNameMask) { 367205b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->types; 367305b261ecSmrg if (client->swapped) { 367405b261ecSmrg swapl(desc,n); 367505b261ecSmrg } 367605b261ecSmrg desc+= 4; 367705b261ecSmrg } 367805b261ecSmrg if (which&XkbCompatNameMask) { 367905b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->compat; 368005b261ecSmrg if (client->swapped) { 368105b261ecSmrg swapl(desc,n); 368205b261ecSmrg } 368305b261ecSmrg desc+= 4; 368405b261ecSmrg } 368505b261ecSmrg if (which&XkbKeyTypeNamesMask) { 368605b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 368705b261ecSmrg register XkbKeyTypePtr type= xkb->map->types; 368805b261ecSmrg 368905b261ecSmrg for (i=0;i<xkb->map->num_types;i++,atm++,type++) { 369005b261ecSmrg *atm= (CARD32)type->name; 369105b261ecSmrg if (client->swapped) { 369205b261ecSmrg swapl(atm,n); 369305b261ecSmrg } 369405b261ecSmrg } 369505b261ecSmrg desc= (char *)atm; 369605b261ecSmrg } 369705b261ecSmrg if (which&XkbKTLevelNamesMask && xkb->map) { 369805b261ecSmrg XkbKeyTypePtr type = xkb->map->types; 369905b261ecSmrg register CARD32 *atm; 370005b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 370105b261ecSmrg *desc++ = type->num_levels; 370205b261ecSmrg } 370305b261ecSmrg desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes; 370405b261ecSmrg 370505b261ecSmrg atm= (CARD32 *)desc; 370605b261ecSmrg type = xkb->map->types; 370705b261ecSmrg for (i=0;i<xkb->map->num_types;i++,type++) { 370805b261ecSmrg register unsigned l; 370905b261ecSmrg if (type->level_names) { 371005b261ecSmrg for (l=0;l<type->num_levels;l++,atm++) { 371105b261ecSmrg *atm= type->level_names[l]; 371205b261ecSmrg if (client->swapped) { 371305b261ecSmrg swapl(atm,n); 371405b261ecSmrg } 371505b261ecSmrg } 371605b261ecSmrg desc+= type->num_levels*4; 371705b261ecSmrg } 371805b261ecSmrg } 371905b261ecSmrg } 372005b261ecSmrg if (which&XkbIndicatorNamesMask) { 372105b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators, 372205b261ecSmrg client->swapped); 372305b261ecSmrg } 372405b261ecSmrg if (which&XkbVirtualModNamesMask) { 372505b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods, 372605b261ecSmrg client->swapped); 372705b261ecSmrg } 372805b261ecSmrg if (which&XkbGroupNamesMask) { 372905b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups, 373005b261ecSmrg client->swapped); 373105b261ecSmrg } 373205b261ecSmrg if (which&XkbKeyNamesMask) { 373305b261ecSmrg for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) { 373405b261ecSmrg *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey]; 373505b261ecSmrg } 373605b261ecSmrg } 373705b261ecSmrg if (which&XkbKeyAliasesMask) { 373805b261ecSmrg XkbKeyAliasPtr pAl; 373905b261ecSmrg pAl= xkb->names->key_aliases; 374005b261ecSmrg for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) { 374105b261ecSmrg *((XkbKeyAliasPtr)desc)= *pAl; 374205b261ecSmrg } 374305b261ecSmrg } 374405b261ecSmrg if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) { 374505b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 374605b261ecSmrg for (i=0;i<rep->nRadioGroups;i++,atm++) { 374705b261ecSmrg *atm= (CARD32)xkb->names->radio_groups[i]; 374805b261ecSmrg if (client->swapped) { 374905b261ecSmrg swapl(atm,n); 375005b261ecSmrg } 375105b261ecSmrg } 375205b261ecSmrg desc+= rep->nRadioGroups*4; 375305b261ecSmrg } 375405b261ecSmrg } 375505b261ecSmrg 375605b261ecSmrg if ((desc-start)!=(length)) { 37574642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 375805b261ecSmrg length, (unsigned long)(desc-start)); 375905b261ecSmrg } 376005b261ecSmrg WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep); 376105b261ecSmrg WriteToClient(client, length, start); 37624642e01fSmrg xfree((char *)start); 376305b261ecSmrg return client->noClientException; 376405b261ecSmrg} 376505b261ecSmrg 376605b261ecSmrgint 376705b261ecSmrgProcXkbGetNames(ClientPtr client) 376805b261ecSmrg{ 376905b261ecSmrg DeviceIntPtr dev; 377005b261ecSmrg XkbDescPtr xkb; 377105b261ecSmrg xkbGetNamesReply rep; 377205b261ecSmrg 377305b261ecSmrg REQUEST(xkbGetNamesReq); 377405b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamesReq); 377505b261ecSmrg 377605b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 377705b261ecSmrg return BadAccess; 377805b261ecSmrg 37794642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 378005b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 378105b261ecSmrg 378205b261ecSmrg xkb = dev->key->xkbInfo->desc; 378305b261ecSmrg rep.type= X_Reply; 378405b261ecSmrg rep.sequenceNumber= client->sequence; 378505b261ecSmrg rep.length = 0; 378605b261ecSmrg rep.deviceID = dev->id; 378705b261ecSmrg rep.which = stuff->which; 378805b261ecSmrg rep.nTypes = xkb->map->num_types; 378905b261ecSmrg rep.firstKey = xkb->min_key_code; 379005b261ecSmrg rep.nKeys = XkbNumKeys(xkb); 379105b261ecSmrg if (xkb->names!=NULL) { 379205b261ecSmrg rep.nKeyAliases= xkb->names->num_key_aliases; 379305b261ecSmrg rep.nRadioGroups = xkb->names->num_rg; 379405b261ecSmrg } 379505b261ecSmrg else { 379605b261ecSmrg rep.nKeyAliases= rep.nRadioGroups= 0; 379705b261ecSmrg } 379805b261ecSmrg XkbComputeGetNamesReplySize(xkb,&rep); 379905b261ecSmrg return XkbSendNames(client,xkb,&rep); 380005b261ecSmrg} 380105b261ecSmrg 380205b261ecSmrg/***====================================================================***/ 380305b261ecSmrg 380405b261ecSmrgstatic CARD32 * 380505b261ecSmrg_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError) 380605b261ecSmrg{ 380705b261ecSmrgregister int i; 380805b261ecSmrg 380905b261ecSmrg for (i=0;i<nAtoms;i++,wire++) { 381005b261ecSmrg if (swapped) { 381105b261ecSmrg register int n; 381205b261ecSmrg swapl(wire,n); 381305b261ecSmrg } 381405b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) { 381505b261ecSmrg *pError= ((Atom)*wire); 381605b261ecSmrg return NULL; 381705b261ecSmrg } 381805b261ecSmrg } 381905b261ecSmrg return wire; 382005b261ecSmrg} 382105b261ecSmrg 382205b261ecSmrgstatic CARD32 * 382305b261ecSmrg_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped, 382405b261ecSmrg Atom *pError) 382505b261ecSmrg{ 382605b261ecSmrgregister unsigned i,bit; 382705b261ecSmrg 382805b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 382905b261ecSmrg if ((present&bit)==0) 383005b261ecSmrg continue; 383105b261ecSmrg if (swapped) { 383205b261ecSmrg register int n; 383305b261ecSmrg swapl(wire,n); 383405b261ecSmrg } 383505b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) { 383605b261ecSmrg *pError= (Atom)*wire; 383705b261ecSmrg return NULL; 383805b261ecSmrg } 383905b261ecSmrg wire++; 384005b261ecSmrg } 384105b261ecSmrg return wire; 384205b261ecSmrg} 384305b261ecSmrg 384405b261ecSmrgstatic Atom * 384505b261ecSmrg_XkbCopyMaskedAtoms( Atom *wire, 384605b261ecSmrg Atom *dest, 384705b261ecSmrg int nAtoms, 384805b261ecSmrg CARD32 present) 384905b261ecSmrg{ 385005b261ecSmrgregister int i,bit; 385105b261ecSmrg 385205b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 385305b261ecSmrg if ((present&bit)==0) 385405b261ecSmrg continue; 385505b261ecSmrg dest[i]= *wire++; 385605b261ecSmrg } 385705b261ecSmrg return wire; 385805b261ecSmrg} 385905b261ecSmrg 386005b261ecSmrgstatic Bool 386105b261ecSmrg_XkbCheckTypeName(Atom name,int typeNdx) 386205b261ecSmrg{ 386305b261ecSmrgchar * str; 386405b261ecSmrg 386505b261ecSmrg str= NameForAtom(name); 386605b261ecSmrg if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)|| 386705b261ecSmrg (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0)) 386805b261ecSmrg return False; 386905b261ecSmrg return True; 387005b261ecSmrg} 387105b261ecSmrg 38724642e01fSmrg/** 38734642e01fSmrg * Check the device-dependent data in the request against the device. Returns 38744642e01fSmrg * Success, or the appropriate error code. 38754642e01fSmrg */ 38764642e01fSmrgstatic int 38774642e01fSmrg_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 38784642e01fSmrg xkbSetNamesReq *stuff, CARD32 *data) 387905b261ecSmrg{ 388005b261ecSmrg XkbDescRec *xkb; 388105b261ecSmrg XkbNamesRec *names; 388205b261ecSmrg CARD32 *tmp; 388305b261ecSmrg Atom bad; 388405b261ecSmrg 38854642e01fSmrg tmp = data; 38864642e01fSmrg xkb = dev->key->xkbInfo->desc; 38874642e01fSmrg names = xkb->names; 38884642e01fSmrg 38894642e01fSmrg 38904642e01fSmrg if (stuff->which & XkbKeyTypeNamesMask) { 38914642e01fSmrg int i; 38924642e01fSmrg CARD32 *old; 38934642e01fSmrg if ( stuff->nTypes<1 ) { 38944642e01fSmrg client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); 38954642e01fSmrg return BadValue; 38964642e01fSmrg } 38974642e01fSmrg if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { 38984642e01fSmrg client->errorValue = _XkbErrCode4(0x03,stuff->firstType, 38994642e01fSmrg stuff->nTypes, 39004642e01fSmrg xkb->map->num_types); 39014642e01fSmrg return BadValue; 39024642e01fSmrg } 39034642e01fSmrg if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { 39044642e01fSmrg client->errorValue = _XkbErrCode2(0x04,stuff->firstType); 39054642e01fSmrg return BadAccess; 39064642e01fSmrg } 39074642e01fSmrg old= tmp; 39084642e01fSmrg tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); 39094642e01fSmrg if (!tmp) { 39104642e01fSmrg client->errorValue= bad; 39114642e01fSmrg return BadAtom; 39124642e01fSmrg } 39134642e01fSmrg for (i=0;i<stuff->nTypes;i++,old++) { 39144642e01fSmrg if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) 39154642e01fSmrg client->errorValue= _XkbErrCode2(0x05,i); 39164642e01fSmrg } 39174642e01fSmrg } 39184642e01fSmrg if (stuff->which&XkbKTLevelNamesMask) { 39194642e01fSmrg unsigned i; 39204642e01fSmrg XkbKeyTypePtr type; 39214642e01fSmrg CARD8 * width; 39224642e01fSmrg if ( stuff->nKTLevels<1 ) { 39234642e01fSmrg client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); 39244642e01fSmrg return BadValue; 39254642e01fSmrg } 39264642e01fSmrg if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= 39274642e01fSmrg xkb->map->num_types) { 39284642e01fSmrg client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, 39294642e01fSmrg stuff->nKTLevels,xkb->map->num_types); 39304642e01fSmrg return BadValue; 39314642e01fSmrg } 39324642e01fSmrg width = (CARD8 *)tmp; 39334642e01fSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 39344642e01fSmrg type = &xkb->map->types[stuff->firstKTLevel]; 39354642e01fSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 39364642e01fSmrg if (width[i]==0) 39374642e01fSmrg continue; 39384642e01fSmrg else if (width[i]!=type->num_levels) { 39394642e01fSmrg client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, 39404642e01fSmrg type->num_levels,width[i]); 39414642e01fSmrg return BadMatch; 39424642e01fSmrg } 39434642e01fSmrg tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); 39444642e01fSmrg if (!tmp) { 39454642e01fSmrg client->errorValue= bad; 39464642e01fSmrg return BadAtom; 39474642e01fSmrg } 39484642e01fSmrg } 39494642e01fSmrg } 39504642e01fSmrg if (stuff->which&XkbIndicatorNamesMask) { 39514642e01fSmrg if (stuff->indicators==0) { 39524642e01fSmrg client->errorValue= 0x08; 39534642e01fSmrg return BadMatch; 39544642e01fSmrg } 39554642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, 39564642e01fSmrg client->swapped,&bad); 39574642e01fSmrg if (!tmp) { 39584642e01fSmrg client->errorValue= bad; 39594642e01fSmrg return BadAtom; 39604642e01fSmrg } 39614642e01fSmrg } 39624642e01fSmrg if (stuff->which&XkbVirtualModNamesMask) { 39634642e01fSmrg if (stuff->virtualMods==0) { 39644642e01fSmrg client->errorValue= 0x09; 39654642e01fSmrg return BadMatch; 39664642e01fSmrg } 39674642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, 39684642e01fSmrg (CARD32)stuff->virtualMods, 39694642e01fSmrg client->swapped,&bad); 39704642e01fSmrg if (!tmp) { 39714642e01fSmrg client->errorValue = bad; 39724642e01fSmrg return BadAtom; 39734642e01fSmrg } 39744642e01fSmrg } 39754642e01fSmrg if (stuff->which&XkbGroupNamesMask) { 39764642e01fSmrg if (stuff->groupNames==0) { 39774642e01fSmrg client->errorValue= 0x0a; 39784642e01fSmrg return BadMatch; 39794642e01fSmrg } 39804642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, 39814642e01fSmrg (CARD32)stuff->groupNames, 39824642e01fSmrg client->swapped,&bad); 39834642e01fSmrg if (!tmp) { 39844642e01fSmrg client->errorValue = bad; 39854642e01fSmrg return BadAtom; 39864642e01fSmrg } 39874642e01fSmrg } 39884642e01fSmrg if (stuff->which&XkbKeyNamesMask) { 39894642e01fSmrg if (stuff->firstKey<(unsigned)xkb->min_key_code) { 39904642e01fSmrg client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, 39914642e01fSmrg stuff->firstKey); 39924642e01fSmrg return BadValue; 39934642e01fSmrg } 39944642e01fSmrg if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| 39954642e01fSmrg (stuff->nKeys<1)) { 39964642e01fSmrg client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, 39974642e01fSmrg stuff->firstKey,stuff->nKeys); 39984642e01fSmrg return BadValue; 39994642e01fSmrg } 40004642e01fSmrg tmp+= stuff->nKeys; 40014642e01fSmrg } 40024642e01fSmrg if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { 40034642e01fSmrg tmp+= stuff->nKeyAliases*2; 40044642e01fSmrg } 40054642e01fSmrg if (stuff->which&XkbRGNamesMask) { 40064642e01fSmrg if ( stuff->nRadioGroups<1 ) { 40074642e01fSmrg client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); 40084642e01fSmrg return BadValue; 40094642e01fSmrg } 40104642e01fSmrg tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); 40114642e01fSmrg if (!tmp) { 40124642e01fSmrg client->errorValue= bad; 40134642e01fSmrg return BadAtom; 40144642e01fSmrg } 40154642e01fSmrg } 40164642e01fSmrg if ((tmp-((CARD32 *)stuff))!=stuff->length) { 40174642e01fSmrg client->errorValue = stuff->length; 40184642e01fSmrg return BadLength; 40194642e01fSmrg } 40204642e01fSmrg 40214642e01fSmrg 40224642e01fSmrg 40234642e01fSmrg return Success; 40244642e01fSmrg} 40254642e01fSmrg 40264642e01fSmrgstatic int 40274642e01fSmrg_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) 40284642e01fSmrg{ 40294642e01fSmrg XkbDescRec *xkb; 40304642e01fSmrg XkbNamesRec *names; 40314642e01fSmrg CARD32 *tmp; 40324642e01fSmrg xkbNamesNotify nn; 40334642e01fSmrg 40344642e01fSmrg tmp = (CARD32 *)&stuff[1]; 40354642e01fSmrg xkb = dev->key->xkbInfo->desc; 40364642e01fSmrg names = xkb->names; 40374642e01fSmrg 40384642e01fSmrg if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, 40394642e01fSmrg stuff->nKeyAliases)!=Success) { 40404642e01fSmrg return BadAlloc; 40414642e01fSmrg } 40424642e01fSmrg 40434642e01fSmrg bzero(&nn,sizeof(xkbNamesNotify)); 40444642e01fSmrg nn.changed= stuff->which; 40454642e01fSmrg tmp = (CARD32 *)&stuff[1]; 40464642e01fSmrg if (stuff->which&XkbKeycodesNameMask) 40474642e01fSmrg names->keycodes= *tmp++; 40484642e01fSmrg if (stuff->which&XkbGeometryNameMask) 40494642e01fSmrg names->geometry= *tmp++; 40504642e01fSmrg if (stuff->which&XkbSymbolsNameMask) 40514642e01fSmrg names->symbols= *tmp++; 40524642e01fSmrg if (stuff->which&XkbPhysSymbolsNameMask) 40534642e01fSmrg names->phys_symbols= *tmp++; 40544642e01fSmrg if (stuff->which&XkbTypesNameMask) 40554642e01fSmrg names->types= *tmp++; 40564642e01fSmrg if (stuff->which&XkbCompatNameMask) 40574642e01fSmrg names->compat= *tmp++; 40584642e01fSmrg if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { 40594642e01fSmrg register unsigned i; 40604642e01fSmrg register XkbKeyTypePtr type; 40614642e01fSmrg 40624642e01fSmrg type= &xkb->map->types[stuff->firstType]; 40634642e01fSmrg for (i=0;i<stuff->nTypes;i++,type++) { 40644642e01fSmrg type->name= *tmp++; 40654642e01fSmrg } 40664642e01fSmrg nn.firstType= stuff->firstType; 40674642e01fSmrg nn.nTypes= stuff->nTypes; 40684642e01fSmrg } 40694642e01fSmrg if (stuff->which&XkbKTLevelNamesMask) { 40704642e01fSmrg register XkbKeyTypePtr type; 40714642e01fSmrg register unsigned i; 40724642e01fSmrg CARD8 *width; 40734642e01fSmrg 40744642e01fSmrg width = (CARD8 *)tmp; 40754642e01fSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 40764642e01fSmrg type= &xkb->map->types[stuff->firstKTLevel]; 40774642e01fSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 40784642e01fSmrg if (width[i]>0) { 40794642e01fSmrg if (type->level_names) { 40804642e01fSmrg register unsigned n; 40814642e01fSmrg for (n=0;n<width[i];n++) { 40824642e01fSmrg type->level_names[n]= tmp[n]; 40834642e01fSmrg } 40844642e01fSmrg } 40854642e01fSmrg tmp+= width[i]; 40864642e01fSmrg } 40874642e01fSmrg } 40884642e01fSmrg nn.firstLevelName= 0; 40894642e01fSmrg nn.nLevelNames= stuff->nTypes; 40904642e01fSmrg } 40914642e01fSmrg if (stuff->which&XkbIndicatorNamesMask) { 40924642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, 40934642e01fSmrg stuff->indicators); 40944642e01fSmrg nn.changedIndicators= stuff->indicators; 40954642e01fSmrg } 40964642e01fSmrg if (stuff->which&XkbVirtualModNamesMask) { 40974642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, 40984642e01fSmrg stuff->virtualMods); 40994642e01fSmrg nn.changedVirtualMods= stuff->virtualMods; 41004642e01fSmrg } 41014642e01fSmrg if (stuff->which&XkbGroupNamesMask) { 41024642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, 41034642e01fSmrg stuff->groupNames); 41044642e01fSmrg nn.changedVirtualMods= stuff->groupNames; 41054642e01fSmrg } 41064642e01fSmrg if (stuff->which&XkbKeyNamesMask) { 41074642e01fSmrg memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, 41084642e01fSmrg stuff->nKeys*XkbKeyNameLength); 41094642e01fSmrg tmp+= stuff->nKeys; 41104642e01fSmrg nn.firstKey= stuff->firstKey; 41114642e01fSmrg nn.nKeys= stuff->nKeys; 41124642e01fSmrg } 41134642e01fSmrg if (stuff->which&XkbKeyAliasesMask) { 41144642e01fSmrg if (stuff->nKeyAliases>0) { 41154642e01fSmrg register int na= stuff->nKeyAliases; 41164642e01fSmrg if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) 41174642e01fSmrg return BadAlloc; 41184642e01fSmrg memcpy((char *)names->key_aliases,(char *)tmp, 41194642e01fSmrg stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); 41204642e01fSmrg tmp+= stuff->nKeyAliases*2; 41214642e01fSmrg } 41224642e01fSmrg else if (names->key_aliases!=NULL) { 41234642e01fSmrg _XkbFree(names->key_aliases); 41244642e01fSmrg names->key_aliases= NULL; 41254642e01fSmrg names->num_key_aliases= 0; 41264642e01fSmrg } 41274642e01fSmrg nn.nAliases= names->num_key_aliases; 41284642e01fSmrg } 41294642e01fSmrg if (stuff->which&XkbRGNamesMask) { 41304642e01fSmrg if (stuff->nRadioGroups>0) { 41314642e01fSmrg register unsigned i,nrg; 41324642e01fSmrg nrg= stuff->nRadioGroups; 41334642e01fSmrg if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) 41344642e01fSmrg return BadAlloc; 41354642e01fSmrg 41364642e01fSmrg for (i=0;i<stuff->nRadioGroups;i++) { 41374642e01fSmrg names->radio_groups[i]= tmp[i]; 41384642e01fSmrg } 41394642e01fSmrg tmp+= stuff->nRadioGroups; 41404642e01fSmrg } 41414642e01fSmrg else if (names->radio_groups) { 41424642e01fSmrg _XkbFree(names->radio_groups); 41434642e01fSmrg names->radio_groups= NULL; 41444642e01fSmrg names->num_rg= 0; 41454642e01fSmrg } 41464642e01fSmrg nn.nRadioGroups= names->num_rg; 41474642e01fSmrg } 41484642e01fSmrg if (nn.changed) { 41494642e01fSmrg Bool needExtEvent; 41504642e01fSmrg needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; 41514642e01fSmrg XkbSendNamesNotify(dev,&nn); 41524642e01fSmrg if (needExtEvent) { 41534642e01fSmrg XkbSrvLedInfoPtr sli; 41544642e01fSmrg xkbExtensionDeviceNotify edev; 41554642e01fSmrg register int i; 41564642e01fSmrg register unsigned bit; 41574642e01fSmrg 41584642e01fSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 41594642e01fSmrg XkbXI_IndicatorsMask); 41604642e01fSmrg sli->namesPresent= 0; 41614642e01fSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 41624642e01fSmrg if (names->indicators[i]!=None) 41634642e01fSmrg sli->namesPresent|= bit; 41644642e01fSmrg } 41654642e01fSmrg bzero(&edev,sizeof(xkbExtensionDeviceNotify)); 41664642e01fSmrg edev.reason= XkbXI_IndicatorNamesMask; 41674642e01fSmrg edev.ledClass= KbdFeedbackClass; 41684642e01fSmrg edev.ledID= dev->kbdfeed->ctrl.id; 41694642e01fSmrg edev.ledsDefined= sli->namesPresent|sli->mapsPresent; 41704642e01fSmrg edev.ledState= sli->effectiveState; 41714642e01fSmrg edev.firstBtn= 0; 41724642e01fSmrg edev.nBtns= 0; 41734642e01fSmrg edev.supported= XkbXI_AllFeaturesMask; 41744642e01fSmrg edev.unsupported= 0; 41754642e01fSmrg XkbSendExtensionDeviceNotify(dev,client,&edev); 41764642e01fSmrg } 41774642e01fSmrg } 41784642e01fSmrg return Success; 41794642e01fSmrg} 41804642e01fSmrg 41814642e01fSmrgint 41824642e01fSmrgProcXkbSetNames(ClientPtr client) 41834642e01fSmrg{ 41844642e01fSmrg DeviceIntPtr dev; 41854642e01fSmrg CARD32 *tmp; 41864642e01fSmrg Atom bad; 41874642e01fSmrg int rc; 41884642e01fSmrg 418905b261ecSmrg REQUEST(xkbSetNamesReq); 419005b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 419105b261ecSmrg 419205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 419305b261ecSmrg return BadAccess; 419405b261ecSmrg 41954642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 419605b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 419705b261ecSmrg 41984642e01fSmrg /* check device-independent stuff */ 419905b261ecSmrg tmp = (CARD32 *)&stuff[1]; 420005b261ecSmrg 420105b261ecSmrg if (stuff->which&XkbKeycodesNameMask) { 420205b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 420305b261ecSmrg if (!tmp) { 420405b261ecSmrg client->errorValue = bad; 420505b261ecSmrg return BadAtom; 420605b261ecSmrg } 420705b261ecSmrg } 420805b261ecSmrg if (stuff->which&XkbGeometryNameMask) { 420905b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 421005b261ecSmrg if (!tmp) { 421105b261ecSmrg client->errorValue = bad; 421205b261ecSmrg return BadAtom; 421305b261ecSmrg } 421405b261ecSmrg } 421505b261ecSmrg if (stuff->which&XkbSymbolsNameMask) { 421605b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 421705b261ecSmrg if (!tmp) { 421805b261ecSmrg client->errorValue = bad; 421905b261ecSmrg return BadAtom; 422005b261ecSmrg } 422105b261ecSmrg } 422205b261ecSmrg if (stuff->which&XkbPhysSymbolsNameMask) { 422305b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 422405b261ecSmrg if (!tmp) { 422505b261ecSmrg client->errorValue= bad; 422605b261ecSmrg return BadAtom; 422705b261ecSmrg } 422805b261ecSmrg } 422905b261ecSmrg if (stuff->which&XkbTypesNameMask) { 423005b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 423105b261ecSmrg if (!tmp) { 423205b261ecSmrg client->errorValue = bad; 423305b261ecSmrg return BadAtom; 423405b261ecSmrg } 423505b261ecSmrg } 423605b261ecSmrg if (stuff->which&XkbCompatNameMask) { 423705b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 423805b261ecSmrg if (!tmp) { 423905b261ecSmrg client->errorValue = bad; 424005b261ecSmrg return BadAtom; 424105b261ecSmrg } 424205b261ecSmrg } 42434642e01fSmrg 42444642e01fSmrg /* start of device-dependent tests */ 42454642e01fSmrg rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 42464642e01fSmrg if (rc != Success) 42474642e01fSmrg return rc; 42484642e01fSmrg 42494642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 42504642e01fSmrg { 42514642e01fSmrg DeviceIntPtr other; 42524642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 42534642e01fSmrg { 42544642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 42554642e01fSmrg { 42564642e01fSmrg 42574642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 42584642e01fSmrg if (rc == Success) 42594642e01fSmrg { 42604642e01fSmrg rc = _XkbSetNamesCheck(client, other, stuff, tmp); 42614642e01fSmrg if (rc != Success) 42624642e01fSmrg return rc; 42634642e01fSmrg } 42644642e01fSmrg } 42654642e01fSmrg } 426605b261ecSmrg } 426705b261ecSmrg 426805b261ecSmrg /* everything is okay -- update names */ 426905b261ecSmrg 42704642e01fSmrg rc = _XkbSetNames(client, dev, stuff); 42714642e01fSmrg if (rc != Success) 42724642e01fSmrg return rc; 427305b261ecSmrg 42744642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 42754642e01fSmrg { 42764642e01fSmrg DeviceIntPtr other; 42774642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 42784642e01fSmrg { 42794642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 42804642e01fSmrg { 42814642e01fSmrg 42824642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 42834642e01fSmrg if (rc == Success) 42844642e01fSmrg _XkbSetNames(client, other, stuff); 42854642e01fSmrg } 42864642e01fSmrg } 428705b261ecSmrg } 42884642e01fSmrg 42894642e01fSmrg /* everything is okay -- update names */ 42904642e01fSmrg 429105b261ecSmrg return client->noClientException; 429205b261ecSmrg} 429305b261ecSmrg 429405b261ecSmrg/***====================================================================***/ 429505b261ecSmrg 42964642e01fSmrg#include "xkbgeom.h" 429705b261ecSmrg 429805b261ecSmrg#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 429905b261ecSmrg 430005b261ecSmrgstatic char * 430105b261ecSmrgXkbWriteCountedString(char *wire,char *str,Bool swap) 430205b261ecSmrg{ 430305b261ecSmrgCARD16 len,*pLen; 430405b261ecSmrg 430505b261ecSmrg len= (str?strlen(str):0); 430605b261ecSmrg pLen= (CARD16 *)wire; 430705b261ecSmrg *pLen= len; 430805b261ecSmrg if (swap) { 430905b261ecSmrg register int n; 431005b261ecSmrg swaps(pLen,n); 431105b261ecSmrg } 431205b261ecSmrg memcpy(&wire[2],str,len); 431305b261ecSmrg wire+= ((2+len+3)/4)*4; 431405b261ecSmrg return wire; 431505b261ecSmrg} 431605b261ecSmrg 431705b261ecSmrgstatic int 431805b261ecSmrgXkbSizeGeomProperties(XkbGeometryPtr geom) 431905b261ecSmrg{ 432005b261ecSmrgregister int i,size; 432105b261ecSmrgXkbPropertyPtr prop; 432205b261ecSmrg 432305b261ecSmrg for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 432405b261ecSmrg size+= XkbSizeCountedString(prop->name); 432505b261ecSmrg size+= XkbSizeCountedString(prop->value); 432605b261ecSmrg } 432705b261ecSmrg return size; 432805b261ecSmrg} 432905b261ecSmrg 433005b261ecSmrgstatic char * 433105b261ecSmrgXkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap) 433205b261ecSmrg{ 433305b261ecSmrgregister int i; 433405b261ecSmrgregister XkbPropertyPtr prop; 433505b261ecSmrg 433605b261ecSmrg for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 433705b261ecSmrg wire= XkbWriteCountedString(wire,prop->name,swap); 433805b261ecSmrg wire= XkbWriteCountedString(wire,prop->value,swap); 433905b261ecSmrg } 434005b261ecSmrg return wire; 434105b261ecSmrg} 434205b261ecSmrg 434305b261ecSmrgstatic int 434405b261ecSmrgXkbSizeGeomKeyAliases(XkbGeometryPtr geom) 434505b261ecSmrg{ 434605b261ecSmrg return geom->num_key_aliases*(2*XkbKeyNameLength); 434705b261ecSmrg} 434805b261ecSmrg 434905b261ecSmrgstatic char * 435005b261ecSmrgXkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap) 435105b261ecSmrg{ 435205b261ecSmrgregister int sz; 435305b261ecSmrg 435405b261ecSmrg sz= geom->num_key_aliases*(XkbKeyNameLength*2); 435505b261ecSmrg if (sz>0) { 435605b261ecSmrg memcpy(wire,(char *)geom->key_aliases,sz); 435705b261ecSmrg wire+= sz; 435805b261ecSmrg } 435905b261ecSmrg return wire; 436005b261ecSmrg} 436105b261ecSmrg 436205b261ecSmrgstatic int 436305b261ecSmrgXkbSizeGeomColors(XkbGeometryPtr geom) 436405b261ecSmrg{ 436505b261ecSmrgregister int i,size; 436605b261ecSmrgregister XkbColorPtr color; 436705b261ecSmrg 436805b261ecSmrg for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { 436905b261ecSmrg size+= XkbSizeCountedString(color->spec); 437005b261ecSmrg } 437105b261ecSmrg return size; 437205b261ecSmrg} 437305b261ecSmrg 437405b261ecSmrgstatic char * 437505b261ecSmrgXkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap) 437605b261ecSmrg{ 437705b261ecSmrgregister int i; 437805b261ecSmrgregister XkbColorPtr color; 437905b261ecSmrg 438005b261ecSmrg for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 438105b261ecSmrg wire= XkbWriteCountedString(wire,color->spec,swap); 438205b261ecSmrg } 438305b261ecSmrg return wire; 438405b261ecSmrg} 438505b261ecSmrg 438605b261ecSmrgstatic int 438705b261ecSmrgXkbSizeGeomShapes(XkbGeometryPtr geom) 438805b261ecSmrg{ 438905b261ecSmrgregister int i,size; 439005b261ecSmrgregister XkbShapePtr shape; 439105b261ecSmrg 439205b261ecSmrg for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 439305b261ecSmrg register int n; 439405b261ecSmrg register XkbOutlinePtr ol; 439505b261ecSmrg size+= SIZEOF(xkbShapeWireDesc); 439605b261ecSmrg for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 439705b261ecSmrg size+= SIZEOF(xkbOutlineWireDesc); 439805b261ecSmrg size+= ol->num_points*SIZEOF(xkbPointWireDesc); 439905b261ecSmrg } 440005b261ecSmrg } 440105b261ecSmrg return size; 440205b261ecSmrg} 440305b261ecSmrg 440405b261ecSmrgstatic char * 440505b261ecSmrgXkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap) 440605b261ecSmrg{ 440705b261ecSmrgint i; 440805b261ecSmrgXkbShapePtr shape; 440905b261ecSmrgxkbShapeWireDesc * shapeWire; 441005b261ecSmrg 441105b261ecSmrg for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 441205b261ecSmrg register int o; 441305b261ecSmrg XkbOutlinePtr ol; 441405b261ecSmrg xkbOutlineWireDesc * olWire; 441505b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 441605b261ecSmrg shapeWire->name= shape->name; 441705b261ecSmrg shapeWire->nOutlines= shape->num_outlines; 441805b261ecSmrg if (shape->primary!=NULL) 441905b261ecSmrg shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); 442005b261ecSmrg else shapeWire->primaryNdx= XkbNoShape; 442105b261ecSmrg if (shape->approx!=NULL) 442205b261ecSmrg shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); 442305b261ecSmrg else shapeWire->approxNdx= XkbNoShape; 442405b261ecSmrg if (swap) { 442505b261ecSmrg register int n; 442605b261ecSmrg swapl(&shapeWire->name,n); 442705b261ecSmrg } 442805b261ecSmrg wire= (char *)&shapeWire[1]; 442905b261ecSmrg for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 443005b261ecSmrg register int p; 443105b261ecSmrg XkbPointPtr pt; 443205b261ecSmrg xkbPointWireDesc * ptWire; 443305b261ecSmrg olWire= (xkbOutlineWireDesc *)wire; 443405b261ecSmrg olWire->nPoints= ol->num_points; 443505b261ecSmrg olWire->cornerRadius= ol->corner_radius; 443605b261ecSmrg wire= (char *)&olWire[1]; 443705b261ecSmrg ptWire= (xkbPointWireDesc *)wire; 443805b261ecSmrg for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 443905b261ecSmrg ptWire[p].x= pt->x; 444005b261ecSmrg ptWire[p].y= pt->y; 444105b261ecSmrg if (swap) { 444205b261ecSmrg register int n; 444305b261ecSmrg swaps(&ptWire[p].x,n); 444405b261ecSmrg swaps(&ptWire[p].y,n); 444505b261ecSmrg } 444605b261ecSmrg } 444705b261ecSmrg wire= (char *)&ptWire[ol->num_points]; 444805b261ecSmrg } 444905b261ecSmrg } 445005b261ecSmrg return wire; 445105b261ecSmrg} 445205b261ecSmrg 445305b261ecSmrgstatic int 445405b261ecSmrgXkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) 445505b261ecSmrg{ 445605b261ecSmrgregister int i,size; 445705b261ecSmrg 445805b261ecSmrg for (i=size=0;i<num_doodads;i++,doodad++) { 445905b261ecSmrg size+= SIZEOF(xkbAnyDoodadWireDesc); 446005b261ecSmrg if (doodad->any.type==XkbTextDoodad) { 446105b261ecSmrg size+= XkbSizeCountedString(doodad->text.text); 446205b261ecSmrg size+= XkbSizeCountedString(doodad->text.font); 446305b261ecSmrg } 446405b261ecSmrg else if (doodad->any.type==XkbLogoDoodad) { 446505b261ecSmrg size+= XkbSizeCountedString(doodad->logo.logo_name); 446605b261ecSmrg } 446705b261ecSmrg } 446805b261ecSmrg return size; 446905b261ecSmrg} 447005b261ecSmrg 447105b261ecSmrgstatic char * 447205b261ecSmrgXkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap) 447305b261ecSmrg{ 447405b261ecSmrgregister int i; 447505b261ecSmrgxkbDoodadWireDesc * doodadWire; 447605b261ecSmrg 447705b261ecSmrg for (i=0;i<num_doodads;i++,doodad++) { 447805b261ecSmrg doodadWire= (xkbDoodadWireDesc *)wire; 447905b261ecSmrg wire= (char *)&doodadWire[1]; 448005b261ecSmrg bzero(doodadWire,SIZEOF(xkbDoodadWireDesc)); 448105b261ecSmrg doodadWire->any.name= doodad->any.name; 448205b261ecSmrg doodadWire->any.type= doodad->any.type; 448305b261ecSmrg doodadWire->any.priority= doodad->any.priority; 448405b261ecSmrg doodadWire->any.top= doodad->any.top; 448505b261ecSmrg doodadWire->any.left= doodad->any.left; 448605b261ecSmrg if (swap) { 448705b261ecSmrg register int n; 448805b261ecSmrg swapl(&doodadWire->any.name,n); 448905b261ecSmrg swaps(&doodadWire->any.top,n); 449005b261ecSmrg swaps(&doodadWire->any.left,n); 449105b261ecSmrg } 449205b261ecSmrg switch (doodad->any.type) { 449305b261ecSmrg case XkbOutlineDoodad: 449405b261ecSmrg case XkbSolidDoodad: 449505b261ecSmrg doodadWire->shape.angle= doodad->shape.angle; 449605b261ecSmrg doodadWire->shape.colorNdx= doodad->shape.color_ndx; 449705b261ecSmrg doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; 449805b261ecSmrg if (swap) { 449905b261ecSmrg register int n; 450005b261ecSmrg swaps(&doodadWire->shape.angle,n); 450105b261ecSmrg } 450205b261ecSmrg break; 450305b261ecSmrg case XkbTextDoodad: 450405b261ecSmrg doodadWire->text.angle= doodad->text.angle; 450505b261ecSmrg doodadWire->text.width= doodad->text.width; 450605b261ecSmrg doodadWire->text.height= doodad->text.height; 450705b261ecSmrg doodadWire->text.colorNdx= doodad->text.color_ndx; 450805b261ecSmrg if (swap) { 450905b261ecSmrg register int n; 451005b261ecSmrg swaps(&doodadWire->text.angle,n); 451105b261ecSmrg swaps(&doodadWire->text.width,n); 451205b261ecSmrg swaps(&doodadWire->text.height,n); 451305b261ecSmrg } 451405b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.text,swap); 451505b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.font,swap); 451605b261ecSmrg break; 451705b261ecSmrg case XkbIndicatorDoodad: 451805b261ecSmrg doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; 451905b261ecSmrg doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; 452005b261ecSmrg doodadWire->indicator.offColorNdx= 452105b261ecSmrg doodad->indicator.off_color_ndx; 452205b261ecSmrg break; 452305b261ecSmrg case XkbLogoDoodad: 452405b261ecSmrg doodadWire->logo.angle= doodad->logo.angle; 452505b261ecSmrg doodadWire->logo.colorNdx= doodad->logo.color_ndx; 452605b261ecSmrg doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; 452705b261ecSmrg wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap); 452805b261ecSmrg break; 452905b261ecSmrg default: 45304642e01fSmrg ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 453105b261ecSmrg doodad->any.type); 45324642e01fSmrg ErrorF("[xkb] Ignored\n"); 453305b261ecSmrg break; 453405b261ecSmrg } 453505b261ecSmrg } 453605b261ecSmrg return wire; 453705b261ecSmrg} 453805b261ecSmrg 453905b261ecSmrgstatic char * 454005b261ecSmrgXkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap) 454105b261ecSmrg{ 454205b261ecSmrgregister int r; 454305b261ecSmrgXkbOverlayRowPtr row; 454405b261ecSmrgxkbOverlayWireDesc * olWire; 454505b261ecSmrg 454605b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 454705b261ecSmrg olWire->name= ol->name; 454805b261ecSmrg olWire->nRows= ol->num_rows; 454905b261ecSmrg if (swap) { 455005b261ecSmrg register int n; 455105b261ecSmrg swapl(&olWire->name,n); 455205b261ecSmrg } 455305b261ecSmrg wire= (char *)&olWire[1]; 455405b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 455505b261ecSmrg unsigned int k; 455605b261ecSmrg XkbOverlayKeyPtr key; 455705b261ecSmrg xkbOverlayRowWireDesc * rowWire; 455805b261ecSmrg rowWire= (xkbOverlayRowWireDesc *)wire; 455905b261ecSmrg rowWire->rowUnder= row->row_under; 456005b261ecSmrg rowWire->nKeys= row->num_keys; 456105b261ecSmrg wire= (char *)&rowWire[1]; 456205b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 456305b261ecSmrg xkbOverlayKeyWireDesc * keyWire; 456405b261ecSmrg keyWire= (xkbOverlayKeyWireDesc *)wire; 456505b261ecSmrg memcpy(keyWire->over,key->over.name,XkbKeyNameLength); 456605b261ecSmrg memcpy(keyWire->under,key->under.name,XkbKeyNameLength); 456705b261ecSmrg wire= (char *)&keyWire[1]; 456805b261ecSmrg } 456905b261ecSmrg } 457005b261ecSmrg return wire; 457105b261ecSmrg} 457205b261ecSmrg 457305b261ecSmrgstatic int 457405b261ecSmrgXkbSizeGeomSections(XkbGeometryPtr geom) 457505b261ecSmrg{ 457605b261ecSmrgregister int i,size; 457705b261ecSmrgXkbSectionPtr section; 457805b261ecSmrg 457905b261ecSmrg for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { 458005b261ecSmrg size+= SIZEOF(xkbSectionWireDesc); 458105b261ecSmrg if (section->rows) { 458205b261ecSmrg int r; 458305b261ecSmrg XkbRowPtr row; 458405b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;row++,r++) { 458505b261ecSmrg size+= SIZEOF(xkbRowWireDesc); 458605b261ecSmrg size+= row->num_keys*SIZEOF(xkbKeyWireDesc); 458705b261ecSmrg } 458805b261ecSmrg } 458905b261ecSmrg if (section->doodads) 459005b261ecSmrg size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads); 459105b261ecSmrg if (section->overlays) { 459205b261ecSmrg int o; 459305b261ecSmrg XkbOverlayPtr ol; 459405b261ecSmrg for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { 459505b261ecSmrg int r; 459605b261ecSmrg XkbOverlayRowPtr row; 459705b261ecSmrg size+= SIZEOF(xkbOverlayWireDesc); 459805b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 459905b261ecSmrg size+= SIZEOF(xkbOverlayRowWireDesc); 460005b261ecSmrg size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); 460105b261ecSmrg } 460205b261ecSmrg } 460305b261ecSmrg } 460405b261ecSmrg } 460505b261ecSmrg return size; 460605b261ecSmrg} 460705b261ecSmrg 460805b261ecSmrgstatic char * 460905b261ecSmrgXkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap) 461005b261ecSmrg{ 461105b261ecSmrgregister int i; 461205b261ecSmrgXkbSectionPtr section; 461305b261ecSmrgxkbSectionWireDesc * sectionWire; 461405b261ecSmrg 461505b261ecSmrg for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 461605b261ecSmrg sectionWire= (xkbSectionWireDesc *)wire; 461705b261ecSmrg sectionWire->name= section->name; 461805b261ecSmrg sectionWire->top= section->top; 461905b261ecSmrg sectionWire->left= section->left; 462005b261ecSmrg sectionWire->width= section->width; 462105b261ecSmrg sectionWire->height= section->height; 462205b261ecSmrg sectionWire->angle= section->angle; 462305b261ecSmrg sectionWire->priority= section->priority; 462405b261ecSmrg sectionWire->nRows= section->num_rows; 462505b261ecSmrg sectionWire->nDoodads= section->num_doodads; 462605b261ecSmrg sectionWire->nOverlays= section->num_overlays; 462705b261ecSmrg sectionWire->pad= 0; 462805b261ecSmrg if (swap) { 462905b261ecSmrg register int n; 463005b261ecSmrg swapl(§ionWire->name,n); 463105b261ecSmrg swaps(§ionWire->top,n); 463205b261ecSmrg swaps(§ionWire->left,n); 463305b261ecSmrg swaps(§ionWire->width,n); 463405b261ecSmrg swaps(§ionWire->height,n); 463505b261ecSmrg swaps(§ionWire->angle,n); 463605b261ecSmrg } 463705b261ecSmrg wire= (char *)§ionWire[1]; 463805b261ecSmrg if (section->rows) { 463905b261ecSmrg int r; 464005b261ecSmrg XkbRowPtr row; 464105b261ecSmrg xkbRowWireDesc * rowWire; 464205b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 464305b261ecSmrg rowWire= (xkbRowWireDesc *)wire; 464405b261ecSmrg rowWire->top= row->top; 464505b261ecSmrg rowWire->left= row->left; 464605b261ecSmrg rowWire->nKeys= row->num_keys; 464705b261ecSmrg rowWire->vertical= row->vertical; 464805b261ecSmrg rowWire->pad= 0; 464905b261ecSmrg if (swap) { 465005b261ecSmrg register int n; 465105b261ecSmrg swaps(&rowWire->top,n); 465205b261ecSmrg swaps(&rowWire->left,n); 465305b261ecSmrg } 465405b261ecSmrg wire= (char *)&rowWire[1]; 465505b261ecSmrg if (row->keys) { 465605b261ecSmrg int k; 465705b261ecSmrg XkbKeyPtr key; 465805b261ecSmrg xkbKeyWireDesc * keyWire; 465905b261ecSmrg keyWire= (xkbKeyWireDesc *)wire; 466005b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 466105b261ecSmrg memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); 466205b261ecSmrg keyWire[k].gap= key->gap; 466305b261ecSmrg keyWire[k].shapeNdx= key->shape_ndx; 466405b261ecSmrg keyWire[k].colorNdx= key->color_ndx; 466505b261ecSmrg if (swap) { 466605b261ecSmrg register int n; 466705b261ecSmrg swaps(&keyWire[k].gap,n); 466805b261ecSmrg } 466905b261ecSmrg } 467005b261ecSmrg wire= (char *)&keyWire[row->num_keys]; 467105b261ecSmrg } 467205b261ecSmrg } 467305b261ecSmrg } 467405b261ecSmrg if (section->doodads) { 467505b261ecSmrg wire= XkbWriteGeomDoodads(wire, 467605b261ecSmrg section->num_doodads,section->doodads, 467705b261ecSmrg swap); 467805b261ecSmrg } 467905b261ecSmrg if (section->overlays) { 468005b261ecSmrg register int o; 468105b261ecSmrg for (o=0;o<section->num_overlays;o++) { 468205b261ecSmrg wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap); 468305b261ecSmrg } 468405b261ecSmrg } 468505b261ecSmrg } 468605b261ecSmrg return wire; 468705b261ecSmrg} 468805b261ecSmrg 468905b261ecSmrgstatic Status 469005b261ecSmrgXkbComputeGetGeometryReplySize( XkbGeometryPtr geom, 469105b261ecSmrg xkbGetGeometryReply * rep, 469205b261ecSmrg Atom name) 469305b261ecSmrg{ 469405b261ecSmrgint len; 469505b261ecSmrg 469605b261ecSmrg if (geom!=NULL) { 469705b261ecSmrg len= XkbSizeCountedString(geom->label_font); 469805b261ecSmrg len+= XkbSizeGeomProperties(geom); 469905b261ecSmrg len+= XkbSizeGeomColors(geom); 470005b261ecSmrg len+= XkbSizeGeomShapes(geom); 470105b261ecSmrg len+= XkbSizeGeomSections(geom); 470205b261ecSmrg len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads); 470305b261ecSmrg len+= XkbSizeGeomKeyAliases(geom); 470405b261ecSmrg rep->length= len/4; 470505b261ecSmrg rep->found= True; 470605b261ecSmrg rep->name= geom->name; 470705b261ecSmrg rep->widthMM= geom->width_mm; 470805b261ecSmrg rep->heightMM= geom->height_mm; 470905b261ecSmrg rep->nProperties= geom->num_properties; 471005b261ecSmrg rep->nColors= geom->num_colors; 471105b261ecSmrg rep->nShapes= geom->num_shapes; 471205b261ecSmrg rep->nSections= geom->num_sections; 471305b261ecSmrg rep->nDoodads= geom->num_doodads; 471405b261ecSmrg rep->nKeyAliases= geom->num_key_aliases; 471505b261ecSmrg rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color); 471605b261ecSmrg rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color); 471705b261ecSmrg } 471805b261ecSmrg else { 471905b261ecSmrg rep->length= 0; 472005b261ecSmrg rep->found= False; 472105b261ecSmrg rep->name= name; 472205b261ecSmrg rep->widthMM= rep->heightMM= 0; 472305b261ecSmrg rep->nProperties= rep->nColors= rep->nShapes= 0; 472405b261ecSmrg rep->nSections= rep->nDoodads= 0; 472505b261ecSmrg rep->nKeyAliases= 0; 472605b261ecSmrg rep->labelColorNdx= rep->baseColorNdx= 0; 472705b261ecSmrg } 472805b261ecSmrg return Success; 472905b261ecSmrg} 473005b261ecSmrg 473105b261ecSmrgstatic int 473205b261ecSmrgXkbSendGeometry( ClientPtr client, 473305b261ecSmrg XkbGeometryPtr geom, 473405b261ecSmrg xkbGetGeometryReply * rep, 473505b261ecSmrg Bool freeGeom) 473605b261ecSmrg{ 473705b261ecSmrg char *desc,*start; 473805b261ecSmrg int len; 473905b261ecSmrg 474005b261ecSmrg if (geom!=NULL) { 474105b261ecSmrg len= rep->length*4; 47424642e01fSmrg start= desc= (char *)xalloc(len); 474305b261ecSmrg if (!start) 474405b261ecSmrg return BadAlloc; 474505b261ecSmrg desc= XkbWriteCountedString(desc,geom->label_font,client->swapped); 474605b261ecSmrg if ( rep->nProperties>0 ) 474705b261ecSmrg desc = XkbWriteGeomProperties(desc,geom,client->swapped); 474805b261ecSmrg if ( rep->nColors>0 ) 474905b261ecSmrg desc = XkbWriteGeomColors(desc,geom,client->swapped); 475005b261ecSmrg if ( rep->nShapes>0 ) 475105b261ecSmrg desc = XkbWriteGeomShapes(desc,geom,client->swapped); 475205b261ecSmrg if ( rep->nSections>0 ) 475305b261ecSmrg desc = XkbWriteGeomSections(desc,geom,client->swapped); 475405b261ecSmrg if ( rep->nDoodads>0 ) 475505b261ecSmrg desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads, 475605b261ecSmrg client->swapped); 475705b261ecSmrg if ( rep->nKeyAliases>0 ) 475805b261ecSmrg desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped); 475905b261ecSmrg if ((desc-start)!=(len)) { 47604642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 476105b261ecSmrg len, (unsigned long)(desc-start)); 476205b261ecSmrg } 476305b261ecSmrg } 476405b261ecSmrg else { 476505b261ecSmrg len= 0; 476605b261ecSmrg start= NULL; 476705b261ecSmrg } 476805b261ecSmrg if (client->swapped) { 476905b261ecSmrg register int n; 477005b261ecSmrg swaps(&rep->sequenceNumber,n); 477105b261ecSmrg swapl(&rep->length,n); 477205b261ecSmrg swapl(&rep->name,n); 477305b261ecSmrg swaps(&rep->widthMM,n); 477405b261ecSmrg swaps(&rep->heightMM,n); 477505b261ecSmrg swaps(&rep->nProperties,n); 477605b261ecSmrg swaps(&rep->nColors,n); 477705b261ecSmrg swaps(&rep->nShapes,n); 477805b261ecSmrg swaps(&rep->nSections,n); 477905b261ecSmrg swaps(&rep->nDoodads,n); 478005b261ecSmrg swaps(&rep->nKeyAliases,n); 478105b261ecSmrg } 478205b261ecSmrg WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep); 478305b261ecSmrg if (len>0) 478405b261ecSmrg WriteToClient(client, len, start); 478505b261ecSmrg if (start!=NULL) 47864642e01fSmrg xfree((char *)start); 478705b261ecSmrg if (freeGeom) 478805b261ecSmrg XkbFreeGeometry(geom,XkbGeomAllMask,True); 478905b261ecSmrg return client->noClientException; 479005b261ecSmrg} 479105b261ecSmrg 479205b261ecSmrgint 479305b261ecSmrgProcXkbGetGeometry(ClientPtr client) 479405b261ecSmrg{ 479505b261ecSmrg DeviceIntPtr dev; 479605b261ecSmrg xkbGetGeometryReply rep; 479705b261ecSmrg XkbGeometryPtr geom; 479805b261ecSmrg Bool shouldFree; 479905b261ecSmrg Status status; 480005b261ecSmrg 480105b261ecSmrg REQUEST(xkbGetGeometryReq); 480205b261ecSmrg REQUEST_SIZE_MATCH(xkbGetGeometryReq); 480305b261ecSmrg 480405b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 480505b261ecSmrg return BadAccess; 480605b261ecSmrg 48074642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 480805b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 480905b261ecSmrg 481005b261ecSmrg geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree); 481105b261ecSmrg rep.type= X_Reply; 481205b261ecSmrg rep.deviceID= dev->id; 481305b261ecSmrg rep.sequenceNumber= client->sequence; 481405b261ecSmrg rep.length= 0; 481505b261ecSmrg status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name); 481605b261ecSmrg if (status!=Success) 481705b261ecSmrg return status; 481805b261ecSmrg else return XkbSendGeometry(client,geom,&rep,shouldFree); 481905b261ecSmrg} 482005b261ecSmrg 482105b261ecSmrg/***====================================================================***/ 482205b261ecSmrg 482305b261ecSmrgstatic char * 482405b261ecSmrg_GetCountedString(char **wire_inout,Bool swap) 482505b261ecSmrg{ 482605b261ecSmrgchar * wire,*str; 482705b261ecSmrgCARD16 len,*plen; 482805b261ecSmrg 482905b261ecSmrg wire= *wire_inout; 483005b261ecSmrg plen= (CARD16 *)wire; 483105b261ecSmrg if (swap) { 483205b261ecSmrg register int n; 483305b261ecSmrg swaps(plen,n); 483405b261ecSmrg } 483505b261ecSmrg len= *plen; 483605b261ecSmrg str= (char *)_XkbAlloc(len+1); 483705b261ecSmrg if (str) { 483805b261ecSmrg memcpy(str,&wire[2],len); 483905b261ecSmrg str[len]= '\0'; 484005b261ecSmrg } 484105b261ecSmrg wire+= XkbPaddedSize(len+2); 484205b261ecSmrg *wire_inout= wire; 484305b261ecSmrg return str; 484405b261ecSmrg} 484505b261ecSmrg 484605b261ecSmrgstatic Status 484705b261ecSmrg_CheckSetDoodad( char ** wire_inout, 484805b261ecSmrg XkbGeometryPtr geom, 484905b261ecSmrg XkbSectionPtr section, 485005b261ecSmrg ClientPtr client) 485105b261ecSmrg{ 485205b261ecSmrgchar * wire; 485305b261ecSmrgxkbDoodadWireDesc * dWire; 485405b261ecSmrgXkbDoodadPtr doodad; 485505b261ecSmrg 485605b261ecSmrg dWire= (xkbDoodadWireDesc *)(*wire_inout); 485705b261ecSmrg wire= (char *)&dWire[1]; 485805b261ecSmrg if (client->swapped) { 485905b261ecSmrg register int n; 486005b261ecSmrg swapl(&dWire->any.name,n); 486105b261ecSmrg swaps(&dWire->any.top,n); 486205b261ecSmrg swaps(&dWire->any.left,n); 486305b261ecSmrg swaps(&dWire->any.angle,n); 486405b261ecSmrg } 486505b261ecSmrg CHK_ATOM_ONLY(dWire->any.name); 486605b261ecSmrg doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); 486705b261ecSmrg if (!doodad) 486805b261ecSmrg return BadAlloc; 486905b261ecSmrg doodad->any.type= dWire->any.type; 487005b261ecSmrg doodad->any.priority= dWire->any.priority; 487105b261ecSmrg doodad->any.top= dWire->any.top; 487205b261ecSmrg doodad->any.left= dWire->any.left; 487305b261ecSmrg doodad->any.angle= dWire->any.angle; 487405b261ecSmrg switch (doodad->any.type) { 487505b261ecSmrg case XkbOutlineDoodad: 487605b261ecSmrg case XkbSolidDoodad: 487705b261ecSmrg if (dWire->shape.colorNdx>=geom->num_colors) { 487805b261ecSmrg client->errorValue= _XkbErrCode3(0x40,geom->num_colors, 487905b261ecSmrg dWire->shape.colorNdx); 488005b261ecSmrg return BadMatch; 488105b261ecSmrg } 488205b261ecSmrg if (dWire->shape.shapeNdx>=geom->num_shapes) { 488305b261ecSmrg client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, 488405b261ecSmrg dWire->shape.shapeNdx); 488505b261ecSmrg return BadMatch; 488605b261ecSmrg } 488705b261ecSmrg doodad->shape.color_ndx= dWire->shape.colorNdx; 488805b261ecSmrg doodad->shape.shape_ndx= dWire->shape.shapeNdx; 488905b261ecSmrg break; 489005b261ecSmrg case XkbTextDoodad: 489105b261ecSmrg if (dWire->text.colorNdx>=geom->num_colors) { 489205b261ecSmrg client->errorValue= _XkbErrCode3(0x42,geom->num_colors, 489305b261ecSmrg dWire->text.colorNdx); 489405b261ecSmrg return BadMatch; 489505b261ecSmrg } 489605b261ecSmrg if (client->swapped) { 489705b261ecSmrg register int n; 489805b261ecSmrg swaps(&dWire->text.width,n); 489905b261ecSmrg swaps(&dWire->text.height,n); 490005b261ecSmrg } 490105b261ecSmrg doodad->text.width= dWire->text.width; 490205b261ecSmrg doodad->text.height= dWire->text.height; 490305b261ecSmrg doodad->text.color_ndx= dWire->text.colorNdx; 490405b261ecSmrg doodad->text.text= _GetCountedString(&wire,client->swapped); 490505b261ecSmrg doodad->text.font= _GetCountedString(&wire,client->swapped); 490605b261ecSmrg break; 490705b261ecSmrg case XkbIndicatorDoodad: 490805b261ecSmrg if (dWire->indicator.onColorNdx>=geom->num_colors) { 490905b261ecSmrg client->errorValue= _XkbErrCode3(0x43,geom->num_colors, 491005b261ecSmrg dWire->indicator.onColorNdx); 491105b261ecSmrg return BadMatch; 491205b261ecSmrg } 491305b261ecSmrg if (dWire->indicator.offColorNdx>=geom->num_colors) { 491405b261ecSmrg client->errorValue= _XkbErrCode3(0x44,geom->num_colors, 491505b261ecSmrg dWire->indicator.offColorNdx); 491605b261ecSmrg return BadMatch; 491705b261ecSmrg } 491805b261ecSmrg if (dWire->indicator.shapeNdx>=geom->num_shapes) { 491905b261ecSmrg client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, 492005b261ecSmrg dWire->indicator.shapeNdx); 492105b261ecSmrg return BadMatch; 492205b261ecSmrg } 492305b261ecSmrg doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; 492405b261ecSmrg doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; 492505b261ecSmrg doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; 492605b261ecSmrg break; 492705b261ecSmrg case XkbLogoDoodad: 492805b261ecSmrg if (dWire->logo.colorNdx>=geom->num_colors) { 492905b261ecSmrg client->errorValue= _XkbErrCode3(0x46,geom->num_colors, 493005b261ecSmrg dWire->logo.colorNdx); 493105b261ecSmrg return BadMatch; 493205b261ecSmrg } 493305b261ecSmrg if (dWire->logo.shapeNdx>=geom->num_shapes) { 493405b261ecSmrg client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, 493505b261ecSmrg dWire->logo.shapeNdx); 493605b261ecSmrg return BadMatch; 493705b261ecSmrg } 493805b261ecSmrg doodad->logo.color_ndx= dWire->logo.colorNdx; 493905b261ecSmrg doodad->logo.shape_ndx= dWire->logo.shapeNdx; 494005b261ecSmrg doodad->logo.logo_name= _GetCountedString(&wire,client->swapped); 494105b261ecSmrg break; 494205b261ecSmrg default: 494305b261ecSmrg client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); 494405b261ecSmrg return BadValue; 494505b261ecSmrg } 494605b261ecSmrg *wire_inout= wire; 494705b261ecSmrg return Success; 494805b261ecSmrg} 494905b261ecSmrg 495005b261ecSmrgstatic Status 495105b261ecSmrg_CheckSetOverlay( char ** wire_inout, 495205b261ecSmrg XkbGeometryPtr geom, 495305b261ecSmrg XkbSectionPtr section, 495405b261ecSmrg ClientPtr client) 495505b261ecSmrg{ 495605b261ecSmrgregister int r; 495705b261ecSmrgchar * wire; 495805b261ecSmrgXkbOverlayPtr ol; 495905b261ecSmrgxkbOverlayWireDesc * olWire; 496005b261ecSmrgxkbOverlayRowWireDesc * rWire; 496105b261ecSmrg 496205b261ecSmrg wire= *wire_inout; 496305b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 496405b261ecSmrg if (client->swapped) { 496505b261ecSmrg register int n; 496605b261ecSmrg swapl(&olWire->name,n); 496705b261ecSmrg } 496805b261ecSmrg CHK_ATOM_ONLY(olWire->name); 496905b261ecSmrg ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); 497005b261ecSmrg rWire= (xkbOverlayRowWireDesc *)&olWire[1]; 497105b261ecSmrg for (r=0;r<olWire->nRows;r++) { 497205b261ecSmrg register int k; 497305b261ecSmrg xkbOverlayKeyWireDesc * kWire; 497405b261ecSmrg XkbOverlayRowPtr row; 497505b261ecSmrg 497605b261ecSmrg if (rWire->rowUnder>section->num_rows) { 497705b261ecSmrg client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, 497805b261ecSmrg rWire->rowUnder); 497905b261ecSmrg return BadMatch; 498005b261ecSmrg } 498105b261ecSmrg row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); 498205b261ecSmrg kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; 498305b261ecSmrg for (k=0;k<rWire->nKeys;k++,kWire++) { 498405b261ecSmrg if (XkbAddGeomOverlayKey(ol,row, 498505b261ecSmrg (char *)kWire->over,(char *)kWire->under)==NULL) { 498605b261ecSmrg client->errorValue= _XkbErrCode3(0x21,r,k); 498705b261ecSmrg return BadMatch; 498805b261ecSmrg } 498905b261ecSmrg } 499005b261ecSmrg rWire= (xkbOverlayRowWireDesc *)kWire; 499105b261ecSmrg } 499205b261ecSmrg olWire= (xkbOverlayWireDesc *)rWire; 499305b261ecSmrg wire= (char *)olWire; 499405b261ecSmrg *wire_inout= wire; 499505b261ecSmrg return Success; 499605b261ecSmrg} 499705b261ecSmrg 499805b261ecSmrgstatic Status 499905b261ecSmrg_CheckSetSections( XkbGeometryPtr geom, 500005b261ecSmrg xkbSetGeometryReq * req, 500105b261ecSmrg char ** wire_inout, 500205b261ecSmrg ClientPtr client) 500305b261ecSmrg{ 500405b261ecSmrgStatus status; 500505b261ecSmrgregister int s; 500605b261ecSmrgchar * wire; 500705b261ecSmrgxkbSectionWireDesc * sWire; 500805b261ecSmrgXkbSectionPtr section; 500905b261ecSmrg 501005b261ecSmrg wire= *wire_inout; 501105b261ecSmrg if (req->nSections<1) 501205b261ecSmrg return Success; 501305b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 501405b261ecSmrg for (s=0;s<req->nSections;s++) { 501505b261ecSmrg register int r; 501605b261ecSmrg xkbRowWireDesc * rWire; 501705b261ecSmrg if (client->swapped) { 501805b261ecSmrg register int n; 501905b261ecSmrg swapl(&sWire->name,n); 502005b261ecSmrg swaps(&sWire->top,n); 502105b261ecSmrg swaps(&sWire->left,n); 502205b261ecSmrg swaps(&sWire->width,n); 502305b261ecSmrg swaps(&sWire->height,n); 502405b261ecSmrg swaps(&sWire->angle,n); 502505b261ecSmrg } 502605b261ecSmrg CHK_ATOM_ONLY(sWire->name); 502705b261ecSmrg section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, 502805b261ecSmrg sWire->nDoodads,sWire->nOverlays); 502905b261ecSmrg if (!section) 503005b261ecSmrg return BadAlloc; 503105b261ecSmrg section->priority= sWire->priority; 503205b261ecSmrg section->top= sWire->top; 503305b261ecSmrg section->left= sWire->left; 503405b261ecSmrg section->width= sWire->width; 503505b261ecSmrg section->height= sWire->height; 503605b261ecSmrg section->angle= sWire->angle; 503705b261ecSmrg rWire= (xkbRowWireDesc *)&sWire[1]; 503805b261ecSmrg for (r=0;r<sWire->nRows;r++) { 503905b261ecSmrg register int k; 504005b261ecSmrg XkbRowPtr row; 504105b261ecSmrg xkbKeyWireDesc * kWire; 504205b261ecSmrg if (client->swapped) { 504305b261ecSmrg register int n; 504405b261ecSmrg swaps(&rWire->top,n); 504505b261ecSmrg swaps(&rWire->left,n); 504605b261ecSmrg } 504705b261ecSmrg row= XkbAddGeomRow(section,rWire->nKeys); 504805b261ecSmrg if (!row) 504905b261ecSmrg return BadAlloc; 505005b261ecSmrg row->top= rWire->top; 505105b261ecSmrg row->left= rWire->left; 505205b261ecSmrg row->vertical= rWire->vertical; 505305b261ecSmrg kWire= (xkbKeyWireDesc *)&rWire[1]; 505405b261ecSmrg for (k=0;k<rWire->nKeys;k++) { 505505b261ecSmrg XkbKeyPtr key; 505605b261ecSmrg key= XkbAddGeomKey(row); 505705b261ecSmrg if (!key) 505805b261ecSmrg return BadAlloc; 505905b261ecSmrg memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); 506005b261ecSmrg key->gap= kWire[k].gap; 506105b261ecSmrg key->shape_ndx= kWire[k].shapeNdx; 506205b261ecSmrg key->color_ndx= kWire[k].colorNdx; 506305b261ecSmrg if (key->shape_ndx>=geom->num_shapes) { 506405b261ecSmrg client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, 506505b261ecSmrg geom->num_shapes); 506605b261ecSmrg return BadMatch; 506705b261ecSmrg } 506805b261ecSmrg if (key->color_ndx>=geom->num_colors) { 506905b261ecSmrg client->errorValue= _XkbErrCode3(0x11,key->color_ndx, 507005b261ecSmrg geom->num_colors); 507105b261ecSmrg return BadMatch; 507205b261ecSmrg } 507305b261ecSmrg } 507405b261ecSmrg rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; 507505b261ecSmrg } 507605b261ecSmrg wire= (char *)rWire; 507705b261ecSmrg if (sWire->nDoodads>0) { 507805b261ecSmrg register int d; 507905b261ecSmrg for (d=0;d<sWire->nDoodads;d++) { 508005b261ecSmrg status=_CheckSetDoodad(&wire,geom,section,client); 508105b261ecSmrg if (status!=Success) 508205b261ecSmrg return status; 508305b261ecSmrg } 508405b261ecSmrg } 508505b261ecSmrg if (sWire->nOverlays>0) { 508605b261ecSmrg register int o; 508705b261ecSmrg for (o=0;o<sWire->nOverlays;o++) { 508805b261ecSmrg status= _CheckSetOverlay(&wire,geom,section,client); 508905b261ecSmrg if (status!=Success) 509005b261ecSmrg return status; 509105b261ecSmrg } 509205b261ecSmrg } 509305b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 509405b261ecSmrg } 509505b261ecSmrg wire= (char *)sWire; 509605b261ecSmrg *wire_inout= wire; 509705b261ecSmrg return Success; 509805b261ecSmrg} 509905b261ecSmrg 510005b261ecSmrgstatic Status 510105b261ecSmrg_CheckSetShapes( XkbGeometryPtr geom, 510205b261ecSmrg xkbSetGeometryReq * req, 510305b261ecSmrg char ** wire_inout, 510405b261ecSmrg ClientPtr client) 510505b261ecSmrg{ 510605b261ecSmrgregister int i; 510705b261ecSmrgchar * wire; 510805b261ecSmrg 510905b261ecSmrg wire= *wire_inout; 511005b261ecSmrg if (req->nShapes<1) { 511105b261ecSmrg client->errorValue= _XkbErrCode2(0x06,req->nShapes); 511205b261ecSmrg return BadValue; 511305b261ecSmrg } 511405b261ecSmrg else { 511505b261ecSmrg xkbShapeWireDesc * shapeWire; 511605b261ecSmrg XkbShapePtr shape; 511705b261ecSmrg register int o; 511805b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 511905b261ecSmrg for (i=0;i<req->nShapes;i++) { 512005b261ecSmrg xkbOutlineWireDesc * olWire; 512105b261ecSmrg XkbOutlinePtr ol; 512205b261ecSmrg shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); 512305b261ecSmrg if (!shape) 512405b261ecSmrg return BadAlloc; 512505b261ecSmrg olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); 512605b261ecSmrg for (o=0;o<shapeWire->nOutlines;o++) { 512705b261ecSmrg register int p; 512805b261ecSmrg XkbPointPtr pt; 512905b261ecSmrg xkbPointWireDesc * ptWire; 513005b261ecSmrg 513105b261ecSmrg ol= XkbAddGeomOutline(shape,olWire->nPoints); 513205b261ecSmrg if (!ol) 513305b261ecSmrg return BadAlloc; 513405b261ecSmrg ol->corner_radius= olWire->cornerRadius; 513505b261ecSmrg ptWire= (xkbPointWireDesc *)&olWire[1]; 513605b261ecSmrg for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { 513705b261ecSmrg pt->x= ptWire[p].x; 513805b261ecSmrg pt->y= ptWire[p].y; 513905b261ecSmrg if (client->swapped) { 514005b261ecSmrg register int n; 514105b261ecSmrg swaps(&pt->x,n); 514205b261ecSmrg swaps(&pt->y,n); 514305b261ecSmrg } 514405b261ecSmrg } 514505b261ecSmrg ol->num_points= olWire->nPoints; 514605b261ecSmrg olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); 514705b261ecSmrg } 514805b261ecSmrg if (shapeWire->primaryNdx!=XkbNoShape) 514905b261ecSmrg shape->primary= &shape->outlines[shapeWire->primaryNdx]; 515005b261ecSmrg if (shapeWire->approxNdx!=XkbNoShape) 515105b261ecSmrg shape->approx= &shape->outlines[shapeWire->approxNdx]; 515205b261ecSmrg shapeWire= (xkbShapeWireDesc *)olWire; 515305b261ecSmrg } 515405b261ecSmrg wire= (char *)shapeWire; 515505b261ecSmrg } 515605b261ecSmrg if (geom->num_shapes!=req->nShapes) { 515705b261ecSmrg client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); 515805b261ecSmrg return BadMatch; 515905b261ecSmrg } 516005b261ecSmrg 516105b261ecSmrg *wire_inout= wire; 516205b261ecSmrg return Success; 516305b261ecSmrg} 516405b261ecSmrg 516505b261ecSmrgstatic Status 516605b261ecSmrg_CheckSetGeom( XkbGeometryPtr geom, 516705b261ecSmrg xkbSetGeometryReq * req, 516805b261ecSmrg ClientPtr client) 516905b261ecSmrg{ 517005b261ecSmrgregister int i; 517105b261ecSmrgStatus status; 517205b261ecSmrgchar * wire; 517305b261ecSmrg 517405b261ecSmrg wire= (char *)&req[1]; 517505b261ecSmrg geom->label_font= _GetCountedString(&wire,client->swapped); 517605b261ecSmrg 517705b261ecSmrg for (i=0;i<req->nProperties;i++) { 517805b261ecSmrg char *name,*val; 517905b261ecSmrg name= _GetCountedString(&wire,client->swapped); 518005b261ecSmrg if (!name) 518105b261ecSmrg return BadAlloc; 518205b261ecSmrg val= _GetCountedString(&wire,client->swapped); 518305b261ecSmrg if (!val) { 518405b261ecSmrg xfree(name); 518505b261ecSmrg return BadAlloc; 518605b261ecSmrg } 518705b261ecSmrg if (XkbAddGeomProperty(geom,name,val)==NULL) { 518805b261ecSmrg xfree(name); 518905b261ecSmrg xfree(val); 519005b261ecSmrg return BadAlloc; 519105b261ecSmrg } 519205b261ecSmrg xfree(name); 519305b261ecSmrg xfree(val); 519405b261ecSmrg } 519505b261ecSmrg 519605b261ecSmrg if (req->nColors<2) { 519705b261ecSmrg client->errorValue= _XkbErrCode3(0x01,2,req->nColors); 519805b261ecSmrg return BadValue; 519905b261ecSmrg } 520005b261ecSmrg if (req->baseColorNdx>req->nColors) { 520105b261ecSmrg client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); 520205b261ecSmrg return BadMatch; 520305b261ecSmrg } 520405b261ecSmrg if (req->labelColorNdx>req->nColors) { 520505b261ecSmrg client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); 520605b261ecSmrg return BadMatch; 520705b261ecSmrg } 520805b261ecSmrg if (req->labelColorNdx==req->baseColorNdx) { 520905b261ecSmrg client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, 521005b261ecSmrg req->labelColorNdx); 521105b261ecSmrg return BadMatch; 521205b261ecSmrg } 521305b261ecSmrg 521405b261ecSmrg for (i=0;i<req->nColors;i++) { 521505b261ecSmrg char *name; 521605b261ecSmrg name= _GetCountedString(&wire,client->swapped); 521705b261ecSmrg if (!name) 521805b261ecSmrg return BadAlloc; 521905b261ecSmrg if (!XkbAddGeomColor(geom,name,geom->num_colors)) { 522005b261ecSmrg xfree(name); 522105b261ecSmrg return BadAlloc; 522205b261ecSmrg } 522305b261ecSmrg xfree(name); 522405b261ecSmrg } 522505b261ecSmrg if (req->nColors!=geom->num_colors) { 522605b261ecSmrg client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); 522705b261ecSmrg return BadMatch; 522805b261ecSmrg } 522905b261ecSmrg geom->label_color= &geom->colors[req->labelColorNdx]; 523005b261ecSmrg geom->base_color= &geom->colors[req->baseColorNdx]; 523105b261ecSmrg 523205b261ecSmrg if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) 523305b261ecSmrg return status; 523405b261ecSmrg 523505b261ecSmrg if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) 523605b261ecSmrg return status; 523705b261ecSmrg 523805b261ecSmrg for (i=0;i<req->nDoodads;i++) { 523905b261ecSmrg status=_CheckSetDoodad(&wire,geom,NULL,client); 524005b261ecSmrg if (status!=Success) 524105b261ecSmrg return status; 524205b261ecSmrg } 524305b261ecSmrg 524405b261ecSmrg for (i=0;i<req->nKeyAliases;i++) { 524505b261ecSmrg if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) 524605b261ecSmrg return BadAlloc; 524705b261ecSmrg wire+= 2*XkbKeyNameLength; 524805b261ecSmrg } 524905b261ecSmrg return Success; 525005b261ecSmrg} 525105b261ecSmrg 52524642e01fSmrgstatic int 52534642e01fSmrg_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) 525405b261ecSmrg{ 525505b261ecSmrg XkbDescPtr xkb; 525605b261ecSmrg Bool new_name; 525705b261ecSmrg xkbNewKeyboardNotify nkn; 52584642e01fSmrg XkbGeometryPtr geom,old; 52594642e01fSmrg XkbGeometrySizesRec sizes; 52604642e01fSmrg Status status; 526105b261ecSmrg 526205b261ecSmrg xkb= dev->key->xkbInfo->desc; 526305b261ecSmrg old= xkb->geom; 526405b261ecSmrg xkb->geom= NULL; 526505b261ecSmrg 52664642e01fSmrg sizes.which= XkbGeomAllMask; 526705b261ecSmrg sizes.num_properties= stuff->nProperties; 52684642e01fSmrg sizes.num_colors= stuff->nColors; 52694642e01fSmrg sizes.num_shapes= stuff->nShapes; 52704642e01fSmrg sizes.num_sections= stuff->nSections; 52714642e01fSmrg sizes.num_doodads= stuff->nDoodads; 527205b261ecSmrg sizes.num_key_aliases= stuff->nKeyAliases; 527305b261ecSmrg if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { 52744642e01fSmrg xkb->geom= old; 52754642e01fSmrg return status; 527605b261ecSmrg } 527705b261ecSmrg geom= xkb->geom; 527805b261ecSmrg geom->name= stuff->name; 527905b261ecSmrg geom->width_mm= stuff->widthMM; 528005b261ecSmrg geom->height_mm= stuff->heightMM; 528105b261ecSmrg if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { 52824642e01fSmrg XkbFreeGeometry(geom,XkbGeomAllMask,True); 52834642e01fSmrg xkb->geom= old; 52844642e01fSmrg return status; 528505b261ecSmrg } 528605b261ecSmrg new_name= (xkb->names->geometry!=geom->name); 528705b261ecSmrg xkb->names->geometry= geom->name; 528805b261ecSmrg if (old) 52894642e01fSmrg XkbFreeGeometry(old,XkbGeomAllMask,True); 529005b261ecSmrg if (new_name) { 52914642e01fSmrg xkbNamesNotify nn; 52924642e01fSmrg bzero(&nn,sizeof(xkbNamesNotify)); 52934642e01fSmrg nn.changed= XkbGeometryNameMask; 52944642e01fSmrg XkbSendNamesNotify(dev,&nn); 529505b261ecSmrg } 529605b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 529705b261ecSmrg nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; 529805b261ecSmrg nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; 529905b261ecSmrg nkn.requestMajor= XkbReqCode; 530005b261ecSmrg nkn.requestMinor= X_kbSetGeometry; 530105b261ecSmrg nkn.changed= XkbNKN_GeometryMask; 530205b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 530305b261ecSmrg return Success; 530405b261ecSmrg} 530505b261ecSmrg 53064642e01fSmrgint 53074642e01fSmrgProcXkbSetGeometry(ClientPtr client) 53084642e01fSmrg{ 53094642e01fSmrg DeviceIntPtr dev; 53104642e01fSmrg int rc; 53114642e01fSmrg 53124642e01fSmrg REQUEST(xkbSetGeometryReq); 53134642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 53144642e01fSmrg 53154642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 53164642e01fSmrg return BadAccess; 53174642e01fSmrg 53184642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 53194642e01fSmrg CHK_ATOM_OR_NONE(stuff->name); 53204642e01fSmrg 53214642e01fSmrg rc = _XkbSetGeometry(client, dev, stuff); 53224642e01fSmrg if (rc != Success) 53234642e01fSmrg return rc; 53244642e01fSmrg 53254642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 53264642e01fSmrg { 53274642e01fSmrg DeviceIntPtr other; 53284642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 53294642e01fSmrg { 53304642e01fSmrg if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 53314642e01fSmrg { 53324642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 53334642e01fSmrg if (rc == Success) 53344642e01fSmrg _XkbSetGeometry(client, other, stuff); 53354642e01fSmrg } 53364642e01fSmrg } 53374642e01fSmrg } 53384642e01fSmrg 53394642e01fSmrg return Success; 53404642e01fSmrg} 53414642e01fSmrg 534205b261ecSmrg/***====================================================================***/ 534305b261ecSmrg 534405b261ecSmrgint 534505b261ecSmrgProcXkbPerClientFlags(ClientPtr client) 534605b261ecSmrg{ 534705b261ecSmrg DeviceIntPtr dev; 534805b261ecSmrg xkbPerClientFlagsReply rep; 534905b261ecSmrg XkbInterestPtr interest; 53504642e01fSmrg Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 535105b261ecSmrg 535205b261ecSmrg REQUEST(xkbPerClientFlagsReq); 535305b261ecSmrg REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 535405b261ecSmrg 535505b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 535605b261ecSmrg return BadAccess; 535705b261ecSmrg 53584642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 535905b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); 536005b261ecSmrg CHK_MASK_MATCH(0x02,stuff->change,stuff->value); 536105b261ecSmrg 536205b261ecSmrg interest = XkbFindClientResource((DevicePtr)dev,client); 536305b261ecSmrg rep.type= X_Reply; 536405b261ecSmrg rep.length = 0; 536505b261ecSmrg rep.sequenceNumber = client->sequence; 536605b261ecSmrg if (stuff->change) { 536705b261ecSmrg client->xkbClientFlags&= ~stuff->change; 536805b261ecSmrg client->xkbClientFlags|= stuff->value; 536905b261ecSmrg } 537005b261ecSmrg if (stuff->change&XkbPCF_AutoResetControlsMask) { 537105b261ecSmrg Bool want; 537205b261ecSmrg want= stuff->value&XkbPCF_AutoResetControlsMask; 537305b261ecSmrg if (interest && !want) { 537405b261ecSmrg interest->autoCtrls= interest->autoCtrlValues= 0; 537505b261ecSmrg } 537605b261ecSmrg else if (want && (!interest)) { 537705b261ecSmrg XID id = FakeClientID(client->index); 537805b261ecSmrg AddResource(id,RT_XKBCLIENT,dev); 537905b261ecSmrg interest= XkbAddClientResource((DevicePtr)dev,client,id); 538005b261ecSmrg if (!interest) 538105b261ecSmrg return BadAlloc; 538205b261ecSmrg } 538305b261ecSmrg if (interest && want ) { 538405b261ecSmrg register unsigned affect; 538505b261ecSmrg affect= stuff->ctrlsToChange; 538605b261ecSmrg 538705b261ecSmrg CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); 538805b261ecSmrg CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); 538905b261ecSmrg CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); 539005b261ecSmrg 539105b261ecSmrg interest->autoCtrls&= ~affect; 539205b261ecSmrg interest->autoCtrlValues&= ~affect; 539305b261ecSmrg interest->autoCtrls|= stuff->autoCtrls&affect; 539405b261ecSmrg interest->autoCtrlValues|= stuff->autoCtrlValues&affect; 539505b261ecSmrg } 539605b261ecSmrg } 539705b261ecSmrg rep.supported = XkbPCF_AllFlagsMask; 539805b261ecSmrg rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; 539905b261ecSmrg if (interest) { 540005b261ecSmrg rep.autoCtrls= interest->autoCtrls; 540105b261ecSmrg rep.autoCtrlValues= interest->autoCtrlValues; 540205b261ecSmrg } 540305b261ecSmrg else { 540405b261ecSmrg rep.autoCtrls= rep.autoCtrlValues= 0; 540505b261ecSmrg } 540605b261ecSmrg if ( client->swapped ) { 540705b261ecSmrg register int n; 540805b261ecSmrg swaps(&rep.sequenceNumber, n); 540905b261ecSmrg swapl(&rep.supported,n); 541005b261ecSmrg swapl(&rep.value,n); 541105b261ecSmrg swapl(&rep.autoCtrls,n); 541205b261ecSmrg swapl(&rep.autoCtrlValues,n); 541305b261ecSmrg } 541405b261ecSmrg WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); 541505b261ecSmrg return client->noClientException; 541605b261ecSmrg} 541705b261ecSmrg 541805b261ecSmrg/***====================================================================***/ 541905b261ecSmrg 542005b261ecSmrg/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 542105b261ecSmrg/* and wildcards */ 542205b261ecSmrgstatic unsigned char componentSpecLegal[] = { 542305b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 542405b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 542505b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 542605b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 542705b261ecSmrg}; 542805b261ecSmrg 542905b261ecSmrg/* same as above but accepts percent, plus and bar too */ 543005b261ecSmrgstatic unsigned char componentExprLegal[] = { 543105b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 543205b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 543305b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 543405b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 543505b261ecSmrg}; 543605b261ecSmrg 543705b261ecSmrgstatic char * 543805b261ecSmrgGetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) 543905b261ecSmrg{ 544005b261ecSmrgint len; 544105b261ecSmrgregister int i; 544205b261ecSmrgunsigned char *wire,*str,*tmp,*legal; 544305b261ecSmrg 544405b261ecSmrg if (allowExpr) legal= &componentExprLegal[0]; 544505b261ecSmrg else legal= &componentSpecLegal[0]; 544605b261ecSmrg 544705b261ecSmrg wire= *pWire; 544805b261ecSmrg len= (*(unsigned char *)wire++); 544905b261ecSmrg if (len>0) { 545005b261ecSmrg str= (unsigned char *)_XkbCalloc(1, len+1); 545105b261ecSmrg if (str) { 545205b261ecSmrg tmp= str; 545305b261ecSmrg for (i=0;i<len;i++) { 545405b261ecSmrg if (legal[(*wire)/8]&(1<<((*wire)%8))) 545505b261ecSmrg *tmp++= *wire++; 545605b261ecSmrg else wire++; 545705b261ecSmrg } 545805b261ecSmrg if (tmp!=str) 545905b261ecSmrg *tmp++= '\0'; 546005b261ecSmrg else { 546105b261ecSmrg _XkbFree(str); 546205b261ecSmrg str= NULL; 546305b261ecSmrg } 546405b261ecSmrg } 546505b261ecSmrg else { 546605b261ecSmrg *errRtrn= BadAlloc; 546705b261ecSmrg } 546805b261ecSmrg } 546905b261ecSmrg else { 547005b261ecSmrg str= NULL; 547105b261ecSmrg } 547205b261ecSmrg *pWire= wire; 547305b261ecSmrg return (char *)str; 547405b261ecSmrg} 547505b261ecSmrg 547605b261ecSmrg/***====================================================================***/ 547705b261ecSmrg 547805b261ecSmrgint 547905b261ecSmrgProcXkbListComponents(ClientPtr client) 548005b261ecSmrg{ 548105b261ecSmrg DeviceIntPtr dev; 548205b261ecSmrg xkbListComponentsReply rep; 548305b261ecSmrg unsigned len; 548405b261ecSmrg int status; 548505b261ecSmrg unsigned char * str; 548605b261ecSmrg XkbSrvListInfoRec list; 548705b261ecSmrg 548805b261ecSmrg REQUEST(xkbListComponentsReq); 548905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 549005b261ecSmrg 549105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 549205b261ecSmrg return BadAccess; 549305b261ecSmrg 54944642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 549505b261ecSmrg 549605b261ecSmrg status= Success; 549705b261ecSmrg str= (unsigned char *)&stuff[1]; 549805b261ecSmrg bzero(&list,sizeof(XkbSrvListInfoRec)); 549905b261ecSmrg list.maxRtrn= stuff->maxNames; 550005b261ecSmrg list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status); 550105b261ecSmrg list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status); 550205b261ecSmrg list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status); 550305b261ecSmrg list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status); 550405b261ecSmrg list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status); 550505b261ecSmrg list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status); 550605b261ecSmrg if (status!=Success) 550705b261ecSmrg return status; 550805b261ecSmrg len= str-((unsigned char *)stuff); 550905b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 551005b261ecSmrg return BadLength; 551105b261ecSmrg if ((status=XkbDDXList(dev,&list,client))!=Success) { 551205b261ecSmrg if (list.pool) { 551305b261ecSmrg _XkbFree(list.pool); 551405b261ecSmrg list.pool= NULL; 551505b261ecSmrg } 551605b261ecSmrg return status; 551705b261ecSmrg } 551805b261ecSmrg bzero(&rep,sizeof(xkbListComponentsReply)); 551905b261ecSmrg rep.type= X_Reply; 552005b261ecSmrg rep.deviceID = dev->id; 552105b261ecSmrg rep.sequenceNumber = client->sequence; 552205b261ecSmrg rep.length = XkbPaddedSize(list.nPool)/4; 552305b261ecSmrg rep.nKeymaps = list.nFound[_XkbListKeymaps]; 552405b261ecSmrg rep.nKeycodes = list.nFound[_XkbListKeycodes]; 552505b261ecSmrg rep.nTypes = list.nFound[_XkbListTypes]; 552605b261ecSmrg rep.nCompatMaps = list.nFound[_XkbListCompat]; 552705b261ecSmrg rep.nSymbols = list.nFound[_XkbListSymbols]; 552805b261ecSmrg rep.nGeometries = list.nFound[_XkbListGeometry]; 552905b261ecSmrg rep.extra= 0; 553005b261ecSmrg if (list.nTotal>list.maxRtrn) 553105b261ecSmrg rep.extra = (list.nTotal-list.maxRtrn); 553205b261ecSmrg if (client->swapped) { 553305b261ecSmrg register int n; 553405b261ecSmrg swaps(&rep.sequenceNumber,n); 553505b261ecSmrg swapl(&rep.length,n); 553605b261ecSmrg swaps(&rep.nKeymaps,n); 553705b261ecSmrg swaps(&rep.nKeycodes,n); 553805b261ecSmrg swaps(&rep.nTypes,n); 553905b261ecSmrg swaps(&rep.nCompatMaps,n); 554005b261ecSmrg swaps(&rep.nSymbols,n); 554105b261ecSmrg swaps(&rep.nGeometries,n); 554205b261ecSmrg swaps(&rep.extra,n); 554305b261ecSmrg } 554405b261ecSmrg WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); 554505b261ecSmrg if (list.nPool && list.pool) { 554605b261ecSmrg WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); 554705b261ecSmrg _XkbFree(list.pool); 554805b261ecSmrg list.pool= NULL; 554905b261ecSmrg } 555005b261ecSmrg return client->noClientException; 555105b261ecSmrg} 555205b261ecSmrg 555305b261ecSmrg/***====================================================================***/ 555405b261ecSmrg 555505b261ecSmrgint 555605b261ecSmrgProcXkbGetKbdByName(ClientPtr client) 555705b261ecSmrg{ 555805b261ecSmrg DeviceIntPtr dev; 555905b261ecSmrg DeviceIntPtr tmpd; 556005b261ecSmrg xkbGetKbdByNameReply rep; 556105b261ecSmrg xkbGetMapReply mrep; 556205b261ecSmrg xkbGetCompatMapReply crep; 556305b261ecSmrg xkbGetIndicatorMapReply irep; 556405b261ecSmrg xkbGetNamesReply nrep; 556505b261ecSmrg xkbGetGeometryReply grep; 556605b261ecSmrg XkbComponentNamesRec names; 55674642e01fSmrg XkbDescPtr xkb, new; 556805b261ecSmrg unsigned char * str; 556905b261ecSmrg char mapFile[PATH_MAX]; 557005b261ecSmrg unsigned len; 557105b261ecSmrg unsigned fwant,fneed,reported; 557205b261ecSmrg int status; 557305b261ecSmrg Bool geom_changed; 557405b261ecSmrg XkbSrvLedInfoPtr old_sli; 557505b261ecSmrg XkbSrvLedInfoPtr sli; 55764642e01fSmrg Mask access_mode = DixGetAttrAccess | DixManageAccess; 557705b261ecSmrg 557805b261ecSmrg REQUEST(xkbGetKbdByNameReq); 557905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 558005b261ecSmrg 558105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 558205b261ecSmrg return BadAccess; 558305b261ecSmrg 55844642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 558505b261ecSmrg 558605b261ecSmrg xkb = dev->key->xkbInfo->desc; 558705b261ecSmrg status= Success; 558805b261ecSmrg str= (unsigned char *)&stuff[1]; 558905b261ecSmrg names.keymap= GetComponentSpec(&str,True,&status); 559005b261ecSmrg names.keycodes= GetComponentSpec(&str,True,&status); 559105b261ecSmrg names.types= GetComponentSpec(&str,True,&status); 559205b261ecSmrg names.compat= GetComponentSpec(&str,True,&status); 559305b261ecSmrg names.symbols= GetComponentSpec(&str,True,&status); 559405b261ecSmrg names.geometry= GetComponentSpec(&str,True,&status); 559505b261ecSmrg if (status!=Success) 559605b261ecSmrg return status; 559705b261ecSmrg len= str-((unsigned char *)stuff); 559805b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 559905b261ecSmrg return BadLength; 560005b261ecSmrg 560105b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); 560205b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); 560305b261ecSmrg 560405b261ecSmrg if (stuff->load) 560505b261ecSmrg fwant= XkbGBN_AllComponentsMask; 560605b261ecSmrg else fwant= stuff->want|stuff->need; 56074642e01fSmrg if ((!names.compat)&& 56084642e01fSmrg (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { 56094642e01fSmrg names.compat= _XkbDupString("%"); 561005b261ecSmrg } 56114642e01fSmrg if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { 56124642e01fSmrg names.types= _XkbDupString("%"); 56134642e01fSmrg } 56144642e01fSmrg if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { 56154642e01fSmrg names.symbols= _XkbDupString("%"); 56164642e01fSmrg } 56174642e01fSmrg geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); 56184642e01fSmrg if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { 56194642e01fSmrg names.geometry= _XkbDupString("%"); 56204642e01fSmrg geom_changed= False; 562105b261ecSmrg } 562205b261ecSmrg 562305b261ecSmrg bzero(mapFile,PATH_MAX); 562405b261ecSmrg rep.type= X_Reply; 562505b261ecSmrg rep.deviceID = dev->id; 562605b261ecSmrg rep.sequenceNumber = client->sequence; 562705b261ecSmrg rep.length = 0; 562805b261ecSmrg rep.minKeyCode = xkb->min_key_code; 562905b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 563005b261ecSmrg rep.loaded= False; 563105b261ecSmrg fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask; 563205b261ecSmrg fneed= XkbConvertGetByNameComponents(True,stuff->need); 563305b261ecSmrg rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed); 563405b261ecSmrg if (stuff->load) { 563505b261ecSmrg fneed|= XkmKeymapRequired; 563605b261ecSmrg fwant|= XkmKeymapLegal; 563705b261ecSmrg } 563805b261ecSmrg if ((fwant|fneed)&XkmSymbolsMask) { 563905b261ecSmrg fneed|= XkmKeyNamesIndex|XkmTypesIndex; 564005b261ecSmrg fwant|= XkmIndicatorsIndex; 564105b261ecSmrg } 564205b261ecSmrg 564305b261ecSmrg /* We pass dev in here so we can get the old names out if needed. */ 56444642e01fSmrg rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new, 564505b261ecSmrg mapFile,PATH_MAX); 564605b261ecSmrg rep.newKeyboard= False; 564705b261ecSmrg rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; 564805b261ecSmrg 564905b261ecSmrg stuff->want|= stuff->need; 56504642e01fSmrg if (new==NULL) 565105b261ecSmrg rep.reported= 0; 565205b261ecSmrg else { 565305b261ecSmrg if (stuff->load) 565405b261ecSmrg rep.loaded= True; 565505b261ecSmrg if (stuff->load || 56564642e01fSmrg ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) { 565705b261ecSmrg XkbChangesRec changes; 565805b261ecSmrg bzero(&changes,sizeof(changes)); 56594642e01fSmrg XkbUpdateDescActions(new, 56604642e01fSmrg new->min_key_code,XkbNumKeys(new), 566105b261ecSmrg &changes); 566205b261ecSmrg } 566305b261ecSmrg 56644642e01fSmrg if (new->map==NULL) 566505b261ecSmrg rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); 566605b261ecSmrg else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { 566705b261ecSmrg mrep.type= X_Reply; 566805b261ecSmrg mrep.deviceID = dev->id; 566905b261ecSmrg mrep.sequenceNumber= client->sequence; 567005b261ecSmrg mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); 56714642e01fSmrg mrep.minKeyCode = new->min_key_code; 56724642e01fSmrg mrep.maxKeyCode = new->max_key_code; 567305b261ecSmrg mrep.present = 0; 567405b261ecSmrg mrep.totalSyms = mrep.totalActs = 567505b261ecSmrg mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 567652397711Smrg mrep.totalModMapKeys= mrep.totalVModMapKeys= 0; 567705b261ecSmrg if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { 567805b261ecSmrg mrep.present|= XkbKeyTypesMask; 567905b261ecSmrg mrep.firstType = 0; 56804642e01fSmrg mrep.nTypes = mrep.totalTypes= new->map->num_types; 568105b261ecSmrg } 568205b261ecSmrg else { 568305b261ecSmrg mrep.firstType = mrep.nTypes= 0; 568405b261ecSmrg mrep.totalTypes= 0; 568505b261ecSmrg } 568605b261ecSmrg if (rep.reported&XkbGBN_ClientSymbolsMask) { 568705b261ecSmrg mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); 56884642e01fSmrg mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code; 56894642e01fSmrg mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new); 569005b261ecSmrg } 569105b261ecSmrg else { 569205b261ecSmrg mrep.firstKeySym= mrep.firstModMapKey= 0; 569305b261ecSmrg mrep.nKeySyms= mrep.nModMapKeys= 0; 569405b261ecSmrg } 569505b261ecSmrg if (rep.reported&XkbGBN_ServerSymbolsMask) { 569605b261ecSmrg mrep.present|= XkbAllServerInfoMask; 569705b261ecSmrg mrep.virtualMods= ~0; 569805b261ecSmrg mrep.firstKeyAct = mrep.firstKeyBehavior = 56994642e01fSmrg mrep.firstKeyExplicit = new->min_key_code; 570005b261ecSmrg mrep.nKeyActs = mrep.nKeyBehaviors = 57014642e01fSmrg mrep.nKeyExplicit = XkbNumKeys(new); 570252397711Smrg mrep.firstVModMapKey= new->min_key_code; 570352397711Smrg mrep.nVModMapKeys= XkbNumKeys(new); 570405b261ecSmrg } 570505b261ecSmrg else { 570605b261ecSmrg mrep.virtualMods= 0; 570705b261ecSmrg mrep.firstKeyAct= mrep.firstKeyBehavior= 570805b261ecSmrg mrep.firstKeyExplicit = 0; 570905b261ecSmrg mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; 571005b261ecSmrg } 57114642e01fSmrg XkbComputeGetMapReplySize(new,&mrep); 571205b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+mrep.length; 571305b261ecSmrg } 57144642e01fSmrg if (new->compat==NULL) 571505b261ecSmrg rep.reported&= ~XkbGBN_CompatMapMask; 571605b261ecSmrg else if (rep.reported&XkbGBN_CompatMapMask) { 571705b261ecSmrg crep.type= X_Reply; 571805b261ecSmrg crep.deviceID= dev->id; 571905b261ecSmrg crep.sequenceNumber= client->sequence; 572005b261ecSmrg crep.length= 0; 572105b261ecSmrg crep.groups= XkbAllGroupsMask; 572205b261ecSmrg crep.firstSI= 0; 57234642e01fSmrg crep.nSI= crep.nTotalSI= new->compat->num_si; 57244642e01fSmrg XkbComputeGetCompatMapReplySize(new->compat,&crep); 572505b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+crep.length; 572605b261ecSmrg } 57274642e01fSmrg if (new->indicators==NULL) 572805b261ecSmrg rep.reported&= ~XkbGBN_IndicatorMapMask; 572905b261ecSmrg else if (rep.reported&XkbGBN_IndicatorMapMask) { 573005b261ecSmrg irep.type= X_Reply; 573105b261ecSmrg irep.deviceID= dev->id; 573205b261ecSmrg irep.sequenceNumber= client->sequence; 573305b261ecSmrg irep.length= 0; 573405b261ecSmrg irep.which= XkbAllIndicatorsMask; 57354642e01fSmrg XkbComputeGetIndicatorMapReplySize(new->indicators,&irep); 573605b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+irep.length; 573705b261ecSmrg } 57384642e01fSmrg if (new->names==NULL) 573905b261ecSmrg rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); 574005b261ecSmrg else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { 574105b261ecSmrg nrep.type= X_Reply; 574205b261ecSmrg nrep.deviceID= dev->id; 574305b261ecSmrg nrep.sequenceNumber= client->sequence; 574405b261ecSmrg nrep.length= 0; 57454642e01fSmrg nrep.minKeyCode= new->min_key_code; 57464642e01fSmrg nrep.maxKeyCode= new->max_key_code; 574705b261ecSmrg if (rep.reported&XkbGBN_OtherNamesMask) { 574805b261ecSmrg nrep.which= XkbAllNamesMask; 57494642e01fSmrg if (new->map!=NULL) 57504642e01fSmrg nrep.nTypes= new->map->num_types; 575105b261ecSmrg else nrep.nTypes= 0; 575205b261ecSmrg nrep.nKTLevels= 0; 575305b261ecSmrg nrep.groupNames= XkbAllGroupsMask; 575405b261ecSmrg nrep.virtualMods= XkbAllVirtualModsMask; 575505b261ecSmrg nrep.indicators= XkbAllIndicatorsMask; 57564642e01fSmrg nrep.nRadioGroups= new->names->num_rg; 575705b261ecSmrg } 575805b261ecSmrg else { 575905b261ecSmrg nrep.which= 0; 576005b261ecSmrg nrep.nTypes= 0; 576105b261ecSmrg nrep.nKTLevels= 0; 576205b261ecSmrg nrep.groupNames= 0; 576305b261ecSmrg nrep.virtualMods= 0; 576405b261ecSmrg nrep.indicators= 0; 576505b261ecSmrg nrep.nRadioGroups= 0; 576605b261ecSmrg } 576705b261ecSmrg if (rep.reported&XkbGBN_KeyNamesMask) { 576805b261ecSmrg nrep.which|= XkbKeyNamesMask; 57694642e01fSmrg nrep.firstKey= new->min_key_code; 57704642e01fSmrg nrep.nKeys= XkbNumKeys(new); 57714642e01fSmrg nrep.nKeyAliases= new->names->num_key_aliases; 577205b261ecSmrg if (nrep.nKeyAliases) 577305b261ecSmrg nrep.which|= XkbKeyAliasesMask; 577405b261ecSmrg } 577505b261ecSmrg else { 577605b261ecSmrg nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); 577705b261ecSmrg nrep.firstKey= nrep.nKeys= 0; 577805b261ecSmrg nrep.nKeyAliases= 0; 577905b261ecSmrg } 57804642e01fSmrg XkbComputeGetNamesReplySize(new,&nrep); 578105b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+nrep.length; 578205b261ecSmrg } 57834642e01fSmrg if (new->geom==NULL) 578405b261ecSmrg rep.reported&= ~XkbGBN_GeometryMask; 578505b261ecSmrg else if (rep.reported&XkbGBN_GeometryMask) { 578605b261ecSmrg grep.type= X_Reply; 578705b261ecSmrg grep.deviceID= dev->id; 578805b261ecSmrg grep.sequenceNumber= client->sequence; 578905b261ecSmrg grep.length= 0; 579005b261ecSmrg grep.found= True; 579105b261ecSmrg grep.pad= 0; 579205b261ecSmrg grep.widthMM= grep.heightMM= 0; 579305b261ecSmrg grep.nProperties= grep.nColors= grep.nShapes= 0; 579405b261ecSmrg grep.nSections= grep.nDoodads= 0; 579505b261ecSmrg grep.baseColorNdx= grep.labelColorNdx= 0; 57964642e01fSmrg XkbComputeGetGeometryReplySize(new->geom,&grep,None); 579705b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+grep.length; 579805b261ecSmrg } 579905b261ecSmrg } 580005b261ecSmrg 580105b261ecSmrg reported= rep.reported; 580205b261ecSmrg if ( client->swapped ) { 580305b261ecSmrg register int n; 580405b261ecSmrg swaps(&rep.sequenceNumber,n); 580505b261ecSmrg swapl(&rep.length,n); 580605b261ecSmrg swaps(&rep.found,n); 580705b261ecSmrg swaps(&rep.reported,n); 580805b261ecSmrg } 580905b261ecSmrg WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); 581005b261ecSmrg if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) 58114642e01fSmrg XkbSendMap(client,new,&mrep); 581205b261ecSmrg if (reported&XkbGBN_CompatMapMask) 58134642e01fSmrg XkbSendCompatMap(client,new->compat,&crep); 581405b261ecSmrg if (reported&XkbGBN_IndicatorMapMask) 58154642e01fSmrg XkbSendIndicatorMap(client,new->indicators,&irep); 581605b261ecSmrg if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) 58174642e01fSmrg XkbSendNames(client,new,&nrep); 581805b261ecSmrg if (reported&XkbGBN_GeometryMask) 58194642e01fSmrg XkbSendGeometry(client,new->geom,&grep,False); 582005b261ecSmrg if (rep.loaded) { 582105b261ecSmrg XkbDescPtr old_xkb; 582205b261ecSmrg xkbNewKeyboardNotify nkn; 582305b261ecSmrg int i,nG,nTG; 582405b261ecSmrg old_xkb= xkb; 58254642e01fSmrg xkb= new; 582605b261ecSmrg dev->key->xkbInfo->desc= xkb; 58274642e01fSmrg new= old_xkb; /* so it'll get freed automatically */ 582805b261ecSmrg 582905b261ecSmrg *xkb->ctrls= *old_xkb->ctrls; 583005b261ecSmrg for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 583105b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 583205b261ecSmrg if (nG>=XkbNumKbdGroups) { 583305b261ecSmrg nTG= XkbNumKbdGroups; 583405b261ecSmrg break; 583505b261ecSmrg } 583605b261ecSmrg if (nG>nTG) { 583705b261ecSmrg nTG= nG; 583805b261ecSmrg } 583905b261ecSmrg } 584005b261ecSmrg xkb->ctrls->num_groups= nTG; 584105b261ecSmrg 584205b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 584305b261ecSmrg if (tmpd == dev || 584405b261ecSmrg (dev->id == inputInfo.keyboard->id && tmpd->key && 584505b261ecSmrg tmpd->coreEvents)) { 584605b261ecSmrg 584705b261ecSmrg memcpy(tmpd->key->modifierMap, xkb->map->modmap, 584805b261ecSmrg xkb->max_key_code + 1); 584905b261ecSmrg if (tmpd != dev) 585005b261ecSmrg XkbCopyKeymap(dev->key->xkbInfo->desc, 585105b261ecSmrg tmpd->key->xkbInfo->desc, True); 585205b261ecSmrg XkbUpdateCoreDescription(tmpd, True); 585305b261ecSmrg 585405b261ecSmrg if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 585505b261ecSmrg old_sli = tmpd->kbdfeed->xkb_sli; 585605b261ecSmrg tmpd->kbdfeed->xkb_sli = NULL; 585705b261ecSmrg sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 585805b261ecSmrg if (sli) { 585905b261ecSmrg sli->explicitState = old_sli->explicitState; 586005b261ecSmrg sli->effectiveState = old_sli->effectiveState; 586105b261ecSmrg } 586205b261ecSmrg tmpd->kbdfeed->xkb_sli = sli; 586305b261ecSmrg XkbFreeSrvLedInfo(old_sli); 586405b261ecSmrg } 586505b261ecSmrg } 586605b261ecSmrg } 586705b261ecSmrg 586805b261ecSmrg /* this should be either a MN or an NKN, depending on whether or not 586905b261ecSmrg * the keycode range changed? */ 587005b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 58714642e01fSmrg nkn.minKeyCode= new->min_key_code; 58724642e01fSmrg nkn.maxKeyCode= new->max_key_code; 587305b261ecSmrg nkn.oldMinKeyCode= xkb->min_key_code; 587405b261ecSmrg nkn.oldMaxKeyCode= xkb->max_key_code; 587505b261ecSmrg nkn.requestMajor= XkbReqCode; 587605b261ecSmrg nkn.requestMinor= X_kbGetKbdByName; 587705b261ecSmrg nkn.changed= XkbNKN_KeycodesMask; 587805b261ecSmrg if (geom_changed) 587905b261ecSmrg nkn.changed|= XkbNKN_GeometryMask; 588005b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 588105b261ecSmrg } 58824642e01fSmrg if ((new!=NULL)&&(new!=xkb)) { 58834642e01fSmrg XkbFreeKeyboard(new,XkbAllComponentsMask,True); 58844642e01fSmrg new= NULL; 588505b261ecSmrg } 588605b261ecSmrg if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; } 588705b261ecSmrg if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; } 588805b261ecSmrg if (names.types) { _XkbFree(names.types); names.types= NULL; } 588905b261ecSmrg if (names.compat) { _XkbFree(names.compat); names.compat= NULL; } 589005b261ecSmrg if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; } 589105b261ecSmrg if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; } 589205b261ecSmrg return client->noClientException; 589305b261ecSmrg} 589405b261ecSmrg 589505b261ecSmrg/***====================================================================***/ 589605b261ecSmrg 589705b261ecSmrgstatic int 589805b261ecSmrgComputeDeviceLedInfoSize( DeviceIntPtr dev, 589905b261ecSmrg unsigned int what, 590005b261ecSmrg XkbSrvLedInfoPtr sli) 590105b261ecSmrg{ 590205b261ecSmrgint nNames,nMaps; 590305b261ecSmrgregister unsigned n,bit; 590405b261ecSmrg 590505b261ecSmrg if (sli==NULL) 590605b261ecSmrg return 0; 590705b261ecSmrg nNames= nMaps= 0; 590805b261ecSmrg if ((what&XkbXI_IndicatorNamesMask)==0) 590905b261ecSmrg sli->namesPresent= 0; 591005b261ecSmrg if ((what&XkbXI_IndicatorMapsMask)==0) 591105b261ecSmrg sli->mapsPresent= 0; 591205b261ecSmrg 591305b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 591405b261ecSmrg if (sli->names && sli->names[n]!=None) { 591505b261ecSmrg sli->namesPresent|= bit; 591605b261ecSmrg nNames++; 591705b261ecSmrg } 591805b261ecSmrg if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 591905b261ecSmrg sli->mapsPresent|= bit; 592005b261ecSmrg nMaps++; 592105b261ecSmrg } 592205b261ecSmrg } 592305b261ecSmrg return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); 592405b261ecSmrg} 592505b261ecSmrg 592605b261ecSmrgstatic int 592705b261ecSmrgCheckDeviceLedFBs( DeviceIntPtr dev, 592805b261ecSmrg int class, 592905b261ecSmrg int id, 593005b261ecSmrg xkbGetDeviceInfoReply * rep, 593105b261ecSmrg ClientPtr client) 593205b261ecSmrg{ 593305b261ecSmrgint nFBs= 0; 593405b261ecSmrgint length= 0; 593505b261ecSmrgBool classOk; 593605b261ecSmrg 593705b261ecSmrg if (class==XkbDfltXIClass) { 593805b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 593905b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 594005b261ecSmrg else { 594105b261ecSmrg client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 594205b261ecSmrg return XkbKeyboardErrorCode; 594305b261ecSmrg } 594405b261ecSmrg } 594505b261ecSmrg classOk= False; 594605b261ecSmrg if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 594705b261ecSmrg KbdFeedbackPtr kf; 594805b261ecSmrg classOk= True; 594905b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 595005b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) 595105b261ecSmrg continue; 595205b261ecSmrg nFBs++; 595305b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 595405b261ecSmrg if (!kf->xkb_sli) 595505b261ecSmrg kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); 595605b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); 595705b261ecSmrg if (id!=XkbAllXIIds) 595805b261ecSmrg break; 595905b261ecSmrg } 596005b261ecSmrg } 596105b261ecSmrg if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 596205b261ecSmrg LedFeedbackPtr lf; 596305b261ecSmrg classOk= True; 596405b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 596505b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) 596605b261ecSmrg continue; 596705b261ecSmrg nFBs++; 596805b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 596905b261ecSmrg if (!lf->xkb_sli) 597005b261ecSmrg lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); 597105b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); 597205b261ecSmrg if (id!=XkbAllXIIds) 597305b261ecSmrg break; 597405b261ecSmrg } 597505b261ecSmrg } 597605b261ecSmrg if (nFBs>0) { 597705b261ecSmrg if (rep->supported&XkbXI_IndicatorsMask) { 597805b261ecSmrg rep->nDeviceLedFBs= nFBs; 597905b261ecSmrg rep->length+= (length/4); 598005b261ecSmrg } 598105b261ecSmrg return Success; 598205b261ecSmrg } 598305b261ecSmrg if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); 598405b261ecSmrg else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 598505b261ecSmrg return XkbKeyboardErrorCode; 598605b261ecSmrg} 598705b261ecSmrg 598805b261ecSmrgstatic int 598905b261ecSmrgSendDeviceLedInfo( XkbSrvLedInfoPtr sli, 599005b261ecSmrg ClientPtr client) 599105b261ecSmrg{ 599205b261ecSmrgxkbDeviceLedsWireDesc wire; 599305b261ecSmrgint length; 599405b261ecSmrg 599505b261ecSmrg length= 0; 599605b261ecSmrg wire.ledClass= sli->class; 599705b261ecSmrg wire.ledID= sli->id; 599805b261ecSmrg wire.namesPresent= sli->namesPresent; 599905b261ecSmrg wire.mapsPresent= sli->mapsPresent; 600005b261ecSmrg wire.physIndicators= sli->physIndicators; 600105b261ecSmrg wire.state= sli->effectiveState; 600205b261ecSmrg if (client->swapped) { 600305b261ecSmrg register int n; 600405b261ecSmrg swaps(&wire.ledClass,n); 600505b261ecSmrg swaps(&wire.ledID,n); 600605b261ecSmrg swapl(&wire.namesPresent,n); 600705b261ecSmrg swapl(&wire.mapsPresent,n); 600805b261ecSmrg swapl(&wire.physIndicators,n); 600905b261ecSmrg swapl(&wire.state,n); 601005b261ecSmrg } 601105b261ecSmrg WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); 601205b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 601305b261ecSmrg if (sli->namesPresent|sli->mapsPresent) { 601405b261ecSmrg register unsigned i,bit; 601505b261ecSmrg if (sli->namesPresent) { 601605b261ecSmrg CARD32 awire; 601705b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 601805b261ecSmrg if (sli->namesPresent&bit) { 601905b261ecSmrg awire= (CARD32)sli->names[i]; 602005b261ecSmrg if (client->swapped) { 602105b261ecSmrg register int n; 602205b261ecSmrg swapl(&awire,n); 602305b261ecSmrg } 602405b261ecSmrg WriteToClient(client,4,(char *)&awire); 602505b261ecSmrg length+= 4; 602605b261ecSmrg } 602705b261ecSmrg } 602805b261ecSmrg } 602905b261ecSmrg if (sli->mapsPresent) { 603005b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 603105b261ecSmrg xkbIndicatorMapWireDesc iwire; 603205b261ecSmrg if (sli->mapsPresent&bit) { 603305b261ecSmrg iwire.flags= sli->maps[i].flags; 603405b261ecSmrg iwire.whichGroups= sli->maps[i].which_groups; 603505b261ecSmrg iwire.groups= sli->maps[i].groups; 603605b261ecSmrg iwire.whichMods= sli->maps[i].which_mods; 603705b261ecSmrg iwire.mods= sli->maps[i].mods.mask; 603805b261ecSmrg iwire.realMods= sli->maps[i].mods.real_mods; 603905b261ecSmrg iwire.virtualMods= sli->maps[i].mods.vmods; 604005b261ecSmrg iwire.ctrls= sli->maps[i].ctrls; 604105b261ecSmrg if (client->swapped) { 604205b261ecSmrg register int n; 604305b261ecSmrg swaps(&iwire.virtualMods,n); 604405b261ecSmrg swapl(&iwire.ctrls,n); 604505b261ecSmrg } 604605b261ecSmrg WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), 604705b261ecSmrg (char *)&iwire); 604805b261ecSmrg length+= SIZEOF(xkbIndicatorMapWireDesc); 604905b261ecSmrg } 605005b261ecSmrg } 605105b261ecSmrg } 605205b261ecSmrg } 605305b261ecSmrg return length; 605405b261ecSmrg} 605505b261ecSmrg 605605b261ecSmrgstatic int 605705b261ecSmrgSendDeviceLedFBs( DeviceIntPtr dev, 605805b261ecSmrg int class, 605905b261ecSmrg int id, 606005b261ecSmrg unsigned wantLength, 606105b261ecSmrg ClientPtr client) 606205b261ecSmrg{ 606305b261ecSmrgint length= 0; 606405b261ecSmrg 606505b261ecSmrg if (class==XkbDfltXIClass) { 606605b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 606705b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 606805b261ecSmrg } 606905b261ecSmrg if ((dev->kbdfeed)&& 607005b261ecSmrg ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 607105b261ecSmrg KbdFeedbackPtr kf; 607205b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 607305b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { 607405b261ecSmrg length+= SendDeviceLedInfo(kf->xkb_sli,client); 607505b261ecSmrg if (id!=XkbAllXIIds) 607605b261ecSmrg break; 607705b261ecSmrg } 607805b261ecSmrg } 607905b261ecSmrg } 608005b261ecSmrg if ((dev->leds)&& 608105b261ecSmrg ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 608205b261ecSmrg LedFeedbackPtr lf; 608305b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 608405b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { 608505b261ecSmrg length+= SendDeviceLedInfo(lf->xkb_sli,client); 608605b261ecSmrg if (id!=XkbAllXIIds) 608705b261ecSmrg break; 608805b261ecSmrg } 608905b261ecSmrg } 609005b261ecSmrg } 609105b261ecSmrg if (length==wantLength) 609205b261ecSmrg return Success; 609305b261ecSmrg else return BadLength; 609405b261ecSmrg} 609505b261ecSmrg 609605b261ecSmrgint 609705b261ecSmrgProcXkbGetDeviceInfo(ClientPtr client) 609805b261ecSmrg{ 609905b261ecSmrgDeviceIntPtr dev; 610005b261ecSmrgxkbGetDeviceInfoReply rep; 610105b261ecSmrgint status,nDeviceLedFBs; 610205b261ecSmrgunsigned length,nameLen; 610305b261ecSmrgCARD16 ledClass,ledID; 610405b261ecSmrgunsigned wanted,supported; 610505b261ecSmrgchar * str; 610605b261ecSmrg 610705b261ecSmrg REQUEST(xkbGetDeviceInfoReq); 610805b261ecSmrg REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 610905b261ecSmrg 611005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 611105b261ecSmrg return BadAccess; 611205b261ecSmrg 611305b261ecSmrg wanted= stuff->wanted; 611405b261ecSmrg 61154642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 611605b261ecSmrg CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); 611705b261ecSmrg 611805b261ecSmrg if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) 611905b261ecSmrg wanted&= ~XkbXI_ButtonActionsMask; 612005b261ecSmrg if ((!dev->kbdfeed)&&(!dev->leds)) 612105b261ecSmrg wanted&= ~XkbXI_IndicatorsMask; 612205b261ecSmrg 612305b261ecSmrg nameLen= XkbSizeCountedString(dev->name); 612405b261ecSmrg bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply)); 612505b261ecSmrg rep.type = X_Reply; 612605b261ecSmrg rep.deviceID= dev->id; 612705b261ecSmrg rep.sequenceNumber = client->sequence; 612805b261ecSmrg rep.length = nameLen/4; 612905b261ecSmrg rep.present = wanted; 613005b261ecSmrg rep.supported = XkbXI_AllDeviceFeaturesMask; 613105b261ecSmrg rep.unsupported = 0; 613205b261ecSmrg rep.firstBtnWanted = rep.nBtnsWanted = 0; 613305b261ecSmrg rep.firstBtnRtrn = rep.nBtnsRtrn = 0; 613405b261ecSmrg if (dev->button) 613505b261ecSmrg rep.totalBtns= dev->button->numButtons; 613605b261ecSmrg else rep.totalBtns= 0; 613705b261ecSmrg rep.devType= dev->type; 613805b261ecSmrg rep.hasOwnState= (dev->key && dev->key->xkbInfo); 613905b261ecSmrg rep.nDeviceLedFBs = 0; 614005b261ecSmrg if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; 614105b261ecSmrg else rep.dfltKbdFB= XkbXINone; 614205b261ecSmrg if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; 614305b261ecSmrg else rep.dfltLedFB= XkbXINone; 614405b261ecSmrg 614505b261ecSmrg ledClass= stuff->ledClass; 614605b261ecSmrg ledID= stuff->ledID; 614705b261ecSmrg 614805b261ecSmrg rep.firstBtnWanted= rep.nBtnsWanted= 0; 614905b261ecSmrg rep.firstBtnRtrn= rep.nBtnsRtrn= 0; 615005b261ecSmrg if (wanted&XkbXI_ButtonActionsMask) { 615105b261ecSmrg if (stuff->allBtns) { 615205b261ecSmrg stuff->firstBtn= 0; 615305b261ecSmrg stuff->nBtns= dev->button->numButtons; 615405b261ecSmrg } 615505b261ecSmrg 615605b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 615705b261ecSmrg client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, 615805b261ecSmrg stuff->firstBtn, 615905b261ecSmrg stuff->nBtns); 616005b261ecSmrg return BadValue; 616105b261ecSmrg } 616205b261ecSmrg else { 616305b261ecSmrg rep.firstBtnWanted= stuff->firstBtn; 616405b261ecSmrg rep.nBtnsWanted= stuff->nBtns; 616505b261ecSmrg if (dev->button->xkb_acts!=NULL) { 616605b261ecSmrg XkbAction *act; 616705b261ecSmrg register int i; 616805b261ecSmrg 616905b261ecSmrg rep.firstBtnRtrn= stuff->firstBtn; 617005b261ecSmrg rep.nBtnsRtrn= stuff->nBtns; 617105b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnWanted]; 617205b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act++) { 617305b261ecSmrg if (act->type!=XkbSA_NoAction) 617405b261ecSmrg break; 617505b261ecSmrg } 617605b261ecSmrg rep.firstBtnRtrn+= i; 617705b261ecSmrg rep.nBtnsRtrn-= i; 617805b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; 617905b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act--) { 618005b261ecSmrg if (act->type!=XkbSA_NoAction) 618105b261ecSmrg break; 618205b261ecSmrg } 618305b261ecSmrg rep.nBtnsRtrn-= i; 618405b261ecSmrg } 618505b261ecSmrg rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; 618605b261ecSmrg } 618705b261ecSmrg } 618805b261ecSmrg 618905b261ecSmrg if (wanted&XkbXI_IndicatorsMask) { 619005b261ecSmrg status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); 619105b261ecSmrg if (status!=Success) 619205b261ecSmrg return status; 619305b261ecSmrg } 619405b261ecSmrg length= rep.length*4; 619505b261ecSmrg supported= rep.supported; 619605b261ecSmrg nDeviceLedFBs = rep.nDeviceLedFBs; 619705b261ecSmrg if (client->swapped) { 619805b261ecSmrg register int n; 619905b261ecSmrg swaps(&rep.sequenceNumber,n); 620005b261ecSmrg swapl(&rep.length,n); 620105b261ecSmrg swaps(&rep.present,n); 620205b261ecSmrg swaps(&rep.supported,n); 620305b261ecSmrg swaps(&rep.unsupported,n); 620405b261ecSmrg swaps(&rep.nDeviceLedFBs,n); 620505b261ecSmrg swapl(&rep.type,n); 620605b261ecSmrg } 620705b261ecSmrg WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); 620805b261ecSmrg 62094642e01fSmrg str= (char*) xalloc(nameLen); 621005b261ecSmrg if (!str) 621105b261ecSmrg return BadAlloc; 621205b261ecSmrg XkbWriteCountedString(str,dev->name,client->swapped); 621305b261ecSmrg WriteToClient(client,nameLen,str); 62144642e01fSmrg xfree(str); 621505b261ecSmrg length-= nameLen; 621605b261ecSmrg 621705b261ecSmrg if (rep.nBtnsRtrn>0) { 621805b261ecSmrg int sz; 621905b261ecSmrg xkbActionWireDesc * awire; 622005b261ecSmrg sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); 622105b261ecSmrg awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; 622205b261ecSmrg WriteToClient(client,sz,(char *)awire); 622305b261ecSmrg length-= sz; 622405b261ecSmrg } 622505b261ecSmrg if (nDeviceLedFBs>0) { 622605b261ecSmrg status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); 622705b261ecSmrg if (status!=Success) 622805b261ecSmrg return status; 622905b261ecSmrg } 623005b261ecSmrg else if (length!=0) { 62314642e01fSmrg ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 62324642e01fSmrg ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length); 623305b261ecSmrg return BadLength; 623405b261ecSmrg } 623505b261ecSmrg if (stuff->wanted&(~supported)) { 623605b261ecSmrg xkbExtensionDeviceNotify ed; 623705b261ecSmrg bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 623805b261ecSmrg ed.ledClass= ledClass; 623905b261ecSmrg ed.ledID= ledID; 624005b261ecSmrg ed.ledsDefined= 0; 624105b261ecSmrg ed.ledState= 0; 624205b261ecSmrg ed.firstBtn= ed.nBtns= 0; 624305b261ecSmrg ed.reason= XkbXI_UnsupportedFeatureMask; 624405b261ecSmrg ed.supported= supported; 624505b261ecSmrg ed.unsupported= stuff->wanted&(~supported); 624605b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&ed); 624705b261ecSmrg } 624805b261ecSmrg return client->noClientException; 624905b261ecSmrg} 625005b261ecSmrg 625105b261ecSmrgstatic char * 625205b261ecSmrgCheckSetDeviceIndicators( char * wire, 625305b261ecSmrg DeviceIntPtr dev, 625405b261ecSmrg int num, 625505b261ecSmrg int * status_rtrn, 625605b261ecSmrg ClientPtr client) 625705b261ecSmrg{ 625805b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 625905b261ecSmrgint i; 626005b261ecSmrgXkbSrvLedInfoPtr sli; 626105b261ecSmrg 626205b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 626305b261ecSmrg for (i=0;i<num;i++) { 626405b261ecSmrg if (client->swapped) { 626505b261ecSmrg register int n; 626605b261ecSmrg swaps(&ledWire->ledClass,n); 626705b261ecSmrg swaps(&ledWire->ledID,n); 626805b261ecSmrg swapl(&ledWire->namesPresent,n); 626905b261ecSmrg swapl(&ledWire->mapsPresent,n); 627005b261ecSmrg swapl(&ledWire->physIndicators,n); 627105b261ecSmrg } 627205b261ecSmrg 627305b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 627405b261ecSmrg XkbXI_IndicatorsMask); 627505b261ecSmrg if (sli!=NULL) { 627605b261ecSmrg register int n; 627705b261ecSmrg register unsigned bit; 627805b261ecSmrg int nMaps,nNames; 627905b261ecSmrg CARD32 *atomWire; 628005b261ecSmrg xkbIndicatorMapWireDesc *mapWire; 628105b261ecSmrg 628205b261ecSmrg nMaps= nNames= 0; 628305b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 628405b261ecSmrg if (ledWire->namesPresent&bit) 628505b261ecSmrg nNames++; 628605b261ecSmrg if (ledWire->mapsPresent&bit) 628705b261ecSmrg nMaps++; 628805b261ecSmrg } 628905b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 629005b261ecSmrg if (nNames>0) { 629105b261ecSmrg for (n=0;n<nNames;n++) { 629205b261ecSmrg if (client->swapped) { 629305b261ecSmrg register int t; 629405b261ecSmrg swapl(atomWire,t); 629505b261ecSmrg } 629605b261ecSmrg CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, 629705b261ecSmrg *status_rtrn,NULL); 629805b261ecSmrg atomWire++; 629905b261ecSmrg } 630005b261ecSmrg } 630105b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 630205b261ecSmrg if (nMaps>0) { 630305b261ecSmrg for (n=0;n<nMaps;n++) { 630405b261ecSmrg if (client->swapped) { 630505b261ecSmrg register int t; 630605b261ecSmrg swaps(&mapWire->virtualMods,t); 630705b261ecSmrg swapl(&mapWire->ctrls,t); 630805b261ecSmrg } 630905b261ecSmrg CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, 631005b261ecSmrg XkbIM_UseAnyGroup, 631105b261ecSmrg client->errorValue, 631205b261ecSmrg *status_rtrn,NULL); 631305b261ecSmrg CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, 631405b261ecSmrg client->errorValue, 631505b261ecSmrg *status_rtrn,NULL); 631605b261ecSmrg mapWire++; 631705b261ecSmrg } 631805b261ecSmrg } 631905b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 632005b261ecSmrg } 632105b261ecSmrg else { 632205b261ecSmrg /* SHOULD NEVER HAPPEN */ 632305b261ecSmrg return (char *)ledWire; 632405b261ecSmrg } 632505b261ecSmrg } 632605b261ecSmrg return (char *)ledWire; 632705b261ecSmrg} 632805b261ecSmrg 632905b261ecSmrgstatic char * 633005b261ecSmrgSetDeviceIndicators( char * wire, 633105b261ecSmrg DeviceIntPtr dev, 633205b261ecSmrg unsigned changed, 633305b261ecSmrg int num, 633405b261ecSmrg int * status_rtrn, 633505b261ecSmrg ClientPtr client, 633605b261ecSmrg xkbExtensionDeviceNotify *ev) 633705b261ecSmrg{ 633805b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 633905b261ecSmrgint i; 634005b261ecSmrgXkbEventCauseRec cause; 634105b261ecSmrgunsigned namec,mapc,statec; 634205b261ecSmrgxkbExtensionDeviceNotify ed; 634305b261ecSmrgXkbChangesRec changes; 634405b261ecSmrgDeviceIntPtr kbd; 634505b261ecSmrg 634605b261ecSmrg bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 634705b261ecSmrg bzero((char *)&changes,sizeof(XkbChangesRec)); 634805b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); 634905b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 635005b261ecSmrg for (i=0;i<num;i++) { 635105b261ecSmrg register int n; 635205b261ecSmrg register unsigned bit; 635305b261ecSmrg CARD32 * atomWire; 635405b261ecSmrg xkbIndicatorMapWireDesc * mapWire; 635505b261ecSmrg XkbSrvLedInfoPtr sli; 635605b261ecSmrg 635705b261ecSmrg namec= mapc= statec= 0; 635805b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 635905b261ecSmrg XkbXI_IndicatorMapsMask); 636005b261ecSmrg if (!sli) { 636105b261ecSmrg /* SHOULD NEVER HAPPEN!! */ 636205b261ecSmrg return (char *)ledWire; 636305b261ecSmrg } 636405b261ecSmrg 636505b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 636605b261ecSmrg if (changed&XkbXI_IndicatorNamesMask) { 636705b261ecSmrg namec= sli->namesPresent|ledWire->namesPresent; 636805b261ecSmrg bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 636905b261ecSmrg } 637005b261ecSmrg if (ledWire->namesPresent) { 637105b261ecSmrg sli->namesPresent= ledWire->namesPresent; 637205b261ecSmrg bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 637305b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 637405b261ecSmrg if (ledWire->namesPresent&bit) { 637505b261ecSmrg sli->names[n]= (Atom)*atomWire; 637605b261ecSmrg if (sli->names[n]==None) 637705b261ecSmrg ledWire->namesPresent&= ~bit; 637805b261ecSmrg atomWire++; 637905b261ecSmrg } 638005b261ecSmrg } 638105b261ecSmrg } 638205b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 638305b261ecSmrg if (changed&XkbXI_IndicatorMapsMask) { 638405b261ecSmrg mapc= sli->mapsPresent|ledWire->mapsPresent; 638505b261ecSmrg sli->mapsPresent= ledWire->mapsPresent; 638605b261ecSmrg bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec)); 638705b261ecSmrg } 638805b261ecSmrg if (ledWire->mapsPresent) { 638905b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 639005b261ecSmrg if (ledWire->mapsPresent&bit) { 639105b261ecSmrg sli->maps[n].flags= mapWire->flags; 639205b261ecSmrg sli->maps[n].which_groups= mapWire->whichGroups; 639305b261ecSmrg sli->maps[n].groups= mapWire->groups; 639405b261ecSmrg sli->maps[n].which_mods= mapWire->whichMods; 639505b261ecSmrg sli->maps[n].mods.mask= mapWire->mods; 639605b261ecSmrg sli->maps[n].mods.real_mods=mapWire->realMods; 639705b261ecSmrg sli->maps[n].mods.vmods= mapWire->virtualMods; 639805b261ecSmrg sli->maps[n].ctrls= mapWire->ctrls; 639905b261ecSmrg mapWire++; 640005b261ecSmrg } 640105b261ecSmrg } 640205b261ecSmrg } 640305b261ecSmrg if (changed&XkbXI_IndicatorStateMask) { 640405b261ecSmrg statec= sli->effectiveState^ledWire->state; 640505b261ecSmrg sli->explicitState&= ~statec; 640605b261ecSmrg sli->explicitState|= (ledWire->state&statec); 640705b261ecSmrg } 640805b261ecSmrg if (namec) 640905b261ecSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 641005b261ecSmrg if (mapc) 641105b261ecSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 641205b261ecSmrg if (statec) 641305b261ecSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 641405b261ecSmrg 641505b261ecSmrg kbd= dev; 641605b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 64174642e01fSmrg kbd = inputInfo.keyboard; 641805b261ecSmrg 641905b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 642005b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 642105b261ecSmrg } 642205b261ecSmrg return (char *)ledWire; 642305b261ecSmrg} 642405b261ecSmrg 642505b261ecSmrg 64264642e01fSmrgstatic int 64274642e01fSmrg_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 64284642e01fSmrg xkbSetDeviceInfoReq *stuff) 64294642e01fSmrg{ 64304642e01fSmrg char *wire; 643105b261ecSmrg 643205b261ecSmrg wire= (char *)&stuff[1]; 64334642e01fSmrg if (stuff->change&XkbXI_ButtonActionsMask) { 643405b261ecSmrg if (!dev->button) { 643505b261ecSmrg client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); 643605b261ecSmrg return XkbKeyboardErrorCode; 643705b261ecSmrg } 643805b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 643905b261ecSmrg client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, 644005b261ecSmrg dev->button->numButtons); 644105b261ecSmrg return BadMatch; 644205b261ecSmrg } 644305b261ecSmrg wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); 644405b261ecSmrg } 644505b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 644605b261ecSmrg int status= Success; 644705b261ecSmrg wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, 644805b261ecSmrg &status,client); 644905b261ecSmrg if (status!=Success) 645005b261ecSmrg return status; 645105b261ecSmrg } 645205b261ecSmrg if (((wire-((char *)stuff))/4)!=stuff->length) 645305b261ecSmrg return BadLength; 645405b261ecSmrg 64554642e01fSmrg return Success; 64564642e01fSmrg} 64574642e01fSmrg 64584642e01fSmrgstatic int 64594642e01fSmrg_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 64604642e01fSmrg xkbSetDeviceInfoReq *stuff) 64614642e01fSmrg{ 64624642e01fSmrg char *wire; 64634642e01fSmrg xkbExtensionDeviceNotify ed; 64644642e01fSmrg 646505b261ecSmrg bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 646605b261ecSmrg ed.deviceID= dev->id; 646705b261ecSmrg wire= (char *)&stuff[1]; 64684642e01fSmrg if (stuff->change&XkbXI_ButtonActionsMask) { 646905b261ecSmrg int nBtns,sz,i; 647005b261ecSmrg XkbAction * acts; 647105b261ecSmrg DeviceIntPtr kbd; 647205b261ecSmrg 647305b261ecSmrg nBtns= dev->button->numButtons; 647405b261ecSmrg acts= dev->button->xkb_acts; 647505b261ecSmrg if (acts==NULL) { 647605b261ecSmrg acts= _XkbTypedCalloc(nBtns,XkbAction); 647705b261ecSmrg if (!acts) 647805b261ecSmrg return BadAlloc; 647905b261ecSmrg dev->button->xkb_acts= acts; 648005b261ecSmrg } 648105b261ecSmrg sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); 648205b261ecSmrg memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); 648305b261ecSmrg wire+= sz; 648405b261ecSmrg ed.reason|= XkbXI_ButtonActionsMask; 648505b261ecSmrg ed.firstBtn= stuff->firstBtn; 648605b261ecSmrg ed.nBtns= stuff->nBtns; 648705b261ecSmrg 648805b261ecSmrg if (dev->key) kbd= dev; 64894642e01fSmrg else kbd= inputInfo.keyboard; 649005b261ecSmrg acts= &dev->button->xkb_acts[stuff->firstBtn]; 649105b261ecSmrg for (i=0;i<stuff->nBtns;i++,acts++) { 649205b261ecSmrg if (acts->type!=XkbSA_NoAction) 649305b261ecSmrg XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); 649405b261ecSmrg } 649505b261ecSmrg } 649605b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 649705b261ecSmrg int status= Success; 64984642e01fSmrg wire= SetDeviceIndicators(wire,dev,stuff->change, 64994642e01fSmrg stuff->nDeviceLedFBs, &status,client,&ed); 650005b261ecSmrg if (status!=Success) 650105b261ecSmrg return status; 650205b261ecSmrg } 650305b261ecSmrg if ((stuff->change)&&(ed.reason)) 650405b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&ed); 65054642e01fSmrg return Success; 65064642e01fSmrg} 65074642e01fSmrg 65084642e01fSmrgint 65094642e01fSmrgProcXkbSetDeviceInfo(ClientPtr client) 65104642e01fSmrg{ 65114642e01fSmrg DeviceIntPtr dev; 65124642e01fSmrg int rc; 65134642e01fSmrg 65144642e01fSmrg REQUEST(xkbSetDeviceInfoReq); 65154642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 65164642e01fSmrg 65174642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 65184642e01fSmrg return BadAccess; 65194642e01fSmrg 65204642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 65214642e01fSmrg CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask); 65224642e01fSmrg 65234642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 65244642e01fSmrg 65254642e01fSmrg if (rc != Success) 65264642e01fSmrg return rc; 65274642e01fSmrg 65284642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 65294642e01fSmrg { 65304642e01fSmrg DeviceIntPtr other; 65314642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 65324642e01fSmrg { 65334642e01fSmrg if (((other != dev) && !other->isMaster && (other->u.master == dev)) && 65344642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 65354642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) 65364642e01fSmrg { 65374642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 65384642e01fSmrg if (rc == Success) 65394642e01fSmrg { 65404642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, other, stuff); 65414642e01fSmrg if (rc != Success) 65424642e01fSmrg return rc; 65434642e01fSmrg } 65444642e01fSmrg } 65454642e01fSmrg } 65464642e01fSmrg } 65474642e01fSmrg 65484642e01fSmrg /* checks done, apply */ 65494642e01fSmrg rc = _XkbSetDeviceInfo(client, dev, stuff); 65504642e01fSmrg if (rc != Success) 65514642e01fSmrg return rc; 65524642e01fSmrg 65534642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 65544642e01fSmrg { 65554642e01fSmrg DeviceIntPtr other; 65564642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 65574642e01fSmrg { 65584642e01fSmrg if (((other != dev) && !other->isMaster && (other->u.master == dev)) && 65594642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 65604642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) 65614642e01fSmrg { 65624642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 65634642e01fSmrg if (rc == Success) 65644642e01fSmrg { 65654642e01fSmrg rc = _XkbSetDeviceInfo(client, other, stuff); 65664642e01fSmrg if (rc != Success) 65674642e01fSmrg return rc; 65684642e01fSmrg } 65694642e01fSmrg } 65704642e01fSmrg } 65714642e01fSmrg } 65724642e01fSmrg 657305b261ecSmrg return client->noClientException; 657405b261ecSmrg} 657505b261ecSmrg 657605b261ecSmrg/***====================================================================***/ 657705b261ecSmrg 657805b261ecSmrgint 657905b261ecSmrgProcXkbSetDebuggingFlags(ClientPtr client) 658005b261ecSmrg{ 658105b261ecSmrgCARD32 newFlags,newCtrls,extraLength; 658205b261ecSmrgxkbSetDebuggingFlagsReply rep; 65834642e01fSmrgint rc; 658405b261ecSmrg 658505b261ecSmrg REQUEST(xkbSetDebuggingFlagsReq); 658605b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 658705b261ecSmrg 65884642e01fSmrg rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 65894642e01fSmrg if (rc != Success) 65904642e01fSmrg return rc; 65914642e01fSmrg 659205b261ecSmrg newFlags= xkbDebugFlags&(~stuff->affectFlags); 659305b261ecSmrg newFlags|= (stuff->flags&stuff->affectFlags); 659405b261ecSmrg newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); 659505b261ecSmrg newCtrls|= (stuff->ctrls&stuff->affectCtrls); 659605b261ecSmrg if (xkbDebugFlags || newFlags || stuff->msgLength) { 65974642e01fSmrg ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); 659805b261ecSmrg if (newCtrls!=xkbDebugCtrls) 65994642e01fSmrg ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); 660005b261ecSmrg } 660105b261ecSmrg extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; 660205b261ecSmrg if (stuff->msgLength>0) { 660305b261ecSmrg char *msg; 660405b261ecSmrg if (extraLength<XkbPaddedSize(stuff->msgLength)) { 66054642e01fSmrg ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 660605b261ecSmrg stuff->msgLength,(long)extraLength, 660705b261ecSmrg XkbPaddedSize(stuff->msgLength)); 660805b261ecSmrg return BadLength; 660905b261ecSmrg } 661005b261ecSmrg msg= (char *)&stuff[1]; 661105b261ecSmrg if (msg[stuff->msgLength-1]!='\0') { 66124642e01fSmrg ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 661305b261ecSmrg return BadValue; 661405b261ecSmrg } 66154642e01fSmrg ErrorF("[xkb] XkbDebug: %s\n",msg); 661605b261ecSmrg } 661705b261ecSmrg xkbDebugFlags = newFlags; 661805b261ecSmrg xkbDebugCtrls = newCtrls; 661905b261ecSmrg 662005b261ecSmrg XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks); 662105b261ecSmrg 662205b261ecSmrg rep.type= X_Reply; 662305b261ecSmrg rep.length = 0; 662405b261ecSmrg rep.sequenceNumber = client->sequence; 662505b261ecSmrg rep.currentFlags = newFlags; 662605b261ecSmrg rep.currentCtrls = newCtrls; 662705b261ecSmrg rep.supportedFlags = ~0; 662805b261ecSmrg rep.supportedCtrls = ~0; 662905b261ecSmrg if ( client->swapped ) { 663005b261ecSmrg register int n; 663105b261ecSmrg swaps(&rep.sequenceNumber, n); 663205b261ecSmrg swapl(&rep.currentFlags, n); 663305b261ecSmrg swapl(&rep.currentCtrls, n); 663405b261ecSmrg swapl(&rep.supportedFlags, n); 663505b261ecSmrg swapl(&rep.supportedCtrls, n); 663605b261ecSmrg } 663705b261ecSmrg WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); 663805b261ecSmrg return client->noClientException; 663905b261ecSmrg} 664005b261ecSmrg 664105b261ecSmrg/***====================================================================***/ 664205b261ecSmrg 664305b261ecSmrgstatic int 664405b261ecSmrgProcXkbDispatch (ClientPtr client) 664505b261ecSmrg{ 664605b261ecSmrg REQUEST(xReq); 664705b261ecSmrg switch (stuff->data) 664805b261ecSmrg { 664905b261ecSmrg case X_kbUseExtension: 665005b261ecSmrg return ProcXkbUseExtension(client); 665105b261ecSmrg case X_kbSelectEvents: 665205b261ecSmrg return ProcXkbSelectEvents(client); 665305b261ecSmrg case X_kbBell: 665405b261ecSmrg return ProcXkbBell(client); 665505b261ecSmrg case X_kbGetState: 665605b261ecSmrg return ProcXkbGetState(client); 665705b261ecSmrg case X_kbLatchLockState: 665805b261ecSmrg return ProcXkbLatchLockState(client); 665905b261ecSmrg case X_kbGetControls: 666005b261ecSmrg return ProcXkbGetControls(client); 666105b261ecSmrg case X_kbSetControls: 666205b261ecSmrg return ProcXkbSetControls(client); 666305b261ecSmrg case X_kbGetMap: 666405b261ecSmrg return ProcXkbGetMap(client); 666505b261ecSmrg case X_kbSetMap: 666605b261ecSmrg return ProcXkbSetMap(client); 666705b261ecSmrg case X_kbGetCompatMap: 666805b261ecSmrg return ProcXkbGetCompatMap(client); 666905b261ecSmrg case X_kbSetCompatMap: 667005b261ecSmrg return ProcXkbSetCompatMap(client); 667105b261ecSmrg case X_kbGetIndicatorState: 667205b261ecSmrg return ProcXkbGetIndicatorState(client); 667305b261ecSmrg case X_kbGetIndicatorMap: 667405b261ecSmrg return ProcXkbGetIndicatorMap(client); 667505b261ecSmrg case X_kbSetIndicatorMap: 667605b261ecSmrg return ProcXkbSetIndicatorMap(client); 667705b261ecSmrg case X_kbGetNamedIndicator: 667805b261ecSmrg return ProcXkbGetNamedIndicator(client); 667905b261ecSmrg case X_kbSetNamedIndicator: 668005b261ecSmrg return ProcXkbSetNamedIndicator(client); 668105b261ecSmrg case X_kbGetNames: 668205b261ecSmrg return ProcXkbGetNames(client); 668305b261ecSmrg case X_kbSetNames: 668405b261ecSmrg return ProcXkbSetNames(client); 668505b261ecSmrg case X_kbGetGeometry: 668605b261ecSmrg return ProcXkbGetGeometry(client); 668705b261ecSmrg case X_kbSetGeometry: 668805b261ecSmrg return ProcXkbSetGeometry(client); 668905b261ecSmrg case X_kbPerClientFlags: 669005b261ecSmrg return ProcXkbPerClientFlags(client); 669105b261ecSmrg case X_kbListComponents: 669205b261ecSmrg return ProcXkbListComponents(client); 669305b261ecSmrg case X_kbGetKbdByName: 669405b261ecSmrg return ProcXkbGetKbdByName(client); 669505b261ecSmrg case X_kbGetDeviceInfo: 669605b261ecSmrg return ProcXkbGetDeviceInfo(client); 669705b261ecSmrg case X_kbSetDeviceInfo: 669805b261ecSmrg return ProcXkbSetDeviceInfo(client); 669905b261ecSmrg case X_kbSetDebuggingFlags: 670005b261ecSmrg return ProcXkbSetDebuggingFlags(client); 670105b261ecSmrg default: 670205b261ecSmrg return BadRequest; 670305b261ecSmrg } 670405b261ecSmrg} 670505b261ecSmrg 670605b261ecSmrgstatic int 670705b261ecSmrgXkbClientGone(pointer data,XID id) 670805b261ecSmrg{ 670905b261ecSmrg DevicePtr pXDev = (DevicePtr)data; 671005b261ecSmrg 671105b261ecSmrg if (!XkbRemoveResourceClient(pXDev,id)) { 67124642e01fSmrg ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 671305b261ecSmrg } 671405b261ecSmrg return 1; 671505b261ecSmrg} 671605b261ecSmrg 671705b261ecSmrgvoid 671805b261ecSmrgXkbExtensionInit(void) 671905b261ecSmrg{ 672005b261ecSmrg ExtensionEntry *extEntry; 672105b261ecSmrg 672205b261ecSmrg if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 672305b261ecSmrg ProcXkbDispatch, SProcXkbDispatch, 67244642e01fSmrg NULL, StandardMinorOpcode))) { 672505b261ecSmrg XkbReqCode = (unsigned char)extEntry->base; 672605b261ecSmrg XkbEventBase = (unsigned char)extEntry->eventBase; 672705b261ecSmrg XkbErrorBase = (unsigned char)extEntry->errorBase; 672805b261ecSmrg XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; 672905b261ecSmrg RT_XKBCLIENT = CreateNewResourceType(XkbClientGone); 673005b261ecSmrg } 673105b261ecSmrg return; 673205b261ecSmrg} 673305b261ecSmrg 673405b261ecSmrg 6735