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