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