xkb.c revision 1e26616a
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#include <X11/Xproto.h> 3405b261ecSmrg#include "misc.h" 3505b261ecSmrg#include "inputstr.h" 3605b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 3705b261ecSmrg#include <xkbsrv.h> 3805b261ecSmrg#include "extnsionst.h" 394642e01fSmrg#include "xace.h" 4005b261ecSmrg#include "xkb.h" 416747b715Smrg#include "protocol-versions.h" 4205b261ecSmrg 4305b261ecSmrg#include <X11/extensions/XI.h> 446747b715Smrg#include <X11/extensions/XKMformat.h> 4505b261ecSmrg 466747b715Smrgint XkbEventBase; 4705b261ecSmrgstatic int XkbErrorBase; 486747b715Smrgint XkbReqCode; 496747b715Smrgint XkbKeyboardErrorCode; 506747b715SmrgCARD32 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); 1656747b715Smrg if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) { 16605b261ecSmrg /* pre-release version 0.65 is compatible with 1.00 */ 1676747b715Smrg supported= ((SERVER_XKB_MAJOR_VERSION==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, 1826747b715Smrg SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION); 18305b261ecSmrg } 1846747b715Smrg memset(&rep, 0, sizeof(xkbUseExtensionReply)); 18505b261ecSmrg rep.type = X_Reply; 18605b261ecSmrg rep.supported = supported; 18705b261ecSmrg rep.length = 0; 18805b261ecSmrg rep.sequenceNumber = client->sequence; 1896747b715Smrg rep.serverMajor = SERVER_XKB_MAJOR_VERSION; 1906747b715Smrg rep.serverMinor = SERVER_XKB_MINOR_VERSION; 19105b261ecSmrg if ( client->swapped ) { 19205b261ecSmrg swaps(&rep.sequenceNumber, n); 19305b261ecSmrg swaps(&rep.serverMajor, n); 19405b261ecSmrg swaps(&rep.serverMinor, n); 19505b261ecSmrg } 19605b261ecSmrg WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep); 1976747b715Smrg return Success; 19805b261ecSmrg} 19905b261ecSmrg 20005b261ecSmrg/***====================================================================***/ 20105b261ecSmrg 20205b261ecSmrgint 20305b261ecSmrgProcXkbSelectEvents(ClientPtr client) 20405b261ecSmrg{ 20505b261ecSmrg unsigned legal; 20605b261ecSmrg DeviceIntPtr dev; 20705b261ecSmrg XkbInterestPtr masks; 20805b261ecSmrg REQUEST(xkbSelectEventsReq); 20905b261ecSmrg 21005b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); 21105b261ecSmrg 21205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 21305b261ecSmrg return BadAccess; 21405b261ecSmrg 2154642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess); 21605b261ecSmrg 21705b261ecSmrg if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) { 21805b261ecSmrg client->mapNotifyMask&= ~stuff->affectMap; 21905b261ecSmrg client->mapNotifyMask|= (stuff->affectMap&stuff->map); 22005b261ecSmrg } 22105b261ecSmrg if ((stuff->affectWhich&(~XkbMapNotifyMask))==0) 2226747b715Smrg return Success; 22305b261ecSmrg 22405b261ecSmrg masks = XkbFindClientResource((DevicePtr)dev,client); 22505b261ecSmrg if (!masks){ 22605b261ecSmrg XID id = FakeClientID(client->index); 2276747b715Smrg if (!AddResource(id,RT_XKBCLIENT,dev)) 2286747b715Smrg return BadAlloc; 22905b261ecSmrg masks= XkbAddClientResource((DevicePtr)dev,client,id); 23005b261ecSmrg } 23105b261ecSmrg if (masks) { 23205b261ecSmrg union { 23305b261ecSmrg CARD8 *c8; 23405b261ecSmrg CARD16 *c16; 23505b261ecSmrg CARD32 *c32; 23605b261ecSmrg } from,to; 23705b261ecSmrg register unsigned bit,ndx,maskLeft,dataLeft,size; 23805b261ecSmrg 23905b261ecSmrg from.c8= (CARD8 *)&stuff[1]; 24005b261ecSmrg dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq); 24105b261ecSmrg maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask)); 24205b261ecSmrg for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) { 24305b261ecSmrg if ((bit&maskLeft)==0) 24405b261ecSmrg continue; 24505b261ecSmrg maskLeft&= ~bit; 24605b261ecSmrg switch (ndx) { 24705b261ecSmrg case XkbNewKeyboardNotify: 24805b261ecSmrg to.c16= &client->newKeyboardNotifyMask; 24905b261ecSmrg legal= XkbAllNewKeyboardEventsMask; 25005b261ecSmrg size= 2; 25105b261ecSmrg break; 25205b261ecSmrg case XkbStateNotify: 25305b261ecSmrg to.c16= &masks->stateNotifyMask; 25405b261ecSmrg legal= XkbAllStateEventsMask; 25505b261ecSmrg size= 2; 25605b261ecSmrg break; 25705b261ecSmrg case XkbControlsNotify: 25805b261ecSmrg to.c32= &masks->ctrlsNotifyMask; 25905b261ecSmrg legal= XkbAllControlEventsMask; 26005b261ecSmrg size= 4; 26105b261ecSmrg break; 26205b261ecSmrg case XkbIndicatorStateNotify: 26305b261ecSmrg to.c32= &masks->iStateNotifyMask; 26405b261ecSmrg legal= XkbAllIndicatorEventsMask; 26505b261ecSmrg size= 4; 26605b261ecSmrg break; 26705b261ecSmrg case XkbIndicatorMapNotify: 26805b261ecSmrg to.c32= &masks->iMapNotifyMask; 26905b261ecSmrg legal= XkbAllIndicatorEventsMask; 27005b261ecSmrg size= 4; 27105b261ecSmrg break; 27205b261ecSmrg case XkbNamesNotify: 27305b261ecSmrg to.c16= &masks->namesNotifyMask; 27405b261ecSmrg legal= XkbAllNameEventsMask; 27505b261ecSmrg size= 2; 27605b261ecSmrg break; 27705b261ecSmrg case XkbCompatMapNotify: 27805b261ecSmrg to.c8= &masks->compatNotifyMask; 27905b261ecSmrg legal= XkbAllCompatMapEventsMask; 28005b261ecSmrg size= 1; 28105b261ecSmrg break; 28205b261ecSmrg case XkbBellNotify: 28305b261ecSmrg to.c8= &masks->bellNotifyMask; 28405b261ecSmrg legal= XkbAllBellEventsMask; 28505b261ecSmrg size= 1; 28605b261ecSmrg break; 28705b261ecSmrg case XkbActionMessage: 28805b261ecSmrg to.c8= &masks->actionMessageMask; 28905b261ecSmrg legal= XkbAllActionMessagesMask; 29005b261ecSmrg size= 1; 29105b261ecSmrg break; 29205b261ecSmrg case XkbAccessXNotify: 29305b261ecSmrg to.c16= &masks->accessXNotifyMask; 29405b261ecSmrg legal= XkbAllAccessXEventsMask; 29505b261ecSmrg size= 2; 29605b261ecSmrg break; 29705b261ecSmrg case XkbExtensionDeviceNotify: 29805b261ecSmrg to.c16= &masks->extDevNotifyMask; 29905b261ecSmrg legal= XkbAllExtensionDeviceEventsMask; 30005b261ecSmrg size= 2; 30105b261ecSmrg break; 30205b261ecSmrg default: 30305b261ecSmrg client->errorValue = _XkbErrCode2(33,bit); 30405b261ecSmrg return BadValue; 30505b261ecSmrg } 30605b261ecSmrg 30705b261ecSmrg if (stuff->clear&bit) { 30805b261ecSmrg if (size==2) to.c16[0]= 0; 30905b261ecSmrg else if (size==4) to.c32[0]= 0; 31005b261ecSmrg else to.c8[0]= 0; 31105b261ecSmrg } 31205b261ecSmrg else if (stuff->selectAll&bit) { 31305b261ecSmrg if (size==2) to.c16[0]= ~0; 31405b261ecSmrg else if (size==4) to.c32[0]= ~0; 31505b261ecSmrg else to.c8[0]= ~0; 31605b261ecSmrg } 31705b261ecSmrg else { 31805b261ecSmrg if (dataLeft<(size*2)) 31905b261ecSmrg return BadLength; 32005b261ecSmrg if (size==2) { 32105b261ecSmrg CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]); 32205b261ecSmrg CHK_MASK_LEGAL(ndx,from.c16[0],legal); 32305b261ecSmrg to.c16[0]&= ~from.c16[0]; 32405b261ecSmrg to.c16[0]|= (from.c16[0]&from.c16[1]); 32505b261ecSmrg } 32605b261ecSmrg else if (size==4) { 32705b261ecSmrg CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]); 32805b261ecSmrg CHK_MASK_LEGAL(ndx,from.c32[0],legal); 32905b261ecSmrg to.c32[0]&= ~from.c32[0]; 33005b261ecSmrg to.c32[0]|= (from.c32[0]&from.c32[1]); 33105b261ecSmrg } 33205b261ecSmrg else { 33305b261ecSmrg CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]); 33405b261ecSmrg CHK_MASK_LEGAL(ndx,from.c8[0],legal); 33505b261ecSmrg to.c8[0]&= ~from.c8[0]; 33605b261ecSmrg to.c8[0]|= (from.c8[0]&from.c8[1]); 33705b261ecSmrg size= 2; 33805b261ecSmrg } 33905b261ecSmrg from.c8+= (size*2); 34005b261ecSmrg dataLeft-= (size*2); 34105b261ecSmrg } 34205b261ecSmrg } 34305b261ecSmrg if (dataLeft>2) { 3444642e01fSmrg ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft); 34505b261ecSmrg return BadLength; 34605b261ecSmrg } 3476747b715Smrg return Success; 34805b261ecSmrg } 34905b261ecSmrg return BadAlloc; 35005b261ecSmrg} 35105b261ecSmrg 35205b261ecSmrg/***====================================================================***/ 3534642e01fSmrg/** 3544642e01fSmrg * Ring a bell on the given device for the given client. 3554642e01fSmrg */ 3564642e01fSmrgstatic int 3574642e01fSmrg_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, 3584642e01fSmrg int bellClass, int bellID, int pitch, int duration, 3594642e01fSmrg int percent, int forceSound, int eventOnly, Atom name) 3604642e01fSmrg{ 3614642e01fSmrg int base; 3624642e01fSmrg pointer ctrl; 3634642e01fSmrg int oldPitch, oldDuration; 3644642e01fSmrg int newPercent; 3654642e01fSmrg 3664642e01fSmrg if (bellClass == KbdFeedbackClass) { 3674642e01fSmrg KbdFeedbackPtr k; 3684642e01fSmrg if (bellID==XkbDfltXIId) 3694642e01fSmrg k= dev->kbdfeed; 3704642e01fSmrg else { 3714642e01fSmrg for (k=dev->kbdfeed; k; k=k->next) { 3724642e01fSmrg if (k->ctrl.id == bellID) 3734642e01fSmrg break; 3744642e01fSmrg } 3754642e01fSmrg } 3764642e01fSmrg if (!k) { 3774642e01fSmrg client->errorValue = _XkbErrCode2(0x5,bellID); 3784642e01fSmrg return BadValue; 3794642e01fSmrg } 3804642e01fSmrg base = k->ctrl.bell; 3814642e01fSmrg ctrl = (pointer) &(k->ctrl); 3824642e01fSmrg oldPitch= k->ctrl.bell_pitch; 3834642e01fSmrg oldDuration= k->ctrl.bell_duration; 3844642e01fSmrg if (pitch!=0) { 3854642e01fSmrg if (pitch==-1) 3864642e01fSmrg k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; 3874642e01fSmrg else k->ctrl.bell_pitch= pitch; 3884642e01fSmrg } 3894642e01fSmrg if (duration!=0) { 3904642e01fSmrg if (duration==-1) 3914642e01fSmrg k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; 3924642e01fSmrg else k->ctrl.bell_duration= duration; 3934642e01fSmrg } 3944642e01fSmrg } 3954642e01fSmrg else if (bellClass == BellFeedbackClass) { 3964642e01fSmrg BellFeedbackPtr b; 3974642e01fSmrg if (bellID==XkbDfltXIId) 3984642e01fSmrg b= dev->bell; 3994642e01fSmrg else { 4004642e01fSmrg for (b=dev->bell; b; b=b->next) { 4014642e01fSmrg if (b->ctrl.id == bellID) 4024642e01fSmrg break; 4034642e01fSmrg } 4044642e01fSmrg } 4054642e01fSmrg if (!b) { 4064642e01fSmrg client->errorValue = _XkbErrCode2(0x6,bellID); 4074642e01fSmrg return BadValue; 4084642e01fSmrg } 4094642e01fSmrg base = b->ctrl.percent; 4104642e01fSmrg ctrl = (pointer) &(b->ctrl); 4114642e01fSmrg oldPitch= b->ctrl.pitch; 4124642e01fSmrg oldDuration= b->ctrl.duration; 4134642e01fSmrg if (pitch!=0) { 4144642e01fSmrg if (pitch==-1) 4154642e01fSmrg b->ctrl.pitch= defaultKeyboardControl.bell_pitch; 4164642e01fSmrg else b->ctrl.pitch= pitch; 4174642e01fSmrg } 4184642e01fSmrg if (duration!=0) { 4194642e01fSmrg if (duration==-1) 4204642e01fSmrg b->ctrl.duration= defaultKeyboardControl.bell_duration; 4214642e01fSmrg else b->ctrl.duration= duration; 4224642e01fSmrg } 4234642e01fSmrg } 4244642e01fSmrg else { 4254642e01fSmrg client->errorValue = _XkbErrCode2(0x7, bellClass); 4264642e01fSmrg return BadValue; 4274642e01fSmrg } 4284642e01fSmrg 4294642e01fSmrg newPercent = (base * percent)/100; 4304642e01fSmrg if (percent < 0) 4314642e01fSmrg newPercent = base + newPercent; 4324642e01fSmrg else newPercent = base - newPercent + percent; 4334642e01fSmrg 4344642e01fSmrg XkbHandleBell(forceSound, eventOnly, 4354642e01fSmrg dev, newPercent, ctrl, bellClass, 4364642e01fSmrg name, pWin, client); 4374642e01fSmrg if ((pitch!=0)||(duration!=0)) { 4384642e01fSmrg if (bellClass == KbdFeedbackClass) { 4394642e01fSmrg KbdFeedbackPtr k; 4404642e01fSmrg k= (KbdFeedbackPtr)ctrl; 4414642e01fSmrg if (pitch!=0) 4424642e01fSmrg k->ctrl.bell_pitch= oldPitch; 4434642e01fSmrg if (duration!=0) 4444642e01fSmrg k->ctrl.bell_duration= oldDuration; 4454642e01fSmrg } 4464642e01fSmrg else { 4474642e01fSmrg BellFeedbackPtr b; 4484642e01fSmrg b= (BellFeedbackPtr)ctrl; 4494642e01fSmrg if (pitch!=0) 4504642e01fSmrg b->ctrl.pitch= oldPitch; 4514642e01fSmrg if (duration!=0) 4524642e01fSmrg b->ctrl.duration= oldDuration; 4534642e01fSmrg } 4544642e01fSmrg } 4554642e01fSmrg 4564642e01fSmrg return Success; 4574642e01fSmrg} 45805b261ecSmrg 45905b261ecSmrgint 46005b261ecSmrgProcXkbBell(ClientPtr client) 46105b261ecSmrg{ 46205b261ecSmrg REQUEST(xkbBellReq); 46305b261ecSmrg DeviceIntPtr dev; 46405b261ecSmrg WindowPtr pWin; 4654642e01fSmrg int rc; 46605b261ecSmrg 46705b261ecSmrg REQUEST_SIZE_MATCH(xkbBellReq); 46805b261ecSmrg 46905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 47005b261ecSmrg return BadAccess; 47105b261ecSmrg 4724642e01fSmrg CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); 47305b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 47405b261ecSmrg 4754642e01fSmrg /* device-independent checks request for sane values */ 47605b261ecSmrg if ((stuff->forceSound)&&(stuff->eventOnly)) { 47705b261ecSmrg client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); 47805b261ecSmrg return BadMatch; 47905b261ecSmrg } 48005b261ecSmrg if (stuff->percent < -100 || stuff->percent > 100) { 48105b261ecSmrg client->errorValue = _XkbErrCode2(0x2,stuff->percent); 48205b261ecSmrg return BadValue; 48305b261ecSmrg } 48405b261ecSmrg if (stuff->duration<-1) { 48505b261ecSmrg client->errorValue = _XkbErrCode2(0x3,stuff->duration); 48605b261ecSmrg return BadValue; 48705b261ecSmrg } 48805b261ecSmrg if (stuff->pitch<-1) { 48905b261ecSmrg client->errorValue = _XkbErrCode2(0x4,stuff->pitch); 49005b261ecSmrg return BadValue; 49105b261ecSmrg } 49205b261ecSmrg 49305b261ecSmrg if (stuff->bellClass == XkbDfltXIClass) { 49405b261ecSmrg if (dev->kbdfeed!=NULL) 49505b261ecSmrg stuff->bellClass= KbdFeedbackClass; 49605b261ecSmrg else stuff->bellClass= BellFeedbackClass; 49705b261ecSmrg } 4984642e01fSmrg 49905b261ecSmrg if (stuff->window!=None) { 5004642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 5014642e01fSmrg if (rc != Success) { 50205b261ecSmrg client->errorValue= stuff->window; 5034642e01fSmrg return rc; 50405b261ecSmrg } 50505b261ecSmrg } 50605b261ecSmrg else pWin= NULL; 50705b261ecSmrg 5084642e01fSmrg /* Client wants to ring a bell on the core keyboard? 5094642e01fSmrg Ring the bell on the core keyboard (which does nothing, but if that 5104642e01fSmrg fails the client is screwed anyway), and then on all extension devices. 5114642e01fSmrg Fail if the core keyboard fails but not the extension devices. this 5124642e01fSmrg may cause some keyboards to ding and others to stay silent. Fix 5134642e01fSmrg your client to use explicit keyboards to avoid this. 5144642e01fSmrg 5154642e01fSmrg dev is the device the client requested. 5164642e01fSmrg */ 5174642e01fSmrg rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, 5184642e01fSmrg stuff->pitch, stuff->duration, stuff->percent, 5194642e01fSmrg stuff->forceSound, stuff->eventOnly, stuff->name); 5204642e01fSmrg 5214642e01fSmrg if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || 5224642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr))) 5234642e01fSmrg { 5244642e01fSmrg DeviceIntPtr other; 5254642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 5264642e01fSmrg { 5276747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 5284642e01fSmrg { 5294642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); 5304642e01fSmrg if (rc == Success) 5314642e01fSmrg _XkbBell(client, other, pWin, stuff->bellClass, 5324642e01fSmrg stuff->bellID, stuff->pitch, stuff->duration, 5334642e01fSmrg stuff->percent, stuff->forceSound, 5344642e01fSmrg stuff->eventOnly, stuff->name); 5354642e01fSmrg } 5364642e01fSmrg } 5374642e01fSmrg rc = Success; /* reset to success, that's what we got for the VCK */ 53805b261ecSmrg } 5394642e01fSmrg 5404642e01fSmrg return rc; 54105b261ecSmrg} 54205b261ecSmrg 54305b261ecSmrg/***====================================================================***/ 54405b261ecSmrg 54505b261ecSmrgint 54605b261ecSmrgProcXkbGetState(ClientPtr client) 54705b261ecSmrg{ 54805b261ecSmrg REQUEST(xkbGetStateReq); 54905b261ecSmrg DeviceIntPtr dev; 55005b261ecSmrg xkbGetStateReply rep; 55105b261ecSmrg XkbStateRec *xkb; 55205b261ecSmrg 55305b261ecSmrg REQUEST_SIZE_MATCH(xkbGetStateReq); 55405b261ecSmrg 55505b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 55605b261ecSmrg return BadAccess; 55705b261ecSmrg 5586747b715Smrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 55905b261ecSmrg 56005b261ecSmrg xkb= &dev->key->xkbInfo->state; 5616747b715Smrg memset(&rep, 0, sizeof(xkbGetStateReply)); 56205b261ecSmrg rep.type= X_Reply; 56305b261ecSmrg rep.sequenceNumber= client->sequence; 56405b261ecSmrg rep.length = 0; 56505b261ecSmrg rep.deviceID = dev->id; 5666747b715Smrg rep.mods = XkbStateFieldFromRec(xkb) & 0xff; 56705b261ecSmrg rep.baseMods = xkb->base_mods; 56805b261ecSmrg rep.lockedMods = xkb->locked_mods; 56905b261ecSmrg rep.latchedMods = xkb->latched_mods; 57005b261ecSmrg rep.group = xkb->group; 57105b261ecSmrg rep.baseGroup = xkb->base_group; 57205b261ecSmrg rep.latchedGroup = xkb->latched_group; 57305b261ecSmrg rep.lockedGroup = xkb->locked_group; 57405b261ecSmrg rep.compatState = xkb->compat_state; 57505b261ecSmrg rep.ptrBtnState = xkb->ptr_buttons; 57605b261ecSmrg if (client->swapped) { 57705b261ecSmrg register int n; 57805b261ecSmrg swaps(&rep.sequenceNumber,n); 57905b261ecSmrg swaps(&rep.ptrBtnState,n); 58005b261ecSmrg } 58105b261ecSmrg WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep); 5826747b715Smrg return Success; 58305b261ecSmrg} 58405b261ecSmrg 58505b261ecSmrg/***====================================================================***/ 58605b261ecSmrg 58705b261ecSmrgint 58805b261ecSmrgProcXkbLatchLockState(ClientPtr client) 58905b261ecSmrg{ 59005b261ecSmrg int status; 59105b261ecSmrg DeviceIntPtr dev, tmpd; 59205b261ecSmrg XkbStateRec oldState,*newState; 59305b261ecSmrg CARD16 changed; 59405b261ecSmrg xkbStateNotify sn; 59505b261ecSmrg XkbEventCauseRec cause; 59605b261ecSmrg 59705b261ecSmrg REQUEST(xkbLatchLockStateReq); 59805b261ecSmrg REQUEST_SIZE_MATCH(xkbLatchLockStateReq); 59905b261ecSmrg 60005b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 60105b261ecSmrg return BadAccess; 60205b261ecSmrg 6034642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 60405b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); 60505b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); 60605b261ecSmrg 60705b261ecSmrg status = Success; 60805b261ecSmrg 60905b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 6106747b715Smrg if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 6116747b715Smrg if (!tmpd->key || !tmpd->key->xkbInfo) 61205b261ecSmrg continue; 61305b261ecSmrg 61405b261ecSmrg oldState = tmpd->key->xkbInfo->state; 61505b261ecSmrg newState = &tmpd->key->xkbInfo->state; 61605b261ecSmrg if (stuff->affectModLocks) { 61705b261ecSmrg newState->locked_mods &= ~stuff->affectModLocks; 61805b261ecSmrg newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks); 61905b261ecSmrg } 62005b261ecSmrg if (status == Success && stuff->lockGroup) 62105b261ecSmrg newState->locked_group = stuff->groupLock; 62205b261ecSmrg if (status == Success && stuff->affectModLatches) 62305b261ecSmrg status = XkbLatchModifiers(tmpd, stuff->affectModLatches, 62405b261ecSmrg stuff->modLatches); 62505b261ecSmrg if (status == Success && stuff->latchGroup) 62605b261ecSmrg status = XkbLatchGroup(tmpd, stuff->groupLatch); 62705b261ecSmrg 62805b261ecSmrg if (status != Success) 62905b261ecSmrg return status; 63005b261ecSmrg 63105b261ecSmrg XkbComputeDerivedState(tmpd->key->xkbInfo); 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); 6416747b715Smrg changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE); 64205b261ecSmrg if (changed) { 64305b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); 6446747b715Smrg XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause); 64505b261ecSmrg } 64605b261ecSmrg } 64705b261ecSmrg } 64805b261ecSmrg } 64905b261ecSmrg 6506747b715Smrg return Success; 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; 6736747b715Smrg rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)- 6746747b715Smrg SIZEOF(xGenericReply)); 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); 7266747b715Smrg return Success; 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 7496747b715Smrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 7506747b715Smrg if (!tmpd->key || !tmpd->key->xkbInfo) 7516747b715Smrg continue; 7526747b715Smrg if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 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 9189ace9065Smrg if (stuff->changeCtrls & XkbPerKeyRepeatMask) { 91905b261ecSmrg memcpy(new.per_key_repeat, stuff->perKeyRepeat, 92005b261ecSmrg XkbPerKeyBitArraySize); 9219ace9065Smrg if (xkbi->repeatKey && 9229ace9065Smrg !BitIsOn(new.per_key_repeat, xkbi->repeatKey)) { 9239ace9065Smrg AccessXCancelRepeatKey(xkbi, xkbi->repeatKey); 9249ace9065Smrg } 9259ace9065Smrg } 92605b261ecSmrg 92705b261ecSmrg old= *ctrl; 92805b261ecSmrg *ctrl= new; 92905b261ecSmrg XkbDDXChangeControls(tmpd, &old, ctrl); 93005b261ecSmrg 9316747b715Smrg if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) { 93205b261ecSmrg cn.keycode = 0; 93305b261ecSmrg cn.eventType = 0; 93405b261ecSmrg cn.requestMajor = XkbReqCode; 93505b261ecSmrg cn.requestMinor = X_kbSetControls; 93605b261ecSmrg XkbSendControlsNotify(tmpd, &cn); 93705b261ecSmrg } 93805b261ecSmrg 93905b261ecSmrg sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); 94005b261ecSmrg if (sli) 9416747b715Smrg XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL, 94205b261ecSmrg &cause); 94305b261ecSmrg 94405b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 94505b261ecSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 94605b261ecSmrg !(ctrl->enabled_ctrls & XkbStickyKeysMask)) 9476747b715Smrg XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause); 94805b261ecSmrg } 94905b261ecSmrg } 95005b261ecSmrg 9516747b715Smrg return Success; 95205b261ecSmrg} 95305b261ecSmrg 95405b261ecSmrg/***====================================================================***/ 95505b261ecSmrg 95605b261ecSmrgstatic int 95705b261ecSmrgXkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep) 95805b261ecSmrg{ 95905b261ecSmrg XkbKeyTypeRec *type; 96005b261ecSmrg unsigned i,len; 96105b261ecSmrg 96205b261ecSmrg len= 0; 96305b261ecSmrg if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)|| 96405b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->types)) { 96505b261ecSmrg rep->present&= ~XkbKeyTypesMask; 96605b261ecSmrg rep->firstType= rep->nTypes= 0; 96705b261ecSmrg return 0; 96805b261ecSmrg } 96905b261ecSmrg type= &xkb->map->types[rep->firstType]; 97005b261ecSmrg for (i=0;i<rep->nTypes;i++,type++){ 97105b261ecSmrg len+= SIZEOF(xkbKeyTypeWireDesc); 97205b261ecSmrg if (type->map_count>0) { 97305b261ecSmrg len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc)); 97405b261ecSmrg if (type->preserve) 97505b261ecSmrg len+= (type->map_count*SIZEOF(xkbModsWireDesc)); 97605b261ecSmrg } 97705b261ecSmrg } 97805b261ecSmrg return len; 97905b261ecSmrg} 98005b261ecSmrg 98105b261ecSmrgstatic char * 98205b261ecSmrgXkbWriteKeyTypes( XkbDescPtr xkb, 98305b261ecSmrg xkbGetMapReply * rep, 98405b261ecSmrg char * buf, 98505b261ecSmrg ClientPtr client) 98605b261ecSmrg{ 98705b261ecSmrg XkbKeyTypePtr type; 98805b261ecSmrg unsigned i; 98905b261ecSmrg xkbKeyTypeWireDesc *wire; 99005b261ecSmrg 99105b261ecSmrg type= &xkb->map->types[rep->firstType]; 99205b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 99305b261ecSmrg register unsigned n; 99405b261ecSmrg wire= (xkbKeyTypeWireDesc *)buf; 99505b261ecSmrg wire->mask = type->mods.mask; 99605b261ecSmrg wire->realMods = type->mods.real_mods; 99705b261ecSmrg wire->virtualMods = type->mods.vmods; 99805b261ecSmrg wire->numLevels = type->num_levels; 99905b261ecSmrg wire->nMapEntries = type->map_count; 100005b261ecSmrg wire->preserve = (type->preserve!=NULL); 100105b261ecSmrg if (client->swapped) { 100205b261ecSmrg register int n; 100305b261ecSmrg swaps(&wire->virtualMods,n); 100405b261ecSmrg } 100505b261ecSmrg 100605b261ecSmrg buf= (char *)&wire[1]; 100705b261ecSmrg if (wire->nMapEntries>0) { 100805b261ecSmrg xkbKTMapEntryWireDesc * wire; 100905b261ecSmrg XkbKTMapEntryPtr entry; 101005b261ecSmrg wire= (xkbKTMapEntryWireDesc *)buf; 101105b261ecSmrg entry= type->map; 101205b261ecSmrg for (n=0;n<type->map_count;n++,wire++,entry++) { 101305b261ecSmrg wire->active= entry->active; 101405b261ecSmrg wire->mask= entry->mods.mask; 101505b261ecSmrg wire->level= entry->level; 101605b261ecSmrg wire->realMods= entry->mods.real_mods; 101705b261ecSmrg wire->virtualMods= entry->mods.vmods; 101805b261ecSmrg if (client->swapped) { 101905b261ecSmrg register int n; 102005b261ecSmrg swaps(&wire->virtualMods,n); 102105b261ecSmrg } 102205b261ecSmrg } 102305b261ecSmrg buf= (char *)wire; 102405b261ecSmrg if (type->preserve!=NULL) { 102505b261ecSmrg xkbModsWireDesc * pwire; 102605b261ecSmrg XkbModsPtr preserve; 102705b261ecSmrg pwire= (xkbModsWireDesc *)buf; 102805b261ecSmrg preserve= type->preserve; 102905b261ecSmrg for (n=0;n<type->map_count;n++,pwire++,preserve++) { 103005b261ecSmrg pwire->mask= preserve->mask; 103105b261ecSmrg pwire->realMods= preserve->real_mods; 103205b261ecSmrg pwire->virtualMods= preserve->vmods; 103305b261ecSmrg if (client->swapped) { 103405b261ecSmrg register int n; 103505b261ecSmrg swaps(&pwire->virtualMods,n); 103605b261ecSmrg } 103705b261ecSmrg } 103805b261ecSmrg buf= (char *)pwire; 103905b261ecSmrg } 104005b261ecSmrg } 104105b261ecSmrg } 104205b261ecSmrg return buf; 104305b261ecSmrg} 104405b261ecSmrg 104505b261ecSmrgstatic int 104605b261ecSmrgXkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep) 104705b261ecSmrg{ 104805b261ecSmrg XkbSymMapPtr symMap; 104905b261ecSmrg unsigned i,len; 105005b261ecSmrg unsigned nSyms,nSymsThisKey; 105105b261ecSmrg 105205b261ecSmrg if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)|| 105305b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) { 105405b261ecSmrg rep->present&= ~XkbKeySymsMask; 105505b261ecSmrg rep->firstKeySym= rep->nKeySyms= 0; 105605b261ecSmrg rep->totalSyms= 0; 105705b261ecSmrg return 0; 105805b261ecSmrg } 105905b261ecSmrg len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc); 106005b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 106105b261ecSmrg for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) { 106205b261ecSmrg if (symMap->offset!=0) { 106305b261ecSmrg nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width; 106405b261ecSmrg nSyms+= nSymsThisKey; 106505b261ecSmrg } 106605b261ecSmrg } 106705b261ecSmrg len+= nSyms*4; 106805b261ecSmrg rep->totalSyms= nSyms; 106905b261ecSmrg return len; 107005b261ecSmrg} 107105b261ecSmrg 107205b261ecSmrgstatic int 107305b261ecSmrgXkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep) 107405b261ecSmrg{ 107505b261ecSmrgregister unsigned i,nMods,bit; 107605b261ecSmrg 107705b261ecSmrg if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)|| 107805b261ecSmrg (!xkb)||(!xkb->server)) { 107905b261ecSmrg rep->present&= ~XkbVirtualModsMask; 108005b261ecSmrg rep->virtualMods= 0; 108105b261ecSmrg return 0; 108205b261ecSmrg } 108305b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 108405b261ecSmrg if (rep->virtualMods&bit) 108505b261ecSmrg nMods++; 108605b261ecSmrg } 108705b261ecSmrg return XkbPaddedSize(nMods); 108805b261ecSmrg} 108905b261ecSmrg 109005b261ecSmrgstatic char * 109105b261ecSmrgXkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 109205b261ecSmrg{ 109305b261ecSmrgregister KeySym * pSym; 109405b261ecSmrgXkbSymMapPtr symMap; 109505b261ecSmrgxkbSymMapWireDesc * outMap; 109605b261ecSmrgregister unsigned i; 109705b261ecSmrg 109805b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 109905b261ecSmrg for (i=0;i<rep->nKeySyms;i++,symMap++) { 110005b261ecSmrg outMap = (xkbSymMapWireDesc *)buf; 110105b261ecSmrg outMap->ktIndex[0] = symMap->kt_index[0]; 110205b261ecSmrg outMap->ktIndex[1] = symMap->kt_index[1]; 110305b261ecSmrg outMap->ktIndex[2] = symMap->kt_index[2]; 110405b261ecSmrg outMap->ktIndex[3] = symMap->kt_index[3]; 110505b261ecSmrg outMap->groupInfo = symMap->group_info; 110605b261ecSmrg outMap->width= symMap->width; 110705b261ecSmrg outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info); 110805b261ecSmrg buf= (char *)&outMap[1]; 110905b261ecSmrg if (outMap->nSyms==0) 111005b261ecSmrg continue; 111105b261ecSmrg 111205b261ecSmrg pSym = &xkb->map->syms[symMap->offset]; 111305b261ecSmrg memcpy((char *)buf,(char *)pSym,outMap->nSyms*4); 111405b261ecSmrg if (client->swapped) { 111505b261ecSmrg register int n,nSyms= outMap->nSyms; 111605b261ecSmrg swaps(&outMap->nSyms,n); 111705b261ecSmrg while (nSyms-->0) { 111805b261ecSmrg swapl(buf,n); 111905b261ecSmrg buf+= 4; 112005b261ecSmrg } 112105b261ecSmrg } 112205b261ecSmrg else buf+= outMap->nSyms*4; 112305b261ecSmrg } 112405b261ecSmrg return buf; 112505b261ecSmrg} 112605b261ecSmrg 112705b261ecSmrgstatic int 112805b261ecSmrgXkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep) 112905b261ecSmrg{ 113005b261ecSmrg unsigned i,len,nActs; 113105b261ecSmrg register KeyCode firstKey; 113205b261ecSmrg 113305b261ecSmrg if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)|| 113405b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) { 113505b261ecSmrg rep->present&= ~XkbKeyActionsMask; 113605b261ecSmrg rep->firstKeyAct= rep->nKeyActs= 0; 113705b261ecSmrg rep->totalActs= 0; 113805b261ecSmrg return 0; 113905b261ecSmrg } 114005b261ecSmrg firstKey= rep->firstKeyAct; 114105b261ecSmrg for (nActs=i=0;i<rep->nKeyActs;i++) { 114205b261ecSmrg if (xkb->server->key_acts[i+firstKey]!=0) 114305b261ecSmrg nActs+= XkbKeyNumActions(xkb,i+firstKey); 114405b261ecSmrg } 114505b261ecSmrg len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); 114605b261ecSmrg rep->totalActs= nActs; 114705b261ecSmrg return len; 114805b261ecSmrg} 114905b261ecSmrg 115005b261ecSmrgstatic char * 115105b261ecSmrgXkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 115205b261ecSmrg ClientPtr client) 115305b261ecSmrg{ 115405b261ecSmrg unsigned i; 115505b261ecSmrg CARD8 * numDesc; 115605b261ecSmrg XkbAnyAction * actDesc; 115705b261ecSmrg 115805b261ecSmrg numDesc = (CARD8 *)buf; 115905b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 116005b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]==0) 116105b261ecSmrg numDesc[i] = 0; 116205b261ecSmrg else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 116305b261ecSmrg } 116405b261ecSmrg buf+= XkbPaddedSize(rep->nKeyActs); 116505b261ecSmrg 116605b261ecSmrg actDesc = (XkbAnyAction *)buf; 116705b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 116805b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) { 116905b261ecSmrg unsigned int num; 117005b261ecSmrg num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 117105b261ecSmrg memcpy((char *)actDesc, 117205b261ecSmrg (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)), 117305b261ecSmrg num*SIZEOF(xkbActionWireDesc)); 117405b261ecSmrg actDesc+= num; 117505b261ecSmrg } 117605b261ecSmrg } 117705b261ecSmrg buf = (char *)actDesc; 117805b261ecSmrg return buf; 117905b261ecSmrg} 118005b261ecSmrg 118105b261ecSmrgstatic int 118205b261ecSmrgXkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep) 118305b261ecSmrg{ 118405b261ecSmrg unsigned i,len,nBhvr; 118505b261ecSmrg XkbBehavior * bhv; 118605b261ecSmrg 118705b261ecSmrg if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)|| 118805b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) { 118905b261ecSmrg rep->present&= ~XkbKeyBehaviorsMask; 119005b261ecSmrg rep->firstKeyBehavior= rep->nKeyBehaviors= 0; 119105b261ecSmrg rep->totalKeyBehaviors= 0; 119205b261ecSmrg return 0; 119305b261ecSmrg } 119405b261ecSmrg bhv= &xkb->server->behaviors[rep->firstKeyBehavior]; 119505b261ecSmrg for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) { 119605b261ecSmrg if (bhv->type!=XkbKB_Default) 119705b261ecSmrg nBhvr++; 119805b261ecSmrg } 119905b261ecSmrg len= nBhvr*SIZEOF(xkbBehaviorWireDesc); 120005b261ecSmrg rep->totalKeyBehaviors= nBhvr; 120105b261ecSmrg return len; 120205b261ecSmrg} 120305b261ecSmrg 120405b261ecSmrgstatic char * 120505b261ecSmrgXkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 120605b261ecSmrg ClientPtr client) 120705b261ecSmrg{ 120805b261ecSmrg unsigned i; 120905b261ecSmrg xkbBehaviorWireDesc *wire; 121005b261ecSmrg XkbBehavior *pBhvr; 121105b261ecSmrg 121205b261ecSmrg wire = (xkbBehaviorWireDesc *)buf; 121305b261ecSmrg pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior]; 121405b261ecSmrg for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) { 121505b261ecSmrg if (pBhvr->type!=XkbKB_Default) { 121605b261ecSmrg wire->key= i+rep->firstKeyBehavior; 121705b261ecSmrg wire->type= pBhvr->type; 121805b261ecSmrg wire->data= pBhvr->data; 121905b261ecSmrg wire++; 122005b261ecSmrg } 122105b261ecSmrg } 122205b261ecSmrg buf = (char *)wire; 122305b261ecSmrg return buf; 122405b261ecSmrg} 122505b261ecSmrg 122605b261ecSmrgstatic int 122705b261ecSmrgXkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep) 122805b261ecSmrg{ 122905b261ecSmrg unsigned i,len,nRtrn; 123005b261ecSmrg 123105b261ecSmrg if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)|| 123205b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->explicit)) { 123305b261ecSmrg rep->present&= ~XkbExplicitComponentsMask; 123405b261ecSmrg rep->firstKeyExplicit= rep->nKeyExplicit= 0; 123505b261ecSmrg rep->totalKeyExplicit= 0; 123605b261ecSmrg return 0; 123705b261ecSmrg } 123805b261ecSmrg for (nRtrn=i=0;i<rep->nKeyExplicit;i++) { 123905b261ecSmrg if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0) 124005b261ecSmrg nRtrn++; 124105b261ecSmrg } 124205b261ecSmrg rep->totalKeyExplicit= nRtrn; 124305b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */ 124405b261ecSmrg return len; 124505b261ecSmrg} 124605b261ecSmrg 124705b261ecSmrgstatic char * 124805b261ecSmrgXkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 124905b261ecSmrg{ 125005b261ecSmrgunsigned i; 125105b261ecSmrgchar * start; 125205b261ecSmrgunsigned char * pExp; 125305b261ecSmrg 125405b261ecSmrg start= buf; 125505b261ecSmrg pExp= &xkb->server->explicit[rep->firstKeyExplicit]; 125605b261ecSmrg for (i=0;i<rep->nKeyExplicit;i++,pExp++) { 125705b261ecSmrg if (*pExp!=0) { 125805b261ecSmrg *buf++= i+rep->firstKeyExplicit; 125905b261ecSmrg *buf++= *pExp; 126005b261ecSmrg } 126105b261ecSmrg } 126205b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 126305b261ecSmrg return buf+i; 126405b261ecSmrg} 126505b261ecSmrg 126605b261ecSmrgstatic int 126705b261ecSmrgXkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep) 126805b261ecSmrg{ 126905b261ecSmrg unsigned i,len,nRtrn; 127005b261ecSmrg 127105b261ecSmrg if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)|| 127205b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->modmap)) { 127305b261ecSmrg rep->present&= ~XkbModifierMapMask; 127405b261ecSmrg rep->firstModMapKey= rep->nModMapKeys= 0; 127505b261ecSmrg rep->totalModMapKeys= 0; 127605b261ecSmrg return 0; 127705b261ecSmrg } 127805b261ecSmrg for (nRtrn=i=0;i<rep->nModMapKeys;i++) { 127905b261ecSmrg if (xkb->map->modmap[i+rep->firstModMapKey]!=0) 128005b261ecSmrg nRtrn++; 128105b261ecSmrg } 128205b261ecSmrg rep->totalModMapKeys= nRtrn; 128305b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */ 128405b261ecSmrg return len; 128505b261ecSmrg} 128605b261ecSmrg 128705b261ecSmrgstatic char * 128805b261ecSmrgXkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 128905b261ecSmrg ClientPtr client) 129005b261ecSmrg{ 129105b261ecSmrgunsigned i; 129205b261ecSmrgchar * start; 129305b261ecSmrgunsigned char * pMap; 129405b261ecSmrg 129505b261ecSmrg start= buf; 129605b261ecSmrg pMap= &xkb->map->modmap[rep->firstModMapKey]; 129705b261ecSmrg for (i=0;i<rep->nModMapKeys;i++,pMap++) { 129805b261ecSmrg if (*pMap!=0) { 129905b261ecSmrg *buf++= i+rep->firstModMapKey; 130005b261ecSmrg *buf++= *pMap; 130105b261ecSmrg } 130205b261ecSmrg } 130305b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 130405b261ecSmrg return buf+i; 130505b261ecSmrg} 130605b261ecSmrg 130705b261ecSmrgstatic int 130805b261ecSmrgXkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep) 130905b261ecSmrg{ 131005b261ecSmrg unsigned i,len,nRtrn; 131105b261ecSmrg 131205b261ecSmrg if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)|| 131305b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) { 131405b261ecSmrg rep->present&= ~XkbVirtualModMapMask; 131505b261ecSmrg rep->firstVModMapKey= rep->nVModMapKeys= 0; 131605b261ecSmrg rep->totalVModMapKeys= 0; 131705b261ecSmrg return 0; 131805b261ecSmrg } 131952397711Smrg for (nRtrn=i=0;i<rep->nVModMapKeys;i++) { 132005b261ecSmrg if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0) 132105b261ecSmrg nRtrn++; 132205b261ecSmrg } 132305b261ecSmrg rep->totalVModMapKeys= nRtrn; 132405b261ecSmrg len= nRtrn*SIZEOF(xkbVModMapWireDesc); 132505b261ecSmrg return len; 132605b261ecSmrg} 132705b261ecSmrg 132805b261ecSmrgstatic char * 132905b261ecSmrgXkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 133005b261ecSmrg ClientPtr client) 133105b261ecSmrg{ 133205b261ecSmrgunsigned i; 133305b261ecSmrgxkbVModMapWireDesc * wire; 133405b261ecSmrgunsigned short * pMap; 133505b261ecSmrg 133605b261ecSmrg wire= (xkbVModMapWireDesc *)buf; 133705b261ecSmrg pMap= &xkb->server->vmodmap[rep->firstVModMapKey]; 133852397711Smrg for (i=0;i<rep->nVModMapKeys;i++,pMap++) { 133905b261ecSmrg if (*pMap!=0) { 134005b261ecSmrg wire->key= i+rep->firstVModMapKey; 134105b261ecSmrg wire->vmods= *pMap; 134205b261ecSmrg wire++; 134305b261ecSmrg } 134405b261ecSmrg } 134505b261ecSmrg return (char *)wire; 134605b261ecSmrg} 134705b261ecSmrg 134805b261ecSmrgstatic Status 134905b261ecSmrgXkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep) 135005b261ecSmrg{ 135105b261ecSmrgint len; 135205b261ecSmrg 135305b261ecSmrg rep->minKeyCode= xkb->min_key_code; 135405b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 135505b261ecSmrg len= XkbSizeKeyTypes(xkb,rep); 135605b261ecSmrg len+= XkbSizeKeySyms(xkb,rep); 135705b261ecSmrg len+= XkbSizeKeyActions(xkb,rep); 135805b261ecSmrg len+= XkbSizeKeyBehaviors(xkb,rep); 135905b261ecSmrg len+= XkbSizeVirtualMods(xkb,rep); 136005b261ecSmrg len+= XkbSizeExplicit(xkb,rep); 136105b261ecSmrg len+= XkbSizeModifierMap(xkb,rep); 136205b261ecSmrg len+= XkbSizeVirtualModMap(xkb,rep); 136305b261ecSmrg rep->length+= (len/4); 136405b261ecSmrg return Success; 136505b261ecSmrg} 136605b261ecSmrg 136705b261ecSmrgstatic int 136805b261ecSmrgXkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep) 136905b261ecSmrg{ 137005b261ecSmrgunsigned i,len; 137105b261ecSmrgchar *desc,*start; 137205b261ecSmrg 137305b261ecSmrg len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)); 13746747b715Smrg start= desc= calloc(1, len); 137505b261ecSmrg if (!start) 137605b261ecSmrg return BadAlloc; 137705b261ecSmrg if ( rep->nTypes>0 ) 137805b261ecSmrg desc = XkbWriteKeyTypes(xkb,rep,desc,client); 137905b261ecSmrg if ( rep->nKeySyms>0 ) 138005b261ecSmrg desc = XkbWriteKeySyms(xkb,rep,desc,client); 138105b261ecSmrg if ( rep->nKeyActs>0 ) 138205b261ecSmrg desc = XkbWriteKeyActions(xkb,rep,desc,client); 138305b261ecSmrg if ( rep->totalKeyBehaviors>0 ) 138405b261ecSmrg desc = XkbWriteKeyBehaviors(xkb,rep,desc,client); 138505b261ecSmrg if ( rep->virtualMods ) { 138605b261ecSmrg register int sz,bit; 138705b261ecSmrg for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 138805b261ecSmrg if (rep->virtualMods&bit) { 138905b261ecSmrg desc[sz++]= xkb->server->vmods[i]; 139005b261ecSmrg } 139105b261ecSmrg } 139205b261ecSmrg desc+= XkbPaddedSize(sz); 139305b261ecSmrg } 139405b261ecSmrg if ( rep->totalKeyExplicit>0 ) 139505b261ecSmrg desc= XkbWriteExplicit(xkb,rep,desc,client); 139605b261ecSmrg if ( rep->totalModMapKeys>0 ) 139705b261ecSmrg desc= XkbWriteModifierMap(xkb,rep,desc,client); 139805b261ecSmrg if ( rep->totalVModMapKeys>0 ) 139905b261ecSmrg desc= XkbWriteVirtualModMap(xkb,rep,desc,client); 140005b261ecSmrg if ((desc-start)!=(len)) { 14014642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", 140205b261ecSmrg len, (unsigned long)(desc-start)); 140305b261ecSmrg } 140405b261ecSmrg if (client->swapped) { 140505b261ecSmrg register int n; 140605b261ecSmrg swaps(&rep->sequenceNumber,n); 140705b261ecSmrg swapl(&rep->length,n); 140805b261ecSmrg swaps(&rep->present,n); 140905b261ecSmrg swaps(&rep->totalSyms,n); 141005b261ecSmrg swaps(&rep->totalActs,n); 141105b261ecSmrg } 141205b261ecSmrg WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep); 141305b261ecSmrg WriteToClient(client, len, start); 14146747b715Smrg free((char *)start); 14156747b715Smrg return Success; 141605b261ecSmrg} 141705b261ecSmrg 141805b261ecSmrgint 141905b261ecSmrgProcXkbGetMap(ClientPtr client) 142005b261ecSmrg{ 142105b261ecSmrg DeviceIntPtr dev; 142205b261ecSmrg xkbGetMapReply rep; 142305b261ecSmrg XkbDescRec *xkb; 142405b261ecSmrg int n,status; 142505b261ecSmrg 142605b261ecSmrg REQUEST(xkbGetMapReq); 142705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetMapReq); 142805b261ecSmrg 142905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 143005b261ecSmrg return BadAccess; 143105b261ecSmrg 14324642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 143305b261ecSmrg CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial); 143405b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask); 143505b261ecSmrg CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask); 143605b261ecSmrg 143705b261ecSmrg xkb= dev->key->xkbInfo->desc; 14386747b715Smrg memset(&rep, 0, sizeof(xkbGetMapReply)); 143905b261ecSmrg rep.type= X_Reply; 144005b261ecSmrg rep.sequenceNumber= client->sequence; 144105b261ecSmrg rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2; 144205b261ecSmrg rep.deviceID = dev->id; 144305b261ecSmrg rep.present = stuff->partial|stuff->full; 144405b261ecSmrg rep.minKeyCode = xkb->min_key_code; 144505b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 144605b261ecSmrg if ( stuff->full&XkbKeyTypesMask ) { 144705b261ecSmrg rep.firstType = 0; 144805b261ecSmrg rep.nTypes = xkb->map->num_types; 144905b261ecSmrg } 145005b261ecSmrg else if (stuff->partial&XkbKeyTypesMask) { 145105b261ecSmrg if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) { 145205b261ecSmrg client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types, 145305b261ecSmrg stuff->firstType,stuff->nTypes); 145405b261ecSmrg return BadValue; 145505b261ecSmrg } 145605b261ecSmrg rep.firstType = stuff->firstType; 145705b261ecSmrg rep.nTypes = stuff->nTypes; 145805b261ecSmrg } 145905b261ecSmrg else rep.nTypes = 0; 146005b261ecSmrg rep.totalTypes = xkb->map->num_types; 146105b261ecSmrg 146205b261ecSmrg n= XkbNumKeys(xkb); 146305b261ecSmrg if ( stuff->full&XkbKeySymsMask ) { 146405b261ecSmrg rep.firstKeySym = xkb->min_key_code; 146505b261ecSmrg rep.nKeySyms = n; 146605b261ecSmrg } 146705b261ecSmrg else if (stuff->partial&XkbKeySymsMask) { 146805b261ecSmrg CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb); 146905b261ecSmrg rep.firstKeySym = stuff->firstKeySym; 147005b261ecSmrg rep.nKeySyms = stuff->nKeySyms; 147105b261ecSmrg } 147205b261ecSmrg else rep.nKeySyms = 0; 147305b261ecSmrg rep.totalSyms= 0; 147405b261ecSmrg 147505b261ecSmrg if ( stuff->full&XkbKeyActionsMask ) { 147605b261ecSmrg rep.firstKeyAct= xkb->min_key_code; 147705b261ecSmrg rep.nKeyActs= n; 147805b261ecSmrg } 147905b261ecSmrg else if (stuff->partial&XkbKeyActionsMask) { 148005b261ecSmrg CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb); 148105b261ecSmrg rep.firstKeyAct= stuff->firstKeyAct; 148205b261ecSmrg rep.nKeyActs= stuff->nKeyActs; 148305b261ecSmrg } 148405b261ecSmrg else rep.nKeyActs= 0; 148505b261ecSmrg rep.totalActs= 0; 148605b261ecSmrg 148705b261ecSmrg if ( stuff->full&XkbKeyBehaviorsMask ) { 148805b261ecSmrg rep.firstKeyBehavior = xkb->min_key_code; 148905b261ecSmrg rep.nKeyBehaviors = n; 149005b261ecSmrg } 149105b261ecSmrg else if (stuff->partial&XkbKeyBehaviorsMask) { 149205b261ecSmrg CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb); 149305b261ecSmrg rep.firstKeyBehavior= stuff->firstKeyBehavior; 149405b261ecSmrg rep.nKeyBehaviors= stuff->nKeyBehaviors; 149505b261ecSmrg } 149605b261ecSmrg else rep.nKeyBehaviors = 0; 149705b261ecSmrg rep.totalKeyBehaviors= 0; 149805b261ecSmrg 149905b261ecSmrg if (stuff->full&XkbVirtualModsMask) 150005b261ecSmrg rep.virtualMods= ~0; 150105b261ecSmrg else if (stuff->partial&XkbVirtualModsMask) 150205b261ecSmrg rep.virtualMods= stuff->virtualMods; 150305b261ecSmrg 150405b261ecSmrg if (stuff->full&XkbExplicitComponentsMask) { 150505b261ecSmrg rep.firstKeyExplicit= xkb->min_key_code; 150605b261ecSmrg rep.nKeyExplicit= n; 150705b261ecSmrg } 150805b261ecSmrg else if (stuff->partial&XkbExplicitComponentsMask) { 150905b261ecSmrg CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb); 151005b261ecSmrg rep.firstKeyExplicit= stuff->firstKeyExplicit; 151105b261ecSmrg rep.nKeyExplicit= stuff->nKeyExplicit; 151205b261ecSmrg } 151305b261ecSmrg else rep.nKeyExplicit = 0; 151405b261ecSmrg rep.totalKeyExplicit= 0; 151505b261ecSmrg 151605b261ecSmrg if (stuff->full&XkbModifierMapMask) { 151705b261ecSmrg rep.firstModMapKey= xkb->min_key_code; 151805b261ecSmrg rep.nModMapKeys= n; 151905b261ecSmrg } 152005b261ecSmrg else if (stuff->partial&XkbModifierMapMask) { 152105b261ecSmrg CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb); 152205b261ecSmrg rep.firstModMapKey= stuff->firstModMapKey; 152305b261ecSmrg rep.nModMapKeys= stuff->nModMapKeys; 152405b261ecSmrg } 152505b261ecSmrg else rep.nModMapKeys = 0; 152605b261ecSmrg rep.totalModMapKeys= 0; 152705b261ecSmrg 152805b261ecSmrg if (stuff->full&XkbVirtualModMapMask) { 152905b261ecSmrg rep.firstVModMapKey= xkb->min_key_code; 153005b261ecSmrg rep.nVModMapKeys= n; 153105b261ecSmrg } 153205b261ecSmrg else if (stuff->partial&XkbVirtualModMapMask) { 153305b261ecSmrg CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb); 153405b261ecSmrg rep.firstVModMapKey= stuff->firstVModMapKey; 153505b261ecSmrg rep.nVModMapKeys= stuff->nVModMapKeys; 153605b261ecSmrg } 153705b261ecSmrg else rep.nVModMapKeys = 0; 153805b261ecSmrg rep.totalVModMapKeys= 0; 153905b261ecSmrg 154005b261ecSmrg if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success) 154105b261ecSmrg return status; 154205b261ecSmrg return XkbSendMap(client,xkb,&rep); 154305b261ecSmrg} 154405b261ecSmrg 154505b261ecSmrg/***====================================================================***/ 154605b261ecSmrg 154705b261ecSmrgstatic int 154805b261ecSmrgCheckKeyTypes( ClientPtr client, 154905b261ecSmrg XkbDescPtr xkb, 155005b261ecSmrg xkbSetMapReq * req, 155105b261ecSmrg xkbKeyTypeWireDesc **wireRtrn, 155205b261ecSmrg int * nMapsRtrn, 155305b261ecSmrg CARD8 * mapWidthRtrn) 155405b261ecSmrg{ 155505b261ecSmrgunsigned nMaps; 155605b261ecSmrgregister unsigned i,n; 155705b261ecSmrgregister CARD8 * map; 155805b261ecSmrgregister xkbKeyTypeWireDesc *wire = *wireRtrn; 155905b261ecSmrg 156005b261ecSmrg if (req->firstType>((unsigned)xkb->map->num_types)) { 156105b261ecSmrg *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types); 156205b261ecSmrg return 0; 156305b261ecSmrg } 156405b261ecSmrg if (req->flags&XkbSetMapResizeTypes) { 156505b261ecSmrg nMaps = req->firstType+req->nTypes; 156605b261ecSmrg if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */ 156705b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4); 156805b261ecSmrg return 0; 156905b261ecSmrg } 157005b261ecSmrg } 157105b261ecSmrg else if (req->present&XkbKeyTypesMask) { 157205b261ecSmrg nMaps = xkb->map->num_types; 157305b261ecSmrg if ((req->firstType+req->nTypes)>nMaps) { 157405b261ecSmrg *nMapsRtrn = req->firstType+req->nTypes; 157505b261ecSmrg return 0; 157605b261ecSmrg } 157705b261ecSmrg } 157805b261ecSmrg else { 157905b261ecSmrg *nMapsRtrn = xkb->map->num_types; 158005b261ecSmrg for (i=0;i<xkb->map->num_types;i++) { 158105b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 158205b261ecSmrg } 158305b261ecSmrg return 1; 158405b261ecSmrg } 158505b261ecSmrg 158605b261ecSmrg for (i=0;i<req->firstType;i++) { 158705b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 158805b261ecSmrg } 158905b261ecSmrg for (i=0;i<req->nTypes;i++) { 159005b261ecSmrg unsigned width; 159105b261ecSmrg if (client->swapped) { 159205b261ecSmrg register int s; 159305b261ecSmrg swaps(&wire->virtualMods,s); 159405b261ecSmrg } 159505b261ecSmrg n= i+req->firstType; 159605b261ecSmrg width= wire->numLevels; 159705b261ecSmrg if (width<1) { 159805b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x04,n,width); 159905b261ecSmrg return 0; 160005b261ecSmrg } 160105b261ecSmrg else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */ 160205b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 160305b261ecSmrg return 0; 160405b261ecSmrg } 160505b261ecSmrg else if ((width!=2)&& 160605b261ecSmrg ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)|| 160705b261ecSmrg (n==XkbAlphabeticIndex))) { 160805b261ecSmrg /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ 160905b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 161005b261ecSmrg return 0; 161105b261ecSmrg } 161205b261ecSmrg if (wire->nMapEntries>0) { 161305b261ecSmrg xkbKTSetMapEntryWireDesc * mapWire; 161405b261ecSmrg xkbModsWireDesc * preWire; 161505b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1]; 161605b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 161705b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 161805b261ecSmrg if (client->swapped) { 161905b261ecSmrg register int s; 162005b261ecSmrg swaps(&mapWire[n].virtualMods,s); 162105b261ecSmrg } 162205b261ecSmrg if (mapWire[n].realMods&(~wire->realMods)) { 162305b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods, 162405b261ecSmrg wire->realMods); 162505b261ecSmrg return 0; 162605b261ecSmrg } 162705b261ecSmrg if (mapWire[n].virtualMods&(~wire->virtualMods)) { 162805b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods); 162905b261ecSmrg return 0; 163005b261ecSmrg } 163105b261ecSmrg if (mapWire[n].level>=wire->numLevels) { 163205b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels, 163305b261ecSmrg mapWire[n].level); 163405b261ecSmrg return 0; 163505b261ecSmrg } 163605b261ecSmrg if (wire->preserve) { 163705b261ecSmrg if (client->swapped) { 163805b261ecSmrg register int s; 163905b261ecSmrg swaps(&preWire[n].virtualMods,s); 164005b261ecSmrg } 164105b261ecSmrg if (preWire[n].realMods&(~mapWire[n].realMods)) { 164205b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods, 164305b261ecSmrg mapWire[n].realMods); 164405b261ecSmrg return 0; 164505b261ecSmrg } 164605b261ecSmrg if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) { 164705b261ecSmrg *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods); 164805b261ecSmrg return 0; 164905b261ecSmrg } 165005b261ecSmrg } 165105b261ecSmrg } 165205b261ecSmrg if (wire->preserve) 165305b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 165405b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 165505b261ecSmrg } 165605b261ecSmrg else map= (CARD8 *)&wire[1]; 165705b261ecSmrg mapWidthRtrn[i+req->firstType] = wire->numLevels; 165805b261ecSmrg wire= (xkbKeyTypeWireDesc *)map; 165905b261ecSmrg } 166005b261ecSmrg for (i=req->firstType+req->nTypes;i<nMaps;i++) { 166105b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 166205b261ecSmrg } 166305b261ecSmrg *nMapsRtrn = nMaps; 166405b261ecSmrg *wireRtrn = wire; 166505b261ecSmrg return 1; 166605b261ecSmrg} 166705b261ecSmrg 166805b261ecSmrgstatic int 166905b261ecSmrgCheckKeySyms( ClientPtr client, 167005b261ecSmrg XkbDescPtr xkb, 167105b261ecSmrg xkbSetMapReq * req, 167205b261ecSmrg int nTypes, 167305b261ecSmrg CARD8 * mapWidths, 167405b261ecSmrg CARD16 * symsPerKey, 167505b261ecSmrg xkbSymMapWireDesc ** wireRtrn, 167605b261ecSmrg int * errorRtrn) 167705b261ecSmrg{ 167805b261ecSmrgregister unsigned i; 167905b261ecSmrgXkbSymMapPtr map; 168005b261ecSmrgxkbSymMapWireDesc* wire = *wireRtrn; 168105b261ecSmrg 168205b261ecSmrg if (!(XkbKeySymsMask&req->present)) 168305b261ecSmrg return 1; 168405b261ecSmrg CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0); 168505b261ecSmrg for (i=0;i<req->nKeySyms;i++) { 168605b261ecSmrg KeySym *pSyms; 168705b261ecSmrg register unsigned nG; 168805b261ecSmrg if (client->swapped) { 168905b261ecSmrg swaps(&wire->nSyms,nG); 169005b261ecSmrg } 169105b261ecSmrg nG = XkbNumGroups(wire->groupInfo); 169205b261ecSmrg if (nG>XkbNumKbdGroups) { 169305b261ecSmrg *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG); 169405b261ecSmrg return 0; 169505b261ecSmrg } 169605b261ecSmrg if (nG>0) { 169705b261ecSmrg register int g,w; 169805b261ecSmrg for (g=w=0;g<nG;g++) { 169905b261ecSmrg if (wire->ktIndex[g]>=(unsigned)nTypes) { 170005b261ecSmrg *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g, 170105b261ecSmrg wire->ktIndex[g]); 170205b261ecSmrg return 0; 170305b261ecSmrg } 170405b261ecSmrg if (mapWidths[wire->ktIndex[g]]>w) 170505b261ecSmrg w= mapWidths[wire->ktIndex[g]]; 170605b261ecSmrg } 170705b261ecSmrg if (wire->width!=w) { 170805b261ecSmrg *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width); 170905b261ecSmrg return 0; 171005b261ecSmrg } 171105b261ecSmrg w*= nG; 171205b261ecSmrg symsPerKey[i+req->firstKeySym] = w; 171305b261ecSmrg if (w!=wire->nSyms) { 171405b261ecSmrg *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w); 171505b261ecSmrg return 0; 171605b261ecSmrg } 171705b261ecSmrg } 171805b261ecSmrg else if (wire->nSyms!=0) { 171905b261ecSmrg *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms); 172005b261ecSmrg return 0; 172105b261ecSmrg } 172205b261ecSmrg pSyms = (KeySym *)&wire[1]; 172305b261ecSmrg wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 172405b261ecSmrg } 172505b261ecSmrg 172605b261ecSmrg map = &xkb->map->key_sym_map[i]; 172705b261ecSmrg for (;i<=(unsigned)xkb->max_key_code;i++,map++) { 172805b261ecSmrg register int g,nG,w; 172905b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 173005b261ecSmrg for (w=g=0;g<nG;g++) { 173105b261ecSmrg if (map->kt_index[g]>=(unsigned)nTypes) { 173205b261ecSmrg *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]); 173305b261ecSmrg return 0; 173405b261ecSmrg } 173505b261ecSmrg if (mapWidths[map->kt_index[g]]>w) 173605b261ecSmrg w= mapWidths[map->kt_index[g]]; 173705b261ecSmrg } 173805b261ecSmrg symsPerKey[i] = w*nG; 173905b261ecSmrg } 174005b261ecSmrg *wireRtrn = wire; 174105b261ecSmrg return 1; 174205b261ecSmrg} 174305b261ecSmrg 174405b261ecSmrgstatic int 174505b261ecSmrgCheckKeyActions( XkbDescPtr xkb, 174605b261ecSmrg xkbSetMapReq * req, 174705b261ecSmrg int nTypes, 174805b261ecSmrg CARD8 * mapWidths, 174905b261ecSmrg CARD16 * symsPerKey, 175005b261ecSmrg CARD8 ** wireRtrn, 175105b261ecSmrg int * nActsRtrn) 175205b261ecSmrg{ 175305b261ecSmrgint nActs; 175405b261ecSmrgCARD8 * wire = *wireRtrn; 175505b261ecSmrgregister unsigned i; 175605b261ecSmrg 175705b261ecSmrg if (!(XkbKeyActionsMask&req->present)) 175805b261ecSmrg return 1; 175905b261ecSmrg CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0); 176005b261ecSmrg for (nActs=i=0;i<req->nKeyActs;i++) { 176105b261ecSmrg if (wire[0]!=0) { 176205b261ecSmrg if (wire[0]==symsPerKey[i+req->firstKeyAct]) 176305b261ecSmrg nActs+= wire[0]; 176405b261ecSmrg else { 176505b261ecSmrg *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]); 176605b261ecSmrg return 0; 176705b261ecSmrg } 176805b261ecSmrg } 176905b261ecSmrg wire++; 177005b261ecSmrg } 177105b261ecSmrg if (req->nKeyActs%4) 177205b261ecSmrg wire+= 4-(req->nKeyActs%4); 177305b261ecSmrg *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs); 177405b261ecSmrg *nActsRtrn = nActs; 177505b261ecSmrg return 1; 177605b261ecSmrg} 177705b261ecSmrg 177805b261ecSmrgstatic int 177905b261ecSmrgCheckKeyBehaviors( XkbDescPtr xkb, 178005b261ecSmrg xkbSetMapReq * req, 178105b261ecSmrg xkbBehaviorWireDesc ** wireRtrn, 178205b261ecSmrg int * errorRtrn) 178305b261ecSmrg{ 178405b261ecSmrgregister xkbBehaviorWireDesc * wire = *wireRtrn; 178505b261ecSmrgregister XkbServerMapPtr server = xkb->server; 178605b261ecSmrgregister unsigned i; 178705b261ecSmrgunsigned first,last; 178805b261ecSmrg 178905b261ecSmrg if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { 179005b261ecSmrg req->present&= ~XkbKeyBehaviorsMask; 179105b261ecSmrg req->nKeyBehaviors= 0; 179205b261ecSmrg return 1; 179305b261ecSmrg } 179405b261ecSmrg first= req->firstKeyBehavior; 179505b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 179605b261ecSmrg if (first<req->minKeyCode) { 179705b261ecSmrg *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode); 179805b261ecSmrg return 0; 179905b261ecSmrg } 180005b261ecSmrg if (last>req->maxKeyCode) { 180105b261ecSmrg *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode); 180205b261ecSmrg return 0; 180305b261ecSmrg } 180405b261ecSmrg 180505b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++,wire++) { 180605b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 180705b261ecSmrg *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key); 180805b261ecSmrg return 0; 180905b261ecSmrg } 181005b261ecSmrg if ((wire->type&XkbKB_Permanent)&& 181105b261ecSmrg ((server->behaviors[wire->key].type!=wire->type)|| 181205b261ecSmrg (server->behaviors[wire->key].data!=wire->data))) { 181305b261ecSmrg *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type); 181405b261ecSmrg return 0; 181505b261ecSmrg } 181605b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&& 181705b261ecSmrg ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) { 181805b261ecSmrg *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data, 181905b261ecSmrg XkbMaxRadioGroups); 182005b261ecSmrg return 0; 182105b261ecSmrg } 182205b261ecSmrg if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) { 182305b261ecSmrg CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0); 182405b261ecSmrg } 182505b261ecSmrg } 182605b261ecSmrg *wireRtrn = wire; 182705b261ecSmrg return 1; 182805b261ecSmrg} 182905b261ecSmrg 183005b261ecSmrgstatic int 183105b261ecSmrgCheckVirtualMods( XkbDescRec * xkb, 183205b261ecSmrg xkbSetMapReq * req, 183305b261ecSmrg CARD8 ** wireRtrn, 183405b261ecSmrg int * errorRtrn) 183505b261ecSmrg{ 183605b261ecSmrgregister CARD8 *wire = *wireRtrn; 183705b261ecSmrgregister unsigned i,nMods,bit; 183805b261ecSmrg 183905b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 184005b261ecSmrg return 1; 184105b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 184205b261ecSmrg if (req->virtualMods&bit) 184305b261ecSmrg nMods++; 184405b261ecSmrg } 184505b261ecSmrg *wireRtrn= (wire+XkbPaddedSize(nMods)); 184605b261ecSmrg return 1; 184705b261ecSmrg} 184805b261ecSmrg 184905b261ecSmrgstatic int 185005b261ecSmrgCheckKeyExplicit( XkbDescPtr xkb, 185105b261ecSmrg xkbSetMapReq * req, 185205b261ecSmrg CARD8 ** wireRtrn, 185305b261ecSmrg int * errorRtrn) 185405b261ecSmrg{ 185505b261ecSmrgregister CARD8 * wire = *wireRtrn; 185605b261ecSmrgCARD8 * start; 185705b261ecSmrgregister unsigned i; 185805b261ecSmrgint first,last; 185905b261ecSmrg 186005b261ecSmrg if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) { 186105b261ecSmrg req->present&= ~XkbExplicitComponentsMask; 186205b261ecSmrg req->nKeyExplicit= 0; 186305b261ecSmrg return 1; 186405b261ecSmrg } 186505b261ecSmrg first= req->firstKeyExplicit; 186605b261ecSmrg last= first+req->nKeyExplicit-1; 186705b261ecSmrg if (first<req->minKeyCode) { 186805b261ecSmrg *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode); 186905b261ecSmrg return 0; 187005b261ecSmrg } 187105b261ecSmrg if (last>req->maxKeyCode) { 187205b261ecSmrg *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode); 187305b261ecSmrg return 0; 187405b261ecSmrg } 187505b261ecSmrg start= wire; 187605b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+=2) { 187705b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 187805b261ecSmrg *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]); 187905b261ecSmrg return 0; 188005b261ecSmrg } 188105b261ecSmrg if (wire[1]&(~XkbAllExplicitMask)) { 188205b261ecSmrg *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]); 188305b261ecSmrg return 0; 188405b261ecSmrg } 188505b261ecSmrg } 188605b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 188705b261ecSmrg *wireRtrn= wire; 188805b261ecSmrg return 1; 188905b261ecSmrg} 189005b261ecSmrg 189105b261ecSmrgstatic int 189205b261ecSmrgCheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn) 189305b261ecSmrg{ 189405b261ecSmrgregister CARD8 * wire = *wireRtrn; 189505b261ecSmrgCARD8 * start; 189605b261ecSmrgregister unsigned i; 189705b261ecSmrgint first,last; 189805b261ecSmrg 189905b261ecSmrg if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) { 190005b261ecSmrg req->present&= ~XkbModifierMapMask; 190105b261ecSmrg req->nModMapKeys= 0; 190205b261ecSmrg return 1; 190305b261ecSmrg } 190405b261ecSmrg first= req->firstModMapKey; 190505b261ecSmrg last= first+req->nModMapKeys-1; 190605b261ecSmrg if (first<req->minKeyCode) { 190705b261ecSmrg *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode); 190805b261ecSmrg return 0; 190905b261ecSmrg } 191005b261ecSmrg if (last>req->maxKeyCode) { 191105b261ecSmrg *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode); 191205b261ecSmrg return 0; 191305b261ecSmrg } 191405b261ecSmrg start= wire; 191505b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+=2) { 191605b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 191705b261ecSmrg *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]); 191805b261ecSmrg return 0; 191905b261ecSmrg } 192005b261ecSmrg } 192105b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 192205b261ecSmrg *wireRtrn= wire; 192305b261ecSmrg return 1; 192405b261ecSmrg} 192505b261ecSmrg 192605b261ecSmrgstatic int 192705b261ecSmrgCheckVirtualModMap( XkbDescPtr xkb, 192805b261ecSmrg xkbSetMapReq *req, 192905b261ecSmrg xkbVModMapWireDesc **wireRtrn, 193005b261ecSmrg int *errRtrn) 193105b261ecSmrg{ 193205b261ecSmrgregister xkbVModMapWireDesc * wire = *wireRtrn; 193305b261ecSmrgregister unsigned i; 193405b261ecSmrgint first,last; 193505b261ecSmrg 193605b261ecSmrg if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) { 193705b261ecSmrg req->present&= ~XkbVirtualModMapMask; 193805b261ecSmrg req->nVModMapKeys= 0; 193905b261ecSmrg return 1; 194005b261ecSmrg } 194105b261ecSmrg first= req->firstVModMapKey; 194205b261ecSmrg last= first+req->nVModMapKeys-1; 194305b261ecSmrg if (first<req->minKeyCode) { 194405b261ecSmrg *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode); 194505b261ecSmrg return 0; 194605b261ecSmrg } 194705b261ecSmrg if (last>req->maxKeyCode) { 194805b261ecSmrg *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode); 194905b261ecSmrg return 0; 195005b261ecSmrg } 195105b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 195205b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 195305b261ecSmrg *errRtrn = _XkbErrCode4(0x73,first,last,wire->key); 195405b261ecSmrg return 0; 195505b261ecSmrg } 195605b261ecSmrg } 195705b261ecSmrg *wireRtrn= wire; 195805b261ecSmrg return 1; 195905b261ecSmrg} 196005b261ecSmrg 196105b261ecSmrgstatic char * 196205b261ecSmrgSetKeyTypes( XkbDescPtr xkb, 196305b261ecSmrg xkbSetMapReq * req, 196405b261ecSmrg xkbKeyTypeWireDesc * wire, 196505b261ecSmrg XkbChangesPtr changes) 196605b261ecSmrg{ 196705b261ecSmrgregister unsigned i; 196805b261ecSmrgunsigned first,last; 196905b261ecSmrgCARD8 *map; 197005b261ecSmrg 197105b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) { 197205b261ecSmrg i= req->firstType+req->nTypes; 197305b261ecSmrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) { 197405b261ecSmrg return NULL; 197505b261ecSmrg } 197605b261ecSmrg } 197705b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types) 197805b261ecSmrg xkb->map->num_types= req->firstType+req->nTypes; 197905b261ecSmrg 198005b261ecSmrg for (i=0;i<req->nTypes;i++) { 198105b261ecSmrg XkbKeyTypePtr pOld; 198205b261ecSmrg register unsigned n; 198305b261ecSmrg 198405b261ecSmrg if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries, 198505b261ecSmrg wire->preserve,wire->numLevels)!=Success) { 198605b261ecSmrg return NULL; 198705b261ecSmrg } 198805b261ecSmrg pOld = &xkb->map->types[i+req->firstType]; 198905b261ecSmrg map = (CARD8 *)&wire[1]; 199005b261ecSmrg 199105b261ecSmrg pOld->mods.real_mods = wire->realMods; 199205b261ecSmrg pOld->mods.vmods= wire->virtualMods; 199305b261ecSmrg pOld->num_levels = wire->numLevels; 199405b261ecSmrg pOld->map_count= wire->nMapEntries; 199505b261ecSmrg 199605b261ecSmrg pOld->mods.mask= pOld->mods.real_mods| 199705b261ecSmrg XkbMaskForVMask(xkb,pOld->mods.vmods); 199805b261ecSmrg 199905b261ecSmrg if (wire->nMapEntries) { 200005b261ecSmrg xkbKTSetMapEntryWireDesc *mapWire; 200105b261ecSmrg xkbModsWireDesc *preWire; 200205b261ecSmrg unsigned tmp; 200305b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)map; 200405b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 200505b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 200605b261ecSmrg pOld->map[n].active= 1; 200705b261ecSmrg pOld->map[n].mods.mask= mapWire[n].realMods; 200805b261ecSmrg pOld->map[n].mods.real_mods= mapWire[n].realMods; 200905b261ecSmrg pOld->map[n].mods.vmods= mapWire[n].virtualMods; 201005b261ecSmrg pOld->map[n].level= mapWire[n].level; 201105b261ecSmrg if (mapWire[n].virtualMods!=0) { 201205b261ecSmrg tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods); 201305b261ecSmrg pOld->map[n].active= (tmp!=0); 201405b261ecSmrg pOld->map[n].mods.mask|= tmp; 201505b261ecSmrg } 201605b261ecSmrg if (wire->preserve) { 201705b261ecSmrg pOld->preserve[n].real_mods= preWire[n].realMods; 201805b261ecSmrg pOld->preserve[n].vmods= preWire[n].virtualMods; 201905b261ecSmrg tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods); 202005b261ecSmrg pOld->preserve[n].mask= preWire[n].realMods|tmp; 202105b261ecSmrg } 202205b261ecSmrg } 202305b261ecSmrg if (wire->preserve) 202405b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 202505b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 202605b261ecSmrg } 202705b261ecSmrg else map= (CARD8 *)&wire[1]; 202805b261ecSmrg wire = (xkbKeyTypeWireDesc *)map; 202905b261ecSmrg } 203005b261ecSmrg first= req->firstType; 203105b261ecSmrg last= first+req->nTypes-1; /* last changed type */ 203205b261ecSmrg if (changes->map.changed&XkbKeyTypesMask) { 203305b261ecSmrg int oldLast; 203405b261ecSmrg oldLast= changes->map.first_type+changes->map.num_types-1; 203505b261ecSmrg if (changes->map.first_type<first) 203605b261ecSmrg first= changes->map.first_type; 203705b261ecSmrg if (oldLast>last) 203805b261ecSmrg last= oldLast; 203905b261ecSmrg } 204005b261ecSmrg changes->map.changed|= XkbKeyTypesMask; 204105b261ecSmrg changes->map.first_type = first; 204205b261ecSmrg changes->map.num_types = (last-first)+1; 204305b261ecSmrg return (char *)wire; 204405b261ecSmrg} 204505b261ecSmrg 204605b261ecSmrgstatic char * 204705b261ecSmrgSetKeySyms( ClientPtr client, 204805b261ecSmrg XkbDescPtr xkb, 204905b261ecSmrg xkbSetMapReq * req, 205005b261ecSmrg xkbSymMapWireDesc * wire, 205105b261ecSmrg XkbChangesPtr changes, 205205b261ecSmrg DeviceIntPtr dev) 205305b261ecSmrg{ 205405b261ecSmrgregister unsigned i,s; 205505b261ecSmrgXkbSymMapPtr oldMap; 205605b261ecSmrgKeySym * newSyms; 205705b261ecSmrgKeySym * pSyms; 205805b261ecSmrgunsigned first,last; 205905b261ecSmrg 206005b261ecSmrg oldMap = &xkb->map->key_sym_map[req->firstKeySym]; 206105b261ecSmrg for (i=0;i<req->nKeySyms;i++,oldMap++) { 206205b261ecSmrg pSyms = (KeySym *)&wire[1]; 206305b261ecSmrg if (wire->nSyms>0) { 206405b261ecSmrg newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms); 206505b261ecSmrg for (s=0;s<wire->nSyms;s++) { 206605b261ecSmrg newSyms[s]= pSyms[s]; 206705b261ecSmrg } 206805b261ecSmrg if (client->swapped) { 206905b261ecSmrg int n; 207005b261ecSmrg for (s=0;s<wire->nSyms;s++) { 207105b261ecSmrg swapl(&newSyms[s],n); 207205b261ecSmrg } 207305b261ecSmrg } 207405b261ecSmrg } 207505b261ecSmrg oldMap->kt_index[0] = wire->ktIndex[0]; 207605b261ecSmrg oldMap->kt_index[1] = wire->ktIndex[1]; 207705b261ecSmrg oldMap->kt_index[2] = wire->ktIndex[2]; 207805b261ecSmrg oldMap->kt_index[3] = wire->ktIndex[3]; 207905b261ecSmrg oldMap->group_info = wire->groupInfo; 208005b261ecSmrg oldMap->width = wire->width; 208105b261ecSmrg wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 208205b261ecSmrg } 208305b261ecSmrg first= req->firstKeySym; 208405b261ecSmrg last= first+req->nKeySyms-1; 208505b261ecSmrg if (changes->map.changed&XkbKeySymsMask) { 208605b261ecSmrg int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1); 208705b261ecSmrg if (changes->map.first_key_sym<first) 208805b261ecSmrg first= changes->map.first_key_sym; 208905b261ecSmrg if (oldLast>last) 209005b261ecSmrg last= oldLast; 209105b261ecSmrg } 209205b261ecSmrg changes->map.changed|= XkbKeySymsMask; 209305b261ecSmrg changes->map.first_key_sym = first; 209405b261ecSmrg changes->map.num_key_syms = (last-first+1); 209505b261ecSmrg 209605b261ecSmrg s= 0; 209705b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 209805b261ecSmrg if (XkbKeyNumGroups(xkb,i)>s) 209905b261ecSmrg s= XkbKeyNumGroups(xkb,i); 210005b261ecSmrg } 210105b261ecSmrg if (s!=xkb->ctrls->num_groups) { 210205b261ecSmrg xkbControlsNotify cn; 210305b261ecSmrg XkbControlsRec old; 210405b261ecSmrg cn.keycode= 0; 210505b261ecSmrg cn.eventType= 0; 210605b261ecSmrg cn.requestMajor= XkbReqCode; 210705b261ecSmrg cn.requestMinor= X_kbSetMap; 210805b261ecSmrg old= *xkb->ctrls; 210905b261ecSmrg xkb->ctrls->num_groups= s; 21106747b715Smrg if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE)) 211105b261ecSmrg XkbSendControlsNotify(dev,&cn); 211205b261ecSmrg } 211305b261ecSmrg return (char *)wire; 211405b261ecSmrg} 211505b261ecSmrg 211605b261ecSmrgstatic char * 211705b261ecSmrgSetKeyActions( XkbDescPtr xkb, 211805b261ecSmrg xkbSetMapReq * req, 211905b261ecSmrg CARD8 * wire, 212005b261ecSmrg XkbChangesPtr changes) 212105b261ecSmrg{ 212205b261ecSmrgregister unsigned i,first,last; 212305b261ecSmrgCARD8 * nActs = wire; 212405b261ecSmrgXkbAction * newActs; 212505b261ecSmrg 212605b261ecSmrg wire+= XkbPaddedSize(req->nKeyActs); 212705b261ecSmrg for (i=0;i<req->nKeyActs;i++) { 212805b261ecSmrg if (nActs[i]==0) 212905b261ecSmrg xkb->server->key_acts[i+req->firstKeyAct]= 0; 213005b261ecSmrg else { 213105b261ecSmrg newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]); 213205b261ecSmrg memcpy((char *)newActs,(char *)wire, 213305b261ecSmrg nActs[i]*SIZEOF(xkbActionWireDesc)); 213405b261ecSmrg wire+= nActs[i]*SIZEOF(xkbActionWireDesc); 213505b261ecSmrg } 213605b261ecSmrg } 213705b261ecSmrg first= req->firstKeyAct; 213805b261ecSmrg last= (first+req->nKeyActs-1); 213905b261ecSmrg if (changes->map.changed&XkbKeyActionsMask) { 214005b261ecSmrg int oldLast; 214105b261ecSmrg oldLast= changes->map.first_key_act+changes->map.num_key_acts-1; 214205b261ecSmrg if (changes->map.first_key_act<first) 214305b261ecSmrg first= changes->map.first_key_act; 214405b261ecSmrg if (oldLast>last) 214505b261ecSmrg last= oldLast; 214605b261ecSmrg } 214705b261ecSmrg changes->map.changed|= XkbKeyActionsMask; 214805b261ecSmrg changes->map.first_key_act= first; 214905b261ecSmrg changes->map.num_key_acts= (last-first+1); 215005b261ecSmrg return (char *)wire; 215105b261ecSmrg} 215205b261ecSmrg 215305b261ecSmrgstatic char * 215405b261ecSmrgSetKeyBehaviors( XkbSrvInfoPtr xkbi, 215505b261ecSmrg xkbSetMapReq *req, 215605b261ecSmrg xkbBehaviorWireDesc *wire, 215705b261ecSmrg XkbChangesPtr changes) 215805b261ecSmrg{ 215905b261ecSmrgregister unsigned i; 216005b261ecSmrgint maxRG = -1; 216105b261ecSmrgXkbDescPtr xkb = xkbi->desc; 216205b261ecSmrgXkbServerMapPtr server = xkb->server; 216305b261ecSmrgunsigned first,last; 216405b261ecSmrg 216505b261ecSmrg first= req->firstKeyBehavior; 216605b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 21676747b715Smrg memset(&server->behaviors[first], 0, req->nKeyBehaviors*sizeof(XkbBehavior)); 216805b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++) { 216905b261ecSmrg if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) { 217005b261ecSmrg server->behaviors[wire->key].type= wire->type; 217105b261ecSmrg server->behaviors[wire->key].data= wire->data; 217205b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG)) 217305b261ecSmrg maxRG= wire->data + 1; 217405b261ecSmrg } 217505b261ecSmrg wire++; 217605b261ecSmrg } 217705b261ecSmrg 217805b261ecSmrg if (maxRG>(int)xkbi->nRadioGroups) { 217905b261ecSmrg int sz = maxRG*sizeof(XkbRadioGroupRec); 218005b261ecSmrg if (xkbi->radioGroups) 21816747b715Smrg xkbi->radioGroups= realloc(xkbi->radioGroups,sz); 21826747b715Smrg else xkbi->radioGroups= calloc(1, sz); 218305b261ecSmrg if (xkbi->radioGroups) { 218405b261ecSmrg if (xkbi->nRadioGroups) 21856747b715Smrg memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0, 218605b261ecSmrg (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec)); 218705b261ecSmrg xkbi->nRadioGroups= maxRG; 218805b261ecSmrg } 218905b261ecSmrg else xkbi->nRadioGroups= 0; 219005b261ecSmrg /* should compute members here */ 219105b261ecSmrg } 219205b261ecSmrg if (changes->map.changed&XkbKeyBehaviorsMask) { 219305b261ecSmrg unsigned oldLast; 219405b261ecSmrg oldLast= changes->map.first_key_behavior+ 219505b261ecSmrg changes->map.num_key_behaviors-1; 219605b261ecSmrg if (changes->map.first_key_behavior<req->firstKeyBehavior) 219705b261ecSmrg first= changes->map.first_key_behavior; 219805b261ecSmrg if (oldLast>last) 219905b261ecSmrg last= oldLast; 220005b261ecSmrg } 220105b261ecSmrg changes->map.changed|= XkbKeyBehaviorsMask; 220205b261ecSmrg changes->map.first_key_behavior = first; 220305b261ecSmrg changes->map.num_key_behaviors = (last-first+1); 220405b261ecSmrg return (char *)wire; 220505b261ecSmrg} 220605b261ecSmrg 220705b261ecSmrgstatic char * 220805b261ecSmrgSetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 220905b261ecSmrg XkbChangesPtr changes) 221005b261ecSmrg{ 221105b261ecSmrgregister int i,bit,nMods; 221205b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 221305b261ecSmrg 221405b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 221505b261ecSmrg return (char *)wire; 221605b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 221705b261ecSmrg if (req->virtualMods&bit) { 221805b261ecSmrg if (srv->vmods[i]!=wire[nMods]) { 221905b261ecSmrg changes->map.changed|= XkbVirtualModsMask; 222005b261ecSmrg changes->map.vmods|= bit; 222105b261ecSmrg srv->vmods[i]= wire[nMods]; 222205b261ecSmrg } 222305b261ecSmrg nMods++; 222405b261ecSmrg } 222505b261ecSmrg } 222605b261ecSmrg return (char *)(wire+XkbPaddedSize(nMods)); 222705b261ecSmrg} 222805b261ecSmrg 222905b261ecSmrgstatic char * 223005b261ecSmrgSetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 223105b261ecSmrg XkbChangesPtr changes) 223205b261ecSmrg{ 223305b261ecSmrgregister unsigned i,first,last; 223405b261ecSmrgXkbServerMapPtr xkb = xkbi->desc->server; 223505b261ecSmrgCARD8 * start; 223605b261ecSmrg 223705b261ecSmrg start= wire; 223805b261ecSmrg first= req->firstKeyExplicit; 223905b261ecSmrg last= req->firstKeyExplicit+req->nKeyExplicit-1; 22406747b715Smrg memset(&xkb->explicit[first], 0, req->nKeyExplicit); 224105b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) { 224205b261ecSmrg xkb->explicit[wire[0]]= wire[1]; 224305b261ecSmrg } 224405b261ecSmrg if (first>0) { 224505b261ecSmrg if (changes->map.changed&XkbExplicitComponentsMask) { 224605b261ecSmrg int oldLast; 224705b261ecSmrg oldLast= changes->map.first_key_explicit+ 224805b261ecSmrg changes->map.num_key_explicit-1; 224905b261ecSmrg if (changes->map.first_key_explicit<first) 225005b261ecSmrg first= changes->map.first_key_explicit; 225105b261ecSmrg if (oldLast>last) 225205b261ecSmrg last= oldLast; 225305b261ecSmrg } 225405b261ecSmrg changes->map.first_key_explicit= first; 225505b261ecSmrg changes->map.num_key_explicit= (last-first)+1; 225605b261ecSmrg } 225705b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 225805b261ecSmrg return (char *)wire; 225905b261ecSmrg} 226005b261ecSmrg 226105b261ecSmrgstatic char * 226205b261ecSmrgSetModifierMap( XkbSrvInfoPtr xkbi, 226305b261ecSmrg xkbSetMapReq * req, 226405b261ecSmrg CARD8 * wire, 226505b261ecSmrg XkbChangesPtr changes) 226605b261ecSmrg{ 226705b261ecSmrgregister unsigned i,first,last; 226805b261ecSmrgXkbClientMapPtr xkb = xkbi->desc->map; 226905b261ecSmrgCARD8 * start; 227005b261ecSmrg 227105b261ecSmrg start= wire; 227205b261ecSmrg first= req->firstModMapKey; 227305b261ecSmrg last= req->firstModMapKey+req->nModMapKeys-1; 22746747b715Smrg memset(&xkb->modmap[first], 0, req->nModMapKeys); 227505b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+= 2) { 227605b261ecSmrg xkb->modmap[wire[0]]= wire[1]; 227705b261ecSmrg } 227805b261ecSmrg if (first>0) { 227905b261ecSmrg if (changes->map.changed&XkbModifierMapMask) { 228005b261ecSmrg int oldLast; 228105b261ecSmrg oldLast= changes->map.first_modmap_key+ 228205b261ecSmrg changes->map.num_modmap_keys-1; 228305b261ecSmrg if (changes->map.first_modmap_key<first) 228405b261ecSmrg first= changes->map.first_modmap_key; 228505b261ecSmrg if (oldLast>last) 228605b261ecSmrg last= oldLast; 228705b261ecSmrg } 228805b261ecSmrg changes->map.first_modmap_key= first; 228905b261ecSmrg changes->map.num_modmap_keys= (last-first)+1; 229005b261ecSmrg } 229105b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 229205b261ecSmrg return (char *)wire; 229305b261ecSmrg} 229405b261ecSmrg 229505b261ecSmrgstatic char * 229605b261ecSmrgSetVirtualModMap( XkbSrvInfoPtr xkbi, 229705b261ecSmrg xkbSetMapReq * req, 229805b261ecSmrg xkbVModMapWireDesc * wire, 229905b261ecSmrg XkbChangesPtr changes) 230005b261ecSmrg{ 230105b261ecSmrgregister unsigned i,first,last; 230205b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 230305b261ecSmrg 230405b261ecSmrg first= req->firstVModMapKey; 230505b261ecSmrg last= req->firstVModMapKey+req->nVModMapKeys-1; 23066747b715Smrg memset(&srv->vmodmap[first], 0, req->nVModMapKeys*sizeof(unsigned short)); 230705b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 230805b261ecSmrg srv->vmodmap[wire->key]= wire->vmods; 230905b261ecSmrg } 231005b261ecSmrg if (first>0) { 231105b261ecSmrg if (changes->map.changed&XkbVirtualModMapMask) { 231205b261ecSmrg int oldLast; 231305b261ecSmrg oldLast= changes->map.first_vmodmap_key+ 231405b261ecSmrg changes->map.num_vmodmap_keys-1; 231505b261ecSmrg if (changes->map.first_vmodmap_key<first) 231605b261ecSmrg first= changes->map.first_vmodmap_key; 231705b261ecSmrg if (oldLast>last) 231805b261ecSmrg last= oldLast; 231905b261ecSmrg } 232005b261ecSmrg changes->map.first_vmodmap_key= first; 232105b261ecSmrg changes->map.num_vmodmap_keys= (last-first)+1; 232205b261ecSmrg } 232305b261ecSmrg return (char *)wire; 232405b261ecSmrg} 232505b261ecSmrg 23264642e01fSmrg/** 23274642e01fSmrg * Check if the given request can be applied to the given device but don't 23284642e01fSmrg * actually do anything.. 23294642e01fSmrg */ 23304642e01fSmrgstatic int 23314642e01fSmrg_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values) 233205b261ecSmrg{ 23334642e01fSmrg XkbSrvInfoPtr xkbi; 23344642e01fSmrg XkbDescPtr xkb; 23354642e01fSmrg int error; 23364642e01fSmrg int nTypes = 0, nActions; 23378223e2f2Smrg CARD8 mapWidths[XkbMaxLegalKeyCode + 1] = {0}; 23388223e2f2Smrg CARD16 symsPerKey[XkbMaxLegalKeyCode + 1] = {0}; 23399ace9065Smrg XkbSymMapPtr map; 23409ace9065Smrg int i; 234105b261ecSmrg 234205b261ecSmrg xkbi= dev->key->xkbInfo; 234305b261ecSmrg xkb = xkbi->desc; 234405b261ecSmrg 23454642e01fSmrg if ((xkb->min_key_code != req->minKeyCode)|| 23464642e01fSmrg (xkb->max_key_code != req->maxKeyCode)) { 234705b261ecSmrg if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ 23484642e01fSmrg req->minKeyCode= xkb->min_key_code; 23494642e01fSmrg req->maxKeyCode= xkb->max_key_code; 235005b261ecSmrg } 235105b261ecSmrg else { 23524642e01fSmrg if (!XkbIsLegalKeycode(req->minKeyCode)) { 23534642e01fSmrg client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); 235405b261ecSmrg return BadValue; 235505b261ecSmrg } 23564642e01fSmrg if (req->minKeyCode > req->maxKeyCode) { 23574642e01fSmrg client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); 235805b261ecSmrg return BadMatch; 235905b261ecSmrg } 236005b261ecSmrg } 236105b261ecSmrg } 236205b261ecSmrg 23634642e01fSmrg if ((req->present & XkbKeyTypesMask) && 23644642e01fSmrg (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values, 236505b261ecSmrg &nTypes,mapWidths))) { 236605b261ecSmrg client->errorValue = nTypes; 236705b261ecSmrg return BadValue; 236805b261ecSmrg } 23699ace9065Smrg 23709ace9065Smrg /* symsPerKey/mapWidths must be filled regardless of client-side flags */ 23719ace9065Smrg map = &xkb->map->key_sym_map[xkb->min_key_code]; 23729ace9065Smrg for (i=xkb->min_key_code;i<xkb->max_key_code;i++,map++) { 23739ace9065Smrg register int g,ng,w; 23749ace9065Smrg ng= XkbNumGroups(map->group_info); 23759ace9065Smrg for (w=g=0;g<ng;g++) { 23769ace9065Smrg if (map->kt_index[g]>=(unsigned)nTypes) { 23779ace9065Smrg client->errorValue = _XkbErrCode4(0x13,i,g,map->kt_index[g]); 23789ace9065Smrg return 0; 23799ace9065Smrg } 23809ace9065Smrg if (mapWidths[map->kt_index[g]]>w) 23819ace9065Smrg w= mapWidths[map->kt_index[g]]; 23829ace9065Smrg } 23839ace9065Smrg symsPerKey[i] = w*ng; 23849ace9065Smrg } 23859ace9065Smrg 23864642e01fSmrg if ((req->present & XkbKeySymsMask) && 23874642e01fSmrg (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey, 23884642e01fSmrg (xkbSymMapWireDesc **)&values,&error))) { 238905b261ecSmrg client->errorValue = error; 239005b261ecSmrg return BadValue; 239105b261ecSmrg } 239205b261ecSmrg 23934642e01fSmrg if ((req->present & XkbKeyActionsMask) && 23944642e01fSmrg (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey, 23954642e01fSmrg (CARD8 **)&values,&nActions))) { 239605b261ecSmrg client->errorValue = nActions; 239705b261ecSmrg return BadValue; 239805b261ecSmrg } 239905b261ecSmrg 24004642e01fSmrg if ((req->present & XkbKeyBehaviorsMask) && 24014642e01fSmrg (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) { 240205b261ecSmrg client->errorValue = error; 240305b261ecSmrg return BadValue; 240405b261ecSmrg } 240505b261ecSmrg 24064642e01fSmrg if ((req->present & XkbVirtualModsMask) && 24074642e01fSmrg (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) { 240805b261ecSmrg client->errorValue= error; 240905b261ecSmrg return BadValue; 241005b261ecSmrg } 24114642e01fSmrg if ((req->present&XkbExplicitComponentsMask) && 24124642e01fSmrg (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) { 241305b261ecSmrg client->errorValue= error; 241405b261ecSmrg return BadValue; 241505b261ecSmrg } 24164642e01fSmrg if ((req->present&XkbModifierMapMask) && 24174642e01fSmrg (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) { 241805b261ecSmrg client->errorValue= error; 241905b261ecSmrg return BadValue; 242005b261ecSmrg } 24214642e01fSmrg if ((req->present&XkbVirtualModMapMask) && 24224642e01fSmrg (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) { 242305b261ecSmrg client->errorValue= error; 242405b261ecSmrg return BadValue; 242505b261ecSmrg } 24264642e01fSmrg 24274642e01fSmrg if (((values-((char *)req))/4)!= req->length) { 24284642e01fSmrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); 24294642e01fSmrg client->errorValue = values-((char *)&req[1]); 243005b261ecSmrg return BadLength; 243105b261ecSmrg } 24324642e01fSmrg 24334642e01fSmrg return Success; 24344642e01fSmrg} 24354642e01fSmrg 24364642e01fSmrg/** 24374642e01fSmrg * Apply the given request on the given device. 24384642e01fSmrg */ 24394642e01fSmrgstatic int 24404642e01fSmrg_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values) 24414642e01fSmrg{ 24424642e01fSmrg XkbEventCauseRec cause; 24434642e01fSmrg XkbChangesRec change; 24444642e01fSmrg Bool sentNKN; 24454642e01fSmrg XkbSrvInfoPtr xkbi; 24464642e01fSmrg XkbDescPtr xkb; 24474642e01fSmrg 24484642e01fSmrg xkbi= dev->key->xkbInfo; 24494642e01fSmrg xkb = xkbi->desc; 24504642e01fSmrg 24514642e01fSmrg XkbSetCauseXkbReq(&cause,X_kbSetMap,client); 24526747b715Smrg memset(&change, 0, sizeof(change)); 24536747b715Smrg sentNKN = FALSE; 24544642e01fSmrg if ((xkb->min_key_code!=req->minKeyCode)|| 24554642e01fSmrg (xkb->max_key_code!=req->maxKeyCode)) { 245605b261ecSmrg Status status; 245705b261ecSmrg xkbNewKeyboardNotify nkn; 24584642e01fSmrg nkn.deviceID = nkn.oldDeviceID = dev->id; 24594642e01fSmrg nkn.oldMinKeyCode = xkb->min_key_code; 24604642e01fSmrg nkn.oldMaxKeyCode = xkb->max_key_code; 24614642e01fSmrg status= XkbChangeKeycodeRange(xkb, req->minKeyCode, 24624642e01fSmrg req->maxKeyCode, &change); 24634642e01fSmrg if (status != Success) 24644642e01fSmrg return status; /* oh-oh. what about the other keyboards? */ 24654642e01fSmrg nkn.minKeyCode = xkb->min_key_code; 24664642e01fSmrg nkn.maxKeyCode = xkb->max_key_code; 24674642e01fSmrg nkn.requestMajor = XkbReqCode; 24684642e01fSmrg nkn.requestMinor = X_kbSetMap; 24694642e01fSmrg nkn.changed = XkbNKN_KeycodesMask; 247005b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 24716747b715Smrg sentNKN = TRUE; 24724642e01fSmrg } 24734642e01fSmrg 24744642e01fSmrg if (req->present&XkbKeyTypesMask) { 24754642e01fSmrg values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change); 24764642e01fSmrg if (!values) goto allocFailure; 24774642e01fSmrg } 24784642e01fSmrg if (req->present&XkbKeySymsMask) { 24794642e01fSmrg values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev); 24804642e01fSmrg if (!values) goto allocFailure; 24814642e01fSmrg } 24824642e01fSmrg if (req->present&XkbKeyActionsMask) { 24834642e01fSmrg values = SetKeyActions(xkb,req,(CARD8 *)values,&change); 24844642e01fSmrg if (!values) goto allocFailure; 24854642e01fSmrg } 24864642e01fSmrg if (req->present&XkbKeyBehaviorsMask) { 24874642e01fSmrg values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change); 24884642e01fSmrg if (!values) goto allocFailure; 24894642e01fSmrg } 24904642e01fSmrg if (req->present&XkbVirtualModsMask) 24914642e01fSmrg values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change); 24924642e01fSmrg if (req->present&XkbExplicitComponentsMask) 24934642e01fSmrg values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change); 24944642e01fSmrg if (req->present&XkbModifierMapMask) 24954642e01fSmrg values= SetModifierMap(xkbi,req,(CARD8 *)values,&change); 24964642e01fSmrg if (req->present&XkbVirtualModMapMask) 24974642e01fSmrg values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change); 24984642e01fSmrg if (((values-((char *)req))/4)!=req->length) { 24994642e01fSmrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); 25004642e01fSmrg client->errorValue = values-((char *)&req[1]); 250105b261ecSmrg return BadLength; 250205b261ecSmrg } 25034642e01fSmrg if (req->flags&XkbSetMapRecomputeActions) { 250405b261ecSmrg KeyCode first,last,firstMM,lastMM; 250505b261ecSmrg if (change.map.num_key_syms>0) { 250605b261ecSmrg first= change.map.first_key_sym; 250705b261ecSmrg last= first+change.map.num_key_syms-1; 250805b261ecSmrg } 250905b261ecSmrg else first= last= 0; 251005b261ecSmrg if (change.map.num_modmap_keys>0) { 251105b261ecSmrg firstMM= change.map.first_modmap_key; 251205b261ecSmrg lastMM= first+change.map.num_modmap_keys-1; 251305b261ecSmrg } 251405b261ecSmrg else firstMM= lastMM= 0; 251505b261ecSmrg if ((last>0) && (lastMM>0)) { 251605b261ecSmrg if (firstMM<first) 251705b261ecSmrg first= firstMM; 251805b261ecSmrg if (lastMM>last) 251905b261ecSmrg last= lastMM; 252005b261ecSmrg } 252105b261ecSmrg else if (lastMM>0) { 252205b261ecSmrg first= firstMM; 252305b261ecSmrg last= lastMM; 252405b261ecSmrg } 252505b261ecSmrg if (last>0) { 252605b261ecSmrg unsigned check= 0; 252705b261ecSmrg XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause); 252805b261ecSmrg if (check) 252905b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 253005b261ecSmrg } 253105b261ecSmrg } 253205b261ecSmrg if (!sentNKN) 253305b261ecSmrg XkbSendNotification(dev,&change,&cause); 253405b261ecSmrg 25354642e01fSmrg return Success; 253605b261ecSmrgallocFailure: 253705b261ecSmrg return BadAlloc; 253805b261ecSmrg} 253905b261ecSmrg 25404642e01fSmrg 25414642e01fSmrgint 25424642e01fSmrgProcXkbSetMap(ClientPtr client) 25434642e01fSmrg{ 25444642e01fSmrg DeviceIntPtr dev; 25454642e01fSmrg char * tmp; 25464642e01fSmrg int rc; 25474642e01fSmrg 25484642e01fSmrg REQUEST(xkbSetMapReq); 25494642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 25504642e01fSmrg 25514642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 25524642e01fSmrg return BadAccess; 25534642e01fSmrg 25544642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 25554642e01fSmrg CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); 25564642e01fSmrg 25574642e01fSmrg tmp = (char *)&stuff[1]; 25584642e01fSmrg 25594642e01fSmrg /* Check if we can to the SetMap on the requested device. If this 25604642e01fSmrg succeeds, do the same thing for all extension devices (if needed). 25614642e01fSmrg If any of them fails, fail. */ 25624642e01fSmrg rc = _XkbSetMapChecks(client, dev, stuff, tmp); 25634642e01fSmrg 25644642e01fSmrg if (rc != Success) 25654642e01fSmrg return rc; 25664642e01fSmrg 25674642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 25684642e01fSmrg { 25694642e01fSmrg DeviceIntPtr other; 25704642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 25714642e01fSmrg { 25726747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 25734642e01fSmrg { 25744642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 25754642e01fSmrg if (rc == Success) 25764642e01fSmrg { 25774642e01fSmrg rc = _XkbSetMapChecks(client, other, stuff, tmp); 25784642e01fSmrg if (rc != Success) 25794642e01fSmrg return rc; 25804642e01fSmrg } 25814642e01fSmrg } 25824642e01fSmrg } 25834642e01fSmrg } 25844642e01fSmrg 25854642e01fSmrg /* We know now that we will succed with the SetMap. In theory anyway. */ 25864642e01fSmrg rc = _XkbSetMap(client, dev, stuff, tmp); 25874642e01fSmrg if (rc != Success) 25884642e01fSmrg return rc; 25894642e01fSmrg 25904642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 25914642e01fSmrg { 25924642e01fSmrg DeviceIntPtr other; 25934642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 25944642e01fSmrg { 25956747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 25964642e01fSmrg { 25974642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 25984642e01fSmrg if (rc == Success) 25994642e01fSmrg _XkbSetMap(client, other, stuff, tmp); 26004642e01fSmrg /* ignore rc. if the SetMap failed although the check above 26014642e01fSmrg reported true there isn't much we can do. we still need to 26024642e01fSmrg set all other devices, hoping that at least they stay in 26034642e01fSmrg sync. */ 26044642e01fSmrg } 26054642e01fSmrg } 26064642e01fSmrg } 26074642e01fSmrg 26086747b715Smrg return Success; 26094642e01fSmrg} 26104642e01fSmrg 261105b261ecSmrg/***====================================================================***/ 261205b261ecSmrg 261305b261ecSmrgstatic Status 261405b261ecSmrgXkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat, 261505b261ecSmrg xkbGetCompatMapReply * rep) 261605b261ecSmrg{ 261705b261ecSmrgunsigned size,nGroups; 261805b261ecSmrg 261905b261ecSmrg nGroups= 0; 262005b261ecSmrg if (rep->groups!=0) { 262105b261ecSmrg register int i,bit; 262205b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 262305b261ecSmrg if (rep->groups&bit) 262405b261ecSmrg nGroups++; 262505b261ecSmrg } 262605b261ecSmrg } 262705b261ecSmrg size= nGroups*SIZEOF(xkbModsWireDesc); 262805b261ecSmrg size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); 262905b261ecSmrg rep->length= size/4; 263005b261ecSmrg return Success; 263105b261ecSmrg} 263205b261ecSmrg 263305b261ecSmrgstatic int 263405b261ecSmrgXkbSendCompatMap( ClientPtr client, 263505b261ecSmrg XkbCompatMapPtr compat, 263605b261ecSmrg xkbGetCompatMapReply * rep) 263705b261ecSmrg{ 263805b261ecSmrgchar * data; 263905b261ecSmrgint size; 264005b261ecSmrg 264105b261ecSmrg size= rep->length*4; 264205b261ecSmrg if (size>0) { 26436747b715Smrg data = malloc(size); 264405b261ecSmrg if (data) { 264505b261ecSmrg register unsigned i,bit; 264605b261ecSmrg xkbModsWireDesc * grp; 264705b261ecSmrg XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI]; 264805b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 264905b261ecSmrg for (i=0;i<rep->nSI;i++,sym++,wire++) { 265005b261ecSmrg wire->sym= sym->sym; 265105b261ecSmrg wire->mods= sym->mods; 265205b261ecSmrg wire->match= sym->match; 265305b261ecSmrg wire->virtualMod= sym->virtual_mod; 265405b261ecSmrg wire->flags= sym->flags; 265505b261ecSmrg memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc); 265605b261ecSmrg if (client->swapped) { 265705b261ecSmrg register int n; 265805b261ecSmrg swapl(&wire->sym,n); 265905b261ecSmrg } 266005b261ecSmrg } 266105b261ecSmrg if (rep->groups) { 266205b261ecSmrg grp = (xkbModsWireDesc *)wire; 266305b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 266405b261ecSmrg if (rep->groups&bit) { 266505b261ecSmrg grp->mask= compat->groups[i].mask; 266605b261ecSmrg grp->realMods= compat->groups[i].real_mods; 266705b261ecSmrg grp->virtualMods= compat->groups[i].vmods; 266805b261ecSmrg if (client->swapped) { 266905b261ecSmrg register int n; 267005b261ecSmrg swaps(&grp->virtualMods,n); 267105b261ecSmrg } 267205b261ecSmrg grp++; 267305b261ecSmrg } 267405b261ecSmrg } 267505b261ecSmrg wire= (xkbSymInterpretWireDesc*)grp; 267605b261ecSmrg } 267705b261ecSmrg } 267805b261ecSmrg else return BadAlloc; 267905b261ecSmrg } 268005b261ecSmrg else data= NULL; 268105b261ecSmrg 268205b261ecSmrg if (client->swapped) { 268305b261ecSmrg register int n; 268405b261ecSmrg swaps(&rep->sequenceNumber,n); 268505b261ecSmrg swapl(&rep->length,n); 268605b261ecSmrg swaps(&rep->firstSI,n); 268705b261ecSmrg swaps(&rep->nSI,n); 268805b261ecSmrg swaps(&rep->nTotalSI,n); 268905b261ecSmrg } 269005b261ecSmrg 269105b261ecSmrg WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep); 269205b261ecSmrg if (data) { 269305b261ecSmrg WriteToClient(client, size, data); 26946747b715Smrg free((char *)data); 269505b261ecSmrg } 26966747b715Smrg return Success; 269705b261ecSmrg} 269805b261ecSmrg 269905b261ecSmrgint 270005b261ecSmrgProcXkbGetCompatMap(ClientPtr client) 270105b261ecSmrg{ 270205b261ecSmrg xkbGetCompatMapReply rep; 270305b261ecSmrg DeviceIntPtr dev; 270405b261ecSmrg XkbDescPtr xkb; 270505b261ecSmrg XkbCompatMapPtr compat; 270605b261ecSmrg 270705b261ecSmrg REQUEST(xkbGetCompatMapReq); 270805b261ecSmrg REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 270905b261ecSmrg 271005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 271105b261ecSmrg return BadAccess; 271205b261ecSmrg 27134642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 271405b261ecSmrg 271505b261ecSmrg xkb = dev->key->xkbInfo->desc; 271605b261ecSmrg compat= xkb->compat; 271705b261ecSmrg 271805b261ecSmrg rep.type = X_Reply; 271905b261ecSmrg rep.deviceID = dev->id; 272005b261ecSmrg rep.sequenceNumber = client->sequence; 272105b261ecSmrg rep.length = 0; 272205b261ecSmrg rep.firstSI = stuff->firstSI; 272305b261ecSmrg rep.nSI = stuff->nSI; 272405b261ecSmrg if (stuff->getAllSI) { 272505b261ecSmrg rep.firstSI = 0; 272605b261ecSmrg rep.nSI = compat->num_si; 272705b261ecSmrg } 272805b261ecSmrg else if ((((unsigned)stuff->nSI)>0)&& 272905b261ecSmrg ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) { 273005b261ecSmrg client->errorValue = _XkbErrCode2(0x05,compat->num_si); 273105b261ecSmrg return BadValue; 273205b261ecSmrg } 273305b261ecSmrg rep.nTotalSI = compat->num_si; 273405b261ecSmrg rep.groups= stuff->groups; 273505b261ecSmrg XkbComputeGetCompatMapReplySize(compat,&rep); 273605b261ecSmrg return XkbSendCompatMap(client,compat,&rep); 273705b261ecSmrg} 273805b261ecSmrg 27394642e01fSmrg/** 27404642e01fSmrg * Apply the given request on the given device. 27416747b715Smrg * If dryRun is TRUE, then value checks are performed, but the device isn't 27424642e01fSmrg * modified. 27434642e01fSmrg */ 27444642e01fSmrgstatic int 27454642e01fSmrg_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, 27464642e01fSmrg xkbSetCompatMapReq *req, char* data, BOOL dryRun) 274705b261ecSmrg{ 27484642e01fSmrg XkbSrvInfoPtr xkbi; 27494642e01fSmrg XkbDescPtr xkb; 27504642e01fSmrg XkbCompatMapPtr compat; 27514642e01fSmrg int nGroups; 27524642e01fSmrg unsigned i,bit; 275305b261ecSmrg 275405b261ecSmrg xkbi = dev->key->xkbInfo; 27554642e01fSmrg xkb = xkbi->desc; 27564642e01fSmrg compat = xkb->compat; 27574642e01fSmrg 27584642e01fSmrg if ((req->nSI>0)||(req->truncateSI)) { 275905b261ecSmrg xkbSymInterpretWireDesc *wire; 27604642e01fSmrg if (req->firstSI>compat->num_si) { 276105b261ecSmrg client->errorValue = _XkbErrCode2(0x02,compat->num_si); 276205b261ecSmrg return BadValue; 276305b261ecSmrg } 276405b261ecSmrg wire= (xkbSymInterpretWireDesc *)data; 27654642e01fSmrg wire+= req->nSI; 276605b261ecSmrg data = (char *)wire; 276705b261ecSmrg } 27684642e01fSmrg 276905b261ecSmrg nGroups= 0; 27704642e01fSmrg if (req->groups!=0) { 277105b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 27724642e01fSmrg if ( req->groups&bit ) 277305b261ecSmrg nGroups++; 277405b261ecSmrg } 277505b261ecSmrg } 277605b261ecSmrg data+= nGroups*SIZEOF(xkbModsWireDesc); 27774642e01fSmrg if (((data-((char *)req))/4)!=req->length) { 277805b261ecSmrg return BadLength; 277905b261ecSmrg } 27804642e01fSmrg 27814642e01fSmrg /* Done all the checks we can do */ 27824642e01fSmrg if (dryRun) 27834642e01fSmrg return Success; 27844642e01fSmrg 27854642e01fSmrg data = (char *)&req[1]; 27864642e01fSmrg if (req->nSI>0) { 278705b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 278805b261ecSmrg XkbSymInterpretPtr sym; 27894642e01fSmrg if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) { 27904642e01fSmrg compat->num_si= req->firstSI+req->nSI; 27916747b715Smrg compat->sym_interpret= realloc(compat->sym_interpret, 27926747b715Smrg compat->num_si * sizeof(XkbSymInterpretRec)); 279305b261ecSmrg if (!compat->sym_interpret) { 279405b261ecSmrg compat->num_si= 0; 279505b261ecSmrg return BadAlloc; 279605b261ecSmrg } 279705b261ecSmrg } 27984642e01fSmrg else if (req->truncateSI) { 27994642e01fSmrg compat->num_si = req->firstSI+req->nSI; 280005b261ecSmrg } 28014642e01fSmrg sym = &compat->sym_interpret[req->firstSI]; 28024642e01fSmrg for (i=0;i<req->nSI;i++,wire++,sym++) { 280305b261ecSmrg if (client->swapped) { 28044642e01fSmrg int n; 280505b261ecSmrg swapl(&wire->sym,n); 280605b261ecSmrg } 280705b261ecSmrg sym->sym= wire->sym; 280805b261ecSmrg sym->mods= wire->mods; 280905b261ecSmrg sym->match= wire->match; 281005b261ecSmrg sym->flags= wire->flags; 281105b261ecSmrg sym->virtual_mod= wire->virtualMod; 281205b261ecSmrg memcpy((char *)&sym->act,(char *)&wire->act, 28134642e01fSmrg SIZEOF(xkbActionWireDesc)); 281405b261ecSmrg } 281505b261ecSmrg data = (char *)wire; 281605b261ecSmrg } 28174642e01fSmrg else if (req->truncateSI) { 28184642e01fSmrg compat->num_si = req->firstSI; 281905b261ecSmrg } 282005b261ecSmrg 28214642e01fSmrg if (req->groups!=0) { 28224642e01fSmrg unsigned i, bit; 282305b261ecSmrg xkbModsWireDesc *wire = (xkbModsWireDesc *)data; 28244642e01fSmrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 28254642e01fSmrg if (req->groups & bit) { 282605b261ecSmrg if (client->swapped) { 28274642e01fSmrg int n; 282805b261ecSmrg swaps(&wire->virtualMods,n); 282905b261ecSmrg } 283005b261ecSmrg compat->groups[i].mask= wire->realMods; 283105b261ecSmrg compat->groups[i].real_mods= wire->realMods; 283205b261ecSmrg compat->groups[i].vmods= wire->virtualMods; 283305b261ecSmrg if (wire->virtualMods!=0) { 283405b261ecSmrg unsigned tmp; 283505b261ecSmrg tmp= XkbMaskForVMask(xkb,wire->virtualMods); 283605b261ecSmrg compat->groups[i].mask|= tmp; 283705b261ecSmrg } 283805b261ecSmrg data+= SIZEOF(xkbModsWireDesc); 283905b261ecSmrg wire= (xkbModsWireDesc *)data; 284005b261ecSmrg } 284105b261ecSmrg } 284205b261ecSmrg } 28434642e01fSmrg i= XkbPaddedSize((data-((char *)req))); 28444642e01fSmrg if ((i/4)!=req->length) { 28454642e01fSmrg ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); 284605b261ecSmrg return BadLength; 284705b261ecSmrg } 28484642e01fSmrg 284905b261ecSmrg if (dev->xkb_interest) { 285005b261ecSmrg xkbCompatMapNotify ev; 285105b261ecSmrg ev.deviceID = dev->id; 28524642e01fSmrg ev.changedGroups = req->groups; 28534642e01fSmrg ev.firstSI = req->firstSI; 28544642e01fSmrg ev.nSI = req->nSI; 285505b261ecSmrg ev.nTotalSI = compat->num_si; 285605b261ecSmrg XkbSendCompatMapNotify(dev,&ev); 285705b261ecSmrg } 285805b261ecSmrg 28594642e01fSmrg if (req->recomputeActions) { 286005b261ecSmrg XkbChangesRec change; 286105b261ecSmrg unsigned check; 286205b261ecSmrg XkbEventCauseRec cause; 286305b261ecSmrg 286405b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client); 28656747b715Smrg memset(&change, 0, sizeof(XkbChangesRec)); 286605b261ecSmrg XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check, 286705b261ecSmrg &cause); 286805b261ecSmrg if (check) 286905b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 287005b261ecSmrg XkbSendNotification(dev,&change,&cause); 287105b261ecSmrg } 28724642e01fSmrg return Success; 28734642e01fSmrg} 28744642e01fSmrg 28754642e01fSmrgint 28764642e01fSmrgProcXkbSetCompatMap(ClientPtr client) 28774642e01fSmrg{ 28784642e01fSmrg DeviceIntPtr dev; 28794642e01fSmrg char *data; 28804642e01fSmrg int rc; 28814642e01fSmrg 28824642e01fSmrg REQUEST(xkbSetCompatMapReq); 28834642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 28844642e01fSmrg 28854642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 28864642e01fSmrg return BadAccess; 28874642e01fSmrg 28884642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 28894642e01fSmrg 28904642e01fSmrg data = (char *)&stuff[1]; 28914642e01fSmrg 28924642e01fSmrg /* check first using a dry-run */ 28934642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); 28944642e01fSmrg if (rc != Success) 28954642e01fSmrg return rc; 28964642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 28974642e01fSmrg { 28984642e01fSmrg DeviceIntPtr other; 28994642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 29004642e01fSmrg { 29016747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 29024642e01fSmrg { 29034642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 29044642e01fSmrg if (rc == Success) 29054642e01fSmrg { 29064642e01fSmrg /* dry-run */ 29074642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); 29084642e01fSmrg if (rc != Success) 29094642e01fSmrg return rc; 29104642e01fSmrg } 29114642e01fSmrg } 29124642e01fSmrg } 29134642e01fSmrg } 29144642e01fSmrg 29154642e01fSmrg /* Yay, the dry-runs succeed. Let's apply */ 29164642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); 29174642e01fSmrg if (rc != Success) 29184642e01fSmrg return rc; 29194642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 29204642e01fSmrg { 29214642e01fSmrg DeviceIntPtr other; 29224642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 29234642e01fSmrg { 29246747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 29254642e01fSmrg { 29264642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 29274642e01fSmrg if (rc == Success) 29284642e01fSmrg { 29294642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); 29304642e01fSmrg if (rc != Success) 29314642e01fSmrg return rc; 29324642e01fSmrg } 29334642e01fSmrg } 29344642e01fSmrg } 29354642e01fSmrg } 29364642e01fSmrg 29376747b715Smrg return Success; 293805b261ecSmrg} 293905b261ecSmrg 294005b261ecSmrg/***====================================================================***/ 294105b261ecSmrg 294205b261ecSmrgint 294305b261ecSmrgProcXkbGetIndicatorState(ClientPtr client) 294405b261ecSmrg{ 294505b261ecSmrg xkbGetIndicatorStateReply rep; 294605b261ecSmrg XkbSrvLedInfoPtr sli; 294705b261ecSmrg DeviceIntPtr dev; 294805b261ecSmrg register int i; 294905b261ecSmrg 295005b261ecSmrg REQUEST(xkbGetIndicatorStateReq); 295105b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 295205b261ecSmrg 295305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 295405b261ecSmrg return BadAccess; 295505b261ecSmrg 29564642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 295705b261ecSmrg 295805b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 295905b261ecSmrg XkbXI_IndicatorStateMask); 296005b261ecSmrg if (!sli) 296105b261ecSmrg return BadAlloc; 296205b261ecSmrg 296305b261ecSmrg rep.type = X_Reply; 296405b261ecSmrg rep.sequenceNumber = client->sequence; 296505b261ecSmrg rep.length = 0; 296605b261ecSmrg rep.deviceID = dev->id; 296705b261ecSmrg rep.state = sli->effectiveState; 296805b261ecSmrg 296905b261ecSmrg if (client->swapped) { 297005b261ecSmrg swaps(&rep.sequenceNumber,i); 297105b261ecSmrg swapl(&rep.state,i); 297205b261ecSmrg } 297305b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep); 29746747b715Smrg return Success; 297505b261ecSmrg} 297605b261ecSmrg 297705b261ecSmrg/***====================================================================***/ 297805b261ecSmrg 297905b261ecSmrgstatic Status 298005b261ecSmrgXkbComputeGetIndicatorMapReplySize( 298105b261ecSmrg XkbIndicatorPtr indicators, 298205b261ecSmrg xkbGetIndicatorMapReply *rep) 298305b261ecSmrg{ 298405b261ecSmrgregister int i,bit; 298505b261ecSmrgint nIndicators; 298605b261ecSmrg 298705b261ecSmrg rep->realIndicators = indicators->phys_indicators; 298805b261ecSmrg for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 298905b261ecSmrg if (rep->which&bit) 299005b261ecSmrg nIndicators++; 299105b261ecSmrg } 299205b261ecSmrg rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4; 299305b261ecSmrg return Success; 299405b261ecSmrg} 299505b261ecSmrg 299605b261ecSmrgstatic int 299705b261ecSmrgXkbSendIndicatorMap( ClientPtr client, 299805b261ecSmrg XkbIndicatorPtr indicators, 299905b261ecSmrg xkbGetIndicatorMapReply * rep) 300005b261ecSmrg{ 300105b261ecSmrgint length; 300205b261ecSmrgCARD8 * map; 300305b261ecSmrgregister int i; 300405b261ecSmrgregister unsigned bit; 300505b261ecSmrg 300605b261ecSmrg length = rep->length*4; 300705b261ecSmrg if (length>0) { 300805b261ecSmrg CARD8 *to; 30096747b715Smrg to= map= malloc(length); 301005b261ecSmrg if (map) { 301105b261ecSmrg xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to; 301205b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 301305b261ecSmrg if (rep->which&bit) { 301405b261ecSmrg wire->flags= indicators->maps[i].flags; 301505b261ecSmrg wire->whichGroups= indicators->maps[i].which_groups; 301605b261ecSmrg wire->groups= indicators->maps[i].groups; 301705b261ecSmrg wire->whichMods= indicators->maps[i].which_mods; 301805b261ecSmrg wire->mods= indicators->maps[i].mods.mask; 301905b261ecSmrg wire->realMods= indicators->maps[i].mods.real_mods; 302005b261ecSmrg wire->virtualMods= indicators->maps[i].mods.vmods; 302105b261ecSmrg wire->ctrls= indicators->maps[i].ctrls; 302205b261ecSmrg if (client->swapped) { 302305b261ecSmrg register int n; 302405b261ecSmrg swaps(&wire->virtualMods,n); 302505b261ecSmrg swapl(&wire->ctrls,n); 302605b261ecSmrg } 302705b261ecSmrg wire++; 302805b261ecSmrg } 302905b261ecSmrg } 303005b261ecSmrg to = (CARD8 *)wire; 303105b261ecSmrg if ((to-map)!=length) { 303205b261ecSmrg client->errorValue = _XkbErrCode2(0xff,length); 30336747b715Smrg free(map); 303405b261ecSmrg return BadLength; 303505b261ecSmrg } 303605b261ecSmrg } 303705b261ecSmrg else return BadAlloc; 303805b261ecSmrg } 303905b261ecSmrg else map = NULL; 304005b261ecSmrg if (client->swapped) { 304105b261ecSmrg swaps(&rep->sequenceNumber,i); 304205b261ecSmrg swapl(&rep->length,i); 304305b261ecSmrg swapl(&rep->which,i); 304405b261ecSmrg swapl(&rep->realIndicators,i); 304505b261ecSmrg } 304605b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep); 304705b261ecSmrg if (map) { 304805b261ecSmrg WriteToClient(client, length, (char *)map); 30496747b715Smrg free((char *)map); 305005b261ecSmrg } 30516747b715Smrg return Success; 305205b261ecSmrg} 305305b261ecSmrg 305405b261ecSmrgint 305505b261ecSmrgProcXkbGetIndicatorMap(ClientPtr client) 305605b261ecSmrg{ 305705b261ecSmrgxkbGetIndicatorMapReply rep; 305805b261ecSmrgDeviceIntPtr dev; 305905b261ecSmrgXkbDescPtr xkb; 306005b261ecSmrgXkbIndicatorPtr leds; 306105b261ecSmrg 306205b261ecSmrg REQUEST(xkbGetIndicatorMapReq); 306305b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 306405b261ecSmrg 306505b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 306605b261ecSmrg return BadAccess; 306705b261ecSmrg 30684642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 306905b261ecSmrg 307005b261ecSmrg xkb= dev->key->xkbInfo->desc; 307105b261ecSmrg leds= xkb->indicators; 307205b261ecSmrg 307305b261ecSmrg rep.type = X_Reply; 307405b261ecSmrg rep.sequenceNumber = client->sequence; 307505b261ecSmrg rep.length = 0; 307605b261ecSmrg rep.deviceID = dev->id; 307705b261ecSmrg rep.which = stuff->which; 307805b261ecSmrg XkbComputeGetIndicatorMapReplySize(leds,&rep); 307905b261ecSmrg return XkbSendIndicatorMap(client,leds,&rep); 308005b261ecSmrg} 308105b261ecSmrg 30824642e01fSmrg/** 30834642e01fSmrg * Apply the given map to the given device. Which specifies which components 30844642e01fSmrg * to apply. 30854642e01fSmrg */ 30864642e01fSmrgstatic int 30874642e01fSmrg_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, 30884642e01fSmrg int which, xkbIndicatorMapWireDesc *desc) 30894642e01fSmrg{ 30904642e01fSmrg XkbSrvInfoPtr xkbi; 30914642e01fSmrg XkbSrvLedInfoPtr sli; 30924642e01fSmrg XkbEventCauseRec cause; 30934642e01fSmrg int i, bit; 30944642e01fSmrg 30954642e01fSmrg xkbi = dev->key->xkbInfo; 30964642e01fSmrg 30974642e01fSmrg sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 30984642e01fSmrg XkbXI_IndicatorMapsMask); 30994642e01fSmrg if (!sli) 31004642e01fSmrg return BadAlloc; 31014642e01fSmrg 31024642e01fSmrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 31034642e01fSmrg if (which & bit) { 31044642e01fSmrg sli->maps[i].flags = desc->flags; 31054642e01fSmrg sli->maps[i].which_groups = desc->whichGroups; 31064642e01fSmrg sli->maps[i].groups = desc->groups; 31074642e01fSmrg sli->maps[i].which_mods = desc->whichMods; 31084642e01fSmrg sli->maps[i].mods.mask = desc->mods; 31094642e01fSmrg sli->maps[i].mods.real_mods = desc->mods; 31104642e01fSmrg sli->maps[i].mods.vmods= desc->virtualMods; 31114642e01fSmrg sli->maps[i].ctrls = desc->ctrls; 31124642e01fSmrg if (desc->virtualMods!=0) { 31134642e01fSmrg unsigned tmp; 31144642e01fSmrg tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods); 31154642e01fSmrg sli->maps[i].mods.mask= desc->mods|tmp; 31164642e01fSmrg } 31174642e01fSmrg desc++; 31184642e01fSmrg } 31194642e01fSmrg } 31204642e01fSmrg 31214642e01fSmrg XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); 31224642e01fSmrg XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause); 31234642e01fSmrg 31244642e01fSmrg return Success; 31254642e01fSmrg} 31264642e01fSmrg 312705b261ecSmrgint 312805b261ecSmrgProcXkbSetIndicatorMap(ClientPtr client) 312905b261ecSmrg{ 31304642e01fSmrg int i, bit; 31314642e01fSmrg int nIndicators; 31324642e01fSmrg DeviceIntPtr dev; 31334642e01fSmrg xkbIndicatorMapWireDesc *from; 31344642e01fSmrg int rc; 313505b261ecSmrg 313605b261ecSmrg REQUEST(xkbSetIndicatorMapReq); 313705b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 313805b261ecSmrg 313905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 314005b261ecSmrg return BadAccess; 314105b261ecSmrg 31424642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 314305b261ecSmrg 314405b261ecSmrg if (stuff->which==0) 31456747b715Smrg return Success; 314605b261ecSmrg 314705b261ecSmrg for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 314805b261ecSmrg if (stuff->which&bit) 314905b261ecSmrg nIndicators++; 315005b261ecSmrg } 315105b261ecSmrg if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+ 315205b261ecSmrg (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) { 315305b261ecSmrg return BadLength; 315405b261ecSmrg } 315505b261ecSmrg 315605b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 315705b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 315805b261ecSmrg if (stuff->which&bit) { 315905b261ecSmrg if (client->swapped) { 31604642e01fSmrg int n; 316105b261ecSmrg swaps(&from->virtualMods,n); 316205b261ecSmrg swapl(&from->ctrls,n); 316305b261ecSmrg } 316405b261ecSmrg CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup); 316505b261ecSmrg CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods); 316605b261ecSmrg from++; 316705b261ecSmrg } 316805b261ecSmrg } 316905b261ecSmrg 317005b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 31714642e01fSmrg rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); 31724642e01fSmrg if (rc != Success) 31734642e01fSmrg return rc; 31744642e01fSmrg 31754642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 31764642e01fSmrg { 31774642e01fSmrg DeviceIntPtr other; 31784642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 31794642e01fSmrg { 31806747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 31814642e01fSmrg { 31824642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess); 31834642e01fSmrg if (rc == Success) 31844642e01fSmrg _XkbSetIndicatorMap(client, other, stuff->which, from); 31854642e01fSmrg } 31864642e01fSmrg } 318705b261ecSmrg } 318805b261ecSmrg 31894642e01fSmrg return Success; 319005b261ecSmrg} 319105b261ecSmrg 319205b261ecSmrg/***====================================================================***/ 319305b261ecSmrg 319405b261ecSmrgint 319505b261ecSmrgProcXkbGetNamedIndicator(ClientPtr client) 319605b261ecSmrg{ 319705b261ecSmrg DeviceIntPtr dev; 319805b261ecSmrg xkbGetNamedIndicatorReply rep; 319905b261ecSmrg register int i = 0; 320005b261ecSmrg XkbSrvLedInfoPtr sli; 320105b261ecSmrg XkbIndicatorMapPtr map = NULL; 320205b261ecSmrg 320305b261ecSmrg REQUEST(xkbGetNamedIndicatorReq); 320405b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 320505b261ecSmrg 320605b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 320705b261ecSmrg return BadAccess; 320805b261ecSmrg 32094642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 321005b261ecSmrg CHK_ATOM_ONLY(stuff->indicator); 321105b261ecSmrg 321205b261ecSmrg sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0); 321305b261ecSmrg if (!sli) 321405b261ecSmrg return BadAlloc; 321505b261ecSmrg 321605b261ecSmrg i= 0; 321705b261ecSmrg map= NULL; 321805b261ecSmrg if ((sli->names)&&(sli->maps)) { 321905b261ecSmrg for (i=0;i<XkbNumIndicators;i++) { 322005b261ecSmrg if (stuff->indicator==sli->names[i]) { 322105b261ecSmrg map= &sli->maps[i]; 322205b261ecSmrg break; 322305b261ecSmrg } 322405b261ecSmrg } 322505b261ecSmrg } 322605b261ecSmrg 322705b261ecSmrg rep.type= X_Reply; 322805b261ecSmrg rep.length = 0; 322905b261ecSmrg rep.sequenceNumber = client->sequence; 323005b261ecSmrg rep.deviceID = dev->id; 323105b261ecSmrg rep.indicator= stuff->indicator; 323205b261ecSmrg if (map!=NULL) { 32336747b715Smrg rep.found= TRUE; 323405b261ecSmrg rep.on= ((sli->effectiveState&(1<<i))!=0); 323505b261ecSmrg rep.realIndicator= ((sli->physIndicators&(1<<i))!=0); 323605b261ecSmrg rep.ndx= i; 323705b261ecSmrg rep.flags= map->flags; 323805b261ecSmrg rep.whichGroups= map->which_groups; 323905b261ecSmrg rep.groups= map->groups; 324005b261ecSmrg rep.whichMods= map->which_mods; 324105b261ecSmrg rep.mods= map->mods.mask; 324205b261ecSmrg rep.realMods= map->mods.real_mods; 324305b261ecSmrg rep.virtualMods= map->mods.vmods; 324405b261ecSmrg rep.ctrls= map->ctrls; 32456747b715Smrg rep.supported= TRUE; 324605b261ecSmrg } 324705b261ecSmrg else { 32486747b715Smrg rep.found= FALSE; 32496747b715Smrg rep.on= FALSE; 32506747b715Smrg rep.realIndicator= FALSE; 325105b261ecSmrg rep.ndx= XkbNoIndicator; 325205b261ecSmrg rep.flags= 0; 325305b261ecSmrg rep.whichGroups= 0; 325405b261ecSmrg rep.groups= 0; 325505b261ecSmrg rep.whichMods= 0; 325605b261ecSmrg rep.mods= 0; 325705b261ecSmrg rep.realMods= 0; 325805b261ecSmrg rep.virtualMods= 0; 325905b261ecSmrg rep.ctrls= 0; 32606747b715Smrg rep.supported= TRUE; 326105b261ecSmrg } 326205b261ecSmrg if ( client->swapped ) { 326305b261ecSmrg register int n; 326405b261ecSmrg swapl(&rep.length,n); 326505b261ecSmrg swaps(&rep.sequenceNumber,n); 326605b261ecSmrg swapl(&rep.indicator,n); 326705b261ecSmrg swaps(&rep.virtualMods,n); 326805b261ecSmrg swapl(&rep.ctrls,n); 326905b261ecSmrg } 327005b261ecSmrg 327105b261ecSmrg WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep); 32726747b715Smrg return Success; 327305b261ecSmrg} 327405b261ecSmrg 327505b261ecSmrg 32764642e01fSmrg/** 32774642e01fSmrg * Find the IM on the device. 32784642e01fSmrg * Returns the map, or NULL if the map doesn't exist. 32794642e01fSmrg * If the return value is NULL, led_return is undefined. Otherwise, led_return 32804642e01fSmrg * is set to the led index of the map. 32814642e01fSmrg */ 32824642e01fSmrgstatic XkbIndicatorMapPtr 32834642e01fSmrg_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, 32844642e01fSmrg int *led_return) 32854642e01fSmrg{ 32864642e01fSmrg XkbIndicatorMapPtr map; 328705b261ecSmrg 32884642e01fSmrg /* search for the right indicator */ 32894642e01fSmrg map = NULL; 329005b261ecSmrg if (sli->names && sli->maps) { 32916747b715Smrg int led; 32926747b715Smrg 32934642e01fSmrg for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { 32944642e01fSmrg if (sli->names[led] == indicator) { 329505b261ecSmrg map= &sli->maps[led]; 32966747b715Smrg *led_return = led; 329705b261ecSmrg break; 329805b261ecSmrg } 329905b261ecSmrg } 330005b261ecSmrg } 330105b261ecSmrg 33024642e01fSmrg return map; 33034642e01fSmrg} 33044642e01fSmrg 33054642e01fSmrg/** 33066747b715Smrg * Creates an indicator map on the device. If dryRun is TRUE, it only checks 33074642e01fSmrg * if creation is possible, but doesn't actually create it. 33084642e01fSmrg */ 33094642e01fSmrgstatic int 33104642e01fSmrg_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, 33114642e01fSmrg int ledClass, int ledID, 33124642e01fSmrg XkbIndicatorMapPtr *map_return, int *led_return, 33134642e01fSmrg Bool dryRun) 33144642e01fSmrg{ 33154642e01fSmrg XkbSrvLedInfoPtr sli; 33164642e01fSmrg XkbIndicatorMapPtr map; 33174642e01fSmrg int led; 33184642e01fSmrg 33194642e01fSmrg sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); 33204642e01fSmrg if (!sli) 33214642e01fSmrg return BadAlloc; 33224642e01fSmrg 33234642e01fSmrg map = _XkbFindNamedIndicatorMap(sli, indicator, &led); 33244642e01fSmrg 33254642e01fSmrg if (!map) 33264642e01fSmrg { 33274642e01fSmrg /* find first unused indicator maps and assign the name to it */ 33284642e01fSmrg for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) { 33294642e01fSmrg if ((sli->names) && (sli->maps) && (sli->names[led] == None) && 33304642e01fSmrg (!XkbIM_InUse(&sli->maps[led]))) 33314642e01fSmrg { 33324642e01fSmrg map = &sli->maps[led]; 33334642e01fSmrg if (!dryRun) 33344642e01fSmrg sli->names[led] = indicator; 33354642e01fSmrg break; 33364642e01fSmrg } 33374642e01fSmrg } 33384642e01fSmrg } 33394642e01fSmrg 33404642e01fSmrg if (!map) 33414642e01fSmrg return BadAlloc; 33424642e01fSmrg 33434642e01fSmrg *led_return = led; 33444642e01fSmrg *map_return = map; 33454642e01fSmrg return Success; 33464642e01fSmrg} 33474642e01fSmrg 33484642e01fSmrgstatic int 33494642e01fSmrg_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, 33504642e01fSmrg xkbSetNamedIndicatorReq *stuff) 33514642e01fSmrg{ 33524642e01fSmrg unsigned int extDevReason; 33534642e01fSmrg unsigned int statec, namec, mapc; 33544642e01fSmrg XkbSrvLedInfoPtr sli; 33554642e01fSmrg int led = 0; 33564642e01fSmrg XkbIndicatorMapPtr map; 33574642e01fSmrg DeviceIntPtr kbd; 33584642e01fSmrg XkbEventCauseRec cause; 33594642e01fSmrg xkbExtensionDeviceNotify ed; 33604642e01fSmrg XkbChangesRec changes; 33614642e01fSmrg int rc; 33624642e01fSmrg 33634642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, 33644642e01fSmrg stuff->ledID, &map, &led, FALSE); 33654642e01fSmrg if (rc != Success || !map) /* oh-oh */ 33664642e01fSmrg return rc; 33674642e01fSmrg 33684642e01fSmrg sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 33694642e01fSmrg XkbXI_IndicatorsMask); 33704642e01fSmrg if (!sli) 33714642e01fSmrg return BadAlloc; 33724642e01fSmrg 33734642e01fSmrg namec = mapc = statec = 0; 33744642e01fSmrg extDevReason = 0; 33754642e01fSmrg 33764642e01fSmrg namec |= (1<<led); 33774642e01fSmrg sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); 33784642e01fSmrg extDevReason |= XkbXI_IndicatorNamesMask; 33794642e01fSmrg 33804642e01fSmrg if (stuff->setMap) { 33814642e01fSmrg map->flags = stuff->flags; 33824642e01fSmrg map->which_groups = stuff->whichGroups; 33834642e01fSmrg map->groups = stuff->groups; 33844642e01fSmrg map->which_mods = stuff->whichMods; 33854642e01fSmrg map->mods.mask = stuff->realMods; 33864642e01fSmrg map->mods.real_mods = stuff->realMods; 33874642e01fSmrg map->mods.vmods= stuff->virtualMods; 33884642e01fSmrg map->ctrls = stuff->ctrls; 33894642e01fSmrg mapc|= (1<<led); 33904642e01fSmrg } 33914642e01fSmrg 33924642e01fSmrg if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) 33934642e01fSmrg { 33944642e01fSmrg if (stuff->on) sli->explicitState |= (1<<led); 33954642e01fSmrg else sli->explicitState &= ~(1<<led); 33964642e01fSmrg statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); 339705b261ecSmrg } 33984642e01fSmrg 33996747b715Smrg memset((char *)&ed, 0, sizeof(xkbExtensionDeviceNotify)); 34006747b715Smrg memset((char *)&changes, 0, sizeof(XkbChangesRec)); 340105b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client); 340205b261ecSmrg if (namec) 34034642e01fSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 340405b261ecSmrg if (mapc) 34054642e01fSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 340605b261ecSmrg if (statec) 34074642e01fSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 340805b261ecSmrg 34094642e01fSmrg kbd = dev; 341005b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 34114642e01fSmrg kbd = inputInfo.keyboard; 34124642e01fSmrg XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 34134642e01fSmrg 34144642e01fSmrg return Success; 34154642e01fSmrg} 34164642e01fSmrg 34174642e01fSmrgint 34184642e01fSmrgProcXkbSetNamedIndicator(ClientPtr client) 34194642e01fSmrg{ 34204642e01fSmrg int rc; 34214642e01fSmrg DeviceIntPtr dev; 34224642e01fSmrg int led = 0; 34234642e01fSmrg XkbIndicatorMapPtr map; 34244642e01fSmrg 34254642e01fSmrg REQUEST(xkbSetNamedIndicatorReq); 34264642e01fSmrg REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 34274642e01fSmrg 34284642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 34294642e01fSmrg return BadAccess; 34304642e01fSmrg 34314642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 34324642e01fSmrg CHK_ATOM_ONLY(stuff->indicator); 34334642e01fSmrg CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); 34344642e01fSmrg CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); 34354642e01fSmrg 34364642e01fSmrg /* Dry-run for checks */ 34374642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, 34384642e01fSmrg stuff->ledClass, stuff->ledID, 34394642e01fSmrg &map, &led, TRUE); 34404642e01fSmrg if (rc != Success || !map) /* couldn't be created or didn't exist */ 34414642e01fSmrg return rc; 34424642e01fSmrg 34434642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 34444642e01fSmrg stuff->deviceSpec == XkbUseCorePtr) 34454642e01fSmrg { 34464642e01fSmrg DeviceIntPtr other; 34474642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 34484642e01fSmrg { 34496747b715Smrg if ((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev && 345052397711Smrg (other->kbdfeed || other->leds) && 34514642e01fSmrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 34524642e01fSmrg { 34534642e01fSmrg rc = _XkbCreateIndicatorMap(other, stuff->indicator, 34544642e01fSmrg stuff->ledClass, stuff->ledID, 34554642e01fSmrg &map, &led, TRUE); 34564642e01fSmrg if (rc != Success || !map) 34574642e01fSmrg return rc; 34584642e01fSmrg } 34594642e01fSmrg } 34604642e01fSmrg } 34614642e01fSmrg 34624642e01fSmrg /* All checks passed, let's do it */ 34634642e01fSmrg rc = _XkbSetNamedIndicator(client, dev, stuff); 34644642e01fSmrg if (rc != Success) 34654642e01fSmrg return rc; 34664642e01fSmrg 34674642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 34684642e01fSmrg stuff->deviceSpec == XkbUseCorePtr) 34694642e01fSmrg { 34704642e01fSmrg DeviceIntPtr other; 34714642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 34724642e01fSmrg { 34736747b715Smrg if ((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev && 347452397711Smrg (other->kbdfeed || other->leds) && 34754642e01fSmrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 34764642e01fSmrg { 34774642e01fSmrg _XkbSetNamedIndicator(client, other, stuff); 34784642e01fSmrg } 34794642e01fSmrg } 34804642e01fSmrg } 34814642e01fSmrg 34826747b715Smrg return Success; 348305b261ecSmrg} 348405b261ecSmrg 348505b261ecSmrg/***====================================================================***/ 348605b261ecSmrg 348705b261ecSmrgstatic CARD32 348805b261ecSmrg_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) 348905b261ecSmrg{ 349005b261ecSmrgregister unsigned int i,bit,nAtoms; 349105b261ecSmrgregister CARD32 atomsPresent; 349205b261ecSmrg 349305b261ecSmrg for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { 349405b261ecSmrg if (atoms[i]!=None) { 349505b261ecSmrg atomsPresent|= bit; 349605b261ecSmrg nAtoms++; 349705b261ecSmrg } 349805b261ecSmrg } 349905b261ecSmrg if (count) 350005b261ecSmrg *count= nAtoms; 350105b261ecSmrg return atomsPresent; 350205b261ecSmrg} 350305b261ecSmrg 350405b261ecSmrgstatic char * 350505b261ecSmrg_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap) 350605b261ecSmrg{ 350705b261ecSmrgregister unsigned int i; 350805b261ecSmrgAtom *atm; 350905b261ecSmrg 351005b261ecSmrg atm = (Atom *)wire; 351105b261ecSmrg for (i=0;i<maxAtoms;i++) { 351205b261ecSmrg if (atoms[i]!=None) { 351305b261ecSmrg *atm= atoms[i]; 351405b261ecSmrg if (swap) { 351505b261ecSmrg register int n; 351605b261ecSmrg swapl(atm,n); 351705b261ecSmrg } 351805b261ecSmrg atm++; 351905b261ecSmrg } 352005b261ecSmrg } 352105b261ecSmrg return (char *)atm; 352205b261ecSmrg} 352305b261ecSmrg 352405b261ecSmrgstatic Status 352505b261ecSmrgXkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep) 352605b261ecSmrg{ 352705b261ecSmrgregister unsigned which,length; 352805b261ecSmrgregister int i; 352905b261ecSmrg 353005b261ecSmrg rep->minKeyCode= xkb->min_key_code; 353105b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 353205b261ecSmrg which= rep->which; 353305b261ecSmrg length= 0; 353405b261ecSmrg if (xkb->names!=NULL) { 353505b261ecSmrg if (which&XkbKeycodesNameMask) length++; 353605b261ecSmrg if (which&XkbGeometryNameMask) length++; 353705b261ecSmrg if (which&XkbSymbolsNameMask) length++; 353805b261ecSmrg if (which&XkbPhysSymbolsNameMask) length++; 353905b261ecSmrg if (which&XkbTypesNameMask) length++; 354005b261ecSmrg if (which&XkbCompatNameMask) length++; 354105b261ecSmrg } 354205b261ecSmrg else which&= ~XkbComponentNamesMask; 354305b261ecSmrg 354405b261ecSmrg if (xkb->map!=NULL) { 354505b261ecSmrg if (which&XkbKeyTypeNamesMask) 354605b261ecSmrg length+= xkb->map->num_types; 354705b261ecSmrg rep->nTypes= xkb->map->num_types; 354805b261ecSmrg if (which&XkbKTLevelNamesMask) { 354905b261ecSmrg XkbKeyTypePtr pType = xkb->map->types; 355005b261ecSmrg int nKTLevels = 0; 355105b261ecSmrg 355205b261ecSmrg length+= XkbPaddedSize(xkb->map->num_types)/4; 355305b261ecSmrg for (i=0;i<xkb->map->num_types;i++,pType++) { 355405b261ecSmrg if (pType->level_names!=NULL) 355505b261ecSmrg nKTLevels+= pType->num_levels; 355605b261ecSmrg } 355705b261ecSmrg rep->nKTLevels= nKTLevels; 355805b261ecSmrg length+= nKTLevels; 355905b261ecSmrg } 356005b261ecSmrg } 356105b261ecSmrg else { 356205b261ecSmrg rep->nTypes= 0; 356305b261ecSmrg rep->nKTLevels= 0; 356405b261ecSmrg which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask); 356505b261ecSmrg } 356605b261ecSmrg 356705b261ecSmrg rep->minKeyCode= xkb->min_key_code; 356805b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 356905b261ecSmrg rep->indicators= 0; 357005b261ecSmrg rep->virtualMods= 0; 357105b261ecSmrg rep->groupNames= 0; 357205b261ecSmrg if (xkb->names!=NULL) { 357305b261ecSmrg if (which&XkbIndicatorNamesMask) { 357405b261ecSmrg int nLeds; 357505b261ecSmrg rep->indicators= 357605b261ecSmrg _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds); 357705b261ecSmrg length+= nLeds; 357805b261ecSmrg if (nLeds==0) 357905b261ecSmrg which&= ~XkbIndicatorNamesMask; 358005b261ecSmrg } 358105b261ecSmrg 358205b261ecSmrg if (which&XkbVirtualModNamesMask) { 358305b261ecSmrg int nVMods; 358405b261ecSmrg rep->virtualMods= 358505b261ecSmrg _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods); 358605b261ecSmrg length+= nVMods; 358705b261ecSmrg if (nVMods==0) 358805b261ecSmrg which&= ~XkbVirtualModNamesMask; 358905b261ecSmrg } 359005b261ecSmrg 359105b261ecSmrg if (which&XkbGroupNamesMask) { 359205b261ecSmrg int nGroups; 359305b261ecSmrg rep->groupNames= 359405b261ecSmrg _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups); 359505b261ecSmrg length+= nGroups; 359605b261ecSmrg if (nGroups==0) 359705b261ecSmrg which&= ~XkbGroupNamesMask; 359805b261ecSmrg } 359905b261ecSmrg 360005b261ecSmrg if ((which&XkbKeyNamesMask)&&(xkb->names->keys)) 360105b261ecSmrg length+= rep->nKeys; 360205b261ecSmrg else which&= ~XkbKeyNamesMask; 360305b261ecSmrg 360405b261ecSmrg if ((which&XkbKeyAliasesMask)&& 360505b261ecSmrg (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) { 360605b261ecSmrg rep->nKeyAliases= xkb->names->num_key_aliases; 360705b261ecSmrg length+= rep->nKeyAliases*2; 360805b261ecSmrg } 360905b261ecSmrg else { 361005b261ecSmrg which&= ~XkbKeyAliasesMask; 361105b261ecSmrg rep->nKeyAliases= 0; 361205b261ecSmrg } 361305b261ecSmrg 361405b261ecSmrg if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0)) 361505b261ecSmrg length+= xkb->names->num_rg; 361605b261ecSmrg else which&= ~XkbRGNamesMask; 361705b261ecSmrg } 361805b261ecSmrg else { 361905b261ecSmrg which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask); 362005b261ecSmrg which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask); 362105b261ecSmrg which&= ~XkbRGNamesMask; 362205b261ecSmrg } 362305b261ecSmrg 362405b261ecSmrg rep->length= length; 362505b261ecSmrg rep->which= which; 362605b261ecSmrg return Success; 362705b261ecSmrg} 362805b261ecSmrg 362905b261ecSmrgstatic int 363005b261ecSmrgXkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep) 363105b261ecSmrg{ 363205b261ecSmrgregister unsigned i,length,which; 363305b261ecSmrgchar * start; 363405b261ecSmrgchar * desc; 363505b261ecSmrgregister int n; 363605b261ecSmrg 363705b261ecSmrg length= rep->length*4; 363805b261ecSmrg which= rep->which; 363905b261ecSmrg if (client->swapped) { 364005b261ecSmrg swaps(&rep->sequenceNumber,n); 364105b261ecSmrg swapl(&rep->length,n); 364205b261ecSmrg swapl(&rep->which,n); 364305b261ecSmrg swaps(&rep->virtualMods,n); 364405b261ecSmrg swapl(&rep->indicators,n); 364505b261ecSmrg } 364605b261ecSmrg 36479ace9065Smrg start = desc = calloc(1, length); 364805b261ecSmrg if ( !start ) 364905b261ecSmrg return BadAlloc; 365005b261ecSmrg if (xkb->names) { 365105b261ecSmrg if (which&XkbKeycodesNameMask) { 365205b261ecSmrg *((CARD32 *)desc)= xkb->names->keycodes; 365305b261ecSmrg if (client->swapped) { 365405b261ecSmrg swapl(desc,n); 365505b261ecSmrg } 365605b261ecSmrg desc+= 4; 365705b261ecSmrg } 365805b261ecSmrg if (which&XkbGeometryNameMask) { 365905b261ecSmrg *((CARD32 *)desc)= xkb->names->geometry; 366005b261ecSmrg if (client->swapped) { 366105b261ecSmrg swapl(desc,n); 366205b261ecSmrg } 366305b261ecSmrg desc+= 4; 366405b261ecSmrg } 366505b261ecSmrg if (which&XkbSymbolsNameMask) { 366605b261ecSmrg *((CARD32 *)desc)= xkb->names->symbols; 366705b261ecSmrg if (client->swapped) { 366805b261ecSmrg swapl(desc,n); 366905b261ecSmrg } 367005b261ecSmrg desc+= 4; 367105b261ecSmrg } 367205b261ecSmrg if (which&XkbPhysSymbolsNameMask) { 367305b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 367405b261ecSmrg atm[0]= (CARD32)xkb->names->phys_symbols; 367505b261ecSmrg if (client->swapped) { 367605b261ecSmrg swapl(&atm[0],n); 367705b261ecSmrg } 367805b261ecSmrg desc+= 4; 367905b261ecSmrg } 368005b261ecSmrg if (which&XkbTypesNameMask) { 368105b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->types; 368205b261ecSmrg if (client->swapped) { 368305b261ecSmrg swapl(desc,n); 368405b261ecSmrg } 368505b261ecSmrg desc+= 4; 368605b261ecSmrg } 368705b261ecSmrg if (which&XkbCompatNameMask) { 368805b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->compat; 368905b261ecSmrg if (client->swapped) { 369005b261ecSmrg swapl(desc,n); 369105b261ecSmrg } 369205b261ecSmrg desc+= 4; 369305b261ecSmrg } 369405b261ecSmrg if (which&XkbKeyTypeNamesMask) { 369505b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 369605b261ecSmrg register XkbKeyTypePtr type= xkb->map->types; 369705b261ecSmrg 369805b261ecSmrg for (i=0;i<xkb->map->num_types;i++,atm++,type++) { 369905b261ecSmrg *atm= (CARD32)type->name; 370005b261ecSmrg if (client->swapped) { 370105b261ecSmrg swapl(atm,n); 370205b261ecSmrg } 370305b261ecSmrg } 370405b261ecSmrg desc= (char *)atm; 370505b261ecSmrg } 370605b261ecSmrg if (which&XkbKTLevelNamesMask && xkb->map) { 370705b261ecSmrg XkbKeyTypePtr type = xkb->map->types; 370805b261ecSmrg register CARD32 *atm; 370905b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 371005b261ecSmrg *desc++ = type->num_levels; 371105b261ecSmrg } 371205b261ecSmrg desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes; 371305b261ecSmrg 371405b261ecSmrg atm= (CARD32 *)desc; 371505b261ecSmrg type = xkb->map->types; 371605b261ecSmrg for (i=0;i<xkb->map->num_types;i++,type++) { 371705b261ecSmrg register unsigned l; 371805b261ecSmrg if (type->level_names) { 371905b261ecSmrg for (l=0;l<type->num_levels;l++,atm++) { 372005b261ecSmrg *atm= type->level_names[l]; 372105b261ecSmrg if (client->swapped) { 372205b261ecSmrg swapl(atm,n); 372305b261ecSmrg } 372405b261ecSmrg } 372505b261ecSmrg desc+= type->num_levels*4; 372605b261ecSmrg } 372705b261ecSmrg } 372805b261ecSmrg } 372905b261ecSmrg if (which&XkbIndicatorNamesMask) { 373005b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators, 373105b261ecSmrg client->swapped); 373205b261ecSmrg } 373305b261ecSmrg if (which&XkbVirtualModNamesMask) { 373405b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods, 373505b261ecSmrg client->swapped); 373605b261ecSmrg } 373705b261ecSmrg if (which&XkbGroupNamesMask) { 373805b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups, 373905b261ecSmrg client->swapped); 374005b261ecSmrg } 374105b261ecSmrg if (which&XkbKeyNamesMask) { 374205b261ecSmrg for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) { 374305b261ecSmrg *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey]; 374405b261ecSmrg } 374505b261ecSmrg } 374605b261ecSmrg if (which&XkbKeyAliasesMask) { 374705b261ecSmrg XkbKeyAliasPtr pAl; 374805b261ecSmrg pAl= xkb->names->key_aliases; 374905b261ecSmrg for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) { 375005b261ecSmrg *((XkbKeyAliasPtr)desc)= *pAl; 375105b261ecSmrg } 375205b261ecSmrg } 375305b261ecSmrg if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) { 375405b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 375505b261ecSmrg for (i=0;i<rep->nRadioGroups;i++,atm++) { 375605b261ecSmrg *atm= (CARD32)xkb->names->radio_groups[i]; 375705b261ecSmrg if (client->swapped) { 375805b261ecSmrg swapl(atm,n); 375905b261ecSmrg } 376005b261ecSmrg } 376105b261ecSmrg desc+= rep->nRadioGroups*4; 376205b261ecSmrg } 376305b261ecSmrg } 376405b261ecSmrg 376505b261ecSmrg if ((desc-start)!=(length)) { 37664642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 376705b261ecSmrg length, (unsigned long)(desc-start)); 376805b261ecSmrg } 376905b261ecSmrg WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep); 377005b261ecSmrg WriteToClient(client, length, start); 37716747b715Smrg free((char *)start); 37726747b715Smrg return Success; 377305b261ecSmrg} 377405b261ecSmrg 377505b261ecSmrgint 377605b261ecSmrgProcXkbGetNames(ClientPtr client) 377705b261ecSmrg{ 377805b261ecSmrg DeviceIntPtr dev; 377905b261ecSmrg XkbDescPtr xkb; 378005b261ecSmrg xkbGetNamesReply rep; 378105b261ecSmrg 378205b261ecSmrg REQUEST(xkbGetNamesReq); 378305b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamesReq); 378405b261ecSmrg 378505b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 378605b261ecSmrg return BadAccess; 378705b261ecSmrg 37884642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 378905b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 379005b261ecSmrg 379105b261ecSmrg xkb = dev->key->xkbInfo->desc; 37926747b715Smrg memset(&rep, 0, sizeof(xkbGetNamesReply)); 379305b261ecSmrg rep.type= X_Reply; 379405b261ecSmrg rep.sequenceNumber= client->sequence; 379505b261ecSmrg rep.length = 0; 379605b261ecSmrg rep.deviceID = dev->id; 379705b261ecSmrg rep.which = stuff->which; 379805b261ecSmrg rep.nTypes = xkb->map->num_types; 379905b261ecSmrg rep.firstKey = xkb->min_key_code; 380005b261ecSmrg rep.nKeys = XkbNumKeys(xkb); 380105b261ecSmrg if (xkb->names!=NULL) { 380205b261ecSmrg rep.nKeyAliases= xkb->names->num_key_aliases; 380305b261ecSmrg rep.nRadioGroups = xkb->names->num_rg; 380405b261ecSmrg } 380505b261ecSmrg else { 380605b261ecSmrg rep.nKeyAliases= rep.nRadioGroups= 0; 380705b261ecSmrg } 380805b261ecSmrg XkbComputeGetNamesReplySize(xkb,&rep); 380905b261ecSmrg return XkbSendNames(client,xkb,&rep); 381005b261ecSmrg} 381105b261ecSmrg 381205b261ecSmrg/***====================================================================***/ 381305b261ecSmrg 381405b261ecSmrgstatic CARD32 * 381505b261ecSmrg_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError) 381605b261ecSmrg{ 381705b261ecSmrgregister int i; 381805b261ecSmrg 381905b261ecSmrg for (i=0;i<nAtoms;i++,wire++) { 382005b261ecSmrg if (swapped) { 382105b261ecSmrg register int n; 382205b261ecSmrg swapl(wire,n); 382305b261ecSmrg } 382405b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) { 382505b261ecSmrg *pError= ((Atom)*wire); 382605b261ecSmrg return NULL; 382705b261ecSmrg } 382805b261ecSmrg } 382905b261ecSmrg return wire; 383005b261ecSmrg} 383105b261ecSmrg 383205b261ecSmrgstatic CARD32 * 383305b261ecSmrg_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped, 383405b261ecSmrg Atom *pError) 383505b261ecSmrg{ 383605b261ecSmrgregister unsigned i,bit; 383705b261ecSmrg 383805b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 383905b261ecSmrg if ((present&bit)==0) 384005b261ecSmrg continue; 384105b261ecSmrg if (swapped) { 384205b261ecSmrg register int n; 384305b261ecSmrg swapl(wire,n); 384405b261ecSmrg } 384505b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) { 384605b261ecSmrg *pError= (Atom)*wire; 384705b261ecSmrg return NULL; 384805b261ecSmrg } 384905b261ecSmrg wire++; 385005b261ecSmrg } 385105b261ecSmrg return wire; 385205b261ecSmrg} 385305b261ecSmrg 385405b261ecSmrgstatic Atom * 385505b261ecSmrg_XkbCopyMaskedAtoms( Atom *wire, 385605b261ecSmrg Atom *dest, 385705b261ecSmrg int nAtoms, 385805b261ecSmrg CARD32 present) 385905b261ecSmrg{ 386005b261ecSmrgregister int i,bit; 386105b261ecSmrg 386205b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 386305b261ecSmrg if ((present&bit)==0) 386405b261ecSmrg continue; 386505b261ecSmrg dest[i]= *wire++; 386605b261ecSmrg } 386705b261ecSmrg return wire; 386805b261ecSmrg} 386905b261ecSmrg 387005b261ecSmrgstatic Bool 387105b261ecSmrg_XkbCheckTypeName(Atom name,int typeNdx) 387205b261ecSmrg{ 38736747b715Smrgconst char * str; 387405b261ecSmrg 387505b261ecSmrg str= NameForAtom(name); 387605b261ecSmrg if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)|| 387705b261ecSmrg (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0)) 38786747b715Smrg return FALSE; 38796747b715Smrg return TRUE; 388005b261ecSmrg} 388105b261ecSmrg 38824642e01fSmrg/** 38834642e01fSmrg * Check the device-dependent data in the request against the device. Returns 38844642e01fSmrg * Success, or the appropriate error code. 38854642e01fSmrg */ 38864642e01fSmrgstatic int 38874642e01fSmrg_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 38884642e01fSmrg xkbSetNamesReq *stuff, CARD32 *data) 388905b261ecSmrg{ 389005b261ecSmrg XkbDescRec *xkb; 389105b261ecSmrg XkbNamesRec *names; 389205b261ecSmrg CARD32 *tmp; 389305b261ecSmrg Atom bad; 389405b261ecSmrg 38954642e01fSmrg tmp = data; 38964642e01fSmrg xkb = dev->key->xkbInfo->desc; 38974642e01fSmrg names = xkb->names; 38984642e01fSmrg 38994642e01fSmrg 39004642e01fSmrg if (stuff->which & XkbKeyTypeNamesMask) { 39014642e01fSmrg int i; 39024642e01fSmrg CARD32 *old; 39034642e01fSmrg if ( stuff->nTypes<1 ) { 39044642e01fSmrg client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); 39054642e01fSmrg return BadValue; 39064642e01fSmrg } 39074642e01fSmrg if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { 39084642e01fSmrg client->errorValue = _XkbErrCode4(0x03,stuff->firstType, 39094642e01fSmrg stuff->nTypes, 39104642e01fSmrg xkb->map->num_types); 39114642e01fSmrg return BadValue; 39124642e01fSmrg } 39134642e01fSmrg if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { 39144642e01fSmrg client->errorValue = _XkbErrCode2(0x04,stuff->firstType); 39154642e01fSmrg return BadAccess; 39164642e01fSmrg } 39174642e01fSmrg old= tmp; 39184642e01fSmrg tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); 39194642e01fSmrg if (!tmp) { 39204642e01fSmrg client->errorValue= bad; 39214642e01fSmrg return BadAtom; 39224642e01fSmrg } 39234642e01fSmrg for (i=0;i<stuff->nTypes;i++,old++) { 39244642e01fSmrg if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) 39254642e01fSmrg client->errorValue= _XkbErrCode2(0x05,i); 39264642e01fSmrg } 39274642e01fSmrg } 39284642e01fSmrg if (stuff->which&XkbKTLevelNamesMask) { 39294642e01fSmrg unsigned i; 39304642e01fSmrg XkbKeyTypePtr type; 39314642e01fSmrg CARD8 * width; 39324642e01fSmrg if ( stuff->nKTLevels<1 ) { 39334642e01fSmrg client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); 39344642e01fSmrg return BadValue; 39354642e01fSmrg } 39364642e01fSmrg if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= 39374642e01fSmrg xkb->map->num_types) { 39384642e01fSmrg client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, 39394642e01fSmrg stuff->nKTLevels,xkb->map->num_types); 39404642e01fSmrg return BadValue; 39414642e01fSmrg } 39424642e01fSmrg width = (CARD8 *)tmp; 39434642e01fSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 39444642e01fSmrg type = &xkb->map->types[stuff->firstKTLevel]; 39454642e01fSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 39464642e01fSmrg if (width[i]==0) 39474642e01fSmrg continue; 39484642e01fSmrg else if (width[i]!=type->num_levels) { 39494642e01fSmrg client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, 39504642e01fSmrg type->num_levels,width[i]); 39514642e01fSmrg return BadMatch; 39524642e01fSmrg } 39534642e01fSmrg tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); 39544642e01fSmrg if (!tmp) { 39554642e01fSmrg client->errorValue= bad; 39564642e01fSmrg return BadAtom; 39574642e01fSmrg } 39584642e01fSmrg } 39594642e01fSmrg } 39604642e01fSmrg if (stuff->which&XkbIndicatorNamesMask) { 39614642e01fSmrg if (stuff->indicators==0) { 39624642e01fSmrg client->errorValue= 0x08; 39634642e01fSmrg return BadMatch; 39644642e01fSmrg } 39654642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, 39664642e01fSmrg client->swapped,&bad); 39674642e01fSmrg if (!tmp) { 39684642e01fSmrg client->errorValue= bad; 39694642e01fSmrg return BadAtom; 39704642e01fSmrg } 39714642e01fSmrg } 39724642e01fSmrg if (stuff->which&XkbVirtualModNamesMask) { 39734642e01fSmrg if (stuff->virtualMods==0) { 39744642e01fSmrg client->errorValue= 0x09; 39754642e01fSmrg return BadMatch; 39764642e01fSmrg } 39774642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, 39784642e01fSmrg (CARD32)stuff->virtualMods, 39794642e01fSmrg client->swapped,&bad); 39804642e01fSmrg if (!tmp) { 39814642e01fSmrg client->errorValue = bad; 39824642e01fSmrg return BadAtom; 39834642e01fSmrg } 39844642e01fSmrg } 39854642e01fSmrg if (stuff->which&XkbGroupNamesMask) { 39864642e01fSmrg if (stuff->groupNames==0) { 39874642e01fSmrg client->errorValue= 0x0a; 39884642e01fSmrg return BadMatch; 39894642e01fSmrg } 39904642e01fSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, 39914642e01fSmrg (CARD32)stuff->groupNames, 39924642e01fSmrg client->swapped,&bad); 39934642e01fSmrg if (!tmp) { 39944642e01fSmrg client->errorValue = bad; 39954642e01fSmrg return BadAtom; 39964642e01fSmrg } 39974642e01fSmrg } 39984642e01fSmrg if (stuff->which&XkbKeyNamesMask) { 39994642e01fSmrg if (stuff->firstKey<(unsigned)xkb->min_key_code) { 40004642e01fSmrg client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, 40014642e01fSmrg stuff->firstKey); 40024642e01fSmrg return BadValue; 40034642e01fSmrg } 40044642e01fSmrg if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| 40054642e01fSmrg (stuff->nKeys<1)) { 40064642e01fSmrg client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, 40074642e01fSmrg stuff->firstKey,stuff->nKeys); 40084642e01fSmrg return BadValue; 40094642e01fSmrg } 40104642e01fSmrg tmp+= stuff->nKeys; 40114642e01fSmrg } 40124642e01fSmrg if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { 40134642e01fSmrg tmp+= stuff->nKeyAliases*2; 40144642e01fSmrg } 40154642e01fSmrg if (stuff->which&XkbRGNamesMask) { 40164642e01fSmrg if ( stuff->nRadioGroups<1 ) { 40174642e01fSmrg client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); 40184642e01fSmrg return BadValue; 40194642e01fSmrg } 40204642e01fSmrg tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); 40214642e01fSmrg if (!tmp) { 40224642e01fSmrg client->errorValue= bad; 40234642e01fSmrg return BadAtom; 40244642e01fSmrg } 40254642e01fSmrg } 40264642e01fSmrg if ((tmp-((CARD32 *)stuff))!=stuff->length) { 40274642e01fSmrg client->errorValue = stuff->length; 40284642e01fSmrg return BadLength; 40294642e01fSmrg } 40304642e01fSmrg 40314642e01fSmrg 40324642e01fSmrg 40334642e01fSmrg return Success; 40344642e01fSmrg} 40354642e01fSmrg 40364642e01fSmrgstatic int 40374642e01fSmrg_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) 40384642e01fSmrg{ 40394642e01fSmrg XkbDescRec *xkb; 40404642e01fSmrg XkbNamesRec *names; 40414642e01fSmrg CARD32 *tmp; 40424642e01fSmrg xkbNamesNotify nn; 40434642e01fSmrg 40444642e01fSmrg tmp = (CARD32 *)&stuff[1]; 40454642e01fSmrg xkb = dev->key->xkbInfo->desc; 40464642e01fSmrg names = xkb->names; 40474642e01fSmrg 40484642e01fSmrg if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, 40494642e01fSmrg stuff->nKeyAliases)!=Success) { 40504642e01fSmrg return BadAlloc; 40514642e01fSmrg } 40524642e01fSmrg 40536747b715Smrg memset(&nn, 0, sizeof(xkbNamesNotify)); 40544642e01fSmrg nn.changed= stuff->which; 40554642e01fSmrg tmp = (CARD32 *)&stuff[1]; 40564642e01fSmrg if (stuff->which&XkbKeycodesNameMask) 40574642e01fSmrg names->keycodes= *tmp++; 40584642e01fSmrg if (stuff->which&XkbGeometryNameMask) 40594642e01fSmrg names->geometry= *tmp++; 40604642e01fSmrg if (stuff->which&XkbSymbolsNameMask) 40614642e01fSmrg names->symbols= *tmp++; 40624642e01fSmrg if (stuff->which&XkbPhysSymbolsNameMask) 40634642e01fSmrg names->phys_symbols= *tmp++; 40644642e01fSmrg if (stuff->which&XkbTypesNameMask) 40654642e01fSmrg names->types= *tmp++; 40664642e01fSmrg if (stuff->which&XkbCompatNameMask) 40674642e01fSmrg names->compat= *tmp++; 40684642e01fSmrg if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { 40694642e01fSmrg register unsigned i; 40704642e01fSmrg register XkbKeyTypePtr type; 40714642e01fSmrg 40724642e01fSmrg type= &xkb->map->types[stuff->firstType]; 40734642e01fSmrg for (i=0;i<stuff->nTypes;i++,type++) { 40744642e01fSmrg type->name= *tmp++; 40754642e01fSmrg } 40764642e01fSmrg nn.firstType= stuff->firstType; 40774642e01fSmrg nn.nTypes= stuff->nTypes; 40784642e01fSmrg } 40794642e01fSmrg if (stuff->which&XkbKTLevelNamesMask) { 40804642e01fSmrg register XkbKeyTypePtr type; 40814642e01fSmrg register unsigned i; 40824642e01fSmrg CARD8 *width; 40834642e01fSmrg 40844642e01fSmrg width = (CARD8 *)tmp; 40854642e01fSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 40864642e01fSmrg type= &xkb->map->types[stuff->firstKTLevel]; 40874642e01fSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 40884642e01fSmrg if (width[i]>0) { 40894642e01fSmrg if (type->level_names) { 40904642e01fSmrg register unsigned n; 40914642e01fSmrg for (n=0;n<width[i];n++) { 40924642e01fSmrg type->level_names[n]= tmp[n]; 40934642e01fSmrg } 40944642e01fSmrg } 40954642e01fSmrg tmp+= width[i]; 40964642e01fSmrg } 40974642e01fSmrg } 40984642e01fSmrg nn.firstLevelName= 0; 40994642e01fSmrg nn.nLevelNames= stuff->nTypes; 41004642e01fSmrg } 41014642e01fSmrg if (stuff->which&XkbIndicatorNamesMask) { 41024642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, 41034642e01fSmrg stuff->indicators); 41044642e01fSmrg nn.changedIndicators= stuff->indicators; 41054642e01fSmrg } 41064642e01fSmrg if (stuff->which&XkbVirtualModNamesMask) { 41074642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, 41084642e01fSmrg stuff->virtualMods); 41094642e01fSmrg nn.changedVirtualMods= stuff->virtualMods; 41104642e01fSmrg } 41114642e01fSmrg if (stuff->which&XkbGroupNamesMask) { 41124642e01fSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, 41134642e01fSmrg stuff->groupNames); 41144642e01fSmrg nn.changedVirtualMods= stuff->groupNames; 41154642e01fSmrg } 41164642e01fSmrg if (stuff->which&XkbKeyNamesMask) { 41174642e01fSmrg memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, 41184642e01fSmrg stuff->nKeys*XkbKeyNameLength); 41194642e01fSmrg tmp+= stuff->nKeys; 41204642e01fSmrg nn.firstKey= stuff->firstKey; 41214642e01fSmrg nn.nKeys= stuff->nKeys; 41224642e01fSmrg } 41234642e01fSmrg if (stuff->which&XkbKeyAliasesMask) { 41244642e01fSmrg if (stuff->nKeyAliases>0) { 41254642e01fSmrg register int na= stuff->nKeyAliases; 41264642e01fSmrg if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) 41274642e01fSmrg return BadAlloc; 41284642e01fSmrg memcpy((char *)names->key_aliases,(char *)tmp, 41294642e01fSmrg stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); 41304642e01fSmrg tmp+= stuff->nKeyAliases*2; 41314642e01fSmrg } 41324642e01fSmrg else if (names->key_aliases!=NULL) { 41336747b715Smrg free(names->key_aliases); 41344642e01fSmrg names->key_aliases= NULL; 41354642e01fSmrg names->num_key_aliases= 0; 41364642e01fSmrg } 41374642e01fSmrg nn.nAliases= names->num_key_aliases; 41384642e01fSmrg } 41394642e01fSmrg if (stuff->which&XkbRGNamesMask) { 41404642e01fSmrg if (stuff->nRadioGroups>0) { 41414642e01fSmrg register unsigned i,nrg; 41424642e01fSmrg nrg= stuff->nRadioGroups; 41434642e01fSmrg if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) 41444642e01fSmrg return BadAlloc; 41454642e01fSmrg 41464642e01fSmrg for (i=0;i<stuff->nRadioGroups;i++) { 41474642e01fSmrg names->radio_groups[i]= tmp[i]; 41484642e01fSmrg } 41494642e01fSmrg tmp+= stuff->nRadioGroups; 41504642e01fSmrg } 41514642e01fSmrg else if (names->radio_groups) { 41526747b715Smrg free(names->radio_groups); 41534642e01fSmrg names->radio_groups= NULL; 41544642e01fSmrg names->num_rg= 0; 41554642e01fSmrg } 41564642e01fSmrg nn.nRadioGroups= names->num_rg; 41574642e01fSmrg } 41584642e01fSmrg if (nn.changed) { 41594642e01fSmrg Bool needExtEvent; 41604642e01fSmrg needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; 41614642e01fSmrg XkbSendNamesNotify(dev,&nn); 41624642e01fSmrg if (needExtEvent) { 41634642e01fSmrg XkbSrvLedInfoPtr sli; 41644642e01fSmrg xkbExtensionDeviceNotify edev; 41654642e01fSmrg register int i; 41664642e01fSmrg register unsigned bit; 41674642e01fSmrg 41684642e01fSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 41694642e01fSmrg XkbXI_IndicatorsMask); 41704642e01fSmrg sli->namesPresent= 0; 41714642e01fSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 41724642e01fSmrg if (names->indicators[i]!=None) 41734642e01fSmrg sli->namesPresent|= bit; 41744642e01fSmrg } 41756747b715Smrg memset(&edev, 0, sizeof(xkbExtensionDeviceNotify)); 41764642e01fSmrg edev.reason= XkbXI_IndicatorNamesMask; 41774642e01fSmrg edev.ledClass= KbdFeedbackClass; 41784642e01fSmrg edev.ledID= dev->kbdfeed->ctrl.id; 41794642e01fSmrg edev.ledsDefined= sli->namesPresent|sli->mapsPresent; 41804642e01fSmrg edev.ledState= sli->effectiveState; 41814642e01fSmrg edev.firstBtn= 0; 41824642e01fSmrg edev.nBtns= 0; 41834642e01fSmrg edev.supported= XkbXI_AllFeaturesMask; 41844642e01fSmrg edev.unsupported= 0; 41854642e01fSmrg XkbSendExtensionDeviceNotify(dev,client,&edev); 41864642e01fSmrg } 41874642e01fSmrg } 41884642e01fSmrg return Success; 41894642e01fSmrg} 41904642e01fSmrg 41914642e01fSmrgint 41924642e01fSmrgProcXkbSetNames(ClientPtr client) 41934642e01fSmrg{ 41944642e01fSmrg DeviceIntPtr dev; 41954642e01fSmrg CARD32 *tmp; 41964642e01fSmrg Atom bad; 41974642e01fSmrg int rc; 41984642e01fSmrg 419905b261ecSmrg REQUEST(xkbSetNamesReq); 420005b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 420105b261ecSmrg 420205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 420305b261ecSmrg return BadAccess; 420405b261ecSmrg 42054642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 420605b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 420705b261ecSmrg 42084642e01fSmrg /* check device-independent stuff */ 420905b261ecSmrg tmp = (CARD32 *)&stuff[1]; 421005b261ecSmrg 421105b261ecSmrg if (stuff->which&XkbKeycodesNameMask) { 421205b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 421305b261ecSmrg if (!tmp) { 421405b261ecSmrg client->errorValue = bad; 421505b261ecSmrg return BadAtom; 421605b261ecSmrg } 421705b261ecSmrg } 421805b261ecSmrg if (stuff->which&XkbGeometryNameMask) { 421905b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 422005b261ecSmrg if (!tmp) { 422105b261ecSmrg client->errorValue = bad; 422205b261ecSmrg return BadAtom; 422305b261ecSmrg } 422405b261ecSmrg } 422505b261ecSmrg if (stuff->which&XkbSymbolsNameMask) { 422605b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 422705b261ecSmrg if (!tmp) { 422805b261ecSmrg client->errorValue = bad; 422905b261ecSmrg return BadAtom; 423005b261ecSmrg } 423105b261ecSmrg } 423205b261ecSmrg if (stuff->which&XkbPhysSymbolsNameMask) { 423305b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 423405b261ecSmrg if (!tmp) { 423505b261ecSmrg client->errorValue= bad; 423605b261ecSmrg return BadAtom; 423705b261ecSmrg } 423805b261ecSmrg } 423905b261ecSmrg if (stuff->which&XkbTypesNameMask) { 424005b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 424105b261ecSmrg if (!tmp) { 424205b261ecSmrg client->errorValue = bad; 424305b261ecSmrg return BadAtom; 424405b261ecSmrg } 424505b261ecSmrg } 424605b261ecSmrg if (stuff->which&XkbCompatNameMask) { 424705b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 424805b261ecSmrg if (!tmp) { 424905b261ecSmrg client->errorValue = bad; 425005b261ecSmrg return BadAtom; 425105b261ecSmrg } 425205b261ecSmrg } 42534642e01fSmrg 42544642e01fSmrg /* start of device-dependent tests */ 42554642e01fSmrg rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 42564642e01fSmrg if (rc != Success) 42574642e01fSmrg return rc; 42584642e01fSmrg 42594642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 42604642e01fSmrg { 42614642e01fSmrg DeviceIntPtr other; 42624642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 42634642e01fSmrg { 42646747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 42654642e01fSmrg { 42664642e01fSmrg 42674642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 42684642e01fSmrg if (rc == Success) 42694642e01fSmrg { 42704642e01fSmrg rc = _XkbSetNamesCheck(client, other, stuff, tmp); 42714642e01fSmrg if (rc != Success) 42724642e01fSmrg return rc; 42734642e01fSmrg } 42744642e01fSmrg } 42754642e01fSmrg } 427605b261ecSmrg } 427705b261ecSmrg 427805b261ecSmrg /* everything is okay -- update names */ 427905b261ecSmrg 42804642e01fSmrg rc = _XkbSetNames(client, dev, stuff); 42814642e01fSmrg if (rc != Success) 42824642e01fSmrg return rc; 428305b261ecSmrg 42844642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 42854642e01fSmrg { 42864642e01fSmrg DeviceIntPtr other; 42874642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 42884642e01fSmrg { 42896747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 42904642e01fSmrg { 42914642e01fSmrg 42924642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 42934642e01fSmrg if (rc == Success) 42944642e01fSmrg _XkbSetNames(client, other, stuff); 42954642e01fSmrg } 42964642e01fSmrg } 429705b261ecSmrg } 42984642e01fSmrg 42994642e01fSmrg /* everything is okay -- update names */ 43004642e01fSmrg 43016747b715Smrg return Success; 430205b261ecSmrg} 430305b261ecSmrg 430405b261ecSmrg/***====================================================================***/ 430505b261ecSmrg 43064642e01fSmrg#include "xkbgeom.h" 430705b261ecSmrg 430805b261ecSmrg#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 430905b261ecSmrg 431005b261ecSmrgstatic char * 431105b261ecSmrgXkbWriteCountedString(char *wire,char *str,Bool swap) 431205b261ecSmrg{ 43139ace9065Smrg CARD16 len,*pLen, paddedLen; 431405b261ecSmrg 43156747b715Smrg if (!str) 43166747b715Smrg return wire; 43176747b715Smrg 43186747b715Smrg len= strlen(str); 431905b261ecSmrg pLen= (CARD16 *)wire; 432005b261ecSmrg *pLen= len; 432105b261ecSmrg if (swap) { 432205b261ecSmrg register int n; 432305b261ecSmrg swaps(pLen,n); 432405b261ecSmrg } 43259ace9065Smrg paddedLen= pad_to_int32(sizeof(len)+len)-sizeof(len); 43269ace9065Smrg strncpy(&wire[sizeof(len)],str,paddedLen); 43279ace9065Smrg wire+= sizeof(len)+paddedLen; 432805b261ecSmrg return wire; 432905b261ecSmrg} 433005b261ecSmrg 433105b261ecSmrgstatic int 433205b261ecSmrgXkbSizeGeomProperties(XkbGeometryPtr geom) 433305b261ecSmrg{ 433405b261ecSmrgregister int i,size; 433505b261ecSmrgXkbPropertyPtr prop; 433605b261ecSmrg 433705b261ecSmrg for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 433805b261ecSmrg size+= XkbSizeCountedString(prop->name); 433905b261ecSmrg size+= XkbSizeCountedString(prop->value); 434005b261ecSmrg } 434105b261ecSmrg return size; 434205b261ecSmrg} 434305b261ecSmrg 434405b261ecSmrgstatic char * 434505b261ecSmrgXkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap) 434605b261ecSmrg{ 434705b261ecSmrgregister int i; 434805b261ecSmrgregister XkbPropertyPtr prop; 434905b261ecSmrg 435005b261ecSmrg for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 435105b261ecSmrg wire= XkbWriteCountedString(wire,prop->name,swap); 435205b261ecSmrg wire= XkbWriteCountedString(wire,prop->value,swap); 435305b261ecSmrg } 435405b261ecSmrg return wire; 435505b261ecSmrg} 435605b261ecSmrg 435705b261ecSmrgstatic int 435805b261ecSmrgXkbSizeGeomKeyAliases(XkbGeometryPtr geom) 435905b261ecSmrg{ 436005b261ecSmrg return geom->num_key_aliases*(2*XkbKeyNameLength); 436105b261ecSmrg} 436205b261ecSmrg 436305b261ecSmrgstatic char * 436405b261ecSmrgXkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap) 436505b261ecSmrg{ 436605b261ecSmrgregister int sz; 436705b261ecSmrg 436805b261ecSmrg sz= geom->num_key_aliases*(XkbKeyNameLength*2); 436905b261ecSmrg if (sz>0) { 437005b261ecSmrg memcpy(wire,(char *)geom->key_aliases,sz); 437105b261ecSmrg wire+= sz; 437205b261ecSmrg } 437305b261ecSmrg return wire; 437405b261ecSmrg} 437505b261ecSmrg 437605b261ecSmrgstatic int 437705b261ecSmrgXkbSizeGeomColors(XkbGeometryPtr geom) 437805b261ecSmrg{ 437905b261ecSmrgregister int i,size; 438005b261ecSmrgregister XkbColorPtr color; 438105b261ecSmrg 438205b261ecSmrg for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { 438305b261ecSmrg size+= XkbSizeCountedString(color->spec); 438405b261ecSmrg } 438505b261ecSmrg return size; 438605b261ecSmrg} 438705b261ecSmrg 438805b261ecSmrgstatic char * 438905b261ecSmrgXkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap) 439005b261ecSmrg{ 439105b261ecSmrgregister int i; 439205b261ecSmrgregister XkbColorPtr color; 439305b261ecSmrg 439405b261ecSmrg for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 439505b261ecSmrg wire= XkbWriteCountedString(wire,color->spec,swap); 439605b261ecSmrg } 439705b261ecSmrg return wire; 439805b261ecSmrg} 439905b261ecSmrg 440005b261ecSmrgstatic int 440105b261ecSmrgXkbSizeGeomShapes(XkbGeometryPtr geom) 440205b261ecSmrg{ 440305b261ecSmrgregister int i,size; 440405b261ecSmrgregister XkbShapePtr shape; 440505b261ecSmrg 440605b261ecSmrg for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 440705b261ecSmrg register int n; 440805b261ecSmrg register XkbOutlinePtr ol; 440905b261ecSmrg size+= SIZEOF(xkbShapeWireDesc); 441005b261ecSmrg for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 441105b261ecSmrg size+= SIZEOF(xkbOutlineWireDesc); 441205b261ecSmrg size+= ol->num_points*SIZEOF(xkbPointWireDesc); 441305b261ecSmrg } 441405b261ecSmrg } 441505b261ecSmrg return size; 441605b261ecSmrg} 441705b261ecSmrg 441805b261ecSmrgstatic char * 441905b261ecSmrgXkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap) 442005b261ecSmrg{ 442105b261ecSmrgint i; 442205b261ecSmrgXkbShapePtr shape; 442305b261ecSmrgxkbShapeWireDesc * shapeWire; 442405b261ecSmrg 442505b261ecSmrg for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 442605b261ecSmrg register int o; 442705b261ecSmrg XkbOutlinePtr ol; 442805b261ecSmrg xkbOutlineWireDesc * olWire; 442905b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 443005b261ecSmrg shapeWire->name= shape->name; 443105b261ecSmrg shapeWire->nOutlines= shape->num_outlines; 443205b261ecSmrg if (shape->primary!=NULL) 443305b261ecSmrg shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); 443405b261ecSmrg else shapeWire->primaryNdx= XkbNoShape; 443505b261ecSmrg if (shape->approx!=NULL) 443605b261ecSmrg shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); 443705b261ecSmrg else shapeWire->approxNdx= XkbNoShape; 44389ace9065Smrg shapeWire->pad= 0; 443905b261ecSmrg if (swap) { 444005b261ecSmrg register int n; 444105b261ecSmrg swapl(&shapeWire->name,n); 444205b261ecSmrg } 444305b261ecSmrg wire= (char *)&shapeWire[1]; 444405b261ecSmrg for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 444505b261ecSmrg register int p; 444605b261ecSmrg XkbPointPtr pt; 444705b261ecSmrg xkbPointWireDesc * ptWire; 444805b261ecSmrg olWire= (xkbOutlineWireDesc *)wire; 444905b261ecSmrg olWire->nPoints= ol->num_points; 445005b261ecSmrg olWire->cornerRadius= ol->corner_radius; 44519ace9065Smrg olWire->pad= 0; 445205b261ecSmrg wire= (char *)&olWire[1]; 445305b261ecSmrg ptWire= (xkbPointWireDesc *)wire; 445405b261ecSmrg for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 445505b261ecSmrg ptWire[p].x= pt->x; 445605b261ecSmrg ptWire[p].y= pt->y; 445705b261ecSmrg if (swap) { 445805b261ecSmrg register int n; 445905b261ecSmrg swaps(&ptWire[p].x,n); 446005b261ecSmrg swaps(&ptWire[p].y,n); 446105b261ecSmrg } 446205b261ecSmrg } 446305b261ecSmrg wire= (char *)&ptWire[ol->num_points]; 446405b261ecSmrg } 446505b261ecSmrg } 446605b261ecSmrg return wire; 446705b261ecSmrg} 446805b261ecSmrg 446905b261ecSmrgstatic int 447005b261ecSmrgXkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) 447105b261ecSmrg{ 447205b261ecSmrgregister int i,size; 447305b261ecSmrg 447405b261ecSmrg for (i=size=0;i<num_doodads;i++,doodad++) { 447505b261ecSmrg size+= SIZEOF(xkbAnyDoodadWireDesc); 447605b261ecSmrg if (doodad->any.type==XkbTextDoodad) { 447705b261ecSmrg size+= XkbSizeCountedString(doodad->text.text); 447805b261ecSmrg size+= XkbSizeCountedString(doodad->text.font); 447905b261ecSmrg } 448005b261ecSmrg else if (doodad->any.type==XkbLogoDoodad) { 448105b261ecSmrg size+= XkbSizeCountedString(doodad->logo.logo_name); 448205b261ecSmrg } 448305b261ecSmrg } 448405b261ecSmrg return size; 448505b261ecSmrg} 448605b261ecSmrg 448705b261ecSmrgstatic char * 448805b261ecSmrgXkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap) 448905b261ecSmrg{ 449005b261ecSmrgregister int i; 449105b261ecSmrgxkbDoodadWireDesc * doodadWire; 449205b261ecSmrg 449305b261ecSmrg for (i=0;i<num_doodads;i++,doodad++) { 449405b261ecSmrg doodadWire= (xkbDoodadWireDesc *)wire; 449505b261ecSmrg wire= (char *)&doodadWire[1]; 44966747b715Smrg memset(doodadWire, 0, SIZEOF(xkbDoodadWireDesc)); 449705b261ecSmrg doodadWire->any.name= doodad->any.name; 449805b261ecSmrg doodadWire->any.type= doodad->any.type; 449905b261ecSmrg doodadWire->any.priority= doodad->any.priority; 450005b261ecSmrg doodadWire->any.top= doodad->any.top; 450105b261ecSmrg doodadWire->any.left= doodad->any.left; 450205b261ecSmrg if (swap) { 450305b261ecSmrg register int n; 450405b261ecSmrg swapl(&doodadWire->any.name,n); 450505b261ecSmrg swaps(&doodadWire->any.top,n); 450605b261ecSmrg swaps(&doodadWire->any.left,n); 450705b261ecSmrg } 450805b261ecSmrg switch (doodad->any.type) { 450905b261ecSmrg case XkbOutlineDoodad: 451005b261ecSmrg case XkbSolidDoodad: 451105b261ecSmrg doodadWire->shape.angle= doodad->shape.angle; 451205b261ecSmrg doodadWire->shape.colorNdx= doodad->shape.color_ndx; 451305b261ecSmrg doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; 451405b261ecSmrg if (swap) { 451505b261ecSmrg register int n; 451605b261ecSmrg swaps(&doodadWire->shape.angle,n); 451705b261ecSmrg } 451805b261ecSmrg break; 451905b261ecSmrg case XkbTextDoodad: 452005b261ecSmrg doodadWire->text.angle= doodad->text.angle; 452105b261ecSmrg doodadWire->text.width= doodad->text.width; 452205b261ecSmrg doodadWire->text.height= doodad->text.height; 452305b261ecSmrg doodadWire->text.colorNdx= doodad->text.color_ndx; 452405b261ecSmrg if (swap) { 452505b261ecSmrg register int n; 452605b261ecSmrg swaps(&doodadWire->text.angle,n); 452705b261ecSmrg swaps(&doodadWire->text.width,n); 452805b261ecSmrg swaps(&doodadWire->text.height,n); 452905b261ecSmrg } 453005b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.text,swap); 453105b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.font,swap); 453205b261ecSmrg break; 453305b261ecSmrg case XkbIndicatorDoodad: 453405b261ecSmrg doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; 453505b261ecSmrg doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; 453605b261ecSmrg doodadWire->indicator.offColorNdx= 453705b261ecSmrg doodad->indicator.off_color_ndx; 453805b261ecSmrg break; 453905b261ecSmrg case XkbLogoDoodad: 454005b261ecSmrg doodadWire->logo.angle= doodad->logo.angle; 454105b261ecSmrg doodadWire->logo.colorNdx= doodad->logo.color_ndx; 454205b261ecSmrg doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; 454305b261ecSmrg wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap); 454405b261ecSmrg break; 454505b261ecSmrg default: 45464642e01fSmrg ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 454705b261ecSmrg doodad->any.type); 45484642e01fSmrg ErrorF("[xkb] Ignored\n"); 454905b261ecSmrg break; 455005b261ecSmrg } 455105b261ecSmrg } 455205b261ecSmrg return wire; 455305b261ecSmrg} 455405b261ecSmrg 455505b261ecSmrgstatic char * 455605b261ecSmrgXkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap) 455705b261ecSmrg{ 455805b261ecSmrgregister int r; 455905b261ecSmrgXkbOverlayRowPtr row; 456005b261ecSmrgxkbOverlayWireDesc * olWire; 456105b261ecSmrg 456205b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 456305b261ecSmrg olWire->name= ol->name; 456405b261ecSmrg olWire->nRows= ol->num_rows; 45659ace9065Smrg olWire->pad1= 0; 45669ace9065Smrg olWire->pad2= 0; 456705b261ecSmrg if (swap) { 456805b261ecSmrg register int n; 456905b261ecSmrg swapl(&olWire->name,n); 457005b261ecSmrg } 457105b261ecSmrg wire= (char *)&olWire[1]; 457205b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 457305b261ecSmrg unsigned int k; 457405b261ecSmrg XkbOverlayKeyPtr key; 457505b261ecSmrg xkbOverlayRowWireDesc * rowWire; 457605b261ecSmrg rowWire= (xkbOverlayRowWireDesc *)wire; 457705b261ecSmrg rowWire->rowUnder= row->row_under; 457805b261ecSmrg rowWire->nKeys= row->num_keys; 45799ace9065Smrg rowWire->pad1= 0; 458005b261ecSmrg wire= (char *)&rowWire[1]; 458105b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 458205b261ecSmrg xkbOverlayKeyWireDesc * keyWire; 458305b261ecSmrg keyWire= (xkbOverlayKeyWireDesc *)wire; 458405b261ecSmrg memcpy(keyWire->over,key->over.name,XkbKeyNameLength); 458505b261ecSmrg memcpy(keyWire->under,key->under.name,XkbKeyNameLength); 458605b261ecSmrg wire= (char *)&keyWire[1]; 458705b261ecSmrg } 458805b261ecSmrg } 458905b261ecSmrg return wire; 459005b261ecSmrg} 459105b261ecSmrg 459205b261ecSmrgstatic int 459305b261ecSmrgXkbSizeGeomSections(XkbGeometryPtr geom) 459405b261ecSmrg{ 459505b261ecSmrgregister int i,size; 459605b261ecSmrgXkbSectionPtr section; 459705b261ecSmrg 459805b261ecSmrg for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { 459905b261ecSmrg size+= SIZEOF(xkbSectionWireDesc); 460005b261ecSmrg if (section->rows) { 460105b261ecSmrg int r; 460205b261ecSmrg XkbRowPtr row; 460305b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;row++,r++) { 460405b261ecSmrg size+= SIZEOF(xkbRowWireDesc); 460505b261ecSmrg size+= row->num_keys*SIZEOF(xkbKeyWireDesc); 460605b261ecSmrg } 460705b261ecSmrg } 460805b261ecSmrg if (section->doodads) 460905b261ecSmrg size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads); 461005b261ecSmrg if (section->overlays) { 461105b261ecSmrg int o; 461205b261ecSmrg XkbOverlayPtr ol; 461305b261ecSmrg for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { 461405b261ecSmrg int r; 461505b261ecSmrg XkbOverlayRowPtr row; 461605b261ecSmrg size+= SIZEOF(xkbOverlayWireDesc); 461705b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 461805b261ecSmrg size+= SIZEOF(xkbOverlayRowWireDesc); 461905b261ecSmrg size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); 462005b261ecSmrg } 462105b261ecSmrg } 462205b261ecSmrg } 462305b261ecSmrg } 462405b261ecSmrg return size; 462505b261ecSmrg} 462605b261ecSmrg 462705b261ecSmrgstatic char * 462805b261ecSmrgXkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap) 462905b261ecSmrg{ 463005b261ecSmrgregister int i; 463105b261ecSmrgXkbSectionPtr section; 463205b261ecSmrgxkbSectionWireDesc * sectionWire; 463305b261ecSmrg 463405b261ecSmrg for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 463505b261ecSmrg sectionWire= (xkbSectionWireDesc *)wire; 463605b261ecSmrg sectionWire->name= section->name; 463705b261ecSmrg sectionWire->top= section->top; 463805b261ecSmrg sectionWire->left= section->left; 463905b261ecSmrg sectionWire->width= section->width; 464005b261ecSmrg sectionWire->height= section->height; 464105b261ecSmrg sectionWire->angle= section->angle; 464205b261ecSmrg sectionWire->priority= section->priority; 464305b261ecSmrg sectionWire->nRows= section->num_rows; 464405b261ecSmrg sectionWire->nDoodads= section->num_doodads; 464505b261ecSmrg sectionWire->nOverlays= section->num_overlays; 464605b261ecSmrg sectionWire->pad= 0; 464705b261ecSmrg if (swap) { 464805b261ecSmrg register int n; 464905b261ecSmrg swapl(§ionWire->name,n); 465005b261ecSmrg swaps(§ionWire->top,n); 465105b261ecSmrg swaps(§ionWire->left,n); 465205b261ecSmrg swaps(§ionWire->width,n); 465305b261ecSmrg swaps(§ionWire->height,n); 465405b261ecSmrg swaps(§ionWire->angle,n); 465505b261ecSmrg } 465605b261ecSmrg wire= (char *)§ionWire[1]; 465705b261ecSmrg if (section->rows) { 465805b261ecSmrg int r; 465905b261ecSmrg XkbRowPtr row; 466005b261ecSmrg xkbRowWireDesc * rowWire; 466105b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 466205b261ecSmrg rowWire= (xkbRowWireDesc *)wire; 466305b261ecSmrg rowWire->top= row->top; 466405b261ecSmrg rowWire->left= row->left; 466505b261ecSmrg rowWire->nKeys= row->num_keys; 466605b261ecSmrg rowWire->vertical= row->vertical; 466705b261ecSmrg rowWire->pad= 0; 466805b261ecSmrg if (swap) { 466905b261ecSmrg register int n; 467005b261ecSmrg swaps(&rowWire->top,n); 467105b261ecSmrg swaps(&rowWire->left,n); 467205b261ecSmrg } 467305b261ecSmrg wire= (char *)&rowWire[1]; 467405b261ecSmrg if (row->keys) { 467505b261ecSmrg int k; 467605b261ecSmrg XkbKeyPtr key; 467705b261ecSmrg xkbKeyWireDesc * keyWire; 467805b261ecSmrg keyWire= (xkbKeyWireDesc *)wire; 467905b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 468005b261ecSmrg memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); 468105b261ecSmrg keyWire[k].gap= key->gap; 468205b261ecSmrg keyWire[k].shapeNdx= key->shape_ndx; 468305b261ecSmrg keyWire[k].colorNdx= key->color_ndx; 468405b261ecSmrg if (swap) { 468505b261ecSmrg register int n; 468605b261ecSmrg swaps(&keyWire[k].gap,n); 468705b261ecSmrg } 468805b261ecSmrg } 468905b261ecSmrg wire= (char *)&keyWire[row->num_keys]; 469005b261ecSmrg } 469105b261ecSmrg } 469205b261ecSmrg } 469305b261ecSmrg if (section->doodads) { 469405b261ecSmrg wire= XkbWriteGeomDoodads(wire, 469505b261ecSmrg section->num_doodads,section->doodads, 469605b261ecSmrg swap); 469705b261ecSmrg } 469805b261ecSmrg if (section->overlays) { 469905b261ecSmrg register int o; 470005b261ecSmrg for (o=0;o<section->num_overlays;o++) { 470105b261ecSmrg wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap); 470205b261ecSmrg } 470305b261ecSmrg } 470405b261ecSmrg } 470505b261ecSmrg return wire; 470605b261ecSmrg} 470705b261ecSmrg 470805b261ecSmrgstatic Status 470905b261ecSmrgXkbComputeGetGeometryReplySize( XkbGeometryPtr geom, 471005b261ecSmrg xkbGetGeometryReply * rep, 471105b261ecSmrg Atom name) 471205b261ecSmrg{ 471305b261ecSmrgint len; 471405b261ecSmrg 471505b261ecSmrg if (geom!=NULL) { 471605b261ecSmrg len= XkbSizeCountedString(geom->label_font); 471705b261ecSmrg len+= XkbSizeGeomProperties(geom); 471805b261ecSmrg len+= XkbSizeGeomColors(geom); 471905b261ecSmrg len+= XkbSizeGeomShapes(geom); 472005b261ecSmrg len+= XkbSizeGeomSections(geom); 472105b261ecSmrg len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads); 472205b261ecSmrg len+= XkbSizeGeomKeyAliases(geom); 472305b261ecSmrg rep->length= len/4; 47246747b715Smrg rep->found= TRUE; 472505b261ecSmrg rep->name= geom->name; 472605b261ecSmrg rep->widthMM= geom->width_mm; 472705b261ecSmrg rep->heightMM= geom->height_mm; 472805b261ecSmrg rep->nProperties= geom->num_properties; 472905b261ecSmrg rep->nColors= geom->num_colors; 473005b261ecSmrg rep->nShapes= geom->num_shapes; 473105b261ecSmrg rep->nSections= geom->num_sections; 473205b261ecSmrg rep->nDoodads= geom->num_doodads; 473305b261ecSmrg rep->nKeyAliases= geom->num_key_aliases; 473405b261ecSmrg rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color); 473505b261ecSmrg rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color); 473605b261ecSmrg } 473705b261ecSmrg else { 473805b261ecSmrg rep->length= 0; 47396747b715Smrg rep->found= FALSE; 474005b261ecSmrg rep->name= name; 474105b261ecSmrg rep->widthMM= rep->heightMM= 0; 474205b261ecSmrg rep->nProperties= rep->nColors= rep->nShapes= 0; 474305b261ecSmrg rep->nSections= rep->nDoodads= 0; 474405b261ecSmrg rep->nKeyAliases= 0; 474505b261ecSmrg rep->labelColorNdx= rep->baseColorNdx= 0; 474605b261ecSmrg } 474705b261ecSmrg return Success; 474805b261ecSmrg} 474905b261ecSmrg 475005b261ecSmrgstatic int 475105b261ecSmrgXkbSendGeometry( ClientPtr client, 475205b261ecSmrg XkbGeometryPtr geom, 475305b261ecSmrg xkbGetGeometryReply * rep, 475405b261ecSmrg Bool freeGeom) 475505b261ecSmrg{ 475605b261ecSmrg char *desc,*start; 475705b261ecSmrg int len; 475805b261ecSmrg 475905b261ecSmrg if (geom!=NULL) { 476005b261ecSmrg len= rep->length*4; 47616747b715Smrg start= desc= malloc(len); 476205b261ecSmrg if (!start) 476305b261ecSmrg return BadAlloc; 476405b261ecSmrg desc= XkbWriteCountedString(desc,geom->label_font,client->swapped); 476505b261ecSmrg if ( rep->nProperties>0 ) 476605b261ecSmrg desc = XkbWriteGeomProperties(desc,geom,client->swapped); 476705b261ecSmrg if ( rep->nColors>0 ) 476805b261ecSmrg desc = XkbWriteGeomColors(desc,geom,client->swapped); 476905b261ecSmrg if ( rep->nShapes>0 ) 477005b261ecSmrg desc = XkbWriteGeomShapes(desc,geom,client->swapped); 477105b261ecSmrg if ( rep->nSections>0 ) 477205b261ecSmrg desc = XkbWriteGeomSections(desc,geom,client->swapped); 477305b261ecSmrg if ( rep->nDoodads>0 ) 477405b261ecSmrg desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads, 477505b261ecSmrg client->swapped); 477605b261ecSmrg if ( rep->nKeyAliases>0 ) 477705b261ecSmrg desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped); 477805b261ecSmrg if ((desc-start)!=(len)) { 47794642e01fSmrg ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 478005b261ecSmrg len, (unsigned long)(desc-start)); 478105b261ecSmrg } 478205b261ecSmrg } 478305b261ecSmrg else { 478405b261ecSmrg len= 0; 478505b261ecSmrg start= NULL; 478605b261ecSmrg } 478705b261ecSmrg if (client->swapped) { 478805b261ecSmrg register int n; 478905b261ecSmrg swaps(&rep->sequenceNumber,n); 479005b261ecSmrg swapl(&rep->length,n); 479105b261ecSmrg swapl(&rep->name,n); 479205b261ecSmrg swaps(&rep->widthMM,n); 479305b261ecSmrg swaps(&rep->heightMM,n); 479405b261ecSmrg swaps(&rep->nProperties,n); 479505b261ecSmrg swaps(&rep->nColors,n); 479605b261ecSmrg swaps(&rep->nShapes,n); 479705b261ecSmrg swaps(&rep->nSections,n); 479805b261ecSmrg swaps(&rep->nDoodads,n); 479905b261ecSmrg swaps(&rep->nKeyAliases,n); 480005b261ecSmrg } 480105b261ecSmrg WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep); 480205b261ecSmrg if (len>0) 480305b261ecSmrg WriteToClient(client, len, start); 480405b261ecSmrg if (start!=NULL) 48056747b715Smrg free((char *)start); 480605b261ecSmrg if (freeGeom) 48076747b715Smrg XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); 48086747b715Smrg return Success; 480905b261ecSmrg} 481005b261ecSmrg 481105b261ecSmrgint 481205b261ecSmrgProcXkbGetGeometry(ClientPtr client) 481305b261ecSmrg{ 481405b261ecSmrg DeviceIntPtr dev; 481505b261ecSmrg xkbGetGeometryReply rep; 481605b261ecSmrg XkbGeometryPtr geom; 481705b261ecSmrg Bool shouldFree; 481805b261ecSmrg Status status; 481905b261ecSmrg 482005b261ecSmrg REQUEST(xkbGetGeometryReq); 482105b261ecSmrg REQUEST_SIZE_MATCH(xkbGetGeometryReq); 482205b261ecSmrg 482305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 482405b261ecSmrg return BadAccess; 482505b261ecSmrg 48264642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 482705b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 482805b261ecSmrg 482905b261ecSmrg geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree); 483005b261ecSmrg rep.type= X_Reply; 483105b261ecSmrg rep.deviceID= dev->id; 483205b261ecSmrg rep.sequenceNumber= client->sequence; 483305b261ecSmrg rep.length= 0; 483405b261ecSmrg status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name); 483505b261ecSmrg if (status!=Success) 483605b261ecSmrg return status; 483705b261ecSmrg else return XkbSendGeometry(client,geom,&rep,shouldFree); 483805b261ecSmrg} 483905b261ecSmrg 484005b261ecSmrg/***====================================================================***/ 484105b261ecSmrg 48421e26616aSmrgstatic Status 48431e26616aSmrg_GetCountedString(char **wire_inout, ClientPtr client, char **str) 484405b261ecSmrg{ 48451e26616aSmrg char *wire, *next; 48461e26616aSmrg CARD16 len; 484705b261ecSmrg 48481e26616aSmrg wire = *wire_inout; 48491e26616aSmrg len = *(CARD16 *) wire; 48501e26616aSmrg if (client->swapped) { 48511e26616aSmrg int n; 48521e26616aSmrg swaps(&len, n); 485305b261ecSmrg } 48541e26616aSmrg next = wire + XkbPaddedSize(len + 2); 48551e26616aSmrg /* Check we're still within the size of the request */ 48561e26616aSmrg if (client->req_len < 48571e26616aSmrg bytes_to_int32(next - (char *) client->requestBuffer)) 48581e26616aSmrg return BadValue; 48591e26616aSmrg *str = malloc(len + 1); 48601e26616aSmrg if (!*str) 48611e26616aSmrg return BadAlloc; 48621e26616aSmrg memcpy(*str, &wire[2], len); 48631e26616aSmrg *(*str + len) = '\0'; 48641e26616aSmrg *wire_inout = next; 48651e26616aSmrg return Success; 486605b261ecSmrg} 486705b261ecSmrg 486805b261ecSmrgstatic Status 486905b261ecSmrg_CheckSetDoodad( char ** wire_inout, 487005b261ecSmrg XkbGeometryPtr geom, 487105b261ecSmrg XkbSectionPtr section, 487205b261ecSmrg ClientPtr client) 487305b261ecSmrg{ 487405b261ecSmrgchar * wire; 487505b261ecSmrgxkbDoodadWireDesc * dWire; 487605b261ecSmrgXkbDoodadPtr doodad; 48771e26616aSmrg Status status; 487805b261ecSmrg 487905b261ecSmrg dWire= (xkbDoodadWireDesc *)(*wire_inout); 488005b261ecSmrg wire= (char *)&dWire[1]; 488105b261ecSmrg if (client->swapped) { 488205b261ecSmrg register int n; 488305b261ecSmrg swapl(&dWire->any.name,n); 488405b261ecSmrg swaps(&dWire->any.top,n); 488505b261ecSmrg swaps(&dWire->any.left,n); 488605b261ecSmrg swaps(&dWire->any.angle,n); 488705b261ecSmrg } 488805b261ecSmrg CHK_ATOM_ONLY(dWire->any.name); 488905b261ecSmrg doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); 489005b261ecSmrg if (!doodad) 489105b261ecSmrg return BadAlloc; 489205b261ecSmrg doodad->any.type= dWire->any.type; 489305b261ecSmrg doodad->any.priority= dWire->any.priority; 489405b261ecSmrg doodad->any.top= dWire->any.top; 489505b261ecSmrg doodad->any.left= dWire->any.left; 489605b261ecSmrg doodad->any.angle= dWire->any.angle; 489705b261ecSmrg switch (doodad->any.type) { 489805b261ecSmrg case XkbOutlineDoodad: 489905b261ecSmrg case XkbSolidDoodad: 490005b261ecSmrg if (dWire->shape.colorNdx>=geom->num_colors) { 490105b261ecSmrg client->errorValue= _XkbErrCode3(0x40,geom->num_colors, 490205b261ecSmrg dWire->shape.colorNdx); 490305b261ecSmrg return BadMatch; 490405b261ecSmrg } 490505b261ecSmrg if (dWire->shape.shapeNdx>=geom->num_shapes) { 490605b261ecSmrg client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, 490705b261ecSmrg dWire->shape.shapeNdx); 490805b261ecSmrg return BadMatch; 490905b261ecSmrg } 491005b261ecSmrg doodad->shape.color_ndx= dWire->shape.colorNdx; 491105b261ecSmrg doodad->shape.shape_ndx= dWire->shape.shapeNdx; 491205b261ecSmrg break; 491305b261ecSmrg case XkbTextDoodad: 491405b261ecSmrg if (dWire->text.colorNdx>=geom->num_colors) { 491505b261ecSmrg client->errorValue= _XkbErrCode3(0x42,geom->num_colors, 491605b261ecSmrg dWire->text.colorNdx); 491705b261ecSmrg return BadMatch; 491805b261ecSmrg } 491905b261ecSmrg if (client->swapped) { 492005b261ecSmrg register int n; 492105b261ecSmrg swaps(&dWire->text.width,n); 492205b261ecSmrg swaps(&dWire->text.height,n); 492305b261ecSmrg } 492405b261ecSmrg doodad->text.width= dWire->text.width; 492505b261ecSmrg doodad->text.height= dWire->text.height; 492605b261ecSmrg doodad->text.color_ndx= dWire->text.colorNdx; 49271e26616aSmrg status = _GetCountedString(&wire, client, &doodad->text.text); 49281e26616aSmrg if (status != Success) 49291e26616aSmrg return status; 49301e26616aSmrg status = _GetCountedString(&wire, client, &doodad->text.font); 49311e26616aSmrg if (status != Success) { 49321e26616aSmrg free (doodad->text.text); 49331e26616aSmrg return status; 49341e26616aSmrg } 493505b261ecSmrg break; 493605b261ecSmrg case XkbIndicatorDoodad: 493705b261ecSmrg if (dWire->indicator.onColorNdx>=geom->num_colors) { 493805b261ecSmrg client->errorValue= _XkbErrCode3(0x43,geom->num_colors, 493905b261ecSmrg dWire->indicator.onColorNdx); 494005b261ecSmrg return BadMatch; 494105b261ecSmrg } 494205b261ecSmrg if (dWire->indicator.offColorNdx>=geom->num_colors) { 494305b261ecSmrg client->errorValue= _XkbErrCode3(0x44,geom->num_colors, 494405b261ecSmrg dWire->indicator.offColorNdx); 494505b261ecSmrg return BadMatch; 494605b261ecSmrg } 494705b261ecSmrg if (dWire->indicator.shapeNdx>=geom->num_shapes) { 494805b261ecSmrg client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, 494905b261ecSmrg dWire->indicator.shapeNdx); 495005b261ecSmrg return BadMatch; 495105b261ecSmrg } 495205b261ecSmrg doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; 495305b261ecSmrg doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; 495405b261ecSmrg doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; 495505b261ecSmrg break; 495605b261ecSmrg case XkbLogoDoodad: 495705b261ecSmrg if (dWire->logo.colorNdx>=geom->num_colors) { 495805b261ecSmrg client->errorValue= _XkbErrCode3(0x46,geom->num_colors, 495905b261ecSmrg dWire->logo.colorNdx); 496005b261ecSmrg return BadMatch; 496105b261ecSmrg } 496205b261ecSmrg if (dWire->logo.shapeNdx>=geom->num_shapes) { 496305b261ecSmrg client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, 496405b261ecSmrg dWire->logo.shapeNdx); 496505b261ecSmrg return BadMatch; 496605b261ecSmrg } 496705b261ecSmrg doodad->logo.color_ndx= dWire->logo.colorNdx; 496805b261ecSmrg doodad->logo.shape_ndx= dWire->logo.shapeNdx; 49691e26616aSmrg status = _GetCountedString(&wire, client, &doodad->logo.logo_name); 49701e26616aSmrg if (status != Success) 49711e26616aSmrg return status; 497205b261ecSmrg break; 497305b261ecSmrg default: 497405b261ecSmrg client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); 497505b261ecSmrg return BadValue; 497605b261ecSmrg } 497705b261ecSmrg *wire_inout= wire; 497805b261ecSmrg return Success; 497905b261ecSmrg} 498005b261ecSmrg 498105b261ecSmrgstatic Status 498205b261ecSmrg_CheckSetOverlay( char ** wire_inout, 498305b261ecSmrg XkbGeometryPtr geom, 498405b261ecSmrg XkbSectionPtr section, 498505b261ecSmrg ClientPtr client) 498605b261ecSmrg{ 498705b261ecSmrgregister int r; 498805b261ecSmrgchar * wire; 498905b261ecSmrgXkbOverlayPtr ol; 499005b261ecSmrgxkbOverlayWireDesc * olWire; 499105b261ecSmrgxkbOverlayRowWireDesc * rWire; 499205b261ecSmrg 499305b261ecSmrg wire= *wire_inout; 499405b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 499505b261ecSmrg if (client->swapped) { 499605b261ecSmrg register int n; 499705b261ecSmrg swapl(&olWire->name,n); 499805b261ecSmrg } 499905b261ecSmrg CHK_ATOM_ONLY(olWire->name); 500005b261ecSmrg ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); 500105b261ecSmrg rWire= (xkbOverlayRowWireDesc *)&olWire[1]; 500205b261ecSmrg for (r=0;r<olWire->nRows;r++) { 500305b261ecSmrg register int k; 500405b261ecSmrg xkbOverlayKeyWireDesc * kWire; 500505b261ecSmrg XkbOverlayRowPtr row; 500605b261ecSmrg 500705b261ecSmrg if (rWire->rowUnder>section->num_rows) { 500805b261ecSmrg client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, 500905b261ecSmrg rWire->rowUnder); 501005b261ecSmrg return BadMatch; 501105b261ecSmrg } 501205b261ecSmrg row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); 501305b261ecSmrg kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; 501405b261ecSmrg for (k=0;k<rWire->nKeys;k++,kWire++) { 501505b261ecSmrg if (XkbAddGeomOverlayKey(ol,row, 501605b261ecSmrg (char *)kWire->over,(char *)kWire->under)==NULL) { 501705b261ecSmrg client->errorValue= _XkbErrCode3(0x21,r,k); 501805b261ecSmrg return BadMatch; 501905b261ecSmrg } 502005b261ecSmrg } 502105b261ecSmrg rWire= (xkbOverlayRowWireDesc *)kWire; 502205b261ecSmrg } 502305b261ecSmrg olWire= (xkbOverlayWireDesc *)rWire; 502405b261ecSmrg wire= (char *)olWire; 502505b261ecSmrg *wire_inout= wire; 502605b261ecSmrg return Success; 502705b261ecSmrg} 502805b261ecSmrg 502905b261ecSmrgstatic Status 503005b261ecSmrg_CheckSetSections( XkbGeometryPtr geom, 503105b261ecSmrg xkbSetGeometryReq * req, 503205b261ecSmrg char ** wire_inout, 503305b261ecSmrg ClientPtr client) 503405b261ecSmrg{ 503505b261ecSmrgStatus status; 503605b261ecSmrgregister int s; 503705b261ecSmrgchar * wire; 503805b261ecSmrgxkbSectionWireDesc * sWire; 503905b261ecSmrgXkbSectionPtr section; 504005b261ecSmrg 504105b261ecSmrg wire= *wire_inout; 504205b261ecSmrg if (req->nSections<1) 504305b261ecSmrg return Success; 504405b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 504505b261ecSmrg for (s=0;s<req->nSections;s++) { 504605b261ecSmrg register int r; 504705b261ecSmrg xkbRowWireDesc * rWire; 504805b261ecSmrg if (client->swapped) { 504905b261ecSmrg register int n; 505005b261ecSmrg swapl(&sWire->name,n); 505105b261ecSmrg swaps(&sWire->top,n); 505205b261ecSmrg swaps(&sWire->left,n); 505305b261ecSmrg swaps(&sWire->width,n); 505405b261ecSmrg swaps(&sWire->height,n); 505505b261ecSmrg swaps(&sWire->angle,n); 505605b261ecSmrg } 505705b261ecSmrg CHK_ATOM_ONLY(sWire->name); 505805b261ecSmrg section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, 505905b261ecSmrg sWire->nDoodads,sWire->nOverlays); 506005b261ecSmrg if (!section) 506105b261ecSmrg return BadAlloc; 506205b261ecSmrg section->priority= sWire->priority; 506305b261ecSmrg section->top= sWire->top; 506405b261ecSmrg section->left= sWire->left; 506505b261ecSmrg section->width= sWire->width; 506605b261ecSmrg section->height= sWire->height; 506705b261ecSmrg section->angle= sWire->angle; 506805b261ecSmrg rWire= (xkbRowWireDesc *)&sWire[1]; 506905b261ecSmrg for (r=0;r<sWire->nRows;r++) { 507005b261ecSmrg register int k; 507105b261ecSmrg XkbRowPtr row; 507205b261ecSmrg xkbKeyWireDesc * kWire; 507305b261ecSmrg if (client->swapped) { 507405b261ecSmrg register int n; 507505b261ecSmrg swaps(&rWire->top,n); 507605b261ecSmrg swaps(&rWire->left,n); 507705b261ecSmrg } 507805b261ecSmrg row= XkbAddGeomRow(section,rWire->nKeys); 507905b261ecSmrg if (!row) 508005b261ecSmrg return BadAlloc; 508105b261ecSmrg row->top= rWire->top; 508205b261ecSmrg row->left= rWire->left; 508305b261ecSmrg row->vertical= rWire->vertical; 508405b261ecSmrg kWire= (xkbKeyWireDesc *)&rWire[1]; 508505b261ecSmrg for (k=0;k<rWire->nKeys;k++) { 508605b261ecSmrg XkbKeyPtr key; 508705b261ecSmrg key= XkbAddGeomKey(row); 508805b261ecSmrg if (!key) 508905b261ecSmrg return BadAlloc; 509005b261ecSmrg memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); 509105b261ecSmrg key->gap= kWire[k].gap; 509205b261ecSmrg key->shape_ndx= kWire[k].shapeNdx; 509305b261ecSmrg key->color_ndx= kWire[k].colorNdx; 509405b261ecSmrg if (key->shape_ndx>=geom->num_shapes) { 509505b261ecSmrg client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, 509605b261ecSmrg geom->num_shapes); 509705b261ecSmrg return BadMatch; 509805b261ecSmrg } 509905b261ecSmrg if (key->color_ndx>=geom->num_colors) { 510005b261ecSmrg client->errorValue= _XkbErrCode3(0x11,key->color_ndx, 510105b261ecSmrg geom->num_colors); 510205b261ecSmrg return BadMatch; 510305b261ecSmrg } 510405b261ecSmrg } 510505b261ecSmrg rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; 510605b261ecSmrg } 510705b261ecSmrg wire= (char *)rWire; 510805b261ecSmrg if (sWire->nDoodads>0) { 510905b261ecSmrg register int d; 511005b261ecSmrg for (d=0;d<sWire->nDoodads;d++) { 511105b261ecSmrg status=_CheckSetDoodad(&wire,geom,section,client); 511205b261ecSmrg if (status!=Success) 511305b261ecSmrg return status; 511405b261ecSmrg } 511505b261ecSmrg } 511605b261ecSmrg if (sWire->nOverlays>0) { 511705b261ecSmrg register int o; 511805b261ecSmrg for (o=0;o<sWire->nOverlays;o++) { 511905b261ecSmrg status= _CheckSetOverlay(&wire,geom,section,client); 512005b261ecSmrg if (status!=Success) 512105b261ecSmrg return status; 512205b261ecSmrg } 512305b261ecSmrg } 512405b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 512505b261ecSmrg } 512605b261ecSmrg wire= (char *)sWire; 512705b261ecSmrg *wire_inout= wire; 512805b261ecSmrg return Success; 512905b261ecSmrg} 513005b261ecSmrg 513105b261ecSmrgstatic Status 513205b261ecSmrg_CheckSetShapes( XkbGeometryPtr geom, 513305b261ecSmrg xkbSetGeometryReq * req, 513405b261ecSmrg char ** wire_inout, 513505b261ecSmrg ClientPtr client) 513605b261ecSmrg{ 513705b261ecSmrgregister int i; 513805b261ecSmrgchar * wire; 513905b261ecSmrg 514005b261ecSmrg wire= *wire_inout; 514105b261ecSmrg if (req->nShapes<1) { 514205b261ecSmrg client->errorValue= _XkbErrCode2(0x06,req->nShapes); 514305b261ecSmrg return BadValue; 514405b261ecSmrg } 514505b261ecSmrg else { 514605b261ecSmrg xkbShapeWireDesc * shapeWire; 514705b261ecSmrg XkbShapePtr shape; 514805b261ecSmrg register int o; 514905b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 515005b261ecSmrg for (i=0;i<req->nShapes;i++) { 515105b261ecSmrg xkbOutlineWireDesc * olWire; 515205b261ecSmrg XkbOutlinePtr ol; 515305b261ecSmrg shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); 515405b261ecSmrg if (!shape) 515505b261ecSmrg return BadAlloc; 515605b261ecSmrg olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); 515705b261ecSmrg for (o=0;o<shapeWire->nOutlines;o++) { 515805b261ecSmrg register int p; 515905b261ecSmrg XkbPointPtr pt; 516005b261ecSmrg xkbPointWireDesc * ptWire; 516105b261ecSmrg 516205b261ecSmrg ol= XkbAddGeomOutline(shape,olWire->nPoints); 516305b261ecSmrg if (!ol) 516405b261ecSmrg return BadAlloc; 516505b261ecSmrg ol->corner_radius= olWire->cornerRadius; 516605b261ecSmrg ptWire= (xkbPointWireDesc *)&olWire[1]; 516705b261ecSmrg for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { 516805b261ecSmrg pt->x= ptWire[p].x; 516905b261ecSmrg pt->y= ptWire[p].y; 517005b261ecSmrg if (client->swapped) { 517105b261ecSmrg register int n; 517205b261ecSmrg swaps(&pt->x,n); 517305b261ecSmrg swaps(&pt->y,n); 517405b261ecSmrg } 517505b261ecSmrg } 517605b261ecSmrg ol->num_points= olWire->nPoints; 517705b261ecSmrg olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); 517805b261ecSmrg } 517905b261ecSmrg if (shapeWire->primaryNdx!=XkbNoShape) 518005b261ecSmrg shape->primary= &shape->outlines[shapeWire->primaryNdx]; 518105b261ecSmrg if (shapeWire->approxNdx!=XkbNoShape) 518205b261ecSmrg shape->approx= &shape->outlines[shapeWire->approxNdx]; 518305b261ecSmrg shapeWire= (xkbShapeWireDesc *)olWire; 518405b261ecSmrg } 518505b261ecSmrg wire= (char *)shapeWire; 518605b261ecSmrg } 518705b261ecSmrg if (geom->num_shapes!=req->nShapes) { 518805b261ecSmrg client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); 518905b261ecSmrg return BadMatch; 519005b261ecSmrg } 519105b261ecSmrg 519205b261ecSmrg *wire_inout= wire; 519305b261ecSmrg return Success; 519405b261ecSmrg} 519505b261ecSmrg 519605b261ecSmrgstatic Status 519705b261ecSmrg_CheckSetGeom( XkbGeometryPtr geom, 519805b261ecSmrg xkbSetGeometryReq * req, 519905b261ecSmrg ClientPtr client) 520005b261ecSmrg{ 520105b261ecSmrgregister int i; 520205b261ecSmrgStatus status; 520305b261ecSmrgchar * wire; 520405b261ecSmrg 520505b261ecSmrg wire= (char *)&req[1]; 52061e26616aSmrg status = _GetCountedString(&wire, client, &geom->label_font); 52071e26616aSmrg if (status != Success) 52081e26616aSmrg return status; 52091e26616aSmrg 52101e26616aSmrg for (i = 0; i < req->nProperties; i++) { 52111e26616aSmrg char *name, *val; 52121e26616aSmrg 52131e26616aSmrg status = _GetCountedString(&wire, client, &name); 52141e26616aSmrg if (status != Success) 52151e26616aSmrg return status; 52161e26616aSmrg status = _GetCountedString(&wire, client, &val); 52171e26616aSmrg if (status != Success) { 52186747b715Smrg free(name); 52191e26616aSmrg return status; 522005b261ecSmrg } 522105b261ecSmrg if (XkbAddGeomProperty(geom,name,val)==NULL) { 52226747b715Smrg free(name); 52236747b715Smrg free(val); 522405b261ecSmrg return BadAlloc; 522505b261ecSmrg } 52266747b715Smrg free(name); 52276747b715Smrg free(val); 522805b261ecSmrg } 522905b261ecSmrg 523005b261ecSmrg if (req->nColors<2) { 523105b261ecSmrg client->errorValue= _XkbErrCode3(0x01,2,req->nColors); 523205b261ecSmrg return BadValue; 523305b261ecSmrg } 523405b261ecSmrg if (req->baseColorNdx>req->nColors) { 523505b261ecSmrg client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); 523605b261ecSmrg return BadMatch; 523705b261ecSmrg } 523805b261ecSmrg if (req->labelColorNdx>req->nColors) { 523905b261ecSmrg client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); 524005b261ecSmrg return BadMatch; 524105b261ecSmrg } 524205b261ecSmrg if (req->labelColorNdx==req->baseColorNdx) { 524305b261ecSmrg client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, 524405b261ecSmrg req->labelColorNdx); 524505b261ecSmrg return BadMatch; 524605b261ecSmrg } 524705b261ecSmrg 52481e26616aSmrg for (i = 0; i < req->nColors; i++) { 524905b261ecSmrg char *name; 52501e26616aSmrg status = _GetCountedString(&wire, client, &name); 52511e26616aSmrg if (status != Success) 52521e26616aSmrg return status; 525305b261ecSmrg if (!XkbAddGeomColor(geom,name,geom->num_colors)) { 52546747b715Smrg free(name); 525505b261ecSmrg return BadAlloc; 525605b261ecSmrg } 52576747b715Smrg free(name); 525805b261ecSmrg } 525905b261ecSmrg if (req->nColors!=geom->num_colors) { 526005b261ecSmrg client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); 526105b261ecSmrg return BadMatch; 526205b261ecSmrg } 526305b261ecSmrg geom->label_color= &geom->colors[req->labelColorNdx]; 526405b261ecSmrg geom->base_color= &geom->colors[req->baseColorNdx]; 526505b261ecSmrg 526605b261ecSmrg if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) 526705b261ecSmrg return status; 526805b261ecSmrg 526905b261ecSmrg if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) 527005b261ecSmrg return status; 527105b261ecSmrg 527205b261ecSmrg for (i=0;i<req->nDoodads;i++) { 527305b261ecSmrg status=_CheckSetDoodad(&wire,geom,NULL,client); 527405b261ecSmrg if (status!=Success) 527505b261ecSmrg return status; 527605b261ecSmrg } 527705b261ecSmrg 527805b261ecSmrg for (i=0;i<req->nKeyAliases;i++) { 527905b261ecSmrg if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) 528005b261ecSmrg return BadAlloc; 528105b261ecSmrg wire+= 2*XkbKeyNameLength; 528205b261ecSmrg } 528305b261ecSmrg return Success; 528405b261ecSmrg} 528505b261ecSmrg 52864642e01fSmrgstatic int 52874642e01fSmrg_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) 528805b261ecSmrg{ 528905b261ecSmrg XkbDescPtr xkb; 529005b261ecSmrg Bool new_name; 529105b261ecSmrg xkbNewKeyboardNotify nkn; 52924642e01fSmrg XkbGeometryPtr geom,old; 52934642e01fSmrg XkbGeometrySizesRec sizes; 52944642e01fSmrg Status status; 529505b261ecSmrg 529605b261ecSmrg xkb= dev->key->xkbInfo->desc; 529705b261ecSmrg old= xkb->geom; 529805b261ecSmrg xkb->geom= NULL; 529905b261ecSmrg 53004642e01fSmrg sizes.which= XkbGeomAllMask; 530105b261ecSmrg sizes.num_properties= stuff->nProperties; 53024642e01fSmrg sizes.num_colors= stuff->nColors; 53034642e01fSmrg sizes.num_shapes= stuff->nShapes; 53044642e01fSmrg sizes.num_sections= stuff->nSections; 53054642e01fSmrg sizes.num_doodads= stuff->nDoodads; 530605b261ecSmrg sizes.num_key_aliases= stuff->nKeyAliases; 530705b261ecSmrg if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { 53084642e01fSmrg xkb->geom= old; 53094642e01fSmrg return status; 531005b261ecSmrg } 531105b261ecSmrg geom= xkb->geom; 531205b261ecSmrg geom->name= stuff->name; 531305b261ecSmrg geom->width_mm= stuff->widthMM; 531405b261ecSmrg geom->height_mm= stuff->heightMM; 531505b261ecSmrg if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { 53166747b715Smrg XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); 53174642e01fSmrg xkb->geom= old; 53184642e01fSmrg return status; 531905b261ecSmrg } 532005b261ecSmrg new_name= (xkb->names->geometry!=geom->name); 532105b261ecSmrg xkb->names->geometry= geom->name; 532205b261ecSmrg if (old) 53236747b715Smrg XkbFreeGeometry(old,XkbGeomAllMask,TRUE); 532405b261ecSmrg if (new_name) { 53254642e01fSmrg xkbNamesNotify nn; 53266747b715Smrg memset(&nn, 0, sizeof(xkbNamesNotify)); 53274642e01fSmrg nn.changed= XkbGeometryNameMask; 53284642e01fSmrg XkbSendNamesNotify(dev,&nn); 532905b261ecSmrg } 533005b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 533105b261ecSmrg nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; 533205b261ecSmrg nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; 533305b261ecSmrg nkn.requestMajor= XkbReqCode; 533405b261ecSmrg nkn.requestMinor= X_kbSetGeometry; 533505b261ecSmrg nkn.changed= XkbNKN_GeometryMask; 533605b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 533705b261ecSmrg return Success; 533805b261ecSmrg} 533905b261ecSmrg 53404642e01fSmrgint 53414642e01fSmrgProcXkbSetGeometry(ClientPtr client) 53424642e01fSmrg{ 53434642e01fSmrg DeviceIntPtr dev; 53444642e01fSmrg int rc; 53454642e01fSmrg 53464642e01fSmrg REQUEST(xkbSetGeometryReq); 53474642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 53484642e01fSmrg 53494642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 53504642e01fSmrg return BadAccess; 53514642e01fSmrg 53524642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 53534642e01fSmrg CHK_ATOM_OR_NONE(stuff->name); 53544642e01fSmrg 53554642e01fSmrg rc = _XkbSetGeometry(client, dev, stuff); 53564642e01fSmrg if (rc != Success) 53574642e01fSmrg return rc; 53584642e01fSmrg 53594642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd) 53604642e01fSmrg { 53614642e01fSmrg DeviceIntPtr other; 53624642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 53634642e01fSmrg { 53646747b715Smrg if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 53654642e01fSmrg { 53664642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 53674642e01fSmrg if (rc == Success) 53684642e01fSmrg _XkbSetGeometry(client, other, stuff); 53694642e01fSmrg } 53704642e01fSmrg } 53714642e01fSmrg } 53724642e01fSmrg 53734642e01fSmrg return Success; 53744642e01fSmrg} 53754642e01fSmrg 537605b261ecSmrg/***====================================================================***/ 537705b261ecSmrg 537805b261ecSmrgint 537905b261ecSmrgProcXkbPerClientFlags(ClientPtr client) 538005b261ecSmrg{ 538105b261ecSmrg DeviceIntPtr dev; 538205b261ecSmrg xkbPerClientFlagsReply rep; 538305b261ecSmrg XkbInterestPtr interest; 53844642e01fSmrg Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 538505b261ecSmrg 538605b261ecSmrg REQUEST(xkbPerClientFlagsReq); 538705b261ecSmrg REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 538805b261ecSmrg 538905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 539005b261ecSmrg return BadAccess; 539105b261ecSmrg 53924642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 539305b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); 539405b261ecSmrg CHK_MASK_MATCH(0x02,stuff->change,stuff->value); 539505b261ecSmrg 539605b261ecSmrg interest = XkbFindClientResource((DevicePtr)dev,client); 53976747b715Smrg memset(&rep, 0, sizeof(xkbPerClientFlagsReply)); 539805b261ecSmrg rep.type= X_Reply; 539905b261ecSmrg rep.length = 0; 540005b261ecSmrg rep.sequenceNumber = client->sequence; 540105b261ecSmrg if (stuff->change) { 540205b261ecSmrg client->xkbClientFlags&= ~stuff->change; 540305b261ecSmrg client->xkbClientFlags|= stuff->value; 540405b261ecSmrg } 540505b261ecSmrg if (stuff->change&XkbPCF_AutoResetControlsMask) { 540605b261ecSmrg Bool want; 540705b261ecSmrg want= stuff->value&XkbPCF_AutoResetControlsMask; 540805b261ecSmrg if (interest && !want) { 540905b261ecSmrg interest->autoCtrls= interest->autoCtrlValues= 0; 541005b261ecSmrg } 541105b261ecSmrg else if (want && (!interest)) { 541205b261ecSmrg XID id = FakeClientID(client->index); 54136747b715Smrg if (!AddResource(id,RT_XKBCLIENT,dev)) 54146747b715Smrg return BadAlloc; 541505b261ecSmrg interest= XkbAddClientResource((DevicePtr)dev,client,id); 541605b261ecSmrg if (!interest) 541705b261ecSmrg return BadAlloc; 541805b261ecSmrg } 541905b261ecSmrg if (interest && want ) { 542005b261ecSmrg register unsigned affect; 542105b261ecSmrg affect= stuff->ctrlsToChange; 542205b261ecSmrg 542305b261ecSmrg CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); 542405b261ecSmrg CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); 542505b261ecSmrg CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); 542605b261ecSmrg 542705b261ecSmrg interest->autoCtrls&= ~affect; 542805b261ecSmrg interest->autoCtrlValues&= ~affect; 542905b261ecSmrg interest->autoCtrls|= stuff->autoCtrls&affect; 543005b261ecSmrg interest->autoCtrlValues|= stuff->autoCtrlValues&affect; 543105b261ecSmrg } 543205b261ecSmrg } 543305b261ecSmrg rep.supported = XkbPCF_AllFlagsMask; 543405b261ecSmrg rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; 543505b261ecSmrg if (interest) { 543605b261ecSmrg rep.autoCtrls= interest->autoCtrls; 543705b261ecSmrg rep.autoCtrlValues= interest->autoCtrlValues; 543805b261ecSmrg } 543905b261ecSmrg else { 544005b261ecSmrg rep.autoCtrls= rep.autoCtrlValues= 0; 544105b261ecSmrg } 544205b261ecSmrg if ( client->swapped ) { 544305b261ecSmrg register int n; 544405b261ecSmrg swaps(&rep.sequenceNumber, n); 544505b261ecSmrg swapl(&rep.supported,n); 544605b261ecSmrg swapl(&rep.value,n); 544705b261ecSmrg swapl(&rep.autoCtrls,n); 544805b261ecSmrg swapl(&rep.autoCtrlValues,n); 544905b261ecSmrg } 545005b261ecSmrg WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); 54516747b715Smrg return Success; 545205b261ecSmrg} 545305b261ecSmrg 545405b261ecSmrg/***====================================================================***/ 545505b261ecSmrg 545605b261ecSmrg/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 545705b261ecSmrg/* and wildcards */ 545805b261ecSmrgstatic unsigned char componentSpecLegal[] = { 545905b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 546005b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 546105b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 546205b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 546305b261ecSmrg}; 546405b261ecSmrg 546505b261ecSmrg/* same as above but accepts percent, plus and bar too */ 546605b261ecSmrgstatic unsigned char componentExprLegal[] = { 546705b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 546805b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 546905b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 547005b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 547105b261ecSmrg}; 547205b261ecSmrg 547305b261ecSmrgstatic char * 547405b261ecSmrgGetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) 547505b261ecSmrg{ 547605b261ecSmrgint len; 547705b261ecSmrgregister int i; 547805b261ecSmrgunsigned char *wire,*str,*tmp,*legal; 547905b261ecSmrg 548005b261ecSmrg if (allowExpr) legal= &componentExprLegal[0]; 548105b261ecSmrg else legal= &componentSpecLegal[0]; 548205b261ecSmrg 548305b261ecSmrg wire= *pWire; 548405b261ecSmrg len= (*(unsigned char *)wire++); 548505b261ecSmrg if (len>0) { 54866747b715Smrg str= calloc(1, len+1); 548705b261ecSmrg if (str) { 548805b261ecSmrg tmp= str; 548905b261ecSmrg for (i=0;i<len;i++) { 549005b261ecSmrg if (legal[(*wire)/8]&(1<<((*wire)%8))) 549105b261ecSmrg *tmp++= *wire++; 549205b261ecSmrg else wire++; 549305b261ecSmrg } 549405b261ecSmrg if (tmp!=str) 549505b261ecSmrg *tmp++= '\0'; 549605b261ecSmrg else { 54976747b715Smrg free(str); 549805b261ecSmrg str= NULL; 549905b261ecSmrg } 550005b261ecSmrg } 550105b261ecSmrg else { 550205b261ecSmrg *errRtrn= BadAlloc; 550305b261ecSmrg } 550405b261ecSmrg } 550505b261ecSmrg else { 550605b261ecSmrg str= NULL; 550705b261ecSmrg } 550805b261ecSmrg *pWire= wire; 550905b261ecSmrg return (char *)str; 551005b261ecSmrg} 551105b261ecSmrg 551205b261ecSmrg/***====================================================================***/ 551305b261ecSmrg 551405b261ecSmrgint 551505b261ecSmrgProcXkbListComponents(ClientPtr client) 551605b261ecSmrg{ 551705b261ecSmrg DeviceIntPtr dev; 551805b261ecSmrg xkbListComponentsReply rep; 551905b261ecSmrg unsigned len; 552005b261ecSmrg int status; 552105b261ecSmrg unsigned char * str; 552205b261ecSmrg XkbSrvListInfoRec list; 552305b261ecSmrg 552405b261ecSmrg REQUEST(xkbListComponentsReq); 552505b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 552605b261ecSmrg 552705b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 552805b261ecSmrg return BadAccess; 552905b261ecSmrg 55304642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 553105b261ecSmrg 553205b261ecSmrg status= Success; 553305b261ecSmrg str= (unsigned char *)&stuff[1]; 55346747b715Smrg memset(&list, 0, sizeof(XkbSrvListInfoRec)); 553505b261ecSmrg list.maxRtrn= stuff->maxNames; 55366747b715Smrg list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status); 55376747b715Smrg list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status); 55386747b715Smrg list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status); 55396747b715Smrg list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status); 55406747b715Smrg list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status); 554105b261ecSmrg if (status!=Success) 554205b261ecSmrg return status; 554305b261ecSmrg len= str-((unsigned char *)stuff); 554405b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 554505b261ecSmrg return BadLength; 554605b261ecSmrg if ((status=XkbDDXList(dev,&list,client))!=Success) { 55476747b715Smrg free(list.pool); 55486747b715Smrg list.pool = NULL; 554905b261ecSmrg return status; 555005b261ecSmrg } 55516747b715Smrg memset(&rep, 0, sizeof(xkbListComponentsReply)); 555205b261ecSmrg rep.type= X_Reply; 555305b261ecSmrg rep.deviceID = dev->id; 555405b261ecSmrg rep.sequenceNumber = client->sequence; 555505b261ecSmrg rep.length = XkbPaddedSize(list.nPool)/4; 55566747b715Smrg rep.nKeymaps = 0; 555705b261ecSmrg rep.nKeycodes = list.nFound[_XkbListKeycodes]; 555805b261ecSmrg rep.nTypes = list.nFound[_XkbListTypes]; 555905b261ecSmrg rep.nCompatMaps = list.nFound[_XkbListCompat]; 556005b261ecSmrg rep.nSymbols = list.nFound[_XkbListSymbols]; 556105b261ecSmrg rep.nGeometries = list.nFound[_XkbListGeometry]; 556205b261ecSmrg rep.extra= 0; 556305b261ecSmrg if (list.nTotal>list.maxRtrn) 556405b261ecSmrg rep.extra = (list.nTotal-list.maxRtrn); 556505b261ecSmrg if (client->swapped) { 556605b261ecSmrg register int n; 556705b261ecSmrg swaps(&rep.sequenceNumber,n); 556805b261ecSmrg swapl(&rep.length,n); 556905b261ecSmrg swaps(&rep.nKeymaps,n); 557005b261ecSmrg swaps(&rep.nKeycodes,n); 557105b261ecSmrg swaps(&rep.nTypes,n); 557205b261ecSmrg swaps(&rep.nCompatMaps,n); 557305b261ecSmrg swaps(&rep.nSymbols,n); 557405b261ecSmrg swaps(&rep.nGeometries,n); 557505b261ecSmrg swaps(&rep.extra,n); 557605b261ecSmrg } 557705b261ecSmrg WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); 557805b261ecSmrg if (list.nPool && list.pool) { 557905b261ecSmrg WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); 55806747b715Smrg free(list.pool); 558105b261ecSmrg list.pool= NULL; 558205b261ecSmrg } 55836747b715Smrg return Success; 558405b261ecSmrg} 558505b261ecSmrg 558605b261ecSmrg/***====================================================================***/ 558705b261ecSmrg 558805b261ecSmrgint 558905b261ecSmrgProcXkbGetKbdByName(ClientPtr client) 559005b261ecSmrg{ 559105b261ecSmrg DeviceIntPtr dev; 559205b261ecSmrg DeviceIntPtr tmpd; 55939ace9065Smrg xkbGetKbdByNameReply rep = {0}; 55949ace9065Smrg xkbGetMapReply mrep = {0}; 55959ace9065Smrg xkbGetCompatMapReply crep = {0}; 55969ace9065Smrg xkbGetIndicatorMapReply irep = {0}; 55979ace9065Smrg xkbGetNamesReply nrep = {0}; 55989ace9065Smrg xkbGetGeometryReply grep = {0}; 55999ace9065Smrg XkbComponentNamesRec names = {0}; 56004642e01fSmrg XkbDescPtr xkb, new; 560105b261ecSmrg unsigned char * str; 560205b261ecSmrg char mapFile[PATH_MAX]; 560305b261ecSmrg unsigned len; 560405b261ecSmrg unsigned fwant,fneed,reported; 560505b261ecSmrg int status; 560605b261ecSmrg Bool geom_changed; 560705b261ecSmrg XkbSrvLedInfoPtr old_sli; 560805b261ecSmrg XkbSrvLedInfoPtr sli; 56094642e01fSmrg Mask access_mode = DixGetAttrAccess | DixManageAccess; 561005b261ecSmrg 561105b261ecSmrg REQUEST(xkbGetKbdByNameReq); 561205b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 561305b261ecSmrg 561405b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 561505b261ecSmrg return BadAccess; 561605b261ecSmrg 56174642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 561805b261ecSmrg 561905b261ecSmrg xkb = dev->key->xkbInfo->desc; 562005b261ecSmrg status= Success; 562105b261ecSmrg str= (unsigned char *)&stuff[1]; 56226747b715Smrg if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */ 56236747b715Smrg return BadMatch; 56246747b715Smrg names.keycodes= GetComponentSpec(&str,TRUE,&status); 56256747b715Smrg names.types= GetComponentSpec(&str,TRUE,&status); 56266747b715Smrg names.compat= GetComponentSpec(&str,TRUE,&status); 56276747b715Smrg names.symbols= GetComponentSpec(&str,TRUE,&status); 56286747b715Smrg names.geometry= GetComponentSpec(&str,TRUE,&status); 562905b261ecSmrg if (status!=Success) 563005b261ecSmrg return status; 563105b261ecSmrg len= str-((unsigned char *)stuff); 563205b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 563305b261ecSmrg return BadLength; 563405b261ecSmrg 563505b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); 563605b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); 563705b261ecSmrg 563805b261ecSmrg if (stuff->load) 563905b261ecSmrg fwant= XkbGBN_AllComponentsMask; 564005b261ecSmrg else fwant= stuff->want|stuff->need; 56414642e01fSmrg if ((!names.compat)&& 56424642e01fSmrg (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { 56434642e01fSmrg names.compat= _XkbDupString("%"); 564405b261ecSmrg } 56454642e01fSmrg if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { 56464642e01fSmrg names.types= _XkbDupString("%"); 56474642e01fSmrg } 56484642e01fSmrg if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { 56494642e01fSmrg names.symbols= _XkbDupString("%"); 56504642e01fSmrg } 56514642e01fSmrg geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); 56524642e01fSmrg if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { 56534642e01fSmrg names.geometry= _XkbDupString("%"); 56546747b715Smrg geom_changed= FALSE; 565505b261ecSmrg } 565605b261ecSmrg 56576747b715Smrg memset(mapFile, 0, PATH_MAX); 565805b261ecSmrg rep.type= X_Reply; 565905b261ecSmrg rep.deviceID = dev->id; 566005b261ecSmrg rep.sequenceNumber = client->sequence; 566105b261ecSmrg rep.length = 0; 566205b261ecSmrg rep.minKeyCode = xkb->min_key_code; 566305b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 56646747b715Smrg rep.loaded= FALSE; 56656747b715Smrg fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask; 56666747b715Smrg fneed= XkbConvertGetByNameComponents(TRUE,stuff->need); 56676747b715Smrg rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed); 566805b261ecSmrg if (stuff->load) { 566905b261ecSmrg fneed|= XkmKeymapRequired; 567005b261ecSmrg fwant|= XkmKeymapLegal; 567105b261ecSmrg } 567205b261ecSmrg if ((fwant|fneed)&XkmSymbolsMask) { 567305b261ecSmrg fneed|= XkmKeyNamesIndex|XkmTypesIndex; 567405b261ecSmrg fwant|= XkmIndicatorsIndex; 567505b261ecSmrg } 567605b261ecSmrg 567705b261ecSmrg /* We pass dev in here so we can get the old names out if needed. */ 56784642e01fSmrg rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new, 567905b261ecSmrg mapFile,PATH_MAX); 56806747b715Smrg rep.newKeyboard= FALSE; 568105b261ecSmrg rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; 568205b261ecSmrg 568305b261ecSmrg stuff->want|= stuff->need; 56844642e01fSmrg if (new==NULL) 568505b261ecSmrg rep.reported= 0; 568605b261ecSmrg else { 568705b261ecSmrg if (stuff->load) 56886747b715Smrg rep.loaded= TRUE; 568905b261ecSmrg if (stuff->load || 56904642e01fSmrg ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) { 569105b261ecSmrg XkbChangesRec changes; 56926747b715Smrg memset(&changes, 0, sizeof(changes)); 56934642e01fSmrg XkbUpdateDescActions(new, 56944642e01fSmrg new->min_key_code,XkbNumKeys(new), 569505b261ecSmrg &changes); 569605b261ecSmrg } 569705b261ecSmrg 56984642e01fSmrg if (new->map==NULL) 569905b261ecSmrg rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); 570005b261ecSmrg else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { 570105b261ecSmrg mrep.type= X_Reply; 570205b261ecSmrg mrep.deviceID = dev->id; 570305b261ecSmrg mrep.sequenceNumber= client->sequence; 570405b261ecSmrg mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); 57054642e01fSmrg mrep.minKeyCode = new->min_key_code; 57064642e01fSmrg mrep.maxKeyCode = new->max_key_code; 570705b261ecSmrg mrep.present = 0; 570805b261ecSmrg mrep.totalSyms = mrep.totalActs = 570905b261ecSmrg mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 571052397711Smrg mrep.totalModMapKeys= mrep.totalVModMapKeys= 0; 571105b261ecSmrg if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { 571205b261ecSmrg mrep.present|= XkbKeyTypesMask; 571305b261ecSmrg mrep.firstType = 0; 57144642e01fSmrg mrep.nTypes = mrep.totalTypes= new->map->num_types; 571505b261ecSmrg } 571605b261ecSmrg else { 571705b261ecSmrg mrep.firstType = mrep.nTypes= 0; 571805b261ecSmrg mrep.totalTypes= 0; 571905b261ecSmrg } 572005b261ecSmrg if (rep.reported&XkbGBN_ClientSymbolsMask) { 572105b261ecSmrg mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); 57224642e01fSmrg mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code; 57234642e01fSmrg mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new); 572405b261ecSmrg } 572505b261ecSmrg else { 572605b261ecSmrg mrep.firstKeySym= mrep.firstModMapKey= 0; 572705b261ecSmrg mrep.nKeySyms= mrep.nModMapKeys= 0; 572805b261ecSmrg } 572905b261ecSmrg if (rep.reported&XkbGBN_ServerSymbolsMask) { 573005b261ecSmrg mrep.present|= XkbAllServerInfoMask; 573105b261ecSmrg mrep.virtualMods= ~0; 573205b261ecSmrg mrep.firstKeyAct = mrep.firstKeyBehavior = 57334642e01fSmrg mrep.firstKeyExplicit = new->min_key_code; 573405b261ecSmrg mrep.nKeyActs = mrep.nKeyBehaviors = 57354642e01fSmrg mrep.nKeyExplicit = XkbNumKeys(new); 573652397711Smrg mrep.firstVModMapKey= new->min_key_code; 573752397711Smrg mrep.nVModMapKeys= XkbNumKeys(new); 573805b261ecSmrg } 573905b261ecSmrg else { 574005b261ecSmrg mrep.virtualMods= 0; 574105b261ecSmrg mrep.firstKeyAct= mrep.firstKeyBehavior= 574205b261ecSmrg mrep.firstKeyExplicit = 0; 574305b261ecSmrg mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; 574405b261ecSmrg } 57454642e01fSmrg XkbComputeGetMapReplySize(new,&mrep); 574605b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+mrep.length; 574705b261ecSmrg } 57484642e01fSmrg if (new->compat==NULL) 574905b261ecSmrg rep.reported&= ~XkbGBN_CompatMapMask; 575005b261ecSmrg else if (rep.reported&XkbGBN_CompatMapMask) { 575105b261ecSmrg crep.type= X_Reply; 575205b261ecSmrg crep.deviceID= dev->id; 575305b261ecSmrg crep.sequenceNumber= client->sequence; 575405b261ecSmrg crep.length= 0; 575505b261ecSmrg crep.groups= XkbAllGroupsMask; 575605b261ecSmrg crep.firstSI= 0; 57574642e01fSmrg crep.nSI= crep.nTotalSI= new->compat->num_si; 57584642e01fSmrg XkbComputeGetCompatMapReplySize(new->compat,&crep); 575905b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+crep.length; 576005b261ecSmrg } 57614642e01fSmrg if (new->indicators==NULL) 576205b261ecSmrg rep.reported&= ~XkbGBN_IndicatorMapMask; 576305b261ecSmrg else if (rep.reported&XkbGBN_IndicatorMapMask) { 576405b261ecSmrg irep.type= X_Reply; 576505b261ecSmrg irep.deviceID= dev->id; 576605b261ecSmrg irep.sequenceNumber= client->sequence; 576705b261ecSmrg irep.length= 0; 576805b261ecSmrg irep.which= XkbAllIndicatorsMask; 57694642e01fSmrg XkbComputeGetIndicatorMapReplySize(new->indicators,&irep); 577005b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+irep.length; 577105b261ecSmrg } 57724642e01fSmrg if (new->names==NULL) 577305b261ecSmrg rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); 577405b261ecSmrg else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { 577505b261ecSmrg nrep.type= X_Reply; 577605b261ecSmrg nrep.deviceID= dev->id; 577705b261ecSmrg nrep.sequenceNumber= client->sequence; 577805b261ecSmrg nrep.length= 0; 57794642e01fSmrg nrep.minKeyCode= new->min_key_code; 57804642e01fSmrg nrep.maxKeyCode= new->max_key_code; 578105b261ecSmrg if (rep.reported&XkbGBN_OtherNamesMask) { 578205b261ecSmrg nrep.which= XkbAllNamesMask; 57834642e01fSmrg if (new->map!=NULL) 57844642e01fSmrg nrep.nTypes= new->map->num_types; 578505b261ecSmrg else nrep.nTypes= 0; 578605b261ecSmrg nrep.nKTLevels= 0; 578705b261ecSmrg nrep.groupNames= XkbAllGroupsMask; 578805b261ecSmrg nrep.virtualMods= XkbAllVirtualModsMask; 578905b261ecSmrg nrep.indicators= XkbAllIndicatorsMask; 57904642e01fSmrg nrep.nRadioGroups= new->names->num_rg; 579105b261ecSmrg } 579205b261ecSmrg else { 579305b261ecSmrg nrep.which= 0; 579405b261ecSmrg nrep.nTypes= 0; 579505b261ecSmrg nrep.nKTLevels= 0; 579605b261ecSmrg nrep.groupNames= 0; 579705b261ecSmrg nrep.virtualMods= 0; 579805b261ecSmrg nrep.indicators= 0; 579905b261ecSmrg nrep.nRadioGroups= 0; 580005b261ecSmrg } 580105b261ecSmrg if (rep.reported&XkbGBN_KeyNamesMask) { 580205b261ecSmrg nrep.which|= XkbKeyNamesMask; 58034642e01fSmrg nrep.firstKey= new->min_key_code; 58044642e01fSmrg nrep.nKeys= XkbNumKeys(new); 58054642e01fSmrg nrep.nKeyAliases= new->names->num_key_aliases; 580605b261ecSmrg if (nrep.nKeyAliases) 580705b261ecSmrg nrep.which|= XkbKeyAliasesMask; 580805b261ecSmrg } 580905b261ecSmrg else { 581005b261ecSmrg nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); 581105b261ecSmrg nrep.firstKey= nrep.nKeys= 0; 581205b261ecSmrg nrep.nKeyAliases= 0; 581305b261ecSmrg } 58144642e01fSmrg XkbComputeGetNamesReplySize(new,&nrep); 581505b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+nrep.length; 581605b261ecSmrg } 58174642e01fSmrg if (new->geom==NULL) 581805b261ecSmrg rep.reported&= ~XkbGBN_GeometryMask; 581905b261ecSmrg else if (rep.reported&XkbGBN_GeometryMask) { 582005b261ecSmrg grep.type= X_Reply; 582105b261ecSmrg grep.deviceID= dev->id; 582205b261ecSmrg grep.sequenceNumber= client->sequence; 582305b261ecSmrg grep.length= 0; 58246747b715Smrg grep.found= TRUE; 582505b261ecSmrg grep.pad= 0; 582605b261ecSmrg grep.widthMM= grep.heightMM= 0; 582705b261ecSmrg grep.nProperties= grep.nColors= grep.nShapes= 0; 582805b261ecSmrg grep.nSections= grep.nDoodads= 0; 582905b261ecSmrg grep.baseColorNdx= grep.labelColorNdx= 0; 58304642e01fSmrg XkbComputeGetGeometryReplySize(new->geom,&grep,None); 583105b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+grep.length; 583205b261ecSmrg } 583305b261ecSmrg } 583405b261ecSmrg 583505b261ecSmrg reported= rep.reported; 583605b261ecSmrg if ( client->swapped ) { 583705b261ecSmrg register int n; 583805b261ecSmrg swaps(&rep.sequenceNumber,n); 583905b261ecSmrg swapl(&rep.length,n); 584005b261ecSmrg swaps(&rep.found,n); 584105b261ecSmrg swaps(&rep.reported,n); 584205b261ecSmrg } 584305b261ecSmrg WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); 584405b261ecSmrg if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) 58454642e01fSmrg XkbSendMap(client,new,&mrep); 584605b261ecSmrg if (reported&XkbGBN_CompatMapMask) 58474642e01fSmrg XkbSendCompatMap(client,new->compat,&crep); 584805b261ecSmrg if (reported&XkbGBN_IndicatorMapMask) 58494642e01fSmrg XkbSendIndicatorMap(client,new->indicators,&irep); 585005b261ecSmrg if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) 58514642e01fSmrg XkbSendNames(client,new,&nrep); 585205b261ecSmrg if (reported&XkbGBN_GeometryMask) 58536747b715Smrg XkbSendGeometry(client,new->geom,&grep,FALSE); 585405b261ecSmrg if (rep.loaded) { 585505b261ecSmrg XkbDescPtr old_xkb; 585605b261ecSmrg xkbNewKeyboardNotify nkn; 585705b261ecSmrg int i,nG,nTG; 585805b261ecSmrg old_xkb= xkb; 58594642e01fSmrg xkb= new; 586005b261ecSmrg dev->key->xkbInfo->desc= xkb; 58614642e01fSmrg new= old_xkb; /* so it'll get freed automatically */ 586205b261ecSmrg 586305b261ecSmrg *xkb->ctrls= *old_xkb->ctrls; 586405b261ecSmrg for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 586505b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 586605b261ecSmrg if (nG>=XkbNumKbdGroups) { 586705b261ecSmrg nTG= XkbNumKbdGroups; 586805b261ecSmrg break; 586905b261ecSmrg } 587005b261ecSmrg if (nG>nTG) { 587105b261ecSmrg nTG= nG; 587205b261ecSmrg } 587305b261ecSmrg } 587405b261ecSmrg xkb->ctrls->num_groups= nTG; 587505b261ecSmrg 587605b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 58776747b715Smrg if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 587805b261ecSmrg if (tmpd != dev) 58796747b715Smrg XkbCopyDeviceKeymap(tmpd, dev); 588005b261ecSmrg 588105b261ecSmrg if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 588205b261ecSmrg old_sli = tmpd->kbdfeed->xkb_sli; 588305b261ecSmrg tmpd->kbdfeed->xkb_sli = NULL; 588405b261ecSmrg sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 588505b261ecSmrg if (sli) { 588605b261ecSmrg sli->explicitState = old_sli->explicitState; 588705b261ecSmrg sli->effectiveState = old_sli->effectiveState; 588805b261ecSmrg } 588905b261ecSmrg tmpd->kbdfeed->xkb_sli = sli; 589005b261ecSmrg XkbFreeSrvLedInfo(old_sli); 589105b261ecSmrg } 589205b261ecSmrg } 589305b261ecSmrg } 589405b261ecSmrg 589505b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 58964642e01fSmrg nkn.minKeyCode= new->min_key_code; 58974642e01fSmrg nkn.maxKeyCode= new->max_key_code; 589805b261ecSmrg nkn.oldMinKeyCode= xkb->min_key_code; 589905b261ecSmrg nkn.oldMaxKeyCode= xkb->max_key_code; 590005b261ecSmrg nkn.requestMajor= XkbReqCode; 590105b261ecSmrg nkn.requestMinor= X_kbGetKbdByName; 590205b261ecSmrg nkn.changed= XkbNKN_KeycodesMask; 590305b261ecSmrg if (geom_changed) 590405b261ecSmrg nkn.changed|= XkbNKN_GeometryMask; 590505b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 59066747b715Smrg 59076747b715Smrg if (!IsMaster(dev) && dev->u.master) 59086747b715Smrg { 59096747b715Smrg DeviceIntPtr master = dev->u.master; 59106747b715Smrg if (master->u.lastSlave == dev) 59116747b715Smrg { 59126747b715Smrg XkbCopyDeviceKeymap(dev->u.master, dev); 59136747b715Smrg XkbSendNewKeyboardNotify(dev,&nkn); 59146747b715Smrg } 59156747b715Smrg } 591605b261ecSmrg } 59174642e01fSmrg if ((new!=NULL)&&(new!=xkb)) { 59186747b715Smrg XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); 59194642e01fSmrg new= NULL; 592005b261ecSmrg } 59219ace9065Smrg XkbFreeComponentNames(&names, FALSE); 59226747b715Smrg return Success; 592305b261ecSmrg} 592405b261ecSmrg 592505b261ecSmrg/***====================================================================***/ 592605b261ecSmrg 592705b261ecSmrgstatic int 592805b261ecSmrgComputeDeviceLedInfoSize( DeviceIntPtr dev, 592905b261ecSmrg unsigned int what, 593005b261ecSmrg XkbSrvLedInfoPtr sli) 593105b261ecSmrg{ 593205b261ecSmrgint nNames,nMaps; 593305b261ecSmrgregister unsigned n,bit; 593405b261ecSmrg 593505b261ecSmrg if (sli==NULL) 593605b261ecSmrg return 0; 593705b261ecSmrg nNames= nMaps= 0; 593805b261ecSmrg if ((what&XkbXI_IndicatorNamesMask)==0) 593905b261ecSmrg sli->namesPresent= 0; 594005b261ecSmrg if ((what&XkbXI_IndicatorMapsMask)==0) 594105b261ecSmrg sli->mapsPresent= 0; 594205b261ecSmrg 594305b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 594405b261ecSmrg if (sli->names && sli->names[n]!=None) { 594505b261ecSmrg sli->namesPresent|= bit; 594605b261ecSmrg nNames++; 594705b261ecSmrg } 594805b261ecSmrg if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 594905b261ecSmrg sli->mapsPresent|= bit; 595005b261ecSmrg nMaps++; 595105b261ecSmrg } 595205b261ecSmrg } 595305b261ecSmrg return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); 595405b261ecSmrg} 595505b261ecSmrg 595605b261ecSmrgstatic int 595705b261ecSmrgCheckDeviceLedFBs( DeviceIntPtr dev, 595805b261ecSmrg int class, 595905b261ecSmrg int id, 596005b261ecSmrg xkbGetDeviceInfoReply * rep, 596105b261ecSmrg ClientPtr client) 596205b261ecSmrg{ 596305b261ecSmrgint nFBs= 0; 596405b261ecSmrgint length= 0; 596505b261ecSmrgBool classOk; 596605b261ecSmrg 596705b261ecSmrg if (class==XkbDfltXIClass) { 596805b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 596905b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 597005b261ecSmrg else { 597105b261ecSmrg client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 597205b261ecSmrg return XkbKeyboardErrorCode; 597305b261ecSmrg } 597405b261ecSmrg } 59756747b715Smrg classOk= FALSE; 597605b261ecSmrg if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 597705b261ecSmrg KbdFeedbackPtr kf; 59786747b715Smrg classOk= TRUE; 597905b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 598005b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) 598105b261ecSmrg continue; 598205b261ecSmrg nFBs++; 598305b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 598405b261ecSmrg if (!kf->xkb_sli) 598505b261ecSmrg kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); 598605b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); 598705b261ecSmrg if (id!=XkbAllXIIds) 598805b261ecSmrg break; 598905b261ecSmrg } 599005b261ecSmrg } 599105b261ecSmrg if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 599205b261ecSmrg LedFeedbackPtr lf; 59936747b715Smrg classOk= TRUE; 599405b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 599505b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) 599605b261ecSmrg continue; 599705b261ecSmrg nFBs++; 599805b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 599905b261ecSmrg if (!lf->xkb_sli) 600005b261ecSmrg lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); 600105b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); 600205b261ecSmrg if (id!=XkbAllXIIds) 600305b261ecSmrg break; 600405b261ecSmrg } 600505b261ecSmrg } 600605b261ecSmrg if (nFBs>0) { 60076747b715Smrg rep->nDeviceLedFBs= nFBs; 60086747b715Smrg rep->length+= (length/4); 600905b261ecSmrg return Success; 601005b261ecSmrg } 601105b261ecSmrg if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); 601205b261ecSmrg else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 601305b261ecSmrg return XkbKeyboardErrorCode; 601405b261ecSmrg} 601505b261ecSmrg 601605b261ecSmrgstatic int 601705b261ecSmrgSendDeviceLedInfo( XkbSrvLedInfoPtr sli, 601805b261ecSmrg ClientPtr client) 601905b261ecSmrg{ 602005b261ecSmrgxkbDeviceLedsWireDesc wire; 602105b261ecSmrgint length; 602205b261ecSmrg 602305b261ecSmrg length= 0; 602405b261ecSmrg wire.ledClass= sli->class; 602505b261ecSmrg wire.ledID= sli->id; 602605b261ecSmrg wire.namesPresent= sli->namesPresent; 602705b261ecSmrg wire.mapsPresent= sli->mapsPresent; 602805b261ecSmrg wire.physIndicators= sli->physIndicators; 602905b261ecSmrg wire.state= sli->effectiveState; 603005b261ecSmrg if (client->swapped) { 603105b261ecSmrg register int n; 603205b261ecSmrg swaps(&wire.ledClass,n); 603305b261ecSmrg swaps(&wire.ledID,n); 603405b261ecSmrg swapl(&wire.namesPresent,n); 603505b261ecSmrg swapl(&wire.mapsPresent,n); 603605b261ecSmrg swapl(&wire.physIndicators,n); 603705b261ecSmrg swapl(&wire.state,n); 603805b261ecSmrg } 603905b261ecSmrg WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); 604005b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 604105b261ecSmrg if (sli->namesPresent|sli->mapsPresent) { 604205b261ecSmrg register unsigned i,bit; 604305b261ecSmrg if (sli->namesPresent) { 604405b261ecSmrg CARD32 awire; 604505b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 604605b261ecSmrg if (sli->namesPresent&bit) { 604705b261ecSmrg awire= (CARD32)sli->names[i]; 604805b261ecSmrg if (client->swapped) { 604905b261ecSmrg register int n; 605005b261ecSmrg swapl(&awire,n); 605105b261ecSmrg } 605205b261ecSmrg WriteToClient(client,4,(char *)&awire); 605305b261ecSmrg length+= 4; 605405b261ecSmrg } 605505b261ecSmrg } 605605b261ecSmrg } 605705b261ecSmrg if (sli->mapsPresent) { 605805b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 605905b261ecSmrg xkbIndicatorMapWireDesc iwire; 606005b261ecSmrg if (sli->mapsPresent&bit) { 606105b261ecSmrg iwire.flags= sli->maps[i].flags; 606205b261ecSmrg iwire.whichGroups= sli->maps[i].which_groups; 606305b261ecSmrg iwire.groups= sli->maps[i].groups; 606405b261ecSmrg iwire.whichMods= sli->maps[i].which_mods; 606505b261ecSmrg iwire.mods= sli->maps[i].mods.mask; 606605b261ecSmrg iwire.realMods= sli->maps[i].mods.real_mods; 606705b261ecSmrg iwire.virtualMods= sli->maps[i].mods.vmods; 606805b261ecSmrg iwire.ctrls= sli->maps[i].ctrls; 606905b261ecSmrg if (client->swapped) { 607005b261ecSmrg register int n; 607105b261ecSmrg swaps(&iwire.virtualMods,n); 607205b261ecSmrg swapl(&iwire.ctrls,n); 607305b261ecSmrg } 607405b261ecSmrg WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), 607505b261ecSmrg (char *)&iwire); 607605b261ecSmrg length+= SIZEOF(xkbIndicatorMapWireDesc); 607705b261ecSmrg } 607805b261ecSmrg } 607905b261ecSmrg } 608005b261ecSmrg } 608105b261ecSmrg return length; 608205b261ecSmrg} 608305b261ecSmrg 608405b261ecSmrgstatic int 608505b261ecSmrgSendDeviceLedFBs( DeviceIntPtr dev, 608605b261ecSmrg int class, 608705b261ecSmrg int id, 608805b261ecSmrg unsigned wantLength, 608905b261ecSmrg ClientPtr client) 609005b261ecSmrg{ 609105b261ecSmrgint length= 0; 609205b261ecSmrg 609305b261ecSmrg if (class==XkbDfltXIClass) { 609405b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 609505b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 609605b261ecSmrg } 609705b261ecSmrg if ((dev->kbdfeed)&& 609805b261ecSmrg ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 609905b261ecSmrg KbdFeedbackPtr kf; 610005b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 610105b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { 610205b261ecSmrg length+= SendDeviceLedInfo(kf->xkb_sli,client); 610305b261ecSmrg if (id!=XkbAllXIIds) 610405b261ecSmrg break; 610505b261ecSmrg } 610605b261ecSmrg } 610705b261ecSmrg } 610805b261ecSmrg if ((dev->leds)&& 610905b261ecSmrg ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 611005b261ecSmrg LedFeedbackPtr lf; 611105b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 611205b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { 611305b261ecSmrg length+= SendDeviceLedInfo(lf->xkb_sli,client); 611405b261ecSmrg if (id!=XkbAllXIIds) 611505b261ecSmrg break; 611605b261ecSmrg } 611705b261ecSmrg } 611805b261ecSmrg } 611905b261ecSmrg if (length==wantLength) 612005b261ecSmrg return Success; 612105b261ecSmrg else return BadLength; 612205b261ecSmrg} 612305b261ecSmrg 612405b261ecSmrgint 612505b261ecSmrgProcXkbGetDeviceInfo(ClientPtr client) 612605b261ecSmrg{ 612705b261ecSmrgDeviceIntPtr dev; 612805b261ecSmrgxkbGetDeviceInfoReply rep; 612905b261ecSmrgint status,nDeviceLedFBs; 613005b261ecSmrgunsigned length,nameLen; 613105b261ecSmrgCARD16 ledClass,ledID; 61326747b715Smrgunsigned wanted; 613305b261ecSmrgchar * str; 613405b261ecSmrg 613505b261ecSmrg REQUEST(xkbGetDeviceInfoReq); 613605b261ecSmrg REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 613705b261ecSmrg 613805b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 613905b261ecSmrg return BadAccess; 614005b261ecSmrg 614105b261ecSmrg wanted= stuff->wanted; 614205b261ecSmrg 61434642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 614405b261ecSmrg CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); 614505b261ecSmrg 614605b261ecSmrg if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) 614705b261ecSmrg wanted&= ~XkbXI_ButtonActionsMask; 614805b261ecSmrg if ((!dev->kbdfeed)&&(!dev->leds)) 614905b261ecSmrg wanted&= ~XkbXI_IndicatorsMask; 615005b261ecSmrg 615105b261ecSmrg nameLen= XkbSizeCountedString(dev->name); 61526747b715Smrg memset((char *)&rep, 0, SIZEOF(xkbGetDeviceInfoReply)); 615305b261ecSmrg rep.type = X_Reply; 615405b261ecSmrg rep.deviceID= dev->id; 615505b261ecSmrg rep.sequenceNumber = client->sequence; 615605b261ecSmrg rep.length = nameLen/4; 615705b261ecSmrg rep.present = wanted; 615805b261ecSmrg rep.supported = XkbXI_AllDeviceFeaturesMask; 615905b261ecSmrg rep.unsupported = 0; 616005b261ecSmrg rep.firstBtnWanted = rep.nBtnsWanted = 0; 616105b261ecSmrg rep.firstBtnRtrn = rep.nBtnsRtrn = 0; 616205b261ecSmrg if (dev->button) 616305b261ecSmrg rep.totalBtns= dev->button->numButtons; 616405b261ecSmrg else rep.totalBtns= 0; 61656747b715Smrg rep.devType= dev->xinput_type; 616605b261ecSmrg rep.hasOwnState= (dev->key && dev->key->xkbInfo); 616705b261ecSmrg rep.nDeviceLedFBs = 0; 616805b261ecSmrg if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; 616905b261ecSmrg else rep.dfltKbdFB= XkbXINone; 617005b261ecSmrg if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; 617105b261ecSmrg else rep.dfltLedFB= XkbXINone; 617205b261ecSmrg 617305b261ecSmrg ledClass= stuff->ledClass; 617405b261ecSmrg ledID= stuff->ledID; 617505b261ecSmrg 617605b261ecSmrg rep.firstBtnWanted= rep.nBtnsWanted= 0; 617705b261ecSmrg rep.firstBtnRtrn= rep.nBtnsRtrn= 0; 617805b261ecSmrg if (wanted&XkbXI_ButtonActionsMask) { 617905b261ecSmrg if (stuff->allBtns) { 618005b261ecSmrg stuff->firstBtn= 0; 618105b261ecSmrg stuff->nBtns= dev->button->numButtons; 618205b261ecSmrg } 618305b261ecSmrg 618405b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 618505b261ecSmrg client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, 618605b261ecSmrg stuff->firstBtn, 618705b261ecSmrg stuff->nBtns); 618805b261ecSmrg return BadValue; 618905b261ecSmrg } 619005b261ecSmrg else { 619105b261ecSmrg rep.firstBtnWanted= stuff->firstBtn; 619205b261ecSmrg rep.nBtnsWanted= stuff->nBtns; 619305b261ecSmrg if (dev->button->xkb_acts!=NULL) { 619405b261ecSmrg XkbAction *act; 619505b261ecSmrg register int i; 619605b261ecSmrg 619705b261ecSmrg rep.firstBtnRtrn= stuff->firstBtn; 619805b261ecSmrg rep.nBtnsRtrn= stuff->nBtns; 619905b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnWanted]; 620005b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act++) { 620105b261ecSmrg if (act->type!=XkbSA_NoAction) 620205b261ecSmrg break; 620305b261ecSmrg } 620405b261ecSmrg rep.firstBtnRtrn+= i; 620505b261ecSmrg rep.nBtnsRtrn-= i; 620605b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; 620705b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act--) { 620805b261ecSmrg if (act->type!=XkbSA_NoAction) 620905b261ecSmrg break; 621005b261ecSmrg } 621105b261ecSmrg rep.nBtnsRtrn-= i; 621205b261ecSmrg } 621305b261ecSmrg rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; 621405b261ecSmrg } 621505b261ecSmrg } 621605b261ecSmrg 621705b261ecSmrg if (wanted&XkbXI_IndicatorsMask) { 621805b261ecSmrg status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); 621905b261ecSmrg if (status!=Success) 622005b261ecSmrg return status; 622105b261ecSmrg } 622205b261ecSmrg length= rep.length*4; 622305b261ecSmrg nDeviceLedFBs = rep.nDeviceLedFBs; 622405b261ecSmrg if (client->swapped) { 622505b261ecSmrg register int n; 622605b261ecSmrg swaps(&rep.sequenceNumber,n); 622705b261ecSmrg swapl(&rep.length,n); 622805b261ecSmrg swaps(&rep.present,n); 622905b261ecSmrg swaps(&rep.supported,n); 623005b261ecSmrg swaps(&rep.unsupported,n); 623105b261ecSmrg swaps(&rep.nDeviceLedFBs,n); 623205b261ecSmrg swapl(&rep.type,n); 6233475c125cSmrg swaps(&rep.dfltKbdFB, n); 6234475c125cSmrg swaps(&rep.dfltLedFB, n); 6235475c125cSmrg swapl(&rep.devType, n); 623605b261ecSmrg } 623705b261ecSmrg WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); 623805b261ecSmrg 62396747b715Smrg str= malloc(nameLen); 624005b261ecSmrg if (!str) 624105b261ecSmrg return BadAlloc; 624205b261ecSmrg XkbWriteCountedString(str,dev->name,client->swapped); 624305b261ecSmrg WriteToClient(client,nameLen,str); 62446747b715Smrg free(str); 624505b261ecSmrg length-= nameLen; 624605b261ecSmrg 624705b261ecSmrg if (rep.nBtnsRtrn>0) { 624805b261ecSmrg int sz; 624905b261ecSmrg xkbActionWireDesc * awire; 625005b261ecSmrg sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); 625105b261ecSmrg awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; 625205b261ecSmrg WriteToClient(client,sz,(char *)awire); 625305b261ecSmrg length-= sz; 625405b261ecSmrg } 625505b261ecSmrg if (nDeviceLedFBs>0) { 625605b261ecSmrg status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); 625705b261ecSmrg if (status!=Success) 625805b261ecSmrg return status; 625905b261ecSmrg } 626005b261ecSmrg else if (length!=0) { 62614642e01fSmrg ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 62624642e01fSmrg ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length); 626305b261ecSmrg return BadLength; 626405b261ecSmrg } 62656747b715Smrg return Success; 626605b261ecSmrg} 626705b261ecSmrg 626805b261ecSmrgstatic char * 626905b261ecSmrgCheckSetDeviceIndicators( char * wire, 627005b261ecSmrg DeviceIntPtr dev, 627105b261ecSmrg int num, 627205b261ecSmrg int * status_rtrn, 627305b261ecSmrg ClientPtr client) 627405b261ecSmrg{ 627505b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 627605b261ecSmrgint i; 627705b261ecSmrgXkbSrvLedInfoPtr sli; 627805b261ecSmrg 627905b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 628005b261ecSmrg for (i=0;i<num;i++) { 628105b261ecSmrg if (client->swapped) { 628205b261ecSmrg register int n; 628305b261ecSmrg swaps(&ledWire->ledClass,n); 628405b261ecSmrg swaps(&ledWire->ledID,n); 628505b261ecSmrg swapl(&ledWire->namesPresent,n); 628605b261ecSmrg swapl(&ledWire->mapsPresent,n); 628705b261ecSmrg swapl(&ledWire->physIndicators,n); 628805b261ecSmrg } 628905b261ecSmrg 629005b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 629105b261ecSmrg XkbXI_IndicatorsMask); 629205b261ecSmrg if (sli!=NULL) { 629305b261ecSmrg register int n; 629405b261ecSmrg register unsigned bit; 629505b261ecSmrg int nMaps,nNames; 629605b261ecSmrg CARD32 *atomWire; 629705b261ecSmrg xkbIndicatorMapWireDesc *mapWire; 629805b261ecSmrg 629905b261ecSmrg nMaps= nNames= 0; 630005b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 630105b261ecSmrg if (ledWire->namesPresent&bit) 630205b261ecSmrg nNames++; 630305b261ecSmrg if (ledWire->mapsPresent&bit) 630405b261ecSmrg nMaps++; 630505b261ecSmrg } 630605b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 630705b261ecSmrg if (nNames>0) { 630805b261ecSmrg for (n=0;n<nNames;n++) { 630905b261ecSmrg if (client->swapped) { 631005b261ecSmrg register int t; 631105b261ecSmrg swapl(atomWire,t); 631205b261ecSmrg } 631305b261ecSmrg CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, 631405b261ecSmrg *status_rtrn,NULL); 631505b261ecSmrg atomWire++; 631605b261ecSmrg } 631705b261ecSmrg } 631805b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 631905b261ecSmrg if (nMaps>0) { 632005b261ecSmrg for (n=0;n<nMaps;n++) { 632105b261ecSmrg if (client->swapped) { 632205b261ecSmrg register int t; 632305b261ecSmrg swaps(&mapWire->virtualMods,t); 632405b261ecSmrg swapl(&mapWire->ctrls,t); 632505b261ecSmrg } 632605b261ecSmrg CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, 632705b261ecSmrg XkbIM_UseAnyGroup, 632805b261ecSmrg client->errorValue, 632905b261ecSmrg *status_rtrn,NULL); 633005b261ecSmrg CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, 633105b261ecSmrg client->errorValue, 633205b261ecSmrg *status_rtrn,NULL); 633305b261ecSmrg mapWire++; 633405b261ecSmrg } 633505b261ecSmrg } 633605b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 633705b261ecSmrg } 633805b261ecSmrg else { 633905b261ecSmrg /* SHOULD NEVER HAPPEN */ 634005b261ecSmrg return (char *)ledWire; 634105b261ecSmrg } 634205b261ecSmrg } 634305b261ecSmrg return (char *)ledWire; 634405b261ecSmrg} 634505b261ecSmrg 634605b261ecSmrgstatic char * 634705b261ecSmrgSetDeviceIndicators( char * wire, 634805b261ecSmrg DeviceIntPtr dev, 634905b261ecSmrg unsigned changed, 635005b261ecSmrg int num, 635105b261ecSmrg int * status_rtrn, 635205b261ecSmrg ClientPtr client, 635305b261ecSmrg xkbExtensionDeviceNotify *ev) 635405b261ecSmrg{ 635505b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 635605b261ecSmrgint i; 635705b261ecSmrgXkbEventCauseRec cause; 635805b261ecSmrgunsigned namec,mapc,statec; 635905b261ecSmrgxkbExtensionDeviceNotify ed; 636005b261ecSmrgXkbChangesRec changes; 636105b261ecSmrgDeviceIntPtr kbd; 636205b261ecSmrg 63636747b715Smrg memset((char *)&ed, 0, sizeof(xkbExtensionDeviceNotify)); 63646747b715Smrg memset((char *)&changes, 0, sizeof(XkbChangesRec)); 636505b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); 636605b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 636705b261ecSmrg for (i=0;i<num;i++) { 636805b261ecSmrg register int n; 636905b261ecSmrg register unsigned bit; 637005b261ecSmrg CARD32 * atomWire; 637105b261ecSmrg xkbIndicatorMapWireDesc * mapWire; 637205b261ecSmrg XkbSrvLedInfoPtr sli; 637305b261ecSmrg 637405b261ecSmrg namec= mapc= statec= 0; 637505b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 637605b261ecSmrg XkbXI_IndicatorMapsMask); 637705b261ecSmrg if (!sli) { 637805b261ecSmrg /* SHOULD NEVER HAPPEN!! */ 637905b261ecSmrg return (char *)ledWire; 638005b261ecSmrg } 638105b261ecSmrg 638205b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 638305b261ecSmrg if (changed&XkbXI_IndicatorNamesMask) { 638405b261ecSmrg namec= sli->namesPresent|ledWire->namesPresent; 63856747b715Smrg memset((char *)sli->names, 0, XkbNumIndicators*sizeof(Atom)); 638605b261ecSmrg } 638705b261ecSmrg if (ledWire->namesPresent) { 638805b261ecSmrg sli->namesPresent= ledWire->namesPresent; 63896747b715Smrg memset((char *)sli->names, 0, XkbNumIndicators*sizeof(Atom)); 639005b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 639105b261ecSmrg if (ledWire->namesPresent&bit) { 639205b261ecSmrg sli->names[n]= (Atom)*atomWire; 639305b261ecSmrg if (sli->names[n]==None) 639405b261ecSmrg ledWire->namesPresent&= ~bit; 639505b261ecSmrg atomWire++; 639605b261ecSmrg } 639705b261ecSmrg } 639805b261ecSmrg } 639905b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 640005b261ecSmrg if (changed&XkbXI_IndicatorMapsMask) { 640105b261ecSmrg mapc= sli->mapsPresent|ledWire->mapsPresent; 640205b261ecSmrg sli->mapsPresent= ledWire->mapsPresent; 64036747b715Smrg memset((char*)sli->maps, 0, XkbNumIndicators*sizeof(XkbIndicatorMapRec)); 640405b261ecSmrg } 640505b261ecSmrg if (ledWire->mapsPresent) { 640605b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 640705b261ecSmrg if (ledWire->mapsPresent&bit) { 640805b261ecSmrg sli->maps[n].flags= mapWire->flags; 640905b261ecSmrg sli->maps[n].which_groups= mapWire->whichGroups; 641005b261ecSmrg sli->maps[n].groups= mapWire->groups; 641105b261ecSmrg sli->maps[n].which_mods= mapWire->whichMods; 641205b261ecSmrg sli->maps[n].mods.mask= mapWire->mods; 641305b261ecSmrg sli->maps[n].mods.real_mods=mapWire->realMods; 641405b261ecSmrg sli->maps[n].mods.vmods= mapWire->virtualMods; 641505b261ecSmrg sli->maps[n].ctrls= mapWire->ctrls; 641605b261ecSmrg mapWire++; 641705b261ecSmrg } 641805b261ecSmrg } 641905b261ecSmrg } 642005b261ecSmrg if (changed&XkbXI_IndicatorStateMask) { 642105b261ecSmrg statec= sli->effectiveState^ledWire->state; 642205b261ecSmrg sli->explicitState&= ~statec; 642305b261ecSmrg sli->explicitState|= (ledWire->state&statec); 642405b261ecSmrg } 642505b261ecSmrg if (namec) 642605b261ecSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 642705b261ecSmrg if (mapc) 642805b261ecSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 642905b261ecSmrg if (statec) 643005b261ecSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 643105b261ecSmrg 643205b261ecSmrg kbd= dev; 643305b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 64344642e01fSmrg kbd = inputInfo.keyboard; 643505b261ecSmrg 643605b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 643705b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 643805b261ecSmrg } 643905b261ecSmrg return (char *)ledWire; 644005b261ecSmrg} 644105b261ecSmrg 644205b261ecSmrg 64434642e01fSmrgstatic int 64444642e01fSmrg_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 64454642e01fSmrg xkbSetDeviceInfoReq *stuff) 64464642e01fSmrg{ 64474642e01fSmrg char *wire; 644805b261ecSmrg 644905b261ecSmrg wire= (char *)&stuff[1]; 64504642e01fSmrg if (stuff->change&XkbXI_ButtonActionsMask) { 645105b261ecSmrg if (!dev->button) { 645205b261ecSmrg client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); 645305b261ecSmrg return XkbKeyboardErrorCode; 645405b261ecSmrg } 645505b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 645605b261ecSmrg client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, 645705b261ecSmrg dev->button->numButtons); 645805b261ecSmrg return BadMatch; 645905b261ecSmrg } 646005b261ecSmrg wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); 646105b261ecSmrg } 646205b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 646305b261ecSmrg int status= Success; 646405b261ecSmrg wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, 646505b261ecSmrg &status,client); 646605b261ecSmrg if (status!=Success) 646705b261ecSmrg return status; 646805b261ecSmrg } 646905b261ecSmrg if (((wire-((char *)stuff))/4)!=stuff->length) 647005b261ecSmrg return BadLength; 647105b261ecSmrg 64724642e01fSmrg return Success; 64734642e01fSmrg} 64744642e01fSmrg 64754642e01fSmrgstatic int 64764642e01fSmrg_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 64774642e01fSmrg xkbSetDeviceInfoReq *stuff) 64784642e01fSmrg{ 64794642e01fSmrg char *wire; 64804642e01fSmrg xkbExtensionDeviceNotify ed; 64814642e01fSmrg 64826747b715Smrg memset((char *)&ed, 0, SIZEOF(xkbExtensionDeviceNotify)); 648305b261ecSmrg ed.deviceID= dev->id; 648405b261ecSmrg wire= (char *)&stuff[1]; 64854642e01fSmrg if (stuff->change&XkbXI_ButtonActionsMask) { 648605b261ecSmrg int nBtns,sz,i; 648705b261ecSmrg XkbAction * acts; 648805b261ecSmrg DeviceIntPtr kbd; 648905b261ecSmrg 649005b261ecSmrg nBtns= dev->button->numButtons; 649105b261ecSmrg acts= dev->button->xkb_acts; 649205b261ecSmrg if (acts==NULL) { 64936747b715Smrg acts= calloc(nBtns, sizeof(XkbAction)); 649405b261ecSmrg if (!acts) 649505b261ecSmrg return BadAlloc; 649605b261ecSmrg dev->button->xkb_acts= acts; 649705b261ecSmrg } 649805b261ecSmrg sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); 649905b261ecSmrg memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); 650005b261ecSmrg wire+= sz; 650105b261ecSmrg ed.reason|= XkbXI_ButtonActionsMask; 650205b261ecSmrg ed.firstBtn= stuff->firstBtn; 650305b261ecSmrg ed.nBtns= stuff->nBtns; 650405b261ecSmrg 650505b261ecSmrg if (dev->key) kbd= dev; 65064642e01fSmrg else kbd= inputInfo.keyboard; 650705b261ecSmrg acts= &dev->button->xkb_acts[stuff->firstBtn]; 650805b261ecSmrg for (i=0;i<stuff->nBtns;i++,acts++) { 650905b261ecSmrg if (acts->type!=XkbSA_NoAction) 651005b261ecSmrg XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); 651105b261ecSmrg } 651205b261ecSmrg } 651305b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 651405b261ecSmrg int status= Success; 65154642e01fSmrg wire= SetDeviceIndicators(wire,dev,stuff->change, 65164642e01fSmrg stuff->nDeviceLedFBs, &status,client,&ed); 651705b261ecSmrg if (status!=Success) 651805b261ecSmrg return status; 651905b261ecSmrg } 652005b261ecSmrg if ((stuff->change)&&(ed.reason)) 652105b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&ed); 65224642e01fSmrg return Success; 65234642e01fSmrg} 65244642e01fSmrg 65254642e01fSmrgint 65264642e01fSmrgProcXkbSetDeviceInfo(ClientPtr client) 65274642e01fSmrg{ 65284642e01fSmrg DeviceIntPtr dev; 65294642e01fSmrg int rc; 65304642e01fSmrg 65314642e01fSmrg REQUEST(xkbSetDeviceInfoReq); 65324642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 65334642e01fSmrg 65344642e01fSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 65354642e01fSmrg return BadAccess; 65364642e01fSmrg 65374642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 65384642e01fSmrg CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask); 65394642e01fSmrg 65404642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 65414642e01fSmrg 65424642e01fSmrg if (rc != Success) 65434642e01fSmrg return rc; 65444642e01fSmrg 65454642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 65464642e01fSmrg { 65474642e01fSmrg DeviceIntPtr other; 65484642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 65494642e01fSmrg { 65506747b715Smrg if (((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) && 65514642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 65524642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) 65534642e01fSmrg { 65544642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 65554642e01fSmrg if (rc == Success) 65564642e01fSmrg { 65574642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, other, stuff); 65584642e01fSmrg if (rc != Success) 65594642e01fSmrg return rc; 65604642e01fSmrg } 65614642e01fSmrg } 65624642e01fSmrg } 65634642e01fSmrg } 65644642e01fSmrg 65654642e01fSmrg /* checks done, apply */ 65664642e01fSmrg rc = _XkbSetDeviceInfo(client, dev, stuff); 65674642e01fSmrg if (rc != Success) 65684642e01fSmrg return rc; 65694642e01fSmrg 65704642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 65714642e01fSmrg { 65724642e01fSmrg DeviceIntPtr other; 65734642e01fSmrg for (other = inputInfo.devices; other; other = other->next) 65744642e01fSmrg { 65756747b715Smrg if (((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) && 65764642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 65774642e01fSmrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) 65784642e01fSmrg { 65794642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 65804642e01fSmrg if (rc == Success) 65814642e01fSmrg { 65824642e01fSmrg rc = _XkbSetDeviceInfo(client, other, stuff); 65834642e01fSmrg if (rc != Success) 65844642e01fSmrg return rc; 65854642e01fSmrg } 65864642e01fSmrg } 65874642e01fSmrg } 65884642e01fSmrg } 65894642e01fSmrg 65906747b715Smrg return Success; 659105b261ecSmrg} 659205b261ecSmrg 659305b261ecSmrg/***====================================================================***/ 659405b261ecSmrg 659505b261ecSmrgint 659605b261ecSmrgProcXkbSetDebuggingFlags(ClientPtr client) 659705b261ecSmrg{ 659805b261ecSmrgCARD32 newFlags,newCtrls,extraLength; 659905b261ecSmrgxkbSetDebuggingFlagsReply rep; 66004642e01fSmrgint rc; 660105b261ecSmrg 660205b261ecSmrg REQUEST(xkbSetDebuggingFlagsReq); 660305b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 660405b261ecSmrg 66054642e01fSmrg rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 66064642e01fSmrg if (rc != Success) 66074642e01fSmrg return rc; 66084642e01fSmrg 660905b261ecSmrg newFlags= xkbDebugFlags&(~stuff->affectFlags); 661005b261ecSmrg newFlags|= (stuff->flags&stuff->affectFlags); 661105b261ecSmrg newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); 661205b261ecSmrg newCtrls|= (stuff->ctrls&stuff->affectCtrls); 661305b261ecSmrg if (xkbDebugFlags || newFlags || stuff->msgLength) { 66144642e01fSmrg ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); 661505b261ecSmrg if (newCtrls!=xkbDebugCtrls) 66164642e01fSmrg ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); 661705b261ecSmrg } 661805b261ecSmrg extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; 661905b261ecSmrg if (stuff->msgLength>0) { 662005b261ecSmrg char *msg; 662105b261ecSmrg if (extraLength<XkbPaddedSize(stuff->msgLength)) { 66224642e01fSmrg ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 662305b261ecSmrg stuff->msgLength,(long)extraLength, 662405b261ecSmrg XkbPaddedSize(stuff->msgLength)); 662505b261ecSmrg return BadLength; 662605b261ecSmrg } 662705b261ecSmrg msg= (char *)&stuff[1]; 662805b261ecSmrg if (msg[stuff->msgLength-1]!='\0') { 66294642e01fSmrg ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 663005b261ecSmrg return BadValue; 663105b261ecSmrg } 66324642e01fSmrg ErrorF("[xkb] XkbDebug: %s\n",msg); 663305b261ecSmrg } 663405b261ecSmrg xkbDebugFlags = newFlags; 663505b261ecSmrg xkbDebugCtrls = newCtrls; 663605b261ecSmrg 663705b261ecSmrg rep.type= X_Reply; 663805b261ecSmrg rep.length = 0; 663905b261ecSmrg rep.sequenceNumber = client->sequence; 664005b261ecSmrg rep.currentFlags = newFlags; 664105b261ecSmrg rep.currentCtrls = newCtrls; 664205b261ecSmrg rep.supportedFlags = ~0; 664305b261ecSmrg rep.supportedCtrls = ~0; 664405b261ecSmrg if ( client->swapped ) { 664505b261ecSmrg register int n; 664605b261ecSmrg swaps(&rep.sequenceNumber, n); 664705b261ecSmrg swapl(&rep.currentFlags, n); 664805b261ecSmrg swapl(&rep.currentCtrls, n); 664905b261ecSmrg swapl(&rep.supportedFlags, n); 665005b261ecSmrg swapl(&rep.supportedCtrls, n); 665105b261ecSmrg } 665205b261ecSmrg WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); 66536747b715Smrg return Success; 665405b261ecSmrg} 665505b261ecSmrg 665605b261ecSmrg/***====================================================================***/ 665705b261ecSmrg 665805b261ecSmrgstatic int 665905b261ecSmrgProcXkbDispatch (ClientPtr client) 666005b261ecSmrg{ 666105b261ecSmrg REQUEST(xReq); 666205b261ecSmrg switch (stuff->data) 666305b261ecSmrg { 666405b261ecSmrg case X_kbUseExtension: 666505b261ecSmrg return ProcXkbUseExtension(client); 666605b261ecSmrg case X_kbSelectEvents: 666705b261ecSmrg return ProcXkbSelectEvents(client); 666805b261ecSmrg case X_kbBell: 666905b261ecSmrg return ProcXkbBell(client); 667005b261ecSmrg case X_kbGetState: 667105b261ecSmrg return ProcXkbGetState(client); 667205b261ecSmrg case X_kbLatchLockState: 667305b261ecSmrg return ProcXkbLatchLockState(client); 667405b261ecSmrg case X_kbGetControls: 667505b261ecSmrg return ProcXkbGetControls(client); 667605b261ecSmrg case X_kbSetControls: 667705b261ecSmrg return ProcXkbSetControls(client); 667805b261ecSmrg case X_kbGetMap: 667905b261ecSmrg return ProcXkbGetMap(client); 668005b261ecSmrg case X_kbSetMap: 668105b261ecSmrg return ProcXkbSetMap(client); 668205b261ecSmrg case X_kbGetCompatMap: 668305b261ecSmrg return ProcXkbGetCompatMap(client); 668405b261ecSmrg case X_kbSetCompatMap: 668505b261ecSmrg return ProcXkbSetCompatMap(client); 668605b261ecSmrg case X_kbGetIndicatorState: 668705b261ecSmrg return ProcXkbGetIndicatorState(client); 668805b261ecSmrg case X_kbGetIndicatorMap: 668905b261ecSmrg return ProcXkbGetIndicatorMap(client); 669005b261ecSmrg case X_kbSetIndicatorMap: 669105b261ecSmrg return ProcXkbSetIndicatorMap(client); 669205b261ecSmrg case X_kbGetNamedIndicator: 669305b261ecSmrg return ProcXkbGetNamedIndicator(client); 669405b261ecSmrg case X_kbSetNamedIndicator: 669505b261ecSmrg return ProcXkbSetNamedIndicator(client); 669605b261ecSmrg case X_kbGetNames: 669705b261ecSmrg return ProcXkbGetNames(client); 669805b261ecSmrg case X_kbSetNames: 669905b261ecSmrg return ProcXkbSetNames(client); 670005b261ecSmrg case X_kbGetGeometry: 670105b261ecSmrg return ProcXkbGetGeometry(client); 670205b261ecSmrg case X_kbSetGeometry: 670305b261ecSmrg return ProcXkbSetGeometry(client); 670405b261ecSmrg case X_kbPerClientFlags: 670505b261ecSmrg return ProcXkbPerClientFlags(client); 670605b261ecSmrg case X_kbListComponents: 670705b261ecSmrg return ProcXkbListComponents(client); 670805b261ecSmrg case X_kbGetKbdByName: 670905b261ecSmrg return ProcXkbGetKbdByName(client); 671005b261ecSmrg case X_kbGetDeviceInfo: 671105b261ecSmrg return ProcXkbGetDeviceInfo(client); 671205b261ecSmrg case X_kbSetDeviceInfo: 671305b261ecSmrg return ProcXkbSetDeviceInfo(client); 671405b261ecSmrg case X_kbSetDebuggingFlags: 671505b261ecSmrg return ProcXkbSetDebuggingFlags(client); 671605b261ecSmrg default: 671705b261ecSmrg return BadRequest; 671805b261ecSmrg } 671905b261ecSmrg} 672005b261ecSmrg 672105b261ecSmrgstatic int 672205b261ecSmrgXkbClientGone(pointer data,XID id) 672305b261ecSmrg{ 672405b261ecSmrg DevicePtr pXDev = (DevicePtr)data; 672505b261ecSmrg 672605b261ecSmrg if (!XkbRemoveResourceClient(pXDev,id)) { 67274642e01fSmrg ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 672805b261ecSmrg } 672905b261ecSmrg return 1; 673005b261ecSmrg} 673105b261ecSmrg 673205b261ecSmrgvoid 673305b261ecSmrgXkbExtensionInit(void) 673405b261ecSmrg{ 673505b261ecSmrg ExtensionEntry *extEntry; 673605b261ecSmrg 67376747b715Smrg RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); 67386747b715Smrg if (!RT_XKBCLIENT) 67396747b715Smrg return; 67406747b715Smrg 67416747b715Smrg if (!XkbInitPrivates()) 67426747b715Smrg return; 67436747b715Smrg 674405b261ecSmrg if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 674505b261ecSmrg ProcXkbDispatch, SProcXkbDispatch, 67464642e01fSmrg NULL, StandardMinorOpcode))) { 674705b261ecSmrg XkbReqCode = (unsigned char)extEntry->base; 674805b261ecSmrg XkbEventBase = (unsigned char)extEntry->eventBase; 674905b261ecSmrg XkbErrorBase = (unsigned char)extEntry->errorBase; 675005b261ecSmrg XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; 675105b261ecSmrg } 675205b261ecSmrg return; 675305b261ecSmrg} 675405b261ecSmrg 675505b261ecSmrg 6756