xkb.c revision 7e31ba66
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 oldMap->kt_index[0] = wire->ktIndex[0]; 2114 oldMap->kt_index[1] = wire->ktIndex[1]; 2115 oldMap->kt_index[2] = wire->ktIndex[2]; 2116 oldMap->kt_index[3] = wire->ktIndex[3]; 2117 oldMap->group_info = wire->groupInfo; 2118 oldMap->width = wire->width; 2119 wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; 2120 } 2121 first = req->firstKeySym; 2122 last = first + req->nKeySyms - 1; 2123 if (changes->map.changed & XkbKeySymsMask) { 2124 int oldLast = 2125 (changes->map.first_key_sym + changes->map.num_key_syms - 1); 2126 if (changes->map.first_key_sym < first) 2127 first = changes->map.first_key_sym; 2128 if (oldLast > last) 2129 last = oldLast; 2130 } 2131 changes->map.changed |= XkbKeySymsMask; 2132 changes->map.first_key_sym = first; 2133 changes->map.num_key_syms = (last - first + 1); 2134 2135 s = 0; 2136 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 2137 if (XkbKeyNumGroups(xkb, i) > s) 2138 s = XkbKeyNumGroups(xkb, i); 2139 } 2140 if (s != xkb->ctrls->num_groups) { 2141 xkbControlsNotify cn; 2142 XkbControlsRec old; 2143 2144 cn.keycode = 0; 2145 cn.eventType = 0; 2146 cn.requestMajor = XkbReqCode; 2147 cn.requestMinor = X_kbSetMap; 2148 old = *xkb->ctrls; 2149 xkb->ctrls->num_groups = s; 2150 if (XkbComputeControlsNotify(dev, &old, xkb->ctrls, &cn, FALSE)) 2151 XkbSendControlsNotify(dev, &cn); 2152 } 2153 return (char *) wire; 2154} 2155 2156static char * 2157SetKeyActions(XkbDescPtr xkb, 2158 xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 2159{ 2160 register unsigned i, first, last; 2161 CARD8 *nActs = wire; 2162 XkbAction *newActs; 2163 2164 wire += XkbPaddedSize(req->nKeyActs); 2165 for (i = 0; i < req->nKeyActs; i++) { 2166 if (nActs[i] == 0) 2167 xkb->server->key_acts[i + req->firstKeyAct] = 0; 2168 else { 2169 newActs = XkbResizeKeyActions(xkb, i + req->firstKeyAct, nActs[i]); 2170 memcpy((char *) newActs, (char *) wire, 2171 nActs[i] * SIZEOF(xkbActionWireDesc)); 2172 wire += nActs[i] * SIZEOF(xkbActionWireDesc); 2173 } 2174 } 2175 first = req->firstKeyAct; 2176 last = (first + req->nKeyActs - 1); 2177 if (changes->map.changed & XkbKeyActionsMask) { 2178 int oldLast; 2179 2180 oldLast = changes->map.first_key_act + changes->map.num_key_acts - 1; 2181 if (changes->map.first_key_act < first) 2182 first = changes->map.first_key_act; 2183 if (oldLast > last) 2184 last = oldLast; 2185 } 2186 changes->map.changed |= XkbKeyActionsMask; 2187 changes->map.first_key_act = first; 2188 changes->map.num_key_acts = (last - first + 1); 2189 return (char *) wire; 2190} 2191 2192static char * 2193SetKeyBehaviors(XkbSrvInfoPtr xkbi, 2194 xkbSetMapReq * req, 2195 xkbBehaviorWireDesc * wire, XkbChangesPtr changes) 2196{ 2197 register unsigned i; 2198 int maxRG = -1; 2199 XkbDescPtr xkb = xkbi->desc; 2200 XkbServerMapPtr server = xkb->server; 2201 unsigned first, last; 2202 2203 first = req->firstKeyBehavior; 2204 last = req->firstKeyBehavior + req->nKeyBehaviors - 1; 2205 memset(&server->behaviors[first], 0, 2206 req->nKeyBehaviors * sizeof(XkbBehavior)); 2207 for (i = 0; i < req->totalKeyBehaviors; i++) { 2208 if ((server->behaviors[wire->key].type & XkbKB_Permanent) == 0) { 2209 server->behaviors[wire->key].type = wire->type; 2210 server->behaviors[wire->key].data = wire->data; 2211 if ((wire->type == XkbKB_RadioGroup) && 2212 (((int) wire->data) > maxRG)) 2213 maxRG = wire->data + 1; 2214 } 2215 wire++; 2216 } 2217 2218 if (maxRG > (int) xkbi->nRadioGroups) { 2219 if (xkbi->radioGroups) 2220 xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG, 2221 sizeof(XkbRadioGroupRec)); 2222 else 2223 xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec)); 2224 if (xkbi->radioGroups) { 2225 if (xkbi->nRadioGroups) 2226 memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0, 2227 (maxRG - xkbi->nRadioGroups) * sizeof(XkbRadioGroupRec)); 2228 xkbi->nRadioGroups = maxRG; 2229 } 2230 else 2231 xkbi->nRadioGroups = 0; 2232 /* should compute members here */ 2233 } 2234 if (changes->map.changed & XkbKeyBehaviorsMask) { 2235 unsigned oldLast; 2236 2237 oldLast = changes->map.first_key_behavior + 2238 changes->map.num_key_behaviors - 1; 2239 if (changes->map.first_key_behavior < req->firstKeyBehavior) 2240 first = changes->map.first_key_behavior; 2241 if (oldLast > last) 2242 last = oldLast; 2243 } 2244 changes->map.changed |= XkbKeyBehaviorsMask; 2245 changes->map.first_key_behavior = first; 2246 changes->map.num_key_behaviors = (last - first + 1); 2247 return (char *) wire; 2248} 2249 2250static char * 2251SetVirtualMods(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2252 XkbChangesPtr changes) 2253{ 2254 register int i, bit, nMods; 2255 XkbServerMapPtr srv = xkbi->desc->server; 2256 2257 if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) 2258 return (char *) wire; 2259 for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 2260 if (req->virtualMods & bit) { 2261 if (srv->vmods[i] != wire[nMods]) { 2262 changes->map.changed |= XkbVirtualModsMask; 2263 changes->map.vmods |= bit; 2264 srv->vmods[i] = wire[nMods]; 2265 } 2266 nMods++; 2267 } 2268 } 2269 return (char *) (wire + XkbPaddedSize(nMods)); 2270} 2271 2272static char * 2273SetKeyExplicit(XkbSrvInfoPtr xkbi, xkbSetMapReq * req, CARD8 *wire, 2274 XkbChangesPtr changes) 2275{ 2276 register unsigned i, first, last; 2277 XkbServerMapPtr xkb = xkbi->desc->server; 2278 CARD8 *start; 2279 2280 start = wire; 2281 first = req->firstKeyExplicit; 2282 last = req->firstKeyExplicit + req->nKeyExplicit - 1; 2283 memset(&xkb->explicit[first], 0, req->nKeyExplicit); 2284 for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { 2285 xkb->explicit[wire[0]] = wire[1]; 2286 } 2287 if (first > 0) { 2288 if (changes->map.changed & XkbExplicitComponentsMask) { 2289 int oldLast; 2290 2291 oldLast = changes->map.first_key_explicit + 2292 changes->map.num_key_explicit - 1; 2293 if (changes->map.first_key_explicit < first) 2294 first = changes->map.first_key_explicit; 2295 if (oldLast > last) 2296 last = oldLast; 2297 } 2298 changes->map.first_key_explicit = first; 2299 changes->map.num_key_explicit = (last - first) + 1; 2300 } 2301 wire += XkbPaddedSize(wire - start) - (wire - start); 2302 return (char *) wire; 2303} 2304 2305static char * 2306SetModifierMap(XkbSrvInfoPtr xkbi, 2307 xkbSetMapReq * req, CARD8 *wire, XkbChangesPtr changes) 2308{ 2309 register unsigned i, first, last; 2310 XkbClientMapPtr xkb = xkbi->desc->map; 2311 CARD8 *start; 2312 2313 start = wire; 2314 first = req->firstModMapKey; 2315 last = req->firstModMapKey + req->nModMapKeys - 1; 2316 memset(&xkb->modmap[first], 0, req->nModMapKeys); 2317 for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { 2318 xkb->modmap[wire[0]] = wire[1]; 2319 } 2320 if (first > 0) { 2321 if (changes->map.changed & XkbModifierMapMask) { 2322 int oldLast; 2323 2324 oldLast = changes->map.first_modmap_key + 2325 changes->map.num_modmap_keys - 1; 2326 if (changes->map.first_modmap_key < first) 2327 first = changes->map.first_modmap_key; 2328 if (oldLast > last) 2329 last = oldLast; 2330 } 2331 changes->map.first_modmap_key = first; 2332 changes->map.num_modmap_keys = (last - first) + 1; 2333 } 2334 wire += XkbPaddedSize(wire - start) - (wire - start); 2335 return (char *) wire; 2336} 2337 2338static char * 2339SetVirtualModMap(XkbSrvInfoPtr xkbi, 2340 xkbSetMapReq * req, 2341 xkbVModMapWireDesc * wire, XkbChangesPtr changes) 2342{ 2343 register unsigned i, first, last; 2344 XkbServerMapPtr srv = xkbi->desc->server; 2345 2346 first = req->firstVModMapKey; 2347 last = req->firstVModMapKey + req->nVModMapKeys - 1; 2348 memset(&srv->vmodmap[first], 0, req->nVModMapKeys * sizeof(unsigned short)); 2349 for (i = 0; i < req->totalVModMapKeys; i++, wire++) { 2350 srv->vmodmap[wire->key] = wire->vmods; 2351 } 2352 if (first > 0) { 2353 if (changes->map.changed & XkbVirtualModMapMask) { 2354 int oldLast; 2355 2356 oldLast = changes->map.first_vmodmap_key + 2357 changes->map.num_vmodmap_keys - 1; 2358 if (changes->map.first_vmodmap_key < first) 2359 first = changes->map.first_vmodmap_key; 2360 if (oldLast > last) 2361 last = oldLast; 2362 } 2363 changes->map.first_vmodmap_key = first; 2364 changes->map.num_vmodmap_keys = (last - first) + 1; 2365 } 2366 return (char *) wire; 2367} 2368 2369/** 2370 * Check if the given request can be applied to the given device but don't 2371 * actually do anything.. 2372 */ 2373static int 2374_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, 2375 char *values) 2376{ 2377 XkbSrvInfoPtr xkbi; 2378 XkbDescPtr xkb; 2379 int error; 2380 int nTypes = 0, nActions; 2381 CARD8 mapWidths[XkbMaxLegalKeyCode + 1] = { 0 }; 2382 CARD16 symsPerKey[XkbMaxLegalKeyCode + 1] = { 0 }; 2383 XkbSymMapPtr map; 2384 int i; 2385 2386 xkbi = dev->key->xkbInfo; 2387 xkb = xkbi->desc; 2388 2389 if ((xkb->min_key_code != req->minKeyCode) || 2390 (xkb->max_key_code != req->maxKeyCode)) { 2391 if (client->xkbClientFlags & _XkbClientIsAncient) { 2392 /* pre 1.0 versions of Xlib have a bug */ 2393 req->minKeyCode = xkb->min_key_code; 2394 req->maxKeyCode = xkb->max_key_code; 2395 } 2396 else { 2397 if (!XkbIsLegalKeycode(req->minKeyCode)) { 2398 client->errorValue = 2399 _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); 2400 return BadValue; 2401 } 2402 if (req->minKeyCode > req->maxKeyCode) { 2403 client->errorValue = 2404 _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); 2405 return BadMatch; 2406 } 2407 } 2408 } 2409 2410 if ((req->present & XkbKeyTypesMask) && 2411 (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values, 2412 &nTypes, mapWidths))) { 2413 client->errorValue = nTypes; 2414 return BadValue; 2415 } 2416 2417 /* symsPerKey/mapWidths must be filled regardless of client-side flags */ 2418 map = &xkb->map->key_sym_map[xkb->min_key_code]; 2419 for (i = xkb->min_key_code; i < xkb->max_key_code; i++, map++) { 2420 register int g, ng, w; 2421 2422 ng = XkbNumGroups(map->group_info); 2423 for (w = g = 0; g < ng; g++) { 2424 if (map->kt_index[g] >= (unsigned) nTypes) { 2425 client->errorValue = _XkbErrCode4(0x13, i, g, map->kt_index[g]); 2426 return 0; 2427 } 2428 if (mapWidths[map->kt_index[g]] > w) 2429 w = mapWidths[map->kt_index[g]]; 2430 } 2431 symsPerKey[i] = w * ng; 2432 } 2433 2434 if ((req->present & XkbKeySymsMask) && 2435 (!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey, 2436 (xkbSymMapWireDesc **) &values, &error))) { 2437 client->errorValue = error; 2438 return BadValue; 2439 } 2440 2441 if ((req->present & XkbKeyActionsMask) && 2442 (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey, 2443 (CARD8 **) &values, &nActions))) { 2444 client->errorValue = nActions; 2445 return BadValue; 2446 } 2447 2448 if ((req->present & XkbKeyBehaviorsMask) && 2449 (!CheckKeyBehaviors 2450 (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) { 2451 client->errorValue = error; 2452 return BadValue; 2453 } 2454 2455 if ((req->present & XkbVirtualModsMask) && 2456 (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) { 2457 client->errorValue = error; 2458 return BadValue; 2459 } 2460 if ((req->present & XkbExplicitComponentsMask) && 2461 (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) { 2462 client->errorValue = error; 2463 return BadValue; 2464 } 2465 if ((req->present & XkbModifierMapMask) && 2466 (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) { 2467 client->errorValue = error; 2468 return BadValue; 2469 } 2470 if ((req->present & XkbVirtualModMapMask) && 2471 (!CheckVirtualModMap 2472 (xkb, req, (xkbVModMapWireDesc **) &values, &error))) { 2473 client->errorValue = error; 2474 return BadValue; 2475 } 2476 2477 if (((values - ((char *) req)) / 4) != req->length) { 2478 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); 2479 client->errorValue = values - ((char *) &req[1]); 2480 return BadLength; 2481 } 2482 2483 return Success; 2484} 2485 2486/** 2487 * Apply the given request on the given device. 2488 */ 2489static int 2490_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values) 2491{ 2492 XkbEventCauseRec cause; 2493 XkbChangesRec change; 2494 Bool sentNKN; 2495 XkbSrvInfoPtr xkbi; 2496 XkbDescPtr xkb; 2497 2498 xkbi = dev->key->xkbInfo; 2499 xkb = xkbi->desc; 2500 2501 XkbSetCauseXkbReq(&cause, X_kbSetMap, client); 2502 memset(&change, 0, sizeof(change)); 2503 sentNKN = FALSE; 2504 if ((xkb->min_key_code != req->minKeyCode) || 2505 (xkb->max_key_code != req->maxKeyCode)) { 2506 Status status; 2507 xkbNewKeyboardNotify nkn; 2508 2509 nkn.deviceID = nkn.oldDeviceID = dev->id; 2510 nkn.oldMinKeyCode = xkb->min_key_code; 2511 nkn.oldMaxKeyCode = xkb->max_key_code; 2512 status = XkbChangeKeycodeRange(xkb, req->minKeyCode, 2513 req->maxKeyCode, &change); 2514 if (status != Success) 2515 return status; /* oh-oh. what about the other keyboards? */ 2516 nkn.minKeyCode = xkb->min_key_code; 2517 nkn.maxKeyCode = xkb->max_key_code; 2518 nkn.requestMajor = XkbReqCode; 2519 nkn.requestMinor = X_kbSetMap; 2520 nkn.changed = XkbNKN_KeycodesMask; 2521 XkbSendNewKeyboardNotify(dev, &nkn); 2522 sentNKN = TRUE; 2523 } 2524 2525 if (req->present & XkbKeyTypesMask) { 2526 values = SetKeyTypes(xkb, req, (xkbKeyTypeWireDesc *) values, &change); 2527 if (!values) 2528 goto allocFailure; 2529 } 2530 if (req->present & XkbKeySymsMask) { 2531 values = 2532 SetKeySyms(client, xkb, req, (xkbSymMapWireDesc *) values, &change, 2533 dev); 2534 if (!values) 2535 goto allocFailure; 2536 } 2537 if (req->present & XkbKeyActionsMask) { 2538 values = SetKeyActions(xkb, req, (CARD8 *) values, &change); 2539 if (!values) 2540 goto allocFailure; 2541 } 2542 if (req->present & XkbKeyBehaviorsMask) { 2543 values = 2544 SetKeyBehaviors(xkbi, req, (xkbBehaviorWireDesc *) values, &change); 2545 if (!values) 2546 goto allocFailure; 2547 } 2548 if (req->present & XkbVirtualModsMask) 2549 values = SetVirtualMods(xkbi, req, (CARD8 *) values, &change); 2550 if (req->present & XkbExplicitComponentsMask) 2551 values = SetKeyExplicit(xkbi, req, (CARD8 *) values, &change); 2552 if (req->present & XkbModifierMapMask) 2553 values = SetModifierMap(xkbi, req, (CARD8 *) values, &change); 2554 if (req->present & XkbVirtualModMapMask) 2555 values = 2556 SetVirtualModMap(xkbi, req, (xkbVModMapWireDesc *) values, &change); 2557 if (((values - ((char *) req)) / 4) != req->length) { 2558 ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); 2559 client->errorValue = values - ((char *) &req[1]); 2560 return BadLength; 2561 } 2562 if (req->flags & XkbSetMapRecomputeActions) { 2563 KeyCode first, last, firstMM, lastMM; 2564 2565 if (change.map.num_key_syms > 0) { 2566 first = change.map.first_key_sym; 2567 last = first + change.map.num_key_syms - 1; 2568 } 2569 else 2570 first = last = 0; 2571 if (change.map.num_modmap_keys > 0) { 2572 firstMM = change.map.first_modmap_key; 2573 lastMM = firstMM + change.map.num_modmap_keys - 1; 2574 } 2575 else 2576 firstMM = lastMM = 0; 2577 if ((last > 0) && (lastMM > 0)) { 2578 if (firstMM < first) 2579 first = firstMM; 2580 if (lastMM > last) 2581 last = lastMM; 2582 } 2583 else if (lastMM > 0) { 2584 first = firstMM; 2585 last = lastMM; 2586 } 2587 if (last > 0) { 2588 unsigned check = 0; 2589 2590 XkbUpdateActions(dev, first, (last - first + 1), &change, &check, 2591 &cause); 2592 if (check) 2593 XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 2594 } 2595 } 2596 if (!sentNKN) 2597 XkbSendNotification(dev, &change, &cause); 2598 2599 return Success; 2600 allocFailure: 2601 return BadAlloc; 2602} 2603 2604int 2605ProcXkbSetMap(ClientPtr client) 2606{ 2607 DeviceIntPtr dev; 2608 char *tmp; 2609 int rc; 2610 2611 REQUEST(xkbSetMapReq); 2612 REQUEST_AT_LEAST_SIZE(xkbSetMapReq); 2613 2614 if (!(client->xkbClientFlags & _XkbClientInitialized)) 2615 return BadAccess; 2616 2617 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 2618 CHK_MASK_LEGAL(0x01, stuff->present, XkbAllMapComponentsMask); 2619 2620 tmp = (char *) &stuff[1]; 2621 2622 /* Check if we can to the SetMap on the requested device. If this 2623 succeeds, do the same thing for all extension devices (if needed). 2624 If any of them fails, fail. */ 2625 rc = _XkbSetMapChecks(client, dev, stuff, tmp); 2626 2627 if (rc != Success) 2628 return rc; 2629 2630 DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); 2631 2632 if (stuff->deviceSpec == XkbUseCoreKbd) { 2633 DeviceIntPtr other; 2634 2635 for (other = inputInfo.devices; other; other = other->next) { 2636 if ((other != dev) && other->key && !IsMaster(other) && 2637 GetMaster(other, MASTER_KEYBOARD) == dev) { 2638 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2639 DixManageAccess); 2640 if (rc == Success) { 2641 rc = _XkbSetMapChecks(client, other, stuff, tmp); 2642 if (rc != Success) 2643 return rc; 2644 } 2645 } 2646 } 2647 } else { 2648 DeviceIntPtr other; 2649 2650 for (other = inputInfo.devices; other; other = other->next) { 2651 if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 2652 (other != master || dev != master->lastSlave)) 2653 continue; 2654 2655 rc = _XkbSetMapChecks(client, other, stuff, tmp); 2656 if (rc != Success) 2657 return rc; 2658 } 2659 } 2660 2661 /* We know now that we will succeed with the SetMap. In theory anyway. */ 2662 rc = _XkbSetMap(client, dev, stuff, tmp); 2663 if (rc != Success) 2664 return rc; 2665 2666 if (stuff->deviceSpec == XkbUseCoreKbd) { 2667 DeviceIntPtr other; 2668 2669 for (other = inputInfo.devices; other; other = other->next) { 2670 if ((other != dev) && other->key && !IsMaster(other) && 2671 GetMaster(other, MASTER_KEYBOARD) == dev) { 2672 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 2673 DixManageAccess); 2674 if (rc == Success) 2675 _XkbSetMap(client, other, stuff, tmp); 2676 /* ignore rc. if the SetMap failed although the check above 2677 reported true there isn't much we can do. we still need to 2678 set all other devices, hoping that at least they stay in 2679 sync. */ 2680 } 2681 } 2682 } else { 2683 DeviceIntPtr other; 2684 2685 for (other = inputInfo.devices; other; other = other->next) { 2686 if (other != dev && GetMaster(other, MASTER_KEYBOARD) != dev && 2687 (other != master || dev != master->lastSlave)) 2688 continue; 2689 2690 _XkbSetMap(client, other, stuff, tmp); //ignore rc 2691 } 2692 } 2693 2694 return Success; 2695} 2696 2697/***====================================================================***/ 2698 2699static Status 2700XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat, 2701 xkbGetCompatMapReply * rep) 2702{ 2703 unsigned size, nGroups; 2704 2705 nGroups = 0; 2706 if (rep->groups != 0) { 2707 register int i, bit; 2708 2709 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2710 if (rep->groups & bit) 2711 nGroups++; 2712 } 2713 } 2714 size = nGroups * SIZEOF(xkbModsWireDesc); 2715 size += (rep->nSI * SIZEOF(xkbSymInterpretWireDesc)); 2716 rep->length = size / 4; 2717 return Success; 2718} 2719 2720static int 2721XkbSendCompatMap(ClientPtr client, 2722 XkbCompatMapPtr compat, xkbGetCompatMapReply * rep) 2723{ 2724 char *data; 2725 int size; 2726 2727 if (rep->length > 0) { 2728 data = xallocarray(rep->length, 4); 2729 if (data) { 2730 register unsigned i, bit; 2731 xkbModsWireDesc *grp; 2732 XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI]; 2733 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2734 2735 size = rep->length * 4; 2736 2737 for (i = 0; i < rep->nSI; i++, sym++, wire++) { 2738 wire->sym = sym->sym; 2739 wire->mods = sym->mods; 2740 wire->match = sym->match; 2741 wire->virtualMod = sym->virtual_mod; 2742 wire->flags = sym->flags; 2743 memcpy((char *) &wire->act, (char *) &sym->act, 2744 sz_xkbActionWireDesc); 2745 if (client->swapped) { 2746 swapl(&wire->sym); 2747 } 2748 } 2749 if (rep->groups) { 2750 grp = (xkbModsWireDesc *) wire; 2751 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2752 if (rep->groups & bit) { 2753 grp->mask = compat->groups[i].mask; 2754 grp->realMods = compat->groups[i].real_mods; 2755 grp->virtualMods = compat->groups[i].vmods; 2756 if (client->swapped) { 2757 swaps(&grp->virtualMods); 2758 } 2759 grp++; 2760 } 2761 } 2762 wire = (xkbSymInterpretWireDesc *) grp; 2763 } 2764 } 2765 else 2766 return BadAlloc; 2767 } 2768 else 2769 data = NULL; 2770 2771 if (client->swapped) { 2772 swaps(&rep->sequenceNumber); 2773 swapl(&rep->length); 2774 swaps(&rep->firstSI); 2775 swaps(&rep->nSI); 2776 swaps(&rep->nTotalSI); 2777 } 2778 2779 WriteToClient(client, SIZEOF(xkbGetCompatMapReply), rep); 2780 if (data) { 2781 WriteToClient(client, size, data); 2782 free((char *) data); 2783 } 2784 return Success; 2785} 2786 2787int 2788ProcXkbGetCompatMap(ClientPtr client) 2789{ 2790 xkbGetCompatMapReply rep; 2791 DeviceIntPtr dev; 2792 XkbDescPtr xkb; 2793 XkbCompatMapPtr compat; 2794 2795 REQUEST(xkbGetCompatMapReq); 2796 REQUEST_SIZE_MATCH(xkbGetCompatMapReq); 2797 2798 if (!(client->xkbClientFlags & _XkbClientInitialized)) 2799 return BadAccess; 2800 2801 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 2802 2803 xkb = dev->key->xkbInfo->desc; 2804 compat = xkb->compat; 2805 2806 rep = (xkbGetCompatMapReply) { 2807 .type = X_Reply, 2808 .sequenceNumber = client->sequence, 2809 .length = 0, 2810 .deviceID = dev->id, 2811 .firstSI = stuff->firstSI, 2812 .nSI = stuff->nSI 2813 }; 2814 if (stuff->getAllSI) { 2815 rep.firstSI = 0; 2816 rep.nSI = compat->num_si; 2817 } 2818 else if ((((unsigned) stuff->nSI) > 0) && 2819 ((unsigned) (stuff->firstSI + stuff->nSI - 1) >= compat->num_si)) { 2820 client->errorValue = _XkbErrCode2(0x05, compat->num_si); 2821 return BadValue; 2822 } 2823 rep.nTotalSI = compat->num_si; 2824 rep.groups = stuff->groups; 2825 XkbComputeGetCompatMapReplySize(compat, &rep); 2826 return XkbSendCompatMap(client, compat, &rep); 2827} 2828 2829/** 2830 * Apply the given request on the given device. 2831 * If dryRun is TRUE, then value checks are performed, but the device isn't 2832 * modified. 2833 */ 2834static int 2835_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, 2836 xkbSetCompatMapReq * req, char *data, BOOL dryRun) 2837{ 2838 XkbSrvInfoPtr xkbi; 2839 XkbDescPtr xkb; 2840 XkbCompatMapPtr compat; 2841 int nGroups; 2842 unsigned i, bit; 2843 2844 xkbi = dev->key->xkbInfo; 2845 xkb = xkbi->desc; 2846 compat = xkb->compat; 2847 2848 if ((req->nSI > 0) || (req->truncateSI)) { 2849 xkbSymInterpretWireDesc *wire; 2850 2851 if (req->firstSI > compat->num_si) { 2852 client->errorValue = _XkbErrCode2(0x02, compat->num_si); 2853 return BadValue; 2854 } 2855 wire = (xkbSymInterpretWireDesc *) data; 2856 wire += req->nSI; 2857 data = (char *) wire; 2858 } 2859 2860 nGroups = 0; 2861 if (req->groups != 0) { 2862 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2863 if (req->groups & bit) 2864 nGroups++; 2865 } 2866 } 2867 data += nGroups * SIZEOF(xkbModsWireDesc); 2868 if (((data - ((char *) req)) / 4) != req->length) { 2869 return BadLength; 2870 } 2871 2872 /* Done all the checks we can do */ 2873 if (dryRun) 2874 return Success; 2875 2876 data = (char *) &req[1]; 2877 if (req->nSI > 0) { 2878 xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; 2879 XkbSymInterpretPtr sym; 2880 unsigned int skipped = 0; 2881 2882 if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) { 2883 compat->num_si = req->firstSI + req->nSI; 2884 compat->sym_interpret = reallocarray(compat->sym_interpret, 2885 compat->num_si, 2886 sizeof(XkbSymInterpretRec)); 2887 if (!compat->sym_interpret) { 2888 compat->num_si = 0; 2889 return BadAlloc; 2890 } 2891 } 2892 else if (req->truncateSI) { 2893 compat->num_si = req->firstSI + req->nSI; 2894 } 2895 sym = &compat->sym_interpret[req->firstSI]; 2896 for (i = 0; i < req->nSI; i++, wire++) { 2897 if (client->swapped) { 2898 swapl(&wire->sym); 2899 } 2900 if (wire->sym == NoSymbol && wire->match == XkbSI_AnyOfOrNone && 2901 (wire->mods & 0xff) == 0xff && 2902 wire->act.type == XkbSA_XFree86Private) { 2903 ErrorF("XKB: Skipping broken Any+AnyOfOrNone(All) -> Private " 2904 "action from client\n"); 2905 skipped++; 2906 continue; 2907 } 2908 sym->sym = wire->sym; 2909 sym->mods = wire->mods; 2910 sym->match = wire->match; 2911 sym->flags = wire->flags; 2912 sym->virtual_mod = wire->virtualMod; 2913 memcpy((char *) &sym->act, (char *) &wire->act, 2914 SIZEOF(xkbActionWireDesc)); 2915 sym++; 2916 } 2917 if (skipped) { 2918 if (req->firstSI + req->nSI < compat->num_si) 2919 memmove(sym, sym + skipped, 2920 (compat->num_si - req->firstSI - req->nSI) * 2921 sizeof(*sym)); 2922 compat->num_si -= skipped; 2923 } 2924 data = (char *) wire; 2925 } 2926 else if (req->truncateSI) { 2927 compat->num_si = req->firstSI; 2928 } 2929 2930 if (req->groups != 0) { 2931 xkbModsWireDesc *wire = (xkbModsWireDesc *) data; 2932 2933 for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 2934 if (req->groups & bit) { 2935 if (client->swapped) { 2936 swaps(&wire->virtualMods); 2937 } 2938 compat->groups[i].mask = wire->realMods; 2939 compat->groups[i].real_mods = wire->realMods; 2940 compat->groups[i].vmods = wire->virtualMods; 2941 if (wire->virtualMods != 0) { 2942 unsigned tmp; 2943 2944 tmp = XkbMaskForVMask(xkb, wire->virtualMods); 2945 compat->groups[i].mask |= tmp; 2946 } 2947 data += SIZEOF(xkbModsWireDesc); 2948 wire = (xkbModsWireDesc *) data; 2949 } 2950 } 2951 } 2952 i = XkbPaddedSize((data - ((char *) req))); 2953 if ((i / 4) != req->length) { 2954 ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); 2955 return BadLength; 2956 } 2957 2958 if (dev->xkb_interest) { 2959 xkbCompatMapNotify ev; 2960 2961 ev.deviceID = dev->id; 2962 ev.changedGroups = req->groups; 2963 ev.firstSI = req->firstSI; 2964 ev.nSI = req->nSI; 2965 ev.nTotalSI = compat->num_si; 2966 XkbSendCompatMapNotify(dev, &ev); 2967 } 2968 2969 if (req->recomputeActions) { 2970 XkbChangesRec change; 2971 unsigned check; 2972 XkbEventCauseRec cause; 2973 2974 XkbSetCauseXkbReq(&cause, X_kbSetCompatMap, client); 2975 memset(&change, 0, sizeof(XkbChangesRec)); 2976 XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &change, 2977 &check, &cause); 2978 if (check) 2979 XkbCheckSecondaryEffects(xkbi, check, &change, &cause); 2980 XkbSendNotification(dev, &change, &cause); 2981 } 2982 return Success; 2983} 2984 2985int 2986ProcXkbSetCompatMap(ClientPtr client) 2987{ 2988 DeviceIntPtr dev; 2989 char *data; 2990 int rc; 2991 2992 REQUEST(xkbSetCompatMapReq); 2993 REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); 2994 2995 if (!(client->xkbClientFlags & _XkbClientInitialized)) 2996 return BadAccess; 2997 2998 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 2999 3000 data = (char *) &stuff[1]; 3001 3002 /* check first using a dry-run */ 3003 rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); 3004 if (rc != Success) 3005 return rc; 3006 if (stuff->deviceSpec == XkbUseCoreKbd) { 3007 DeviceIntPtr other; 3008 3009 for (other = inputInfo.devices; other; other = other->next) { 3010 if ((other != dev) && other->key && !IsMaster(other) && 3011 GetMaster(other, MASTER_KEYBOARD) == dev) { 3012 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3013 DixManageAccess); 3014 if (rc == Success) { 3015 /* dry-run */ 3016 rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); 3017 if (rc != Success) 3018 return rc; 3019 } 3020 } 3021 } 3022 } 3023 3024 /* Yay, the dry-runs succeed. Let's apply */ 3025 rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); 3026 if (rc != Success) 3027 return rc; 3028 if (stuff->deviceSpec == XkbUseCoreKbd) { 3029 DeviceIntPtr other; 3030 3031 for (other = inputInfo.devices; other; other = other->next) { 3032 if ((other != dev) && other->key && !IsMaster(other) && 3033 GetMaster(other, MASTER_KEYBOARD) == dev) { 3034 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3035 DixManageAccess); 3036 if (rc == Success) { 3037 rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); 3038 if (rc != Success) 3039 return rc; 3040 } 3041 } 3042 } 3043 } 3044 3045 return Success; 3046} 3047 3048/***====================================================================***/ 3049 3050int 3051ProcXkbGetIndicatorState(ClientPtr client) 3052{ 3053 xkbGetIndicatorStateReply rep; 3054 XkbSrvLedInfoPtr sli; 3055 DeviceIntPtr dev; 3056 3057 REQUEST(xkbGetIndicatorStateReq); 3058 REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); 3059 3060 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3061 return BadAccess; 3062 3063 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 3064 3065 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3066 XkbXI_IndicatorStateMask); 3067 if (!sli) 3068 return BadAlloc; 3069 3070 rep = (xkbGetIndicatorStateReply) { 3071 .type = X_Reply, 3072 .deviceID = dev->id, 3073 .sequenceNumber = client->sequence, 3074 .length = 0, 3075 .state = sli->effectiveState 3076 }; 3077 3078 if (client->swapped) { 3079 swaps(&rep.sequenceNumber); 3080 swapl(&rep.state); 3081 } 3082 WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), &rep); 3083 return Success; 3084} 3085 3086/***====================================================================***/ 3087 3088static Status 3089XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators, 3090 xkbGetIndicatorMapReply * rep) 3091{ 3092 register int i, bit; 3093 int nIndicators; 3094 3095 rep->realIndicators = indicators->phys_indicators; 3096 for (i = nIndicators = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3097 if (rep->which & bit) 3098 nIndicators++; 3099 } 3100 rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4; 3101 rep->nIndicators = nIndicators; 3102 return Success; 3103} 3104 3105static int 3106XkbSendIndicatorMap(ClientPtr client, 3107 XkbIndicatorPtr indicators, xkbGetIndicatorMapReply * rep) 3108{ 3109 int length; 3110 CARD8 *map; 3111 register int i; 3112 register unsigned bit; 3113 3114 if (rep->length > 0) { 3115 CARD8 *to; 3116 3117 to = map = xallocarray(rep->length, 4); 3118 if (map) { 3119 xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to; 3120 3121 length = rep->length * 4; 3122 3123 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3124 if (rep->which & bit) { 3125 wire->flags = indicators->maps[i].flags; 3126 wire->whichGroups = indicators->maps[i].which_groups; 3127 wire->groups = indicators->maps[i].groups; 3128 wire->whichMods = indicators->maps[i].which_mods; 3129 wire->mods = indicators->maps[i].mods.mask; 3130 wire->realMods = indicators->maps[i].mods.real_mods; 3131 wire->virtualMods = indicators->maps[i].mods.vmods; 3132 wire->ctrls = indicators->maps[i].ctrls; 3133 if (client->swapped) { 3134 swaps(&wire->virtualMods); 3135 swapl(&wire->ctrls); 3136 } 3137 wire++; 3138 } 3139 } 3140 to = (CARD8 *) wire; 3141 if ((to - map) != length) { 3142 client->errorValue = _XkbErrCode2(0xff, length); 3143 free(map); 3144 return BadLength; 3145 } 3146 } 3147 else 3148 return BadAlloc; 3149 } 3150 else 3151 map = NULL; 3152 if (client->swapped) { 3153 swaps(&rep->sequenceNumber); 3154 swapl(&rep->length); 3155 swapl(&rep->which); 3156 swapl(&rep->realIndicators); 3157 } 3158 WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), rep); 3159 if (map) { 3160 WriteToClient(client, length, map); 3161 free((char *) map); 3162 } 3163 return Success; 3164} 3165 3166int 3167ProcXkbGetIndicatorMap(ClientPtr client) 3168{ 3169 xkbGetIndicatorMapReply rep; 3170 DeviceIntPtr dev; 3171 XkbDescPtr xkb; 3172 XkbIndicatorPtr leds; 3173 3174 REQUEST(xkbGetIndicatorMapReq); 3175 REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); 3176 3177 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3178 return BadAccess; 3179 3180 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 3181 3182 xkb = dev->key->xkbInfo->desc; 3183 leds = xkb->indicators; 3184 3185 rep = (xkbGetIndicatorMapReply) { 3186 .type = X_Reply, 3187 .deviceID = dev->id, 3188 .sequenceNumber = client->sequence, 3189 .length = 0, 3190 .which = stuff->which 3191 }; 3192 XkbComputeGetIndicatorMapReplySize(leds, &rep); 3193 return XkbSendIndicatorMap(client, leds, &rep); 3194} 3195 3196/** 3197 * Apply the given map to the given device. Which specifies which components 3198 * to apply. 3199 */ 3200static int 3201_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, 3202 int which, xkbIndicatorMapWireDesc * desc) 3203{ 3204 XkbSrvInfoPtr xkbi; 3205 XkbSrvLedInfoPtr sli; 3206 XkbEventCauseRec cause; 3207 int i, bit; 3208 3209 xkbi = dev->key->xkbInfo; 3210 3211 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 3212 XkbXI_IndicatorMapsMask); 3213 if (!sli) 3214 return BadAlloc; 3215 3216 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3217 if (which & bit) { 3218 sli->maps[i].flags = desc->flags; 3219 sli->maps[i].which_groups = desc->whichGroups; 3220 sli->maps[i].groups = desc->groups; 3221 sli->maps[i].which_mods = desc->whichMods; 3222 sli->maps[i].mods.mask = desc->mods; 3223 sli->maps[i].mods.real_mods = desc->mods; 3224 sli->maps[i].mods.vmods = desc->virtualMods; 3225 sli->maps[i].ctrls = desc->ctrls; 3226 if (desc->virtualMods != 0) { 3227 unsigned tmp; 3228 3229 tmp = XkbMaskForVMask(xkbi->desc, desc->virtualMods); 3230 sli->maps[i].mods.mask = desc->mods | tmp; 3231 } 3232 desc++; 3233 } 3234 } 3235 3236 XkbSetCauseXkbReq(&cause, X_kbSetIndicatorMap, client); 3237 XkbApplyLedMapChanges(dev, sli, which, NULL, NULL, &cause); 3238 3239 return Success; 3240} 3241 3242int 3243ProcXkbSetIndicatorMap(ClientPtr client) 3244{ 3245 int i, bit; 3246 int nIndicators; 3247 DeviceIntPtr dev; 3248 xkbIndicatorMapWireDesc *from; 3249 int rc; 3250 3251 REQUEST(xkbSetIndicatorMapReq); 3252 REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); 3253 3254 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3255 return BadAccess; 3256 3257 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 3258 3259 if (stuff->which == 0) 3260 return Success; 3261 3262 for (nIndicators = i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3263 if (stuff->which & bit) 3264 nIndicators++; 3265 } 3266 if (stuff->length != ((SIZEOF(xkbSetIndicatorMapReq) + 3267 (nIndicators * SIZEOF(xkbIndicatorMapWireDesc))) / 3268 4)) { 3269 return BadLength; 3270 } 3271 3272 from = (xkbIndicatorMapWireDesc *) &stuff[1]; 3273 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 3274 if (stuff->which & bit) { 3275 if (client->swapped) { 3276 swaps(&from->virtualMods); 3277 swapl(&from->ctrls); 3278 } 3279 CHK_MASK_LEGAL(i, from->whichGroups, XkbIM_UseAnyGroup); 3280 CHK_MASK_LEGAL(i, from->whichMods, XkbIM_UseAnyMods); 3281 from++; 3282 } 3283 } 3284 3285 from = (xkbIndicatorMapWireDesc *) &stuff[1]; 3286 rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); 3287 if (rc != Success) 3288 return rc; 3289 3290 if (stuff->deviceSpec == XkbUseCoreKbd) { 3291 DeviceIntPtr other; 3292 3293 for (other = inputInfo.devices; other; other = other->next) { 3294 if ((other != dev) && other->key && !IsMaster(other) && 3295 GetMaster(other, MASTER_KEYBOARD) == dev) { 3296 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 3297 DixSetAttrAccess); 3298 if (rc == Success) 3299 _XkbSetIndicatorMap(client, other, stuff->which, from); 3300 } 3301 } 3302 } 3303 3304 return Success; 3305} 3306 3307/***====================================================================***/ 3308 3309int 3310ProcXkbGetNamedIndicator(ClientPtr client) 3311{ 3312 DeviceIntPtr dev; 3313 xkbGetNamedIndicatorReply rep; 3314 register int i = 0; 3315 XkbSrvLedInfoPtr sli; 3316 XkbIndicatorMapPtr map = NULL; 3317 3318 REQUEST(xkbGetNamedIndicatorReq); 3319 REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); 3320 3321 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3322 return BadAccess; 3323 3324 CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); 3325 CHK_ATOM_ONLY(stuff->indicator); 3326 3327 sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 0); 3328 if (!sli) 3329 return BadAlloc; 3330 3331 i = 0; 3332 map = NULL; 3333 if ((sli->names) && (sli->maps)) { 3334 for (i = 0; i < XkbNumIndicators; i++) { 3335 if (stuff->indicator == sli->names[i]) { 3336 map = &sli->maps[i]; 3337 break; 3338 } 3339 } 3340 } 3341 3342 rep = (xkbGetNamedIndicatorReply) { 3343 .type = X_Reply, 3344 .sequenceNumber = client->sequence, 3345 .length = 0, 3346 .deviceID = dev->id, 3347 .indicator = stuff->indicator 3348 }; 3349 if (map != NULL) { 3350 rep.found = TRUE; 3351 rep.on = ((sli->effectiveState & (1 << i)) != 0); 3352 rep.realIndicator = ((sli->physIndicators & (1 << i)) != 0); 3353 rep.ndx = i; 3354 rep.flags = map->flags; 3355 rep.whichGroups = map->which_groups; 3356 rep.groups = map->groups; 3357 rep.whichMods = map->which_mods; 3358 rep.mods = map->mods.mask; 3359 rep.realMods = map->mods.real_mods; 3360 rep.virtualMods = map->mods.vmods; 3361 rep.ctrls = map->ctrls; 3362 rep.supported = TRUE; 3363 } 3364 else { 3365 rep.found = FALSE; 3366 rep.on = FALSE; 3367 rep.realIndicator = FALSE; 3368 rep.ndx = XkbNoIndicator; 3369 rep.flags = 0; 3370 rep.whichGroups = 0; 3371 rep.groups = 0; 3372 rep.whichMods = 0; 3373 rep.mods = 0; 3374 rep.realMods = 0; 3375 rep.virtualMods = 0; 3376 rep.ctrls = 0; 3377 rep.supported = TRUE; 3378 } 3379 if (client->swapped) { 3380 swapl(&rep.length); 3381 swaps(&rep.sequenceNumber); 3382 swapl(&rep.indicator); 3383 swaps(&rep.virtualMods); 3384 swapl(&rep.ctrls); 3385 } 3386 3387 WriteToClient(client, SIZEOF(xkbGetNamedIndicatorReply), &rep); 3388 return Success; 3389} 3390 3391/** 3392 * Find the IM on the device. 3393 * Returns the map, or NULL if the map doesn't exist. 3394 * If the return value is NULL, led_return is undefined. Otherwise, led_return 3395 * is set to the led index of the map. 3396 */ 3397static XkbIndicatorMapPtr 3398_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, int *led_return) 3399{ 3400 XkbIndicatorMapPtr map; 3401 3402 /* search for the right indicator */ 3403 map = NULL; 3404 if (sli->names && sli->maps) { 3405 int led; 3406 3407 for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { 3408 if (sli->names[led] == indicator) { 3409 map = &sli->maps[led]; 3410 *led_return = led; 3411 break; 3412 } 3413 } 3414 } 3415 3416 return map; 3417} 3418 3419/** 3420 * Creates an indicator map on the device. If dryRun is TRUE, it only checks 3421 * if creation is possible, but doesn't actually create it. 3422 */ 3423static int 3424_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, 3425 int ledClass, int ledID, 3426 XkbIndicatorMapPtr * map_return, int *led_return, 3427 Bool dryRun) 3428{ 3429 XkbSrvLedInfoPtr sli; 3430 XkbIndicatorMapPtr map; 3431 int led; 3432 3433 sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); 3434 if (!sli) 3435 return BadAlloc; 3436 3437 map = _XkbFindNamedIndicatorMap(sli, indicator, &led); 3438 3439 if (!map) { 3440 /* find first unused indicator maps and assign the name to it */ 3441 for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); 3442 led++) { 3443 if ((sli->names) && (sli->maps) && (sli->names[led] == None) && 3444 (!XkbIM_InUse(&sli->maps[led]))) { 3445 map = &sli->maps[led]; 3446 if (!dryRun) 3447 sli->names[led] = indicator; 3448 break; 3449 } 3450 } 3451 } 3452 3453 if (!map) 3454 return BadAlloc; 3455 3456 *led_return = led; 3457 *map_return = map; 3458 return Success; 3459} 3460 3461static int 3462_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, 3463 xkbSetNamedIndicatorReq * stuff) 3464{ 3465 unsigned int extDevReason; 3466 unsigned int statec, namec, mapc; 3467 XkbSrvLedInfoPtr sli; 3468 int led = 0; 3469 XkbIndicatorMapPtr map; 3470 DeviceIntPtr kbd; 3471 XkbEventCauseRec cause; 3472 xkbExtensionDeviceNotify ed; 3473 XkbChangesRec changes; 3474 int rc; 3475 3476 rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, 3477 stuff->ledID, &map, &led, FALSE); 3478 if (rc != Success || !map) /* oh-oh */ 3479 return rc; 3480 3481 sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, 3482 XkbXI_IndicatorsMask); 3483 if (!sli) 3484 return BadAlloc; 3485 3486 namec = mapc = statec = 0; 3487 extDevReason = 0; 3488 3489 namec |= (1 << led); 3490 sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); 3491 extDevReason |= XkbXI_IndicatorNamesMask; 3492 3493 if (stuff->setMap) { 3494 map->flags = stuff->flags; 3495 map->which_groups = stuff->whichGroups; 3496 map->groups = stuff->groups; 3497 map->which_mods = stuff->whichMods; 3498 map->mods.mask = stuff->realMods; 3499 map->mods.real_mods = stuff->realMods; 3500 map->mods.vmods = stuff->virtualMods; 3501 map->ctrls = stuff->ctrls; 3502 mapc |= (1 << led); 3503 } 3504 3505 if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) { 3506 if (stuff->on) 3507 sli->explicitState |= (1 << led); 3508 else 3509 sli->explicitState &= ~(1 << led); 3510 statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); 3511 } 3512 3513 memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 3514 memset((char *) &changes, 0, sizeof(XkbChangesRec)); 3515 XkbSetCauseXkbReq(&cause, X_kbSetNamedIndicator, client); 3516 if (namec) 3517 XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 3518 if (mapc) 3519 XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 3520 if (statec) 3521 XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 3522 3523 kbd = dev; 3524 if ((sli->flags & XkbSLI_HasOwnState) == 0) 3525 kbd = inputInfo.keyboard; 3526 XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 3527 3528 return Success; 3529} 3530 3531int 3532ProcXkbSetNamedIndicator(ClientPtr client) 3533{ 3534 int rc; 3535 DeviceIntPtr dev; 3536 int led = 0; 3537 XkbIndicatorMapPtr map; 3538 3539 REQUEST(xkbSetNamedIndicatorReq); 3540 REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); 3541 3542 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3543 return BadAccess; 3544 3545 CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); 3546 CHK_ATOM_ONLY(stuff->indicator); 3547 CHK_MASK_LEGAL(0x10, stuff->whichGroups, XkbIM_UseAnyGroup); 3548 CHK_MASK_LEGAL(0x11, stuff->whichMods, XkbIM_UseAnyMods); 3549 3550 /* Dry-run for checks */ 3551 rc = _XkbCreateIndicatorMap(dev, stuff->indicator, 3552 stuff->ledClass, stuff->ledID, 3553 &map, &led, TRUE); 3554 if (rc != Success || !map) /* couldn't be created or didn't exist */ 3555 return rc; 3556 3557 if (stuff->deviceSpec == XkbUseCoreKbd || 3558 stuff->deviceSpec == XkbUseCorePtr) { 3559 DeviceIntPtr other; 3560 3561 for (other = inputInfo.devices; other; other = other->next) { 3562 if ((other != dev) && !IsMaster(other) && 3563 GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3564 other->leds) && 3565 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3566 == Success)) { 3567 rc = _XkbCreateIndicatorMap(other, stuff->indicator, 3568 stuff->ledClass, stuff->ledID, &map, 3569 &led, TRUE); 3570 if (rc != Success || !map) 3571 return rc; 3572 } 3573 } 3574 } 3575 3576 /* All checks passed, let's do it */ 3577 rc = _XkbSetNamedIndicator(client, dev, stuff); 3578 if (rc != Success) 3579 return rc; 3580 3581 if (stuff->deviceSpec == XkbUseCoreKbd || 3582 stuff->deviceSpec == XkbUseCorePtr) { 3583 DeviceIntPtr other; 3584 3585 for (other = inputInfo.devices; other; other = other->next) { 3586 if ((other != dev) && !IsMaster(other) && 3587 GetMaster(other, MASTER_KEYBOARD) == dev && (other->kbdfeed || 3588 other->leds) && 3589 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) 3590 == Success)) { 3591 _XkbSetNamedIndicator(client, other, stuff); 3592 } 3593 } 3594 } 3595 3596 return Success; 3597} 3598 3599/***====================================================================***/ 3600 3601static CARD32 3602_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 3603{ 3604 register unsigned int i, bit, nAtoms; 3605 register CARD32 atomsPresent; 3606 3607 for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 3608 if (atoms[i] != None) { 3609 atomsPresent |= bit; 3610 nAtoms++; 3611 } 3612 } 3613 if (count) 3614 *count = nAtoms; 3615 return atomsPresent; 3616} 3617 3618static char * 3619_XkbWriteAtoms(char *wire, Atom *atoms, int maxAtoms, int swap) 3620{ 3621 register unsigned int i; 3622 Atom *atm; 3623 3624 atm = (Atom *) wire; 3625 for (i = 0; i < maxAtoms; i++) { 3626 if (atoms[i] != None) { 3627 *atm = atoms[i]; 3628 if (swap) { 3629 swapl(atm); 3630 } 3631 atm++; 3632 } 3633 } 3634 return (char *) atm; 3635} 3636 3637static Status 3638XkbComputeGetNamesReplySize(XkbDescPtr xkb, xkbGetNamesReply * rep) 3639{ 3640 register unsigned which, length; 3641 register int i; 3642 3643 rep->minKeyCode = xkb->min_key_code; 3644 rep->maxKeyCode = xkb->max_key_code; 3645 which = rep->which; 3646 length = 0; 3647 if (xkb->names != NULL) { 3648 if (which & XkbKeycodesNameMask) 3649 length++; 3650 if (which & XkbGeometryNameMask) 3651 length++; 3652 if (which & XkbSymbolsNameMask) 3653 length++; 3654 if (which & XkbPhysSymbolsNameMask) 3655 length++; 3656 if (which & XkbTypesNameMask) 3657 length++; 3658 if (which & XkbCompatNameMask) 3659 length++; 3660 } 3661 else 3662 which &= ~XkbComponentNamesMask; 3663 3664 if (xkb->map != NULL) { 3665 if (which & XkbKeyTypeNamesMask) 3666 length += xkb->map->num_types; 3667 rep->nTypes = xkb->map->num_types; 3668 if (which & XkbKTLevelNamesMask) { 3669 XkbKeyTypePtr pType = xkb->map->types; 3670 int nKTLevels = 0; 3671 3672 length += XkbPaddedSize(xkb->map->num_types) / 4; 3673 for (i = 0; i < xkb->map->num_types; i++, pType++) { 3674 if (pType->level_names != NULL) 3675 nKTLevels += pType->num_levels; 3676 } 3677 rep->nKTLevels = nKTLevels; 3678 length += nKTLevels; 3679 } 3680 } 3681 else { 3682 rep->nTypes = 0; 3683 rep->nKTLevels = 0; 3684 which &= ~(XkbKeyTypeNamesMask | XkbKTLevelNamesMask); 3685 } 3686 3687 rep->minKeyCode = xkb->min_key_code; 3688 rep->maxKeyCode = xkb->max_key_code; 3689 rep->indicators = 0; 3690 rep->virtualMods = 0; 3691 rep->groupNames = 0; 3692 if (xkb->names != NULL) { 3693 if (which & XkbIndicatorNamesMask) { 3694 int nLeds; 3695 3696 rep->indicators = 3697 _XkbCountAtoms(xkb->names->indicators, XkbNumIndicators, 3698 &nLeds); 3699 length += nLeds; 3700 if (nLeds == 0) 3701 which &= ~XkbIndicatorNamesMask; 3702 } 3703 3704 if (which & XkbVirtualModNamesMask) { 3705 int nVMods; 3706 3707 rep->virtualMods = 3708 _XkbCountAtoms(xkb->names->vmods, XkbNumVirtualMods, &nVMods); 3709 length += nVMods; 3710 if (nVMods == 0) 3711 which &= ~XkbVirtualModNamesMask; 3712 } 3713 3714 if (which & XkbGroupNamesMask) { 3715 int nGroups; 3716 3717 rep->groupNames = 3718 _XkbCountAtoms(xkb->names->groups, XkbNumKbdGroups, &nGroups); 3719 length += nGroups; 3720 if (nGroups == 0) 3721 which &= ~XkbGroupNamesMask; 3722 } 3723 3724 if ((which & XkbKeyNamesMask) && (xkb->names->keys)) 3725 length += rep->nKeys; 3726 else 3727 which &= ~XkbKeyNamesMask; 3728 3729 if ((which & XkbKeyAliasesMask) && 3730 (xkb->names->key_aliases) && (xkb->names->num_key_aliases > 0)) { 3731 rep->nKeyAliases = xkb->names->num_key_aliases; 3732 length += rep->nKeyAliases * 2; 3733 } 3734 else { 3735 which &= ~XkbKeyAliasesMask; 3736 rep->nKeyAliases = 0; 3737 } 3738 3739 if ((which & XkbRGNamesMask) && (xkb->names->num_rg > 0)) 3740 length += xkb->names->num_rg; 3741 else 3742 which &= ~XkbRGNamesMask; 3743 } 3744 else { 3745 which &= ~(XkbIndicatorNamesMask | XkbVirtualModNamesMask); 3746 which &= ~(XkbGroupNamesMask | XkbKeyNamesMask | XkbKeyAliasesMask); 3747 which &= ~XkbRGNamesMask; 3748 } 3749 3750 rep->length = length; 3751 rep->which = which; 3752 return Success; 3753} 3754 3755static int 3756XkbSendNames(ClientPtr client, XkbDescPtr xkb, xkbGetNamesReply * rep) 3757{ 3758 register unsigned i, length, which; 3759 char *start; 3760 char *desc; 3761 3762 length = rep->length * 4; 3763 which = rep->which; 3764 if (client->swapped) { 3765 swaps(&rep->sequenceNumber); 3766 swapl(&rep->length); 3767 swapl(&rep->which); 3768 swaps(&rep->virtualMods); 3769 swapl(&rep->indicators); 3770 } 3771 3772 start = desc = calloc(1, length); 3773 if (!start) 3774 return BadAlloc; 3775 if (xkb->names) { 3776 if (which & XkbKeycodesNameMask) { 3777 *((CARD32 *) desc) = xkb->names->keycodes; 3778 if (client->swapped) { 3779 swapl((int *) desc); 3780 } 3781 desc += 4; 3782 } 3783 if (which & XkbGeometryNameMask) { 3784 *((CARD32 *) desc) = xkb->names->geometry; 3785 if (client->swapped) { 3786 swapl((int *) desc); 3787 } 3788 desc += 4; 3789 } 3790 if (which & XkbSymbolsNameMask) { 3791 *((CARD32 *) desc) = xkb->names->symbols; 3792 if (client->swapped) { 3793 swapl((int *) desc); 3794 } 3795 desc += 4; 3796 } 3797 if (which & XkbPhysSymbolsNameMask) { 3798 register CARD32 *atm = (CARD32 *) desc; 3799 3800 atm[0] = (CARD32) xkb->names->phys_symbols; 3801 if (client->swapped) { 3802 swapl(&atm[0]); 3803 } 3804 desc += 4; 3805 } 3806 if (which & XkbTypesNameMask) { 3807 *((CARD32 *) desc) = (CARD32) xkb->names->types; 3808 if (client->swapped) { 3809 swapl((int *) desc); 3810 } 3811 desc += 4; 3812 } 3813 if (which & XkbCompatNameMask) { 3814 *((CARD32 *) desc) = (CARD32) xkb->names->compat; 3815 if (client->swapped) { 3816 swapl((int *) desc); 3817 } 3818 desc += 4; 3819 } 3820 if (which & XkbKeyTypeNamesMask) { 3821 register CARD32 *atm = (CARD32 *) desc; 3822 register XkbKeyTypePtr type = xkb->map->types; 3823 3824 for (i = 0; i < xkb->map->num_types; i++, atm++, type++) { 3825 *atm = (CARD32) type->name; 3826 if (client->swapped) { 3827 swapl(atm); 3828 } 3829 } 3830 desc = (char *) atm; 3831 } 3832 if (which & XkbKTLevelNamesMask && xkb->map) { 3833 XkbKeyTypePtr type = xkb->map->types; 3834 register CARD32 *atm; 3835 3836 for (i = 0; i < rep->nTypes; i++, type++) { 3837 *desc++ = type->num_levels; 3838 } 3839 desc += XkbPaddedSize(rep->nTypes) - rep->nTypes; 3840 3841 atm = (CARD32 *) desc; 3842 type = xkb->map->types; 3843 for (i = 0; i < xkb->map->num_types; i++, type++) { 3844 register unsigned l; 3845 3846 if (type->level_names) { 3847 for (l = 0; l < type->num_levels; l++, atm++) { 3848 *atm = type->level_names[l]; 3849 if (client->swapped) { 3850 swapl(atm); 3851 } 3852 } 3853 desc += type->num_levels * 4; 3854 } 3855 } 3856 } 3857 if (which & XkbIndicatorNamesMask) { 3858 desc = 3859 _XkbWriteAtoms(desc, xkb->names->indicators, XkbNumIndicators, 3860 client->swapped); 3861 } 3862 if (which & XkbVirtualModNamesMask) { 3863 desc = _XkbWriteAtoms(desc, xkb->names->vmods, XkbNumVirtualMods, 3864 client->swapped); 3865 } 3866 if (which & XkbGroupNamesMask) { 3867 desc = _XkbWriteAtoms(desc, xkb->names->groups, XkbNumKbdGroups, 3868 client->swapped); 3869 } 3870 if (which & XkbKeyNamesMask) { 3871 for (i = 0; i < rep->nKeys; i++, desc += sizeof(XkbKeyNameRec)) { 3872 *((XkbKeyNamePtr) desc) = xkb->names->keys[i + rep->firstKey]; 3873 } 3874 } 3875 if (which & XkbKeyAliasesMask) { 3876 XkbKeyAliasPtr pAl; 3877 3878 pAl = xkb->names->key_aliases; 3879 for (i = 0; i < rep->nKeyAliases; 3880 i++, pAl++, desc += 2 * XkbKeyNameLength) { 3881 *((XkbKeyAliasPtr) desc) = *pAl; 3882 } 3883 } 3884 if ((which & XkbRGNamesMask) && (rep->nRadioGroups > 0)) { 3885 register CARD32 *atm = (CARD32 *) desc; 3886 3887 for (i = 0; i < rep->nRadioGroups; i++, atm++) { 3888 *atm = (CARD32) xkb->names->radio_groups[i]; 3889 if (client->swapped) { 3890 swapl(atm); 3891 } 3892 } 3893 desc += rep->nRadioGroups * 4; 3894 } 3895 } 3896 3897 if ((desc - start) != (length)) { 3898 ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 3899 length, (unsigned long) (desc - start)); 3900 } 3901 WriteToClient(client, SIZEOF(xkbGetNamesReply), rep); 3902 WriteToClient(client, length, start); 3903 free((char *) start); 3904 return Success; 3905} 3906 3907int 3908ProcXkbGetNames(ClientPtr client) 3909{ 3910 DeviceIntPtr dev; 3911 XkbDescPtr xkb; 3912 xkbGetNamesReply rep; 3913 3914 REQUEST(xkbGetNamesReq); 3915 REQUEST_SIZE_MATCH(xkbGetNamesReq); 3916 3917 if (!(client->xkbClientFlags & _XkbClientInitialized)) 3918 return BadAccess; 3919 3920 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 3921 CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 3922 3923 xkb = dev->key->xkbInfo->desc; 3924 rep = (xkbGetNamesReply) { 3925 .type = X_Reply, 3926 .deviceID = dev->id, 3927 .sequenceNumber = client->sequence, 3928 .length = 0, 3929 .which = stuff->which, 3930 .nTypes = xkb->map->num_types, 3931 .firstKey = xkb->min_key_code, 3932 .nKeys = XkbNumKeys(xkb), 3933 .nKeyAliases = xkb->names ? xkb->names->num_key_aliases : 0, 3934 .nRadioGroups = xkb->names ? xkb->names->num_rg : 0 3935 }; 3936 XkbComputeGetNamesReplySize(xkb, &rep); 3937 return XkbSendNames(client, xkb, &rep); 3938} 3939 3940/***====================================================================***/ 3941 3942static CARD32 * 3943_XkbCheckAtoms(CARD32 *wire, int nAtoms, int swapped, Atom *pError) 3944{ 3945 register int i; 3946 3947 for (i = 0; i < nAtoms; i++, wire++) { 3948 if (swapped) { 3949 swapl(wire); 3950 } 3951 if ((((Atom) *wire) != None) && (!ValidAtom((Atom) *wire))) { 3952 *pError = ((Atom) *wire); 3953 return NULL; 3954 } 3955 } 3956 return wire; 3957} 3958 3959static CARD32 * 3960_XkbCheckMaskedAtoms(CARD32 *wire, int nAtoms, CARD32 present, int swapped, 3961 Atom *pError) 3962{ 3963 register unsigned i, bit; 3964 3965 for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 3966 if ((present & bit) == 0) 3967 continue; 3968 if (swapped) { 3969 swapl(wire); 3970 } 3971 if ((((Atom) *wire) != None) && (!ValidAtom(((Atom) *wire)))) { 3972 *pError = (Atom) *wire; 3973 return NULL; 3974 } 3975 wire++; 3976 } 3977 return wire; 3978} 3979 3980static Atom * 3981_XkbCopyMaskedAtoms(Atom *wire, Atom *dest, int nAtoms, CARD32 present) 3982{ 3983 register int i, bit; 3984 3985 for (i = 0, bit = 1; (i < nAtoms) && (present); i++, bit <<= 1) { 3986 if ((present & bit) == 0) 3987 continue; 3988 dest[i] = *wire++; 3989 } 3990 return wire; 3991} 3992 3993static Bool 3994_XkbCheckTypeName(Atom name, int typeNdx) 3995{ 3996 const char *str; 3997 3998 str = NameForAtom(name); 3999 if ((strcmp(str, "ONE_LEVEL") == 0) || (strcmp(str, "TWO_LEVEL") == 0) || 4000 (strcmp(str, "ALPHABETIC") == 0) || (strcmp(str, "KEYPAD") == 0)) 4001 return FALSE; 4002 return TRUE; 4003} 4004 4005/** 4006 * Check the device-dependent data in the request against the device. Returns 4007 * Success, or the appropriate error code. 4008 */ 4009static int 4010_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 4011 xkbSetNamesReq * stuff, CARD32 *data) 4012{ 4013 XkbDescRec *xkb; 4014 CARD32 *tmp; 4015 Atom bad = None; 4016 4017 tmp = data; 4018 xkb = dev->key->xkbInfo->desc; 4019 4020 if (stuff->which & XkbKeyTypeNamesMask) { 4021 int i; 4022 CARD32 *old; 4023 4024 if (stuff->nTypes < 1) { 4025 client->errorValue = _XkbErrCode2(0x02, stuff->nTypes); 4026 return BadValue; 4027 } 4028 if ((unsigned) (stuff->firstType + stuff->nTypes - 1) >= 4029 xkb->map->num_types) { 4030 client->errorValue = 4031 _XkbErrCode4(0x03, stuff->firstType, stuff->nTypes, 4032 xkb->map->num_types); 4033 return BadValue; 4034 } 4035 if (((unsigned) stuff->firstType) <= XkbLastRequiredType) { 4036 client->errorValue = _XkbErrCode2(0x04, stuff->firstType); 4037 return BadAccess; 4038 } 4039 old = tmp; 4040 tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad); 4041 if (!tmp) { 4042 client->errorValue = bad; 4043 return BadAtom; 4044 } 4045 for (i = 0; i < stuff->nTypes; i++, old++) { 4046 if (!_XkbCheckTypeName((Atom) *old, stuff->firstType + i)) 4047 client->errorValue = _XkbErrCode2(0x05, i); 4048 } 4049 } 4050 if (stuff->which & XkbKTLevelNamesMask) { 4051 unsigned i; 4052 XkbKeyTypePtr type; 4053 CARD8 *width; 4054 4055 if (stuff->nKTLevels < 1) { 4056 client->errorValue = _XkbErrCode2(0x05, stuff->nKTLevels); 4057 return BadValue; 4058 } 4059 if ((unsigned) (stuff->firstKTLevel + stuff->nKTLevels - 1) >= 4060 xkb->map->num_types) { 4061 client->errorValue = _XkbErrCode4(0x06, stuff->firstKTLevel, 4062 stuff->nKTLevels, 4063 xkb->map->num_types); 4064 return BadValue; 4065 } 4066 width = (CARD8 *) tmp; 4067 tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4068 type = &xkb->map->types[stuff->firstKTLevel]; 4069 for (i = 0; i < stuff->nKTLevels; i++, type++) { 4070 if (width[i] == 0) 4071 continue; 4072 else if (width[i] != type->num_levels) { 4073 client->errorValue = _XkbErrCode4(0x07, i + stuff->firstKTLevel, 4074 type->num_levels, width[i]); 4075 return BadMatch; 4076 } 4077 tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad); 4078 if (!tmp) { 4079 client->errorValue = bad; 4080 return BadAtom; 4081 } 4082 } 4083 } 4084 if (stuff->which & XkbIndicatorNamesMask) { 4085 if (stuff->indicators == 0) { 4086 client->errorValue = 0x08; 4087 return BadMatch; 4088 } 4089 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators, 4090 client->swapped, &bad); 4091 if (!tmp) { 4092 client->errorValue = bad; 4093 return BadAtom; 4094 } 4095 } 4096 if (stuff->which & XkbVirtualModNamesMask) { 4097 if (stuff->virtualMods == 0) { 4098 client->errorValue = 0x09; 4099 return BadMatch; 4100 } 4101 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods, 4102 (CARD32) stuff->virtualMods, 4103 client->swapped, &bad); 4104 if (!tmp) { 4105 client->errorValue = bad; 4106 return BadAtom; 4107 } 4108 } 4109 if (stuff->which & XkbGroupNamesMask) { 4110 if (stuff->groupNames == 0) { 4111 client->errorValue = 0x0a; 4112 return BadMatch; 4113 } 4114 tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups, 4115 (CARD32) stuff->groupNames, 4116 client->swapped, &bad); 4117 if (!tmp) { 4118 client->errorValue = bad; 4119 return BadAtom; 4120 } 4121 } 4122 if (stuff->which & XkbKeyNamesMask) { 4123 if (stuff->firstKey < (unsigned) xkb->min_key_code) { 4124 client->errorValue = _XkbErrCode3(0x0b, xkb->min_key_code, 4125 stuff->firstKey); 4126 return BadValue; 4127 } 4128 if (((unsigned) (stuff->firstKey + stuff->nKeys - 1) > 4129 xkb->max_key_code) || (stuff->nKeys < 1)) { 4130 client->errorValue = 4131 _XkbErrCode4(0x0c, xkb->max_key_code, stuff->firstKey, 4132 stuff->nKeys); 4133 return BadValue; 4134 } 4135 tmp += stuff->nKeys; 4136 } 4137 if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) { 4138 tmp += stuff->nKeyAliases * 2; 4139 } 4140 if (stuff->which & XkbRGNamesMask) { 4141 if (stuff->nRadioGroups < 1) { 4142 client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups); 4143 return BadValue; 4144 } 4145 tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad); 4146 if (!tmp) { 4147 client->errorValue = bad; 4148 return BadAtom; 4149 } 4150 } 4151 if ((tmp - ((CARD32 *) stuff)) != stuff->length) { 4152 client->errorValue = stuff->length; 4153 return BadLength; 4154 } 4155 4156 return Success; 4157} 4158 4159static int 4160_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq * stuff) 4161{ 4162 XkbDescRec *xkb; 4163 XkbNamesRec *names; 4164 CARD32 *tmp; 4165 xkbNamesNotify nn; 4166 4167 tmp = (CARD32 *) &stuff[1]; 4168 xkb = dev->key->xkbInfo->desc; 4169 names = xkb->names; 4170 4171 if (XkbAllocNames(xkb, stuff->which, stuff->nRadioGroups, 4172 stuff->nKeyAliases) != Success) { 4173 return BadAlloc; 4174 } 4175 4176 memset(&nn, 0, sizeof(xkbNamesNotify)); 4177 nn.changed = stuff->which; 4178 tmp = (CARD32 *) &stuff[1]; 4179 if (stuff->which & XkbKeycodesNameMask) 4180 names->keycodes = *tmp++; 4181 if (stuff->which & XkbGeometryNameMask) 4182 names->geometry = *tmp++; 4183 if (stuff->which & XkbSymbolsNameMask) 4184 names->symbols = *tmp++; 4185 if (stuff->which & XkbPhysSymbolsNameMask) 4186 names->phys_symbols = *tmp++; 4187 if (stuff->which & XkbTypesNameMask) 4188 names->types = *tmp++; 4189 if (stuff->which & XkbCompatNameMask) 4190 names->compat = *tmp++; 4191 if ((stuff->which & XkbKeyTypeNamesMask) && (stuff->nTypes > 0)) { 4192 register unsigned i; 4193 register XkbKeyTypePtr type; 4194 4195 type = &xkb->map->types[stuff->firstType]; 4196 for (i = 0; i < stuff->nTypes; i++, type++) { 4197 type->name = *tmp++; 4198 } 4199 nn.firstType = stuff->firstType; 4200 nn.nTypes = stuff->nTypes; 4201 } 4202 if (stuff->which & XkbKTLevelNamesMask) { 4203 register XkbKeyTypePtr type; 4204 register unsigned i; 4205 CARD8 *width; 4206 4207 width = (CARD8 *) tmp; 4208 tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); 4209 type = &xkb->map->types[stuff->firstKTLevel]; 4210 for (i = 0; i < stuff->nKTLevels; i++, type++) { 4211 if (width[i] > 0) { 4212 if (type->level_names) { 4213 register unsigned n; 4214 4215 for (n = 0; n < width[i]; n++) { 4216 type->level_names[n] = tmp[n]; 4217 } 4218 } 4219 tmp += width[i]; 4220 } 4221 } 4222 nn.firstLevelName = 0; 4223 nn.nLevelNames = stuff->nTypes; 4224 } 4225 if (stuff->which & XkbIndicatorNamesMask) { 4226 tmp = _XkbCopyMaskedAtoms(tmp, names->indicators, XkbNumIndicators, 4227 stuff->indicators); 4228 nn.changedIndicators = stuff->indicators; 4229 } 4230 if (stuff->which & XkbVirtualModNamesMask) { 4231 tmp = _XkbCopyMaskedAtoms(tmp, names->vmods, XkbNumVirtualMods, 4232 stuff->virtualMods); 4233 nn.changedVirtualMods = stuff->virtualMods; 4234 } 4235 if (stuff->which & XkbGroupNamesMask) { 4236 tmp = _XkbCopyMaskedAtoms(tmp, names->groups, XkbNumKbdGroups, 4237 stuff->groupNames); 4238 nn.changedVirtualMods = stuff->groupNames; 4239 } 4240 if (stuff->which & XkbKeyNamesMask) { 4241 memcpy((char *) &names->keys[stuff->firstKey], (char *) tmp, 4242 stuff->nKeys * XkbKeyNameLength); 4243 tmp += stuff->nKeys; 4244 nn.firstKey = stuff->firstKey; 4245 nn.nKeys = stuff->nKeys; 4246 } 4247 if (stuff->which & XkbKeyAliasesMask) { 4248 if (stuff->nKeyAliases > 0) { 4249 register int na = stuff->nKeyAliases; 4250 4251 if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, na) != Success) 4252 return BadAlloc; 4253 memcpy((char *) names->key_aliases, (char *) tmp, 4254 stuff->nKeyAliases * sizeof(XkbKeyAliasRec)); 4255 tmp += stuff->nKeyAliases * 2; 4256 } 4257 else if (names->key_aliases != NULL) { 4258 free(names->key_aliases); 4259 names->key_aliases = NULL; 4260 names->num_key_aliases = 0; 4261 } 4262 nn.nAliases = names->num_key_aliases; 4263 } 4264 if (stuff->which & XkbRGNamesMask) { 4265 if (stuff->nRadioGroups > 0) { 4266 register unsigned i, nrg; 4267 4268 nrg = stuff->nRadioGroups; 4269 if (XkbAllocNames(xkb, XkbRGNamesMask, nrg, 0) != Success) 4270 return BadAlloc; 4271 4272 for (i = 0; i < stuff->nRadioGroups; i++) { 4273 names->radio_groups[i] = tmp[i]; 4274 } 4275 tmp += stuff->nRadioGroups; 4276 } 4277 else if (names->radio_groups) { 4278 free(names->radio_groups); 4279 names->radio_groups = NULL; 4280 names->num_rg = 0; 4281 } 4282 nn.nRadioGroups = names->num_rg; 4283 } 4284 if (nn.changed) { 4285 Bool needExtEvent; 4286 4287 needExtEvent = (nn.changed & XkbIndicatorNamesMask) != 0; 4288 XkbSendNamesNotify(dev, &nn); 4289 if (needExtEvent) { 4290 XkbSrvLedInfoPtr sli; 4291 xkbExtensionDeviceNotify edev; 4292 register int i; 4293 register unsigned bit; 4294 4295 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 4296 XkbXI_IndicatorsMask); 4297 sli->namesPresent = 0; 4298 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 4299 if (names->indicators[i] != None) 4300 sli->namesPresent |= bit; 4301 } 4302 memset(&edev, 0, sizeof(xkbExtensionDeviceNotify)); 4303 edev.reason = XkbXI_IndicatorNamesMask; 4304 edev.ledClass = KbdFeedbackClass; 4305 edev.ledID = dev->kbdfeed->ctrl.id; 4306 edev.ledsDefined = sli->namesPresent | sli->mapsPresent; 4307 edev.ledState = sli->effectiveState; 4308 edev.firstBtn = 0; 4309 edev.nBtns = 0; 4310 edev.supported = XkbXI_AllFeaturesMask; 4311 edev.unsupported = 0; 4312 XkbSendExtensionDeviceNotify(dev, client, &edev); 4313 } 4314 } 4315 return Success; 4316} 4317 4318int 4319ProcXkbSetNames(ClientPtr client) 4320{ 4321 DeviceIntPtr dev; 4322 CARD32 *tmp; 4323 Atom bad; 4324 int rc; 4325 4326 REQUEST(xkbSetNamesReq); 4327 REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 4328 4329 if (!(client->xkbClientFlags & _XkbClientInitialized)) 4330 return BadAccess; 4331 4332 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 4333 CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); 4334 4335 /* check device-independent stuff */ 4336 tmp = (CARD32 *) &stuff[1]; 4337 4338 if (stuff->which & XkbKeycodesNameMask) { 4339 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4340 if (!tmp) { 4341 client->errorValue = bad; 4342 return BadAtom; 4343 } 4344 } 4345 if (stuff->which & XkbGeometryNameMask) { 4346 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4347 if (!tmp) { 4348 client->errorValue = bad; 4349 return BadAtom; 4350 } 4351 } 4352 if (stuff->which & XkbSymbolsNameMask) { 4353 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4354 if (!tmp) { 4355 client->errorValue = bad; 4356 return BadAtom; 4357 } 4358 } 4359 if (stuff->which & XkbPhysSymbolsNameMask) { 4360 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4361 if (!tmp) { 4362 client->errorValue = bad; 4363 return BadAtom; 4364 } 4365 } 4366 if (stuff->which & XkbTypesNameMask) { 4367 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4368 if (!tmp) { 4369 client->errorValue = bad; 4370 return BadAtom; 4371 } 4372 } 4373 if (stuff->which & XkbCompatNameMask) { 4374 tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); 4375 if (!tmp) { 4376 client->errorValue = bad; 4377 return BadAtom; 4378 } 4379 } 4380 4381 /* start of device-dependent tests */ 4382 rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 4383 if (rc != Success) 4384 return rc; 4385 4386 if (stuff->deviceSpec == XkbUseCoreKbd) { 4387 DeviceIntPtr other; 4388 4389 for (other = inputInfo.devices; other; other = other->next) { 4390 if ((other != dev) && other->key && !IsMaster(other) && 4391 GetMaster(other, MASTER_KEYBOARD) == dev) { 4392 4393 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4394 DixManageAccess); 4395 if (rc == Success) { 4396 rc = _XkbSetNamesCheck(client, other, stuff, tmp); 4397 if (rc != Success) 4398 return rc; 4399 } 4400 } 4401 } 4402 } 4403 4404 /* everything is okay -- update names */ 4405 4406 rc = _XkbSetNames(client, dev, stuff); 4407 if (rc != Success) 4408 return rc; 4409 4410 if (stuff->deviceSpec == XkbUseCoreKbd) { 4411 DeviceIntPtr other; 4412 4413 for (other = inputInfo.devices; other; other = other->next) { 4414 if ((other != dev) && other->key && !IsMaster(other) && 4415 GetMaster(other, MASTER_KEYBOARD) == dev) { 4416 4417 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 4418 DixManageAccess); 4419 if (rc == Success) 4420 _XkbSetNames(client, other, stuff); 4421 } 4422 } 4423 } 4424 4425 /* everything is okay -- update names */ 4426 4427 return Success; 4428} 4429 4430/***====================================================================***/ 4431 4432#include "xkbgeom.h" 4433 4434#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 4435 4436/** 4437 * Write the zero-terminated string str into wire as a pascal string with a 4438 * 16-bit length field prefixed before the actual string. 4439 * 4440 * @param wire The destination array, usually the wire struct 4441 * @param str The source string as zero-terminated C string 4442 * @param swap If TRUE, the length field is swapped. 4443 * 4444 * @return The input string in the format <string length><string> with a 4445 * (swapped) 16 bit string length, non-zero terminated. 4446 */ 4447static char * 4448XkbWriteCountedString(char *wire, const char *str, Bool swap) 4449{ 4450 CARD16 len, *pLen, paddedLen; 4451 4452 if (!str) 4453 return wire; 4454 4455 len = strlen(str); 4456 pLen = (CARD16 *) wire; 4457 *pLen = len; 4458 if (swap) { 4459 swaps(pLen); 4460 } 4461 paddedLen = pad_to_int32(sizeof(len) + len) - sizeof(len); 4462 strncpy(&wire[sizeof(len)], str, paddedLen); 4463 wire += sizeof(len) + paddedLen; 4464 return wire; 4465} 4466 4467static int 4468XkbSizeGeomProperties(XkbGeometryPtr geom) 4469{ 4470 register int i, size; 4471 XkbPropertyPtr prop; 4472 4473 for (size = i = 0, prop = geom->properties; i < geom->num_properties; 4474 i++, prop++) { 4475 size += XkbSizeCountedString(prop->name); 4476 size += XkbSizeCountedString(prop->value); 4477 } 4478 return size; 4479} 4480 4481static char * 4482XkbWriteGeomProperties(char *wire, XkbGeometryPtr geom, Bool swap) 4483{ 4484 register int i; 4485 register XkbPropertyPtr prop; 4486 4487 for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { 4488 wire = XkbWriteCountedString(wire, prop->name, swap); 4489 wire = XkbWriteCountedString(wire, prop->value, swap); 4490 } 4491 return wire; 4492} 4493 4494static int 4495XkbSizeGeomKeyAliases(XkbGeometryPtr geom) 4496{ 4497 return geom->num_key_aliases * (2 * XkbKeyNameLength); 4498} 4499 4500static char * 4501XkbWriteGeomKeyAliases(char *wire, XkbGeometryPtr geom, Bool swap) 4502{ 4503 register int sz; 4504 4505 sz = geom->num_key_aliases * (XkbKeyNameLength * 2); 4506 if (sz > 0) { 4507 memcpy(wire, (char *) geom->key_aliases, sz); 4508 wire += sz; 4509 } 4510 return wire; 4511} 4512 4513static int 4514XkbSizeGeomColors(XkbGeometryPtr geom) 4515{ 4516 register int i, size; 4517 register XkbColorPtr color; 4518 4519 for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4520 size += XkbSizeCountedString(color->spec); 4521 } 4522 return size; 4523} 4524 4525static char * 4526XkbWriteGeomColors(char *wire, XkbGeometryPtr geom, Bool swap) 4527{ 4528 register int i; 4529 register XkbColorPtr color; 4530 4531 for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 4532 wire = XkbWriteCountedString(wire, color->spec, swap); 4533 } 4534 return wire; 4535} 4536 4537static int 4538XkbSizeGeomShapes(XkbGeometryPtr geom) 4539{ 4540 register int i, size; 4541 register XkbShapePtr shape; 4542 4543 for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4544 register int n; 4545 register XkbOutlinePtr ol; 4546 4547 size += SIZEOF(xkbShapeWireDesc); 4548 for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) { 4549 size += SIZEOF(xkbOutlineWireDesc); 4550 size += ol->num_points * SIZEOF(xkbPointWireDesc); 4551 } 4552 } 4553 return size; 4554} 4555 4556static char * 4557XkbWriteGeomShapes(char *wire, XkbGeometryPtr geom, Bool swap) 4558{ 4559 int i; 4560 XkbShapePtr shape; 4561 xkbShapeWireDesc *shapeWire; 4562 4563 for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 4564 register int o; 4565 XkbOutlinePtr ol; 4566 xkbOutlineWireDesc *olWire; 4567 4568 shapeWire = (xkbShapeWireDesc *) wire; 4569 shapeWire->name = shape->name; 4570 shapeWire->nOutlines = shape->num_outlines; 4571 if (shape->primary != NULL) 4572 shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary); 4573 else 4574 shapeWire->primaryNdx = XkbNoShape; 4575 if (shape->approx != NULL) 4576 shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx); 4577 else 4578 shapeWire->approxNdx = XkbNoShape; 4579 shapeWire->pad = 0; 4580 if (swap) { 4581 swapl(&shapeWire->name); 4582 } 4583 wire = (char *) &shapeWire[1]; 4584 for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { 4585 register int p; 4586 XkbPointPtr pt; 4587 xkbPointWireDesc *ptWire; 4588 4589 olWire = (xkbOutlineWireDesc *) wire; 4590 olWire->nPoints = ol->num_points; 4591 olWire->cornerRadius = ol->corner_radius; 4592 olWire->pad = 0; 4593 wire = (char *) &olWire[1]; 4594 ptWire = (xkbPointWireDesc *) wire; 4595 for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) { 4596 ptWire[p].x = pt->x; 4597 ptWire[p].y = pt->y; 4598 if (swap) { 4599 swaps(&ptWire[p].x); 4600 swaps(&ptWire[p].y); 4601 } 4602 } 4603 wire = (char *) &ptWire[ol->num_points]; 4604 } 4605 } 4606 return wire; 4607} 4608 4609static int 4610XkbSizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad) 4611{ 4612 register int i, size; 4613 4614 for (i = size = 0; i < num_doodads; i++, doodad++) { 4615 size += SIZEOF(xkbAnyDoodadWireDesc); 4616 if (doodad->any.type == XkbTextDoodad) { 4617 size += XkbSizeCountedString(doodad->text.text); 4618 size += XkbSizeCountedString(doodad->text.font); 4619 } 4620 else if (doodad->any.type == XkbLogoDoodad) { 4621 size += XkbSizeCountedString(doodad->logo.logo_name); 4622 } 4623 } 4624 return size; 4625} 4626 4627static char * 4628XkbWriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad, Bool swap) 4629{ 4630 register int i; 4631 xkbDoodadWireDesc *doodadWire; 4632 4633 for (i = 0; i < num_doodads; i++, doodad++) { 4634 doodadWire = (xkbDoodadWireDesc *) wire; 4635 wire = (char *) &doodadWire[1]; 4636 memset(doodadWire, 0, SIZEOF(xkbDoodadWireDesc)); 4637 doodadWire->any.name = doodad->any.name; 4638 doodadWire->any.type = doodad->any.type; 4639 doodadWire->any.priority = doodad->any.priority; 4640 doodadWire->any.top = doodad->any.top; 4641 doodadWire->any.left = doodad->any.left; 4642 if (swap) { 4643 swapl(&doodadWire->any.name); 4644 swaps(&doodadWire->any.top); 4645 swaps(&doodadWire->any.left); 4646 } 4647 switch (doodad->any.type) { 4648 case XkbOutlineDoodad: 4649 case XkbSolidDoodad: 4650 doodadWire->shape.angle = doodad->shape.angle; 4651 doodadWire->shape.colorNdx = doodad->shape.color_ndx; 4652 doodadWire->shape.shapeNdx = doodad->shape.shape_ndx; 4653 if (swap) { 4654 swaps(&doodadWire->shape.angle); 4655 } 4656 break; 4657 case XkbTextDoodad: 4658 doodadWire->text.angle = doodad->text.angle; 4659 doodadWire->text.width = doodad->text.width; 4660 doodadWire->text.height = doodad->text.height; 4661 doodadWire->text.colorNdx = doodad->text.color_ndx; 4662 if (swap) { 4663 swaps(&doodadWire->text.angle); 4664 swaps(&doodadWire->text.width); 4665 swaps(&doodadWire->text.height); 4666 } 4667 wire = XkbWriteCountedString(wire, doodad->text.text, swap); 4668 wire = XkbWriteCountedString(wire, doodad->text.font, swap); 4669 break; 4670 case XkbIndicatorDoodad: 4671 doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx; 4672 doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx; 4673 doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx; 4674 break; 4675 case XkbLogoDoodad: 4676 doodadWire->logo.angle = doodad->logo.angle; 4677 doodadWire->logo.colorNdx = doodad->logo.color_ndx; 4678 doodadWire->logo.shapeNdx = doodad->logo.shape_ndx; 4679 wire = XkbWriteCountedString(wire, doodad->logo.logo_name, swap); 4680 break; 4681 default: 4682 ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 4683 doodad->any.type); 4684 ErrorF("[xkb] Ignored\n"); 4685 break; 4686 } 4687 } 4688 return wire; 4689} 4690 4691static char * 4692XkbWriteGeomOverlay(char *wire, XkbOverlayPtr ol, Bool swap) 4693{ 4694 register int r; 4695 XkbOverlayRowPtr row; 4696 xkbOverlayWireDesc *olWire; 4697 4698 olWire = (xkbOverlayWireDesc *) wire; 4699 olWire->name = ol->name; 4700 olWire->nRows = ol->num_rows; 4701 olWire->pad1 = 0; 4702 olWire->pad2 = 0; 4703 if (swap) { 4704 swapl(&olWire->name); 4705 } 4706 wire = (char *) &olWire[1]; 4707 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4708 unsigned int k; 4709 XkbOverlayKeyPtr key; 4710 xkbOverlayRowWireDesc *rowWire; 4711 4712 rowWire = (xkbOverlayRowWireDesc *) wire; 4713 rowWire->rowUnder = row->row_under; 4714 rowWire->nKeys = row->num_keys; 4715 rowWire->pad1 = 0; 4716 wire = (char *) &rowWire[1]; 4717 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4718 xkbOverlayKeyWireDesc *keyWire; 4719 4720 keyWire = (xkbOverlayKeyWireDesc *) wire; 4721 memcpy(keyWire->over, key->over.name, XkbKeyNameLength); 4722 memcpy(keyWire->under, key->under.name, XkbKeyNameLength); 4723 wire = (char *) &keyWire[1]; 4724 } 4725 } 4726 return wire; 4727} 4728 4729static int 4730XkbSizeGeomSections(XkbGeometryPtr geom) 4731{ 4732 register int i, size; 4733 XkbSectionPtr section; 4734 4735 for (i = size = 0, section = geom->sections; i < geom->num_sections; 4736 i++, section++) { 4737 size += SIZEOF(xkbSectionWireDesc); 4738 if (section->rows) { 4739 int r; 4740 XkbRowPtr row; 4741 4742 for (r = 0, row = section->rows; r < section->num_rows; row++, r++) { 4743 size += SIZEOF(xkbRowWireDesc); 4744 size += row->num_keys * SIZEOF(xkbKeyWireDesc); 4745 } 4746 } 4747 if (section->doodads) 4748 size += XkbSizeGeomDoodads(section->num_doodads, section->doodads); 4749 if (section->overlays) { 4750 int o; 4751 XkbOverlayPtr ol; 4752 4753 for (o = 0, ol = section->overlays; o < section->num_overlays; 4754 o++, ol++) { 4755 int r; 4756 XkbOverlayRowPtr row; 4757 4758 size += SIZEOF(xkbOverlayWireDesc); 4759 for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 4760 size += SIZEOF(xkbOverlayRowWireDesc); 4761 size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc); 4762 } 4763 } 4764 } 4765 } 4766 return size; 4767} 4768 4769static char * 4770XkbWriteGeomSections(char *wire, XkbGeometryPtr geom, Bool swap) 4771{ 4772 register int i; 4773 XkbSectionPtr section; 4774 xkbSectionWireDesc *sectionWire; 4775 4776 for (i = 0, section = geom->sections; i < geom->num_sections; 4777 i++, section++) { 4778 sectionWire = (xkbSectionWireDesc *) wire; 4779 sectionWire->name = section->name; 4780 sectionWire->top = section->top; 4781 sectionWire->left = section->left; 4782 sectionWire->width = section->width; 4783 sectionWire->height = section->height; 4784 sectionWire->angle = section->angle; 4785 sectionWire->priority = section->priority; 4786 sectionWire->nRows = section->num_rows; 4787 sectionWire->nDoodads = section->num_doodads; 4788 sectionWire->nOverlays = section->num_overlays; 4789 sectionWire->pad = 0; 4790 if (swap) { 4791 swapl(§ionWire->name); 4792 swaps(§ionWire->top); 4793 swaps(§ionWire->left); 4794 swaps(§ionWire->width); 4795 swaps(§ionWire->height); 4796 swaps(§ionWire->angle); 4797 } 4798 wire = (char *) §ionWire[1]; 4799 if (section->rows) { 4800 int r; 4801 XkbRowPtr row; 4802 xkbRowWireDesc *rowWire; 4803 4804 for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { 4805 rowWire = (xkbRowWireDesc *) wire; 4806 rowWire->top = row->top; 4807 rowWire->left = row->left; 4808 rowWire->nKeys = row->num_keys; 4809 rowWire->vertical = row->vertical; 4810 rowWire->pad = 0; 4811 if (swap) { 4812 swaps(&rowWire->top); 4813 swaps(&rowWire->left); 4814 } 4815 wire = (char *) &rowWire[1]; 4816 if (row->keys) { 4817 int k; 4818 XkbKeyPtr key; 4819 xkbKeyWireDesc *keyWire; 4820 4821 keyWire = (xkbKeyWireDesc *) wire; 4822 for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 4823 memcpy(keyWire[k].name, key->name.name, 4824 XkbKeyNameLength); 4825 keyWire[k].gap = key->gap; 4826 keyWire[k].shapeNdx = key->shape_ndx; 4827 keyWire[k].colorNdx = key->color_ndx; 4828 if (swap) { 4829 swaps(&keyWire[k].gap); 4830 } 4831 } 4832 wire = (char *) &keyWire[row->num_keys]; 4833 } 4834 } 4835 } 4836 if (section->doodads) { 4837 wire = XkbWriteGeomDoodads(wire, 4838 section->num_doodads, section->doodads, 4839 swap); 4840 } 4841 if (section->overlays) { 4842 register int o; 4843 4844 for (o = 0; o < section->num_overlays; o++) { 4845 wire = XkbWriteGeomOverlay(wire, §ion->overlays[o], swap); 4846 } 4847 } 4848 } 4849 return wire; 4850} 4851 4852static Status 4853XkbComputeGetGeometryReplySize(XkbGeometryPtr geom, 4854 xkbGetGeometryReply * rep, Atom name) 4855{ 4856 int len; 4857 4858 if (geom != NULL) { 4859 len = XkbSizeCountedString(geom->label_font); 4860 len += XkbSizeGeomProperties(geom); 4861 len += XkbSizeGeomColors(geom); 4862 len += XkbSizeGeomShapes(geom); 4863 len += XkbSizeGeomSections(geom); 4864 len += XkbSizeGeomDoodads(geom->num_doodads, geom->doodads); 4865 len += XkbSizeGeomKeyAliases(geom); 4866 rep->length = len / 4; 4867 rep->found = TRUE; 4868 rep->name = geom->name; 4869 rep->widthMM = geom->width_mm; 4870 rep->heightMM = geom->height_mm; 4871 rep->nProperties = geom->num_properties; 4872 rep->nColors = geom->num_colors; 4873 rep->nShapes = geom->num_shapes; 4874 rep->nSections = geom->num_sections; 4875 rep->nDoodads = geom->num_doodads; 4876 rep->nKeyAliases = geom->num_key_aliases; 4877 rep->baseColorNdx = XkbGeomColorIndex(geom, geom->base_color); 4878 rep->labelColorNdx = XkbGeomColorIndex(geom, geom->label_color); 4879 } 4880 else { 4881 rep->length = 0; 4882 rep->found = FALSE; 4883 rep->name = name; 4884 rep->widthMM = rep->heightMM = 0; 4885 rep->nProperties = rep->nColors = rep->nShapes = 0; 4886 rep->nSections = rep->nDoodads = 0; 4887 rep->nKeyAliases = 0; 4888 rep->labelColorNdx = rep->baseColorNdx = 0; 4889 } 4890 return Success; 4891} 4892static int 4893XkbSendGeometry(ClientPtr client, 4894 XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom) 4895{ 4896 char *desc, *start; 4897 int len; 4898 4899 if (geom != NULL) { 4900 start = desc = xallocarray(rep->length, 4); 4901 if (!start) 4902 return BadAlloc; 4903 len = rep->length * 4; 4904 desc = XkbWriteCountedString(desc, geom->label_font, client->swapped); 4905 if (rep->nProperties > 0) 4906 desc = XkbWriteGeomProperties(desc, geom, client->swapped); 4907 if (rep->nColors > 0) 4908 desc = XkbWriteGeomColors(desc, geom, client->swapped); 4909 if (rep->nShapes > 0) 4910 desc = XkbWriteGeomShapes(desc, geom, client->swapped); 4911 if (rep->nSections > 0) 4912 desc = XkbWriteGeomSections(desc, geom, client->swapped); 4913 if (rep->nDoodads > 0) 4914 desc = XkbWriteGeomDoodads(desc, geom->num_doodads, geom->doodads, 4915 client->swapped); 4916 if (rep->nKeyAliases > 0) 4917 desc = XkbWriteGeomKeyAliases(desc, geom, client->swapped); 4918 if ((desc - start) != (len)) { 4919 ErrorF 4920 ("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 4921 len, (unsigned long) (desc - start)); 4922 } 4923 } 4924 else { 4925 len = 0; 4926 start = NULL; 4927 } 4928 if (client->swapped) { 4929 swaps(&rep->sequenceNumber); 4930 swapl(&rep->length); 4931 swapl(&rep->name); 4932 swaps(&rep->widthMM); 4933 swaps(&rep->heightMM); 4934 swaps(&rep->nProperties); 4935 swaps(&rep->nColors); 4936 swaps(&rep->nShapes); 4937 swaps(&rep->nSections); 4938 swaps(&rep->nDoodads); 4939 swaps(&rep->nKeyAliases); 4940 } 4941 WriteToClient(client, SIZEOF(xkbGetGeometryReply), rep); 4942 if (len > 0) 4943 WriteToClient(client, len, start); 4944 if (start != NULL) 4945 free((char *) start); 4946 if (freeGeom) 4947 XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 4948 return Success; 4949} 4950 4951int 4952ProcXkbGetGeometry(ClientPtr client) 4953{ 4954 DeviceIntPtr dev; 4955 xkbGetGeometryReply rep; 4956 XkbGeometryPtr geom; 4957 Bool shouldFree; 4958 Status status; 4959 4960 REQUEST(xkbGetGeometryReq); 4961 REQUEST_SIZE_MATCH(xkbGetGeometryReq); 4962 4963 if (!(client->xkbClientFlags & _XkbClientInitialized)) 4964 return BadAccess; 4965 4966 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 4967 CHK_ATOM_OR_NONE(stuff->name); 4968 4969 geom = XkbLookupNamedGeometry(dev, stuff->name, &shouldFree); 4970 rep = (xkbGetGeometryReply) { 4971 .type = X_Reply, 4972 .deviceID = dev->id, 4973 .sequenceNumber = client->sequence, 4974 .length = 0 4975 }; 4976 status = XkbComputeGetGeometryReplySize(geom, &rep, stuff->name); 4977 if (status != Success) 4978 return status; 4979 else 4980 return XkbSendGeometry(client, geom, &rep, shouldFree); 4981} 4982 4983/***====================================================================***/ 4984 4985static Status 4986_GetCountedString(char **wire_inout, ClientPtr client, char **str) 4987{ 4988 char *wire, *next; 4989 CARD16 len; 4990 4991 wire = *wire_inout; 4992 len = *(CARD16 *) wire; 4993 if (client->swapped) { 4994 swaps(&len); 4995 } 4996 next = wire + XkbPaddedSize(len + 2); 4997 /* Check we're still within the size of the request */ 4998 if (client->req_len < 4999 bytes_to_int32(next - (char *) client->requestBuffer)) 5000 return BadValue; 5001 *str = malloc(len + 1); 5002 if (!*str) 5003 return BadAlloc; 5004 memcpy(*str, &wire[2], len); 5005 *(*str + len) = '\0'; 5006 *wire_inout = next; 5007 return Success; 5008} 5009 5010static Status 5011_CheckSetDoodad(char **wire_inout, 5012 XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 5013{ 5014 char *wire; 5015 xkbDoodadWireDesc *dWire; 5016 xkbAnyDoodadWireDesc any; 5017 xkbTextDoodadWireDesc text; 5018 XkbDoodadPtr doodad; 5019 Status status; 5020 5021 dWire = (xkbDoodadWireDesc *) (*wire_inout); 5022 any = dWire->any; 5023 wire = (char *) &dWire[1]; 5024 if (client->swapped) { 5025 swapl(&any.name); 5026 swaps(&any.top); 5027 swaps(&any.left); 5028 swaps(&any.angle); 5029 } 5030 CHK_ATOM_ONLY(dWire->any.name); 5031 doodad = XkbAddGeomDoodad(geom, section, any.name); 5032 if (!doodad) 5033 return BadAlloc; 5034 doodad->any.type = dWire->any.type; 5035 doodad->any.priority = dWire->any.priority; 5036 doodad->any.top = any.top; 5037 doodad->any.left = any.left; 5038 doodad->any.angle = any.angle; 5039 switch (doodad->any.type) { 5040 case XkbOutlineDoodad: 5041 case XkbSolidDoodad: 5042 if (dWire->shape.colorNdx >= geom->num_colors) { 5043 client->errorValue = _XkbErrCode3(0x40, geom->num_colors, 5044 dWire->shape.colorNdx); 5045 return BadMatch; 5046 } 5047 if (dWire->shape.shapeNdx >= geom->num_shapes) { 5048 client->errorValue = _XkbErrCode3(0x41, geom->num_shapes, 5049 dWire->shape.shapeNdx); 5050 return BadMatch; 5051 } 5052 doodad->shape.color_ndx = dWire->shape.colorNdx; 5053 doodad->shape.shape_ndx = dWire->shape.shapeNdx; 5054 break; 5055 case XkbTextDoodad: 5056 if (dWire->text.colorNdx >= geom->num_colors) { 5057 client->errorValue = _XkbErrCode3(0x42, geom->num_colors, 5058 dWire->text.colorNdx); 5059 return BadMatch; 5060 } 5061 text = dWire->text; 5062 if (client->swapped) { 5063 swaps(&text.width); 5064 swaps(&text.height); 5065 } 5066 doodad->text.width = text.width; 5067 doodad->text.height = text.height; 5068 doodad->text.color_ndx = dWire->text.colorNdx; 5069 status = _GetCountedString(&wire, client, &doodad->text.text); 5070 if (status != Success) 5071 return status; 5072 status = _GetCountedString(&wire, client, &doodad->text.font); 5073 if (status != Success) { 5074 free (doodad->text.text); 5075 return status; 5076 } 5077 break; 5078 case XkbIndicatorDoodad: 5079 if (dWire->indicator.onColorNdx >= geom->num_colors) { 5080 client->errorValue = _XkbErrCode3(0x43, geom->num_colors, 5081 dWire->indicator.onColorNdx); 5082 return BadMatch; 5083 } 5084 if (dWire->indicator.offColorNdx >= geom->num_colors) { 5085 client->errorValue = _XkbErrCode3(0x44, geom->num_colors, 5086 dWire->indicator.offColorNdx); 5087 return BadMatch; 5088 } 5089 if (dWire->indicator.shapeNdx >= geom->num_shapes) { 5090 client->errorValue = _XkbErrCode3(0x45, geom->num_shapes, 5091 dWire->indicator.shapeNdx); 5092 return BadMatch; 5093 } 5094 doodad->indicator.shape_ndx = dWire->indicator.shapeNdx; 5095 doodad->indicator.on_color_ndx = dWire->indicator.onColorNdx; 5096 doodad->indicator.off_color_ndx = dWire->indicator.offColorNdx; 5097 break; 5098 case XkbLogoDoodad: 5099 if (dWire->logo.colorNdx >= geom->num_colors) { 5100 client->errorValue = _XkbErrCode3(0x46, geom->num_colors, 5101 dWire->logo.colorNdx); 5102 return BadMatch; 5103 } 5104 if (dWire->logo.shapeNdx >= geom->num_shapes) { 5105 client->errorValue = _XkbErrCode3(0x47, geom->num_shapes, 5106 dWire->logo.shapeNdx); 5107 return BadMatch; 5108 } 5109 doodad->logo.color_ndx = dWire->logo.colorNdx; 5110 doodad->logo.shape_ndx = dWire->logo.shapeNdx; 5111 status = _GetCountedString(&wire, client, &doodad->logo.logo_name); 5112 if (status != Success) 5113 return status; 5114 break; 5115 default: 5116 client->errorValue = _XkbErrCode2(0x4F, dWire->any.type); 5117 return BadValue; 5118 } 5119 *wire_inout = wire; 5120 return Success; 5121} 5122 5123static Status 5124_CheckSetOverlay(char **wire_inout, 5125 XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) 5126{ 5127 register int r; 5128 char *wire; 5129 XkbOverlayPtr ol; 5130 xkbOverlayWireDesc *olWire; 5131 xkbOverlayRowWireDesc *rWire; 5132 5133 wire = *wire_inout; 5134 olWire = (xkbOverlayWireDesc *) wire; 5135 if (client->swapped) { 5136 swapl(&olWire->name); 5137 } 5138 CHK_ATOM_ONLY(olWire->name); 5139 ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows); 5140 rWire = (xkbOverlayRowWireDesc *) &olWire[1]; 5141 for (r = 0; r < olWire->nRows; r++) { 5142 register int k; 5143 xkbOverlayKeyWireDesc *kWire; 5144 XkbOverlayRowPtr row; 5145 5146 if (rWire->rowUnder > section->num_rows) { 5147 client->errorValue = _XkbErrCode4(0x20, r, section->num_rows, 5148 rWire->rowUnder); 5149 return BadMatch; 5150 } 5151 row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys); 5152 kWire = (xkbOverlayKeyWireDesc *) &rWire[1]; 5153 for (k = 0; k < rWire->nKeys; k++, kWire++) { 5154 if (XkbAddGeomOverlayKey(ol, row, 5155 (char *) kWire->over, 5156 (char *) kWire->under) == NULL) { 5157 client->errorValue = _XkbErrCode3(0x21, r, k); 5158 return BadMatch; 5159 } 5160 } 5161 rWire = (xkbOverlayRowWireDesc *) kWire; 5162 } 5163 olWire = (xkbOverlayWireDesc *) rWire; 5164 wire = (char *) olWire; 5165 *wire_inout = wire; 5166 return Success; 5167} 5168 5169static Status 5170_CheckSetSections(XkbGeometryPtr geom, 5171 xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5172{ 5173 Status status; 5174 register int s; 5175 char *wire; 5176 xkbSectionWireDesc *sWire; 5177 XkbSectionPtr section; 5178 5179 wire = *wire_inout; 5180 if (req->nSections < 1) 5181 return Success; 5182 sWire = (xkbSectionWireDesc *) wire; 5183 for (s = 0; s < req->nSections; s++) { 5184 register int r; 5185 xkbRowWireDesc *rWire; 5186 5187 if (client->swapped) { 5188 swapl(&sWire->name); 5189 swaps(&sWire->top); 5190 swaps(&sWire->left); 5191 swaps(&sWire->width); 5192 swaps(&sWire->height); 5193 swaps(&sWire->angle); 5194 } 5195 CHK_ATOM_ONLY(sWire->name); 5196 section = XkbAddGeomSection(geom, sWire->name, sWire->nRows, 5197 sWire->nDoodads, sWire->nOverlays); 5198 if (!section) 5199 return BadAlloc; 5200 section->priority = sWire->priority; 5201 section->top = sWire->top; 5202 section->left = sWire->left; 5203 section->width = sWire->width; 5204 section->height = sWire->height; 5205 section->angle = sWire->angle; 5206 rWire = (xkbRowWireDesc *) &sWire[1]; 5207 for (r = 0; r < sWire->nRows; r++) { 5208 register int k; 5209 XkbRowPtr row; 5210 xkbKeyWireDesc *kWire; 5211 5212 if (client->swapped) { 5213 swaps(&rWire->top); 5214 swaps(&rWire->left); 5215 } 5216 row = XkbAddGeomRow(section, rWire->nKeys); 5217 if (!row) 5218 return BadAlloc; 5219 row->top = rWire->top; 5220 row->left = rWire->left; 5221 row->vertical = rWire->vertical; 5222 kWire = (xkbKeyWireDesc *) &rWire[1]; 5223 for (k = 0; k < rWire->nKeys; k++) { 5224 XkbKeyPtr key; 5225 5226 key = XkbAddGeomKey(row); 5227 if (!key) 5228 return BadAlloc; 5229 memcpy(key->name.name, kWire[k].name, XkbKeyNameLength); 5230 key->gap = kWire[k].gap; 5231 key->shape_ndx = kWire[k].shapeNdx; 5232 key->color_ndx = kWire[k].colorNdx; 5233 if (key->shape_ndx >= geom->num_shapes) { 5234 client->errorValue = _XkbErrCode3(0x10, key->shape_ndx, 5235 geom->num_shapes); 5236 return BadMatch; 5237 } 5238 if (key->color_ndx >= geom->num_colors) { 5239 client->errorValue = _XkbErrCode3(0x11, key->color_ndx, 5240 geom->num_colors); 5241 return BadMatch; 5242 } 5243 } 5244 rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys]; 5245 } 5246 wire = (char *) rWire; 5247 if (sWire->nDoodads > 0) { 5248 register int d; 5249 5250 for (d = 0; d < sWire->nDoodads; d++) { 5251 status = _CheckSetDoodad(&wire, geom, section, client); 5252 if (status != Success) 5253 return status; 5254 } 5255 } 5256 if (sWire->nOverlays > 0) { 5257 register int o; 5258 5259 for (o = 0; o < sWire->nOverlays; o++) { 5260 status = _CheckSetOverlay(&wire, geom, section, client); 5261 if (status != Success) 5262 return status; 5263 } 5264 } 5265 sWire = (xkbSectionWireDesc *) wire; 5266 } 5267 wire = (char *) sWire; 5268 *wire_inout = wire; 5269 return Success; 5270} 5271 5272static Status 5273_CheckSetShapes(XkbGeometryPtr geom, 5274 xkbSetGeometryReq * req, char **wire_inout, ClientPtr client) 5275{ 5276 register int i; 5277 char *wire; 5278 5279 wire = *wire_inout; 5280 if (req->nShapes < 1) { 5281 client->errorValue = _XkbErrCode2(0x06, req->nShapes); 5282 return BadValue; 5283 } 5284 else { 5285 xkbShapeWireDesc *shapeWire; 5286 XkbShapePtr shape; 5287 register int o; 5288 5289 shapeWire = (xkbShapeWireDesc *) wire; 5290 for (i = 0; i < req->nShapes; i++) { 5291 xkbOutlineWireDesc *olWire; 5292 XkbOutlinePtr ol; 5293 5294 shape = 5295 XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); 5296 if (!shape) 5297 return BadAlloc; 5298 olWire = (xkbOutlineWireDesc *) (&shapeWire[1]); 5299 for (o = 0; o < shapeWire->nOutlines; o++) { 5300 register int p; 5301 XkbPointPtr pt; 5302 xkbPointWireDesc *ptWire; 5303 5304 ol = XkbAddGeomOutline(shape, olWire->nPoints); 5305 if (!ol) 5306 return BadAlloc; 5307 ol->corner_radius = olWire->cornerRadius; 5308 ptWire = (xkbPointWireDesc *) &olWire[1]; 5309 for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { 5310 pt->x = ptWire[p].x; 5311 pt->y = ptWire[p].y; 5312 if (client->swapped) { 5313 swaps(&pt->x); 5314 swaps(&pt->y); 5315 } 5316 } 5317 ol->num_points = olWire->nPoints; 5318 olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]); 5319 } 5320 if (shapeWire->primaryNdx != XkbNoShape) 5321 shape->primary = &shape->outlines[shapeWire->primaryNdx]; 5322 if (shapeWire->approxNdx != XkbNoShape) 5323 shape->approx = &shape->outlines[shapeWire->approxNdx]; 5324 shapeWire = (xkbShapeWireDesc *) olWire; 5325 } 5326 wire = (char *) shapeWire; 5327 } 5328 if (geom->num_shapes != req->nShapes) { 5329 client->errorValue = _XkbErrCode3(0x07, geom->num_shapes, req->nShapes); 5330 return BadMatch; 5331 } 5332 5333 *wire_inout = wire; 5334 return Success; 5335} 5336 5337static Status 5338_CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client) 5339{ 5340 register int i; 5341 Status status; 5342 char *wire; 5343 5344 wire = (char *) &req[1]; 5345 status = _GetCountedString(&wire, client, &geom->label_font); 5346 if (status != Success) 5347 return status; 5348 5349 for (i = 0; i < req->nProperties; i++) { 5350 char *name, *val; 5351 5352 status = _GetCountedString(&wire, client, &name); 5353 if (status != Success) 5354 return status; 5355 status = _GetCountedString(&wire, client, &val); 5356 if (status != Success) { 5357 free(name); 5358 return status; 5359 } 5360 if (XkbAddGeomProperty(geom, name, val) == NULL) { 5361 free(name); 5362 free(val); 5363 return BadAlloc; 5364 } 5365 free(name); 5366 free(val); 5367 } 5368 5369 if (req->nColors < 2) { 5370 client->errorValue = _XkbErrCode3(0x01, 2, req->nColors); 5371 return BadValue; 5372 } 5373 if (req->baseColorNdx > req->nColors) { 5374 client->errorValue = 5375 _XkbErrCode3(0x03, req->nColors, req->baseColorNdx); 5376 return BadMatch; 5377 } 5378 if (req->labelColorNdx > req->nColors) { 5379 client->errorValue = 5380 _XkbErrCode3(0x03, req->nColors, req->labelColorNdx); 5381 return BadMatch; 5382 } 5383 if (req->labelColorNdx == req->baseColorNdx) { 5384 client->errorValue = _XkbErrCode3(0x04, req->baseColorNdx, 5385 req->labelColorNdx); 5386 return BadMatch; 5387 } 5388 5389 for (i = 0; i < req->nColors; i++) { 5390 char *name; 5391 5392 status = _GetCountedString(&wire, client, &name); 5393 if (status != Success) 5394 return status; 5395 if (!XkbAddGeomColor(geom, name, geom->num_colors)) { 5396 free(name); 5397 return BadAlloc; 5398 } 5399 free(name); 5400 } 5401 if (req->nColors != geom->num_colors) { 5402 client->errorValue = _XkbErrCode3(0x05, req->nColors, geom->num_colors); 5403 return BadMatch; 5404 } 5405 geom->label_color = &geom->colors[req->labelColorNdx]; 5406 geom->base_color = &geom->colors[req->baseColorNdx]; 5407 5408 if ((status = _CheckSetShapes(geom, req, &wire, client)) != Success) 5409 return status; 5410 5411 if ((status = _CheckSetSections(geom, req, &wire, client)) != Success) 5412 return status; 5413 5414 for (i = 0; i < req->nDoodads; i++) { 5415 status = _CheckSetDoodad(&wire, geom, NULL, client); 5416 if (status != Success) 5417 return status; 5418 } 5419 5420 for (i = 0; i < req->nKeyAliases; i++) { 5421 if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL) 5422 return BadAlloc; 5423 wire += 2 * XkbKeyNameLength; 5424 } 5425 return Success; 5426} 5427 5428static int 5429_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq * stuff) 5430{ 5431 XkbDescPtr xkb; 5432 Bool new_name; 5433 xkbNewKeyboardNotify nkn; 5434 XkbGeometryPtr geom, old; 5435 XkbGeometrySizesRec sizes; 5436 Status status; 5437 5438 xkb = dev->key->xkbInfo->desc; 5439 old = xkb->geom; 5440 xkb->geom = NULL; 5441 5442 sizes.which = XkbGeomAllMask; 5443 sizes.num_properties = stuff->nProperties; 5444 sizes.num_colors = stuff->nColors; 5445 sizes.num_shapes = stuff->nShapes; 5446 sizes.num_sections = stuff->nSections; 5447 sizes.num_doodads = stuff->nDoodads; 5448 sizes.num_key_aliases = stuff->nKeyAliases; 5449 if ((status = XkbAllocGeometry(xkb, &sizes)) != Success) { 5450 xkb->geom = old; 5451 return status; 5452 } 5453 geom = xkb->geom; 5454 geom->name = stuff->name; 5455 geom->width_mm = stuff->widthMM; 5456 geom->height_mm = stuff->heightMM; 5457 if ((status = _CheckSetGeom(geom, stuff, client)) != Success) { 5458 XkbFreeGeometry(geom, XkbGeomAllMask, TRUE); 5459 xkb->geom = old; 5460 return status; 5461 } 5462 new_name = (xkb->names->geometry != geom->name); 5463 xkb->names->geometry = geom->name; 5464 if (old) 5465 XkbFreeGeometry(old, XkbGeomAllMask, TRUE); 5466 if (new_name) { 5467 xkbNamesNotify nn; 5468 5469 memset(&nn, 0, sizeof(xkbNamesNotify)); 5470 nn.changed = XkbGeometryNameMask; 5471 XkbSendNamesNotify(dev, &nn); 5472 } 5473 nkn.deviceID = nkn.oldDeviceID = dev->id; 5474 nkn.minKeyCode = nkn.oldMinKeyCode = xkb->min_key_code; 5475 nkn.maxKeyCode = nkn.oldMaxKeyCode = xkb->max_key_code; 5476 nkn.requestMajor = XkbReqCode; 5477 nkn.requestMinor = X_kbSetGeometry; 5478 nkn.changed = XkbNKN_GeometryMask; 5479 XkbSendNewKeyboardNotify(dev, &nkn); 5480 return Success; 5481} 5482 5483int 5484ProcXkbSetGeometry(ClientPtr client) 5485{ 5486 DeviceIntPtr dev; 5487 int rc; 5488 5489 REQUEST(xkbSetGeometryReq); 5490 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 5491 5492 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5493 return BadAccess; 5494 5495 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 5496 CHK_ATOM_OR_NONE(stuff->name); 5497 5498 rc = _XkbSetGeometry(client, dev, stuff); 5499 if (rc != Success) 5500 return rc; 5501 5502 if (stuff->deviceSpec == XkbUseCoreKbd) { 5503 DeviceIntPtr other; 5504 5505 for (other = inputInfo.devices; other; other = other->next) { 5506 if ((other != dev) && other->key && !IsMaster(other) && 5507 GetMaster(other, MASTER_KEYBOARD) == dev) { 5508 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 5509 DixManageAccess); 5510 if (rc == Success) 5511 _XkbSetGeometry(client, other, stuff); 5512 } 5513 } 5514 } 5515 5516 return Success; 5517} 5518 5519/***====================================================================***/ 5520 5521int 5522ProcXkbPerClientFlags(ClientPtr client) 5523{ 5524 DeviceIntPtr dev; 5525 xkbPerClientFlagsReply rep; 5526 XkbInterestPtr interest; 5527 Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 5528 5529 REQUEST(xkbPerClientFlagsReq); 5530 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 5531 5532 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5533 return BadAccess; 5534 5535 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5536 CHK_MASK_LEGAL(0x01, stuff->change, XkbPCF_AllFlagsMask); 5537 CHK_MASK_MATCH(0x02, stuff->change, stuff->value); 5538 5539 interest = XkbFindClientResource((DevicePtr) dev, client); 5540 if (stuff->change) { 5541 client->xkbClientFlags &= ~stuff->change; 5542 client->xkbClientFlags |= stuff->value; 5543 } 5544 if (stuff->change & XkbPCF_AutoResetControlsMask) { 5545 Bool want; 5546 5547 want = stuff->value & XkbPCF_AutoResetControlsMask; 5548 if (interest && !want) { 5549 interest->autoCtrls = interest->autoCtrlValues = 0; 5550 } 5551 else if (want && (!interest)) { 5552 XID id = FakeClientID(client->index); 5553 5554 if (!AddResource(id, RT_XKBCLIENT, dev)) 5555 return BadAlloc; 5556 interest = XkbAddClientResource((DevicePtr) dev, client, id); 5557 if (!interest) 5558 return BadAlloc; 5559 } 5560 if (interest && want) { 5561 register unsigned affect; 5562 5563 affect = stuff->ctrlsToChange; 5564 5565 CHK_MASK_LEGAL(0x03, affect, XkbAllBooleanCtrlsMask); 5566 CHK_MASK_MATCH(0x04, affect, stuff->autoCtrls); 5567 CHK_MASK_MATCH(0x05, stuff->autoCtrls, stuff->autoCtrlValues); 5568 5569 interest->autoCtrls &= ~affect; 5570 interest->autoCtrlValues &= ~affect; 5571 interest->autoCtrls |= stuff->autoCtrls & affect; 5572 interest->autoCtrlValues |= stuff->autoCtrlValues & affect; 5573 } 5574 } 5575 5576 rep = (xkbPerClientFlagsReply) { 5577 .type = X_Reply, 5578 .sequenceNumber = client->sequence, 5579 .length = 0, 5580 .supported = XkbPCF_AllFlagsMask, 5581 .value = client->xkbClientFlags & XkbPCF_AllFlagsMask, 5582 .autoCtrls = interest ? interest->autoCtrls : 0, 5583 .autoCtrlValues = interest ? interest->autoCtrlValues : 0, 5584 }; 5585 if (client->swapped) { 5586 swaps(&rep.sequenceNumber); 5587 swapl(&rep.supported); 5588 swapl(&rep.value); 5589 swapl(&rep.autoCtrls); 5590 swapl(&rep.autoCtrlValues); 5591 } 5592 WriteToClient(client, SIZEOF(xkbPerClientFlagsReply), &rep); 5593 return Success; 5594} 5595 5596/***====================================================================***/ 5597 5598/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 5599/* and wildcards */ 5600static unsigned char componentSpecLegal[] = { 5601 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 5602 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 5603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5604 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5605}; 5606 5607/* same as above but accepts percent, plus and bar too */ 5608static unsigned char componentExprLegal[] = { 5609 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 5610 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 5611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5612 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5613}; 5614 5615static char * 5616GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn) 5617{ 5618 int len; 5619 register int i; 5620 unsigned char *wire, *str, *tmp, *legal; 5621 5622 if (allowExpr) 5623 legal = &componentExprLegal[0]; 5624 else 5625 legal = &componentSpecLegal[0]; 5626 5627 wire = *pWire; 5628 len = (*(unsigned char *) wire++); 5629 if (len > 0) { 5630 str = calloc(1, len + 1); 5631 if (str) { 5632 tmp = str; 5633 for (i = 0; i < len; i++) { 5634 if (legal[(*wire) / 8] & (1 << ((*wire) % 8))) 5635 *tmp++ = *wire++; 5636 else 5637 wire++; 5638 } 5639 if (tmp != str) 5640 *tmp++ = '\0'; 5641 else { 5642 free(str); 5643 str = NULL; 5644 } 5645 } 5646 else { 5647 *errRtrn = BadAlloc; 5648 } 5649 } 5650 else { 5651 str = NULL; 5652 } 5653 *pWire = wire; 5654 return (char *) str; 5655} 5656 5657/***====================================================================***/ 5658 5659int 5660ProcXkbListComponents(ClientPtr client) 5661{ 5662 DeviceIntPtr dev; 5663 xkbListComponentsReply rep; 5664 unsigned len; 5665 unsigned char *str; 5666 uint8_t size; 5667 int i; 5668 5669 REQUEST(xkbListComponentsReq); 5670 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 5671 5672 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5673 return BadAccess; 5674 5675 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 5676 5677 /* The request is followed by six Pascal strings (i.e. size in characters 5678 * followed by a string pattern) describing what the client wants us to 5679 * list. We don't care, but might as well check they haven't got the 5680 * length wrong. */ 5681 str = (unsigned char *) &stuff[1]; 5682 for (i = 0; i < 6; i++) { 5683 size = *((uint8_t *)str); 5684 len = (str + size + 1) - ((unsigned char *) stuff); 5685 if ((XkbPaddedSize(len) / 4) > stuff->length) 5686 return BadLength; 5687 str += (size + 1); 5688 } 5689 if ((XkbPaddedSize(len) / 4) != stuff->length) 5690 return BadLength; 5691 rep = (xkbListComponentsReply) { 5692 .type = X_Reply, 5693 .deviceID = dev->id, 5694 .sequenceNumber = client->sequence, 5695 .length = 0, 5696 .nKeymaps = 0, 5697 .nKeycodes = 0, 5698 .nTypes = 0, 5699 .nCompatMaps = 0, 5700 .nSymbols = 0, 5701 .nGeometries = 0, 5702 .extra = 0 5703 }; 5704 if (client->swapped) { 5705 swaps(&rep.sequenceNumber); 5706 swapl(&rep.length); 5707 swaps(&rep.nKeymaps); 5708 swaps(&rep.nKeycodes); 5709 swaps(&rep.nTypes); 5710 swaps(&rep.nCompatMaps); 5711 swaps(&rep.nSymbols); 5712 swaps(&rep.nGeometries); 5713 swaps(&rep.extra); 5714 } 5715 WriteToClient(client, SIZEOF(xkbListComponentsReply), &rep); 5716 return Success; 5717} 5718 5719/***====================================================================***/ 5720int 5721ProcXkbGetKbdByName(ClientPtr client) 5722{ 5723 DeviceIntPtr dev; 5724 DeviceIntPtr tmpd; 5725 DeviceIntPtr master; 5726 xkbGetKbdByNameReply rep = { 0 }; 5727 xkbGetMapReply mrep = { 0 }; 5728 xkbGetCompatMapReply crep = { 0 }; 5729 xkbGetIndicatorMapReply irep = { 0 }; 5730 xkbGetNamesReply nrep = { 0 }; 5731 xkbGetGeometryReply grep = { 0 }; 5732 XkbComponentNamesRec names = { 0 }; 5733 XkbDescPtr xkb, new; 5734 XkbEventCauseRec cause; 5735 unsigned char *str; 5736 char mapFile[PATH_MAX]; 5737 unsigned len; 5738 unsigned fwant, fneed, reported; 5739 int status; 5740 Bool geom_changed; 5741 XkbSrvLedInfoPtr old_sli; 5742 XkbSrvLedInfoPtr sli; 5743 Mask access_mode = DixGetAttrAccess | DixManageAccess; 5744 5745 REQUEST(xkbGetKbdByNameReq); 5746 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 5747 5748 if (!(client->xkbClientFlags & _XkbClientInitialized)) 5749 return BadAccess; 5750 5751 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5752 master = GetMaster(dev, MASTER_KEYBOARD); 5753 5754 xkb = dev->key->xkbInfo->desc; 5755 status = Success; 5756 str = (unsigned char *) &stuff[1]; 5757 if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */ 5758 return BadMatch; 5759 names.keycodes = GetComponentSpec(&str, TRUE, &status); 5760 names.types = GetComponentSpec(&str, TRUE, &status); 5761 names.compat = GetComponentSpec(&str, TRUE, &status); 5762 names.symbols = GetComponentSpec(&str, TRUE, &status); 5763 names.geometry = GetComponentSpec(&str, TRUE, &status); 5764 if (status != Success) 5765 return status; 5766 len = str - ((unsigned char *) stuff); 5767 if ((XkbPaddedSize(len) / 4) != stuff->length) 5768 return BadLength; 5769 5770 CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask); 5771 CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask); 5772 5773 if (stuff->load) 5774 fwant = XkbGBN_AllComponentsMask; 5775 else 5776 fwant = stuff->want | stuff->need; 5777 if ((!names.compat) && 5778 (fwant & (XkbGBN_CompatMapMask | XkbGBN_IndicatorMapMask))) { 5779 names.compat = Xstrdup("%"); 5780 } 5781 if ((!names.types) && (fwant & (XkbGBN_TypesMask))) { 5782 names.types = Xstrdup("%"); 5783 } 5784 if ((!names.symbols) && (fwant & XkbGBN_SymbolsMask)) { 5785 names.symbols = Xstrdup("%"); 5786 } 5787 geom_changed = ((names.geometry != NULL) && 5788 (strcmp(names.geometry, "%") != 0)); 5789 if ((!names.geometry) && (fwant & XkbGBN_GeometryMask)) { 5790 names.geometry = Xstrdup("%"); 5791 geom_changed = FALSE; 5792 } 5793 5794 memset(mapFile, 0, PATH_MAX); 5795 rep.type = X_Reply; 5796 rep.deviceID = dev->id; 5797 rep.sequenceNumber = client->sequence; 5798 rep.length = 0; 5799 rep.minKeyCode = xkb->min_key_code; 5800 rep.maxKeyCode = xkb->max_key_code; 5801 rep.loaded = FALSE; 5802 fwant = 5803 XkbConvertGetByNameComponents(TRUE, stuff->want) | XkmVirtualModsMask; 5804 fneed = XkbConvertGetByNameComponents(TRUE, stuff->need); 5805 rep.reported = XkbConvertGetByNameComponents(FALSE, fwant | fneed); 5806 if (stuff->load) { 5807 fneed |= XkmKeymapRequired; 5808 fwant |= XkmKeymapLegal; 5809 } 5810 if ((fwant | fneed) & XkmSymbolsMask) { 5811 fneed |= XkmKeyNamesIndex | XkmTypesIndex; 5812 fwant |= XkmIndicatorsIndex; 5813 } 5814 5815 /* We pass dev in here so we can get the old names out if needed. */ 5816 rep.found = XkbDDXLoadKeymapByNames(dev, &names, fwant, fneed, &new, 5817 mapFile, PATH_MAX); 5818 rep.newKeyboard = FALSE; 5819 rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0; 5820 5821 stuff->want |= stuff->need; 5822 if (new == NULL) 5823 rep.reported = 0; 5824 else { 5825 if (stuff->load) 5826 rep.loaded = TRUE; 5827 if (stuff->load || 5828 ((rep.reported & XkbGBN_SymbolsMask) && (new->compat))) { 5829 XkbChangesRec changes; 5830 5831 memset(&changes, 0, sizeof(changes)); 5832 XkbUpdateDescActions(new, 5833 new->min_key_code, XkbNumKeys(new), &changes); 5834 } 5835 5836 if (new->map == NULL) 5837 rep.reported &= ~(XkbGBN_SymbolsMask | XkbGBN_TypesMask); 5838 else if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) { 5839 mrep.type = X_Reply; 5840 mrep.deviceID = dev->id; 5841 mrep.sequenceNumber = client->sequence; 5842 mrep.length = 5843 ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2); 5844 mrep.minKeyCode = new->min_key_code; 5845 mrep.maxKeyCode = new->max_key_code; 5846 mrep.present = 0; 5847 mrep.totalSyms = mrep.totalActs = 5848 mrep.totalKeyBehaviors = mrep.totalKeyExplicit = 5849 mrep.totalModMapKeys = mrep.totalVModMapKeys = 0; 5850 if (rep.reported & (XkbGBN_TypesMask | XkbGBN_ClientSymbolsMask)) { 5851 mrep.present |= XkbKeyTypesMask; 5852 mrep.firstType = 0; 5853 mrep.nTypes = mrep.totalTypes = new->map->num_types; 5854 } 5855 else { 5856 mrep.firstType = mrep.nTypes = 0; 5857 mrep.totalTypes = 0; 5858 } 5859 if (rep.reported & XkbGBN_ClientSymbolsMask) { 5860 mrep.present |= (XkbKeySymsMask | XkbModifierMapMask); 5861 mrep.firstKeySym = mrep.firstModMapKey = new->min_key_code; 5862 mrep.nKeySyms = mrep.nModMapKeys = XkbNumKeys(new); 5863 } 5864 else { 5865 mrep.firstKeySym = mrep.firstModMapKey = 0; 5866 mrep.nKeySyms = mrep.nModMapKeys = 0; 5867 } 5868 if (rep.reported & XkbGBN_ServerSymbolsMask) { 5869 mrep.present |= XkbAllServerInfoMask; 5870 mrep.virtualMods = ~0; 5871 mrep.firstKeyAct = mrep.firstKeyBehavior = 5872 mrep.firstKeyExplicit = new->min_key_code; 5873 mrep.nKeyActs = mrep.nKeyBehaviors = 5874 mrep.nKeyExplicit = XkbNumKeys(new); 5875 mrep.firstVModMapKey = new->min_key_code; 5876 mrep.nVModMapKeys = XkbNumKeys(new); 5877 } 5878 else { 5879 mrep.virtualMods = 0; 5880 mrep.firstKeyAct = mrep.firstKeyBehavior = 5881 mrep.firstKeyExplicit = 0; 5882 mrep.nKeyActs = mrep.nKeyBehaviors = mrep.nKeyExplicit = 0; 5883 } 5884 XkbComputeGetMapReplySize(new, &mrep); 5885 rep.length += SIZEOF(xGenericReply) / 4 + mrep.length; 5886 } 5887 if (new->compat == NULL) 5888 rep.reported &= ~XkbGBN_CompatMapMask; 5889 else if (rep.reported & XkbGBN_CompatMapMask) { 5890 crep.type = X_Reply; 5891 crep.deviceID = dev->id; 5892 crep.sequenceNumber = client->sequence; 5893 crep.length = 0; 5894 crep.groups = XkbAllGroupsMask; 5895 crep.firstSI = 0; 5896 crep.nSI = crep.nTotalSI = new->compat->num_si; 5897 XkbComputeGetCompatMapReplySize(new->compat, &crep); 5898 rep.length += SIZEOF(xGenericReply) / 4 + crep.length; 5899 } 5900 if (new->indicators == NULL) 5901 rep.reported &= ~XkbGBN_IndicatorMapMask; 5902 else if (rep.reported & XkbGBN_IndicatorMapMask) { 5903 irep.type = X_Reply; 5904 irep.deviceID = dev->id; 5905 irep.sequenceNumber = client->sequence; 5906 irep.length = 0; 5907 irep.which = XkbAllIndicatorsMask; 5908 XkbComputeGetIndicatorMapReplySize(new->indicators, &irep); 5909 rep.length += SIZEOF(xGenericReply) / 4 + irep.length; 5910 } 5911 if (new->names == NULL) 5912 rep.reported &= ~(XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask); 5913 else if (rep.reported & (XkbGBN_OtherNamesMask | XkbGBN_KeyNamesMask)) { 5914 nrep.type = X_Reply; 5915 nrep.deviceID = dev->id; 5916 nrep.sequenceNumber = client->sequence; 5917 nrep.length = 0; 5918 nrep.minKeyCode = new->min_key_code; 5919 nrep.maxKeyCode = new->max_key_code; 5920 if (rep.reported & XkbGBN_OtherNamesMask) { 5921 nrep.which = XkbAllNamesMask; 5922 if (new->map != NULL) 5923 nrep.nTypes = new->map->num_types; 5924 else 5925 nrep.nTypes = 0; 5926 nrep.nKTLevels = 0; 5927 nrep.groupNames = XkbAllGroupsMask; 5928 nrep.virtualMods = XkbAllVirtualModsMask; 5929 nrep.indicators = XkbAllIndicatorsMask; 5930 nrep.nRadioGroups = new->names->num_rg; 5931 } 5932 else { 5933 nrep.which = 0; 5934 nrep.nTypes = 0; 5935 nrep.nKTLevels = 0; 5936 nrep.groupNames = 0; 5937 nrep.virtualMods = 0; 5938 nrep.indicators = 0; 5939 nrep.nRadioGroups = 0; 5940 } 5941 if (rep.reported & XkbGBN_KeyNamesMask) { 5942 nrep.which |= XkbKeyNamesMask; 5943 nrep.firstKey = new->min_key_code; 5944 nrep.nKeys = XkbNumKeys(new); 5945 nrep.nKeyAliases = new->names->num_key_aliases; 5946 if (nrep.nKeyAliases) 5947 nrep.which |= XkbKeyAliasesMask; 5948 } 5949 else { 5950 nrep.which &= ~(XkbKeyNamesMask | XkbKeyAliasesMask); 5951 nrep.firstKey = nrep.nKeys = 0; 5952 nrep.nKeyAliases = 0; 5953 } 5954 XkbComputeGetNamesReplySize(new, &nrep); 5955 rep.length += SIZEOF(xGenericReply) / 4 + nrep.length; 5956 } 5957 if (new->geom == NULL) 5958 rep.reported &= ~XkbGBN_GeometryMask; 5959 else if (rep.reported & XkbGBN_GeometryMask) { 5960 grep.type = X_Reply; 5961 grep.deviceID = dev->id; 5962 grep.sequenceNumber = client->sequence; 5963 grep.length = 0; 5964 grep.found = TRUE; 5965 grep.pad = 0; 5966 grep.widthMM = grep.heightMM = 0; 5967 grep.nProperties = grep.nColors = grep.nShapes = 0; 5968 grep.nSections = grep.nDoodads = 0; 5969 grep.baseColorNdx = grep.labelColorNdx = 0; 5970 XkbComputeGetGeometryReplySize(new->geom, &grep, None); 5971 rep.length += SIZEOF(xGenericReply) / 4 + grep.length; 5972 } 5973 } 5974 5975 reported = rep.reported; 5976 if (client->swapped) { 5977 swaps(&rep.sequenceNumber); 5978 swapl(&rep.length); 5979 swaps(&rep.found); 5980 swaps(&rep.reported); 5981 } 5982 WriteToClient(client, SIZEOF(xkbGetKbdByNameReply), &rep); 5983 if (reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) 5984 XkbSendMap(client, new, &mrep); 5985 if (reported & XkbGBN_CompatMapMask) 5986 XkbSendCompatMap(client, new->compat, &crep); 5987 if (reported & XkbGBN_IndicatorMapMask) 5988 XkbSendIndicatorMap(client, new->indicators, &irep); 5989 if (reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) 5990 XkbSendNames(client, new, &nrep); 5991 if (reported & XkbGBN_GeometryMask) 5992 XkbSendGeometry(client, new->geom, &grep, FALSE); 5993 if (rep.loaded) { 5994 XkbDescPtr old_xkb; 5995 xkbNewKeyboardNotify nkn; 5996 5997 old_xkb = xkb; 5998 xkb = new; 5999 dev->key->xkbInfo->desc = xkb; 6000 new = old_xkb; /* so it'll get freed automatically */ 6001 6002 XkbCopyControls(xkb, old_xkb); 6003 6004 nkn.deviceID = nkn.oldDeviceID = dev->id; 6005 nkn.minKeyCode = new->min_key_code; 6006 nkn.maxKeyCode = new->max_key_code; 6007 nkn.oldMinKeyCode = xkb->min_key_code; 6008 nkn.oldMaxKeyCode = xkb->max_key_code; 6009 nkn.requestMajor = XkbReqCode; 6010 nkn.requestMinor = X_kbGetKbdByName; 6011 nkn.changed = XkbNKN_KeycodesMask; 6012 if (geom_changed) 6013 nkn.changed |= XkbNKN_GeometryMask; 6014 XkbSendNewKeyboardNotify(dev, &nkn); 6015 6016 /* Update the map and LED info on the device itself, as well as 6017 * any slaves if it's an MD, or its MD if it's an SD and was the 6018 * last device used on that MD. */ 6019 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 6020 if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev && 6021 (tmpd != master || dev != master->lastSlave)) 6022 continue; 6023 6024 if (tmpd != dev) 6025 XkbDeviceApplyKeymap(tmpd, xkb); 6026 6027 if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 6028 old_sli = tmpd->kbdfeed->xkb_sli; 6029 tmpd->kbdfeed->xkb_sli = NULL; 6030 sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 6031 if (sli) { 6032 sli->explicitState = old_sli->explicitState; 6033 sli->effectiveState = old_sli->effectiveState; 6034 } 6035 tmpd->kbdfeed->xkb_sli = sli; 6036 XkbFreeSrvLedInfo(old_sli); 6037 } 6038 } 6039 } 6040 if ((new != NULL) && (new != xkb)) { 6041 XkbFreeKeyboard(new, XkbAllComponentsMask, TRUE); 6042 new = NULL; 6043 } 6044 XkbFreeComponentNames(&names, FALSE); 6045 XkbSetCauseXkbReq(&cause, X_kbGetKbdByName, client); 6046 XkbUpdateAllDeviceIndicators(NULL, &cause); 6047 6048 return Success; 6049} 6050 6051/***====================================================================***/ 6052 6053static int 6054ComputeDeviceLedInfoSize(DeviceIntPtr dev, 6055 unsigned int what, XkbSrvLedInfoPtr sli) 6056{ 6057 int nNames, nMaps; 6058 register unsigned n, bit; 6059 6060 if (sli == NULL) 6061 return 0; 6062 nNames = nMaps = 0; 6063 if ((what & XkbXI_IndicatorNamesMask) == 0) 6064 sli->namesPresent = 0; 6065 if ((what & XkbXI_IndicatorMapsMask) == 0) 6066 sli->mapsPresent = 0; 6067 6068 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6069 if (sli->names && sli->names[n] != None) { 6070 sli->namesPresent |= bit; 6071 nNames++; 6072 } 6073 if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 6074 sli->mapsPresent |= bit; 6075 nMaps++; 6076 } 6077 } 6078 return (nNames * 4) + (nMaps * SIZEOF(xkbIndicatorMapWireDesc)); 6079} 6080 6081static int 6082CheckDeviceLedFBs(DeviceIntPtr dev, 6083 int class, 6084 int id, xkbGetDeviceInfoReply * rep, ClientPtr client) 6085{ 6086 int nFBs = 0; 6087 int length = 0; 6088 Bool classOk; 6089 6090 if (class == XkbDfltXIClass) { 6091 if (dev->kbdfeed) 6092 class = KbdFeedbackClass; 6093 else if (dev->leds) 6094 class = LedFeedbackClass; 6095 else { 6096 client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 6097 return XkbKeyboardErrorCode; 6098 } 6099 } 6100 classOk = FALSE; 6101 if ((dev->kbdfeed) && 6102 ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6103 KbdFeedbackPtr kf; 6104 6105 classOk = TRUE; 6106 for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6107 if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6108 (id != kf->ctrl.id)) 6109 continue; 6110 nFBs++; 6111 length += SIZEOF(xkbDeviceLedsWireDesc); 6112 if (!kf->xkb_sli) 6113 kf->xkb_sli = XkbAllocSrvLedInfo(dev, kf, NULL, 0); 6114 length += ComputeDeviceLedInfoSize(dev, rep->present, kf->xkb_sli); 6115 if (id != XkbAllXIIds) 6116 break; 6117 } 6118 } 6119 if ((dev->leds) && 6120 ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6121 LedFeedbackPtr lf; 6122 6123 classOk = TRUE; 6124 for (lf = dev->leds; (lf); lf = lf->next) { 6125 if ((id != XkbAllXIIds) && (id != XkbDfltXIId) && 6126 (id != lf->ctrl.id)) 6127 continue; 6128 nFBs++; 6129 length += SIZEOF(xkbDeviceLedsWireDesc); 6130 if (!lf->xkb_sli) 6131 lf->xkb_sli = XkbAllocSrvLedInfo(dev, NULL, lf, 0); 6132 length += ComputeDeviceLedInfoSize(dev, rep->present, lf->xkb_sli); 6133 if (id != XkbAllXIIds) 6134 break; 6135 } 6136 } 6137 if (nFBs > 0) { 6138 rep->nDeviceLedFBs = nFBs; 6139 rep->length += (length / 4); 6140 return Success; 6141 } 6142 if (classOk) 6143 client->errorValue = _XkbErrCode2(XkbErr_BadId, id); 6144 else 6145 client->errorValue = _XkbErrCode2(XkbErr_BadClass, class); 6146 return XkbKeyboardErrorCode; 6147} 6148 6149static int 6150SendDeviceLedInfo(XkbSrvLedInfoPtr sli, ClientPtr client) 6151{ 6152 xkbDeviceLedsWireDesc wire; 6153 int length; 6154 6155 length = 0; 6156 wire.ledClass = sli->class; 6157 wire.ledID = sli->id; 6158 wire.namesPresent = sli->namesPresent; 6159 wire.mapsPresent = sli->mapsPresent; 6160 wire.physIndicators = sli->physIndicators; 6161 wire.state = sli->effectiveState; 6162 if (client->swapped) { 6163 swaps(&wire.ledClass); 6164 swaps(&wire.ledID); 6165 swapl(&wire.namesPresent); 6166 swapl(&wire.mapsPresent); 6167 swapl(&wire.physIndicators); 6168 swapl(&wire.state); 6169 } 6170 WriteToClient(client, SIZEOF(xkbDeviceLedsWireDesc), &wire); 6171 length += SIZEOF(xkbDeviceLedsWireDesc); 6172 if (sli->namesPresent | sli->mapsPresent) { 6173 register unsigned i, bit; 6174 6175 if (sli->namesPresent) { 6176 CARD32 awire; 6177 6178 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6179 if (sli->namesPresent & bit) { 6180 awire = (CARD32) sli->names[i]; 6181 if (client->swapped) { 6182 swapl(&awire); 6183 } 6184 WriteToClient(client, 4, &awire); 6185 length += 4; 6186 } 6187 } 6188 } 6189 if (sli->mapsPresent) { 6190 for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { 6191 xkbIndicatorMapWireDesc iwire; 6192 6193 if (sli->mapsPresent & bit) { 6194 iwire.flags = sli->maps[i].flags; 6195 iwire.whichGroups = sli->maps[i].which_groups; 6196 iwire.groups = sli->maps[i].groups; 6197 iwire.whichMods = sli->maps[i].which_mods; 6198 iwire.mods = sli->maps[i].mods.mask; 6199 iwire.realMods = sli->maps[i].mods.real_mods; 6200 iwire.virtualMods = sli->maps[i].mods.vmods; 6201 iwire.ctrls = sli->maps[i].ctrls; 6202 if (client->swapped) { 6203 swaps(&iwire.virtualMods); 6204 swapl(&iwire.ctrls); 6205 } 6206 WriteToClient(client, SIZEOF(xkbIndicatorMapWireDesc), 6207 &iwire); 6208 length += SIZEOF(xkbIndicatorMapWireDesc); 6209 } 6210 } 6211 } 6212 } 6213 return length; 6214} 6215 6216static int 6217SendDeviceLedFBs(DeviceIntPtr dev, 6218 int class, int id, unsigned wantLength, ClientPtr client) 6219{ 6220 int length = 0; 6221 6222 if (class == XkbDfltXIClass) { 6223 if (dev->kbdfeed) 6224 class = KbdFeedbackClass; 6225 else if (dev->leds) 6226 class = LedFeedbackClass; 6227 } 6228 if ((dev->kbdfeed) && 6229 ((class == KbdFeedbackClass) || (class == XkbAllXIClasses))) { 6230 KbdFeedbackPtr kf; 6231 6232 for (kf = dev->kbdfeed; (kf); kf = kf->next) { 6233 if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6234 (id == kf->ctrl.id)) { 6235 length += SendDeviceLedInfo(kf->xkb_sli, client); 6236 if (id != XkbAllXIIds) 6237 break; 6238 } 6239 } 6240 } 6241 if ((dev->leds) && 6242 ((class == LedFeedbackClass) || (class == XkbAllXIClasses))) { 6243 LedFeedbackPtr lf; 6244 6245 for (lf = dev->leds; (lf); lf = lf->next) { 6246 if ((id == XkbAllXIIds) || (id == XkbDfltXIId) || 6247 (id == lf->ctrl.id)) { 6248 length += SendDeviceLedInfo(lf->xkb_sli, client); 6249 if (id != XkbAllXIIds) 6250 break; 6251 } 6252 } 6253 } 6254 if (length == wantLength) 6255 return Success; 6256 else 6257 return BadLength; 6258} 6259 6260int 6261ProcXkbGetDeviceInfo(ClientPtr client) 6262{ 6263 DeviceIntPtr dev; 6264 xkbGetDeviceInfoReply rep; 6265 int status, nDeviceLedFBs; 6266 unsigned length, nameLen; 6267 CARD16 ledClass, ledID; 6268 unsigned wanted; 6269 char *str; 6270 6271 REQUEST(xkbGetDeviceInfoReq); 6272 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 6273 6274 if (!(client->xkbClientFlags & _XkbClientInitialized)) 6275 return BadAccess; 6276 6277 wanted = stuff->wanted; 6278 6279 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 6280 CHK_MASK_LEGAL(0x01, wanted, XkbXI_AllDeviceFeaturesMask); 6281 6282 if ((!dev->button) || ((stuff->nBtns < 1) && (!stuff->allBtns))) 6283 wanted &= ~XkbXI_ButtonActionsMask; 6284 if ((!dev->kbdfeed) && (!dev->leds)) 6285 wanted &= ~XkbXI_IndicatorsMask; 6286 6287 nameLen = XkbSizeCountedString(dev->name); 6288 rep = (xkbGetDeviceInfoReply) { 6289 .type = X_Reply, 6290 .deviceID = dev->id, 6291 .sequenceNumber = client->sequence, 6292 .length = nameLen / 4, 6293 .present = wanted, 6294 .supported = XkbXI_AllDeviceFeaturesMask, 6295 .unsupported = 0, 6296 .nDeviceLedFBs = 0, 6297 .firstBtnWanted = 0, 6298 .nBtnsWanted = 0, 6299 .firstBtnRtrn = 0, 6300 .nBtnsRtrn = 0, 6301 .totalBtns = dev->button ? dev->button->numButtons : 0, 6302 .hasOwnState = (dev->key && dev->key->xkbInfo), 6303 .dfltKbdFB = dev->kbdfeed ? dev->kbdfeed->ctrl.id : XkbXINone, 6304 .dfltLedFB = dev->leds ? dev->leds->ctrl.id : XkbXINone, 6305 .devType = dev->xinput_type 6306 }; 6307 6308 ledClass = stuff->ledClass; 6309 ledID = stuff->ledID; 6310 6311 if (wanted & XkbXI_ButtonActionsMask) { 6312 if (stuff->allBtns) { 6313 stuff->firstBtn = 0; 6314 stuff->nBtns = dev->button->numButtons; 6315 } 6316 6317 if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6318 client->errorValue = _XkbErrCode4(0x02, dev->button->numButtons, 6319 stuff->firstBtn, stuff->nBtns); 6320 return BadValue; 6321 } 6322 else { 6323 rep.firstBtnWanted = stuff->firstBtn; 6324 rep.nBtnsWanted = stuff->nBtns; 6325 if (dev->button->xkb_acts != NULL) { 6326 XkbAction *act; 6327 register int i; 6328 6329 rep.firstBtnRtrn = stuff->firstBtn; 6330 rep.nBtnsRtrn = stuff->nBtns; 6331 act = &dev->button->xkb_acts[rep.firstBtnWanted]; 6332 for (i = 0; i < rep.nBtnsRtrn; i++, act++) { 6333 if (act->type != XkbSA_NoAction) 6334 break; 6335 } 6336 rep.firstBtnRtrn += i; 6337 rep.nBtnsRtrn -= i; 6338 act = 6339 &dev->button->xkb_acts[rep.firstBtnRtrn + rep.nBtnsRtrn - 6340 1]; 6341 for (i = 0; i < rep.nBtnsRtrn; i++, act--) { 6342 if (act->type != XkbSA_NoAction) 6343 break; 6344 } 6345 rep.nBtnsRtrn -= i; 6346 } 6347 rep.length += (rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc)) / 4; 6348 } 6349 } 6350 6351 if (wanted & XkbXI_IndicatorsMask) { 6352 status = CheckDeviceLedFBs(dev, ledClass, ledID, &rep, client); 6353 if (status != Success) 6354 return status; 6355 } 6356 length = rep.length * 4; 6357 nDeviceLedFBs = rep.nDeviceLedFBs; 6358 if (client->swapped) { 6359 swaps(&rep.sequenceNumber); 6360 swapl(&rep.length); 6361 swaps(&rep.present); 6362 swaps(&rep.supported); 6363 swaps(&rep.unsupported); 6364 swaps(&rep.nDeviceLedFBs); 6365 swaps(&rep.dfltKbdFB); 6366 swaps(&rep.dfltLedFB); 6367 swapl(&rep.devType); 6368 } 6369 WriteToClient(client, SIZEOF(xkbGetDeviceInfoReply), &rep); 6370 6371 str = malloc(nameLen); 6372 if (!str) 6373 return BadAlloc; 6374 XkbWriteCountedString(str, dev->name, client->swapped); 6375 WriteToClient(client, nameLen, str); 6376 free(str); 6377 length -= nameLen; 6378 6379 if (rep.nBtnsRtrn > 0) { 6380 int sz; 6381 xkbActionWireDesc *awire; 6382 6383 sz = rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc); 6384 awire = (xkbActionWireDesc *) &dev->button->xkb_acts[rep.firstBtnRtrn]; 6385 WriteToClient(client, sz, awire); 6386 length -= sz; 6387 } 6388 if (nDeviceLedFBs > 0) { 6389 status = SendDeviceLedFBs(dev, ledClass, ledID, length, client); 6390 if (status != Success) 6391 return status; 6392 } 6393 else if (length != 0) { 6394 ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 6395 ErrorF("[xkb] Wrote %d fewer bytes than expected\n", 6396 length); 6397 return BadLength; 6398 } 6399 return Success; 6400} 6401 6402static char * 6403CheckSetDeviceIndicators(char *wire, 6404 DeviceIntPtr dev, 6405 int num, int *status_rtrn, ClientPtr client) 6406{ 6407 xkbDeviceLedsWireDesc *ledWire; 6408 int i; 6409 XkbSrvLedInfoPtr sli; 6410 6411 ledWire = (xkbDeviceLedsWireDesc *) wire; 6412 for (i = 0; i < num; i++) { 6413 if (client->swapped) { 6414 swaps(&ledWire->ledClass); 6415 swaps(&ledWire->ledID); 6416 swapl(&ledWire->namesPresent); 6417 swapl(&ledWire->mapsPresent); 6418 swapl(&ledWire->physIndicators); 6419 } 6420 6421 sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6422 XkbXI_IndicatorsMask); 6423 if (sli != NULL) { 6424 register int n; 6425 register unsigned bit; 6426 int nMaps, nNames; 6427 CARD32 *atomWire; 6428 xkbIndicatorMapWireDesc *mapWire; 6429 6430 nMaps = nNames = 0; 6431 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6432 if (ledWire->namesPresent & bit) 6433 nNames++; 6434 if (ledWire->mapsPresent & bit) 6435 nMaps++; 6436 } 6437 atomWire = (CARD32 *) &ledWire[1]; 6438 if (nNames > 0) { 6439 for (n = 0; n < nNames; n++) { 6440 if (client->swapped) { 6441 swapl(atomWire); 6442 } 6443 CHK_ATOM_OR_NONE3(((Atom) (*atomWire)), client->errorValue, 6444 *status_rtrn, NULL); 6445 atomWire++; 6446 } 6447 } 6448 mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6449 if (nMaps > 0) { 6450 for (n = 0; n < nMaps; n++) { 6451 if (client->swapped) { 6452 swaps(&mapWire->virtualMods); 6453 swapl(&mapWire->ctrls); 6454 } 6455 CHK_MASK_LEGAL3(0x21, mapWire->whichGroups, 6456 XkbIM_UseAnyGroup, 6457 client->errorValue, *status_rtrn, NULL); 6458 CHK_MASK_LEGAL3(0x22, mapWire->whichMods, XkbIM_UseAnyMods, 6459 client->errorValue, *status_rtrn, NULL); 6460 mapWire++; 6461 } 6462 } 6463 ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6464 } 6465 else { 6466 /* SHOULD NEVER HAPPEN */ 6467 return (char *) ledWire; 6468 } 6469 } 6470 return (char *) ledWire; 6471} 6472 6473static char * 6474SetDeviceIndicators(char *wire, 6475 DeviceIntPtr dev, 6476 unsigned changed, 6477 int num, 6478 int *status_rtrn, 6479 ClientPtr client, xkbExtensionDeviceNotify * ev) 6480{ 6481 xkbDeviceLedsWireDesc *ledWire; 6482 int i; 6483 XkbEventCauseRec cause; 6484 unsigned namec, mapc, statec; 6485 xkbExtensionDeviceNotify ed; 6486 XkbChangesRec changes; 6487 DeviceIntPtr kbd; 6488 6489 memset((char *) &ed, 0, sizeof(xkbExtensionDeviceNotify)); 6490 memset((char *) &changes, 0, sizeof(XkbChangesRec)); 6491 XkbSetCauseXkbReq(&cause, X_kbSetDeviceInfo, client); 6492 ledWire = (xkbDeviceLedsWireDesc *) wire; 6493 for (i = 0; i < num; i++) { 6494 register int n; 6495 register unsigned bit; 6496 CARD32 *atomWire; 6497 xkbIndicatorMapWireDesc *mapWire; 6498 XkbSrvLedInfoPtr sli; 6499 6500 namec = mapc = statec = 0; 6501 sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, 6502 XkbXI_IndicatorMapsMask); 6503 if (!sli) { 6504 /* SHOULD NEVER HAPPEN!! */ 6505 return (char *) ledWire; 6506 } 6507 6508 atomWire = (CARD32 *) &ledWire[1]; 6509 if (changed & XkbXI_IndicatorNamesMask) { 6510 namec = sli->namesPresent | ledWire->namesPresent; 6511 memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6512 } 6513 if (ledWire->namesPresent) { 6514 sli->namesPresent = ledWire->namesPresent; 6515 memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); 6516 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6517 if (ledWire->namesPresent & bit) { 6518 sli->names[n] = (Atom) *atomWire; 6519 if (sli->names[n] == None) 6520 ledWire->namesPresent &= ~bit; 6521 atomWire++; 6522 } 6523 } 6524 } 6525 mapWire = (xkbIndicatorMapWireDesc *) atomWire; 6526 if (changed & XkbXI_IndicatorMapsMask) { 6527 mapc = sli->mapsPresent | ledWire->mapsPresent; 6528 sli->mapsPresent = ledWire->mapsPresent; 6529 memset((char *) sli->maps, 0, 6530 XkbNumIndicators * sizeof(XkbIndicatorMapRec)); 6531 } 6532 if (ledWire->mapsPresent) { 6533 for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { 6534 if (ledWire->mapsPresent & bit) { 6535 sli->maps[n].flags = mapWire->flags; 6536 sli->maps[n].which_groups = mapWire->whichGroups; 6537 sli->maps[n].groups = mapWire->groups; 6538 sli->maps[n].which_mods = mapWire->whichMods; 6539 sli->maps[n].mods.mask = mapWire->mods; 6540 sli->maps[n].mods.real_mods = mapWire->realMods; 6541 sli->maps[n].mods.vmods = mapWire->virtualMods; 6542 sli->maps[n].ctrls = mapWire->ctrls; 6543 mapWire++; 6544 } 6545 } 6546 } 6547 if (changed & XkbXI_IndicatorStateMask) { 6548 statec = sli->effectiveState ^ ledWire->state; 6549 sli->explicitState &= ~statec; 6550 sli->explicitState |= (ledWire->state & statec); 6551 } 6552 if (namec) 6553 XkbApplyLedNameChanges(dev, sli, namec, &ed, &changes, &cause); 6554 if (mapc) 6555 XkbApplyLedMapChanges(dev, sli, mapc, &ed, &changes, &cause); 6556 if (statec) 6557 XkbApplyLedStateChanges(dev, sli, statec, &ed, &changes, &cause); 6558 6559 kbd = dev; 6560 if ((sli->flags & XkbSLI_HasOwnState) == 0) 6561 kbd = inputInfo.keyboard; 6562 6563 XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); 6564 ledWire = (xkbDeviceLedsWireDesc *) mapWire; 6565 } 6566 return (char *) ledWire; 6567} 6568 6569static int 6570_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 6571 xkbSetDeviceInfoReq * stuff) 6572{ 6573 char *wire; 6574 6575 wire = (char *) &stuff[1]; 6576 if (stuff->change & XkbXI_ButtonActionsMask) { 6577 if (!dev->button) { 6578 client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass); 6579 return XkbKeyboardErrorCode; 6580 } 6581 if ((stuff->firstBtn + stuff->nBtns) > dev->button->numButtons) { 6582 client->errorValue = 6583 _XkbErrCode4(0x02, stuff->firstBtn, stuff->nBtns, 6584 dev->button->numButtons); 6585 return BadMatch; 6586 } 6587 wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc)); 6588 } 6589 if (stuff->change & XkbXI_IndicatorsMask) { 6590 int status = Success; 6591 6592 wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs, 6593 &status, client); 6594 if (status != Success) 6595 return status; 6596 } 6597 if (((wire - ((char *) stuff)) / 4) != stuff->length) 6598 return BadLength; 6599 6600 return Success; 6601} 6602 6603static int 6604_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 6605 xkbSetDeviceInfoReq * stuff) 6606{ 6607 char *wire; 6608 xkbExtensionDeviceNotify ed; 6609 6610 memset((char *) &ed, 0, SIZEOF(xkbExtensionDeviceNotify)); 6611 ed.deviceID = dev->id; 6612 wire = (char *) &stuff[1]; 6613 if (stuff->change & XkbXI_ButtonActionsMask) { 6614 int nBtns, sz, i; 6615 XkbAction *acts; 6616 DeviceIntPtr kbd; 6617 6618 nBtns = dev->button->numButtons; 6619 acts = dev->button->xkb_acts; 6620 if (acts == NULL) { 6621 acts = calloc(nBtns, sizeof(XkbAction)); 6622 if (!acts) 6623 return BadAlloc; 6624 dev->button->xkb_acts = acts; 6625 } 6626 sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); 6627 memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz); 6628 wire += sz; 6629 ed.reason |= XkbXI_ButtonActionsMask; 6630 ed.firstBtn = stuff->firstBtn; 6631 ed.nBtns = stuff->nBtns; 6632 6633 if (dev->key) 6634 kbd = dev; 6635 else 6636 kbd = inputInfo.keyboard; 6637 acts = &dev->button->xkb_acts[stuff->firstBtn]; 6638 for (i = 0; i < stuff->nBtns; i++, acts++) { 6639 if (acts->type != XkbSA_NoAction) 6640 XkbSetActionKeyMods(kbd->key->xkbInfo->desc, acts, 0); 6641 } 6642 } 6643 if (stuff->change & XkbXI_IndicatorsMask) { 6644 int status = Success; 6645 6646 wire = SetDeviceIndicators(wire, dev, stuff->change, 6647 stuff->nDeviceLedFBs, &status, client, &ed); 6648 if (status != Success) 6649 return status; 6650 } 6651 if ((stuff->change) && (ed.reason)) 6652 XkbSendExtensionDeviceNotify(dev, client, &ed); 6653 return Success; 6654} 6655 6656int 6657ProcXkbSetDeviceInfo(ClientPtr client) 6658{ 6659 DeviceIntPtr dev; 6660 int rc; 6661 6662 REQUEST(xkbSetDeviceInfoReq); 6663 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 6664 6665 if (!(client->xkbClientFlags & _XkbClientInitialized)) 6666 return BadAccess; 6667 6668 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 6669 CHK_MASK_LEGAL(0x01, stuff->change, XkbXI_AllFeaturesMask); 6670 6671 rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 6672 6673 if (rc != Success) 6674 return rc; 6675 6676 if (stuff->deviceSpec == XkbUseCoreKbd || 6677 stuff->deviceSpec == XkbUseCorePtr) { 6678 DeviceIntPtr other; 6679 6680 for (other = inputInfo.devices; other; other = other->next) { 6681 if (((other != dev) && !IsMaster(other) && 6682 GetMaster(other, MASTER_KEYBOARD) == dev) && 6683 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6684 (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6685 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6686 DixManageAccess); 6687 if (rc == Success) { 6688 rc = _XkbSetDeviceInfoCheck(client, other, stuff); 6689 if (rc != Success) 6690 return rc; 6691 } 6692 } 6693 } 6694 } 6695 6696 /* checks done, apply */ 6697 rc = _XkbSetDeviceInfo(client, dev, stuff); 6698 if (rc != Success) 6699 return rc; 6700 6701 if (stuff->deviceSpec == XkbUseCoreKbd || 6702 stuff->deviceSpec == XkbUseCorePtr) { 6703 DeviceIntPtr other; 6704 6705 for (other = inputInfo.devices; other; other = other->next) { 6706 if (((other != dev) && !IsMaster(other) && 6707 GetMaster(other, MASTER_KEYBOARD) == dev) && 6708 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6709 (stuff->deviceSpec == XkbUseCorePtr && other->button))) { 6710 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 6711 DixManageAccess); 6712 if (rc == Success) { 6713 rc = _XkbSetDeviceInfo(client, other, stuff); 6714 if (rc != Success) 6715 return rc; 6716 } 6717 } 6718 } 6719 } 6720 6721 return Success; 6722} 6723 6724/***====================================================================***/ 6725 6726int 6727ProcXkbSetDebuggingFlags(ClientPtr client) 6728{ 6729 CARD32 newFlags, newCtrls, extraLength; 6730 xkbSetDebuggingFlagsReply rep; 6731 int rc; 6732 6733 REQUEST(xkbSetDebuggingFlagsReq); 6734 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 6735 6736 rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 6737 if (rc != Success) 6738 return rc; 6739 6740 newFlags = xkbDebugFlags & (~stuff->affectFlags); 6741 newFlags |= (stuff->flags & stuff->affectFlags); 6742 newCtrls = xkbDebugCtrls & (~stuff->affectCtrls); 6743 newCtrls |= (stuff->ctrls & stuff->affectCtrls); 6744 if (xkbDebugFlags || newFlags || stuff->msgLength) { 6745 ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n", 6746 (long) newFlags); 6747 if (newCtrls != xkbDebugCtrls) 6748 ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n", 6749 (long) newCtrls); 6750 } 6751 extraLength = (stuff->length << 2) - sz_xkbSetDebuggingFlagsReq; 6752 if (stuff->msgLength > 0) { 6753 char *msg; 6754 6755 if (extraLength < XkbPaddedSize(stuff->msgLength)) { 6756 ErrorF 6757 ("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 6758 stuff->msgLength, (long) extraLength, 6759 XkbPaddedSize(stuff->msgLength)); 6760 return BadLength; 6761 } 6762 msg = (char *) &stuff[1]; 6763 if (msg[stuff->msgLength - 1] != '\0') { 6764 ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 6765 return BadValue; 6766 } 6767 ErrorF("[xkb] XkbDebug: %s\n", msg); 6768 } 6769 xkbDebugFlags = newFlags; 6770 xkbDebugCtrls = newCtrls; 6771 6772 rep = (xkbSetDebuggingFlagsReply) { 6773 .type = X_Reply, 6774 .sequenceNumber = client->sequence, 6775 .length = 0, 6776 .currentFlags = newFlags, 6777 .currentCtrls = newCtrls, 6778 .supportedFlags = ~0, 6779 .supportedCtrls = ~0 6780 }; 6781 if (client->swapped) { 6782 swaps(&rep.sequenceNumber); 6783 swapl(&rep.currentFlags); 6784 swapl(&rep.currentCtrls); 6785 swapl(&rep.supportedFlags); 6786 swapl(&rep.supportedCtrls); 6787 } 6788 WriteToClient(client, SIZEOF(xkbSetDebuggingFlagsReply), &rep); 6789 return Success; 6790} 6791 6792/***====================================================================***/ 6793 6794static int 6795ProcXkbDispatch(ClientPtr client) 6796{ 6797 REQUEST(xReq); 6798 switch (stuff->data) { 6799 case X_kbUseExtension: 6800 return ProcXkbUseExtension(client); 6801 case X_kbSelectEvents: 6802 return ProcXkbSelectEvents(client); 6803 case X_kbBell: 6804 return ProcXkbBell(client); 6805 case X_kbGetState: 6806 return ProcXkbGetState(client); 6807 case X_kbLatchLockState: 6808 return ProcXkbLatchLockState(client); 6809 case X_kbGetControls: 6810 return ProcXkbGetControls(client); 6811 case X_kbSetControls: 6812 return ProcXkbSetControls(client); 6813 case X_kbGetMap: 6814 return ProcXkbGetMap(client); 6815 case X_kbSetMap: 6816 return ProcXkbSetMap(client); 6817 case X_kbGetCompatMap: 6818 return ProcXkbGetCompatMap(client); 6819 case X_kbSetCompatMap: 6820 return ProcXkbSetCompatMap(client); 6821 case X_kbGetIndicatorState: 6822 return ProcXkbGetIndicatorState(client); 6823 case X_kbGetIndicatorMap: 6824 return ProcXkbGetIndicatorMap(client); 6825 case X_kbSetIndicatorMap: 6826 return ProcXkbSetIndicatorMap(client); 6827 case X_kbGetNamedIndicator: 6828 return ProcXkbGetNamedIndicator(client); 6829 case X_kbSetNamedIndicator: 6830 return ProcXkbSetNamedIndicator(client); 6831 case X_kbGetNames: 6832 return ProcXkbGetNames(client); 6833 case X_kbSetNames: 6834 return ProcXkbSetNames(client); 6835 case X_kbGetGeometry: 6836 return ProcXkbGetGeometry(client); 6837 case X_kbSetGeometry: 6838 return ProcXkbSetGeometry(client); 6839 case X_kbPerClientFlags: 6840 return ProcXkbPerClientFlags(client); 6841 case X_kbListComponents: 6842 return ProcXkbListComponents(client); 6843 case X_kbGetKbdByName: 6844 return ProcXkbGetKbdByName(client); 6845 case X_kbGetDeviceInfo: 6846 return ProcXkbGetDeviceInfo(client); 6847 case X_kbSetDeviceInfo: 6848 return ProcXkbSetDeviceInfo(client); 6849 case X_kbSetDebuggingFlags: 6850 return ProcXkbSetDebuggingFlags(client); 6851 default: 6852 return BadRequest; 6853 } 6854} 6855 6856static int 6857XkbClientGone(void *data, XID id) 6858{ 6859 DevicePtr pXDev = (DevicePtr) data; 6860 6861 if (!XkbRemoveResourceClient(pXDev, id)) { 6862 ErrorF 6863 ("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 6864 } 6865 return 1; 6866} 6867 6868void 6869XkbExtensionInit(void) 6870{ 6871 ExtensionEntry *extEntry; 6872 6873 RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); 6874 if (!RT_XKBCLIENT) 6875 return; 6876 6877 if (!XkbInitPrivates()) 6878 return; 6879 6880 if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 6881 ProcXkbDispatch, SProcXkbDispatch, 6882 NULL, StandardMinorOpcode))) { 6883 XkbReqCode = (unsigned char) extEntry->base; 6884 XkbEventBase = (unsigned char) extEntry->eventBase; 6885 XkbErrorBase = (unsigned char) extEntry->errorBase; 6886 XkbKeyboardErrorCode = XkbErrorBase + XkbKeyboard; 6887 } 6888 return; 6889} 6890