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