xkb.c revision 5a112b11
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 9f7df2e56Smrgdocumentation, and that the name of Silicon Graphics not be 10f7df2e56Smrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 12f7df2e56SmrgSilicon 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 16f7df2e56SmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17f7df2e56SmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19f7df2e56SmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20f7df2e56SmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21f7df2e56SmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <X11/X.h> 3305b261ecSmrg#include <X11/Xproto.h> 3405b261ecSmrg#include "misc.h" 3505b261ecSmrg#include "inputstr.h" 3605b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 3705b261ecSmrg#include <xkbsrv.h> 3805b261ecSmrg#include "extnsionst.h" 39f7df2e56Smrg#include "extinit.h" 404642e01fSmrg#include "xace.h" 4105b261ecSmrg#include "xkb.h" 426747b715Smrg#include "protocol-versions.h" 4305b261ecSmrg 4405b261ecSmrg#include <X11/extensions/XI.h> 456747b715Smrg#include <X11/extensions/XKMformat.h> 4605b261ecSmrg 47f7df2e56Smrgint XkbEventBase; 48f7df2e56Smrgstatic int XkbErrorBase; 49f7df2e56Smrgint XkbReqCode; 50f7df2e56Smrgint XkbKeyboardErrorCode; 51f7df2e56SmrgCARD32 xkbDebugFlags = 0; 52f7df2e56Smrgstatic CARD32 xkbDebugCtrls = 0; 5305b261ecSmrg 54f7df2e56Smrgstatic RESTYPE RT_XKBCLIENT; 5505b261ecSmrg 5605b261ecSmrg/***====================================================================***/ 5705b261ecSmrg 584642e01fSmrg#define CHK_DEVICE(dev, id, client, access_mode, lf) {\ 5905b261ecSmrg int why;\ 60f7df2e56Smrg int tmprc = lf(&(dev), id, client, access_mode, &why);\ 61f7df2e56Smrg if (tmprc != Success) {\ 624642e01fSmrg client->errorValue = _XkbErrCode2(why, id);\ 63f7df2e56Smrg return tmprc;\ 6405b261ecSmrg }\ 6505b261ecSmrg} 6605b261ecSmrg 674642e01fSmrg#define CHK_KBD_DEVICE(dev, id, client, mode) \ 684642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard) 694642e01fSmrg#define CHK_LED_DEVICE(dev, id, client, mode) \ 704642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice) 714642e01fSmrg#define CHK_BELL_DEVICE(dev, id, client, mode) \ 724642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice) 734642e01fSmrg#define CHK_ANY_DEVICE(dev, id, client, mode) \ 744642e01fSmrg CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice) 7505b261ecSmrg 7605b261ecSmrg#define CHK_ATOM_ONLY2(a,ev,er) {\ 7705b261ecSmrg if (((a)==None)||(!ValidAtom((a)))) {\ 7805b261ecSmrg (ev)= (XID)(a);\ 7905b261ecSmrg return er;\ 8005b261ecSmrg }\ 8105b261ecSmrg} 8205b261ecSmrg#define CHK_ATOM_ONLY(a) \ 8305b261ecSmrg CHK_ATOM_ONLY2(a,client->errorValue,BadAtom) 8405b261ecSmrg 8505b261ecSmrg#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\ 8605b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 8705b261ecSmrg (ev)= (XID)(a);\ 8805b261ecSmrg (er)= BadAtom;\ 8905b261ecSmrg return ret;\ 9005b261ecSmrg }\ 9105b261ecSmrg} 9205b261ecSmrg#define CHK_ATOM_OR_NONE2(a,ev,er) {\ 9305b261ecSmrg if (((a)!=None)&&(!ValidAtom((a)))) {\ 9405b261ecSmrg (ev)= (XID)(a);\ 9505b261ecSmrg return er;\ 9605b261ecSmrg }\ 9705b261ecSmrg} 9805b261ecSmrg#define CHK_ATOM_OR_NONE(a) \ 9905b261ecSmrg CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom) 10005b261ecSmrg 10105b261ecSmrg#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\ 10205b261ecSmrg if ((mask)&(~(legal))) { \ 10305b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 10405b261ecSmrg (er)= BadValue;\ 10505b261ecSmrg return ret;\ 10605b261ecSmrg }\ 10705b261ecSmrg} 10805b261ecSmrg#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\ 10905b261ecSmrg if ((mask)&(~(legal))) { \ 11005b261ecSmrg (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 11105b261ecSmrg return er;\ 11205b261ecSmrg }\ 11305b261ecSmrg} 11405b261ecSmrg#define CHK_MASK_LEGAL(err,mask,legal) \ 11505b261ecSmrg CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue) 11605b261ecSmrg 11705b261ecSmrg#define CHK_MASK_MATCH(err,affect,value) {\ 11805b261ecSmrg if ((value)&(~(affect))) { \ 11905b261ecSmrg client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\ 12005b261ecSmrg return BadMatch;\ 12105b261ecSmrg }\ 12205b261ecSmrg} 12305b261ecSmrg#define CHK_MASK_OVERLAP(err,m1,m2) {\ 12405b261ecSmrg if ((m1)&(m2)) { \ 12505b261ecSmrg client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\ 12605b261ecSmrg return BadMatch;\ 12705b261ecSmrg }\ 12805b261ecSmrg} 12905b261ecSmrg#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\ 13005b261ecSmrg if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\ 13105b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\ 13205b261ecSmrg return er;\ 13305b261ecSmrg }\ 13405b261ecSmrg else if ( (first)<(x)->min_key_code ) {\ 13505b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\ 13605b261ecSmrg return er;\ 13705b261ecSmrg }\ 13805b261ecSmrg} 13905b261ecSmrg#define CHK_KEY_RANGE(err,first,num,x) \ 14005b261ecSmrg CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue) 14105b261ecSmrg 14205b261ecSmrg#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\ 14305b261ecSmrg if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\ 14405b261ecSmrg (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\ 14505b261ecSmrg return er;\ 14605b261ecSmrg }\ 14705b261ecSmrg else if ( (first)<(r)->minKeyCode ) {\ 14805b261ecSmrg (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\ 14905b261ecSmrg return er;\ 15005b261ecSmrg }\ 15105b261ecSmrg} 15205b261ecSmrg#define CHK_REQ_KEY_RANGE(err,first,num,r) \ 15305b261ecSmrg CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) 15405b261ecSmrg 155806e81e9Smrgstatic Bool 156806e81e9Smrg_XkbCheckRequestBounds(ClientPtr client, void *stuff, void *from, void *to) { 157806e81e9Smrg char *cstuff = (char *)stuff; 158806e81e9Smrg char *cfrom = (char *)from; 159806e81e9Smrg char *cto = (char *)to; 160806e81e9Smrg 161806e81e9Smrg return cfrom < cto && 162806e81e9Smrg cfrom >= cstuff && 163806e81e9Smrg cfrom < cstuff + ((size_t)client->req_len << 2) && 164806e81e9Smrg cto >= cstuff && 165806e81e9Smrg cto <= cstuff + ((size_t)client->req_len << 2); 166806e81e9Smrg} 167806e81e9Smrg 16805b261ecSmrg/***====================================================================***/ 16905b261ecSmrg 17005b261ecSmrgint 17105b261ecSmrgProcXkbUseExtension(ClientPtr client) 17205b261ecSmrg{ 17305b261ecSmrg REQUEST(xkbUseExtensionReq); 174f7df2e56Smrg xkbUseExtensionReply rep; 175f7df2e56Smrg int supported; 17605b261ecSmrg 17705b261ecSmrg REQUEST_SIZE_MATCH(xkbUseExtensionReq); 1786747b715Smrg if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) { 179f7df2e56Smrg /* pre-release version 0.65 is compatible with 1.00 */ 180f7df2e56Smrg supported = ((SERVER_XKB_MAJOR_VERSION == 1) && 181f7df2e56Smrg (stuff->wantedMajor == 0) && (stuff->wantedMinor == 65)); 182f7df2e56Smrg } 183f7df2e56Smrg else 184f7df2e56Smrg supported = 1; 185f7df2e56Smrg 186f7df2e56Smrg if ((supported) && (!(client->xkbClientFlags & _XkbClientInitialized))) { 187f7df2e56Smrg client->xkbClientFlags = _XkbClientInitialized; 1887e31ba66Smrg if (stuff->wantedMajor == 0) 1897e31ba66Smrg client->xkbClientFlags |= _XkbClientIsAncient; 190f7df2e56Smrg } 191f7df2e56Smrg else if (xkbDebugFlags & 0x1) { 192f7df2e56Smrg ErrorF 193f7df2e56Smrg ("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", 194f7df2e56Smrg client->index, (long) client->clientAsMask, stuff->wantedMajor, 195f7df2e56Smrg stuff->wantedMinor, SERVER_XKB_MAJOR_VERSION, 196f7df2e56Smrg SERVER_XKB_MINOR_VERSION); 197f7df2e56Smrg } 198f7df2e56Smrg rep = (xkbUseExtensionReply) { 199f7df2e56Smrg .type = X_Reply, 200f7df2e56Smrg .supported = supported, 201f7df2e56Smrg .sequenceNumber = client->sequence, 202f7df2e56Smrg .length = 0, 203f7df2e56Smrg .serverMajor = SERVER_XKB_MAJOR_VERSION, 204f7df2e56Smrg .serverMinor = SERVER_XKB_MINOR_VERSION 205f7df2e56Smrg }; 206f7df2e56Smrg if (client->swapped) { 207f7df2e56Smrg swaps(&rep.sequenceNumber); 208f7df2e56Smrg swaps(&rep.serverMajor); 209f7df2e56Smrg swaps(&rep.serverMinor); 21005b261ecSmrg } 211f7df2e56Smrg WriteToClient(client, SIZEOF(xkbUseExtensionReply), &rep); 2126747b715Smrg return Success; 21305b261ecSmrg} 21405b261ecSmrg 21505b261ecSmrg/***====================================================================***/ 21605b261ecSmrg 21705b261ecSmrgint 21805b261ecSmrgProcXkbSelectEvents(ClientPtr client) 21905b261ecSmrg{ 220f7df2e56Smrg unsigned legal; 221f7df2e56Smrg DeviceIntPtr dev; 222f7df2e56Smrg XkbInterestPtr masks; 223f7df2e56Smrg 22405b261ecSmrg REQUEST(xkbSelectEventsReq); 22505b261ecSmrg 22605b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); 22705b261ecSmrg 228f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 229f7df2e56Smrg return BadAccess; 23005b261ecSmrg 2314642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess); 23205b261ecSmrg 233f7df2e56Smrg if (((stuff->affectWhich & XkbMapNotifyMask) != 0) && (stuff->affectMap)) { 234f7df2e56Smrg client->mapNotifyMask &= ~stuff->affectMap; 235f7df2e56Smrg client->mapNotifyMask |= (stuff->affectMap & stuff->map); 23605b261ecSmrg } 237f7df2e56Smrg if ((stuff->affectWhich & (~XkbMapNotifyMask)) == 0) 238f7df2e56Smrg return Success; 239f7df2e56Smrg 240f7df2e56Smrg masks = XkbFindClientResource((DevicePtr) dev, client); 241f7df2e56Smrg if (!masks) { 242f7df2e56Smrg XID id = FakeClientID(client->index); 24305b261ecSmrg 244f7df2e56Smrg if (!AddResource(id, RT_XKBCLIENT, dev)) 245f7df2e56Smrg return BadAlloc; 246f7df2e56Smrg masks = XkbAddClientResource((DevicePtr) dev, client, id); 24705b261ecSmrg } 24805b261ecSmrg if (masks) { 249f7df2e56Smrg union { 250f7df2e56Smrg CARD8 *c8; 251f7df2e56Smrg CARD16 *c16; 252f7df2e56Smrg CARD32 *c32; 253f7df2e56Smrg } from, to; 254f7df2e56Smrg register unsigned bit, ndx, maskLeft, dataLeft, size; 255f7df2e56Smrg 256f7df2e56Smrg from.c8 = (CARD8 *) &stuff[1]; 257f7df2e56Smrg dataLeft = (stuff->length * 4) - SIZEOF(xkbSelectEventsReq); 258f7df2e56Smrg maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask)); 259f7df2e56Smrg for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) { 260f7df2e56Smrg if ((bit & maskLeft) == 0) 261f7df2e56Smrg continue; 262f7df2e56Smrg maskLeft &= ~bit; 263f7df2e56Smrg switch (ndx) { 264f7df2e56Smrg case XkbNewKeyboardNotify: 265f7df2e56Smrg to.c16 = &client->newKeyboardNotifyMask; 266f7df2e56Smrg legal = XkbAllNewKeyboardEventsMask; 267f7df2e56Smrg size = 2; 268f7df2e56Smrg break; 269f7df2e56Smrg case XkbStateNotify: 270f7df2e56Smrg to.c16 = &masks->stateNotifyMask; 271f7df2e56Smrg legal = XkbAllStateEventsMask; 272f7df2e56Smrg size = 2; 273f7df2e56Smrg break; 274f7df2e56Smrg case XkbControlsNotify: 275f7df2e56Smrg to.c32 = &masks->ctrlsNotifyMask; 276f7df2e56Smrg legal = XkbAllControlEventsMask; 277f7df2e56Smrg size = 4; 278f7df2e56Smrg break; 279f7df2e56Smrg case XkbIndicatorStateNotify: 280f7df2e56Smrg to.c32 = &masks->iStateNotifyMask; 281f7df2e56Smrg legal = XkbAllIndicatorEventsMask; 282f7df2e56Smrg size = 4; 283f7df2e56Smrg break; 284f7df2e56Smrg case XkbIndicatorMapNotify: 285f7df2e56Smrg to.c32 = &masks->iMapNotifyMask; 286f7df2e56Smrg legal = XkbAllIndicatorEventsMask; 287f7df2e56Smrg size = 4; 288f7df2e56Smrg break; 289f7df2e56Smrg case XkbNamesNotify: 290f7df2e56Smrg to.c16 = &masks->namesNotifyMask; 291f7df2e56Smrg legal = XkbAllNameEventsMask; 292f7df2e56Smrg size = 2; 293f7df2e56Smrg break; 294f7df2e56Smrg case XkbCompatMapNotify: 295f7df2e56Smrg to.c8 = &masks->compatNotifyMask; 296f7df2e56Smrg legal = XkbAllCompatMapEventsMask; 297f7df2e56Smrg size = 1; 298f7df2e56Smrg break; 299f7df2e56Smrg case XkbBellNotify: 300f7df2e56Smrg to.c8 = &masks->bellNotifyMask; 301f7df2e56Smrg legal = XkbAllBellEventsMask; 302f7df2e56Smrg size = 1; 303f7df2e56Smrg break; 304f7df2e56Smrg case XkbActionMessage: 305f7df2e56Smrg to.c8 = &masks->actionMessageMask; 306f7df2e56Smrg legal = XkbAllActionMessagesMask; 307f7df2e56Smrg size = 1; 308f7df2e56Smrg break; 309f7df2e56Smrg case XkbAccessXNotify: 310f7df2e56Smrg to.c16 = &masks->accessXNotifyMask; 311f7df2e56Smrg legal = XkbAllAccessXEventsMask; 312f7df2e56Smrg size = 2; 313f7df2e56Smrg break; 314f7df2e56Smrg case XkbExtensionDeviceNotify: 315f7df2e56Smrg to.c16 = &masks->extDevNotifyMask; 316f7df2e56Smrg legal = XkbAllExtensionDeviceEventsMask; 317f7df2e56Smrg size = 2; 318f7df2e56Smrg break; 319f7df2e56Smrg default: 320f7df2e56Smrg client->errorValue = _XkbErrCode2(33, bit); 321f7df2e56Smrg return BadValue; 322f7df2e56Smrg } 323f7df2e56Smrg 324f7df2e56Smrg if (stuff->clear & bit) { 325f7df2e56Smrg if (size == 2) 326f7df2e56Smrg to.c16[0] = 0; 327f7df2e56Smrg else if (size == 4) 328f7df2e56Smrg to.c32[0] = 0; 329f7df2e56Smrg else 330f7df2e56Smrg to.c8[0] = 0; 331f7df2e56Smrg } 332f7df2e56Smrg else if (stuff->selectAll & bit) { 333f7df2e56Smrg if (size == 2) 334f7df2e56Smrg to.c16[0] = ~0; 335f7df2e56Smrg else if (size == 4) 336f7df2e56Smrg to.c32[0] = ~0; 337f7df2e56Smrg else 338f7df2e56Smrg to.c8[0] = ~0; 339f7df2e56Smrg } 340f7df2e56Smrg else { 341f7df2e56Smrg if (dataLeft < (size * 2)) 342f7df2e56Smrg return BadLength; 343f7df2e56Smrg if (size == 2) { 344f7df2e56Smrg CHK_MASK_MATCH(ndx, from.c16[0], from.c16[1]); 345f7df2e56Smrg CHK_MASK_LEGAL(ndx, from.c16[0], legal); 346f7df2e56Smrg to.c16[0] &= ~from.c16[0]; 347f7df2e56Smrg to.c16[0] |= (from.c16[0] & from.c16[1]); 348f7df2e56Smrg } 349f7df2e56Smrg else if (size == 4) { 350f7df2e56Smrg CHK_MASK_MATCH(ndx, from.c32[0], from.c32[1]); 351f7df2e56Smrg CHK_MASK_LEGAL(ndx, from.c32[0], legal); 352f7df2e56Smrg to.c32[0] &= ~from.c32[0]; 353f7df2e56Smrg to.c32[0] |= (from.c32[0] & from.c32[1]); 354f7df2e56Smrg } 355f7df2e56Smrg else { 356f7df2e56Smrg CHK_MASK_MATCH(ndx, from.c8[0], from.c8[1]); 357f7df2e56Smrg CHK_MASK_LEGAL(ndx, from.c8[0], legal); 358f7df2e56Smrg to.c8[0] &= ~from.c8[0]; 359f7df2e56Smrg to.c8[0] |= (from.c8[0] & from.c8[1]); 360f7df2e56Smrg size = 2; 361f7df2e56Smrg } 362f7df2e56Smrg from.c8 += (size * 2); 363f7df2e56Smrg dataLeft -= (size * 2); 364f7df2e56Smrg } 365f7df2e56Smrg } 366f7df2e56Smrg if (dataLeft > 2) { 367f7df2e56Smrg ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n", 368f7df2e56Smrg dataLeft); 369f7df2e56Smrg return BadLength; 370f7df2e56Smrg } 371f7df2e56Smrg return Success; 37205b261ecSmrg } 37305b261ecSmrg return BadAlloc; 37405b261ecSmrg} 37505b261ecSmrg 37605b261ecSmrg/***====================================================================***/ 3774642e01fSmrg/** 3784642e01fSmrg * Ring a bell on the given device for the given client. 3794642e01fSmrg */ 3804642e01fSmrgstatic int 3814642e01fSmrg_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, 3824642e01fSmrg int bellClass, int bellID, int pitch, int duration, 3834642e01fSmrg int percent, int forceSound, int eventOnly, Atom name) 3844642e01fSmrg{ 385f7df2e56Smrg int base; 386f7df2e56Smrg void *ctrl; 387f7df2e56Smrg int oldPitch, oldDuration; 388f7df2e56Smrg int newPercent; 3894642e01fSmrg 3904642e01fSmrg if (bellClass == KbdFeedbackClass) { 391f7df2e56Smrg KbdFeedbackPtr k; 392f7df2e56Smrg 393f7df2e56Smrg if (bellID == XkbDfltXIId) 394f7df2e56Smrg k = dev->kbdfeed; 3954642e01fSmrg else { 396f7df2e56Smrg for (k = dev->kbdfeed; k; k = k->next) { 3974642e01fSmrg if (k->ctrl.id == bellID) 3984642e01fSmrg break; 3994642e01fSmrg } 4004642e01fSmrg } 4014642e01fSmrg if (!k) { 402f7df2e56Smrg client->errorValue = _XkbErrCode2(0x5, bellID); 4034642e01fSmrg return BadValue; 4044642e01fSmrg } 4054642e01fSmrg base = k->ctrl.bell; 406f7df2e56Smrg ctrl = (void *) &(k->ctrl); 407f7df2e56Smrg oldPitch = k->ctrl.bell_pitch; 408f7df2e56Smrg oldDuration = k->ctrl.bell_duration; 409f7df2e56Smrg if (pitch != 0) { 410f7df2e56Smrg if (pitch == -1) 411f7df2e56Smrg k->ctrl.bell_pitch = defaultKeyboardControl.bell_pitch; 412f7df2e56Smrg else 413f7df2e56Smrg k->ctrl.bell_pitch = pitch; 4144642e01fSmrg } 415f7df2e56Smrg if (duration != 0) { 416f7df2e56Smrg if (duration == -1) 417f7df2e56Smrg k->ctrl.bell_duration = defaultKeyboardControl.bell_duration; 418f7df2e56Smrg else 419f7df2e56Smrg k->ctrl.bell_duration = duration; 4204642e01fSmrg } 4214642e01fSmrg } 4224642e01fSmrg else if (bellClass == BellFeedbackClass) { 423f7df2e56Smrg BellFeedbackPtr b; 424f7df2e56Smrg 425f7df2e56Smrg if (bellID == XkbDfltXIId) 426f7df2e56Smrg b = dev->bell; 4274642e01fSmrg else { 428f7df2e56Smrg for (b = dev->bell; b; b = b->next) { 4294642e01fSmrg if (b->ctrl.id == bellID) 4304642e01fSmrg break; 4314642e01fSmrg } 4324642e01fSmrg } 4334642e01fSmrg if (!b) { 434f7df2e56Smrg client->errorValue = _XkbErrCode2(0x6, bellID); 4354642e01fSmrg return BadValue; 4364642e01fSmrg } 4374642e01fSmrg base = b->ctrl.percent; 438f7df2e56Smrg ctrl = (void *) &(b->ctrl); 439f7df2e56Smrg oldPitch = b->ctrl.pitch; 440f7df2e56Smrg oldDuration = b->ctrl.duration; 441f7df2e56Smrg if (pitch != 0) { 442f7df2e56Smrg if (pitch == -1) 443f7df2e56Smrg b->ctrl.pitch = defaultKeyboardControl.bell_pitch; 444f7df2e56Smrg else 445f7df2e56Smrg b->ctrl.pitch = pitch; 4464642e01fSmrg } 447f7df2e56Smrg if (duration != 0) { 448f7df2e56Smrg if (duration == -1) 449f7df2e56Smrg b->ctrl.duration = defaultKeyboardControl.bell_duration; 450f7df2e56Smrg else 451f7df2e56Smrg b->ctrl.duration = duration; 4524642e01fSmrg } 4534642e01fSmrg } 4544642e01fSmrg else { 4554642e01fSmrg client->errorValue = _XkbErrCode2(0x7, bellClass); 4564642e01fSmrg return BadValue; 4574642e01fSmrg } 4584642e01fSmrg 459f7df2e56Smrg newPercent = (base * percent) / 100; 4604642e01fSmrg if (percent < 0) 461f7df2e56Smrg newPercent = base + newPercent; 462f7df2e56Smrg else 463f7df2e56Smrg newPercent = base - newPercent + percent; 4644642e01fSmrg 4654642e01fSmrg XkbHandleBell(forceSound, eventOnly, 466f7df2e56Smrg dev, newPercent, ctrl, bellClass, name, pWin, client); 467f7df2e56Smrg if ((pitch != 0) || (duration != 0)) { 4684642e01fSmrg if (bellClass == KbdFeedbackClass) { 469f7df2e56Smrg KbdFeedbackPtr k; 470f7df2e56Smrg 471f7df2e56Smrg k = (KbdFeedbackPtr) ctrl; 472f7df2e56Smrg if (pitch != 0) 473f7df2e56Smrg k->ctrl.bell_pitch = oldPitch; 474f7df2e56Smrg if (duration != 0) 475f7df2e56Smrg k->ctrl.bell_duration = oldDuration; 4764642e01fSmrg } 4774642e01fSmrg else { 478f7df2e56Smrg BellFeedbackPtr b; 479f7df2e56Smrg 480f7df2e56Smrg b = (BellFeedbackPtr) ctrl; 481f7df2e56Smrg if (pitch != 0) 482f7df2e56Smrg b->ctrl.pitch = oldPitch; 483f7df2e56Smrg if (duration != 0) 484f7df2e56Smrg b->ctrl.duration = oldDuration; 4854642e01fSmrg } 4864642e01fSmrg } 4874642e01fSmrg 4884642e01fSmrg return Success; 4894642e01fSmrg} 49005b261ecSmrg 49105b261ecSmrgint 49205b261ecSmrgProcXkbBell(ClientPtr client) 49305b261ecSmrg{ 49405b261ecSmrg REQUEST(xkbBellReq); 49505b261ecSmrg DeviceIntPtr dev; 496f7df2e56Smrg WindowPtr pWin; 4974642e01fSmrg int rc; 49805b261ecSmrg 49905b261ecSmrg REQUEST_SIZE_MATCH(xkbBellReq); 50005b261ecSmrg 501f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 502f7df2e56Smrg return BadAccess; 50305b261ecSmrg 5044642e01fSmrg CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); 50505b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 50605b261ecSmrg 5074642e01fSmrg /* device-independent checks request for sane values */ 508f7df2e56Smrg if ((stuff->forceSound) && (stuff->eventOnly)) { 509f7df2e56Smrg client->errorValue = 510f7df2e56Smrg _XkbErrCode3(0x1, stuff->forceSound, stuff->eventOnly); 511f7df2e56Smrg return BadMatch; 51205b261ecSmrg } 51305b261ecSmrg if (stuff->percent < -100 || stuff->percent > 100) { 514f7df2e56Smrg client->errorValue = _XkbErrCode2(0x2, stuff->percent); 515f7df2e56Smrg return BadValue; 51605b261ecSmrg } 517f7df2e56Smrg if (stuff->duration < -1) { 518f7df2e56Smrg client->errorValue = _XkbErrCode2(0x3, stuff->duration); 519f7df2e56Smrg return BadValue; 52005b261ecSmrg } 521f7df2e56Smrg if (stuff->pitch < -1) { 522f7df2e56Smrg client->errorValue = _XkbErrCode2(0x4, stuff->pitch); 523f7df2e56Smrg return BadValue; 52405b261ecSmrg } 52505b261ecSmrg 52605b261ecSmrg if (stuff->bellClass == XkbDfltXIClass) { 527f7df2e56Smrg if (dev->kbdfeed != NULL) 528f7df2e56Smrg stuff->bellClass = KbdFeedbackClass; 529f7df2e56Smrg else 530f7df2e56Smrg stuff->bellClass = BellFeedbackClass; 53105b261ecSmrg } 5324642e01fSmrg 533f7df2e56Smrg if (stuff->window != None) { 534f7df2e56Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 535f7df2e56Smrg if (rc != Success) { 536f7df2e56Smrg client->errorValue = stuff->window; 537f7df2e56Smrg return rc; 538f7df2e56Smrg } 53905b261ecSmrg } 540f7df2e56Smrg else 541f7df2e56Smrg pWin = NULL; 54205b261ecSmrg 5434642e01fSmrg /* Client wants to ring a bell on the core keyboard? 5444642e01fSmrg Ring the bell on the core keyboard (which does nothing, but if that 5454642e01fSmrg fails the client is screwed anyway), and then on all extension devices. 5464642e01fSmrg Fail if the core keyboard fails but not the extension devices. this 5474642e01fSmrg may cause some keyboards to ding and others to stay silent. Fix 5484642e01fSmrg your client to use explicit keyboards to avoid this. 5494642e01fSmrg 5504642e01fSmrg dev is the device the client requested. 5514642e01fSmrg */ 5524642e01fSmrg rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, 5534642e01fSmrg stuff->pitch, stuff->duration, stuff->percent, 5544642e01fSmrg stuff->forceSound, stuff->eventOnly, stuff->name); 5554642e01fSmrg 5564642e01fSmrg if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || 557f7df2e56Smrg (stuff->deviceSpec == XkbUseCorePtr))) { 5584642e01fSmrg DeviceIntPtr other; 559f7df2e56Smrg 560f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 561f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 562f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 5634642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); 5644642e01fSmrg if (rc == Success) 5654642e01fSmrg _XkbBell(client, other, pWin, stuff->bellClass, 5664642e01fSmrg stuff->bellID, stuff->pitch, stuff->duration, 5674642e01fSmrg stuff->percent, stuff->forceSound, 5684642e01fSmrg stuff->eventOnly, stuff->name); 5694642e01fSmrg } 5704642e01fSmrg } 571f7df2e56Smrg rc = Success; /* reset to success, that's what we got for the VCK */ 57205b261ecSmrg } 5734642e01fSmrg 5744642e01fSmrg return rc; 57505b261ecSmrg} 57605b261ecSmrg 57705b261ecSmrg/***====================================================================***/ 57805b261ecSmrg 57905b261ecSmrgint 58005b261ecSmrgProcXkbGetState(ClientPtr client) 58105b261ecSmrg{ 58205b261ecSmrg REQUEST(xkbGetStateReq); 583f7df2e56Smrg DeviceIntPtr dev; 584f7df2e56Smrg xkbGetStateReply rep; 585f7df2e56Smrg XkbStateRec *xkb; 58605b261ecSmrg 58705b261ecSmrg REQUEST_SIZE_MATCH(xkbGetStateReq); 58805b261ecSmrg 589f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 590f7df2e56Smrg return BadAccess; 59105b261ecSmrg 5926747b715Smrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 59305b261ecSmrg 594f7df2e56Smrg xkb = &dev->key->xkbInfo->state; 595f7df2e56Smrg rep = (xkbGetStateReply) { 596f7df2e56Smrg .type = X_Reply, 597f7df2e56Smrg .deviceID = dev->id, 598f7df2e56Smrg .sequenceNumber = client->sequence, 599f7df2e56Smrg .length = 0, 600f7df2e56Smrg .mods = XkbStateFieldFromRec(xkb) & 0xff, 601f7df2e56Smrg .baseMods = xkb->base_mods, 602f7df2e56Smrg .latchedMods = xkb->latched_mods, 603f7df2e56Smrg .lockedMods = xkb->locked_mods, 604f7df2e56Smrg .group = xkb->group, 605f7df2e56Smrg .lockedGroup = xkb->locked_group, 606f7df2e56Smrg .baseGroup = xkb->base_group, 607f7df2e56Smrg .latchedGroup = xkb->latched_group, 608f7df2e56Smrg .compatState = xkb->compat_state, 609f7df2e56Smrg .ptrBtnState = xkb->ptr_buttons 610f7df2e56Smrg }; 61105b261ecSmrg if (client->swapped) { 612f7df2e56Smrg swaps(&rep.sequenceNumber); 613f7df2e56Smrg swaps(&rep.ptrBtnState); 61405b261ecSmrg } 615f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetStateReply), &rep); 6166747b715Smrg return Success; 61705b261ecSmrg} 61805b261ecSmrg 61905b261ecSmrg/***====================================================================***/ 62005b261ecSmrg 62105b261ecSmrgint 62205b261ecSmrgProcXkbLatchLockState(ClientPtr client) 62305b261ecSmrg{ 62405b261ecSmrg int status; 62505b261ecSmrg DeviceIntPtr dev, tmpd; 626f7df2e56Smrg XkbStateRec oldState, *newState; 62705b261ecSmrg CARD16 changed; 62805b261ecSmrg xkbStateNotify sn; 62905b261ecSmrg XkbEventCauseRec cause; 63005b261ecSmrg 63105b261ecSmrg REQUEST(xkbLatchLockStateReq); 63205b261ecSmrg REQUEST_SIZE_MATCH(xkbLatchLockStateReq); 63305b261ecSmrg 63405b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 635f7df2e56Smrg return BadAccess; 63605b261ecSmrg 6374642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 63805b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); 63905b261ecSmrg CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); 64005b261ecSmrg 64105b261ecSmrg status = Success; 64205b261ecSmrg 64305b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 644f7df2e56Smrg if ((tmpd == dev) || 645f7df2e56Smrg (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 6466747b715Smrg if (!tmpd->key || !tmpd->key->xkbInfo) 64705b261ecSmrg continue; 64805b261ecSmrg 64905b261ecSmrg oldState = tmpd->key->xkbInfo->state; 65005b261ecSmrg newState = &tmpd->key->xkbInfo->state; 65105b261ecSmrg if (stuff->affectModLocks) { 65205b261ecSmrg newState->locked_mods &= ~stuff->affectModLocks; 653f7df2e56Smrg newState->locked_mods |= 654f7df2e56Smrg (stuff->affectModLocks & stuff->modLocks); 65505b261ecSmrg } 65605b261ecSmrg if (status == Success && stuff->lockGroup) 65705b261ecSmrg newState->locked_group = stuff->groupLock; 65805b261ecSmrg if (status == Success && stuff->affectModLatches) 65905b261ecSmrg status = XkbLatchModifiers(tmpd, stuff->affectModLatches, 66005b261ecSmrg stuff->modLatches); 66105b261ecSmrg if (status == Success && stuff->latchGroup) 66205b261ecSmrg status = XkbLatchGroup(tmpd, stuff->groupLatch); 66305b261ecSmrg 66405b261ecSmrg if (status != Success) 66505b261ecSmrg return status; 66605b261ecSmrg 66705b261ecSmrg XkbComputeDerivedState(tmpd->key->xkbInfo); 66805b261ecSmrg 66905b261ecSmrg changed = XkbStateChangedFlags(&oldState, newState); 67005b261ecSmrg if (changed) { 67105b261ecSmrg sn.keycode = 0; 67205b261ecSmrg sn.eventType = 0; 67305b261ecSmrg sn.requestMajor = XkbReqCode; 67405b261ecSmrg sn.requestMinor = X_kbLatchLockState; 67505b261ecSmrg sn.changed = changed; 67605b261ecSmrg XkbSendStateNotify(tmpd, &sn); 6776747b715Smrg changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE); 67805b261ecSmrg if (changed) { 67905b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); 6806747b715Smrg XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause); 681f7df2e56Smrg } 68205b261ecSmrg } 68305b261ecSmrg } 68405b261ecSmrg } 68505b261ecSmrg 6866747b715Smrg return Success; 68705b261ecSmrg} 68805b261ecSmrg 68905b261ecSmrg/***====================================================================***/ 69005b261ecSmrg 69105b261ecSmrgint 69205b261ecSmrgProcXkbGetControls(ClientPtr client) 69305b261ecSmrg{ 69405b261ecSmrg xkbGetControlsReply rep; 695f7df2e56Smrg XkbControlsPtr xkb; 696f7df2e56Smrg DeviceIntPtr dev; 69705b261ecSmrg 69805b261ecSmrg REQUEST(xkbGetControlsReq); 69905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetControlsReq); 70005b261ecSmrg 701f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 702f7df2e56Smrg return BadAccess; 70305b261ecSmrg 7044642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 705f7df2e56Smrg 70605b261ecSmrg xkb = dev->key->xkbInfo->desc->ctrls; 707f7df2e56Smrg rep = (xkbGetControlsReply) { 708f7df2e56Smrg .type = X_Reply, 709f7df2e56Smrg .deviceID = ((DeviceIntPtr) dev)->id, 710f7df2e56Smrg .sequenceNumber = client->sequence, 711f7df2e56Smrg .length = bytes_to_int32(SIZEOF(xkbGetControlsReply) - 712f7df2e56Smrg SIZEOF(xGenericReply)), 713f7df2e56Smrg .mkDfltBtn = xkb->mk_dflt_btn, 714f7df2e56Smrg .numGroups = xkb->num_groups, 715f7df2e56Smrg .groupsWrap = xkb->groups_wrap, 716f7df2e56Smrg .internalMods = xkb->internal.mask, 717f7df2e56Smrg .ignoreLockMods = xkb->ignore_lock.mask, 718f7df2e56Smrg .internalRealMods = xkb->internal.real_mods, 719f7df2e56Smrg .ignoreLockRealMods = xkb->ignore_lock.real_mods, 720f7df2e56Smrg .internalVMods = xkb->internal.vmods, 721f7df2e56Smrg .ignoreLockVMods = xkb->ignore_lock.vmods, 722f7df2e56Smrg .repeatDelay = xkb->repeat_delay, 723f7df2e56Smrg .repeatInterval = xkb->repeat_interval, 724f7df2e56Smrg .slowKeysDelay = xkb->slow_keys_delay, 725f7df2e56Smrg .debounceDelay = xkb->debounce_delay, 726f7df2e56Smrg .mkDelay = xkb->mk_delay, 727f7df2e56Smrg .mkInterval = xkb->mk_interval, 728f7df2e56Smrg .mkTimeToMax = xkb->mk_time_to_max, 729f7df2e56Smrg .mkMaxSpeed = xkb->mk_max_speed, 730f7df2e56Smrg .mkCurve = xkb->mk_curve, 731f7df2e56Smrg .axOptions = xkb->ax_options, 732f7df2e56Smrg .axTimeout = xkb->ax_timeout, 733f7df2e56Smrg .axtOptsMask = xkb->axt_opts_mask, 734f7df2e56Smrg .axtOptsValues = xkb->axt_opts_values, 735f7df2e56Smrg .axtCtrlsMask = xkb->axt_ctrls_mask, 736f7df2e56Smrg .axtCtrlsValues = xkb->axt_ctrls_values, 737f7df2e56Smrg .enabledCtrls = xkb->enabled_ctrls, 738f7df2e56Smrg }; 739f7df2e56Smrg memcpy(rep.perKeyRepeat, xkb->per_key_repeat, XkbPerKeyBitArraySize); 74005b261ecSmrg if (client->swapped) { 741f7df2e56Smrg swaps(&rep.sequenceNumber); 742f7df2e56Smrg swapl(&rep.length); 743f7df2e56Smrg swaps(&rep.internalVMods); 744f7df2e56Smrg swaps(&rep.ignoreLockVMods); 745f7df2e56Smrg swapl(&rep.enabledCtrls); 746f7df2e56Smrg swaps(&rep.repeatDelay); 747f7df2e56Smrg swaps(&rep.repeatInterval); 748f7df2e56Smrg swaps(&rep.slowKeysDelay); 749f7df2e56Smrg swaps(&rep.debounceDelay); 750f7df2e56Smrg swaps(&rep.mkDelay); 751f7df2e56Smrg swaps(&rep.mkInterval); 752f7df2e56Smrg swaps(&rep.mkTimeToMax); 753f7df2e56Smrg swaps(&rep.mkMaxSpeed); 754f7df2e56Smrg swaps(&rep.mkCurve); 755f7df2e56Smrg swaps(&rep.axTimeout); 756f7df2e56Smrg swapl(&rep.axtCtrlsMask); 757f7df2e56Smrg swapl(&rep.axtCtrlsValues); 758f7df2e56Smrg swaps(&rep.axtOptsMask); 759f7df2e56Smrg swaps(&rep.axtOptsValues); 760f7df2e56Smrg swaps(&rep.axOptions); 761f7df2e56Smrg } 762f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetControlsReply), &rep); 7636747b715Smrg return Success; 76405b261ecSmrg} 76505b261ecSmrg 76605b261ecSmrgint 76705b261ecSmrgProcXkbSetControls(ClientPtr client) 76805b261ecSmrg{ 769f7df2e56Smrg DeviceIntPtr dev, tmpd; 770f7df2e56Smrg XkbSrvInfoPtr xkbi; 771f7df2e56Smrg XkbControlsPtr ctrl; 772f7df2e56Smrg XkbControlsRec new, old; 773f7df2e56Smrg xkbControlsNotify cn; 774f7df2e56Smrg XkbEventCauseRec cause; 775f7df2e56Smrg XkbSrvLedInfoPtr sli; 77605b261ecSmrg 77705b261ecSmrg REQUEST(xkbSetControlsReq); 77805b261ecSmrg REQUEST_SIZE_MATCH(xkbSetControlsReq); 77905b261ecSmrg 78005b261ecSmrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 781f7df2e56Smrg return BadAccess; 78205b261ecSmrg 7834642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 78405b261ecSmrg CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask); 78505b261ecSmrg 7866747b715Smrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 7876747b715Smrg if (!tmpd->key || !tmpd->key->xkbInfo) 7886747b715Smrg continue; 789f7df2e56Smrg if ((tmpd == dev) || 790f7df2e56Smrg (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 79105b261ecSmrg xkbi = tmpd->key->xkbInfo; 79205b261ecSmrg ctrl = xkbi->desc->ctrls; 79305b261ecSmrg new = *ctrl; 79405b261ecSmrg XkbSetCauseXkbReq(&cause, X_kbSetControls, client); 79505b261ecSmrg 79605b261ecSmrg if (stuff->changeCtrls & XkbInternalModsMask) { 79705b261ecSmrg CHK_MASK_MATCH(0x02, stuff->affectInternalMods, 79805b261ecSmrg stuff->internalMods); 79905b261ecSmrg CHK_MASK_MATCH(0x03, stuff->affectInternalVMods, 80005b261ecSmrg stuff->internalVMods); 80105b261ecSmrg 80205b261ecSmrg new.internal.real_mods &= ~(stuff->affectInternalMods); 80305b261ecSmrg new.internal.real_mods |= (stuff->affectInternalMods & 80405b261ecSmrg stuff->internalMods); 80505b261ecSmrg new.internal.vmods &= ~(stuff->affectInternalVMods); 80605b261ecSmrg new.internal.vmods |= (stuff->affectInternalVMods & 80705b261ecSmrg stuff->internalVMods); 80805b261ecSmrg new.internal.mask = new.internal.real_mods | 809f7df2e56Smrg XkbMaskForVMask(xkbi->desc, new.internal.vmods); 81005b261ecSmrg } 81105b261ecSmrg 81205b261ecSmrg if (stuff->changeCtrls & XkbIgnoreLockModsMask) { 81305b261ecSmrg CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods, 81405b261ecSmrg stuff->ignoreLockMods); 81505b261ecSmrg CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods, 81605b261ecSmrg stuff->ignoreLockVMods); 81705b261ecSmrg 81805b261ecSmrg new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods); 81905b261ecSmrg new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods & 82005b261ecSmrg stuff->ignoreLockMods); 82105b261ecSmrg new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods); 82205b261ecSmrg new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods & 82305b261ecSmrg stuff->ignoreLockVMods); 82405b261ecSmrg new.ignore_lock.mask = new.ignore_lock.real_mods | 825f7df2e56Smrg XkbMaskForVMask(xkbi->desc, new.ignore_lock.vmods); 82605b261ecSmrg } 82705b261ecSmrg 82805b261ecSmrg CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls, 82905b261ecSmrg stuff->enabledCtrls); 83005b261ecSmrg if (stuff->affectEnabledCtrls) { 83105b261ecSmrg CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls, 83205b261ecSmrg XkbAllBooleanCtrlsMask); 83305b261ecSmrg 83405b261ecSmrg new.enabled_ctrls &= ~(stuff->affectEnabledCtrls); 83505b261ecSmrg new.enabled_ctrls |= (stuff->affectEnabledCtrls & 83605b261ecSmrg stuff->enabledCtrls); 83705b261ecSmrg } 83805b261ecSmrg 83905b261ecSmrg if (stuff->changeCtrls & XkbRepeatKeysMask) { 84005b261ecSmrg if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) { 84105b261ecSmrg client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay, 84205b261ecSmrg stuff->repeatInterval); 84305b261ecSmrg return BadValue; 84405b261ecSmrg } 84505b261ecSmrg 84605b261ecSmrg new.repeat_delay = stuff->repeatDelay; 84705b261ecSmrg new.repeat_interval = stuff->repeatInterval; 84805b261ecSmrg } 84905b261ecSmrg 85005b261ecSmrg if (stuff->changeCtrls & XkbSlowKeysMask) { 85105b261ecSmrg if (stuff->slowKeysDelay < 1) { 85205b261ecSmrg client->errorValue = _XkbErrCode2(0x09, 85305b261ecSmrg stuff->slowKeysDelay); 85405b261ecSmrg return BadValue; 85505b261ecSmrg } 85605b261ecSmrg 85705b261ecSmrg new.slow_keys_delay = stuff->slowKeysDelay; 85805b261ecSmrg } 85905b261ecSmrg 86005b261ecSmrg if (stuff->changeCtrls & XkbBounceKeysMask) { 86105b261ecSmrg if (stuff->debounceDelay < 1) { 86205b261ecSmrg client->errorValue = _XkbErrCode2(0x0A, 86305b261ecSmrg stuff->debounceDelay); 86405b261ecSmrg return BadValue; 86505b261ecSmrg } 86605b261ecSmrg 86705b261ecSmrg new.debounce_delay = stuff->debounceDelay; 86805b261ecSmrg } 86905b261ecSmrg 87005b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysMask) { 87105b261ecSmrg if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) { 87205b261ecSmrg client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn); 87305b261ecSmrg return BadValue; 87405b261ecSmrg } 87505b261ecSmrg 87605b261ecSmrg new.mk_dflt_btn = stuff->mkDfltBtn; 87705b261ecSmrg } 87805b261ecSmrg 87905b261ecSmrg if (stuff->changeCtrls & XkbMouseKeysAccelMask) { 88005b261ecSmrg if (stuff->mkDelay < 1 || stuff->mkInterval < 1 || 88105b261ecSmrg stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 || 88205b261ecSmrg stuff->mkCurve < -1000) { 883f7df2e56Smrg client->errorValue = _XkbErrCode2(0x0C, 0); 88405b261ecSmrg return BadValue; 88505b261ecSmrg } 88605b261ecSmrg 88705b261ecSmrg new.mk_delay = stuff->mkDelay; 88805b261ecSmrg new.mk_interval = stuff->mkInterval; 88905b261ecSmrg new.mk_time_to_max = stuff->mkTimeToMax; 89005b261ecSmrg new.mk_max_speed = stuff->mkMaxSpeed; 89105b261ecSmrg new.mk_curve = stuff->mkCurve; 89205b261ecSmrg AccessXComputeCurveFactor(xkbi, &new); 89305b261ecSmrg } 89405b261ecSmrg 89505b261ecSmrg if (stuff->changeCtrls & XkbGroupsWrapMask) { 89605b261ecSmrg unsigned act, num; 89705b261ecSmrg 89805b261ecSmrg act = XkbOutOfRangeGroupAction(stuff->groupsWrap); 89905b261ecSmrg switch (act) { 90005b261ecSmrg case XkbRedirectIntoRange: 90105b261ecSmrg num = XkbOutOfRangeGroupNumber(stuff->groupsWrap); 90205b261ecSmrg if (num >= new.num_groups) { 90305b261ecSmrg client->errorValue = _XkbErrCode3(0x0D, new.num_groups, 90405b261ecSmrg num); 90505b261ecSmrg return BadValue; 90605b261ecSmrg } 90705b261ecSmrg case XkbWrapIntoRange: 90805b261ecSmrg case XkbClampIntoRange: 90905b261ecSmrg break; 91005b261ecSmrg default: 91105b261ecSmrg client->errorValue = _XkbErrCode2(0x0E, act); 91205b261ecSmrg return BadValue; 91305b261ecSmrg } 91405b261ecSmrg 915f7df2e56Smrg new.groups_wrap = stuff->groupsWrap; 91605b261ecSmrg } 91705b261ecSmrg 91805b261ecSmrg CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask); 91905b261ecSmrg if (stuff->changeCtrls & XkbAccessXKeysMask) { 92005b261ecSmrg new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask; 92105b261ecSmrg } 92205b261ecSmrg else { 92305b261ecSmrg if (stuff->changeCtrls & XkbStickyKeysMask) { 92405b261ecSmrg new.ax_options &= ~(XkbAX_SKOptionsMask); 92505b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask); 92605b261ecSmrg } 927f7df2e56Smrg 92805b261ecSmrg if (stuff->changeCtrls & XkbAccessXFeedbackMask) { 92905b261ecSmrg new.ax_options &= ~(XkbAX_FBOptionsMask); 93005b261ecSmrg new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask); 93105b261ecSmrg } 93205b261ecSmrg } 93305b261ecSmrg 93405b261ecSmrg if (stuff->changeCtrls & XkbAccessXTimeoutMask) { 93505b261ecSmrg if (stuff->axTimeout < 1) { 93605b261ecSmrg client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout); 93705b261ecSmrg return BadValue; 93805b261ecSmrg } 93905b261ecSmrg CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask, 94005b261ecSmrg stuff->axtCtrlsValues); 94105b261ecSmrg CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask, 94205b261ecSmrg XkbAllBooleanCtrlsMask); 94305b261ecSmrg CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues); 94405b261ecSmrg CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask); 94505b261ecSmrg new.ax_timeout = stuff->axTimeout; 94605b261ecSmrg new.axt_ctrls_mask = stuff->axtCtrlsMask; 94705b261ecSmrg new.axt_ctrls_values = (stuff->axtCtrlsValues & 94805b261ecSmrg stuff->axtCtrlsMask); 94905b261ecSmrg new.axt_opts_mask = stuff->axtOptsMask; 95005b261ecSmrg new.axt_opts_values = (stuff->axtOptsValues & 95105b261ecSmrg stuff->axtOptsMask); 95205b261ecSmrg } 95305b261ecSmrg 9549ace9065Smrg if (stuff->changeCtrls & XkbPerKeyRepeatMask) { 95505b261ecSmrg memcpy(new.per_key_repeat, stuff->perKeyRepeat, 95605b261ecSmrg XkbPerKeyBitArraySize); 9579ace9065Smrg if (xkbi->repeatKey && 9589ace9065Smrg !BitIsOn(new.per_key_repeat, xkbi->repeatKey)) { 9599ace9065Smrg AccessXCancelRepeatKey(xkbi, xkbi->repeatKey); 9609ace9065Smrg } 9619ace9065Smrg } 96205b261ecSmrg 963f7df2e56Smrg old = *ctrl; 964f7df2e56Smrg *ctrl = new; 96505b261ecSmrg XkbDDXChangeControls(tmpd, &old, ctrl); 96605b261ecSmrg 9676747b715Smrg if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) { 96805b261ecSmrg cn.keycode = 0; 96905b261ecSmrg cn.eventType = 0; 97005b261ecSmrg cn.requestMajor = XkbReqCode; 97105b261ecSmrg cn.requestMinor = X_kbSetControls; 97205b261ecSmrg XkbSendControlsNotify(tmpd, &cn); 97305b261ecSmrg } 97405b261ecSmrg 97505b261ecSmrg sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); 97605b261ecSmrg if (sli) 9776747b715Smrg XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL, 97805b261ecSmrg &cause); 97905b261ecSmrg 98005b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 98105b261ecSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 98205b261ecSmrg !(ctrl->enabled_ctrls & XkbStickyKeysMask)) 9836747b715Smrg XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause); 98405b261ecSmrg } 98505b261ecSmrg } 98605b261ecSmrg 9876747b715Smrg return Success; 98805b261ecSmrg} 98905b261ecSmrg 99005b261ecSmrg/***====================================================================***/ 99105b261ecSmrg 99205b261ecSmrgstatic int 993f7df2e56SmrgXkbSizeKeyTypes(XkbDescPtr xkb, xkbGetMapReply * rep) 99405b261ecSmrg{ 995f7df2e56Smrg XkbKeyTypeRec *type; 996f7df2e56Smrg unsigned i, len; 997f7df2e56Smrg 998f7df2e56Smrg len = 0; 999f7df2e56Smrg if (((rep->present & XkbKeyTypesMask) == 0) || (rep->nTypes < 1) || 1000f7df2e56Smrg (!xkb) || (!xkb->map) || (!xkb->map->types)) { 1001f7df2e56Smrg rep->present &= ~XkbKeyTypesMask; 1002f7df2e56Smrg rep->firstType = rep->nTypes = 0; 1003f7df2e56Smrg return 0; 1004f7df2e56Smrg } 1005f7df2e56Smrg type = &xkb->map->types[rep->firstType]; 1006f7df2e56Smrg for (i = 0; i < rep->nTypes; i++, type++) { 1007f7df2e56Smrg len += SIZEOF(xkbKeyTypeWireDesc); 1008f7df2e56Smrg if (type->map_count > 0) { 1009f7df2e56Smrg len += (type->map_count * SIZEOF(xkbKTMapEntryWireDesc)); 1010f7df2e56Smrg if (type->preserve) 1011f7df2e56Smrg len += (type->map_count * SIZEOF(xkbModsWireDesc)); 1012f7df2e56Smrg } 101305b261ecSmrg } 101405b261ecSmrg return len; 101505b261ecSmrg} 101605b261ecSmrg 101705b261ecSmrgstatic char * 1018f7df2e56SmrgXkbWriteKeyTypes(XkbDescPtr xkb, 1019f7df2e56Smrg xkbGetMapReply * rep, char *buf, ClientPtr client) 102005b261ecSmrg{ 1021f7df2e56Smrg XkbKeyTypePtr type; 1022f7df2e56Smrg unsigned i; 102305b261ecSmrg xkbKeyTypeWireDesc *wire; 102405b261ecSmrg 1025f7df2e56Smrg type = &xkb->map->types[rep->firstType]; 1026f7df2e56Smrg for (i = 0; i < rep->nTypes; i++, type++) { 1027f7df2e56Smrg register unsigned n; 1028f7df2e56Smrg 1029f7df2e56Smrg wire = (xkbKeyTypeWireDesc *) buf; 1030f7df2e56Smrg wire->mask = type->mods.mask; 1031f7df2e56Smrg wire->realMods = type->mods.real_mods; 1032f7df2e56Smrg wire->virtualMods = type->mods.vmods; 1033f7df2e56Smrg wire->numLevels = type->num_levels; 1034f7df2e56Smrg wire->nMapEntries = type->map_count; 1035f7df2e56Smrg wire->preserve = (type->preserve != NULL); 1036f7df2e56Smrg if (client->swapped) { 1037f7df2e56Smrg swaps(&wire->virtualMods); 1038f7df2e56Smrg } 1039f7df2e56Smrg 1040f7df2e56Smrg buf = (char *) &wire[1]; 1041f7df2e56Smrg if (wire->nMapEntries > 0) { 1042f7df2e56Smrg xkbKTMapEntryWireDesc *ewire; 1043f7df2e56Smrg XkbKTMapEntryPtr entry; 1044f7df2e56Smrg 1045f7df2e56Smrg ewire = (xkbKTMapEntryWireDesc *) buf; 1046f7df2e56Smrg entry = type->map; 1047f7df2e56Smrg for (n = 0; n < type->map_count; n++, ewire++, entry++) { 1048f7df2e56Smrg ewire->active = entry->active; 1049f7df2e56Smrg ewire->mask = entry->mods.mask; 1050f7df2e56Smrg ewire->level = entry->level; 1051f7df2e56Smrg ewire->realMods = entry->mods.real_mods; 1052f7df2e56Smrg ewire->virtualMods = entry->mods.vmods; 1053f7df2e56Smrg if (client->swapped) { 1054f7df2e56Smrg swaps(&ewire->virtualMods); 1055f7df2e56Smrg } 1056f7df2e56Smrg } 1057f7df2e56Smrg buf = (char *) ewire; 1058f7df2e56Smrg if (type->preserve != NULL) { 1059f7df2e56Smrg xkbModsWireDesc *pwire; 1060f7df2e56Smrg XkbModsPtr preserve; 1061f7df2e56Smrg 1062f7df2e56Smrg pwire = (xkbModsWireDesc *) buf; 1063f7df2e56Smrg preserve = type->preserve; 1064f7df2e56Smrg for (n = 0; n < type->map_count; n++, pwire++, preserve++) { 1065f7df2e56Smrg pwire->mask = preserve->mask; 1066f7df2e56Smrg pwire->realMods = preserve->real_mods; 1067f7df2e56Smrg pwire->virtualMods = preserve->vmods; 1068f7df2e56Smrg if (client->swapped) { 1069f7df2e56Smrg swaps(&pwire->virtualMods); 1070f7df2e56Smrg } 1071f7df2e56Smrg } 1072f7df2e56Smrg buf = (char *) pwire; 1073f7df2e56Smrg } 1074f7df2e56Smrg } 107505b261ecSmrg } 107605b261ecSmrg return buf; 107705b261ecSmrg} 107805b261ecSmrg 107905b261ecSmrgstatic int 1080f7df2e56SmrgXkbSizeKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep) 108105b261ecSmrg{ 1082f7df2e56Smrg XkbSymMapPtr symMap; 1083f7df2e56Smrg unsigned i, len; 1084f7df2e56Smrg unsigned nSyms, nSymsThisKey; 1085f7df2e56Smrg 1086f7df2e56Smrg if (((rep->present & XkbKeySymsMask) == 0) || (rep->nKeySyms < 1) || 1087f7df2e56Smrg (!xkb) || (!xkb->map) || (!xkb->map->key_sym_map)) { 1088f7df2e56Smrg rep->present &= ~XkbKeySymsMask; 1089f7df2e56Smrg rep->firstKeySym = rep->nKeySyms = 0; 1090f7df2e56Smrg rep->totalSyms = 0; 1091f7df2e56Smrg return 0; 1092f7df2e56Smrg } 1093f7df2e56Smrg len = rep->nKeySyms * SIZEOF(xkbSymMapWireDesc); 109405b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 1095f7df2e56Smrg for (i = nSyms = 0; i < rep->nKeySyms; i++, symMap++) { 1096f7df2e56Smrg if (symMap->offset != 0) { 1097f7df2e56Smrg nSymsThisKey = XkbNumGroups(symMap->group_info) * symMap->width; 1098f7df2e56Smrg nSyms += nSymsThisKey; 1099f7df2e56Smrg } 1100f7df2e56Smrg } 1101f7df2e56Smrg len += nSyms * 4; 1102f7df2e56Smrg rep->totalSyms = nSyms; 110305b261ecSmrg return len; 110405b261ecSmrg} 110505b261ecSmrg 110605b261ecSmrgstatic int 1107f7df2e56SmrgXkbSizeVirtualMods(XkbDescPtr xkb, xkbGetMapReply * rep) 110805b261ecSmrg{ 1109f7df2e56Smrg register unsigned i, nMods, bit; 111005b261ecSmrg 1111f7df2e56Smrg if (((rep->present & XkbVirtualModsMask) == 0) || (rep->virtualMods == 0) || 1112f7df2e56Smrg (!xkb) || (!xkb->server)) { 1113f7df2e56Smrg rep->present &= ~XkbVirtualModsMask; 1114f7df2e56Smrg rep->virtualMods = 0; 1115f7df2e56Smrg return 0; 111605b261ecSmrg } 1117f7df2e56Smrg for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1118f7df2e56Smrg if (rep->virtualMods & bit) 1119f7df2e56Smrg nMods++; 112005b261ecSmrg } 112105b261ecSmrg return XkbPaddedSize(nMods); 112205b261ecSmrg} 112305b261ecSmrg 112405b261ecSmrgstatic char * 1125f7df2e56SmrgXkbWriteKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1126f7df2e56Smrg ClientPtr client) 112705b261ecSmrg{ 1128f7df2e56Smrg register KeySym *pSym; 1129f7df2e56Smrg XkbSymMapPtr symMap; 1130f7df2e56Smrg xkbSymMapWireDesc *outMap; 1131f7df2e56Smrg register unsigned i; 113205b261ecSmrg 113305b261ecSmrg symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 1134f7df2e56Smrg for (i = 0; i < rep->nKeySyms; i++, symMap++) { 1135f7df2e56Smrg outMap = (xkbSymMapWireDesc *) buf; 1136f7df2e56Smrg outMap->ktIndex[0] = symMap->kt_index[0]; 1137f7df2e56Smrg outMap->ktIndex[1] = symMap->kt_index[1]; 1138f7df2e56Smrg outMap->ktIndex[2] = symMap->kt_index[2]; 1139f7df2e56Smrg outMap->ktIndex[3] = symMap->kt_index[3]; 1140f7df2e56Smrg outMap->groupInfo = symMap->group_info; 1141f7df2e56Smrg outMap->width = symMap->width; 1142f7df2e56Smrg outMap->nSyms = symMap->width * XkbNumGroups(symMap->group_info); 1143f7df2e56Smrg buf = (char *) &outMap[1]; 1144f7df2e56Smrg if (outMap->nSyms == 0) 1145f7df2e56Smrg continue; 1146f7df2e56Smrg 1147f7df2e56Smrg pSym = &xkb->map->syms[symMap->offset]; 1148f7df2e56Smrg memcpy((char *) buf, (char *) pSym, outMap->nSyms * 4); 1149f7df2e56Smrg if (client->swapped) { 1150f7df2e56Smrg register int nSyms = outMap->nSyms; 1151f7df2e56Smrg 1152f7df2e56Smrg swaps(&outMap->nSyms); 1153f7df2e56Smrg while (nSyms-- > 0) { 1154f7df2e56Smrg swapl((int *) buf); 1155f7df2e56Smrg buf += 4; 1156f7df2e56Smrg } 1157f7df2e56Smrg } 1158f7df2e56Smrg else 1159f7df2e56Smrg buf += outMap->nSyms * 4; 116005b261ecSmrg } 116105b261ecSmrg return buf; 116205b261ecSmrg} 116305b261ecSmrg 116405b261ecSmrgstatic int 1165f7df2e56SmrgXkbSizeKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep) 116605b261ecSmrg{ 1167f7df2e56Smrg unsigned i, len, nActs; 1168f7df2e56Smrg register KeyCode firstKey; 1169f7df2e56Smrg 1170f7df2e56Smrg if (((rep->present & XkbKeyActionsMask) == 0) || (rep->nKeyActs < 1) || 1171f7df2e56Smrg (!xkb) || (!xkb->server) || (!xkb->server->key_acts)) { 1172f7df2e56Smrg rep->present &= ~XkbKeyActionsMask; 1173f7df2e56Smrg rep->firstKeyAct = rep->nKeyActs = 0; 1174f7df2e56Smrg rep->totalActs = 0; 1175f7df2e56Smrg return 0; 1176f7df2e56Smrg } 1177f7df2e56Smrg firstKey = rep->firstKeyAct; 1178f7df2e56Smrg for (nActs = i = 0; i < rep->nKeyActs; i++) { 1179f7df2e56Smrg if (xkb->server->key_acts[i + firstKey] != 0) 1180f7df2e56Smrg nActs += XkbKeyNumActions(xkb, i + firstKey); 1181f7df2e56Smrg } 1182f7df2e56Smrg len = XkbPaddedSize(rep->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc)); 1183f7df2e56Smrg rep->totalActs = nActs; 118405b261ecSmrg return len; 118505b261ecSmrg} 118605b261ecSmrg 118705b261ecSmrgstatic char * 1188f7df2e56SmrgXkbWriteKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1189f7df2e56Smrg ClientPtr client) 119005b261ecSmrg{ 1191f7df2e56Smrg unsigned i; 1192f7df2e56Smrg CARD8 *numDesc; 1193f7df2e56Smrg XkbAnyAction *actDesc; 1194f7df2e56Smrg 1195f7df2e56Smrg numDesc = (CARD8 *) buf; 1196f7df2e56Smrg for (i = 0; i < rep->nKeyActs; i++) { 1197f7df2e56Smrg if (xkb->server->key_acts[i + rep->firstKeyAct] == 0) 1198f7df2e56Smrg numDesc[i] = 0; 1199f7df2e56Smrg else 1200f7df2e56Smrg numDesc[i] = XkbKeyNumActions(xkb, (i + rep->firstKeyAct)); 1201f7df2e56Smrg } 1202f7df2e56Smrg buf += XkbPaddedSize(rep->nKeyActs); 1203f7df2e56Smrg 1204f7df2e56Smrg actDesc = (XkbAnyAction *) buf; 1205f7df2e56Smrg for (i = 0; i < rep->nKeyActs; i++) { 1206f7df2e56Smrg if (xkb->server->key_acts[i + rep->firstKeyAct] != 0) { 1207f7df2e56Smrg unsigned int num; 1208f7df2e56Smrg 1209f7df2e56Smrg num = XkbKeyNumActions(xkb, (i + rep->firstKeyAct)); 1210f7df2e56Smrg memcpy((char *) actDesc, 1211f7df2e56Smrg (char *) XkbKeyActionsPtr(xkb, (i + rep->firstKeyAct)), 1212f7df2e56Smrg num * SIZEOF(xkbActionWireDesc)); 1213f7df2e56Smrg actDesc += num; 1214f7df2e56Smrg } 1215f7df2e56Smrg } 1216f7df2e56Smrg buf = (char *) actDesc; 121705b261ecSmrg return buf; 121805b261ecSmrg} 121905b261ecSmrg 122005b261ecSmrgstatic int 1221f7df2e56SmrgXkbSizeKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep) 122205b261ecSmrg{ 1223f7df2e56Smrg unsigned i, len, nBhvr; 1224f7df2e56Smrg XkbBehavior *bhv; 1225f7df2e56Smrg 1226f7df2e56Smrg if (((rep->present & XkbKeyBehaviorsMask) == 0) || (rep->nKeyBehaviors < 1) 1227f7df2e56Smrg || (!xkb) || (!xkb->server) || (!xkb->server->behaviors)) { 1228f7df2e56Smrg rep->present &= ~XkbKeyBehaviorsMask; 1229f7df2e56Smrg rep->firstKeyBehavior = rep->nKeyBehaviors = 0; 1230f7df2e56Smrg rep->totalKeyBehaviors = 0; 1231f7df2e56Smrg return 0; 1232f7df2e56Smrg } 1233f7df2e56Smrg bhv = &xkb->server->behaviors[rep->firstKeyBehavior]; 1234f7df2e56Smrg for (nBhvr = i = 0; i < rep->nKeyBehaviors; i++, bhv++) { 1235f7df2e56Smrg if (bhv->type != XkbKB_Default) 1236f7df2e56Smrg nBhvr++; 1237f7df2e56Smrg } 1238f7df2e56Smrg len = nBhvr * SIZEOF(xkbBehaviorWireDesc); 1239f7df2e56Smrg rep->totalKeyBehaviors = nBhvr; 124005b261ecSmrg return len; 124105b261ecSmrg} 124205b261ecSmrg 124305b261ecSmrgstatic char * 1244f7df2e56SmrgXkbWriteKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1245f7df2e56Smrg ClientPtr client) 124605b261ecSmrg{ 1247f7df2e56Smrg unsigned i; 1248f7df2e56Smrg xkbBehaviorWireDesc *wire; 1249f7df2e56Smrg XkbBehavior *pBhvr; 1250f7df2e56Smrg 1251f7df2e56Smrg wire = (xkbBehaviorWireDesc *) buf; 1252f7df2e56Smrg pBhvr = &xkb->server->behaviors[rep->firstKeyBehavior]; 1253f7df2e56Smrg for (i = 0; i < rep->nKeyBehaviors; i++, pBhvr++) { 1254f7df2e56Smrg if (pBhvr->type != XkbKB_Default) { 1255f7df2e56Smrg wire->key = i + rep->firstKeyBehavior; 1256f7df2e56Smrg wire->type = pBhvr->type; 1257f7df2e56Smrg wire->data = pBhvr->data; 1258f7df2e56Smrg wire++; 1259f7df2e56Smrg } 1260f7df2e56Smrg } 1261f7df2e56Smrg buf = (char *) wire; 126205b261ecSmrg return buf; 126305b261ecSmrg} 126405b261ecSmrg 126505b261ecSmrgstatic int 1266f7df2e56SmrgXkbSizeExplicit(XkbDescPtr xkb, xkbGetMapReply * rep) 126705b261ecSmrg{ 1268f7df2e56Smrg unsigned i, len, nRtrn; 1269f7df2e56Smrg 1270f7df2e56Smrg if (((rep->present & XkbExplicitComponentsMask) == 0) || 1271f7df2e56Smrg (rep->nKeyExplicit < 1) || (!xkb) || (!xkb->server) || 1272f7df2e56Smrg (!xkb->server->explicit)) { 1273f7df2e56Smrg rep->present &= ~XkbExplicitComponentsMask; 1274f7df2e56Smrg rep->firstKeyExplicit = rep->nKeyExplicit = 0; 1275f7df2e56Smrg rep->totalKeyExplicit = 0; 1276f7df2e56Smrg return 0; 1277f7df2e56Smrg } 1278f7df2e56Smrg for (nRtrn = i = 0; i < rep->nKeyExplicit; i++) { 1279f7df2e56Smrg if (xkb->server->explicit[i + rep->firstKeyExplicit] != 0) 1280f7df2e56Smrg nRtrn++; 1281f7df2e56Smrg } 1282f7df2e56Smrg rep->totalKeyExplicit = nRtrn; 1283f7df2e56Smrg len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero explicit component */ 128405b261ecSmrg return len; 128505b261ecSmrg} 128605b261ecSmrg 128705b261ecSmrgstatic char * 1288f7df2e56SmrgXkbWriteExplicit(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1289f7df2e56Smrg ClientPtr client) 129005b261ecSmrg{ 1291f7df2e56Smrg unsigned i; 1292f7df2e56Smrg char *start; 1293f7df2e56Smrg unsigned char *pExp; 1294f7df2e56Smrg 1295f7df2e56Smrg start = buf; 1296f7df2e56Smrg pExp = &xkb->server->explicit[rep->firstKeyExplicit]; 1297f7df2e56Smrg for (i = 0; i < rep->nKeyExplicit; i++, pExp++) { 1298f7df2e56Smrg if (*pExp != 0) { 1299f7df2e56Smrg *buf++ = i + rep->firstKeyExplicit; 1300f7df2e56Smrg *buf++ = *pExp; 1301f7df2e56Smrg } 1302f7df2e56Smrg } 1303f7df2e56Smrg i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */ 1304f7df2e56Smrg return buf + i; 130505b261ecSmrg} 130605b261ecSmrg 130705b261ecSmrgstatic int 1308f7df2e56SmrgXkbSizeModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep) 130905b261ecSmrg{ 1310f7df2e56Smrg unsigned i, len, nRtrn; 131105b261ecSmrg 1312f7df2e56Smrg if (((rep->present & XkbModifierMapMask) == 0) || (rep->nModMapKeys < 1) || 1313f7df2e56Smrg (!xkb) || (!xkb->map) || (!xkb->map->modmap)) { 1314f7df2e56Smrg rep->present &= ~XkbModifierMapMask; 1315f7df2e56Smrg rep->firstModMapKey = rep->nModMapKeys = 0; 1316f7df2e56Smrg rep->totalModMapKeys = 0; 1317f7df2e56Smrg return 0; 131805b261ecSmrg } 1319f7df2e56Smrg for (nRtrn = i = 0; i < rep->nModMapKeys; i++) { 1320f7df2e56Smrg if (xkb->map->modmap[i + rep->firstModMapKey] != 0) 1321f7df2e56Smrg nRtrn++; 132205b261ecSmrg } 1323f7df2e56Smrg rep->totalModMapKeys = nRtrn; 1324f7df2e56Smrg len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero modmap component */ 132505b261ecSmrg return len; 132605b261ecSmrg} 132705b261ecSmrg 132805b261ecSmrgstatic char * 1329f7df2e56SmrgXkbWriteModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1330f7df2e56Smrg ClientPtr client) 133105b261ecSmrg{ 1332f7df2e56Smrg unsigned i; 1333f7df2e56Smrg char *start; 1334f7df2e56Smrg unsigned char *pMap; 1335f7df2e56Smrg 1336f7df2e56Smrg start = buf; 1337f7df2e56Smrg pMap = &xkb->map->modmap[rep->firstModMapKey]; 1338f7df2e56Smrg for (i = 0; i < rep->nModMapKeys; i++, pMap++) { 1339f7df2e56Smrg if (*pMap != 0) { 1340f7df2e56Smrg *buf++ = i + rep->firstModMapKey; 1341f7df2e56Smrg *buf++ = *pMap; 1342f7df2e56Smrg } 1343f7df2e56Smrg } 1344f7df2e56Smrg i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */ 1345f7df2e56Smrg return buf + i; 134605b261ecSmrg} 134705b261ecSmrg 134805b261ecSmrgstatic int 1349f7df2e56SmrgXkbSizeVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep) 135005b261ecSmrg{ 1351f7df2e56Smrg unsigned i, len, nRtrn; 135205b261ecSmrg 1353f7df2e56Smrg if (((rep->present & XkbVirtualModMapMask) == 0) || (rep->nVModMapKeys < 1) 1354f7df2e56Smrg || (!xkb) || (!xkb->server) || (!xkb->server->vmodmap)) { 1355f7df2e56Smrg rep->present &= ~XkbVirtualModMapMask; 1356f7df2e56Smrg rep->firstVModMapKey = rep->nVModMapKeys = 0; 1357f7df2e56Smrg rep->totalVModMapKeys = 0; 1358f7df2e56Smrg return 0; 135905b261ecSmrg } 1360f7df2e56Smrg for (nRtrn = i = 0; i < rep->nVModMapKeys; i++) { 1361f7df2e56Smrg if (xkb->server->vmodmap[i + rep->firstVModMapKey] != 0) 1362f7df2e56Smrg nRtrn++; 136305b261ecSmrg } 1364f7df2e56Smrg rep->totalVModMapKeys = nRtrn; 1365f7df2e56Smrg len = nRtrn * SIZEOF(xkbVModMapWireDesc); 136605b261ecSmrg return len; 136705b261ecSmrg} 136805b261ecSmrg 136905b261ecSmrgstatic char * 1370f7df2e56SmrgXkbWriteVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1371f7df2e56Smrg ClientPtr client) 137205b261ecSmrg{ 1373f7df2e56Smrg unsigned i; 1374f7df2e56Smrg xkbVModMapWireDesc *wire; 1375f7df2e56Smrg unsigned short *pMap; 1376f7df2e56Smrg 1377f7df2e56Smrg wire = (xkbVModMapWireDesc *) buf; 1378f7df2e56Smrg pMap = &xkb->server->vmodmap[rep->firstVModMapKey]; 1379f7df2e56Smrg for (i = 0; i < rep->nVModMapKeys; i++, pMap++) { 1380f7df2e56Smrg if (*pMap != 0) { 1381f7df2e56Smrg wire->key = i + rep->firstVModMapKey; 1382f7df2e56Smrg wire->vmods = *pMap; 1383f7df2e56Smrg wire++; 1384f7df2e56Smrg } 1385f7df2e56Smrg } 1386f7df2e56Smrg return (char *) wire; 138705b261ecSmrg} 138805b261ecSmrg 138905b261ecSmrgstatic Status 1390f7df2e56SmrgXkbComputeGetMapReplySize(XkbDescPtr xkb, xkbGetMapReply * rep) 139105b261ecSmrg{ 1392f7df2e56Smrg int len; 1393f7df2e56Smrg 1394f7df2e56Smrg rep->minKeyCode = xkb->min_key_code; 1395f7df2e56Smrg rep->maxKeyCode = xkb->max_key_code; 1396f7df2e56Smrg len = XkbSizeKeyTypes(xkb, rep); 1397f7df2e56Smrg len += XkbSizeKeySyms(xkb, rep); 1398f7df2e56Smrg len += XkbSizeKeyActions(xkb, rep); 1399f7df2e56Smrg len += XkbSizeKeyBehaviors(xkb, rep); 1400f7df2e56Smrg len += XkbSizeVirtualMods(xkb, rep); 1401f7df2e56Smrg len += XkbSizeExplicit(xkb, rep); 1402f7df2e56Smrg len += XkbSizeModifierMap(xkb, rep); 1403f7df2e56Smrg len += XkbSizeVirtualModMap(xkb, rep); 1404f7df2e56Smrg rep->length += (len / 4); 140505b261ecSmrg return Success; 140605b261ecSmrg} 140705b261ecSmrg 140805b261ecSmrgstatic int 1409f7df2e56SmrgXkbSendMap(ClientPtr client, XkbDescPtr xkb, xkbGetMapReply * rep) 141005b261ecSmrg{ 1411f7df2e56Smrg unsigned i, len; 1412f7df2e56Smrg char *desc, *start; 141305b261ecSmrg 1414f7df2e56Smrg len = (rep->length * 4) - (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 1415f7df2e56Smrg start = desc = calloc(1, len); 141605b261ecSmrg if (!start) 1417f7df2e56Smrg return BadAlloc; 1418f7df2e56Smrg if (rep->nTypes > 0) 1419f7df2e56Smrg desc = XkbWriteKeyTypes(xkb, rep, desc, client); 1420f7df2e56Smrg if (rep->nKeySyms > 0) 1421f7df2e56Smrg desc = XkbWriteKeySyms(xkb, rep, desc, client); 1422f7df2e56Smrg if (rep->nKeyActs > 0) 1423f7df2e56Smrg desc = XkbWriteKeyActions(xkb, rep, desc, client); 1424f7df2e56Smrg if (rep->totalKeyBehaviors > 0) 1425f7df2e56Smrg desc = XkbWriteKeyBehaviors(xkb, rep, desc, client); 1426f7df2e56Smrg if (rep->virtualMods) { 1427f7df2e56Smrg register int sz, bit; 1428f7df2e56Smrg 1429f7df2e56Smrg for (i = sz = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1430f7df2e56Smrg if (rep->virtualMods & bit) { 1431f7df2e56Smrg desc[sz++] = xkb->server->vmods[i]; 1432f7df2e56Smrg } 1433f7df2e56Smrg } 1434f7df2e56Smrg desc += XkbPaddedSize(sz); 1435f7df2e56Smrg } 1436f7df2e56Smrg if (rep->totalKeyExplicit > 0) 1437f7df2e56Smrg desc = XkbWriteExplicit(xkb, rep, desc, client); 1438f7df2e56Smrg if (rep->totalModMapKeys > 0) 1439f7df2e56Smrg desc = XkbWriteModifierMap(xkb, rep, desc, client); 1440f7df2e56Smrg if (rep->totalVModMapKeys > 0) 1441f7df2e56Smrg desc = XkbWriteVirtualModMap(xkb, rep, desc, client); 1442f7df2e56Smrg if ((desc - start) != (len)) { 1443f7df2e56Smrg ErrorF 1444f7df2e56Smrg ("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", 1445f7df2e56Smrg len, (unsigned long) (desc - start)); 144605b261ecSmrg } 144705b261ecSmrg if (client->swapped) { 1448f7df2e56Smrg swaps(&rep->sequenceNumber); 1449f7df2e56Smrg swapl(&rep->length); 1450f7df2e56Smrg swaps(&rep->present); 1451f7df2e56Smrg swaps(&rep->totalSyms); 1452f7df2e56Smrg swaps(&rep->totalActs); 1453f7df2e56Smrg } 1454f7df2e56Smrg WriteToClient(client, (i = SIZEOF(xkbGetMapReply)), rep); 145505b261ecSmrg WriteToClient(client, len, start); 1456f7df2e56Smrg free((char *) start); 14576747b715Smrg return Success; 145805b261ecSmrg} 145905b261ecSmrg 146005b261ecSmrgint 146105b261ecSmrgProcXkbGetMap(ClientPtr client) 146205b261ecSmrg{ 1463f7df2e56Smrg DeviceIntPtr dev; 1464f7df2e56Smrg xkbGetMapReply rep; 1465f7df2e56Smrg XkbDescRec *xkb; 1466f7df2e56Smrg int n, status; 146705b261ecSmrg 146805b261ecSmrg REQUEST(xkbGetMapReq); 146905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetMapReq); 1470f7df2e56Smrg 1471f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 1472f7df2e56Smrg return BadAccess; 147305b261ecSmrg 14744642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 1475f7df2e56Smrg CHK_MASK_OVERLAP(0x01, stuff->full, stuff->partial); 1476f7df2e56Smrg CHK_MASK_LEGAL(0x02, stuff->full, XkbAllMapComponentsMask); 1477f7df2e56Smrg CHK_MASK_LEGAL(0x03, stuff->partial, XkbAllMapComponentsMask); 1478f7df2e56Smrg 1479f7df2e56Smrg xkb = dev->key->xkbInfo->desc; 1480f7df2e56Smrg rep = (xkbGetMapReply) { 1481f7df2e56Smrg .type = X_Reply, 1482f7df2e56Smrg .deviceID = dev->id, 1483f7df2e56Smrg .sequenceNumber = client->sequence, 1484f7df2e56Smrg .length = (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2, 1485f7df2e56Smrg .present = stuff->partial | stuff->full, 1486f7df2e56Smrg .minKeyCode = xkb->min_key_code, 1487f7df2e56Smrg .maxKeyCode = xkb->max_key_code 1488f7df2e56Smrg }; 1489f7df2e56Smrg 1490f7df2e56Smrg if (stuff->full & XkbKeyTypesMask) { 1491f7df2e56Smrg rep.firstType = 0; 1492f7df2e56Smrg rep.nTypes = xkb->map->num_types; 1493f7df2e56Smrg } 1494f7df2e56Smrg else if (stuff->partial & XkbKeyTypesMask) { 1495f7df2e56Smrg if (((unsigned) stuff->firstType + stuff->nTypes) > xkb->map->num_types) { 1496f7df2e56Smrg client->errorValue = _XkbErrCode4(0x04, xkb->map->num_types, 1497f7df2e56Smrg stuff->firstType, stuff->nTypes); 1498f7df2e56Smrg return BadValue; 1499f7df2e56Smrg } 1500f7df2e56Smrg rep.firstType = stuff->firstType; 1501f7df2e56Smrg rep.nTypes = stuff->nTypes; 1502f7df2e56Smrg } 1503f7df2e56Smrg else 1504f7df2e56Smrg rep.nTypes = 0; 150505b261ecSmrg rep.totalTypes = xkb->map->num_types; 150605b261ecSmrg 1507f7df2e56Smrg n = XkbNumKeys(xkb); 1508f7df2e56Smrg if (stuff->full & XkbKeySymsMask) { 1509f7df2e56Smrg rep.firstKeySym = xkb->min_key_code; 1510f7df2e56Smrg rep.nKeySyms = n; 1511f7df2e56Smrg } 1512f7df2e56Smrg else if (stuff->partial & XkbKeySymsMask) { 1513f7df2e56Smrg CHK_KEY_RANGE(0x05, stuff->firstKeySym, stuff->nKeySyms, xkb); 1514f7df2e56Smrg rep.firstKeySym = stuff->firstKeySym; 1515f7df2e56Smrg rep.nKeySyms = stuff->nKeySyms; 1516f7df2e56Smrg } 1517f7df2e56Smrg else 1518f7df2e56Smrg rep.nKeySyms = 0; 1519f7df2e56Smrg rep.totalSyms = 0; 1520f7df2e56Smrg 1521f7df2e56Smrg if (stuff->full & XkbKeyActionsMask) { 1522f7df2e56Smrg rep.firstKeyAct = xkb->min_key_code; 1523f7df2e56Smrg rep.nKeyActs = n; 1524f7df2e56Smrg } 1525f7df2e56Smrg else if (stuff->partial & XkbKeyActionsMask) { 1526f7df2e56Smrg CHK_KEY_RANGE(0x07, stuff->firstKeyAct, stuff->nKeyActs, xkb); 1527f7df2e56Smrg rep.firstKeyAct = stuff->firstKeyAct; 1528f7df2e56Smrg rep.nKeyActs = stuff->nKeyActs; 1529f7df2e56Smrg } 1530f7df2e56Smrg else 1531f7df2e56Smrg rep.nKeyActs = 0; 1532f7df2e56Smrg rep.totalActs = 0; 1533f7df2e56Smrg 1534f7df2e56Smrg if (stuff->full & XkbKeyBehaviorsMask) { 1535f7df2e56Smrg rep.firstKeyBehavior = xkb->min_key_code; 1536f7df2e56Smrg rep.nKeyBehaviors = n; 1537f7df2e56Smrg } 1538f7df2e56Smrg else if (stuff->partial & XkbKeyBehaviorsMask) { 1539f7df2e56Smrg CHK_KEY_RANGE(0x09, stuff->firstKeyBehavior, stuff->nKeyBehaviors, xkb); 1540f7df2e56Smrg rep.firstKeyBehavior = stuff->firstKeyBehavior; 1541f7df2e56Smrg rep.nKeyBehaviors = stuff->nKeyBehaviors; 1542f7df2e56Smrg } 1543f7df2e56Smrg else 1544f7df2e56Smrg rep.nKeyBehaviors = 0; 1545f7df2e56Smrg rep.totalKeyBehaviors = 0; 1546f7df2e56Smrg 1547f7df2e56Smrg if (stuff->full & XkbVirtualModsMask) 1548f7df2e56Smrg rep.virtualMods = ~0; 1549f7df2e56Smrg else if (stuff->partial & XkbVirtualModsMask) 1550f7df2e56Smrg rep.virtualMods = stuff->virtualMods; 1551f7df2e56Smrg 1552f7df2e56Smrg if (stuff->full & XkbExplicitComponentsMask) { 1553f7df2e56Smrg rep.firstKeyExplicit = xkb->min_key_code; 1554f7df2e56Smrg rep.nKeyExplicit = n; 1555f7df2e56Smrg } 1556f7df2e56Smrg else if (stuff->partial & XkbExplicitComponentsMask) { 1557f7df2e56Smrg CHK_KEY_RANGE(0x0B, stuff->firstKeyExplicit, stuff->nKeyExplicit, xkb); 1558f7df2e56Smrg rep.firstKeyExplicit = stuff->firstKeyExplicit; 1559f7df2e56Smrg rep.nKeyExplicit = stuff->nKeyExplicit; 1560f7df2e56Smrg } 1561f7df2e56Smrg else 1562f7df2e56Smrg rep.nKeyExplicit = 0; 1563f7df2e56Smrg rep.totalKeyExplicit = 0; 1564f7df2e56Smrg 1565f7df2e56Smrg if (stuff->full & XkbModifierMapMask) { 1566f7df2e56Smrg rep.firstModMapKey = xkb->min_key_code; 1567f7df2e56Smrg rep.nModMapKeys = n; 1568f7df2e56Smrg } 1569f7df2e56Smrg else if (stuff->partial & XkbModifierMapMask) { 1570f7df2e56Smrg CHK_KEY_RANGE(0x0D, stuff->firstModMapKey, stuff->nModMapKeys, xkb); 1571f7df2e56Smrg rep.firstModMapKey = stuff->firstModMapKey; 1572f7df2e56Smrg rep.nModMapKeys = stuff->nModMapKeys; 1573f7df2e56Smrg } 1574f7df2e56Smrg else 1575f7df2e56Smrg rep.nModMapKeys = 0; 1576f7df2e56Smrg rep.totalModMapKeys = 0; 1577f7df2e56Smrg 1578f7df2e56Smrg if (stuff->full & XkbVirtualModMapMask) { 1579f7df2e56Smrg rep.firstVModMapKey = xkb->min_key_code; 1580f7df2e56Smrg rep.nVModMapKeys = n; 1581f7df2e56Smrg } 1582f7df2e56Smrg else if (stuff->partial & XkbVirtualModMapMask) { 1583f7df2e56Smrg CHK_KEY_RANGE(0x0F, stuff->firstVModMapKey, stuff->nVModMapKeys, xkb); 1584f7df2e56Smrg rep.firstVModMapKey = stuff->firstVModMapKey; 1585f7df2e56Smrg rep.nVModMapKeys = stuff->nVModMapKeys; 1586f7df2e56Smrg } 1587f7df2e56Smrg else 1588f7df2e56Smrg rep.nVModMapKeys = 0; 1589f7df2e56Smrg rep.totalVModMapKeys = 0; 1590f7df2e56Smrg 1591f7df2e56Smrg if ((status = XkbComputeGetMapReplySize(xkb, &rep)) != Success) 1592f7df2e56Smrg return status; 1593f7df2e56Smrg return XkbSendMap(client, xkb, &rep); 159405b261ecSmrg} 159505b261ecSmrg 159605b261ecSmrg/***====================================================================***/ 159705b261ecSmrg 159805b261ecSmrgstatic int 1599f7df2e56SmrgCheckKeyTypes(ClientPtr client, 1600f7df2e56Smrg XkbDescPtr xkb, 1601f7df2e56Smrg xkbSetMapReq * req, 1602f7df2e56Smrg xkbKeyTypeWireDesc ** wireRtrn, 16035a112b11Smrg int *nMapsRtrn, CARD8 *mapWidthRtrn, Bool doswap) 160405b261ecSmrg{ 1605f7df2e56Smrg unsigned nMaps; 1606f7df2e56Smrg register unsigned i, n; 1607f7df2e56Smrg register CARD8 *map; 1608f7df2e56Smrg register xkbKeyTypeWireDesc *wire = *wireRtrn; 1609f7df2e56Smrg 1610f7df2e56Smrg if (req->firstType > ((unsigned) xkb->map->num_types)) { 1611f7df2e56Smrg *nMapsRtrn = _XkbErrCode3(0x01, req->firstType, xkb->map->num_types); 1612f7df2e56Smrg return 0; 1613f7df2e56Smrg } 1614f7df2e56Smrg if (req->flags & XkbSetMapResizeTypes) { 1615f7df2e56Smrg nMaps = req->firstType + req->nTypes; 1616f7df2e56Smrg if (nMaps < XkbNumRequiredTypes) { /* canonical types must be there */ 1617f7df2e56Smrg *nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, 4); 1618f7df2e56Smrg return 0; 1619f7df2e56Smrg } 1620f7df2e56Smrg } 1621f7df2e56Smrg else if (req->present & XkbKeyTypesMask) { 1622f7df2e56Smrg nMaps = xkb->map->num_types; 1623f7df2e56Smrg if ((req->firstType + req->nTypes) > nMaps) { 1624f7df2e56Smrg *nMapsRtrn = req->firstType + req->nTypes; 1625f7df2e56Smrg return 0; 1626f7df2e56Smrg } 162705b261ecSmrg } 162805b261ecSmrg else { 1629f7df2e56Smrg *nMapsRtrn = xkb->map->num_types; 1630f7df2e56Smrg for (i = 0; i < xkb->map->num_types; i++) { 1631f7df2e56Smrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 1632f7df2e56Smrg } 1633f7df2e56Smrg return 1; 1634f7df2e56Smrg } 1635f7df2e56Smrg 1636f7df2e56Smrg for (i = 0; i < req->firstType; i++) { 1637f7df2e56Smrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 1638f7df2e56Smrg } 1639f7df2e56Smrg for (i = 0; i < req->nTypes; i++) { 1640f7df2e56Smrg unsigned width; 1641f7df2e56Smrg 16425a112b11Smrg if (client->swapped && doswap) { 1643f7df2e56Smrg swaps(&wire->virtualMods); 1644f7df2e56Smrg } 1645f7df2e56Smrg n = i + req->firstType; 1646f7df2e56Smrg width = wire->numLevels; 1647f7df2e56Smrg if (width < 1) { 1648f7df2e56Smrg *nMapsRtrn = _XkbErrCode3(0x04, n, width); 1649f7df2e56Smrg return 0; 1650f7df2e56Smrg } 1651f7df2e56Smrg else if ((n == XkbOneLevelIndex) && (width != 1)) { /* must be width 1 */ 1652f7df2e56Smrg *nMapsRtrn = _XkbErrCode3(0x05, n, width); 1653f7df2e56Smrg return 0; 1654f7df2e56Smrg } 1655f7df2e56Smrg else if ((width != 2) && 1656f7df2e56Smrg ((n == XkbTwoLevelIndex) || (n == XkbKeypadIndex) || 1657f7df2e56Smrg (n == XkbAlphabeticIndex))) { 1658f7df2e56Smrg /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ 1659f7df2e56Smrg *nMapsRtrn = _XkbErrCode3(0x05, n, width); 1660f7df2e56Smrg return 0; 1661f7df2e56Smrg } 1662f7df2e56Smrg if (wire->nMapEntries > 0) { 1663f7df2e56Smrg xkbKTSetMapEntryWireDesc *mapWire; 1664f7df2e56Smrg xkbModsWireDesc *preWire; 1665f7df2e56Smrg 1666f7df2e56Smrg mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1]; 1667f7df2e56Smrg preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries]; 1668f7df2e56Smrg for (n = 0; n < wire->nMapEntries; n++) { 16695a112b11Smrg if (client->swapped && doswap) { 1670f7df2e56Smrg swaps(&mapWire[n].virtualMods); 1671f7df2e56Smrg } 1672f7df2e56Smrg if (mapWire[n].realMods & (~wire->realMods)) { 1673f7df2e56Smrg *nMapsRtrn = _XkbErrCode4(0x06, n, mapWire[n].realMods, 1674f7df2e56Smrg wire->realMods); 1675f7df2e56Smrg return 0; 1676f7df2e56Smrg } 1677f7df2e56Smrg if (mapWire[n].virtualMods & (~wire->virtualMods)) { 1678f7df2e56Smrg *nMapsRtrn = _XkbErrCode3(0x07, n, mapWire[n].virtualMods); 1679f7df2e56Smrg return 0; 1680f7df2e56Smrg } 1681f7df2e56Smrg if (mapWire[n].level >= wire->numLevels) { 1682f7df2e56Smrg *nMapsRtrn = _XkbErrCode4(0x08, n, wire->numLevels, 1683f7df2e56Smrg mapWire[n].level); 1684f7df2e56Smrg return 0; 1685f7df2e56Smrg } 1686f7df2e56Smrg if (wire->preserve) { 16875a112b11Smrg if (client->swapped && doswap) { 1688f7df2e56Smrg swaps(&preWire[n].virtualMods); 1689f7df2e56Smrg } 1690f7df2e56Smrg if (preWire[n].realMods & (~mapWire[n].realMods)) { 1691f7df2e56Smrg *nMapsRtrn = _XkbErrCode4(0x09, n, preWire[n].realMods, 1692f7df2e56Smrg mapWire[n].realMods); 1693f7df2e56Smrg return 0; 1694f7df2e56Smrg } 1695f7df2e56Smrg if (preWire[n].virtualMods & (~mapWire[n].virtualMods)) { 1696f7df2e56Smrg *nMapsRtrn = 1697f7df2e56Smrg _XkbErrCode3(0x0a, n, preWire[n].virtualMods); 1698f7df2e56Smrg return 0; 1699f7df2e56Smrg } 1700f7df2e56Smrg } 1701f7df2e56Smrg } 1702f7df2e56Smrg if (wire->preserve) 1703f7df2e56Smrg map = (CARD8 *) &preWire[wire->nMapEntries]; 1704f7df2e56Smrg else 1705f7df2e56Smrg map = (CARD8 *) &mapWire[wire->nMapEntries]; 1706f7df2e56Smrg } 1707f7df2e56Smrg else 1708f7df2e56Smrg map = (CARD8 *) &wire[1]; 1709f7df2e56Smrg mapWidthRtrn[i + req->firstType] = wire->numLevels; 1710f7df2e56Smrg wire = (xkbKeyTypeWireDesc *) map; 1711f7df2e56Smrg } 1712f7df2e56Smrg for (i = req->firstType + req->nTypes; i < nMaps; i++) { 1713f7df2e56Smrg mapWidthRtrn[i] = xkb->map->types[i].num_levels; 171405b261ecSmrg } 171505b261ecSmrg *nMapsRtrn = nMaps; 171605b261ecSmrg *wireRtrn = wire; 171705b261ecSmrg return 1; 171805b261ecSmrg} 171905b261ecSmrg 172005b261ecSmrgstatic int 1721f7df2e56SmrgCheckKeySyms(ClientPtr client, 1722f7df2e56Smrg XkbDescPtr xkb, 1723f7df2e56Smrg xkbSetMapReq * req, 1724f7df2e56Smrg int nTypes, 1725f7df2e56Smrg CARD8 *mapWidths, 17265a112b11Smrg CARD16 *symsPerKey, xkbSymMapWireDesc ** wireRtrn, int *errorRtrn, Bool doswap) 172705b261ecSmrg{ 1728f7df2e56Smrg register unsigned i; 1729f7df2e56Smrg XkbSymMapPtr map; 1730f7df2e56Smrg xkbSymMapWireDesc *wire = *wireRtrn; 1731f7df2e56Smrg 1732f7df2e56Smrg if (!(XkbKeySymsMask & req->present)) 1733f7df2e56Smrg return 1; 1734f7df2e56Smrg CHK_REQ_KEY_RANGE2(0x11, req->firstKeySym, req->nKeySyms, req, (*errorRtrn), 1735f7df2e56Smrg 0); 1736f7df2e56Smrg for (i = 0; i < req->nKeySyms; i++) { 1737f7df2e56Smrg KeySym *pSyms; 1738f7df2e56Smrg register unsigned nG; 1739f7df2e56Smrg 17405a112b11Smrg if (client->swapped && doswap) { 1741f7df2e56Smrg swaps(&wire->nSyms); 1742f7df2e56Smrg } 1743f7df2e56Smrg nG = XkbNumGroups(wire->groupInfo); 1744f7df2e56Smrg if (nG > XkbNumKbdGroups) { 1745f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x14, i + req->firstKeySym, nG); 1746f7df2e56Smrg return 0; 1747f7df2e56Smrg } 1748f7df2e56Smrg if (nG > 0) { 1749f7df2e56Smrg register int g, w; 1750f7df2e56Smrg 1751f7df2e56Smrg for (g = w = 0; g < nG; g++) { 1752f7df2e56Smrg if (wire->ktIndex[g] >= (unsigned) nTypes) { 1753f7df2e56Smrg *errorRtrn = _XkbErrCode4(0x15, i + req->firstKeySym, g, 1754f7df2e56Smrg wire->ktIndex[g]); 1755f7df2e56Smrg return 0; 1756f7df2e56Smrg } 1757f7df2e56Smrg if (mapWidths[wire->ktIndex[g]] > w) 1758f7df2e56Smrg w = mapWidths[wire->ktIndex[g]]; 1759f7df2e56Smrg } 1760f7df2e56Smrg if (wire->width != w) { 1761f7df2e56Smrg *errorRtrn = 1762f7df2e56Smrg _XkbErrCode3(0x16, i + req->firstKeySym, wire->width); 1763f7df2e56Smrg return 0; 1764f7df2e56Smrg } 1765f7df2e56Smrg w *= nG; 1766f7df2e56Smrg symsPerKey[i + req->firstKeySym] = w; 1767f7df2e56Smrg if (w != wire->nSyms) { 1768f7df2e56Smrg *errorRtrn = 1769f7df2e56Smrg _XkbErrCode4(0x16, i + req->firstKeySym, wire->nSyms, w); 1770f7df2e56Smrg return 0; 1771f7df2e56Smrg } 1772f7df2e56Smrg } 1773f7df2e56Smrg else if (wire->nSyms != 0) { 1774f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x17, i + req->firstKeySym, wire->nSyms); 1775f7df2e56Smrg return 0; 1776f7df2e56Smrg } 1777f7df2e56Smrg pSyms = (KeySym *) &wire[1]; 1778f7df2e56Smrg wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; 177905b261ecSmrg } 178005b261ecSmrg 178105b261ecSmrg map = &xkb->map->key_sym_map[i]; 1782f7df2e56Smrg for (; i <= (unsigned) xkb->max_key_code; i++, map++) { 1783f7df2e56Smrg register int g, nG, w; 1784f7df2e56Smrg 1785f7df2e56Smrg nG = XkbKeyNumGroups(xkb, i); 1786f7df2e56Smrg for (w = g = 0; g < nG; g++) { 1787f7df2e56Smrg if (map->kt_index[g] >= (unsigned) nTypes) { 1788f7df2e56Smrg *errorRtrn = _XkbErrCode4(0x18, i, g, map->kt_index[g]); 1789f7df2e56Smrg return 0; 1790f7df2e56Smrg } 1791f7df2e56Smrg if (mapWidths[map->kt_index[g]] > w) 1792f7df2e56Smrg w = mapWidths[map->kt_index[g]]; 1793f7df2e56Smrg } 1794f7df2e56Smrg symsPerKey[i] = w * nG; 179505b261ecSmrg } 179605b261ecSmrg *wireRtrn = wire; 179705b261ecSmrg return 1; 179805b261ecSmrg} 179905b261ecSmrg 180005b261ecSmrgstatic int 1801f7df2e56SmrgCheckKeyActions(XkbDescPtr xkb, 1802f7df2e56Smrg xkbSetMapReq * req, 1803f7df2e56Smrg int nTypes, 1804f7df2e56Smrg CARD8 *mapWidths, 1805f7df2e56Smrg CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn) 180605b261ecSmrg{ 1807f7df2e56Smrg int nActs; 1808f7df2e56Smrg CARD8 *wire = *wireRtrn; 1809f7df2e56Smrg register unsigned i; 1810f7df2e56Smrg 1811f7df2e56Smrg if (!(XkbKeyActionsMask & req->present)) 1812f7df2e56Smrg return 1; 1813f7df2e56Smrg CHK_REQ_KEY_RANGE2(0x21, req->firstKeyAct, req->nKeyActs, req, (*nActsRtrn), 1814f7df2e56Smrg 0); 1815f7df2e56Smrg for (nActs = i = 0; i < req->nKeyActs; i++) { 1816f7df2e56Smrg if (wire[0] != 0) { 1817f7df2e56Smrg if (wire[0] == symsPerKey[i + req->firstKeyAct]) 1818f7df2e56Smrg nActs += wire[0]; 1819f7df2e56Smrg else { 1820f7df2e56Smrg *nActsRtrn = _XkbErrCode3(0x23, i + req->firstKeyAct, wire[0]); 1821f7df2e56Smrg return 0; 1822f7df2e56Smrg } 1823f7df2e56Smrg } 1824f7df2e56Smrg wire++; 1825f7df2e56Smrg } 1826f7df2e56Smrg if (req->nKeyActs % 4) 1827f7df2e56Smrg wire += 4 - (req->nKeyActs % 4); 1828f7df2e56Smrg *wireRtrn = (CARD8 *) (((XkbAnyAction *) wire) + nActs); 182905b261ecSmrg *nActsRtrn = nActs; 183005b261ecSmrg return 1; 183105b261ecSmrg} 183205b261ecSmrg 183305b261ecSmrgstatic int 1834f7df2e56SmrgCheckKeyBehaviors(XkbDescPtr xkb, 1835f7df2e56Smrg xkbSetMapReq * req, 1836f7df2e56Smrg xkbBehaviorWireDesc ** wireRtrn, int *errorRtrn) 183705b261ecSmrg{ 1838f7df2e56Smrg register xkbBehaviorWireDesc *wire = *wireRtrn; 1839f7df2e56Smrg register XkbServerMapPtr server = xkb->server; 1840f7df2e56Smrg register unsigned i; 1841f7df2e56Smrg unsigned first, last; 1842f7df2e56Smrg 1843f7df2e56Smrg if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) { 1844f7df2e56Smrg req->present &= ~XkbKeyBehaviorsMask; 1845f7df2e56Smrg req->nKeyBehaviors = 0; 1846f7df2e56Smrg return 1; 1847f7df2e56Smrg } 1848f7df2e56Smrg first = req->firstKeyBehavior; 1849f7df2e56Smrg last = req->firstKeyBehavior + req->nKeyBehaviors - 1; 1850f7df2e56Smrg if (first < req->minKeyCode) { 1851f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x31, first, req->minKeyCode); 1852f7df2e56Smrg return 0; 1853f7df2e56Smrg } 1854f7df2e56Smrg if (last > req->maxKeyCode) { 1855f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x32, last, req->maxKeyCode); 1856f7df2e56Smrg return 0; 1857f7df2e56Smrg } 1858f7df2e56Smrg 1859f7df2e56Smrg for (i = 0; i < req->totalKeyBehaviors; i++, wire++) { 1860f7df2e56Smrg if ((wire->key < first) || (wire->key > last)) { 1861f7df2e56Smrg *errorRtrn = _XkbErrCode4(0x33, first, last, wire->key); 1862f7df2e56Smrg return 0; 1863f7df2e56Smrg } 1864f7df2e56Smrg if ((wire->type & XkbKB_Permanent) && 1865f7df2e56Smrg ((server->behaviors[wire->key].type != wire->type) || 1866f7df2e56Smrg (server->behaviors[wire->key].data != wire->data))) { 1867f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x33, wire->key, wire->type); 1868f7df2e56Smrg return 0; 1869f7df2e56Smrg } 1870f7df2e56Smrg if ((wire->type == XkbKB_RadioGroup) && 1871f7df2e56Smrg ((wire->data & (~XkbKB_RGAllowNone)) > XkbMaxRadioGroups)) { 1872f7df2e56Smrg *errorRtrn = _XkbErrCode4(0x34, wire->key, wire->data, 1873f7df2e56Smrg XkbMaxRadioGroups); 1874f7df2e56Smrg return 0; 1875f7df2e56Smrg } 1876f7df2e56Smrg if ((wire->type == XkbKB_Overlay1) || (wire->type == XkbKB_Overlay2)) { 1877f7df2e56Smrg CHK_KEY_RANGE2(0x35, wire->key, 1, xkb, *errorRtrn, 0); 1878f7df2e56Smrg } 187905b261ecSmrg } 188005b261ecSmrg *wireRtrn = wire; 188105b261ecSmrg return 1; 188205b261ecSmrg} 188305b261ecSmrg 188405b261ecSmrgstatic int 1885f7df2e56SmrgCheckVirtualMods(XkbDescRec * xkb, 1886f7df2e56Smrg xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) 188705b261ecSmrg{ 1888f7df2e56Smrg register CARD8 *wire = *wireRtrn; 1889f7df2e56Smrg register unsigned i, nMods, bit; 189005b261ecSmrg 1891f7df2e56Smrg if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) 1892f7df2e56Smrg return 1; 1893f7df2e56Smrg for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1894f7df2e56Smrg if (req->virtualMods & bit) 1895f7df2e56Smrg nMods++; 189605b261ecSmrg } 1897f7df2e56Smrg *wireRtrn = (wire + XkbPaddedSize(nMods)); 189805b261ecSmrg return 1; 189905b261ecSmrg} 190005b261ecSmrg 190105b261ecSmrgstatic int 1902f7df2e56SmrgCheckKeyExplicit(XkbDescPtr xkb, 1903f7df2e56Smrg xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) 190405b261ecSmrg{ 1905f7df2e56Smrg register CARD8 *wire = *wireRtrn; 1906f7df2e56Smrg CARD8 *start; 1907f7df2e56Smrg register unsigned i; 1908f7df2e56Smrg int first, last; 1909f7df2e56Smrg 1910f7df2e56Smrg if (((req->present & XkbExplicitComponentsMask) == 0) || 1911f7df2e56Smrg (req->nKeyExplicit < 1)) { 1912f7df2e56Smrg req->present &= ~XkbExplicitComponentsMask; 1913f7df2e56Smrg req->nKeyExplicit = 0; 1914f7df2e56Smrg return 1; 1915f7df2e56Smrg } 1916f7df2e56Smrg first = req->firstKeyExplicit; 1917f7df2e56Smrg last = first + req->nKeyExplicit - 1; 1918f7df2e56Smrg if (first < req->minKeyCode) { 1919f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x51, first, req->minKeyCode); 1920f7df2e56Smrg return 0; 1921f7df2e56Smrg } 1922f7df2e56Smrg if (last > req->maxKeyCode) { 1923f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x52, last, req->maxKeyCode); 1924f7df2e56Smrg return 0; 1925f7df2e56Smrg } 1926f7df2e56Smrg start = wire; 1927f7df2e56Smrg for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { 1928f7df2e56Smrg if ((wire[0] < first) || (wire[0] > last)) { 1929f7df2e56Smrg *errorRtrn = _XkbErrCode4(0x53, first, last, wire[0]); 1930f7df2e56Smrg return 0; 1931f7df2e56Smrg } 1932f7df2e56Smrg if (wire[1] & (~XkbAllExplicitMask)) { 1933f7df2e56Smrg *errorRtrn = _XkbErrCode3(0x52, ~XkbAllExplicitMask, wire[1]); 1934f7df2e56Smrg return 0; 1935f7df2e56Smrg } 1936f7df2e56Smrg } 1937f7df2e56Smrg wire += XkbPaddedSize(wire - start) - (wire - start); 1938f7df2e56Smrg *wireRtrn = wire; 193905b261ecSmrg return 1; 194005b261ecSmrg} 194105b261ecSmrg 194205b261ecSmrgstatic int 1943f7df2e56SmrgCheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn, 1944f7df2e56Smrg int *errRtrn) 194505b261ecSmrg{ 1946f7df2e56Smrg register CARD8 *wire = *wireRtrn; 1947f7df2e56Smrg CARD8 *start; 1948f7df2e56Smrg register unsigned i; 1949f7df2e56Smrg int first, last; 1950f7df2e56Smrg 1951f7df2e56Smrg if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys < 1)) { 1952f7df2e56Smrg req->present &= ~XkbModifierMapMask; 1953f7df2e56Smrg req->nModMapKeys = 0; 1954f7df2e56Smrg return 1; 1955f7df2e56Smrg } 1956f7df2e56Smrg first = req->firstModMapKey; 1957f7df2e56Smrg last = first + req->nModMapKeys - 1; 1958f7df2e56Smrg if (first < req->minKeyCode) { 1959f7df2e56Smrg *errRtrn = _XkbErrCode3(0x61, first, req->minKeyCode); 1960f7df2e56Smrg return 0; 1961f7df2e56Smrg } 1962f7df2e56Smrg if (last > req->maxKeyCode) { 1963f7df2e56Smrg *errRtrn = _XkbErrCode3(0x62, last, req->maxKeyCode); 1964f7df2e56Smrg return 0; 1965f7df2e56Smrg } 1966f7df2e56Smrg start = wire; 1967f7df2e56Smrg for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { 1968f7df2e56Smrg if ((wire[0] < first) || (wire[0] > last)) { 1969f7df2e56Smrg *errRtrn = _XkbErrCode4(0x63, first, last, wire[0]); 1970f7df2e56Smrg return 0; 1971f7df2e56Smrg } 1972f7df2e56Smrg } 1973f7df2e56Smrg wire += XkbPaddedSize(wire - start) - (wire - start); 1974f7df2e56Smrg *wireRtrn = wire; 197505b261ecSmrg return 1; 197605b261ecSmrg} 197705b261ecSmrg 197805b261ecSmrgstatic int 1979f7df2e56SmrgCheckVirtualModMap(XkbDescPtr xkb, 1980f7df2e56Smrg xkbSetMapReq * req, 1981f7df2e56Smrg xkbVModMapWireDesc ** wireRtrn, int *errRtrn) 198205b261ecSmrg{ 1983f7df2e56Smrg register xkbVModMapWireDesc *wire = *wireRtrn; 1984f7df2e56Smrg register unsigned i; 1985f7df2e56Smrg int first, last; 1986f7df2e56Smrg 1987f7df2e56Smrg if (((req->present & XkbVirtualModMapMask) == 0) || (req->nVModMapKeys < 1)) { 1988f7df2e56Smrg req->present &= ~XkbVirtualModMapMask; 1989f7df2e56Smrg req->nVModMapKeys = 0; 1990f7df2e56Smrg return 1; 1991f7df2e56Smrg } 1992f7df2e56Smrg first = req->firstVModMapKey; 1993f7df2e56Smrg last = first + req->nVModMapKeys - 1; 1994f7df2e56Smrg if (first < req->minKeyCode) { 1995f7df2e56Smrg *errRtrn = _XkbErrCode3(0x71, first, req->minKeyCode); 1996f7df2e56Smrg return 0; 1997f7df2e56Smrg } 1998f7df2e56Smrg if (last > req->maxKeyCode) { 1999f7df2e56Smrg *errRtrn = _XkbErrCode3(0x72, last, req->maxKeyCode); 2000f7df2e56Smrg return 0; 2001f7df2e56Smrg } 2002f7df2e56Smrg for (i = 0; i < req->totalVModMapKeys; i++, wire++) { 2003f7df2e56Smrg if ((wire->key < first) || (wire->key > last)) { 2004f7df2e56Smrg *errRtrn = _XkbErrCode4(0x73, first, last, wire->key); 2005f7df2e56Smrg return 0; 2006f7df2e56Smrg } 2007f7df2e56Smrg } 2008f7df2e56Smrg *wireRtrn = wire; 200905b261ecSmrg return 1; 201005b261ecSmrg} 201105b261ecSmrg 201205b261ecSmrgstatic char * 2013f7df2e56SmrgSetKeyTypes(XkbDescPtr xkb, 2014f7df2e56Smrg xkbSetMapReq * req, 2015f7df2e56Smrg xkbKeyTypeWireDesc * wire, XkbChangesPtr changes) 201605b261ecSmrg{ 2017f7df2e56Smrg register unsigned i; 2018f7df2e56Smrg unsigned first, last; 2019f7df2e56Smrg CARD8 *map; 2020f7df2e56Smrg 2021f7df2e56Smrg if ((unsigned) (req->firstType + req->nTypes) > xkb->map->size_types) { 2022f7df2e56Smrg i = req->firstType + req->nTypes; 2023f7df2e56Smrg if (XkbAllocClientMap(xkb, XkbKeyTypesMask, i) != Success) { 2024f7df2e56Smrg return NULL; 2025f7df2e56Smrg } 2026f7df2e56Smrg } 2027f7df2e56Smrg if ((unsigned) (req->firstType + req->nTypes) > xkb->map->num_types) 2028f7df2e56Smrg xkb->map->num_types = req->firstType + req->nTypes; 2029f7df2e56Smrg 2030f7df2e56Smrg for (i = 0; i < req->nTypes; i++) { 2031f7df2e56Smrg XkbKeyTypePtr pOld; 2032f7df2e56Smrg register unsigned n; 2033f7df2e56Smrg 2034f7df2e56Smrg if (XkbResizeKeyType(xkb, i + req->firstType, wire->nMapEntries, 2035f7df2e56Smrg wire->preserve, wire->numLevels) != Success) { 2036f7df2e56Smrg return NULL; 2037f7df2e56Smrg } 2038f7df2e56Smrg pOld = &xkb->map->types[i + req->firstType]; 2039f7df2e56Smrg map = (CARD8 *) &wire[1]; 2040f7df2e56Smrg 2041f7df2e56Smrg pOld->mods.real_mods = wire->realMods; 2042f7df2e56Smrg pOld->mods.vmods = wire->virtualMods; 2043f7df2e56Smrg pOld->num_levels = wire->numLevels; 2044f7df2e56Smrg pOld->map_count = wire->nMapEntries; 2045f7df2e56Smrg 2046f7df2e56Smrg pOld->mods.mask = pOld->mods.real_mods | 2047f7df2e56Smrg XkbMaskForVMask(xkb, pOld->mods.vmods); 2048f7df2e56Smrg 2049f7df2e56Smrg if (wire->nMapEntries) { 2050f7df2e56Smrg xkbKTSetMapEntryWireDesc *mapWire; 2051f7df2e56Smrg xkbModsWireDesc *preWire; 2052f7df2e56Smrg unsigned tmp; 2053f7df2e56Smrg 2054f7df2e56Smrg mapWire = (xkbKTSetMapEntryWireDesc *) map; 2055f7df2e56Smrg preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries]; 2056f7df2e56Smrg for (n = 0; n < wire->nMapEntries; n++) { 2057f7df2e56Smrg pOld->map[n].active = 1; 2058f7df2e56Smrg pOld->map[n].mods.mask = mapWire[n].realMods; 2059f7df2e56Smrg pOld->map[n].mods.real_mods = mapWire[n].realMods; 2060f7df2e56Smrg pOld->map[n].mods.vmods = mapWire[n].virtualMods; 2061f7df2e56Smrg pOld->map[n].level = mapWire[n].level; 2062f7df2e56Smrg if (mapWire[n].virtualMods != 0) { 2063f7df2e56Smrg tmp = XkbMaskForVMask(xkb, mapWire[n].virtualMods); 2064f7df2e56Smrg pOld->map[n].active = (tmp != 0); 2065f7df2e56Smrg pOld->map[n].mods.mask |= tmp; 2066f7df2e56Smrg } 2067f7df2e56Smrg if (wire->preserve) { 2068f7df2e56Smrg pOld->preserve[n].real_mods = preWire[n].realMods; 2069f7df2e56Smrg pOld->preserve[n].vmods = preWire[n].virtualMods; 2070f7df2e56Smrg tmp = XkbMaskForVMask(xkb, preWire[n].virtualMods); 2071f7df2e56Smrg pOld->preserve[n].mask = preWire[n].realMods | tmp; 2072f7df2e56Smrg } 2073f7df2e56Smrg } 2074f7df2e56Smrg if (wire->preserve) 2075f7df2e56Smrg map = (CARD8 *) &preWire[wire->nMapEntries]; 2076f7df2e56Smrg else 2077f7df2e56Smrg map = (CARD8 *) &mapWire[wire->nMapEntries]; 2078f7df2e56Smrg } 2079f7df2e56Smrg else 2080f7df2e56Smrg map = (CARD8 *) &wire[1]; 2081f7df2e56Smrg wire = (xkbKeyTypeWireDesc *) map; 2082f7df2e56Smrg } 2083f7df2e56Smrg first = req->firstType; 2084f7df2e56Smrg last = first + req->nTypes - 1; /* last changed type */ 2085f7df2e56Smrg if (changes->map.changed & XkbKeyTypesMask) { 2086f7df2e56Smrg int oldLast; 2087f7df2e56Smrg 2088f7df2e56Smrg oldLast = changes->map.first_type + changes->map.num_types - 1; 2089f7df2e56Smrg if (changes->map.first_type < first) 2090f7df2e56Smrg first = changes->map.first_type; 2091f7df2e56Smrg if (oldLast > last) 2092f7df2e56Smrg last = oldLast; 2093f7df2e56Smrg } 2094f7df2e56Smrg changes->map.changed |= XkbKeyTypesMask; 209505b261ecSmrg changes->map.first_type = first; 2096f7df2e56Smrg changes->map.num_types = (last - first) + 1; 2097f7df2e56Smrg return (char *) wire; 209805b261ecSmrg} 209905b261ecSmrg 210005b261ecSmrgstatic char * 2101f7df2e56SmrgSetKeySyms(ClientPtr client, 2102f7df2e56Smrg XkbDescPtr xkb, 2103f7df2e56Smrg xkbSetMapReq * req, 2104f7df2e56Smrg xkbSymMapWireDesc * wire, XkbChangesPtr changes, DeviceIntPtr dev) 210505b261ecSmrg{ 2106f7df2e56Smrg register unsigned i, s; 2107f7df2e56Smrg XkbSymMapPtr oldMap; 2108f7df2e56Smrg KeySym *newSyms; 2109f7df2e56Smrg KeySym *pSyms; 2110f7df2e56Smrg unsigned first, last; 211105b261ecSmrg 211205b261ecSmrg oldMap = &xkb->map->key_sym_map[req->firstKeySym]; 2113f7df2e56Smrg for (i = 0; i < req->nKeySyms; i++, oldMap++) { 2114f7df2e56Smrg pSyms = (KeySym *) &wire[1]; 2115f7df2e56Smrg if (wire->nSyms > 0) { 2116f7df2e56Smrg newSyms = XkbResizeKeySyms(xkb, i + req->firstKeySym, wire->nSyms); 2117f7df2e56Smrg for (s = 0; s < wire->nSyms; s++) { 2118f7df2e56Smrg newSyms[s] = pSyms[s]; 2119f7df2e56Smrg } 2120f7df2e56Smrg if (client->swapped) { 2121f7df2e56Smrg for (s = 0; s < wire->nSyms; s++) { 2122f7df2e56Smrg swapl(&newSyms[s]); 2123f7df2e56Smrg } 2124f7df2e56Smrg } 2125f7df2e56Smrg } 21264e185dc0Smrg if (XkbKeyHasActions(xkb, i + req->firstKeySym)) 21274e185dc0Smrg XkbResizeKeyActions(xkb, i + req->firstKeySym, 21284e185dc0Smrg XkbNumGroups(wire->groupInfo) * wire->width); 2129f7df2e56Smrg oldMap->kt_index[0] = wire->ktIndex[0]; 2130f7df2e56Smrg oldMap->kt_index[1] = wire->ktIndex[1]; 2131f7df2e56Smrg oldMap->kt_index[2] = wire->ktIndex[2]; 2132f7df2e56Smrg oldMap->kt_index[3] = wire->ktIndex[3]; 2133f7df2e56Smrg oldMap->group_info = wire->groupInfo; 2134f7df2e56Smrg oldMap->width = wire->width; 2135f7df2e56Smrg wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; 2136f7df2e56Smrg } 2137f7df2e56Smrg first = req->firstKeySym; 2138f7df2e56Smrg last = first + req->nKeySyms - 1; 2139f7df2e56Smrg if (changes->map.changed & XkbKeySymsMask) { 2140f7df2e56Smrg int oldLast = 2141f7df2e56Smrg (changes->map.first_key_sym + changes->map.num_key_syms - 1); 2142f7df2e56Smrg if (changes->map.first_key_sym < first) 2143f7df2e56Smrg first = changes->map.first_key_sym; 2144f7df2e56Smrg if (oldLast > last) 2145f7df2e56Smrg last = oldLast; 2146f7df2e56Smrg } 2147f7df2e56Smrg changes->map.changed |= XkbKeySymsMask; 214805b261ecSmrg changes->map.first_key_sym = first; 2149f7df2e56Smrg changes->map.num_key_syms = (last - first + 1); 2150f7df2e56Smrg 2151f7df2e56Smrg s = 0; 2152f7df2e56Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 2153f7df2e56Smrg if (XkbKeyNumGroups(xkb, i) > s) 2154f7df2e56Smrg s = XkbKeyNumGroups(xkb, i); 2155f7df2e56Smrg } 2156f7df2e56Smrg if (s != xkb->ctrls->num_groups) { 2157f7df2e56Smrg xkbControlsNotify cn; 2158f7df2e56Smrg XkbControlsRec old; 2159f7df2e56Smrg 2160f7df2e56Smrg cn.keycode = 0; 2161f7df2e56Smrg cn.eventType = 0; 2162f7df2e56Smrg cn.requestMajor = XkbReqCode; 2163f7df2e56Smrg cn.requestMinor = X_kbSetMap; 2164f7df2e56Smrg old = *xkb->ctrls; 2165f7df2e56Smrg xkb->ctrls->num_groups = s; 2166f7df2e56Smrg if (XkbComputeControlsNotify(dev, &old, xkb->ctrls, &cn, FALSE)) 2167f7df2e56Smrg XkbSendControlsNotify(dev, &cn); 2168f7df2e56Smrg } 2169f7df2e56Smrg return (char *) wire; 217005b261ecSmrg} 217105b261ecSmrg 217205b261ecSmrgstatic char * 2173f7df2e56SmrgSetKeyActions(XkbDescPtr xkb, 2174f7df2e56Smrg xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 217505b261ecSmrg{ 2176f7df2e56Smrg register unsigned i, first, last; 2177f7df2e56Smrg CARD8 *nActs = wire; 2178f7df2e56Smrg XkbAction *newActs; 2179f7df2e56Smrg 2180f7df2e56Smrg wire += XkbPaddedSize(req->nKeyActs); 2181f7df2e56Smrg for (i = 0; i < req->nKeyActs; i++) { 2182f7df2e56Smrg if (nActs[i] == 0) 2183f7df2e56Smrg xkb->server->key_acts[i + req->firstKeyAct] = 0; 2184f7df2e56Smrg else { 2185f7df2e56Smrg newActs = XkbResizeKeyActions(xkb, i + req->firstKeyAct, nActs[i]); 2186f7df2e56Smrg memcpy((char *) newActs, (char *) wire, 2187f7df2e56Smrg nActs[i] * SIZEOF(xkbActionWireDesc)); 2188f7df2e56Smrg wire += nActs[i] * SIZEOF(xkbActionWireDesc); 2189f7df2e56Smrg } 2190f7df2e56Smrg } 2191f7df2e56Smrg first = req->firstKeyAct; 2192f7df2e56Smrg last = (first + req->nKeyActs - 1); 2193f7df2e56Smrg if (changes->map.changed & XkbKeyActionsMask) { 2194f7df2e56Smrg int oldLast; 2195f7df2e56Smrg 2196f7df2e56Smrg oldLast = changes->map.first_key_act + changes->map.num_key_acts - 1; 2197f7df2e56Smrg if (changes->map.first_key_act < first) 2198f7df2e56Smrg first = changes->map.first_key_act; 2199f7df2e56Smrg if (oldLast > last) 2200f7df2e56Smrg last = oldLast; 2201f7df2e56Smrg } 2202f7df2e56Smrg changes->map.changed |= XkbKeyActionsMask; 2203f7df2e56Smrg changes->map.first_key_act = first; 2204f7df2e56Smrg changes->map.num_key_acts = (last - first + 1); 2205f7df2e56Smrg return (char *) wire; 220605b261ecSmrg} 220705b261ecSmrg 220805b261ecSmrgstatic char * 2209f7df2e56SmrgSetKeyBehaviors(XkbSrvInfoPtr xkbi, 2210f7df2e56Smrg xkbSetMapReq * req, 2211f7df2e56Smrg xkbBehaviorWireDesc * wire, XkbChangesPtr changes) 221205b261ecSmrg{ 2213f7df2e56Smrg register unsigned i; 2214f7df2e56Smrg int maxRG = -1; 2215f7df2e56Smrg XkbDescPtr xkb = xkbi->desc; 2216f7df2e56Smrg XkbServerMapPtr server = xkb->server; 2217f7df2e56Smrg unsigned first, last; 2218f7df2e56Smrg 2219f7df2e56Smrg first = req->firstKeyBehavior; 2220f7df2e56Smrg last = req->firstKeyBehavior + req->nKeyBehaviors - 1; 2221f7df2e56Smrg memset(&server->behaviors[first], 0, 2222f7df2e56Smrg req->nKeyBehaviors * sizeof(XkbBehavior)); 2223f7df2e56Smrg for (i = 0; i < req->totalKeyBehaviors; i++) { 2224f7df2e56Smrg if ((server->behaviors[wire->key].type & XkbKB_Permanent) == 0) { 2225f7df2e56Smrg server->behaviors[wire->key].type = wire->type; 2226f7df2e56Smrg server->behaviors[wire->key].data = wire->data; 2227f7df2e56Smrg if ((wire->type == XkbKB_RadioGroup) && 2228f7df2e56Smrg (((int) wire->data) > maxRG)) 2229f7df2e56Smrg maxRG = wire->data + 1; 2230f7df2e56Smrg } 2231f7df2e56Smrg wire++; 2232f7df2e56Smrg } 2233f7df2e56Smrg 2234f7df2e56Smrg if (maxRG > (int) xkbi->nRadioGroups) { 223505b261ecSmrg if (xkbi->radioGroups) 2236f7df2e56Smrg xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG, 2237f7df2e56Smrg sizeof(XkbRadioGroupRec)); 2238f7df2e56Smrg else 2239f7df2e56Smrg xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec)); 224005b261ecSmrg if (xkbi->radioGroups) { 2241f7df2e56Smrg if (xkbi->nRadioGroups) 2242f7df2e56Smrg memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0, 2243f7df2e56Smrg (maxRG - xkbi->nRadioGroups) * sizeof(XkbRadioGroupRec)); 2244f7df2e56Smrg xkbi->nRadioGroups = maxRG; 224505b261ecSmrg } 2246f7df2e56Smrg else 2247f7df2e56Smrg xkbi->nRadioGroups = 0; 224805b261ecSmrg /* should compute members here */ 224905b261ecSmrg } 2250f7df2e56Smrg if (changes->map.changed & XkbKeyBehaviorsMask) { 2251f7df2e56Smrg unsigned oldLast; 2252f7df2e56Smrg 2253f7df2e56Smrg oldLast = changes->map.first_key_behavior + 2254f7df2e56Smrg changes->map.num_key_behaviors - 1; 2255f7df2e56Smrg if (changes->map.first_key_behavior < req->firstKeyBehavior) 2256f7df2e56Smrg first = changes->map.first_key_behavior; 2257f7df2e56Smrg if (oldLast > last) 2258f7df2e56Smrg last = oldLast; 225905b261ecSmrg } 2260f7df2e56Smrg changes->map.changed |= XkbKeyBehaviorsMask; 226105b261ecSmrg changes->map.first_key_behavior = first; 2262f7df2e56Smrg changes->map.num_key_behaviors = (last - first + 1); 2263f7df2e56Smrg return (char *) wire; 226405b261ecSmrg} 226505b261ecSmrg 226605b261ecSmrgstatic char * 2267f7df2e56SmrgSetVirtualMods(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2268f7df2e56Smrg XkbChangesPtr changes) 226905b261ecSmrg{ 2270f7df2e56Smrg register int i, bit, nMods; 2271f7df2e56Smrg XkbServerMapPtr srv = xkbi->desc->server; 2272f7df2e56Smrg 2273f7df2e56Smrg if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) 2274f7df2e56Smrg return (char *) wire; 2275f7df2e56Smrg for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 2276f7df2e56Smrg if (req->virtualMods & bit) { 2277f7df2e56Smrg if (srv->vmods[i] != wire[nMods]) { 2278f7df2e56Smrg changes->map.changed |= XkbVirtualModsMask; 2279f7df2e56Smrg changes->map.vmods |= bit; 2280f7df2e56Smrg srv->vmods[i] = wire[nMods]; 2281f7df2e56Smrg } 2282f7df2e56Smrg nMods++; 2283f7df2e56Smrg } 2284f7df2e56Smrg } 2285f7df2e56Smrg return (char *) (wire + XkbPaddedSize(nMods)); 228605b261ecSmrg} 228705b261ecSmrg 228805b261ecSmrgstatic char * 2289f7df2e56SmrgSetKeyExplicit(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2290f7df2e56Smrg XkbChangesPtr changes) 229105b261ecSmrg{ 2292f7df2e56Smrg register unsigned i, first, last; 2293f7df2e56Smrg XkbServerMapPtr xkb = xkbi->desc->server; 2294f7df2e56Smrg CARD8 *start; 229505b261ecSmrg 2296f7df2e56Smrg start = wire; 2297f7df2e56Smrg first = req->firstKeyExplicit; 2298f7df2e56Smrg last = req->firstKeyExplicit + req->nKeyExplicit - 1; 22996747b715Smrg memset(&xkb->explicit[first], 0, req->nKeyExplicit); 2300f7df2e56Smrg for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { 2301f7df2e56Smrg xkb->explicit[wire[0]] = wire[1]; 2302f7df2e56Smrg } 2303f7df2e56Smrg if (first > 0) { 2304f7df2e56Smrg if (changes->map.changed & XkbExplicitComponentsMask) { 2305f7df2e56Smrg int oldLast; 2306f7df2e56Smrg 2307f7df2e56Smrg oldLast = changes->map.first_key_explicit + 2308f7df2e56Smrg changes->map.num_key_explicit - 1; 2309f7df2e56Smrg if (changes->map.first_key_explicit < first) 2310f7df2e56Smrg first = changes->map.first_key_explicit; 2311f7df2e56Smrg if (oldLast > last) 2312f7df2e56Smrg last = oldLast; 2313f7df2e56Smrg } 2314f7df2e56Smrg changes->map.first_key_explicit = first; 2315f7df2e56Smrg changes->map.num_key_explicit = (last - first) + 1; 2316f7df2e56Smrg } 2317f7df2e56Smrg wire += XkbPaddedSize(wire - start) - (wire - start); 2318f7df2e56Smrg return (char *) wire; 231905b261ecSmrg} 232005b261ecSmrg 232105b261ecSmrgstatic char * 2322f7df2e56SmrgSetModifierMap(XkbSrvInfoPtr xkbi, 2323f7df2e56Smrg xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 232405b261ecSmrg{ 2325f7df2e56Smrg register unsigned i, first, last; 2326f7df2e56Smrg XkbClientMapPtr xkb = xkbi->desc->map; 2327f7df2e56Smrg CARD8 *start; 232805b261ecSmrg 2329f7df2e56Smrg start = wire; 2330f7df2e56Smrg first = req->firstModMapKey; 2331f7df2e56Smrg last = req->firstModMapKey + req->nModMapKeys - 1; 23326747b715Smrg memset(&xkb->modmap[first], 0, req->nModMapKeys); 2333f7df2e56Smrg for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { 2334f7df2e56Smrg xkb->modmap[wire[0]] = wire[1]; 2335f7df2e56Smrg } 2336f7df2e56Smrg if (first > 0) { 2337f7df2e56Smrg if (changes->map.changed & XkbModifierMapMask) { 2338f7df2e56Smrg int oldLast; 2339f7df2e56Smrg 2340f7df2e56Smrg oldLast = changes->map.first_modmap_key + 2341f7df2e56Smrg changes->map.num_modmap_keys - 1; 2342f7df2e56Smrg if (changes->map.first_modmap_key < first) 2343f7df2e56Smrg first = changes->map.first_modmap_key; 2344f7df2e56Smrg if (oldLast > last) 2345f7df2e56Smrg last = oldLast; 2346f7df2e56Smrg } 2347f7df2e56Smrg changes->map.first_modmap_key = first; 2348f7df2e56Smrg changes->map.num_modmap_keys = (last - first) + 1; 2349f7df2e56Smrg } 2350f7df2e56Smrg wire += XkbPaddedSize(wire - start) - (wire - start); 2351f7df2e56Smrg return (char *) wire; 235205b261ecSmrg} 235305b261ecSmrg 235405b261ecSmrgstatic char * 2355f7df2e56SmrgSetVirtualModMap(XkbSrvInfoPtr xkbi, 2356f7df2e56Smrg xkbSetMapReq * req, 2357f7df2e56Smrg xkbVModMapWireDesc * wire, XkbChangesPtr changes) 235805b261ecSmrg{ 2359f7df2e56Smrg register unsigned i, first, last; 2360f7df2e56Smrg XkbServerMapPtr srv = xkbi->desc->server; 2361f7df2e56Smrg 2362f7df2e56Smrg first = req->firstVModMapKey; 2363f7df2e56Smrg last = req->firstVModMapKey + req->nVModMapKeys - 1; 2364f7df2e56Smrg memset(&srv->vmodmap[first], 0, req->nVModMapKeys * sizeof(unsigned short)); 2365f7df2e56Smrg for (i = 0; i < req->totalVModMapKeys; i++, wire++) { 2366f7df2e56Smrg srv->vmodmap[wire->key] = wire->vmods; 2367f7df2e56Smrg } 2368f7df2e56Smrg if (first > 0) { 2369f7df2e56Smrg if (changes->map.changed & XkbVirtualModMapMask) { 2370f7df2e56Smrg int oldLast; 2371f7df2e56Smrg 2372f7df2e56Smrg oldLast = changes->map.first_vmodmap_key + 2373f7df2e56Smrg changes->map.num_vmodmap_keys - 1; 2374f7df2e56Smrg if (changes->map.first_vmodmap_key < first) 2375f7df2e56Smrg first = changes->map.first_vmodmap_key; 2376f7df2e56Smrg if (oldLast > last) 2377f7df2e56Smrg last = oldLast; 2378f7df2e56Smrg } 2379f7df2e56Smrg changes->map.first_vmodmap_key = first; 2380f7df2e56Smrg changes->map.num_vmodmap_keys = (last - first) + 1; 2381f7df2e56Smrg } 2382f7df2e56Smrg return (char *) wire; 238305b261ecSmrg} 238405b261ecSmrg 2385806e81e9Smrg#define _add_check_len(new) \ 2386806e81e9Smrg if (len > UINT32_MAX - (new) || len > req_len - (new)) goto bad; \ 2387806e81e9Smrg else len += new 2388806e81e9Smrg 2389806e81e9Smrg/** 2390806e81e9Smrg * Check the length of the SetMap request 2391806e81e9Smrg */ 2392806e81e9Smrgstatic int 2393806e81e9Smrg_XkbSetMapCheckLength(xkbSetMapReq *req) 2394806e81e9Smrg{ 2395806e81e9Smrg size_t len = sz_xkbSetMapReq, req_len = req->length << 2; 2396806e81e9Smrg xkbKeyTypeWireDesc *keytype; 2397806e81e9Smrg xkbSymMapWireDesc *symmap; 2398806e81e9Smrg BOOL preserve; 2399806e81e9Smrg int i, map_count, nSyms; 2400806e81e9Smrg 2401806e81e9Smrg if (req_len < len) 2402806e81e9Smrg goto bad; 2403806e81e9Smrg /* types */ 2404806e81e9Smrg if (req->present & XkbKeyTypesMask) { 2405806e81e9Smrg keytype = (xkbKeyTypeWireDesc *)(req + 1); 2406806e81e9Smrg for (i = 0; i < req->nTypes; i++) { 2407806e81e9Smrg _add_check_len(XkbPaddedSize(sz_xkbKeyTypeWireDesc)); 24085a112b11Smrg _add_check_len(keytype->nMapEntries 24095a112b11Smrg * sz_xkbKTSetMapEntryWireDesc); 24105a112b11Smrg preserve = keytype->preserve; 24115a112b11Smrg map_count = keytype->nMapEntries; 24125a112b11Smrg if (preserve) { 24135a112b11Smrg _add_check_len(map_count * sz_xkbModsWireDesc); 2414806e81e9Smrg } 24155a112b11Smrg keytype += 1; 24165a112b11Smrg keytype = (xkbKeyTypeWireDesc *) 24175a112b11Smrg ((xkbKTSetMapEntryWireDesc *)keytype + map_count); 24185a112b11Smrg if (preserve) 24195a112b11Smrg keytype = (xkbKeyTypeWireDesc *) 24205a112b11Smrg ((xkbModsWireDesc *)keytype + map_count); 2421806e81e9Smrg } 2422806e81e9Smrg } 2423806e81e9Smrg /* syms */ 2424806e81e9Smrg if (req->present & XkbKeySymsMask) { 2425806e81e9Smrg symmap = (xkbSymMapWireDesc *)((char *)req + len); 2426806e81e9Smrg for (i = 0; i < req->nKeySyms; i++) { 2427806e81e9Smrg _add_check_len(sz_xkbSymMapWireDesc); 2428806e81e9Smrg nSyms = symmap->nSyms; 2429806e81e9Smrg _add_check_len(nSyms*sizeof(CARD32)); 2430806e81e9Smrg symmap += 1; 2431806e81e9Smrg symmap = (xkbSymMapWireDesc *)((CARD32 *)symmap + nSyms); 2432806e81e9Smrg } 2433806e81e9Smrg } 2434806e81e9Smrg /* actions */ 2435806e81e9Smrg if (req->present & XkbKeyActionsMask) { 2436806e81e9Smrg _add_check_len(req->totalActs * sz_xkbActionWireDesc 2437806e81e9Smrg + XkbPaddedSize(req->nKeyActs)); 2438806e81e9Smrg } 2439806e81e9Smrg /* behaviours */ 2440806e81e9Smrg if (req->present & XkbKeyBehaviorsMask) { 2441806e81e9Smrg _add_check_len(req->totalKeyBehaviors * sz_xkbBehaviorWireDesc); 2442806e81e9Smrg } 2443806e81e9Smrg /* vmods */ 2444806e81e9Smrg if (req->present & XkbVirtualModsMask) { 2445806e81e9Smrg _add_check_len(XkbPaddedSize(Ones(req->virtualMods))); 2446806e81e9Smrg } 2447806e81e9Smrg /* explicit */ 2448806e81e9Smrg if (req->present & XkbExplicitComponentsMask) { 2449806e81e9Smrg /* two bytes per non-zero explicit componen */ 2450806e81e9Smrg _add_check_len(XkbPaddedSize(req->totalKeyExplicit * sizeof(CARD16))); 2451806e81e9Smrg } 2452806e81e9Smrg /* modmap */ 2453806e81e9Smrg if (req->present & XkbModifierMapMask) { 2454806e81e9Smrg /* two bytes per non-zero modmap component */ 2455806e81e9Smrg _add_check_len(XkbPaddedSize(req->totalModMapKeys * sizeof(CARD16))); 2456806e81e9Smrg } 2457806e81e9Smrg /* vmodmap */ 2458806e81e9Smrg if (req->present & XkbVirtualModMapMask) { 2459806e81e9Smrg _add_check_len(req->totalVModMapKeys * sz_xkbVModMapWireDesc); 2460806e81e9Smrg } 2461806e81e9Smrg if (len == req_len) 2462806e81e9Smrg return Success; 2463806e81e9Smrgbad: 2464806e81e9Smrg ErrorF("[xkb] BOGUS LENGTH in SetMap: expected %ld got %ld\n", 2465806e81e9Smrg len, req_len); 2466806e81e9Smrg return BadLength; 2467806e81e9Smrg} 2468806e81e9Smrg 2469806e81e9Smrg 24704642e01fSmrg/** 24714642e01fSmrg * Check if the given request can be applied to the given device but don't 24725a112b11Smrg * actually do anything, except swap values when client->swapped and doswap are both true. 24734642e01fSmrg */ 24744642e01fSmrgstatic int 2475f7df2e56Smrg_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, 24765a112b11Smrg char *values, Bool doswap) 247705b261ecSmrg{ 2478f7df2e56Smrg XkbSrvInfoPtr xkbi; 2479f7df2e56Smrg XkbDescPtr xkb; 2480f7df2e56Smrg int error; 2481f7df2e56Smrg int nTypes = 0, nActions; 2482f7df2e56Smrg CARD8 mapWidths[XkbMaxLegalKeyCode + 1] = { 0 }; 2483f7df2e56Smrg CARD16 symsPerKey[XkbMaxLegalKeyCode + 1] = { 0 }; 2484f7df2e56Smrg XkbSymMapPtr map; 2485f7df2e56Smrg int i; 2486f7df2e56Smrg 24874e185dc0Smrg if (!dev->key) 24884e185dc0Smrg return 0; 24894e185dc0Smrg 2490f7df2e56Smrg xkbi = dev->key->xkbInfo; 249105b261ecSmrg xkb = xkbi->desc; 249205b261ecSmrg 2493f7df2e56Smrg if ((xkb->min_key_code != req->minKeyCode) || 24944642e01fSmrg (xkb->max_key_code != req->maxKeyCode)) { 24957e31ba66Smrg if (client->xkbClientFlags & _XkbClientIsAncient) { 24967e31ba66Smrg /* pre 1.0 versions of Xlib have a bug */ 2497f7df2e56Smrg req->minKeyCode = xkb->min_key_code; 2498f7df2e56Smrg req->maxKeyCode = xkb->max_key_code; 2499f7df2e56Smrg } 2500f7df2e56Smrg else { 2501f7df2e56Smrg if (!XkbIsLegalKeycode(req->minKeyCode)) { 2502f7df2e56Smrg client->errorValue = 2503f7df2e56Smrg _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); 2504f7df2e56Smrg return BadValue; 2505f7df2e56Smrg } 2506f7df2e56Smrg if (req->minKeyCode > req->maxKeyCode) { 2507f7df2e56Smrg client->errorValue = 2508f7df2e56Smrg _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); 2509f7df2e56Smrg return BadMatch; 2510f7df2e56Smrg } 2511f7df2e56Smrg } 251205b261ecSmrg } 251305b261ecSmrg 25145a112b11Smrg if (!(req->present & XkbKeyTypesMask)) { 25155a112b11Smrg nTypes = xkb->map->num_types; 25165a112b11Smrg } 25175a112b11Smrg else if (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values, 25185a112b11Smrg &nTypes, mapWidths, doswap)) { 25195a112b11Smrg client->errorValue = nTypes; 25205a112b11Smrg return BadValue; 252105b261ecSmrg } 25229ace9065Smrg 25239ace9065Smrg /* symsPerKey/mapWidths must be filled regardless of client-side flags */ 25249ace9065Smrg map = &xkb->map->key_sym_map[xkb->min_key_code]; 2525f7df2e56Smrg for (i = xkb->min_key_code; i < xkb->max_key_code; i++, map++) { 2526f7df2e56Smrg register int g, ng, w; 2527f7df2e56Smrg 2528f7df2e56Smrg ng = XkbNumGroups(map->group_info); 2529f7df2e56Smrg for (w = g = 0; g < ng; g++) { 2530f7df2e56Smrg if (map->kt_index[g] >= (unsigned) nTypes) { 2531f7df2e56Smrg client->errorValue = _XkbErrCode4(0x13, i, g, map->kt_index[g]); 25325a112b11Smrg return BadValue; 2533f7df2e56Smrg } 2534f7df2e56Smrg if (mapWidths[map->kt_index[g]] > w) 2535f7df2e56Smrg w = mapWidths[map->kt_index[g]]; 2536f7df2e56Smrg } 2537f7df2e56Smrg symsPerKey[i] = w * ng; 25389ace9065Smrg } 25399ace9065Smrg 25404642e01fSmrg if ((req->present & XkbKeySymsMask) && 2541f7df2e56Smrg (!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey, 25425a112b11Smrg (xkbSymMapWireDesc **) &values, &error, doswap))) { 2543f7df2e56Smrg client->errorValue = error; 2544f7df2e56Smrg return BadValue; 254505b261ecSmrg } 254605b261ecSmrg 25474642e01fSmrg if ((req->present & XkbKeyActionsMask) && 2548f7df2e56Smrg (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey, 2549f7df2e56Smrg (CARD8 **) &values, &nActions))) { 2550f7df2e56Smrg client->errorValue = nActions; 2551f7df2e56Smrg return BadValue; 255205b261ecSmrg } 255305b261ecSmrg 25544642e01fSmrg if ((req->present & XkbKeyBehaviorsMask) && 2555f7df2e56Smrg (!CheckKeyBehaviors 2556f7df2e56Smrg (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) { 2557f7df2e56Smrg client->errorValue = error; 2558f7df2e56Smrg return BadValue; 255905b261ecSmrg } 256005b261ecSmrg 25614642e01fSmrg if ((req->present & XkbVirtualModsMask) && 2562f7df2e56Smrg (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) { 2563f7df2e56Smrg client->errorValue = error; 2564f7df2e56Smrg return BadValue; 256505b261ecSmrg } 2566f7df2e56Smrg if ((req->present & XkbExplicitComponentsMask) && 2567f7df2e56Smrg (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) { 2568f7df2e56Smrg client->errorValue = error; 2569f7df2e56Smrg return BadValue; 257005b261ecSmrg } 2571f7df2e56Smrg if ((req->present & XkbModifierMapMask) && 2572f7df2e56Smrg (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) { 2573f7df2e56Smrg client->errorValue = error; 2574f7df2e56Smrg return BadValue; 257505b261ecSmrg } 2576f7df2e56Smrg if ((req->present & XkbVirtualModMapMask) && 2577f7df2e56Smrg (!CheckVirtualModMap 2578f7df2e56Smrg (xkb, req, (xkbVModMapWireDesc **) &values, &error))) { 2579f7df2e56Smrg client->errorValue = error; 2580f7df2e56Smrg return BadValue; 258105b261ecSmrg } 25824642e01fSmrg 2583f7df2e56Smrg if (((values - ((char *) req)) / 4) != req->length) { 2584f7df2e56Smrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); 2585f7df2e56Smrg client->errorValue = values - ((char *) &req[1]); 2586f7df2e56Smrg return BadLength; 258705b261ecSmrg } 25884642e01fSmrg 25894642e01fSmrg return Success; 25904642e01fSmrg} 25914642e01fSmrg 25924642e01fSmrg/** 25934642e01fSmrg * Apply the given request on the given device. 25944642e01fSmrg */ 25954642e01fSmrgstatic int 2596f7df2e56Smrg_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values) 25974642e01fSmrg{ 2598f7df2e56Smrg XkbEventCauseRec cause; 2599f7df2e56Smrg XkbChangesRec change; 2600f7df2e56Smrg Bool sentNKN; 2601f7df2e56Smrg XkbSrvInfoPtr xkbi; 2602f7df2e56Smrg XkbDescPtr xkb; 26034642e01fSmrg 26044e185dc0Smrg if (!dev->key) 26054e185dc0Smrg return Success; 26064e185dc0Smrg 2607f7df2e56Smrg xkbi = dev->key->xkbInfo; 26084642e01fSmrg xkb = xkbi->desc; 26094642e01fSmrg 2610f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbSetMap, client); 26116747b715Smrg memset(&change, 0, sizeof(change)); 26126747b715Smrg sentNKN = FALSE; 2613f7df2e56Smrg if ((xkb->min_key_code != req->minKeyCode) || 2614f7df2e56Smrg (xkb->max_key_code != req->maxKeyCode)) { 2615f7df2e56Smrg Status status; 2616f7df2e56Smrg xkbNewKeyboardNotify nkn; 2617f7df2e56Smrg 2618f7df2e56Smrg nkn.deviceID = nkn.oldDeviceID = dev->id; 2619f7df2e56Smrg nkn.oldMinKeyCode = xkb->min_key_code; 2620f7df2e56Smrg nkn.oldMaxKeyCode = xkb->max_key_code; 2621f7df2e56Smrg status = XkbChangeKeycodeRange(xkb, req->minKeyCode, 2622f7df2e56Smrg req->maxKeyCode, &change); 2623f7df2e56Smrg if (status != Success) 2624f7df2e56Smrg return status; /* oh-oh. what about the other keyboards? */ 2625f7df2e56Smrg nkn.minKeyCode = xkb->min_key_code; 2626f7df2e56Smrg nkn.maxKeyCode = xkb->max_key_code; 2627f7df2e56Smrg nkn.requestMajor = XkbReqCode; 2628f7df2e56Smrg nkn.requestMinor = X_kbSetMap; 2629f7df2e56Smrg nkn.changed = XkbNKN_KeycodesMask; 2630f7df2e56Smrg XkbSendNewKeyboardNotify(dev, &nkn); 2631f7df2e56Smrg sentNKN = TRUE; 2632f7df2e56Smrg } 2633f7df2e56Smrg 2634f7df2e56Smrg if (req->present & XkbKeyTypesMask) { 2635f7df2e56Smrg values = SetKeyTypes(xkb, req, (xkbKeyTypeWireDesc *) values, &change); 2636f7df2e56Smrg if (!values) 2637f7df2e56Smrg goto allocFailure; 2638f7df2e56Smrg } 2639f7df2e56Smrg if (req->present & XkbKeySymsMask) { 2640f7df2e56Smrg values = 2641f7df2e56Smrg SetKeySyms(client, xkb, req, (xkbSymMapWireDesc *) values, &change, 2642f7df2e56Smrg dev); 2643f7df2e56Smrg if (!values) 2644f7df2e56Smrg goto allocFailure; 2645f7df2e56Smrg } 2646f7df2e56Smrg if (req->present & XkbKeyActionsMask) { 2647f7df2e56Smrg values = SetKeyActions(xkb, req, (CARD8 *) values, &change); 2648f7df2e56Smrg if (!values) 2649f7df2e56Smrg goto allocFailure; 2650f7df2e56Smrg } 2651f7df2e56Smrg if (req->present & XkbKeyBehaviorsMask) { 2652f7df2e56Smrg values = 2653f7df2e56Smrg SetKeyBehaviors(xkbi, req, (xkbBehaviorWireDesc *) values, &change); 2654f7df2e56Smrg if (!values) 2655f7df2e56Smrg goto allocFailure; 2656f7df2e56Smrg } 2657f7df2e56Smrg if (req->present & XkbVirtualModsMask) 2658f7df2e56Smrg values = SetVirtualMods(xkbi, req, (CARD8 *) values, &change); 2659f7df2e56Smrg if (req->present & XkbExplicitComponentsMask) 2660f7df2e56Smrg values = SetKeyExplicit(xkbi, req, (CARD8 *) values, &change); 2661f7df2e56Smrg if (req->present & XkbModifierMapMask) 2662f7df2e56Smrg values = SetModifierMap(xkbi, req, (CARD8 *) values, &change); 2663f7df2e56Smrg if (req->present & XkbVirtualModMapMask) 2664f7df2e56Smrg values = 2665f7df2e56Smrg SetVirtualModMap(xkbi, req, (xkbVModMapWireDesc *) values, &change); 2666f7df2e56Smrg if (((values - ((char *) req)) / 4) != req->length) { 2667f7df2e56Smrg ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); 2668f7df2e56Smrg client->errorValue = values - ((char *) &req[1]); 2669f7df2e56Smrg return BadLength; 2670f7df2e56Smrg } 2671f7df2e56Smrg if (req->flags & XkbSetMapRecomputeActions) { 2672f7df2e56Smrg KeyCode first, last, firstMM, lastMM; 2673f7df2e56Smrg 2674f7df2e56Smrg if (change.map.num_key_syms > 0) { 2675f7df2e56Smrg first = change.map.first_key_sym; 2676f7df2e56Smrg last = first + change.map.num_key_syms - 1; 2677f7df2e56Smrg } 2678f7df2e56Smrg else 2679f7df2e56Smrg first = last = 0; 2680f7df2e56Smrg if (change.map.num_modmap_keys > 0) { 2681f7df2e56Smrg firstMM = change.map.first_modmap_key; 26827e31ba66Smrg lastMM = firstMM + change.map.num_modmap_keys - 1; 2683f7df2e56Smrg } 2684f7df2e56Smrg else 2685f7df2e56Smrg firstMM = lastMM = 0; 2686f7df2e56Smrg if ((last > 0) && (lastMM > 0)) { 2687f7df2e56Smrg if (firstMM < first) 2688f7df2e56Smrg first = firstMM; 2689f7df2e56Smrg if (lastMM > last) 2690f7df2e56Smrg last = lastMM; 2691f7df2e56Smrg } 2692f7df2e56Smrg else if (lastMM > 0) { 2693f7df2e56Smrg first = firstMM; 2694f7df2e56Smrg last = lastMM; 2695f7df2e56Smrg } 2696f7df2e56Smrg if (last > 0) { 2697f7df2e56Smrg unsigned check = 0; 2698f7df2e56Smrg 2699f7df2e56Smrg XkbUpdateActions(dev, first, (last - first + 1), &change, &check, 2700f7df2e56Smrg &cause); 2701f7df2e56Smrg if (check) 2702f7df2e56Smrg XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 2703f7df2e56Smrg } 270405b261ecSmrg } 270505b261ecSmrg if (!sentNKN) 2706f7df2e56Smrg XkbSendNotification(dev, &change, &cause); 270705b261ecSmrg 27084642e01fSmrg return Success; 2709f7df2e56Smrg allocFailure: 271005b261ecSmrg return BadAlloc; 271105b261ecSmrg} 271205b261ecSmrg 27134642e01fSmrgint 27144642e01fSmrgProcXkbSetMap(ClientPtr client) 27154642e01fSmrg{ 27165a112b11Smrg DeviceIntPtr dev, master; 2717f7df2e56Smrg char *tmp; 2718f7df2e56Smrg int rc; 27194642e01fSmrg 27204642e01fSmrg REQUEST(xkbSetMapReq); 27214642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 27224642e01fSmrg 2723f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 2724f7df2e56Smrg return BadAccess; 27254642e01fSmrg 27264642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 2727f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->present, XkbAllMapComponentsMask); 27284642e01fSmrg 2729806e81e9Smrg /* first verify the request length carefully */ 2730806e81e9Smrg rc = _XkbSetMapCheckLength(stuff); 2731806e81e9Smrg if (rc != Success) 2732806e81e9Smrg return rc; 2733806e81e9Smrg 2734f7df2e56Smrg tmp = (char *) &stuff[1]; 27354642e01fSmrg 27364642e01fSmrg /* Check if we can to the SetMap on the requested device. If this 27374642e01fSmrg succeeds, do the same thing for all extension devices (if needed). 27384642e01fSmrg If any of them fails, fail. */ 27395a112b11Smrg rc = _XkbSetMapChecks(client, dev, stuff, tmp, TRUE); 27404642e01fSmrg 27414642e01fSmrg if (rc != Success) 27424642e01fSmrg return rc; 27434642e01fSmrg 27445a112b11Smrg master = GetMaster(dev, MASTER_KEYBOARD); 27457e31ba66Smrg 2746f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 27474642e01fSmrg DeviceIntPtr other; 2748f7df2e56Smrg 2749f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 2750f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 2751f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 2752f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2753f7df2e56Smrg DixManageAccess); 2754f7df2e56Smrg if (rc == Success) { 27555a112b11Smrg rc = _XkbSetMapChecks(client, other, stuff, tmp, FALSE); 27564642e01fSmrg if (rc != Success) 27574642e01fSmrg return rc; 27584642e01fSmrg } 27594642e01fSmrg } 27604642e01fSmrg } 27617e31ba66Smrg } else { 27627e31ba66Smrg DeviceIntPtr other; 27637e31ba66Smrg 27647e31ba66Smrg for (other = inputInfo.devices; other; other = other->next) { 27657e31ba66Smrg if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 27667e31ba66Smrg (other != master || dev != master->lastSlave)) 27677e31ba66Smrg continue; 27687e31ba66Smrg 27695a112b11Smrg rc = _XkbSetMapChecks(client, other, stuff, tmp, FALSE); 27707e31ba66Smrg if (rc != Success) 27717e31ba66Smrg return rc; 27727e31ba66Smrg } 27734642e01fSmrg } 27744642e01fSmrg 27757e31ba66Smrg /* We know now that we will succeed with the SetMap. In theory anyway. */ 27764642e01fSmrg rc = _XkbSetMap(client, dev, stuff, tmp); 27774642e01fSmrg if (rc != Success) 27784642e01fSmrg return rc; 27794642e01fSmrg 2780f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 27814642e01fSmrg DeviceIntPtr other; 2782f7df2e56Smrg 2783f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 2784f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 2785f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 2786f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2787f7df2e56Smrg DixManageAccess); 27884642e01fSmrg if (rc == Success) 27894642e01fSmrg _XkbSetMap(client, other, stuff, tmp); 27904642e01fSmrg /* ignore rc. if the SetMap failed although the check above 27914642e01fSmrg reported true there isn't much we can do. we still need to 27924642e01fSmrg set all other devices, hoping that at least they stay in 27934642e01fSmrg sync. */ 27944642e01fSmrg } 27954642e01fSmrg } 27967e31ba66Smrg } else { 27977e31ba66Smrg DeviceIntPtr other; 27987e31ba66Smrg 27997e31ba66Smrg for (other = inputInfo.devices; other; other = other->next) { 28007e31ba66Smrg if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 28017e31ba66Smrg (other != master || dev != master->lastSlave)) 28027e31ba66Smrg continue; 28037e31ba66Smrg 28047e31ba66Smrg _XkbSetMap(client, other, stuff, tmp); //ignore rc 28057e31ba66Smrg } 28064642e01fSmrg } 28074642e01fSmrg 28086747b715Smrg return Success; 28094642e01fSmrg} 28104642e01fSmrg 281105b261ecSmrg/***====================================================================***/ 281205b261ecSmrg 281305b261ecSmrgstatic Status 2814f7df2e56SmrgXkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat, 2815f7df2e56Smrg xkbGetCompatMapReply * rep) 281605b261ecSmrg{ 2817f7df2e56Smrg unsigned size, nGroups; 2818f7df2e56Smrg 2819f7df2e56Smrg nGroups = 0; 2820f7df2e56Smrg if (rep->groups != 0) { 2821f7df2e56Smrg register int i, bit; 2822f7df2e56Smrg 2823f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2824f7df2e56Smrg if (rep->groups & bit) 2825f7df2e56Smrg nGroups++; 2826f7df2e56Smrg } 2827f7df2e56Smrg } 2828f7df2e56Smrg size = nGroups * SIZEOF(xkbModsWireDesc); 2829f7df2e56Smrg size += (rep->nSI * SIZEOF(xkbSymInterpretWireDesc)); 2830f7df2e56Smrg rep->length = size / 4; 283105b261ecSmrg return Success; 283205b261ecSmrg} 283305b261ecSmrg 283405b261ecSmrgstatic int 2835f7df2e56SmrgXkbSendCompatMap(ClientPtr client, 2836f7df2e56Smrg XkbCompatMapPtr compat, xkbGetCompatMapReply * rep) 283705b261ecSmrg{ 2838f7df2e56Smrg char *data; 2839f7df2e56Smrg int size; 2840f7df2e56Smrg 2841f7df2e56Smrg if (rep->length > 0) { 2842f7df2e56Smrg data = xallocarray(rep->length, 4); 2843f7df2e56Smrg if (data) { 2844f7df2e56Smrg register unsigned i, bit; 2845f7df2e56Smrg xkbModsWireDesc *grp; 2846f7df2e56Smrg XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI]; 2847f7df2e56Smrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2848f7df2e56Smrg 2849f7df2e56Smrg size = rep->length * 4; 2850f7df2e56Smrg 2851f7df2e56Smrg for (i = 0; i < rep->nSI; i++, sym++, wire++) { 2852f7df2e56Smrg wire->sym = sym->sym; 2853f7df2e56Smrg wire->mods = sym->mods; 2854f7df2e56Smrg wire->match = sym->match; 2855f7df2e56Smrg wire->virtualMod = sym->virtual_mod; 2856f7df2e56Smrg wire->flags = sym->flags; 2857f7df2e56Smrg memcpy((char *) &wire->act, (char *) &sym->act, 2858f7df2e56Smrg sz_xkbActionWireDesc); 2859f7df2e56Smrg if (client->swapped) { 2860f7df2e56Smrg swapl(&wire->sym); 2861f7df2e56Smrg } 2862f7df2e56Smrg } 2863f7df2e56Smrg if (rep->groups) { 2864f7df2e56Smrg grp = (xkbModsWireDesc *) wire; 2865f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2866f7df2e56Smrg if (rep->groups & bit) { 2867f7df2e56Smrg grp->mask = compat->groups[i].mask; 2868f7df2e56Smrg grp->realMods = compat->groups[i].real_mods; 2869f7df2e56Smrg grp->virtualMods = compat->groups[i].vmods; 2870f7df2e56Smrg if (client->swapped) { 2871f7df2e56Smrg swaps(&grp->virtualMods); 2872f7df2e56Smrg } 2873f7df2e56Smrg grp++; 2874f7df2e56Smrg } 2875f7df2e56Smrg } 2876f7df2e56Smrg wire = (xkbSymInterpretWireDesc *) grp; 2877f7df2e56Smrg } 2878f7df2e56Smrg } 2879f7df2e56Smrg else 2880f7df2e56Smrg return BadAlloc; 2881f7df2e56Smrg } 2882f7df2e56Smrg else 2883f7df2e56Smrg data = NULL; 288405b261ecSmrg 288505b261ecSmrg if (client->swapped) { 2886f7df2e56Smrg swaps(&rep->sequenceNumber); 2887f7df2e56Smrg swapl(&rep->length); 2888f7df2e56Smrg swaps(&rep->firstSI); 2889f7df2e56Smrg swaps(&rep->nSI); 2890f7df2e56Smrg swaps(&rep->nTotalSI); 289105b261ecSmrg } 289205b261ecSmrg 2893f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetCompatMapReply), rep); 289405b261ecSmrg if (data) { 2895f7df2e56Smrg WriteToClient(client, size, data); 2896f7df2e56Smrg free((char *) data); 289705b261ecSmrg } 28986747b715Smrg return Success; 289905b261ecSmrg} 290005b261ecSmrg 290105b261ecSmrgint 290205b261ecSmrgProcXkbGetCompatMap(ClientPtr client) 290305b261ecSmrg{ 2904f7df2e56Smrg xkbGetCompatMapReply rep; 2905f7df2e56Smrg DeviceIntPtr dev; 2906f7df2e56Smrg XkbDescPtr xkb; 2907f7df2e56Smrg XkbCompatMapPtr compat; 290805b261ecSmrg 290905b261ecSmrg REQUEST(xkbGetCompatMapReq); 291005b261ecSmrg REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 291105b261ecSmrg 2912f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 2913f7df2e56Smrg return BadAccess; 291405b261ecSmrg 29154642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 291605b261ecSmrg 291705b261ecSmrg xkb = dev->key->xkbInfo->desc; 2918f7df2e56Smrg compat = xkb->compat; 291905b261ecSmrg 2920f7df2e56Smrg rep = (xkbGetCompatMapReply) { 2921f7df2e56Smrg .type = X_Reply, 2922f7df2e56Smrg .sequenceNumber = client->sequence, 2923f7df2e56Smrg .length = 0, 2924f7df2e56Smrg .deviceID = dev->id, 2925f7df2e56Smrg .firstSI = stuff->firstSI, 2926f7df2e56Smrg .nSI = stuff->nSI 2927f7df2e56Smrg }; 292805b261ecSmrg if (stuff->getAllSI) { 2929f7df2e56Smrg rep.firstSI = 0; 2930f7df2e56Smrg rep.nSI = compat->num_si; 293105b261ecSmrg } 2932f7df2e56Smrg else if ((((unsigned) stuff->nSI) > 0) && 2933f7df2e56Smrg ((unsigned) (stuff->firstSI + stuff->nSI - 1) >= compat->num_si)) { 2934f7df2e56Smrg client->errorValue = _XkbErrCode2(0x05, compat->num_si); 2935f7df2e56Smrg return BadValue; 293605b261ecSmrg } 293705b261ecSmrg rep.nTotalSI = compat->num_si; 2938f7df2e56Smrg rep.groups = stuff->groups; 2939f7df2e56Smrg XkbComputeGetCompatMapReplySize(compat, &rep); 2940f7df2e56Smrg return XkbSendCompatMap(client, compat, &rep); 294105b261ecSmrg} 294205b261ecSmrg 29434642e01fSmrg/** 29444642e01fSmrg * Apply the given request on the given device. 29456747b715Smrg * If dryRun is TRUE, then value checks are performed, but the device isn't 29464642e01fSmrg * modified. 29474642e01fSmrg */ 29484642e01fSmrgstatic int 29494642e01fSmrg_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, 2950f7df2e56Smrg xkbSetCompatMapReq * req, char *data, BOOL dryRun) 295105b261ecSmrg{ 2952f7df2e56Smrg XkbSrvInfoPtr xkbi; 2953f7df2e56Smrg XkbDescPtr xkb; 2954f7df2e56Smrg XkbCompatMapPtr compat; 2955f7df2e56Smrg int nGroups; 2956f7df2e56Smrg unsigned i, bit; 295705b261ecSmrg 295805b261ecSmrg xkbi = dev->key->xkbInfo; 29594642e01fSmrg xkb = xkbi->desc; 29604642e01fSmrg compat = xkb->compat; 29614642e01fSmrg 2962f7df2e56Smrg if ((req->nSI > 0) || (req->truncateSI)) { 2963f7df2e56Smrg xkbSymInterpretWireDesc *wire; 2964f7df2e56Smrg 2965f7df2e56Smrg if (req->firstSI > compat->num_si) { 2966f7df2e56Smrg client->errorValue = _XkbErrCode2(0x02, compat->num_si); 2967f7df2e56Smrg return BadValue; 2968f7df2e56Smrg } 2969f7df2e56Smrg wire = (xkbSymInterpretWireDesc *) data; 2970f7df2e56Smrg wire += req->nSI; 2971f7df2e56Smrg data = (char *) wire; 297205b261ecSmrg } 29734642e01fSmrg 2974f7df2e56Smrg nGroups = 0; 2975f7df2e56Smrg if (req->groups != 0) { 2976f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2977f7df2e56Smrg if (req->groups & bit) 2978f7df2e56Smrg nGroups++; 2979f7df2e56Smrg } 298005b261ecSmrg } 2981f7df2e56Smrg data += nGroups * SIZEOF(xkbModsWireDesc); 2982f7df2e56Smrg if (((data - ((char *) req)) / 4) != req->length) { 2983f7df2e56Smrg return BadLength; 298405b261ecSmrg } 29854642e01fSmrg 29864642e01fSmrg /* Done all the checks we can do */ 29874642e01fSmrg if (dryRun) 29884642e01fSmrg return Success; 29894642e01fSmrg 2990f7df2e56Smrg data = (char *) &req[1]; 2991f7df2e56Smrg if (req->nSI > 0) { 2992f7df2e56Smrg xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2993f7df2e56Smrg XkbSymInterpretPtr sym; 2994f7df2e56Smrg unsigned int skipped = 0; 2995f7df2e56Smrg 2996f7df2e56Smrg if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) { 2997f7df2e56Smrg compat->num_si = req->firstSI + req->nSI; 2998f7df2e56Smrg compat->sym_interpret = reallocarray(compat->sym_interpret, 2999f7df2e56Smrg compat->num_si, 3000f7df2e56Smrg sizeof(XkbSymInterpretRec)); 3001f7df2e56Smrg if (!compat->sym_interpret) { 3002f7df2e56Smrg compat->num_si = 0; 3003f7df2e56Smrg return BadAlloc; 3004f7df2e56Smrg } 3005f7df2e56Smrg } 3006f7df2e56Smrg else if (req->truncateSI) { 3007f7df2e56Smrg compat->num_si = req->firstSI + req->nSI; 3008f7df2e56Smrg } 3009f7df2e56Smrg sym = &compat->sym_interpret[req->firstSI]; 3010f7df2e56Smrg for (i = 0; i < req->nSI; i++, wire++) { 3011f7df2e56Smrg if (client->swapped) { 3012f7df2e56Smrg swapl(&wire->sym); 3013f7df2e56Smrg } 3014f7df2e56Smrg if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone && 3015f7df2e56Smrg (wire->mods & 0xff) == 0xff && 3016f7df2e56Smrg wire->act.type == XkbSA_XFree86Private) { 3017f7df2e56Smrg ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private " 3018f7df2e56Smrg "action from client\n"); 3019f7df2e56Smrg skipped++; 3020f7df2e56Smrg continue; 3021f7df2e56Smrg } 3022f7df2e56Smrg sym->sym = wire->sym; 3023f7df2e56Smrg sym->mods = wire->mods; 3024f7df2e56Smrg sym->match = wire->match; 3025f7df2e56Smrg sym->flags = wire->flags; 3026f7df2e56Smrg sym->virtual_mod = wire->virtualMod; 3027f7df2e56Smrg memcpy((char *) &sym->act, (char *) &wire->act, 3028f7df2e56Smrg SIZEOF(xkbActionWireDesc)); 3029f7df2e56Smrg sym++; 3030f7df2e56Smrg } 3031f7df2e56Smrg if (skipped) { 3032f7df2e56Smrg if (req->firstSI + req->nSI < compat->num_si) 3033f7df2e56Smrg memmove(sym, sym + skipped, 3034f7df2e56Smrg (compat->num_si - req->firstSI - req->nSI) * 3035f7df2e56Smrg sizeof(*sym)); 3036f7df2e56Smrg compat->num_si -= skipped; 3037f7df2e56Smrg } 3038f7df2e56Smrg data = (char *) wire; 303905b261ecSmrg } 30404642e01fSmrg else if (req->truncateSI) { 3041f7df2e56Smrg compat->num_si = req->firstSI; 3042f7df2e56Smrg } 3043f7df2e56Smrg 3044f7df2e56Smrg if (req->groups != 0) { 3045f7df2e56Smrg xkbModsWireDesc *wire = (xkbModsWireDesc *) data; 3046f7df2e56Smrg 3047f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 3048f7df2e56Smrg if (req->groups & bit) { 3049f7df2e56Smrg if (client->swapped) { 3050f7df2e56Smrg swaps(&wire->virtualMods); 3051f7df2e56Smrg } 3052f7df2e56Smrg compat->groups[i].mask = wire->realMods; 3053f7df2e56Smrg compat->groups[i].real_mods = wire->realMods; 3054f7df2e56Smrg compat->groups[i].vmods = wire->virtualMods; 3055f7df2e56Smrg if (wire->virtualMods != 0) { 3056f7df2e56Smrg unsigned tmp; 3057f7df2e56Smrg 3058f7df2e56Smrg tmp = XkbMaskForVMask(xkb, wire->virtualMods); 3059f7df2e56Smrg compat->groups[i].mask |= tmp; 3060f7df2e56Smrg } 3061f7df2e56Smrg data += SIZEOF(xkbModsWireDesc); 3062f7df2e56Smrg wire = (xkbModsWireDesc *) data; 3063f7df2e56Smrg } 3064f7df2e56Smrg } 3065f7df2e56Smrg } 3066f7df2e56Smrg i = XkbPaddedSize((data - ((char *) req))); 3067f7df2e56Smrg if ((i / 4) != req->length) { 3068f7df2e56Smrg ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); 3069f7df2e56Smrg return BadLength; 307005b261ecSmrg } 30714642e01fSmrg 307205b261ecSmrg if (dev->xkb_interest) { 3073f7df2e56Smrg xkbCompatMapNotify ev; 3074f7df2e56Smrg 3075f7df2e56Smrg ev.deviceID = dev->id; 3076f7df2e56Smrg ev.changedGroups = req->groups; 3077f7df2e56Smrg ev.firstSI = req->firstSI; 3078f7df2e56Smrg ev.nSI = req->nSI; 3079f7df2e56Smrg ev.nTotalSI = compat->num_si; 3080f7df2e56Smrg XkbSendCompatMapNotify(dev, &ev); 308105b261ecSmrg } 308205b261ecSmrg 30834642e01fSmrg if (req->recomputeActions) { 3084f7df2e56Smrg XkbChangesRec change; 3085f7df2e56Smrg unsigned check; 3086f7df2e56Smrg XkbEventCauseRec cause; 3087f7df2e56Smrg 3088f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbSetCompatMap, client); 3089f7df2e56Smrg memset(&change, 0, sizeof(XkbChangesRec)); 3090f7df2e56Smrg XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &change, 3091f7df2e56Smrg &check, &cause); 3092f7df2e56Smrg if (check) 3093f7df2e56Smrg XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 3094f7df2e56Smrg XkbSendNotification(dev, &change, &cause); 309505b261ecSmrg } 30964642e01fSmrg return Success; 30974642e01fSmrg} 30984642e01fSmrg 30994642e01fSmrgint 31004642e01fSmrgProcXkbSetCompatMap(ClientPtr client) 31014642e01fSmrg{ 3102f7df2e56Smrg DeviceIntPtr dev; 3103f7df2e56Smrg char *data; 3104f7df2e56Smrg int rc; 31054642e01fSmrg 31064642e01fSmrg REQUEST(xkbSetCompatMapReq); 31074642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 31084642e01fSmrg 3109f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3110f7df2e56Smrg return BadAccess; 31114642e01fSmrg 31124642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 31134642e01fSmrg 3114f7df2e56Smrg data = (char *) &stuff[1]; 31154642e01fSmrg 31164642e01fSmrg /* check first using a dry-run */ 31174642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); 31184642e01fSmrg if (rc != Success) 31194642e01fSmrg return rc; 3120f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 31214642e01fSmrg DeviceIntPtr other; 3122f7df2e56Smrg 3123f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 3124f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 3125f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 3126f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3127f7df2e56Smrg DixManageAccess); 3128f7df2e56Smrg if (rc == Success) { 31294642e01fSmrg /* dry-run */ 31304642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); 31314642e01fSmrg if (rc != Success) 31324642e01fSmrg return rc; 31334642e01fSmrg } 31344642e01fSmrg } 31354642e01fSmrg } 31364642e01fSmrg } 31374642e01fSmrg 31384642e01fSmrg /* Yay, the dry-runs succeed. Let's apply */ 31394642e01fSmrg rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); 31404642e01fSmrg if (rc != Success) 31414642e01fSmrg return rc; 3142f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 31434642e01fSmrg DeviceIntPtr other; 3144f7df2e56Smrg 3145f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 3146f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 3147f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 3148f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3149f7df2e56Smrg DixManageAccess); 3150f7df2e56Smrg if (rc == Success) { 31514642e01fSmrg rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); 31524642e01fSmrg if (rc != Success) 31534642e01fSmrg return rc; 31544642e01fSmrg } 31554642e01fSmrg } 31564642e01fSmrg } 31574642e01fSmrg } 31584642e01fSmrg 31596747b715Smrg return Success; 316005b261ecSmrg} 316105b261ecSmrg 316205b261ecSmrg/***====================================================================***/ 316305b261ecSmrg 316405b261ecSmrgint 316505b261ecSmrgProcXkbGetIndicatorState(ClientPtr client) 316605b261ecSmrg{ 3167f7df2e56Smrg xkbGetIndicatorStateReply rep; 3168f7df2e56Smrg XkbSrvLedInfoPtr sli; 3169f7df2e56Smrg DeviceIntPtr dev; 317005b261ecSmrg 317105b261ecSmrg REQUEST(xkbGetIndicatorStateReq); 317205b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 317305b261ecSmrg 3174f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3175f7df2e56Smrg return BadAccess; 317605b261ecSmrg 31774642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 317805b261ecSmrg 3179f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3180f7df2e56Smrg XkbXI_IndicatorStateMask); 318105b261ecSmrg if (!sli) 3182f7df2e56Smrg return BadAlloc; 318305b261ecSmrg 3184f7df2e56Smrg rep = (xkbGetIndicatorStateReply) { 3185f7df2e56Smrg .type = X_Reply, 3186f7df2e56Smrg .deviceID = dev->id, 3187f7df2e56Smrg .sequenceNumber = client->sequence, 3188f7df2e56Smrg .length = 0, 3189f7df2e56Smrg .state = sli->effectiveState 3190f7df2e56Smrg }; 319105b261ecSmrg 319205b261ecSmrg if (client->swapped) { 3193f7df2e56Smrg swaps(&rep.sequenceNumber); 3194f7df2e56Smrg swapl(&rep.state); 319505b261ecSmrg } 3196f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), &rep); 31976747b715Smrg return Success; 319805b261ecSmrg} 319905b261ecSmrg 320005b261ecSmrg/***====================================================================***/ 320105b261ecSmrg 320205b261ecSmrgstatic Status 3203f7df2e56SmrgXkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators, 3204f7df2e56Smrg xkbGetIndicatorMapReply * rep) 320505b261ecSmrg{ 3206f7df2e56Smrg register int i, bit; 3207f7df2e56Smrg int nIndicators; 320805b261ecSmrg 320905b261ecSmrg rep->realIndicators = indicators->phys_indicators; 3210f7df2e56Smrg for (i = nIndicators = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3211f7df2e56Smrg if (rep->which & bit) 3212f7df2e56Smrg nIndicators++; 321305b261ecSmrg } 3214f7df2e56Smrg rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4; 3215f7df2e56Smrg rep->nIndicators = nIndicators; 321605b261ecSmrg return Success; 321705b261ecSmrg} 321805b261ecSmrg 321905b261ecSmrgstatic int 3220f7df2e56SmrgXkbSendIndicatorMap(ClientPtr client, 3221f7df2e56Smrg XkbIndicatorPtr indicators, xkbGetIndicatorMapReply * rep) 322205b261ecSmrg{ 3223f7df2e56Smrg int length; 3224f7df2e56Smrg CARD8 *map; 3225f7df2e56Smrg register int i; 3226f7df2e56Smrg register unsigned bit; 3227f7df2e56Smrg 3228f7df2e56Smrg if (rep->length > 0) { 3229f7df2e56Smrg CARD8 *to; 3230f7df2e56Smrg 3231f7df2e56Smrg to = map = xallocarray(rep->length, 4); 3232f7df2e56Smrg if (map) { 3233f7df2e56Smrg xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to; 3234f7df2e56Smrg 3235f7df2e56Smrg length = rep->length * 4; 3236f7df2e56Smrg 3237f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3238f7df2e56Smrg if (rep->which & bit) { 3239f7df2e56Smrg wire->flags = indicators->maps[i].flags; 3240f7df2e56Smrg wire->whichGroups = indicators->maps[i].which_groups; 3241f7df2e56Smrg wire->groups = indicators->maps[i].groups; 3242f7df2e56Smrg wire->whichMods = indicators->maps[i].which_mods; 3243f7df2e56Smrg wire->mods = indicators->maps[i].mods.mask; 3244f7df2e56Smrg wire->realMods = indicators->maps[i].mods.real_mods; 3245f7df2e56Smrg wire->virtualMods = indicators->maps[i].mods.vmods; 3246f7df2e56Smrg wire->ctrls = indicators->maps[i].ctrls; 3247f7df2e56Smrg if (client->swapped) { 3248f7df2e56Smrg swaps(&wire->virtualMods); 3249f7df2e56Smrg swapl(&wire->ctrls); 3250f7df2e56Smrg } 3251f7df2e56Smrg wire++; 3252f7df2e56Smrg } 3253f7df2e56Smrg } 3254f7df2e56Smrg to = (CARD8 *) wire; 3255f7df2e56Smrg if ((to - map) != length) { 3256f7df2e56Smrg client->errorValue = _XkbErrCode2(0xff, length); 3257f7df2e56Smrg free(map); 3258f7df2e56Smrg return BadLength; 3259f7df2e56Smrg } 3260f7df2e56Smrg } 3261f7df2e56Smrg else 3262f7df2e56Smrg return BadAlloc; 3263f7df2e56Smrg } 3264f7df2e56Smrg else 3265f7df2e56Smrg map = NULL; 326605b261ecSmrg if (client->swapped) { 3267f7df2e56Smrg swaps(&rep->sequenceNumber); 3268f7df2e56Smrg swapl(&rep->length); 3269f7df2e56Smrg swapl(&rep->which); 3270f7df2e56Smrg swapl(&rep->realIndicators); 327105b261ecSmrg } 3272f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), rep); 327305b261ecSmrg if (map) { 3274f7df2e56Smrg WriteToClient(client, length, map); 3275f7df2e56Smrg free((char *) map); 327605b261ecSmrg } 32776747b715Smrg return Success; 327805b261ecSmrg} 327905b261ecSmrg 328005b261ecSmrgint 328105b261ecSmrgProcXkbGetIndicatorMap(ClientPtr client) 328205b261ecSmrg{ 3283f7df2e56Smrg xkbGetIndicatorMapReply rep; 3284f7df2e56Smrg DeviceIntPtr dev; 3285f7df2e56Smrg XkbDescPtr xkb; 3286f7df2e56Smrg XkbIndicatorPtr leds; 328705b261ecSmrg 328805b261ecSmrg REQUEST(xkbGetIndicatorMapReq); 328905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 329005b261ecSmrg 3291f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3292f7df2e56Smrg return BadAccess; 329305b261ecSmrg 32944642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 329505b261ecSmrg 3296f7df2e56Smrg xkb = dev->key->xkbInfo->desc; 3297f7df2e56Smrg leds = xkb->indicators; 3298f7df2e56Smrg 3299f7df2e56Smrg rep = (xkbGetIndicatorMapReply) { 3300f7df2e56Smrg .type = X_Reply, 3301f7df2e56Smrg .deviceID = dev->id, 3302f7df2e56Smrg .sequenceNumber = client->sequence, 3303f7df2e56Smrg .length = 0, 3304f7df2e56Smrg .which = stuff->which 3305f7df2e56Smrg }; 3306f7df2e56Smrg XkbComputeGetIndicatorMapReplySize(leds, &rep); 3307f7df2e56Smrg return XkbSendIndicatorMap(client, leds, &rep); 330805b261ecSmrg} 330905b261ecSmrg 33104642e01fSmrg/** 33114642e01fSmrg * Apply the given map to the given device. Which specifies which components 33124642e01fSmrg * to apply. 33134642e01fSmrg */ 33144642e01fSmrgstatic int 33154642e01fSmrg_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, 3316f7df2e56Smrg int which, xkbIndicatorMapWireDesc * desc) 33174642e01fSmrg{ 3318f7df2e56Smrg XkbSrvInfoPtr xkbi; 3319f7df2e56Smrg XkbSrvLedInfoPtr sli; 3320f7df2e56Smrg XkbEventCauseRec cause; 3321f7df2e56Smrg int i, bit; 33224642e01fSmrg 33234642e01fSmrg xkbi = dev->key->xkbInfo; 33244642e01fSmrg 3325f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3326f7df2e56Smrg XkbXI_IndicatorMapsMask); 33274642e01fSmrg if (!sli) 3328f7df2e56Smrg return BadAlloc; 33294642e01fSmrg 33304642e01fSmrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3331f7df2e56Smrg if (which & bit) { 3332f7df2e56Smrg sli->maps[i].flags = desc->flags; 3333f7df2e56Smrg sli->maps[i].which_groups = desc->whichGroups; 3334f7df2e56Smrg sli->maps[i].groups = desc->groups; 3335f7df2e56Smrg sli->maps[i].which_mods = desc->whichMods; 3336f7df2e56Smrg sli->maps[i].mods.mask = desc->mods; 3337f7df2e56Smrg sli->maps[i].mods.real_mods = desc->mods; 3338f7df2e56Smrg sli->maps[i].mods.vmods = desc->virtualMods; 3339f7df2e56Smrg sli->maps[i].ctrls = desc->ctrls; 3340f7df2e56Smrg if (desc->virtualMods != 0) { 3341f7df2e56Smrg unsigned tmp; 3342f7df2e56Smrg 3343f7df2e56Smrg tmp = XkbMaskForVMask(xkbi->desc, desc->virtualMods); 3344f7df2e56Smrg sli->maps[i].mods.mask = desc->mods | tmp; 3345f7df2e56Smrg } 3346f7df2e56Smrg desc++; 3347f7df2e56Smrg } 3348f7df2e56Smrg } 3349f7df2e56Smrg 3350f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbSetIndicatorMap, client); 3351f7df2e56Smrg XkbApplyLedMapChanges(dev, sli, which, NULL, NULL, &cause); 33524642e01fSmrg 33534642e01fSmrg return Success; 33544642e01fSmrg} 33554642e01fSmrg 335605b261ecSmrgint 335705b261ecSmrgProcXkbSetIndicatorMap(ClientPtr client) 335805b261ecSmrg{ 3359f7df2e56Smrg int i, bit; 3360f7df2e56Smrg int nIndicators; 3361f7df2e56Smrg DeviceIntPtr dev; 3362f7df2e56Smrg xkbIndicatorMapWireDesc *from; 3363f7df2e56Smrg int rc; 336405b261ecSmrg 336505b261ecSmrg REQUEST(xkbSetIndicatorMapReq); 336605b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 336705b261ecSmrg 3368f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3369f7df2e56Smrg return BadAccess; 337005b261ecSmrg 33714642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 337205b261ecSmrg 3373f7df2e56Smrg if (stuff->which == 0) 3374f7df2e56Smrg return Success; 337505b261ecSmrg 3376f7df2e56Smrg for (nIndicators = i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3377f7df2e56Smrg if (stuff->which & bit) 3378f7df2e56Smrg nIndicators++; 337905b261ecSmrg } 3380f7df2e56Smrg if (stuff->length != ((SIZEOF(xkbSetIndicatorMapReq) + 3381f7df2e56Smrg (nIndicators * SIZEOF(xkbIndicatorMapWireDesc))) / 3382f7df2e56Smrg 4)) { 3383f7df2e56Smrg return BadLength; 338405b261ecSmrg } 338505b261ecSmrg 3386f7df2e56Smrg from = (xkbIndicatorMapWireDesc *) &stuff[1]; 3387f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3388f7df2e56Smrg if (stuff->which & bit) { 3389f7df2e56Smrg if (client->swapped) { 3390f7df2e56Smrg swaps(&from->virtualMods); 3391f7df2e56Smrg swapl(&from->ctrls); 3392f7df2e56Smrg } 3393f7df2e56Smrg CHK_MASK_LEGAL(i, from->whichGroups, XkbIM_UseAnyGroup); 3394f7df2e56Smrg CHK_MASK_LEGAL(i, from->whichMods, XkbIM_UseAnyMods); 3395f7df2e56Smrg from++; 3396f7df2e56Smrg } 339705b261ecSmrg } 339805b261ecSmrg 3399f7df2e56Smrg from = (xkbIndicatorMapWireDesc *) &stuff[1]; 34004642e01fSmrg rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); 34014642e01fSmrg if (rc != Success) 34024642e01fSmrg return rc; 34034642e01fSmrg 3404f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 34054642e01fSmrg DeviceIntPtr other; 3406f7df2e56Smrg 3407f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 3408f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 3409f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 3410f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3411f7df2e56Smrg DixSetAttrAccess); 34124642e01fSmrg if (rc == Success) 34134642e01fSmrg _XkbSetIndicatorMap(client, other, stuff->which, from); 34144642e01fSmrg } 34154642e01fSmrg } 341605b261ecSmrg } 341705b261ecSmrg 34184642e01fSmrg return Success; 341905b261ecSmrg} 342005b261ecSmrg 342105b261ecSmrg/***====================================================================***/ 342205b261ecSmrg 342305b261ecSmrgint 342405b261ecSmrgProcXkbGetNamedIndicator(ClientPtr client) 342505b261ecSmrg{ 3426f7df2e56Smrg DeviceIntPtr dev; 3427f7df2e56Smrg xkbGetNamedIndicatorReply rep; 3428f7df2e56Smrg register int i = 0; 3429f7df2e56Smrg XkbSrvLedInfoPtr sli; 3430f7df2e56Smrg XkbIndicatorMapPtr map = NULL; 343105b261ecSmrg 343205b261ecSmrg REQUEST(xkbGetNamedIndicatorReq); 343305b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 343405b261ecSmrg 3435f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3436f7df2e56Smrg return BadAccess; 343705b261ecSmrg 34384642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 343905b261ecSmrg CHK_ATOM_ONLY(stuff->indicator); 344005b261ecSmrg 3441f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 0); 344205b261ecSmrg if (!sli) 3443f7df2e56Smrg return BadAlloc; 3444f7df2e56Smrg 3445f7df2e56Smrg i = 0; 3446f7df2e56Smrg map = NULL; 3447f7df2e56Smrg if ((sli->names) && (sli->maps)) { 3448f7df2e56Smrg for (i = 0; i < XkbNumIndicators; i++) { 3449f7df2e56Smrg if (stuff->indicator == sli->names[i]) { 3450f7df2e56Smrg map = &sli->maps[i]; 345105b261ecSmrg break; 345205b261ecSmrg } 345305b261ecSmrg } 345405b261ecSmrg } 345505b261ecSmrg 3456f7df2e56Smrg rep = (xkbGetNamedIndicatorReply) { 3457f7df2e56Smrg .type = X_Reply, 3458f7df2e56Smrg .sequenceNumber = client->sequence, 3459f7df2e56Smrg .length = 0, 3460f7df2e56Smrg .deviceID = dev->id, 3461f7df2e56Smrg .indicator = stuff->indicator 3462f7df2e56Smrg }; 3463f7df2e56Smrg if (map != NULL) { 3464f7df2e56Smrg rep.found = TRUE; 3465f7df2e56Smrg rep.on = ((sli->effectiveState & (1 << i)) != 0); 3466f7df2e56Smrg rep.realIndicator = ((sli->physIndicators & (1 << i)) != 0); 3467f7df2e56Smrg rep.ndx = i; 3468f7df2e56Smrg rep.flags = map->flags; 3469f7df2e56Smrg rep.whichGroups = map->which_groups; 3470f7df2e56Smrg rep.groups = map->groups; 3471f7df2e56Smrg rep.whichMods = map->which_mods; 3472f7df2e56Smrg rep.mods = map->mods.mask; 3473f7df2e56Smrg rep.realMods = map->mods.real_mods; 3474f7df2e56Smrg rep.virtualMods = map->mods.vmods; 3475f7df2e56Smrg rep.ctrls = map->ctrls; 3476f7df2e56Smrg rep.supported = TRUE; 3477f7df2e56Smrg } 3478f7df2e56Smrg else { 3479f7df2e56Smrg rep.found = FALSE; 3480f7df2e56Smrg rep.on = FALSE; 3481f7df2e56Smrg rep.realIndicator = FALSE; 3482f7df2e56Smrg rep.ndx = XkbNoIndicator; 3483f7df2e56Smrg rep.flags = 0; 3484f7df2e56Smrg rep.whichGroups = 0; 3485f7df2e56Smrg rep.groups = 0; 3486f7df2e56Smrg rep.whichMods = 0; 3487f7df2e56Smrg rep.mods = 0; 3488f7df2e56Smrg rep.realMods = 0; 3489f7df2e56Smrg rep.virtualMods = 0; 3490f7df2e56Smrg rep.ctrls = 0; 3491f7df2e56Smrg rep.supported = TRUE; 3492f7df2e56Smrg } 3493f7df2e56Smrg if (client->swapped) { 3494f7df2e56Smrg swapl(&rep.length); 3495f7df2e56Smrg swaps(&rep.sequenceNumber); 3496f7df2e56Smrg swapl(&rep.indicator); 3497f7df2e56Smrg swaps(&rep.virtualMods); 3498f7df2e56Smrg swapl(&rep.ctrls); 3499f7df2e56Smrg } 3500f7df2e56Smrg 3501f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetNamedIndicatorReply), &rep); 35026747b715Smrg return Success; 350305b261ecSmrg} 350405b261ecSmrg 35054642e01fSmrg/** 35064642e01fSmrg * Find the IM on the device. 35074642e01fSmrg * Returns the map, or NULL if the map doesn't exist. 35084642e01fSmrg * If the return value is NULL, led_return is undefined. Otherwise, led_return 35094642e01fSmrg * is set to the led index of the map. 35104642e01fSmrg */ 35114642e01fSmrgstatic XkbIndicatorMapPtr 3512f7df2e56Smrg_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, int *led_return) 35134642e01fSmrg{ 3514f7df2e56Smrg XkbIndicatorMapPtr map; 351505b261ecSmrg 35164642e01fSmrg /* search for the right indicator */ 35174642e01fSmrg map = NULL; 351805b261ecSmrg if (sli->names && sli->maps) { 3519f7df2e56Smrg int led; 35206747b715Smrg 3521f7df2e56Smrg for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { 3522f7df2e56Smrg if (sli->names[led] == indicator) { 3523f7df2e56Smrg map = &sli->maps[led]; 3524f7df2e56Smrg *led_return = led; 3525f7df2e56Smrg break; 3526f7df2e56Smrg } 3527f7df2e56Smrg } 352805b261ecSmrg } 352905b261ecSmrg 35304642e01fSmrg return map; 35314642e01fSmrg} 35324642e01fSmrg 35334642e01fSmrg/** 35346747b715Smrg * Creates an indicator map on the device. If dryRun is TRUE, it only checks 35354642e01fSmrg * if creation is possible, but doesn't actually create it. 35364642e01fSmrg */ 35374642e01fSmrgstatic int 35384642e01fSmrg_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, 35394642e01fSmrg int ledClass, int ledID, 3540f7df2e56Smrg XkbIndicatorMapPtr * map_return, int *led_return, 35414642e01fSmrg Bool dryRun) 35424642e01fSmrg{ 3543f7df2e56Smrg XkbSrvLedInfoPtr sli; 3544f7df2e56Smrg XkbIndicatorMapPtr map; 3545f7df2e56Smrg int led; 35464642e01fSmrg 35474642e01fSmrg sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); 35484642e01fSmrg if (!sli) 35494642e01fSmrg return BadAlloc; 35504642e01fSmrg 35514642e01fSmrg map = _XkbFindNamedIndicatorMap(sli, indicator, &led); 35524642e01fSmrg 3553f7df2e56Smrg if (!map) { 35544642e01fSmrg /* find first unused indicator maps and assign the name to it */ 3555f7df2e56Smrg for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); 3556f7df2e56Smrg led++) { 35574642e01fSmrg if ((sli->names) && (sli->maps) && (sli->names[led] == None) && 3558f7df2e56Smrg (!XkbIM_InUse(&sli->maps[led]))) { 35594642e01fSmrg map = &sli->maps[led]; 35604642e01fSmrg if (!dryRun) 35614642e01fSmrg sli->names[led] = indicator; 35624642e01fSmrg break; 35634642e01fSmrg } 35644642e01fSmrg } 35654642e01fSmrg } 35664642e01fSmrg 35674642e01fSmrg if (!map) 35684642e01fSmrg return BadAlloc; 35694642e01fSmrg 35704642e01fSmrg *led_return = led; 35714642e01fSmrg *map_return = map; 35724642e01fSmrg return Success; 35734642e01fSmrg} 35744642e01fSmrg 35754642e01fSmrgstatic int 35764642e01fSmrg_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, 3577f7df2e56Smrg xkbSetNamedIndicatorReq * stuff) 35784642e01fSmrg{ 3579f7df2e56Smrg unsigned int extDevReason; 3580f7df2e56Smrg unsigned int statec, namec, mapc; 3581f7df2e56Smrg XkbSrvLedInfoPtr sli; 3582f7df2e56Smrg int led = 0; 3583f7df2e56Smrg XkbIndicatorMapPtr map; 3584f7df2e56Smrg DeviceIntPtr kbd; 3585f7df2e56Smrg XkbEventCauseRec cause; 3586f7df2e56Smrg xkbExtensionDeviceNotify ed; 3587f7df2e56Smrg XkbChangesRec changes; 3588f7df2e56Smrg int rc; 35894642e01fSmrg 35904642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, 35914642e01fSmrg stuff->ledID, &map, &led, FALSE); 3592f7df2e56Smrg if (rc != Success || !map) /* oh-oh */ 35934642e01fSmrg return rc; 35944642e01fSmrg 35954642e01fSmrg sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 35964642e01fSmrg XkbXI_IndicatorsMask); 35974642e01fSmrg if (!sli) 35984642e01fSmrg return BadAlloc; 35994642e01fSmrg 36004642e01fSmrg namec = mapc = statec = 0; 36014642e01fSmrg extDevReason = 0; 36024642e01fSmrg 3603f7df2e56Smrg namec |= (1 << led); 36044642e01fSmrg sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); 36054642e01fSmrg extDevReason |= XkbXI_IndicatorNamesMask; 36064642e01fSmrg 36074642e01fSmrg if (stuff->setMap) { 36084642e01fSmrg map->flags = stuff->flags; 36094642e01fSmrg map->which_groups = stuff->whichGroups; 36104642e01fSmrg map->groups = stuff->groups; 36114642e01fSmrg map->which_mods = stuff->whichMods; 36124642e01fSmrg map->mods.mask = stuff->realMods; 36134642e01fSmrg map->mods.real_mods = stuff->realMods; 3614f7df2e56Smrg map->mods.vmods = stuff->virtualMods; 36154642e01fSmrg map->ctrls = stuff->ctrls; 3616f7df2e56Smrg mapc |= (1 << led); 36174642e01fSmrg } 36184642e01fSmrg 3619f7df2e56Smrg if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) { 3620f7df2e56Smrg if (stuff->on) 3621f7df2e56Smrg sli->explicitState |= (1 << led); 3622f7df2e56Smrg else 3623f7df2e56Smrg sli->explicitState &= ~(1 << led); 36244642e01fSmrg statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); 362505b261ecSmrg } 36264642e01fSmrg 3627f7df2e56Smrg memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 3628f7df2e56Smrg memset((char *) &changes, 0, sizeof(XkbChangesRec)); 3629f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbSetNamedIndicator, client); 363005b261ecSmrg if (namec) 3631f7df2e56Smrg XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 363205b261ecSmrg if (mapc) 3633f7df2e56Smrg XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 363405b261ecSmrg if (statec) 3635f7df2e56Smrg XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 363605b261ecSmrg 36374642e01fSmrg kbd = dev; 3638f7df2e56Smrg if ((sli->flags & XkbSLI_HasOwnState) == 0) 36394642e01fSmrg kbd = inputInfo.keyboard; 36404642e01fSmrg XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 36414642e01fSmrg 36424642e01fSmrg return Success; 36434642e01fSmrg} 36444642e01fSmrg 36454642e01fSmrgint 36464642e01fSmrgProcXkbSetNamedIndicator(ClientPtr client) 36474642e01fSmrg{ 3648f7df2e56Smrg int rc; 3649f7df2e56Smrg DeviceIntPtr dev; 3650f7df2e56Smrg int led = 0; 3651f7df2e56Smrg XkbIndicatorMapPtr map; 36524642e01fSmrg 36534642e01fSmrg REQUEST(xkbSetNamedIndicatorReq); 36544642e01fSmrg REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 36554642e01fSmrg 3656f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 3657f7df2e56Smrg return BadAccess; 36584642e01fSmrg 36594642e01fSmrg CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 36604642e01fSmrg CHK_ATOM_ONLY(stuff->indicator); 3661f7df2e56Smrg CHK_MASK_LEGAL(0x10, stuff->whichGroups, XkbIM_UseAnyGroup); 3662f7df2e56Smrg CHK_MASK_LEGAL(0x11, stuff->whichMods, XkbIM_UseAnyMods); 36634642e01fSmrg 36644642e01fSmrg /* Dry-run for checks */ 36654642e01fSmrg rc = _XkbCreateIndicatorMap(dev, stuff->indicator, 36664642e01fSmrg stuff->ledClass, stuff->ledID, 36674642e01fSmrg &map, &led, TRUE); 3668f7df2e56Smrg if (rc != Success || !map) /* couldn't be created or didn't exist */ 36694642e01fSmrg return rc; 36704642e01fSmrg 36714642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 3672f7df2e56Smrg stuff->deviceSpec == XkbUseCorePtr) { 36734642e01fSmrg DeviceIntPtr other; 3674f7df2e56Smrg 3675f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 3676f7df2e56Smrg if ((other != dev) && !IsMaster(other) && 3677f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3678f7df2e56Smrg other->leds) && 3679f7df2e56Smrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3680f7df2e56Smrg == Success)) { 36814642e01fSmrg rc = _XkbCreateIndicatorMap(other, stuff->indicator, 3682f7df2e56Smrg stuff->ledClass, stuff->ledID, &map, 3683f7df2e56Smrg &led, TRUE); 36844642e01fSmrg if (rc != Success || !map) 36854642e01fSmrg return rc; 36864642e01fSmrg } 36874642e01fSmrg } 36884642e01fSmrg } 36894642e01fSmrg 36904642e01fSmrg /* All checks passed, let's do it */ 36914642e01fSmrg rc = _XkbSetNamedIndicator(client, dev, stuff); 36924642e01fSmrg if (rc != Success) 36934642e01fSmrg return rc; 36944642e01fSmrg 36954642e01fSmrg if (stuff->deviceSpec == XkbUseCoreKbd || 3696f7df2e56Smrg stuff->deviceSpec == XkbUseCorePtr) { 36974642e01fSmrg DeviceIntPtr other; 3698f7df2e56Smrg 3699f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 3700f7df2e56Smrg if ((other != dev) && !IsMaster(other) && 3701f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3702f7df2e56Smrg other->leds) && 3703f7df2e56Smrg (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3704f7df2e56Smrg == Success)) { 37054642e01fSmrg _XkbSetNamedIndicator(client, other, stuff); 37064642e01fSmrg } 37074642e01fSmrg } 37084642e01fSmrg } 37094642e01fSmrg 37106747b715Smrg return Success; 371105b261ecSmrg} 371205b261ecSmrg 371305b261ecSmrg/***====================================================================***/ 371405b261ecSmrg 371505b261ecSmrgstatic CARD32 3716f7df2e56Smrg_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 371705b261ecSmrg{ 3718f7df2e56Smrg register unsigned int i, bit, nAtoms; 3719f7df2e56Smrg register CARD32 atomsPresent; 372005b261ecSmrg 3721f7df2e56Smrg for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 3722f7df2e56Smrg if (atoms[i] != None) { 3723f7df2e56Smrg atomsPresent |= bit; 3724f7df2e56Smrg nAtoms++; 3725f7df2e56Smrg } 372605b261ecSmrg } 372705b261ecSmrg if (count) 3728f7df2e56Smrg *count = nAtoms; 372905b261ecSmrg return atomsPresent; 373005b261ecSmrg} 373105b261ecSmrg 373205b261ecSmrgstatic char * 3733f7df2e56Smrg_XkbWriteAtoms(char *wire, Atom *atoms, int maxAtoms, int swap) 373405b261ecSmrg{ 3735f7df2e56Smrg register unsigned int i; 3736f7df2e56Smrg Atom *atm; 3737f7df2e56Smrg 3738f7df2e56Smrg atm = (Atom *) wire; 3739f7df2e56Smrg for (i = 0; i < maxAtoms; i++) { 3740f7df2e56Smrg if (atoms[i] != None) { 3741f7df2e56Smrg *atm = atoms[i]; 3742f7df2e56Smrg if (swap) { 3743f7df2e56Smrg swapl(atm); 3744f7df2e56Smrg } 3745f7df2e56Smrg atm++; 3746f7df2e56Smrg } 3747f7df2e56Smrg } 3748f7df2e56Smrg return (char *) atm; 374905b261ecSmrg} 375005b261ecSmrg 375105b261ecSmrgstatic Status 3752f7df2e56SmrgXkbComputeGetNamesReplySize(XkbDescPtr xkb, xkbGetNamesReply * rep) 375305b261ecSmrg{ 3754f7df2e56Smrg register unsigned which, length; 3755f7df2e56Smrg register int i; 3756f7df2e56Smrg 3757f7df2e56Smrg rep->minKeyCode = xkb->min_key_code; 3758f7df2e56Smrg rep->maxKeyCode = xkb->max_key_code; 3759f7df2e56Smrg which = rep->which; 3760f7df2e56Smrg length = 0; 3761f7df2e56Smrg if (xkb->names != NULL) { 3762f7df2e56Smrg if (which & XkbKeycodesNameMask) 3763f7df2e56Smrg length++; 3764f7df2e56Smrg if (which & XkbGeometryNameMask) 3765f7df2e56Smrg length++; 3766f7df2e56Smrg if (which & XkbSymbolsNameMask) 3767f7df2e56Smrg length++; 3768f7df2e56Smrg if (which & XkbPhysSymbolsNameMask) 3769f7df2e56Smrg length++; 3770f7df2e56Smrg if (which & XkbTypesNameMask) 3771f7df2e56Smrg length++; 3772f7df2e56Smrg if (which & XkbCompatNameMask) 3773f7df2e56Smrg length++; 3774f7df2e56Smrg } 3775f7df2e56Smrg else 3776f7df2e56Smrg which &= ~XkbComponentNamesMask; 3777f7df2e56Smrg 3778f7df2e56Smrg if (xkb->map != NULL) { 3779f7df2e56Smrg if (which & XkbKeyTypeNamesMask) 3780f7df2e56Smrg length += xkb->map->num_types; 3781f7df2e56Smrg rep->nTypes = xkb->map->num_types; 3782f7df2e56Smrg if (which & XkbKTLevelNamesMask) { 3783f7df2e56Smrg XkbKeyTypePtr pType = xkb->map->types; 3784f7df2e56Smrg int nKTLevels = 0; 3785f7df2e56Smrg 3786f7df2e56Smrg length += XkbPaddedSize(xkb->map->num_types) / 4; 3787f7df2e56Smrg for (i = 0; i < xkb->map->num_types; i++, pType++) { 3788f7df2e56Smrg if (pType->level_names != NULL) 3789f7df2e56Smrg nKTLevels += pType->num_levels; 3790f7df2e56Smrg } 3791f7df2e56Smrg rep->nKTLevels = nKTLevels; 3792f7df2e56Smrg length += nKTLevels; 3793f7df2e56Smrg } 379405b261ecSmrg } 379505b261ecSmrg else { 3796f7df2e56Smrg rep->nTypes = 0; 3797f7df2e56Smrg rep->nKTLevels = 0; 3798f7df2e56Smrg which &= ~(XkbKeyTypeNamesMask | XkbKTLevelNamesMask); 3799f7df2e56Smrg } 3800f7df2e56Smrg 3801f7df2e56Smrg rep->minKeyCode = xkb->min_key_code; 3802f7df2e56Smrg rep->maxKeyCode = xkb->max_key_code; 3803f7df2e56Smrg rep->indicators = 0; 3804f7df2e56Smrg rep->virtualMods = 0; 3805f7df2e56Smrg rep->groupNames = 0; 3806f7df2e56Smrg if (xkb->names != NULL) { 3807f7df2e56Smrg if (which & XkbIndicatorNamesMask) { 3808f7df2e56Smrg int nLeds; 3809f7df2e56Smrg 3810f7df2e56Smrg rep->indicators = 3811f7df2e56Smrg _XkbCountAtoms(xkb->names->indicators, XkbNumIndicators, 3812f7df2e56Smrg &nLeds); 3813f7df2e56Smrg length += nLeds; 3814f7df2e56Smrg if (nLeds == 0) 3815f7df2e56Smrg which &= ~XkbIndicatorNamesMask; 3816f7df2e56Smrg } 3817f7df2e56Smrg 3818f7df2e56Smrg if (which & XkbVirtualModNamesMask) { 3819f7df2e56Smrg int nVMods; 3820f7df2e56Smrg 3821f7df2e56Smrg rep->virtualMods = 3822f7df2e56Smrg _XkbCountAtoms(xkb->names->vmods, XkbNumVirtualMods, &nVMods); 3823f7df2e56Smrg length += nVMods; 3824f7df2e56Smrg if (nVMods == 0) 3825f7df2e56Smrg which &= ~XkbVirtualModNamesMask; 3826f7df2e56Smrg } 3827f7df2e56Smrg 3828f7df2e56Smrg if (which & XkbGroupNamesMask) { 3829f7df2e56Smrg int nGroups; 3830f7df2e56Smrg 3831f7df2e56Smrg rep->groupNames = 3832f7df2e56Smrg _XkbCountAtoms(xkb->names->groups, XkbNumKbdGroups, &nGroups); 3833f7df2e56Smrg length += nGroups; 3834f7df2e56Smrg if (nGroups == 0) 3835f7df2e56Smrg which &= ~XkbGroupNamesMask; 3836f7df2e56Smrg } 3837f7df2e56Smrg 3838f7df2e56Smrg if ((which & XkbKeyNamesMask) && (xkb->names->keys)) 3839f7df2e56Smrg length += rep->nKeys; 3840f7df2e56Smrg else 3841f7df2e56Smrg which &= ~XkbKeyNamesMask; 3842f7df2e56Smrg 3843f7df2e56Smrg if ((which & XkbKeyAliasesMask) && 3844f7df2e56Smrg (xkb->names->key_aliases) && (xkb->names->num_key_aliases > 0)) { 3845f7df2e56Smrg rep->nKeyAliases = xkb->names->num_key_aliases; 3846f7df2e56Smrg length += rep->nKeyAliases * 2; 3847f7df2e56Smrg } 3848f7df2e56Smrg else { 3849f7df2e56Smrg which &= ~XkbKeyAliasesMask; 3850f7df2e56Smrg rep->nKeyAliases = 0; 3851f7df2e56Smrg } 3852f7df2e56Smrg 3853f7df2e56Smrg if ((which & XkbRGNamesMask) && (xkb->names->num_rg > 0)) 3854f7df2e56Smrg length += xkb->names->num_rg; 3855f7df2e56Smrg else 3856f7df2e56Smrg which &= ~XkbRGNamesMask; 385705b261ecSmrg } 385805b261ecSmrg else { 3859f7df2e56Smrg which &= ~(XkbIndicatorNamesMask | XkbVirtualModNamesMask); 3860f7df2e56Smrg which &= ~(XkbGroupNamesMask | XkbKeyNamesMask | XkbKeyAliasesMask); 3861f7df2e56Smrg which &= ~XkbRGNamesMask; 386205b261ecSmrg } 386305b261ecSmrg 3864f7df2e56Smrg rep->length = length; 3865f7df2e56Smrg rep->which = which; 386605b261ecSmrg return Success; 386705b261ecSmrg} 386805b261ecSmrg 386905b261ecSmrgstatic int 3870f7df2e56SmrgXkbSendNames(ClientPtr client, XkbDescPtr xkb, xkbGetNamesReply * rep) 387105b261ecSmrg{ 3872f7df2e56Smrg register unsigned i, length, which; 3873f7df2e56Smrg char *start; 3874f7df2e56Smrg char *desc; 387505b261ecSmrg 3876f7df2e56Smrg length = rep->length * 4; 3877f7df2e56Smrg which = rep->which; 387805b261ecSmrg if (client->swapped) { 3879f7df2e56Smrg swaps(&rep->sequenceNumber); 3880f7df2e56Smrg swapl(&rep->length); 3881f7df2e56Smrg swapl(&rep->which); 3882f7df2e56Smrg swaps(&rep->virtualMods); 3883f7df2e56Smrg swapl(&rep->indicators); 388405b261ecSmrg } 388505b261ecSmrg 38869ace9065Smrg start = desc = calloc(1, length); 3887f7df2e56Smrg if (!start) 3888f7df2e56Smrg return BadAlloc; 388905b261ecSmrg if (xkb->names) { 3890f7df2e56Smrg if (which & XkbKeycodesNameMask) { 3891f7df2e56Smrg *((CARD32 *) desc) = xkb->names->keycodes; 389205b261ecSmrg if (client->swapped) { 3893f7df2e56Smrg swapl((int *) desc); 389405b261ecSmrg } 3895f7df2e56Smrg desc += 4; 389605b261ecSmrg } 3897f7df2e56Smrg if (which & XkbGeometryNameMask) { 3898f7df2e56Smrg *((CARD32 *) desc) = xkb->names->geometry; 389905b261ecSmrg if (client->swapped) { 3900f7df2e56Smrg swapl((int *) desc); 390105b261ecSmrg } 3902f7df2e56Smrg desc += 4; 390305b261ecSmrg } 3904f7df2e56Smrg if (which & XkbSymbolsNameMask) { 3905f7df2e56Smrg *((CARD32 *) desc) = xkb->names->symbols; 390605b261ecSmrg if (client->swapped) { 3907f7df2e56Smrg swapl((int *) desc); 390805b261ecSmrg } 3909f7df2e56Smrg desc += 4; 391005b261ecSmrg } 3911f7df2e56Smrg if (which & XkbPhysSymbolsNameMask) { 3912f7df2e56Smrg register CARD32 *atm = (CARD32 *) desc; 3913f7df2e56Smrg 3914f7df2e56Smrg atm[0] = (CARD32) xkb->names->phys_symbols; 391505b261ecSmrg if (client->swapped) { 3916f7df2e56Smrg swapl(&atm[0]); 391705b261ecSmrg } 3918f7df2e56Smrg desc += 4; 391905b261ecSmrg } 3920f7df2e56Smrg if (which & XkbTypesNameMask) { 3921f7df2e56Smrg *((CARD32 *) desc) = (CARD32) xkb->names->types; 392205b261ecSmrg if (client->swapped) { 3923f7df2e56Smrg swapl((int *) desc); 392405b261ecSmrg } 3925f7df2e56Smrg desc += 4; 392605b261ecSmrg } 3927f7df2e56Smrg if (which & XkbCompatNameMask) { 3928f7df2e56Smrg *((CARD32 *) desc) = (CARD32) xkb->names->compat; 392905b261ecSmrg if (client->swapped) { 3930f7df2e56Smrg swapl((int *) desc); 393105b261ecSmrg } 3932f7df2e56Smrg desc += 4; 393305b261ecSmrg } 3934f7df2e56Smrg if (which & XkbKeyTypeNamesMask) { 3935f7df2e56Smrg register CARD32 *atm = (CARD32 *) desc; 3936f7df2e56Smrg register XkbKeyTypePtr type = xkb->map->types; 393705b261ecSmrg 3938f7df2e56Smrg for (i = 0; i < xkb->map->num_types; i++, atm++, type++) { 3939f7df2e56Smrg *atm = (CARD32) type->name; 394005b261ecSmrg if (client->swapped) { 3941f7df2e56Smrg swapl(atm); 394205b261ecSmrg } 394305b261ecSmrg } 3944f7df2e56Smrg desc = (char *) atm; 394505b261ecSmrg } 3946f7df2e56Smrg if (which & XkbKTLevelNamesMask && xkb->map) { 394705b261ecSmrg XkbKeyTypePtr type = xkb->map->types; 394805b261ecSmrg register CARD32 *atm; 3949f7df2e56Smrg 3950f7df2e56Smrg for (i = 0; i < rep->nTypes; i++, type++) { 395105b261ecSmrg *desc++ = type->num_levels; 395205b261ecSmrg } 3953f7df2e56Smrg desc += XkbPaddedSize(rep->nTypes) - rep->nTypes; 395405b261ecSmrg 3955f7df2e56Smrg atm = (CARD32 *) desc; 395605b261ecSmrg type = xkb->map->types; 3957f7df2e56Smrg for (i = 0; i < xkb->map->num_types; i++, type++) { 395805b261ecSmrg register unsigned l; 3959f7df2e56Smrg 396005b261ecSmrg if (type->level_names) { 3961f7df2e56Smrg for (l = 0; l < type->num_levels; l++, atm++) { 3962f7df2e56Smrg *atm = type->level_names[l]; 396305b261ecSmrg if (client->swapped) { 3964f7df2e56Smrg swapl(atm); 396505b261ecSmrg } 396605b261ecSmrg } 3967f7df2e56Smrg desc += type->num_levels * 4; 396805b261ecSmrg } 396905b261ecSmrg } 397005b261ecSmrg } 3971f7df2e56Smrg if (which & XkbIndicatorNamesMask) { 3972f7df2e56Smrg desc = 3973f7df2e56Smrg _XkbWriteAtoms(desc, xkb->names->indicators, XkbNumIndicators, 3974f7df2e56Smrg client->swapped); 397505b261ecSmrg } 3976f7df2e56Smrg if (which & XkbVirtualModNamesMask) { 3977f7df2e56Smrg desc = _XkbWriteAtoms(desc, xkb->names->vmods, XkbNumVirtualMods, 3978f7df2e56Smrg client->swapped); 397905b261ecSmrg } 3980f7df2e56Smrg if (which & XkbGroupNamesMask) { 3981f7df2e56Smrg desc = _XkbWriteAtoms(desc, xkb->names->groups, XkbNumKbdGroups, 3982f7df2e56Smrg client->swapped); 398305b261ecSmrg } 3984f7df2e56Smrg if (which & XkbKeyNamesMask) { 3985f7df2e56Smrg for (i = 0; i < rep->nKeys; i++, desc += sizeof(XkbKeyNameRec)) { 3986f7df2e56Smrg *((XkbKeyNamePtr) desc) = xkb->names->keys[i + rep->firstKey]; 398705b261ecSmrg } 398805b261ecSmrg } 3989f7df2e56Smrg if (which & XkbKeyAliasesMask) { 3990f7df2e56Smrg XkbKeyAliasPtr pAl; 3991f7df2e56Smrg 3992f7df2e56Smrg pAl = xkb->names->key_aliases; 3993f7df2e56Smrg for (i = 0; i < rep->nKeyAliases; 3994f7df2e56Smrg i++, pAl++, desc += 2 * XkbKeyNameLength) { 3995f7df2e56Smrg *((XkbKeyAliasPtr) desc) = *pAl; 399605b261ecSmrg } 399705b261ecSmrg } 3998f7df2e56Smrg if ((which & XkbRGNamesMask) && (rep->nRadioGroups > 0)) { 3999f7df2e56Smrg register CARD32 *atm = (CARD32 *) desc; 4000f7df2e56Smrg 4001f7df2e56Smrg for (i = 0; i < rep->nRadioGroups; i++, atm++) { 4002f7df2e56Smrg *atm = (CARD32) xkb->names->radio_groups[i]; 400305b261ecSmrg if (client->swapped) { 4004f7df2e56Smrg swapl(atm); 400505b261ecSmrg } 400605b261ecSmrg } 4007f7df2e56Smrg desc += rep->nRadioGroups * 4; 400805b261ecSmrg } 400905b261ecSmrg } 401005b261ecSmrg 4011f7df2e56Smrg if ((desc - start) != (length)) { 4012f7df2e56Smrg ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 4013f7df2e56Smrg length, (unsigned long) (desc - start)); 401405b261ecSmrg } 4015f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetNamesReply), rep); 401605b261ecSmrg WriteToClient(client, length, start); 4017f7df2e56Smrg free((char *) start); 40186747b715Smrg return Success; 401905b261ecSmrg} 402005b261ecSmrg 402105b261ecSmrgint 402205b261ecSmrgProcXkbGetNames(ClientPtr client) 402305b261ecSmrg{ 4024f7df2e56Smrg DeviceIntPtr dev; 4025f7df2e56Smrg XkbDescPtr xkb; 4026f7df2e56Smrg xkbGetNamesReply rep; 402705b261ecSmrg 402805b261ecSmrg REQUEST(xkbGetNamesReq); 402905b261ecSmrg REQUEST_SIZE_MATCH(xkbGetNamesReq); 403005b261ecSmrg 4031f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 4032f7df2e56Smrg return BadAccess; 403305b261ecSmrg 40344642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 4035f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 403605b261ecSmrg 403705b261ecSmrg xkb = dev->key->xkbInfo->desc; 4038f7df2e56Smrg rep = (xkbGetNamesReply) { 4039f7df2e56Smrg .type = X_Reply, 4040f7df2e56Smrg .deviceID = dev->id, 4041f7df2e56Smrg .sequenceNumber = client->sequence, 4042f7df2e56Smrg .length = 0, 4043f7df2e56Smrg .which = stuff->which, 4044f7df2e56Smrg .nTypes = xkb->map->num_types, 4045f7df2e56Smrg .firstKey = xkb->min_key_code, 4046f7df2e56Smrg .nKeys = XkbNumKeys(xkb), 4047f7df2e56Smrg .nKeyAliases = xkb->names ? xkb->names->num_key_aliases : 0, 4048f7df2e56Smrg .nRadioGroups = xkb->names ? xkb->names->num_rg : 0 4049f7df2e56Smrg }; 4050f7df2e56Smrg XkbComputeGetNamesReplySize(xkb, &rep); 4051f7df2e56Smrg return XkbSendNames(client, xkb, &rep); 405205b261ecSmrg} 405305b261ecSmrg 405405b261ecSmrg/***====================================================================***/ 405505b261ecSmrg 405605b261ecSmrgstatic CARD32 * 4057f7df2e56Smrg_XkbCheckAtoms(CARD32 *wire, int nAtoms, int swapped, Atom *pError) 405805b261ecSmrg{ 4059f7df2e56Smrg register int i; 4060f7df2e56Smrg 4061f7df2e56Smrg for (i = 0; i < nAtoms; i++, wire++) { 4062f7df2e56Smrg if (swapped) { 4063f7df2e56Smrg swapl(wire); 4064f7df2e56Smrg } 4065f7df2e56Smrg if ((((Atom) *wire) != None) && (!ValidAtom((Atom) *wire))) { 4066f7df2e56Smrg *pError = ((Atom) *wire); 4067f7df2e56Smrg return NULL; 4068f7df2e56Smrg } 406905b261ecSmrg } 407005b261ecSmrg return wire; 407105b261ecSmrg} 407205b261ecSmrg 407305b261ecSmrgstatic CARD32 * 4074f7df2e56Smrg_XkbCheckMaskedAtoms(CARD32 *wire, int nAtoms, CARD32 present, int swapped, 4075f7df2e56Smrg Atom *pError) 407605b261ecSmrg{ 4077f7df2e56Smrg register unsigned i, bit; 4078f7df2e56Smrg 4079f7df2e56Smrg for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 4080f7df2e56Smrg if ((present & bit) == 0) 4081f7df2e56Smrg continue; 4082f7df2e56Smrg if (swapped) { 4083f7df2e56Smrg swapl(wire); 4084f7df2e56Smrg } 4085f7df2e56Smrg if ((((Atom) *wire) != None) && (!ValidAtom(((Atom) *wire)))) { 4086f7df2e56Smrg *pError = (Atom) *wire; 4087f7df2e56Smrg return NULL; 4088f7df2e56Smrg } 4089f7df2e56Smrg wire++; 409005b261ecSmrg } 409105b261ecSmrg return wire; 409205b261ecSmrg} 409305b261ecSmrg 409405b261ecSmrgstatic Atom * 4095f7df2e56Smrg_XkbCopyMaskedAtoms(Atom *wire, Atom *dest, int nAtoms, CARD32 present) 409605b261ecSmrg{ 4097f7df2e56Smrg register int i, bit; 409805b261ecSmrg 4099f7df2e56Smrg for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 4100f7df2e56Smrg if ((present & bit) == 0) 4101f7df2e56Smrg continue; 4102f7df2e56Smrg dest[i] = *wire++; 410305b261ecSmrg } 410405b261ecSmrg return wire; 410505b261ecSmrg} 410605b261ecSmrg 410705b261ecSmrgstatic Bool 4108f7df2e56Smrg_XkbCheckTypeName(Atom name, int typeNdx) 410905b261ecSmrg{ 4110f7df2e56Smrg const char *str; 411105b261ecSmrg 4112f7df2e56Smrg str = NameForAtom(name); 4113f7df2e56Smrg if ((strcmp(str, "ONE_LEVEL") == 0) || (strcmp(str, "TWO_LEVEL") == 0) || 4114f7df2e56Smrg (strcmp(str, "ALPHABETIC") == 0) || (strcmp(str, "KEYPAD") == 0)) 4115f7df2e56Smrg return FALSE; 41166747b715Smrg return TRUE; 411705b261ecSmrg} 411805b261ecSmrg 41194642e01fSmrg/** 41204642e01fSmrg * Check the device-dependent data in the request against the device. Returns 41214642e01fSmrg * Success, or the appropriate error code. 41224642e01fSmrg */ 41234642e01fSmrgstatic int 41244642e01fSmrg_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 4125f7df2e56Smrg xkbSetNamesReq * stuff, CARD32 *data) 412605b261ecSmrg{ 4127f7df2e56Smrg XkbDescRec *xkb; 4128f7df2e56Smrg CARD32 *tmp; 4129f7df2e56Smrg Atom bad = None; 413005b261ecSmrg 41314642e01fSmrg tmp = data; 41324642e01fSmrg xkb = dev->key->xkbInfo->desc; 41334642e01fSmrg 41344642e01fSmrg if (stuff->which & XkbKeyTypeNamesMask) { 41354642e01fSmrg int i; 4136f7df2e56Smrg CARD32 *old; 4137f7df2e56Smrg 4138f7df2e56Smrg if (stuff->nTypes < 1) { 4139f7df2e56Smrg client->errorValue = _XkbErrCode2(0x02, stuff->nTypes); 41404642e01fSmrg return BadValue; 41414642e01fSmrg } 4142f7df2e56Smrg if ((unsigned) (stuff->firstType + stuff->nTypes - 1) >= 4143f7df2e56Smrg xkb->map->num_types) { 4144f7df2e56Smrg client->errorValue = 4145f7df2e56Smrg _XkbErrCode4(0x03, stuff->firstType, stuff->nTypes, 4146f7df2e56Smrg xkb->map->num_types); 41474642e01fSmrg return BadValue; 41484642e01fSmrg } 4149f7df2e56Smrg if (((unsigned) stuff->firstType) <= XkbLastRequiredType) { 4150f7df2e56Smrg client->errorValue = _XkbErrCode2(0x04, stuff->firstType); 41514642e01fSmrg return BadAccess; 41524642e01fSmrg } 4153806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nTypes)) 4154806e81e9Smrg return BadLength; 4155f7df2e56Smrg old = tmp; 4156f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad); 41574642e01fSmrg if (!tmp) { 4158f7df2e56Smrg client->errorValue = bad; 41594642e01fSmrg return BadAtom; 41604642e01fSmrg } 4161f7df2e56Smrg for (i = 0; i < stuff->nTypes; i++, old++) { 4162f7df2e56Smrg if (!_XkbCheckTypeName((Atom) *old, stuff->firstType + i)) 4163f7df2e56Smrg client->errorValue = _XkbErrCode2(0x05, i); 41644642e01fSmrg } 41654642e01fSmrg } 4166f7df2e56Smrg if (stuff->which & XkbKTLevelNamesMask) { 41674642e01fSmrg unsigned i; 4168f7df2e56Smrg XkbKeyTypePtr type; 4169f7df2e56Smrg CARD8 *width; 4170f7df2e56Smrg 4171f7df2e56Smrg if (stuff->nKTLevels < 1) { 4172f7df2e56Smrg client->errorValue = _XkbErrCode2(0x05, stuff->nKTLevels); 41734642e01fSmrg return BadValue; 41744642e01fSmrg } 4175f7df2e56Smrg if ((unsigned) (stuff->firstKTLevel + stuff->nKTLevels - 1) >= 4176f7df2e56Smrg xkb->map->num_types) { 4177f7df2e56Smrg client->errorValue = _XkbErrCode4(0x06, stuff->firstKTLevel, 4178f7df2e56Smrg stuff->nKTLevels, 4179f7df2e56Smrg xkb->map->num_types); 41804642e01fSmrg return BadValue; 41814642e01fSmrg } 4182f7df2e56Smrg width = (CARD8 *) tmp; 4183f7df2e56Smrg tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4184806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, width, tmp)) 4185806e81e9Smrg return BadLength; 41864642e01fSmrg type = &xkb->map->types[stuff->firstKTLevel]; 4187f7df2e56Smrg for (i = 0; i < stuff->nKTLevels; i++, type++) { 4188f7df2e56Smrg if (width[i] == 0) 41894642e01fSmrg continue; 4190f7df2e56Smrg else if (width[i] != type->num_levels) { 4191f7df2e56Smrg client->errorValue = _XkbErrCode4(0x07, i + stuff->firstKTLevel, 4192f7df2e56Smrg type->num_levels, width[i]); 41934642e01fSmrg return BadMatch; 41944642e01fSmrg } 4195806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + width[i])) 4196806e81e9Smrg return BadLength; 4197f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad); 41984642e01fSmrg if (!tmp) { 4199f7df2e56Smrg client->errorValue = bad; 42004642e01fSmrg return BadAtom; 42014642e01fSmrg } 42024642e01fSmrg } 42034642e01fSmrg } 4204f7df2e56Smrg if (stuff->which & XkbIndicatorNamesMask) { 4205f7df2e56Smrg if (stuff->indicators == 0) { 4206f7df2e56Smrg client->errorValue = 0x08; 42074642e01fSmrg return BadMatch; 42084642e01fSmrg } 4209806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, 4210806e81e9Smrg tmp + Ones(stuff->indicators))) 4211806e81e9Smrg return BadLength; 4212f7df2e56Smrg tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators, 4213f7df2e56Smrg client->swapped, &bad); 42144642e01fSmrg if (!tmp) { 4215f7df2e56Smrg client->errorValue = bad; 42164642e01fSmrg return BadAtom; 42174642e01fSmrg } 42184642e01fSmrg } 4219f7df2e56Smrg if (stuff->which & XkbVirtualModNamesMask) { 4220f7df2e56Smrg if (stuff->virtualMods == 0) { 4221f7df2e56Smrg client->errorValue = 0x09; 42224642e01fSmrg return BadMatch; 42234642e01fSmrg } 4224806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, 4225806e81e9Smrg tmp + Ones(stuff->virtualMods))) 4226806e81e9Smrg return BadLength; 4227f7df2e56Smrg tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods, 4228f7df2e56Smrg (CARD32) stuff->virtualMods, 4229f7df2e56Smrg client->swapped, &bad); 42304642e01fSmrg if (!tmp) { 42314642e01fSmrg client->errorValue = bad; 42324642e01fSmrg return BadAtom; 42334642e01fSmrg } 42344642e01fSmrg } 4235f7df2e56Smrg if (stuff->which & XkbGroupNamesMask) { 4236f7df2e56Smrg if (stuff->groupNames == 0) { 4237f7df2e56Smrg client->errorValue = 0x0a; 42384642e01fSmrg return BadMatch; 42394642e01fSmrg } 4240806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, 4241806e81e9Smrg tmp + Ones(stuff->groupNames))) 4242806e81e9Smrg return BadLength; 4243f7df2e56Smrg tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups, 4244f7df2e56Smrg (CARD32) stuff->groupNames, 4245f7df2e56Smrg client->swapped, &bad); 42464642e01fSmrg if (!tmp) { 42474642e01fSmrg client->errorValue = bad; 42484642e01fSmrg return BadAtom; 42494642e01fSmrg } 42504642e01fSmrg } 4251f7df2e56Smrg if (stuff->which & XkbKeyNamesMask) { 4252f7df2e56Smrg if (stuff->firstKey < (unsigned) xkb->min_key_code) { 4253f7df2e56Smrg client->errorValue = _XkbErrCode3(0x0b, xkb->min_key_code, 4254f7df2e56Smrg stuff->firstKey); 42554642e01fSmrg return BadValue; 42564642e01fSmrg } 4257f7df2e56Smrg if (((unsigned) (stuff->firstKey + stuff->nKeys - 1) > 4258f7df2e56Smrg xkb->max_key_code) || (stuff->nKeys < 1)) { 4259f7df2e56Smrg client->errorValue = 4260f7df2e56Smrg _XkbErrCode4(0x0c, xkb->max_key_code, stuff->firstKey, 4261f7df2e56Smrg stuff->nKeys); 42624642e01fSmrg return BadValue; 42634642e01fSmrg } 4264806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nKeys)) 4265806e81e9Smrg return BadLength; 4266f7df2e56Smrg tmp += stuff->nKeys; 42674642e01fSmrg } 4268f7df2e56Smrg if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) { 4269806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, 4270806e81e9Smrg tmp + (stuff->nKeyAliases * 2))) 4271806e81e9Smrg return BadLength; 4272f7df2e56Smrg tmp += stuff->nKeyAliases * 2; 42734642e01fSmrg } 4274f7df2e56Smrg if (stuff->which & XkbRGNamesMask) { 4275f7df2e56Smrg if (stuff->nRadioGroups < 1) { 4276f7df2e56Smrg client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups); 42774642e01fSmrg return BadValue; 42784642e01fSmrg } 4279806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, 4280806e81e9Smrg tmp + stuff->nRadioGroups)) 4281806e81e9Smrg return BadLength; 4282f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad); 42834642e01fSmrg if (!tmp) { 4284f7df2e56Smrg client->errorValue = bad; 42854642e01fSmrg return BadAtom; 42864642e01fSmrg } 42874642e01fSmrg } 4288f7df2e56Smrg if ((tmp - ((CARD32 *) stuff)) != stuff->length) { 42894642e01fSmrg client->errorValue = stuff->length; 42904642e01fSmrg return BadLength; 42914642e01fSmrg } 42924642e01fSmrg 42934642e01fSmrg return Success; 42944642e01fSmrg} 42954642e01fSmrg 42964642e01fSmrgstatic int 4297f7df2e56Smrg_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq * stuff) 42984642e01fSmrg{ 4299f7df2e56Smrg XkbDescRec *xkb; 4300f7df2e56Smrg XkbNamesRec *names; 4301f7df2e56Smrg CARD32 *tmp; 4302f7df2e56Smrg xkbNamesNotify nn; 43034642e01fSmrg 4304f7df2e56Smrg tmp = (CARD32 *) &stuff[1]; 43054642e01fSmrg xkb = dev->key->xkbInfo->desc; 43064642e01fSmrg names = xkb->names; 43074642e01fSmrg 4308f7df2e56Smrg if (XkbAllocNames(xkb, stuff->which, stuff->nRadioGroups, 4309f7df2e56Smrg stuff->nKeyAliases) != Success) { 43104642e01fSmrg return BadAlloc; 43114642e01fSmrg } 43124642e01fSmrg 43136747b715Smrg memset(&nn, 0, sizeof(xkbNamesNotify)); 4314f7df2e56Smrg nn.changed = stuff->which; 4315f7df2e56Smrg tmp = (CARD32 *) &stuff[1]; 4316f7df2e56Smrg if (stuff->which & XkbKeycodesNameMask) 4317f7df2e56Smrg names->keycodes = *tmp++; 4318f7df2e56Smrg if (stuff->which & XkbGeometryNameMask) 4319f7df2e56Smrg names->geometry = *tmp++; 4320f7df2e56Smrg if (stuff->which & XkbSymbolsNameMask) 4321f7df2e56Smrg names->symbols = *tmp++; 4322f7df2e56Smrg if (stuff->which & XkbPhysSymbolsNameMask) 4323f7df2e56Smrg names->phys_symbols = *tmp++; 4324f7df2e56Smrg if (stuff->which & XkbTypesNameMask) 4325f7df2e56Smrg names->types = *tmp++; 4326f7df2e56Smrg if (stuff->which & XkbCompatNameMask) 4327f7df2e56Smrg names->compat = *tmp++; 4328f7df2e56Smrg if ((stuff->which & XkbKeyTypeNamesMask) && (stuff->nTypes > 0)) { 43294642e01fSmrg register unsigned i; 43304642e01fSmrg register XkbKeyTypePtr type; 43314642e01fSmrg 4332f7df2e56Smrg type = &xkb->map->types[stuff->firstType]; 4333f7df2e56Smrg for (i = 0; i < stuff->nTypes; i++, type++) { 4334f7df2e56Smrg type->name = *tmp++; 43354642e01fSmrg } 4336f7df2e56Smrg nn.firstType = stuff->firstType; 4337f7df2e56Smrg nn.nTypes = stuff->nTypes; 43384642e01fSmrg } 4339f7df2e56Smrg if (stuff->which & XkbKTLevelNamesMask) { 4340f7df2e56Smrg register XkbKeyTypePtr type; 43414642e01fSmrg register unsigned i; 43424642e01fSmrg CARD8 *width; 43434642e01fSmrg 4344f7df2e56Smrg width = (CARD8 *) tmp; 4345f7df2e56Smrg tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4346f7df2e56Smrg type = &xkb->map->types[stuff->firstKTLevel]; 4347f7df2e56Smrg for (i = 0; i < stuff->nKTLevels; i++, type++) { 4348f7df2e56Smrg if (width[i] > 0) { 43494642e01fSmrg if (type->level_names) { 43504642e01fSmrg register unsigned n; 4351f7df2e56Smrg 4352f7df2e56Smrg for (n = 0; n < width[i]; n++) { 4353f7df2e56Smrg type->level_names[n] = tmp[n]; 43544642e01fSmrg } 43554642e01fSmrg } 4356f7df2e56Smrg tmp += width[i]; 43574642e01fSmrg } 43584642e01fSmrg } 4359f7df2e56Smrg nn.firstLevelName = 0; 4360f7df2e56Smrg nn.nLevelNames = stuff->nTypes; 4361f7df2e56Smrg } 4362f7df2e56Smrg if (stuff->which & XkbIndicatorNamesMask) { 4363f7df2e56Smrg tmp = _XkbCopyMaskedAtoms(tmp, names->indicators, XkbNumIndicators, 4364f7df2e56Smrg stuff->indicators); 4365f7df2e56Smrg nn.changedIndicators = stuff->indicators; 4366f7df2e56Smrg } 4367f7df2e56Smrg if (stuff->which & XkbVirtualModNamesMask) { 4368f7df2e56Smrg tmp = _XkbCopyMaskedAtoms(tmp, names->vmods, XkbNumVirtualMods, 4369f7df2e56Smrg stuff->virtualMods); 4370f7df2e56Smrg nn.changedVirtualMods = stuff->virtualMods; 4371f7df2e56Smrg } 4372f7df2e56Smrg if (stuff->which & XkbGroupNamesMask) { 4373f7df2e56Smrg tmp = _XkbCopyMaskedAtoms(tmp, names->groups, XkbNumKbdGroups, 4374f7df2e56Smrg stuff->groupNames); 4375f7df2e56Smrg nn.changedVirtualMods = stuff->groupNames; 4376f7df2e56Smrg } 4377f7df2e56Smrg if (stuff->which & XkbKeyNamesMask) { 4378f7df2e56Smrg memcpy((char *) &names->keys[stuff->firstKey], (char *) tmp, 4379f7df2e56Smrg stuff->nKeys * XkbKeyNameLength); 4380f7df2e56Smrg tmp += stuff->nKeys; 4381f7df2e56Smrg nn.firstKey = stuff->firstKey; 4382f7df2e56Smrg nn.nKeys = stuff->nKeys; 4383f7df2e56Smrg } 4384f7df2e56Smrg if (stuff->which & XkbKeyAliasesMask) { 4385f7df2e56Smrg if (stuff->nKeyAliases > 0) { 4386f7df2e56Smrg register int na = stuff->nKeyAliases; 4387f7df2e56Smrg 4388f7df2e56Smrg if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, na) != Success) 43894642e01fSmrg return BadAlloc; 4390f7df2e56Smrg memcpy((char *) names->key_aliases, (char *) tmp, 4391f7df2e56Smrg stuff->nKeyAliases * sizeof(XkbKeyAliasRec)); 4392f7df2e56Smrg tmp += stuff->nKeyAliases * 2; 43934642e01fSmrg } 4394f7df2e56Smrg else if (names->key_aliases != NULL) { 43956747b715Smrg free(names->key_aliases); 4396f7df2e56Smrg names->key_aliases = NULL; 4397f7df2e56Smrg names->num_key_aliases = 0; 43984642e01fSmrg } 4399f7df2e56Smrg nn.nAliases = names->num_key_aliases; 44004642e01fSmrg } 4401f7df2e56Smrg if (stuff->which & XkbRGNamesMask) { 4402f7df2e56Smrg if (stuff->nRadioGroups > 0) { 4403f7df2e56Smrg register unsigned i, nrg; 4404f7df2e56Smrg 4405f7df2e56Smrg nrg = stuff->nRadioGroups; 4406f7df2e56Smrg if (XkbAllocNames(xkb, XkbRGNamesMask, nrg, 0) != Success) 44074642e01fSmrg return BadAlloc; 44084642e01fSmrg 4409f7df2e56Smrg for (i = 0; i < stuff->nRadioGroups; i++) { 4410f7df2e56Smrg names->radio_groups[i] = tmp[i]; 44114642e01fSmrg } 4412f7df2e56Smrg tmp += stuff->nRadioGroups; 44134642e01fSmrg } 44144642e01fSmrg else if (names->radio_groups) { 44156747b715Smrg free(names->radio_groups); 4416f7df2e56Smrg names->radio_groups = NULL; 4417f7df2e56Smrg names->num_rg = 0; 44184642e01fSmrg } 4419f7df2e56Smrg nn.nRadioGroups = names->num_rg; 44204642e01fSmrg } 44214642e01fSmrg if (nn.changed) { 44224642e01fSmrg Bool needExtEvent; 4423f7df2e56Smrg 4424f7df2e56Smrg needExtEvent = (nn.changed & XkbIndicatorNamesMask) != 0; 4425f7df2e56Smrg XkbSendNamesNotify(dev, &nn); 44264642e01fSmrg if (needExtEvent) { 4427f7df2e56Smrg XkbSrvLedInfoPtr sli; 4428f7df2e56Smrg xkbExtensionDeviceNotify edev; 4429f7df2e56Smrg register int i; 4430f7df2e56Smrg register unsigned bit; 4431f7df2e56Smrg 4432f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 4433f7df2e56Smrg XkbXI_IndicatorsMask); 4434f7df2e56Smrg sli->namesPresent = 0; 4435f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 4436f7df2e56Smrg if (names->indicators[i] != None) 4437f7df2e56Smrg sli->namesPresent |= bit; 44384642e01fSmrg } 44396747b715Smrg memset(&edev, 0, sizeof(xkbExtensionDeviceNotify)); 4440f7df2e56Smrg edev.reason = XkbXI_IndicatorNamesMask; 4441f7df2e56Smrg edev.ledClass = KbdFeedbackClass; 4442f7df2e56Smrg edev.ledID = dev->kbdfeed->ctrl.id; 4443f7df2e56Smrg edev.ledsDefined = sli->namesPresent | sli->mapsPresent; 4444f7df2e56Smrg edev.ledState = sli->effectiveState; 4445f7df2e56Smrg edev.firstBtn = 0; 4446f7df2e56Smrg edev.nBtns = 0; 4447f7df2e56Smrg edev.supported = XkbXI_AllFeaturesMask; 4448f7df2e56Smrg edev.unsupported = 0; 4449f7df2e56Smrg XkbSendExtensionDeviceNotify(dev, client, &edev); 44504642e01fSmrg } 44514642e01fSmrg } 44524642e01fSmrg return Success; 44534642e01fSmrg} 44544642e01fSmrg 44554642e01fSmrgint 44564642e01fSmrgProcXkbSetNames(ClientPtr client) 44574642e01fSmrg{ 4458f7df2e56Smrg DeviceIntPtr dev; 4459f7df2e56Smrg CARD32 *tmp; 4460f7df2e56Smrg Atom bad; 4461f7df2e56Smrg int rc; 44624642e01fSmrg 446305b261ecSmrg REQUEST(xkbSetNamesReq); 446405b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 446505b261ecSmrg 4466f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 4467f7df2e56Smrg return BadAccess; 446805b261ecSmrg 44694642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 4470f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 447105b261ecSmrg 44724642e01fSmrg /* check device-independent stuff */ 4473f7df2e56Smrg tmp = (CARD32 *) &stuff[1]; 4474f7df2e56Smrg 4475806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4476806e81e9Smrg return BadLength; 4477f7df2e56Smrg if (stuff->which & XkbKeycodesNameMask) { 4478f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4479f7df2e56Smrg if (!tmp) { 4480f7df2e56Smrg client->errorValue = bad; 4481f7df2e56Smrg return BadAtom; 4482f7df2e56Smrg } 4483f7df2e56Smrg } 4484806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4485806e81e9Smrg return BadLength; 4486f7df2e56Smrg if (stuff->which & XkbGeometryNameMask) { 4487f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4488f7df2e56Smrg if (!tmp) { 4489f7df2e56Smrg client->errorValue = bad; 4490f7df2e56Smrg return BadAtom; 4491f7df2e56Smrg } 4492f7df2e56Smrg } 4493806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4494806e81e9Smrg return BadLength; 4495f7df2e56Smrg if (stuff->which & XkbSymbolsNameMask) { 4496f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4497f7df2e56Smrg if (!tmp) { 4498f7df2e56Smrg client->errorValue = bad; 4499f7df2e56Smrg return BadAtom; 4500f7df2e56Smrg } 4501f7df2e56Smrg } 4502806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4503806e81e9Smrg return BadLength; 4504f7df2e56Smrg if (stuff->which & XkbPhysSymbolsNameMask) { 4505f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4506f7df2e56Smrg if (!tmp) { 4507f7df2e56Smrg client->errorValue = bad; 4508f7df2e56Smrg return BadAtom; 4509f7df2e56Smrg } 4510f7df2e56Smrg } 4511806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4512806e81e9Smrg return BadLength; 4513f7df2e56Smrg if (stuff->which & XkbTypesNameMask) { 4514f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4515f7df2e56Smrg if (!tmp) { 4516f7df2e56Smrg client->errorValue = bad; 4517f7df2e56Smrg return BadAtom; 4518f7df2e56Smrg } 4519f7df2e56Smrg } 4520806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) 4521806e81e9Smrg return BadLength; 4522f7df2e56Smrg if (stuff->which & XkbCompatNameMask) { 4523f7df2e56Smrg tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4524f7df2e56Smrg if (!tmp) { 4525f7df2e56Smrg client->errorValue = bad; 4526f7df2e56Smrg return BadAtom; 4527f7df2e56Smrg } 452805b261ecSmrg } 45294642e01fSmrg 45304642e01fSmrg /* start of device-dependent tests */ 45314642e01fSmrg rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 45324642e01fSmrg if (rc != Success) 45334642e01fSmrg return rc; 45344642e01fSmrg 4535f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 45364642e01fSmrg DeviceIntPtr other; 45374642e01fSmrg 4538f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 4539f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 4540f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 4541f7df2e56Smrg 4542f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4543f7df2e56Smrg DixManageAccess); 4544f7df2e56Smrg if (rc == Success) { 45454642e01fSmrg rc = _XkbSetNamesCheck(client, other, stuff, tmp); 45464642e01fSmrg if (rc != Success) 45474642e01fSmrg return rc; 45484642e01fSmrg } 45494642e01fSmrg } 45504642e01fSmrg } 455105b261ecSmrg } 455205b261ecSmrg 455305b261ecSmrg /* everything is okay -- update names */ 455405b261ecSmrg 45554642e01fSmrg rc = _XkbSetNames(client, dev, stuff); 45564642e01fSmrg if (rc != Success) 45574642e01fSmrg return rc; 455805b261ecSmrg 4559f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 45604642e01fSmrg DeviceIntPtr other; 45614642e01fSmrg 4562f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 4563f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 4564f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 4565f7df2e56Smrg 4566f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4567f7df2e56Smrg DixManageAccess); 45684642e01fSmrg if (rc == Success) 45694642e01fSmrg _XkbSetNames(client, other, stuff); 45704642e01fSmrg } 45714642e01fSmrg } 457205b261ecSmrg } 45734642e01fSmrg 45744642e01fSmrg /* everything is okay -- update names */ 45754642e01fSmrg 45766747b715Smrg return Success; 457705b261ecSmrg} 457805b261ecSmrg 457905b261ecSmrg/***====================================================================***/ 458005b261ecSmrg 45814642e01fSmrg#include "xkbgeom.h" 458205b261ecSmrg 458305b261ecSmrg#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 458405b261ecSmrg 4585f7df2e56Smrg/** 4586f7df2e56Smrg * Write the zero-terminated string str into wire as a pascal string with a 4587f7df2e56Smrg * 16-bit length field prefixed before the actual string. 4588f7df2e56Smrg * 4589f7df2e56Smrg * @param wire The destination array, usually the wire struct 4590f7df2e56Smrg * @param str The source string as zero-terminated C string 4591f7df2e56Smrg * @param swap If TRUE, the length field is swapped. 4592f7df2e56Smrg * 4593f7df2e56Smrg * @return The input string in the format <string length><string> with a 4594f7df2e56Smrg * (swapped) 16 bit string length, non-zero terminated. 4595f7df2e56Smrg */ 459605b261ecSmrgstatic char * 4597f7df2e56SmrgXkbWriteCountedString(char *wire, const char *str, Bool swap) 459805b261ecSmrg{ 4599f7df2e56Smrg CARD16 len, *pLen, paddedLen; 460005b261ecSmrg 46016747b715Smrg if (!str) 46026747b715Smrg return wire; 46036747b715Smrg 4604f7df2e56Smrg len = strlen(str); 4605f7df2e56Smrg pLen = (CARD16 *) wire; 4606f7df2e56Smrg *pLen = len; 460705b261ecSmrg if (swap) { 4608f7df2e56Smrg swaps(pLen); 460905b261ecSmrg } 4610f7df2e56Smrg paddedLen = pad_to_int32(sizeof(len) + len) - sizeof(len); 4611f7df2e56Smrg strncpy(&wire[sizeof(len)], str, paddedLen); 4612f7df2e56Smrg wire += sizeof(len) + paddedLen; 461305b261ecSmrg return wire; 461405b261ecSmrg} 461505b261ecSmrg 461605b261ecSmrgstatic int 461705b261ecSmrgXkbSizeGeomProperties(XkbGeometryPtr geom) 461805b261ecSmrg{ 4619f7df2e56Smrg register int i, size; 4620f7df2e56Smrg XkbPropertyPtr prop; 4621f7df2e56Smrg 4622f7df2e56Smrg for (size = i = 0, prop = geom->properties; i < geom->num_properties; 4623f7df2e56Smrg i++, prop++) { 4624f7df2e56Smrg size += XkbSizeCountedString(prop->name); 4625f7df2e56Smrg size += XkbSizeCountedString(prop->value); 462605b261ecSmrg } 462705b261ecSmrg return size; 462805b261ecSmrg} 462905b261ecSmrg 463005b261ecSmrgstatic char * 4631f7df2e56SmrgXkbWriteGeomProperties(char *wire, XkbGeometryPtr geom, Bool swap) 463205b261ecSmrg{ 4633f7df2e56Smrg register int i; 4634f7df2e56Smrg register XkbPropertyPtr prop; 4635f7df2e56Smrg 4636f7df2e56Smrg for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { 4637f7df2e56Smrg wire = XkbWriteCountedString(wire, prop->name, swap); 4638f7df2e56Smrg wire = XkbWriteCountedString(wire, prop->value, swap); 463905b261ecSmrg } 464005b261ecSmrg return wire; 464105b261ecSmrg} 464205b261ecSmrg 464305b261ecSmrgstatic int 464405b261ecSmrgXkbSizeGeomKeyAliases(XkbGeometryPtr geom) 464505b261ecSmrg{ 4646f7df2e56Smrg return geom->num_key_aliases * (2 * XkbKeyNameLength); 464705b261ecSmrg} 464805b261ecSmrg 464905b261ecSmrgstatic char * 4650f7df2e56SmrgXkbWriteGeomKeyAliases(char *wire, XkbGeometryPtr geom, Bool swap) 465105b261ecSmrg{ 4652f7df2e56Smrg register int sz; 4653f7df2e56Smrg 4654f7df2e56Smrg sz = geom->num_key_aliases * (XkbKeyNameLength * 2); 4655f7df2e56Smrg if (sz > 0) { 4656f7df2e56Smrg memcpy(wire, (char *) geom->key_aliases, sz); 4657f7df2e56Smrg wire += sz; 465805b261ecSmrg } 465905b261ecSmrg return wire; 466005b261ecSmrg} 466105b261ecSmrg 466205b261ecSmrgstatic int 466305b261ecSmrgXkbSizeGeomColors(XkbGeometryPtr geom) 466405b261ecSmrg{ 4665f7df2e56Smrg register int i, size; 4666f7df2e56Smrg register XkbColorPtr color; 466705b261ecSmrg 4668f7df2e56Smrg for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4669f7df2e56Smrg size += XkbSizeCountedString(color->spec); 467005b261ecSmrg } 467105b261ecSmrg return size; 467205b261ecSmrg} 467305b261ecSmrg 467405b261ecSmrgstatic char * 4675f7df2e56SmrgXkbWriteGeomColors(char *wire, XkbGeometryPtr geom, Bool swap) 467605b261ecSmrg{ 4677f7df2e56Smrg register int i; 4678f7df2e56Smrg register XkbColorPtr color; 467905b261ecSmrg 4680f7df2e56Smrg for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4681f7df2e56Smrg wire = XkbWriteCountedString(wire, color->spec, swap); 468205b261ecSmrg } 468305b261ecSmrg return wire; 468405b261ecSmrg} 468505b261ecSmrg 468605b261ecSmrgstatic int 468705b261ecSmrgXkbSizeGeomShapes(XkbGeometryPtr geom) 468805b261ecSmrg{ 4689f7df2e56Smrg register int i, size; 4690f7df2e56Smrg register XkbShapePtr shape; 4691f7df2e56Smrg 4692f7df2e56Smrg for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4693f7df2e56Smrg register int n; 4694f7df2e56Smrg register XkbOutlinePtr ol; 4695f7df2e56Smrg 4696f7df2e56Smrg size += SIZEOF(xkbShapeWireDesc); 4697f7df2e56Smrg for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) { 4698f7df2e56Smrg size += SIZEOF(xkbOutlineWireDesc); 4699f7df2e56Smrg size += ol->num_points * SIZEOF(xkbPointWireDesc); 4700f7df2e56Smrg } 470105b261ecSmrg } 470205b261ecSmrg return size; 470305b261ecSmrg} 470405b261ecSmrg 470505b261ecSmrgstatic char * 4706f7df2e56SmrgXkbWriteGeomShapes(char *wire, XkbGeometryPtr geom, Bool swap) 470705b261ecSmrg{ 4708f7df2e56Smrg int i; 4709f7df2e56Smrg XkbShapePtr shape; 4710f7df2e56Smrg xkbShapeWireDesc *shapeWire; 4711f7df2e56Smrg 4712f7df2e56Smrg for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4713f7df2e56Smrg register int o; 4714f7df2e56Smrg XkbOutlinePtr ol; 4715f7df2e56Smrg xkbOutlineWireDesc *olWire; 4716f7df2e56Smrg 4717f7df2e56Smrg shapeWire = (xkbShapeWireDesc *) wire; 4718f7df2e56Smrg shapeWire->name = shape->name; 4719f7df2e56Smrg shapeWire->nOutlines = shape->num_outlines; 4720f7df2e56Smrg if (shape->primary != NULL) 4721f7df2e56Smrg shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary); 4722f7df2e56Smrg else 4723f7df2e56Smrg shapeWire->primaryNdx = XkbNoShape; 4724f7df2e56Smrg if (shape->approx != NULL) 4725f7df2e56Smrg shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx); 4726f7df2e56Smrg else 4727f7df2e56Smrg shapeWire->approxNdx = XkbNoShape; 4728f7df2e56Smrg shapeWire->pad = 0; 4729f7df2e56Smrg if (swap) { 4730f7df2e56Smrg swapl(&shapeWire->name); 4731f7df2e56Smrg } 4732f7df2e56Smrg wire = (char *) &shapeWire[1]; 4733f7df2e56Smrg for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { 4734f7df2e56Smrg register int p; 4735f7df2e56Smrg XkbPointPtr pt; 4736f7df2e56Smrg xkbPointWireDesc *ptWire; 4737f7df2e56Smrg 4738f7df2e56Smrg olWire = (xkbOutlineWireDesc *) wire; 4739f7df2e56Smrg olWire->nPoints = ol->num_points; 4740f7df2e56Smrg olWire->cornerRadius = ol->corner_radius; 4741f7df2e56Smrg olWire->pad = 0; 4742f7df2e56Smrg wire = (char *) &olWire[1]; 4743f7df2e56Smrg ptWire = (xkbPointWireDesc *) wire; 4744f7df2e56Smrg for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) { 4745f7df2e56Smrg ptWire[p].x = pt->x; 4746f7df2e56Smrg ptWire[p].y = pt->y; 4747f7df2e56Smrg if (swap) { 4748f7df2e56Smrg swaps(&ptWire[p].x); 4749f7df2e56Smrg swaps(&ptWire[p].y); 4750f7df2e56Smrg } 4751f7df2e56Smrg } 4752f7df2e56Smrg wire = (char *) &ptWire[ol->num_points]; 4753f7df2e56Smrg } 475405b261ecSmrg } 475505b261ecSmrg return wire; 475605b261ecSmrg} 475705b261ecSmrg 475805b261ecSmrgstatic int 4759f7df2e56SmrgXkbSizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad) 476005b261ecSmrg{ 4761f7df2e56Smrg register int i, size; 4762f7df2e56Smrg 4763f7df2e56Smrg for (i = size = 0; i < num_doodads; i++, doodad++) { 4764f7df2e56Smrg size += SIZEOF(xkbAnyDoodadWireDesc); 4765f7df2e56Smrg if (doodad->any.type == XkbTextDoodad) { 4766f7df2e56Smrg size += XkbSizeCountedString(doodad->text.text); 4767f7df2e56Smrg size += XkbSizeCountedString(doodad->text.font); 4768f7df2e56Smrg } 4769f7df2e56Smrg else if (doodad->any.type == XkbLogoDoodad) { 4770f7df2e56Smrg size += XkbSizeCountedString(doodad->logo.logo_name); 4771f7df2e56Smrg } 477205b261ecSmrg } 477305b261ecSmrg return size; 477405b261ecSmrg} 477505b261ecSmrg 477605b261ecSmrgstatic char * 4777f7df2e56SmrgXkbWriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad, Bool swap) 477805b261ecSmrg{ 4779f7df2e56Smrg register int i; 4780f7df2e56Smrg xkbDoodadWireDesc *doodadWire; 4781f7df2e56Smrg 4782f7df2e56Smrg for (i = 0; i < num_doodads; i++, doodad++) { 4783f7df2e56Smrg doodadWire = (xkbDoodadWireDesc *) wire; 4784f7df2e56Smrg wire = (char *) &doodadWire[1]; 4785f7df2e56Smrg memset(doodadWire, 0, SIZEOF(xkbDoodadWireDesc)); 4786f7df2e56Smrg doodadWire->any.name = doodad->any.name; 4787f7df2e56Smrg doodadWire->any.type = doodad->any.type; 4788f7df2e56Smrg doodadWire->any.priority = doodad->any.priority; 4789f7df2e56Smrg doodadWire->any.top = doodad->any.top; 4790f7df2e56Smrg doodadWire->any.left = doodad->any.left; 4791f7df2e56Smrg if (swap) { 4792f7df2e56Smrg swapl(&doodadWire->any.name); 4793f7df2e56Smrg swaps(&doodadWire->any.top); 4794f7df2e56Smrg swaps(&doodadWire->any.left); 4795f7df2e56Smrg } 4796f7df2e56Smrg switch (doodad->any.type) { 4797f7df2e56Smrg case XkbOutlineDoodad: 4798f7df2e56Smrg case XkbSolidDoodad: 4799f7df2e56Smrg doodadWire->shape.angle = doodad->shape.angle; 4800f7df2e56Smrg doodadWire->shape.colorNdx = doodad->shape.color_ndx; 4801f7df2e56Smrg doodadWire->shape.shapeNdx = doodad->shape.shape_ndx; 4802f7df2e56Smrg if (swap) { 4803f7df2e56Smrg swaps(&doodadWire->shape.angle); 4804f7df2e56Smrg } 4805f7df2e56Smrg break; 4806f7df2e56Smrg case XkbTextDoodad: 4807f7df2e56Smrg doodadWire->text.angle = doodad->text.angle; 4808f7df2e56Smrg doodadWire->text.width = doodad->text.width; 4809f7df2e56Smrg doodadWire->text.height = doodad->text.height; 4810f7df2e56Smrg doodadWire->text.colorNdx = doodad->text.color_ndx; 4811f7df2e56Smrg if (swap) { 4812f7df2e56Smrg swaps(&doodadWire->text.angle); 4813f7df2e56Smrg swaps(&doodadWire->text.width); 4814f7df2e56Smrg swaps(&doodadWire->text.height); 4815f7df2e56Smrg } 4816f7df2e56Smrg wire = XkbWriteCountedString(wire, doodad->text.text, swap); 4817f7df2e56Smrg wire = XkbWriteCountedString(wire, doodad->text.font, swap); 4818f7df2e56Smrg break; 4819f7df2e56Smrg case XkbIndicatorDoodad: 4820f7df2e56Smrg doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx; 4821f7df2e56Smrg doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx; 4822f7df2e56Smrg doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx; 4823f7df2e56Smrg break; 4824f7df2e56Smrg case XkbLogoDoodad: 4825f7df2e56Smrg doodadWire->logo.angle = doodad->logo.angle; 4826f7df2e56Smrg doodadWire->logo.colorNdx = doodad->logo.color_ndx; 4827f7df2e56Smrg doodadWire->logo.shapeNdx = doodad->logo.shape_ndx; 4828f7df2e56Smrg wire = XkbWriteCountedString(wire, doodad->logo.logo_name, swap); 4829f7df2e56Smrg break; 4830f7df2e56Smrg default: 4831f7df2e56Smrg ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 4832f7df2e56Smrg doodad->any.type); 4833f7df2e56Smrg ErrorF("[xkb] Ignored\n"); 4834f7df2e56Smrg break; 4835f7df2e56Smrg } 483605b261ecSmrg } 483705b261ecSmrg return wire; 483805b261ecSmrg} 483905b261ecSmrg 484005b261ecSmrgstatic char * 4841f7df2e56SmrgXkbWriteGeomOverlay(char *wire, XkbOverlayPtr ol, Bool swap) 484205b261ecSmrg{ 4843f7df2e56Smrg register int r; 4844f7df2e56Smrg XkbOverlayRowPtr row; 4845f7df2e56Smrg xkbOverlayWireDesc *olWire; 4846f7df2e56Smrg 4847f7df2e56Smrg olWire = (xkbOverlayWireDesc *) wire; 4848f7df2e56Smrg olWire->name = ol->name; 4849f7df2e56Smrg olWire->nRows = ol->num_rows; 4850f7df2e56Smrg olWire->pad1 = 0; 4851f7df2e56Smrg olWire->pad2 = 0; 4852f7df2e56Smrg if (swap) { 4853f7df2e56Smrg swapl(&olWire->name); 4854f7df2e56Smrg } 4855f7df2e56Smrg wire = (char *) &olWire[1]; 4856f7df2e56Smrg for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4857f7df2e56Smrg unsigned int k; 4858f7df2e56Smrg XkbOverlayKeyPtr key; 4859f7df2e56Smrg xkbOverlayRowWireDesc *rowWire; 4860f7df2e56Smrg 4861f7df2e56Smrg rowWire = (xkbOverlayRowWireDesc *) wire; 4862f7df2e56Smrg rowWire->rowUnder = row->row_under; 4863f7df2e56Smrg rowWire->nKeys = row->num_keys; 4864f7df2e56Smrg rowWire->pad1 = 0; 4865f7df2e56Smrg wire = (char *) &rowWire[1]; 4866f7df2e56Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4867f7df2e56Smrg xkbOverlayKeyWireDesc *keyWire; 4868f7df2e56Smrg 4869f7df2e56Smrg keyWire = (xkbOverlayKeyWireDesc *) wire; 4870f7df2e56Smrg memcpy(keyWire->over, key->over.name, XkbKeyNameLength); 4871f7df2e56Smrg memcpy(keyWire->under, key->under.name, XkbKeyNameLength); 4872f7df2e56Smrg wire = (char *) &keyWire[1]; 4873f7df2e56Smrg } 4874f7df2e56Smrg } 4875f7df2e56Smrg return wire; 487605b261ecSmrg} 487705b261ecSmrg 487805b261ecSmrgstatic int 487905b261ecSmrgXkbSizeGeomSections(XkbGeometryPtr geom) 488005b261ecSmrg{ 4881f7df2e56Smrg register int i, size; 4882f7df2e56Smrg XkbSectionPtr section; 4883f7df2e56Smrg 4884f7df2e56Smrg for (i = size = 0, section = geom->sections; i < geom->num_sections; 4885f7df2e56Smrg i++, section++) { 4886f7df2e56Smrg size += SIZEOF(xkbSectionWireDesc); 4887f7df2e56Smrg if (section->rows) { 4888f7df2e56Smrg int r; 4889f7df2e56Smrg XkbRowPtr row; 4890f7df2e56Smrg 4891f7df2e56Smrg for (r = 0, row = section->rows; r < section->num_rows; row++, r++) { 4892f7df2e56Smrg size += SIZEOF(xkbRowWireDesc); 4893f7df2e56Smrg size += row->num_keys * SIZEOF(xkbKeyWireDesc); 4894f7df2e56Smrg } 4895f7df2e56Smrg } 4896f7df2e56Smrg if (section->doodads) 4897f7df2e56Smrg size += XkbSizeGeomDoodads(section->num_doodads, section->doodads); 4898f7df2e56Smrg if (section->overlays) { 4899f7df2e56Smrg int o; 4900f7df2e56Smrg XkbOverlayPtr ol; 4901f7df2e56Smrg 4902f7df2e56Smrg for (o = 0, ol = section->overlays; o < section->num_overlays; 4903f7df2e56Smrg o++, ol++) { 4904f7df2e56Smrg int r; 4905f7df2e56Smrg XkbOverlayRowPtr row; 4906f7df2e56Smrg 4907f7df2e56Smrg size += SIZEOF(xkbOverlayWireDesc); 4908f7df2e56Smrg for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4909f7df2e56Smrg size += SIZEOF(xkbOverlayRowWireDesc); 4910f7df2e56Smrg size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc); 4911f7df2e56Smrg } 4912f7df2e56Smrg } 4913f7df2e56Smrg } 491405b261ecSmrg } 491505b261ecSmrg return size; 491605b261ecSmrg} 491705b261ecSmrg 491805b261ecSmrgstatic char * 4919f7df2e56SmrgXkbWriteGeomSections(char *wire, XkbGeometryPtr geom, Bool swap) 492005b261ecSmrg{ 4921f7df2e56Smrg register int i; 4922f7df2e56Smrg XkbSectionPtr section; 4923f7df2e56Smrg xkbSectionWireDesc *sectionWire; 4924f7df2e56Smrg 4925f7df2e56Smrg for (i = 0, section = geom->sections; i < geom->num_sections; 4926f7df2e56Smrg i++, section++) { 4927f7df2e56Smrg sectionWire = (xkbSectionWireDesc *) wire; 4928f7df2e56Smrg sectionWire->name = section->name; 4929f7df2e56Smrg sectionWire->top = section->top; 4930f7df2e56Smrg sectionWire->left = section->left; 4931f7df2e56Smrg sectionWire->width = section->width; 4932f7df2e56Smrg sectionWire->height = section->height; 4933f7df2e56Smrg sectionWire->angle = section->angle; 4934f7df2e56Smrg sectionWire->priority = section->priority; 4935f7df2e56Smrg sectionWire->nRows = section->num_rows; 4936f7df2e56Smrg sectionWire->nDoodads = section->num_doodads; 4937f7df2e56Smrg sectionWire->nOverlays = section->num_overlays; 4938f7df2e56Smrg sectionWire->pad = 0; 4939f7df2e56Smrg if (swap) { 4940f7df2e56Smrg swapl(§ionWire->name); 4941f7df2e56Smrg swaps(§ionWire->top); 4942f7df2e56Smrg swaps(§ionWire->left); 4943f7df2e56Smrg swaps(§ionWire->width); 4944f7df2e56Smrg swaps(§ionWire->height); 4945f7df2e56Smrg swaps(§ionWire->angle); 4946f7df2e56Smrg } 4947f7df2e56Smrg wire = (char *) §ionWire[1]; 4948f7df2e56Smrg if (section->rows) { 4949f7df2e56Smrg int r; 4950f7df2e56Smrg XkbRowPtr row; 4951f7df2e56Smrg xkbRowWireDesc *rowWire; 4952f7df2e56Smrg 4953f7df2e56Smrg for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 4954f7df2e56Smrg rowWire = (xkbRowWireDesc *) wire; 4955f7df2e56Smrg rowWire->top = row->top; 4956f7df2e56Smrg rowWire->left = row->left; 4957f7df2e56Smrg rowWire->nKeys = row->num_keys; 4958f7df2e56Smrg rowWire->vertical = row->vertical; 4959f7df2e56Smrg rowWire->pad = 0; 4960f7df2e56Smrg if (swap) { 4961f7df2e56Smrg swaps(&rowWire->top); 4962f7df2e56Smrg swaps(&rowWire->left); 4963f7df2e56Smrg } 4964f7df2e56Smrg wire = (char *) &rowWire[1]; 4965f7df2e56Smrg if (row->keys) { 4966f7df2e56Smrg int k; 4967f7df2e56Smrg XkbKeyPtr key; 4968f7df2e56Smrg xkbKeyWireDesc *keyWire; 4969f7df2e56Smrg 4970f7df2e56Smrg keyWire = (xkbKeyWireDesc *) wire; 4971f7df2e56Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4972f7df2e56Smrg memcpy(keyWire[k].name, key->name.name, 4973f7df2e56Smrg XkbKeyNameLength); 4974f7df2e56Smrg keyWire[k].gap = key->gap; 4975f7df2e56Smrg keyWire[k].shapeNdx = key->shape_ndx; 4976f7df2e56Smrg keyWire[k].colorNdx = key->color_ndx; 4977f7df2e56Smrg if (swap) { 4978f7df2e56Smrg swaps(&keyWire[k].gap); 4979f7df2e56Smrg } 4980f7df2e56Smrg } 4981f7df2e56Smrg wire = (char *) &keyWire[row->num_keys]; 4982f7df2e56Smrg } 4983f7df2e56Smrg } 4984f7df2e56Smrg } 4985f7df2e56Smrg if (section->doodads) { 4986f7df2e56Smrg wire = XkbWriteGeomDoodads(wire, 4987f7df2e56Smrg section->num_doodads, section->doodads, 4988f7df2e56Smrg swap); 4989f7df2e56Smrg } 4990f7df2e56Smrg if (section->overlays) { 4991f7df2e56Smrg register int o; 4992f7df2e56Smrg 4993f7df2e56Smrg for (o = 0; o < section->num_overlays; o++) { 4994f7df2e56Smrg wire = XkbWriteGeomOverlay(wire, §ion->overlays[o], swap); 4995f7df2e56Smrg } 4996f7df2e56Smrg } 499705b261ecSmrg } 499805b261ecSmrg return wire; 499905b261ecSmrg} 500005b261ecSmrg 500105b261ecSmrgstatic Status 5002f7df2e56SmrgXkbComputeGetGeometryReplySize(XkbGeometryPtr geom, 5003f7df2e56Smrg xkbGetGeometryReply * rep, Atom name) 500405b261ecSmrg{ 5005f7df2e56Smrg int len; 5006f7df2e56Smrg 5007f7df2e56Smrg if (geom != NULL) { 5008f7df2e56Smrg len = XkbSizeCountedString(geom->label_font); 5009f7df2e56Smrg len += XkbSizeGeomProperties(geom); 5010f7df2e56Smrg len += XkbSizeGeomColors(geom); 5011f7df2e56Smrg len += XkbSizeGeomShapes(geom); 5012f7df2e56Smrg len += XkbSizeGeomSections(geom); 5013f7df2e56Smrg len += XkbSizeGeomDoodads(geom->num_doodads, geom->doodads); 5014f7df2e56Smrg len += XkbSizeGeomKeyAliases(geom); 5015f7df2e56Smrg rep->length = len / 4; 5016f7df2e56Smrg rep->found = TRUE; 5017f7df2e56Smrg rep->name = geom->name; 5018f7df2e56Smrg rep->widthMM = geom->width_mm; 5019f7df2e56Smrg rep->heightMM = geom->height_mm; 5020f7df2e56Smrg rep->nProperties = geom->num_properties; 5021f7df2e56Smrg rep->nColors = geom->num_colors; 5022f7df2e56Smrg rep->nShapes = geom->num_shapes; 5023f7df2e56Smrg rep->nSections = geom->num_sections; 5024f7df2e56Smrg rep->nDoodads = geom->num_doodads; 5025f7df2e56Smrg rep->nKeyAliases = geom->num_key_aliases; 5026f7df2e56Smrg rep->baseColorNdx = XkbGeomColorIndex(geom, geom->base_color); 5027f7df2e56Smrg rep->labelColorNdx = XkbGeomColorIndex(geom, geom->label_color); 502805b261ecSmrg } 502905b261ecSmrg else { 5030f7df2e56Smrg rep->length = 0; 5031f7df2e56Smrg rep->found = FALSE; 5032f7df2e56Smrg rep->name = name; 5033f7df2e56Smrg rep->widthMM = rep->heightMM = 0; 5034f7df2e56Smrg rep->nProperties = rep->nColors = rep->nShapes = 0; 5035f7df2e56Smrg rep->nSections = rep->nDoodads = 0; 5036f7df2e56Smrg rep->nKeyAliases = 0; 5037f7df2e56Smrg rep->labelColorNdx = rep->baseColorNdx = 0; 503805b261ecSmrg } 503905b261ecSmrg return Success; 504005b261ecSmrg} 504105b261ecSmrgstatic int 5042f7df2e56SmrgXkbSendGeometry(ClientPtr client, 5043f7df2e56Smrg XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom) 504405b261ecSmrg{ 5045f7df2e56Smrg char *desc, *start; 5046f7df2e56Smrg int len; 5047f7df2e56Smrg 5048f7df2e56Smrg if (geom != NULL) { 5049f7df2e56Smrg start = desc = xallocarray(rep->length, 4); 5050f7df2e56Smrg if (!start) 5051f7df2e56Smrg return BadAlloc; 5052f7df2e56Smrg len = rep->length * 4; 5053f7df2e56Smrg desc = XkbWriteCountedString(desc, geom->label_font, client->swapped); 5054f7df2e56Smrg if (rep->nProperties > 0) 5055f7df2e56Smrg desc = XkbWriteGeomProperties(desc, geom, client->swapped); 5056f7df2e56Smrg if (rep->nColors > 0) 5057f7df2e56Smrg desc = XkbWriteGeomColors(desc, geom, client->swapped); 5058f7df2e56Smrg if (rep->nShapes > 0) 5059f7df2e56Smrg desc = XkbWriteGeomShapes(desc, geom, client->swapped); 5060f7df2e56Smrg if (rep->nSections > 0) 5061f7df2e56Smrg desc = XkbWriteGeomSections(desc, geom, client->swapped); 5062f7df2e56Smrg if (rep->nDoodads > 0) 5063f7df2e56Smrg desc = XkbWriteGeomDoodads(desc, geom->num_doodads, geom->doodads, 5064f7df2e56Smrg client->swapped); 5065f7df2e56Smrg if (rep->nKeyAliases > 0) 5066f7df2e56Smrg desc = XkbWriteGeomKeyAliases(desc, geom, client->swapped); 5067f7df2e56Smrg if ((desc - start) != (len)) { 5068f7df2e56Smrg ErrorF 5069f7df2e56Smrg ("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 5070f7df2e56Smrg len, (unsigned long) (desc - start)); 5071f7df2e56Smrg } 507205b261ecSmrg } 507305b261ecSmrg else { 5074f7df2e56Smrg len = 0; 5075f7df2e56Smrg start = NULL; 507605b261ecSmrg } 507705b261ecSmrg if (client->swapped) { 5078f7df2e56Smrg swaps(&rep->sequenceNumber); 5079f7df2e56Smrg swapl(&rep->length); 5080f7df2e56Smrg swapl(&rep->name); 5081f7df2e56Smrg swaps(&rep->widthMM); 5082f7df2e56Smrg swaps(&rep->heightMM); 5083f7df2e56Smrg swaps(&rep->nProperties); 5084f7df2e56Smrg swaps(&rep->nColors); 5085f7df2e56Smrg swaps(&rep->nShapes); 5086f7df2e56Smrg swaps(&rep->nSections); 5087f7df2e56Smrg swaps(&rep->nDoodads); 5088f7df2e56Smrg swaps(&rep->nKeyAliases); 5089f7df2e56Smrg } 5090f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetGeometryReply), rep); 5091f7df2e56Smrg if (len > 0) 5092f7df2e56Smrg WriteToClient(client, len, start); 5093f7df2e56Smrg if (start != NULL) 5094f7df2e56Smrg free((char *) start); 509505b261ecSmrg if (freeGeom) 5096f7df2e56Smrg XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 50976747b715Smrg return Success; 509805b261ecSmrg} 509905b261ecSmrg 510005b261ecSmrgint 510105b261ecSmrgProcXkbGetGeometry(ClientPtr client) 510205b261ecSmrg{ 5103f7df2e56Smrg DeviceIntPtr dev; 510405b261ecSmrg xkbGetGeometryReply rep; 5105f7df2e56Smrg XkbGeometryPtr geom; 5106f7df2e56Smrg Bool shouldFree; 5107f7df2e56Smrg Status status; 510805b261ecSmrg 510905b261ecSmrg REQUEST(xkbGetGeometryReq); 511005b261ecSmrg REQUEST_SIZE_MATCH(xkbGetGeometryReq); 511105b261ecSmrg 5112f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 5113f7df2e56Smrg return BadAccess; 511405b261ecSmrg 51154642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 511605b261ecSmrg CHK_ATOM_OR_NONE(stuff->name); 511705b261ecSmrg 5118f7df2e56Smrg geom = XkbLookupNamedGeometry(dev, stuff->name, &shouldFree); 5119f7df2e56Smrg rep = (xkbGetGeometryReply) { 5120f7df2e56Smrg .type = X_Reply, 5121f7df2e56Smrg .deviceID = dev->id, 5122f7df2e56Smrg .sequenceNumber = client->sequence, 5123f7df2e56Smrg .length = 0 5124f7df2e56Smrg }; 5125f7df2e56Smrg status = XkbComputeGetGeometryReplySize(geom, &rep, stuff->name); 5126f7df2e56Smrg if (status != Success) 5127f7df2e56Smrg return status; 5128f7df2e56Smrg else 5129f7df2e56Smrg return XkbSendGeometry(client, geom, &rep, shouldFree); 513005b261ecSmrg} 513105b261ecSmrg 513205b261ecSmrg/***====================================================================***/ 513305b261ecSmrg 51341e26616aSmrgstatic Status 51351e26616aSmrg_GetCountedString(char **wire_inout, ClientPtr client, char **str) 513605b261ecSmrg{ 51371e26616aSmrg char *wire, *next; 51381e26616aSmrg CARD16 len; 513905b261ecSmrg 51401e26616aSmrg wire = *wire_inout; 51411e26616aSmrg len = *(CARD16 *) wire; 51421e26616aSmrg if (client->swapped) { 5143f7df2e56Smrg swaps(&len); 514405b261ecSmrg } 51451e26616aSmrg next = wire + XkbPaddedSize(len + 2); 51461e26616aSmrg /* Check we're still within the size of the request */ 51471e26616aSmrg if (client->req_len < 51481e26616aSmrg bytes_to_int32(next - (char *) client->requestBuffer)) 51491e26616aSmrg return BadValue; 51501e26616aSmrg *str = malloc(len + 1); 51511e26616aSmrg if (!*str) 51521e26616aSmrg return BadAlloc; 51531e26616aSmrg memcpy(*str, &wire[2], len); 51541e26616aSmrg *(*str + len) = '\0'; 51551e26616aSmrg *wire_inout = next; 51561e26616aSmrg return Success; 515705b261ecSmrg} 515805b261ecSmrg 515905b261ecSmrgstatic Status 5160f7df2e56Smrg_CheckSetDoodad(char **wire_inout, 5161f7df2e56Smrg XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 516205b261ecSmrg{ 5163f7df2e56Smrg char *wire; 5164f7df2e56Smrg xkbDoodadWireDesc *dWire; 5165f7df2e56Smrg xkbAnyDoodadWireDesc any; 5166f7df2e56Smrg xkbTextDoodadWireDesc text; 5167f7df2e56Smrg XkbDoodadPtr doodad; 51681e26616aSmrg Status status; 516905b261ecSmrg 5170f7df2e56Smrg dWire = (xkbDoodadWireDesc *) (*wire_inout); 5171f7df2e56Smrg any = dWire->any; 5172f7df2e56Smrg wire = (char *) &dWire[1]; 517305b261ecSmrg if (client->swapped) { 5174f7df2e56Smrg swapl(&any.name); 5175f7df2e56Smrg swaps(&any.top); 5176f7df2e56Smrg swaps(&any.left); 5177f7df2e56Smrg swaps(&any.angle); 517805b261ecSmrg } 517905b261ecSmrg CHK_ATOM_ONLY(dWire->any.name); 5180f7df2e56Smrg doodad = XkbAddGeomDoodad(geom, section, any.name); 518105b261ecSmrg if (!doodad) 5182f7df2e56Smrg return BadAlloc; 5183f7df2e56Smrg doodad->any.type = dWire->any.type; 5184f7df2e56Smrg doodad->any.priority = dWire->any.priority; 5185f7df2e56Smrg doodad->any.top = any.top; 5186f7df2e56Smrg doodad->any.left = any.left; 5187f7df2e56Smrg doodad->any.angle = any.angle; 518805b261ecSmrg switch (doodad->any.type) { 5189f7df2e56Smrg case XkbOutlineDoodad: 5190f7df2e56Smrg case XkbSolidDoodad: 5191f7df2e56Smrg if (dWire->shape.colorNdx >= geom->num_colors) { 5192f7df2e56Smrg client->errorValue = _XkbErrCode3(0x40, geom->num_colors, 5193f7df2e56Smrg dWire->shape.colorNdx); 5194f7df2e56Smrg return BadMatch; 5195f7df2e56Smrg } 5196f7df2e56Smrg if (dWire->shape.shapeNdx >= geom->num_shapes) { 5197f7df2e56Smrg client->errorValue = _XkbErrCode3(0x41, geom->num_shapes, 5198f7df2e56Smrg dWire->shape.shapeNdx); 5199f7df2e56Smrg return BadMatch; 5200f7df2e56Smrg } 5201f7df2e56Smrg doodad->shape.color_ndx = dWire->shape.colorNdx; 5202f7df2e56Smrg doodad->shape.shape_ndx = dWire->shape.shapeNdx; 5203f7df2e56Smrg break; 5204f7df2e56Smrg case XkbTextDoodad: 5205f7df2e56Smrg if (dWire->text.colorNdx >= geom->num_colors) { 5206f7df2e56Smrg client->errorValue = _XkbErrCode3(0x42, geom->num_colors, 5207f7df2e56Smrg dWire->text.colorNdx); 5208f7df2e56Smrg return BadMatch; 5209f7df2e56Smrg } 5210f7df2e56Smrg text = dWire->text; 5211f7df2e56Smrg if (client->swapped) { 5212f7df2e56Smrg swaps(&text.width); 5213f7df2e56Smrg swaps(&text.height); 5214f7df2e56Smrg } 5215f7df2e56Smrg doodad->text.width = text.width; 5216f7df2e56Smrg doodad->text.height = text.height; 5217f7df2e56Smrg doodad->text.color_ndx = dWire->text.colorNdx; 5218f7df2e56Smrg status = _GetCountedString(&wire, client, &doodad->text.text); 5219f7df2e56Smrg if (status != Success) 5220f7df2e56Smrg return status; 5221f7df2e56Smrg status = _GetCountedString(&wire, client, &doodad->text.font); 5222f7df2e56Smrg if (status != Success) { 5223f7df2e56Smrg free (doodad->text.text); 5224f7df2e56Smrg return status; 5225f7df2e56Smrg } 5226f7df2e56Smrg break; 5227f7df2e56Smrg case XkbIndicatorDoodad: 5228f7df2e56Smrg if (dWire->indicator.onColorNdx >= geom->num_colors) { 5229f7df2e56Smrg client->errorValue = _XkbErrCode3(0x43, geom->num_colors, 5230f7df2e56Smrg dWire->indicator.onColorNdx); 5231f7df2e56Smrg return BadMatch; 5232f7df2e56Smrg } 5233f7df2e56Smrg if (dWire->indicator.offColorNdx >= geom->num_colors) { 5234f7df2e56Smrg client->errorValue = _XkbErrCode3(0x44, geom->num_colors, 5235f7df2e56Smrg dWire->indicator.offColorNdx); 5236f7df2e56Smrg return BadMatch; 5237f7df2e56Smrg } 5238f7df2e56Smrg if (dWire->indicator.shapeNdx >= geom->num_shapes) { 5239f7df2e56Smrg client->errorValue = _XkbErrCode3(0x45, geom->num_shapes, 5240f7df2e56Smrg dWire->indicator.shapeNdx); 5241f7df2e56Smrg return BadMatch; 5242f7df2e56Smrg } 5243f7df2e56Smrg doodad->indicator.shape_ndx = dWire->indicator.shapeNdx; 5244f7df2e56Smrg doodad->indicator.on_color_ndx = dWire->indicator.onColorNdx; 5245f7df2e56Smrg doodad->indicator.off_color_ndx = dWire->indicator.offColorNdx; 5246f7df2e56Smrg break; 5247f7df2e56Smrg case XkbLogoDoodad: 5248f7df2e56Smrg if (dWire->logo.colorNdx >= geom->num_colors) { 5249f7df2e56Smrg client->errorValue = _XkbErrCode3(0x46, geom->num_colors, 5250f7df2e56Smrg dWire->logo.colorNdx); 5251f7df2e56Smrg return BadMatch; 5252f7df2e56Smrg } 5253f7df2e56Smrg if (dWire->logo.shapeNdx >= geom->num_shapes) { 5254f7df2e56Smrg client->errorValue = _XkbErrCode3(0x47, geom->num_shapes, 5255f7df2e56Smrg dWire->logo.shapeNdx); 5256f7df2e56Smrg return BadMatch; 5257f7df2e56Smrg } 5258f7df2e56Smrg doodad->logo.color_ndx = dWire->logo.colorNdx; 5259f7df2e56Smrg doodad->logo.shape_ndx = dWire->logo.shapeNdx; 5260f7df2e56Smrg status = _GetCountedString(&wire, client, &doodad->logo.logo_name); 5261f7df2e56Smrg if (status != Success) 5262f7df2e56Smrg return status; 5263f7df2e56Smrg break; 5264f7df2e56Smrg default: 5265f7df2e56Smrg client->errorValue = _XkbErrCode2(0x4F, dWire->any.type); 5266f7df2e56Smrg return BadValue; 5267f7df2e56Smrg } 5268f7df2e56Smrg *wire_inout = wire; 5269f7df2e56Smrg return Success; 5270f7df2e56Smrg} 5271f7df2e56Smrg 5272f7df2e56Smrgstatic Status 5273f7df2e56Smrg_CheckSetOverlay(char **wire_inout, 5274f7df2e56Smrg XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 527505b261ecSmrg{ 5276f7df2e56Smrg register int r; 5277f7df2e56Smrg char *wire; 5278f7df2e56Smrg XkbOverlayPtr ol; 5279f7df2e56Smrg xkbOverlayWireDesc *olWire; 5280f7df2e56Smrg xkbOverlayRowWireDesc *rWire; 528105b261ecSmrg 5282f7df2e56Smrg wire = *wire_inout; 5283f7df2e56Smrg olWire = (xkbOverlayWireDesc *) wire; 5284f7df2e56Smrg if (client->swapped) { 5285f7df2e56Smrg swapl(&olWire->name); 5286f7df2e56Smrg } 5287f7df2e56Smrg CHK_ATOM_ONLY(olWire->name); 5288f7df2e56Smrg ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows); 5289f7df2e56Smrg rWire = (xkbOverlayRowWireDesc *) &olWire[1]; 5290f7df2e56Smrg for (r = 0; r < olWire->nRows; r++) { 5291f7df2e56Smrg register int k; 5292f7df2e56Smrg xkbOverlayKeyWireDesc *kWire; 5293f7df2e56Smrg XkbOverlayRowPtr row; 5294f7df2e56Smrg 5295f7df2e56Smrg if (rWire->rowUnder > section->num_rows) { 5296f7df2e56Smrg client->errorValue = _XkbErrCode4(0x20, r, section->num_rows, 5297f7df2e56Smrg rWire->rowUnder); 5298f7df2e56Smrg return BadMatch; 5299f7df2e56Smrg } 5300f7df2e56Smrg row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys); 5301f7df2e56Smrg kWire = (xkbOverlayKeyWireDesc *) &rWire[1]; 5302f7df2e56Smrg for (k = 0; k < rWire->nKeys; k++, kWire++) { 5303f7df2e56Smrg if (XkbAddGeomOverlayKey(ol, row, 5304f7df2e56Smrg (char *) kWire->over, 5305f7df2e56Smrg (char *) kWire->under) == NULL) { 5306f7df2e56Smrg client->errorValue = _XkbErrCode3(0x21, r, k); 5307f7df2e56Smrg return BadMatch; 5308f7df2e56Smrg } 5309f7df2e56Smrg } 5310f7df2e56Smrg rWire = (xkbOverlayRowWireDesc *) kWire; 5311f7df2e56Smrg } 5312f7df2e56Smrg olWire = (xkbOverlayWireDesc *) rWire; 5313f7df2e56Smrg wire = (char *) olWire; 5314f7df2e56Smrg *wire_inout = wire; 5315f7df2e56Smrg return Success; 5316f7df2e56Smrg} 5317f7df2e56Smrg 5318f7df2e56Smrgstatic Status 5319f7df2e56Smrg_CheckSetSections(XkbGeometryPtr geom, 5320f7df2e56Smrg xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5321f7df2e56Smrg{ 5322f7df2e56Smrg Status status; 5323f7df2e56Smrg register int s; 5324f7df2e56Smrg char *wire; 5325f7df2e56Smrg xkbSectionWireDesc *sWire; 5326f7df2e56Smrg XkbSectionPtr section; 5327f7df2e56Smrg 5328f7df2e56Smrg wire = *wire_inout; 5329f7df2e56Smrg if (req->nSections < 1) 5330f7df2e56Smrg return Success; 5331f7df2e56Smrg sWire = (xkbSectionWireDesc *) wire; 5332f7df2e56Smrg for (s = 0; s < req->nSections; s++) { 5333f7df2e56Smrg register int r; 5334f7df2e56Smrg xkbRowWireDesc *rWire; 5335f7df2e56Smrg 5336f7df2e56Smrg if (client->swapped) { 5337f7df2e56Smrg swapl(&sWire->name); 5338f7df2e56Smrg swaps(&sWire->top); 5339f7df2e56Smrg swaps(&sWire->left); 5340f7df2e56Smrg swaps(&sWire->width); 5341f7df2e56Smrg swaps(&sWire->height); 5342f7df2e56Smrg swaps(&sWire->angle); 5343f7df2e56Smrg } 5344f7df2e56Smrg CHK_ATOM_ONLY(sWire->name); 5345f7df2e56Smrg section = XkbAddGeomSection(geom, sWire->name, sWire->nRows, 5346f7df2e56Smrg sWire->nDoodads, sWire->nOverlays); 5347f7df2e56Smrg if (!section) 5348f7df2e56Smrg return BadAlloc; 5349f7df2e56Smrg section->priority = sWire->priority; 5350f7df2e56Smrg section->top = sWire->top; 5351f7df2e56Smrg section->left = sWire->left; 5352f7df2e56Smrg section->width = sWire->width; 5353f7df2e56Smrg section->height = sWire->height; 5354f7df2e56Smrg section->angle = sWire->angle; 5355f7df2e56Smrg rWire = (xkbRowWireDesc *) &sWire[1]; 5356f7df2e56Smrg for (r = 0; r < sWire->nRows; r++) { 5357f7df2e56Smrg register int k; 5358f7df2e56Smrg XkbRowPtr row; 5359f7df2e56Smrg xkbKeyWireDesc *kWire; 5360f7df2e56Smrg 5361f7df2e56Smrg if (client->swapped) { 5362f7df2e56Smrg swaps(&rWire->top); 5363f7df2e56Smrg swaps(&rWire->left); 5364f7df2e56Smrg } 5365f7df2e56Smrg row = XkbAddGeomRow(section, rWire->nKeys); 5366f7df2e56Smrg if (!row) 5367f7df2e56Smrg return BadAlloc; 5368f7df2e56Smrg row->top = rWire->top; 5369f7df2e56Smrg row->left = rWire->left; 5370f7df2e56Smrg row->vertical = rWire->vertical; 5371f7df2e56Smrg kWire = (xkbKeyWireDesc *) &rWire[1]; 5372f7df2e56Smrg for (k = 0; k < rWire->nKeys; k++) { 5373f7df2e56Smrg XkbKeyPtr key; 5374f7df2e56Smrg 5375f7df2e56Smrg key = XkbAddGeomKey(row); 5376f7df2e56Smrg if (!key) 5377f7df2e56Smrg return BadAlloc; 5378f7df2e56Smrg memcpy(key->name.name, kWire[k].name, XkbKeyNameLength); 5379f7df2e56Smrg key->gap = kWire[k].gap; 5380f7df2e56Smrg key->shape_ndx = kWire[k].shapeNdx; 5381f7df2e56Smrg key->color_ndx = kWire[k].colorNdx; 5382f7df2e56Smrg if (key->shape_ndx >= geom->num_shapes) { 5383f7df2e56Smrg client->errorValue = _XkbErrCode3(0x10, key->shape_ndx, 5384f7df2e56Smrg geom->num_shapes); 5385f7df2e56Smrg return BadMatch; 5386f7df2e56Smrg } 5387f7df2e56Smrg if (key->color_ndx >= geom->num_colors) { 5388f7df2e56Smrg client->errorValue = _XkbErrCode3(0x11, key->color_ndx, 5389f7df2e56Smrg geom->num_colors); 5390f7df2e56Smrg return BadMatch; 5391f7df2e56Smrg } 5392f7df2e56Smrg } 5393f7df2e56Smrg rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys]; 5394f7df2e56Smrg } 5395f7df2e56Smrg wire = (char *) rWire; 5396f7df2e56Smrg if (sWire->nDoodads > 0) { 5397f7df2e56Smrg register int d; 5398f7df2e56Smrg 5399f7df2e56Smrg for (d = 0; d < sWire->nDoodads; d++) { 5400f7df2e56Smrg status = _CheckSetDoodad(&wire, geom, section, client); 5401f7df2e56Smrg if (status != Success) 5402f7df2e56Smrg return status; 5403f7df2e56Smrg } 5404f7df2e56Smrg } 5405f7df2e56Smrg if (sWire->nOverlays > 0) { 5406f7df2e56Smrg register int o; 5407f7df2e56Smrg 5408f7df2e56Smrg for (o = 0; o < sWire->nOverlays; o++) { 5409f7df2e56Smrg status = _CheckSetOverlay(&wire, geom, section, client); 5410f7df2e56Smrg if (status != Success) 5411f7df2e56Smrg return status; 5412f7df2e56Smrg } 5413f7df2e56Smrg } 5414f7df2e56Smrg sWire = (xkbSectionWireDesc *) wire; 5415f7df2e56Smrg } 5416f7df2e56Smrg wire = (char *) sWire; 5417f7df2e56Smrg *wire_inout = wire; 5418f7df2e56Smrg return Success; 5419f7df2e56Smrg} 5420f7df2e56Smrg 5421f7df2e56Smrgstatic Status 5422f7df2e56Smrg_CheckSetShapes(XkbGeometryPtr geom, 5423f7df2e56Smrg xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5424f7df2e56Smrg{ 5425f7df2e56Smrg register int i; 5426f7df2e56Smrg char *wire; 5427f7df2e56Smrg 5428f7df2e56Smrg wire = *wire_inout; 5429f7df2e56Smrg if (req->nShapes < 1) { 5430f7df2e56Smrg client->errorValue = _XkbErrCode2(0x06, req->nShapes); 5431f7df2e56Smrg return BadValue; 543205b261ecSmrg } 543305b261ecSmrg else { 5434f7df2e56Smrg xkbShapeWireDesc *shapeWire; 5435f7df2e56Smrg XkbShapePtr shape; 5436f7df2e56Smrg register int o; 5437f7df2e56Smrg 5438f7df2e56Smrg shapeWire = (xkbShapeWireDesc *) wire; 5439f7df2e56Smrg for (i = 0; i < req->nShapes; i++) { 5440f7df2e56Smrg xkbOutlineWireDesc *olWire; 5441f7df2e56Smrg XkbOutlinePtr ol; 5442f7df2e56Smrg 5443f7df2e56Smrg shape = 5444f7df2e56Smrg XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); 5445f7df2e56Smrg if (!shape) 5446f7df2e56Smrg return BadAlloc; 5447f7df2e56Smrg olWire = (xkbOutlineWireDesc *) (&shapeWire[1]); 5448f7df2e56Smrg for (o = 0; o < shapeWire->nOutlines; o++) { 5449f7df2e56Smrg register int p; 5450f7df2e56Smrg XkbPointPtr pt; 5451f7df2e56Smrg xkbPointWireDesc *ptWire; 5452f7df2e56Smrg 5453f7df2e56Smrg ol = XkbAddGeomOutline(shape, olWire->nPoints); 5454f7df2e56Smrg if (!ol) 5455f7df2e56Smrg return BadAlloc; 5456f7df2e56Smrg ol->corner_radius = olWire->cornerRadius; 5457f7df2e56Smrg ptWire = (xkbPointWireDesc *) &olWire[1]; 5458f7df2e56Smrg for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { 5459f7df2e56Smrg pt->x = ptWire[p].x; 5460f7df2e56Smrg pt->y = ptWire[p].y; 5461f7df2e56Smrg if (client->swapped) { 5462f7df2e56Smrg swaps(&pt->x); 5463f7df2e56Smrg swaps(&pt->y); 5464f7df2e56Smrg } 5465f7df2e56Smrg } 5466f7df2e56Smrg ol->num_points = olWire->nPoints; 5467f7df2e56Smrg olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]); 5468f7df2e56Smrg } 5469f7df2e56Smrg if (shapeWire->primaryNdx != XkbNoShape) 5470f7df2e56Smrg shape->primary = &shape->outlines[shapeWire->primaryNdx]; 5471f7df2e56Smrg if (shapeWire->approxNdx != XkbNoShape) 5472f7df2e56Smrg shape->approx = &shape->outlines[shapeWire->approxNdx]; 5473f7df2e56Smrg shapeWire = (xkbShapeWireDesc *) olWire; 5474f7df2e56Smrg } 5475f7df2e56Smrg wire = (char *) shapeWire; 5476f7df2e56Smrg } 5477f7df2e56Smrg if (geom->num_shapes != req->nShapes) { 5478f7df2e56Smrg client->errorValue = _XkbErrCode3(0x07, geom->num_shapes, req->nShapes); 5479f7df2e56Smrg return BadMatch; 5480f7df2e56Smrg } 5481f7df2e56Smrg 5482f7df2e56Smrg *wire_inout = wire; 548305b261ecSmrg return Success; 548405b261ecSmrg} 548505b261ecSmrg 548605b261ecSmrgstatic Status 5487f7df2e56Smrg_CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client) 548805b261ecSmrg{ 5489f7df2e56Smrg register int i; 5490f7df2e56Smrg Status status; 5491f7df2e56Smrg char *wire; 549205b261ecSmrg 5493f7df2e56Smrg wire = (char *) &req[1]; 54941e26616aSmrg status = _GetCountedString(&wire, client, &geom->label_font); 54951e26616aSmrg if (status != Success) 54961e26616aSmrg return status; 54971e26616aSmrg 54981e26616aSmrg for (i = 0; i < req->nProperties; i++) { 5499f7df2e56Smrg char *name, *val; 55001e26616aSmrg 55011e26616aSmrg status = _GetCountedString(&wire, client, &name); 55021e26616aSmrg if (status != Success) 55031e26616aSmrg return status; 55041e26616aSmrg status = _GetCountedString(&wire, client, &val); 55051e26616aSmrg if (status != Success) { 55066747b715Smrg free(name); 55071e26616aSmrg return status; 550805b261ecSmrg } 5509f7df2e56Smrg if (XkbAddGeomProperty(geom, name, val) == NULL) { 55106747b715Smrg free(name); 55116747b715Smrg free(val); 5512f7df2e56Smrg return BadAlloc; 551305b261ecSmrg } 55146747b715Smrg free(name); 55156747b715Smrg free(val); 551605b261ecSmrg } 551705b261ecSmrg 5518f7df2e56Smrg if (req->nColors < 2) { 5519f7df2e56Smrg client->errorValue = _XkbErrCode3(0x01, 2, req->nColors); 5520f7df2e56Smrg return BadValue; 552105b261ecSmrg } 5522f7df2e56Smrg if (req->baseColorNdx > req->nColors) { 5523f7df2e56Smrg client->errorValue = 5524f7df2e56Smrg _XkbErrCode3(0x03, req->nColors, req->baseColorNdx); 5525f7df2e56Smrg return BadMatch; 552605b261ecSmrg } 5527f7df2e56Smrg if (req->labelColorNdx > req->nColors) { 5528f7df2e56Smrg client->errorValue = 5529f7df2e56Smrg _XkbErrCode3(0x03, req->nColors, req->labelColorNdx); 5530f7df2e56Smrg return BadMatch; 553105b261ecSmrg } 5532f7df2e56Smrg if (req->labelColorNdx == req->baseColorNdx) { 5533f7df2e56Smrg client->errorValue = _XkbErrCode3(0x04, req->baseColorNdx, 5534f7df2e56Smrg req->labelColorNdx); 5535f7df2e56Smrg return BadMatch; 553605b261ecSmrg } 553705b261ecSmrg 55381e26616aSmrg for (i = 0; i < req->nColors; i++) { 5539f7df2e56Smrg char *name; 5540f7df2e56Smrg 55411e26616aSmrg status = _GetCountedString(&wire, client, &name); 55421e26616aSmrg if (status != Success) 55431e26616aSmrg return status; 5544f7df2e56Smrg if (!XkbAddGeomColor(geom, name, geom->num_colors)) { 55456747b715Smrg free(name); 5546f7df2e56Smrg return BadAlloc; 554705b261ecSmrg } 55486747b715Smrg free(name); 554905b261ecSmrg } 5550f7df2e56Smrg if (req->nColors != geom->num_colors) { 5551f7df2e56Smrg client->errorValue = _XkbErrCode3(0x05, req->nColors, geom->num_colors); 5552f7df2e56Smrg return BadMatch; 555305b261ecSmrg } 5554f7df2e56Smrg geom->label_color = &geom->colors[req->labelColorNdx]; 5555f7df2e56Smrg geom->base_color = &geom->colors[req->baseColorNdx]; 555605b261ecSmrg 5557f7df2e56Smrg if ((status = _CheckSetShapes(geom, req, &wire, client)) != Success) 5558f7df2e56Smrg return status; 555905b261ecSmrg 5560f7df2e56Smrg if ((status = _CheckSetSections(geom, req, &wire, client)) != Success) 5561f7df2e56Smrg return status; 556205b261ecSmrg 5563f7df2e56Smrg for (i = 0; i < req->nDoodads; i++) { 5564f7df2e56Smrg status = _CheckSetDoodad(&wire, geom, NULL, client); 5565f7df2e56Smrg if (status != Success) 5566f7df2e56Smrg return status; 556705b261ecSmrg } 556805b261ecSmrg 5569f7df2e56Smrg for (i = 0; i < req->nKeyAliases; i++) { 5570f7df2e56Smrg if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL) 5571f7df2e56Smrg return BadAlloc; 5572f7df2e56Smrg wire += 2 * XkbKeyNameLength; 557305b261ecSmrg } 557405b261ecSmrg return Success; 557505b261ecSmrg} 557605b261ecSmrg 55774642e01fSmrgstatic int 5578f7df2e56Smrg_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq * stuff) 557905b261ecSmrg{ 5580f7df2e56Smrg XkbDescPtr xkb; 5581f7df2e56Smrg Bool new_name; 5582f7df2e56Smrg xkbNewKeyboardNotify nkn; 5583f7df2e56Smrg XkbGeometryPtr geom, old; 5584f7df2e56Smrg XkbGeometrySizesRec sizes; 5585f7df2e56Smrg Status status; 5586f7df2e56Smrg 5587f7df2e56Smrg xkb = dev->key->xkbInfo->desc; 5588f7df2e56Smrg old = xkb->geom; 5589f7df2e56Smrg xkb->geom = NULL; 5590f7df2e56Smrg 5591f7df2e56Smrg sizes.which = XkbGeomAllMask; 5592f7df2e56Smrg sizes.num_properties = stuff->nProperties; 5593f7df2e56Smrg sizes.num_colors = stuff->nColors; 5594f7df2e56Smrg sizes.num_shapes = stuff->nShapes; 5595f7df2e56Smrg sizes.num_sections = stuff->nSections; 5596f7df2e56Smrg sizes.num_doodads = stuff->nDoodads; 5597f7df2e56Smrg sizes.num_key_aliases = stuff->nKeyAliases; 5598f7df2e56Smrg if ((status = XkbAllocGeometry(xkb, &sizes)) != Success) { 5599f7df2e56Smrg xkb->geom = old; 56004642e01fSmrg return status; 560105b261ecSmrg } 5602f7df2e56Smrg geom = xkb->geom; 5603f7df2e56Smrg geom->name = stuff->name; 5604f7df2e56Smrg geom->width_mm = stuff->widthMM; 5605f7df2e56Smrg geom->height_mm = stuff->heightMM; 5606f7df2e56Smrg if ((status = _CheckSetGeom(geom, stuff, client)) != Success) { 5607f7df2e56Smrg XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 5608f7df2e56Smrg xkb->geom = old; 56094642e01fSmrg return status; 561005b261ecSmrg } 5611f7df2e56Smrg new_name = (xkb->names->geometry != geom->name); 5612f7df2e56Smrg xkb->names->geometry = geom->name; 561305b261ecSmrg if (old) 5614f7df2e56Smrg XkbFreeGeometry(old, XkbGeomAllMask, TRUE); 561505b261ecSmrg if (new_name) { 5616f7df2e56Smrg xkbNamesNotify nn; 5617f7df2e56Smrg 56186747b715Smrg memset(&nn, 0, sizeof(xkbNamesNotify)); 5619f7df2e56Smrg nn.changed = XkbGeometryNameMask; 5620f7df2e56Smrg XkbSendNamesNotify(dev, &nn); 5621f7df2e56Smrg } 5622f7df2e56Smrg nkn.deviceID = nkn.oldDeviceID = dev->id; 5623f7df2e56Smrg nkn.minKeyCode = nkn.oldMinKeyCode = xkb->min_key_code; 5624f7df2e56Smrg nkn.maxKeyCode = nkn.oldMaxKeyCode = xkb->max_key_code; 5625f7df2e56Smrg nkn.requestMajor = XkbReqCode; 5626f7df2e56Smrg nkn.requestMinor = X_kbSetGeometry; 5627f7df2e56Smrg nkn.changed = XkbNKN_GeometryMask; 5628f7df2e56Smrg XkbSendNewKeyboardNotify(dev, &nkn); 562905b261ecSmrg return Success; 563005b261ecSmrg} 563105b261ecSmrg 56324642e01fSmrgint 56334642e01fSmrgProcXkbSetGeometry(ClientPtr client) 56344642e01fSmrg{ 5635f7df2e56Smrg DeviceIntPtr dev; 5636f7df2e56Smrg int rc; 56374642e01fSmrg 56384642e01fSmrg REQUEST(xkbSetGeometryReq); 56394642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 56404642e01fSmrg 5641f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 5642f7df2e56Smrg return BadAccess; 56434642e01fSmrg 56444642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 56454642e01fSmrg CHK_ATOM_OR_NONE(stuff->name); 56464642e01fSmrg 56474642e01fSmrg rc = _XkbSetGeometry(client, dev, stuff); 56484642e01fSmrg if (rc != Success) 56494642e01fSmrg return rc; 56504642e01fSmrg 5651f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd) { 56524642e01fSmrg DeviceIntPtr other; 5653f7df2e56Smrg 5654f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 5655f7df2e56Smrg if ((other != dev) && other->key && !IsMaster(other) && 5656f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) { 5657f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 5658f7df2e56Smrg DixManageAccess); 56594642e01fSmrg if (rc == Success) 56604642e01fSmrg _XkbSetGeometry(client, other, stuff); 56614642e01fSmrg } 56624642e01fSmrg } 56634642e01fSmrg } 56644642e01fSmrg 56654642e01fSmrg return Success; 56664642e01fSmrg} 56674642e01fSmrg 566805b261ecSmrg/***====================================================================***/ 566905b261ecSmrg 567005b261ecSmrgint 567105b261ecSmrgProcXkbPerClientFlags(ClientPtr client) 567205b261ecSmrg{ 5673f7df2e56Smrg DeviceIntPtr dev; 5674f7df2e56Smrg xkbPerClientFlagsReply rep; 5675f7df2e56Smrg XkbInterestPtr interest; 56764642e01fSmrg Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 567705b261ecSmrg 567805b261ecSmrg REQUEST(xkbPerClientFlagsReq); 567905b261ecSmrg REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 568005b261ecSmrg 5681f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 5682f7df2e56Smrg return BadAccess; 568305b261ecSmrg 56844642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5685f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->change, XkbPCF_AllFlagsMask); 5686f7df2e56Smrg CHK_MASK_MATCH(0x02, stuff->change, stuff->value); 568705b261ecSmrg 5688f7df2e56Smrg interest = XkbFindClientResource((DevicePtr) dev, client); 568905b261ecSmrg if (stuff->change) { 5690f7df2e56Smrg client->xkbClientFlags &= ~stuff->change; 5691f7df2e56Smrg client->xkbClientFlags |= stuff->value; 569205b261ecSmrg } 5693f7df2e56Smrg if (stuff->change & XkbPCF_AutoResetControlsMask) { 5694f7df2e56Smrg Bool want; 5695f7df2e56Smrg 5696f7df2e56Smrg want = stuff->value & XkbPCF_AutoResetControlsMask; 5697f7df2e56Smrg if (interest && !want) { 5698f7df2e56Smrg interest->autoCtrls = interest->autoCtrlValues = 0; 5699f7df2e56Smrg } 5700f7df2e56Smrg else if (want && (!interest)) { 5701f7df2e56Smrg XID id = FakeClientID(client->index); 5702f7df2e56Smrg 5703f7df2e56Smrg if (!AddResource(id, RT_XKBCLIENT, dev)) 5704f7df2e56Smrg return BadAlloc; 5705f7df2e56Smrg interest = XkbAddClientResource((DevicePtr) dev, client, id); 5706f7df2e56Smrg if (!interest) 5707f7df2e56Smrg return BadAlloc; 5708f7df2e56Smrg } 5709f7df2e56Smrg if (interest && want) { 5710f7df2e56Smrg register unsigned affect; 5711f7df2e56Smrg 5712f7df2e56Smrg affect = stuff->ctrlsToChange; 5713f7df2e56Smrg 5714f7df2e56Smrg CHK_MASK_LEGAL(0x03, affect, XkbAllBooleanCtrlsMask); 5715f7df2e56Smrg CHK_MASK_MATCH(0x04, affect, stuff->autoCtrls); 5716f7df2e56Smrg CHK_MASK_MATCH(0x05, stuff->autoCtrls, stuff->autoCtrlValues); 5717f7df2e56Smrg 5718f7df2e56Smrg interest->autoCtrls &= ~affect; 5719f7df2e56Smrg interest->autoCtrlValues &= ~affect; 5720f7df2e56Smrg interest->autoCtrls |= stuff->autoCtrls & affect; 5721f7df2e56Smrg interest->autoCtrlValues |= stuff->autoCtrlValues & affect; 5722f7df2e56Smrg } 572305b261ecSmrg } 5724f7df2e56Smrg 5725f7df2e56Smrg rep = (xkbPerClientFlagsReply) { 5726f7df2e56Smrg .type = X_Reply, 5727f7df2e56Smrg .sequenceNumber = client->sequence, 5728f7df2e56Smrg .length = 0, 5729f7df2e56Smrg .supported = XkbPCF_AllFlagsMask, 5730f7df2e56Smrg .value = client->xkbClientFlags & XkbPCF_AllFlagsMask, 5731f7df2e56Smrg .autoCtrls = interest ? interest->autoCtrls : 0, 5732f7df2e56Smrg .autoCtrlValues = interest ? interest->autoCtrlValues : 0, 5733f7df2e56Smrg }; 5734f7df2e56Smrg if (client->swapped) { 5735f7df2e56Smrg swaps(&rep.sequenceNumber); 5736f7df2e56Smrg swapl(&rep.supported); 5737f7df2e56Smrg swapl(&rep.value); 5738f7df2e56Smrg swapl(&rep.autoCtrls); 5739f7df2e56Smrg swapl(&rep.autoCtrlValues); 574005b261ecSmrg } 5741f7df2e56Smrg WriteToClient(client, SIZEOF(xkbPerClientFlagsReply), &rep); 57426747b715Smrg return Success; 574305b261ecSmrg} 574405b261ecSmrg 574505b261ecSmrg/***====================================================================***/ 574605b261ecSmrg 574705b261ecSmrg/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 574805b261ecSmrg/* and wildcards */ 574905b261ecSmrgstatic unsigned char componentSpecLegal[] = { 5750f7df2e56Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 5751f7df2e56Smrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 5752f7df2e56Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5753f7df2e56Smrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 575405b261ecSmrg}; 575505b261ecSmrg 575605b261ecSmrg/* same as above but accepts percent, plus and bar too */ 575705b261ecSmrgstatic unsigned char componentExprLegal[] = { 5758f7df2e56Smrg 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 5759f7df2e56Smrg 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 5760f7df2e56Smrg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5761f7df2e56Smrg 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 576205b261ecSmrg}; 576305b261ecSmrg 576405b261ecSmrgstatic char * 5765f7df2e56SmrgGetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn) 576605b261ecSmrg{ 5767f7df2e56Smrg int len; 5768f7df2e56Smrg register int i; 5769f7df2e56Smrg unsigned char *wire, *str, *tmp, *legal; 5770f7df2e56Smrg 5771f7df2e56Smrg if (allowExpr) 5772f7df2e56Smrg legal = &componentExprLegal[0]; 5773f7df2e56Smrg else 5774f7df2e56Smrg legal = &componentSpecLegal[0]; 5775f7df2e56Smrg 5776f7df2e56Smrg wire = *pWire; 5777f7df2e56Smrg len = (*(unsigned char *) wire++); 5778f7df2e56Smrg if (len > 0) { 5779f7df2e56Smrg str = calloc(1, len + 1); 5780f7df2e56Smrg if (str) { 5781f7df2e56Smrg tmp = str; 5782f7df2e56Smrg for (i = 0; i < len; i++) { 5783f7df2e56Smrg if (legal[(*wire) / 8] & (1 << ((*wire) % 8))) 5784f7df2e56Smrg *tmp++ = *wire++; 5785f7df2e56Smrg else 5786f7df2e56Smrg wire++; 5787f7df2e56Smrg } 5788f7df2e56Smrg if (tmp != str) 5789f7df2e56Smrg *tmp++ = '\0'; 5790f7df2e56Smrg else { 5791f7df2e56Smrg free(str); 5792f7df2e56Smrg str = NULL; 5793f7df2e56Smrg } 5794f7df2e56Smrg } 5795f7df2e56Smrg else { 5796f7df2e56Smrg *errRtrn = BadAlloc; 5797f7df2e56Smrg } 579805b261ecSmrg } 579905b261ecSmrg else { 5800f7df2e56Smrg str = NULL; 580105b261ecSmrg } 5802f7df2e56Smrg *pWire = wire; 5803f7df2e56Smrg return (char *) str; 580405b261ecSmrg} 580505b261ecSmrg 580605b261ecSmrg/***====================================================================***/ 580705b261ecSmrg 580805b261ecSmrgint 580905b261ecSmrgProcXkbListComponents(ClientPtr client) 581005b261ecSmrg{ 5811f7df2e56Smrg DeviceIntPtr dev; 5812f7df2e56Smrg xkbListComponentsReply rep; 5813f7df2e56Smrg unsigned len; 5814f7df2e56Smrg unsigned char *str; 5815f7df2e56Smrg uint8_t size; 5816f7df2e56Smrg int i; 581705b261ecSmrg 581805b261ecSmrg REQUEST(xkbListComponentsReq); 581905b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 582005b261ecSmrg 5821f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 5822f7df2e56Smrg return BadAccess; 582305b261ecSmrg 58244642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 582505b261ecSmrg 5826f7df2e56Smrg /* The request is followed by six Pascal strings (i.e. size in characters 5827f7df2e56Smrg * followed by a string pattern) describing what the client wants us to 5828f7df2e56Smrg * list. We don't care, but might as well check they haven't got the 5829f7df2e56Smrg * length wrong. */ 5830f7df2e56Smrg str = (unsigned char *) &stuff[1]; 5831f7df2e56Smrg for (i = 0; i < 6; i++) { 5832f7df2e56Smrg size = *((uint8_t *)str); 5833f7df2e56Smrg len = (str + size + 1) - ((unsigned char *) stuff); 5834f7df2e56Smrg if ((XkbPaddedSize(len) / 4) > stuff->length) 5835f7df2e56Smrg return BadLength; 5836f7df2e56Smrg str += (size + 1); 5837f7df2e56Smrg } 5838f7df2e56Smrg if ((XkbPaddedSize(len) / 4) != stuff->length) 5839f7df2e56Smrg return BadLength; 5840f7df2e56Smrg rep = (xkbListComponentsReply) { 5841f7df2e56Smrg .type = X_Reply, 5842f7df2e56Smrg .deviceID = dev->id, 5843f7df2e56Smrg .sequenceNumber = client->sequence, 5844f7df2e56Smrg .length = 0, 5845f7df2e56Smrg .nKeymaps = 0, 5846f7df2e56Smrg .nKeycodes = 0, 5847f7df2e56Smrg .nTypes = 0, 5848f7df2e56Smrg .nCompatMaps = 0, 5849f7df2e56Smrg .nSymbols = 0, 5850f7df2e56Smrg .nGeometries = 0, 5851f7df2e56Smrg .extra = 0 5852f7df2e56Smrg }; 585305b261ecSmrg if (client->swapped) { 5854f7df2e56Smrg swaps(&rep.sequenceNumber); 5855f7df2e56Smrg swapl(&rep.length); 5856f7df2e56Smrg swaps(&rep.nKeymaps); 5857f7df2e56Smrg swaps(&rep.nKeycodes); 5858f7df2e56Smrg swaps(&rep.nTypes); 5859f7df2e56Smrg swaps(&rep.nCompatMaps); 5860f7df2e56Smrg swaps(&rep.nSymbols); 5861f7df2e56Smrg swaps(&rep.nGeometries); 5862f7df2e56Smrg swaps(&rep.extra); 5863f7df2e56Smrg } 5864f7df2e56Smrg WriteToClient(client, SIZEOF(xkbListComponentsReply), &rep); 58656747b715Smrg return Success; 586605b261ecSmrg} 586705b261ecSmrg 586805b261ecSmrg/***====================================================================***/ 586905b261ecSmrgint 587005b261ecSmrgProcXkbGetKbdByName(ClientPtr client) 587105b261ecSmrg{ 5872f7df2e56Smrg DeviceIntPtr dev; 5873f7df2e56Smrg DeviceIntPtr tmpd; 5874f7df2e56Smrg DeviceIntPtr master; 5875f7df2e56Smrg xkbGetKbdByNameReply rep = { 0 }; 5876f7df2e56Smrg xkbGetMapReply mrep = { 0 }; 5877f7df2e56Smrg xkbGetCompatMapReply crep = { 0 }; 5878f7df2e56Smrg xkbGetIndicatorMapReply irep = { 0 }; 5879f7df2e56Smrg xkbGetNamesReply nrep = { 0 }; 5880f7df2e56Smrg xkbGetGeometryReply grep = { 0 }; 5881f7df2e56Smrg XkbComponentNamesRec names = { 0 }; 5882f7df2e56Smrg XkbDescPtr xkb, new; 5883f7df2e56Smrg XkbEventCauseRec cause; 5884f7df2e56Smrg unsigned char *str; 5885f7df2e56Smrg char mapFile[PATH_MAX]; 5886f7df2e56Smrg unsigned len; 5887f7df2e56Smrg unsigned fwant, fneed, reported; 5888f7df2e56Smrg int status; 5889f7df2e56Smrg Bool geom_changed; 5890f7df2e56Smrg XkbSrvLedInfoPtr old_sli; 5891f7df2e56Smrg XkbSrvLedInfoPtr sli; 58924642e01fSmrg Mask access_mode = DixGetAttrAccess | DixManageAccess; 589305b261ecSmrg 589405b261ecSmrg REQUEST(xkbGetKbdByNameReq); 589505b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 589605b261ecSmrg 5897f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 5898f7df2e56Smrg return BadAccess; 589905b261ecSmrg 59004642e01fSmrg CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5901f7df2e56Smrg master = GetMaster(dev, MASTER_KEYBOARD); 590205b261ecSmrg 590305b261ecSmrg xkb = dev->key->xkbInfo->desc; 5904f7df2e56Smrg status = Success; 5905f7df2e56Smrg str = (unsigned char *) &stuff[1]; 5906f7df2e56Smrg if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */ 59076747b715Smrg return BadMatch; 5908f7df2e56Smrg names.keycodes = GetComponentSpec(&str, TRUE, &status); 5909f7df2e56Smrg names.types = GetComponentSpec(&str, TRUE, &status); 5910f7df2e56Smrg names.compat = GetComponentSpec(&str, TRUE, &status); 5911f7df2e56Smrg names.symbols = GetComponentSpec(&str, TRUE, &status); 5912f7df2e56Smrg names.geometry = GetComponentSpec(&str, TRUE, &status); 5913f7df2e56Smrg if (status != Success) 5914f7df2e56Smrg return status; 5915f7df2e56Smrg len = str - ((unsigned char *) stuff); 5916f7df2e56Smrg if ((XkbPaddedSize(len) / 4) != stuff->length) 5917f7df2e56Smrg return BadLength; 5918f7df2e56Smrg 5919f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask); 5920f7df2e56Smrg CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask); 5921f7df2e56Smrg 592205b261ecSmrg if (stuff->load) 5923f7df2e56Smrg fwant = XkbGBN_AllComponentsMask; 5924f7df2e56Smrg else 5925f7df2e56Smrg fwant = stuff->want | stuff->need; 5926f7df2e56Smrg if ((!names.compat) && 5927f7df2e56Smrg (fwant & (XkbGBN_CompatMapMask | XkbGBN_IndicatorMapMask))) { 5928f7df2e56Smrg names.compat = Xstrdup("%"); 592905b261ecSmrg } 5930f7df2e56Smrg if ((!names.types) && (fwant & (XkbGBN_TypesMask))) { 5931f7df2e56Smrg names.types = Xstrdup("%"); 59324642e01fSmrg } 5933f7df2e56Smrg if ((!names.symbols) && (fwant & XkbGBN_SymbolsMask)) { 5934f7df2e56Smrg names.symbols = Xstrdup("%"); 59354642e01fSmrg } 5936f7df2e56Smrg geom_changed = ((names.geometry != NULL) && 5937f7df2e56Smrg (strcmp(names.geometry, "%") != 0)); 5938f7df2e56Smrg if ((!names.geometry) && (fwant & XkbGBN_GeometryMask)) { 5939f7df2e56Smrg names.geometry = Xstrdup("%"); 5940f7df2e56Smrg geom_changed = FALSE; 594105b261ecSmrg } 594205b261ecSmrg 59436747b715Smrg memset(mapFile, 0, PATH_MAX); 5944f7df2e56Smrg rep.type = X_Reply; 594505b261ecSmrg rep.deviceID = dev->id; 594605b261ecSmrg rep.sequenceNumber = client->sequence; 594705b261ecSmrg rep.length = 0; 594805b261ecSmrg rep.minKeyCode = xkb->min_key_code; 594905b261ecSmrg rep.maxKeyCode = xkb->max_key_code; 5950f7df2e56Smrg rep.loaded = FALSE; 5951f7df2e56Smrg fwant = 5952f7df2e56Smrg XkbConvertGetByNameComponents(TRUE, stuff->want) | XkmVirtualModsMask; 5953f7df2e56Smrg fneed = XkbConvertGetByNameComponents(TRUE, stuff->need); 5954f7df2e56Smrg rep.reported = XkbConvertGetByNameComponents(FALSE, fwant | fneed); 595505b261ecSmrg if (stuff->load) { 5956f7df2e56Smrg fneed |= XkmKeymapRequired; 5957f7df2e56Smrg fwant |= XkmKeymapLegal; 595805b261ecSmrg } 5959f7df2e56Smrg if ((fwant | fneed) & XkmSymbolsMask) { 5960f7df2e56Smrg fneed |= XkmKeyNamesIndex | XkmTypesIndex; 5961f7df2e56Smrg fwant |= XkmIndicatorsIndex; 596205b261ecSmrg } 596305b261ecSmrg 596405b261ecSmrg /* We pass dev in here so we can get the old names out if needed. */ 5965f7df2e56Smrg rep.found = XkbDDXLoadKeymapByNames(dev, &names, fwant, fneed, &new, 5966f7df2e56Smrg mapFile, PATH_MAX); 5967f7df2e56Smrg rep.newKeyboard = FALSE; 5968f7df2e56Smrg rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0; 5969f7df2e56Smrg 5970f7df2e56Smrg stuff->want |= stuff->need; 5971f7df2e56Smrg if (new == NULL) 5972f7df2e56Smrg rep.reported = 0; 597305b261ecSmrg else { 5974f7df2e56Smrg if (stuff->load) 5975f7df2e56Smrg rep.loaded = TRUE; 5976f7df2e56Smrg if (stuff->load || 5977f7df2e56Smrg ((rep.reported & XkbGBN_SymbolsMask) && (new->compat))) { 5978f7df2e56Smrg XkbChangesRec changes; 5979f7df2e56Smrg 5980f7df2e56Smrg memset(&changes, 0, sizeof(changes)); 5981f7df2e56Smrg XkbUpdateDescActions(new, 5982f7df2e56Smrg new->min_key_code, XkbNumKeys(new), &changes); 5983f7df2e56Smrg } 598405b261ecSmrg 5985f7df2e56Smrg if (new->map == NULL) 5986f7df2e56Smrg rep.reported &= ~(XkbGBN_SymbolsMask | XkbGBN_TypesMask); 5987f7df2e56Smrg else if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) { 5988f7df2e56Smrg mrep.type = X_Reply; 5989f7df2e56Smrg mrep.deviceID = dev->id; 5990f7df2e56Smrg mrep.sequenceNumber = client->sequence; 5991f7df2e56Smrg mrep.length = 5992f7df2e56Smrg ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2); 5993f7df2e56Smrg mrep.minKeyCode = new->min_key_code; 5994f7df2e56Smrg mrep.maxKeyCode = new->max_key_code; 5995f7df2e56Smrg mrep.present = 0; 5996f7df2e56Smrg mrep.totalSyms = mrep.totalActs = 5997f7df2e56Smrg mrep.totalKeyBehaviors = mrep.totalKeyExplicit = 5998f7df2e56Smrg mrep.totalModMapKeys = mrep.totalVModMapKeys = 0; 5999f7df2e56Smrg if (rep.reported & (XkbGBN_TypesMask | XkbGBN_ClientSymbolsMask)) { 6000f7df2e56Smrg mrep.present |= XkbKeyTypesMask; 6001f7df2e56Smrg mrep.firstType = 0; 6002f7df2e56Smrg mrep.nTypes = mrep.totalTypes = new->map->num_types; 6003f7df2e56Smrg } 6004f7df2e56Smrg else { 6005f7df2e56Smrg mrep.firstType = mrep.nTypes = 0; 6006f7df2e56Smrg mrep.totalTypes = 0; 6007f7df2e56Smrg } 6008f7df2e56Smrg if (rep.reported & XkbGBN_ClientSymbolsMask) { 6009f7df2e56Smrg mrep.present |= (XkbKeySymsMask | XkbModifierMapMask); 6010f7df2e56Smrg mrep.firstKeySym = mrep.firstModMapKey = new->min_key_code; 6011f7df2e56Smrg mrep.nKeySyms = mrep.nModMapKeys = XkbNumKeys(new); 6012f7df2e56Smrg } 6013f7df2e56Smrg else { 6014f7df2e56Smrg mrep.firstKeySym = mrep.firstModMapKey = 0; 6015f7df2e56Smrg mrep.nKeySyms = mrep.nModMapKeys = 0; 6016f7df2e56Smrg } 6017f7df2e56Smrg if (rep.reported & XkbGBN_ServerSymbolsMask) { 6018f7df2e56Smrg mrep.present |= XkbAllServerInfoMask; 6019f7df2e56Smrg mrep.virtualMods = ~0; 6020f7df2e56Smrg mrep.firstKeyAct = mrep.firstKeyBehavior = 6021f7df2e56Smrg mrep.firstKeyExplicit = new->min_key_code; 6022f7df2e56Smrg mrep.nKeyActs = mrep.nKeyBehaviors = 6023f7df2e56Smrg mrep.nKeyExplicit = XkbNumKeys(new); 6024f7df2e56Smrg mrep.firstVModMapKey = new->min_key_code; 6025f7df2e56Smrg mrep.nVModMapKeys = XkbNumKeys(new); 6026f7df2e56Smrg } 6027f7df2e56Smrg else { 6028f7df2e56Smrg mrep.virtualMods = 0; 6029f7df2e56Smrg mrep.firstKeyAct = mrep.firstKeyBehavior = 6030f7df2e56Smrg mrep.firstKeyExplicit = 0; 6031f7df2e56Smrg mrep.nKeyActs = mrep.nKeyBehaviors = mrep.nKeyExplicit = 0; 6032f7df2e56Smrg } 6033f7df2e56Smrg XkbComputeGetMapReplySize(new, &mrep); 6034f7df2e56Smrg rep.length += SIZEOF(xGenericReply) / 4 + mrep.length; 6035f7df2e56Smrg } 6036f7df2e56Smrg if (new->compat == NULL) 6037f7df2e56Smrg rep.reported &= ~XkbGBN_CompatMapMask; 6038f7df2e56Smrg else if (rep.reported & XkbGBN_CompatMapMask) { 6039f7df2e56Smrg crep.type = X_Reply; 6040f7df2e56Smrg crep.deviceID = dev->id; 6041f7df2e56Smrg crep.sequenceNumber = client->sequence; 6042f7df2e56Smrg crep.length = 0; 6043f7df2e56Smrg crep.groups = XkbAllGroupsMask; 6044f7df2e56Smrg crep.firstSI = 0; 6045f7df2e56Smrg crep.nSI = crep.nTotalSI = new->compat->num_si; 6046f7df2e56Smrg XkbComputeGetCompatMapReplySize(new->compat, &crep); 6047f7df2e56Smrg rep.length += SIZEOF(xGenericReply) / 4 + crep.length; 6048f7df2e56Smrg } 6049f7df2e56Smrg if (new->indicators == NULL) 6050f7df2e56Smrg rep.reported &= ~XkbGBN_IndicatorMapMask; 6051f7df2e56Smrg else if (rep.reported & XkbGBN_IndicatorMapMask) { 6052f7df2e56Smrg irep.type = X_Reply; 6053f7df2e56Smrg irep.deviceID = dev->id; 6054f7df2e56Smrg irep.sequenceNumber = client->sequence; 6055f7df2e56Smrg irep.length = 0; 6056f7df2e56Smrg irep.which = XkbAllIndicatorsMask; 6057f7df2e56Smrg XkbComputeGetIndicatorMapReplySize(new->indicators, &irep); 6058f7df2e56Smrg rep.length += SIZEOF(xGenericReply) / 4 + irep.length; 6059f7df2e56Smrg } 6060f7df2e56Smrg if (new->names == NULL) 6061f7df2e56Smrg rep.reported &= ~(XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask); 6062f7df2e56Smrg else if (rep.reported & (XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask)) { 6063f7df2e56Smrg nrep.type = X_Reply; 6064f7df2e56Smrg nrep.deviceID = dev->id; 6065f7df2e56Smrg nrep.sequenceNumber = client->sequence; 6066f7df2e56Smrg nrep.length = 0; 6067f7df2e56Smrg nrep.minKeyCode = new->min_key_code; 6068f7df2e56Smrg nrep.maxKeyCode = new->max_key_code; 6069f7df2e56Smrg if (rep.reported & XkbGBN_OtherNamesMask) { 6070f7df2e56Smrg nrep.which = XkbAllNamesMask; 6071f7df2e56Smrg if (new->map != NULL) 6072f7df2e56Smrg nrep.nTypes = new->map->num_types; 6073f7df2e56Smrg else 6074f7df2e56Smrg nrep.nTypes = 0; 6075f7df2e56Smrg nrep.nKTLevels = 0; 6076f7df2e56Smrg nrep.groupNames = XkbAllGroupsMask; 6077f7df2e56Smrg nrep.virtualMods = XkbAllVirtualModsMask; 6078f7df2e56Smrg nrep.indicators = XkbAllIndicatorsMask; 6079f7df2e56Smrg nrep.nRadioGroups = new->names->num_rg; 6080f7df2e56Smrg } 6081f7df2e56Smrg else { 6082f7df2e56Smrg nrep.which = 0; 6083f7df2e56Smrg nrep.nTypes = 0; 6084f7df2e56Smrg nrep.nKTLevels = 0; 6085f7df2e56Smrg nrep.groupNames = 0; 6086f7df2e56Smrg nrep.virtualMods = 0; 6087f7df2e56Smrg nrep.indicators = 0; 6088f7df2e56Smrg nrep.nRadioGroups = 0; 6089f7df2e56Smrg } 6090f7df2e56Smrg if (rep.reported & XkbGBN_KeyNamesMask) { 6091f7df2e56Smrg nrep.which |= XkbKeyNamesMask; 6092f7df2e56Smrg nrep.firstKey = new->min_key_code; 6093f7df2e56Smrg nrep.nKeys = XkbNumKeys(new); 6094f7df2e56Smrg nrep.nKeyAliases = new->names->num_key_aliases; 6095f7df2e56Smrg if (nrep.nKeyAliases) 6096f7df2e56Smrg nrep.which |= XkbKeyAliasesMask; 6097f7df2e56Smrg } 6098f7df2e56Smrg else { 6099f7df2e56Smrg nrep.which &= ~(XkbKeyNamesMask | XkbKeyAliasesMask); 6100f7df2e56Smrg nrep.firstKey = nrep.nKeys = 0; 6101f7df2e56Smrg nrep.nKeyAliases = 0; 6102f7df2e56Smrg } 6103f7df2e56Smrg XkbComputeGetNamesReplySize(new, &nrep); 6104f7df2e56Smrg rep.length += SIZEOF(xGenericReply) / 4 + nrep.length; 6105f7df2e56Smrg } 6106f7df2e56Smrg if (new->geom == NULL) 6107f7df2e56Smrg rep.reported &= ~XkbGBN_GeometryMask; 6108f7df2e56Smrg else if (rep.reported & XkbGBN_GeometryMask) { 6109f7df2e56Smrg grep.type = X_Reply; 6110f7df2e56Smrg grep.deviceID = dev->id; 6111f7df2e56Smrg grep.sequenceNumber = client->sequence; 6112f7df2e56Smrg grep.length = 0; 6113f7df2e56Smrg grep.found = TRUE; 6114f7df2e56Smrg grep.pad = 0; 6115f7df2e56Smrg grep.widthMM = grep.heightMM = 0; 6116f7df2e56Smrg grep.nProperties = grep.nColors = grep.nShapes = 0; 6117f7df2e56Smrg grep.nSections = grep.nDoodads = 0; 6118f7df2e56Smrg grep.baseColorNdx = grep.labelColorNdx = 0; 6119f7df2e56Smrg XkbComputeGetGeometryReplySize(new->geom, &grep, None); 6120f7df2e56Smrg rep.length += SIZEOF(xGenericReply) / 4 + grep.length; 6121f7df2e56Smrg } 6122f7df2e56Smrg } 6123f7df2e56Smrg 6124f7df2e56Smrg reported = rep.reported; 6125f7df2e56Smrg if (client->swapped) { 6126f7df2e56Smrg swaps(&rep.sequenceNumber); 6127f7df2e56Smrg swapl(&rep.length); 6128f7df2e56Smrg swaps(&rep.found); 6129f7df2e56Smrg swaps(&rep.reported); 6130f7df2e56Smrg } 6131f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetKbdByNameReply), &rep); 6132f7df2e56Smrg if (reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) 6133f7df2e56Smrg XkbSendMap(client, new, &mrep); 6134f7df2e56Smrg if (reported & XkbGBN_CompatMapMask) 6135f7df2e56Smrg XkbSendCompatMap(client, new->compat, &crep); 6136f7df2e56Smrg if (reported & XkbGBN_IndicatorMapMask) 6137f7df2e56Smrg XkbSendIndicatorMap(client, new->indicators, &irep); 6138f7df2e56Smrg if (reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) 6139f7df2e56Smrg XkbSendNames(client, new, &nrep); 6140f7df2e56Smrg if (reported & XkbGBN_GeometryMask) 6141f7df2e56Smrg XkbSendGeometry(client, new->geom, &grep, FALSE); 6142f7df2e56Smrg if (rep.loaded) { 6143f7df2e56Smrg XkbDescPtr old_xkb; 6144f7df2e56Smrg xkbNewKeyboardNotify nkn; 6145f7df2e56Smrg 6146f7df2e56Smrg old_xkb = xkb; 6147f7df2e56Smrg xkb = new; 6148f7df2e56Smrg dev->key->xkbInfo->desc = xkb; 6149f7df2e56Smrg new = old_xkb; /* so it'll get freed automatically */ 6150f7df2e56Smrg 6151f7df2e56Smrg XkbCopyControls(xkb, old_xkb); 6152f7df2e56Smrg 6153f7df2e56Smrg nkn.deviceID = nkn.oldDeviceID = dev->id; 6154f7df2e56Smrg nkn.minKeyCode = new->min_key_code; 6155f7df2e56Smrg nkn.maxKeyCode = new->max_key_code; 6156f7df2e56Smrg nkn.oldMinKeyCode = xkb->min_key_code; 6157f7df2e56Smrg nkn.oldMaxKeyCode = xkb->max_key_code; 6158f7df2e56Smrg nkn.requestMajor = XkbReqCode; 6159f7df2e56Smrg nkn.requestMinor = X_kbGetKbdByName; 6160f7df2e56Smrg nkn.changed = XkbNKN_KeycodesMask; 6161f7df2e56Smrg if (geom_changed) 6162f7df2e56Smrg nkn.changed |= XkbNKN_GeometryMask; 6163f7df2e56Smrg XkbSendNewKeyboardNotify(dev, &nkn); 6164f7df2e56Smrg 6165f7df2e56Smrg /* Update the map and LED info on the device itself, as well as 6166f7df2e56Smrg * any slaves if it's an MD, or its MD if it's an SD and was the 6167f7df2e56Smrg * last device used on that MD. */ 616805b261ecSmrg for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 6169f7df2e56Smrg if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev && 6170f7df2e56Smrg (tmpd != master || dev != master->lastSlave)) 6171f7df2e56Smrg continue; 6172f7df2e56Smrg 6173f7df2e56Smrg if (tmpd != dev) 6174f7df2e56Smrg XkbDeviceApplyKeymap(tmpd, xkb); 6175f7df2e56Smrg 6176f7df2e56Smrg if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 6177f7df2e56Smrg old_sli = tmpd->kbdfeed->xkb_sli; 6178f7df2e56Smrg tmpd->kbdfeed->xkb_sli = NULL; 6179f7df2e56Smrg sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 6180f7df2e56Smrg if (sli) { 6181f7df2e56Smrg sli->explicitState = old_sli->explicitState; 6182f7df2e56Smrg sli->effectiveState = old_sli->effectiveState; 618305b261ecSmrg } 6184f7df2e56Smrg tmpd->kbdfeed->xkb_sli = sli; 6185f7df2e56Smrg XkbFreeSrvLedInfo(old_sli); 618605b261ecSmrg } 618705b261ecSmrg } 6188f7df2e56Smrg } 6189f7df2e56Smrg if ((new != NULL) && (new != xkb)) { 6190f7df2e56Smrg XkbFreeKeyboard(new, XkbAllComponentsMask, TRUE); 6191f7df2e56Smrg new = NULL; 619205b261ecSmrg } 61939ace9065Smrg XkbFreeComponentNames(&names, FALSE); 6194f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbGetKbdByName, client); 6195f7df2e56Smrg XkbUpdateAllDeviceIndicators(NULL, &cause); 6196f7df2e56Smrg 61976747b715Smrg return Success; 619805b261ecSmrg} 619905b261ecSmrg 620005b261ecSmrg/***====================================================================***/ 620105b261ecSmrg 620205b261ecSmrgstatic int 6203f7df2e56SmrgComputeDeviceLedInfoSize(DeviceIntPtr dev, 6204f7df2e56Smrg unsigned int what, XkbSrvLedInfoPtr sli) 620505b261ecSmrg{ 6206f7df2e56Smrg int nNames, nMaps; 6207f7df2e56Smrg register unsigned n, bit; 6208f7df2e56Smrg 6209f7df2e56Smrg if (sli == NULL) 6210f7df2e56Smrg return 0; 6211f7df2e56Smrg nNames = nMaps = 0; 6212f7df2e56Smrg if ((what & XkbXI_IndicatorNamesMask) == 0) 6213f7df2e56Smrg sli->namesPresent = 0; 6214f7df2e56Smrg if ((what & XkbXI_IndicatorMapsMask) == 0) 6215f7df2e56Smrg sli->mapsPresent = 0; 6216f7df2e56Smrg 6217f7df2e56Smrg for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6218f7df2e56Smrg if (sli->names && sli->names[n] != None) { 6219f7df2e56Smrg sli->namesPresent |= bit; 6220f7df2e56Smrg nNames++; 6221f7df2e56Smrg } 6222f7df2e56Smrg if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 6223f7df2e56Smrg sli->mapsPresent |= bit; 6224f7df2e56Smrg nMaps++; 6225f7df2e56Smrg } 6226f7df2e56Smrg } 6227f7df2e56Smrg return (nNames * 4) + (nMaps * SIZEOF(xkbIndicatorMapWireDesc)); 622805b261ecSmrg} 622905b261ecSmrg 6230f7df2e56Smrgstatic int 6231f7df2e56SmrgCheckDeviceLedFBs(DeviceIntPtr dev, 6232f7df2e56Smrg int class, 6233f7df2e56Smrg int id, xkbGetDeviceInfoReply * rep, ClientPtr client) 623405b261ecSmrg{ 6235f7df2e56Smrg int nFBs = 0; 6236f7df2e56Smrg int length = 0; 6237f7df2e56Smrg Bool classOk; 6238f7df2e56Smrg 6239f7df2e56Smrg if (class == XkbDfltXIClass) { 6240f7df2e56Smrg if (dev->kbdfeed) 6241f7df2e56Smrg class = KbdFeedbackClass; 6242f7df2e56Smrg else if (dev->leds) 6243f7df2e56Smrg class = LedFeedbackClass; 6244f7df2e56Smrg else { 6245f7df2e56Smrg client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 6246f7df2e56Smrg return XkbKeyboardErrorCode; 6247f7df2e56Smrg } 6248f7df2e56Smrg } 6249f7df2e56Smrg classOk = FALSE; 6250f7df2e56Smrg if ((dev->kbdfeed) && 6251f7df2e56Smrg ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6252f7df2e56Smrg KbdFeedbackPtr kf; 6253f7df2e56Smrg 6254f7df2e56Smrg classOk = TRUE; 6255f7df2e56Smrg for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6256f7df2e56Smrg if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6257f7df2e56Smrg (id != kf->ctrl.id)) 6258f7df2e56Smrg continue; 6259f7df2e56Smrg nFBs++; 6260f7df2e56Smrg length += SIZEOF(xkbDeviceLedsWireDesc); 6261f7df2e56Smrg if (!kf->xkb_sli) 6262f7df2e56Smrg kf->xkb_sli = XkbAllocSrvLedInfo(dev, kf, NULL, 0); 6263f7df2e56Smrg length += ComputeDeviceLedInfoSize(dev, rep->present, kf->xkb_sli); 6264f7df2e56Smrg if (id != XkbAllXIIds) 6265f7df2e56Smrg break; 6266f7df2e56Smrg } 6267f7df2e56Smrg } 6268f7df2e56Smrg if ((dev->leds) && 6269f7df2e56Smrg ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6270f7df2e56Smrg LedFeedbackPtr lf; 6271f7df2e56Smrg 6272f7df2e56Smrg classOk = TRUE; 6273f7df2e56Smrg for (lf = dev->leds; (lf); lf = lf->next) { 6274f7df2e56Smrg if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6275f7df2e56Smrg (id != lf->ctrl.id)) 6276f7df2e56Smrg continue; 6277f7df2e56Smrg nFBs++; 6278f7df2e56Smrg length += SIZEOF(xkbDeviceLedsWireDesc); 6279f7df2e56Smrg if (!lf->xkb_sli) 6280f7df2e56Smrg lf->xkb_sli = XkbAllocSrvLedInfo(dev, NULL, lf, 0); 6281f7df2e56Smrg length += ComputeDeviceLedInfoSize(dev, rep->present, lf->xkb_sli); 6282f7df2e56Smrg if (id != XkbAllXIIds) 6283f7df2e56Smrg break; 6284f7df2e56Smrg } 6285f7df2e56Smrg } 6286f7df2e56Smrg if (nFBs > 0) { 6287f7df2e56Smrg rep->nDeviceLedFBs = nFBs; 6288f7df2e56Smrg rep->length += (length / 4); 6289f7df2e56Smrg return Success; 6290f7df2e56Smrg } 6291f7df2e56Smrg if (classOk) 6292f7df2e56Smrg client->errorValue = _XkbErrCode2(XkbErr_BadId, id); 6293f7df2e56Smrg else 6294f7df2e56Smrg client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 629505b261ecSmrg return XkbKeyboardErrorCode; 629605b261ecSmrg} 629705b261ecSmrg 629805b261ecSmrgstatic int 6299f7df2e56SmrgSendDeviceLedInfo(XkbSrvLedInfoPtr sli, ClientPtr client) 630005b261ecSmrg{ 6301f7df2e56Smrg xkbDeviceLedsWireDesc wire; 6302f7df2e56Smrg int length; 6303f7df2e56Smrg 6304f7df2e56Smrg length = 0; 6305f7df2e56Smrg wire.ledClass = sli->class; 6306f7df2e56Smrg wire.ledID = sli->id; 6307f7df2e56Smrg wire.namesPresent = sli->namesPresent; 6308f7df2e56Smrg wire.mapsPresent = sli->mapsPresent; 6309f7df2e56Smrg wire.physIndicators = sli->physIndicators; 6310f7df2e56Smrg wire.state = sli->effectiveState; 631105b261ecSmrg if (client->swapped) { 6312f7df2e56Smrg swaps(&wire.ledClass); 6313f7df2e56Smrg swaps(&wire.ledID); 6314f7df2e56Smrg swapl(&wire.namesPresent); 6315f7df2e56Smrg swapl(&wire.mapsPresent); 6316f7df2e56Smrg swapl(&wire.physIndicators); 6317f7df2e56Smrg swapl(&wire.state); 6318f7df2e56Smrg } 6319f7df2e56Smrg WriteToClient(client, SIZEOF(xkbDeviceLedsWireDesc), &wire); 6320f7df2e56Smrg length += SIZEOF(xkbDeviceLedsWireDesc); 6321f7df2e56Smrg if (sli->namesPresent | sli->mapsPresent) { 6322f7df2e56Smrg register unsigned i, bit; 6323f7df2e56Smrg 6324f7df2e56Smrg if (sli->namesPresent) { 6325f7df2e56Smrg CARD32 awire; 6326f7df2e56Smrg 6327f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6328f7df2e56Smrg if (sli->namesPresent & bit) { 6329f7df2e56Smrg awire = (CARD32) sli->names[i]; 6330f7df2e56Smrg if (client->swapped) { 6331f7df2e56Smrg swapl(&awire); 6332f7df2e56Smrg } 6333f7df2e56Smrg WriteToClient(client, 4, &awire); 6334f7df2e56Smrg length += 4; 6335f7df2e56Smrg } 6336f7df2e56Smrg } 6337f7df2e56Smrg } 6338f7df2e56Smrg if (sli->mapsPresent) { 6339f7df2e56Smrg for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6340f7df2e56Smrg xkbIndicatorMapWireDesc iwire; 6341f7df2e56Smrg 6342f7df2e56Smrg if (sli->mapsPresent & bit) { 6343f7df2e56Smrg iwire.flags = sli->maps[i].flags; 6344f7df2e56Smrg iwire.whichGroups = sli->maps[i].which_groups; 6345f7df2e56Smrg iwire.groups = sli->maps[i].groups; 6346f7df2e56Smrg iwire.whichMods = sli->maps[i].which_mods; 6347f7df2e56Smrg iwire.mods = sli->maps[i].mods.mask; 6348f7df2e56Smrg iwire.realMods = sli->maps[i].mods.real_mods; 6349f7df2e56Smrg iwire.virtualMods = sli->maps[i].mods.vmods; 6350f7df2e56Smrg iwire.ctrls = sli->maps[i].ctrls; 6351f7df2e56Smrg if (client->swapped) { 6352f7df2e56Smrg swaps(&iwire.virtualMods); 6353f7df2e56Smrg swapl(&iwire.ctrls); 6354f7df2e56Smrg } 6355f7df2e56Smrg WriteToClient(client, SIZEOF(xkbIndicatorMapWireDesc), 6356f7df2e56Smrg &iwire); 6357f7df2e56Smrg length += SIZEOF(xkbIndicatorMapWireDesc); 6358f7df2e56Smrg } 6359f7df2e56Smrg } 6360f7df2e56Smrg } 636105b261ecSmrg } 636205b261ecSmrg return length; 636305b261ecSmrg} 636405b261ecSmrg 636505b261ecSmrgstatic int 6366f7df2e56SmrgSendDeviceLedFBs(DeviceIntPtr dev, 6367f7df2e56Smrg int class, int id, unsigned wantLength, ClientPtr client) 636805b261ecSmrg{ 6369f7df2e56Smrg int length = 0; 6370f7df2e56Smrg 6371f7df2e56Smrg if (class == XkbDfltXIClass) { 6372f7df2e56Smrg if (dev->kbdfeed) 6373f7df2e56Smrg class = KbdFeedbackClass; 6374f7df2e56Smrg else if (dev->leds) 6375f7df2e56Smrg class = LedFeedbackClass; 6376f7df2e56Smrg } 6377f7df2e56Smrg if ((dev->kbdfeed) && 6378f7df2e56Smrg ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6379f7df2e56Smrg KbdFeedbackPtr kf; 6380f7df2e56Smrg 6381f7df2e56Smrg for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6382f7df2e56Smrg if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6383f7df2e56Smrg (id == kf->ctrl.id)) { 6384f7df2e56Smrg length += SendDeviceLedInfo(kf->xkb_sli, client); 6385f7df2e56Smrg if (id != XkbAllXIIds) 6386f7df2e56Smrg break; 6387f7df2e56Smrg } 6388f7df2e56Smrg } 6389f7df2e56Smrg } 6390f7df2e56Smrg if ((dev->leds) && 6391f7df2e56Smrg ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6392f7df2e56Smrg LedFeedbackPtr lf; 6393f7df2e56Smrg 6394f7df2e56Smrg for (lf = dev->leds; (lf); lf = lf->next) { 6395f7df2e56Smrg if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6396f7df2e56Smrg (id == lf->ctrl.id)) { 6397f7df2e56Smrg length += SendDeviceLedInfo(lf->xkb_sli, client); 6398f7df2e56Smrg if (id != XkbAllXIIds) 6399f7df2e56Smrg break; 6400f7df2e56Smrg } 6401f7df2e56Smrg } 6402f7df2e56Smrg } 6403f7df2e56Smrg if (length == wantLength) 6404f7df2e56Smrg return Success; 6405f7df2e56Smrg else 6406f7df2e56Smrg return BadLength; 640705b261ecSmrg} 640805b261ecSmrg 640905b261ecSmrgint 641005b261ecSmrgProcXkbGetDeviceInfo(ClientPtr client) 641105b261ecSmrg{ 6412f7df2e56Smrg DeviceIntPtr dev; 6413f7df2e56Smrg xkbGetDeviceInfoReply rep; 6414f7df2e56Smrg int status, nDeviceLedFBs; 6415f7df2e56Smrg unsigned length, nameLen; 6416f7df2e56Smrg CARD16 ledClass, ledID; 6417f7df2e56Smrg unsigned wanted; 6418f7df2e56Smrg char *str; 641905b261ecSmrg 642005b261ecSmrg REQUEST(xkbGetDeviceInfoReq); 642105b261ecSmrg REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 642205b261ecSmrg 6423f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 6424f7df2e56Smrg return BadAccess; 642505b261ecSmrg 6426f7df2e56Smrg wanted = stuff->wanted; 642705b261ecSmrg 64284642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 6429f7df2e56Smrg CHK_MASK_LEGAL(0x01, wanted, XkbXI_AllDeviceFeaturesMask); 6430f7df2e56Smrg 6431f7df2e56Smrg if ((!dev->button) || ((stuff->nBtns < 1) && (!stuff->allBtns))) 6432f7df2e56Smrg wanted &= ~XkbXI_ButtonActionsMask; 6433f7df2e56Smrg if ((!dev->kbdfeed) && (!dev->leds)) 6434f7df2e56Smrg wanted &= ~XkbXI_IndicatorsMask; 6435f7df2e56Smrg 6436f7df2e56Smrg nameLen = XkbSizeCountedString(dev->name); 6437f7df2e56Smrg rep = (xkbGetDeviceInfoReply) { 6438f7df2e56Smrg .type = X_Reply, 6439f7df2e56Smrg .deviceID = dev->id, 6440f7df2e56Smrg .sequenceNumber = client->sequence, 6441f7df2e56Smrg .length = nameLen / 4, 6442f7df2e56Smrg .present = wanted, 6443f7df2e56Smrg .supported = XkbXI_AllDeviceFeaturesMask, 6444f7df2e56Smrg .unsupported = 0, 6445f7df2e56Smrg .nDeviceLedFBs = 0, 6446f7df2e56Smrg .firstBtnWanted = 0, 6447f7df2e56Smrg .nBtnsWanted = 0, 6448f7df2e56Smrg .firstBtnRtrn = 0, 6449f7df2e56Smrg .nBtnsRtrn = 0, 6450f7df2e56Smrg .totalBtns = dev->button ? dev->button->numButtons : 0, 6451f7df2e56Smrg .hasOwnState = (dev->key && dev->key->xkbInfo), 6452f7df2e56Smrg .dfltKbdFB = dev->kbdfeed ? dev->kbdfeed->ctrl.id : XkbXINone, 6453f7df2e56Smrg .dfltLedFB = dev->leds ? dev->leds->ctrl.id : XkbXINone, 6454f7df2e56Smrg .devType = dev->xinput_type 6455f7df2e56Smrg }; 6456f7df2e56Smrg 6457f7df2e56Smrg ledClass = stuff->ledClass; 6458f7df2e56Smrg ledID = stuff->ledID; 6459f7df2e56Smrg 6460f7df2e56Smrg if (wanted & XkbXI_ButtonActionsMask) { 6461f7df2e56Smrg if (stuff->allBtns) { 6462f7df2e56Smrg stuff->firstBtn = 0; 6463f7df2e56Smrg stuff->nBtns = dev->button->numButtons; 6464f7df2e56Smrg } 646505b261ecSmrg 6466f7df2e56Smrg if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6467f7df2e56Smrg client->errorValue = _XkbErrCode4(0x02, dev->button->numButtons, 6468f7df2e56Smrg stuff->firstBtn, stuff->nBtns); 6469f7df2e56Smrg return BadValue; 6470f7df2e56Smrg } 6471f7df2e56Smrg else { 6472f7df2e56Smrg rep.firstBtnWanted = stuff->firstBtn; 6473f7df2e56Smrg rep.nBtnsWanted = stuff->nBtns; 6474f7df2e56Smrg if (dev->button->xkb_acts != NULL) { 6475f7df2e56Smrg XkbAction *act; 6476f7df2e56Smrg register int i; 6477f7df2e56Smrg 6478f7df2e56Smrg rep.firstBtnRtrn = stuff->firstBtn; 6479f7df2e56Smrg rep.nBtnsRtrn = stuff->nBtns; 6480f7df2e56Smrg act = &dev->button->xkb_acts[rep.firstBtnWanted]; 6481f7df2e56Smrg for (i = 0; i < rep.nBtnsRtrn; i++, act++) { 6482f7df2e56Smrg if (act->type != XkbSA_NoAction) 6483f7df2e56Smrg break; 6484f7df2e56Smrg } 6485f7df2e56Smrg rep.firstBtnRtrn += i; 6486f7df2e56Smrg rep.nBtnsRtrn -= i; 6487f7df2e56Smrg act = 6488f7df2e56Smrg &dev->button->xkb_acts[rep.firstBtnRtrn + rep.nBtnsRtrn - 6489f7df2e56Smrg 1]; 6490f7df2e56Smrg for (i = 0; i < rep.nBtnsRtrn; i++, act--) { 6491f7df2e56Smrg if (act->type != XkbSA_NoAction) 6492f7df2e56Smrg break; 6493f7df2e56Smrg } 6494f7df2e56Smrg rep.nBtnsRtrn -= i; 6495f7df2e56Smrg } 6496f7df2e56Smrg rep.length += (rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc)) / 4; 6497f7df2e56Smrg } 6498f7df2e56Smrg } 649905b261ecSmrg 6500f7df2e56Smrg if (wanted & XkbXI_IndicatorsMask) { 6501f7df2e56Smrg status = CheckDeviceLedFBs(dev, ledClass, ledID, &rep, client); 6502f7df2e56Smrg if (status != Success) 6503f7df2e56Smrg return status; 6504f7df2e56Smrg } 6505f7df2e56Smrg length = rep.length * 4; 650605b261ecSmrg nDeviceLedFBs = rep.nDeviceLedFBs; 650705b261ecSmrg if (client->swapped) { 6508f7df2e56Smrg swaps(&rep.sequenceNumber); 6509f7df2e56Smrg swapl(&rep.length); 6510f7df2e56Smrg swaps(&rep.present); 6511f7df2e56Smrg swaps(&rep.supported); 6512f7df2e56Smrg swaps(&rep.unsupported); 6513f7df2e56Smrg swaps(&rep.nDeviceLedFBs); 6514f7df2e56Smrg swaps(&rep.dfltKbdFB); 6515f7df2e56Smrg swaps(&rep.dfltLedFB); 6516f7df2e56Smrg swapl(&rep.devType); 6517f7df2e56Smrg } 6518f7df2e56Smrg WriteToClient(client, SIZEOF(xkbGetDeviceInfoReply), &rep); 6519f7df2e56Smrg 6520f7df2e56Smrg str = malloc(nameLen); 6521f7df2e56Smrg if (!str) 6522f7df2e56Smrg return BadAlloc; 6523f7df2e56Smrg XkbWriteCountedString(str, dev->name, client->swapped); 6524f7df2e56Smrg WriteToClient(client, nameLen, str); 65256747b715Smrg free(str); 6526f7df2e56Smrg length -= nameLen; 6527f7df2e56Smrg 6528f7df2e56Smrg if (rep.nBtnsRtrn > 0) { 6529f7df2e56Smrg int sz; 6530f7df2e56Smrg xkbActionWireDesc *awire; 6531f7df2e56Smrg 6532f7df2e56Smrg sz = rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc); 6533f7df2e56Smrg awire = (xkbActionWireDesc *) &dev->button->xkb_acts[rep.firstBtnRtrn]; 6534f7df2e56Smrg WriteToClient(client, sz, awire); 6535f7df2e56Smrg length -= sz; 6536f7df2e56Smrg } 6537f7df2e56Smrg if (nDeviceLedFBs > 0) { 6538f7df2e56Smrg status = SendDeviceLedFBs(dev, ledClass, ledID, length, client); 6539f7df2e56Smrg if (status != Success) 6540f7df2e56Smrg return status; 6541f7df2e56Smrg } 6542f7df2e56Smrg else if (length != 0) { 6543f7df2e56Smrg ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 6544f7df2e56Smrg ErrorF("[xkb] Wrote %d fewer bytes than expected\n", 6545f7df2e56Smrg length); 6546f7df2e56Smrg return BadLength; 654705b261ecSmrg } 65486747b715Smrg return Success; 654905b261ecSmrg} 655005b261ecSmrg 655105b261ecSmrgstatic char * 6552f7df2e56SmrgCheckSetDeviceIndicators(char *wire, 6553f7df2e56Smrg DeviceIntPtr dev, 6554f7df2e56Smrg int num, int *status_rtrn, ClientPtr client) 655505b261ecSmrg{ 6556f7df2e56Smrg xkbDeviceLedsWireDesc *ledWire; 6557f7df2e56Smrg int i; 6558f7df2e56Smrg XkbSrvLedInfoPtr sli; 6559f7df2e56Smrg 6560f7df2e56Smrg ledWire = (xkbDeviceLedsWireDesc *) wire; 6561f7df2e56Smrg for (i = 0; i < num; i++) { 6562f7df2e56Smrg if (client->swapped) { 6563f7df2e56Smrg swaps(&ledWire->ledClass); 6564f7df2e56Smrg swaps(&ledWire->ledID); 6565f7df2e56Smrg swapl(&ledWire->namesPresent); 6566f7df2e56Smrg swapl(&ledWire->mapsPresent); 6567f7df2e56Smrg swapl(&ledWire->physIndicators); 6568f7df2e56Smrg } 6569f7df2e56Smrg 6570f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6571f7df2e56Smrg XkbXI_IndicatorsMask); 6572f7df2e56Smrg if (sli != NULL) { 6573f7df2e56Smrg register int n; 6574f7df2e56Smrg register unsigned bit; 6575f7df2e56Smrg int nMaps, nNames; 6576f7df2e56Smrg CARD32 *atomWire; 6577f7df2e56Smrg xkbIndicatorMapWireDesc *mapWire; 6578f7df2e56Smrg 6579f7df2e56Smrg nMaps = nNames = 0; 6580f7df2e56Smrg for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6581f7df2e56Smrg if (ledWire->namesPresent & bit) 6582f7df2e56Smrg nNames++; 6583f7df2e56Smrg if (ledWire->mapsPresent & bit) 6584f7df2e56Smrg nMaps++; 6585f7df2e56Smrg } 6586f7df2e56Smrg atomWire = (CARD32 *) &ledWire[1]; 6587f7df2e56Smrg if (nNames > 0) { 6588f7df2e56Smrg for (n = 0; n < nNames; n++) { 6589f7df2e56Smrg if (client->swapped) { 6590f7df2e56Smrg swapl(atomWire); 6591f7df2e56Smrg } 6592f7df2e56Smrg CHK_ATOM_OR_NONE3(((Atom) (*atomWire)), client->errorValue, 6593f7df2e56Smrg *status_rtrn, NULL); 6594f7df2e56Smrg atomWire++; 6595f7df2e56Smrg } 6596f7df2e56Smrg } 6597f7df2e56Smrg mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6598f7df2e56Smrg if (nMaps > 0) { 6599f7df2e56Smrg for (n = 0; n < nMaps; n++) { 6600f7df2e56Smrg if (client->swapped) { 6601f7df2e56Smrg swaps(&mapWire->virtualMods); 6602f7df2e56Smrg swapl(&mapWire->ctrls); 6603f7df2e56Smrg } 6604f7df2e56Smrg CHK_MASK_LEGAL3(0x21, mapWire->whichGroups, 6605f7df2e56Smrg XkbIM_UseAnyGroup, 6606f7df2e56Smrg client->errorValue, *status_rtrn, NULL); 6607f7df2e56Smrg CHK_MASK_LEGAL3(0x22, mapWire->whichMods, XkbIM_UseAnyMods, 6608f7df2e56Smrg client->errorValue, *status_rtrn, NULL); 6609f7df2e56Smrg mapWire++; 6610f7df2e56Smrg } 6611f7df2e56Smrg } 6612f7df2e56Smrg ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6613f7df2e56Smrg } 6614f7df2e56Smrg else { 6615f7df2e56Smrg /* SHOULD NEVER HAPPEN */ 6616f7df2e56Smrg return (char *) ledWire; 6617f7df2e56Smrg } 6618f7df2e56Smrg } 6619f7df2e56Smrg return (char *) ledWire; 662005b261ecSmrg} 662105b261ecSmrg 662205b261ecSmrgstatic char * 6623f7df2e56SmrgSetDeviceIndicators(char *wire, 6624f7df2e56Smrg DeviceIntPtr dev, 6625f7df2e56Smrg unsigned changed, 6626f7df2e56Smrg int num, 6627f7df2e56Smrg int *status_rtrn, 6628806e81e9Smrg ClientPtr client, 6629806e81e9Smrg xkbExtensionDeviceNotify * ev, 6630806e81e9Smrg xkbSetDeviceInfoReq * stuff) 663105b261ecSmrg{ 6632f7df2e56Smrg xkbDeviceLedsWireDesc *ledWire; 6633f7df2e56Smrg int i; 6634f7df2e56Smrg XkbEventCauseRec cause; 6635f7df2e56Smrg unsigned namec, mapc, statec; 6636f7df2e56Smrg xkbExtensionDeviceNotify ed; 6637f7df2e56Smrg XkbChangesRec changes; 6638f7df2e56Smrg DeviceIntPtr kbd; 6639f7df2e56Smrg 6640f7df2e56Smrg memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 6641f7df2e56Smrg memset((char *) &changes, 0, sizeof(XkbChangesRec)); 6642f7df2e56Smrg XkbSetCauseXkbReq(&cause, X_kbSetDeviceInfo, client); 6643f7df2e56Smrg ledWire = (xkbDeviceLedsWireDesc *) wire; 6644f7df2e56Smrg for (i = 0; i < num; i++) { 6645f7df2e56Smrg register int n; 6646f7df2e56Smrg register unsigned bit; 6647f7df2e56Smrg CARD32 *atomWire; 6648f7df2e56Smrg xkbIndicatorMapWireDesc *mapWire; 6649f7df2e56Smrg XkbSrvLedInfoPtr sli; 6650f7df2e56Smrg 6651806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) { 6652806e81e9Smrg *status_rtrn = BadLength; 6653806e81e9Smrg return (char *) ledWire; 6654806e81e9Smrg } 6655806e81e9Smrg 6656f7df2e56Smrg namec = mapc = statec = 0; 6657f7df2e56Smrg sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6658f7df2e56Smrg XkbXI_IndicatorMapsMask); 6659f7df2e56Smrg if (!sli) { 6660f7df2e56Smrg /* SHOULD NEVER HAPPEN!! */ 6661f7df2e56Smrg return (char *) ledWire; 6662f7df2e56Smrg } 666305b261ecSmrg 6664f7df2e56Smrg atomWire = (CARD32 *) &ledWire[1]; 6665f7df2e56Smrg if (changed & XkbXI_IndicatorNamesMask) { 6666f7df2e56Smrg namec = sli->namesPresent | ledWire->namesPresent; 6667f7df2e56Smrg memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6668f7df2e56Smrg } 6669f7df2e56Smrg if (ledWire->namesPresent) { 6670f7df2e56Smrg sli->namesPresent = ledWire->namesPresent; 6671f7df2e56Smrg memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6672f7df2e56Smrg for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6673f7df2e56Smrg if (ledWire->namesPresent & bit) { 6674806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) { 6675806e81e9Smrg *status_rtrn = BadLength; 6676806e81e9Smrg return (char *) atomWire; 6677806e81e9Smrg } 6678f7df2e56Smrg sli->names[n] = (Atom) *atomWire; 6679f7df2e56Smrg if (sli->names[n] == None) 6680f7df2e56Smrg ledWire->namesPresent &= ~bit; 6681f7df2e56Smrg atomWire++; 6682f7df2e56Smrg } 6683f7df2e56Smrg } 6684f7df2e56Smrg } 6685f7df2e56Smrg mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6686f7df2e56Smrg if (changed & XkbXI_IndicatorMapsMask) { 6687f7df2e56Smrg mapc = sli->mapsPresent | ledWire->mapsPresent; 6688f7df2e56Smrg sli->mapsPresent = ledWire->mapsPresent; 6689f7df2e56Smrg memset((char *) sli->maps, 0, 6690f7df2e56Smrg XkbNumIndicators * sizeof(XkbIndicatorMapRec)); 6691f7df2e56Smrg } 6692f7df2e56Smrg if (ledWire->mapsPresent) { 6693f7df2e56Smrg for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6694f7df2e56Smrg if (ledWire->mapsPresent & bit) { 6695806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) { 6696806e81e9Smrg *status_rtrn = BadLength; 6697806e81e9Smrg return (char *) mapWire; 6698806e81e9Smrg } 6699f7df2e56Smrg sli->maps[n].flags = mapWire->flags; 6700f7df2e56Smrg sli->maps[n].which_groups = mapWire->whichGroups; 6701f7df2e56Smrg sli->maps[n].groups = mapWire->groups; 6702f7df2e56Smrg sli->maps[n].which_mods = mapWire->whichMods; 6703f7df2e56Smrg sli->maps[n].mods.mask = mapWire->mods; 6704f7df2e56Smrg sli->maps[n].mods.real_mods = mapWire->realMods; 6705f7df2e56Smrg sli->maps[n].mods.vmods = mapWire->virtualMods; 6706f7df2e56Smrg sli->maps[n].ctrls = mapWire->ctrls; 6707f7df2e56Smrg mapWire++; 6708f7df2e56Smrg } 6709f7df2e56Smrg } 6710f7df2e56Smrg } 6711f7df2e56Smrg if (changed & XkbXI_IndicatorStateMask) { 6712f7df2e56Smrg statec = sli->effectiveState ^ ledWire->state; 6713f7df2e56Smrg sli->explicitState &= ~statec; 6714f7df2e56Smrg sli->explicitState |= (ledWire->state & statec); 6715f7df2e56Smrg } 6716f7df2e56Smrg if (namec) 6717f7df2e56Smrg XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 6718f7df2e56Smrg if (mapc) 6719f7df2e56Smrg XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 6720f7df2e56Smrg if (statec) 6721f7df2e56Smrg XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 6722f7df2e56Smrg 6723f7df2e56Smrg kbd = dev; 6724f7df2e56Smrg if ((sli->flags & XkbSLI_HasOwnState) == 0) 6725f7df2e56Smrg kbd = inputInfo.keyboard; 6726f7df2e56Smrg 6727f7df2e56Smrg XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 6728f7df2e56Smrg ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6729f7df2e56Smrg } 6730f7df2e56Smrg return (char *) ledWire; 6731f7df2e56Smrg} 673205b261ecSmrg 67334642e01fSmrgstatic int 67344642e01fSmrg_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 6735f7df2e56Smrg xkbSetDeviceInfoReq * stuff) 67364642e01fSmrg{ 6737f7df2e56Smrg char *wire; 6738f7df2e56Smrg 6739f7df2e56Smrg wire = (char *) &stuff[1]; 6740f7df2e56Smrg if (stuff->change & XkbXI_ButtonActionsMask) { 6741f7df2e56Smrg if (!dev->button) { 6742f7df2e56Smrg client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass); 6743f7df2e56Smrg return XkbKeyboardErrorCode; 6744f7df2e56Smrg } 6745f7df2e56Smrg if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6746f7df2e56Smrg client->errorValue = 6747f7df2e56Smrg _XkbErrCode4(0x02, stuff->firstBtn, stuff->nBtns, 6748f7df2e56Smrg dev->button->numButtons); 6749f7df2e56Smrg return BadMatch; 6750f7df2e56Smrg } 6751f7df2e56Smrg wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc)); 6752f7df2e56Smrg } 6753f7df2e56Smrg if (stuff->change & XkbXI_IndicatorsMask) { 6754f7df2e56Smrg int status = Success; 6755f7df2e56Smrg 6756f7df2e56Smrg wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs, 6757f7df2e56Smrg &status, client); 6758f7df2e56Smrg if (status != Success) 6759f7df2e56Smrg return status; 6760f7df2e56Smrg } 6761f7df2e56Smrg if (((wire - ((char *) stuff)) / 4) != stuff->length) 6762f7df2e56Smrg return BadLength; 676305b261ecSmrg 67644642e01fSmrg return Success; 67654642e01fSmrg} 67664642e01fSmrg 67674642e01fSmrgstatic int 67684642e01fSmrg_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 6769f7df2e56Smrg xkbSetDeviceInfoReq * stuff) 67704642e01fSmrg{ 6771f7df2e56Smrg char *wire; 6772f7df2e56Smrg xkbExtensionDeviceNotify ed; 6773f7df2e56Smrg 6774f7df2e56Smrg memset((char *) &ed, 0, SIZEOF(xkbExtensionDeviceNotify)); 6775f7df2e56Smrg ed.deviceID = dev->id; 6776f7df2e56Smrg wire = (char *) &stuff[1]; 6777f7df2e56Smrg if (stuff->change & XkbXI_ButtonActionsMask) { 6778806e81e9Smrg int nBtns, sz, i; 6779f7df2e56Smrg XkbAction *acts; 6780f7df2e56Smrg DeviceIntPtr kbd; 6781f7df2e56Smrg 6782f7df2e56Smrg nBtns = dev->button->numButtons; 6783f7df2e56Smrg acts = dev->button->xkb_acts; 6784f7df2e56Smrg if (acts == NULL) { 6785f7df2e56Smrg acts = calloc(nBtns, sizeof(XkbAction)); 6786f7df2e56Smrg if (!acts) 6787f7df2e56Smrg return BadAlloc; 6788f7df2e56Smrg dev->button->xkb_acts = acts; 6789f7df2e56Smrg } 6790806e81e9Smrg if (stuff->firstBtn + stuff->nBtns > nBtns) 6791806e81e9Smrg return BadValue; 6792f7df2e56Smrg sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); 6793806e81e9Smrg if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz)) 6794806e81e9Smrg return BadLength; 6795f7df2e56Smrg memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz); 6796f7df2e56Smrg wire += sz; 6797f7df2e56Smrg ed.reason |= XkbXI_ButtonActionsMask; 6798f7df2e56Smrg ed.firstBtn = stuff->firstBtn; 6799f7df2e56Smrg ed.nBtns = stuff->nBtns; 6800f7df2e56Smrg 6801f7df2e56Smrg if (dev->key) 6802f7df2e56Smrg kbd = dev; 6803f7df2e56Smrg else 6804f7df2e56Smrg kbd = inputInfo.keyboard; 6805f7df2e56Smrg acts = &dev->button->xkb_acts[stuff->firstBtn]; 6806f7df2e56Smrg for (i = 0; i < stuff->nBtns; i++, acts++) { 6807f7df2e56Smrg if (acts->type != XkbSA_NoAction) 6808f7df2e56Smrg XkbSetActionKeyMods(kbd->key->xkbInfo->desc, acts, 0); 6809f7df2e56Smrg } 6810f7df2e56Smrg } 6811f7df2e56Smrg if (stuff->change & XkbXI_IndicatorsMask) { 6812f7df2e56Smrg int status = Success; 6813f7df2e56Smrg 6814f7df2e56Smrg wire = SetDeviceIndicators(wire, dev, stuff->change, 6815806e81e9Smrg stuff->nDeviceLedFBs, &status, client, &ed, 6816806e81e9Smrg stuff); 6817f7df2e56Smrg if (status != Success) 6818f7df2e56Smrg return status; 6819f7df2e56Smrg } 6820f7df2e56Smrg if ((stuff->change) && (ed.reason)) 6821f7df2e56Smrg XkbSendExtensionDeviceNotify(dev, client, &ed); 68224642e01fSmrg return Success; 68234642e01fSmrg} 68244642e01fSmrg 68254642e01fSmrgint 68264642e01fSmrgProcXkbSetDeviceInfo(ClientPtr client) 68274642e01fSmrg{ 6828f7df2e56Smrg DeviceIntPtr dev; 6829f7df2e56Smrg int rc; 68304642e01fSmrg 68314642e01fSmrg REQUEST(xkbSetDeviceInfoReq); 68324642e01fSmrg REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 68334642e01fSmrg 6834f7df2e56Smrg if (!(client->xkbClientFlags & _XkbClientInitialized)) 6835f7df2e56Smrg return BadAccess; 68364642e01fSmrg 68374642e01fSmrg CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 6838f7df2e56Smrg CHK_MASK_LEGAL(0x01, stuff->change, XkbXI_AllFeaturesMask); 68394642e01fSmrg 68404642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 68414642e01fSmrg 68424642e01fSmrg if (rc != Success) 68434642e01fSmrg return rc; 68444642e01fSmrg 6845f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd || 6846f7df2e56Smrg stuff->deviceSpec == XkbUseCorePtr) { 68474642e01fSmrg DeviceIntPtr other; 6848f7df2e56Smrg 6849f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 6850f7df2e56Smrg if (((other != dev) && !IsMaster(other) && 6851f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) && 68524642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6853f7df2e56Smrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6854f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6855f7df2e56Smrg DixManageAccess); 6856f7df2e56Smrg if (rc == Success) { 68574642e01fSmrg rc = _XkbSetDeviceInfoCheck(client, other, stuff); 68584642e01fSmrg if (rc != Success) 68594642e01fSmrg return rc; 68604642e01fSmrg } 68614642e01fSmrg } 68624642e01fSmrg } 68634642e01fSmrg } 68644642e01fSmrg 68654642e01fSmrg /* checks done, apply */ 68664642e01fSmrg rc = _XkbSetDeviceInfo(client, dev, stuff); 68674642e01fSmrg if (rc != Success) 68684642e01fSmrg return rc; 68694642e01fSmrg 6870f7df2e56Smrg if (stuff->deviceSpec == XkbUseCoreKbd || 6871f7df2e56Smrg stuff->deviceSpec == XkbUseCorePtr) { 68724642e01fSmrg DeviceIntPtr other; 6873f7df2e56Smrg 6874f7df2e56Smrg for (other = inputInfo.devices; other; other = other->next) { 6875f7df2e56Smrg if (((other != dev) && !IsMaster(other) && 6876f7df2e56Smrg GetMaster(other, MASTER_KEYBOARD) == dev) && 68774642e01fSmrg ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6878f7df2e56Smrg (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6879f7df2e56Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6880f7df2e56Smrg DixManageAccess); 6881f7df2e56Smrg if (rc == Success) { 68824642e01fSmrg rc = _XkbSetDeviceInfo(client, other, stuff); 68834642e01fSmrg if (rc != Success) 68844642e01fSmrg return rc; 68854642e01fSmrg } 68864642e01fSmrg } 68874642e01fSmrg } 68884642e01fSmrg } 68894642e01fSmrg 68906747b715Smrg return Success; 689105b261ecSmrg} 689205b261ecSmrg 689305b261ecSmrg/***====================================================================***/ 689405b261ecSmrg 689505b261ecSmrgint 689605b261ecSmrgProcXkbSetDebuggingFlags(ClientPtr client) 689705b261ecSmrg{ 6898f7df2e56Smrg CARD32 newFlags, newCtrls, extraLength; 6899f7df2e56Smrg xkbSetDebuggingFlagsReply rep; 6900f7df2e56Smrg int rc; 690105b261ecSmrg 690205b261ecSmrg REQUEST(xkbSetDebuggingFlagsReq); 690305b261ecSmrg REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 690405b261ecSmrg 69054642e01fSmrg rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 69064642e01fSmrg if (rc != Success) 6907f7df2e56Smrg return rc; 69084642e01fSmrg 6909f7df2e56Smrg newFlags = xkbDebugFlags & (~stuff->affectFlags); 6910f7df2e56Smrg newFlags |= (stuff->flags & stuff->affectFlags); 6911f7df2e56Smrg newCtrls = xkbDebugCtrls & (~stuff->affectCtrls); 6912f7df2e56Smrg newCtrls |= (stuff->ctrls & stuff->affectCtrls); 691305b261ecSmrg if (xkbDebugFlags || newFlags || stuff->msgLength) { 6914f7df2e56Smrg ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n", 6915f7df2e56Smrg (long) newFlags); 6916f7df2e56Smrg if (newCtrls != xkbDebugCtrls) 6917f7df2e56Smrg ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n", 6918f7df2e56Smrg (long) newCtrls); 6919f7df2e56Smrg } 6920f7df2e56Smrg extraLength = (stuff->length << 2) - sz_xkbSetDebuggingFlagsReq; 6921f7df2e56Smrg if (stuff->msgLength > 0) { 6922f7df2e56Smrg char *msg; 6923f7df2e56Smrg 6924f7df2e56Smrg if (extraLength < XkbPaddedSize(stuff->msgLength)) { 6925f7df2e56Smrg ErrorF 6926f7df2e56Smrg ("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 6927f7df2e56Smrg stuff->msgLength, (long) extraLength, 6928f7df2e56Smrg XkbPaddedSize(stuff->msgLength)); 6929f7df2e56Smrg return BadLength; 6930f7df2e56Smrg } 6931f7df2e56Smrg msg = (char *) &stuff[1]; 6932f7df2e56Smrg if (msg[stuff->msgLength - 1] != '\0') { 6933f7df2e56Smrg ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 6934f7df2e56Smrg return BadValue; 6935f7df2e56Smrg } 6936f7df2e56Smrg ErrorF("[xkb] XkbDebug: %s\n", msg); 693705b261ecSmrg } 693805b261ecSmrg xkbDebugFlags = newFlags; 693905b261ecSmrg xkbDebugCtrls = newCtrls; 694005b261ecSmrg 6941f7df2e56Smrg rep = (xkbSetDebuggingFlagsReply) { 6942f7df2e56Smrg .type = X_Reply, 6943f7df2e56Smrg .sequenceNumber = client->sequence, 6944f7df2e56Smrg .length = 0, 6945f7df2e56Smrg .currentFlags = newFlags, 6946f7df2e56Smrg .currentCtrls = newCtrls, 6947f7df2e56Smrg .supportedFlags = ~0, 6948f7df2e56Smrg .supportedCtrls = ~0 6949f7df2e56Smrg }; 6950f7df2e56Smrg if (client->swapped) { 6951f7df2e56Smrg swaps(&rep.sequenceNumber); 6952f7df2e56Smrg swapl(&rep.currentFlags); 6953f7df2e56Smrg swapl(&rep.currentCtrls); 6954f7df2e56Smrg swapl(&rep.supportedFlags); 6955f7df2e56Smrg swapl(&rep.supportedCtrls); 6956f7df2e56Smrg } 6957f7df2e56Smrg WriteToClient(client, SIZEOF(xkbSetDebuggingFlagsReply), &rep); 69586747b715Smrg return Success; 695905b261ecSmrg} 696005b261ecSmrg 696105b261ecSmrg/***====================================================================***/ 696205b261ecSmrg 696305b261ecSmrgstatic int 6964f7df2e56SmrgProcXkbDispatch(ClientPtr client) 696505b261ecSmrg{ 696605b261ecSmrg REQUEST(xReq); 6967f7df2e56Smrg switch (stuff->data) { 696805b261ecSmrg case X_kbUseExtension: 6969f7df2e56Smrg return ProcXkbUseExtension(client); 697005b261ecSmrg case X_kbSelectEvents: 6971f7df2e56Smrg return ProcXkbSelectEvents(client); 697205b261ecSmrg case X_kbBell: 6973f7df2e56Smrg return ProcXkbBell(client); 697405b261ecSmrg case X_kbGetState: 6975f7df2e56Smrg return ProcXkbGetState(client); 697605b261ecSmrg case X_kbLatchLockState: 6977f7df2e56Smrg return ProcXkbLatchLockState(client); 697805b261ecSmrg case X_kbGetControls: 6979f7df2e56Smrg return ProcXkbGetControls(client); 698005b261ecSmrg case X_kbSetControls: 6981f7df2e56Smrg return ProcXkbSetControls(client); 698205b261ecSmrg case X_kbGetMap: 6983f7df2e56Smrg return ProcXkbGetMap(client); 698405b261ecSmrg case X_kbSetMap: 6985f7df2e56Smrg return ProcXkbSetMap(client); 698605b261ecSmrg case X_kbGetCompatMap: 6987f7df2e56Smrg return ProcXkbGetCompatMap(client); 698805b261ecSmrg case X_kbSetCompatMap: 6989f7df2e56Smrg return ProcXkbSetCompatMap(client); 699005b261ecSmrg case X_kbGetIndicatorState: 6991f7df2e56Smrg return ProcXkbGetIndicatorState(client); 699205b261ecSmrg case X_kbGetIndicatorMap: 6993f7df2e56Smrg return ProcXkbGetIndicatorMap(client); 699405b261ecSmrg case X_kbSetIndicatorMap: 6995f7df2e56Smrg return ProcXkbSetIndicatorMap(client); 699605b261ecSmrg case X_kbGetNamedIndicator: 6997f7df2e56Smrg return ProcXkbGetNamedIndicator(client); 699805b261ecSmrg case X_kbSetNamedIndicator: 6999f7df2e56Smrg return ProcXkbSetNamedIndicator(client); 700005b261ecSmrg case X_kbGetNames: 7001f7df2e56Smrg return ProcXkbGetNames(client); 700205b261ecSmrg case X_kbSetNames: 7003f7df2e56Smrg return ProcXkbSetNames(client); 700405b261ecSmrg case X_kbGetGeometry: 7005f7df2e56Smrg return ProcXkbGetGeometry(client); 700605b261ecSmrg case X_kbSetGeometry: 7007f7df2e56Smrg return ProcXkbSetGeometry(client); 700805b261ecSmrg case X_kbPerClientFlags: 7009f7df2e56Smrg return ProcXkbPerClientFlags(client); 701005b261ecSmrg case X_kbListComponents: 7011f7df2e56Smrg return ProcXkbListComponents(client); 701205b261ecSmrg case X_kbGetKbdByName: 7013f7df2e56Smrg return ProcXkbGetKbdByName(client); 701405b261ecSmrg case X_kbGetDeviceInfo: 7015f7df2e56Smrg return ProcXkbGetDeviceInfo(client); 701605b261ecSmrg case X_kbSetDeviceInfo: 7017f7df2e56Smrg return ProcXkbSetDeviceInfo(client); 701805b261ecSmrg case X_kbSetDebuggingFlags: 7019f7df2e56Smrg return ProcXkbSetDebuggingFlags(client); 702005b261ecSmrg default: 7021f7df2e56Smrg return BadRequest; 702205b261ecSmrg } 702305b261ecSmrg} 702405b261ecSmrg 702505b261ecSmrgstatic int 7026f7df2e56SmrgXkbClientGone(void *data, XID id) 702705b261ecSmrg{ 7028f7df2e56Smrg DevicePtr pXDev = (DevicePtr) data; 702905b261ecSmrg 7030f7df2e56Smrg if (!XkbRemoveResourceClient(pXDev, id)) { 7031f7df2e56Smrg ErrorF 7032f7df2e56Smrg ("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 703305b261ecSmrg } 703405b261ecSmrg return 1; 703505b261ecSmrg} 703605b261ecSmrg 703705b261ecSmrgvoid 703805b261ecSmrgXkbExtensionInit(void) 703905b261ecSmrg{ 704005b261ecSmrg ExtensionEntry *extEntry; 704105b261ecSmrg 70426747b715Smrg RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); 70436747b715Smrg if (!RT_XKBCLIENT) 7044f7df2e56Smrg return; 70456747b715Smrg 70466747b715Smrg if (!XkbInitPrivates()) 7047f7df2e56Smrg return; 70486747b715Smrg 704905b261ecSmrg if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 7050f7df2e56Smrg ProcXkbDispatch, SProcXkbDispatch, 7051f7df2e56Smrg NULL, StandardMinorOpcode))) { 7052f7df2e56Smrg XkbReqCode = (unsigned char) extEntry->base; 7053f7df2e56Smrg XkbEventBase = (unsigned char) extEntry->eventBase; 7054f7df2e56Smrg XkbErrorBase = (unsigned char) extEntry->errorBase; 7055f7df2e56Smrg XkbKeyboardErrorCode = XkbErrorBase + XkbKeyboard; 705605b261ecSmrg } 705705b261ecSmrg return; 705805b261ecSmrg} 7059