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