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