xkb.c revision 4e185dc0
1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <X11/X.h> 33#include <X11/Xproto.h> 34#include "misc.h" 35#include "inputstr.h" 36#define XKBSRV_NEED_FILE_FUNCS 37#include <xkbsrv.h> 38#include "extnsionst.h" 39#include "extinit.h" 40#include "xace.h" 41#include "xkb.h" 42#include "protocol-versions.h" 43 44#include <X11/extensions/XI.h> 45#include <X11/extensions/XKMformat.h> 46 47int XkbEventBase; 48static int XkbErrorBase; 49int XkbReqCode; 50int XkbKeyboardErrorCode; 51CARD32 xkbDebugFlags = 0; 52static CARD32 xkbDebugCtrls = 0; 53 54static RESTYPE RT_XKBCLIENT; 55 56/***====================================================================***/ 57 58#define CHK_DEVICE(dev, id, client, access_mode, lf) {\ 59 int why;\ 60 int tmprc = lf(&(dev), id, client, access_mode, &why);\ 61 if (tmprc != Success) {\ 62 client->errorValue = _XkbErrCode2(why, id);\ 63 return tmprc;\ 64 }\ 65} 66 67#define CHK_KBD_DEVICE(dev, id, client, mode) \ 68 CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard) 69#define CHK_LED_DEVICE(dev, id, client, mode) \ 70 CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice) 71#define CHK_BELL_DEVICE(dev, id, client, mode) \ 72 CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice) 73#define CHK_ANY_DEVICE(dev, id, client, mode) \ 74 CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice) 75 76#define CHK_ATOM_ONLY2(a,ev,er) {\ 77 if (((a)==None)||(!ValidAtom((a)))) {\ 78 (ev)= (XID)(a);\ 79 return er;\ 80 }\ 81} 82#define CHK_ATOM_ONLY(a) \ 83 CHK_ATOM_ONLY2(a,client->errorValue,BadAtom) 84 85#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\ 86 if (((a)!=None)&&(!ValidAtom((a)))) {\ 87 (ev)= (XID)(a);\ 88 (er)= BadAtom;\ 89 return ret;\ 90 }\ 91} 92#define CHK_ATOM_OR_NONE2(a,ev,er) {\ 93 if (((a)!=None)&&(!ValidAtom((a)))) {\ 94 (ev)= (XID)(a);\ 95 return er;\ 96 }\ 97} 98#define CHK_ATOM_OR_NONE(a) \ 99 CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom) 100 101#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\ 102 if ((mask)&(~(legal))) { \ 103 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 104 (er)= BadValue;\ 105 return ret;\ 106 }\ 107} 108#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\ 109 if ((mask)&(~(legal))) { \ 110 (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ 111 return er;\ 112 }\ 113} 114#define CHK_MASK_LEGAL(err,mask,legal) \ 115 CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue) 116 117#define CHK_MASK_MATCH(err,affect,value) {\ 118 if ((value)&(~(affect))) { \ 119 client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\ 120 return BadMatch;\ 121 }\ 122} 123#define CHK_MASK_OVERLAP(err,m1,m2) {\ 124 if ((m1)&(m2)) { \ 125 client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\ 126 return BadMatch;\ 127 }\ 128} 129#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\ 130 if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\ 131 (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\ 132 return er;\ 133 }\ 134 else if ( (first)<(x)->min_key_code ) {\ 135 (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\ 136 return er;\ 137 }\ 138} 139#define CHK_KEY_RANGE(err,first,num,x) \ 140 CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue) 141 142#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\ 143 if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\ 144 (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\ 145 return er;\ 146 }\ 147 else if ( (first)<(r)->minKeyCode ) {\ 148 (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\ 149 return er;\ 150 }\ 151} 152#define CHK_REQ_KEY_RANGE(err,first,num,r) \ 153 CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) 154 155/***====================================================================***/ 156 157int 158ProcXkbUseExtension(ClientPtr client) 159{ 160 REQUEST(xkbUseExtensionReq); 161 xkbUseExtensionReply rep; 162 int supported; 163 164 REQUEST_SIZE_MATCH(xkbUseExtensionReq); 165 if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) { 166 /* pre-release version 0.65 is compatible with 1.00 */ 167 supported = ((SERVER_XKB_MAJOR_VERSION == 1) && 168 (stuff->wantedMajor == 0) && (stuff->wantedMinor == 65)); 169 } 170 else 171 supported = 1; 172 173 if ((supported) && (!(client->xkbClientFlags & _XkbClientInitialized))) { 174 client->xkbClientFlags = _XkbClientInitialized; 175 if (stuff->wantedMajor == 0) 176 client->xkbClientFlags |= _XkbClientIsAncient; 177 } 178 else if (xkbDebugFlags & 0x1) { 179 ErrorF 180 ("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", 181 client->index, (long) client->clientAsMask, stuff->wantedMajor, 182 stuff->wantedMinor, SERVER_XKB_MAJOR_VERSION, 183 SERVER_XKB_MINOR_VERSION); 184 } 185 rep = (xkbUseExtensionReply) { 186 .type = X_Reply, 187 .supported = supported, 188 .sequenceNumber = client->sequence, 189 .length = 0, 190 .serverMajor = SERVER_XKB_MAJOR_VERSION, 191 .serverMinor = SERVER_XKB_MINOR_VERSION 192 }; 193 if (client->swapped) { 194 swaps(&rep.sequenceNumber); 195 swaps(&rep.serverMajor); 196 swaps(&rep.serverMinor); 197 } 198 WriteToClient(client, SIZEOF(xkbUseExtensionReply), &rep); 199 return Success; 200} 201 202/***====================================================================***/ 203 204int 205ProcXkbSelectEvents(ClientPtr client) 206{ 207 unsigned legal; 208 DeviceIntPtr dev; 209 XkbInterestPtr masks; 210 211 REQUEST(xkbSelectEventsReq); 212 213 REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); 214 215 if (!(client->xkbClientFlags & _XkbClientInitialized)) 216 return BadAccess; 217 218 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess); 219 220 if (((stuff->affectWhich & XkbMapNotifyMask) != 0) && (stuff->affectMap)) { 221 client->mapNotifyMask &= ~stuff->affectMap; 222 client->mapNotifyMask |= (stuff->affectMap & stuff->map); 223 } 224 if ((stuff->affectWhich & (~XkbMapNotifyMask)) == 0) 225 return Success; 226 227 masks = XkbFindClientResource((DevicePtr) dev, client); 228 if (!masks) { 229 XID id = FakeClientID(client->index); 230 231 if (!AddResource(id, RT_XKBCLIENT, dev)) 232 return BadAlloc; 233 masks = XkbAddClientResource((DevicePtr) dev, client, id); 234 } 235 if (masks) { 236 union { 237 CARD8 *c8; 238 CARD16 *c16; 239 CARD32 *c32; 240 } from, to; 241 register unsigned bit, ndx, maskLeft, dataLeft, size; 242 243 from.c8 = (CARD8 *) &stuff[1]; 244 dataLeft = (stuff->length * 4) - SIZEOF(xkbSelectEventsReq); 245 maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask)); 246 for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) { 247 if ((bit & maskLeft) == 0) 248 continue; 249 maskLeft &= ~bit; 250 switch (ndx) { 251 case XkbNewKeyboardNotify: 252 to.c16 = &client->newKeyboardNotifyMask; 253 legal = XkbAllNewKeyboardEventsMask; 254 size = 2; 255 break; 256 case XkbStateNotify: 257 to.c16 = &masks->stateNotifyMask; 258 legal = XkbAllStateEventsMask; 259 size = 2; 260 break; 261 case XkbControlsNotify: 262 to.c32 = &masks->ctrlsNotifyMask; 263 legal = XkbAllControlEventsMask; 264 size = 4; 265 break; 266 case XkbIndicatorStateNotify: 267 to.c32 = &masks->iStateNotifyMask; 268 legal = XkbAllIndicatorEventsMask; 269 size = 4; 270 break; 271 case XkbIndicatorMapNotify: 272 to.c32 = &masks->iMapNotifyMask; 273 legal = XkbAllIndicatorEventsMask; 274 size = 4; 275 break; 276 case XkbNamesNotify: 277 to.c16 = &masks->namesNotifyMask; 278 legal = XkbAllNameEventsMask; 279 size = 2; 280 break; 281 case XkbCompatMapNotify: 282 to.c8 = &masks->compatNotifyMask; 283 legal = XkbAllCompatMapEventsMask; 284 size = 1; 285 break; 286 case XkbBellNotify: 287 to.c8 = &masks->bellNotifyMask; 288 legal = XkbAllBellEventsMask; 289 size = 1; 290 break; 291 case XkbActionMessage: 292 to.c8 = &masks->actionMessageMask; 293 legal = XkbAllActionMessagesMask; 294 size = 1; 295 break; 296 case XkbAccessXNotify: 297 to.c16 = &masks->accessXNotifyMask; 298 legal = XkbAllAccessXEventsMask; 299 size = 2; 300 break; 301 case XkbExtensionDeviceNotify: 302 to.c16 = &masks->extDevNotifyMask; 303 legal = XkbAllExtensionDeviceEventsMask; 304 size = 2; 305 break; 306 default: 307 client->errorValue = _XkbErrCode2(33, bit); 308 return BadValue; 309 } 310 311 if (stuff->clear & bit) { 312 if (size == 2) 313 to.c16[0] = 0; 314 else if (size == 4) 315 to.c32[0] = 0; 316 else 317 to.c8[0] = 0; 318 } 319 else if (stuff->selectAll & bit) { 320 if (size == 2) 321 to.c16[0] = ~0; 322 else if (size == 4) 323 to.c32[0] = ~0; 324 else 325 to.c8[0] = ~0; 326 } 327 else { 328 if (dataLeft < (size * 2)) 329 return BadLength; 330 if (size == 2) { 331 CHK_MASK_MATCH(ndx, from.c16[0], from.c16[1]); 332 CHK_MASK_LEGAL(ndx, from.c16[0], legal); 333 to.c16[0] &= ~from.c16[0]; 334 to.c16[0] |= (from.c16[0] & from.c16[1]); 335 } 336 else if (size == 4) { 337 CHK_MASK_MATCH(ndx, from.c32[0], from.c32[1]); 338 CHK_MASK_LEGAL(ndx, from.c32[0], legal); 339 to.c32[0] &= ~from.c32[0]; 340 to.c32[0] |= (from.c32[0] & from.c32[1]); 341 } 342 else { 343 CHK_MASK_MATCH(ndx, from.c8[0], from.c8[1]); 344 CHK_MASK_LEGAL(ndx, from.c8[0], legal); 345 to.c8[0] &= ~from.c8[0]; 346 to.c8[0] |= (from.c8[0] & from.c8[1]); 347 size = 2; 348 } 349 from.c8 += (size * 2); 350 dataLeft -= (size * 2); 351 } 352 } 353 if (dataLeft > 2) { 354 ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n", 355 dataLeft); 356 return BadLength; 357 } 358 return Success; 359 } 360 return BadAlloc; 361} 362 363/***====================================================================***/ 364/** 365 * Ring a bell on the given device for the given client. 366 */ 367static int 368_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, 369 int bellClass, int bellID, int pitch, int duration, 370 int percent, int forceSound, int eventOnly, Atom name) 371{ 372 int base; 373 void *ctrl; 374 int oldPitch, oldDuration; 375 int newPercent; 376 377 if (bellClass == KbdFeedbackClass) { 378 KbdFeedbackPtr k; 379 380 if (bellID == XkbDfltXIId) 381 k = dev->kbdfeed; 382 else { 383 for (k = dev->kbdfeed; k; k = k->next) { 384 if (k->ctrl.id == bellID) 385 break; 386 } 387 } 388 if (!k) { 389 client->errorValue = _XkbErrCode2(0x5, bellID); 390 return BadValue; 391 } 392 base = k->ctrl.bell; 393 ctrl = (void *) &(k->ctrl); 394 oldPitch = k->ctrl.bell_pitch; 395 oldDuration = k->ctrl.bell_duration; 396 if (pitch != 0) { 397 if (pitch == -1) 398 k->ctrl.bell_pitch = defaultKeyboardControl.bell_pitch; 399 else 400 k->ctrl.bell_pitch = pitch; 401 } 402 if (duration != 0) { 403 if (duration == -1) 404 k->ctrl.bell_duration = defaultKeyboardControl.bell_duration; 405 else 406 k->ctrl.bell_duration = duration; 407 } 408 } 409 else if (bellClass == BellFeedbackClass) { 410 BellFeedbackPtr b; 411 412 if (bellID == XkbDfltXIId) 413 b = dev->bell; 414 else { 415 for (b = dev->bell; b; b = b->next) { 416 if (b->ctrl.id == bellID) 417 break; 418 } 419 } 420 if (!b) { 421 client->errorValue = _XkbErrCode2(0x6, bellID); 422 return BadValue; 423 } 424 base = b->ctrl.percent; 425 ctrl = (void *) &(b->ctrl); 426 oldPitch = b->ctrl.pitch; 427 oldDuration = b->ctrl.duration; 428 if (pitch != 0) { 429 if (pitch == -1) 430 b->ctrl.pitch = defaultKeyboardControl.bell_pitch; 431 else 432 b->ctrl.pitch = pitch; 433 } 434 if (duration != 0) { 435 if (duration == -1) 436 b->ctrl.duration = defaultKeyboardControl.bell_duration; 437 else 438 b->ctrl.duration = duration; 439 } 440 } 441 else { 442 client->errorValue = _XkbErrCode2(0x7, bellClass); 443 return BadValue; 444 } 445 446 newPercent = (base * percent) / 100; 447 if (percent < 0) 448 newPercent = base + newPercent; 449 else 450 newPercent = base - newPercent + percent; 451 452 XkbHandleBell(forceSound, eventOnly, 453 dev, newPercent, ctrl, bellClass, name, pWin, client); 454 if ((pitch != 0) || (duration != 0)) { 455 if (bellClass == KbdFeedbackClass) { 456 KbdFeedbackPtr k; 457 458 k = (KbdFeedbackPtr) ctrl; 459 if (pitch != 0) 460 k->ctrl.bell_pitch = oldPitch; 461 if (duration != 0) 462 k->ctrl.bell_duration = oldDuration; 463 } 464 else { 465 BellFeedbackPtr b; 466 467 b = (BellFeedbackPtr) ctrl; 468 if (pitch != 0) 469 b->ctrl.pitch = oldPitch; 470 if (duration != 0) 471 b->ctrl.duration = oldDuration; 472 } 473 } 474 475 return Success; 476} 477 478int 479ProcXkbBell(ClientPtr client) 480{ 481 REQUEST(xkbBellReq); 482 DeviceIntPtr dev; 483 WindowPtr pWin; 484 int rc; 485 486 REQUEST_SIZE_MATCH(xkbBellReq); 487 488 if (!(client->xkbClientFlags & _XkbClientInitialized)) 489 return BadAccess; 490 491 CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); 492 CHK_ATOM_OR_NONE(stuff->name); 493 494 /* device-independent checks request for sane values */ 495 if ((stuff->forceSound) && (stuff->eventOnly)) { 496 client->errorValue = 497 _XkbErrCode3(0x1, stuff->forceSound, stuff->eventOnly); 498 return BadMatch; 499 } 500 if (stuff->percent < -100 || stuff->percent > 100) { 501 client->errorValue = _XkbErrCode2(0x2, stuff->percent); 502 return BadValue; 503 } 504 if (stuff->duration < -1) { 505 client->errorValue = _XkbErrCode2(0x3, stuff->duration); 506 return BadValue; 507 } 508 if (stuff->pitch < -1) { 509 client->errorValue = _XkbErrCode2(0x4, stuff->pitch); 510 return BadValue; 511 } 512 513 if (stuff->bellClass == XkbDfltXIClass) { 514 if (dev->kbdfeed != NULL) 515 stuff->bellClass = KbdFeedbackClass; 516 else 517 stuff->bellClass = BellFeedbackClass; 518 } 519 520 if (stuff->window != None) { 521 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 522 if (rc != Success) { 523 client->errorValue = stuff->window; 524 return rc; 525 } 526 } 527 else 528 pWin = NULL; 529 530 /* Client wants to ring a bell on the core keyboard? 531 Ring the bell on the core keyboard (which does nothing, but if that 532 fails the client is screwed anyway), and then on all extension devices. 533 Fail if the core keyboard fails but not the extension devices. this 534 may cause some keyboards to ding and others to stay silent. Fix 535 your client to use explicit keyboards to avoid this. 536 537 dev is the device the client requested. 538 */ 539 rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, 540 stuff->pitch, stuff->duration, stuff->percent, 541 stuff->forceSound, stuff->eventOnly, stuff->name); 542 543 if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || 544 (stuff->deviceSpec == XkbUseCorePtr))) { 545 DeviceIntPtr other; 546 547 for (other = inputInfo.devices; other; other = other->next) { 548 if ((other != dev) && other->key && !IsMaster(other) && 549 GetMaster(other, MASTER_KEYBOARD) == dev) { 550 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); 551 if (rc == Success) 552 _XkbBell(client, other, pWin, stuff->bellClass, 553 stuff->bellID, stuff->pitch, stuff->duration, 554 stuff->percent, stuff->forceSound, 555 stuff->eventOnly, stuff->name); 556 } 557 } 558 rc = Success; /* reset to success, that's what we got for the VCK */ 559 } 560 561 return rc; 562} 563 564/***====================================================================***/ 565 566int 567ProcXkbGetState(ClientPtr client) 568{ 569 REQUEST(xkbGetStateReq); 570 DeviceIntPtr dev; 571 xkbGetStateReply rep; 572 XkbStateRec *xkb; 573 574 REQUEST_SIZE_MATCH(xkbGetStateReq); 575 576 if (!(client->xkbClientFlags & _XkbClientInitialized)) 577 return BadAccess; 578 579 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 580 581 xkb = &dev->key->xkbInfo->state; 582 rep = (xkbGetStateReply) { 583 .type = X_Reply, 584 .deviceID = dev->id, 585 .sequenceNumber = client->sequence, 586 .length = 0, 587 .mods = XkbStateFieldFromRec(xkb) & 0xff, 588 .baseMods = xkb->base_mods, 589 .latchedMods = xkb->latched_mods, 590 .lockedMods = xkb->locked_mods, 591 .group = xkb->group, 592 .lockedGroup = xkb->locked_group, 593 .baseGroup = xkb->base_group, 594 .latchedGroup = xkb->latched_group, 595 .compatState = xkb->compat_state, 596 .ptrBtnState = xkb->ptr_buttons 597 }; 598 if (client->swapped) { 599 swaps(&rep.sequenceNumber); 600 swaps(&rep.ptrBtnState); 601 } 602 WriteToClient(client, SIZEOF(xkbGetStateReply), &rep); 603 return Success; 604} 605 606/***====================================================================***/ 607 608int 609ProcXkbLatchLockState(ClientPtr client) 610{ 611 int status; 612 DeviceIntPtr dev, tmpd; 613 XkbStateRec oldState, *newState; 614 CARD16 changed; 615 xkbStateNotify sn; 616 XkbEventCauseRec cause; 617 618 REQUEST(xkbLatchLockStateReq); 619 REQUEST_SIZE_MATCH(xkbLatchLockStateReq); 620 621 if (!(client->xkbClientFlags & _XkbClientInitialized)) 622 return BadAccess; 623 624 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 625 CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); 626 CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); 627 628 status = Success; 629 630 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 631 if ((tmpd == dev) || 632 (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 633 if (!tmpd->key || !tmpd->key->xkbInfo) 634 continue; 635 636 oldState = tmpd->key->xkbInfo->state; 637 newState = &tmpd->key->xkbInfo->state; 638 if (stuff->affectModLocks) { 639 newState->locked_mods &= ~stuff->affectModLocks; 640 newState->locked_mods |= 641 (stuff->affectModLocks & stuff->modLocks); 642 } 643 if (status == Success && stuff->lockGroup) 644 newState->locked_group = stuff->groupLock; 645 if (status == Success && stuff->affectModLatches) 646 status = XkbLatchModifiers(tmpd, stuff->affectModLatches, 647 stuff->modLatches); 648 if (status == Success && stuff->latchGroup) 649 status = XkbLatchGroup(tmpd, stuff->groupLatch); 650 651 if (status != Success) 652 return status; 653 654 XkbComputeDerivedState(tmpd->key->xkbInfo); 655 656 changed = XkbStateChangedFlags(&oldState, newState); 657 if (changed) { 658 sn.keycode = 0; 659 sn.eventType = 0; 660 sn.requestMajor = XkbReqCode; 661 sn.requestMinor = X_kbLatchLockState; 662 sn.changed = changed; 663 XkbSendStateNotify(tmpd, &sn); 664 changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE); 665 if (changed) { 666 XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); 667 XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause); 668 } 669 } 670 } 671 } 672 673 return Success; 674} 675 676/***====================================================================***/ 677 678int 679ProcXkbGetControls(ClientPtr client) 680{ 681 xkbGetControlsReply rep; 682 XkbControlsPtr xkb; 683 DeviceIntPtr dev; 684 685 REQUEST(xkbGetControlsReq); 686 REQUEST_SIZE_MATCH(xkbGetControlsReq); 687 688 if (!(client->xkbClientFlags & _XkbClientInitialized)) 689 return BadAccess; 690 691 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 692 693 xkb = dev->key->xkbInfo->desc->ctrls; 694 rep = (xkbGetControlsReply) { 695 .type = X_Reply, 696 .deviceID = ((DeviceIntPtr) dev)->id, 697 .sequenceNumber = client->sequence, 698 .length = bytes_to_int32(SIZEOF(xkbGetControlsReply) - 699 SIZEOF(xGenericReply)), 700 .mkDfltBtn = xkb->mk_dflt_btn, 701 .numGroups = xkb->num_groups, 702 .groupsWrap = xkb->groups_wrap, 703 .internalMods = xkb->internal.mask, 704 .ignoreLockMods = xkb->ignore_lock.mask, 705 .internalRealMods = xkb->internal.real_mods, 706 .ignoreLockRealMods = xkb->ignore_lock.real_mods, 707 .internalVMods = xkb->internal.vmods, 708 .ignoreLockVMods = xkb->ignore_lock.vmods, 709 .repeatDelay = xkb->repeat_delay, 710 .repeatInterval = xkb->repeat_interval, 711 .slowKeysDelay = xkb->slow_keys_delay, 712 .debounceDelay = xkb->debounce_delay, 713 .mkDelay = xkb->mk_delay, 714 .mkInterval = xkb->mk_interval, 715 .mkTimeToMax = xkb->mk_time_to_max, 716 .mkMaxSpeed = xkb->mk_max_speed, 717 .mkCurve = xkb->mk_curve, 718 .axOptions = xkb->ax_options, 719 .axTimeout = xkb->ax_timeout, 720 .axtOptsMask = xkb->axt_opts_mask, 721 .axtOptsValues = xkb->axt_opts_values, 722 .axtCtrlsMask = xkb->axt_ctrls_mask, 723 .axtCtrlsValues = xkb->axt_ctrls_values, 724 .enabledCtrls = xkb->enabled_ctrls, 725 }; 726 memcpy(rep.perKeyRepeat, xkb->per_key_repeat, XkbPerKeyBitArraySize); 727 if (client->swapped) { 728 swaps(&rep.sequenceNumber); 729 swapl(&rep.length); 730 swaps(&rep.internalVMods); 731 swaps(&rep.ignoreLockVMods); 732 swapl(&rep.enabledCtrls); 733 swaps(&rep.repeatDelay); 734 swaps(&rep.repeatInterval); 735 swaps(&rep.slowKeysDelay); 736 swaps(&rep.debounceDelay); 737 swaps(&rep.mkDelay); 738 swaps(&rep.mkInterval); 739 swaps(&rep.mkTimeToMax); 740 swaps(&rep.mkMaxSpeed); 741 swaps(&rep.mkCurve); 742 swaps(&rep.axTimeout); 743 swapl(&rep.axtCtrlsMask); 744 swapl(&rep.axtCtrlsValues); 745 swaps(&rep.axtOptsMask); 746 swaps(&rep.axtOptsValues); 747 swaps(&rep.axOptions); 748 } 749 WriteToClient(client, SIZEOF(xkbGetControlsReply), &rep); 750 return Success; 751} 752 753int 754ProcXkbSetControls(ClientPtr client) 755{ 756 DeviceIntPtr dev, tmpd; 757 XkbSrvInfoPtr xkbi; 758 XkbControlsPtr ctrl; 759 XkbControlsRec new, old; 760 xkbControlsNotify cn; 761 XkbEventCauseRec cause; 762 XkbSrvLedInfoPtr sli; 763 764 REQUEST(xkbSetControlsReq); 765 REQUEST_SIZE_MATCH(xkbSetControlsReq); 766 767 if (!(client->xkbClientFlags & _XkbClientInitialized)) 768 return BadAccess; 769 770 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 771 CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask); 772 773 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 774 if (!tmpd->key || !tmpd->key->xkbInfo) 775 continue; 776 if ((tmpd == dev) || 777 (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 778 xkbi = tmpd->key->xkbInfo; 779 ctrl = xkbi->desc->ctrls; 780 new = *ctrl; 781 XkbSetCauseXkbReq(&cause, X_kbSetControls, client); 782 783 if (stuff->changeCtrls & XkbInternalModsMask) { 784 CHK_MASK_MATCH(0x02, stuff->affectInternalMods, 785 stuff->internalMods); 786 CHK_MASK_MATCH(0x03, stuff->affectInternalVMods, 787 stuff->internalVMods); 788 789 new.internal.real_mods &= ~(stuff->affectInternalMods); 790 new.internal.real_mods |= (stuff->affectInternalMods & 791 stuff->internalMods); 792 new.internal.vmods &= ~(stuff->affectInternalVMods); 793 new.internal.vmods |= (stuff->affectInternalVMods & 794 stuff->internalVMods); 795 new.internal.mask = new.internal.real_mods | 796 XkbMaskForVMask(xkbi->desc, new.internal.vmods); 797 } 798 799 if (stuff->changeCtrls & XkbIgnoreLockModsMask) { 800 CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods, 801 stuff->ignoreLockMods); 802 CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods, 803 stuff->ignoreLockVMods); 804 805 new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods); 806 new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods & 807 stuff->ignoreLockMods); 808 new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods); 809 new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods & 810 stuff->ignoreLockVMods); 811 new.ignore_lock.mask = new.ignore_lock.real_mods | 812 XkbMaskForVMask(xkbi->desc, new.ignore_lock.vmods); 813 } 814 815 CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls, 816 stuff->enabledCtrls); 817 if (stuff->affectEnabledCtrls) { 818 CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls, 819 XkbAllBooleanCtrlsMask); 820 821 new.enabled_ctrls &= ~(stuff->affectEnabledCtrls); 822 new.enabled_ctrls |= (stuff->affectEnabledCtrls & 823 stuff->enabledCtrls); 824 } 825 826 if (stuff->changeCtrls & XkbRepeatKeysMask) { 827 if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) { 828 client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay, 829 stuff->repeatInterval); 830 return BadValue; 831 } 832 833 new.repeat_delay = stuff->repeatDelay; 834 new.repeat_interval = stuff->repeatInterval; 835 } 836 837 if (stuff->changeCtrls & XkbSlowKeysMask) { 838 if (stuff->slowKeysDelay < 1) { 839 client->errorValue = _XkbErrCode2(0x09, 840 stuff->slowKeysDelay); 841 return BadValue; 842 } 843 844 new.slow_keys_delay = stuff->slowKeysDelay; 845 } 846 847 if (stuff->changeCtrls & XkbBounceKeysMask) { 848 if (stuff->debounceDelay < 1) { 849 client->errorValue = _XkbErrCode2(0x0A, 850 stuff->debounceDelay); 851 return BadValue; 852 } 853 854 new.debounce_delay = stuff->debounceDelay; 855 } 856 857 if (stuff->changeCtrls & XkbMouseKeysMask) { 858 if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) { 859 client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn); 860 return BadValue; 861 } 862 863 new.mk_dflt_btn = stuff->mkDfltBtn; 864 } 865 866 if (stuff->changeCtrls & XkbMouseKeysAccelMask) { 867 if (stuff->mkDelay < 1 || stuff->mkInterval < 1 || 868 stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 || 869 stuff->mkCurve < -1000) { 870 client->errorValue = _XkbErrCode2(0x0C, 0); 871 return BadValue; 872 } 873 874 new.mk_delay = stuff->mkDelay; 875 new.mk_interval = stuff->mkInterval; 876 new.mk_time_to_max = stuff->mkTimeToMax; 877 new.mk_max_speed = stuff->mkMaxSpeed; 878 new.mk_curve = stuff->mkCurve; 879 AccessXComputeCurveFactor(xkbi, &new); 880 } 881 882 if (stuff->changeCtrls & XkbGroupsWrapMask) { 883 unsigned act, num; 884 885 act = XkbOutOfRangeGroupAction(stuff->groupsWrap); 886 switch (act) { 887 case XkbRedirectIntoRange: 888 num = XkbOutOfRangeGroupNumber(stuff->groupsWrap); 889 if (num >= new.num_groups) { 890 client->errorValue = _XkbErrCode3(0x0D, new.num_groups, 891 num); 892 return BadValue; 893 } 894 case XkbWrapIntoRange: 895 case XkbClampIntoRange: 896 break; 897 default: 898 client->errorValue = _XkbErrCode2(0x0E, act); 899 return BadValue; 900 } 901 902 new.groups_wrap = stuff->groupsWrap; 903 } 904 905 CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask); 906 if (stuff->changeCtrls & XkbAccessXKeysMask) { 907 new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask; 908 } 909 else { 910 if (stuff->changeCtrls & XkbStickyKeysMask) { 911 new.ax_options &= ~(XkbAX_SKOptionsMask); 912 new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask); 913 } 914 915 if (stuff->changeCtrls & XkbAccessXFeedbackMask) { 916 new.ax_options &= ~(XkbAX_FBOptionsMask); 917 new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask); 918 } 919 } 920 921 if (stuff->changeCtrls & XkbAccessXTimeoutMask) { 922 if (stuff->axTimeout < 1) { 923 client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout); 924 return BadValue; 925 } 926 CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask, 927 stuff->axtCtrlsValues); 928 CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask, 929 XkbAllBooleanCtrlsMask); 930 CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues); 931 CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask); 932 new.ax_timeout = stuff->axTimeout; 933 new.axt_ctrls_mask = stuff->axtCtrlsMask; 934 new.axt_ctrls_values = (stuff->axtCtrlsValues & 935 stuff->axtCtrlsMask); 936 new.axt_opts_mask = stuff->axtOptsMask; 937 new.axt_opts_values = (stuff->axtOptsValues & 938 stuff->axtOptsMask); 939 } 940 941 if (stuff->changeCtrls & XkbPerKeyRepeatMask) { 942 memcpy(new.per_key_repeat, stuff->perKeyRepeat, 943 XkbPerKeyBitArraySize); 944 if (xkbi->repeatKey && 945 !BitIsOn(new.per_key_repeat, xkbi->repeatKey)) { 946 AccessXCancelRepeatKey(xkbi, xkbi->repeatKey); 947 } 948 } 949 950 old = *ctrl; 951 *ctrl = new; 952 XkbDDXChangeControls(tmpd, &old, ctrl); 953 954 if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) { 955 cn.keycode = 0; 956 cn.eventType = 0; 957 cn.requestMajor = XkbReqCode; 958 cn.requestMinor = X_kbSetControls; 959 XkbSendControlsNotify(tmpd, &cn); 960 } 961 962 sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); 963 if (sli) 964 XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL, 965 &cause); 966 967 /* If sticky keys were disabled, clear all locks and latches */ 968 if ((old.enabled_ctrls & XkbStickyKeysMask) && 969 !(ctrl->enabled_ctrls & XkbStickyKeysMask)) 970 XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause); 971 } 972 } 973 974 return Success; 975} 976 977/***====================================================================***/ 978 979static int 980XkbSizeKeyTypes(XkbDescPtr xkb, xkbGetMapReply * rep) 981{ 982 XkbKeyTypeRec *type; 983 unsigned i, len; 984 985 len = 0; 986 if (((rep->present & XkbKeyTypesMask) == 0) || (rep->nTypes < 1) || 987 (!xkb) || (!xkb->map) || (!xkb->map->types)) { 988 rep->present &= ~XkbKeyTypesMask; 989 rep->firstType = rep->nTypes = 0; 990 return 0; 991 } 992 type = &xkb->map->types[rep->firstType]; 993 for (i = 0; i < rep->nTypes; i++, type++) { 994 len += SIZEOF(xkbKeyTypeWireDesc); 995 if (type->map_count > 0) { 996 len += (type->map_count * SIZEOF(xkbKTMapEntryWireDesc)); 997 if (type->preserve) 998 len += (type->map_count * SIZEOF(xkbModsWireDesc)); 999 } 1000 } 1001 return len; 1002} 1003 1004static char * 1005XkbWriteKeyTypes(XkbDescPtr xkb, 1006 xkbGetMapReply * rep, char *buf, ClientPtr client) 1007{ 1008 XkbKeyTypePtr type; 1009 unsigned i; 1010 xkbKeyTypeWireDesc *wire; 1011 1012 type = &xkb->map->types[rep->firstType]; 1013 for (i = 0; i < rep->nTypes; i++, type++) { 1014 register unsigned n; 1015 1016 wire = (xkbKeyTypeWireDesc *) buf; 1017 wire->mask = type->mods.mask; 1018 wire->realMods = type->mods.real_mods; 1019 wire->virtualMods = type->mods.vmods; 1020 wire->numLevels = type->num_levels; 1021 wire->nMapEntries = type->map_count; 1022 wire->preserve = (type->preserve != NULL); 1023 if (client->swapped) { 1024 swaps(&wire->virtualMods); 1025 } 1026 1027 buf = (char *) &wire[1]; 1028 if (wire->nMapEntries > 0) { 1029 xkbKTMapEntryWireDesc *ewire; 1030 XkbKTMapEntryPtr entry; 1031 1032 ewire = (xkbKTMapEntryWireDesc *) buf; 1033 entry = type->map; 1034 for (n = 0; n < type->map_count; n++, ewire++, entry++) { 1035 ewire->active = entry->active; 1036 ewire->mask = entry->mods.mask; 1037 ewire->level = entry->level; 1038 ewire->realMods = entry->mods.real_mods; 1039 ewire->virtualMods = entry->mods.vmods; 1040 if (client->swapped) { 1041 swaps(&ewire->virtualMods); 1042 } 1043 } 1044 buf = (char *) ewire; 1045 if (type->preserve != NULL) { 1046 xkbModsWireDesc *pwire; 1047 XkbModsPtr preserve; 1048 1049 pwire = (xkbModsWireDesc *) buf; 1050 preserve = type->preserve; 1051 for (n = 0; n < type->map_count; n++, pwire++, preserve++) { 1052 pwire->mask = preserve->mask; 1053 pwire->realMods = preserve->real_mods; 1054 pwire->virtualMods = preserve->vmods; 1055 if (client->swapped) { 1056 swaps(&pwire->virtualMods); 1057 } 1058 } 1059 buf = (char *) pwire; 1060 } 1061 } 1062 } 1063 return buf; 1064} 1065 1066static int 1067XkbSizeKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep) 1068{ 1069 XkbSymMapPtr symMap; 1070 unsigned i, len; 1071 unsigned nSyms, nSymsThisKey; 1072 1073 if (((rep->present & XkbKeySymsMask) == 0) || (rep->nKeySyms < 1) || 1074 (!xkb) || (!xkb->map) || (!xkb->map->key_sym_map)) { 1075 rep->present &= ~XkbKeySymsMask; 1076 rep->firstKeySym = rep->nKeySyms = 0; 1077 rep->totalSyms = 0; 1078 return 0; 1079 } 1080 len = rep->nKeySyms * SIZEOF(xkbSymMapWireDesc); 1081 symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 1082 for (i = nSyms = 0; i < rep->nKeySyms; i++, symMap++) { 1083 if (symMap->offset != 0) { 1084 nSymsThisKey = XkbNumGroups(symMap->group_info) * symMap->width; 1085 nSyms += nSymsThisKey; 1086 } 1087 } 1088 len += nSyms * 4; 1089 rep->totalSyms = nSyms; 1090 return len; 1091} 1092 1093static int 1094XkbSizeVirtualMods(XkbDescPtr xkb, xkbGetMapReply * rep) 1095{ 1096 register unsigned i, nMods, bit; 1097 1098 if (((rep->present & XkbVirtualModsMask) == 0) || (rep->virtualMods == 0) || 1099 (!xkb) || (!xkb->server)) { 1100 rep->present &= ~XkbVirtualModsMask; 1101 rep->virtualMods = 0; 1102 return 0; 1103 } 1104 for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1105 if (rep->virtualMods & bit) 1106 nMods++; 1107 } 1108 return XkbPaddedSize(nMods); 1109} 1110 1111static char * 1112XkbWriteKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1113 ClientPtr client) 1114{ 1115 register KeySym *pSym; 1116 XkbSymMapPtr symMap; 1117 xkbSymMapWireDesc *outMap; 1118 register unsigned i; 1119 1120 symMap = &xkb->map->key_sym_map[rep->firstKeySym]; 1121 for (i = 0; i < rep->nKeySyms; i++, symMap++) { 1122 outMap = (xkbSymMapWireDesc *) buf; 1123 outMap->ktIndex[0] = symMap->kt_index[0]; 1124 outMap->ktIndex[1] = symMap->kt_index[1]; 1125 outMap->ktIndex[2] = symMap->kt_index[2]; 1126 outMap->ktIndex[3] = symMap->kt_index[3]; 1127 outMap->groupInfo = symMap->group_info; 1128 outMap->width = symMap->width; 1129 outMap->nSyms = symMap->width * XkbNumGroups(symMap->group_info); 1130 buf = (char *) &outMap[1]; 1131 if (outMap->nSyms == 0) 1132 continue; 1133 1134 pSym = &xkb->map->syms[symMap->offset]; 1135 memcpy((char *) buf, (char *) pSym, outMap->nSyms * 4); 1136 if (client->swapped) { 1137 register int nSyms = outMap->nSyms; 1138 1139 swaps(&outMap->nSyms); 1140 while (nSyms-- > 0) { 1141 swapl((int *) buf); 1142 buf += 4; 1143 } 1144 } 1145 else 1146 buf += outMap->nSyms * 4; 1147 } 1148 return buf; 1149} 1150 1151static int 1152XkbSizeKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep) 1153{ 1154 unsigned i, len, nActs; 1155 register KeyCode firstKey; 1156 1157 if (((rep->present & XkbKeyActionsMask) == 0) || (rep->nKeyActs < 1) || 1158 (!xkb) || (!xkb->server) || (!xkb->server->key_acts)) { 1159 rep->present &= ~XkbKeyActionsMask; 1160 rep->firstKeyAct = rep->nKeyActs = 0; 1161 rep->totalActs = 0; 1162 return 0; 1163 } 1164 firstKey = rep->firstKeyAct; 1165 for (nActs = i = 0; i < rep->nKeyActs; i++) { 1166 if (xkb->server->key_acts[i + firstKey] != 0) 1167 nActs += XkbKeyNumActions(xkb, i + firstKey); 1168 } 1169 len = XkbPaddedSize(rep->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc)); 1170 rep->totalActs = nActs; 1171 return len; 1172} 1173 1174static char * 1175XkbWriteKeyActions(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1176 ClientPtr client) 1177{ 1178 unsigned i; 1179 CARD8 *numDesc; 1180 XkbAnyAction *actDesc; 1181 1182 numDesc = (CARD8 *) buf; 1183 for (i = 0; i < rep->nKeyActs; i++) { 1184 if (xkb->server->key_acts[i + rep->firstKeyAct] == 0) 1185 numDesc[i] = 0; 1186 else 1187 numDesc[i] = XkbKeyNumActions(xkb, (i + rep->firstKeyAct)); 1188 } 1189 buf += XkbPaddedSize(rep->nKeyActs); 1190 1191 actDesc = (XkbAnyAction *) buf; 1192 for (i = 0; i < rep->nKeyActs; i++) { 1193 if (xkb->server->key_acts[i + rep->firstKeyAct] != 0) { 1194 unsigned int num; 1195 1196 num = XkbKeyNumActions(xkb, (i + rep->firstKeyAct)); 1197 memcpy((char *) actDesc, 1198 (char *) XkbKeyActionsPtr(xkb, (i + rep->firstKeyAct)), 1199 num * SIZEOF(xkbActionWireDesc)); 1200 actDesc += num; 1201 } 1202 } 1203 buf = (char *) actDesc; 1204 return buf; 1205} 1206 1207static int 1208XkbSizeKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep) 1209{ 1210 unsigned i, len, nBhvr; 1211 XkbBehavior *bhv; 1212 1213 if (((rep->present & XkbKeyBehaviorsMask) == 0) || (rep->nKeyBehaviors < 1) 1214 || (!xkb) || (!xkb->server) || (!xkb->server->behaviors)) { 1215 rep->present &= ~XkbKeyBehaviorsMask; 1216 rep->firstKeyBehavior = rep->nKeyBehaviors = 0; 1217 rep->totalKeyBehaviors = 0; 1218 return 0; 1219 } 1220 bhv = &xkb->server->behaviors[rep->firstKeyBehavior]; 1221 for (nBhvr = i = 0; i < rep->nKeyBehaviors; i++, bhv++) { 1222 if (bhv->type != XkbKB_Default) 1223 nBhvr++; 1224 } 1225 len = nBhvr * SIZEOF(xkbBehaviorWireDesc); 1226 rep->totalKeyBehaviors = nBhvr; 1227 return len; 1228} 1229 1230static char * 1231XkbWriteKeyBehaviors(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1232 ClientPtr client) 1233{ 1234 unsigned i; 1235 xkbBehaviorWireDesc *wire; 1236 XkbBehavior *pBhvr; 1237 1238 wire = (xkbBehaviorWireDesc *) buf; 1239 pBhvr = &xkb->server->behaviors[rep->firstKeyBehavior]; 1240 for (i = 0; i < rep->nKeyBehaviors; i++, pBhvr++) { 1241 if (pBhvr->type != XkbKB_Default) { 1242 wire->key = i + rep->firstKeyBehavior; 1243 wire->type = pBhvr->type; 1244 wire->data = pBhvr->data; 1245 wire++; 1246 } 1247 } 1248 buf = (char *) wire; 1249 return buf; 1250} 1251 1252static int 1253XkbSizeExplicit(XkbDescPtr xkb, xkbGetMapReply * rep) 1254{ 1255 unsigned i, len, nRtrn; 1256 1257 if (((rep->present & XkbExplicitComponentsMask) == 0) || 1258 (rep->nKeyExplicit < 1) || (!xkb) || (!xkb->server) || 1259 (!xkb->server->explicit)) { 1260 rep->present &= ~XkbExplicitComponentsMask; 1261 rep->firstKeyExplicit = rep->nKeyExplicit = 0; 1262 rep->totalKeyExplicit = 0; 1263 return 0; 1264 } 1265 for (nRtrn = i = 0; i < rep->nKeyExplicit; i++) { 1266 if (xkb->server->explicit[i + rep->firstKeyExplicit] != 0) 1267 nRtrn++; 1268 } 1269 rep->totalKeyExplicit = nRtrn; 1270 len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero explicit component */ 1271 return len; 1272} 1273 1274static char * 1275XkbWriteExplicit(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1276 ClientPtr client) 1277{ 1278 unsigned i; 1279 char *start; 1280 unsigned char *pExp; 1281 1282 start = buf; 1283 pExp = &xkb->server->explicit[rep->firstKeyExplicit]; 1284 for (i = 0; i < rep->nKeyExplicit; i++, pExp++) { 1285 if (*pExp != 0) { 1286 *buf++ = i + rep->firstKeyExplicit; 1287 *buf++ = *pExp; 1288 } 1289 } 1290 i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */ 1291 return buf + i; 1292} 1293 1294static int 1295XkbSizeModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep) 1296{ 1297 unsigned i, len, nRtrn; 1298 1299 if (((rep->present & XkbModifierMapMask) == 0) || (rep->nModMapKeys < 1) || 1300 (!xkb) || (!xkb->map) || (!xkb->map->modmap)) { 1301 rep->present &= ~XkbModifierMapMask; 1302 rep->firstModMapKey = rep->nModMapKeys = 0; 1303 rep->totalModMapKeys = 0; 1304 return 0; 1305 } 1306 for (nRtrn = i = 0; i < rep->nModMapKeys; i++) { 1307 if (xkb->map->modmap[i + rep->firstModMapKey] != 0) 1308 nRtrn++; 1309 } 1310 rep->totalModMapKeys = nRtrn; 1311 len = XkbPaddedSize(nRtrn * 2); /* two bytes per non-zero modmap component */ 1312 return len; 1313} 1314 1315static char * 1316XkbWriteModifierMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1317 ClientPtr client) 1318{ 1319 unsigned i; 1320 char *start; 1321 unsigned char *pMap; 1322 1323 start = buf; 1324 pMap = &xkb->map->modmap[rep->firstModMapKey]; 1325 for (i = 0; i < rep->nModMapKeys; i++, pMap++) { 1326 if (*pMap != 0) { 1327 *buf++ = i + rep->firstModMapKey; 1328 *buf++ = *pMap; 1329 } 1330 } 1331 i = XkbPaddedSize(buf - start) - (buf - start); /* pad to word boundary */ 1332 return buf + i; 1333} 1334 1335static int 1336XkbSizeVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep) 1337{ 1338 unsigned i, len, nRtrn; 1339 1340 if (((rep->present & XkbVirtualModMapMask) == 0) || (rep->nVModMapKeys < 1) 1341 || (!xkb) || (!xkb->server) || (!xkb->server->vmodmap)) { 1342 rep->present &= ~XkbVirtualModMapMask; 1343 rep->firstVModMapKey = rep->nVModMapKeys = 0; 1344 rep->totalVModMapKeys = 0; 1345 return 0; 1346 } 1347 for (nRtrn = i = 0; i < rep->nVModMapKeys; i++) { 1348 if (xkb->server->vmodmap[i + rep->firstVModMapKey] != 0) 1349 nRtrn++; 1350 } 1351 rep->totalVModMapKeys = nRtrn; 1352 len = nRtrn * SIZEOF(xkbVModMapWireDesc); 1353 return len; 1354} 1355 1356static char * 1357XkbWriteVirtualModMap(XkbDescPtr xkb, xkbGetMapReply * rep, char *buf, 1358 ClientPtr client) 1359{ 1360 unsigned i; 1361 xkbVModMapWireDesc *wire; 1362 unsigned short *pMap; 1363 1364 wire = (xkbVModMapWireDesc *) buf; 1365 pMap = &xkb->server->vmodmap[rep->firstVModMapKey]; 1366 for (i = 0; i < rep->nVModMapKeys; i++, pMap++) { 1367 if (*pMap != 0) { 1368 wire->key = i + rep->firstVModMapKey; 1369 wire->vmods = *pMap; 1370 wire++; 1371 } 1372 } 1373 return (char *) wire; 1374} 1375 1376static Status 1377XkbComputeGetMapReplySize(XkbDescPtr xkb, xkbGetMapReply * rep) 1378{ 1379 int len; 1380 1381 rep->minKeyCode = xkb->min_key_code; 1382 rep->maxKeyCode = xkb->max_key_code; 1383 len = XkbSizeKeyTypes(xkb, rep); 1384 len += XkbSizeKeySyms(xkb, rep); 1385 len += XkbSizeKeyActions(xkb, rep); 1386 len += XkbSizeKeyBehaviors(xkb, rep); 1387 len += XkbSizeVirtualMods(xkb, rep); 1388 len += XkbSizeExplicit(xkb, rep); 1389 len += XkbSizeModifierMap(xkb, rep); 1390 len += XkbSizeVirtualModMap(xkb, rep); 1391 rep->length += (len / 4); 1392 return Success; 1393} 1394 1395static int 1396XkbSendMap(ClientPtr client, XkbDescPtr xkb, xkbGetMapReply * rep) 1397{ 1398 unsigned i, len; 1399 char *desc, *start; 1400 1401 len = (rep->length * 4) - (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 1402 start = desc = calloc(1, len); 1403 if (!start) 1404 return BadAlloc; 1405 if (rep->nTypes > 0) 1406 desc = XkbWriteKeyTypes(xkb, rep, desc, client); 1407 if (rep->nKeySyms > 0) 1408 desc = XkbWriteKeySyms(xkb, rep, desc, client); 1409 if (rep->nKeyActs > 0) 1410 desc = XkbWriteKeyActions(xkb, rep, desc, client); 1411 if (rep->totalKeyBehaviors > 0) 1412 desc = XkbWriteKeyBehaviors(xkb, rep, desc, client); 1413 if (rep->virtualMods) { 1414 register int sz, bit; 1415 1416 for (i = sz = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1417 if (rep->virtualMods & bit) { 1418 desc[sz++] = xkb->server->vmods[i]; 1419 } 1420 } 1421 desc += XkbPaddedSize(sz); 1422 } 1423 if (rep->totalKeyExplicit > 0) 1424 desc = XkbWriteExplicit(xkb, rep, desc, client); 1425 if (rep->totalModMapKeys > 0) 1426 desc = XkbWriteModifierMap(xkb, rep, desc, client); 1427 if (rep->totalVModMapKeys > 0) 1428 desc = XkbWriteVirtualModMap(xkb, rep, desc, client); 1429 if ((desc - start) != (len)) { 1430 ErrorF 1431 ("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", 1432 len, (unsigned long) (desc - start)); 1433 } 1434 if (client->swapped) { 1435 swaps(&rep->sequenceNumber); 1436 swapl(&rep->length); 1437 swaps(&rep->present); 1438 swaps(&rep->totalSyms); 1439 swaps(&rep->totalActs); 1440 } 1441 WriteToClient(client, (i = SIZEOF(xkbGetMapReply)), rep); 1442 WriteToClient(client, len, start); 1443 free((char *) start); 1444 return Success; 1445} 1446 1447int 1448ProcXkbGetMap(ClientPtr client) 1449{ 1450 DeviceIntPtr dev; 1451 xkbGetMapReply rep; 1452 XkbDescRec *xkb; 1453 int n, status; 1454 1455 REQUEST(xkbGetMapReq); 1456 REQUEST_SIZE_MATCH(xkbGetMapReq); 1457 1458 if (!(client->xkbClientFlags & _XkbClientInitialized)) 1459 return BadAccess; 1460 1461 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 1462 CHK_MASK_OVERLAP(0x01, stuff->full, stuff->partial); 1463 CHK_MASK_LEGAL(0x02, stuff->full, XkbAllMapComponentsMask); 1464 CHK_MASK_LEGAL(0x03, stuff->partial, XkbAllMapComponentsMask); 1465 1466 xkb = dev->key->xkbInfo->desc; 1467 rep = (xkbGetMapReply) { 1468 .type = X_Reply, 1469 .deviceID = dev->id, 1470 .sequenceNumber = client->sequence, 1471 .length = (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2, 1472 .present = stuff->partial | stuff->full, 1473 .minKeyCode = xkb->min_key_code, 1474 .maxKeyCode = xkb->max_key_code 1475 }; 1476 1477 if (stuff->full & XkbKeyTypesMask) { 1478 rep.firstType = 0; 1479 rep.nTypes = xkb->map->num_types; 1480 } 1481 else if (stuff->partial & XkbKeyTypesMask) { 1482 if (((unsigned) stuff->firstType + stuff->nTypes) > xkb->map->num_types) { 1483 client->errorValue = _XkbErrCode4(0x04, xkb->map->num_types, 1484 stuff->firstType, stuff->nTypes); 1485 return BadValue; 1486 } 1487 rep.firstType = stuff->firstType; 1488 rep.nTypes = stuff->nTypes; 1489 } 1490 else 1491 rep.nTypes = 0; 1492 rep.totalTypes = xkb->map->num_types; 1493 1494 n = XkbNumKeys(xkb); 1495 if (stuff->full & XkbKeySymsMask) { 1496 rep.firstKeySym = xkb->min_key_code; 1497 rep.nKeySyms = n; 1498 } 1499 else if (stuff->partial & XkbKeySymsMask) { 1500 CHK_KEY_RANGE(0x05, stuff->firstKeySym, stuff->nKeySyms, xkb); 1501 rep.firstKeySym = stuff->firstKeySym; 1502 rep.nKeySyms = stuff->nKeySyms; 1503 } 1504 else 1505 rep.nKeySyms = 0; 1506 rep.totalSyms = 0; 1507 1508 if (stuff->full & XkbKeyActionsMask) { 1509 rep.firstKeyAct = xkb->min_key_code; 1510 rep.nKeyActs = n; 1511 } 1512 else if (stuff->partial & XkbKeyActionsMask) { 1513 CHK_KEY_RANGE(0x07, stuff->firstKeyAct, stuff->nKeyActs, xkb); 1514 rep.firstKeyAct = stuff->firstKeyAct; 1515 rep.nKeyActs = stuff->nKeyActs; 1516 } 1517 else 1518 rep.nKeyActs = 0; 1519 rep.totalActs = 0; 1520 1521 if (stuff->full & XkbKeyBehaviorsMask) { 1522 rep.firstKeyBehavior = xkb->min_key_code; 1523 rep.nKeyBehaviors = n; 1524 } 1525 else if (stuff->partial & XkbKeyBehaviorsMask) { 1526 CHK_KEY_RANGE(0x09, stuff->firstKeyBehavior, stuff->nKeyBehaviors, xkb); 1527 rep.firstKeyBehavior = stuff->firstKeyBehavior; 1528 rep.nKeyBehaviors = stuff->nKeyBehaviors; 1529 } 1530 else 1531 rep.nKeyBehaviors = 0; 1532 rep.totalKeyBehaviors = 0; 1533 1534 if (stuff->full & XkbVirtualModsMask) 1535 rep.virtualMods = ~0; 1536 else if (stuff->partial & XkbVirtualModsMask) 1537 rep.virtualMods = stuff->virtualMods; 1538 1539 if (stuff->full & XkbExplicitComponentsMask) { 1540 rep.firstKeyExplicit = xkb->min_key_code; 1541 rep.nKeyExplicit = n; 1542 } 1543 else if (stuff->partial & XkbExplicitComponentsMask) { 1544 CHK_KEY_RANGE(0x0B, stuff->firstKeyExplicit, stuff->nKeyExplicit, xkb); 1545 rep.firstKeyExplicit = stuff->firstKeyExplicit; 1546 rep.nKeyExplicit = stuff->nKeyExplicit; 1547 } 1548 else 1549 rep.nKeyExplicit = 0; 1550 rep.totalKeyExplicit = 0; 1551 1552 if (stuff->full & XkbModifierMapMask) { 1553 rep.firstModMapKey = xkb->min_key_code; 1554 rep.nModMapKeys = n; 1555 } 1556 else if (stuff->partial & XkbModifierMapMask) { 1557 CHK_KEY_RANGE(0x0D, stuff->firstModMapKey, stuff->nModMapKeys, xkb); 1558 rep.firstModMapKey = stuff->firstModMapKey; 1559 rep.nModMapKeys = stuff->nModMapKeys; 1560 } 1561 else 1562 rep.nModMapKeys = 0; 1563 rep.totalModMapKeys = 0; 1564 1565 if (stuff->full & XkbVirtualModMapMask) { 1566 rep.firstVModMapKey = xkb->min_key_code; 1567 rep.nVModMapKeys = n; 1568 } 1569 else if (stuff->partial & XkbVirtualModMapMask) { 1570 CHK_KEY_RANGE(0x0F, stuff->firstVModMapKey, stuff->nVModMapKeys, xkb); 1571 rep.firstVModMapKey = stuff->firstVModMapKey; 1572 rep.nVModMapKeys = stuff->nVModMapKeys; 1573 } 1574 else 1575 rep.nVModMapKeys = 0; 1576 rep.totalVModMapKeys = 0; 1577 1578 if ((status = XkbComputeGetMapReplySize(xkb, &rep)) != Success) 1579 return status; 1580 return XkbSendMap(client, xkb, &rep); 1581} 1582 1583/***====================================================================***/ 1584 1585static int 1586CheckKeyTypes(ClientPtr client, 1587 XkbDescPtr xkb, 1588 xkbSetMapReq * req, 1589 xkbKeyTypeWireDesc ** wireRtrn, 1590 int *nMapsRtrn, CARD8 *mapWidthRtrn) 1591{ 1592 unsigned nMaps; 1593 register unsigned i, n; 1594 register CARD8 *map; 1595 register xkbKeyTypeWireDesc *wire = *wireRtrn; 1596 1597 if (req->firstType > ((unsigned) xkb->map->num_types)) { 1598 *nMapsRtrn = _XkbErrCode3(0x01, req->firstType, xkb->map->num_types); 1599 return 0; 1600 } 1601 if (req->flags & XkbSetMapResizeTypes) { 1602 nMaps = req->firstType + req->nTypes; 1603 if (nMaps < XkbNumRequiredTypes) { /* canonical types must be there */ 1604 *nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, 4); 1605 return 0; 1606 } 1607 } 1608 else if (req->present & XkbKeyTypesMask) { 1609 nMaps = xkb->map->num_types; 1610 if ((req->firstType + req->nTypes) > nMaps) { 1611 *nMapsRtrn = req->firstType + req->nTypes; 1612 return 0; 1613 } 1614 } 1615 else { 1616 *nMapsRtrn = xkb->map->num_types; 1617 for (i = 0; i < xkb->map->num_types; i++) { 1618 mapWidthRtrn[i] = xkb->map->types[i].num_levels; 1619 } 1620 return 1; 1621 } 1622 1623 for (i = 0; i < req->firstType; i++) { 1624 mapWidthRtrn[i] = xkb->map->types[i].num_levels; 1625 } 1626 for (i = 0; i < req->nTypes; i++) { 1627 unsigned width; 1628 1629 if (client->swapped) { 1630 swaps(&wire->virtualMods); 1631 } 1632 n = i + req->firstType; 1633 width = wire->numLevels; 1634 if (width < 1) { 1635 *nMapsRtrn = _XkbErrCode3(0x04, n, width); 1636 return 0; 1637 } 1638 else if ((n == XkbOneLevelIndex) && (width != 1)) { /* must be width 1 */ 1639 *nMapsRtrn = _XkbErrCode3(0x05, n, width); 1640 return 0; 1641 } 1642 else if ((width != 2) && 1643 ((n == XkbTwoLevelIndex) || (n == XkbKeypadIndex) || 1644 (n == XkbAlphabeticIndex))) { 1645 /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ 1646 *nMapsRtrn = _XkbErrCode3(0x05, n, width); 1647 return 0; 1648 } 1649 if (wire->nMapEntries > 0) { 1650 xkbKTSetMapEntryWireDesc *mapWire; 1651 xkbModsWireDesc *preWire; 1652 1653 mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1]; 1654 preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries]; 1655 for (n = 0; n < wire->nMapEntries; n++) { 1656 if (client->swapped) { 1657 swaps(&mapWire[n].virtualMods); 1658 } 1659 if (mapWire[n].realMods & (~wire->realMods)) { 1660 *nMapsRtrn = _XkbErrCode4(0x06, n, mapWire[n].realMods, 1661 wire->realMods); 1662 return 0; 1663 } 1664 if (mapWire[n].virtualMods & (~wire->virtualMods)) { 1665 *nMapsRtrn = _XkbErrCode3(0x07, n, mapWire[n].virtualMods); 1666 return 0; 1667 } 1668 if (mapWire[n].level >= wire->numLevels) { 1669 *nMapsRtrn = _XkbErrCode4(0x08, n, wire->numLevels, 1670 mapWire[n].level); 1671 return 0; 1672 } 1673 if (wire->preserve) { 1674 if (client->swapped) { 1675 swaps(&preWire[n].virtualMods); 1676 } 1677 if (preWire[n].realMods & (~mapWire[n].realMods)) { 1678 *nMapsRtrn = _XkbErrCode4(0x09, n, preWire[n].realMods, 1679 mapWire[n].realMods); 1680 return 0; 1681 } 1682 if (preWire[n].virtualMods & (~mapWire[n].virtualMods)) { 1683 *nMapsRtrn = 1684 _XkbErrCode3(0x0a, n, preWire[n].virtualMods); 1685 return 0; 1686 } 1687 } 1688 } 1689 if (wire->preserve) 1690 map = (CARD8 *) &preWire[wire->nMapEntries]; 1691 else 1692 map = (CARD8 *) &mapWire[wire->nMapEntries]; 1693 } 1694 else 1695 map = (CARD8 *) &wire[1]; 1696 mapWidthRtrn[i + req->firstType] = wire->numLevels; 1697 wire = (xkbKeyTypeWireDesc *) map; 1698 } 1699 for (i = req->firstType + req->nTypes; i < nMaps; i++) { 1700 mapWidthRtrn[i] = xkb->map->types[i].num_levels; 1701 } 1702 *nMapsRtrn = nMaps; 1703 *wireRtrn = wire; 1704 return 1; 1705} 1706 1707static int 1708CheckKeySyms(ClientPtr client, 1709 XkbDescPtr xkb, 1710 xkbSetMapReq * req, 1711 int nTypes, 1712 CARD8 *mapWidths, 1713 CARD16 *symsPerKey, xkbSymMapWireDesc ** wireRtrn, int *errorRtrn) 1714{ 1715 register unsigned i; 1716 XkbSymMapPtr map; 1717 xkbSymMapWireDesc *wire = *wireRtrn; 1718 1719 if (!(XkbKeySymsMask & req->present)) 1720 return 1; 1721 CHK_REQ_KEY_RANGE2(0x11, req->firstKeySym, req->nKeySyms, req, (*errorRtrn), 1722 0); 1723 for (i = 0; i < req->nKeySyms; i++) { 1724 KeySym *pSyms; 1725 register unsigned nG; 1726 1727 if (client->swapped) { 1728 swaps(&wire->nSyms); 1729 } 1730 nG = XkbNumGroups(wire->groupInfo); 1731 if (nG > XkbNumKbdGroups) { 1732 *errorRtrn = _XkbErrCode3(0x14, i + req->firstKeySym, nG); 1733 return 0; 1734 } 1735 if (nG > 0) { 1736 register int g, w; 1737 1738 for (g = w = 0; g < nG; g++) { 1739 if (wire->ktIndex[g] >= (unsigned) nTypes) { 1740 *errorRtrn = _XkbErrCode4(0x15, i + req->firstKeySym, g, 1741 wire->ktIndex[g]); 1742 return 0; 1743 } 1744 if (mapWidths[wire->ktIndex[g]] > w) 1745 w = mapWidths[wire->ktIndex[g]]; 1746 } 1747 if (wire->width != w) { 1748 *errorRtrn = 1749 _XkbErrCode3(0x16, i + req->firstKeySym, wire->width); 1750 return 0; 1751 } 1752 w *= nG; 1753 symsPerKey[i + req->firstKeySym] = w; 1754 if (w != wire->nSyms) { 1755 *errorRtrn = 1756 _XkbErrCode4(0x16, i + req->firstKeySym, wire->nSyms, w); 1757 return 0; 1758 } 1759 } 1760 else if (wire->nSyms != 0) { 1761 *errorRtrn = _XkbErrCode3(0x17, i + req->firstKeySym, wire->nSyms); 1762 return 0; 1763 } 1764 pSyms = (KeySym *) &wire[1]; 1765 wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; 1766 } 1767 1768 map = &xkb->map->key_sym_map[i]; 1769 for (; i <= (unsigned) xkb->max_key_code; i++, map++) { 1770 register int g, nG, w; 1771 1772 nG = XkbKeyNumGroups(xkb, i); 1773 for (w = g = 0; g < nG; g++) { 1774 if (map->kt_index[g] >= (unsigned) nTypes) { 1775 *errorRtrn = _XkbErrCode4(0x18, i, g, map->kt_index[g]); 1776 return 0; 1777 } 1778 if (mapWidths[map->kt_index[g]] > w) 1779 w = mapWidths[map->kt_index[g]]; 1780 } 1781 symsPerKey[i] = w * nG; 1782 } 1783 *wireRtrn = wire; 1784 return 1; 1785} 1786 1787static int 1788CheckKeyActions(XkbDescPtr xkb, 1789 xkbSetMapReq * req, 1790 int nTypes, 1791 CARD8 *mapWidths, 1792 CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn) 1793{ 1794 int nActs; 1795 CARD8 *wire = *wireRtrn; 1796 register unsigned i; 1797 1798 if (!(XkbKeyActionsMask & req->present)) 1799 return 1; 1800 CHK_REQ_KEY_RANGE2(0x21, req->firstKeyAct, req->nKeyActs, req, (*nActsRtrn), 1801 0); 1802 for (nActs = i = 0; i < req->nKeyActs; i++) { 1803 if (wire[0] != 0) { 1804 if (wire[0] == symsPerKey[i + req->firstKeyAct]) 1805 nActs += wire[0]; 1806 else { 1807 *nActsRtrn = _XkbErrCode3(0x23, i + req->firstKeyAct, wire[0]); 1808 return 0; 1809 } 1810 } 1811 wire++; 1812 } 1813 if (req->nKeyActs % 4) 1814 wire += 4 - (req->nKeyActs % 4); 1815 *wireRtrn = (CARD8 *) (((XkbAnyAction *) wire) + nActs); 1816 *nActsRtrn = nActs; 1817 return 1; 1818} 1819 1820static int 1821CheckKeyBehaviors(XkbDescPtr xkb, 1822 xkbSetMapReq * req, 1823 xkbBehaviorWireDesc ** wireRtrn, int *errorRtrn) 1824{ 1825 register xkbBehaviorWireDesc *wire = *wireRtrn; 1826 register XkbServerMapPtr server = xkb->server; 1827 register unsigned i; 1828 unsigned first, last; 1829 1830 if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) { 1831 req->present &= ~XkbKeyBehaviorsMask; 1832 req->nKeyBehaviors = 0; 1833 return 1; 1834 } 1835 first = req->firstKeyBehavior; 1836 last = req->firstKeyBehavior + req->nKeyBehaviors - 1; 1837 if (first < req->minKeyCode) { 1838 *errorRtrn = _XkbErrCode3(0x31, first, req->minKeyCode); 1839 return 0; 1840 } 1841 if (last > req->maxKeyCode) { 1842 *errorRtrn = _XkbErrCode3(0x32, last, req->maxKeyCode); 1843 return 0; 1844 } 1845 1846 for (i = 0; i < req->totalKeyBehaviors; i++, wire++) { 1847 if ((wire->key < first) || (wire->key > last)) { 1848 *errorRtrn = _XkbErrCode4(0x33, first, last, wire->key); 1849 return 0; 1850 } 1851 if ((wire->type & XkbKB_Permanent) && 1852 ((server->behaviors[wire->key].type != wire->type) || 1853 (server->behaviors[wire->key].data != wire->data))) { 1854 *errorRtrn = _XkbErrCode3(0x33, wire->key, wire->type); 1855 return 0; 1856 } 1857 if ((wire->type == XkbKB_RadioGroup) && 1858 ((wire->data & (~XkbKB_RGAllowNone)) > XkbMaxRadioGroups)) { 1859 *errorRtrn = _XkbErrCode4(0x34, wire->key, wire->data, 1860 XkbMaxRadioGroups); 1861 return 0; 1862 } 1863 if ((wire->type == XkbKB_Overlay1) || (wire->type == XkbKB_Overlay2)) { 1864 CHK_KEY_RANGE2(0x35, wire->key, 1, xkb, *errorRtrn, 0); 1865 } 1866 } 1867 *wireRtrn = wire; 1868 return 1; 1869} 1870 1871static int 1872CheckVirtualMods(XkbDescRec * xkb, 1873 xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) 1874{ 1875 register CARD8 *wire = *wireRtrn; 1876 register unsigned i, nMods, bit; 1877 1878 if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) 1879 return 1; 1880 for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 1881 if (req->virtualMods & bit) 1882 nMods++; 1883 } 1884 *wireRtrn = (wire + XkbPaddedSize(nMods)); 1885 return 1; 1886} 1887 1888static int 1889CheckKeyExplicit(XkbDescPtr xkb, 1890 xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) 1891{ 1892 register CARD8 *wire = *wireRtrn; 1893 CARD8 *start; 1894 register unsigned i; 1895 int first, last; 1896 1897 if (((req->present & XkbExplicitComponentsMask) == 0) || 1898 (req->nKeyExplicit < 1)) { 1899 req->present &= ~XkbExplicitComponentsMask; 1900 req->nKeyExplicit = 0; 1901 return 1; 1902 } 1903 first = req->firstKeyExplicit; 1904 last = first + req->nKeyExplicit - 1; 1905 if (first < req->minKeyCode) { 1906 *errorRtrn = _XkbErrCode3(0x51, first, req->minKeyCode); 1907 return 0; 1908 } 1909 if (last > req->maxKeyCode) { 1910 *errorRtrn = _XkbErrCode3(0x52, last, req->maxKeyCode); 1911 return 0; 1912 } 1913 start = wire; 1914 for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { 1915 if ((wire[0] < first) || (wire[0] > last)) { 1916 *errorRtrn = _XkbErrCode4(0x53, first, last, wire[0]); 1917 return 0; 1918 } 1919 if (wire[1] & (~XkbAllExplicitMask)) { 1920 *errorRtrn = _XkbErrCode3(0x52, ~XkbAllExplicitMask, wire[1]); 1921 return 0; 1922 } 1923 } 1924 wire += XkbPaddedSize(wire - start) - (wire - start); 1925 *wireRtrn = wire; 1926 return 1; 1927} 1928 1929static int 1930CheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn, 1931 int *errRtrn) 1932{ 1933 register CARD8 *wire = *wireRtrn; 1934 CARD8 *start; 1935 register unsigned i; 1936 int first, last; 1937 1938 if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys < 1)) { 1939 req->present &= ~XkbModifierMapMask; 1940 req->nModMapKeys = 0; 1941 return 1; 1942 } 1943 first = req->firstModMapKey; 1944 last = first + req->nModMapKeys - 1; 1945 if (first < req->minKeyCode) { 1946 *errRtrn = _XkbErrCode3(0x61, first, req->minKeyCode); 1947 return 0; 1948 } 1949 if (last > req->maxKeyCode) { 1950 *errRtrn = _XkbErrCode3(0x62, last, req->maxKeyCode); 1951 return 0; 1952 } 1953 start = wire; 1954 for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { 1955 if ((wire[0] < first) || (wire[0] > last)) { 1956 *errRtrn = _XkbErrCode4(0x63, first, last, wire[0]); 1957 return 0; 1958 } 1959 } 1960 wire += XkbPaddedSize(wire - start) - (wire - start); 1961 *wireRtrn = wire; 1962 return 1; 1963} 1964 1965static int 1966CheckVirtualModMap(XkbDescPtr xkb, 1967 xkbSetMapReq * req, 1968 xkbVModMapWireDesc ** wireRtrn, int *errRtrn) 1969{ 1970 register xkbVModMapWireDesc *wire = *wireRtrn; 1971 register unsigned i; 1972 int first, last; 1973 1974 if (((req->present & XkbVirtualModMapMask) == 0) || (req->nVModMapKeys < 1)) { 1975 req->present &= ~XkbVirtualModMapMask; 1976 req->nVModMapKeys = 0; 1977 return 1; 1978 } 1979 first = req->firstVModMapKey; 1980 last = first + req->nVModMapKeys - 1; 1981 if (first < req->minKeyCode) { 1982 *errRtrn = _XkbErrCode3(0x71, first, req->minKeyCode); 1983 return 0; 1984 } 1985 if (last > req->maxKeyCode) { 1986 *errRtrn = _XkbErrCode3(0x72, last, req->maxKeyCode); 1987 return 0; 1988 } 1989 for (i = 0; i < req->totalVModMapKeys; i++, wire++) { 1990 if ((wire->key < first) || (wire->key > last)) { 1991 *errRtrn = _XkbErrCode4(0x73, first, last, wire->key); 1992 return 0; 1993 } 1994 } 1995 *wireRtrn = wire; 1996 return 1; 1997} 1998 1999static char * 2000SetKeyTypes(XkbDescPtr xkb, 2001 xkbSetMapReq * req, 2002 xkbKeyTypeWireDesc * wire, XkbChangesPtr changes) 2003{ 2004 register unsigned i; 2005 unsigned first, last; 2006 CARD8 *map; 2007 2008 if ((unsigned) (req->firstType + req->nTypes) > xkb->map->size_types) { 2009 i = req->firstType + req->nTypes; 2010 if (XkbAllocClientMap(xkb, XkbKeyTypesMask, i) != Success) { 2011 return NULL; 2012 } 2013 } 2014 if ((unsigned) (req->firstType + req->nTypes) > xkb->map->num_types) 2015 xkb->map->num_types = req->firstType + req->nTypes; 2016 2017 for (i = 0; i < req->nTypes; i++) { 2018 XkbKeyTypePtr pOld; 2019 register unsigned n; 2020 2021 if (XkbResizeKeyType(xkb, i + req->firstType, wire->nMapEntries, 2022 wire->preserve, wire->numLevels) != Success) { 2023 return NULL; 2024 } 2025 pOld = &xkb->map->types[i + req->firstType]; 2026 map = (CARD8 *) &wire[1]; 2027 2028 pOld->mods.real_mods = wire->realMods; 2029 pOld->mods.vmods = wire->virtualMods; 2030 pOld->num_levels = wire->numLevels; 2031 pOld->map_count = wire->nMapEntries; 2032 2033 pOld->mods.mask = pOld->mods.real_mods | 2034 XkbMaskForVMask(xkb, pOld->mods.vmods); 2035 2036 if (wire->nMapEntries) { 2037 xkbKTSetMapEntryWireDesc *mapWire; 2038 xkbModsWireDesc *preWire; 2039 unsigned tmp; 2040 2041 mapWire = (xkbKTSetMapEntryWireDesc *) map; 2042 preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries]; 2043 for (n = 0; n < wire->nMapEntries; n++) { 2044 pOld->map[n].active = 1; 2045 pOld->map[n].mods.mask = mapWire[n].realMods; 2046 pOld->map[n].mods.real_mods = mapWire[n].realMods; 2047 pOld->map[n].mods.vmods = mapWire[n].virtualMods; 2048 pOld->map[n].level = mapWire[n].level; 2049 if (mapWire[n].virtualMods != 0) { 2050 tmp = XkbMaskForVMask(xkb, mapWire[n].virtualMods); 2051 pOld->map[n].active = (tmp != 0); 2052 pOld->map[n].mods.mask |= tmp; 2053 } 2054 if (wire->preserve) { 2055 pOld->preserve[n].real_mods = preWire[n].realMods; 2056 pOld->preserve[n].vmods = preWire[n].virtualMods; 2057 tmp = XkbMaskForVMask(xkb, preWire[n].virtualMods); 2058 pOld->preserve[n].mask = preWire[n].realMods | tmp; 2059 } 2060 } 2061 if (wire->preserve) 2062 map = (CARD8 *) &preWire[wire->nMapEntries]; 2063 else 2064 map = (CARD8 *) &mapWire[wire->nMapEntries]; 2065 } 2066 else 2067 map = (CARD8 *) &wire[1]; 2068 wire = (xkbKeyTypeWireDesc *) map; 2069 } 2070 first = req->firstType; 2071 last = first + req->nTypes - 1; /* last changed type */ 2072 if (changes->map.changed & XkbKeyTypesMask) { 2073 int oldLast; 2074 2075 oldLast = changes->map.first_type + changes->map.num_types - 1; 2076 if (changes->map.first_type < first) 2077 first = changes->map.first_type; 2078 if (oldLast > last) 2079 last = oldLast; 2080 } 2081 changes->map.changed |= XkbKeyTypesMask; 2082 changes->map.first_type = first; 2083 changes->map.num_types = (last - first) + 1; 2084 return (char *) wire; 2085} 2086 2087static char * 2088SetKeySyms(ClientPtr client, 2089 XkbDescPtr xkb, 2090 xkbSetMapReq * req, 2091 xkbSymMapWireDesc * wire, XkbChangesPtr changes, DeviceIntPtr dev) 2092{ 2093 register unsigned i, s; 2094 XkbSymMapPtr oldMap; 2095 KeySym *newSyms; 2096 KeySym *pSyms; 2097 unsigned first, last; 2098 2099 oldMap = &xkb->map->key_sym_map[req->firstKeySym]; 2100 for (i = 0; i < req->nKeySyms; i++, oldMap++) { 2101 pSyms = (KeySym *) &wire[1]; 2102 if (wire->nSyms > 0) { 2103 newSyms = XkbResizeKeySyms(xkb, i + req->firstKeySym, wire->nSyms); 2104 for (s = 0; s < wire->nSyms; s++) { 2105 newSyms[s] = pSyms[s]; 2106 } 2107 if (client->swapped) { 2108 for (s = 0; s < wire->nSyms; s++) { 2109 swapl(&newSyms[s]); 2110 } 2111 } 2112 } 2113 if (XkbKeyHasActions(xkb, i + req->firstKeySym)) 2114 XkbResizeKeyActions(xkb, i + req->firstKeySym, 2115 XkbNumGroups(wire->groupInfo) * wire->width); 2116 oldMap->kt_index[0] = wire->ktIndex[0]; 2117 oldMap->kt_index[1] = wire->ktIndex[1]; 2118 oldMap->kt_index[2] = wire->ktIndex[2]; 2119 oldMap->kt_index[3] = wire->ktIndex[3]; 2120 oldMap->group_info = wire->groupInfo; 2121 oldMap->width = wire->width; 2122 wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; 2123 } 2124 first = req->firstKeySym; 2125 last = first + req->nKeySyms - 1; 2126 if (changes->map.changed & XkbKeySymsMask) { 2127 int oldLast = 2128 (changes->map.first_key_sym + changes->map.num_key_syms - 1); 2129 if (changes->map.first_key_sym < first) 2130 first = changes->map.first_key_sym; 2131 if (oldLast > last) 2132 last = oldLast; 2133 } 2134 changes->map.changed |= XkbKeySymsMask; 2135 changes->map.first_key_sym = first; 2136 changes->map.num_key_syms = (last - first + 1); 2137 2138 s = 0; 2139 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 2140 if (XkbKeyNumGroups(xkb, i) > s) 2141 s = XkbKeyNumGroups(xkb, i); 2142 } 2143 if (s != xkb->ctrls->num_groups) { 2144 xkbControlsNotify cn; 2145 XkbControlsRec old; 2146 2147 cn.keycode = 0; 2148 cn.eventType = 0; 2149 cn.requestMajor = XkbReqCode; 2150 cn.requestMinor = X_kbSetMap; 2151 old = *xkb->ctrls; 2152 xkb->ctrls->num_groups = s; 2153 if (XkbComputeControlsNotify(dev, &old, xkb->ctrls, &cn, FALSE)) 2154 XkbSendControlsNotify(dev, &cn); 2155 } 2156 return (char *) wire; 2157} 2158 2159static char * 2160SetKeyActions(XkbDescPtr xkb, 2161 xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 2162{ 2163 register unsigned i, first, last; 2164 CARD8 *nActs = wire; 2165 XkbAction *newActs; 2166 2167 wire += XkbPaddedSize(req->nKeyActs); 2168 for (i = 0; i < req->nKeyActs; i++) { 2169 if (nActs[i] == 0) 2170 xkb->server->key_acts[i + req->firstKeyAct] = 0; 2171 else { 2172 newActs = XkbResizeKeyActions(xkb, i + req->firstKeyAct, nActs[i]); 2173 memcpy((char *) newActs, (char *) wire, 2174 nActs[i] * SIZEOF(xkbActionWireDesc)); 2175 wire += nActs[i] * SIZEOF(xkbActionWireDesc); 2176 } 2177 } 2178 first = req->firstKeyAct; 2179 last = (first + req->nKeyActs - 1); 2180 if (changes->map.changed & XkbKeyActionsMask) { 2181 int oldLast; 2182 2183 oldLast = changes->map.first_key_act + changes->map.num_key_acts - 1; 2184 if (changes->map.first_key_act < first) 2185 first = changes->map.first_key_act; 2186 if (oldLast > last) 2187 last = oldLast; 2188 } 2189 changes->map.changed |= XkbKeyActionsMask; 2190 changes->map.first_key_act = first; 2191 changes->map.num_key_acts = (last - first + 1); 2192 return (char *) wire; 2193} 2194 2195static char * 2196SetKeyBehaviors(XkbSrvInfoPtr xkbi, 2197 xkbSetMapReq * req, 2198 xkbBehaviorWireDesc * wire, XkbChangesPtr changes) 2199{ 2200 register unsigned i; 2201 int maxRG = -1; 2202 XkbDescPtr xkb = xkbi->desc; 2203 XkbServerMapPtr server = xkb->server; 2204 unsigned first, last; 2205 2206 first = req->firstKeyBehavior; 2207 last = req->firstKeyBehavior + req->nKeyBehaviors - 1; 2208 memset(&server->behaviors[first], 0, 2209 req->nKeyBehaviors * sizeof(XkbBehavior)); 2210 for (i = 0; i < req->totalKeyBehaviors; i++) { 2211 if ((server->behaviors[wire->key].type & XkbKB_Permanent) == 0) { 2212 server->behaviors[wire->key].type = wire->type; 2213 server->behaviors[wire->key].data = wire->data; 2214 if ((wire->type == XkbKB_RadioGroup) && 2215 (((int) wire->data) > maxRG)) 2216 maxRG = wire->data + 1; 2217 } 2218 wire++; 2219 } 2220 2221 if (maxRG > (int) xkbi->nRadioGroups) { 2222 if (xkbi->radioGroups) 2223 xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG, 2224 sizeof(XkbRadioGroupRec)); 2225 else 2226 xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec)); 2227 if (xkbi->radioGroups) { 2228 if (xkbi->nRadioGroups) 2229 memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0, 2230 (maxRG - xkbi->nRadioGroups) * sizeof(XkbRadioGroupRec)); 2231 xkbi->nRadioGroups = maxRG; 2232 } 2233 else 2234 xkbi->nRadioGroups = 0; 2235 /* should compute members here */ 2236 } 2237 if (changes->map.changed & XkbKeyBehaviorsMask) { 2238 unsigned oldLast; 2239 2240 oldLast = changes->map.first_key_behavior + 2241 changes->map.num_key_behaviors - 1; 2242 if (changes->map.first_key_behavior < req->firstKeyBehavior) 2243 first = changes->map.first_key_behavior; 2244 if (oldLast > last) 2245 last = oldLast; 2246 } 2247 changes->map.changed |= XkbKeyBehaviorsMask; 2248 changes->map.first_key_behavior = first; 2249 changes->map.num_key_behaviors = (last - first + 1); 2250 return (char *) wire; 2251} 2252 2253static char * 2254SetVirtualMods(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2255 XkbChangesPtr changes) 2256{ 2257 register int i, bit, nMods; 2258 XkbServerMapPtr srv = xkbi->desc->server; 2259 2260 if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) 2261 return (char *) wire; 2262 for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 2263 if (req->virtualMods & bit) { 2264 if (srv->vmods[i] != wire[nMods]) { 2265 changes->map.changed |= XkbVirtualModsMask; 2266 changes->map.vmods |= bit; 2267 srv->vmods[i] = wire[nMods]; 2268 } 2269 nMods++; 2270 } 2271 } 2272 return (char *) (wire + XkbPaddedSize(nMods)); 2273} 2274 2275static char * 2276SetKeyExplicit(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2277 XkbChangesPtr changes) 2278{ 2279 register unsigned i, first, last; 2280 XkbServerMapPtr xkb = xkbi->desc->server; 2281 CARD8 *start; 2282 2283 start = wire; 2284 first = req->firstKeyExplicit; 2285 last = req->firstKeyExplicit + req->nKeyExplicit - 1; 2286 memset(&xkb->explicit[first], 0, req->nKeyExplicit); 2287 for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { 2288 xkb->explicit[wire[0]] = wire[1]; 2289 } 2290 if (first > 0) { 2291 if (changes->map.changed & XkbExplicitComponentsMask) { 2292 int oldLast; 2293 2294 oldLast = changes->map.first_key_explicit + 2295 changes->map.num_key_explicit - 1; 2296 if (changes->map.first_key_explicit < first) 2297 first = changes->map.first_key_explicit; 2298 if (oldLast > last) 2299 last = oldLast; 2300 } 2301 changes->map.first_key_explicit = first; 2302 changes->map.num_key_explicit = (last - first) + 1; 2303 } 2304 wire += XkbPaddedSize(wire - start) - (wire - start); 2305 return (char *) wire; 2306} 2307 2308static char * 2309SetModifierMap(XkbSrvInfoPtr xkbi, 2310 xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 2311{ 2312 register unsigned i, first, last; 2313 XkbClientMapPtr xkb = xkbi->desc->map; 2314 CARD8 *start; 2315 2316 start = wire; 2317 first = req->firstModMapKey; 2318 last = req->firstModMapKey + req->nModMapKeys - 1; 2319 memset(&xkb->modmap[first], 0, req->nModMapKeys); 2320 for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { 2321 xkb->modmap[wire[0]] = wire[1]; 2322 } 2323 if (first > 0) { 2324 if (changes->map.changed & XkbModifierMapMask) { 2325 int oldLast; 2326 2327 oldLast = changes->map.first_modmap_key + 2328 changes->map.num_modmap_keys - 1; 2329 if (changes->map.first_modmap_key < first) 2330 first = changes->map.first_modmap_key; 2331 if (oldLast > last) 2332 last = oldLast; 2333 } 2334 changes->map.first_modmap_key = first; 2335 changes->map.num_modmap_keys = (last - first) + 1; 2336 } 2337 wire += XkbPaddedSize(wire - start) - (wire - start); 2338 return (char *) wire; 2339} 2340 2341static char * 2342SetVirtualModMap(XkbSrvInfoPtr xkbi, 2343 xkbSetMapReq * req, 2344 xkbVModMapWireDesc * wire, XkbChangesPtr changes) 2345{ 2346 register unsigned i, first, last; 2347 XkbServerMapPtr srv = xkbi->desc->server; 2348 2349 first = req->firstVModMapKey; 2350 last = req->firstVModMapKey + req->nVModMapKeys - 1; 2351 memset(&srv->vmodmap[first], 0, req->nVModMapKeys * sizeof(unsigned short)); 2352 for (i = 0; i < req->totalVModMapKeys; i++, wire++) { 2353 srv->vmodmap[wire->key] = wire->vmods; 2354 } 2355 if (first > 0) { 2356 if (changes->map.changed & XkbVirtualModMapMask) { 2357 int oldLast; 2358 2359 oldLast = changes->map.first_vmodmap_key + 2360 changes->map.num_vmodmap_keys - 1; 2361 if (changes->map.first_vmodmap_key < first) 2362 first = changes->map.first_vmodmap_key; 2363 if (oldLast > last) 2364 last = oldLast; 2365 } 2366 changes->map.first_vmodmap_key = first; 2367 changes->map.num_vmodmap_keys = (last - first) + 1; 2368 } 2369 return (char *) wire; 2370} 2371 2372/** 2373 * Check if the given request can be applied to the given device but don't 2374 * actually do anything.. 2375 */ 2376static int 2377_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, 2378 char *values) 2379{ 2380 XkbSrvInfoPtr xkbi; 2381 XkbDescPtr xkb; 2382 int error; 2383 int nTypes = 0, nActions; 2384 CARD8 mapWidths[XkbMaxLegalKeyCode + 1] = { 0 }; 2385 CARD16 symsPerKey[XkbMaxLegalKeyCode + 1] = { 0 }; 2386 XkbSymMapPtr map; 2387 int i; 2388 2389 if (!dev->key) 2390 return 0; 2391 2392 xkbi = dev->key->xkbInfo; 2393 xkb = xkbi->desc; 2394 2395 if ((xkb->min_key_code != req->minKeyCode) || 2396 (xkb->max_key_code != req->maxKeyCode)) { 2397 if (client->xkbClientFlags & _XkbClientIsAncient) { 2398 /* pre 1.0 versions of Xlib have a bug */ 2399 req->minKeyCode = xkb->min_key_code; 2400 req->maxKeyCode = xkb->max_key_code; 2401 } 2402 else { 2403 if (!XkbIsLegalKeycode(req->minKeyCode)) { 2404 client->errorValue = 2405 _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); 2406 return BadValue; 2407 } 2408 if (req->minKeyCode > req->maxKeyCode) { 2409 client->errorValue = 2410 _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); 2411 return BadMatch; 2412 } 2413 } 2414 } 2415 2416 if ((req->present & XkbKeyTypesMask) && 2417 (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values, 2418 &nTypes, mapWidths))) { 2419 client->errorValue = nTypes; 2420 return BadValue; 2421 } 2422 2423 /* symsPerKey/mapWidths must be filled regardless of client-side flags */ 2424 map = &xkb->map->key_sym_map[xkb->min_key_code]; 2425 for (i = xkb->min_key_code; i < xkb->max_key_code; i++, map++) { 2426 register int g, ng, w; 2427 2428 ng = XkbNumGroups(map->group_info); 2429 for (w = g = 0; g < ng; g++) { 2430 if (map->kt_index[g] >= (unsigned) nTypes) { 2431 client->errorValue = _XkbErrCode4(0x13, i, g, map->kt_index[g]); 2432 return 0; 2433 } 2434 if (mapWidths[map->kt_index[g]] > w) 2435 w = mapWidths[map->kt_index[g]]; 2436 } 2437 symsPerKey[i] = w * ng; 2438 } 2439 2440 if ((req->present & XkbKeySymsMask) && 2441 (!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey, 2442 (xkbSymMapWireDesc **) &values, &error))) { 2443 client->errorValue = error; 2444 return BadValue; 2445 } 2446 2447 if ((req->present & XkbKeyActionsMask) && 2448 (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey, 2449 (CARD8 **) &values, &nActions))) { 2450 client->errorValue = nActions; 2451 return BadValue; 2452 } 2453 2454 if ((req->present & XkbKeyBehaviorsMask) && 2455 (!CheckKeyBehaviors 2456 (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) { 2457 client->errorValue = error; 2458 return BadValue; 2459 } 2460 2461 if ((req->present & XkbVirtualModsMask) && 2462 (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) { 2463 client->errorValue = error; 2464 return BadValue; 2465 } 2466 if ((req->present & XkbExplicitComponentsMask) && 2467 (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) { 2468 client->errorValue = error; 2469 return BadValue; 2470 } 2471 if ((req->present & XkbModifierMapMask) && 2472 (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) { 2473 client->errorValue = error; 2474 return BadValue; 2475 } 2476 if ((req->present & XkbVirtualModMapMask) && 2477 (!CheckVirtualModMap 2478 (xkb, req, (xkbVModMapWireDesc **) &values, &error))) { 2479 client->errorValue = error; 2480 return BadValue; 2481 } 2482 2483 if (((values - ((char *) req)) / 4) != req->length) { 2484 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); 2485 client->errorValue = values - ((char *) &req[1]); 2486 return BadLength; 2487 } 2488 2489 return Success; 2490} 2491 2492/** 2493 * Apply the given request on the given device. 2494 */ 2495static int 2496_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values) 2497{ 2498 XkbEventCauseRec cause; 2499 XkbChangesRec change; 2500 Bool sentNKN; 2501 XkbSrvInfoPtr xkbi; 2502 XkbDescPtr xkb; 2503 2504 if (!dev->key) 2505 return Success; 2506 2507 xkbi = dev->key->xkbInfo; 2508 xkb = xkbi->desc; 2509 2510 XkbSetCauseXkbReq(&cause, X_kbSetMap, client); 2511 memset(&change, 0, sizeof(change)); 2512 sentNKN = FALSE; 2513 if ((xkb->min_key_code != req->minKeyCode) || 2514 (xkb->max_key_code != req->maxKeyCode)) { 2515 Status status; 2516 xkbNewKeyboardNotify nkn; 2517 2518 nkn.deviceID = nkn.oldDeviceID = dev->id; 2519 nkn.oldMinKeyCode = xkb->min_key_code; 2520 nkn.oldMaxKeyCode = xkb->max_key_code; 2521 status = XkbChangeKeycodeRange(xkb, req->minKeyCode, 2522 req->maxKeyCode, &change); 2523 if (status != Success) 2524 return status; /* oh-oh. what about the other keyboards? */ 2525 nkn.minKeyCode = xkb->min_key_code; 2526 nkn.maxKeyCode = xkb->max_key_code; 2527 nkn.requestMajor = XkbReqCode; 2528 nkn.requestMinor = X_kbSetMap; 2529 nkn.changed = XkbNKN_KeycodesMask; 2530 XkbSendNewKeyboardNotify(dev, &nkn); 2531 sentNKN = TRUE; 2532 } 2533 2534 if (req->present & XkbKeyTypesMask) { 2535 values = SetKeyTypes(xkb, req, (xkbKeyTypeWireDesc *) values, &change); 2536 if (!values) 2537 goto allocFailure; 2538 } 2539 if (req->present & XkbKeySymsMask) { 2540 values = 2541 SetKeySyms(client, xkb, req, (xkbSymMapWireDesc *) values, &change, 2542 dev); 2543 if (!values) 2544 goto allocFailure; 2545 } 2546 if (req->present & XkbKeyActionsMask) { 2547 values = SetKeyActions(xkb, req, (CARD8 *) values, &change); 2548 if (!values) 2549 goto allocFailure; 2550 } 2551 if (req->present & XkbKeyBehaviorsMask) { 2552 values = 2553 SetKeyBehaviors(xkbi, req, (xkbBehaviorWireDesc *) values, &change); 2554 if (!values) 2555 goto allocFailure; 2556 } 2557 if (req->present & XkbVirtualModsMask) 2558 values = SetVirtualMods(xkbi, req, (CARD8 *) values, &change); 2559 if (req->present & XkbExplicitComponentsMask) 2560 values = SetKeyExplicit(xkbi, req, (CARD8 *) values, &change); 2561 if (req->present & XkbModifierMapMask) 2562 values = SetModifierMap(xkbi, req, (CARD8 *) values, &change); 2563 if (req->present & XkbVirtualModMapMask) 2564 values = 2565 SetVirtualModMap(xkbi, req, (xkbVModMapWireDesc *) values, &change); 2566 if (((values - ((char *) req)) / 4) != req->length) { 2567 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); 2568 client->errorValue = values - ((char *) &req[1]); 2569 return BadLength; 2570 } 2571 if (req->flags & XkbSetMapRecomputeActions) { 2572 KeyCode first, last, firstMM, lastMM; 2573 2574 if (change.map.num_key_syms > 0) { 2575 first = change.map.first_key_sym; 2576 last = first + change.map.num_key_syms - 1; 2577 } 2578 else 2579 first = last = 0; 2580 if (change.map.num_modmap_keys > 0) { 2581 firstMM = change.map.first_modmap_key; 2582 lastMM = firstMM + change.map.num_modmap_keys - 1; 2583 } 2584 else 2585 firstMM = lastMM = 0; 2586 if ((last > 0) && (lastMM > 0)) { 2587 if (firstMM < first) 2588 first = firstMM; 2589 if (lastMM > last) 2590 last = lastMM; 2591 } 2592 else if (lastMM > 0) { 2593 first = firstMM; 2594 last = lastMM; 2595 } 2596 if (last > 0) { 2597 unsigned check = 0; 2598 2599 XkbUpdateActions(dev, first, (last - first + 1), &change, &check, 2600 &cause); 2601 if (check) 2602 XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 2603 } 2604 } 2605 if (!sentNKN) 2606 XkbSendNotification(dev, &change, &cause); 2607 2608 return Success; 2609 allocFailure: 2610 return BadAlloc; 2611} 2612 2613int 2614ProcXkbSetMap(ClientPtr client) 2615{ 2616 DeviceIntPtr dev; 2617 char *tmp; 2618 int rc; 2619 2620 REQUEST(xkbSetMapReq); 2621 REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 2622 2623 if (!(client->xkbClientFlags & _XkbClientInitialized)) 2624 return BadAccess; 2625 2626 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 2627 CHK_MASK_LEGAL(0x01, stuff->present, XkbAllMapComponentsMask); 2628 2629 tmp = (char *) &stuff[1]; 2630 2631 /* Check if we can to the SetMap on the requested device. If this 2632 succeeds, do the same thing for all extension devices (if needed). 2633 If any of them fails, fail. */ 2634 rc = _XkbSetMapChecks(client, dev, stuff, tmp); 2635 2636 if (rc != Success) 2637 return rc; 2638 2639 DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); 2640 2641 if (stuff->deviceSpec == XkbUseCoreKbd) { 2642 DeviceIntPtr other; 2643 2644 for (other = inputInfo.devices; other; other = other->next) { 2645 if ((other != dev) && other->key && !IsMaster(other) && 2646 GetMaster(other, MASTER_KEYBOARD) == dev) { 2647 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2648 DixManageAccess); 2649 if (rc == Success) { 2650 rc = _XkbSetMapChecks(client, other, stuff, tmp); 2651 if (rc != Success) 2652 return rc; 2653 } 2654 } 2655 } 2656 } else { 2657 DeviceIntPtr other; 2658 2659 for (other = inputInfo.devices; other; other = other->next) { 2660 if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 2661 (other != master || dev != master->lastSlave)) 2662 continue; 2663 2664 rc = _XkbSetMapChecks(client, other, stuff, tmp); 2665 if (rc != Success) 2666 return rc; 2667 } 2668 } 2669 2670 /* We know now that we will succeed with the SetMap. In theory anyway. */ 2671 rc = _XkbSetMap(client, dev, stuff, tmp); 2672 if (rc != Success) 2673 return rc; 2674 2675 if (stuff->deviceSpec == XkbUseCoreKbd) { 2676 DeviceIntPtr other; 2677 2678 for (other = inputInfo.devices; other; other = other->next) { 2679 if ((other != dev) && other->key && !IsMaster(other) && 2680 GetMaster(other, MASTER_KEYBOARD) == dev) { 2681 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2682 DixManageAccess); 2683 if (rc == Success) 2684 _XkbSetMap(client, other, stuff, tmp); 2685 /* ignore rc. if the SetMap failed although the check above 2686 reported true there isn't much we can do. we still need to 2687 set all other devices, hoping that at least they stay in 2688 sync. */ 2689 } 2690 } 2691 } else { 2692 DeviceIntPtr other; 2693 2694 for (other = inputInfo.devices; other; other = other->next) { 2695 if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 2696 (other != master || dev != master->lastSlave)) 2697 continue; 2698 2699 _XkbSetMap(client, other, stuff, tmp); //ignore rc 2700 } 2701 } 2702 2703 return Success; 2704} 2705 2706/***====================================================================***/ 2707 2708static Status 2709XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat, 2710 xkbGetCompatMapReply * rep) 2711{ 2712 unsigned size, nGroups; 2713 2714 nGroups = 0; 2715 if (rep->groups != 0) { 2716 register int i, bit; 2717 2718 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2719 if (rep->groups & bit) 2720 nGroups++; 2721 } 2722 } 2723 size = nGroups * SIZEOF(xkbModsWireDesc); 2724 size += (rep->nSI * SIZEOF(xkbSymInterpretWireDesc)); 2725 rep->length = size / 4; 2726 return Success; 2727} 2728 2729static int 2730XkbSendCompatMap(ClientPtr client, 2731 XkbCompatMapPtr compat, xkbGetCompatMapReply * rep) 2732{ 2733 char *data; 2734 int size; 2735 2736 if (rep->length > 0) { 2737 data = xallocarray(rep->length, 4); 2738 if (data) { 2739 register unsigned i, bit; 2740 xkbModsWireDesc *grp; 2741 XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI]; 2742 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2743 2744 size = rep->length * 4; 2745 2746 for (i = 0; i < rep->nSI; i++, sym++, wire++) { 2747 wire->sym = sym->sym; 2748 wire->mods = sym->mods; 2749 wire->match = sym->match; 2750 wire->virtualMod = sym->virtual_mod; 2751 wire->flags = sym->flags; 2752 memcpy((char *) &wire->act, (char *) &sym->act, 2753 sz_xkbActionWireDesc); 2754 if (client->swapped) { 2755 swapl(&wire->sym); 2756 } 2757 } 2758 if (rep->groups) { 2759 grp = (xkbModsWireDesc *) wire; 2760 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2761 if (rep->groups & bit) { 2762 grp->mask = compat->groups[i].mask; 2763 grp->realMods = compat->groups[i].real_mods; 2764 grp->virtualMods = compat->groups[i].vmods; 2765 if (client->swapped) { 2766 swaps(&grp->virtualMods); 2767 } 2768 grp++; 2769 } 2770 } 2771 wire = (xkbSymInterpretWireDesc *) grp; 2772 } 2773 } 2774 else 2775 return BadAlloc; 2776 } 2777 else 2778 data = NULL; 2779 2780 if (client->swapped) { 2781 swaps(&rep->sequenceNumber); 2782 swapl(&rep->length); 2783 swaps(&rep->firstSI); 2784 swaps(&rep->nSI); 2785 swaps(&rep->nTotalSI); 2786 } 2787 2788 WriteToClient(client, SIZEOF(xkbGetCompatMapReply), rep); 2789 if (data) { 2790 WriteToClient(client, size, data); 2791 free((char *) data); 2792 } 2793 return Success; 2794} 2795 2796int 2797ProcXkbGetCompatMap(ClientPtr client) 2798{ 2799 xkbGetCompatMapReply rep; 2800 DeviceIntPtr dev; 2801 XkbDescPtr xkb; 2802 XkbCompatMapPtr compat; 2803 2804 REQUEST(xkbGetCompatMapReq); 2805 REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 2806 2807 if (!(client->xkbClientFlags & _XkbClientInitialized)) 2808 return BadAccess; 2809 2810 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 2811 2812 xkb = dev->key->xkbInfo->desc; 2813 compat = xkb->compat; 2814 2815 rep = (xkbGetCompatMapReply) { 2816 .type = X_Reply, 2817 .sequenceNumber = client->sequence, 2818 .length = 0, 2819 .deviceID = dev->id, 2820 .firstSI = stuff->firstSI, 2821 .nSI = stuff->nSI 2822 }; 2823 if (stuff->getAllSI) { 2824 rep.firstSI = 0; 2825 rep.nSI = compat->num_si; 2826 } 2827 else if ((((unsigned) stuff->nSI) > 0) && 2828 ((unsigned) (stuff->firstSI + stuff->nSI - 1) >= compat->num_si)) { 2829 client->errorValue = _XkbErrCode2(0x05, compat->num_si); 2830 return BadValue; 2831 } 2832 rep.nTotalSI = compat->num_si; 2833 rep.groups = stuff->groups; 2834 XkbComputeGetCompatMapReplySize(compat, &rep); 2835 return XkbSendCompatMap(client, compat, &rep); 2836} 2837 2838/** 2839 * Apply the given request on the given device. 2840 * If dryRun is TRUE, then value checks are performed, but the device isn't 2841 * modified. 2842 */ 2843static int 2844_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, 2845 xkbSetCompatMapReq * req, char *data, BOOL dryRun) 2846{ 2847 XkbSrvInfoPtr xkbi; 2848 XkbDescPtr xkb; 2849 XkbCompatMapPtr compat; 2850 int nGroups; 2851 unsigned i, bit; 2852 2853 xkbi = dev->key->xkbInfo; 2854 xkb = xkbi->desc; 2855 compat = xkb->compat; 2856 2857 if ((req->nSI > 0) || (req->truncateSI)) { 2858 xkbSymInterpretWireDesc *wire; 2859 2860 if (req->firstSI > compat->num_si) { 2861 client->errorValue = _XkbErrCode2(0x02, compat->num_si); 2862 return BadValue; 2863 } 2864 wire = (xkbSymInterpretWireDesc *) data; 2865 wire += req->nSI; 2866 data = (char *) wire; 2867 } 2868 2869 nGroups = 0; 2870 if (req->groups != 0) { 2871 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2872 if (req->groups & bit) 2873 nGroups++; 2874 } 2875 } 2876 data += nGroups * SIZEOF(xkbModsWireDesc); 2877 if (((data - ((char *) req)) / 4) != req->length) { 2878 return BadLength; 2879 } 2880 2881 /* Done all the checks we can do */ 2882 if (dryRun) 2883 return Success; 2884 2885 data = (char *) &req[1]; 2886 if (req->nSI > 0) { 2887 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2888 XkbSymInterpretPtr sym; 2889 unsigned int skipped = 0; 2890 2891 if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) { 2892 compat->num_si = req->firstSI + req->nSI; 2893 compat->sym_interpret = reallocarray(compat->sym_interpret, 2894 compat->num_si, 2895 sizeof(XkbSymInterpretRec)); 2896 if (!compat->sym_interpret) { 2897 compat->num_si = 0; 2898 return BadAlloc; 2899 } 2900 } 2901 else if (req->truncateSI) { 2902 compat->num_si = req->firstSI + req->nSI; 2903 } 2904 sym = &compat->sym_interpret[req->firstSI]; 2905 for (i = 0; i < req->nSI; i++, wire++) { 2906 if (client->swapped) { 2907 swapl(&wire->sym); 2908 } 2909 if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone && 2910 (wire->mods & 0xff) == 0xff && 2911 wire->act.type == XkbSA_XFree86Private) { 2912 ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private " 2913 "action from client\n"); 2914 skipped++; 2915 continue; 2916 } 2917 sym->sym = wire->sym; 2918 sym->mods = wire->mods; 2919 sym->match = wire->match; 2920 sym->flags = wire->flags; 2921 sym->virtual_mod = wire->virtualMod; 2922 memcpy((char *) &sym->act, (char *) &wire->act, 2923 SIZEOF(xkbActionWireDesc)); 2924 sym++; 2925 } 2926 if (skipped) { 2927 if (req->firstSI + req->nSI < compat->num_si) 2928 memmove(sym, sym + skipped, 2929 (compat->num_si - req->firstSI - req->nSI) * 2930 sizeof(*sym)); 2931 compat->num_si -= skipped; 2932 } 2933 data = (char *) wire; 2934 } 2935 else if (req->truncateSI) { 2936 compat->num_si = req->firstSI; 2937 } 2938 2939 if (req->groups != 0) { 2940 xkbModsWireDesc *wire = (xkbModsWireDesc *) data; 2941 2942 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2943 if (req->groups & bit) { 2944 if (client->swapped) { 2945 swaps(&wire->virtualMods); 2946 } 2947 compat->groups[i].mask = wire->realMods; 2948 compat->groups[i].real_mods = wire->realMods; 2949 compat->groups[i].vmods = wire->virtualMods; 2950 if (wire->virtualMods != 0) { 2951 unsigned tmp; 2952 2953 tmp = XkbMaskForVMask(xkb, wire->virtualMods); 2954 compat->groups[i].mask |= tmp; 2955 } 2956 data += SIZEOF(xkbModsWireDesc); 2957 wire = (xkbModsWireDesc *) data; 2958 } 2959 } 2960 } 2961 i = XkbPaddedSize((data - ((char *) req))); 2962 if ((i / 4) != req->length) { 2963 ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); 2964 return BadLength; 2965 } 2966 2967 if (dev->xkb_interest) { 2968 xkbCompatMapNotify ev; 2969 2970 ev.deviceID = dev->id; 2971 ev.changedGroups = req->groups; 2972 ev.firstSI = req->firstSI; 2973 ev.nSI = req->nSI; 2974 ev.nTotalSI = compat->num_si; 2975 XkbSendCompatMapNotify(dev, &ev); 2976 } 2977 2978 if (req->recomputeActions) { 2979 XkbChangesRec change; 2980 unsigned check; 2981 XkbEventCauseRec cause; 2982 2983 XkbSetCauseXkbReq(&cause, X_kbSetCompatMap, client); 2984 memset(&change, 0, sizeof(XkbChangesRec)); 2985 XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &change, 2986 &check, &cause); 2987 if (check) 2988 XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 2989 XkbSendNotification(dev, &change, &cause); 2990 } 2991 return Success; 2992} 2993 2994int 2995ProcXkbSetCompatMap(ClientPtr client) 2996{ 2997 DeviceIntPtr dev; 2998 char *data; 2999 int rc; 3000 3001 REQUEST(xkbSetCompatMapReq); 3002 REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 3003 3004 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3005 return BadAccess; 3006 3007 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 3008 3009 data = (char *) &stuff[1]; 3010 3011 /* check first using a dry-run */ 3012 rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); 3013 if (rc != Success) 3014 return rc; 3015 if (stuff->deviceSpec == XkbUseCoreKbd) { 3016 DeviceIntPtr other; 3017 3018 for (other = inputInfo.devices; other; other = other->next) { 3019 if ((other != dev) && other->key && !IsMaster(other) && 3020 GetMaster(other, MASTER_KEYBOARD) == dev) { 3021 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3022 DixManageAccess); 3023 if (rc == Success) { 3024 /* dry-run */ 3025 rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); 3026 if (rc != Success) 3027 return rc; 3028 } 3029 } 3030 } 3031 } 3032 3033 /* Yay, the dry-runs succeed. Let's apply */ 3034 rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); 3035 if (rc != Success) 3036 return rc; 3037 if (stuff->deviceSpec == XkbUseCoreKbd) { 3038 DeviceIntPtr other; 3039 3040 for (other = inputInfo.devices; other; other = other->next) { 3041 if ((other != dev) && other->key && !IsMaster(other) && 3042 GetMaster(other, MASTER_KEYBOARD) == dev) { 3043 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3044 DixManageAccess); 3045 if (rc == Success) { 3046 rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); 3047 if (rc != Success) 3048 return rc; 3049 } 3050 } 3051 } 3052 } 3053 3054 return Success; 3055} 3056 3057/***====================================================================***/ 3058 3059int 3060ProcXkbGetIndicatorState(ClientPtr client) 3061{ 3062 xkbGetIndicatorStateReply rep; 3063 XkbSrvLedInfoPtr sli; 3064 DeviceIntPtr dev; 3065 3066 REQUEST(xkbGetIndicatorStateReq); 3067 REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 3068 3069 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3070 return BadAccess; 3071 3072 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 3073 3074 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3075 XkbXI_IndicatorStateMask); 3076 if (!sli) 3077 return BadAlloc; 3078 3079 rep = (xkbGetIndicatorStateReply) { 3080 .type = X_Reply, 3081 .deviceID = dev->id, 3082 .sequenceNumber = client->sequence, 3083 .length = 0, 3084 .state = sli->effectiveState 3085 }; 3086 3087 if (client->swapped) { 3088 swaps(&rep.sequenceNumber); 3089 swapl(&rep.state); 3090 } 3091 WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), &rep); 3092 return Success; 3093} 3094 3095/***====================================================================***/ 3096 3097static Status 3098XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators, 3099 xkbGetIndicatorMapReply * rep) 3100{ 3101 register int i, bit; 3102 int nIndicators; 3103 3104 rep->realIndicators = indicators->phys_indicators; 3105 for (i = nIndicators = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3106 if (rep->which & bit) 3107 nIndicators++; 3108 } 3109 rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4; 3110 rep->nIndicators = nIndicators; 3111 return Success; 3112} 3113 3114static int 3115XkbSendIndicatorMap(ClientPtr client, 3116 XkbIndicatorPtr indicators, xkbGetIndicatorMapReply * rep) 3117{ 3118 int length; 3119 CARD8 *map; 3120 register int i; 3121 register unsigned bit; 3122 3123 if (rep->length > 0) { 3124 CARD8 *to; 3125 3126 to = map = xallocarray(rep->length, 4); 3127 if (map) { 3128 xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to; 3129 3130 length = rep->length * 4; 3131 3132 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3133 if (rep->which & bit) { 3134 wire->flags = indicators->maps[i].flags; 3135 wire->whichGroups = indicators->maps[i].which_groups; 3136 wire->groups = indicators->maps[i].groups; 3137 wire->whichMods = indicators->maps[i].which_mods; 3138 wire->mods = indicators->maps[i].mods.mask; 3139 wire->realMods = indicators->maps[i].mods.real_mods; 3140 wire->virtualMods = indicators->maps[i].mods.vmods; 3141 wire->ctrls = indicators->maps[i].ctrls; 3142 if (client->swapped) { 3143 swaps(&wire->virtualMods); 3144 swapl(&wire->ctrls); 3145 } 3146 wire++; 3147 } 3148 } 3149 to = (CARD8 *) wire; 3150 if ((to - map) != length) { 3151 client->errorValue = _XkbErrCode2(0xff, length); 3152 free(map); 3153 return BadLength; 3154 } 3155 } 3156 else 3157 return BadAlloc; 3158 } 3159 else 3160 map = NULL; 3161 if (client->swapped) { 3162 swaps(&rep->sequenceNumber); 3163 swapl(&rep->length); 3164 swapl(&rep->which); 3165 swapl(&rep->realIndicators); 3166 } 3167 WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), rep); 3168 if (map) { 3169 WriteToClient(client, length, map); 3170 free((char *) map); 3171 } 3172 return Success; 3173} 3174 3175int 3176ProcXkbGetIndicatorMap(ClientPtr client) 3177{ 3178 xkbGetIndicatorMapReply rep; 3179 DeviceIntPtr dev; 3180 XkbDescPtr xkb; 3181 XkbIndicatorPtr leds; 3182 3183 REQUEST(xkbGetIndicatorMapReq); 3184 REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 3185 3186 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3187 return BadAccess; 3188 3189 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 3190 3191 xkb = dev->key->xkbInfo->desc; 3192 leds = xkb->indicators; 3193 3194 rep = (xkbGetIndicatorMapReply) { 3195 .type = X_Reply, 3196 .deviceID = dev->id, 3197 .sequenceNumber = client->sequence, 3198 .length = 0, 3199 .which = stuff->which 3200 }; 3201 XkbComputeGetIndicatorMapReplySize(leds, &rep); 3202 return XkbSendIndicatorMap(client, leds, &rep); 3203} 3204 3205/** 3206 * Apply the given map to the given device. Which specifies which components 3207 * to apply. 3208 */ 3209static int 3210_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, 3211 int which, xkbIndicatorMapWireDesc * desc) 3212{ 3213 XkbSrvInfoPtr xkbi; 3214 XkbSrvLedInfoPtr sli; 3215 XkbEventCauseRec cause; 3216 int i, bit; 3217 3218 xkbi = dev->key->xkbInfo; 3219 3220 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3221 XkbXI_IndicatorMapsMask); 3222 if (!sli) 3223 return BadAlloc; 3224 3225 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3226 if (which & bit) { 3227 sli->maps[i].flags = desc->flags; 3228 sli->maps[i].which_groups = desc->whichGroups; 3229 sli->maps[i].groups = desc->groups; 3230 sli->maps[i].which_mods = desc->whichMods; 3231 sli->maps[i].mods.mask = desc->mods; 3232 sli->maps[i].mods.real_mods = desc->mods; 3233 sli->maps[i].mods.vmods = desc->virtualMods; 3234 sli->maps[i].ctrls = desc->ctrls; 3235 if (desc->virtualMods != 0) { 3236 unsigned tmp; 3237 3238 tmp = XkbMaskForVMask(xkbi->desc, desc->virtualMods); 3239 sli->maps[i].mods.mask = desc->mods | tmp; 3240 } 3241 desc++; 3242 } 3243 } 3244 3245 XkbSetCauseXkbReq(&cause, X_kbSetIndicatorMap, client); 3246 XkbApplyLedMapChanges(dev, sli, which, NULL, NULL, &cause); 3247 3248 return Success; 3249} 3250 3251int 3252ProcXkbSetIndicatorMap(ClientPtr client) 3253{ 3254 int i, bit; 3255 int nIndicators; 3256 DeviceIntPtr dev; 3257 xkbIndicatorMapWireDesc *from; 3258 int rc; 3259 3260 REQUEST(xkbSetIndicatorMapReq); 3261 REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 3262 3263 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3264 return BadAccess; 3265 3266 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 3267 3268 if (stuff->which == 0) 3269 return Success; 3270 3271 for (nIndicators = i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3272 if (stuff->which & bit) 3273 nIndicators++; 3274 } 3275 if (stuff->length != ((SIZEOF(xkbSetIndicatorMapReq) + 3276 (nIndicators * SIZEOF(xkbIndicatorMapWireDesc))) / 3277 4)) { 3278 return BadLength; 3279 } 3280 3281 from = (xkbIndicatorMapWireDesc *) &stuff[1]; 3282 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3283 if (stuff->which & bit) { 3284 if (client->swapped) { 3285 swaps(&from->virtualMods); 3286 swapl(&from->ctrls); 3287 } 3288 CHK_MASK_LEGAL(i, from->whichGroups, XkbIM_UseAnyGroup); 3289 CHK_MASK_LEGAL(i, from->whichMods, XkbIM_UseAnyMods); 3290 from++; 3291 } 3292 } 3293 3294 from = (xkbIndicatorMapWireDesc *) &stuff[1]; 3295 rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); 3296 if (rc != Success) 3297 return rc; 3298 3299 if (stuff->deviceSpec == XkbUseCoreKbd) { 3300 DeviceIntPtr other; 3301 3302 for (other = inputInfo.devices; other; other = other->next) { 3303 if ((other != dev) && other->key && !IsMaster(other) && 3304 GetMaster(other, MASTER_KEYBOARD) == dev) { 3305 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3306 DixSetAttrAccess); 3307 if (rc == Success) 3308 _XkbSetIndicatorMap(client, other, stuff->which, from); 3309 } 3310 } 3311 } 3312 3313 return Success; 3314} 3315 3316/***====================================================================***/ 3317 3318int 3319ProcXkbGetNamedIndicator(ClientPtr client) 3320{ 3321 DeviceIntPtr dev; 3322 xkbGetNamedIndicatorReply rep; 3323 register int i = 0; 3324 XkbSrvLedInfoPtr sli; 3325 XkbIndicatorMapPtr map = NULL; 3326 3327 REQUEST(xkbGetNamedIndicatorReq); 3328 REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 3329 3330 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3331 return BadAccess; 3332 3333 CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 3334 CHK_ATOM_ONLY(stuff->indicator); 3335 3336 sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 0); 3337 if (!sli) 3338 return BadAlloc; 3339 3340 i = 0; 3341 map = NULL; 3342 if ((sli->names) && (sli->maps)) { 3343 for (i = 0; i < XkbNumIndicators; i++) { 3344 if (stuff->indicator == sli->names[i]) { 3345 map = &sli->maps[i]; 3346 break; 3347 } 3348 } 3349 } 3350 3351 rep = (xkbGetNamedIndicatorReply) { 3352 .type = X_Reply, 3353 .sequenceNumber = client->sequence, 3354 .length = 0, 3355 .deviceID = dev->id, 3356 .indicator = stuff->indicator 3357 }; 3358 if (map != NULL) { 3359 rep.found = TRUE; 3360 rep.on = ((sli->effectiveState & (1 << i)) != 0); 3361 rep.realIndicator = ((sli->physIndicators & (1 << i)) != 0); 3362 rep.ndx = i; 3363 rep.flags = map->flags; 3364 rep.whichGroups = map->which_groups; 3365 rep.groups = map->groups; 3366 rep.whichMods = map->which_mods; 3367 rep.mods = map->mods.mask; 3368 rep.realMods = map->mods.real_mods; 3369 rep.virtualMods = map->mods.vmods; 3370 rep.ctrls = map->ctrls; 3371 rep.supported = TRUE; 3372 } 3373 else { 3374 rep.found = FALSE; 3375 rep.on = FALSE; 3376 rep.realIndicator = FALSE; 3377 rep.ndx = XkbNoIndicator; 3378 rep.flags = 0; 3379 rep.whichGroups = 0; 3380 rep.groups = 0; 3381 rep.whichMods = 0; 3382 rep.mods = 0; 3383 rep.realMods = 0; 3384 rep.virtualMods = 0; 3385 rep.ctrls = 0; 3386 rep.supported = TRUE; 3387 } 3388 if (client->swapped) { 3389 swapl(&rep.length); 3390 swaps(&rep.sequenceNumber); 3391 swapl(&rep.indicator); 3392 swaps(&rep.virtualMods); 3393 swapl(&rep.ctrls); 3394 } 3395 3396 WriteToClient(client, SIZEOF(xkbGetNamedIndicatorReply), &rep); 3397 return Success; 3398} 3399 3400/** 3401 * Find the IM on the device. 3402 * Returns the map, or NULL if the map doesn't exist. 3403 * If the return value is NULL, led_return is undefined. Otherwise, led_return 3404 * is set to the led index of the map. 3405 */ 3406static XkbIndicatorMapPtr 3407_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, int *led_return) 3408{ 3409 XkbIndicatorMapPtr map; 3410 3411 /* search for the right indicator */ 3412 map = NULL; 3413 if (sli->names && sli->maps) { 3414 int led; 3415 3416 for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { 3417 if (sli->names[led] == indicator) { 3418 map = &sli->maps[led]; 3419 *led_return = led; 3420 break; 3421 } 3422 } 3423 } 3424 3425 return map; 3426} 3427 3428/** 3429 * Creates an indicator map on the device. If dryRun is TRUE, it only checks 3430 * if creation is possible, but doesn't actually create it. 3431 */ 3432static int 3433_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, 3434 int ledClass, int ledID, 3435 XkbIndicatorMapPtr * map_return, int *led_return, 3436 Bool dryRun) 3437{ 3438 XkbSrvLedInfoPtr sli; 3439 XkbIndicatorMapPtr map; 3440 int led; 3441 3442 sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); 3443 if (!sli) 3444 return BadAlloc; 3445 3446 map = _XkbFindNamedIndicatorMap(sli, indicator, &led); 3447 3448 if (!map) { 3449 /* find first unused indicator maps and assign the name to it */ 3450 for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); 3451 led++) { 3452 if ((sli->names) && (sli->maps) && (sli->names[led] == None) && 3453 (!XkbIM_InUse(&sli->maps[led]))) { 3454 map = &sli->maps[led]; 3455 if (!dryRun) 3456 sli->names[led] = indicator; 3457 break; 3458 } 3459 } 3460 } 3461 3462 if (!map) 3463 return BadAlloc; 3464 3465 *led_return = led; 3466 *map_return = map; 3467 return Success; 3468} 3469 3470static int 3471_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, 3472 xkbSetNamedIndicatorReq * stuff) 3473{ 3474 unsigned int extDevReason; 3475 unsigned int statec, namec, mapc; 3476 XkbSrvLedInfoPtr sli; 3477 int led = 0; 3478 XkbIndicatorMapPtr map; 3479 DeviceIntPtr kbd; 3480 XkbEventCauseRec cause; 3481 xkbExtensionDeviceNotify ed; 3482 XkbChangesRec changes; 3483 int rc; 3484 3485 rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, 3486 stuff->ledID, &map, &led, FALSE); 3487 if (rc != Success || !map) /* oh-oh */ 3488 return rc; 3489 3490 sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 3491 XkbXI_IndicatorsMask); 3492 if (!sli) 3493 return BadAlloc; 3494 3495 namec = mapc = statec = 0; 3496 extDevReason = 0; 3497 3498 namec |= (1 << led); 3499 sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); 3500 extDevReason |= XkbXI_IndicatorNamesMask; 3501 3502 if (stuff->setMap) { 3503 map->flags = stuff->flags; 3504 map->which_groups = stuff->whichGroups; 3505 map->groups = stuff->groups; 3506 map->which_mods = stuff->whichMods; 3507 map->mods.mask = stuff->realMods; 3508 map->mods.real_mods = stuff->realMods; 3509 map->mods.vmods = stuff->virtualMods; 3510 map->ctrls = stuff->ctrls; 3511 mapc |= (1 << led); 3512 } 3513 3514 if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) { 3515 if (stuff->on) 3516 sli->explicitState |= (1 << led); 3517 else 3518 sli->explicitState &= ~(1 << led); 3519 statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); 3520 } 3521 3522 memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 3523 memset((char *) &changes, 0, sizeof(XkbChangesRec)); 3524 XkbSetCauseXkbReq(&cause, X_kbSetNamedIndicator, client); 3525 if (namec) 3526 XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 3527 if (mapc) 3528 XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 3529 if (statec) 3530 XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 3531 3532 kbd = dev; 3533 if ((sli->flags & XkbSLI_HasOwnState) == 0) 3534 kbd = inputInfo.keyboard; 3535 XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 3536 3537 return Success; 3538} 3539 3540int 3541ProcXkbSetNamedIndicator(ClientPtr client) 3542{ 3543 int rc; 3544 DeviceIntPtr dev; 3545 int led = 0; 3546 XkbIndicatorMapPtr map; 3547 3548 REQUEST(xkbSetNamedIndicatorReq); 3549 REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 3550 3551 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3552 return BadAccess; 3553 3554 CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 3555 CHK_ATOM_ONLY(stuff->indicator); 3556 CHK_MASK_LEGAL(0x10, stuff->whichGroups, XkbIM_UseAnyGroup); 3557 CHK_MASK_LEGAL(0x11, stuff->whichMods, XkbIM_UseAnyMods); 3558 3559 /* Dry-run for checks */ 3560 rc = _XkbCreateIndicatorMap(dev, stuff->indicator, 3561 stuff->ledClass, stuff->ledID, 3562 &map, &led, TRUE); 3563 if (rc != Success || !map) /* couldn't be created or didn't exist */ 3564 return rc; 3565 3566 if (stuff->deviceSpec == XkbUseCoreKbd || 3567 stuff->deviceSpec == XkbUseCorePtr) { 3568 DeviceIntPtr other; 3569 3570 for (other = inputInfo.devices; other; other = other->next) { 3571 if ((other != dev) && !IsMaster(other) && 3572 GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3573 other->leds) && 3574 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3575 == Success)) { 3576 rc = _XkbCreateIndicatorMap(other, stuff->indicator, 3577 stuff->ledClass, stuff->ledID, &map, 3578 &led, TRUE); 3579 if (rc != Success || !map) 3580 return rc; 3581 } 3582 } 3583 } 3584 3585 /* All checks passed, let's do it */ 3586 rc = _XkbSetNamedIndicator(client, dev, stuff); 3587 if (rc != Success) 3588 return rc; 3589 3590 if (stuff->deviceSpec == XkbUseCoreKbd || 3591 stuff->deviceSpec == XkbUseCorePtr) { 3592 DeviceIntPtr other; 3593 3594 for (other = inputInfo.devices; other; other = other->next) { 3595 if ((other != dev) && !IsMaster(other) && 3596 GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3597 other->leds) && 3598 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3599 == Success)) { 3600 _XkbSetNamedIndicator(client, other, stuff); 3601 } 3602 } 3603 } 3604 3605 return Success; 3606} 3607 3608/***====================================================================***/ 3609 3610static CARD32 3611_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 3612{ 3613 register unsigned int i, bit, nAtoms; 3614 register CARD32 atomsPresent; 3615 3616 for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 3617 if (atoms[i] != None) { 3618 atomsPresent |= bit; 3619 nAtoms++; 3620 } 3621 } 3622 if (count) 3623 *count = nAtoms; 3624 return atomsPresent; 3625} 3626 3627static char * 3628_XkbWriteAtoms(char *wire, Atom *atoms, int maxAtoms, int swap) 3629{ 3630 register unsigned int i; 3631 Atom *atm; 3632 3633 atm = (Atom *) wire; 3634 for (i = 0; i < maxAtoms; i++) { 3635 if (atoms[i] != None) { 3636 *atm = atoms[i]; 3637 if (swap) { 3638 swapl(atm); 3639 } 3640 atm++; 3641 } 3642 } 3643 return (char *) atm; 3644} 3645 3646static Status 3647XkbComputeGetNamesReplySize(XkbDescPtr xkb, xkbGetNamesReply * rep) 3648{ 3649 register unsigned which, length; 3650 register int i; 3651 3652 rep->minKeyCode = xkb->min_key_code; 3653 rep->maxKeyCode = xkb->max_key_code; 3654 which = rep->which; 3655 length = 0; 3656 if (xkb->names != NULL) { 3657 if (which & XkbKeycodesNameMask) 3658 length++; 3659 if (which & XkbGeometryNameMask) 3660 length++; 3661 if (which & XkbSymbolsNameMask) 3662 length++; 3663 if (which & XkbPhysSymbolsNameMask) 3664 length++; 3665 if (which & XkbTypesNameMask) 3666 length++; 3667 if (which & XkbCompatNameMask) 3668 length++; 3669 } 3670 else 3671 which &= ~XkbComponentNamesMask; 3672 3673 if (xkb->map != NULL) { 3674 if (which & XkbKeyTypeNamesMask) 3675 length += xkb->map->num_types; 3676 rep->nTypes = xkb->map->num_types; 3677 if (which & XkbKTLevelNamesMask) { 3678 XkbKeyTypePtr pType = xkb->map->types; 3679 int nKTLevels = 0; 3680 3681 length += XkbPaddedSize(xkb->map->num_types) / 4; 3682 for (i = 0; i < xkb->map->num_types; i++, pType++) { 3683 if (pType->level_names != NULL) 3684 nKTLevels += pType->num_levels; 3685 } 3686 rep->nKTLevels = nKTLevels; 3687 length += nKTLevels; 3688 } 3689 } 3690 else { 3691 rep->nTypes = 0; 3692 rep->nKTLevels = 0; 3693 which &= ~(XkbKeyTypeNamesMask | XkbKTLevelNamesMask); 3694 } 3695 3696 rep->minKeyCode = xkb->min_key_code; 3697 rep->maxKeyCode = xkb->max_key_code; 3698 rep->indicators = 0; 3699 rep->virtualMods = 0; 3700 rep->groupNames = 0; 3701 if (xkb->names != NULL) { 3702 if (which & XkbIndicatorNamesMask) { 3703 int nLeds; 3704 3705 rep->indicators = 3706 _XkbCountAtoms(xkb->names->indicators, XkbNumIndicators, 3707 &nLeds); 3708 length += nLeds; 3709 if (nLeds == 0) 3710 which &= ~XkbIndicatorNamesMask; 3711 } 3712 3713 if (which & XkbVirtualModNamesMask) { 3714 int nVMods; 3715 3716 rep->virtualMods = 3717 _XkbCountAtoms(xkb->names->vmods, XkbNumVirtualMods, &nVMods); 3718 length += nVMods; 3719 if (nVMods == 0) 3720 which &= ~XkbVirtualModNamesMask; 3721 } 3722 3723 if (which & XkbGroupNamesMask) { 3724 int nGroups; 3725 3726 rep->groupNames = 3727 _XkbCountAtoms(xkb->names->groups, XkbNumKbdGroups, &nGroups); 3728 length += nGroups; 3729 if (nGroups == 0) 3730 which &= ~XkbGroupNamesMask; 3731 } 3732 3733 if ((which & XkbKeyNamesMask) && (xkb->names->keys)) 3734 length += rep->nKeys; 3735 else 3736 which &= ~XkbKeyNamesMask; 3737 3738 if ((which & XkbKeyAliasesMask) && 3739 (xkb->names->key_aliases) && (xkb->names->num_key_aliases > 0)) { 3740 rep->nKeyAliases = xkb->names->num_key_aliases; 3741 length += rep->nKeyAliases * 2; 3742 } 3743 else { 3744 which &= ~XkbKeyAliasesMask; 3745 rep->nKeyAliases = 0; 3746 } 3747 3748 if ((which & XkbRGNamesMask) && (xkb->names->num_rg > 0)) 3749 length += xkb->names->num_rg; 3750 else 3751 which &= ~XkbRGNamesMask; 3752 } 3753 else { 3754 which &= ~(XkbIndicatorNamesMask | XkbVirtualModNamesMask); 3755 which &= ~(XkbGroupNamesMask | XkbKeyNamesMask | XkbKeyAliasesMask); 3756 which &= ~XkbRGNamesMask; 3757 } 3758 3759 rep->length = length; 3760 rep->which = which; 3761 return Success; 3762} 3763 3764static int 3765XkbSendNames(ClientPtr client, XkbDescPtr xkb, xkbGetNamesReply * rep) 3766{ 3767 register unsigned i, length, which; 3768 char *start; 3769 char *desc; 3770 3771 length = rep->length * 4; 3772 which = rep->which; 3773 if (client->swapped) { 3774 swaps(&rep->sequenceNumber); 3775 swapl(&rep->length); 3776 swapl(&rep->which); 3777 swaps(&rep->virtualMods); 3778 swapl(&rep->indicators); 3779 } 3780 3781 start = desc = calloc(1, length); 3782 if (!start) 3783 return BadAlloc; 3784 if (xkb->names) { 3785 if (which & XkbKeycodesNameMask) { 3786 *((CARD32 *) desc) = xkb->names->keycodes; 3787 if (client->swapped) { 3788 swapl((int *) desc); 3789 } 3790 desc += 4; 3791 } 3792 if (which & XkbGeometryNameMask) { 3793 *((CARD32 *) desc) = xkb->names->geometry; 3794 if (client->swapped) { 3795 swapl((int *) desc); 3796 } 3797 desc += 4; 3798 } 3799 if (which & XkbSymbolsNameMask) { 3800 *((CARD32 *) desc) = xkb->names->symbols; 3801 if (client->swapped) { 3802 swapl((int *) desc); 3803 } 3804 desc += 4; 3805 } 3806 if (which & XkbPhysSymbolsNameMask) { 3807 register CARD32 *atm = (CARD32 *) desc; 3808 3809 atm[0] = (CARD32) xkb->names->phys_symbols; 3810 if (client->swapped) { 3811 swapl(&atm[0]); 3812 } 3813 desc += 4; 3814 } 3815 if (which & XkbTypesNameMask) { 3816 *((CARD32 *) desc) = (CARD32) xkb->names->types; 3817 if (client->swapped) { 3818 swapl((int *) desc); 3819 } 3820 desc += 4; 3821 } 3822 if (which & XkbCompatNameMask) { 3823 *((CARD32 *) desc) = (CARD32) xkb->names->compat; 3824 if (client->swapped) { 3825 swapl((int *) desc); 3826 } 3827 desc += 4; 3828 } 3829 if (which & XkbKeyTypeNamesMask) { 3830 register CARD32 *atm = (CARD32 *) desc; 3831 register XkbKeyTypePtr type = xkb->map->types; 3832 3833 for (i = 0; i < xkb->map->num_types; i++, atm++, type++) { 3834 *atm = (CARD32) type->name; 3835 if (client->swapped) { 3836 swapl(atm); 3837 } 3838 } 3839 desc = (char *) atm; 3840 } 3841 if (which & XkbKTLevelNamesMask && xkb->map) { 3842 XkbKeyTypePtr type = xkb->map->types; 3843 register CARD32 *atm; 3844 3845 for (i = 0; i < rep->nTypes; i++, type++) { 3846 *desc++ = type->num_levels; 3847 } 3848 desc += XkbPaddedSize(rep->nTypes) - rep->nTypes; 3849 3850 atm = (CARD32 *) desc; 3851 type = xkb->map->types; 3852 for (i = 0; i < xkb->map->num_types; i++, type++) { 3853 register unsigned l; 3854 3855 if (type->level_names) { 3856 for (l = 0; l < type->num_levels; l++, atm++) { 3857 *atm = type->level_names[l]; 3858 if (client->swapped) { 3859 swapl(atm); 3860 } 3861 } 3862 desc += type->num_levels * 4; 3863 } 3864 } 3865 } 3866 if (which & XkbIndicatorNamesMask) { 3867 desc = 3868 _XkbWriteAtoms(desc, xkb->names->indicators, XkbNumIndicators, 3869 client->swapped); 3870 } 3871 if (which & XkbVirtualModNamesMask) { 3872 desc = _XkbWriteAtoms(desc, xkb->names->vmods, XkbNumVirtualMods, 3873 client->swapped); 3874 } 3875 if (which & XkbGroupNamesMask) { 3876 desc = _XkbWriteAtoms(desc, xkb->names->groups, XkbNumKbdGroups, 3877 client->swapped); 3878 } 3879 if (which & XkbKeyNamesMask) { 3880 for (i = 0; i < rep->nKeys; i++, desc += sizeof(XkbKeyNameRec)) { 3881 *((XkbKeyNamePtr) desc) = xkb->names->keys[i + rep->firstKey]; 3882 } 3883 } 3884 if (which & XkbKeyAliasesMask) { 3885 XkbKeyAliasPtr pAl; 3886 3887 pAl = xkb->names->key_aliases; 3888 for (i = 0; i < rep->nKeyAliases; 3889 i++, pAl++, desc += 2 * XkbKeyNameLength) { 3890 *((XkbKeyAliasPtr) desc) = *pAl; 3891 } 3892 } 3893 if ((which & XkbRGNamesMask) && (rep->nRadioGroups > 0)) { 3894 register CARD32 *atm = (CARD32 *) desc; 3895 3896 for (i = 0; i < rep->nRadioGroups; i++, atm++) { 3897 *atm = (CARD32) xkb->names->radio_groups[i]; 3898 if (client->swapped) { 3899 swapl(atm); 3900 } 3901 } 3902 desc += rep->nRadioGroups * 4; 3903 } 3904 } 3905 3906 if ((desc - start) != (length)) { 3907 ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 3908 length, (unsigned long) (desc - start)); 3909 } 3910 WriteToClient(client, SIZEOF(xkbGetNamesReply), rep); 3911 WriteToClient(client, length, start); 3912 free((char *) start); 3913 return Success; 3914} 3915 3916int 3917ProcXkbGetNames(ClientPtr client) 3918{ 3919 DeviceIntPtr dev; 3920 XkbDescPtr xkb; 3921 xkbGetNamesReply rep; 3922 3923 REQUEST(xkbGetNamesReq); 3924 REQUEST_SIZE_MATCH(xkbGetNamesReq); 3925 3926 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3927 return BadAccess; 3928 3929 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 3930 CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 3931 3932 xkb = dev->key->xkbInfo->desc; 3933 rep = (xkbGetNamesReply) { 3934 .type = X_Reply, 3935 .deviceID = dev->id, 3936 .sequenceNumber = client->sequence, 3937 .length = 0, 3938 .which = stuff->which, 3939 .nTypes = xkb->map->num_types, 3940 .firstKey = xkb->min_key_code, 3941 .nKeys = XkbNumKeys(xkb), 3942 .nKeyAliases = xkb->names ? xkb->names->num_key_aliases : 0, 3943 .nRadioGroups = xkb->names ? xkb->names->num_rg : 0 3944 }; 3945 XkbComputeGetNamesReplySize(xkb, &rep); 3946 return XkbSendNames(client, xkb, &rep); 3947} 3948 3949/***====================================================================***/ 3950 3951static CARD32 * 3952_XkbCheckAtoms(CARD32 *wire, int nAtoms, int swapped, Atom *pError) 3953{ 3954 register int i; 3955 3956 for (i = 0; i < nAtoms; i++, wire++) { 3957 if (swapped) { 3958 swapl(wire); 3959 } 3960 if ((((Atom) *wire) != None) && (!ValidAtom((Atom) *wire))) { 3961 *pError = ((Atom) *wire); 3962 return NULL; 3963 } 3964 } 3965 return wire; 3966} 3967 3968static CARD32 * 3969_XkbCheckMaskedAtoms(CARD32 *wire, int nAtoms, CARD32 present, int swapped, 3970 Atom *pError) 3971{ 3972 register unsigned i, bit; 3973 3974 for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 3975 if ((present & bit) == 0) 3976 continue; 3977 if (swapped) { 3978 swapl(wire); 3979 } 3980 if ((((Atom) *wire) != None) && (!ValidAtom(((Atom) *wire)))) { 3981 *pError = (Atom) *wire; 3982 return NULL; 3983 } 3984 wire++; 3985 } 3986 return wire; 3987} 3988 3989static Atom * 3990_XkbCopyMaskedAtoms(Atom *wire, Atom *dest, int nAtoms, CARD32 present) 3991{ 3992 register int i, bit; 3993 3994 for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 3995 if ((present & bit) == 0) 3996 continue; 3997 dest[i] = *wire++; 3998 } 3999 return wire; 4000} 4001 4002static Bool 4003_XkbCheckTypeName(Atom name, int typeNdx) 4004{ 4005 const char *str; 4006 4007 str = NameForAtom(name); 4008 if ((strcmp(str, "ONE_LEVEL") == 0) || (strcmp(str, "TWO_LEVEL") == 0) || 4009 (strcmp(str, "ALPHABETIC") == 0) || (strcmp(str, "KEYPAD") == 0)) 4010 return FALSE; 4011 return TRUE; 4012} 4013 4014/** 4015 * Check the device-dependent data in the request against the device. Returns 4016 * Success, or the appropriate error code. 4017 */ 4018static int 4019_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 4020 xkbSetNamesReq * stuff, CARD32 *data) 4021{ 4022 XkbDescRec *xkb; 4023 CARD32 *tmp; 4024 Atom bad = None; 4025 4026 tmp = data; 4027 xkb = dev->key->xkbInfo->desc; 4028 4029 if (stuff->which & XkbKeyTypeNamesMask) { 4030 int i; 4031 CARD32 *old; 4032 4033 if (stuff->nTypes < 1) { 4034 client->errorValue = _XkbErrCode2(0x02, stuff->nTypes); 4035 return BadValue; 4036 } 4037 if ((unsigned) (stuff->firstType + stuff->nTypes - 1) >= 4038 xkb->map->num_types) { 4039 client->errorValue = 4040 _XkbErrCode4(0x03, stuff->firstType, stuff->nTypes, 4041 xkb->map->num_types); 4042 return BadValue; 4043 } 4044 if (((unsigned) stuff->firstType) <= XkbLastRequiredType) { 4045 client->errorValue = _XkbErrCode2(0x04, stuff->firstType); 4046 return BadAccess; 4047 } 4048 old = tmp; 4049 tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad); 4050 if (!tmp) { 4051 client->errorValue = bad; 4052 return BadAtom; 4053 } 4054 for (i = 0; i < stuff->nTypes; i++, old++) { 4055 if (!_XkbCheckTypeName((Atom) *old, stuff->firstType + i)) 4056 client->errorValue = _XkbErrCode2(0x05, i); 4057 } 4058 } 4059 if (stuff->which & XkbKTLevelNamesMask) { 4060 unsigned i; 4061 XkbKeyTypePtr type; 4062 CARD8 *width; 4063 4064 if (stuff->nKTLevels < 1) { 4065 client->errorValue = _XkbErrCode2(0x05, stuff->nKTLevels); 4066 return BadValue; 4067 } 4068 if ((unsigned) (stuff->firstKTLevel + stuff->nKTLevels - 1) >= 4069 xkb->map->num_types) { 4070 client->errorValue = _XkbErrCode4(0x06, stuff->firstKTLevel, 4071 stuff->nKTLevels, 4072 xkb->map->num_types); 4073 return BadValue; 4074 } 4075 width = (CARD8 *) tmp; 4076 tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4077 type = &xkb->map->types[stuff->firstKTLevel]; 4078 for (i = 0; i < stuff->nKTLevels; i++, type++) { 4079 if (width[i] == 0) 4080 continue; 4081 else if (width[i] != type->num_levels) { 4082 client->errorValue = _XkbErrCode4(0x07, i + stuff->firstKTLevel, 4083 type->num_levels, width[i]); 4084 return BadMatch; 4085 } 4086 tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad); 4087 if (!tmp) { 4088 client->errorValue = bad; 4089 return BadAtom; 4090 } 4091 } 4092 } 4093 if (stuff->which & XkbIndicatorNamesMask) { 4094 if (stuff->indicators == 0) { 4095 client->errorValue = 0x08; 4096 return BadMatch; 4097 } 4098 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators, 4099 client->swapped, &bad); 4100 if (!tmp) { 4101 client->errorValue = bad; 4102 return BadAtom; 4103 } 4104 } 4105 if (stuff->which & XkbVirtualModNamesMask) { 4106 if (stuff->virtualMods == 0) { 4107 client->errorValue = 0x09; 4108 return BadMatch; 4109 } 4110 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods, 4111 (CARD32) stuff->virtualMods, 4112 client->swapped, &bad); 4113 if (!tmp) { 4114 client->errorValue = bad; 4115 return BadAtom; 4116 } 4117 } 4118 if (stuff->which & XkbGroupNamesMask) { 4119 if (stuff->groupNames == 0) { 4120 client->errorValue = 0x0a; 4121 return BadMatch; 4122 } 4123 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups, 4124 (CARD32) stuff->groupNames, 4125 client->swapped, &bad); 4126 if (!tmp) { 4127 client->errorValue = bad; 4128 return BadAtom; 4129 } 4130 } 4131 if (stuff->which & XkbKeyNamesMask) { 4132 if (stuff->firstKey < (unsigned) xkb->min_key_code) { 4133 client->errorValue = _XkbErrCode3(0x0b, xkb->min_key_code, 4134 stuff->firstKey); 4135 return BadValue; 4136 } 4137 if (((unsigned) (stuff->firstKey + stuff->nKeys - 1) > 4138 xkb->max_key_code) || (stuff->nKeys < 1)) { 4139 client->errorValue = 4140 _XkbErrCode4(0x0c, xkb->max_key_code, stuff->firstKey, 4141 stuff->nKeys); 4142 return BadValue; 4143 } 4144 tmp += stuff->nKeys; 4145 } 4146 if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) { 4147 tmp += stuff->nKeyAliases * 2; 4148 } 4149 if (stuff->which & XkbRGNamesMask) { 4150 if (stuff->nRadioGroups < 1) { 4151 client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups); 4152 return BadValue; 4153 } 4154 tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad); 4155 if (!tmp) { 4156 client->errorValue = bad; 4157 return BadAtom; 4158 } 4159 } 4160 if ((tmp - ((CARD32 *) stuff)) != stuff->length) { 4161 client->errorValue = stuff->length; 4162 return BadLength; 4163 } 4164 4165 return Success; 4166} 4167 4168static int 4169_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq * stuff) 4170{ 4171 XkbDescRec *xkb; 4172 XkbNamesRec *names; 4173 CARD32 *tmp; 4174 xkbNamesNotify nn; 4175 4176 tmp = (CARD32 *) &stuff[1]; 4177 xkb = dev->key->xkbInfo->desc; 4178 names = xkb->names; 4179 4180 if (XkbAllocNames(xkb, stuff->which, stuff->nRadioGroups, 4181 stuff->nKeyAliases) != Success) { 4182 return BadAlloc; 4183 } 4184 4185 memset(&nn, 0, sizeof(xkbNamesNotify)); 4186 nn.changed = stuff->which; 4187 tmp = (CARD32 *) &stuff[1]; 4188 if (stuff->which & XkbKeycodesNameMask) 4189 names->keycodes = *tmp++; 4190 if (stuff->which & XkbGeometryNameMask) 4191 names->geometry = *tmp++; 4192 if (stuff->which & XkbSymbolsNameMask) 4193 names->symbols = *tmp++; 4194 if (stuff->which & XkbPhysSymbolsNameMask) 4195 names->phys_symbols = *tmp++; 4196 if (stuff->which & XkbTypesNameMask) 4197 names->types = *tmp++; 4198 if (stuff->which & XkbCompatNameMask) 4199 names->compat = *tmp++; 4200 if ((stuff->which & XkbKeyTypeNamesMask) && (stuff->nTypes > 0)) { 4201 register unsigned i; 4202 register XkbKeyTypePtr type; 4203 4204 type = &xkb->map->types[stuff->firstType]; 4205 for (i = 0; i < stuff->nTypes; i++, type++) { 4206 type->name = *tmp++; 4207 } 4208 nn.firstType = stuff->firstType; 4209 nn.nTypes = stuff->nTypes; 4210 } 4211 if (stuff->which & XkbKTLevelNamesMask) { 4212 register XkbKeyTypePtr type; 4213 register unsigned i; 4214 CARD8 *width; 4215 4216 width = (CARD8 *) tmp; 4217 tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4218 type = &xkb->map->types[stuff->firstKTLevel]; 4219 for (i = 0; i < stuff->nKTLevels; i++, type++) { 4220 if (width[i] > 0) { 4221 if (type->level_names) { 4222 register unsigned n; 4223 4224 for (n = 0; n < width[i]; n++) { 4225 type->level_names[n] = tmp[n]; 4226 } 4227 } 4228 tmp += width[i]; 4229 } 4230 } 4231 nn.firstLevelName = 0; 4232 nn.nLevelNames = stuff->nTypes; 4233 } 4234 if (stuff->which & XkbIndicatorNamesMask) { 4235 tmp = _XkbCopyMaskedAtoms(tmp, names->indicators, XkbNumIndicators, 4236 stuff->indicators); 4237 nn.changedIndicators = stuff->indicators; 4238 } 4239 if (stuff->which & XkbVirtualModNamesMask) { 4240 tmp = _XkbCopyMaskedAtoms(tmp, names->vmods, XkbNumVirtualMods, 4241 stuff->virtualMods); 4242 nn.changedVirtualMods = stuff->virtualMods; 4243 } 4244 if (stuff->which & XkbGroupNamesMask) { 4245 tmp = _XkbCopyMaskedAtoms(tmp, names->groups, XkbNumKbdGroups, 4246 stuff->groupNames); 4247 nn.changedVirtualMods = stuff->groupNames; 4248 } 4249 if (stuff->which & XkbKeyNamesMask) { 4250 memcpy((char *) &names->keys[stuff->firstKey], (char *) tmp, 4251 stuff->nKeys * XkbKeyNameLength); 4252 tmp += stuff->nKeys; 4253 nn.firstKey = stuff->firstKey; 4254 nn.nKeys = stuff->nKeys; 4255 } 4256 if (stuff->which & XkbKeyAliasesMask) { 4257 if (stuff->nKeyAliases > 0) { 4258 register int na = stuff->nKeyAliases; 4259 4260 if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, na) != Success) 4261 return BadAlloc; 4262 memcpy((char *) names->key_aliases, (char *) tmp, 4263 stuff->nKeyAliases * sizeof(XkbKeyAliasRec)); 4264 tmp += stuff->nKeyAliases * 2; 4265 } 4266 else if (names->key_aliases != NULL) { 4267 free(names->key_aliases); 4268 names->key_aliases = NULL; 4269 names->num_key_aliases = 0; 4270 } 4271 nn.nAliases = names->num_key_aliases; 4272 } 4273 if (stuff->which & XkbRGNamesMask) { 4274 if (stuff->nRadioGroups > 0) { 4275 register unsigned i, nrg; 4276 4277 nrg = stuff->nRadioGroups; 4278 if (XkbAllocNames(xkb, XkbRGNamesMask, nrg, 0) != Success) 4279 return BadAlloc; 4280 4281 for (i = 0; i < stuff->nRadioGroups; i++) { 4282 names->radio_groups[i] = tmp[i]; 4283 } 4284 tmp += stuff->nRadioGroups; 4285 } 4286 else if (names->radio_groups) { 4287 free(names->radio_groups); 4288 names->radio_groups = NULL; 4289 names->num_rg = 0; 4290 } 4291 nn.nRadioGroups = names->num_rg; 4292 } 4293 if (nn.changed) { 4294 Bool needExtEvent; 4295 4296 needExtEvent = (nn.changed & XkbIndicatorNamesMask) != 0; 4297 XkbSendNamesNotify(dev, &nn); 4298 if (needExtEvent) { 4299 XkbSrvLedInfoPtr sli; 4300 xkbExtensionDeviceNotify edev; 4301 register int i; 4302 register unsigned bit; 4303 4304 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 4305 XkbXI_IndicatorsMask); 4306 sli->namesPresent = 0; 4307 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 4308 if (names->indicators[i] != None) 4309 sli->namesPresent |= bit; 4310 } 4311 memset(&edev, 0, sizeof(xkbExtensionDeviceNotify)); 4312 edev.reason = XkbXI_IndicatorNamesMask; 4313 edev.ledClass = KbdFeedbackClass; 4314 edev.ledID = dev->kbdfeed->ctrl.id; 4315 edev.ledsDefined = sli->namesPresent | sli->mapsPresent; 4316 edev.ledState = sli->effectiveState; 4317 edev.firstBtn = 0; 4318 edev.nBtns = 0; 4319 edev.supported = XkbXI_AllFeaturesMask; 4320 edev.unsupported = 0; 4321 XkbSendExtensionDeviceNotify(dev, client, &edev); 4322 } 4323 } 4324 return Success; 4325} 4326 4327int 4328ProcXkbSetNames(ClientPtr client) 4329{ 4330 DeviceIntPtr dev; 4331 CARD32 *tmp; 4332 Atom bad; 4333 int rc; 4334 4335 REQUEST(xkbSetNamesReq); 4336 REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 4337 4338 if (!(client->xkbClientFlags & _XkbClientInitialized)) 4339 return BadAccess; 4340 4341 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 4342 CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 4343 4344 /* check device-independent stuff */ 4345 tmp = (CARD32 *) &stuff[1]; 4346 4347 if (stuff->which & XkbKeycodesNameMask) { 4348 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4349 if (!tmp) { 4350 client->errorValue = bad; 4351 return BadAtom; 4352 } 4353 } 4354 if (stuff->which & XkbGeometryNameMask) { 4355 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4356 if (!tmp) { 4357 client->errorValue = bad; 4358 return BadAtom; 4359 } 4360 } 4361 if (stuff->which & XkbSymbolsNameMask) { 4362 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4363 if (!tmp) { 4364 client->errorValue = bad; 4365 return BadAtom; 4366 } 4367 } 4368 if (stuff->which & XkbPhysSymbolsNameMask) { 4369 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4370 if (!tmp) { 4371 client->errorValue = bad; 4372 return BadAtom; 4373 } 4374 } 4375 if (stuff->which & XkbTypesNameMask) { 4376 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4377 if (!tmp) { 4378 client->errorValue = bad; 4379 return BadAtom; 4380 } 4381 } 4382 if (stuff->which & XkbCompatNameMask) { 4383 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4384 if (!tmp) { 4385 client->errorValue = bad; 4386 return BadAtom; 4387 } 4388 } 4389 4390 /* start of device-dependent tests */ 4391 rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 4392 if (rc != Success) 4393 return rc; 4394 4395 if (stuff->deviceSpec == XkbUseCoreKbd) { 4396 DeviceIntPtr other; 4397 4398 for (other = inputInfo.devices; other; other = other->next) { 4399 if ((other != dev) && other->key && !IsMaster(other) && 4400 GetMaster(other, MASTER_KEYBOARD) == dev) { 4401 4402 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4403 DixManageAccess); 4404 if (rc == Success) { 4405 rc = _XkbSetNamesCheck(client, other, stuff, tmp); 4406 if (rc != Success) 4407 return rc; 4408 } 4409 } 4410 } 4411 } 4412 4413 /* everything is okay -- update names */ 4414 4415 rc = _XkbSetNames(client, dev, stuff); 4416 if (rc != Success) 4417 return rc; 4418 4419 if (stuff->deviceSpec == XkbUseCoreKbd) { 4420 DeviceIntPtr other; 4421 4422 for (other = inputInfo.devices; other; other = other->next) { 4423 if ((other != dev) && other->key && !IsMaster(other) && 4424 GetMaster(other, MASTER_KEYBOARD) == dev) { 4425 4426 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4427 DixManageAccess); 4428 if (rc == Success) 4429 _XkbSetNames(client, other, stuff); 4430 } 4431 } 4432 } 4433 4434 /* everything is okay -- update names */ 4435 4436 return Success; 4437} 4438 4439/***====================================================================***/ 4440 4441#include "xkbgeom.h" 4442 4443#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 4444 4445/** 4446 * Write the zero-terminated string str into wire as a pascal string with a 4447 * 16-bit length field prefixed before the actual string. 4448 * 4449 * @param wire The destination array, usually the wire struct 4450 * @param str The source string as zero-terminated C string 4451 * @param swap If TRUE, the length field is swapped. 4452 * 4453 * @return The input string in the format <string length><string> with a 4454 * (swapped) 16 bit string length, non-zero terminated. 4455 */ 4456static char * 4457XkbWriteCountedString(char *wire, const char *str, Bool swap) 4458{ 4459 CARD16 len, *pLen, paddedLen; 4460 4461 if (!str) 4462 return wire; 4463 4464 len = strlen(str); 4465 pLen = (CARD16 *) wire; 4466 *pLen = len; 4467 if (swap) { 4468 swaps(pLen); 4469 } 4470 paddedLen = pad_to_int32(sizeof(len) + len) - sizeof(len); 4471 strncpy(&wire[sizeof(len)], str, paddedLen); 4472 wire += sizeof(len) + paddedLen; 4473 return wire; 4474} 4475 4476static int 4477XkbSizeGeomProperties(XkbGeometryPtr geom) 4478{ 4479 register int i, size; 4480 XkbPropertyPtr prop; 4481 4482 for (size = i = 0, prop = geom->properties; i < geom->num_properties; 4483 i++, prop++) { 4484 size += XkbSizeCountedString(prop->name); 4485 size += XkbSizeCountedString(prop->value); 4486 } 4487 return size; 4488} 4489 4490static char * 4491XkbWriteGeomProperties(char *wire, XkbGeometryPtr geom, Bool swap) 4492{ 4493 register int i; 4494 register XkbPropertyPtr prop; 4495 4496 for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { 4497 wire = XkbWriteCountedString(wire, prop->name, swap); 4498 wire = XkbWriteCountedString(wire, prop->value, swap); 4499 } 4500 return wire; 4501} 4502 4503static int 4504XkbSizeGeomKeyAliases(XkbGeometryPtr geom) 4505{ 4506 return geom->num_key_aliases * (2 * XkbKeyNameLength); 4507} 4508 4509static char * 4510XkbWriteGeomKeyAliases(char *wire, XkbGeometryPtr geom, Bool swap) 4511{ 4512 register int sz; 4513 4514 sz = geom->num_key_aliases * (XkbKeyNameLength * 2); 4515 if (sz > 0) { 4516 memcpy(wire, (char *) geom->key_aliases, sz); 4517 wire += sz; 4518 } 4519 return wire; 4520} 4521 4522static int 4523XkbSizeGeomColors(XkbGeometryPtr geom) 4524{ 4525 register int i, size; 4526 register XkbColorPtr color; 4527 4528 for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4529 size += XkbSizeCountedString(color->spec); 4530 } 4531 return size; 4532} 4533 4534static char * 4535XkbWriteGeomColors(char *wire, XkbGeometryPtr geom, Bool swap) 4536{ 4537 register int i; 4538 register XkbColorPtr color; 4539 4540 for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4541 wire = XkbWriteCountedString(wire, color->spec, swap); 4542 } 4543 return wire; 4544} 4545 4546static int 4547XkbSizeGeomShapes(XkbGeometryPtr geom) 4548{ 4549 register int i, size; 4550 register XkbShapePtr shape; 4551 4552 for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4553 register int n; 4554 register XkbOutlinePtr ol; 4555 4556 size += SIZEOF(xkbShapeWireDesc); 4557 for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) { 4558 size += SIZEOF(xkbOutlineWireDesc); 4559 size += ol->num_points * SIZEOF(xkbPointWireDesc); 4560 } 4561 } 4562 return size; 4563} 4564 4565static char * 4566XkbWriteGeomShapes(char *wire, XkbGeometryPtr geom, Bool swap) 4567{ 4568 int i; 4569 XkbShapePtr shape; 4570 xkbShapeWireDesc *shapeWire; 4571 4572 for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4573 register int o; 4574 XkbOutlinePtr ol; 4575 xkbOutlineWireDesc *olWire; 4576 4577 shapeWire = (xkbShapeWireDesc *) wire; 4578 shapeWire->name = shape->name; 4579 shapeWire->nOutlines = shape->num_outlines; 4580 if (shape->primary != NULL) 4581 shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary); 4582 else 4583 shapeWire->primaryNdx = XkbNoShape; 4584 if (shape->approx != NULL) 4585 shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx); 4586 else 4587 shapeWire->approxNdx = XkbNoShape; 4588 shapeWire->pad = 0; 4589 if (swap) { 4590 swapl(&shapeWire->name); 4591 } 4592 wire = (char *) &shapeWire[1]; 4593 for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { 4594 register int p; 4595 XkbPointPtr pt; 4596 xkbPointWireDesc *ptWire; 4597 4598 olWire = (xkbOutlineWireDesc *) wire; 4599 olWire->nPoints = ol->num_points; 4600 olWire->cornerRadius = ol->corner_radius; 4601 olWire->pad = 0; 4602 wire = (char *) &olWire[1]; 4603 ptWire = (xkbPointWireDesc *) wire; 4604 for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) { 4605 ptWire[p].x = pt->x; 4606 ptWire[p].y = pt->y; 4607 if (swap) { 4608 swaps(&ptWire[p].x); 4609 swaps(&ptWire[p].y); 4610 } 4611 } 4612 wire = (char *) &ptWire[ol->num_points]; 4613 } 4614 } 4615 return wire; 4616} 4617 4618static int 4619XkbSizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad) 4620{ 4621 register int i, size; 4622 4623 for (i = size = 0; i < num_doodads; i++, doodad++) { 4624 size += SIZEOF(xkbAnyDoodadWireDesc); 4625 if (doodad->any.type == XkbTextDoodad) { 4626 size += XkbSizeCountedString(doodad->text.text); 4627 size += XkbSizeCountedString(doodad->text.font); 4628 } 4629 else if (doodad->any.type == XkbLogoDoodad) { 4630 size += XkbSizeCountedString(doodad->logo.logo_name); 4631 } 4632 } 4633 return size; 4634} 4635 4636static char * 4637XkbWriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad, Bool swap) 4638{ 4639 register int i; 4640 xkbDoodadWireDesc *doodadWire; 4641 4642 for (i = 0; i < num_doodads; i++, doodad++) { 4643 doodadWire = (xkbDoodadWireDesc *) wire; 4644 wire = (char *) &doodadWire[1]; 4645 memset(doodadWire, 0, SIZEOF(xkbDoodadWireDesc)); 4646 doodadWire->any.name = doodad->any.name; 4647 doodadWire->any.type = doodad->any.type; 4648 doodadWire->any.priority = doodad->any.priority; 4649 doodadWire->any.top = doodad->any.top; 4650 doodadWire->any.left = doodad->any.left; 4651 if (swap) { 4652 swapl(&doodadWire->any.name); 4653 swaps(&doodadWire->any.top); 4654 swaps(&doodadWire->any.left); 4655 } 4656 switch (doodad->any.type) { 4657 case XkbOutlineDoodad: 4658 case XkbSolidDoodad: 4659 doodadWire->shape.angle = doodad->shape.angle; 4660 doodadWire->shape.colorNdx = doodad->shape.color_ndx; 4661 doodadWire->shape.shapeNdx = doodad->shape.shape_ndx; 4662 if (swap) { 4663 swaps(&doodadWire->shape.angle); 4664 } 4665 break; 4666 case XkbTextDoodad: 4667 doodadWire->text.angle = doodad->text.angle; 4668 doodadWire->text.width = doodad->text.width; 4669 doodadWire->text.height = doodad->text.height; 4670 doodadWire->text.colorNdx = doodad->text.color_ndx; 4671 if (swap) { 4672 swaps(&doodadWire->text.angle); 4673 swaps(&doodadWire->text.width); 4674 swaps(&doodadWire->text.height); 4675 } 4676 wire = XkbWriteCountedString(wire, doodad->text.text, swap); 4677 wire = XkbWriteCountedString(wire, doodad->text.font, swap); 4678 break; 4679 case XkbIndicatorDoodad: 4680 doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx; 4681 doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx; 4682 doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx; 4683 break; 4684 case XkbLogoDoodad: 4685 doodadWire->logo.angle = doodad->logo.angle; 4686 doodadWire->logo.colorNdx = doodad->logo.color_ndx; 4687 doodadWire->logo.shapeNdx = doodad->logo.shape_ndx; 4688 wire = XkbWriteCountedString(wire, doodad->logo.logo_name, swap); 4689 break; 4690 default: 4691 ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 4692 doodad->any.type); 4693 ErrorF("[xkb] Ignored\n"); 4694 break; 4695 } 4696 } 4697 return wire; 4698} 4699 4700static char * 4701XkbWriteGeomOverlay(char *wire, XkbOverlayPtr ol, Bool swap) 4702{ 4703 register int r; 4704 XkbOverlayRowPtr row; 4705 xkbOverlayWireDesc *olWire; 4706 4707 olWire = (xkbOverlayWireDesc *) wire; 4708 olWire->name = ol->name; 4709 olWire->nRows = ol->num_rows; 4710 olWire->pad1 = 0; 4711 olWire->pad2 = 0; 4712 if (swap) { 4713 swapl(&olWire->name); 4714 } 4715 wire = (char *) &olWire[1]; 4716 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4717 unsigned int k; 4718 XkbOverlayKeyPtr key; 4719 xkbOverlayRowWireDesc *rowWire; 4720 4721 rowWire = (xkbOverlayRowWireDesc *) wire; 4722 rowWire->rowUnder = row->row_under; 4723 rowWire->nKeys = row->num_keys; 4724 rowWire->pad1 = 0; 4725 wire = (char *) &rowWire[1]; 4726 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4727 xkbOverlayKeyWireDesc *keyWire; 4728 4729 keyWire = (xkbOverlayKeyWireDesc *) wire; 4730 memcpy(keyWire->over, key->over.name, XkbKeyNameLength); 4731 memcpy(keyWire->under, key->under.name, XkbKeyNameLength); 4732 wire = (char *) &keyWire[1]; 4733 } 4734 } 4735 return wire; 4736} 4737 4738static int 4739XkbSizeGeomSections(XkbGeometryPtr geom) 4740{ 4741 register int i, size; 4742 XkbSectionPtr section; 4743 4744 for (i = size = 0, section = geom->sections; i < geom->num_sections; 4745 i++, section++) { 4746 size += SIZEOF(xkbSectionWireDesc); 4747 if (section->rows) { 4748 int r; 4749 XkbRowPtr row; 4750 4751 for (r = 0, row = section->rows; r < section->num_rows; row++, r++) { 4752 size += SIZEOF(xkbRowWireDesc); 4753 size += row->num_keys * SIZEOF(xkbKeyWireDesc); 4754 } 4755 } 4756 if (section->doodads) 4757 size += XkbSizeGeomDoodads(section->num_doodads, section->doodads); 4758 if (section->overlays) { 4759 int o; 4760 XkbOverlayPtr ol; 4761 4762 for (o = 0, ol = section->overlays; o < section->num_overlays; 4763 o++, ol++) { 4764 int r; 4765 XkbOverlayRowPtr row; 4766 4767 size += SIZEOF(xkbOverlayWireDesc); 4768 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4769 size += SIZEOF(xkbOverlayRowWireDesc); 4770 size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc); 4771 } 4772 } 4773 } 4774 } 4775 return size; 4776} 4777 4778static char * 4779XkbWriteGeomSections(char *wire, XkbGeometryPtr geom, Bool swap) 4780{ 4781 register int i; 4782 XkbSectionPtr section; 4783 xkbSectionWireDesc *sectionWire; 4784 4785 for (i = 0, section = geom->sections; i < geom->num_sections; 4786 i++, section++) { 4787 sectionWire = (xkbSectionWireDesc *) wire; 4788 sectionWire->name = section->name; 4789 sectionWire->top = section->top; 4790 sectionWire->left = section->left; 4791 sectionWire->width = section->width; 4792 sectionWire->height = section->height; 4793 sectionWire->angle = section->angle; 4794 sectionWire->priority = section->priority; 4795 sectionWire->nRows = section->num_rows; 4796 sectionWire->nDoodads = section->num_doodads; 4797 sectionWire->nOverlays = section->num_overlays; 4798 sectionWire->pad = 0; 4799 if (swap) { 4800 swapl(§ionWire->name); 4801 swaps(§ionWire->top); 4802 swaps(§ionWire->left); 4803 swaps(§ionWire->width); 4804 swaps(§ionWire->height); 4805 swaps(§ionWire->angle); 4806 } 4807 wire = (char *) §ionWire[1]; 4808 if (section->rows) { 4809 int r; 4810 XkbRowPtr row; 4811 xkbRowWireDesc *rowWire; 4812 4813 for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 4814 rowWire = (xkbRowWireDesc *) wire; 4815 rowWire->top = row->top; 4816 rowWire->left = row->left; 4817 rowWire->nKeys = row->num_keys; 4818 rowWire->vertical = row->vertical; 4819 rowWire->pad = 0; 4820 if (swap) { 4821 swaps(&rowWire->top); 4822 swaps(&rowWire->left); 4823 } 4824 wire = (char *) &rowWire[1]; 4825 if (row->keys) { 4826 int k; 4827 XkbKeyPtr key; 4828 xkbKeyWireDesc *keyWire; 4829 4830 keyWire = (xkbKeyWireDesc *) wire; 4831 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4832 memcpy(keyWire[k].name, key->name.name, 4833 XkbKeyNameLength); 4834 keyWire[k].gap = key->gap; 4835 keyWire[k].shapeNdx = key->shape_ndx; 4836 keyWire[k].colorNdx = key->color_ndx; 4837 if (swap) { 4838 swaps(&keyWire[k].gap); 4839 } 4840 } 4841 wire = (char *) &keyWire[row->num_keys]; 4842 } 4843 } 4844 } 4845 if (section->doodads) { 4846 wire = XkbWriteGeomDoodads(wire, 4847 section->num_doodads, section->doodads, 4848 swap); 4849 } 4850 if (section->overlays) { 4851 register int o; 4852 4853 for (o = 0; o < section->num_overlays; o++) { 4854 wire = XkbWriteGeomOverlay(wire, §ion->overlays[o], swap); 4855 } 4856 } 4857 } 4858 return wire; 4859} 4860 4861static Status 4862XkbComputeGetGeometryReplySize(XkbGeometryPtr geom, 4863 xkbGetGeometryReply * rep, Atom name) 4864{ 4865 int len; 4866 4867 if (geom != NULL) { 4868 len = XkbSizeCountedString(geom->label_font); 4869 len += XkbSizeGeomProperties(geom); 4870 len += XkbSizeGeomColors(geom); 4871 len += XkbSizeGeomShapes(geom); 4872 len += XkbSizeGeomSections(geom); 4873 len += XkbSizeGeomDoodads(geom->num_doodads, geom->doodads); 4874 len += XkbSizeGeomKeyAliases(geom); 4875 rep->length = len / 4; 4876 rep->found = TRUE; 4877 rep->name = geom->name; 4878 rep->widthMM = geom->width_mm; 4879 rep->heightMM = geom->height_mm; 4880 rep->nProperties = geom->num_properties; 4881 rep->nColors = geom->num_colors; 4882 rep->nShapes = geom->num_shapes; 4883 rep->nSections = geom->num_sections; 4884 rep->nDoodads = geom->num_doodads; 4885 rep->nKeyAliases = geom->num_key_aliases; 4886 rep->baseColorNdx = XkbGeomColorIndex(geom, geom->base_color); 4887 rep->labelColorNdx = XkbGeomColorIndex(geom, geom->label_color); 4888 } 4889 else { 4890 rep->length = 0; 4891 rep->found = FALSE; 4892 rep->name = name; 4893 rep->widthMM = rep->heightMM = 0; 4894 rep->nProperties = rep->nColors = rep->nShapes = 0; 4895 rep->nSections = rep->nDoodads = 0; 4896 rep->nKeyAliases = 0; 4897 rep->labelColorNdx = rep->baseColorNdx = 0; 4898 } 4899 return Success; 4900} 4901static int 4902XkbSendGeometry(ClientPtr client, 4903 XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom) 4904{ 4905 char *desc, *start; 4906 int len; 4907 4908 if (geom != NULL) { 4909 start = desc = xallocarray(rep->length, 4); 4910 if (!start) 4911 return BadAlloc; 4912 len = rep->length * 4; 4913 desc = XkbWriteCountedString(desc, geom->label_font, client->swapped); 4914 if (rep->nProperties > 0) 4915 desc = XkbWriteGeomProperties(desc, geom, client->swapped); 4916 if (rep->nColors > 0) 4917 desc = XkbWriteGeomColors(desc, geom, client->swapped); 4918 if (rep->nShapes > 0) 4919 desc = XkbWriteGeomShapes(desc, geom, client->swapped); 4920 if (rep->nSections > 0) 4921 desc = XkbWriteGeomSections(desc, geom, client->swapped); 4922 if (rep->nDoodads > 0) 4923 desc = XkbWriteGeomDoodads(desc, geom->num_doodads, geom->doodads, 4924 client->swapped); 4925 if (rep->nKeyAliases > 0) 4926 desc = XkbWriteGeomKeyAliases(desc, geom, client->swapped); 4927 if ((desc - start) != (len)) { 4928 ErrorF 4929 ("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 4930 len, (unsigned long) (desc - start)); 4931 } 4932 } 4933 else { 4934 len = 0; 4935 start = NULL; 4936 } 4937 if (client->swapped) { 4938 swaps(&rep->sequenceNumber); 4939 swapl(&rep->length); 4940 swapl(&rep->name); 4941 swaps(&rep->widthMM); 4942 swaps(&rep->heightMM); 4943 swaps(&rep->nProperties); 4944 swaps(&rep->nColors); 4945 swaps(&rep->nShapes); 4946 swaps(&rep->nSections); 4947 swaps(&rep->nDoodads); 4948 swaps(&rep->nKeyAliases); 4949 } 4950 WriteToClient(client, SIZEOF(xkbGetGeometryReply), rep); 4951 if (len > 0) 4952 WriteToClient(client, len, start); 4953 if (start != NULL) 4954 free((char *) start); 4955 if (freeGeom) 4956 XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 4957 return Success; 4958} 4959 4960int 4961ProcXkbGetGeometry(ClientPtr client) 4962{ 4963 DeviceIntPtr dev; 4964 xkbGetGeometryReply rep; 4965 XkbGeometryPtr geom; 4966 Bool shouldFree; 4967 Status status; 4968 4969 REQUEST(xkbGetGeometryReq); 4970 REQUEST_SIZE_MATCH(xkbGetGeometryReq); 4971 4972 if (!(client->xkbClientFlags & _XkbClientInitialized)) 4973 return BadAccess; 4974 4975 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 4976 CHK_ATOM_OR_NONE(stuff->name); 4977 4978 geom = XkbLookupNamedGeometry(dev, stuff->name, &shouldFree); 4979 rep = (xkbGetGeometryReply) { 4980 .type = X_Reply, 4981 .deviceID = dev->id, 4982 .sequenceNumber = client->sequence, 4983 .length = 0 4984 }; 4985 status = XkbComputeGetGeometryReplySize(geom, &rep, stuff->name); 4986 if (status != Success) 4987 return status; 4988 else 4989 return XkbSendGeometry(client, geom, &rep, shouldFree); 4990} 4991 4992/***====================================================================***/ 4993 4994static Status 4995_GetCountedString(char **wire_inout, ClientPtr client, char **str) 4996{ 4997 char *wire, *next; 4998 CARD16 len; 4999 5000 wire = *wire_inout; 5001 len = *(CARD16 *) wire; 5002 if (client->swapped) { 5003 swaps(&len); 5004 } 5005 next = wire + XkbPaddedSize(len + 2); 5006 /* Check we're still within the size of the request */ 5007 if (client->req_len < 5008 bytes_to_int32(next - (char *) client->requestBuffer)) 5009 return BadValue; 5010 *str = malloc(len + 1); 5011 if (!*str) 5012 return BadAlloc; 5013 memcpy(*str, &wire[2], len); 5014 *(*str + len) = '\0'; 5015 *wire_inout = next; 5016 return Success; 5017} 5018 5019static Status 5020_CheckSetDoodad(char **wire_inout, 5021 XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 5022{ 5023 char *wire; 5024 xkbDoodadWireDesc *dWire; 5025 xkbAnyDoodadWireDesc any; 5026 xkbTextDoodadWireDesc text; 5027 XkbDoodadPtr doodad; 5028 Status status; 5029 5030 dWire = (xkbDoodadWireDesc *) (*wire_inout); 5031 any = dWire->any; 5032 wire = (char *) &dWire[1]; 5033 if (client->swapped) { 5034 swapl(&any.name); 5035 swaps(&any.top); 5036 swaps(&any.left); 5037 swaps(&any.angle); 5038 } 5039 CHK_ATOM_ONLY(dWire->any.name); 5040 doodad = XkbAddGeomDoodad(geom, section, any.name); 5041 if (!doodad) 5042 return BadAlloc; 5043 doodad->any.type = dWire->any.type; 5044 doodad->any.priority = dWire->any.priority; 5045 doodad->any.top = any.top; 5046 doodad->any.left = any.left; 5047 doodad->any.angle = any.angle; 5048 switch (doodad->any.type) { 5049 case XkbOutlineDoodad: 5050 case XkbSolidDoodad: 5051 if (dWire->shape.colorNdx >= geom->num_colors) { 5052 client->errorValue = _XkbErrCode3(0x40, geom->num_colors, 5053 dWire->shape.colorNdx); 5054 return BadMatch; 5055 } 5056 if (dWire->shape.shapeNdx >= geom->num_shapes) { 5057 client->errorValue = _XkbErrCode3(0x41, geom->num_shapes, 5058 dWire->shape.shapeNdx); 5059 return BadMatch; 5060 } 5061 doodad->shape.color_ndx = dWire->shape.colorNdx; 5062 doodad->shape.shape_ndx = dWire->shape.shapeNdx; 5063 break; 5064 case XkbTextDoodad: 5065 if (dWire->text.colorNdx >= geom->num_colors) { 5066 client->errorValue = _XkbErrCode3(0x42, geom->num_colors, 5067 dWire->text.colorNdx); 5068 return BadMatch; 5069 } 5070 text = dWire->text; 5071 if (client->swapped) { 5072 swaps(&text.width); 5073 swaps(&text.height); 5074 } 5075 doodad->text.width = text.width; 5076 doodad->text.height = text.height; 5077 doodad->text.color_ndx = dWire->text.colorNdx; 5078 status = _GetCountedString(&wire, client, &doodad->text.text); 5079 if (status != Success) 5080 return status; 5081 status = _GetCountedString(&wire, client, &doodad->text.font); 5082 if (status != Success) { 5083 free (doodad->text.text); 5084 return status; 5085 } 5086 break; 5087 case XkbIndicatorDoodad: 5088 if (dWire->indicator.onColorNdx >= geom->num_colors) { 5089 client->errorValue = _XkbErrCode3(0x43, geom->num_colors, 5090 dWire->indicator.onColorNdx); 5091 return BadMatch; 5092 } 5093 if (dWire->indicator.offColorNdx >= geom->num_colors) { 5094 client->errorValue = _XkbErrCode3(0x44, geom->num_colors, 5095 dWire->indicator.offColorNdx); 5096 return BadMatch; 5097 } 5098 if (dWire->indicator.shapeNdx >= geom->num_shapes) { 5099 client->errorValue = _XkbErrCode3(0x45, geom->num_shapes, 5100 dWire->indicator.shapeNdx); 5101 return BadMatch; 5102 } 5103 doodad->indicator.shape_ndx = dWire->indicator.shapeNdx; 5104 doodad->indicator.on_color_ndx = dWire->indicator.onColorNdx; 5105 doodad->indicator.off_color_ndx = dWire->indicator.offColorNdx; 5106 break; 5107 case XkbLogoDoodad: 5108 if (dWire->logo.colorNdx >= geom->num_colors) { 5109 client->errorValue = _XkbErrCode3(0x46, geom->num_colors, 5110 dWire->logo.colorNdx); 5111 return BadMatch; 5112 } 5113 if (dWire->logo.shapeNdx >= geom->num_shapes) { 5114 client->errorValue = _XkbErrCode3(0x47, geom->num_shapes, 5115 dWire->logo.shapeNdx); 5116 return BadMatch; 5117 } 5118 doodad->logo.color_ndx = dWire->logo.colorNdx; 5119 doodad->logo.shape_ndx = dWire->logo.shapeNdx; 5120 status = _GetCountedString(&wire, client, &doodad->logo.logo_name); 5121 if (status != Success) 5122 return status; 5123 break; 5124 default: 5125 client->errorValue = _XkbErrCode2(0x4F, dWire->any.type); 5126 return BadValue; 5127 } 5128 *wire_inout = wire; 5129 return Success; 5130} 5131 5132static Status 5133_CheckSetOverlay(char **wire_inout, 5134 XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 5135{ 5136 register int r; 5137 char *wire; 5138 XkbOverlayPtr ol; 5139 xkbOverlayWireDesc *olWire; 5140 xkbOverlayRowWireDesc *rWire; 5141 5142 wire = *wire_inout; 5143 olWire = (xkbOverlayWireDesc *) wire; 5144 if (client->swapped) { 5145 swapl(&olWire->name); 5146 } 5147 CHK_ATOM_ONLY(olWire->name); 5148 ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows); 5149 rWire = (xkbOverlayRowWireDesc *) &olWire[1]; 5150 for (r = 0; r < olWire->nRows; r++) { 5151 register int k; 5152 xkbOverlayKeyWireDesc *kWire; 5153 XkbOverlayRowPtr row; 5154 5155 if (rWire->rowUnder > section->num_rows) { 5156 client->errorValue = _XkbErrCode4(0x20, r, section->num_rows, 5157 rWire->rowUnder); 5158 return BadMatch; 5159 } 5160 row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys); 5161 kWire = (xkbOverlayKeyWireDesc *) &rWire[1]; 5162 for (k = 0; k < rWire->nKeys; k++, kWire++) { 5163 if (XkbAddGeomOverlayKey(ol, row, 5164 (char *) kWire->over, 5165 (char *) kWire->under) == NULL) { 5166 client->errorValue = _XkbErrCode3(0x21, r, k); 5167 return BadMatch; 5168 } 5169 } 5170 rWire = (xkbOverlayRowWireDesc *) kWire; 5171 } 5172 olWire = (xkbOverlayWireDesc *) rWire; 5173 wire = (char *) olWire; 5174 *wire_inout = wire; 5175 return Success; 5176} 5177 5178static Status 5179_CheckSetSections(XkbGeometryPtr geom, 5180 xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5181{ 5182 Status status; 5183 register int s; 5184 char *wire; 5185 xkbSectionWireDesc *sWire; 5186 XkbSectionPtr section; 5187 5188 wire = *wire_inout; 5189 if (req->nSections < 1) 5190 return Success; 5191 sWire = (xkbSectionWireDesc *) wire; 5192 for (s = 0; s < req->nSections; s++) { 5193 register int r; 5194 xkbRowWireDesc *rWire; 5195 5196 if (client->swapped) { 5197 swapl(&sWire->name); 5198 swaps(&sWire->top); 5199 swaps(&sWire->left); 5200 swaps(&sWire->width); 5201 swaps(&sWire->height); 5202 swaps(&sWire->angle); 5203 } 5204 CHK_ATOM_ONLY(sWire->name); 5205 section = XkbAddGeomSection(geom, sWire->name, sWire->nRows, 5206 sWire->nDoodads, sWire->nOverlays); 5207 if (!section) 5208 return BadAlloc; 5209 section->priority = sWire->priority; 5210 section->top = sWire->top; 5211 section->left = sWire->left; 5212 section->width = sWire->width; 5213 section->height = sWire->height; 5214 section->angle = sWire->angle; 5215 rWire = (xkbRowWireDesc *) &sWire[1]; 5216 for (r = 0; r < sWire->nRows; r++) { 5217 register int k; 5218 XkbRowPtr row; 5219 xkbKeyWireDesc *kWire; 5220 5221 if (client->swapped) { 5222 swaps(&rWire->top); 5223 swaps(&rWire->left); 5224 } 5225 row = XkbAddGeomRow(section, rWire->nKeys); 5226 if (!row) 5227 return BadAlloc; 5228 row->top = rWire->top; 5229 row->left = rWire->left; 5230 row->vertical = rWire->vertical; 5231 kWire = (xkbKeyWireDesc *) &rWire[1]; 5232 for (k = 0; k < rWire->nKeys; k++) { 5233 XkbKeyPtr key; 5234 5235 key = XkbAddGeomKey(row); 5236 if (!key) 5237 return BadAlloc; 5238 memcpy(key->name.name, kWire[k].name, XkbKeyNameLength); 5239 key->gap = kWire[k].gap; 5240 key->shape_ndx = kWire[k].shapeNdx; 5241 key->color_ndx = kWire[k].colorNdx; 5242 if (key->shape_ndx >= geom->num_shapes) { 5243 client->errorValue = _XkbErrCode3(0x10, key->shape_ndx, 5244 geom->num_shapes); 5245 return BadMatch; 5246 } 5247 if (key->color_ndx >= geom->num_colors) { 5248 client->errorValue = _XkbErrCode3(0x11, key->color_ndx, 5249 geom->num_colors); 5250 return BadMatch; 5251 } 5252 } 5253 rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys]; 5254 } 5255 wire = (char *) rWire; 5256 if (sWire->nDoodads > 0) { 5257 register int d; 5258 5259 for (d = 0; d < sWire->nDoodads; d++) { 5260 status = _CheckSetDoodad(&wire, geom, section, client); 5261 if (status != Success) 5262 return status; 5263 } 5264 } 5265 if (sWire->nOverlays > 0) { 5266 register int o; 5267 5268 for (o = 0; o < sWire->nOverlays; o++) { 5269 status = _CheckSetOverlay(&wire, geom, section, client); 5270 if (status != Success) 5271 return status; 5272 } 5273 } 5274 sWire = (xkbSectionWireDesc *) wire; 5275 } 5276 wire = (char *) sWire; 5277 *wire_inout = wire; 5278 return Success; 5279} 5280 5281static Status 5282_CheckSetShapes(XkbGeometryPtr geom, 5283 xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5284{ 5285 register int i; 5286 char *wire; 5287 5288 wire = *wire_inout; 5289 if (req->nShapes < 1) { 5290 client->errorValue = _XkbErrCode2(0x06, req->nShapes); 5291 return BadValue; 5292 } 5293 else { 5294 xkbShapeWireDesc *shapeWire; 5295 XkbShapePtr shape; 5296 register int o; 5297 5298 shapeWire = (xkbShapeWireDesc *) wire; 5299 for (i = 0; i < req->nShapes; i++) { 5300 xkbOutlineWireDesc *olWire; 5301 XkbOutlinePtr ol; 5302 5303 shape = 5304 XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); 5305 if (!shape) 5306 return BadAlloc; 5307 olWire = (xkbOutlineWireDesc *) (&shapeWire[1]); 5308 for (o = 0; o < shapeWire->nOutlines; o++) { 5309 register int p; 5310 XkbPointPtr pt; 5311 xkbPointWireDesc *ptWire; 5312 5313 ol = XkbAddGeomOutline(shape, olWire->nPoints); 5314 if (!ol) 5315 return BadAlloc; 5316 ol->corner_radius = olWire->cornerRadius; 5317 ptWire = (xkbPointWireDesc *) &olWire[1]; 5318 for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { 5319 pt->x = ptWire[p].x; 5320 pt->y = ptWire[p].y; 5321 if (client->swapped) { 5322 swaps(&pt->x); 5323 swaps(&pt->y); 5324 } 5325 } 5326 ol->num_points = olWire->nPoints; 5327 olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]); 5328 } 5329 if (shapeWire->primaryNdx != XkbNoShape) 5330 shape->primary = &shape->outlines[shapeWire->primaryNdx]; 5331 if (shapeWire->approxNdx != XkbNoShape) 5332 shape->approx = &shape->outlines[shapeWire->approxNdx]; 5333 shapeWire = (xkbShapeWireDesc *) olWire; 5334 } 5335 wire = (char *) shapeWire; 5336 } 5337 if (geom->num_shapes != req->nShapes) { 5338 client->errorValue = _XkbErrCode3(0x07, geom->num_shapes, req->nShapes); 5339 return BadMatch; 5340 } 5341 5342 *wire_inout = wire; 5343 return Success; 5344} 5345 5346static Status 5347_CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client) 5348{ 5349 register int i; 5350 Status status; 5351 char *wire; 5352 5353 wire = (char *) &req[1]; 5354 status = _GetCountedString(&wire, client, &geom->label_font); 5355 if (status != Success) 5356 return status; 5357 5358 for (i = 0; i < req->nProperties; i++) { 5359 char *name, *val; 5360 5361 status = _GetCountedString(&wire, client, &name); 5362 if (status != Success) 5363 return status; 5364 status = _GetCountedString(&wire, client, &val); 5365 if (status != Success) { 5366 free(name); 5367 return status; 5368 } 5369 if (XkbAddGeomProperty(geom, name, val) == NULL) { 5370 free(name); 5371 free(val); 5372 return BadAlloc; 5373 } 5374 free(name); 5375 free(val); 5376 } 5377 5378 if (req->nColors < 2) { 5379 client->errorValue = _XkbErrCode3(0x01, 2, req->nColors); 5380 return BadValue; 5381 } 5382 if (req->baseColorNdx > req->nColors) { 5383 client->errorValue = 5384 _XkbErrCode3(0x03, req->nColors, req->baseColorNdx); 5385 return BadMatch; 5386 } 5387 if (req->labelColorNdx > req->nColors) { 5388 client->errorValue = 5389 _XkbErrCode3(0x03, req->nColors, req->labelColorNdx); 5390 return BadMatch; 5391 } 5392 if (req->labelColorNdx == req->baseColorNdx) { 5393 client->errorValue = _XkbErrCode3(0x04, req->baseColorNdx, 5394 req->labelColorNdx); 5395 return BadMatch; 5396 } 5397 5398 for (i = 0; i < req->nColors; i++) { 5399 char *name; 5400 5401 status = _GetCountedString(&wire, client, &name); 5402 if (status != Success) 5403 return status; 5404 if (!XkbAddGeomColor(geom, name, geom->num_colors)) { 5405 free(name); 5406 return BadAlloc; 5407 } 5408 free(name); 5409 } 5410 if (req->nColors != geom->num_colors) { 5411 client->errorValue = _XkbErrCode3(0x05, req->nColors, geom->num_colors); 5412 return BadMatch; 5413 } 5414 geom->label_color = &geom->colors[req->labelColorNdx]; 5415 geom->base_color = &geom->colors[req->baseColorNdx]; 5416 5417 if ((status = _CheckSetShapes(geom, req, &wire, client)) != Success) 5418 return status; 5419 5420 if ((status = _CheckSetSections(geom, req, &wire, client)) != Success) 5421 return status; 5422 5423 for (i = 0; i < req->nDoodads; i++) { 5424 status = _CheckSetDoodad(&wire, geom, NULL, client); 5425 if (status != Success) 5426 return status; 5427 } 5428 5429 for (i = 0; i < req->nKeyAliases; i++) { 5430 if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL) 5431 return BadAlloc; 5432 wire += 2 * XkbKeyNameLength; 5433 } 5434 return Success; 5435} 5436 5437static int 5438_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq * stuff) 5439{ 5440 XkbDescPtr xkb; 5441 Bool new_name; 5442 xkbNewKeyboardNotify nkn; 5443 XkbGeometryPtr geom, old; 5444 XkbGeometrySizesRec sizes; 5445 Status status; 5446 5447 xkb = dev->key->xkbInfo->desc; 5448 old = xkb->geom; 5449 xkb->geom = NULL; 5450 5451 sizes.which = XkbGeomAllMask; 5452 sizes.num_properties = stuff->nProperties; 5453 sizes.num_colors = stuff->nColors; 5454 sizes.num_shapes = stuff->nShapes; 5455 sizes.num_sections = stuff->nSections; 5456 sizes.num_doodads = stuff->nDoodads; 5457 sizes.num_key_aliases = stuff->nKeyAliases; 5458 if ((status = XkbAllocGeometry(xkb, &sizes)) != Success) { 5459 xkb->geom = old; 5460 return status; 5461 } 5462 geom = xkb->geom; 5463 geom->name = stuff->name; 5464 geom->width_mm = stuff->widthMM; 5465 geom->height_mm = stuff->heightMM; 5466 if ((status = _CheckSetGeom(geom, stuff, client)) != Success) { 5467 XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 5468 xkb->geom = old; 5469 return status; 5470 } 5471 new_name = (xkb->names->geometry != geom->name); 5472 xkb->names->geometry = geom->name; 5473 if (old) 5474 XkbFreeGeometry(old, XkbGeomAllMask, TRUE); 5475 if (new_name) { 5476 xkbNamesNotify nn; 5477 5478 memset(&nn, 0, sizeof(xkbNamesNotify)); 5479 nn.changed = XkbGeometryNameMask; 5480 XkbSendNamesNotify(dev, &nn); 5481 } 5482 nkn.deviceID = nkn.oldDeviceID = dev->id; 5483 nkn.minKeyCode = nkn.oldMinKeyCode = xkb->min_key_code; 5484 nkn.maxKeyCode = nkn.oldMaxKeyCode = xkb->max_key_code; 5485 nkn.requestMajor = XkbReqCode; 5486 nkn.requestMinor = X_kbSetGeometry; 5487 nkn.changed = XkbNKN_GeometryMask; 5488 XkbSendNewKeyboardNotify(dev, &nkn); 5489 return Success; 5490} 5491 5492int 5493ProcXkbSetGeometry(ClientPtr client) 5494{ 5495 DeviceIntPtr dev; 5496 int rc; 5497 5498 REQUEST(xkbSetGeometryReq); 5499 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 5500 5501 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5502 return BadAccess; 5503 5504 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 5505 CHK_ATOM_OR_NONE(stuff->name); 5506 5507 rc = _XkbSetGeometry(client, dev, stuff); 5508 if (rc != Success) 5509 return rc; 5510 5511 if (stuff->deviceSpec == XkbUseCoreKbd) { 5512 DeviceIntPtr other; 5513 5514 for (other = inputInfo.devices; other; other = other->next) { 5515 if ((other != dev) && other->key && !IsMaster(other) && 5516 GetMaster(other, MASTER_KEYBOARD) == dev) { 5517 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 5518 DixManageAccess); 5519 if (rc == Success) 5520 _XkbSetGeometry(client, other, stuff); 5521 } 5522 } 5523 } 5524 5525 return Success; 5526} 5527 5528/***====================================================================***/ 5529 5530int 5531ProcXkbPerClientFlags(ClientPtr client) 5532{ 5533 DeviceIntPtr dev; 5534 xkbPerClientFlagsReply rep; 5535 XkbInterestPtr interest; 5536 Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 5537 5538 REQUEST(xkbPerClientFlagsReq); 5539 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 5540 5541 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5542 return BadAccess; 5543 5544 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5545 CHK_MASK_LEGAL(0x01, stuff->change, XkbPCF_AllFlagsMask); 5546 CHK_MASK_MATCH(0x02, stuff->change, stuff->value); 5547 5548 interest = XkbFindClientResource((DevicePtr) dev, client); 5549 if (stuff->change) { 5550 client->xkbClientFlags &= ~stuff->change; 5551 client->xkbClientFlags |= stuff->value; 5552 } 5553 if (stuff->change & XkbPCF_AutoResetControlsMask) { 5554 Bool want; 5555 5556 want = stuff->value & XkbPCF_AutoResetControlsMask; 5557 if (interest && !want) { 5558 interest->autoCtrls = interest->autoCtrlValues = 0; 5559 } 5560 else if (want && (!interest)) { 5561 XID id = FakeClientID(client->index); 5562 5563 if (!AddResource(id, RT_XKBCLIENT, dev)) 5564 return BadAlloc; 5565 interest = XkbAddClientResource((DevicePtr) dev, client, id); 5566 if (!interest) 5567 return BadAlloc; 5568 } 5569 if (interest && want) { 5570 register unsigned affect; 5571 5572 affect = stuff->ctrlsToChange; 5573 5574 CHK_MASK_LEGAL(0x03, affect, XkbAllBooleanCtrlsMask); 5575 CHK_MASK_MATCH(0x04, affect, stuff->autoCtrls); 5576 CHK_MASK_MATCH(0x05, stuff->autoCtrls, stuff->autoCtrlValues); 5577 5578 interest->autoCtrls &= ~affect; 5579 interest->autoCtrlValues &= ~affect; 5580 interest->autoCtrls |= stuff->autoCtrls & affect; 5581 interest->autoCtrlValues |= stuff->autoCtrlValues & affect; 5582 } 5583 } 5584 5585 rep = (xkbPerClientFlagsReply) { 5586 .type = X_Reply, 5587 .sequenceNumber = client->sequence, 5588 .length = 0, 5589 .supported = XkbPCF_AllFlagsMask, 5590 .value = client->xkbClientFlags & XkbPCF_AllFlagsMask, 5591 .autoCtrls = interest ? interest->autoCtrls : 0, 5592 .autoCtrlValues = interest ? interest->autoCtrlValues : 0, 5593 }; 5594 if (client->swapped) { 5595 swaps(&rep.sequenceNumber); 5596 swapl(&rep.supported); 5597 swapl(&rep.value); 5598 swapl(&rep.autoCtrls); 5599 swapl(&rep.autoCtrlValues); 5600 } 5601 WriteToClient(client, SIZEOF(xkbPerClientFlagsReply), &rep); 5602 return Success; 5603} 5604 5605/***====================================================================***/ 5606 5607/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 5608/* and wildcards */ 5609static unsigned char componentSpecLegal[] = { 5610 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 5611 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 5612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5613 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5614}; 5615 5616/* same as above but accepts percent, plus and bar too */ 5617static unsigned char componentExprLegal[] = { 5618 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 5619 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 5620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5621 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5622}; 5623 5624static char * 5625GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn) 5626{ 5627 int len; 5628 register int i; 5629 unsigned char *wire, *str, *tmp, *legal; 5630 5631 if (allowExpr) 5632 legal = &componentExprLegal[0]; 5633 else 5634 legal = &componentSpecLegal[0]; 5635 5636 wire = *pWire; 5637 len = (*(unsigned char *) wire++); 5638 if (len > 0) { 5639 str = calloc(1, len + 1); 5640 if (str) { 5641 tmp = str; 5642 for (i = 0; i < len; i++) { 5643 if (legal[(*wire) / 8] & (1 << ((*wire) % 8))) 5644 *tmp++ = *wire++; 5645 else 5646 wire++; 5647 } 5648 if (tmp != str) 5649 *tmp++ = '\0'; 5650 else { 5651 free(str); 5652 str = NULL; 5653 } 5654 } 5655 else { 5656 *errRtrn = BadAlloc; 5657 } 5658 } 5659 else { 5660 str = NULL; 5661 } 5662 *pWire = wire; 5663 return (char *) str; 5664} 5665 5666/***====================================================================***/ 5667 5668int 5669ProcXkbListComponents(ClientPtr client) 5670{ 5671 DeviceIntPtr dev; 5672 xkbListComponentsReply rep; 5673 unsigned len; 5674 unsigned char *str; 5675 uint8_t size; 5676 int i; 5677 5678 REQUEST(xkbListComponentsReq); 5679 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 5680 5681 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5682 return BadAccess; 5683 5684 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 5685 5686 /* The request is followed by six Pascal strings (i.e. size in characters 5687 * followed by a string pattern) describing what the client wants us to 5688 * list. We don't care, but might as well check they haven't got the 5689 * length wrong. */ 5690 str = (unsigned char *) &stuff[1]; 5691 for (i = 0; i < 6; i++) { 5692 size = *((uint8_t *)str); 5693 len = (str + size + 1) - ((unsigned char *) stuff); 5694 if ((XkbPaddedSize(len) / 4) > stuff->length) 5695 return BadLength; 5696 str += (size + 1); 5697 } 5698 if ((XkbPaddedSize(len) / 4) != stuff->length) 5699 return BadLength; 5700 rep = (xkbListComponentsReply) { 5701 .type = X_Reply, 5702 .deviceID = dev->id, 5703 .sequenceNumber = client->sequence, 5704 .length = 0, 5705 .nKeymaps = 0, 5706 .nKeycodes = 0, 5707 .nTypes = 0, 5708 .nCompatMaps = 0, 5709 .nSymbols = 0, 5710 .nGeometries = 0, 5711 .extra = 0 5712 }; 5713 if (client->swapped) { 5714 swaps(&rep.sequenceNumber); 5715 swapl(&rep.length); 5716 swaps(&rep.nKeymaps); 5717 swaps(&rep.nKeycodes); 5718 swaps(&rep.nTypes); 5719 swaps(&rep.nCompatMaps); 5720 swaps(&rep.nSymbols); 5721 swaps(&rep.nGeometries); 5722 swaps(&rep.extra); 5723 } 5724 WriteToClient(client, SIZEOF(xkbListComponentsReply), &rep); 5725 return Success; 5726} 5727 5728/***====================================================================***/ 5729int 5730ProcXkbGetKbdByName(ClientPtr client) 5731{ 5732 DeviceIntPtr dev; 5733 DeviceIntPtr tmpd; 5734 DeviceIntPtr master; 5735 xkbGetKbdByNameReply rep = { 0 }; 5736 xkbGetMapReply mrep = { 0 }; 5737 xkbGetCompatMapReply crep = { 0 }; 5738 xkbGetIndicatorMapReply irep = { 0 }; 5739 xkbGetNamesReply nrep = { 0 }; 5740 xkbGetGeometryReply grep = { 0 }; 5741 XkbComponentNamesRec names = { 0 }; 5742 XkbDescPtr xkb, new; 5743 XkbEventCauseRec cause; 5744 unsigned char *str; 5745 char mapFile[PATH_MAX]; 5746 unsigned len; 5747 unsigned fwant, fneed, reported; 5748 int status; 5749 Bool geom_changed; 5750 XkbSrvLedInfoPtr old_sli; 5751 XkbSrvLedInfoPtr sli; 5752 Mask access_mode = DixGetAttrAccess | DixManageAccess; 5753 5754 REQUEST(xkbGetKbdByNameReq); 5755 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 5756 5757 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5758 return BadAccess; 5759 5760 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5761 master = GetMaster(dev, MASTER_KEYBOARD); 5762 5763 xkb = dev->key->xkbInfo->desc; 5764 status = Success; 5765 str = (unsigned char *) &stuff[1]; 5766 if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */ 5767 return BadMatch; 5768 names.keycodes = GetComponentSpec(&str, TRUE, &status); 5769 names.types = GetComponentSpec(&str, TRUE, &status); 5770 names.compat = GetComponentSpec(&str, TRUE, &status); 5771 names.symbols = GetComponentSpec(&str, TRUE, &status); 5772 names.geometry = GetComponentSpec(&str, TRUE, &status); 5773 if (status != Success) 5774 return status; 5775 len = str - ((unsigned char *) stuff); 5776 if ((XkbPaddedSize(len) / 4) != stuff->length) 5777 return BadLength; 5778 5779 CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask); 5780 CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask); 5781 5782 if (stuff->load) 5783 fwant = XkbGBN_AllComponentsMask; 5784 else 5785 fwant = stuff->want | stuff->need; 5786 if ((!names.compat) && 5787 (fwant & (XkbGBN_CompatMapMask | XkbGBN_IndicatorMapMask))) { 5788 names.compat = Xstrdup("%"); 5789 } 5790 if ((!names.types) && (fwant & (XkbGBN_TypesMask))) { 5791 names.types = Xstrdup("%"); 5792 } 5793 if ((!names.symbols) && (fwant & XkbGBN_SymbolsMask)) { 5794 names.symbols = Xstrdup("%"); 5795 } 5796 geom_changed = ((names.geometry != NULL) && 5797 (strcmp(names.geometry, "%") != 0)); 5798 if ((!names.geometry) && (fwant & XkbGBN_GeometryMask)) { 5799 names.geometry = Xstrdup("%"); 5800 geom_changed = FALSE; 5801 } 5802 5803 memset(mapFile, 0, PATH_MAX); 5804 rep.type = X_Reply; 5805 rep.deviceID = dev->id; 5806 rep.sequenceNumber = client->sequence; 5807 rep.length = 0; 5808 rep.minKeyCode = xkb->min_key_code; 5809 rep.maxKeyCode = xkb->max_key_code; 5810 rep.loaded = FALSE; 5811 fwant = 5812 XkbConvertGetByNameComponents(TRUE, stuff->want) | XkmVirtualModsMask; 5813 fneed = XkbConvertGetByNameComponents(TRUE, stuff->need); 5814 rep.reported = XkbConvertGetByNameComponents(FALSE, fwant | fneed); 5815 if (stuff->load) { 5816 fneed |= XkmKeymapRequired; 5817 fwant |= XkmKeymapLegal; 5818 } 5819 if ((fwant | fneed) & XkmSymbolsMask) { 5820 fneed |= XkmKeyNamesIndex | XkmTypesIndex; 5821 fwant |= XkmIndicatorsIndex; 5822 } 5823 5824 /* We pass dev in here so we can get the old names out if needed. */ 5825 rep.found = XkbDDXLoadKeymapByNames(dev, &names, fwant, fneed, &new, 5826 mapFile, PATH_MAX); 5827 rep.newKeyboard = FALSE; 5828 rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0; 5829 5830 stuff->want |= stuff->need; 5831 if (new == NULL) 5832 rep.reported = 0; 5833 else { 5834 if (stuff->load) 5835 rep.loaded = TRUE; 5836 if (stuff->load || 5837 ((rep.reported & XkbGBN_SymbolsMask) && (new->compat))) { 5838 XkbChangesRec changes; 5839 5840 memset(&changes, 0, sizeof(changes)); 5841 XkbUpdateDescActions(new, 5842 new->min_key_code, XkbNumKeys(new), &changes); 5843 } 5844 5845 if (new->map == NULL) 5846 rep.reported &= ~(XkbGBN_SymbolsMask | XkbGBN_TypesMask); 5847 else if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) { 5848 mrep.type = X_Reply; 5849 mrep.deviceID = dev->id; 5850 mrep.sequenceNumber = client->sequence; 5851 mrep.length = 5852 ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2); 5853 mrep.minKeyCode = new->min_key_code; 5854 mrep.maxKeyCode = new->max_key_code; 5855 mrep.present = 0; 5856 mrep.totalSyms = mrep.totalActs = 5857 mrep.totalKeyBehaviors = mrep.totalKeyExplicit = 5858 mrep.totalModMapKeys = mrep.totalVModMapKeys = 0; 5859 if (rep.reported & (XkbGBN_TypesMask | XkbGBN_ClientSymbolsMask)) { 5860 mrep.present |= XkbKeyTypesMask; 5861 mrep.firstType = 0; 5862 mrep.nTypes = mrep.totalTypes = new->map->num_types; 5863 } 5864 else { 5865 mrep.firstType = mrep.nTypes = 0; 5866 mrep.totalTypes = 0; 5867 } 5868 if (rep.reported & XkbGBN_ClientSymbolsMask) { 5869 mrep.present |= (XkbKeySymsMask | XkbModifierMapMask); 5870 mrep.firstKeySym = mrep.firstModMapKey = new->min_key_code; 5871 mrep.nKeySyms = mrep.nModMapKeys = XkbNumKeys(new); 5872 } 5873 else { 5874 mrep.firstKeySym = mrep.firstModMapKey = 0; 5875 mrep.nKeySyms = mrep.nModMapKeys = 0; 5876 } 5877 if (rep.reported & XkbGBN_ServerSymbolsMask) { 5878 mrep.present |= XkbAllServerInfoMask; 5879 mrep.virtualMods = ~0; 5880 mrep.firstKeyAct = mrep.firstKeyBehavior = 5881 mrep.firstKeyExplicit = new->min_key_code; 5882 mrep.nKeyActs = mrep.nKeyBehaviors = 5883 mrep.nKeyExplicit = XkbNumKeys(new); 5884 mrep.firstVModMapKey = new->min_key_code; 5885 mrep.nVModMapKeys = XkbNumKeys(new); 5886 } 5887 else { 5888 mrep.virtualMods = 0; 5889 mrep.firstKeyAct = mrep.firstKeyBehavior = 5890 mrep.firstKeyExplicit = 0; 5891 mrep.nKeyActs = mrep.nKeyBehaviors = mrep.nKeyExplicit = 0; 5892 } 5893 XkbComputeGetMapReplySize(new, &mrep); 5894 rep.length += SIZEOF(xGenericReply) / 4 + mrep.length; 5895 } 5896 if (new->compat == NULL) 5897 rep.reported &= ~XkbGBN_CompatMapMask; 5898 else if (rep.reported & XkbGBN_CompatMapMask) { 5899 crep.type = X_Reply; 5900 crep.deviceID = dev->id; 5901 crep.sequenceNumber = client->sequence; 5902 crep.length = 0; 5903 crep.groups = XkbAllGroupsMask; 5904 crep.firstSI = 0; 5905 crep.nSI = crep.nTotalSI = new->compat->num_si; 5906 XkbComputeGetCompatMapReplySize(new->compat, &crep); 5907 rep.length += SIZEOF(xGenericReply) / 4 + crep.length; 5908 } 5909 if (new->indicators == NULL) 5910 rep.reported &= ~XkbGBN_IndicatorMapMask; 5911 else if (rep.reported & XkbGBN_IndicatorMapMask) { 5912 irep.type = X_Reply; 5913 irep.deviceID = dev->id; 5914 irep.sequenceNumber = client->sequence; 5915 irep.length = 0; 5916 irep.which = XkbAllIndicatorsMask; 5917 XkbComputeGetIndicatorMapReplySize(new->indicators, &irep); 5918 rep.length += SIZEOF(xGenericReply) / 4 + irep.length; 5919 } 5920 if (new->names == NULL) 5921 rep.reported &= ~(XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask); 5922 else if (rep.reported & (XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask)) { 5923 nrep.type = X_Reply; 5924 nrep.deviceID = dev->id; 5925 nrep.sequenceNumber = client->sequence; 5926 nrep.length = 0; 5927 nrep.minKeyCode = new->min_key_code; 5928 nrep.maxKeyCode = new->max_key_code; 5929 if (rep.reported & XkbGBN_OtherNamesMask) { 5930 nrep.which = XkbAllNamesMask; 5931 if (new->map != NULL) 5932 nrep.nTypes = new->map->num_types; 5933 else 5934 nrep.nTypes = 0; 5935 nrep.nKTLevels = 0; 5936 nrep.groupNames = XkbAllGroupsMask; 5937 nrep.virtualMods = XkbAllVirtualModsMask; 5938 nrep.indicators = XkbAllIndicatorsMask; 5939 nrep.nRadioGroups = new->names->num_rg; 5940 } 5941 else { 5942 nrep.which = 0; 5943 nrep.nTypes = 0; 5944 nrep.nKTLevels = 0; 5945 nrep.groupNames = 0; 5946 nrep.virtualMods = 0; 5947 nrep.indicators = 0; 5948 nrep.nRadioGroups = 0; 5949 } 5950 if (rep.reported & XkbGBN_KeyNamesMask) { 5951 nrep.which |= XkbKeyNamesMask; 5952 nrep.firstKey = new->min_key_code; 5953 nrep.nKeys = XkbNumKeys(new); 5954 nrep.nKeyAliases = new->names->num_key_aliases; 5955 if (nrep.nKeyAliases) 5956 nrep.which |= XkbKeyAliasesMask; 5957 } 5958 else { 5959 nrep.which &= ~(XkbKeyNamesMask | XkbKeyAliasesMask); 5960 nrep.firstKey = nrep.nKeys = 0; 5961 nrep.nKeyAliases = 0; 5962 } 5963 XkbComputeGetNamesReplySize(new, &nrep); 5964 rep.length += SIZEOF(xGenericReply) / 4 + nrep.length; 5965 } 5966 if (new->geom == NULL) 5967 rep.reported &= ~XkbGBN_GeometryMask; 5968 else if (rep.reported & XkbGBN_GeometryMask) { 5969 grep.type = X_Reply; 5970 grep.deviceID = dev->id; 5971 grep.sequenceNumber = client->sequence; 5972 grep.length = 0; 5973 grep.found = TRUE; 5974 grep.pad = 0; 5975 grep.widthMM = grep.heightMM = 0; 5976 grep.nProperties = grep.nColors = grep.nShapes = 0; 5977 grep.nSections = grep.nDoodads = 0; 5978 grep.baseColorNdx = grep.labelColorNdx = 0; 5979 XkbComputeGetGeometryReplySize(new->geom, &grep, None); 5980 rep.length += SIZEOF(xGenericReply) / 4 + grep.length; 5981 } 5982 } 5983 5984 reported = rep.reported; 5985 if (client->swapped) { 5986 swaps(&rep.sequenceNumber); 5987 swapl(&rep.length); 5988 swaps(&rep.found); 5989 swaps(&rep.reported); 5990 } 5991 WriteToClient(client, SIZEOF(xkbGetKbdByNameReply), &rep); 5992 if (reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) 5993 XkbSendMap(client, new, &mrep); 5994 if (reported & XkbGBN_CompatMapMask) 5995 XkbSendCompatMap(client, new->compat, &crep); 5996 if (reported & XkbGBN_IndicatorMapMask) 5997 XkbSendIndicatorMap(client, new->indicators, &irep); 5998 if (reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) 5999 XkbSendNames(client, new, &nrep); 6000 if (reported & XkbGBN_GeometryMask) 6001 XkbSendGeometry(client, new->geom, &grep, FALSE); 6002 if (rep.loaded) { 6003 XkbDescPtr old_xkb; 6004 xkbNewKeyboardNotify nkn; 6005 6006 old_xkb = xkb; 6007 xkb = new; 6008 dev->key->xkbInfo->desc = xkb; 6009 new = old_xkb; /* so it'll get freed automatically */ 6010 6011 XkbCopyControls(xkb, old_xkb); 6012 6013 nkn.deviceID = nkn.oldDeviceID = dev->id; 6014 nkn.minKeyCode = new->min_key_code; 6015 nkn.maxKeyCode = new->max_key_code; 6016 nkn.oldMinKeyCode = xkb->min_key_code; 6017 nkn.oldMaxKeyCode = xkb->max_key_code; 6018 nkn.requestMajor = XkbReqCode; 6019 nkn.requestMinor = X_kbGetKbdByName; 6020 nkn.changed = XkbNKN_KeycodesMask; 6021 if (geom_changed) 6022 nkn.changed |= XkbNKN_GeometryMask; 6023 XkbSendNewKeyboardNotify(dev, &nkn); 6024 6025 /* Update the map and LED info on the device itself, as well as 6026 * any slaves if it's an MD, or its MD if it's an SD and was the 6027 * last device used on that MD. */ 6028 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 6029 if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev && 6030 (tmpd != master || dev != master->lastSlave)) 6031 continue; 6032 6033 if (tmpd != dev) 6034 XkbDeviceApplyKeymap(tmpd, xkb); 6035 6036 if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 6037 old_sli = tmpd->kbdfeed->xkb_sli; 6038 tmpd->kbdfeed->xkb_sli = NULL; 6039 sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 6040 if (sli) { 6041 sli->explicitState = old_sli->explicitState; 6042 sli->effectiveState = old_sli->effectiveState; 6043 } 6044 tmpd->kbdfeed->xkb_sli = sli; 6045 XkbFreeSrvLedInfo(old_sli); 6046 } 6047 } 6048 } 6049 if ((new != NULL) && (new != xkb)) { 6050 XkbFreeKeyboard(new, XkbAllComponentsMask, TRUE); 6051 new = NULL; 6052 } 6053 XkbFreeComponentNames(&names, FALSE); 6054 XkbSetCauseXkbReq(&cause, X_kbGetKbdByName, client); 6055 XkbUpdateAllDeviceIndicators(NULL, &cause); 6056 6057 return Success; 6058} 6059 6060/***====================================================================***/ 6061 6062static int 6063ComputeDeviceLedInfoSize(DeviceIntPtr dev, 6064 unsigned int what, XkbSrvLedInfoPtr sli) 6065{ 6066 int nNames, nMaps; 6067 register unsigned n, bit; 6068 6069 if (sli == NULL) 6070 return 0; 6071 nNames = nMaps = 0; 6072 if ((what & XkbXI_IndicatorNamesMask) == 0) 6073 sli->namesPresent = 0; 6074 if ((what & XkbXI_IndicatorMapsMask) == 0) 6075 sli->mapsPresent = 0; 6076 6077 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6078 if (sli->names && sli->names[n] != None) { 6079 sli->namesPresent |= bit; 6080 nNames++; 6081 } 6082 if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 6083 sli->mapsPresent |= bit; 6084 nMaps++; 6085 } 6086 } 6087 return (nNames * 4) + (nMaps * SIZEOF(xkbIndicatorMapWireDesc)); 6088} 6089 6090static int 6091CheckDeviceLedFBs(DeviceIntPtr dev, 6092 int class, 6093 int id, xkbGetDeviceInfoReply * rep, ClientPtr client) 6094{ 6095 int nFBs = 0; 6096 int length = 0; 6097 Bool classOk; 6098 6099 if (class == XkbDfltXIClass) { 6100 if (dev->kbdfeed) 6101 class = KbdFeedbackClass; 6102 else if (dev->leds) 6103 class = LedFeedbackClass; 6104 else { 6105 client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 6106 return XkbKeyboardErrorCode; 6107 } 6108 } 6109 classOk = FALSE; 6110 if ((dev->kbdfeed) && 6111 ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6112 KbdFeedbackPtr kf; 6113 6114 classOk = TRUE; 6115 for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6116 if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6117 (id != kf->ctrl.id)) 6118 continue; 6119 nFBs++; 6120 length += SIZEOF(xkbDeviceLedsWireDesc); 6121 if (!kf->xkb_sli) 6122 kf->xkb_sli = XkbAllocSrvLedInfo(dev, kf, NULL, 0); 6123 length += ComputeDeviceLedInfoSize(dev, rep->present, kf->xkb_sli); 6124 if (id != XkbAllXIIds) 6125 break; 6126 } 6127 } 6128 if ((dev->leds) && 6129 ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6130 LedFeedbackPtr lf; 6131 6132 classOk = TRUE; 6133 for (lf = dev->leds; (lf); lf = lf->next) { 6134 if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6135 (id != lf->ctrl.id)) 6136 continue; 6137 nFBs++; 6138 length += SIZEOF(xkbDeviceLedsWireDesc); 6139 if (!lf->xkb_sli) 6140 lf->xkb_sli = XkbAllocSrvLedInfo(dev, NULL, lf, 0); 6141 length += ComputeDeviceLedInfoSize(dev, rep->present, lf->xkb_sli); 6142 if (id != XkbAllXIIds) 6143 break; 6144 } 6145 } 6146 if (nFBs > 0) { 6147 rep->nDeviceLedFBs = nFBs; 6148 rep->length += (length / 4); 6149 return Success; 6150 } 6151 if (classOk) 6152 client->errorValue = _XkbErrCode2(XkbErr_BadId, id); 6153 else 6154 client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 6155 return XkbKeyboardErrorCode; 6156} 6157 6158static int 6159SendDeviceLedInfo(XkbSrvLedInfoPtr sli, ClientPtr client) 6160{ 6161 xkbDeviceLedsWireDesc wire; 6162 int length; 6163 6164 length = 0; 6165 wire.ledClass = sli->class; 6166 wire.ledID = sli->id; 6167 wire.namesPresent = sli->namesPresent; 6168 wire.mapsPresent = sli->mapsPresent; 6169 wire.physIndicators = sli->physIndicators; 6170 wire.state = sli->effectiveState; 6171 if (client->swapped) { 6172 swaps(&wire.ledClass); 6173 swaps(&wire.ledID); 6174 swapl(&wire.namesPresent); 6175 swapl(&wire.mapsPresent); 6176 swapl(&wire.physIndicators); 6177 swapl(&wire.state); 6178 } 6179 WriteToClient(client, SIZEOF(xkbDeviceLedsWireDesc), &wire); 6180 length += SIZEOF(xkbDeviceLedsWireDesc); 6181 if (sli->namesPresent | sli->mapsPresent) { 6182 register unsigned i, bit; 6183 6184 if (sli->namesPresent) { 6185 CARD32 awire; 6186 6187 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6188 if (sli->namesPresent & bit) { 6189 awire = (CARD32) sli->names[i]; 6190 if (client->swapped) { 6191 swapl(&awire); 6192 } 6193 WriteToClient(client, 4, &awire); 6194 length += 4; 6195 } 6196 } 6197 } 6198 if (sli->mapsPresent) { 6199 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6200 xkbIndicatorMapWireDesc iwire; 6201 6202 if (sli->mapsPresent & bit) { 6203 iwire.flags = sli->maps[i].flags; 6204 iwire.whichGroups = sli->maps[i].which_groups; 6205 iwire.groups = sli->maps[i].groups; 6206 iwire.whichMods = sli->maps[i].which_mods; 6207 iwire.mods = sli->maps[i].mods.mask; 6208 iwire.realMods = sli->maps[i].mods.real_mods; 6209 iwire.virtualMods = sli->maps[i].mods.vmods; 6210 iwire.ctrls = sli->maps[i].ctrls; 6211 if (client->swapped) { 6212 swaps(&iwire.virtualMods); 6213 swapl(&iwire.ctrls); 6214 } 6215 WriteToClient(client, SIZEOF(xkbIndicatorMapWireDesc), 6216 &iwire); 6217 length += SIZEOF(xkbIndicatorMapWireDesc); 6218 } 6219 } 6220 } 6221 } 6222 return length; 6223} 6224 6225static int 6226SendDeviceLedFBs(DeviceIntPtr dev, 6227 int class, int id, unsigned wantLength, ClientPtr client) 6228{ 6229 int length = 0; 6230 6231 if (class == XkbDfltXIClass) { 6232 if (dev->kbdfeed) 6233 class = KbdFeedbackClass; 6234 else if (dev->leds) 6235 class = LedFeedbackClass; 6236 } 6237 if ((dev->kbdfeed) && 6238 ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6239 KbdFeedbackPtr kf; 6240 6241 for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6242 if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6243 (id == kf->ctrl.id)) { 6244 length += SendDeviceLedInfo(kf->xkb_sli, client); 6245 if (id != XkbAllXIIds) 6246 break; 6247 } 6248 } 6249 } 6250 if ((dev->leds) && 6251 ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6252 LedFeedbackPtr lf; 6253 6254 for (lf = dev->leds; (lf); lf = lf->next) { 6255 if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6256 (id == lf->ctrl.id)) { 6257 length += SendDeviceLedInfo(lf->xkb_sli, client); 6258 if (id != XkbAllXIIds) 6259 break; 6260 } 6261 } 6262 } 6263 if (length == wantLength) 6264 return Success; 6265 else 6266 return BadLength; 6267} 6268 6269int 6270ProcXkbGetDeviceInfo(ClientPtr client) 6271{ 6272 DeviceIntPtr dev; 6273 xkbGetDeviceInfoReply rep; 6274 int status, nDeviceLedFBs; 6275 unsigned length, nameLen; 6276 CARD16 ledClass, ledID; 6277 unsigned wanted; 6278 char *str; 6279 6280 REQUEST(xkbGetDeviceInfoReq); 6281 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 6282 6283 if (!(client->xkbClientFlags & _XkbClientInitialized)) 6284 return BadAccess; 6285 6286 wanted = stuff->wanted; 6287 6288 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 6289 CHK_MASK_LEGAL(0x01, wanted, XkbXI_AllDeviceFeaturesMask); 6290 6291 if ((!dev->button) || ((stuff->nBtns < 1) && (!stuff->allBtns))) 6292 wanted &= ~XkbXI_ButtonActionsMask; 6293 if ((!dev->kbdfeed) && (!dev->leds)) 6294 wanted &= ~XkbXI_IndicatorsMask; 6295 6296 nameLen = XkbSizeCountedString(dev->name); 6297 rep = (xkbGetDeviceInfoReply) { 6298 .type = X_Reply, 6299 .deviceID = dev->id, 6300 .sequenceNumber = client->sequence, 6301 .length = nameLen / 4, 6302 .present = wanted, 6303 .supported = XkbXI_AllDeviceFeaturesMask, 6304 .unsupported = 0, 6305 .nDeviceLedFBs = 0, 6306 .firstBtnWanted = 0, 6307 .nBtnsWanted = 0, 6308 .firstBtnRtrn = 0, 6309 .nBtnsRtrn = 0, 6310 .totalBtns = dev->button ? dev->button->numButtons : 0, 6311 .hasOwnState = (dev->key && dev->key->xkbInfo), 6312 .dfltKbdFB = dev->kbdfeed ? dev->kbdfeed->ctrl.id : XkbXINone, 6313 .dfltLedFB = dev->leds ? dev->leds->ctrl.id : XkbXINone, 6314 .devType = dev->xinput_type 6315 }; 6316 6317 ledClass = stuff->ledClass; 6318 ledID = stuff->ledID; 6319 6320 if (wanted & XkbXI_ButtonActionsMask) { 6321 if (stuff->allBtns) { 6322 stuff->firstBtn = 0; 6323 stuff->nBtns = dev->button->numButtons; 6324 } 6325 6326 if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6327 client->errorValue = _XkbErrCode4(0x02, dev->button->numButtons, 6328 stuff->firstBtn, stuff->nBtns); 6329 return BadValue; 6330 } 6331 else { 6332 rep.firstBtnWanted = stuff->firstBtn; 6333 rep.nBtnsWanted = stuff->nBtns; 6334 if (dev->button->xkb_acts != NULL) { 6335 XkbAction *act; 6336 register int i; 6337 6338 rep.firstBtnRtrn = stuff->firstBtn; 6339 rep.nBtnsRtrn = stuff->nBtns; 6340 act = &dev->button->xkb_acts[rep.firstBtnWanted]; 6341 for (i = 0; i < rep.nBtnsRtrn; i++, act++) { 6342 if (act->type != XkbSA_NoAction) 6343 break; 6344 } 6345 rep.firstBtnRtrn += i; 6346 rep.nBtnsRtrn -= i; 6347 act = 6348 &dev->button->xkb_acts[rep.firstBtnRtrn + rep.nBtnsRtrn - 6349 1]; 6350 for (i = 0; i < rep.nBtnsRtrn; i++, act--) { 6351 if (act->type != XkbSA_NoAction) 6352 break; 6353 } 6354 rep.nBtnsRtrn -= i; 6355 } 6356 rep.length += (rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc)) / 4; 6357 } 6358 } 6359 6360 if (wanted & XkbXI_IndicatorsMask) { 6361 status = CheckDeviceLedFBs(dev, ledClass, ledID, &rep, client); 6362 if (status != Success) 6363 return status; 6364 } 6365 length = rep.length * 4; 6366 nDeviceLedFBs = rep.nDeviceLedFBs; 6367 if (client->swapped) { 6368 swaps(&rep.sequenceNumber); 6369 swapl(&rep.length); 6370 swaps(&rep.present); 6371 swaps(&rep.supported); 6372 swaps(&rep.unsupported); 6373 swaps(&rep.nDeviceLedFBs); 6374 swaps(&rep.dfltKbdFB); 6375 swaps(&rep.dfltLedFB); 6376 swapl(&rep.devType); 6377 } 6378 WriteToClient(client, SIZEOF(xkbGetDeviceInfoReply), &rep); 6379 6380 str = malloc(nameLen); 6381 if (!str) 6382 return BadAlloc; 6383 XkbWriteCountedString(str, dev->name, client->swapped); 6384 WriteToClient(client, nameLen, str); 6385 free(str); 6386 length -= nameLen; 6387 6388 if (rep.nBtnsRtrn > 0) { 6389 int sz; 6390 xkbActionWireDesc *awire; 6391 6392 sz = rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc); 6393 awire = (xkbActionWireDesc *) &dev->button->xkb_acts[rep.firstBtnRtrn]; 6394 WriteToClient(client, sz, awire); 6395 length -= sz; 6396 } 6397 if (nDeviceLedFBs > 0) { 6398 status = SendDeviceLedFBs(dev, ledClass, ledID, length, client); 6399 if (status != Success) 6400 return status; 6401 } 6402 else if (length != 0) { 6403 ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 6404 ErrorF("[xkb] Wrote %d fewer bytes than expected\n", 6405 length); 6406 return BadLength; 6407 } 6408 return Success; 6409} 6410 6411static char * 6412CheckSetDeviceIndicators(char *wire, 6413 DeviceIntPtr dev, 6414 int num, int *status_rtrn, ClientPtr client) 6415{ 6416 xkbDeviceLedsWireDesc *ledWire; 6417 int i; 6418 XkbSrvLedInfoPtr sli; 6419 6420 ledWire = (xkbDeviceLedsWireDesc *) wire; 6421 for (i = 0; i < num; i++) { 6422 if (client->swapped) { 6423 swaps(&ledWire->ledClass); 6424 swaps(&ledWire->ledID); 6425 swapl(&ledWire->namesPresent); 6426 swapl(&ledWire->mapsPresent); 6427 swapl(&ledWire->physIndicators); 6428 } 6429 6430 sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6431 XkbXI_IndicatorsMask); 6432 if (sli != NULL) { 6433 register int n; 6434 register unsigned bit; 6435 int nMaps, nNames; 6436 CARD32 *atomWire; 6437 xkbIndicatorMapWireDesc *mapWire; 6438 6439 nMaps = nNames = 0; 6440 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6441 if (ledWire->namesPresent & bit) 6442 nNames++; 6443 if (ledWire->mapsPresent & bit) 6444 nMaps++; 6445 } 6446 atomWire = (CARD32 *) &ledWire[1]; 6447 if (nNames > 0) { 6448 for (n = 0; n < nNames; n++) { 6449 if (client->swapped) { 6450 swapl(atomWire); 6451 } 6452 CHK_ATOM_OR_NONE3(((Atom) (*atomWire)), client->errorValue, 6453 *status_rtrn, NULL); 6454 atomWire++; 6455 } 6456 } 6457 mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6458 if (nMaps > 0) { 6459 for (n = 0; n < nMaps; n++) { 6460 if (client->swapped) { 6461 swaps(&mapWire->virtualMods); 6462 swapl(&mapWire->ctrls); 6463 } 6464 CHK_MASK_LEGAL3(0x21, mapWire->whichGroups, 6465 XkbIM_UseAnyGroup, 6466 client->errorValue, *status_rtrn, NULL); 6467 CHK_MASK_LEGAL3(0x22, mapWire->whichMods, XkbIM_UseAnyMods, 6468 client->errorValue, *status_rtrn, NULL); 6469 mapWire++; 6470 } 6471 } 6472 ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6473 } 6474 else { 6475 /* SHOULD NEVER HAPPEN */ 6476 return (char *) ledWire; 6477 } 6478 } 6479 return (char *) ledWire; 6480} 6481 6482static char * 6483SetDeviceIndicators(char *wire, 6484 DeviceIntPtr dev, 6485 unsigned changed, 6486 int num, 6487 int *status_rtrn, 6488 ClientPtr client, xkbExtensionDeviceNotify * ev) 6489{ 6490 xkbDeviceLedsWireDesc *ledWire; 6491 int i; 6492 XkbEventCauseRec cause; 6493 unsigned namec, mapc, statec; 6494 xkbExtensionDeviceNotify ed; 6495 XkbChangesRec changes; 6496 DeviceIntPtr kbd; 6497 6498 memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 6499 memset((char *) &changes, 0, sizeof(XkbChangesRec)); 6500 XkbSetCauseXkbReq(&cause, X_kbSetDeviceInfo, client); 6501 ledWire = (xkbDeviceLedsWireDesc *) wire; 6502 for (i = 0; i < num; i++) { 6503 register int n; 6504 register unsigned bit; 6505 CARD32 *atomWire; 6506 xkbIndicatorMapWireDesc *mapWire; 6507 XkbSrvLedInfoPtr sli; 6508 6509 namec = mapc = statec = 0; 6510 sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6511 XkbXI_IndicatorMapsMask); 6512 if (!sli) { 6513 /* SHOULD NEVER HAPPEN!! */ 6514 return (char *) ledWire; 6515 } 6516 6517 atomWire = (CARD32 *) &ledWire[1]; 6518 if (changed & XkbXI_IndicatorNamesMask) { 6519 namec = sli->namesPresent | ledWire->namesPresent; 6520 memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6521 } 6522 if (ledWire->namesPresent) { 6523 sli->namesPresent = ledWire->namesPresent; 6524 memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6525 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6526 if (ledWire->namesPresent & bit) { 6527 sli->names[n] = (Atom) *atomWire; 6528 if (sli->names[n] == None) 6529 ledWire->namesPresent &= ~bit; 6530 atomWire++; 6531 } 6532 } 6533 } 6534 mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6535 if (changed & XkbXI_IndicatorMapsMask) { 6536 mapc = sli->mapsPresent | ledWire->mapsPresent; 6537 sli->mapsPresent = ledWire->mapsPresent; 6538 memset((char *) sli->maps, 0, 6539 XkbNumIndicators * sizeof(XkbIndicatorMapRec)); 6540 } 6541 if (ledWire->mapsPresent) { 6542 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6543 if (ledWire->mapsPresent & bit) { 6544 sli->maps[n].flags = mapWire->flags; 6545 sli->maps[n].which_groups = mapWire->whichGroups; 6546 sli->maps[n].groups = mapWire->groups; 6547 sli->maps[n].which_mods = mapWire->whichMods; 6548 sli->maps[n].mods.mask = mapWire->mods; 6549 sli->maps[n].mods.real_mods = mapWire->realMods; 6550 sli->maps[n].mods.vmods = mapWire->virtualMods; 6551 sli->maps[n].ctrls = mapWire->ctrls; 6552 mapWire++; 6553 } 6554 } 6555 } 6556 if (changed & XkbXI_IndicatorStateMask) { 6557 statec = sli->effectiveState ^ ledWire->state; 6558 sli->explicitState &= ~statec; 6559 sli->explicitState |= (ledWire->state & statec); 6560 } 6561 if (namec) 6562 XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 6563 if (mapc) 6564 XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 6565 if (statec) 6566 XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 6567 6568 kbd = dev; 6569 if ((sli->flags & XkbSLI_HasOwnState) == 0) 6570 kbd = inputInfo.keyboard; 6571 6572 XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 6573 ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6574 } 6575 return (char *) ledWire; 6576} 6577 6578static int 6579_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 6580 xkbSetDeviceInfoReq * stuff) 6581{ 6582 char *wire; 6583 6584 wire = (char *) &stuff[1]; 6585 if (stuff->change & XkbXI_ButtonActionsMask) { 6586 if (!dev->button) { 6587 client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass); 6588 return XkbKeyboardErrorCode; 6589 } 6590 if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6591 client->errorValue = 6592 _XkbErrCode4(0x02, stuff->firstBtn, stuff->nBtns, 6593 dev->button->numButtons); 6594 return BadMatch; 6595 } 6596 wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc)); 6597 } 6598 if (stuff->change & XkbXI_IndicatorsMask) { 6599 int status = Success; 6600 6601 wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs, 6602 &status, client); 6603 if (status != Success) 6604 return status; 6605 } 6606 if (((wire - ((char *) stuff)) / 4) != stuff->length) 6607 return BadLength; 6608 6609 return Success; 6610} 6611 6612static int 6613_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 6614 xkbSetDeviceInfoReq * stuff) 6615{ 6616 char *wire; 6617 xkbExtensionDeviceNotify ed; 6618 6619 memset((char *) &ed, 0, SIZEOF(xkbExtensionDeviceNotify)); 6620 ed.deviceID = dev->id; 6621 wire = (char *) &stuff[1]; 6622 if (stuff->change & XkbXI_ButtonActionsMask) { 6623 int nBtns, sz, i; 6624 XkbAction *acts; 6625 DeviceIntPtr kbd; 6626 6627 nBtns = dev->button->numButtons; 6628 acts = dev->button->xkb_acts; 6629 if (acts == NULL) { 6630 acts = calloc(nBtns, sizeof(XkbAction)); 6631 if (!acts) 6632 return BadAlloc; 6633 dev->button->xkb_acts = acts; 6634 } 6635 sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); 6636 memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz); 6637 wire += sz; 6638 ed.reason |= XkbXI_ButtonActionsMask; 6639 ed.firstBtn = stuff->firstBtn; 6640 ed.nBtns = stuff->nBtns; 6641 6642 if (dev->key) 6643 kbd = dev; 6644 else 6645 kbd = inputInfo.keyboard; 6646 acts = &dev->button->xkb_acts[stuff->firstBtn]; 6647 for (i = 0; i < stuff->nBtns; i++, acts++) { 6648 if (acts->type != XkbSA_NoAction) 6649 XkbSetActionKeyMods(kbd->key->xkbInfo->desc, acts, 0); 6650 } 6651 } 6652 if (stuff->change & XkbXI_IndicatorsMask) { 6653 int status = Success; 6654 6655 wire = SetDeviceIndicators(wire, dev, stuff->change, 6656 stuff->nDeviceLedFBs, &status, client, &ed); 6657 if (status != Success) 6658 return status; 6659 } 6660 if ((stuff->change) && (ed.reason)) 6661 XkbSendExtensionDeviceNotify(dev, client, &ed); 6662 return Success; 6663} 6664 6665int 6666ProcXkbSetDeviceInfo(ClientPtr client) 6667{ 6668 DeviceIntPtr dev; 6669 int rc; 6670 6671 REQUEST(xkbSetDeviceInfoReq); 6672 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 6673 6674 if (!(client->xkbClientFlags & _XkbClientInitialized)) 6675 return BadAccess; 6676 6677 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 6678 CHK_MASK_LEGAL(0x01, stuff->change, XkbXI_AllFeaturesMask); 6679 6680 rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 6681 6682 if (rc != Success) 6683 return rc; 6684 6685 if (stuff->deviceSpec == XkbUseCoreKbd || 6686 stuff->deviceSpec == XkbUseCorePtr) { 6687 DeviceIntPtr other; 6688 6689 for (other = inputInfo.devices; other; other = other->next) { 6690 if (((other != dev) && !IsMaster(other) && 6691 GetMaster(other, MASTER_KEYBOARD) == dev) && 6692 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6693 (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6694 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6695 DixManageAccess); 6696 if (rc == Success) { 6697 rc = _XkbSetDeviceInfoCheck(client, other, stuff); 6698 if (rc != Success) 6699 return rc; 6700 } 6701 } 6702 } 6703 } 6704 6705 /* checks done, apply */ 6706 rc = _XkbSetDeviceInfo(client, dev, stuff); 6707 if (rc != Success) 6708 return rc; 6709 6710 if (stuff->deviceSpec == XkbUseCoreKbd || 6711 stuff->deviceSpec == XkbUseCorePtr) { 6712 DeviceIntPtr other; 6713 6714 for (other = inputInfo.devices; other; other = other->next) { 6715 if (((other != dev) && !IsMaster(other) && 6716 GetMaster(other, MASTER_KEYBOARD) == dev) && 6717 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6718 (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6719 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6720 DixManageAccess); 6721 if (rc == Success) { 6722 rc = _XkbSetDeviceInfo(client, other, stuff); 6723 if (rc != Success) 6724 return rc; 6725 } 6726 } 6727 } 6728 } 6729 6730 return Success; 6731} 6732 6733/***====================================================================***/ 6734 6735int 6736ProcXkbSetDebuggingFlags(ClientPtr client) 6737{ 6738 CARD32 newFlags, newCtrls, extraLength; 6739 xkbSetDebuggingFlagsReply rep; 6740 int rc; 6741 6742 REQUEST(xkbSetDebuggingFlagsReq); 6743 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 6744 6745 rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 6746 if (rc != Success) 6747 return rc; 6748 6749 newFlags = xkbDebugFlags & (~stuff->affectFlags); 6750 newFlags |= (stuff->flags & stuff->affectFlags); 6751 newCtrls = xkbDebugCtrls & (~stuff->affectCtrls); 6752 newCtrls |= (stuff->ctrls & stuff->affectCtrls); 6753 if (xkbDebugFlags || newFlags || stuff->msgLength) { 6754 ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n", 6755 (long) newFlags); 6756 if (newCtrls != xkbDebugCtrls) 6757 ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n", 6758 (long) newCtrls); 6759 } 6760 extraLength = (stuff->length << 2) - sz_xkbSetDebuggingFlagsReq; 6761 if (stuff->msgLength > 0) { 6762 char *msg; 6763 6764 if (extraLength < XkbPaddedSize(stuff->msgLength)) { 6765 ErrorF 6766 ("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 6767 stuff->msgLength, (long) extraLength, 6768 XkbPaddedSize(stuff->msgLength)); 6769 return BadLength; 6770 } 6771 msg = (char *) &stuff[1]; 6772 if (msg[stuff->msgLength - 1] != '\0') { 6773 ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 6774 return BadValue; 6775 } 6776 ErrorF("[xkb] XkbDebug: %s\n", msg); 6777 } 6778 xkbDebugFlags = newFlags; 6779 xkbDebugCtrls = newCtrls; 6780 6781 rep = (xkbSetDebuggingFlagsReply) { 6782 .type = X_Reply, 6783 .sequenceNumber = client->sequence, 6784 .length = 0, 6785 .currentFlags = newFlags, 6786 .currentCtrls = newCtrls, 6787 .supportedFlags = ~0, 6788 .supportedCtrls = ~0 6789 }; 6790 if (client->swapped) { 6791 swaps(&rep.sequenceNumber); 6792 swapl(&rep.currentFlags); 6793 swapl(&rep.currentCtrls); 6794 swapl(&rep.supportedFlags); 6795 swapl(&rep.supportedCtrls); 6796 } 6797 WriteToClient(client, SIZEOF(xkbSetDebuggingFlagsReply), &rep); 6798 return Success; 6799} 6800 6801/***====================================================================***/ 6802 6803static int 6804ProcXkbDispatch(ClientPtr client) 6805{ 6806 REQUEST(xReq); 6807 switch (stuff->data) { 6808 case X_kbUseExtension: 6809 return ProcXkbUseExtension(client); 6810 case X_kbSelectEvents: 6811 return ProcXkbSelectEvents(client); 6812 case X_kbBell: 6813 return ProcXkbBell(client); 6814 case X_kbGetState: 6815 return ProcXkbGetState(client); 6816 case X_kbLatchLockState: 6817 return ProcXkbLatchLockState(client); 6818 case X_kbGetControls: 6819 return ProcXkbGetControls(client); 6820 case X_kbSetControls: 6821 return ProcXkbSetControls(client); 6822 case X_kbGetMap: 6823 return ProcXkbGetMap(client); 6824 case X_kbSetMap: 6825 return ProcXkbSetMap(client); 6826 case X_kbGetCompatMap: 6827 return ProcXkbGetCompatMap(client); 6828 case X_kbSetCompatMap: 6829 return ProcXkbSetCompatMap(client); 6830 case X_kbGetIndicatorState: 6831 return ProcXkbGetIndicatorState(client); 6832 case X_kbGetIndicatorMap: 6833 return ProcXkbGetIndicatorMap(client); 6834 case X_kbSetIndicatorMap: 6835 return ProcXkbSetIndicatorMap(client); 6836 case X_kbGetNamedIndicator: 6837 return ProcXkbGetNamedIndicator(client); 6838 case X_kbSetNamedIndicator: 6839 return ProcXkbSetNamedIndicator(client); 6840 case X_kbGetNames: 6841 return ProcXkbGetNames(client); 6842 case X_kbSetNames: 6843 return ProcXkbSetNames(client); 6844 case X_kbGetGeometry: 6845 return ProcXkbGetGeometry(client); 6846 case X_kbSetGeometry: 6847 return ProcXkbSetGeometry(client); 6848 case X_kbPerClientFlags: 6849 return ProcXkbPerClientFlags(client); 6850 case X_kbListComponents: 6851 return ProcXkbListComponents(client); 6852 case X_kbGetKbdByName: 6853 return ProcXkbGetKbdByName(client); 6854 case X_kbGetDeviceInfo: 6855 return ProcXkbGetDeviceInfo(client); 6856 case X_kbSetDeviceInfo: 6857 return ProcXkbSetDeviceInfo(client); 6858 case X_kbSetDebuggingFlags: 6859 return ProcXkbSetDebuggingFlags(client); 6860 default: 6861 return BadRequest; 6862 } 6863} 6864 6865static int 6866XkbClientGone(void *data, XID id) 6867{ 6868 DevicePtr pXDev = (DevicePtr) data; 6869 6870 if (!XkbRemoveResourceClient(pXDev, id)) { 6871 ErrorF 6872 ("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 6873 } 6874 return 1; 6875} 6876 6877void 6878XkbExtensionInit(void) 6879{ 6880 ExtensionEntry *extEntry; 6881 6882 RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); 6883 if (!RT_XKBCLIENT) 6884 return; 6885 6886 if (!XkbInitPrivates()) 6887 return; 6888 6889 if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 6890 ProcXkbDispatch, SProcXkbDispatch, 6891 NULL, StandardMinorOpcode))) { 6892 XkbReqCode = (unsigned char) extEntry->base; 6893 XkbEventBase = (unsigned char) extEntry->eventBase; 6894 XkbErrorBase = (unsigned char) extEntry->errorBase; 6895 XkbKeyboardErrorCode = XkbErrorBase + XkbKeyboard; 6896 } 6897 return; 6898} 6899