xkb.c revision 05b261ec
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" 4105b261ecSmrg#include "xkb.h" 4205b261ecSmrg 4305b261ecSmrg#include <X11/extensions/XI.h> 4405b261ecSmrg 4505b261ecSmrg int XkbEventBase; 4605b261ecSmrgstatic int XkbErrorBase; 4705b261ecSmrg int XkbReqCode; 4805b261ecSmrgstatic int XkbKeyboardErrorCode; 4905b261ecSmrgCARD32 xkbDebugFlags = 0; 5005b261ecSmrgstatic CARD32 xkbDebugCtrls = 0; 5105b261ecSmrg 5205b261ecSmrgstatic RESTYPE RT_XKBCLIENT; 5305b261ecSmrg 5405b261ecSmrg/***====================================================================***/ 5505b261ecSmrg 5605b261ecSmrg#define CHK_DEVICE(d,sp,lf) {\ 5705b261ecSmrg int why;\ 5805b261ecSmrg d = (DeviceIntPtr)lf((sp),&why);\ 5905b261ecSmrg if (!dev) {\ 6005b261ecSmrg client->errorValue = _XkbErrCode2(why,(sp));\ 6105b261ecSmrg return XkbKeyboardErrorCode;\ 6205b261ecSmrg }\ 6305b261ecSmrg} 6405b261ecSmrg 6505b261ecSmrg#define CHK_KBD_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupKeyboard) 6605b261ecSmrg#define CHK_LED_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupLedDevice) 6705b261ecSmrg#define CHK_BELL_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupBellDevice) 6805b261ecSmrg#define CHK_ANY_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupAnyDevice) 6905b261ecSmrg 7005b261ecSmrg#define CHK_ATOM_ONLY2(a,ev,er) {\ 7105b261ecSmrg if (((a)==None)||(!ValidAtom((a)))) {\ 7205b261ecSmrg (ev)= (XID)(a);\ 7305b261ecSmrg return er;\ 7405b261ecSmrg }\ 7505b261ecSmrg} 7605b261ecSmrg#define CHK_ATOM_ONLY(a) \ 7705b261ecSmrg CHK_ATOM_ONLY2(a,client->errorValue,BadAtom) 7805b261ecSmrg 7905b261ecSmrg#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\ 8005b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 8105b261ecSmrg (ev)= (XID)(a);\ 8205b261ecSmrg (er)= BadAtom;\ 8305b261ecSmrg return ret;\ 8405b261ecSmrg }\ 8505b261ecSmrg} 8605b261ecSmrg#define CHK_ATOM_OR_NONE2(a,ev,er) {\ 8705b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 8805b261ecSmrg (ev)= (XID)(a);\ 8905b261ecSmrg return er;\ 9005b261ecSmrg }\ 9105b261ecSmrg} 9205b261ecSmrg#define CHK_ATOM_OR_NONE(a) \ 9305b261ecSmrg CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom) 9405b261ecSmrg 9505b261ecSmrg#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\ 9605b261ecSmrg if ((mask)&(~(legal))) { \ 9705b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 9805b261ecSmrg (er)= BadValue;\ 9905b261ecSmrg return ret;\ 10005b261ecSmrg }\ 10105b261ecSmrg} 10205b261ecSmrg#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\ 10305b261ecSmrg if ((mask)&(~(legal))) { \ 10405b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 10505b261ecSmrg return er;\ 10605b261ecSmrg }\ 10705b261ecSmrg} 10805b261ecSmrg#define CHK_MASK_LEGAL(err,mask,legal) \ 10905b261ecSmrg CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue) 11005b261ecSmrg 11105b261ecSmrg#define CHK_MASK_MATCH(err,affect,value) {\ 11205b261ecSmrg if ((value)&(~(affect))) { \ 11305b261ecSmrg client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\ 11405b261ecSmrg return BadMatch;\ 11505b261ecSmrg }\ 11605b261ecSmrg} 11705b261ecSmrg#define CHK_MASK_OVERLAP(err,m1,m2) {\ 11805b261ecSmrg if ((m1)&(m2)) { \ 11905b261ecSmrg client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\ 12005b261ecSmrg return BadMatch;\ 12105b261ecSmrg }\ 12205b261ecSmrg} 12305b261ecSmrg#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\ 12405b261ecSmrg if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\ 12505b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\ 12605b261ecSmrg return er;\ 12705b261ecSmrg }\ 12805b261ecSmrg else if ( (first)<(x)->min_key_code ) {\ 12905b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\ 13005b261ecSmrg return er;\ 13105b261ecSmrg }\ 13205b261ecSmrg} 13305b261ecSmrg#define CHK_KEY_RANGE(err,first,num,x) \ 13405b261ecSmrg CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue) 13505b261ecSmrg 13605b261ecSmrg#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\ 13705b261ecSmrg if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\ 13805b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\ 13905b261ecSmrg return er;\ 14005b261ecSmrg }\ 14105b261ecSmrg else if ( (first)<(r)->minKeyCode ) {\ 14205b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\ 14305b261ecSmrg return er;\ 14405b261ecSmrg }\ 14505b261ecSmrg} 14605b261ecSmrg#define CHK_REQ_KEY_RANGE(err,first,num,r) \ 14705b261ecSmrg CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) 14805b261ecSmrg 14905b261ecSmrg/***====================================================================***/ 15005b261ecSmrg 15105b261ecSmrgint 15205b261ecSmrgProcXkbUseExtension(ClientPtr client) 15305b261ecSmrg{ 15405b261ecSmrg REQUEST(xkbUseExtensionReq); 15505b261ecSmrg xkbUseExtensionReply rep; 15605b261ecSmrg register int n; 15705b261ecSmrg int supported; 15805b261ecSmrg 15905b261ecSmrg REQUEST_SIZE_MATCH(xkbUseExtensionReq); 16005b261ecSmrg if (stuff->wantedMajor != XkbMajorVersion) { 16105b261ecSmrg /* pre-release version 0.65 is compatible with 1.00 */ 16205b261ecSmrg supported= ((XkbMajorVersion==1)&& 16305b261ecSmrg (stuff->wantedMajor==0)&&(stuff->wantedMinor==65)); 16405b261ecSmrg } 16505b261ecSmrg else supported = 1; 16605b261ecSmrg 16705b261ecSmrg if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) { 16805b261ecSmrg client->xkbClientFlags= _XkbClientInitialized; 16905b261ecSmrg client->vMajor= stuff->wantedMajor; 17005b261ecSmrg client->vMinor= stuff->wantedMinor; 17105b261ecSmrg } 17205b261ecSmrg else if (xkbDebugFlags&0x1) { 17305b261ecSmrg ErrorF("Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", 17405b261ecSmrg client->index, 17505b261ecSmrg (long)client->clientAsMask, 17605b261ecSmrg stuff->wantedMajor,stuff->wantedMinor, 17705b261ecSmrg XkbMajorVersion,XkbMinorVersion); 17805b261ecSmrg } 17905b261ecSmrg rep.type = X_Reply; 18005b261ecSmrg rep.supported = supported; 18105b261ecSmrg rep.length = 0; 18205b261ecSmrg rep.sequenceNumber = client->sequence; 18305b261ecSmrg rep.serverMajor = XkbMajorVersion; 18405b261ecSmrg rep.serverMinor = XkbMinorVersion; 18505b261ecSmrg if ( client->swapped ) { 18605b261ecSmrg swaps(&rep.sequenceNumber, n); 18705b261ecSmrg swaps(&rep.serverMajor, n); 18805b261ecSmrg swaps(&rep.serverMinor, n); 18905b261ecSmrg } 19005b261ecSmrg WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep); 19105b261ecSmrg return client->noClientException; 19205b261ecSmrg} 19305b261ecSmrg 19405b261ecSmrg/***====================================================================***/ 19505b261ecSmrg 19605b261ecSmrgint 19705b261ecSmrgProcXkbSelectEvents(ClientPtr client) 19805b261ecSmrg{ 19905b261ecSmrg unsigned legal; 20005b261ecSmrg DeviceIntPtr dev; 20105b261ecSmrg XkbInterestPtr masks; 20205b261ecSmrg REQUEST(xkbSelectEventsReq); 20305b261ecSmrg 20405b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); 20505b261ecSmrg 20605b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 20705b261ecSmrg return BadAccess; 20805b261ecSmrg 20905b261ecSmrg CHK_ANY_DEVICE(dev,stuff->deviceSpec); 21005b261ecSmrg 21105b261ecSmrg if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) { 21205b261ecSmrg client->mapNotifyMask&= ~stuff->affectMap; 21305b261ecSmrg client->mapNotifyMask|= (stuff->affectMap&stuff->map); 21405b261ecSmrg } 21505b261ecSmrg if ((stuff->affectWhich&(~XkbMapNotifyMask))==0) 21605b261ecSmrg return client->noClientException; 21705b261ecSmrg 21805b261ecSmrg masks = XkbFindClientResource((DevicePtr)dev,client); 21905b261ecSmrg if (!masks){ 22005b261ecSmrg XID id = FakeClientID(client->index); 22105b261ecSmrg AddResource(id,RT_XKBCLIENT,dev); 22205b261ecSmrg masks= XkbAddClientResource((DevicePtr)dev,client,id); 22305b261ecSmrg } 22405b261ecSmrg if (masks) { 22505b261ecSmrg union { 22605b261ecSmrg CARD8 *c8; 22705b261ecSmrg CARD16 *c16; 22805b261ecSmrg CARD32 *c32; 22905b261ecSmrg } from,to; 23005b261ecSmrg register unsigned bit,ndx,maskLeft,dataLeft,size; 23105b261ecSmrg 23205b261ecSmrg from.c8= (CARD8 *)&stuff[1]; 23305b261ecSmrg dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq); 23405b261ecSmrg maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask)); 23505b261ecSmrg for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) { 23605b261ecSmrg if ((bit&maskLeft)==0) 23705b261ecSmrg continue; 23805b261ecSmrg maskLeft&= ~bit; 23905b261ecSmrg switch (ndx) { 24005b261ecSmrg case XkbNewKeyboardNotify: 24105b261ecSmrg to.c16= &client->newKeyboardNotifyMask; 24205b261ecSmrg legal= XkbAllNewKeyboardEventsMask; 24305b261ecSmrg size= 2; 24405b261ecSmrg break; 24505b261ecSmrg case XkbStateNotify: 24605b261ecSmrg to.c16= &masks->stateNotifyMask; 24705b261ecSmrg legal= XkbAllStateEventsMask; 24805b261ecSmrg size= 2; 24905b261ecSmrg break; 25005b261ecSmrg case XkbControlsNotify: 25105b261ecSmrg to.c32= &masks->ctrlsNotifyMask; 25205b261ecSmrg legal= XkbAllControlEventsMask; 25305b261ecSmrg size= 4; 25405b261ecSmrg break; 25505b261ecSmrg case XkbIndicatorStateNotify: 25605b261ecSmrg to.c32= &masks->iStateNotifyMask; 25705b261ecSmrg legal= XkbAllIndicatorEventsMask; 25805b261ecSmrg size= 4; 25905b261ecSmrg break; 26005b261ecSmrg case XkbIndicatorMapNotify: 26105b261ecSmrg to.c32= &masks->iMapNotifyMask; 26205b261ecSmrg legal= XkbAllIndicatorEventsMask; 26305b261ecSmrg size= 4; 26405b261ecSmrg break; 26505b261ecSmrg case XkbNamesNotify: 26605b261ecSmrg to.c16= &masks->namesNotifyMask; 26705b261ecSmrg legal= XkbAllNameEventsMask; 26805b261ecSmrg size= 2; 26905b261ecSmrg break; 27005b261ecSmrg case XkbCompatMapNotify: 27105b261ecSmrg to.c8= &masks->compatNotifyMask; 27205b261ecSmrg legal= XkbAllCompatMapEventsMask; 27305b261ecSmrg size= 1; 27405b261ecSmrg break; 27505b261ecSmrg case XkbBellNotify: 27605b261ecSmrg to.c8= &masks->bellNotifyMask; 27705b261ecSmrg legal= XkbAllBellEventsMask; 27805b261ecSmrg size= 1; 27905b261ecSmrg break; 28005b261ecSmrg case XkbActionMessage: 28105b261ecSmrg to.c8= &masks->actionMessageMask; 28205b261ecSmrg legal= XkbAllActionMessagesMask; 28305b261ecSmrg size= 1; 28405b261ecSmrg break; 28505b261ecSmrg case XkbAccessXNotify: 28605b261ecSmrg to.c16= &masks->accessXNotifyMask; 28705b261ecSmrg legal= XkbAllAccessXEventsMask; 28805b261ecSmrg size= 2; 28905b261ecSmrg break; 29005b261ecSmrg case XkbExtensionDeviceNotify: 29105b261ecSmrg to.c16= &masks->extDevNotifyMask; 29205b261ecSmrg legal= XkbAllExtensionDeviceEventsMask; 29305b261ecSmrg size= 2; 29405b261ecSmrg break; 29505b261ecSmrg default: 29605b261ecSmrg client->errorValue = _XkbErrCode2(33,bit); 29705b261ecSmrg return BadValue; 29805b261ecSmrg } 29905b261ecSmrg 30005b261ecSmrg if (stuff->clear&bit) { 30105b261ecSmrg if (size==2) to.c16[0]= 0; 30205b261ecSmrg else if (size==4) to.c32[0]= 0; 30305b261ecSmrg else to.c8[0]= 0; 30405b261ecSmrg } 30505b261ecSmrg else if (stuff->selectAll&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 { 31105b261ecSmrg if (dataLeft<(size*2)) 31205b261ecSmrg return BadLength; 31305b261ecSmrg if (size==2) { 31405b261ecSmrg CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]); 31505b261ecSmrg CHK_MASK_LEGAL(ndx,from.c16[0],legal); 31605b261ecSmrg to.c16[0]&= ~from.c16[0]; 31705b261ecSmrg to.c16[0]|= (from.c16[0]&from.c16[1]); 31805b261ecSmrg } 31905b261ecSmrg else if (size==4) { 32005b261ecSmrg CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]); 32105b261ecSmrg CHK_MASK_LEGAL(ndx,from.c32[0],legal); 32205b261ecSmrg to.c32[0]&= ~from.c32[0]; 32305b261ecSmrg to.c32[0]|= (from.c32[0]&from.c32[1]); 32405b261ecSmrg } 32505b261ecSmrg else { 32605b261ecSmrg CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]); 32705b261ecSmrg CHK_MASK_LEGAL(ndx,from.c8[0],legal); 32805b261ecSmrg to.c8[0]&= ~from.c8[0]; 32905b261ecSmrg to.c8[0]|= (from.c8[0]&from.c8[1]); 33005b261ecSmrg size= 2; 33105b261ecSmrg } 33205b261ecSmrg from.c8+= (size*2); 33305b261ecSmrg dataLeft-= (size*2); 33405b261ecSmrg } 33505b261ecSmrg } 33605b261ecSmrg if (dataLeft>2) { 33705b261ecSmrg ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft); 33805b261ecSmrg return BadLength; 33905b261ecSmrg } 34005b261ecSmrg return client->noClientException; 34105b261ecSmrg } 34205b261ecSmrg return BadAlloc; 34305b261ecSmrg} 34405b261ecSmrg 34505b261ecSmrg/***====================================================================***/ 34605b261ecSmrg 34705b261ecSmrg/* FIXME: Needs to ding on all core-sending devices. */ 34805b261ecSmrgint 34905b261ecSmrgProcXkbBell(ClientPtr client) 35005b261ecSmrg{ 35105b261ecSmrg REQUEST(xkbBellReq); 35205b261ecSmrg DeviceIntPtr dev; 35305b261ecSmrg WindowPtr pWin; 35405b261ecSmrg int base; 35505b261ecSmrg int newPercent,oldPitch,oldDuration; 35605b261ecSmrg pointer ctrl; 35705b261ecSmrg 35805b261ecSmrg REQUEST_SIZE_MATCH(xkbBellReq); 35905b261ecSmrg 36005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 36105b261ecSmrg return BadAccess; 36205b261ecSmrg 36305b261ecSmrg CHK_BELL_DEVICE(dev,stuff->deviceSpec); 36405b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 36505b261ecSmrg 36605b261ecSmrg if ((stuff->forceSound)&&(stuff->eventOnly)) { 36705b261ecSmrg client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); 36805b261ecSmrg return BadMatch; 36905b261ecSmrg } 37005b261ecSmrg if (stuff->percent < -100 || stuff->percent > 100) { 37105b261ecSmrg client->errorValue = _XkbErrCode2(0x2,stuff->percent); 37205b261ecSmrg return BadValue; 37305b261ecSmrg } 37405b261ecSmrg if (stuff->duration<-1) { 37505b261ecSmrg client->errorValue = _XkbErrCode2(0x3,stuff->duration); 37605b261ecSmrg return BadValue; 37705b261ecSmrg } 37805b261ecSmrg if (stuff->pitch<-1) { 37905b261ecSmrg client->errorValue = _XkbErrCode2(0x4,stuff->pitch); 38005b261ecSmrg return BadValue; 38105b261ecSmrg } 38205b261ecSmrg 38305b261ecSmrg if (stuff->bellClass == XkbDfltXIClass) { 38405b261ecSmrg if (dev->kbdfeed!=NULL) 38505b261ecSmrg stuff->bellClass= KbdFeedbackClass; 38605b261ecSmrg else stuff->bellClass= BellFeedbackClass; 38705b261ecSmrg } 38805b261ecSmrg if (stuff->bellClass == KbdFeedbackClass) { 38905b261ecSmrg KbdFeedbackPtr k; 39005b261ecSmrg if (stuff->bellID==XkbDfltXIId) 39105b261ecSmrg k= dev->kbdfeed; 39205b261ecSmrg else { 39305b261ecSmrg for (k=dev->kbdfeed; k; k=k->next) { 39405b261ecSmrg if (k->ctrl.id == stuff->bellID) 39505b261ecSmrg break; 39605b261ecSmrg } 39705b261ecSmrg } 39805b261ecSmrg if (!k) { 39905b261ecSmrg client->errorValue= _XkbErrCode2(0x5,stuff->bellID); 40005b261ecSmrg return BadValue; 40105b261ecSmrg } 40205b261ecSmrg base = k->ctrl.bell; 40305b261ecSmrg ctrl = (pointer) &(k->ctrl); 40405b261ecSmrg oldPitch= k->ctrl.bell_pitch; 40505b261ecSmrg oldDuration= k->ctrl.bell_duration; 40605b261ecSmrg if (stuff->pitch!=0) { 40705b261ecSmrg if (stuff->pitch==-1) 40805b261ecSmrg k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; 40905b261ecSmrg else k->ctrl.bell_pitch= stuff->pitch; 41005b261ecSmrg } 41105b261ecSmrg if (stuff->duration!=0) { 41205b261ecSmrg if (stuff->duration==-1) 41305b261ecSmrg k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; 41405b261ecSmrg else k->ctrl.bell_duration= stuff->duration; 41505b261ecSmrg } 41605b261ecSmrg } 41705b261ecSmrg else if (stuff->bellClass == BellFeedbackClass) { 41805b261ecSmrg BellFeedbackPtr b; 41905b261ecSmrg if (stuff->bellID==XkbDfltXIId) 42005b261ecSmrg b= dev->bell; 42105b261ecSmrg else { 42205b261ecSmrg for (b=dev->bell; b; b=b->next) { 42305b261ecSmrg if (b->ctrl.id == stuff->bellID) 42405b261ecSmrg break; 42505b261ecSmrg } 42605b261ecSmrg } 42705b261ecSmrg if (!b) { 42805b261ecSmrg client->errorValue = _XkbErrCode2(0x6,stuff->bellID); 42905b261ecSmrg return BadValue; 43005b261ecSmrg } 43105b261ecSmrg base = b->ctrl.percent; 43205b261ecSmrg ctrl = (pointer) &(b->ctrl); 43305b261ecSmrg oldPitch= b->ctrl.pitch; 43405b261ecSmrg oldDuration= b->ctrl.duration; 43505b261ecSmrg if (stuff->pitch!=0) { 43605b261ecSmrg if (stuff->pitch==-1) 43705b261ecSmrg b->ctrl.pitch= defaultKeyboardControl.bell_pitch; 43805b261ecSmrg else b->ctrl.pitch= stuff->pitch; 43905b261ecSmrg } 44005b261ecSmrg if (stuff->duration!=0) { 44105b261ecSmrg if (stuff->duration==-1) 44205b261ecSmrg b->ctrl.duration= defaultKeyboardControl.bell_duration; 44305b261ecSmrg else b->ctrl.duration= stuff->duration; 44405b261ecSmrg } 44505b261ecSmrg } 44605b261ecSmrg else { 44705b261ecSmrg client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);; 44805b261ecSmrg return BadValue; 44905b261ecSmrg } 45005b261ecSmrg if (stuff->window!=None) { 45105b261ecSmrg pWin= (WindowPtr)LookupIDByType(stuff->window,RT_WINDOW); 45205b261ecSmrg if (pWin==NULL) { 45305b261ecSmrg client->errorValue= stuff->window; 45405b261ecSmrg return BadValue; 45505b261ecSmrg } 45605b261ecSmrg } 45705b261ecSmrg else pWin= NULL; 45805b261ecSmrg 45905b261ecSmrg newPercent= (base*stuff->percent)/100; 46005b261ecSmrg if (stuff->percent < 0) 46105b261ecSmrg newPercent= base+newPercent; 46205b261ecSmrg else newPercent= base-newPercent+stuff->percent; 46305b261ecSmrg XkbHandleBell(stuff->forceSound, stuff->eventOnly, 46405b261ecSmrg dev, newPercent, ctrl, stuff->bellClass, 46505b261ecSmrg stuff->name, pWin, client); 46605b261ecSmrg if ((stuff->pitch!=0)||(stuff->duration!=0)) { 46705b261ecSmrg if (stuff->bellClass == KbdFeedbackClass) { 46805b261ecSmrg KbdFeedbackPtr k; 46905b261ecSmrg k= (KbdFeedbackPtr)ctrl; 47005b261ecSmrg if (stuff->pitch!=0) 47105b261ecSmrg k->ctrl.bell_pitch= oldPitch; 47205b261ecSmrg if (stuff->duration!=0) 47305b261ecSmrg k->ctrl.bell_duration= oldDuration; 47405b261ecSmrg } 47505b261ecSmrg else { 47605b261ecSmrg BellFeedbackPtr b; 47705b261ecSmrg b= (BellFeedbackPtr)ctrl; 47805b261ecSmrg if (stuff->pitch!=0) 47905b261ecSmrg b->ctrl.pitch= oldPitch; 48005b261ecSmrg if (stuff->duration!=0) 48105b261ecSmrg b->ctrl.duration= oldDuration; 48205b261ecSmrg } 48305b261ecSmrg } 48405b261ecSmrg return Success; 48505b261ecSmrg} 48605b261ecSmrg 48705b261ecSmrg/***====================================================================***/ 48805b261ecSmrg 48905b261ecSmrgint 49005b261ecSmrgProcXkbGetState(ClientPtr client) 49105b261ecSmrg{ 49205b261ecSmrg REQUEST(xkbGetStateReq); 49305b261ecSmrg DeviceIntPtr dev; 49405b261ecSmrg xkbGetStateReply rep; 49505b261ecSmrg XkbStateRec *xkb; 49605b261ecSmrg 49705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetStateReq); 49805b261ecSmrg 49905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 50005b261ecSmrg return BadAccess; 50105b261ecSmrg 50205b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 50305b261ecSmrg 50405b261ecSmrg xkb= &dev->key->xkbInfo->state; 50505b261ecSmrg bzero(&rep,sizeof(xkbGetStateReply)); 50605b261ecSmrg rep.type= X_Reply; 50705b261ecSmrg rep.sequenceNumber= client->sequence; 50805b261ecSmrg rep.length = 0; 50905b261ecSmrg rep.deviceID = dev->id; 51005b261ecSmrg rep.mods = dev->key->state&0xff; 51105b261ecSmrg rep.baseMods = xkb->base_mods; 51205b261ecSmrg rep.lockedMods = xkb->locked_mods; 51305b261ecSmrg rep.latchedMods = xkb->latched_mods; 51405b261ecSmrg rep.group = xkb->group; 51505b261ecSmrg rep.baseGroup = xkb->base_group; 51605b261ecSmrg rep.latchedGroup = xkb->latched_group; 51705b261ecSmrg rep.lockedGroup = xkb->locked_group; 51805b261ecSmrg rep.compatState = xkb->compat_state; 51905b261ecSmrg rep.ptrBtnState = xkb->ptr_buttons; 52005b261ecSmrg if (client->swapped) { 52105b261ecSmrg register int n; 52205b261ecSmrg swaps(&rep.sequenceNumber,n); 52305b261ecSmrg swaps(&rep.ptrBtnState,n); 52405b261ecSmrg } 52505b261ecSmrg WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep); 52605b261ecSmrg return client->noClientException; 52705b261ecSmrg} 52805b261ecSmrg 52905b261ecSmrg/***====================================================================***/ 53005b261ecSmrg 53105b261ecSmrgint 53205b261ecSmrgProcXkbLatchLockState(ClientPtr client) 53305b261ecSmrg{ 53405b261ecSmrg int status; 53505b261ecSmrg DeviceIntPtr dev, tmpd; 53605b261ecSmrg XkbStateRec oldState,*newState; 53705b261ecSmrg CARD16 changed; 53805b261ecSmrg xkbStateNotify sn; 53905b261ecSmrg XkbEventCauseRec cause; 54005b261ecSmrg 54105b261ecSmrg REQUEST(xkbLatchLockStateReq); 54205b261ecSmrg REQUEST_SIZE_MATCH(xkbLatchLockStateReq); 54305b261ecSmrg 54405b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 54505b261ecSmrg return BadAccess; 54605b261ecSmrg 54705b261ecSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec); 54805b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); 54905b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); 55005b261ecSmrg 55105b261ecSmrg status = Success; 55205b261ecSmrg 55305b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 55405b261ecSmrg if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) || 55505b261ecSmrg tmpd == dev) { 55605b261ecSmrg if (!tmpd->key->xkbInfo) 55705b261ecSmrg continue; 55805b261ecSmrg 55905b261ecSmrg oldState = tmpd->key->xkbInfo->state; 56005b261ecSmrg newState = &tmpd->key->xkbInfo->state; 56105b261ecSmrg if (stuff->affectModLocks) { 56205b261ecSmrg newState->locked_mods &= ~stuff->affectModLocks; 56305b261ecSmrg newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks); 56405b261ecSmrg } 56505b261ecSmrg if (status == Success && stuff->lockGroup) 56605b261ecSmrg newState->locked_group = stuff->groupLock; 56705b261ecSmrg if (status == Success && stuff->affectModLatches) 56805b261ecSmrg status = XkbLatchModifiers(tmpd, stuff->affectModLatches, 56905b261ecSmrg stuff->modLatches); 57005b261ecSmrg if (status == Success && stuff->latchGroup) 57105b261ecSmrg status = XkbLatchGroup(tmpd, stuff->groupLatch); 57205b261ecSmrg 57305b261ecSmrg if (status != Success) 57405b261ecSmrg return status; 57505b261ecSmrg 57605b261ecSmrg XkbComputeDerivedState(tmpd->key->xkbInfo); 57705b261ecSmrg tmpd->key->state = XkbStateFieldFromRec(newState); 57805b261ecSmrg 57905b261ecSmrg changed = XkbStateChangedFlags(&oldState, newState); 58005b261ecSmrg if (changed) { 58105b261ecSmrg sn.keycode = 0; 58205b261ecSmrg sn.eventType = 0; 58305b261ecSmrg sn.requestMajor = XkbReqCode; 58405b261ecSmrg sn.requestMinor = X_kbLatchLockState; 58505b261ecSmrg sn.changed = changed; 58605b261ecSmrg XkbSendStateNotify(tmpd, &sn); 58705b261ecSmrg changed = XkbIndicatorsToUpdate(tmpd, changed, False); 58805b261ecSmrg if (changed) { 58905b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); 59005b261ecSmrg XkbUpdateIndicators(tmpd, changed, True, NULL, &cause); 59105b261ecSmrg } 59205b261ecSmrg } 59305b261ecSmrg } 59405b261ecSmrg } 59505b261ecSmrg 59605b261ecSmrg return client->noClientException; 59705b261ecSmrg} 59805b261ecSmrg 59905b261ecSmrg/***====================================================================***/ 60005b261ecSmrg 60105b261ecSmrgint 60205b261ecSmrgProcXkbGetControls(ClientPtr client) 60305b261ecSmrg{ 60405b261ecSmrg xkbGetControlsReply rep; 60505b261ecSmrg XkbControlsPtr xkb; 60605b261ecSmrg DeviceIntPtr dev; 60705b261ecSmrg register int n; 60805b261ecSmrg 60905b261ecSmrg REQUEST(xkbGetControlsReq); 61005b261ecSmrg REQUEST_SIZE_MATCH(xkbGetControlsReq); 61105b261ecSmrg 61205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 61305b261ecSmrg return BadAccess; 61405b261ecSmrg 61505b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 61605b261ecSmrg 61705b261ecSmrg xkb = dev->key->xkbInfo->desc->ctrls; 61805b261ecSmrg rep.type = X_Reply; 61905b261ecSmrg rep.length = (SIZEOF(xkbGetControlsReply)- 62005b261ecSmrg SIZEOF(xGenericReply)) >> 2; 62105b261ecSmrg rep.sequenceNumber = client->sequence; 62205b261ecSmrg rep.deviceID = ((DeviceIntPtr)dev)->id; 62305b261ecSmrg rep.numGroups = xkb->num_groups; 62405b261ecSmrg rep.groupsWrap = xkb->groups_wrap; 62505b261ecSmrg rep.internalMods = xkb->internal.mask; 62605b261ecSmrg rep.ignoreLockMods = xkb->ignore_lock.mask; 62705b261ecSmrg rep.internalRealMods = xkb->internal.real_mods; 62805b261ecSmrg rep.ignoreLockRealMods = xkb->ignore_lock.real_mods; 62905b261ecSmrg rep.internalVMods = xkb->internal.vmods; 63005b261ecSmrg rep.ignoreLockVMods = xkb->ignore_lock.vmods; 63105b261ecSmrg rep.enabledCtrls = xkb->enabled_ctrls; 63205b261ecSmrg rep.repeatDelay = xkb->repeat_delay; 63305b261ecSmrg rep.repeatInterval = xkb->repeat_interval; 63405b261ecSmrg rep.slowKeysDelay = xkb->slow_keys_delay; 63505b261ecSmrg rep.debounceDelay = xkb->debounce_delay; 63605b261ecSmrg rep.mkDelay = xkb->mk_delay; 63705b261ecSmrg rep.mkInterval = xkb->mk_interval; 63805b261ecSmrg rep.mkTimeToMax = xkb->mk_time_to_max; 63905b261ecSmrg rep.mkMaxSpeed = xkb->mk_max_speed; 64005b261ecSmrg rep.mkCurve = xkb->mk_curve; 64105b261ecSmrg rep.mkDfltBtn = xkb->mk_dflt_btn; 64205b261ecSmrg rep.axTimeout = xkb->ax_timeout; 64305b261ecSmrg rep.axtCtrlsMask = xkb->axt_ctrls_mask; 64405b261ecSmrg rep.axtCtrlsValues = xkb->axt_ctrls_values; 64505b261ecSmrg rep.axtOptsMask = xkb->axt_opts_mask; 64605b261ecSmrg rep.axtOptsValues = xkb->axt_opts_values; 64705b261ecSmrg rep.axOptions = xkb->ax_options; 64805b261ecSmrg memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize); 64905b261ecSmrg if (client->swapped) { 65005b261ecSmrg swaps(&rep.sequenceNumber, n); 65105b261ecSmrg swapl(&rep.length,n); 65205b261ecSmrg swaps(&rep.internalVMods, n); 65305b261ecSmrg swaps(&rep.ignoreLockVMods, n); 65405b261ecSmrg swapl(&rep.enabledCtrls, n); 65505b261ecSmrg swaps(&rep.repeatDelay, n); 65605b261ecSmrg swaps(&rep.repeatInterval, n); 65705b261ecSmrg swaps(&rep.slowKeysDelay, n); 65805b261ecSmrg swaps(&rep.debounceDelay, n); 65905b261ecSmrg swaps(&rep.mkDelay, n); 66005b261ecSmrg swaps(&rep.mkInterval, n); 66105b261ecSmrg swaps(&rep.mkTimeToMax, n); 66205b261ecSmrg swaps(&rep.mkMaxSpeed, n); 66305b261ecSmrg swaps(&rep.mkCurve, n); 66405b261ecSmrg swaps(&rep.axTimeout, n); 66505b261ecSmrg swapl(&rep.axtCtrlsMask, n); 66605b261ecSmrg swapl(&rep.axtCtrlsValues, n); 66705b261ecSmrg swaps(&rep.axtOptsMask, n); 66805b261ecSmrg swaps(&rep.axtOptsValues, n); 66905b261ecSmrg swaps(&rep.axOptions, n); 67005b261ecSmrg } 67105b261ecSmrg WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep); 67205b261ecSmrg return(client->noClientException); 67305b261ecSmrg} 67405b261ecSmrg 67505b261ecSmrgint 67605b261ecSmrgProcXkbSetControls(ClientPtr client) 67705b261ecSmrg{ 67805b261ecSmrg DeviceIntPtr dev, tmpd; 67905b261ecSmrg XkbSrvInfoPtr xkbi; 68005b261ecSmrg XkbControlsPtr ctrl; 68105b261ecSmrg XkbControlsRec new,old; 68205b261ecSmrg xkbControlsNotify cn; 68305b261ecSmrg XkbEventCauseRec cause; 68405b261ecSmrg XkbSrvLedInfoPtr sli; 68505b261ecSmrg 68605b261ecSmrg REQUEST(xkbSetControlsReq); 68705b261ecSmrg REQUEST_SIZE_MATCH(xkbSetControlsReq); 68805b261ecSmrg 68905b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 69005b261ecSmrg return BadAccess; 69105b261ecSmrg 69205b261ecSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec); 69305b261ecSmrg CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask); 69405b261ecSmrg 69505b261ecSmrg for (tmpd = inputInfo.keyboard; tmpd; tmpd = tmpd->next) { 69605b261ecSmrg if ((dev == inputInfo.keyboard && tmpd->key && tmpd->coreEvents) || 69705b261ecSmrg tmpd == dev) { 69805b261ecSmrg 69905b261ecSmrg xkbi = tmpd->key->xkbInfo; 70005b261ecSmrg ctrl = xkbi->desc->ctrls; 70105b261ecSmrg new = *ctrl; 70205b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbSetControls, client); 70305b261ecSmrg 70405b261ecSmrg if (stuff->changeCtrls & XkbInternalModsMask) { 70505b261ecSmrg CHK_MASK_MATCH(0x02, stuff->affectInternalMods, 70605b261ecSmrg stuff->internalMods); 70705b261ecSmrg CHK_MASK_MATCH(0x03, stuff->affectInternalVMods, 70805b261ecSmrg stuff->internalVMods); 70905b261ecSmrg 71005b261ecSmrg new.internal.real_mods &= ~(stuff->affectInternalMods); 71105b261ecSmrg new.internal.real_mods |= (stuff->affectInternalMods & 71205b261ecSmrg stuff->internalMods); 71305b261ecSmrg new.internal.vmods &= ~(stuff->affectInternalVMods); 71405b261ecSmrg new.internal.vmods |= (stuff->affectInternalVMods & 71505b261ecSmrg stuff->internalVMods); 71605b261ecSmrg new.internal.mask = new.internal.real_mods | 71705b261ecSmrg XkbMaskForVMask(xkbi->desc, 71805b261ecSmrg new.internal.vmods); 71905b261ecSmrg } 72005b261ecSmrg 72105b261ecSmrg if (stuff->changeCtrls & XkbIgnoreLockModsMask) { 72205b261ecSmrg CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods, 72305b261ecSmrg stuff->ignoreLockMods); 72405b261ecSmrg CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods, 72505b261ecSmrg stuff->ignoreLockVMods); 72605b261ecSmrg 72705b261ecSmrg new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods); 72805b261ecSmrg new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods & 72905b261ecSmrg stuff->ignoreLockMods); 73005b261ecSmrg new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods); 73105b261ecSmrg new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods & 73205b261ecSmrg stuff->ignoreLockVMods); 73305b261ecSmrg new.ignore_lock.mask = new.ignore_lock.real_mods | 73405b261ecSmrg XkbMaskForVMask(xkbi->desc, 73505b261ecSmrg new.ignore_lock.vmods); 73605b261ecSmrg } 73705b261ecSmrg 73805b261ecSmrg CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls, 73905b261ecSmrg stuff->enabledCtrls); 74005b261ecSmrg if (stuff->affectEnabledCtrls) { 74105b261ecSmrg CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls, 74205b261ecSmrg XkbAllBooleanCtrlsMask); 74305b261ecSmrg 74405b261ecSmrg new.enabled_ctrls &= ~(stuff->affectEnabledCtrls); 74505b261ecSmrg new.enabled_ctrls |= (stuff->affectEnabledCtrls & 74605b261ecSmrg stuff->enabledCtrls); 74705b261ecSmrg } 74805b261ecSmrg 74905b261ecSmrg if (stuff->changeCtrls & XkbRepeatKeysMask) { 75005b261ecSmrg if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) { 75105b261ecSmrg client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay, 75205b261ecSmrg stuff->repeatInterval); 75305b261ecSmrg return BadValue; 75405b261ecSmrg } 75505b261ecSmrg 75605b261ecSmrg new.repeat_delay = stuff->repeatDelay; 75705b261ecSmrg new.repeat_interval = stuff->repeatInterval; 75805b261ecSmrg } 75905b261ecSmrg 76005b261ecSmrg if (stuff->changeCtrls & XkbSlowKeysMask) { 76105b261ecSmrg if (stuff->slowKeysDelay < 1) { 76205b261ecSmrg client->errorValue = _XkbErrCode2(0x09, 76305b261ecSmrg stuff->slowKeysDelay); 76405b261ecSmrg return BadValue; 76505b261ecSmrg } 76605b261ecSmrg 76705b261ecSmrg new.slow_keys_delay = stuff->slowKeysDelay; 76805b261ecSmrg } 76905b261ecSmrg 77005b261ecSmrg if (stuff->changeCtrls & XkbBounceKeysMask) { 77105b261ecSmrg if (stuff->debounceDelay < 1) { 77205b261ecSmrg client->errorValue = _XkbErrCode2(0x0A, 77305b261ecSmrg stuff->debounceDelay); 77405b261ecSmrg return BadValue; 77505b261ecSmrg } 77605b261ecSmrg 77705b261ecSmrg new.debounce_delay = stuff->debounceDelay; 77805b261ecSmrg } 77905b261ecSmrg 78005b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysMask) { 78105b261ecSmrg if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) { 78205b261ecSmrg client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn); 78305b261ecSmrg return BadValue; 78405b261ecSmrg } 78505b261ecSmrg 78605b261ecSmrg new.mk_dflt_btn = stuff->mkDfltBtn; 78705b261ecSmrg } 78805b261ecSmrg 78905b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysAccelMask) { 79005b261ecSmrg if (stuff->mkDelay < 1 || stuff->mkInterval < 1 || 79105b261ecSmrg stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 || 79205b261ecSmrg stuff->mkCurve < -1000) { 79305b261ecSmrg client->errorValue = _XkbErrCode2(0x0C,0); 79405b261ecSmrg return BadValue; 79505b261ecSmrg } 79605b261ecSmrg 79705b261ecSmrg new.mk_delay = stuff->mkDelay; 79805b261ecSmrg new.mk_interval = stuff->mkInterval; 79905b261ecSmrg new.mk_time_to_max = stuff->mkTimeToMax; 80005b261ecSmrg new.mk_max_speed = stuff->mkMaxSpeed; 80105b261ecSmrg new.mk_curve = stuff->mkCurve; 80205b261ecSmrg AccessXComputeCurveFactor(xkbi, &new); 80305b261ecSmrg } 80405b261ecSmrg 80505b261ecSmrg if (stuff->changeCtrls & XkbGroupsWrapMask) { 80605b261ecSmrg unsigned act, num; 80705b261ecSmrg 80805b261ecSmrg act = XkbOutOfRangeGroupAction(stuff->groupsWrap); 80905b261ecSmrg switch (act) { 81005b261ecSmrg case XkbRedirectIntoRange: 81105b261ecSmrg num = XkbOutOfRangeGroupNumber(stuff->groupsWrap); 81205b261ecSmrg if (num >= new.num_groups) { 81305b261ecSmrg client->errorValue = _XkbErrCode3(0x0D, new.num_groups, 81405b261ecSmrg num); 81505b261ecSmrg return BadValue; 81605b261ecSmrg } 81705b261ecSmrg case XkbWrapIntoRange: 81805b261ecSmrg case XkbClampIntoRange: 81905b261ecSmrg break; 82005b261ecSmrg default: 82105b261ecSmrg client->errorValue = _XkbErrCode2(0x0E, act); 82205b261ecSmrg return BadValue; 82305b261ecSmrg } 82405b261ecSmrg 82505b261ecSmrg new.groups_wrap= stuff->groupsWrap; 82605b261ecSmrg } 82705b261ecSmrg 82805b261ecSmrg CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask); 82905b261ecSmrg if (stuff->changeCtrls & XkbAccessXKeysMask) { 83005b261ecSmrg new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask; 83105b261ecSmrg } 83205b261ecSmrg else { 83305b261ecSmrg if (stuff->changeCtrls & XkbStickyKeysMask) { 83405b261ecSmrg new.ax_options &= ~(XkbAX_SKOptionsMask); 83505b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask); 83605b261ecSmrg } 83705b261ecSmrg 83805b261ecSmrg if (stuff->changeCtrls & XkbAccessXFeedbackMask) { 83905b261ecSmrg new.ax_options &= ~(XkbAX_FBOptionsMask); 84005b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask); 84105b261ecSmrg } 84205b261ecSmrg } 84305b261ecSmrg 84405b261ecSmrg if (stuff->changeCtrls & XkbAccessXTimeoutMask) { 84505b261ecSmrg if (stuff->axTimeout < 1) { 84605b261ecSmrg client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout); 84705b261ecSmrg return BadValue; 84805b261ecSmrg } 84905b261ecSmrg CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask, 85005b261ecSmrg stuff->axtCtrlsValues); 85105b261ecSmrg CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask, 85205b261ecSmrg XkbAllBooleanCtrlsMask); 85305b261ecSmrg CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues); 85405b261ecSmrg CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask); 85505b261ecSmrg new.ax_timeout = stuff->axTimeout; 85605b261ecSmrg new.axt_ctrls_mask = stuff->axtCtrlsMask; 85705b261ecSmrg new.axt_ctrls_values = (stuff->axtCtrlsValues & 85805b261ecSmrg stuff->axtCtrlsMask); 85905b261ecSmrg new.axt_opts_mask = stuff->axtOptsMask; 86005b261ecSmrg new.axt_opts_values = (stuff->axtOptsValues & 86105b261ecSmrg stuff->axtOptsMask); 86205b261ecSmrg } 86305b261ecSmrg 86405b261ecSmrg if (stuff->changeCtrls & XkbPerKeyRepeatMask) 86505b261ecSmrg memcpy(new.per_key_repeat, stuff->perKeyRepeat, 86605b261ecSmrg XkbPerKeyBitArraySize); 86705b261ecSmrg 86805b261ecSmrg old= *ctrl; 86905b261ecSmrg *ctrl= new; 87005b261ecSmrg XkbDDXChangeControls(tmpd, &old, ctrl); 87105b261ecSmrg 87205b261ecSmrg if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, False)) { 87305b261ecSmrg cn.keycode = 0; 87405b261ecSmrg cn.eventType = 0; 87505b261ecSmrg cn.requestMajor = XkbReqCode; 87605b261ecSmrg cn.requestMinor = X_kbSetControls; 87705b261ecSmrg XkbSendControlsNotify(tmpd, &cn); 87805b261ecSmrg } 87905b261ecSmrg 88005b261ecSmrg sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); 88105b261ecSmrg if (sli) 88205b261ecSmrg XkbUpdateIndicators(tmpd, sli->usesControls, True, NULL, 88305b261ecSmrg &cause); 88405b261ecSmrg 88505b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 88605b261ecSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 88705b261ecSmrg !(ctrl->enabled_ctrls & XkbStickyKeysMask)) 88805b261ecSmrg XkbClearAllLatchesAndLocks(tmpd, xkbi, True, &cause); 88905b261ecSmrg } 89005b261ecSmrg } 89105b261ecSmrg 89205b261ecSmrg return client->noClientException; 89305b261ecSmrg} 89405b261ecSmrg 89505b261ecSmrg/***====================================================================***/ 89605b261ecSmrg 89705b261ecSmrgstatic int 89805b261ecSmrgXkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep) 89905b261ecSmrg{ 90005b261ecSmrg XkbKeyTypeRec *type; 90105b261ecSmrg unsigned i,len; 90205b261ecSmrg 90305b261ecSmrg len= 0; 90405b261ecSmrg if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)|| 90505b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->types)) { 90605b261ecSmrg rep->present&= ~XkbKeyTypesMask; 90705b261ecSmrg rep->firstType= rep->nTypes= 0; 90805b261ecSmrg return 0; 90905b261ecSmrg } 91005b261ecSmrg type= &xkb->map->types[rep->firstType]; 91105b261ecSmrg for (i=0;i<rep->nTypes;i++,type++){ 91205b261ecSmrg len+= SIZEOF(xkbKeyTypeWireDesc); 91305b261ecSmrg if (type->map_count>0) { 91405b261ecSmrg len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc)); 91505b261ecSmrg if (type->preserve) 91605b261ecSmrg len+= (type->map_count*SIZEOF(xkbModsWireDesc)); 91705b261ecSmrg } 91805b261ecSmrg } 91905b261ecSmrg return len; 92005b261ecSmrg} 92105b261ecSmrg 92205b261ecSmrgstatic char * 92305b261ecSmrgXkbWriteKeyTypes( XkbDescPtr xkb, 92405b261ecSmrg xkbGetMapReply * rep, 92505b261ecSmrg char * buf, 92605b261ecSmrg ClientPtr client) 92705b261ecSmrg{ 92805b261ecSmrg XkbKeyTypePtr type; 92905b261ecSmrg unsigned i; 93005b261ecSmrg xkbKeyTypeWireDesc *wire; 93105b261ecSmrg 93205b261ecSmrg type= &xkb->map->types[rep->firstType]; 93305b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 93405b261ecSmrg register unsigned n; 93505b261ecSmrg wire= (xkbKeyTypeWireDesc *)buf; 93605b261ecSmrg wire->mask = type->mods.mask; 93705b261ecSmrg wire->realMods = type->mods.real_mods; 93805b261ecSmrg wire->virtualMods = type->mods.vmods; 93905b261ecSmrg wire->numLevels = type->num_levels; 94005b261ecSmrg wire->nMapEntries = type->map_count; 94105b261ecSmrg wire->preserve = (type->preserve!=NULL); 94205b261ecSmrg if (client->swapped) { 94305b261ecSmrg register int n; 94405b261ecSmrg swaps(&wire->virtualMods,n); 94505b261ecSmrg } 94605b261ecSmrg 94705b261ecSmrg buf= (char *)&wire[1]; 94805b261ecSmrg if (wire->nMapEntries>0) { 94905b261ecSmrg xkbKTMapEntryWireDesc * wire; 95005b261ecSmrg XkbKTMapEntryPtr entry; 95105b261ecSmrg wire= (xkbKTMapEntryWireDesc *)buf; 95205b261ecSmrg entry= type->map; 95305b261ecSmrg for (n=0;n<type->map_count;n++,wire++,entry++) { 95405b261ecSmrg wire->active= entry->active; 95505b261ecSmrg wire->mask= entry->mods.mask; 95605b261ecSmrg wire->level= entry->level; 95705b261ecSmrg wire->realMods= entry->mods.real_mods; 95805b261ecSmrg wire->virtualMods= entry->mods.vmods; 95905b261ecSmrg if (client->swapped) { 96005b261ecSmrg register int n; 96105b261ecSmrg swaps(&wire->virtualMods,n); 96205b261ecSmrg } 96305b261ecSmrg } 96405b261ecSmrg buf= (char *)wire; 96505b261ecSmrg if (type->preserve!=NULL) { 96605b261ecSmrg xkbModsWireDesc * pwire; 96705b261ecSmrg XkbModsPtr preserve; 96805b261ecSmrg pwire= (xkbModsWireDesc *)buf; 96905b261ecSmrg preserve= type->preserve; 97005b261ecSmrg for (n=0;n<type->map_count;n++,pwire++,preserve++) { 97105b261ecSmrg pwire->mask= preserve->mask; 97205b261ecSmrg pwire->realMods= preserve->real_mods; 97305b261ecSmrg pwire->virtualMods= preserve->vmods; 97405b261ecSmrg if (client->swapped) { 97505b261ecSmrg register int n; 97605b261ecSmrg swaps(&pwire->virtualMods,n); 97705b261ecSmrg } 97805b261ecSmrg } 97905b261ecSmrg buf= (char *)pwire; 98005b261ecSmrg } 98105b261ecSmrg } 98205b261ecSmrg } 98305b261ecSmrg return buf; 98405b261ecSmrg} 98505b261ecSmrg 98605b261ecSmrgstatic int 98705b261ecSmrgXkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep) 98805b261ecSmrg{ 98905b261ecSmrg XkbSymMapPtr symMap; 99005b261ecSmrg unsigned i,len; 99105b261ecSmrg unsigned nSyms,nSymsThisKey; 99205b261ecSmrg 99305b261ecSmrg if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)|| 99405b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) { 99505b261ecSmrg rep->present&= ~XkbKeySymsMask; 99605b261ecSmrg rep->firstKeySym= rep->nKeySyms= 0; 99705b261ecSmrg rep->totalSyms= 0; 99805b261ecSmrg return 0; 99905b261ecSmrg } 100005b261ecSmrg len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc); 100105b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 100205b261ecSmrg for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) { 100305b261ecSmrg if (symMap->offset!=0) { 100405b261ecSmrg nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width; 100505b261ecSmrg nSyms+= nSymsThisKey; 100605b261ecSmrg } 100705b261ecSmrg } 100805b261ecSmrg len+= nSyms*4; 100905b261ecSmrg rep->totalSyms= nSyms; 101005b261ecSmrg return len; 101105b261ecSmrg} 101205b261ecSmrg 101305b261ecSmrgstatic int 101405b261ecSmrgXkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep) 101505b261ecSmrg{ 101605b261ecSmrgregister unsigned i,nMods,bit; 101705b261ecSmrg 101805b261ecSmrg if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)|| 101905b261ecSmrg (!xkb)||(!xkb->server)) { 102005b261ecSmrg rep->present&= ~XkbVirtualModsMask; 102105b261ecSmrg rep->virtualMods= 0; 102205b261ecSmrg return 0; 102305b261ecSmrg } 102405b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 102505b261ecSmrg if (rep->virtualMods&bit) 102605b261ecSmrg nMods++; 102705b261ecSmrg } 102805b261ecSmrg return XkbPaddedSize(nMods); 102905b261ecSmrg} 103005b261ecSmrg 103105b261ecSmrgstatic char * 103205b261ecSmrgXkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 103305b261ecSmrg{ 103405b261ecSmrgregister KeySym * pSym; 103505b261ecSmrgXkbSymMapPtr symMap; 103605b261ecSmrgxkbSymMapWireDesc * outMap; 103705b261ecSmrgregister unsigned i; 103805b261ecSmrg 103905b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 104005b261ecSmrg for (i=0;i<rep->nKeySyms;i++,symMap++) { 104105b261ecSmrg outMap = (xkbSymMapWireDesc *)buf; 104205b261ecSmrg outMap->ktIndex[0] = symMap->kt_index[0]; 104305b261ecSmrg outMap->ktIndex[1] = symMap->kt_index[1]; 104405b261ecSmrg outMap->ktIndex[2] = symMap->kt_index[2]; 104505b261ecSmrg outMap->ktIndex[3] = symMap->kt_index[3]; 104605b261ecSmrg outMap->groupInfo = symMap->group_info; 104705b261ecSmrg outMap->width= symMap->width; 104805b261ecSmrg outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info); 104905b261ecSmrg buf= (char *)&outMap[1]; 105005b261ecSmrg if (outMap->nSyms==0) 105105b261ecSmrg continue; 105205b261ecSmrg 105305b261ecSmrg pSym = &xkb->map->syms[symMap->offset]; 105405b261ecSmrg memcpy((char *)buf,(char *)pSym,outMap->nSyms*4); 105505b261ecSmrg if (client->swapped) { 105605b261ecSmrg register int n,nSyms= outMap->nSyms; 105705b261ecSmrg swaps(&outMap->nSyms,n); 105805b261ecSmrg while (nSyms-->0) { 105905b261ecSmrg swapl(buf,n); 106005b261ecSmrg buf+= 4; 106105b261ecSmrg } 106205b261ecSmrg } 106305b261ecSmrg else buf+= outMap->nSyms*4; 106405b261ecSmrg } 106505b261ecSmrg return buf; 106605b261ecSmrg} 106705b261ecSmrg 106805b261ecSmrgstatic int 106905b261ecSmrgXkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep) 107005b261ecSmrg{ 107105b261ecSmrg unsigned i,len,nActs; 107205b261ecSmrg register KeyCode firstKey; 107305b261ecSmrg 107405b261ecSmrg if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)|| 107505b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) { 107605b261ecSmrg rep->present&= ~XkbKeyActionsMask; 107705b261ecSmrg rep->firstKeyAct= rep->nKeyActs= 0; 107805b261ecSmrg rep->totalActs= 0; 107905b261ecSmrg return 0; 108005b261ecSmrg } 108105b261ecSmrg firstKey= rep->firstKeyAct; 108205b261ecSmrg for (nActs=i=0;i<rep->nKeyActs;i++) { 108305b261ecSmrg if (xkb->server->key_acts[i+firstKey]!=0) 108405b261ecSmrg nActs+= XkbKeyNumActions(xkb,i+firstKey); 108505b261ecSmrg } 108605b261ecSmrg len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); 108705b261ecSmrg rep->totalActs= nActs; 108805b261ecSmrg return len; 108905b261ecSmrg} 109005b261ecSmrg 109105b261ecSmrgstatic char * 109205b261ecSmrgXkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 109305b261ecSmrg ClientPtr client) 109405b261ecSmrg{ 109505b261ecSmrg unsigned i; 109605b261ecSmrg CARD8 * numDesc; 109705b261ecSmrg XkbAnyAction * actDesc; 109805b261ecSmrg 109905b261ecSmrg numDesc = (CARD8 *)buf; 110005b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 110105b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]==0) 110205b261ecSmrg numDesc[i] = 0; 110305b261ecSmrg else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 110405b261ecSmrg } 110505b261ecSmrg buf+= XkbPaddedSize(rep->nKeyActs); 110605b261ecSmrg 110705b261ecSmrg actDesc = (XkbAnyAction *)buf; 110805b261ecSmrg for (i=0;i<rep->nKeyActs;i++) { 110905b261ecSmrg if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) { 111005b261ecSmrg unsigned int num; 111105b261ecSmrg num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); 111205b261ecSmrg memcpy((char *)actDesc, 111305b261ecSmrg (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)), 111405b261ecSmrg num*SIZEOF(xkbActionWireDesc)); 111505b261ecSmrg actDesc+= num; 111605b261ecSmrg } 111705b261ecSmrg } 111805b261ecSmrg buf = (char *)actDesc; 111905b261ecSmrg return buf; 112005b261ecSmrg} 112105b261ecSmrg 112205b261ecSmrgstatic int 112305b261ecSmrgXkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep) 112405b261ecSmrg{ 112505b261ecSmrg unsigned i,len,nBhvr; 112605b261ecSmrg XkbBehavior * bhv; 112705b261ecSmrg 112805b261ecSmrg if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)|| 112905b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) { 113005b261ecSmrg rep->present&= ~XkbKeyBehaviorsMask; 113105b261ecSmrg rep->firstKeyBehavior= rep->nKeyBehaviors= 0; 113205b261ecSmrg rep->totalKeyBehaviors= 0; 113305b261ecSmrg return 0; 113405b261ecSmrg } 113505b261ecSmrg bhv= &xkb->server->behaviors[rep->firstKeyBehavior]; 113605b261ecSmrg for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) { 113705b261ecSmrg if (bhv->type!=XkbKB_Default) 113805b261ecSmrg nBhvr++; 113905b261ecSmrg } 114005b261ecSmrg len= nBhvr*SIZEOF(xkbBehaviorWireDesc); 114105b261ecSmrg rep->totalKeyBehaviors= nBhvr; 114205b261ecSmrg return len; 114305b261ecSmrg} 114405b261ecSmrg 114505b261ecSmrgstatic char * 114605b261ecSmrgXkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 114705b261ecSmrg ClientPtr client) 114805b261ecSmrg{ 114905b261ecSmrg unsigned i; 115005b261ecSmrg xkbBehaviorWireDesc *wire; 115105b261ecSmrg XkbBehavior *pBhvr; 115205b261ecSmrg 115305b261ecSmrg wire = (xkbBehaviorWireDesc *)buf; 115405b261ecSmrg pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior]; 115505b261ecSmrg for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) { 115605b261ecSmrg if (pBhvr->type!=XkbKB_Default) { 115705b261ecSmrg wire->key= i+rep->firstKeyBehavior; 115805b261ecSmrg wire->type= pBhvr->type; 115905b261ecSmrg wire->data= pBhvr->data; 116005b261ecSmrg wire++; 116105b261ecSmrg } 116205b261ecSmrg } 116305b261ecSmrg buf = (char *)wire; 116405b261ecSmrg return buf; 116505b261ecSmrg} 116605b261ecSmrg 116705b261ecSmrgstatic int 116805b261ecSmrgXkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep) 116905b261ecSmrg{ 117005b261ecSmrg unsigned i,len,nRtrn; 117105b261ecSmrg 117205b261ecSmrg if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)|| 117305b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->explicit)) { 117405b261ecSmrg rep->present&= ~XkbExplicitComponentsMask; 117505b261ecSmrg rep->firstKeyExplicit= rep->nKeyExplicit= 0; 117605b261ecSmrg rep->totalKeyExplicit= 0; 117705b261ecSmrg return 0; 117805b261ecSmrg } 117905b261ecSmrg for (nRtrn=i=0;i<rep->nKeyExplicit;i++) { 118005b261ecSmrg if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0) 118105b261ecSmrg nRtrn++; 118205b261ecSmrg } 118305b261ecSmrg rep->totalKeyExplicit= nRtrn; 118405b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */ 118505b261ecSmrg return len; 118605b261ecSmrg} 118705b261ecSmrg 118805b261ecSmrgstatic char * 118905b261ecSmrgXkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) 119005b261ecSmrg{ 119105b261ecSmrgunsigned i; 119205b261ecSmrgchar * start; 119305b261ecSmrgunsigned char * pExp; 119405b261ecSmrg 119505b261ecSmrg start= buf; 119605b261ecSmrg pExp= &xkb->server->explicit[rep->firstKeyExplicit]; 119705b261ecSmrg for (i=0;i<rep->nKeyExplicit;i++,pExp++) { 119805b261ecSmrg if (*pExp!=0) { 119905b261ecSmrg *buf++= i+rep->firstKeyExplicit; 120005b261ecSmrg *buf++= *pExp; 120105b261ecSmrg } 120205b261ecSmrg } 120305b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 120405b261ecSmrg return buf+i; 120505b261ecSmrg} 120605b261ecSmrg 120705b261ecSmrgstatic int 120805b261ecSmrgXkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep) 120905b261ecSmrg{ 121005b261ecSmrg unsigned i,len,nRtrn; 121105b261ecSmrg 121205b261ecSmrg if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)|| 121305b261ecSmrg (!xkb)||(!xkb->map)||(!xkb->map->modmap)) { 121405b261ecSmrg rep->present&= ~XkbModifierMapMask; 121505b261ecSmrg rep->firstModMapKey= rep->nModMapKeys= 0; 121605b261ecSmrg rep->totalModMapKeys= 0; 121705b261ecSmrg return 0; 121805b261ecSmrg } 121905b261ecSmrg for (nRtrn=i=0;i<rep->nModMapKeys;i++) { 122005b261ecSmrg if (xkb->map->modmap[i+rep->firstModMapKey]!=0) 122105b261ecSmrg nRtrn++; 122205b261ecSmrg } 122305b261ecSmrg rep->totalModMapKeys= nRtrn; 122405b261ecSmrg len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */ 122505b261ecSmrg return len; 122605b261ecSmrg} 122705b261ecSmrg 122805b261ecSmrgstatic char * 122905b261ecSmrgXkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 123005b261ecSmrg ClientPtr client) 123105b261ecSmrg{ 123205b261ecSmrgunsigned i; 123305b261ecSmrgchar * start; 123405b261ecSmrgunsigned char * pMap; 123505b261ecSmrg 123605b261ecSmrg start= buf; 123705b261ecSmrg pMap= &xkb->map->modmap[rep->firstModMapKey]; 123805b261ecSmrg for (i=0;i<rep->nModMapKeys;i++,pMap++) { 123905b261ecSmrg if (*pMap!=0) { 124005b261ecSmrg *buf++= i+rep->firstModMapKey; 124105b261ecSmrg *buf++= *pMap; 124205b261ecSmrg } 124305b261ecSmrg } 124405b261ecSmrg i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ 124505b261ecSmrg return buf+i; 124605b261ecSmrg} 124705b261ecSmrg 124805b261ecSmrgstatic int 124905b261ecSmrgXkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep) 125005b261ecSmrg{ 125105b261ecSmrg unsigned i,len,nRtrn; 125205b261ecSmrg 125305b261ecSmrg if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)|| 125405b261ecSmrg (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) { 125505b261ecSmrg rep->present&= ~XkbVirtualModMapMask; 125605b261ecSmrg rep->firstVModMapKey= rep->nVModMapKeys= 0; 125705b261ecSmrg rep->totalVModMapKeys= 0; 125805b261ecSmrg return 0; 125905b261ecSmrg } 126005b261ecSmrg for (nRtrn=i=0;i<rep->nVModMapKeys-1;i++) { 126105b261ecSmrg if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0) 126205b261ecSmrg nRtrn++; 126305b261ecSmrg } 126405b261ecSmrg rep->totalVModMapKeys= nRtrn; 126505b261ecSmrg len= nRtrn*SIZEOF(xkbVModMapWireDesc); 126605b261ecSmrg return len; 126705b261ecSmrg} 126805b261ecSmrg 126905b261ecSmrgstatic char * 127005b261ecSmrgXkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, 127105b261ecSmrg ClientPtr client) 127205b261ecSmrg{ 127305b261ecSmrgunsigned i; 127405b261ecSmrgxkbVModMapWireDesc * wire; 127505b261ecSmrgunsigned short * pMap; 127605b261ecSmrg 127705b261ecSmrg wire= (xkbVModMapWireDesc *)buf; 127805b261ecSmrg pMap= &xkb->server->vmodmap[rep->firstVModMapKey]; 127905b261ecSmrg for (i=0;i<rep->nVModMapKeys-1;i++,pMap++) { 128005b261ecSmrg if (*pMap!=0) { 128105b261ecSmrg wire->key= i+rep->firstVModMapKey; 128205b261ecSmrg wire->vmods= *pMap; 128305b261ecSmrg wire++; 128405b261ecSmrg } 128505b261ecSmrg } 128605b261ecSmrg return (char *)wire; 128705b261ecSmrg} 128805b261ecSmrg 128905b261ecSmrgstatic Status 129005b261ecSmrgXkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep) 129105b261ecSmrg{ 129205b261ecSmrgint len; 129305b261ecSmrg 129405b261ecSmrg rep->minKeyCode= xkb->min_key_code; 129505b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 129605b261ecSmrg len= XkbSizeKeyTypes(xkb,rep); 129705b261ecSmrg len+= XkbSizeKeySyms(xkb,rep); 129805b261ecSmrg len+= XkbSizeKeyActions(xkb,rep); 129905b261ecSmrg len+= XkbSizeKeyBehaviors(xkb,rep); 130005b261ecSmrg len+= XkbSizeVirtualMods(xkb,rep); 130105b261ecSmrg len+= XkbSizeExplicit(xkb,rep); 130205b261ecSmrg len+= XkbSizeModifierMap(xkb,rep); 130305b261ecSmrg len+= XkbSizeVirtualModMap(xkb,rep); 130405b261ecSmrg rep->length+= (len/4); 130505b261ecSmrg return Success; 130605b261ecSmrg} 130705b261ecSmrg 130805b261ecSmrgstatic int 130905b261ecSmrgXkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep) 131005b261ecSmrg{ 131105b261ecSmrgunsigned i,len; 131205b261ecSmrgchar *desc,*start; 131305b261ecSmrg 131405b261ecSmrg len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)); 131505b261ecSmrg start= desc= (char *)ALLOCATE_LOCAL(len); 131605b261ecSmrg if (!start) 131705b261ecSmrg return BadAlloc; 131805b261ecSmrg if ( rep->nTypes>0 ) 131905b261ecSmrg desc = XkbWriteKeyTypes(xkb,rep,desc,client); 132005b261ecSmrg if ( rep->nKeySyms>0 ) 132105b261ecSmrg desc = XkbWriteKeySyms(xkb,rep,desc,client); 132205b261ecSmrg if ( rep->nKeyActs>0 ) 132305b261ecSmrg desc = XkbWriteKeyActions(xkb,rep,desc,client); 132405b261ecSmrg if ( rep->totalKeyBehaviors>0 ) 132505b261ecSmrg desc = XkbWriteKeyBehaviors(xkb,rep,desc,client); 132605b261ecSmrg if ( rep->virtualMods ) { 132705b261ecSmrg register int sz,bit; 132805b261ecSmrg for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 132905b261ecSmrg if (rep->virtualMods&bit) { 133005b261ecSmrg desc[sz++]= xkb->server->vmods[i]; 133105b261ecSmrg } 133205b261ecSmrg } 133305b261ecSmrg desc+= XkbPaddedSize(sz); 133405b261ecSmrg } 133505b261ecSmrg if ( rep->totalKeyExplicit>0 ) 133605b261ecSmrg desc= XkbWriteExplicit(xkb,rep,desc,client); 133705b261ecSmrg if ( rep->totalModMapKeys>0 ) 133805b261ecSmrg desc= XkbWriteModifierMap(xkb,rep,desc,client); 133905b261ecSmrg if ( rep->totalVModMapKeys>0 ) 134005b261ecSmrg desc= XkbWriteVirtualModMap(xkb,rep,desc,client); 134105b261ecSmrg if ((desc-start)!=(len)) { 134205b261ecSmrg ErrorF("BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", 134305b261ecSmrg len, (unsigned long)(desc-start)); 134405b261ecSmrg } 134505b261ecSmrg if (client->swapped) { 134605b261ecSmrg register int n; 134705b261ecSmrg swaps(&rep->sequenceNumber,n); 134805b261ecSmrg swapl(&rep->length,n); 134905b261ecSmrg swaps(&rep->present,n); 135005b261ecSmrg swaps(&rep->totalSyms,n); 135105b261ecSmrg swaps(&rep->totalActs,n); 135205b261ecSmrg } 135305b261ecSmrg WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep); 135405b261ecSmrg WriteToClient(client, len, start); 135505b261ecSmrg DEALLOCATE_LOCAL((char *)start); 135605b261ecSmrg return client->noClientException; 135705b261ecSmrg} 135805b261ecSmrg 135905b261ecSmrgint 136005b261ecSmrgProcXkbGetMap(ClientPtr client) 136105b261ecSmrg{ 136205b261ecSmrg DeviceIntPtr dev; 136305b261ecSmrg xkbGetMapReply rep; 136405b261ecSmrg XkbDescRec *xkb; 136505b261ecSmrg int n,status; 136605b261ecSmrg 136705b261ecSmrg REQUEST(xkbGetMapReq); 136805b261ecSmrg REQUEST_SIZE_MATCH(xkbGetMapReq); 136905b261ecSmrg 137005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 137105b261ecSmrg return BadAccess; 137205b261ecSmrg 137305b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 137405b261ecSmrg CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial); 137505b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask); 137605b261ecSmrg CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask); 137705b261ecSmrg 137805b261ecSmrg xkb= dev->key->xkbInfo->desc; 137905b261ecSmrg bzero(&rep,sizeof(xkbGetMapReply)); 138005b261ecSmrg rep.type= X_Reply; 138105b261ecSmrg rep.sequenceNumber= client->sequence; 138205b261ecSmrg rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2; 138305b261ecSmrg rep.deviceID = dev->id; 138405b261ecSmrg rep.present = stuff->partial|stuff->full; 138505b261ecSmrg rep.minKeyCode = xkb->min_key_code; 138605b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 138705b261ecSmrg if ( stuff->full&XkbKeyTypesMask ) { 138805b261ecSmrg rep.firstType = 0; 138905b261ecSmrg rep.nTypes = xkb->map->num_types; 139005b261ecSmrg } 139105b261ecSmrg else if (stuff->partial&XkbKeyTypesMask) { 139205b261ecSmrg if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) { 139305b261ecSmrg client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types, 139405b261ecSmrg stuff->firstType,stuff->nTypes); 139505b261ecSmrg return BadValue; 139605b261ecSmrg } 139705b261ecSmrg rep.firstType = stuff->firstType; 139805b261ecSmrg rep.nTypes = stuff->nTypes; 139905b261ecSmrg } 140005b261ecSmrg else rep.nTypes = 0; 140105b261ecSmrg rep.totalTypes = xkb->map->num_types; 140205b261ecSmrg 140305b261ecSmrg n= XkbNumKeys(xkb); 140405b261ecSmrg if ( stuff->full&XkbKeySymsMask ) { 140505b261ecSmrg rep.firstKeySym = xkb->min_key_code; 140605b261ecSmrg rep.nKeySyms = n; 140705b261ecSmrg } 140805b261ecSmrg else if (stuff->partial&XkbKeySymsMask) { 140905b261ecSmrg CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb); 141005b261ecSmrg rep.firstKeySym = stuff->firstKeySym; 141105b261ecSmrg rep.nKeySyms = stuff->nKeySyms; 141205b261ecSmrg } 141305b261ecSmrg else rep.nKeySyms = 0; 141405b261ecSmrg rep.totalSyms= 0; 141505b261ecSmrg 141605b261ecSmrg if ( stuff->full&XkbKeyActionsMask ) { 141705b261ecSmrg rep.firstKeyAct= xkb->min_key_code; 141805b261ecSmrg rep.nKeyActs= n; 141905b261ecSmrg } 142005b261ecSmrg else if (stuff->partial&XkbKeyActionsMask) { 142105b261ecSmrg CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb); 142205b261ecSmrg rep.firstKeyAct= stuff->firstKeyAct; 142305b261ecSmrg rep.nKeyActs= stuff->nKeyActs; 142405b261ecSmrg } 142505b261ecSmrg else rep.nKeyActs= 0; 142605b261ecSmrg rep.totalActs= 0; 142705b261ecSmrg 142805b261ecSmrg if ( stuff->full&XkbKeyBehaviorsMask ) { 142905b261ecSmrg rep.firstKeyBehavior = xkb->min_key_code; 143005b261ecSmrg rep.nKeyBehaviors = n; 143105b261ecSmrg } 143205b261ecSmrg else if (stuff->partial&XkbKeyBehaviorsMask) { 143305b261ecSmrg CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb); 143405b261ecSmrg rep.firstKeyBehavior= stuff->firstKeyBehavior; 143505b261ecSmrg rep.nKeyBehaviors= stuff->nKeyBehaviors; 143605b261ecSmrg } 143705b261ecSmrg else rep.nKeyBehaviors = 0; 143805b261ecSmrg rep.totalKeyBehaviors= 0; 143905b261ecSmrg 144005b261ecSmrg if (stuff->full&XkbVirtualModsMask) 144105b261ecSmrg rep.virtualMods= ~0; 144205b261ecSmrg else if (stuff->partial&XkbVirtualModsMask) 144305b261ecSmrg rep.virtualMods= stuff->virtualMods; 144405b261ecSmrg 144505b261ecSmrg if (stuff->full&XkbExplicitComponentsMask) { 144605b261ecSmrg rep.firstKeyExplicit= xkb->min_key_code; 144705b261ecSmrg rep.nKeyExplicit= n; 144805b261ecSmrg } 144905b261ecSmrg else if (stuff->partial&XkbExplicitComponentsMask) { 145005b261ecSmrg CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb); 145105b261ecSmrg rep.firstKeyExplicit= stuff->firstKeyExplicit; 145205b261ecSmrg rep.nKeyExplicit= stuff->nKeyExplicit; 145305b261ecSmrg } 145405b261ecSmrg else rep.nKeyExplicit = 0; 145505b261ecSmrg rep.totalKeyExplicit= 0; 145605b261ecSmrg 145705b261ecSmrg if (stuff->full&XkbModifierMapMask) { 145805b261ecSmrg rep.firstModMapKey= xkb->min_key_code; 145905b261ecSmrg rep.nModMapKeys= n; 146005b261ecSmrg } 146105b261ecSmrg else if (stuff->partial&XkbModifierMapMask) { 146205b261ecSmrg CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb); 146305b261ecSmrg rep.firstModMapKey= stuff->firstModMapKey; 146405b261ecSmrg rep.nModMapKeys= stuff->nModMapKeys; 146505b261ecSmrg } 146605b261ecSmrg else rep.nModMapKeys = 0; 146705b261ecSmrg rep.totalModMapKeys= 0; 146805b261ecSmrg 146905b261ecSmrg if (stuff->full&XkbVirtualModMapMask) { 147005b261ecSmrg rep.firstVModMapKey= xkb->min_key_code; 147105b261ecSmrg rep.nVModMapKeys= n; 147205b261ecSmrg } 147305b261ecSmrg else if (stuff->partial&XkbVirtualModMapMask) { 147405b261ecSmrg CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb); 147505b261ecSmrg rep.firstVModMapKey= stuff->firstVModMapKey; 147605b261ecSmrg rep.nVModMapKeys= stuff->nVModMapKeys; 147705b261ecSmrg } 147805b261ecSmrg else rep.nVModMapKeys = 0; 147905b261ecSmrg rep.totalVModMapKeys= 0; 148005b261ecSmrg 148105b261ecSmrg if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success) 148205b261ecSmrg return status; 148305b261ecSmrg return XkbSendMap(client,xkb,&rep); 148405b261ecSmrg} 148505b261ecSmrg 148605b261ecSmrg/***====================================================================***/ 148705b261ecSmrg 148805b261ecSmrgstatic int 148905b261ecSmrgCheckKeyTypes( ClientPtr client, 149005b261ecSmrg XkbDescPtr xkb, 149105b261ecSmrg xkbSetMapReq * req, 149205b261ecSmrg xkbKeyTypeWireDesc **wireRtrn, 149305b261ecSmrg int * nMapsRtrn, 149405b261ecSmrg CARD8 * mapWidthRtrn) 149505b261ecSmrg{ 149605b261ecSmrgunsigned nMaps; 149705b261ecSmrgregister unsigned i,n; 149805b261ecSmrgregister CARD8 * map; 149905b261ecSmrgregister xkbKeyTypeWireDesc *wire = *wireRtrn; 150005b261ecSmrg 150105b261ecSmrg if (req->firstType>((unsigned)xkb->map->num_types)) { 150205b261ecSmrg *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types); 150305b261ecSmrg return 0; 150405b261ecSmrg } 150505b261ecSmrg if (req->flags&XkbSetMapResizeTypes) { 150605b261ecSmrg nMaps = req->firstType+req->nTypes; 150705b261ecSmrg if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */ 150805b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4); 150905b261ecSmrg return 0; 151005b261ecSmrg } 151105b261ecSmrg } 151205b261ecSmrg else if (req->present&XkbKeyTypesMask) { 151305b261ecSmrg nMaps = xkb->map->num_types; 151405b261ecSmrg if ((req->firstType+req->nTypes)>nMaps) { 151505b261ecSmrg *nMapsRtrn = req->firstType+req->nTypes; 151605b261ecSmrg return 0; 151705b261ecSmrg } 151805b261ecSmrg } 151905b261ecSmrg else { 152005b261ecSmrg *nMapsRtrn = xkb->map->num_types; 152105b261ecSmrg for (i=0;i<xkb->map->num_types;i++) { 152205b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 152305b261ecSmrg } 152405b261ecSmrg return 1; 152505b261ecSmrg } 152605b261ecSmrg 152705b261ecSmrg for (i=0;i<req->firstType;i++) { 152805b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 152905b261ecSmrg } 153005b261ecSmrg for (i=0;i<req->nTypes;i++) { 153105b261ecSmrg unsigned width; 153205b261ecSmrg if (client->swapped) { 153305b261ecSmrg register int s; 153405b261ecSmrg swaps(&wire->virtualMods,s); 153505b261ecSmrg } 153605b261ecSmrg n= i+req->firstType; 153705b261ecSmrg width= wire->numLevels; 153805b261ecSmrg if (width<1) { 153905b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x04,n,width); 154005b261ecSmrg return 0; 154105b261ecSmrg } 154205b261ecSmrg else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */ 154305b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 154405b261ecSmrg return 0; 154505b261ecSmrg } 154605b261ecSmrg else if ((width!=2)&& 154705b261ecSmrg ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)|| 154805b261ecSmrg (n==XkbAlphabeticIndex))) { 154905b261ecSmrg /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ 155005b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x05,n,width); 155105b261ecSmrg return 0; 155205b261ecSmrg } 155305b261ecSmrg if (wire->nMapEntries>0) { 155405b261ecSmrg xkbKTSetMapEntryWireDesc * mapWire; 155505b261ecSmrg xkbModsWireDesc * preWire; 155605b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1]; 155705b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 155805b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 155905b261ecSmrg if (client->swapped) { 156005b261ecSmrg register int s; 156105b261ecSmrg swaps(&mapWire[n].virtualMods,s); 156205b261ecSmrg } 156305b261ecSmrg if (mapWire[n].realMods&(~wire->realMods)) { 156405b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods, 156505b261ecSmrg wire->realMods); 156605b261ecSmrg return 0; 156705b261ecSmrg } 156805b261ecSmrg if (mapWire[n].virtualMods&(~wire->virtualMods)) { 156905b261ecSmrg *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods); 157005b261ecSmrg return 0; 157105b261ecSmrg } 157205b261ecSmrg if (mapWire[n].level>=wire->numLevels) { 157305b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels, 157405b261ecSmrg mapWire[n].level); 157505b261ecSmrg return 0; 157605b261ecSmrg } 157705b261ecSmrg if (wire->preserve) { 157805b261ecSmrg if (client->swapped) { 157905b261ecSmrg register int s; 158005b261ecSmrg swaps(&preWire[n].virtualMods,s); 158105b261ecSmrg } 158205b261ecSmrg if (preWire[n].realMods&(~mapWire[n].realMods)) { 158305b261ecSmrg *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods, 158405b261ecSmrg mapWire[n].realMods); 158505b261ecSmrg return 0; 158605b261ecSmrg } 158705b261ecSmrg if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) { 158805b261ecSmrg *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods); 158905b261ecSmrg return 0; 159005b261ecSmrg } 159105b261ecSmrg } 159205b261ecSmrg } 159305b261ecSmrg if (wire->preserve) 159405b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 159505b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 159605b261ecSmrg } 159705b261ecSmrg else map= (CARD8 *)&wire[1]; 159805b261ecSmrg mapWidthRtrn[i+req->firstType] = wire->numLevels; 159905b261ecSmrg wire= (xkbKeyTypeWireDesc *)map; 160005b261ecSmrg } 160105b261ecSmrg for (i=req->firstType+req->nTypes;i<nMaps;i++) { 160205b261ecSmrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 160305b261ecSmrg } 160405b261ecSmrg *nMapsRtrn = nMaps; 160505b261ecSmrg *wireRtrn = wire; 160605b261ecSmrg return 1; 160705b261ecSmrg} 160805b261ecSmrg 160905b261ecSmrgstatic int 161005b261ecSmrgCheckKeySyms( ClientPtr client, 161105b261ecSmrg XkbDescPtr xkb, 161205b261ecSmrg xkbSetMapReq * req, 161305b261ecSmrg int nTypes, 161405b261ecSmrg CARD8 * mapWidths, 161505b261ecSmrg CARD16 * symsPerKey, 161605b261ecSmrg xkbSymMapWireDesc ** wireRtrn, 161705b261ecSmrg int * errorRtrn) 161805b261ecSmrg{ 161905b261ecSmrgregister unsigned i; 162005b261ecSmrgXkbSymMapPtr map; 162105b261ecSmrgxkbSymMapWireDesc* wire = *wireRtrn; 162205b261ecSmrg 162305b261ecSmrg if (!(XkbKeySymsMask&req->present)) 162405b261ecSmrg return 1; 162505b261ecSmrg CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0); 162605b261ecSmrg map = &xkb->map->key_sym_map[xkb->min_key_code]; 162705b261ecSmrg for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) { 162805b261ecSmrg register int g,ng,w; 162905b261ecSmrg ng= XkbNumGroups(map->group_info); 163005b261ecSmrg for (w=g=0;g<ng;g++) { 163105b261ecSmrg if (map->kt_index[g]>=(unsigned)nTypes) { 163205b261ecSmrg *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]); 163305b261ecSmrg return 0; 163405b261ecSmrg } 163505b261ecSmrg if (mapWidths[map->kt_index[g]]>w) 163605b261ecSmrg w= mapWidths[map->kt_index[g]]; 163705b261ecSmrg } 163805b261ecSmrg symsPerKey[i] = w*ng; 163905b261ecSmrg } 164005b261ecSmrg for (i=0;i<req->nKeySyms;i++) { 164105b261ecSmrg KeySym *pSyms; 164205b261ecSmrg register unsigned nG; 164305b261ecSmrg if (client->swapped) { 164405b261ecSmrg swaps(&wire->nSyms,nG); 164505b261ecSmrg } 164605b261ecSmrg nG = XkbNumGroups(wire->groupInfo); 164705b261ecSmrg if (nG>XkbNumKbdGroups) { 164805b261ecSmrg *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG); 164905b261ecSmrg return 0; 165005b261ecSmrg } 165105b261ecSmrg if (nG>0) { 165205b261ecSmrg register int g,w; 165305b261ecSmrg for (g=w=0;g<nG;g++) { 165405b261ecSmrg if (wire->ktIndex[g]>=(unsigned)nTypes) { 165505b261ecSmrg *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g, 165605b261ecSmrg wire->ktIndex[g]); 165705b261ecSmrg return 0; 165805b261ecSmrg } 165905b261ecSmrg if (mapWidths[wire->ktIndex[g]]>w) 166005b261ecSmrg w= mapWidths[wire->ktIndex[g]]; 166105b261ecSmrg } 166205b261ecSmrg if (wire->width!=w) { 166305b261ecSmrg *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width); 166405b261ecSmrg return 0; 166505b261ecSmrg } 166605b261ecSmrg w*= nG; 166705b261ecSmrg symsPerKey[i+req->firstKeySym] = w; 166805b261ecSmrg if (w!=wire->nSyms) { 166905b261ecSmrg *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w); 167005b261ecSmrg return 0; 167105b261ecSmrg } 167205b261ecSmrg } 167305b261ecSmrg else if (wire->nSyms!=0) { 167405b261ecSmrg *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms); 167505b261ecSmrg return 0; 167605b261ecSmrg } 167705b261ecSmrg pSyms = (KeySym *)&wire[1]; 167805b261ecSmrg wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 167905b261ecSmrg } 168005b261ecSmrg 168105b261ecSmrg map = &xkb->map->key_sym_map[i]; 168205b261ecSmrg for (;i<=(unsigned)xkb->max_key_code;i++,map++) { 168305b261ecSmrg register int g,nG,w; 168405b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 168505b261ecSmrg for (w=g=0;g<nG;g++) { 168605b261ecSmrg if (map->kt_index[g]>=(unsigned)nTypes) { 168705b261ecSmrg *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]); 168805b261ecSmrg return 0; 168905b261ecSmrg } 169005b261ecSmrg if (mapWidths[map->kt_index[g]]>w) 169105b261ecSmrg w= mapWidths[map->kt_index[g]]; 169205b261ecSmrg } 169305b261ecSmrg symsPerKey[i] = w*nG; 169405b261ecSmrg } 169505b261ecSmrg *wireRtrn = wire; 169605b261ecSmrg return 1; 169705b261ecSmrg} 169805b261ecSmrg 169905b261ecSmrgstatic int 170005b261ecSmrgCheckKeyActions( XkbDescPtr xkb, 170105b261ecSmrg xkbSetMapReq * req, 170205b261ecSmrg int nTypes, 170305b261ecSmrg CARD8 * mapWidths, 170405b261ecSmrg CARD16 * symsPerKey, 170505b261ecSmrg CARD8 ** wireRtrn, 170605b261ecSmrg int * nActsRtrn) 170705b261ecSmrg{ 170805b261ecSmrgint nActs; 170905b261ecSmrgCARD8 * wire = *wireRtrn; 171005b261ecSmrgregister unsigned i; 171105b261ecSmrg 171205b261ecSmrg if (!(XkbKeyActionsMask&req->present)) 171305b261ecSmrg return 1; 171405b261ecSmrg CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0); 171505b261ecSmrg for (nActs=i=0;i<req->nKeyActs;i++) { 171605b261ecSmrg if (wire[0]!=0) { 171705b261ecSmrg if (wire[0]==symsPerKey[i+req->firstKeyAct]) 171805b261ecSmrg nActs+= wire[0]; 171905b261ecSmrg else { 172005b261ecSmrg *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]); 172105b261ecSmrg return 0; 172205b261ecSmrg } 172305b261ecSmrg } 172405b261ecSmrg wire++; 172505b261ecSmrg } 172605b261ecSmrg if (req->nKeyActs%4) 172705b261ecSmrg wire+= 4-(req->nKeyActs%4); 172805b261ecSmrg *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs); 172905b261ecSmrg *nActsRtrn = nActs; 173005b261ecSmrg return 1; 173105b261ecSmrg} 173205b261ecSmrg 173305b261ecSmrgstatic int 173405b261ecSmrgCheckKeyBehaviors( XkbDescPtr xkb, 173505b261ecSmrg xkbSetMapReq * req, 173605b261ecSmrg xkbBehaviorWireDesc ** wireRtrn, 173705b261ecSmrg int * errorRtrn) 173805b261ecSmrg{ 173905b261ecSmrgregister xkbBehaviorWireDesc * wire = *wireRtrn; 174005b261ecSmrgregister XkbServerMapPtr server = xkb->server; 174105b261ecSmrgregister unsigned i; 174205b261ecSmrgunsigned first,last; 174305b261ecSmrg 174405b261ecSmrg if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { 174505b261ecSmrg req->present&= ~XkbKeyBehaviorsMask; 174605b261ecSmrg req->nKeyBehaviors= 0; 174705b261ecSmrg return 1; 174805b261ecSmrg } 174905b261ecSmrg first= req->firstKeyBehavior; 175005b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 175105b261ecSmrg if (first<req->minKeyCode) { 175205b261ecSmrg *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode); 175305b261ecSmrg return 0; 175405b261ecSmrg } 175505b261ecSmrg if (last>req->maxKeyCode) { 175605b261ecSmrg *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode); 175705b261ecSmrg return 0; 175805b261ecSmrg } 175905b261ecSmrg 176005b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++,wire++) { 176105b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 176205b261ecSmrg *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key); 176305b261ecSmrg return 0; 176405b261ecSmrg } 176505b261ecSmrg if ((wire->type&XkbKB_Permanent)&& 176605b261ecSmrg ((server->behaviors[wire->key].type!=wire->type)|| 176705b261ecSmrg (server->behaviors[wire->key].data!=wire->data))) { 176805b261ecSmrg *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type); 176905b261ecSmrg return 0; 177005b261ecSmrg } 177105b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&& 177205b261ecSmrg ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) { 177305b261ecSmrg *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data, 177405b261ecSmrg XkbMaxRadioGroups); 177505b261ecSmrg return 0; 177605b261ecSmrg } 177705b261ecSmrg if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) { 177805b261ecSmrg CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0); 177905b261ecSmrg } 178005b261ecSmrg } 178105b261ecSmrg *wireRtrn = wire; 178205b261ecSmrg return 1; 178305b261ecSmrg} 178405b261ecSmrg 178505b261ecSmrgstatic int 178605b261ecSmrgCheckVirtualMods( XkbDescRec * xkb, 178705b261ecSmrg xkbSetMapReq * req, 178805b261ecSmrg CARD8 ** wireRtrn, 178905b261ecSmrg int * errorRtrn) 179005b261ecSmrg{ 179105b261ecSmrgregister CARD8 *wire = *wireRtrn; 179205b261ecSmrgregister unsigned i,nMods,bit; 179305b261ecSmrg 179405b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 179505b261ecSmrg return 1; 179605b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 179705b261ecSmrg if (req->virtualMods&bit) 179805b261ecSmrg nMods++; 179905b261ecSmrg } 180005b261ecSmrg *wireRtrn= (wire+XkbPaddedSize(nMods)); 180105b261ecSmrg return 1; 180205b261ecSmrg} 180305b261ecSmrg 180405b261ecSmrgstatic int 180505b261ecSmrgCheckKeyExplicit( XkbDescPtr xkb, 180605b261ecSmrg xkbSetMapReq * req, 180705b261ecSmrg CARD8 ** wireRtrn, 180805b261ecSmrg int * errorRtrn) 180905b261ecSmrg{ 181005b261ecSmrgregister CARD8 * wire = *wireRtrn; 181105b261ecSmrgCARD8 * start; 181205b261ecSmrgregister unsigned i; 181305b261ecSmrgint first,last; 181405b261ecSmrg 181505b261ecSmrg if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) { 181605b261ecSmrg req->present&= ~XkbExplicitComponentsMask; 181705b261ecSmrg req->nKeyExplicit= 0; 181805b261ecSmrg return 1; 181905b261ecSmrg } 182005b261ecSmrg first= req->firstKeyExplicit; 182105b261ecSmrg last= first+req->nKeyExplicit-1; 182205b261ecSmrg if (first<req->minKeyCode) { 182305b261ecSmrg *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode); 182405b261ecSmrg return 0; 182505b261ecSmrg } 182605b261ecSmrg if (last>req->maxKeyCode) { 182705b261ecSmrg *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode); 182805b261ecSmrg return 0; 182905b261ecSmrg } 183005b261ecSmrg start= wire; 183105b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+=2) { 183205b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 183305b261ecSmrg *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]); 183405b261ecSmrg return 0; 183505b261ecSmrg } 183605b261ecSmrg if (wire[1]&(~XkbAllExplicitMask)) { 183705b261ecSmrg *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]); 183805b261ecSmrg return 0; 183905b261ecSmrg } 184005b261ecSmrg } 184105b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 184205b261ecSmrg *wireRtrn= wire; 184305b261ecSmrg return 1; 184405b261ecSmrg} 184505b261ecSmrg 184605b261ecSmrgstatic int 184705b261ecSmrgCheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn) 184805b261ecSmrg{ 184905b261ecSmrgregister CARD8 * wire = *wireRtrn; 185005b261ecSmrgCARD8 * start; 185105b261ecSmrgregister unsigned i; 185205b261ecSmrgint first,last; 185305b261ecSmrg 185405b261ecSmrg if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) { 185505b261ecSmrg req->present&= ~XkbModifierMapMask; 185605b261ecSmrg req->nModMapKeys= 0; 185705b261ecSmrg return 1; 185805b261ecSmrg } 185905b261ecSmrg first= req->firstModMapKey; 186005b261ecSmrg last= first+req->nModMapKeys-1; 186105b261ecSmrg if (first<req->minKeyCode) { 186205b261ecSmrg *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode); 186305b261ecSmrg return 0; 186405b261ecSmrg } 186505b261ecSmrg if (last>req->maxKeyCode) { 186605b261ecSmrg *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode); 186705b261ecSmrg return 0; 186805b261ecSmrg } 186905b261ecSmrg start= wire; 187005b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+=2) { 187105b261ecSmrg if ((wire[0]<first)||(wire[0]>last)) { 187205b261ecSmrg *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]); 187305b261ecSmrg return 0; 187405b261ecSmrg } 187505b261ecSmrg } 187605b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 187705b261ecSmrg *wireRtrn= wire; 187805b261ecSmrg return 1; 187905b261ecSmrg} 188005b261ecSmrg 188105b261ecSmrgstatic int 188205b261ecSmrgCheckVirtualModMap( XkbDescPtr xkb, 188305b261ecSmrg xkbSetMapReq *req, 188405b261ecSmrg xkbVModMapWireDesc **wireRtrn, 188505b261ecSmrg int *errRtrn) 188605b261ecSmrg{ 188705b261ecSmrgregister xkbVModMapWireDesc * wire = *wireRtrn; 188805b261ecSmrgregister unsigned i; 188905b261ecSmrgint first,last; 189005b261ecSmrg 189105b261ecSmrg if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) { 189205b261ecSmrg req->present&= ~XkbVirtualModMapMask; 189305b261ecSmrg req->nVModMapKeys= 0; 189405b261ecSmrg return 1; 189505b261ecSmrg } 189605b261ecSmrg first= req->firstVModMapKey; 189705b261ecSmrg last= first+req->nVModMapKeys-1; 189805b261ecSmrg if (first<req->minKeyCode) { 189905b261ecSmrg *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode); 190005b261ecSmrg return 0; 190105b261ecSmrg } 190205b261ecSmrg if (last>req->maxKeyCode) { 190305b261ecSmrg *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode); 190405b261ecSmrg return 0; 190505b261ecSmrg } 190605b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 190705b261ecSmrg if ((wire->key<first)||(wire->key>last)) { 190805b261ecSmrg *errRtrn = _XkbErrCode4(0x73,first,last,wire->key); 190905b261ecSmrg return 0; 191005b261ecSmrg } 191105b261ecSmrg } 191205b261ecSmrg *wireRtrn= wire; 191305b261ecSmrg return 1; 191405b261ecSmrg} 191505b261ecSmrg 191605b261ecSmrgstatic char * 191705b261ecSmrgSetKeyTypes( XkbDescPtr xkb, 191805b261ecSmrg xkbSetMapReq * req, 191905b261ecSmrg xkbKeyTypeWireDesc * wire, 192005b261ecSmrg XkbChangesPtr changes) 192105b261ecSmrg{ 192205b261ecSmrgregister unsigned i; 192305b261ecSmrgunsigned first,last; 192405b261ecSmrgCARD8 *map; 192505b261ecSmrg 192605b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) { 192705b261ecSmrg i= req->firstType+req->nTypes; 192805b261ecSmrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) { 192905b261ecSmrg return NULL; 193005b261ecSmrg } 193105b261ecSmrg } 193205b261ecSmrg if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types) 193305b261ecSmrg xkb->map->num_types= req->firstType+req->nTypes; 193405b261ecSmrg 193505b261ecSmrg for (i=0;i<req->nTypes;i++) { 193605b261ecSmrg XkbKeyTypePtr pOld; 193705b261ecSmrg register unsigned n; 193805b261ecSmrg 193905b261ecSmrg if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries, 194005b261ecSmrg wire->preserve,wire->numLevels)!=Success) { 194105b261ecSmrg return NULL; 194205b261ecSmrg } 194305b261ecSmrg pOld = &xkb->map->types[i+req->firstType]; 194405b261ecSmrg map = (CARD8 *)&wire[1]; 194505b261ecSmrg 194605b261ecSmrg pOld->mods.real_mods = wire->realMods; 194705b261ecSmrg pOld->mods.vmods= wire->virtualMods; 194805b261ecSmrg pOld->num_levels = wire->numLevels; 194905b261ecSmrg pOld->map_count= wire->nMapEntries; 195005b261ecSmrg 195105b261ecSmrg pOld->mods.mask= pOld->mods.real_mods| 195205b261ecSmrg XkbMaskForVMask(xkb,pOld->mods.vmods); 195305b261ecSmrg 195405b261ecSmrg if (wire->nMapEntries) { 195505b261ecSmrg xkbKTSetMapEntryWireDesc *mapWire; 195605b261ecSmrg xkbModsWireDesc *preWire; 195705b261ecSmrg unsigned tmp; 195805b261ecSmrg mapWire= (xkbKTSetMapEntryWireDesc *)map; 195905b261ecSmrg preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; 196005b261ecSmrg for (n=0;n<wire->nMapEntries;n++) { 196105b261ecSmrg pOld->map[n].active= 1; 196205b261ecSmrg pOld->map[n].mods.mask= mapWire[n].realMods; 196305b261ecSmrg pOld->map[n].mods.real_mods= mapWire[n].realMods; 196405b261ecSmrg pOld->map[n].mods.vmods= mapWire[n].virtualMods; 196505b261ecSmrg pOld->map[n].level= mapWire[n].level; 196605b261ecSmrg if (mapWire[n].virtualMods!=0) { 196705b261ecSmrg tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods); 196805b261ecSmrg pOld->map[n].active= (tmp!=0); 196905b261ecSmrg pOld->map[n].mods.mask|= tmp; 197005b261ecSmrg } 197105b261ecSmrg if (wire->preserve) { 197205b261ecSmrg pOld->preserve[n].real_mods= preWire[n].realMods; 197305b261ecSmrg pOld->preserve[n].vmods= preWire[n].virtualMods; 197405b261ecSmrg tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods); 197505b261ecSmrg pOld->preserve[n].mask= preWire[n].realMods|tmp; 197605b261ecSmrg } 197705b261ecSmrg } 197805b261ecSmrg if (wire->preserve) 197905b261ecSmrg map= (CARD8 *)&preWire[wire->nMapEntries]; 198005b261ecSmrg else map= (CARD8 *)&mapWire[wire->nMapEntries]; 198105b261ecSmrg } 198205b261ecSmrg else map= (CARD8 *)&wire[1]; 198305b261ecSmrg wire = (xkbKeyTypeWireDesc *)map; 198405b261ecSmrg } 198505b261ecSmrg first= req->firstType; 198605b261ecSmrg last= first+req->nTypes-1; /* last changed type */ 198705b261ecSmrg if (changes->map.changed&XkbKeyTypesMask) { 198805b261ecSmrg int oldLast; 198905b261ecSmrg oldLast= changes->map.first_type+changes->map.num_types-1; 199005b261ecSmrg if (changes->map.first_type<first) 199105b261ecSmrg first= changes->map.first_type; 199205b261ecSmrg if (oldLast>last) 199305b261ecSmrg last= oldLast; 199405b261ecSmrg } 199505b261ecSmrg changes->map.changed|= XkbKeyTypesMask; 199605b261ecSmrg changes->map.first_type = first; 199705b261ecSmrg changes->map.num_types = (last-first)+1; 199805b261ecSmrg return (char *)wire; 199905b261ecSmrg} 200005b261ecSmrg 200105b261ecSmrgstatic char * 200205b261ecSmrgSetKeySyms( ClientPtr client, 200305b261ecSmrg XkbDescPtr xkb, 200405b261ecSmrg xkbSetMapReq * req, 200505b261ecSmrg xkbSymMapWireDesc * wire, 200605b261ecSmrg XkbChangesPtr changes, 200705b261ecSmrg DeviceIntPtr dev) 200805b261ecSmrg{ 200905b261ecSmrgregister unsigned i,s; 201005b261ecSmrgXkbSymMapPtr oldMap; 201105b261ecSmrgKeySym * newSyms; 201205b261ecSmrgKeySym * pSyms; 201305b261ecSmrgunsigned first,last; 201405b261ecSmrg 201505b261ecSmrg oldMap = &xkb->map->key_sym_map[req->firstKeySym]; 201605b261ecSmrg for (i=0;i<req->nKeySyms;i++,oldMap++) { 201705b261ecSmrg pSyms = (KeySym *)&wire[1]; 201805b261ecSmrg if (wire->nSyms>0) { 201905b261ecSmrg newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms); 202005b261ecSmrg for (s=0;s<wire->nSyms;s++) { 202105b261ecSmrg newSyms[s]= pSyms[s]; 202205b261ecSmrg } 202305b261ecSmrg if (client->swapped) { 202405b261ecSmrg int n; 202505b261ecSmrg for (s=0;s<wire->nSyms;s++) { 202605b261ecSmrg swapl(&newSyms[s],n); 202705b261ecSmrg } 202805b261ecSmrg } 202905b261ecSmrg } 203005b261ecSmrg oldMap->kt_index[0] = wire->ktIndex[0]; 203105b261ecSmrg oldMap->kt_index[1] = wire->ktIndex[1]; 203205b261ecSmrg oldMap->kt_index[2] = wire->ktIndex[2]; 203305b261ecSmrg oldMap->kt_index[3] = wire->ktIndex[3]; 203405b261ecSmrg oldMap->group_info = wire->groupInfo; 203505b261ecSmrg oldMap->width = wire->width; 203605b261ecSmrg wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; 203705b261ecSmrg } 203805b261ecSmrg first= req->firstKeySym; 203905b261ecSmrg last= first+req->nKeySyms-1; 204005b261ecSmrg if (changes->map.changed&XkbKeySymsMask) { 204105b261ecSmrg int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1); 204205b261ecSmrg if (changes->map.first_key_sym<first) 204305b261ecSmrg first= changes->map.first_key_sym; 204405b261ecSmrg if (oldLast>last) 204505b261ecSmrg last= oldLast; 204605b261ecSmrg } 204705b261ecSmrg changes->map.changed|= XkbKeySymsMask; 204805b261ecSmrg changes->map.first_key_sym = first; 204905b261ecSmrg changes->map.num_key_syms = (last-first+1); 205005b261ecSmrg 205105b261ecSmrg s= 0; 205205b261ecSmrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 205305b261ecSmrg if (XkbKeyNumGroups(xkb,i)>s) 205405b261ecSmrg s= XkbKeyNumGroups(xkb,i); 205505b261ecSmrg } 205605b261ecSmrg if (s!=xkb->ctrls->num_groups) { 205705b261ecSmrg xkbControlsNotify cn; 205805b261ecSmrg XkbControlsRec old; 205905b261ecSmrg cn.keycode= 0; 206005b261ecSmrg cn.eventType= 0; 206105b261ecSmrg cn.requestMajor= XkbReqCode; 206205b261ecSmrg cn.requestMinor= X_kbSetMap; 206305b261ecSmrg old= *xkb->ctrls; 206405b261ecSmrg xkb->ctrls->num_groups= s; 206505b261ecSmrg if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,False)) 206605b261ecSmrg XkbSendControlsNotify(dev,&cn); 206705b261ecSmrg } 206805b261ecSmrg return (char *)wire; 206905b261ecSmrg} 207005b261ecSmrg 207105b261ecSmrgstatic char * 207205b261ecSmrgSetKeyActions( XkbDescPtr xkb, 207305b261ecSmrg xkbSetMapReq * req, 207405b261ecSmrg CARD8 * wire, 207505b261ecSmrg XkbChangesPtr changes) 207605b261ecSmrg{ 207705b261ecSmrgregister unsigned i,first,last; 207805b261ecSmrgCARD8 * nActs = wire; 207905b261ecSmrgXkbAction * newActs; 208005b261ecSmrg 208105b261ecSmrg wire+= XkbPaddedSize(req->nKeyActs); 208205b261ecSmrg for (i=0;i<req->nKeyActs;i++) { 208305b261ecSmrg if (nActs[i]==0) 208405b261ecSmrg xkb->server->key_acts[i+req->firstKeyAct]= 0; 208505b261ecSmrg else { 208605b261ecSmrg newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]); 208705b261ecSmrg memcpy((char *)newActs,(char *)wire, 208805b261ecSmrg nActs[i]*SIZEOF(xkbActionWireDesc)); 208905b261ecSmrg wire+= nActs[i]*SIZEOF(xkbActionWireDesc); 209005b261ecSmrg } 209105b261ecSmrg } 209205b261ecSmrg first= req->firstKeyAct; 209305b261ecSmrg last= (first+req->nKeyActs-1); 209405b261ecSmrg if (changes->map.changed&XkbKeyActionsMask) { 209505b261ecSmrg int oldLast; 209605b261ecSmrg oldLast= changes->map.first_key_act+changes->map.num_key_acts-1; 209705b261ecSmrg if (changes->map.first_key_act<first) 209805b261ecSmrg first= changes->map.first_key_act; 209905b261ecSmrg if (oldLast>last) 210005b261ecSmrg last= oldLast; 210105b261ecSmrg } 210205b261ecSmrg changes->map.changed|= XkbKeyActionsMask; 210305b261ecSmrg changes->map.first_key_act= first; 210405b261ecSmrg changes->map.num_key_acts= (last-first+1); 210505b261ecSmrg return (char *)wire; 210605b261ecSmrg} 210705b261ecSmrg 210805b261ecSmrgstatic char * 210905b261ecSmrgSetKeyBehaviors( XkbSrvInfoPtr xkbi, 211005b261ecSmrg xkbSetMapReq *req, 211105b261ecSmrg xkbBehaviorWireDesc *wire, 211205b261ecSmrg XkbChangesPtr changes) 211305b261ecSmrg{ 211405b261ecSmrgregister unsigned i; 211505b261ecSmrgint maxRG = -1; 211605b261ecSmrgXkbDescPtr xkb = xkbi->desc; 211705b261ecSmrgXkbServerMapPtr server = xkb->server; 211805b261ecSmrgunsigned first,last; 211905b261ecSmrg 212005b261ecSmrg first= req->firstKeyBehavior; 212105b261ecSmrg last= req->firstKeyBehavior+req->nKeyBehaviors-1; 212205b261ecSmrg bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior)); 212305b261ecSmrg for (i=0;i<req->totalKeyBehaviors;i++) { 212405b261ecSmrg if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) { 212505b261ecSmrg server->behaviors[wire->key].type= wire->type; 212605b261ecSmrg server->behaviors[wire->key].data= wire->data; 212705b261ecSmrg if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG)) 212805b261ecSmrg maxRG= wire->data + 1; 212905b261ecSmrg } 213005b261ecSmrg wire++; 213105b261ecSmrg } 213205b261ecSmrg 213305b261ecSmrg if (maxRG>(int)xkbi->nRadioGroups) { 213405b261ecSmrg int sz = maxRG*sizeof(XkbRadioGroupRec); 213505b261ecSmrg if (xkbi->radioGroups) 213605b261ecSmrg xkbi->radioGroups=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz); 213705b261ecSmrg else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(1, sz); 213805b261ecSmrg if (xkbi->radioGroups) { 213905b261ecSmrg if (xkbi->nRadioGroups) 214005b261ecSmrg bzero(&xkbi->radioGroups[xkbi->nRadioGroups], 214105b261ecSmrg (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec)); 214205b261ecSmrg xkbi->nRadioGroups= maxRG; 214305b261ecSmrg } 214405b261ecSmrg else xkbi->nRadioGroups= 0; 214505b261ecSmrg /* should compute members here */ 214605b261ecSmrg } 214705b261ecSmrg if (changes->map.changed&XkbKeyBehaviorsMask) { 214805b261ecSmrg unsigned oldLast; 214905b261ecSmrg oldLast= changes->map.first_key_behavior+ 215005b261ecSmrg changes->map.num_key_behaviors-1; 215105b261ecSmrg if (changes->map.first_key_behavior<req->firstKeyBehavior) 215205b261ecSmrg first= changes->map.first_key_behavior; 215305b261ecSmrg if (oldLast>last) 215405b261ecSmrg last= oldLast; 215505b261ecSmrg } 215605b261ecSmrg changes->map.changed|= XkbKeyBehaviorsMask; 215705b261ecSmrg changes->map.first_key_behavior = first; 215805b261ecSmrg changes->map.num_key_behaviors = (last-first+1); 215905b261ecSmrg return (char *)wire; 216005b261ecSmrg} 216105b261ecSmrg 216205b261ecSmrgstatic char * 216305b261ecSmrgSetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 216405b261ecSmrg XkbChangesPtr changes) 216505b261ecSmrg{ 216605b261ecSmrgregister int i,bit,nMods; 216705b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 216805b261ecSmrg 216905b261ecSmrg if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) 217005b261ecSmrg return (char *)wire; 217105b261ecSmrg for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 217205b261ecSmrg if (req->virtualMods&bit) { 217305b261ecSmrg if (srv->vmods[i]!=wire[nMods]) { 217405b261ecSmrg changes->map.changed|= XkbVirtualModsMask; 217505b261ecSmrg changes->map.vmods|= bit; 217605b261ecSmrg srv->vmods[i]= wire[nMods]; 217705b261ecSmrg } 217805b261ecSmrg nMods++; 217905b261ecSmrg } 218005b261ecSmrg } 218105b261ecSmrg return (char *)(wire+XkbPaddedSize(nMods)); 218205b261ecSmrg} 218305b261ecSmrg 218405b261ecSmrgstatic char * 218505b261ecSmrgSetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, 218605b261ecSmrg XkbChangesPtr changes) 218705b261ecSmrg{ 218805b261ecSmrgregister unsigned i,first,last; 218905b261ecSmrgXkbServerMapPtr xkb = xkbi->desc->server; 219005b261ecSmrgCARD8 * start; 219105b261ecSmrg 219205b261ecSmrg start= wire; 219305b261ecSmrg first= req->firstKeyExplicit; 219405b261ecSmrg last= req->firstKeyExplicit+req->nKeyExplicit-1; 219505b261ecSmrg bzero(&xkb->explicit[first],req->nKeyExplicit); 219605b261ecSmrg for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) { 219705b261ecSmrg xkb->explicit[wire[0]]= wire[1]; 219805b261ecSmrg } 219905b261ecSmrg if (first>0) { 220005b261ecSmrg if (changes->map.changed&XkbExplicitComponentsMask) { 220105b261ecSmrg int oldLast; 220205b261ecSmrg oldLast= changes->map.first_key_explicit+ 220305b261ecSmrg changes->map.num_key_explicit-1; 220405b261ecSmrg if (changes->map.first_key_explicit<first) 220505b261ecSmrg first= changes->map.first_key_explicit; 220605b261ecSmrg if (oldLast>last) 220705b261ecSmrg last= oldLast; 220805b261ecSmrg } 220905b261ecSmrg changes->map.first_key_explicit= first; 221005b261ecSmrg changes->map.num_key_explicit= (last-first)+1; 221105b261ecSmrg } 221205b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 221305b261ecSmrg return (char *)wire; 221405b261ecSmrg} 221505b261ecSmrg 221605b261ecSmrgstatic char * 221705b261ecSmrgSetModifierMap( XkbSrvInfoPtr xkbi, 221805b261ecSmrg xkbSetMapReq * req, 221905b261ecSmrg CARD8 * wire, 222005b261ecSmrg XkbChangesPtr changes) 222105b261ecSmrg{ 222205b261ecSmrgregister unsigned i,first,last; 222305b261ecSmrgXkbClientMapPtr xkb = xkbi->desc->map; 222405b261ecSmrgCARD8 * start; 222505b261ecSmrg 222605b261ecSmrg start= wire; 222705b261ecSmrg first= req->firstModMapKey; 222805b261ecSmrg last= req->firstModMapKey+req->nModMapKeys-1; 222905b261ecSmrg bzero(&xkb->modmap[first],req->nModMapKeys); 223005b261ecSmrg for (i=0;i<req->totalModMapKeys;i++,wire+= 2) { 223105b261ecSmrg xkb->modmap[wire[0]]= wire[1]; 223205b261ecSmrg } 223305b261ecSmrg if (first>0) { 223405b261ecSmrg if (changes->map.changed&XkbModifierMapMask) { 223505b261ecSmrg int oldLast; 223605b261ecSmrg oldLast= changes->map.first_modmap_key+ 223705b261ecSmrg changes->map.num_modmap_keys-1; 223805b261ecSmrg if (changes->map.first_modmap_key<first) 223905b261ecSmrg first= changes->map.first_modmap_key; 224005b261ecSmrg if (oldLast>last) 224105b261ecSmrg last= oldLast; 224205b261ecSmrg } 224305b261ecSmrg changes->map.first_modmap_key= first; 224405b261ecSmrg changes->map.num_modmap_keys= (last-first)+1; 224505b261ecSmrg } 224605b261ecSmrg wire+= XkbPaddedSize(wire-start)-(wire-start); 224705b261ecSmrg return (char *)wire; 224805b261ecSmrg} 224905b261ecSmrg 225005b261ecSmrgstatic char * 225105b261ecSmrgSetVirtualModMap( XkbSrvInfoPtr xkbi, 225205b261ecSmrg xkbSetMapReq * req, 225305b261ecSmrg xkbVModMapWireDesc * wire, 225405b261ecSmrg XkbChangesPtr changes) 225505b261ecSmrg{ 225605b261ecSmrgregister unsigned i,first,last; 225705b261ecSmrgXkbServerMapPtr srv = xkbi->desc->server; 225805b261ecSmrg 225905b261ecSmrg first= req->firstVModMapKey; 226005b261ecSmrg last= req->firstVModMapKey+req->nVModMapKeys-1; 226105b261ecSmrg bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short)); 226205b261ecSmrg for (i=0;i<req->totalVModMapKeys;i++,wire++) { 226305b261ecSmrg srv->vmodmap[wire->key]= wire->vmods; 226405b261ecSmrg } 226505b261ecSmrg if (first>0) { 226605b261ecSmrg if (changes->map.changed&XkbVirtualModMapMask) { 226705b261ecSmrg int oldLast; 226805b261ecSmrg oldLast= changes->map.first_vmodmap_key+ 226905b261ecSmrg changes->map.num_vmodmap_keys-1; 227005b261ecSmrg if (changes->map.first_vmodmap_key<first) 227105b261ecSmrg first= changes->map.first_vmodmap_key; 227205b261ecSmrg if (oldLast>last) 227305b261ecSmrg last= oldLast; 227405b261ecSmrg } 227505b261ecSmrg changes->map.first_vmodmap_key= first; 227605b261ecSmrg changes->map.num_vmodmap_keys= (last-first)+1; 227705b261ecSmrg } 227805b261ecSmrg return (char *)wire; 227905b261ecSmrg} 228005b261ecSmrg 228105b261ecSmrg/* FIXME: Needs to set map on all core-sending devices. */ 228205b261ecSmrgint 228305b261ecSmrgProcXkbSetMap(ClientPtr client) 228405b261ecSmrg{ 228505b261ecSmrg DeviceIntPtr dev; 228605b261ecSmrg XkbSrvInfoPtr xkbi; 228705b261ecSmrg XkbDescPtr xkb; 228805b261ecSmrg XkbChangesRec change; 228905b261ecSmrg XkbEventCauseRec cause; 229005b261ecSmrg int nTypes = 0,nActions,error; 229105b261ecSmrg char * tmp; 229205b261ecSmrg CARD8 mapWidths[XkbMaxLegalKeyCode+1]; 229305b261ecSmrg CARD16 symsPerKey[XkbMaxLegalKeyCode+1]; 229405b261ecSmrg Bool sentNKN; 229505b261ecSmrg 229605b261ecSmrg REQUEST(xkbSetMapReq); 229705b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 229805b261ecSmrg 229905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 230005b261ecSmrg return BadAccess; 230105b261ecSmrg 230205b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 230305b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); 230405b261ecSmrg 230505b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetMap,client); 230605b261ecSmrg xkbi= dev->key->xkbInfo; 230705b261ecSmrg xkb = xkbi->desc; 230805b261ecSmrg 230905b261ecSmrg if ((xkb->min_key_code!=stuff->minKeyCode)|| 231005b261ecSmrg (xkb->max_key_code!=stuff->maxKeyCode)) { 231105b261ecSmrg if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ 231205b261ecSmrg stuff->minKeyCode= xkb->min_key_code; 231305b261ecSmrg stuff->maxKeyCode= xkb->max_key_code; 231405b261ecSmrg } 231505b261ecSmrg else { 231605b261ecSmrg if (!XkbIsLegalKeycode(stuff->minKeyCode)) { 231705b261ecSmrg client->errorValue= _XkbErrCode3(2,stuff->minKeyCode, 231805b261ecSmrg stuff->maxKeyCode); 231905b261ecSmrg return BadValue; 232005b261ecSmrg } 232105b261ecSmrg if (stuff->minKeyCode>stuff->maxKeyCode) { 232205b261ecSmrg client->errorValue= _XkbErrCode3(3,stuff->minKeyCode, 232305b261ecSmrg stuff->maxKeyCode); 232405b261ecSmrg return BadMatch; 232505b261ecSmrg } 232605b261ecSmrg } 232705b261ecSmrg } 232805b261ecSmrg 232905b261ecSmrg tmp = (char *)&stuff[1]; 233005b261ecSmrg if ((stuff->present&XkbKeyTypesMask)&& 233105b261ecSmrg (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp, 233205b261ecSmrg &nTypes,mapWidths))) { 233305b261ecSmrg client->errorValue = nTypes; 233405b261ecSmrg return BadValue; 233505b261ecSmrg } 233605b261ecSmrg if ((stuff->present&XkbKeySymsMask)&& 233705b261ecSmrg (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey, 233805b261ecSmrg (xkbSymMapWireDesc **)&tmp,&error))) { 233905b261ecSmrg client->errorValue = error; 234005b261ecSmrg return BadValue; 234105b261ecSmrg } 234205b261ecSmrg 234305b261ecSmrg if ((stuff->present&XkbKeyActionsMask)&& 234405b261ecSmrg (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey, 234505b261ecSmrg (CARD8 **)&tmp,&nActions))) { 234605b261ecSmrg client->errorValue = nActions; 234705b261ecSmrg return BadValue; 234805b261ecSmrg } 234905b261ecSmrg 235005b261ecSmrg if ((stuff->present&XkbKeyBehaviorsMask)&& 235105b261ecSmrg (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) { 235205b261ecSmrg client->errorValue = error; 235305b261ecSmrg return BadValue; 235405b261ecSmrg } 235505b261ecSmrg 235605b261ecSmrg if ((stuff->present&XkbVirtualModsMask)&& 235705b261ecSmrg (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) { 235805b261ecSmrg client->errorValue= error; 235905b261ecSmrg return BadValue; 236005b261ecSmrg } 236105b261ecSmrg if ((stuff->present&XkbExplicitComponentsMask)&& 236205b261ecSmrg (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) { 236305b261ecSmrg client->errorValue= error; 236405b261ecSmrg return BadValue; 236505b261ecSmrg } 236605b261ecSmrg if ((stuff->present&XkbModifierMapMask)&& 236705b261ecSmrg (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) { 236805b261ecSmrg client->errorValue= error; 236905b261ecSmrg return BadValue; 237005b261ecSmrg } 237105b261ecSmrg if ((stuff->present&XkbVirtualModMapMask)&& 237205b261ecSmrg (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) { 237305b261ecSmrg client->errorValue= error; 237405b261ecSmrg return BadValue; 237505b261ecSmrg } 237605b261ecSmrg if (((tmp-((char *)stuff))/4)!=stuff->length) { 237705b261ecSmrg ErrorF("Internal error! Bad length in XkbSetMap (after check)\n"); 237805b261ecSmrg client->errorValue = tmp-((char *)&stuff[1]); 237905b261ecSmrg return BadLength; 238005b261ecSmrg } 238105b261ecSmrg bzero(&change,sizeof(change)); 238205b261ecSmrg sentNKN= False; 238305b261ecSmrg if ((xkb->min_key_code!=stuff->minKeyCode)|| 238405b261ecSmrg (xkb->max_key_code!=stuff->maxKeyCode)) { 238505b261ecSmrg Status status; 238605b261ecSmrg xkbNewKeyboardNotify nkn; 238705b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 238805b261ecSmrg nkn.oldMinKeyCode= xkb->min_key_code; 238905b261ecSmrg nkn.oldMaxKeyCode= xkb->max_key_code; 239005b261ecSmrg status= XkbChangeKeycodeRange(xkb,stuff->minKeyCode,stuff->maxKeyCode, 239105b261ecSmrg &change); 239205b261ecSmrg if (status!=Success) 239305b261ecSmrg return status; 239405b261ecSmrg nkn.minKeyCode= xkb->min_key_code; 239505b261ecSmrg nkn.maxKeyCode= xkb->max_key_code; 239605b261ecSmrg nkn.requestMajor= XkbReqCode; 239705b261ecSmrg nkn.requestMinor= X_kbSetMap; 239805b261ecSmrg nkn.changed= XkbNKN_KeycodesMask; 239905b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 240005b261ecSmrg sentNKN= True; 240105b261ecSmrg } 240205b261ecSmrg tmp = (char *)&stuff[1]; 240305b261ecSmrg if (stuff->present&XkbKeyTypesMask) { 240405b261ecSmrg tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change); 240505b261ecSmrg if (!tmp) goto allocFailure; 240605b261ecSmrg } 240705b261ecSmrg if (stuff->present&XkbKeySymsMask) { 240805b261ecSmrg tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev); 240905b261ecSmrg if (!tmp) goto allocFailure; 241005b261ecSmrg } 241105b261ecSmrg if (stuff->present&XkbKeyActionsMask) { 241205b261ecSmrg tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change); 241305b261ecSmrg if (!tmp) goto allocFailure; 241405b261ecSmrg } 241505b261ecSmrg if (stuff->present&XkbKeyBehaviorsMask) { 241605b261ecSmrg tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change); 241705b261ecSmrg if (!tmp) goto allocFailure; 241805b261ecSmrg } 241905b261ecSmrg if (stuff->present&XkbVirtualModsMask) 242005b261ecSmrg tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change); 242105b261ecSmrg if (stuff->present&XkbExplicitComponentsMask) 242205b261ecSmrg tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change); 242305b261ecSmrg if (stuff->present&XkbModifierMapMask) 242405b261ecSmrg tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change); 242505b261ecSmrg if (stuff->present&XkbVirtualModMapMask) 242605b261ecSmrg tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change); 242705b261ecSmrg if (((tmp-((char *)stuff))/4)!=stuff->length) { 242805b261ecSmrg ErrorF("Internal error! Bad length in XkbSetMap (after set)\n"); 242905b261ecSmrg client->errorValue = tmp-((char *)&stuff[1]); 243005b261ecSmrg return BadLength; 243105b261ecSmrg } 243205b261ecSmrg if (stuff->flags&XkbSetMapRecomputeActions) { 243305b261ecSmrg KeyCode first,last,firstMM,lastMM; 243405b261ecSmrg if (change.map.num_key_syms>0) { 243505b261ecSmrg first= change.map.first_key_sym; 243605b261ecSmrg last= first+change.map.num_key_syms-1; 243705b261ecSmrg } 243805b261ecSmrg else first= last= 0; 243905b261ecSmrg if (change.map.num_modmap_keys>0) { 244005b261ecSmrg firstMM= change.map.first_modmap_key; 244105b261ecSmrg lastMM= first+change.map.num_modmap_keys-1; 244205b261ecSmrg } 244305b261ecSmrg else firstMM= lastMM= 0; 244405b261ecSmrg if ((last>0) && (lastMM>0)) { 244505b261ecSmrg if (firstMM<first) 244605b261ecSmrg first= firstMM; 244705b261ecSmrg if (lastMM>last) 244805b261ecSmrg last= lastMM; 244905b261ecSmrg } 245005b261ecSmrg else if (lastMM>0) { 245105b261ecSmrg first= firstMM; 245205b261ecSmrg last= lastMM; 245305b261ecSmrg } 245405b261ecSmrg if (last>0) { 245505b261ecSmrg unsigned check= 0; 245605b261ecSmrg XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause); 245705b261ecSmrg if (check) 245805b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 245905b261ecSmrg } 246005b261ecSmrg } 246105b261ecSmrg if (!sentNKN) 246205b261ecSmrg XkbSendNotification(dev,&change,&cause); 246305b261ecSmrg 246405b261ecSmrg XkbUpdateCoreDescription(dev,False); 246505b261ecSmrg return client->noClientException; 246605b261ecSmrgallocFailure: 246705b261ecSmrg return BadAlloc; 246805b261ecSmrg} 246905b261ecSmrg 247005b261ecSmrg/***====================================================================***/ 247105b261ecSmrg 247205b261ecSmrgstatic Status 247305b261ecSmrgXkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat, 247405b261ecSmrg xkbGetCompatMapReply * rep) 247505b261ecSmrg{ 247605b261ecSmrgunsigned size,nGroups; 247705b261ecSmrg 247805b261ecSmrg nGroups= 0; 247905b261ecSmrg if (rep->groups!=0) { 248005b261ecSmrg register int i,bit; 248105b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 248205b261ecSmrg if (rep->groups&bit) 248305b261ecSmrg nGroups++; 248405b261ecSmrg } 248505b261ecSmrg } 248605b261ecSmrg size= nGroups*SIZEOF(xkbModsWireDesc); 248705b261ecSmrg size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); 248805b261ecSmrg rep->length= size/4; 248905b261ecSmrg return Success; 249005b261ecSmrg} 249105b261ecSmrg 249205b261ecSmrgstatic int 249305b261ecSmrgXkbSendCompatMap( ClientPtr client, 249405b261ecSmrg XkbCompatMapPtr compat, 249505b261ecSmrg xkbGetCompatMapReply * rep) 249605b261ecSmrg{ 249705b261ecSmrgchar * data; 249805b261ecSmrgint size; 249905b261ecSmrg 250005b261ecSmrg size= rep->length*4; 250105b261ecSmrg if (size>0) { 250205b261ecSmrg data = (char *)ALLOCATE_LOCAL(size); 250305b261ecSmrg if (data) { 250405b261ecSmrg register unsigned i,bit; 250505b261ecSmrg xkbModsWireDesc * grp; 250605b261ecSmrg XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI]; 250705b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 250805b261ecSmrg for (i=0;i<rep->nSI;i++,sym++,wire++) { 250905b261ecSmrg wire->sym= sym->sym; 251005b261ecSmrg wire->mods= sym->mods; 251105b261ecSmrg wire->match= sym->match; 251205b261ecSmrg wire->virtualMod= sym->virtual_mod; 251305b261ecSmrg wire->flags= sym->flags; 251405b261ecSmrg memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc); 251505b261ecSmrg if (client->swapped) { 251605b261ecSmrg register int n; 251705b261ecSmrg swapl(&wire->sym,n); 251805b261ecSmrg } 251905b261ecSmrg } 252005b261ecSmrg if (rep->groups) { 252105b261ecSmrg grp = (xkbModsWireDesc *)wire; 252205b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 252305b261ecSmrg if (rep->groups&bit) { 252405b261ecSmrg grp->mask= compat->groups[i].mask; 252505b261ecSmrg grp->realMods= compat->groups[i].real_mods; 252605b261ecSmrg grp->virtualMods= compat->groups[i].vmods; 252705b261ecSmrg if (client->swapped) { 252805b261ecSmrg register int n; 252905b261ecSmrg swaps(&grp->virtualMods,n); 253005b261ecSmrg } 253105b261ecSmrg grp++; 253205b261ecSmrg } 253305b261ecSmrg } 253405b261ecSmrg wire= (xkbSymInterpretWireDesc*)grp; 253505b261ecSmrg } 253605b261ecSmrg } 253705b261ecSmrg else return BadAlloc; 253805b261ecSmrg } 253905b261ecSmrg else data= NULL; 254005b261ecSmrg 254105b261ecSmrg if (client->swapped) { 254205b261ecSmrg register int n; 254305b261ecSmrg swaps(&rep->sequenceNumber,n); 254405b261ecSmrg swapl(&rep->length,n); 254505b261ecSmrg swaps(&rep->firstSI,n); 254605b261ecSmrg swaps(&rep->nSI,n); 254705b261ecSmrg swaps(&rep->nTotalSI,n); 254805b261ecSmrg } 254905b261ecSmrg 255005b261ecSmrg WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep); 255105b261ecSmrg if (data) { 255205b261ecSmrg WriteToClient(client, size, data); 255305b261ecSmrg DEALLOCATE_LOCAL((char *)data); 255405b261ecSmrg } 255505b261ecSmrg return client->noClientException; 255605b261ecSmrg} 255705b261ecSmrg 255805b261ecSmrgint 255905b261ecSmrgProcXkbGetCompatMap(ClientPtr client) 256005b261ecSmrg{ 256105b261ecSmrg xkbGetCompatMapReply rep; 256205b261ecSmrg DeviceIntPtr dev; 256305b261ecSmrg XkbDescPtr xkb; 256405b261ecSmrg XkbCompatMapPtr compat; 256505b261ecSmrg 256605b261ecSmrg REQUEST(xkbGetCompatMapReq); 256705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 256805b261ecSmrg 256905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 257005b261ecSmrg return BadAccess; 257105b261ecSmrg 257205b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 257305b261ecSmrg 257405b261ecSmrg xkb = dev->key->xkbInfo->desc; 257505b261ecSmrg compat= xkb->compat; 257605b261ecSmrg 257705b261ecSmrg rep.type = X_Reply; 257805b261ecSmrg rep.deviceID = dev->id; 257905b261ecSmrg rep.sequenceNumber = client->sequence; 258005b261ecSmrg rep.length = 0; 258105b261ecSmrg rep.firstSI = stuff->firstSI; 258205b261ecSmrg rep.nSI = stuff->nSI; 258305b261ecSmrg if (stuff->getAllSI) { 258405b261ecSmrg rep.firstSI = 0; 258505b261ecSmrg rep.nSI = compat->num_si; 258605b261ecSmrg } 258705b261ecSmrg else if ((((unsigned)stuff->nSI)>0)&& 258805b261ecSmrg ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) { 258905b261ecSmrg client->errorValue = _XkbErrCode2(0x05,compat->num_si); 259005b261ecSmrg return BadValue; 259105b261ecSmrg } 259205b261ecSmrg rep.nTotalSI = compat->num_si; 259305b261ecSmrg rep.groups= stuff->groups; 259405b261ecSmrg XkbComputeGetCompatMapReplySize(compat,&rep); 259505b261ecSmrg return XkbSendCompatMap(client,compat,&rep); 259605b261ecSmrg} 259705b261ecSmrg 259805b261ecSmrg/* FIXME: Needs to set compat map on all core-sending devices. */ 259905b261ecSmrgint 260005b261ecSmrgProcXkbSetCompatMap(ClientPtr client) 260105b261ecSmrg{ 260205b261ecSmrg DeviceIntPtr dev; 260305b261ecSmrg XkbSrvInfoPtr xkbi; 260405b261ecSmrg XkbDescPtr xkb; 260505b261ecSmrg XkbCompatMapPtr compat; 260605b261ecSmrg char * data; 260705b261ecSmrg int nGroups; 260805b261ecSmrg register unsigned i,bit; 260905b261ecSmrg 261005b261ecSmrg REQUEST(xkbSetCompatMapReq); 261105b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 261205b261ecSmrg 261305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 261405b261ecSmrg return BadAccess; 261505b261ecSmrg 261605b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 261705b261ecSmrg 261805b261ecSmrg data = (char *)&stuff[1]; 261905b261ecSmrg xkbi = dev->key->xkbInfo; 262005b261ecSmrg xkb= xkbi->desc; 262105b261ecSmrg compat= xkb->compat; 262205b261ecSmrg if ((stuff->nSI>0)||(stuff->truncateSI)) { 262305b261ecSmrg xkbSymInterpretWireDesc *wire; 262405b261ecSmrg if (stuff->firstSI>compat->num_si) { 262505b261ecSmrg client->errorValue = _XkbErrCode2(0x02,compat->num_si); 262605b261ecSmrg return BadValue; 262705b261ecSmrg } 262805b261ecSmrg wire= (xkbSymInterpretWireDesc *)data; 262905b261ecSmrg wire+= stuff->nSI; 263005b261ecSmrg data = (char *)wire; 263105b261ecSmrg } 263205b261ecSmrg nGroups= 0; 263305b261ecSmrg if (stuff->groups!=0) { 263405b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 263505b261ecSmrg if ( stuff->groups&bit ) 263605b261ecSmrg nGroups++; 263705b261ecSmrg } 263805b261ecSmrg } 263905b261ecSmrg data+= nGroups*SIZEOF(xkbModsWireDesc); 264005b261ecSmrg if (((data-((char *)stuff))/4)!=stuff->length) { 264105b261ecSmrg return BadLength; 264205b261ecSmrg } 264305b261ecSmrg data = (char *)&stuff[1]; 264405b261ecSmrg if (stuff->nSI>0) { 264505b261ecSmrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; 264605b261ecSmrg XkbSymInterpretPtr sym; 264705b261ecSmrg if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) { 264805b261ecSmrg compat->num_si= stuff->firstSI+stuff->nSI; 264905b261ecSmrg compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, 265005b261ecSmrg compat->num_si, 265105b261ecSmrg XkbSymInterpretRec); 265205b261ecSmrg if (!compat->sym_interpret) { 265305b261ecSmrg compat->num_si= 0; 265405b261ecSmrg return BadAlloc; 265505b261ecSmrg } 265605b261ecSmrg } 265705b261ecSmrg else if (stuff->truncateSI) { 265805b261ecSmrg compat->num_si = stuff->firstSI+stuff->nSI; 265905b261ecSmrg } 266005b261ecSmrg sym = &compat->sym_interpret[stuff->firstSI]; 266105b261ecSmrg for (i=0;i<stuff->nSI;i++,wire++,sym++) { 266205b261ecSmrg if (client->swapped) { 266305b261ecSmrg register int n; 266405b261ecSmrg swapl(&wire->sym,n); 266505b261ecSmrg } 266605b261ecSmrg sym->sym= wire->sym; 266705b261ecSmrg sym->mods= wire->mods; 266805b261ecSmrg sym->match= wire->match; 266905b261ecSmrg sym->flags= wire->flags; 267005b261ecSmrg sym->virtual_mod= wire->virtualMod; 267105b261ecSmrg memcpy((char *)&sym->act,(char *)&wire->act, 267205b261ecSmrg SIZEOF(xkbActionWireDesc)); 267305b261ecSmrg } 267405b261ecSmrg data = (char *)wire; 267505b261ecSmrg } 267605b261ecSmrg else if (stuff->truncateSI) { 267705b261ecSmrg compat->num_si = stuff->firstSI; 267805b261ecSmrg } 267905b261ecSmrg 268005b261ecSmrg if (stuff->groups!=0) { 268105b261ecSmrg register unsigned i,bit; 268205b261ecSmrg xkbModsWireDesc *wire = (xkbModsWireDesc *)data; 268305b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 268405b261ecSmrg if (stuff->groups&bit) { 268505b261ecSmrg if (client->swapped) { 268605b261ecSmrg register int n; 268705b261ecSmrg swaps(&wire->virtualMods,n); 268805b261ecSmrg } 268905b261ecSmrg compat->groups[i].mask= wire->realMods; 269005b261ecSmrg compat->groups[i].real_mods= wire->realMods; 269105b261ecSmrg compat->groups[i].vmods= wire->virtualMods; 269205b261ecSmrg if (wire->virtualMods!=0) { 269305b261ecSmrg unsigned tmp; 269405b261ecSmrg tmp= XkbMaskForVMask(xkb,wire->virtualMods); 269505b261ecSmrg compat->groups[i].mask|= tmp; 269605b261ecSmrg } 269705b261ecSmrg data+= SIZEOF(xkbModsWireDesc); 269805b261ecSmrg wire= (xkbModsWireDesc *)data; 269905b261ecSmrg } 270005b261ecSmrg } 270105b261ecSmrg } 270205b261ecSmrg i= XkbPaddedSize((data-((char *)stuff))); 270305b261ecSmrg if ((i/4)!=stuff->length) { 270405b261ecSmrg ErrorF("Internal length error on read in ProcXkbSetCompatMap\n"); 270505b261ecSmrg return BadLength; 270605b261ecSmrg } 270705b261ecSmrg 270805b261ecSmrg if (dev->xkb_interest) { 270905b261ecSmrg xkbCompatMapNotify ev; 271005b261ecSmrg ev.deviceID = dev->id; 271105b261ecSmrg ev.changedGroups = stuff->groups; 271205b261ecSmrg ev.firstSI = stuff->firstSI; 271305b261ecSmrg ev.nSI = stuff->nSI; 271405b261ecSmrg ev.nTotalSI = compat->num_si; 271505b261ecSmrg XkbSendCompatMapNotify(dev,&ev); 271605b261ecSmrg } 271705b261ecSmrg 271805b261ecSmrg if (stuff->recomputeActions) { 271905b261ecSmrg XkbChangesRec change; 272005b261ecSmrg unsigned check; 272105b261ecSmrg XkbEventCauseRec cause; 272205b261ecSmrg 272305b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client); 272405b261ecSmrg bzero(&change,sizeof(XkbChangesRec)); 272505b261ecSmrg XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check, 272605b261ecSmrg &cause); 272705b261ecSmrg if (check) 272805b261ecSmrg XkbCheckSecondaryEffects(xkbi,check,&change,&cause); 272905b261ecSmrg XkbUpdateCoreDescription(dev,False); 273005b261ecSmrg XkbSendNotification(dev,&change,&cause); 273105b261ecSmrg } 273205b261ecSmrg return client->noClientException; 273305b261ecSmrg} 273405b261ecSmrg 273505b261ecSmrg/***====================================================================***/ 273605b261ecSmrg 273705b261ecSmrgint 273805b261ecSmrgProcXkbGetIndicatorState(ClientPtr client) 273905b261ecSmrg{ 274005b261ecSmrg xkbGetIndicatorStateReply rep; 274105b261ecSmrg XkbSrvLedInfoPtr sli; 274205b261ecSmrg DeviceIntPtr dev; 274305b261ecSmrg register int i; 274405b261ecSmrg 274505b261ecSmrg REQUEST(xkbGetIndicatorStateReq); 274605b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 274705b261ecSmrg 274805b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 274905b261ecSmrg return BadAccess; 275005b261ecSmrg 275105b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 275205b261ecSmrg 275305b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 275405b261ecSmrg XkbXI_IndicatorStateMask); 275505b261ecSmrg if (!sli) 275605b261ecSmrg return BadAlloc; 275705b261ecSmrg 275805b261ecSmrg rep.type = X_Reply; 275905b261ecSmrg rep.sequenceNumber = client->sequence; 276005b261ecSmrg rep.length = 0; 276105b261ecSmrg rep.deviceID = dev->id; 276205b261ecSmrg rep.state = sli->effectiveState; 276305b261ecSmrg 276405b261ecSmrg if (client->swapped) { 276505b261ecSmrg swaps(&rep.sequenceNumber,i); 276605b261ecSmrg swapl(&rep.state,i); 276705b261ecSmrg } 276805b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep); 276905b261ecSmrg return client->noClientException; 277005b261ecSmrg} 277105b261ecSmrg 277205b261ecSmrg/***====================================================================***/ 277305b261ecSmrg 277405b261ecSmrgstatic Status 277505b261ecSmrgXkbComputeGetIndicatorMapReplySize( 277605b261ecSmrg XkbIndicatorPtr indicators, 277705b261ecSmrg xkbGetIndicatorMapReply *rep) 277805b261ecSmrg{ 277905b261ecSmrgregister int i,bit; 278005b261ecSmrgint nIndicators; 278105b261ecSmrg 278205b261ecSmrg rep->realIndicators = indicators->phys_indicators; 278305b261ecSmrg for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 278405b261ecSmrg if (rep->which&bit) 278505b261ecSmrg nIndicators++; 278605b261ecSmrg } 278705b261ecSmrg rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4; 278805b261ecSmrg return Success; 278905b261ecSmrg} 279005b261ecSmrg 279105b261ecSmrgstatic int 279205b261ecSmrgXkbSendIndicatorMap( ClientPtr client, 279305b261ecSmrg XkbIndicatorPtr indicators, 279405b261ecSmrg xkbGetIndicatorMapReply * rep) 279505b261ecSmrg{ 279605b261ecSmrgint length; 279705b261ecSmrgCARD8 * map; 279805b261ecSmrgregister int i; 279905b261ecSmrgregister unsigned bit; 280005b261ecSmrg 280105b261ecSmrg length = rep->length*4; 280205b261ecSmrg if (length>0) { 280305b261ecSmrg CARD8 *to; 280405b261ecSmrg to= map= (CARD8 *)ALLOCATE_LOCAL(length); 280505b261ecSmrg if (map) { 280605b261ecSmrg xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to; 280705b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 280805b261ecSmrg if (rep->which&bit) { 280905b261ecSmrg wire->flags= indicators->maps[i].flags; 281005b261ecSmrg wire->whichGroups= indicators->maps[i].which_groups; 281105b261ecSmrg wire->groups= indicators->maps[i].groups; 281205b261ecSmrg wire->whichMods= indicators->maps[i].which_mods; 281305b261ecSmrg wire->mods= indicators->maps[i].mods.mask; 281405b261ecSmrg wire->realMods= indicators->maps[i].mods.real_mods; 281505b261ecSmrg wire->virtualMods= indicators->maps[i].mods.vmods; 281605b261ecSmrg wire->ctrls= indicators->maps[i].ctrls; 281705b261ecSmrg if (client->swapped) { 281805b261ecSmrg register int n; 281905b261ecSmrg swaps(&wire->virtualMods,n); 282005b261ecSmrg swapl(&wire->ctrls,n); 282105b261ecSmrg } 282205b261ecSmrg wire++; 282305b261ecSmrg } 282405b261ecSmrg } 282505b261ecSmrg to = (CARD8 *)wire; 282605b261ecSmrg if ((to-map)!=length) { 282705b261ecSmrg client->errorValue = _XkbErrCode2(0xff,length); 282805b261ecSmrg return BadLength; 282905b261ecSmrg } 283005b261ecSmrg } 283105b261ecSmrg else return BadAlloc; 283205b261ecSmrg } 283305b261ecSmrg else map = NULL; 283405b261ecSmrg if (client->swapped) { 283505b261ecSmrg swaps(&rep->sequenceNumber,i); 283605b261ecSmrg swapl(&rep->length,i); 283705b261ecSmrg swapl(&rep->which,i); 283805b261ecSmrg swapl(&rep->realIndicators,i); 283905b261ecSmrg } 284005b261ecSmrg WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep); 284105b261ecSmrg if (map) { 284205b261ecSmrg WriteToClient(client, length, (char *)map); 284305b261ecSmrg DEALLOCATE_LOCAL((char *)map); 284405b261ecSmrg } 284505b261ecSmrg return client->noClientException; 284605b261ecSmrg} 284705b261ecSmrg 284805b261ecSmrgint 284905b261ecSmrgProcXkbGetIndicatorMap(ClientPtr client) 285005b261ecSmrg{ 285105b261ecSmrgxkbGetIndicatorMapReply rep; 285205b261ecSmrgDeviceIntPtr dev; 285305b261ecSmrgXkbDescPtr xkb; 285405b261ecSmrgXkbIndicatorPtr leds; 285505b261ecSmrg 285605b261ecSmrg REQUEST(xkbGetIndicatorMapReq); 285705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 285805b261ecSmrg 285905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 286005b261ecSmrg return BadAccess; 286105b261ecSmrg 286205b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 286305b261ecSmrg 286405b261ecSmrg xkb= dev->key->xkbInfo->desc; 286505b261ecSmrg leds= xkb->indicators; 286605b261ecSmrg 286705b261ecSmrg rep.type = X_Reply; 286805b261ecSmrg rep.sequenceNumber = client->sequence; 286905b261ecSmrg rep.length = 0; 287005b261ecSmrg rep.deviceID = dev->id; 287105b261ecSmrg rep.which = stuff->which; 287205b261ecSmrg XkbComputeGetIndicatorMapReplySize(leds,&rep); 287305b261ecSmrg return XkbSendIndicatorMap(client,leds,&rep); 287405b261ecSmrg} 287505b261ecSmrg 287605b261ecSmrg/* FIXME: Needs to set indicator map on all core-sending devices. */ 287705b261ecSmrgint 287805b261ecSmrgProcXkbSetIndicatorMap(ClientPtr client) 287905b261ecSmrg{ 288005b261ecSmrg register int i,bit; 288105b261ecSmrg int nIndicators,why; 288205b261ecSmrg DeviceIntPtr dev; 288305b261ecSmrg XkbSrvInfoPtr xkbi; 288405b261ecSmrg xkbIndicatorMapWireDesc *from; 288505b261ecSmrg XkbSrvLedInfoPtr sli; 288605b261ecSmrg XkbEventCauseRec cause; 288705b261ecSmrg 288805b261ecSmrg REQUEST(xkbSetIndicatorMapReq); 288905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 289005b261ecSmrg 289105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 289205b261ecSmrg return BadAccess; 289305b261ecSmrg 289405b261ecSmrg dev = _XkbLookupKeyboard(stuff->deviceSpec,&why); 289505b261ecSmrg if (!dev) { 289605b261ecSmrg client->errorValue = _XkbErrCode2(why,stuff->deviceSpec); 289705b261ecSmrg return XkbKeyboardErrorCode; 289805b261ecSmrg } 289905b261ecSmrg xkbi= dev->key->xkbInfo; 290005b261ecSmrg 290105b261ecSmrg if (stuff->which==0) 290205b261ecSmrg return client->noClientException; 290305b261ecSmrg 290405b261ecSmrg for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 290505b261ecSmrg if (stuff->which&bit) 290605b261ecSmrg nIndicators++; 290705b261ecSmrg } 290805b261ecSmrg if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+ 290905b261ecSmrg (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) { 291005b261ecSmrg return BadLength; 291105b261ecSmrg } 291205b261ecSmrg 291305b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 291405b261ecSmrg XkbXI_IndicatorMapsMask); 291505b261ecSmrg if (!sli) 291605b261ecSmrg return BadAlloc; 291705b261ecSmrg 291805b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 291905b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 292005b261ecSmrg if (stuff->which&bit) { 292105b261ecSmrg if (client->swapped) { 292205b261ecSmrg register int n; 292305b261ecSmrg swaps(&from->virtualMods,n); 292405b261ecSmrg swapl(&from->ctrls,n); 292505b261ecSmrg } 292605b261ecSmrg CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup); 292705b261ecSmrg CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods); 292805b261ecSmrg from++; 292905b261ecSmrg } 293005b261ecSmrg } 293105b261ecSmrg 293205b261ecSmrg from = (xkbIndicatorMapWireDesc *)&stuff[1]; 293305b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 293405b261ecSmrg if (stuff->which&bit) { 293505b261ecSmrg sli->maps[i].flags = from->flags; 293605b261ecSmrg sli->maps[i].which_groups = from->whichGroups; 293705b261ecSmrg sli->maps[i].groups = from->groups; 293805b261ecSmrg sli->maps[i].which_mods = from->whichMods; 293905b261ecSmrg sli->maps[i].mods.mask = from->mods; 294005b261ecSmrg sli->maps[i].mods.real_mods = from->mods; 294105b261ecSmrg sli->maps[i].mods.vmods= from->virtualMods; 294205b261ecSmrg sli->maps[i].ctrls = from->ctrls; 294305b261ecSmrg if (from->virtualMods!=0) { 294405b261ecSmrg unsigned tmp; 294505b261ecSmrg tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods); 294605b261ecSmrg sli->maps[i].mods.mask= from->mods|tmp; 294705b261ecSmrg } 294805b261ecSmrg from++; 294905b261ecSmrg } 295005b261ecSmrg } 295105b261ecSmrg 295205b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); 295305b261ecSmrg XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause); 295405b261ecSmrg return client->noClientException; 295505b261ecSmrg} 295605b261ecSmrg 295705b261ecSmrg/***====================================================================***/ 295805b261ecSmrg 295905b261ecSmrgint 296005b261ecSmrgProcXkbGetNamedIndicator(ClientPtr client) 296105b261ecSmrg{ 296205b261ecSmrg DeviceIntPtr dev; 296305b261ecSmrg xkbGetNamedIndicatorReply rep; 296405b261ecSmrg register int i = 0; 296505b261ecSmrg XkbSrvLedInfoPtr sli; 296605b261ecSmrg XkbIndicatorMapPtr map = NULL; 296705b261ecSmrg 296805b261ecSmrg REQUEST(xkbGetNamedIndicatorReq); 296905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 297005b261ecSmrg 297105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 297205b261ecSmrg return BadAccess; 297305b261ecSmrg 297405b261ecSmrg CHK_LED_DEVICE(dev,stuff->deviceSpec); 297505b261ecSmrg CHK_ATOM_ONLY(stuff->indicator); 297605b261ecSmrg 297705b261ecSmrg sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0); 297805b261ecSmrg if (!sli) 297905b261ecSmrg return BadAlloc; 298005b261ecSmrg 298105b261ecSmrg i= 0; 298205b261ecSmrg map= NULL; 298305b261ecSmrg if ((sli->names)&&(sli->maps)) { 298405b261ecSmrg for (i=0;i<XkbNumIndicators;i++) { 298505b261ecSmrg if (stuff->indicator==sli->names[i]) { 298605b261ecSmrg map= &sli->maps[i]; 298705b261ecSmrg break; 298805b261ecSmrg } 298905b261ecSmrg } 299005b261ecSmrg } 299105b261ecSmrg 299205b261ecSmrg rep.type= X_Reply; 299305b261ecSmrg rep.length = 0; 299405b261ecSmrg rep.sequenceNumber = client->sequence; 299505b261ecSmrg rep.deviceID = dev->id; 299605b261ecSmrg rep.indicator= stuff->indicator; 299705b261ecSmrg if (map!=NULL) { 299805b261ecSmrg rep.found= True; 299905b261ecSmrg rep.on= ((sli->effectiveState&(1<<i))!=0); 300005b261ecSmrg rep.realIndicator= ((sli->physIndicators&(1<<i))!=0); 300105b261ecSmrg rep.ndx= i; 300205b261ecSmrg rep.flags= map->flags; 300305b261ecSmrg rep.whichGroups= map->which_groups; 300405b261ecSmrg rep.groups= map->groups; 300505b261ecSmrg rep.whichMods= map->which_mods; 300605b261ecSmrg rep.mods= map->mods.mask; 300705b261ecSmrg rep.realMods= map->mods.real_mods; 300805b261ecSmrg rep.virtualMods= map->mods.vmods; 300905b261ecSmrg rep.ctrls= map->ctrls; 301005b261ecSmrg rep.supported= True; 301105b261ecSmrg } 301205b261ecSmrg else { 301305b261ecSmrg rep.found= False; 301405b261ecSmrg rep.on= False; 301505b261ecSmrg rep.realIndicator= False; 301605b261ecSmrg rep.ndx= XkbNoIndicator; 301705b261ecSmrg rep.flags= 0; 301805b261ecSmrg rep.whichGroups= 0; 301905b261ecSmrg rep.groups= 0; 302005b261ecSmrg rep.whichMods= 0; 302105b261ecSmrg rep.mods= 0; 302205b261ecSmrg rep.realMods= 0; 302305b261ecSmrg rep.virtualMods= 0; 302405b261ecSmrg rep.ctrls= 0; 302505b261ecSmrg rep.supported= True; 302605b261ecSmrg } 302705b261ecSmrg if ( client->swapped ) { 302805b261ecSmrg register int n; 302905b261ecSmrg swapl(&rep.length,n); 303005b261ecSmrg swaps(&rep.sequenceNumber,n); 303105b261ecSmrg swapl(&rep.indicator,n); 303205b261ecSmrg swaps(&rep.virtualMods,n); 303305b261ecSmrg swapl(&rep.ctrls,n); 303405b261ecSmrg } 303505b261ecSmrg 303605b261ecSmrg WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep); 303705b261ecSmrg return client->noClientException; 303805b261ecSmrg} 303905b261ecSmrg 304005b261ecSmrg/* FIXME: Needs to set indicator on all core-sending devices. */ 304105b261ecSmrgint 304205b261ecSmrgProcXkbSetNamedIndicator(ClientPtr client) 304305b261ecSmrg{ 304405b261ecSmrg DeviceIntPtr dev,kbd; 304505b261ecSmrg XkbIndicatorMapPtr map; 304605b261ecSmrg XkbSrvLedInfoPtr sli; 304705b261ecSmrg register int led = 0; 304805b261ecSmrg unsigned extDevReason; 304905b261ecSmrg unsigned statec,namec,mapc; 305005b261ecSmrg XkbEventCauseRec cause; 305105b261ecSmrg xkbExtensionDeviceNotify ed; 305205b261ecSmrg XkbChangesRec changes; 305305b261ecSmrg 305405b261ecSmrg REQUEST(xkbSetNamedIndicatorReq); 305505b261ecSmrg REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 305605b261ecSmrg 305705b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 305805b261ecSmrg return BadAccess; 305905b261ecSmrg 306005b261ecSmrg CHK_LED_DEVICE(dev,stuff->deviceSpec); 306105b261ecSmrg CHK_ATOM_ONLY(stuff->indicator); 306205b261ecSmrg CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); 306305b261ecSmrg CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); 306405b261ecSmrg 306505b261ecSmrg extDevReason= 0; 306605b261ecSmrg 306705b261ecSmrg sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID, 306805b261ecSmrg XkbXI_IndicatorsMask); 306905b261ecSmrg if (!sli) 307005b261ecSmrg return BadAlloc; 307105b261ecSmrg 307205b261ecSmrg statec= mapc= namec= 0; 307305b261ecSmrg map= NULL; 307405b261ecSmrg if (sli->names && sli->maps) { 307505b261ecSmrg for (led=0;(led<XkbNumIndicators)&&(map==NULL);led++) { 307605b261ecSmrg if (sli->names[led]==stuff->indicator) { 307705b261ecSmrg map= &sli->maps[led]; 307805b261ecSmrg break; 307905b261ecSmrg } 308005b261ecSmrg } 308105b261ecSmrg } 308205b261ecSmrg if (map==NULL) { 308305b261ecSmrg if (!stuff->createMap) 308405b261ecSmrg return client->noClientException; 308505b261ecSmrg for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) { 308605b261ecSmrg if ((sli->names)&&(sli->maps)&&(sli->names[led]==None)&& 308705b261ecSmrg (!XkbIM_InUse(&sli->maps[led]))) { 308805b261ecSmrg map= &sli->maps[led]; 308905b261ecSmrg sli->names[led]= stuff->indicator; 309005b261ecSmrg break; 309105b261ecSmrg } 309205b261ecSmrg } 309305b261ecSmrg if (map==NULL) 309405b261ecSmrg return client->noClientException; 309505b261ecSmrg namec|= (1<<led); 309605b261ecSmrg sli->namesPresent|= ((stuff->indicator!=None)?(1<<led):0); 309705b261ecSmrg extDevReason|= XkbXI_IndicatorNamesMask; 309805b261ecSmrg } 309905b261ecSmrg 310005b261ecSmrg if (stuff->setMap) { 310105b261ecSmrg map->flags = stuff->flags; 310205b261ecSmrg map->which_groups = stuff->whichGroups; 310305b261ecSmrg map->groups = stuff->groups; 310405b261ecSmrg map->which_mods = stuff->whichMods; 310505b261ecSmrg map->mods.mask = stuff->realMods; 310605b261ecSmrg map->mods.real_mods = stuff->realMods; 310705b261ecSmrg map->mods.vmods= stuff->virtualMods; 310805b261ecSmrg map->ctrls = stuff->ctrls; 310905b261ecSmrg mapc|= (1<<led); 311005b261ecSmrg } 311105b261ecSmrg if ((stuff->setState)&&((map->flags&XkbIM_NoExplicit)==0)) { 311205b261ecSmrg if (stuff->on) sli->explicitState|= (1<<led); 311305b261ecSmrg else sli->explicitState&= ~(1<<led); 311405b261ecSmrg statec|= ((sli->effectiveState^sli->explicitState)&(1<<led)); 311505b261ecSmrg } 311605b261ecSmrg bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 311705b261ecSmrg bzero((char *)&changes,sizeof(XkbChangesRec)); 311805b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client); 311905b261ecSmrg if (namec) 312005b261ecSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 312105b261ecSmrg if (mapc) 312205b261ecSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 312305b261ecSmrg if (statec) 312405b261ecSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 312505b261ecSmrg 312605b261ecSmrg kbd= dev; 312705b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 312805b261ecSmrg kbd= (DeviceIntPtr)LookupKeyboardDevice(); 312905b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 313005b261ecSmrg return client->noClientException; 313105b261ecSmrg} 313205b261ecSmrg 313305b261ecSmrg/***====================================================================***/ 313405b261ecSmrg 313505b261ecSmrgstatic CARD32 313605b261ecSmrg_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) 313705b261ecSmrg{ 313805b261ecSmrgregister unsigned int i,bit,nAtoms; 313905b261ecSmrgregister CARD32 atomsPresent; 314005b261ecSmrg 314105b261ecSmrg for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { 314205b261ecSmrg if (atoms[i]!=None) { 314305b261ecSmrg atomsPresent|= bit; 314405b261ecSmrg nAtoms++; 314505b261ecSmrg } 314605b261ecSmrg } 314705b261ecSmrg if (count) 314805b261ecSmrg *count= nAtoms; 314905b261ecSmrg return atomsPresent; 315005b261ecSmrg} 315105b261ecSmrg 315205b261ecSmrgstatic char * 315305b261ecSmrg_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap) 315405b261ecSmrg{ 315505b261ecSmrgregister unsigned int i; 315605b261ecSmrgAtom *atm; 315705b261ecSmrg 315805b261ecSmrg atm = (Atom *)wire; 315905b261ecSmrg for (i=0;i<maxAtoms;i++) { 316005b261ecSmrg if (atoms[i]!=None) { 316105b261ecSmrg *atm= atoms[i]; 316205b261ecSmrg if (swap) { 316305b261ecSmrg register int n; 316405b261ecSmrg swapl(atm,n); 316505b261ecSmrg } 316605b261ecSmrg atm++; 316705b261ecSmrg } 316805b261ecSmrg } 316905b261ecSmrg return (char *)atm; 317005b261ecSmrg} 317105b261ecSmrg 317205b261ecSmrgstatic Status 317305b261ecSmrgXkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep) 317405b261ecSmrg{ 317505b261ecSmrgregister unsigned which,length; 317605b261ecSmrgregister int i; 317705b261ecSmrg 317805b261ecSmrg rep->minKeyCode= xkb->min_key_code; 317905b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 318005b261ecSmrg which= rep->which; 318105b261ecSmrg length= 0; 318205b261ecSmrg if (xkb->names!=NULL) { 318305b261ecSmrg if (which&XkbKeycodesNameMask) length++; 318405b261ecSmrg if (which&XkbGeometryNameMask) length++; 318505b261ecSmrg if (which&XkbSymbolsNameMask) length++; 318605b261ecSmrg if (which&XkbPhysSymbolsNameMask) length++; 318705b261ecSmrg if (which&XkbTypesNameMask) length++; 318805b261ecSmrg if (which&XkbCompatNameMask) length++; 318905b261ecSmrg } 319005b261ecSmrg else which&= ~XkbComponentNamesMask; 319105b261ecSmrg 319205b261ecSmrg if (xkb->map!=NULL) { 319305b261ecSmrg if (which&XkbKeyTypeNamesMask) 319405b261ecSmrg length+= xkb->map->num_types; 319505b261ecSmrg rep->nTypes= xkb->map->num_types; 319605b261ecSmrg if (which&XkbKTLevelNamesMask) { 319705b261ecSmrg XkbKeyTypePtr pType = xkb->map->types; 319805b261ecSmrg int nKTLevels = 0; 319905b261ecSmrg 320005b261ecSmrg length+= XkbPaddedSize(xkb->map->num_types)/4; 320105b261ecSmrg for (i=0;i<xkb->map->num_types;i++,pType++) { 320205b261ecSmrg if (pType->level_names!=NULL) 320305b261ecSmrg nKTLevels+= pType->num_levels; 320405b261ecSmrg } 320505b261ecSmrg rep->nKTLevels= nKTLevels; 320605b261ecSmrg length+= nKTLevels; 320705b261ecSmrg } 320805b261ecSmrg } 320905b261ecSmrg else { 321005b261ecSmrg rep->nTypes= 0; 321105b261ecSmrg rep->nKTLevels= 0; 321205b261ecSmrg which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask); 321305b261ecSmrg } 321405b261ecSmrg 321505b261ecSmrg rep->minKeyCode= xkb->min_key_code; 321605b261ecSmrg rep->maxKeyCode= xkb->max_key_code; 321705b261ecSmrg rep->indicators= 0; 321805b261ecSmrg rep->virtualMods= 0; 321905b261ecSmrg rep->groupNames= 0; 322005b261ecSmrg if (xkb->names!=NULL) { 322105b261ecSmrg if (which&XkbIndicatorNamesMask) { 322205b261ecSmrg int nLeds; 322305b261ecSmrg rep->indicators= 322405b261ecSmrg _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds); 322505b261ecSmrg length+= nLeds; 322605b261ecSmrg if (nLeds==0) 322705b261ecSmrg which&= ~XkbIndicatorNamesMask; 322805b261ecSmrg } 322905b261ecSmrg 323005b261ecSmrg if (which&XkbVirtualModNamesMask) { 323105b261ecSmrg int nVMods; 323205b261ecSmrg rep->virtualMods= 323305b261ecSmrg _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods); 323405b261ecSmrg length+= nVMods; 323505b261ecSmrg if (nVMods==0) 323605b261ecSmrg which&= ~XkbVirtualModNamesMask; 323705b261ecSmrg } 323805b261ecSmrg 323905b261ecSmrg if (which&XkbGroupNamesMask) { 324005b261ecSmrg int nGroups; 324105b261ecSmrg rep->groupNames= 324205b261ecSmrg _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups); 324305b261ecSmrg length+= nGroups; 324405b261ecSmrg if (nGroups==0) 324505b261ecSmrg which&= ~XkbGroupNamesMask; 324605b261ecSmrg } 324705b261ecSmrg 324805b261ecSmrg if ((which&XkbKeyNamesMask)&&(xkb->names->keys)) 324905b261ecSmrg length+= rep->nKeys; 325005b261ecSmrg else which&= ~XkbKeyNamesMask; 325105b261ecSmrg 325205b261ecSmrg if ((which&XkbKeyAliasesMask)&& 325305b261ecSmrg (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) { 325405b261ecSmrg rep->nKeyAliases= xkb->names->num_key_aliases; 325505b261ecSmrg length+= rep->nKeyAliases*2; 325605b261ecSmrg } 325705b261ecSmrg else { 325805b261ecSmrg which&= ~XkbKeyAliasesMask; 325905b261ecSmrg rep->nKeyAliases= 0; 326005b261ecSmrg } 326105b261ecSmrg 326205b261ecSmrg if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0)) 326305b261ecSmrg length+= xkb->names->num_rg; 326405b261ecSmrg else which&= ~XkbRGNamesMask; 326505b261ecSmrg } 326605b261ecSmrg else { 326705b261ecSmrg which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask); 326805b261ecSmrg which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask); 326905b261ecSmrg which&= ~XkbRGNamesMask; 327005b261ecSmrg } 327105b261ecSmrg 327205b261ecSmrg rep->length= length; 327305b261ecSmrg rep->which= which; 327405b261ecSmrg return Success; 327505b261ecSmrg} 327605b261ecSmrg 327705b261ecSmrgstatic int 327805b261ecSmrgXkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep) 327905b261ecSmrg{ 328005b261ecSmrgregister unsigned i,length,which; 328105b261ecSmrgchar * start; 328205b261ecSmrgchar * desc; 328305b261ecSmrgregister int n; 328405b261ecSmrg 328505b261ecSmrg length= rep->length*4; 328605b261ecSmrg which= rep->which; 328705b261ecSmrg if (client->swapped) { 328805b261ecSmrg swaps(&rep->sequenceNumber,n); 328905b261ecSmrg swapl(&rep->length,n); 329005b261ecSmrg swapl(&rep->which,n); 329105b261ecSmrg swaps(&rep->virtualMods,n); 329205b261ecSmrg swapl(&rep->indicators,n); 329305b261ecSmrg } 329405b261ecSmrg 329505b261ecSmrg start = desc = (char *)ALLOCATE_LOCAL(length); 329605b261ecSmrg if ( !start ) 329705b261ecSmrg return BadAlloc; 329805b261ecSmrg if (xkb->names) { 329905b261ecSmrg if (which&XkbKeycodesNameMask) { 330005b261ecSmrg *((CARD32 *)desc)= xkb->names->keycodes; 330105b261ecSmrg if (client->swapped) { 330205b261ecSmrg swapl(desc,n); 330305b261ecSmrg } 330405b261ecSmrg desc+= 4; 330505b261ecSmrg } 330605b261ecSmrg if (which&XkbGeometryNameMask) { 330705b261ecSmrg *((CARD32 *)desc)= xkb->names->geometry; 330805b261ecSmrg if (client->swapped) { 330905b261ecSmrg swapl(desc,n); 331005b261ecSmrg } 331105b261ecSmrg desc+= 4; 331205b261ecSmrg } 331305b261ecSmrg if (which&XkbSymbolsNameMask) { 331405b261ecSmrg *((CARD32 *)desc)= xkb->names->symbols; 331505b261ecSmrg if (client->swapped) { 331605b261ecSmrg swapl(desc,n); 331705b261ecSmrg } 331805b261ecSmrg desc+= 4; 331905b261ecSmrg } 332005b261ecSmrg if (which&XkbPhysSymbolsNameMask) { 332105b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 332205b261ecSmrg atm[0]= (CARD32)xkb->names->phys_symbols; 332305b261ecSmrg if (client->swapped) { 332405b261ecSmrg swapl(&atm[0],n); 332505b261ecSmrg } 332605b261ecSmrg desc+= 4; 332705b261ecSmrg } 332805b261ecSmrg if (which&XkbTypesNameMask) { 332905b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->types; 333005b261ecSmrg if (client->swapped) { 333105b261ecSmrg swapl(desc,n); 333205b261ecSmrg } 333305b261ecSmrg desc+= 4; 333405b261ecSmrg } 333505b261ecSmrg if (which&XkbCompatNameMask) { 333605b261ecSmrg *((CARD32 *)desc)= (CARD32)xkb->names->compat; 333705b261ecSmrg if (client->swapped) { 333805b261ecSmrg swapl(desc,n); 333905b261ecSmrg } 334005b261ecSmrg desc+= 4; 334105b261ecSmrg } 334205b261ecSmrg if (which&XkbKeyTypeNamesMask) { 334305b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 334405b261ecSmrg register XkbKeyTypePtr type= xkb->map->types; 334505b261ecSmrg 334605b261ecSmrg for (i=0;i<xkb->map->num_types;i++,atm++,type++) { 334705b261ecSmrg *atm= (CARD32)type->name; 334805b261ecSmrg if (client->swapped) { 334905b261ecSmrg swapl(atm,n); 335005b261ecSmrg } 335105b261ecSmrg } 335205b261ecSmrg desc= (char *)atm; 335305b261ecSmrg } 335405b261ecSmrg if (which&XkbKTLevelNamesMask && xkb->map) { 335505b261ecSmrg XkbKeyTypePtr type = xkb->map->types; 335605b261ecSmrg register CARD32 *atm; 335705b261ecSmrg for (i=0;i<rep->nTypes;i++,type++) { 335805b261ecSmrg *desc++ = type->num_levels; 335905b261ecSmrg } 336005b261ecSmrg desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes; 336105b261ecSmrg 336205b261ecSmrg atm= (CARD32 *)desc; 336305b261ecSmrg type = xkb->map->types; 336405b261ecSmrg for (i=0;i<xkb->map->num_types;i++,type++) { 336505b261ecSmrg register unsigned l; 336605b261ecSmrg if (type->level_names) { 336705b261ecSmrg for (l=0;l<type->num_levels;l++,atm++) { 336805b261ecSmrg *atm= type->level_names[l]; 336905b261ecSmrg if (client->swapped) { 337005b261ecSmrg swapl(atm,n); 337105b261ecSmrg } 337205b261ecSmrg } 337305b261ecSmrg desc+= type->num_levels*4; 337405b261ecSmrg } 337505b261ecSmrg } 337605b261ecSmrg } 337705b261ecSmrg if (which&XkbIndicatorNamesMask) { 337805b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators, 337905b261ecSmrg client->swapped); 338005b261ecSmrg } 338105b261ecSmrg if (which&XkbVirtualModNamesMask) { 338205b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods, 338305b261ecSmrg client->swapped); 338405b261ecSmrg } 338505b261ecSmrg if (which&XkbGroupNamesMask) { 338605b261ecSmrg desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups, 338705b261ecSmrg client->swapped); 338805b261ecSmrg } 338905b261ecSmrg if (which&XkbKeyNamesMask) { 339005b261ecSmrg for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) { 339105b261ecSmrg *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey]; 339205b261ecSmrg } 339305b261ecSmrg } 339405b261ecSmrg if (which&XkbKeyAliasesMask) { 339505b261ecSmrg XkbKeyAliasPtr pAl; 339605b261ecSmrg pAl= xkb->names->key_aliases; 339705b261ecSmrg for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) { 339805b261ecSmrg *((XkbKeyAliasPtr)desc)= *pAl; 339905b261ecSmrg } 340005b261ecSmrg } 340105b261ecSmrg if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) { 340205b261ecSmrg register CARD32 *atm= (CARD32 *)desc; 340305b261ecSmrg for (i=0;i<rep->nRadioGroups;i++,atm++) { 340405b261ecSmrg *atm= (CARD32)xkb->names->radio_groups[i]; 340505b261ecSmrg if (client->swapped) { 340605b261ecSmrg swapl(atm,n); 340705b261ecSmrg } 340805b261ecSmrg } 340905b261ecSmrg desc+= rep->nRadioGroups*4; 341005b261ecSmrg } 341105b261ecSmrg } 341205b261ecSmrg 341305b261ecSmrg if ((desc-start)!=(length)) { 341405b261ecSmrg ErrorF("BOGUS LENGTH in write names, expected %d, got %ld\n", 341505b261ecSmrg length, (unsigned long)(desc-start)); 341605b261ecSmrg } 341705b261ecSmrg WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep); 341805b261ecSmrg WriteToClient(client, length, start); 341905b261ecSmrg DEALLOCATE_LOCAL((char *)start); 342005b261ecSmrg return client->noClientException; 342105b261ecSmrg} 342205b261ecSmrg 342305b261ecSmrgint 342405b261ecSmrgProcXkbGetNames(ClientPtr client) 342505b261ecSmrg{ 342605b261ecSmrg DeviceIntPtr dev; 342705b261ecSmrg XkbDescPtr xkb; 342805b261ecSmrg xkbGetNamesReply rep; 342905b261ecSmrg 343005b261ecSmrg REQUEST(xkbGetNamesReq); 343105b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamesReq); 343205b261ecSmrg 343305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 343405b261ecSmrg return BadAccess; 343505b261ecSmrg 343605b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 343705b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 343805b261ecSmrg 343905b261ecSmrg xkb = dev->key->xkbInfo->desc; 344005b261ecSmrg rep.type= X_Reply; 344105b261ecSmrg rep.sequenceNumber= client->sequence; 344205b261ecSmrg rep.length = 0; 344305b261ecSmrg rep.deviceID = dev->id; 344405b261ecSmrg rep.which = stuff->which; 344505b261ecSmrg rep.nTypes = xkb->map->num_types; 344605b261ecSmrg rep.firstKey = xkb->min_key_code; 344705b261ecSmrg rep.nKeys = XkbNumKeys(xkb); 344805b261ecSmrg if (xkb->names!=NULL) { 344905b261ecSmrg rep.nKeyAliases= xkb->names->num_key_aliases; 345005b261ecSmrg rep.nRadioGroups = xkb->names->num_rg; 345105b261ecSmrg } 345205b261ecSmrg else { 345305b261ecSmrg rep.nKeyAliases= rep.nRadioGroups= 0; 345405b261ecSmrg } 345505b261ecSmrg XkbComputeGetNamesReplySize(xkb,&rep); 345605b261ecSmrg return XkbSendNames(client,xkb,&rep); 345705b261ecSmrg} 345805b261ecSmrg 345905b261ecSmrg/***====================================================================***/ 346005b261ecSmrg 346105b261ecSmrgstatic CARD32 * 346205b261ecSmrg_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError) 346305b261ecSmrg{ 346405b261ecSmrgregister int i; 346505b261ecSmrg 346605b261ecSmrg for (i=0;i<nAtoms;i++,wire++) { 346705b261ecSmrg if (swapped) { 346805b261ecSmrg register int n; 346905b261ecSmrg swapl(wire,n); 347005b261ecSmrg } 347105b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) { 347205b261ecSmrg *pError= ((Atom)*wire); 347305b261ecSmrg return NULL; 347405b261ecSmrg } 347505b261ecSmrg } 347605b261ecSmrg return wire; 347705b261ecSmrg} 347805b261ecSmrg 347905b261ecSmrgstatic CARD32 * 348005b261ecSmrg_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped, 348105b261ecSmrg Atom *pError) 348205b261ecSmrg{ 348305b261ecSmrgregister unsigned i,bit; 348405b261ecSmrg 348505b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 348605b261ecSmrg if ((present&bit)==0) 348705b261ecSmrg continue; 348805b261ecSmrg if (swapped) { 348905b261ecSmrg register int n; 349005b261ecSmrg swapl(wire,n); 349105b261ecSmrg } 349205b261ecSmrg if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) { 349305b261ecSmrg *pError= (Atom)*wire; 349405b261ecSmrg return NULL; 349505b261ecSmrg } 349605b261ecSmrg wire++; 349705b261ecSmrg } 349805b261ecSmrg return wire; 349905b261ecSmrg} 350005b261ecSmrg 350105b261ecSmrgstatic Atom * 350205b261ecSmrg_XkbCopyMaskedAtoms( Atom *wire, 350305b261ecSmrg Atom *dest, 350405b261ecSmrg int nAtoms, 350505b261ecSmrg CARD32 present) 350605b261ecSmrg{ 350705b261ecSmrgregister int i,bit; 350805b261ecSmrg 350905b261ecSmrg for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 351005b261ecSmrg if ((present&bit)==0) 351105b261ecSmrg continue; 351205b261ecSmrg dest[i]= *wire++; 351305b261ecSmrg } 351405b261ecSmrg return wire; 351505b261ecSmrg} 351605b261ecSmrg 351705b261ecSmrgstatic Bool 351805b261ecSmrg_XkbCheckTypeName(Atom name,int typeNdx) 351905b261ecSmrg{ 352005b261ecSmrgchar * str; 352105b261ecSmrg 352205b261ecSmrg str= NameForAtom(name); 352305b261ecSmrg if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)|| 352405b261ecSmrg (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0)) 352505b261ecSmrg return False; 352605b261ecSmrg return True; 352705b261ecSmrg} 352805b261ecSmrg 352905b261ecSmrg/* FIXME: Needs to set names on all core-sending devices. */ 353005b261ecSmrgint 353105b261ecSmrgProcXkbSetNames(ClientPtr client) 353205b261ecSmrg{ 353305b261ecSmrg DeviceIntPtr dev; 353405b261ecSmrg XkbDescRec *xkb; 353505b261ecSmrg XkbNamesRec *names; 353605b261ecSmrg xkbNamesNotify nn; 353705b261ecSmrg CARD32 *tmp; 353805b261ecSmrg Atom bad; 353905b261ecSmrg 354005b261ecSmrg REQUEST(xkbSetNamesReq); 354105b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 354205b261ecSmrg 354305b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 354405b261ecSmrg return BadAccess; 354505b261ecSmrg 354605b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 354705b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 354805b261ecSmrg 354905b261ecSmrg xkb = dev->key->xkbInfo->desc; 355005b261ecSmrg names = xkb->names; 355105b261ecSmrg tmp = (CARD32 *)&stuff[1]; 355205b261ecSmrg 355305b261ecSmrg if (stuff->which&XkbKeycodesNameMask) { 355405b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 355505b261ecSmrg if (!tmp) { 355605b261ecSmrg client->errorValue = bad; 355705b261ecSmrg return BadAtom; 355805b261ecSmrg } 355905b261ecSmrg } 356005b261ecSmrg if (stuff->which&XkbGeometryNameMask) { 356105b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 356205b261ecSmrg if (!tmp) { 356305b261ecSmrg client->errorValue = bad; 356405b261ecSmrg return BadAtom; 356505b261ecSmrg } 356605b261ecSmrg } 356705b261ecSmrg if (stuff->which&XkbSymbolsNameMask) { 356805b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 356905b261ecSmrg if (!tmp) { 357005b261ecSmrg client->errorValue = bad; 357105b261ecSmrg return BadAtom; 357205b261ecSmrg } 357305b261ecSmrg } 357405b261ecSmrg if (stuff->which&XkbPhysSymbolsNameMask) { 357505b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 357605b261ecSmrg if (!tmp) { 357705b261ecSmrg client->errorValue= bad; 357805b261ecSmrg return BadAtom; 357905b261ecSmrg } 358005b261ecSmrg } 358105b261ecSmrg if (stuff->which&XkbTypesNameMask) { 358205b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 358305b261ecSmrg if (!tmp) { 358405b261ecSmrg client->errorValue = bad; 358505b261ecSmrg return BadAtom; 358605b261ecSmrg } 358705b261ecSmrg } 358805b261ecSmrg if (stuff->which&XkbCompatNameMask) { 358905b261ecSmrg tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 359005b261ecSmrg if (!tmp) { 359105b261ecSmrg client->errorValue = bad; 359205b261ecSmrg return BadAtom; 359305b261ecSmrg } 359405b261ecSmrg } 359505b261ecSmrg if (stuff->which&XkbKeyTypeNamesMask) { 359605b261ecSmrg register int i; 359705b261ecSmrg CARD32 *old; 359805b261ecSmrg if ( stuff->nTypes<1 ) { 359905b261ecSmrg client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); 360005b261ecSmrg return BadValue; 360105b261ecSmrg } 360205b261ecSmrg if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { 360305b261ecSmrg client->errorValue = _XkbErrCode4(0x03,stuff->firstType, 360405b261ecSmrg stuff->nTypes, 360505b261ecSmrg xkb->map->num_types); 360605b261ecSmrg return BadValue; 360705b261ecSmrg } 360805b261ecSmrg if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { 360905b261ecSmrg client->errorValue = _XkbErrCode2(0x04,stuff->firstType); 361005b261ecSmrg return BadAccess; 361105b261ecSmrg } 361205b261ecSmrg old= tmp; 361305b261ecSmrg tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); 361405b261ecSmrg if (!tmp) { 361505b261ecSmrg client->errorValue= bad; 361605b261ecSmrg return BadAtom; 361705b261ecSmrg } 361805b261ecSmrg for (i=0;i<stuff->nTypes;i++,old++) { 361905b261ecSmrg if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) 362005b261ecSmrg client->errorValue= _XkbErrCode2(0x05,i); 362105b261ecSmrg } 362205b261ecSmrg } 362305b261ecSmrg if (stuff->which&XkbKTLevelNamesMask) { 362405b261ecSmrg register unsigned i; 362505b261ecSmrg XkbKeyTypePtr type; 362605b261ecSmrg CARD8 * width; 362705b261ecSmrg if ( stuff->nKTLevels<1 ) { 362805b261ecSmrg client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); 362905b261ecSmrg return BadValue; 363005b261ecSmrg } 363105b261ecSmrg if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= 363205b261ecSmrg xkb->map->num_types) { 363305b261ecSmrg client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, 363405b261ecSmrg stuff->nKTLevels,xkb->map->num_types); 363505b261ecSmrg return BadValue; 363605b261ecSmrg } 363705b261ecSmrg width = (CARD8 *)tmp; 363805b261ecSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 363905b261ecSmrg type = &xkb->map->types[stuff->firstKTLevel]; 364005b261ecSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 364105b261ecSmrg if (width[i]==0) 364205b261ecSmrg continue; 364305b261ecSmrg else if (width[i]!=type->num_levels) { 364405b261ecSmrg client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, 364505b261ecSmrg type->num_levels,width[i]); 364605b261ecSmrg return BadMatch; 364705b261ecSmrg } 364805b261ecSmrg tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); 364905b261ecSmrg if (!tmp) { 365005b261ecSmrg client->errorValue= bad; 365105b261ecSmrg return BadAtom; 365205b261ecSmrg } 365305b261ecSmrg } 365405b261ecSmrg } 365505b261ecSmrg if (stuff->which&XkbIndicatorNamesMask) { 365605b261ecSmrg if (stuff->indicators==0) { 365705b261ecSmrg client->errorValue= 0x08; 365805b261ecSmrg return BadMatch; 365905b261ecSmrg } 366005b261ecSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, 366105b261ecSmrg client->swapped,&bad); 366205b261ecSmrg if (!tmp) { 366305b261ecSmrg client->errorValue= bad; 366405b261ecSmrg return BadAtom; 366505b261ecSmrg } 366605b261ecSmrg } 366705b261ecSmrg if (stuff->which&XkbVirtualModNamesMask) { 366805b261ecSmrg if (stuff->virtualMods==0) { 366905b261ecSmrg client->errorValue= 0x09; 367005b261ecSmrg return BadMatch; 367105b261ecSmrg } 367205b261ecSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, 367305b261ecSmrg (CARD32)stuff->virtualMods, 367405b261ecSmrg client->swapped,&bad); 367505b261ecSmrg if (!tmp) { 367605b261ecSmrg client->errorValue = bad; 367705b261ecSmrg return BadAtom; 367805b261ecSmrg } 367905b261ecSmrg } 368005b261ecSmrg if (stuff->which&XkbGroupNamesMask) { 368105b261ecSmrg if (stuff->groupNames==0) { 368205b261ecSmrg client->errorValue= 0x0a; 368305b261ecSmrg return BadMatch; 368405b261ecSmrg } 368505b261ecSmrg tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, 368605b261ecSmrg (CARD32)stuff->groupNames, 368705b261ecSmrg client->swapped,&bad); 368805b261ecSmrg if (!tmp) { 368905b261ecSmrg client->errorValue = bad; 369005b261ecSmrg return BadAtom; 369105b261ecSmrg } 369205b261ecSmrg } 369305b261ecSmrg if (stuff->which&XkbKeyNamesMask) { 369405b261ecSmrg if (stuff->firstKey<(unsigned)xkb->min_key_code) { 369505b261ecSmrg client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, 369605b261ecSmrg stuff->firstKey); 369705b261ecSmrg return BadValue; 369805b261ecSmrg } 369905b261ecSmrg if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| 370005b261ecSmrg (stuff->nKeys<1)) { 370105b261ecSmrg client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, 370205b261ecSmrg stuff->firstKey,stuff->nKeys); 370305b261ecSmrg return BadValue; 370405b261ecSmrg } 370505b261ecSmrg tmp+= stuff->nKeys; 370605b261ecSmrg } 370705b261ecSmrg if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { 370805b261ecSmrg tmp+= stuff->nKeyAliases*2; 370905b261ecSmrg } 371005b261ecSmrg if (stuff->which&XkbRGNamesMask) { 371105b261ecSmrg if ( stuff->nRadioGroups<1 ) { 371205b261ecSmrg client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); 371305b261ecSmrg return BadValue; 371405b261ecSmrg } 371505b261ecSmrg tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); 371605b261ecSmrg if (!tmp) { 371705b261ecSmrg client->errorValue= bad; 371805b261ecSmrg return BadAtom; 371905b261ecSmrg } 372005b261ecSmrg } 372105b261ecSmrg if ((tmp-((CARD32 *)stuff))!=stuff->length) { 372205b261ecSmrg client->errorValue = stuff->length; 372305b261ecSmrg return BadLength; 372405b261ecSmrg } 372505b261ecSmrg if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, 372605b261ecSmrg stuff->nKeyAliases)!=Success) { 372705b261ecSmrg return BadAlloc; 372805b261ecSmrg } 372905b261ecSmrg 373005b261ecSmrg /* everything is okay -- update names */ 373105b261ecSmrg bzero(&nn,sizeof(xkbNamesNotify)); 373205b261ecSmrg nn.changed= stuff->which; 373305b261ecSmrg tmp = (CARD32 *)&stuff[1]; 373405b261ecSmrg if (stuff->which&XkbKeycodesNameMask) 373505b261ecSmrg names->keycodes= *tmp++; 373605b261ecSmrg if (stuff->which&XkbGeometryNameMask) 373705b261ecSmrg names->geometry= *tmp++; 373805b261ecSmrg if (stuff->which&XkbSymbolsNameMask) 373905b261ecSmrg names->symbols= *tmp++; 374005b261ecSmrg if (stuff->which&XkbPhysSymbolsNameMask) 374105b261ecSmrg names->phys_symbols= *tmp++; 374205b261ecSmrg if (stuff->which&XkbTypesNameMask) 374305b261ecSmrg names->types= *tmp++; 374405b261ecSmrg if (stuff->which&XkbCompatNameMask) 374505b261ecSmrg names->compat= *tmp++; 374605b261ecSmrg if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { 374705b261ecSmrg register unsigned i; 374805b261ecSmrg register XkbKeyTypePtr type; 374905b261ecSmrg 375005b261ecSmrg type= &xkb->map->types[stuff->firstType]; 375105b261ecSmrg for (i=0;i<stuff->nTypes;i++,type++) { 375205b261ecSmrg type->name= *tmp++; 375305b261ecSmrg } 375405b261ecSmrg nn.firstType= stuff->firstType; 375505b261ecSmrg nn.nTypes= stuff->nTypes; 375605b261ecSmrg } 375705b261ecSmrg if (stuff->which&XkbKTLevelNamesMask) { 375805b261ecSmrg register XkbKeyTypePtr type; 375905b261ecSmrg register unsigned i; 376005b261ecSmrg CARD8 *width; 376105b261ecSmrg 376205b261ecSmrg width = (CARD8 *)tmp; 376305b261ecSmrg tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 376405b261ecSmrg type= &xkb->map->types[stuff->firstKTLevel]; 376505b261ecSmrg for (i=0;i<stuff->nKTLevels;i++,type++) { 376605b261ecSmrg if (width[i]>0) { 376705b261ecSmrg if (type->level_names) { 376805b261ecSmrg register unsigned n; 376905b261ecSmrg for (n=0;n<width[i];n++) { 377005b261ecSmrg type->level_names[n]= tmp[n]; 377105b261ecSmrg } 377205b261ecSmrg } 377305b261ecSmrg tmp+= width[i]; 377405b261ecSmrg } 377505b261ecSmrg } 377605b261ecSmrg nn.firstLevelName= 0; 377705b261ecSmrg nn.nLevelNames= stuff->nTypes; 377805b261ecSmrg } 377905b261ecSmrg if (stuff->which&XkbIndicatorNamesMask) { 378005b261ecSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, 378105b261ecSmrg stuff->indicators); 378205b261ecSmrg nn.changedIndicators= stuff->indicators; 378305b261ecSmrg } 378405b261ecSmrg if (stuff->which&XkbVirtualModNamesMask) { 378505b261ecSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, 378605b261ecSmrg stuff->virtualMods); 378705b261ecSmrg nn.changedVirtualMods= stuff->virtualMods; 378805b261ecSmrg } 378905b261ecSmrg if (stuff->which&XkbGroupNamesMask) { 379005b261ecSmrg tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, 379105b261ecSmrg stuff->groupNames); 379205b261ecSmrg nn.changedVirtualMods= stuff->groupNames; 379305b261ecSmrg } 379405b261ecSmrg if (stuff->which&XkbKeyNamesMask) { 379505b261ecSmrg memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, 379605b261ecSmrg stuff->nKeys*XkbKeyNameLength); 379705b261ecSmrg tmp+= stuff->nKeys; 379805b261ecSmrg nn.firstKey= stuff->firstKey; 379905b261ecSmrg nn.nKeys= stuff->nKeys; 380005b261ecSmrg } 380105b261ecSmrg if (stuff->which&XkbKeyAliasesMask) { 380205b261ecSmrg if (stuff->nKeyAliases>0) { 380305b261ecSmrg register int na= stuff->nKeyAliases; 380405b261ecSmrg if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) 380505b261ecSmrg return BadAlloc; 380605b261ecSmrg memcpy((char *)names->key_aliases,(char *)tmp, 380705b261ecSmrg stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); 380805b261ecSmrg tmp+= stuff->nKeyAliases*2; 380905b261ecSmrg } 381005b261ecSmrg else if (names->key_aliases!=NULL) { 381105b261ecSmrg _XkbFree(names->key_aliases); 381205b261ecSmrg names->key_aliases= NULL; 381305b261ecSmrg names->num_key_aliases= 0; 381405b261ecSmrg } 381505b261ecSmrg nn.nAliases= names->num_key_aliases; 381605b261ecSmrg } 381705b261ecSmrg if (stuff->which&XkbRGNamesMask) { 381805b261ecSmrg if (stuff->nRadioGroups>0) { 381905b261ecSmrg register unsigned i,nrg; 382005b261ecSmrg nrg= stuff->nRadioGroups; 382105b261ecSmrg if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) 382205b261ecSmrg return BadAlloc; 382305b261ecSmrg 382405b261ecSmrg for (i=0;i<stuff->nRadioGroups;i++) { 382505b261ecSmrg names->radio_groups[i]= tmp[i]; 382605b261ecSmrg } 382705b261ecSmrg tmp+= stuff->nRadioGroups; 382805b261ecSmrg } 382905b261ecSmrg else if (names->radio_groups) { 383005b261ecSmrg _XkbFree(names->radio_groups); 383105b261ecSmrg names->radio_groups= NULL; 383205b261ecSmrg names->num_rg= 0; 383305b261ecSmrg } 383405b261ecSmrg nn.nRadioGroups= names->num_rg; 383505b261ecSmrg } 383605b261ecSmrg if (nn.changed) { 383705b261ecSmrg Bool needExtEvent; 383805b261ecSmrg needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; 383905b261ecSmrg XkbSendNamesNotify(dev,&nn); 384005b261ecSmrg if (needExtEvent) { 384105b261ecSmrg XkbSrvLedInfoPtr sli; 384205b261ecSmrg xkbExtensionDeviceNotify edev; 384305b261ecSmrg register int i; 384405b261ecSmrg register unsigned bit; 384505b261ecSmrg 384605b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 384705b261ecSmrg XkbXI_IndicatorsMask); 384805b261ecSmrg sli->namesPresent= 0; 384905b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 385005b261ecSmrg if (names->indicators[i]!=None) 385105b261ecSmrg sli->namesPresent|= bit; 385205b261ecSmrg } 385305b261ecSmrg bzero(&edev,sizeof(xkbExtensionDeviceNotify)); 385405b261ecSmrg edev.reason= XkbXI_IndicatorNamesMask; 385505b261ecSmrg edev.ledClass= KbdFeedbackClass; 385605b261ecSmrg edev.ledID= dev->kbdfeed->ctrl.id; 385705b261ecSmrg edev.ledsDefined= sli->namesPresent|sli->mapsPresent; 385805b261ecSmrg edev.ledState= sli->effectiveState; 385905b261ecSmrg edev.firstBtn= 0; 386005b261ecSmrg edev.nBtns= 0; 386105b261ecSmrg edev.supported= XkbXI_AllFeaturesMask; 386205b261ecSmrg edev.unsupported= 0; 386305b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&edev); 386405b261ecSmrg } 386505b261ecSmrg } 386605b261ecSmrg return client->noClientException; 386705b261ecSmrg} 386805b261ecSmrg 386905b261ecSmrg/***====================================================================***/ 387005b261ecSmrg 387105b261ecSmrg#include <X11/extensions/XKBgeom.h> 387205b261ecSmrg 387305b261ecSmrg#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 387405b261ecSmrg 387505b261ecSmrgstatic char * 387605b261ecSmrgXkbWriteCountedString(char *wire,char *str,Bool swap) 387705b261ecSmrg{ 387805b261ecSmrgCARD16 len,*pLen; 387905b261ecSmrg 388005b261ecSmrg len= (str?strlen(str):0); 388105b261ecSmrg pLen= (CARD16 *)wire; 388205b261ecSmrg *pLen= len; 388305b261ecSmrg if (swap) { 388405b261ecSmrg register int n; 388505b261ecSmrg swaps(pLen,n); 388605b261ecSmrg } 388705b261ecSmrg memcpy(&wire[2],str,len); 388805b261ecSmrg wire+= ((2+len+3)/4)*4; 388905b261ecSmrg return wire; 389005b261ecSmrg} 389105b261ecSmrg 389205b261ecSmrgstatic int 389305b261ecSmrgXkbSizeGeomProperties(XkbGeometryPtr geom) 389405b261ecSmrg{ 389505b261ecSmrgregister int i,size; 389605b261ecSmrgXkbPropertyPtr prop; 389705b261ecSmrg 389805b261ecSmrg for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 389905b261ecSmrg size+= XkbSizeCountedString(prop->name); 390005b261ecSmrg size+= XkbSizeCountedString(prop->value); 390105b261ecSmrg } 390205b261ecSmrg return size; 390305b261ecSmrg} 390405b261ecSmrg 390505b261ecSmrgstatic char * 390605b261ecSmrgXkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap) 390705b261ecSmrg{ 390805b261ecSmrgregister int i; 390905b261ecSmrgregister XkbPropertyPtr prop; 391005b261ecSmrg 391105b261ecSmrg for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 391205b261ecSmrg wire= XkbWriteCountedString(wire,prop->name,swap); 391305b261ecSmrg wire= XkbWriteCountedString(wire,prop->value,swap); 391405b261ecSmrg } 391505b261ecSmrg return wire; 391605b261ecSmrg} 391705b261ecSmrg 391805b261ecSmrgstatic int 391905b261ecSmrgXkbSizeGeomKeyAliases(XkbGeometryPtr geom) 392005b261ecSmrg{ 392105b261ecSmrg return geom->num_key_aliases*(2*XkbKeyNameLength); 392205b261ecSmrg} 392305b261ecSmrg 392405b261ecSmrgstatic char * 392505b261ecSmrgXkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap) 392605b261ecSmrg{ 392705b261ecSmrgregister int sz; 392805b261ecSmrg 392905b261ecSmrg sz= geom->num_key_aliases*(XkbKeyNameLength*2); 393005b261ecSmrg if (sz>0) { 393105b261ecSmrg memcpy(wire,(char *)geom->key_aliases,sz); 393205b261ecSmrg wire+= sz; 393305b261ecSmrg } 393405b261ecSmrg return wire; 393505b261ecSmrg} 393605b261ecSmrg 393705b261ecSmrgstatic int 393805b261ecSmrgXkbSizeGeomColors(XkbGeometryPtr geom) 393905b261ecSmrg{ 394005b261ecSmrgregister int i,size; 394105b261ecSmrgregister XkbColorPtr color; 394205b261ecSmrg 394305b261ecSmrg for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { 394405b261ecSmrg size+= XkbSizeCountedString(color->spec); 394505b261ecSmrg } 394605b261ecSmrg return size; 394705b261ecSmrg} 394805b261ecSmrg 394905b261ecSmrgstatic char * 395005b261ecSmrgXkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap) 395105b261ecSmrg{ 395205b261ecSmrgregister int i; 395305b261ecSmrgregister XkbColorPtr color; 395405b261ecSmrg 395505b261ecSmrg for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 395605b261ecSmrg wire= XkbWriteCountedString(wire,color->spec,swap); 395705b261ecSmrg } 395805b261ecSmrg return wire; 395905b261ecSmrg} 396005b261ecSmrg 396105b261ecSmrgstatic int 396205b261ecSmrgXkbSizeGeomShapes(XkbGeometryPtr geom) 396305b261ecSmrg{ 396405b261ecSmrgregister int i,size; 396505b261ecSmrgregister XkbShapePtr shape; 396605b261ecSmrg 396705b261ecSmrg for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 396805b261ecSmrg register int n; 396905b261ecSmrg register XkbOutlinePtr ol; 397005b261ecSmrg size+= SIZEOF(xkbShapeWireDesc); 397105b261ecSmrg for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 397205b261ecSmrg size+= SIZEOF(xkbOutlineWireDesc); 397305b261ecSmrg size+= ol->num_points*SIZEOF(xkbPointWireDesc); 397405b261ecSmrg } 397505b261ecSmrg } 397605b261ecSmrg return size; 397705b261ecSmrg} 397805b261ecSmrg 397905b261ecSmrgstatic char * 398005b261ecSmrgXkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap) 398105b261ecSmrg{ 398205b261ecSmrgint i; 398305b261ecSmrgXkbShapePtr shape; 398405b261ecSmrgxkbShapeWireDesc * shapeWire; 398505b261ecSmrg 398605b261ecSmrg for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 398705b261ecSmrg register int o; 398805b261ecSmrg XkbOutlinePtr ol; 398905b261ecSmrg xkbOutlineWireDesc * olWire; 399005b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 399105b261ecSmrg shapeWire->name= shape->name; 399205b261ecSmrg shapeWire->nOutlines= shape->num_outlines; 399305b261ecSmrg if (shape->primary!=NULL) 399405b261ecSmrg shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); 399505b261ecSmrg else shapeWire->primaryNdx= XkbNoShape; 399605b261ecSmrg if (shape->approx!=NULL) 399705b261ecSmrg shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); 399805b261ecSmrg else shapeWire->approxNdx= XkbNoShape; 399905b261ecSmrg if (swap) { 400005b261ecSmrg register int n; 400105b261ecSmrg swapl(&shapeWire->name,n); 400205b261ecSmrg } 400305b261ecSmrg wire= (char *)&shapeWire[1]; 400405b261ecSmrg for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 400505b261ecSmrg register int p; 400605b261ecSmrg XkbPointPtr pt; 400705b261ecSmrg xkbPointWireDesc * ptWire; 400805b261ecSmrg olWire= (xkbOutlineWireDesc *)wire; 400905b261ecSmrg olWire->nPoints= ol->num_points; 401005b261ecSmrg olWire->cornerRadius= ol->corner_radius; 401105b261ecSmrg wire= (char *)&olWire[1]; 401205b261ecSmrg ptWire= (xkbPointWireDesc *)wire; 401305b261ecSmrg for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 401405b261ecSmrg ptWire[p].x= pt->x; 401505b261ecSmrg ptWire[p].y= pt->y; 401605b261ecSmrg if (swap) { 401705b261ecSmrg register int n; 401805b261ecSmrg swaps(&ptWire[p].x,n); 401905b261ecSmrg swaps(&ptWire[p].y,n); 402005b261ecSmrg } 402105b261ecSmrg } 402205b261ecSmrg wire= (char *)&ptWire[ol->num_points]; 402305b261ecSmrg } 402405b261ecSmrg } 402505b261ecSmrg return wire; 402605b261ecSmrg} 402705b261ecSmrg 402805b261ecSmrgstatic int 402905b261ecSmrgXkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) 403005b261ecSmrg{ 403105b261ecSmrgregister int i,size; 403205b261ecSmrg 403305b261ecSmrg for (i=size=0;i<num_doodads;i++,doodad++) { 403405b261ecSmrg size+= SIZEOF(xkbAnyDoodadWireDesc); 403505b261ecSmrg if (doodad->any.type==XkbTextDoodad) { 403605b261ecSmrg size+= XkbSizeCountedString(doodad->text.text); 403705b261ecSmrg size+= XkbSizeCountedString(doodad->text.font); 403805b261ecSmrg } 403905b261ecSmrg else if (doodad->any.type==XkbLogoDoodad) { 404005b261ecSmrg size+= XkbSizeCountedString(doodad->logo.logo_name); 404105b261ecSmrg } 404205b261ecSmrg } 404305b261ecSmrg return size; 404405b261ecSmrg} 404505b261ecSmrg 404605b261ecSmrgstatic char * 404705b261ecSmrgXkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap) 404805b261ecSmrg{ 404905b261ecSmrgregister int i; 405005b261ecSmrgxkbDoodadWireDesc * doodadWire; 405105b261ecSmrg 405205b261ecSmrg for (i=0;i<num_doodads;i++,doodad++) { 405305b261ecSmrg doodadWire= (xkbDoodadWireDesc *)wire; 405405b261ecSmrg wire= (char *)&doodadWire[1]; 405505b261ecSmrg bzero(doodadWire,SIZEOF(xkbDoodadWireDesc)); 405605b261ecSmrg doodadWire->any.name= doodad->any.name; 405705b261ecSmrg doodadWire->any.type= doodad->any.type; 405805b261ecSmrg doodadWire->any.priority= doodad->any.priority; 405905b261ecSmrg doodadWire->any.top= doodad->any.top; 406005b261ecSmrg doodadWire->any.left= doodad->any.left; 406105b261ecSmrg if (swap) { 406205b261ecSmrg register int n; 406305b261ecSmrg swapl(&doodadWire->any.name,n); 406405b261ecSmrg swaps(&doodadWire->any.top,n); 406505b261ecSmrg swaps(&doodadWire->any.left,n); 406605b261ecSmrg } 406705b261ecSmrg switch (doodad->any.type) { 406805b261ecSmrg case XkbOutlineDoodad: 406905b261ecSmrg case XkbSolidDoodad: 407005b261ecSmrg doodadWire->shape.angle= doodad->shape.angle; 407105b261ecSmrg doodadWire->shape.colorNdx= doodad->shape.color_ndx; 407205b261ecSmrg doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; 407305b261ecSmrg if (swap) { 407405b261ecSmrg register int n; 407505b261ecSmrg swaps(&doodadWire->shape.angle,n); 407605b261ecSmrg } 407705b261ecSmrg break; 407805b261ecSmrg case XkbTextDoodad: 407905b261ecSmrg doodadWire->text.angle= doodad->text.angle; 408005b261ecSmrg doodadWire->text.width= doodad->text.width; 408105b261ecSmrg doodadWire->text.height= doodad->text.height; 408205b261ecSmrg doodadWire->text.colorNdx= doodad->text.color_ndx; 408305b261ecSmrg if (swap) { 408405b261ecSmrg register int n; 408505b261ecSmrg swaps(&doodadWire->text.angle,n); 408605b261ecSmrg swaps(&doodadWire->text.width,n); 408705b261ecSmrg swaps(&doodadWire->text.height,n); 408805b261ecSmrg } 408905b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.text,swap); 409005b261ecSmrg wire= XkbWriteCountedString(wire,doodad->text.font,swap); 409105b261ecSmrg break; 409205b261ecSmrg case XkbIndicatorDoodad: 409305b261ecSmrg doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; 409405b261ecSmrg doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; 409505b261ecSmrg doodadWire->indicator.offColorNdx= 409605b261ecSmrg doodad->indicator.off_color_ndx; 409705b261ecSmrg break; 409805b261ecSmrg case XkbLogoDoodad: 409905b261ecSmrg doodadWire->logo.angle= doodad->logo.angle; 410005b261ecSmrg doodadWire->logo.colorNdx= doodad->logo.color_ndx; 410105b261ecSmrg doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; 410205b261ecSmrg wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap); 410305b261ecSmrg break; 410405b261ecSmrg default: 410505b261ecSmrg ErrorF("Unknown doodad type %d in XkbWriteGeomDoodads\n", 410605b261ecSmrg doodad->any.type); 410705b261ecSmrg ErrorF("Ignored\n"); 410805b261ecSmrg break; 410905b261ecSmrg } 411005b261ecSmrg } 411105b261ecSmrg return wire; 411205b261ecSmrg} 411305b261ecSmrg 411405b261ecSmrgstatic char * 411505b261ecSmrgXkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap) 411605b261ecSmrg{ 411705b261ecSmrgregister int r; 411805b261ecSmrgXkbOverlayRowPtr row; 411905b261ecSmrgxkbOverlayWireDesc * olWire; 412005b261ecSmrg 412105b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 412205b261ecSmrg olWire->name= ol->name; 412305b261ecSmrg olWire->nRows= ol->num_rows; 412405b261ecSmrg if (swap) { 412505b261ecSmrg register int n; 412605b261ecSmrg swapl(&olWire->name,n); 412705b261ecSmrg } 412805b261ecSmrg wire= (char *)&olWire[1]; 412905b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 413005b261ecSmrg unsigned int k; 413105b261ecSmrg XkbOverlayKeyPtr key; 413205b261ecSmrg xkbOverlayRowWireDesc * rowWire; 413305b261ecSmrg rowWire= (xkbOverlayRowWireDesc *)wire; 413405b261ecSmrg rowWire->rowUnder= row->row_under; 413505b261ecSmrg rowWire->nKeys= row->num_keys; 413605b261ecSmrg wire= (char *)&rowWire[1]; 413705b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 413805b261ecSmrg xkbOverlayKeyWireDesc * keyWire; 413905b261ecSmrg keyWire= (xkbOverlayKeyWireDesc *)wire; 414005b261ecSmrg memcpy(keyWire->over,key->over.name,XkbKeyNameLength); 414105b261ecSmrg memcpy(keyWire->under,key->under.name,XkbKeyNameLength); 414205b261ecSmrg wire= (char *)&keyWire[1]; 414305b261ecSmrg } 414405b261ecSmrg } 414505b261ecSmrg return wire; 414605b261ecSmrg} 414705b261ecSmrg 414805b261ecSmrgstatic int 414905b261ecSmrgXkbSizeGeomSections(XkbGeometryPtr geom) 415005b261ecSmrg{ 415105b261ecSmrgregister int i,size; 415205b261ecSmrgXkbSectionPtr section; 415305b261ecSmrg 415405b261ecSmrg for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { 415505b261ecSmrg size+= SIZEOF(xkbSectionWireDesc); 415605b261ecSmrg if (section->rows) { 415705b261ecSmrg int r; 415805b261ecSmrg XkbRowPtr row; 415905b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;row++,r++) { 416005b261ecSmrg size+= SIZEOF(xkbRowWireDesc); 416105b261ecSmrg size+= row->num_keys*SIZEOF(xkbKeyWireDesc); 416205b261ecSmrg } 416305b261ecSmrg } 416405b261ecSmrg if (section->doodads) 416505b261ecSmrg size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads); 416605b261ecSmrg if (section->overlays) { 416705b261ecSmrg int o; 416805b261ecSmrg XkbOverlayPtr ol; 416905b261ecSmrg for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { 417005b261ecSmrg int r; 417105b261ecSmrg XkbOverlayRowPtr row; 417205b261ecSmrg size+= SIZEOF(xkbOverlayWireDesc); 417305b261ecSmrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 417405b261ecSmrg size+= SIZEOF(xkbOverlayRowWireDesc); 417505b261ecSmrg size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); 417605b261ecSmrg } 417705b261ecSmrg } 417805b261ecSmrg } 417905b261ecSmrg } 418005b261ecSmrg return size; 418105b261ecSmrg} 418205b261ecSmrg 418305b261ecSmrgstatic char * 418405b261ecSmrgXkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap) 418505b261ecSmrg{ 418605b261ecSmrgregister int i; 418705b261ecSmrgXkbSectionPtr section; 418805b261ecSmrgxkbSectionWireDesc * sectionWire; 418905b261ecSmrg 419005b261ecSmrg for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 419105b261ecSmrg sectionWire= (xkbSectionWireDesc *)wire; 419205b261ecSmrg sectionWire->name= section->name; 419305b261ecSmrg sectionWire->top= section->top; 419405b261ecSmrg sectionWire->left= section->left; 419505b261ecSmrg sectionWire->width= section->width; 419605b261ecSmrg sectionWire->height= section->height; 419705b261ecSmrg sectionWire->angle= section->angle; 419805b261ecSmrg sectionWire->priority= section->priority; 419905b261ecSmrg sectionWire->nRows= section->num_rows; 420005b261ecSmrg sectionWire->nDoodads= section->num_doodads; 420105b261ecSmrg sectionWire->nOverlays= section->num_overlays; 420205b261ecSmrg sectionWire->pad= 0; 420305b261ecSmrg if (swap) { 420405b261ecSmrg register int n; 420505b261ecSmrg swapl(§ionWire->name,n); 420605b261ecSmrg swaps(§ionWire->top,n); 420705b261ecSmrg swaps(§ionWire->left,n); 420805b261ecSmrg swaps(§ionWire->width,n); 420905b261ecSmrg swaps(§ionWire->height,n); 421005b261ecSmrg swaps(§ionWire->angle,n); 421105b261ecSmrg } 421205b261ecSmrg wire= (char *)§ionWire[1]; 421305b261ecSmrg if (section->rows) { 421405b261ecSmrg int r; 421505b261ecSmrg XkbRowPtr row; 421605b261ecSmrg xkbRowWireDesc * rowWire; 421705b261ecSmrg for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 421805b261ecSmrg rowWire= (xkbRowWireDesc *)wire; 421905b261ecSmrg rowWire->top= row->top; 422005b261ecSmrg rowWire->left= row->left; 422105b261ecSmrg rowWire->nKeys= row->num_keys; 422205b261ecSmrg rowWire->vertical= row->vertical; 422305b261ecSmrg rowWire->pad= 0; 422405b261ecSmrg if (swap) { 422505b261ecSmrg register int n; 422605b261ecSmrg swaps(&rowWire->top,n); 422705b261ecSmrg swaps(&rowWire->left,n); 422805b261ecSmrg } 422905b261ecSmrg wire= (char *)&rowWire[1]; 423005b261ecSmrg if (row->keys) { 423105b261ecSmrg int k; 423205b261ecSmrg XkbKeyPtr key; 423305b261ecSmrg xkbKeyWireDesc * keyWire; 423405b261ecSmrg keyWire= (xkbKeyWireDesc *)wire; 423505b261ecSmrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 423605b261ecSmrg memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); 423705b261ecSmrg keyWire[k].gap= key->gap; 423805b261ecSmrg keyWire[k].shapeNdx= key->shape_ndx; 423905b261ecSmrg keyWire[k].colorNdx= key->color_ndx; 424005b261ecSmrg if (swap) { 424105b261ecSmrg register int n; 424205b261ecSmrg swaps(&keyWire[k].gap,n); 424305b261ecSmrg } 424405b261ecSmrg } 424505b261ecSmrg wire= (char *)&keyWire[row->num_keys]; 424605b261ecSmrg } 424705b261ecSmrg } 424805b261ecSmrg } 424905b261ecSmrg if (section->doodads) { 425005b261ecSmrg wire= XkbWriteGeomDoodads(wire, 425105b261ecSmrg section->num_doodads,section->doodads, 425205b261ecSmrg swap); 425305b261ecSmrg } 425405b261ecSmrg if (section->overlays) { 425505b261ecSmrg register int o; 425605b261ecSmrg for (o=0;o<section->num_overlays;o++) { 425705b261ecSmrg wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap); 425805b261ecSmrg } 425905b261ecSmrg } 426005b261ecSmrg } 426105b261ecSmrg return wire; 426205b261ecSmrg} 426305b261ecSmrg 426405b261ecSmrgstatic Status 426505b261ecSmrgXkbComputeGetGeometryReplySize( XkbGeometryPtr geom, 426605b261ecSmrg xkbGetGeometryReply * rep, 426705b261ecSmrg Atom name) 426805b261ecSmrg{ 426905b261ecSmrgint len; 427005b261ecSmrg 427105b261ecSmrg if (geom!=NULL) { 427205b261ecSmrg len= XkbSizeCountedString(geom->label_font); 427305b261ecSmrg len+= XkbSizeGeomProperties(geom); 427405b261ecSmrg len+= XkbSizeGeomColors(geom); 427505b261ecSmrg len+= XkbSizeGeomShapes(geom); 427605b261ecSmrg len+= XkbSizeGeomSections(geom); 427705b261ecSmrg len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads); 427805b261ecSmrg len+= XkbSizeGeomKeyAliases(geom); 427905b261ecSmrg rep->length= len/4; 428005b261ecSmrg rep->found= True; 428105b261ecSmrg rep->name= geom->name; 428205b261ecSmrg rep->widthMM= geom->width_mm; 428305b261ecSmrg rep->heightMM= geom->height_mm; 428405b261ecSmrg rep->nProperties= geom->num_properties; 428505b261ecSmrg rep->nColors= geom->num_colors; 428605b261ecSmrg rep->nShapes= geom->num_shapes; 428705b261ecSmrg rep->nSections= geom->num_sections; 428805b261ecSmrg rep->nDoodads= geom->num_doodads; 428905b261ecSmrg rep->nKeyAliases= geom->num_key_aliases; 429005b261ecSmrg rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color); 429105b261ecSmrg rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color); 429205b261ecSmrg } 429305b261ecSmrg else { 429405b261ecSmrg rep->length= 0; 429505b261ecSmrg rep->found= False; 429605b261ecSmrg rep->name= name; 429705b261ecSmrg rep->widthMM= rep->heightMM= 0; 429805b261ecSmrg rep->nProperties= rep->nColors= rep->nShapes= 0; 429905b261ecSmrg rep->nSections= rep->nDoodads= 0; 430005b261ecSmrg rep->nKeyAliases= 0; 430105b261ecSmrg rep->labelColorNdx= rep->baseColorNdx= 0; 430205b261ecSmrg } 430305b261ecSmrg return Success; 430405b261ecSmrg} 430505b261ecSmrg 430605b261ecSmrgstatic int 430705b261ecSmrgXkbSendGeometry( ClientPtr client, 430805b261ecSmrg XkbGeometryPtr geom, 430905b261ecSmrg xkbGetGeometryReply * rep, 431005b261ecSmrg Bool freeGeom) 431105b261ecSmrg{ 431205b261ecSmrg char *desc,*start; 431305b261ecSmrg int len; 431405b261ecSmrg 431505b261ecSmrg if (geom!=NULL) { 431605b261ecSmrg len= rep->length*4; 431705b261ecSmrg start= desc= (char *)ALLOCATE_LOCAL(len); 431805b261ecSmrg if (!start) 431905b261ecSmrg return BadAlloc; 432005b261ecSmrg desc= XkbWriteCountedString(desc,geom->label_font,client->swapped); 432105b261ecSmrg if ( rep->nProperties>0 ) 432205b261ecSmrg desc = XkbWriteGeomProperties(desc,geom,client->swapped); 432305b261ecSmrg if ( rep->nColors>0 ) 432405b261ecSmrg desc = XkbWriteGeomColors(desc,geom,client->swapped); 432505b261ecSmrg if ( rep->nShapes>0 ) 432605b261ecSmrg desc = XkbWriteGeomShapes(desc,geom,client->swapped); 432705b261ecSmrg if ( rep->nSections>0 ) 432805b261ecSmrg desc = XkbWriteGeomSections(desc,geom,client->swapped); 432905b261ecSmrg if ( rep->nDoodads>0 ) 433005b261ecSmrg desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads, 433105b261ecSmrg client->swapped); 433205b261ecSmrg if ( rep->nKeyAliases>0 ) 433305b261ecSmrg desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped); 433405b261ecSmrg if ((desc-start)!=(len)) { 433505b261ecSmrg ErrorF("BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 433605b261ecSmrg len, (unsigned long)(desc-start)); 433705b261ecSmrg } 433805b261ecSmrg } 433905b261ecSmrg else { 434005b261ecSmrg len= 0; 434105b261ecSmrg start= NULL; 434205b261ecSmrg } 434305b261ecSmrg if (client->swapped) { 434405b261ecSmrg register int n; 434505b261ecSmrg swaps(&rep->sequenceNumber,n); 434605b261ecSmrg swapl(&rep->length,n); 434705b261ecSmrg swapl(&rep->name,n); 434805b261ecSmrg swaps(&rep->widthMM,n); 434905b261ecSmrg swaps(&rep->heightMM,n); 435005b261ecSmrg swaps(&rep->nProperties,n); 435105b261ecSmrg swaps(&rep->nColors,n); 435205b261ecSmrg swaps(&rep->nShapes,n); 435305b261ecSmrg swaps(&rep->nSections,n); 435405b261ecSmrg swaps(&rep->nDoodads,n); 435505b261ecSmrg swaps(&rep->nKeyAliases,n); 435605b261ecSmrg } 435705b261ecSmrg WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep); 435805b261ecSmrg if (len>0) 435905b261ecSmrg WriteToClient(client, len, start); 436005b261ecSmrg if (start!=NULL) 436105b261ecSmrg DEALLOCATE_LOCAL((char *)start); 436205b261ecSmrg if (freeGeom) 436305b261ecSmrg XkbFreeGeometry(geom,XkbGeomAllMask,True); 436405b261ecSmrg return client->noClientException; 436505b261ecSmrg} 436605b261ecSmrg 436705b261ecSmrgint 436805b261ecSmrgProcXkbGetGeometry(ClientPtr client) 436905b261ecSmrg{ 437005b261ecSmrg DeviceIntPtr dev; 437105b261ecSmrg xkbGetGeometryReply rep; 437205b261ecSmrg XkbGeometryPtr geom; 437305b261ecSmrg Bool shouldFree; 437405b261ecSmrg Status status; 437505b261ecSmrg 437605b261ecSmrg REQUEST(xkbGetGeometryReq); 437705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetGeometryReq); 437805b261ecSmrg 437905b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 438005b261ecSmrg return BadAccess; 438105b261ecSmrg 438205b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 438305b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 438405b261ecSmrg 438505b261ecSmrg geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree); 438605b261ecSmrg rep.type= X_Reply; 438705b261ecSmrg rep.deviceID= dev->id; 438805b261ecSmrg rep.sequenceNumber= client->sequence; 438905b261ecSmrg rep.length= 0; 439005b261ecSmrg status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name); 439105b261ecSmrg if (status!=Success) 439205b261ecSmrg return status; 439305b261ecSmrg else return XkbSendGeometry(client,geom,&rep,shouldFree); 439405b261ecSmrg} 439505b261ecSmrg 439605b261ecSmrg/***====================================================================***/ 439705b261ecSmrg 439805b261ecSmrgstatic char * 439905b261ecSmrg_GetCountedString(char **wire_inout,Bool swap) 440005b261ecSmrg{ 440105b261ecSmrgchar * wire,*str; 440205b261ecSmrgCARD16 len,*plen; 440305b261ecSmrg 440405b261ecSmrg wire= *wire_inout; 440505b261ecSmrg plen= (CARD16 *)wire; 440605b261ecSmrg if (swap) { 440705b261ecSmrg register int n; 440805b261ecSmrg swaps(plen,n); 440905b261ecSmrg } 441005b261ecSmrg len= *plen; 441105b261ecSmrg str= (char *)_XkbAlloc(len+1); 441205b261ecSmrg if (str) { 441305b261ecSmrg memcpy(str,&wire[2],len); 441405b261ecSmrg str[len]= '\0'; 441505b261ecSmrg } 441605b261ecSmrg wire+= XkbPaddedSize(len+2); 441705b261ecSmrg *wire_inout= wire; 441805b261ecSmrg return str; 441905b261ecSmrg} 442005b261ecSmrg 442105b261ecSmrgstatic Status 442205b261ecSmrg_CheckSetDoodad( char ** wire_inout, 442305b261ecSmrg XkbGeometryPtr geom, 442405b261ecSmrg XkbSectionPtr section, 442505b261ecSmrg ClientPtr client) 442605b261ecSmrg{ 442705b261ecSmrgchar * wire; 442805b261ecSmrgxkbDoodadWireDesc * dWire; 442905b261ecSmrgXkbDoodadPtr doodad; 443005b261ecSmrg 443105b261ecSmrg dWire= (xkbDoodadWireDesc *)(*wire_inout); 443205b261ecSmrg wire= (char *)&dWire[1]; 443305b261ecSmrg if (client->swapped) { 443405b261ecSmrg register int n; 443505b261ecSmrg swapl(&dWire->any.name,n); 443605b261ecSmrg swaps(&dWire->any.top,n); 443705b261ecSmrg swaps(&dWire->any.left,n); 443805b261ecSmrg swaps(&dWire->any.angle,n); 443905b261ecSmrg } 444005b261ecSmrg CHK_ATOM_ONLY(dWire->any.name); 444105b261ecSmrg doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); 444205b261ecSmrg if (!doodad) 444305b261ecSmrg return BadAlloc; 444405b261ecSmrg doodad->any.type= dWire->any.type; 444505b261ecSmrg doodad->any.priority= dWire->any.priority; 444605b261ecSmrg doodad->any.top= dWire->any.top; 444705b261ecSmrg doodad->any.left= dWire->any.left; 444805b261ecSmrg doodad->any.angle= dWire->any.angle; 444905b261ecSmrg switch (doodad->any.type) { 445005b261ecSmrg case XkbOutlineDoodad: 445105b261ecSmrg case XkbSolidDoodad: 445205b261ecSmrg if (dWire->shape.colorNdx>=geom->num_colors) { 445305b261ecSmrg client->errorValue= _XkbErrCode3(0x40,geom->num_colors, 445405b261ecSmrg dWire->shape.colorNdx); 445505b261ecSmrg return BadMatch; 445605b261ecSmrg } 445705b261ecSmrg if (dWire->shape.shapeNdx>=geom->num_shapes) { 445805b261ecSmrg client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, 445905b261ecSmrg dWire->shape.shapeNdx); 446005b261ecSmrg return BadMatch; 446105b261ecSmrg } 446205b261ecSmrg doodad->shape.color_ndx= dWire->shape.colorNdx; 446305b261ecSmrg doodad->shape.shape_ndx= dWire->shape.shapeNdx; 446405b261ecSmrg break; 446505b261ecSmrg case XkbTextDoodad: 446605b261ecSmrg if (dWire->text.colorNdx>=geom->num_colors) { 446705b261ecSmrg client->errorValue= _XkbErrCode3(0x42,geom->num_colors, 446805b261ecSmrg dWire->text.colorNdx); 446905b261ecSmrg return BadMatch; 447005b261ecSmrg } 447105b261ecSmrg if (client->swapped) { 447205b261ecSmrg register int n; 447305b261ecSmrg swaps(&dWire->text.width,n); 447405b261ecSmrg swaps(&dWire->text.height,n); 447505b261ecSmrg } 447605b261ecSmrg doodad->text.width= dWire->text.width; 447705b261ecSmrg doodad->text.height= dWire->text.height; 447805b261ecSmrg doodad->text.color_ndx= dWire->text.colorNdx; 447905b261ecSmrg doodad->text.text= _GetCountedString(&wire,client->swapped); 448005b261ecSmrg doodad->text.font= _GetCountedString(&wire,client->swapped); 448105b261ecSmrg break; 448205b261ecSmrg case XkbIndicatorDoodad: 448305b261ecSmrg if (dWire->indicator.onColorNdx>=geom->num_colors) { 448405b261ecSmrg client->errorValue= _XkbErrCode3(0x43,geom->num_colors, 448505b261ecSmrg dWire->indicator.onColorNdx); 448605b261ecSmrg return BadMatch; 448705b261ecSmrg } 448805b261ecSmrg if (dWire->indicator.offColorNdx>=geom->num_colors) { 448905b261ecSmrg client->errorValue= _XkbErrCode3(0x44,geom->num_colors, 449005b261ecSmrg dWire->indicator.offColorNdx); 449105b261ecSmrg return BadMatch; 449205b261ecSmrg } 449305b261ecSmrg if (dWire->indicator.shapeNdx>=geom->num_shapes) { 449405b261ecSmrg client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, 449505b261ecSmrg dWire->indicator.shapeNdx); 449605b261ecSmrg return BadMatch; 449705b261ecSmrg } 449805b261ecSmrg doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; 449905b261ecSmrg doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; 450005b261ecSmrg doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; 450105b261ecSmrg break; 450205b261ecSmrg case XkbLogoDoodad: 450305b261ecSmrg if (dWire->logo.colorNdx>=geom->num_colors) { 450405b261ecSmrg client->errorValue= _XkbErrCode3(0x46,geom->num_colors, 450505b261ecSmrg dWire->logo.colorNdx); 450605b261ecSmrg return BadMatch; 450705b261ecSmrg } 450805b261ecSmrg if (dWire->logo.shapeNdx>=geom->num_shapes) { 450905b261ecSmrg client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, 451005b261ecSmrg dWire->logo.shapeNdx); 451105b261ecSmrg return BadMatch; 451205b261ecSmrg } 451305b261ecSmrg doodad->logo.color_ndx= dWire->logo.colorNdx; 451405b261ecSmrg doodad->logo.shape_ndx= dWire->logo.shapeNdx; 451505b261ecSmrg doodad->logo.logo_name= _GetCountedString(&wire,client->swapped); 451605b261ecSmrg break; 451705b261ecSmrg default: 451805b261ecSmrg client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); 451905b261ecSmrg return BadValue; 452005b261ecSmrg } 452105b261ecSmrg *wire_inout= wire; 452205b261ecSmrg return Success; 452305b261ecSmrg} 452405b261ecSmrg 452505b261ecSmrgstatic Status 452605b261ecSmrg_CheckSetOverlay( char ** wire_inout, 452705b261ecSmrg XkbGeometryPtr geom, 452805b261ecSmrg XkbSectionPtr section, 452905b261ecSmrg ClientPtr client) 453005b261ecSmrg{ 453105b261ecSmrgregister int r; 453205b261ecSmrgchar * wire; 453305b261ecSmrgXkbOverlayPtr ol; 453405b261ecSmrgxkbOverlayWireDesc * olWire; 453505b261ecSmrgxkbOverlayRowWireDesc * rWire; 453605b261ecSmrg 453705b261ecSmrg wire= *wire_inout; 453805b261ecSmrg olWire= (xkbOverlayWireDesc *)wire; 453905b261ecSmrg if (client->swapped) { 454005b261ecSmrg register int n; 454105b261ecSmrg swapl(&olWire->name,n); 454205b261ecSmrg } 454305b261ecSmrg CHK_ATOM_ONLY(olWire->name); 454405b261ecSmrg ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); 454505b261ecSmrg rWire= (xkbOverlayRowWireDesc *)&olWire[1]; 454605b261ecSmrg for (r=0;r<olWire->nRows;r++) { 454705b261ecSmrg register int k; 454805b261ecSmrg xkbOverlayKeyWireDesc * kWire; 454905b261ecSmrg XkbOverlayRowPtr row; 455005b261ecSmrg 455105b261ecSmrg if (rWire->rowUnder>section->num_rows) { 455205b261ecSmrg client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, 455305b261ecSmrg rWire->rowUnder); 455405b261ecSmrg return BadMatch; 455505b261ecSmrg } 455605b261ecSmrg row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); 455705b261ecSmrg kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; 455805b261ecSmrg for (k=0;k<rWire->nKeys;k++,kWire++) { 455905b261ecSmrg if (XkbAddGeomOverlayKey(ol,row, 456005b261ecSmrg (char *)kWire->over,(char *)kWire->under)==NULL) { 456105b261ecSmrg client->errorValue= _XkbErrCode3(0x21,r,k); 456205b261ecSmrg return BadMatch; 456305b261ecSmrg } 456405b261ecSmrg } 456505b261ecSmrg rWire= (xkbOverlayRowWireDesc *)kWire; 456605b261ecSmrg } 456705b261ecSmrg olWire= (xkbOverlayWireDesc *)rWire; 456805b261ecSmrg wire= (char *)olWire; 456905b261ecSmrg *wire_inout= wire; 457005b261ecSmrg return Success; 457105b261ecSmrg} 457205b261ecSmrg 457305b261ecSmrgstatic Status 457405b261ecSmrg_CheckSetSections( XkbGeometryPtr geom, 457505b261ecSmrg xkbSetGeometryReq * req, 457605b261ecSmrg char ** wire_inout, 457705b261ecSmrg ClientPtr client) 457805b261ecSmrg{ 457905b261ecSmrgStatus status; 458005b261ecSmrgregister int s; 458105b261ecSmrgchar * wire; 458205b261ecSmrgxkbSectionWireDesc * sWire; 458305b261ecSmrgXkbSectionPtr section; 458405b261ecSmrg 458505b261ecSmrg wire= *wire_inout; 458605b261ecSmrg if (req->nSections<1) 458705b261ecSmrg return Success; 458805b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 458905b261ecSmrg for (s=0;s<req->nSections;s++) { 459005b261ecSmrg register int r; 459105b261ecSmrg xkbRowWireDesc * rWire; 459205b261ecSmrg if (client->swapped) { 459305b261ecSmrg register int n; 459405b261ecSmrg swapl(&sWire->name,n); 459505b261ecSmrg swaps(&sWire->top,n); 459605b261ecSmrg swaps(&sWire->left,n); 459705b261ecSmrg swaps(&sWire->width,n); 459805b261ecSmrg swaps(&sWire->height,n); 459905b261ecSmrg swaps(&sWire->angle,n); 460005b261ecSmrg } 460105b261ecSmrg CHK_ATOM_ONLY(sWire->name); 460205b261ecSmrg section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, 460305b261ecSmrg sWire->nDoodads,sWire->nOverlays); 460405b261ecSmrg if (!section) 460505b261ecSmrg return BadAlloc; 460605b261ecSmrg section->priority= sWire->priority; 460705b261ecSmrg section->top= sWire->top; 460805b261ecSmrg section->left= sWire->left; 460905b261ecSmrg section->width= sWire->width; 461005b261ecSmrg section->height= sWire->height; 461105b261ecSmrg section->angle= sWire->angle; 461205b261ecSmrg rWire= (xkbRowWireDesc *)&sWire[1]; 461305b261ecSmrg for (r=0;r<sWire->nRows;r++) { 461405b261ecSmrg register int k; 461505b261ecSmrg XkbRowPtr row; 461605b261ecSmrg xkbKeyWireDesc * kWire; 461705b261ecSmrg if (client->swapped) { 461805b261ecSmrg register int n; 461905b261ecSmrg swaps(&rWire->top,n); 462005b261ecSmrg swaps(&rWire->left,n); 462105b261ecSmrg } 462205b261ecSmrg row= XkbAddGeomRow(section,rWire->nKeys); 462305b261ecSmrg if (!row) 462405b261ecSmrg return BadAlloc; 462505b261ecSmrg row->top= rWire->top; 462605b261ecSmrg row->left= rWire->left; 462705b261ecSmrg row->vertical= rWire->vertical; 462805b261ecSmrg kWire= (xkbKeyWireDesc *)&rWire[1]; 462905b261ecSmrg for (k=0;k<rWire->nKeys;k++) { 463005b261ecSmrg XkbKeyPtr key; 463105b261ecSmrg key= XkbAddGeomKey(row); 463205b261ecSmrg if (!key) 463305b261ecSmrg return BadAlloc; 463405b261ecSmrg memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); 463505b261ecSmrg key->gap= kWire[k].gap; 463605b261ecSmrg key->shape_ndx= kWire[k].shapeNdx; 463705b261ecSmrg key->color_ndx= kWire[k].colorNdx; 463805b261ecSmrg if (key->shape_ndx>=geom->num_shapes) { 463905b261ecSmrg client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, 464005b261ecSmrg geom->num_shapes); 464105b261ecSmrg return BadMatch; 464205b261ecSmrg } 464305b261ecSmrg if (key->color_ndx>=geom->num_colors) { 464405b261ecSmrg client->errorValue= _XkbErrCode3(0x11,key->color_ndx, 464505b261ecSmrg geom->num_colors); 464605b261ecSmrg return BadMatch; 464705b261ecSmrg } 464805b261ecSmrg } 464905b261ecSmrg rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; 465005b261ecSmrg } 465105b261ecSmrg wire= (char *)rWire; 465205b261ecSmrg if (sWire->nDoodads>0) { 465305b261ecSmrg register int d; 465405b261ecSmrg for (d=0;d<sWire->nDoodads;d++) { 465505b261ecSmrg status=_CheckSetDoodad(&wire,geom,section,client); 465605b261ecSmrg if (status!=Success) 465705b261ecSmrg return status; 465805b261ecSmrg } 465905b261ecSmrg } 466005b261ecSmrg if (sWire->nOverlays>0) { 466105b261ecSmrg register int o; 466205b261ecSmrg for (o=0;o<sWire->nOverlays;o++) { 466305b261ecSmrg status= _CheckSetOverlay(&wire,geom,section,client); 466405b261ecSmrg if (status!=Success) 466505b261ecSmrg return status; 466605b261ecSmrg } 466705b261ecSmrg } 466805b261ecSmrg sWire= (xkbSectionWireDesc *)wire; 466905b261ecSmrg } 467005b261ecSmrg wire= (char *)sWire; 467105b261ecSmrg *wire_inout= wire; 467205b261ecSmrg return Success; 467305b261ecSmrg} 467405b261ecSmrg 467505b261ecSmrgstatic Status 467605b261ecSmrg_CheckSetShapes( XkbGeometryPtr geom, 467705b261ecSmrg xkbSetGeometryReq * req, 467805b261ecSmrg char ** wire_inout, 467905b261ecSmrg ClientPtr client) 468005b261ecSmrg{ 468105b261ecSmrgregister int i; 468205b261ecSmrgchar * wire; 468305b261ecSmrg 468405b261ecSmrg wire= *wire_inout; 468505b261ecSmrg if (req->nShapes<1) { 468605b261ecSmrg client->errorValue= _XkbErrCode2(0x06,req->nShapes); 468705b261ecSmrg return BadValue; 468805b261ecSmrg } 468905b261ecSmrg else { 469005b261ecSmrg xkbShapeWireDesc * shapeWire; 469105b261ecSmrg XkbShapePtr shape; 469205b261ecSmrg register int o; 469305b261ecSmrg shapeWire= (xkbShapeWireDesc *)wire; 469405b261ecSmrg for (i=0;i<req->nShapes;i++) { 469505b261ecSmrg xkbOutlineWireDesc * olWire; 469605b261ecSmrg XkbOutlinePtr ol; 469705b261ecSmrg shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); 469805b261ecSmrg if (!shape) 469905b261ecSmrg return BadAlloc; 470005b261ecSmrg olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); 470105b261ecSmrg for (o=0;o<shapeWire->nOutlines;o++) { 470205b261ecSmrg register int p; 470305b261ecSmrg XkbPointPtr pt; 470405b261ecSmrg xkbPointWireDesc * ptWire; 470505b261ecSmrg 470605b261ecSmrg ol= XkbAddGeomOutline(shape,olWire->nPoints); 470705b261ecSmrg if (!ol) 470805b261ecSmrg return BadAlloc; 470905b261ecSmrg ol->corner_radius= olWire->cornerRadius; 471005b261ecSmrg ptWire= (xkbPointWireDesc *)&olWire[1]; 471105b261ecSmrg for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { 471205b261ecSmrg pt->x= ptWire[p].x; 471305b261ecSmrg pt->y= ptWire[p].y; 471405b261ecSmrg if (client->swapped) { 471505b261ecSmrg register int n; 471605b261ecSmrg swaps(&pt->x,n); 471705b261ecSmrg swaps(&pt->y,n); 471805b261ecSmrg } 471905b261ecSmrg } 472005b261ecSmrg ol->num_points= olWire->nPoints; 472105b261ecSmrg olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); 472205b261ecSmrg } 472305b261ecSmrg if (shapeWire->primaryNdx!=XkbNoShape) 472405b261ecSmrg shape->primary= &shape->outlines[shapeWire->primaryNdx]; 472505b261ecSmrg if (shapeWire->approxNdx!=XkbNoShape) 472605b261ecSmrg shape->approx= &shape->outlines[shapeWire->approxNdx]; 472705b261ecSmrg shapeWire= (xkbShapeWireDesc *)olWire; 472805b261ecSmrg } 472905b261ecSmrg wire= (char *)shapeWire; 473005b261ecSmrg } 473105b261ecSmrg if (geom->num_shapes!=req->nShapes) { 473205b261ecSmrg client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); 473305b261ecSmrg return BadMatch; 473405b261ecSmrg } 473505b261ecSmrg 473605b261ecSmrg *wire_inout= wire; 473705b261ecSmrg return Success; 473805b261ecSmrg} 473905b261ecSmrg 474005b261ecSmrgstatic Status 474105b261ecSmrg_CheckSetGeom( XkbGeometryPtr geom, 474205b261ecSmrg xkbSetGeometryReq * req, 474305b261ecSmrg ClientPtr client) 474405b261ecSmrg{ 474505b261ecSmrgregister int i; 474605b261ecSmrgStatus status; 474705b261ecSmrgchar * wire; 474805b261ecSmrg 474905b261ecSmrg wire= (char *)&req[1]; 475005b261ecSmrg geom->label_font= _GetCountedString(&wire,client->swapped); 475105b261ecSmrg 475205b261ecSmrg for (i=0;i<req->nProperties;i++) { 475305b261ecSmrg char *name,*val; 475405b261ecSmrg name= _GetCountedString(&wire,client->swapped); 475505b261ecSmrg if (!name) 475605b261ecSmrg return BadAlloc; 475705b261ecSmrg val= _GetCountedString(&wire,client->swapped); 475805b261ecSmrg if (!val) { 475905b261ecSmrg xfree(name); 476005b261ecSmrg return BadAlloc; 476105b261ecSmrg } 476205b261ecSmrg if (XkbAddGeomProperty(geom,name,val)==NULL) { 476305b261ecSmrg xfree(name); 476405b261ecSmrg xfree(val); 476505b261ecSmrg return BadAlloc; 476605b261ecSmrg } 476705b261ecSmrg xfree(name); 476805b261ecSmrg xfree(val); 476905b261ecSmrg } 477005b261ecSmrg 477105b261ecSmrg if (req->nColors<2) { 477205b261ecSmrg client->errorValue= _XkbErrCode3(0x01,2,req->nColors); 477305b261ecSmrg return BadValue; 477405b261ecSmrg } 477505b261ecSmrg if (req->baseColorNdx>req->nColors) { 477605b261ecSmrg client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); 477705b261ecSmrg return BadMatch; 477805b261ecSmrg } 477905b261ecSmrg if (req->labelColorNdx>req->nColors) { 478005b261ecSmrg client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); 478105b261ecSmrg return BadMatch; 478205b261ecSmrg } 478305b261ecSmrg if (req->labelColorNdx==req->baseColorNdx) { 478405b261ecSmrg client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, 478505b261ecSmrg req->labelColorNdx); 478605b261ecSmrg return BadMatch; 478705b261ecSmrg } 478805b261ecSmrg 478905b261ecSmrg for (i=0;i<req->nColors;i++) { 479005b261ecSmrg char *name; 479105b261ecSmrg name= _GetCountedString(&wire,client->swapped); 479205b261ecSmrg if (!name) 479305b261ecSmrg return BadAlloc; 479405b261ecSmrg if (!XkbAddGeomColor(geom,name,geom->num_colors)) { 479505b261ecSmrg xfree(name); 479605b261ecSmrg return BadAlloc; 479705b261ecSmrg } 479805b261ecSmrg xfree(name); 479905b261ecSmrg } 480005b261ecSmrg if (req->nColors!=geom->num_colors) { 480105b261ecSmrg client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); 480205b261ecSmrg return BadMatch; 480305b261ecSmrg } 480405b261ecSmrg geom->label_color= &geom->colors[req->labelColorNdx]; 480505b261ecSmrg geom->base_color= &geom->colors[req->baseColorNdx]; 480605b261ecSmrg 480705b261ecSmrg if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) 480805b261ecSmrg return status; 480905b261ecSmrg 481005b261ecSmrg if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) 481105b261ecSmrg return status; 481205b261ecSmrg 481305b261ecSmrg for (i=0;i<req->nDoodads;i++) { 481405b261ecSmrg status=_CheckSetDoodad(&wire,geom,NULL,client); 481505b261ecSmrg if (status!=Success) 481605b261ecSmrg return status; 481705b261ecSmrg } 481805b261ecSmrg 481905b261ecSmrg for (i=0;i<req->nKeyAliases;i++) { 482005b261ecSmrg if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) 482105b261ecSmrg return BadAlloc; 482205b261ecSmrg wire+= 2*XkbKeyNameLength; 482305b261ecSmrg } 482405b261ecSmrg return Success; 482505b261ecSmrg} 482605b261ecSmrg 482705b261ecSmrg/* FIXME: Needs to set geom on all core-sending devices. */ 482805b261ecSmrgint 482905b261ecSmrgProcXkbSetGeometry(ClientPtr client) 483005b261ecSmrg{ 483105b261ecSmrg DeviceIntPtr dev; 483205b261ecSmrg XkbGeometryPtr geom,old; 483305b261ecSmrg XkbGeometrySizesRec sizes; 483405b261ecSmrg Status status; 483505b261ecSmrg XkbDescPtr xkb; 483605b261ecSmrg Bool new_name; 483705b261ecSmrg xkbNewKeyboardNotify nkn; 483805b261ecSmrg 483905b261ecSmrg REQUEST(xkbSetGeometryReq); 484005b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 484105b261ecSmrg 484205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 484305b261ecSmrg return BadAccess; 484405b261ecSmrg 484505b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 484605b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 484705b261ecSmrg 484805b261ecSmrg xkb= dev->key->xkbInfo->desc; 484905b261ecSmrg old= xkb->geom; 485005b261ecSmrg xkb->geom= NULL; 485105b261ecSmrg 485205b261ecSmrg sizes.which= XkbGeomAllMask; 485305b261ecSmrg sizes.num_properties= stuff->nProperties; 485405b261ecSmrg sizes.num_colors= stuff->nColors; 485505b261ecSmrg sizes.num_shapes= stuff->nShapes; 485605b261ecSmrg sizes.num_sections= stuff->nSections; 485705b261ecSmrg sizes.num_doodads= stuff->nDoodads; 485805b261ecSmrg sizes.num_key_aliases= stuff->nKeyAliases; 485905b261ecSmrg if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { 486005b261ecSmrg xkb->geom= old; 486105b261ecSmrg return status; 486205b261ecSmrg } 486305b261ecSmrg geom= xkb->geom; 486405b261ecSmrg geom->name= stuff->name; 486505b261ecSmrg geom->width_mm= stuff->widthMM; 486605b261ecSmrg geom->height_mm= stuff->heightMM; 486705b261ecSmrg if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { 486805b261ecSmrg XkbFreeGeometry(geom,XkbGeomAllMask,True); 486905b261ecSmrg xkb->geom= old; 487005b261ecSmrg return status; 487105b261ecSmrg } 487205b261ecSmrg new_name= (xkb->names->geometry!=geom->name); 487305b261ecSmrg xkb->names->geometry= geom->name; 487405b261ecSmrg if (old) 487505b261ecSmrg XkbFreeGeometry(old,XkbGeomAllMask,True); 487605b261ecSmrg if (new_name) { 487705b261ecSmrg xkbNamesNotify nn; 487805b261ecSmrg bzero(&nn,sizeof(xkbNamesNotify)); 487905b261ecSmrg nn.changed= XkbGeometryNameMask; 488005b261ecSmrg XkbSendNamesNotify(dev,&nn); 488105b261ecSmrg } 488205b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 488305b261ecSmrg nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; 488405b261ecSmrg nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; 488505b261ecSmrg nkn.requestMajor= XkbReqCode; 488605b261ecSmrg nkn.requestMinor= X_kbSetGeometry; 488705b261ecSmrg nkn.changed= XkbNKN_GeometryMask; 488805b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 488905b261ecSmrg return Success; 489005b261ecSmrg} 489105b261ecSmrg 489205b261ecSmrg/***====================================================================***/ 489305b261ecSmrg 489405b261ecSmrgint 489505b261ecSmrgProcXkbPerClientFlags(ClientPtr client) 489605b261ecSmrg{ 489705b261ecSmrg DeviceIntPtr dev; 489805b261ecSmrg xkbPerClientFlagsReply rep; 489905b261ecSmrg XkbInterestPtr interest; 490005b261ecSmrg 490105b261ecSmrg REQUEST(xkbPerClientFlagsReq); 490205b261ecSmrg REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 490305b261ecSmrg 490405b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 490505b261ecSmrg return BadAccess; 490605b261ecSmrg 490705b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 490805b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); 490905b261ecSmrg CHK_MASK_MATCH(0x02,stuff->change,stuff->value); 491005b261ecSmrg 491105b261ecSmrg interest = XkbFindClientResource((DevicePtr)dev,client); 491205b261ecSmrg rep.type= X_Reply; 491305b261ecSmrg rep.length = 0; 491405b261ecSmrg rep.sequenceNumber = client->sequence; 491505b261ecSmrg if (stuff->change) { 491605b261ecSmrg client->xkbClientFlags&= ~stuff->change; 491705b261ecSmrg client->xkbClientFlags|= stuff->value; 491805b261ecSmrg } 491905b261ecSmrg if (stuff->change&XkbPCF_AutoResetControlsMask) { 492005b261ecSmrg Bool want; 492105b261ecSmrg want= stuff->value&XkbPCF_AutoResetControlsMask; 492205b261ecSmrg if (interest && !want) { 492305b261ecSmrg interest->autoCtrls= interest->autoCtrlValues= 0; 492405b261ecSmrg } 492505b261ecSmrg else if (want && (!interest)) { 492605b261ecSmrg XID id = FakeClientID(client->index); 492705b261ecSmrg AddResource(id,RT_XKBCLIENT,dev); 492805b261ecSmrg interest= XkbAddClientResource((DevicePtr)dev,client,id); 492905b261ecSmrg if (!interest) 493005b261ecSmrg return BadAlloc; 493105b261ecSmrg } 493205b261ecSmrg if (interest && want ) { 493305b261ecSmrg register unsigned affect; 493405b261ecSmrg affect= stuff->ctrlsToChange; 493505b261ecSmrg 493605b261ecSmrg CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); 493705b261ecSmrg CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); 493805b261ecSmrg CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); 493905b261ecSmrg 494005b261ecSmrg interest->autoCtrls&= ~affect; 494105b261ecSmrg interest->autoCtrlValues&= ~affect; 494205b261ecSmrg interest->autoCtrls|= stuff->autoCtrls&affect; 494305b261ecSmrg interest->autoCtrlValues|= stuff->autoCtrlValues&affect; 494405b261ecSmrg } 494505b261ecSmrg } 494605b261ecSmrg rep.supported = XkbPCF_AllFlagsMask; 494705b261ecSmrg rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; 494805b261ecSmrg if (interest) { 494905b261ecSmrg rep.autoCtrls= interest->autoCtrls; 495005b261ecSmrg rep.autoCtrlValues= interest->autoCtrlValues; 495105b261ecSmrg } 495205b261ecSmrg else { 495305b261ecSmrg rep.autoCtrls= rep.autoCtrlValues= 0; 495405b261ecSmrg } 495505b261ecSmrg if ( client->swapped ) { 495605b261ecSmrg register int n; 495705b261ecSmrg swaps(&rep.sequenceNumber, n); 495805b261ecSmrg swapl(&rep.supported,n); 495905b261ecSmrg swapl(&rep.value,n); 496005b261ecSmrg swapl(&rep.autoCtrls,n); 496105b261ecSmrg swapl(&rep.autoCtrlValues,n); 496205b261ecSmrg } 496305b261ecSmrg WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); 496405b261ecSmrg return client->noClientException; 496505b261ecSmrg} 496605b261ecSmrg 496705b261ecSmrg/***====================================================================***/ 496805b261ecSmrg 496905b261ecSmrg/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 497005b261ecSmrg/* and wildcards */ 497105b261ecSmrgstatic unsigned char componentSpecLegal[] = { 497205b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 497305b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 497405b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 497505b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 497605b261ecSmrg}; 497705b261ecSmrg 497805b261ecSmrg/* same as above but accepts percent, plus and bar too */ 497905b261ecSmrgstatic unsigned char componentExprLegal[] = { 498005b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 498105b261ecSmrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 498205b261ecSmrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 498305b261ecSmrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 498405b261ecSmrg}; 498505b261ecSmrg 498605b261ecSmrgstatic char * 498705b261ecSmrgGetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) 498805b261ecSmrg{ 498905b261ecSmrgint len; 499005b261ecSmrgregister int i; 499105b261ecSmrgunsigned char *wire,*str,*tmp,*legal; 499205b261ecSmrg 499305b261ecSmrg if (allowExpr) legal= &componentExprLegal[0]; 499405b261ecSmrg else legal= &componentSpecLegal[0]; 499505b261ecSmrg 499605b261ecSmrg wire= *pWire; 499705b261ecSmrg len= (*(unsigned char *)wire++); 499805b261ecSmrg if (len>0) { 499905b261ecSmrg str= (unsigned char *)_XkbCalloc(1, len+1); 500005b261ecSmrg if (str) { 500105b261ecSmrg tmp= str; 500205b261ecSmrg for (i=0;i<len;i++) { 500305b261ecSmrg if (legal[(*wire)/8]&(1<<((*wire)%8))) 500405b261ecSmrg *tmp++= *wire++; 500505b261ecSmrg else wire++; 500605b261ecSmrg } 500705b261ecSmrg if (tmp!=str) 500805b261ecSmrg *tmp++= '\0'; 500905b261ecSmrg else { 501005b261ecSmrg _XkbFree(str); 501105b261ecSmrg str= NULL; 501205b261ecSmrg } 501305b261ecSmrg } 501405b261ecSmrg else { 501505b261ecSmrg *errRtrn= BadAlloc; 501605b261ecSmrg } 501705b261ecSmrg } 501805b261ecSmrg else { 501905b261ecSmrg str= NULL; 502005b261ecSmrg } 502105b261ecSmrg *pWire= wire; 502205b261ecSmrg return (char *)str; 502305b261ecSmrg} 502405b261ecSmrg 502505b261ecSmrg/***====================================================================***/ 502605b261ecSmrg 502705b261ecSmrgint 502805b261ecSmrgProcXkbListComponents(ClientPtr client) 502905b261ecSmrg{ 503005b261ecSmrg DeviceIntPtr dev; 503105b261ecSmrg xkbListComponentsReply rep; 503205b261ecSmrg unsigned len; 503305b261ecSmrg int status; 503405b261ecSmrg unsigned char * str; 503505b261ecSmrg XkbSrvListInfoRec list; 503605b261ecSmrg 503705b261ecSmrg REQUEST(xkbListComponentsReq); 503805b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 503905b261ecSmrg 504005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 504105b261ecSmrg return BadAccess; 504205b261ecSmrg 504305b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 504405b261ecSmrg 504505b261ecSmrg status= Success; 504605b261ecSmrg str= (unsigned char *)&stuff[1]; 504705b261ecSmrg bzero(&list,sizeof(XkbSrvListInfoRec)); 504805b261ecSmrg list.maxRtrn= stuff->maxNames; 504905b261ecSmrg list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status); 505005b261ecSmrg list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status); 505105b261ecSmrg list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status); 505205b261ecSmrg list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status); 505305b261ecSmrg list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status); 505405b261ecSmrg list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status); 505505b261ecSmrg if (status!=Success) 505605b261ecSmrg return status; 505705b261ecSmrg len= str-((unsigned char *)stuff); 505805b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 505905b261ecSmrg return BadLength; 506005b261ecSmrg if ((status=XkbDDXList(dev,&list,client))!=Success) { 506105b261ecSmrg if (list.pool) { 506205b261ecSmrg _XkbFree(list.pool); 506305b261ecSmrg list.pool= NULL; 506405b261ecSmrg } 506505b261ecSmrg return status; 506605b261ecSmrg } 506705b261ecSmrg bzero(&rep,sizeof(xkbListComponentsReply)); 506805b261ecSmrg rep.type= X_Reply; 506905b261ecSmrg rep.deviceID = dev->id; 507005b261ecSmrg rep.sequenceNumber = client->sequence; 507105b261ecSmrg rep.length = XkbPaddedSize(list.nPool)/4; 507205b261ecSmrg rep.nKeymaps = list.nFound[_XkbListKeymaps]; 507305b261ecSmrg rep.nKeycodes = list.nFound[_XkbListKeycodes]; 507405b261ecSmrg rep.nTypes = list.nFound[_XkbListTypes]; 507505b261ecSmrg rep.nCompatMaps = list.nFound[_XkbListCompat]; 507605b261ecSmrg rep.nSymbols = list.nFound[_XkbListSymbols]; 507705b261ecSmrg rep.nGeometries = list.nFound[_XkbListGeometry]; 507805b261ecSmrg rep.extra= 0; 507905b261ecSmrg if (list.nTotal>list.maxRtrn) 508005b261ecSmrg rep.extra = (list.nTotal-list.maxRtrn); 508105b261ecSmrg if (client->swapped) { 508205b261ecSmrg register int n; 508305b261ecSmrg swaps(&rep.sequenceNumber,n); 508405b261ecSmrg swapl(&rep.length,n); 508505b261ecSmrg swaps(&rep.nKeymaps,n); 508605b261ecSmrg swaps(&rep.nKeycodes,n); 508705b261ecSmrg swaps(&rep.nTypes,n); 508805b261ecSmrg swaps(&rep.nCompatMaps,n); 508905b261ecSmrg swaps(&rep.nSymbols,n); 509005b261ecSmrg swaps(&rep.nGeometries,n); 509105b261ecSmrg swaps(&rep.extra,n); 509205b261ecSmrg } 509305b261ecSmrg WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); 509405b261ecSmrg if (list.nPool && list.pool) { 509505b261ecSmrg WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); 509605b261ecSmrg _XkbFree(list.pool); 509705b261ecSmrg list.pool= NULL; 509805b261ecSmrg } 509905b261ecSmrg return client->noClientException; 510005b261ecSmrg} 510105b261ecSmrg 510205b261ecSmrg/***====================================================================***/ 510305b261ecSmrg 510405b261ecSmrgint 510505b261ecSmrgProcXkbGetKbdByName(ClientPtr client) 510605b261ecSmrg{ 510705b261ecSmrg DeviceIntPtr dev; 510805b261ecSmrg DeviceIntPtr tmpd; 510905b261ecSmrg XkbFileInfo finfo; 511005b261ecSmrg xkbGetKbdByNameReply rep; 511105b261ecSmrg xkbGetMapReply mrep; 511205b261ecSmrg xkbGetCompatMapReply crep; 511305b261ecSmrg xkbGetIndicatorMapReply irep; 511405b261ecSmrg xkbGetNamesReply nrep; 511505b261ecSmrg xkbGetGeometryReply grep; 511605b261ecSmrg XkbComponentNamesRec names; 511705b261ecSmrg XkbDescPtr xkb; 511805b261ecSmrg unsigned char * str; 511905b261ecSmrg char mapFile[PATH_MAX]; 512005b261ecSmrg unsigned len; 512105b261ecSmrg unsigned fwant,fneed,reported; 512205b261ecSmrg int status; 512305b261ecSmrg Bool geom_changed; 512405b261ecSmrg XkbSrvLedInfoPtr old_sli; 512505b261ecSmrg XkbSrvLedInfoPtr sli; 512605b261ecSmrg 512705b261ecSmrg REQUEST(xkbGetKbdByNameReq); 512805b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 512905b261ecSmrg 513005b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 513105b261ecSmrg return BadAccess; 513205b261ecSmrg 513305b261ecSmrg CHK_KBD_DEVICE(dev,stuff->deviceSpec); 513405b261ecSmrg 513505b261ecSmrg xkb = dev->key->xkbInfo->desc; 513605b261ecSmrg status= Success; 513705b261ecSmrg str= (unsigned char *)&stuff[1]; 513805b261ecSmrg names.keymap= GetComponentSpec(&str,True,&status); 513905b261ecSmrg names.keycodes= GetComponentSpec(&str,True,&status); 514005b261ecSmrg names.types= GetComponentSpec(&str,True,&status); 514105b261ecSmrg names.compat= GetComponentSpec(&str,True,&status); 514205b261ecSmrg names.symbols= GetComponentSpec(&str,True,&status); 514305b261ecSmrg names.geometry= GetComponentSpec(&str,True,&status); 514405b261ecSmrg if (status!=Success) 514505b261ecSmrg return status; 514605b261ecSmrg len= str-((unsigned char *)stuff); 514705b261ecSmrg if ((XkbPaddedSize(len)/4)!=stuff->length) 514805b261ecSmrg return BadLength; 514905b261ecSmrg 515005b261ecSmrg CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); 515105b261ecSmrg CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); 515205b261ecSmrg 515305b261ecSmrg if (stuff->load) 515405b261ecSmrg fwant= XkbGBN_AllComponentsMask; 515505b261ecSmrg else fwant= stuff->want|stuff->need; 515605b261ecSmrg if (!names.keymap) { 515705b261ecSmrg if ((!names.compat)&& 515805b261ecSmrg (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { 515905b261ecSmrg names.compat= _XkbDupString("%"); 516005b261ecSmrg } 516105b261ecSmrg if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { 516205b261ecSmrg names.types= _XkbDupString("%"); 516305b261ecSmrg } 516405b261ecSmrg if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { 516505b261ecSmrg names.symbols= _XkbDupString("%"); 516605b261ecSmrg } 516705b261ecSmrg geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); 516805b261ecSmrg if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { 516905b261ecSmrg names.geometry= _XkbDupString("%"); 517005b261ecSmrg geom_changed= False; 517105b261ecSmrg } 517205b261ecSmrg } 517305b261ecSmrg else { 517405b261ecSmrg geom_changed= True; 517505b261ecSmrg } 517605b261ecSmrg 517705b261ecSmrg bzero(mapFile,PATH_MAX); 517805b261ecSmrg rep.type= X_Reply; 517905b261ecSmrg rep.deviceID = dev->id; 518005b261ecSmrg rep.sequenceNumber = client->sequence; 518105b261ecSmrg rep.length = 0; 518205b261ecSmrg rep.minKeyCode = xkb->min_key_code; 518305b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 518405b261ecSmrg rep.loaded= False; 518505b261ecSmrg fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask; 518605b261ecSmrg fneed= XkbConvertGetByNameComponents(True,stuff->need); 518705b261ecSmrg rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed); 518805b261ecSmrg if (stuff->load) { 518905b261ecSmrg fneed|= XkmKeymapRequired; 519005b261ecSmrg fwant|= XkmKeymapLegal; 519105b261ecSmrg } 519205b261ecSmrg if ((fwant|fneed)&XkmSymbolsMask) { 519305b261ecSmrg fneed|= XkmKeyNamesIndex|XkmTypesIndex; 519405b261ecSmrg fwant|= XkmIndicatorsIndex; 519505b261ecSmrg } 519605b261ecSmrg 519705b261ecSmrg /* We pass dev in here so we can get the old names out if needed. */ 519805b261ecSmrg rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&finfo, 519905b261ecSmrg mapFile,PATH_MAX); 520005b261ecSmrg rep.newKeyboard= False; 520105b261ecSmrg rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; 520205b261ecSmrg 520305b261ecSmrg stuff->want|= stuff->need; 520405b261ecSmrg if (finfo.xkb==NULL) 520505b261ecSmrg rep.reported= 0; 520605b261ecSmrg else { 520705b261ecSmrg if (stuff->load) 520805b261ecSmrg rep.loaded= True; 520905b261ecSmrg if (stuff->load || 521005b261ecSmrg ((rep.reported&XkbGBN_SymbolsMask) && (finfo.xkb->compat))) { 521105b261ecSmrg XkbChangesRec changes; 521205b261ecSmrg bzero(&changes,sizeof(changes)); 521305b261ecSmrg XkbUpdateDescActions(finfo.xkb, 521405b261ecSmrg finfo.xkb->min_key_code,XkbNumKeys(finfo.xkb), 521505b261ecSmrg &changes); 521605b261ecSmrg } 521705b261ecSmrg 521805b261ecSmrg if (finfo.xkb->map==NULL) 521905b261ecSmrg rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); 522005b261ecSmrg else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { 522105b261ecSmrg mrep.type= X_Reply; 522205b261ecSmrg mrep.deviceID = dev->id; 522305b261ecSmrg mrep.sequenceNumber= client->sequence; 522405b261ecSmrg mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); 522505b261ecSmrg mrep.minKeyCode = finfo.xkb->min_key_code; 522605b261ecSmrg mrep.maxKeyCode = finfo.xkb->max_key_code; 522705b261ecSmrg mrep.present = 0; 522805b261ecSmrg mrep.totalSyms = mrep.totalActs = 522905b261ecSmrg mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 523005b261ecSmrg mrep.totalModMapKeys= 0; 523105b261ecSmrg if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { 523205b261ecSmrg mrep.present|= XkbKeyTypesMask; 523305b261ecSmrg mrep.firstType = 0; 523405b261ecSmrg mrep.nTypes = mrep.totalTypes= finfo.xkb->map->num_types; 523505b261ecSmrg } 523605b261ecSmrg else { 523705b261ecSmrg mrep.firstType = mrep.nTypes= 0; 523805b261ecSmrg mrep.totalTypes= 0; 523905b261ecSmrg } 524005b261ecSmrg if (rep.reported&XkbGBN_ClientSymbolsMask) { 524105b261ecSmrg mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); 524205b261ecSmrg mrep.firstKeySym = mrep.firstModMapKey= finfo.xkb->min_key_code; 524305b261ecSmrg mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(finfo.xkb); 524405b261ecSmrg } 524505b261ecSmrg else { 524605b261ecSmrg mrep.firstKeySym= mrep.firstModMapKey= 0; 524705b261ecSmrg mrep.nKeySyms= mrep.nModMapKeys= 0; 524805b261ecSmrg } 524905b261ecSmrg if (rep.reported&XkbGBN_ServerSymbolsMask) { 525005b261ecSmrg mrep.present|= XkbAllServerInfoMask; 525105b261ecSmrg mrep.virtualMods= ~0; 525205b261ecSmrg mrep.firstKeyAct = mrep.firstKeyBehavior = 525305b261ecSmrg mrep.firstKeyExplicit = finfo.xkb->min_key_code; 525405b261ecSmrg mrep.nKeyActs = mrep.nKeyBehaviors = 525505b261ecSmrg mrep.nKeyExplicit = XkbNumKeys(finfo.xkb); 525605b261ecSmrg } 525705b261ecSmrg else { 525805b261ecSmrg mrep.virtualMods= 0; 525905b261ecSmrg mrep.firstKeyAct= mrep.firstKeyBehavior= 526005b261ecSmrg mrep.firstKeyExplicit = 0; 526105b261ecSmrg mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; 526205b261ecSmrg } 526305b261ecSmrg XkbComputeGetMapReplySize(finfo.xkb,&mrep); 526405b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+mrep.length; 526505b261ecSmrg } 526605b261ecSmrg if (finfo.xkb->compat==NULL) 526705b261ecSmrg rep.reported&= ~XkbGBN_CompatMapMask; 526805b261ecSmrg else if (rep.reported&XkbGBN_CompatMapMask) { 526905b261ecSmrg crep.type= X_Reply; 527005b261ecSmrg crep.deviceID= dev->id; 527105b261ecSmrg crep.sequenceNumber= client->sequence; 527205b261ecSmrg crep.length= 0; 527305b261ecSmrg crep.groups= XkbAllGroupsMask; 527405b261ecSmrg crep.firstSI= 0; 527505b261ecSmrg crep.nSI= crep.nTotalSI= finfo.xkb->compat->num_si; 527605b261ecSmrg XkbComputeGetCompatMapReplySize(finfo.xkb->compat,&crep); 527705b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+crep.length; 527805b261ecSmrg } 527905b261ecSmrg if (finfo.xkb->indicators==NULL) 528005b261ecSmrg rep.reported&= ~XkbGBN_IndicatorMapMask; 528105b261ecSmrg else if (rep.reported&XkbGBN_IndicatorMapMask) { 528205b261ecSmrg irep.type= X_Reply; 528305b261ecSmrg irep.deviceID= dev->id; 528405b261ecSmrg irep.sequenceNumber= client->sequence; 528505b261ecSmrg irep.length= 0; 528605b261ecSmrg irep.which= XkbAllIndicatorsMask; 528705b261ecSmrg XkbComputeGetIndicatorMapReplySize(finfo.xkb->indicators,&irep); 528805b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+irep.length; 528905b261ecSmrg } 529005b261ecSmrg if (finfo.xkb->names==NULL) 529105b261ecSmrg rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); 529205b261ecSmrg else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { 529305b261ecSmrg nrep.type= X_Reply; 529405b261ecSmrg nrep.deviceID= dev->id; 529505b261ecSmrg nrep.sequenceNumber= client->sequence; 529605b261ecSmrg nrep.length= 0; 529705b261ecSmrg nrep.minKeyCode= finfo.xkb->min_key_code; 529805b261ecSmrg nrep.maxKeyCode= finfo.xkb->max_key_code; 529905b261ecSmrg if (rep.reported&XkbGBN_OtherNamesMask) { 530005b261ecSmrg nrep.which= XkbAllNamesMask; 530105b261ecSmrg if (finfo.xkb->map!=NULL) 530205b261ecSmrg nrep.nTypes= finfo.xkb->map->num_types; 530305b261ecSmrg else nrep.nTypes= 0; 530405b261ecSmrg nrep.nKTLevels= 0; 530505b261ecSmrg nrep.groupNames= XkbAllGroupsMask; 530605b261ecSmrg nrep.virtualMods= XkbAllVirtualModsMask; 530705b261ecSmrg nrep.indicators= XkbAllIndicatorsMask; 530805b261ecSmrg nrep.nRadioGroups= finfo.xkb->names->num_rg; 530905b261ecSmrg } 531005b261ecSmrg else { 531105b261ecSmrg nrep.which= 0; 531205b261ecSmrg nrep.nTypes= 0; 531305b261ecSmrg nrep.nKTLevels= 0; 531405b261ecSmrg nrep.groupNames= 0; 531505b261ecSmrg nrep.virtualMods= 0; 531605b261ecSmrg nrep.indicators= 0; 531705b261ecSmrg nrep.nRadioGroups= 0; 531805b261ecSmrg } 531905b261ecSmrg if (rep.reported&XkbGBN_KeyNamesMask) { 532005b261ecSmrg nrep.which|= XkbKeyNamesMask; 532105b261ecSmrg nrep.firstKey= finfo.xkb->min_key_code; 532205b261ecSmrg nrep.nKeys= XkbNumKeys(finfo.xkb); 532305b261ecSmrg nrep.nKeyAliases= finfo.xkb->names->num_key_aliases; 532405b261ecSmrg if (nrep.nKeyAliases) 532505b261ecSmrg nrep.which|= XkbKeyAliasesMask; 532605b261ecSmrg } 532705b261ecSmrg else { 532805b261ecSmrg nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); 532905b261ecSmrg nrep.firstKey= nrep.nKeys= 0; 533005b261ecSmrg nrep.nKeyAliases= 0; 533105b261ecSmrg } 533205b261ecSmrg XkbComputeGetNamesReplySize(finfo.xkb,&nrep); 533305b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+nrep.length; 533405b261ecSmrg } 533505b261ecSmrg if (finfo.xkb->geom==NULL) 533605b261ecSmrg rep.reported&= ~XkbGBN_GeometryMask; 533705b261ecSmrg else if (rep.reported&XkbGBN_GeometryMask) { 533805b261ecSmrg grep.type= X_Reply; 533905b261ecSmrg grep.deviceID= dev->id; 534005b261ecSmrg grep.sequenceNumber= client->sequence; 534105b261ecSmrg grep.length= 0; 534205b261ecSmrg grep.found= True; 534305b261ecSmrg grep.pad= 0; 534405b261ecSmrg grep.widthMM= grep.heightMM= 0; 534505b261ecSmrg grep.nProperties= grep.nColors= grep.nShapes= 0; 534605b261ecSmrg grep.nSections= grep.nDoodads= 0; 534705b261ecSmrg grep.baseColorNdx= grep.labelColorNdx= 0; 534805b261ecSmrg XkbComputeGetGeometryReplySize(finfo.xkb->geom,&grep,None); 534905b261ecSmrg rep.length+= SIZEOF(xGenericReply)/4+grep.length; 535005b261ecSmrg } 535105b261ecSmrg } 535205b261ecSmrg 535305b261ecSmrg reported= rep.reported; 535405b261ecSmrg if ( client->swapped ) { 535505b261ecSmrg register int n; 535605b261ecSmrg swaps(&rep.sequenceNumber,n); 535705b261ecSmrg swapl(&rep.length,n); 535805b261ecSmrg swaps(&rep.found,n); 535905b261ecSmrg swaps(&rep.reported,n); 536005b261ecSmrg } 536105b261ecSmrg WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); 536205b261ecSmrg if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) 536305b261ecSmrg XkbSendMap(client,finfo.xkb,&mrep); 536405b261ecSmrg if (reported&XkbGBN_CompatMapMask) 536505b261ecSmrg XkbSendCompatMap(client,finfo.xkb->compat,&crep); 536605b261ecSmrg if (reported&XkbGBN_IndicatorMapMask) 536705b261ecSmrg XkbSendIndicatorMap(client,finfo.xkb->indicators,&irep); 536805b261ecSmrg if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) 536905b261ecSmrg XkbSendNames(client,finfo.xkb,&nrep); 537005b261ecSmrg if (reported&XkbGBN_GeometryMask) 537105b261ecSmrg XkbSendGeometry(client,finfo.xkb->geom,&grep,False); 537205b261ecSmrg if (rep.loaded) { 537305b261ecSmrg XkbDescPtr old_xkb; 537405b261ecSmrg xkbNewKeyboardNotify nkn; 537505b261ecSmrg int i,nG,nTG; 537605b261ecSmrg old_xkb= xkb; 537705b261ecSmrg xkb= finfo.xkb; 537805b261ecSmrg dev->key->xkbInfo->desc= xkb; 537905b261ecSmrg finfo.xkb= old_xkb; /* so it'll get freed automatically */ 538005b261ecSmrg 538105b261ecSmrg *xkb->ctrls= *old_xkb->ctrls; 538205b261ecSmrg for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 538305b261ecSmrg nG= XkbKeyNumGroups(xkb,i); 538405b261ecSmrg if (nG>=XkbNumKbdGroups) { 538505b261ecSmrg nTG= XkbNumKbdGroups; 538605b261ecSmrg break; 538705b261ecSmrg } 538805b261ecSmrg if (nG>nTG) { 538905b261ecSmrg nTG= nG; 539005b261ecSmrg } 539105b261ecSmrg } 539205b261ecSmrg xkb->ctrls->num_groups= nTG; 539305b261ecSmrg 539405b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 539505b261ecSmrg if (tmpd == dev || 539605b261ecSmrg (dev->id == inputInfo.keyboard->id && tmpd->key && 539705b261ecSmrg tmpd->coreEvents)) { 539805b261ecSmrg 539905b261ecSmrg memcpy(tmpd->key->modifierMap, xkb->map->modmap, 540005b261ecSmrg xkb->max_key_code + 1); 540105b261ecSmrg if (tmpd != dev) 540205b261ecSmrg XkbCopyKeymap(dev->key->xkbInfo->desc, 540305b261ecSmrg tmpd->key->xkbInfo->desc, True); 540405b261ecSmrg XkbUpdateCoreDescription(tmpd, True); 540505b261ecSmrg 540605b261ecSmrg if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 540705b261ecSmrg old_sli = tmpd->kbdfeed->xkb_sli; 540805b261ecSmrg tmpd->kbdfeed->xkb_sli = NULL; 540905b261ecSmrg sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 541005b261ecSmrg if (sli) { 541105b261ecSmrg sli->explicitState = old_sli->explicitState; 541205b261ecSmrg sli->effectiveState = old_sli->effectiveState; 541305b261ecSmrg } 541405b261ecSmrg tmpd->kbdfeed->xkb_sli = sli; 541505b261ecSmrg XkbFreeSrvLedInfo(old_sli); 541605b261ecSmrg } 541705b261ecSmrg } 541805b261ecSmrg } 541905b261ecSmrg 542005b261ecSmrg /* this should be either a MN or an NKN, depending on whether or not 542105b261ecSmrg * the keycode range changed? */ 542205b261ecSmrg nkn.deviceID= nkn.oldDeviceID= dev->id; 542305b261ecSmrg nkn.minKeyCode= finfo.xkb->min_key_code; 542405b261ecSmrg nkn.maxKeyCode= finfo.xkb->max_key_code; 542505b261ecSmrg nkn.oldMinKeyCode= xkb->min_key_code; 542605b261ecSmrg nkn.oldMaxKeyCode= xkb->max_key_code; 542705b261ecSmrg nkn.requestMajor= XkbReqCode; 542805b261ecSmrg nkn.requestMinor= X_kbGetKbdByName; 542905b261ecSmrg nkn.changed= XkbNKN_KeycodesMask; 543005b261ecSmrg if (geom_changed) 543105b261ecSmrg nkn.changed|= XkbNKN_GeometryMask; 543205b261ecSmrg XkbSendNewKeyboardNotify(dev,&nkn); 543305b261ecSmrg } 543405b261ecSmrg if ((finfo.xkb!=NULL)&&(finfo.xkb!=xkb)) { 543505b261ecSmrg XkbFreeKeyboard(finfo.xkb,XkbAllComponentsMask,True); 543605b261ecSmrg finfo.xkb= NULL; 543705b261ecSmrg } 543805b261ecSmrg if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; } 543905b261ecSmrg if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; } 544005b261ecSmrg if (names.types) { _XkbFree(names.types); names.types= NULL; } 544105b261ecSmrg if (names.compat) { _XkbFree(names.compat); names.compat= NULL; } 544205b261ecSmrg if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; } 544305b261ecSmrg if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; } 544405b261ecSmrg return client->noClientException; 544505b261ecSmrg} 544605b261ecSmrg 544705b261ecSmrg/***====================================================================***/ 544805b261ecSmrg 544905b261ecSmrgstatic int 545005b261ecSmrgComputeDeviceLedInfoSize( DeviceIntPtr dev, 545105b261ecSmrg unsigned int what, 545205b261ecSmrg XkbSrvLedInfoPtr sli) 545305b261ecSmrg{ 545405b261ecSmrgint nNames,nMaps; 545505b261ecSmrgregister unsigned n,bit; 545605b261ecSmrg 545705b261ecSmrg if (sli==NULL) 545805b261ecSmrg return 0; 545905b261ecSmrg nNames= nMaps= 0; 546005b261ecSmrg if ((what&XkbXI_IndicatorNamesMask)==0) 546105b261ecSmrg sli->namesPresent= 0; 546205b261ecSmrg if ((what&XkbXI_IndicatorMapsMask)==0) 546305b261ecSmrg sli->mapsPresent= 0; 546405b261ecSmrg 546505b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 546605b261ecSmrg if (sli->names && sli->names[n]!=None) { 546705b261ecSmrg sli->namesPresent|= bit; 546805b261ecSmrg nNames++; 546905b261ecSmrg } 547005b261ecSmrg if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 547105b261ecSmrg sli->mapsPresent|= bit; 547205b261ecSmrg nMaps++; 547305b261ecSmrg } 547405b261ecSmrg } 547505b261ecSmrg return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); 547605b261ecSmrg} 547705b261ecSmrg 547805b261ecSmrgstatic int 547905b261ecSmrgCheckDeviceLedFBs( DeviceIntPtr dev, 548005b261ecSmrg int class, 548105b261ecSmrg int id, 548205b261ecSmrg xkbGetDeviceInfoReply * rep, 548305b261ecSmrg ClientPtr client) 548405b261ecSmrg{ 548505b261ecSmrgint nFBs= 0; 548605b261ecSmrgint length= 0; 548705b261ecSmrgBool classOk; 548805b261ecSmrg 548905b261ecSmrg if (class==XkbDfltXIClass) { 549005b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 549105b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 549205b261ecSmrg else { 549305b261ecSmrg client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 549405b261ecSmrg return XkbKeyboardErrorCode; 549505b261ecSmrg } 549605b261ecSmrg } 549705b261ecSmrg classOk= False; 549805b261ecSmrg if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 549905b261ecSmrg KbdFeedbackPtr kf; 550005b261ecSmrg classOk= True; 550105b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 550205b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) 550305b261ecSmrg continue; 550405b261ecSmrg nFBs++; 550505b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 550605b261ecSmrg if (!kf->xkb_sli) 550705b261ecSmrg kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); 550805b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); 550905b261ecSmrg if (id!=XkbAllXIIds) 551005b261ecSmrg break; 551105b261ecSmrg } 551205b261ecSmrg } 551305b261ecSmrg if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 551405b261ecSmrg LedFeedbackPtr lf; 551505b261ecSmrg classOk= True; 551605b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 551705b261ecSmrg if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) 551805b261ecSmrg continue; 551905b261ecSmrg nFBs++; 552005b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 552105b261ecSmrg if (!lf->xkb_sli) 552205b261ecSmrg lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); 552305b261ecSmrg length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); 552405b261ecSmrg if (id!=XkbAllXIIds) 552505b261ecSmrg break; 552605b261ecSmrg } 552705b261ecSmrg } 552805b261ecSmrg if (nFBs>0) { 552905b261ecSmrg if (rep->supported&XkbXI_IndicatorsMask) { 553005b261ecSmrg rep->nDeviceLedFBs= nFBs; 553105b261ecSmrg rep->length+= (length/4); 553205b261ecSmrg } 553305b261ecSmrg return Success; 553405b261ecSmrg } 553505b261ecSmrg if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); 553605b261ecSmrg else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 553705b261ecSmrg return XkbKeyboardErrorCode; 553805b261ecSmrg} 553905b261ecSmrg 554005b261ecSmrgstatic int 554105b261ecSmrgSendDeviceLedInfo( XkbSrvLedInfoPtr sli, 554205b261ecSmrg ClientPtr client) 554305b261ecSmrg{ 554405b261ecSmrgxkbDeviceLedsWireDesc wire; 554505b261ecSmrgint length; 554605b261ecSmrg 554705b261ecSmrg length= 0; 554805b261ecSmrg wire.ledClass= sli->class; 554905b261ecSmrg wire.ledID= sli->id; 555005b261ecSmrg wire.namesPresent= sli->namesPresent; 555105b261ecSmrg wire.mapsPresent= sli->mapsPresent; 555205b261ecSmrg wire.physIndicators= sli->physIndicators; 555305b261ecSmrg wire.state= sli->effectiveState; 555405b261ecSmrg if (client->swapped) { 555505b261ecSmrg register int n; 555605b261ecSmrg swaps(&wire.ledClass,n); 555705b261ecSmrg swaps(&wire.ledID,n); 555805b261ecSmrg swapl(&wire.namesPresent,n); 555905b261ecSmrg swapl(&wire.mapsPresent,n); 556005b261ecSmrg swapl(&wire.physIndicators,n); 556105b261ecSmrg swapl(&wire.state,n); 556205b261ecSmrg } 556305b261ecSmrg WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); 556405b261ecSmrg length+= SIZEOF(xkbDeviceLedsWireDesc); 556505b261ecSmrg if (sli->namesPresent|sli->mapsPresent) { 556605b261ecSmrg register unsigned i,bit; 556705b261ecSmrg if (sli->namesPresent) { 556805b261ecSmrg CARD32 awire; 556905b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 557005b261ecSmrg if (sli->namesPresent&bit) { 557105b261ecSmrg awire= (CARD32)sli->names[i]; 557205b261ecSmrg if (client->swapped) { 557305b261ecSmrg register int n; 557405b261ecSmrg swapl(&awire,n); 557505b261ecSmrg } 557605b261ecSmrg WriteToClient(client,4,(char *)&awire); 557705b261ecSmrg length+= 4; 557805b261ecSmrg } 557905b261ecSmrg } 558005b261ecSmrg } 558105b261ecSmrg if (sli->mapsPresent) { 558205b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 558305b261ecSmrg xkbIndicatorMapWireDesc iwire; 558405b261ecSmrg if (sli->mapsPresent&bit) { 558505b261ecSmrg iwire.flags= sli->maps[i].flags; 558605b261ecSmrg iwire.whichGroups= sli->maps[i].which_groups; 558705b261ecSmrg iwire.groups= sli->maps[i].groups; 558805b261ecSmrg iwire.whichMods= sli->maps[i].which_mods; 558905b261ecSmrg iwire.mods= sli->maps[i].mods.mask; 559005b261ecSmrg iwire.realMods= sli->maps[i].mods.real_mods; 559105b261ecSmrg iwire.virtualMods= sli->maps[i].mods.vmods; 559205b261ecSmrg iwire.ctrls= sli->maps[i].ctrls; 559305b261ecSmrg if (client->swapped) { 559405b261ecSmrg register int n; 559505b261ecSmrg swaps(&iwire.virtualMods,n); 559605b261ecSmrg swapl(&iwire.ctrls,n); 559705b261ecSmrg } 559805b261ecSmrg WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), 559905b261ecSmrg (char *)&iwire); 560005b261ecSmrg length+= SIZEOF(xkbIndicatorMapWireDesc); 560105b261ecSmrg } 560205b261ecSmrg } 560305b261ecSmrg } 560405b261ecSmrg } 560505b261ecSmrg return length; 560605b261ecSmrg} 560705b261ecSmrg 560805b261ecSmrgstatic int 560905b261ecSmrgSendDeviceLedFBs( DeviceIntPtr dev, 561005b261ecSmrg int class, 561105b261ecSmrg int id, 561205b261ecSmrg unsigned wantLength, 561305b261ecSmrg ClientPtr client) 561405b261ecSmrg{ 561505b261ecSmrgint length= 0; 561605b261ecSmrg 561705b261ecSmrg if (class==XkbDfltXIClass) { 561805b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 561905b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 562005b261ecSmrg } 562105b261ecSmrg if ((dev->kbdfeed)&& 562205b261ecSmrg ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 562305b261ecSmrg KbdFeedbackPtr kf; 562405b261ecSmrg for (kf= dev->kbdfeed;(kf);kf=kf->next) { 562505b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { 562605b261ecSmrg length+= SendDeviceLedInfo(kf->xkb_sli,client); 562705b261ecSmrg if (id!=XkbAllXIIds) 562805b261ecSmrg break; 562905b261ecSmrg } 563005b261ecSmrg } 563105b261ecSmrg } 563205b261ecSmrg if ((dev->leds)&& 563305b261ecSmrg ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 563405b261ecSmrg LedFeedbackPtr lf; 563505b261ecSmrg for (lf= dev->leds;(lf);lf=lf->next) { 563605b261ecSmrg if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { 563705b261ecSmrg length+= SendDeviceLedInfo(lf->xkb_sli,client); 563805b261ecSmrg if (id!=XkbAllXIIds) 563905b261ecSmrg break; 564005b261ecSmrg } 564105b261ecSmrg } 564205b261ecSmrg } 564305b261ecSmrg if (length==wantLength) 564405b261ecSmrg return Success; 564505b261ecSmrg else return BadLength; 564605b261ecSmrg} 564705b261ecSmrg 564805b261ecSmrgint 564905b261ecSmrgProcXkbGetDeviceInfo(ClientPtr client) 565005b261ecSmrg{ 565105b261ecSmrgDeviceIntPtr dev; 565205b261ecSmrgxkbGetDeviceInfoReply rep; 565305b261ecSmrgint status,nDeviceLedFBs; 565405b261ecSmrgunsigned length,nameLen; 565505b261ecSmrgCARD16 ledClass,ledID; 565605b261ecSmrgunsigned wanted,supported; 565705b261ecSmrgchar * str; 565805b261ecSmrg 565905b261ecSmrg REQUEST(xkbGetDeviceInfoReq); 566005b261ecSmrg REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 566105b261ecSmrg 566205b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 566305b261ecSmrg return BadAccess; 566405b261ecSmrg 566505b261ecSmrg wanted= stuff->wanted; 566605b261ecSmrg 566705b261ecSmrg CHK_ANY_DEVICE(dev,stuff->deviceSpec); 566805b261ecSmrg CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); 566905b261ecSmrg 567005b261ecSmrg if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) 567105b261ecSmrg wanted&= ~XkbXI_ButtonActionsMask; 567205b261ecSmrg if ((!dev->kbdfeed)&&(!dev->leds)) 567305b261ecSmrg wanted&= ~XkbXI_IndicatorsMask; 567405b261ecSmrg 567505b261ecSmrg nameLen= XkbSizeCountedString(dev->name); 567605b261ecSmrg bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply)); 567705b261ecSmrg rep.type = X_Reply; 567805b261ecSmrg rep.deviceID= dev->id; 567905b261ecSmrg rep.sequenceNumber = client->sequence; 568005b261ecSmrg rep.length = nameLen/4; 568105b261ecSmrg rep.present = wanted; 568205b261ecSmrg rep.supported = XkbXI_AllDeviceFeaturesMask; 568305b261ecSmrg rep.unsupported = 0; 568405b261ecSmrg rep.firstBtnWanted = rep.nBtnsWanted = 0; 568505b261ecSmrg rep.firstBtnRtrn = rep.nBtnsRtrn = 0; 568605b261ecSmrg if (dev->button) 568705b261ecSmrg rep.totalBtns= dev->button->numButtons; 568805b261ecSmrg else rep.totalBtns= 0; 568905b261ecSmrg rep.devType= dev->type; 569005b261ecSmrg rep.hasOwnState= (dev->key && dev->key->xkbInfo); 569105b261ecSmrg rep.nDeviceLedFBs = 0; 569205b261ecSmrg if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; 569305b261ecSmrg else rep.dfltKbdFB= XkbXINone; 569405b261ecSmrg if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; 569505b261ecSmrg else rep.dfltLedFB= XkbXINone; 569605b261ecSmrg 569705b261ecSmrg ledClass= stuff->ledClass; 569805b261ecSmrg ledID= stuff->ledID; 569905b261ecSmrg 570005b261ecSmrg rep.firstBtnWanted= rep.nBtnsWanted= 0; 570105b261ecSmrg rep.firstBtnRtrn= rep.nBtnsRtrn= 0; 570205b261ecSmrg if (wanted&XkbXI_ButtonActionsMask) { 570305b261ecSmrg if (stuff->allBtns) { 570405b261ecSmrg stuff->firstBtn= 0; 570505b261ecSmrg stuff->nBtns= dev->button->numButtons; 570605b261ecSmrg } 570705b261ecSmrg 570805b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 570905b261ecSmrg client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, 571005b261ecSmrg stuff->firstBtn, 571105b261ecSmrg stuff->nBtns); 571205b261ecSmrg return BadValue; 571305b261ecSmrg } 571405b261ecSmrg else { 571505b261ecSmrg rep.firstBtnWanted= stuff->firstBtn; 571605b261ecSmrg rep.nBtnsWanted= stuff->nBtns; 571705b261ecSmrg if (dev->button->xkb_acts!=NULL) { 571805b261ecSmrg XkbAction *act; 571905b261ecSmrg register int i; 572005b261ecSmrg 572105b261ecSmrg rep.firstBtnRtrn= stuff->firstBtn; 572205b261ecSmrg rep.nBtnsRtrn= stuff->nBtns; 572305b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnWanted]; 572405b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act++) { 572505b261ecSmrg if (act->type!=XkbSA_NoAction) 572605b261ecSmrg break; 572705b261ecSmrg } 572805b261ecSmrg rep.firstBtnRtrn+= i; 572905b261ecSmrg rep.nBtnsRtrn-= i; 573005b261ecSmrg act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; 573105b261ecSmrg for (i=0;i<rep.nBtnsRtrn;i++,act--) { 573205b261ecSmrg if (act->type!=XkbSA_NoAction) 573305b261ecSmrg break; 573405b261ecSmrg } 573505b261ecSmrg rep.nBtnsRtrn-= i; 573605b261ecSmrg } 573705b261ecSmrg rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; 573805b261ecSmrg } 573905b261ecSmrg } 574005b261ecSmrg 574105b261ecSmrg if (wanted&XkbXI_IndicatorsMask) { 574205b261ecSmrg status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); 574305b261ecSmrg if (status!=Success) 574405b261ecSmrg return status; 574505b261ecSmrg } 574605b261ecSmrg length= rep.length*4; 574705b261ecSmrg supported= rep.supported; 574805b261ecSmrg nDeviceLedFBs = rep.nDeviceLedFBs; 574905b261ecSmrg if (client->swapped) { 575005b261ecSmrg register int n; 575105b261ecSmrg swaps(&rep.sequenceNumber,n); 575205b261ecSmrg swapl(&rep.length,n); 575305b261ecSmrg swaps(&rep.present,n); 575405b261ecSmrg swaps(&rep.supported,n); 575505b261ecSmrg swaps(&rep.unsupported,n); 575605b261ecSmrg swaps(&rep.nDeviceLedFBs,n); 575705b261ecSmrg swapl(&rep.type,n); 575805b261ecSmrg } 575905b261ecSmrg WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); 576005b261ecSmrg 576105b261ecSmrg str= (char*) ALLOCATE_LOCAL(nameLen); 576205b261ecSmrg if (!str) 576305b261ecSmrg return BadAlloc; 576405b261ecSmrg XkbWriteCountedString(str,dev->name,client->swapped); 576505b261ecSmrg WriteToClient(client,nameLen,str); 576605b261ecSmrg DEALLOCATE_LOCAL(str); 576705b261ecSmrg length-= nameLen; 576805b261ecSmrg 576905b261ecSmrg if (rep.nBtnsRtrn>0) { 577005b261ecSmrg int sz; 577105b261ecSmrg xkbActionWireDesc * awire; 577205b261ecSmrg sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); 577305b261ecSmrg awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; 577405b261ecSmrg WriteToClient(client,sz,(char *)awire); 577505b261ecSmrg length-= sz; 577605b261ecSmrg } 577705b261ecSmrg if (nDeviceLedFBs>0) { 577805b261ecSmrg status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); 577905b261ecSmrg if (status!=Success) 578005b261ecSmrg return status; 578105b261ecSmrg } 578205b261ecSmrg else if (length!=0) { 578305b261ecSmrg#ifdef DEBUG 578405b261ecSmrg ErrorF("Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 578505b261ecSmrg ErrorF(" Wrote %d fewer bytes than expected\n",length); 578605b261ecSmrg#endif 578705b261ecSmrg return BadLength; 578805b261ecSmrg } 578905b261ecSmrg if (stuff->wanted&(~supported)) { 579005b261ecSmrg xkbExtensionDeviceNotify ed; 579105b261ecSmrg bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 579205b261ecSmrg ed.ledClass= ledClass; 579305b261ecSmrg ed.ledID= ledID; 579405b261ecSmrg ed.ledsDefined= 0; 579505b261ecSmrg ed.ledState= 0; 579605b261ecSmrg ed.firstBtn= ed.nBtns= 0; 579705b261ecSmrg ed.reason= XkbXI_UnsupportedFeatureMask; 579805b261ecSmrg ed.supported= supported; 579905b261ecSmrg ed.unsupported= stuff->wanted&(~supported); 580005b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&ed); 580105b261ecSmrg } 580205b261ecSmrg return client->noClientException; 580305b261ecSmrg} 580405b261ecSmrg 580505b261ecSmrgstatic char * 580605b261ecSmrgCheckSetDeviceIndicators( char * wire, 580705b261ecSmrg DeviceIntPtr dev, 580805b261ecSmrg int num, 580905b261ecSmrg int * status_rtrn, 581005b261ecSmrg ClientPtr client) 581105b261ecSmrg{ 581205b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 581305b261ecSmrgint i; 581405b261ecSmrgXkbSrvLedInfoPtr sli; 581505b261ecSmrg 581605b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 581705b261ecSmrg for (i=0;i<num;i++) { 581805b261ecSmrg if (client->swapped) { 581905b261ecSmrg register int n; 582005b261ecSmrg swaps(&ledWire->ledClass,n); 582105b261ecSmrg swaps(&ledWire->ledID,n); 582205b261ecSmrg swapl(&ledWire->namesPresent,n); 582305b261ecSmrg swapl(&ledWire->mapsPresent,n); 582405b261ecSmrg swapl(&ledWire->physIndicators,n); 582505b261ecSmrg } 582605b261ecSmrg 582705b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 582805b261ecSmrg XkbXI_IndicatorsMask); 582905b261ecSmrg if (sli!=NULL) { 583005b261ecSmrg register int n; 583105b261ecSmrg register unsigned bit; 583205b261ecSmrg int nMaps,nNames; 583305b261ecSmrg CARD32 *atomWire; 583405b261ecSmrg xkbIndicatorMapWireDesc *mapWire; 583505b261ecSmrg 583605b261ecSmrg nMaps= nNames= 0; 583705b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 583805b261ecSmrg if (ledWire->namesPresent&bit) 583905b261ecSmrg nNames++; 584005b261ecSmrg if (ledWire->mapsPresent&bit) 584105b261ecSmrg nMaps++; 584205b261ecSmrg } 584305b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 584405b261ecSmrg if (nNames>0) { 584505b261ecSmrg for (n=0;n<nNames;n++) { 584605b261ecSmrg if (client->swapped) { 584705b261ecSmrg register int t; 584805b261ecSmrg swapl(atomWire,t); 584905b261ecSmrg } 585005b261ecSmrg CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, 585105b261ecSmrg *status_rtrn,NULL); 585205b261ecSmrg atomWire++; 585305b261ecSmrg } 585405b261ecSmrg } 585505b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 585605b261ecSmrg if (nMaps>0) { 585705b261ecSmrg for (n=0;n<nMaps;n++) { 585805b261ecSmrg if (client->swapped) { 585905b261ecSmrg register int t; 586005b261ecSmrg swaps(&mapWire->virtualMods,t); 586105b261ecSmrg swapl(&mapWire->ctrls,t); 586205b261ecSmrg } 586305b261ecSmrg CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, 586405b261ecSmrg XkbIM_UseAnyGroup, 586505b261ecSmrg client->errorValue, 586605b261ecSmrg *status_rtrn,NULL); 586705b261ecSmrg CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, 586805b261ecSmrg client->errorValue, 586905b261ecSmrg *status_rtrn,NULL); 587005b261ecSmrg mapWire++; 587105b261ecSmrg } 587205b261ecSmrg } 587305b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 587405b261ecSmrg } 587505b261ecSmrg else { 587605b261ecSmrg /* SHOULD NEVER HAPPEN */ 587705b261ecSmrg return (char *)ledWire; 587805b261ecSmrg } 587905b261ecSmrg } 588005b261ecSmrg return (char *)ledWire; 588105b261ecSmrg} 588205b261ecSmrg 588305b261ecSmrgstatic char * 588405b261ecSmrgSetDeviceIndicators( char * wire, 588505b261ecSmrg DeviceIntPtr dev, 588605b261ecSmrg unsigned changed, 588705b261ecSmrg int num, 588805b261ecSmrg int * status_rtrn, 588905b261ecSmrg ClientPtr client, 589005b261ecSmrg xkbExtensionDeviceNotify *ev) 589105b261ecSmrg{ 589205b261ecSmrgxkbDeviceLedsWireDesc * ledWire; 589305b261ecSmrgint i; 589405b261ecSmrgXkbEventCauseRec cause; 589505b261ecSmrgunsigned namec,mapc,statec; 589605b261ecSmrgxkbExtensionDeviceNotify ed; 589705b261ecSmrgXkbChangesRec changes; 589805b261ecSmrgDeviceIntPtr kbd; 589905b261ecSmrg 590005b261ecSmrg bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 590105b261ecSmrg bzero((char *)&changes,sizeof(XkbChangesRec)); 590205b261ecSmrg XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); 590305b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)wire; 590405b261ecSmrg for (i=0;i<num;i++) { 590505b261ecSmrg register int n; 590605b261ecSmrg register unsigned bit; 590705b261ecSmrg CARD32 * atomWire; 590805b261ecSmrg xkbIndicatorMapWireDesc * mapWire; 590905b261ecSmrg XkbSrvLedInfoPtr sli; 591005b261ecSmrg 591105b261ecSmrg namec= mapc= statec= 0; 591205b261ecSmrg sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 591305b261ecSmrg XkbXI_IndicatorMapsMask); 591405b261ecSmrg if (!sli) { 591505b261ecSmrg /* SHOULD NEVER HAPPEN!! */ 591605b261ecSmrg return (char *)ledWire; 591705b261ecSmrg } 591805b261ecSmrg 591905b261ecSmrg atomWire= (CARD32 *)&ledWire[1]; 592005b261ecSmrg if (changed&XkbXI_IndicatorNamesMask) { 592105b261ecSmrg namec= sli->namesPresent|ledWire->namesPresent; 592205b261ecSmrg bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 592305b261ecSmrg } 592405b261ecSmrg if (ledWire->namesPresent) { 592505b261ecSmrg sli->namesPresent= ledWire->namesPresent; 592605b261ecSmrg bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 592705b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 592805b261ecSmrg if (ledWire->namesPresent&bit) { 592905b261ecSmrg sli->names[n]= (Atom)*atomWire; 593005b261ecSmrg if (sli->names[n]==None) 593105b261ecSmrg ledWire->namesPresent&= ~bit; 593205b261ecSmrg atomWire++; 593305b261ecSmrg } 593405b261ecSmrg } 593505b261ecSmrg } 593605b261ecSmrg mapWire= (xkbIndicatorMapWireDesc *)atomWire; 593705b261ecSmrg if (changed&XkbXI_IndicatorMapsMask) { 593805b261ecSmrg mapc= sli->mapsPresent|ledWire->mapsPresent; 593905b261ecSmrg sli->mapsPresent= ledWire->mapsPresent; 594005b261ecSmrg bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec)); 594105b261ecSmrg } 594205b261ecSmrg if (ledWire->mapsPresent) { 594305b261ecSmrg for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 594405b261ecSmrg if (ledWire->mapsPresent&bit) { 594505b261ecSmrg sli->maps[n].flags= mapWire->flags; 594605b261ecSmrg sli->maps[n].which_groups= mapWire->whichGroups; 594705b261ecSmrg sli->maps[n].groups= mapWire->groups; 594805b261ecSmrg sli->maps[n].which_mods= mapWire->whichMods; 594905b261ecSmrg sli->maps[n].mods.mask= mapWire->mods; 595005b261ecSmrg sli->maps[n].mods.real_mods=mapWire->realMods; 595105b261ecSmrg sli->maps[n].mods.vmods= mapWire->virtualMods; 595205b261ecSmrg sli->maps[n].ctrls= mapWire->ctrls; 595305b261ecSmrg mapWire++; 595405b261ecSmrg } 595505b261ecSmrg } 595605b261ecSmrg } 595705b261ecSmrg if (changed&XkbXI_IndicatorStateMask) { 595805b261ecSmrg statec= sli->effectiveState^ledWire->state; 595905b261ecSmrg sli->explicitState&= ~statec; 596005b261ecSmrg sli->explicitState|= (ledWire->state&statec); 596105b261ecSmrg } 596205b261ecSmrg if (namec) 596305b261ecSmrg XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 596405b261ecSmrg if (mapc) 596505b261ecSmrg XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 596605b261ecSmrg if (statec) 596705b261ecSmrg XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 596805b261ecSmrg 596905b261ecSmrg kbd= dev; 597005b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 597105b261ecSmrg kbd= (DeviceIntPtr)LookupKeyboardDevice(); 597205b261ecSmrg 597305b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 597405b261ecSmrg ledWire= (xkbDeviceLedsWireDesc *)mapWire; 597505b261ecSmrg } 597605b261ecSmrg return (char *)ledWire; 597705b261ecSmrg} 597805b261ecSmrg 597905b261ecSmrg/* FIXME: Needs to set info on all core-sending devices. */ 598005b261ecSmrgint 598105b261ecSmrgProcXkbSetDeviceInfo(ClientPtr client) 598205b261ecSmrg{ 598305b261ecSmrgDeviceIntPtr dev; 598405b261ecSmrgunsigned change; 598505b261ecSmrgchar * wire; 598605b261ecSmrgxkbExtensionDeviceNotify ed; 598705b261ecSmrg 598805b261ecSmrg REQUEST(xkbSetDeviceInfoReq); 598905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 599005b261ecSmrg 599105b261ecSmrg if (!(client->xkbClientFlags&_XkbClientInitialized)) 599205b261ecSmrg return BadAccess; 599305b261ecSmrg 599405b261ecSmrg change= stuff->change; 599505b261ecSmrg 599605b261ecSmrg CHK_ANY_DEVICE(dev,stuff->deviceSpec); 599705b261ecSmrg CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask); 599805b261ecSmrg 599905b261ecSmrg wire= (char *)&stuff[1]; 600005b261ecSmrg if (change&XkbXI_ButtonActionsMask) { 600105b261ecSmrg if (!dev->button) { 600205b261ecSmrg client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); 600305b261ecSmrg return XkbKeyboardErrorCode; 600405b261ecSmrg } 600505b261ecSmrg if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 600605b261ecSmrg client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, 600705b261ecSmrg dev->button->numButtons); 600805b261ecSmrg return BadMatch; 600905b261ecSmrg } 601005b261ecSmrg wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); 601105b261ecSmrg } 601205b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 601305b261ecSmrg int status= Success; 601405b261ecSmrg wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, 601505b261ecSmrg &status,client); 601605b261ecSmrg if (status!=Success) 601705b261ecSmrg return status; 601805b261ecSmrg } 601905b261ecSmrg if (((wire-((char *)stuff))/4)!=stuff->length) 602005b261ecSmrg return BadLength; 602105b261ecSmrg 602205b261ecSmrg bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 602305b261ecSmrg ed.deviceID= dev->id; 602405b261ecSmrg wire= (char *)&stuff[1]; 602505b261ecSmrg if (change&XkbXI_ButtonActionsMask) { 602605b261ecSmrg int nBtns,sz,i; 602705b261ecSmrg XkbAction * acts; 602805b261ecSmrg DeviceIntPtr kbd; 602905b261ecSmrg 603005b261ecSmrg nBtns= dev->button->numButtons; 603105b261ecSmrg acts= dev->button->xkb_acts; 603205b261ecSmrg if (acts==NULL) { 603305b261ecSmrg acts= _XkbTypedCalloc(nBtns,XkbAction); 603405b261ecSmrg if (!acts) 603505b261ecSmrg return BadAlloc; 603605b261ecSmrg dev->button->xkb_acts= acts; 603705b261ecSmrg } 603805b261ecSmrg sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); 603905b261ecSmrg memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); 604005b261ecSmrg wire+= sz; 604105b261ecSmrg ed.reason|= XkbXI_ButtonActionsMask; 604205b261ecSmrg ed.firstBtn= stuff->firstBtn; 604305b261ecSmrg ed.nBtns= stuff->nBtns; 604405b261ecSmrg 604505b261ecSmrg if (dev->key) kbd= dev; 604605b261ecSmrg else kbd= (DeviceIntPtr)LookupKeyboardDevice(); 604705b261ecSmrg acts= &dev->button->xkb_acts[stuff->firstBtn]; 604805b261ecSmrg for (i=0;i<stuff->nBtns;i++,acts++) { 604905b261ecSmrg if (acts->type!=XkbSA_NoAction) 605005b261ecSmrg XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); 605105b261ecSmrg } 605205b261ecSmrg } 605305b261ecSmrg if (stuff->change&XkbXI_IndicatorsMask) { 605405b261ecSmrg int status= Success; 605505b261ecSmrg wire= SetDeviceIndicators(wire,dev,change,stuff->nDeviceLedFBs, 605605b261ecSmrg &status,client,&ed); 605705b261ecSmrg if (status!=Success) 605805b261ecSmrg return status; 605905b261ecSmrg } 606005b261ecSmrg if ((stuff->change)&&(ed.reason)) 606105b261ecSmrg XkbSendExtensionDeviceNotify(dev,client,&ed); 606205b261ecSmrg return client->noClientException; 606305b261ecSmrg} 606405b261ecSmrg 606505b261ecSmrg/***====================================================================***/ 606605b261ecSmrg 606705b261ecSmrgint 606805b261ecSmrgProcXkbSetDebuggingFlags(ClientPtr client) 606905b261ecSmrg{ 607005b261ecSmrgCARD32 newFlags,newCtrls,extraLength; 607105b261ecSmrgxkbSetDebuggingFlagsReply rep; 607205b261ecSmrg 607305b261ecSmrg REQUEST(xkbSetDebuggingFlagsReq); 607405b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 607505b261ecSmrg 607605b261ecSmrg newFlags= xkbDebugFlags&(~stuff->affectFlags); 607705b261ecSmrg newFlags|= (stuff->flags&stuff->affectFlags); 607805b261ecSmrg newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); 607905b261ecSmrg newCtrls|= (stuff->ctrls&stuff->affectCtrls); 608005b261ecSmrg if (xkbDebugFlags || newFlags || stuff->msgLength) { 608105b261ecSmrg ErrorF("XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); 608205b261ecSmrg if (newCtrls!=xkbDebugCtrls) 608305b261ecSmrg ErrorF("XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); 608405b261ecSmrg } 608505b261ecSmrg extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; 608605b261ecSmrg if (stuff->msgLength>0) { 608705b261ecSmrg char *msg; 608805b261ecSmrg if (extraLength<XkbPaddedSize(stuff->msgLength)) { 608905b261ecSmrg ErrorF("XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 609005b261ecSmrg stuff->msgLength,(long)extraLength, 609105b261ecSmrg XkbPaddedSize(stuff->msgLength)); 609205b261ecSmrg return BadLength; 609305b261ecSmrg } 609405b261ecSmrg msg= (char *)&stuff[1]; 609505b261ecSmrg if (msg[stuff->msgLength-1]!='\0') { 609605b261ecSmrg ErrorF("XkbDebug: message not null-terminated\n"); 609705b261ecSmrg return BadValue; 609805b261ecSmrg } 609905b261ecSmrg ErrorF("XkbDebug: %s\n",msg); 610005b261ecSmrg } 610105b261ecSmrg xkbDebugFlags = newFlags; 610205b261ecSmrg xkbDebugCtrls = newCtrls; 610305b261ecSmrg 610405b261ecSmrg XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks); 610505b261ecSmrg 610605b261ecSmrg rep.type= X_Reply; 610705b261ecSmrg rep.length = 0; 610805b261ecSmrg rep.sequenceNumber = client->sequence; 610905b261ecSmrg rep.currentFlags = newFlags; 611005b261ecSmrg rep.currentCtrls = newCtrls; 611105b261ecSmrg rep.supportedFlags = ~0; 611205b261ecSmrg rep.supportedCtrls = ~0; 611305b261ecSmrg if ( client->swapped ) { 611405b261ecSmrg register int n; 611505b261ecSmrg swaps(&rep.sequenceNumber, n); 611605b261ecSmrg swapl(&rep.currentFlags, n); 611705b261ecSmrg swapl(&rep.currentCtrls, n); 611805b261ecSmrg swapl(&rep.supportedFlags, n); 611905b261ecSmrg swapl(&rep.supportedCtrls, n); 612005b261ecSmrg } 612105b261ecSmrg WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); 612205b261ecSmrg return client->noClientException; 612305b261ecSmrg} 612405b261ecSmrg 612505b261ecSmrg/***====================================================================***/ 612605b261ecSmrg 612705b261ecSmrgstatic int 612805b261ecSmrgProcXkbDispatch (ClientPtr client) 612905b261ecSmrg{ 613005b261ecSmrg REQUEST(xReq); 613105b261ecSmrg switch (stuff->data) 613205b261ecSmrg { 613305b261ecSmrg case X_kbUseExtension: 613405b261ecSmrg return ProcXkbUseExtension(client); 613505b261ecSmrg case X_kbSelectEvents: 613605b261ecSmrg return ProcXkbSelectEvents(client); 613705b261ecSmrg case X_kbBell: 613805b261ecSmrg return ProcXkbBell(client); 613905b261ecSmrg case X_kbGetState: 614005b261ecSmrg return ProcXkbGetState(client); 614105b261ecSmrg case X_kbLatchLockState: 614205b261ecSmrg return ProcXkbLatchLockState(client); 614305b261ecSmrg case X_kbGetControls: 614405b261ecSmrg return ProcXkbGetControls(client); 614505b261ecSmrg case X_kbSetControls: 614605b261ecSmrg return ProcXkbSetControls(client); 614705b261ecSmrg case X_kbGetMap: 614805b261ecSmrg return ProcXkbGetMap(client); 614905b261ecSmrg case X_kbSetMap: 615005b261ecSmrg return ProcXkbSetMap(client); 615105b261ecSmrg case X_kbGetCompatMap: 615205b261ecSmrg return ProcXkbGetCompatMap(client); 615305b261ecSmrg case X_kbSetCompatMap: 615405b261ecSmrg return ProcXkbSetCompatMap(client); 615505b261ecSmrg case X_kbGetIndicatorState: 615605b261ecSmrg return ProcXkbGetIndicatorState(client); 615705b261ecSmrg case X_kbGetIndicatorMap: 615805b261ecSmrg return ProcXkbGetIndicatorMap(client); 615905b261ecSmrg case X_kbSetIndicatorMap: 616005b261ecSmrg return ProcXkbSetIndicatorMap(client); 616105b261ecSmrg case X_kbGetNamedIndicator: 616205b261ecSmrg return ProcXkbGetNamedIndicator(client); 616305b261ecSmrg case X_kbSetNamedIndicator: 616405b261ecSmrg return ProcXkbSetNamedIndicator(client); 616505b261ecSmrg case X_kbGetNames: 616605b261ecSmrg return ProcXkbGetNames(client); 616705b261ecSmrg case X_kbSetNames: 616805b261ecSmrg return ProcXkbSetNames(client); 616905b261ecSmrg case X_kbGetGeometry: 617005b261ecSmrg return ProcXkbGetGeometry(client); 617105b261ecSmrg case X_kbSetGeometry: 617205b261ecSmrg return ProcXkbSetGeometry(client); 617305b261ecSmrg case X_kbPerClientFlags: 617405b261ecSmrg return ProcXkbPerClientFlags(client); 617505b261ecSmrg case X_kbListComponents: 617605b261ecSmrg return ProcXkbListComponents(client); 617705b261ecSmrg case X_kbGetKbdByName: 617805b261ecSmrg return ProcXkbGetKbdByName(client); 617905b261ecSmrg case X_kbGetDeviceInfo: 618005b261ecSmrg return ProcXkbGetDeviceInfo(client); 618105b261ecSmrg case X_kbSetDeviceInfo: 618205b261ecSmrg return ProcXkbSetDeviceInfo(client); 618305b261ecSmrg case X_kbSetDebuggingFlags: 618405b261ecSmrg return ProcXkbSetDebuggingFlags(client); 618505b261ecSmrg default: 618605b261ecSmrg return BadRequest; 618705b261ecSmrg } 618805b261ecSmrg} 618905b261ecSmrg 619005b261ecSmrgstatic int 619105b261ecSmrgXkbClientGone(pointer data,XID id) 619205b261ecSmrg{ 619305b261ecSmrg DevicePtr pXDev = (DevicePtr)data; 619405b261ecSmrg 619505b261ecSmrg if (!XkbRemoveResourceClient(pXDev,id)) { 619605b261ecSmrg ErrorF("Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 619705b261ecSmrg } 619805b261ecSmrg return 1; 619905b261ecSmrg} 620005b261ecSmrg 620105b261ecSmrg/*ARGSUSED*/ 620205b261ecSmrgstatic void 620305b261ecSmrgXkbResetProc(ExtensionEntry *extEntry) 620405b261ecSmrg{ 620505b261ecSmrg} 620605b261ecSmrg 620705b261ecSmrgvoid 620805b261ecSmrgXkbExtensionInit(void) 620905b261ecSmrg{ 621005b261ecSmrg ExtensionEntry *extEntry; 621105b261ecSmrg 621205b261ecSmrg if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 621305b261ecSmrg ProcXkbDispatch, SProcXkbDispatch, 621405b261ecSmrg XkbResetProc, StandardMinorOpcode))) { 621505b261ecSmrg XkbReqCode = (unsigned char)extEntry->base; 621605b261ecSmrg XkbEventBase = (unsigned char)extEntry->eventBase; 621705b261ecSmrg XkbErrorBase = (unsigned char)extEntry->errorBase; 621805b261ecSmrg XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; 621905b261ecSmrg RT_XKBCLIENT = CreateNewResourceType(XkbClientGone); 622005b261ecSmrg } 622105b261ecSmrg return; 622205b261ecSmrg} 622305b261ecSmrg 622405b261ecSmrg 6225