xkb.c revision 52397711
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;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;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 (other->kbdfeed || other->leds) && 3442 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 3443 { 3444 rc = _XkbCreateIndicatorMap(other, stuff->indicator, 3445 stuff->ledClass, stuff->ledID, 3446 &map, &led, TRUE); 3447 if (rc != Success || !map) 3448 return rc; 3449 } 3450 } 3451 } 3452 3453 /* All checks passed, let's do it */ 3454 rc = _XkbSetNamedIndicator(client, dev, stuff); 3455 if (rc != Success) 3456 return rc; 3457 3458 if (stuff->deviceSpec == XkbUseCoreKbd || 3459 stuff->deviceSpec == XkbUseCorePtr) 3460 { 3461 DeviceIntPtr other; 3462 for (other = inputInfo.devices; other; other = other->next) 3463 { 3464 if ((other != dev) && !other->isMaster && (other->u.master == dev) && 3465 (other->kbdfeed || other->leds) && 3466 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) 3467 { 3468 _XkbSetNamedIndicator(client, other, stuff); 3469 } 3470 } 3471 } 3472 3473 return client->noClientException; 3474} 3475 3476/***====================================================================***/ 3477 3478static CARD32 3479_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) 3480{ 3481register unsigned int i,bit,nAtoms; 3482register CARD32 atomsPresent; 3483 3484 for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { 3485 if (atoms[i]!=None) { 3486 atomsPresent|= bit; 3487 nAtoms++; 3488 } 3489 } 3490 if (count) 3491 *count= nAtoms; 3492 return atomsPresent; 3493} 3494 3495static char * 3496_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap) 3497{ 3498register unsigned int i; 3499Atom *atm; 3500 3501 atm = (Atom *)wire; 3502 for (i=0;i<maxAtoms;i++) { 3503 if (atoms[i]!=None) { 3504 *atm= atoms[i]; 3505 if (swap) { 3506 register int n; 3507 swapl(atm,n); 3508 } 3509 atm++; 3510 } 3511 } 3512 return (char *)atm; 3513} 3514 3515static Status 3516XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep) 3517{ 3518register unsigned which,length; 3519register int i; 3520 3521 rep->minKeyCode= xkb->min_key_code; 3522 rep->maxKeyCode= xkb->max_key_code; 3523 which= rep->which; 3524 length= 0; 3525 if (xkb->names!=NULL) { 3526 if (which&XkbKeycodesNameMask) length++; 3527 if (which&XkbGeometryNameMask) length++; 3528 if (which&XkbSymbolsNameMask) length++; 3529 if (which&XkbPhysSymbolsNameMask) length++; 3530 if (which&XkbTypesNameMask) length++; 3531 if (which&XkbCompatNameMask) length++; 3532 } 3533 else which&= ~XkbComponentNamesMask; 3534 3535 if (xkb->map!=NULL) { 3536 if (which&XkbKeyTypeNamesMask) 3537 length+= xkb->map->num_types; 3538 rep->nTypes= xkb->map->num_types; 3539 if (which&XkbKTLevelNamesMask) { 3540 XkbKeyTypePtr pType = xkb->map->types; 3541 int nKTLevels = 0; 3542 3543 length+= XkbPaddedSize(xkb->map->num_types)/4; 3544 for (i=0;i<xkb->map->num_types;i++,pType++) { 3545 if (pType->level_names!=NULL) 3546 nKTLevels+= pType->num_levels; 3547 } 3548 rep->nKTLevels= nKTLevels; 3549 length+= nKTLevels; 3550 } 3551 } 3552 else { 3553 rep->nTypes= 0; 3554 rep->nKTLevels= 0; 3555 which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask); 3556 } 3557 3558 rep->minKeyCode= xkb->min_key_code; 3559 rep->maxKeyCode= xkb->max_key_code; 3560 rep->indicators= 0; 3561 rep->virtualMods= 0; 3562 rep->groupNames= 0; 3563 if (xkb->names!=NULL) { 3564 if (which&XkbIndicatorNamesMask) { 3565 int nLeds; 3566 rep->indicators= 3567 _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds); 3568 length+= nLeds; 3569 if (nLeds==0) 3570 which&= ~XkbIndicatorNamesMask; 3571 } 3572 3573 if (which&XkbVirtualModNamesMask) { 3574 int nVMods; 3575 rep->virtualMods= 3576 _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods); 3577 length+= nVMods; 3578 if (nVMods==0) 3579 which&= ~XkbVirtualModNamesMask; 3580 } 3581 3582 if (which&XkbGroupNamesMask) { 3583 int nGroups; 3584 rep->groupNames= 3585 _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups); 3586 length+= nGroups; 3587 if (nGroups==0) 3588 which&= ~XkbGroupNamesMask; 3589 } 3590 3591 if ((which&XkbKeyNamesMask)&&(xkb->names->keys)) 3592 length+= rep->nKeys; 3593 else which&= ~XkbKeyNamesMask; 3594 3595 if ((which&XkbKeyAliasesMask)&& 3596 (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) { 3597 rep->nKeyAliases= xkb->names->num_key_aliases; 3598 length+= rep->nKeyAliases*2; 3599 } 3600 else { 3601 which&= ~XkbKeyAliasesMask; 3602 rep->nKeyAliases= 0; 3603 } 3604 3605 if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0)) 3606 length+= xkb->names->num_rg; 3607 else which&= ~XkbRGNamesMask; 3608 } 3609 else { 3610 which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask); 3611 which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask); 3612 which&= ~XkbRGNamesMask; 3613 } 3614 3615 rep->length= length; 3616 rep->which= which; 3617 return Success; 3618} 3619 3620static int 3621XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep) 3622{ 3623register unsigned i,length,which; 3624char * start; 3625char * desc; 3626register int n; 3627 3628 length= rep->length*4; 3629 which= rep->which; 3630 if (client->swapped) { 3631 swaps(&rep->sequenceNumber,n); 3632 swapl(&rep->length,n); 3633 swapl(&rep->which,n); 3634 swaps(&rep->virtualMods,n); 3635 swapl(&rep->indicators,n); 3636 } 3637 3638 start = desc = (char *)xalloc(length); 3639 if ( !start ) 3640 return BadAlloc; 3641 if (xkb->names) { 3642 if (which&XkbKeycodesNameMask) { 3643 *((CARD32 *)desc)= xkb->names->keycodes; 3644 if (client->swapped) { 3645 swapl(desc,n); 3646 } 3647 desc+= 4; 3648 } 3649 if (which&XkbGeometryNameMask) { 3650 *((CARD32 *)desc)= xkb->names->geometry; 3651 if (client->swapped) { 3652 swapl(desc,n); 3653 } 3654 desc+= 4; 3655 } 3656 if (which&XkbSymbolsNameMask) { 3657 *((CARD32 *)desc)= xkb->names->symbols; 3658 if (client->swapped) { 3659 swapl(desc,n); 3660 } 3661 desc+= 4; 3662 } 3663 if (which&XkbPhysSymbolsNameMask) { 3664 register CARD32 *atm= (CARD32 *)desc; 3665 atm[0]= (CARD32)xkb->names->phys_symbols; 3666 if (client->swapped) { 3667 swapl(&atm[0],n); 3668 } 3669 desc+= 4; 3670 } 3671 if (which&XkbTypesNameMask) { 3672 *((CARD32 *)desc)= (CARD32)xkb->names->types; 3673 if (client->swapped) { 3674 swapl(desc,n); 3675 } 3676 desc+= 4; 3677 } 3678 if (which&XkbCompatNameMask) { 3679 *((CARD32 *)desc)= (CARD32)xkb->names->compat; 3680 if (client->swapped) { 3681 swapl(desc,n); 3682 } 3683 desc+= 4; 3684 } 3685 if (which&XkbKeyTypeNamesMask) { 3686 register CARD32 *atm= (CARD32 *)desc; 3687 register XkbKeyTypePtr type= xkb->map->types; 3688 3689 for (i=0;i<xkb->map->num_types;i++,atm++,type++) { 3690 *atm= (CARD32)type->name; 3691 if (client->swapped) { 3692 swapl(atm,n); 3693 } 3694 } 3695 desc= (char *)atm; 3696 } 3697 if (which&XkbKTLevelNamesMask && xkb->map) { 3698 XkbKeyTypePtr type = xkb->map->types; 3699 register CARD32 *atm; 3700 for (i=0;i<rep->nTypes;i++,type++) { 3701 *desc++ = type->num_levels; 3702 } 3703 desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes; 3704 3705 atm= (CARD32 *)desc; 3706 type = xkb->map->types; 3707 for (i=0;i<xkb->map->num_types;i++,type++) { 3708 register unsigned l; 3709 if (type->level_names) { 3710 for (l=0;l<type->num_levels;l++,atm++) { 3711 *atm= type->level_names[l]; 3712 if (client->swapped) { 3713 swapl(atm,n); 3714 } 3715 } 3716 desc+= type->num_levels*4; 3717 } 3718 } 3719 } 3720 if (which&XkbIndicatorNamesMask) { 3721 desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators, 3722 client->swapped); 3723 } 3724 if (which&XkbVirtualModNamesMask) { 3725 desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods, 3726 client->swapped); 3727 } 3728 if (which&XkbGroupNamesMask) { 3729 desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups, 3730 client->swapped); 3731 } 3732 if (which&XkbKeyNamesMask) { 3733 for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) { 3734 *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey]; 3735 } 3736 } 3737 if (which&XkbKeyAliasesMask) { 3738 XkbKeyAliasPtr pAl; 3739 pAl= xkb->names->key_aliases; 3740 for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) { 3741 *((XkbKeyAliasPtr)desc)= *pAl; 3742 } 3743 } 3744 if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) { 3745 register CARD32 *atm= (CARD32 *)desc; 3746 for (i=0;i<rep->nRadioGroups;i++,atm++) { 3747 *atm= (CARD32)xkb->names->radio_groups[i]; 3748 if (client->swapped) { 3749 swapl(atm,n); 3750 } 3751 } 3752 desc+= rep->nRadioGroups*4; 3753 } 3754 } 3755 3756 if ((desc-start)!=(length)) { 3757 ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", 3758 length, (unsigned long)(desc-start)); 3759 } 3760 WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep); 3761 WriteToClient(client, length, start); 3762 xfree((char *)start); 3763 return client->noClientException; 3764} 3765 3766int 3767ProcXkbGetNames(ClientPtr client) 3768{ 3769 DeviceIntPtr dev; 3770 XkbDescPtr xkb; 3771 xkbGetNamesReply rep; 3772 3773 REQUEST(xkbGetNamesReq); 3774 REQUEST_SIZE_MATCH(xkbGetNamesReq); 3775 3776 if (!(client->xkbClientFlags&_XkbClientInitialized)) 3777 return BadAccess; 3778 3779 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 3780 CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 3781 3782 xkb = dev->key->xkbInfo->desc; 3783 rep.type= X_Reply; 3784 rep.sequenceNumber= client->sequence; 3785 rep.length = 0; 3786 rep.deviceID = dev->id; 3787 rep.which = stuff->which; 3788 rep.nTypes = xkb->map->num_types; 3789 rep.firstKey = xkb->min_key_code; 3790 rep.nKeys = XkbNumKeys(xkb); 3791 if (xkb->names!=NULL) { 3792 rep.nKeyAliases= xkb->names->num_key_aliases; 3793 rep.nRadioGroups = xkb->names->num_rg; 3794 } 3795 else { 3796 rep.nKeyAliases= rep.nRadioGroups= 0; 3797 } 3798 XkbComputeGetNamesReplySize(xkb,&rep); 3799 return XkbSendNames(client,xkb,&rep); 3800} 3801 3802/***====================================================================***/ 3803 3804static CARD32 * 3805_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError) 3806{ 3807register int i; 3808 3809 for (i=0;i<nAtoms;i++,wire++) { 3810 if (swapped) { 3811 register int n; 3812 swapl(wire,n); 3813 } 3814 if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) { 3815 *pError= ((Atom)*wire); 3816 return NULL; 3817 } 3818 } 3819 return wire; 3820} 3821 3822static CARD32 * 3823_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped, 3824 Atom *pError) 3825{ 3826register unsigned i,bit; 3827 3828 for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 3829 if ((present&bit)==0) 3830 continue; 3831 if (swapped) { 3832 register int n; 3833 swapl(wire,n); 3834 } 3835 if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) { 3836 *pError= (Atom)*wire; 3837 return NULL; 3838 } 3839 wire++; 3840 } 3841 return wire; 3842} 3843 3844static Atom * 3845_XkbCopyMaskedAtoms( Atom *wire, 3846 Atom *dest, 3847 int nAtoms, 3848 CARD32 present) 3849{ 3850register int i,bit; 3851 3852 for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { 3853 if ((present&bit)==0) 3854 continue; 3855 dest[i]= *wire++; 3856 } 3857 return wire; 3858} 3859 3860static Bool 3861_XkbCheckTypeName(Atom name,int typeNdx) 3862{ 3863char * str; 3864 3865 str= NameForAtom(name); 3866 if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)|| 3867 (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0)) 3868 return False; 3869 return True; 3870} 3871 3872/** 3873 * Check the device-dependent data in the request against the device. Returns 3874 * Success, or the appropriate error code. 3875 */ 3876static int 3877_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, 3878 xkbSetNamesReq *stuff, CARD32 *data) 3879{ 3880 XkbDescRec *xkb; 3881 XkbNamesRec *names; 3882 CARD32 *tmp; 3883 Atom bad; 3884 3885 tmp = data; 3886 xkb = dev->key->xkbInfo->desc; 3887 names = xkb->names; 3888 3889 3890 if (stuff->which & XkbKeyTypeNamesMask) { 3891 int i; 3892 CARD32 *old; 3893 if ( stuff->nTypes<1 ) { 3894 client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); 3895 return BadValue; 3896 } 3897 if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { 3898 client->errorValue = _XkbErrCode4(0x03,stuff->firstType, 3899 stuff->nTypes, 3900 xkb->map->num_types); 3901 return BadValue; 3902 } 3903 if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { 3904 client->errorValue = _XkbErrCode2(0x04,stuff->firstType); 3905 return BadAccess; 3906 } 3907 old= tmp; 3908 tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); 3909 if (!tmp) { 3910 client->errorValue= bad; 3911 return BadAtom; 3912 } 3913 for (i=0;i<stuff->nTypes;i++,old++) { 3914 if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) 3915 client->errorValue= _XkbErrCode2(0x05,i); 3916 } 3917 } 3918 if (stuff->which&XkbKTLevelNamesMask) { 3919 unsigned i; 3920 XkbKeyTypePtr type; 3921 CARD8 * width; 3922 if ( stuff->nKTLevels<1 ) { 3923 client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); 3924 return BadValue; 3925 } 3926 if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= 3927 xkb->map->num_types) { 3928 client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, 3929 stuff->nKTLevels,xkb->map->num_types); 3930 return BadValue; 3931 } 3932 width = (CARD8 *)tmp; 3933 tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 3934 type = &xkb->map->types[stuff->firstKTLevel]; 3935 for (i=0;i<stuff->nKTLevels;i++,type++) { 3936 if (width[i]==0) 3937 continue; 3938 else if (width[i]!=type->num_levels) { 3939 client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, 3940 type->num_levels,width[i]); 3941 return BadMatch; 3942 } 3943 tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); 3944 if (!tmp) { 3945 client->errorValue= bad; 3946 return BadAtom; 3947 } 3948 } 3949 } 3950 if (stuff->which&XkbIndicatorNamesMask) { 3951 if (stuff->indicators==0) { 3952 client->errorValue= 0x08; 3953 return BadMatch; 3954 } 3955 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, 3956 client->swapped,&bad); 3957 if (!tmp) { 3958 client->errorValue= bad; 3959 return BadAtom; 3960 } 3961 } 3962 if (stuff->which&XkbVirtualModNamesMask) { 3963 if (stuff->virtualMods==0) { 3964 client->errorValue= 0x09; 3965 return BadMatch; 3966 } 3967 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, 3968 (CARD32)stuff->virtualMods, 3969 client->swapped,&bad); 3970 if (!tmp) { 3971 client->errorValue = bad; 3972 return BadAtom; 3973 } 3974 } 3975 if (stuff->which&XkbGroupNamesMask) { 3976 if (stuff->groupNames==0) { 3977 client->errorValue= 0x0a; 3978 return BadMatch; 3979 } 3980 tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, 3981 (CARD32)stuff->groupNames, 3982 client->swapped,&bad); 3983 if (!tmp) { 3984 client->errorValue = bad; 3985 return BadAtom; 3986 } 3987 } 3988 if (stuff->which&XkbKeyNamesMask) { 3989 if (stuff->firstKey<(unsigned)xkb->min_key_code) { 3990 client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, 3991 stuff->firstKey); 3992 return BadValue; 3993 } 3994 if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| 3995 (stuff->nKeys<1)) { 3996 client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, 3997 stuff->firstKey,stuff->nKeys); 3998 return BadValue; 3999 } 4000 tmp+= stuff->nKeys; 4001 } 4002 if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { 4003 tmp+= stuff->nKeyAliases*2; 4004 } 4005 if (stuff->which&XkbRGNamesMask) { 4006 if ( stuff->nRadioGroups<1 ) { 4007 client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); 4008 return BadValue; 4009 } 4010 tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); 4011 if (!tmp) { 4012 client->errorValue= bad; 4013 return BadAtom; 4014 } 4015 } 4016 if ((tmp-((CARD32 *)stuff))!=stuff->length) { 4017 client->errorValue = stuff->length; 4018 return BadLength; 4019 } 4020 4021 4022 4023 return Success; 4024} 4025 4026static int 4027_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) 4028{ 4029 XkbDescRec *xkb; 4030 XkbNamesRec *names; 4031 CARD32 *tmp; 4032 xkbNamesNotify nn; 4033 4034 tmp = (CARD32 *)&stuff[1]; 4035 xkb = dev->key->xkbInfo->desc; 4036 names = xkb->names; 4037 4038 if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, 4039 stuff->nKeyAliases)!=Success) { 4040 return BadAlloc; 4041 } 4042 4043 bzero(&nn,sizeof(xkbNamesNotify)); 4044 nn.changed= stuff->which; 4045 tmp = (CARD32 *)&stuff[1]; 4046 if (stuff->which&XkbKeycodesNameMask) 4047 names->keycodes= *tmp++; 4048 if (stuff->which&XkbGeometryNameMask) 4049 names->geometry= *tmp++; 4050 if (stuff->which&XkbSymbolsNameMask) 4051 names->symbols= *tmp++; 4052 if (stuff->which&XkbPhysSymbolsNameMask) 4053 names->phys_symbols= *tmp++; 4054 if (stuff->which&XkbTypesNameMask) 4055 names->types= *tmp++; 4056 if (stuff->which&XkbCompatNameMask) 4057 names->compat= *tmp++; 4058 if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { 4059 register unsigned i; 4060 register XkbKeyTypePtr type; 4061 4062 type= &xkb->map->types[stuff->firstType]; 4063 for (i=0;i<stuff->nTypes;i++,type++) { 4064 type->name= *tmp++; 4065 } 4066 nn.firstType= stuff->firstType; 4067 nn.nTypes= stuff->nTypes; 4068 } 4069 if (stuff->which&XkbKTLevelNamesMask) { 4070 register XkbKeyTypePtr type; 4071 register unsigned i; 4072 CARD8 *width; 4073 4074 width = (CARD8 *)tmp; 4075 tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); 4076 type= &xkb->map->types[stuff->firstKTLevel]; 4077 for (i=0;i<stuff->nKTLevels;i++,type++) { 4078 if (width[i]>0) { 4079 if (type->level_names) { 4080 register unsigned n; 4081 for (n=0;n<width[i];n++) { 4082 type->level_names[n]= tmp[n]; 4083 } 4084 } 4085 tmp+= width[i]; 4086 } 4087 } 4088 nn.firstLevelName= 0; 4089 nn.nLevelNames= stuff->nTypes; 4090 } 4091 if (stuff->which&XkbIndicatorNamesMask) { 4092 tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, 4093 stuff->indicators); 4094 nn.changedIndicators= stuff->indicators; 4095 } 4096 if (stuff->which&XkbVirtualModNamesMask) { 4097 tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, 4098 stuff->virtualMods); 4099 nn.changedVirtualMods= stuff->virtualMods; 4100 } 4101 if (stuff->which&XkbGroupNamesMask) { 4102 tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, 4103 stuff->groupNames); 4104 nn.changedVirtualMods= stuff->groupNames; 4105 } 4106 if (stuff->which&XkbKeyNamesMask) { 4107 memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, 4108 stuff->nKeys*XkbKeyNameLength); 4109 tmp+= stuff->nKeys; 4110 nn.firstKey= stuff->firstKey; 4111 nn.nKeys= stuff->nKeys; 4112 } 4113 if (stuff->which&XkbKeyAliasesMask) { 4114 if (stuff->nKeyAliases>0) { 4115 register int na= stuff->nKeyAliases; 4116 if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) 4117 return BadAlloc; 4118 memcpy((char *)names->key_aliases,(char *)tmp, 4119 stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); 4120 tmp+= stuff->nKeyAliases*2; 4121 } 4122 else if (names->key_aliases!=NULL) { 4123 _XkbFree(names->key_aliases); 4124 names->key_aliases= NULL; 4125 names->num_key_aliases= 0; 4126 } 4127 nn.nAliases= names->num_key_aliases; 4128 } 4129 if (stuff->which&XkbRGNamesMask) { 4130 if (stuff->nRadioGroups>0) { 4131 register unsigned i,nrg; 4132 nrg= stuff->nRadioGroups; 4133 if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) 4134 return BadAlloc; 4135 4136 for (i=0;i<stuff->nRadioGroups;i++) { 4137 names->radio_groups[i]= tmp[i]; 4138 } 4139 tmp+= stuff->nRadioGroups; 4140 } 4141 else if (names->radio_groups) { 4142 _XkbFree(names->radio_groups); 4143 names->radio_groups= NULL; 4144 names->num_rg= 0; 4145 } 4146 nn.nRadioGroups= names->num_rg; 4147 } 4148 if (nn.changed) { 4149 Bool needExtEvent; 4150 needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; 4151 XkbSendNamesNotify(dev,&nn); 4152 if (needExtEvent) { 4153 XkbSrvLedInfoPtr sli; 4154 xkbExtensionDeviceNotify edev; 4155 register int i; 4156 register unsigned bit; 4157 4158 sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, 4159 XkbXI_IndicatorsMask); 4160 sli->namesPresent= 0; 4161 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 4162 if (names->indicators[i]!=None) 4163 sli->namesPresent|= bit; 4164 } 4165 bzero(&edev,sizeof(xkbExtensionDeviceNotify)); 4166 edev.reason= XkbXI_IndicatorNamesMask; 4167 edev.ledClass= KbdFeedbackClass; 4168 edev.ledID= dev->kbdfeed->ctrl.id; 4169 edev.ledsDefined= sli->namesPresent|sli->mapsPresent; 4170 edev.ledState= sli->effectiveState; 4171 edev.firstBtn= 0; 4172 edev.nBtns= 0; 4173 edev.supported= XkbXI_AllFeaturesMask; 4174 edev.unsupported= 0; 4175 XkbSendExtensionDeviceNotify(dev,client,&edev); 4176 } 4177 } 4178 return Success; 4179} 4180 4181int 4182ProcXkbSetNames(ClientPtr client) 4183{ 4184 DeviceIntPtr dev; 4185 CARD32 *tmp; 4186 Atom bad; 4187 int rc; 4188 4189 REQUEST(xkbSetNamesReq); 4190 REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); 4191 4192 if (!(client->xkbClientFlags&_XkbClientInitialized)) 4193 return BadAccess; 4194 4195 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 4196 CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); 4197 4198 /* check device-independent stuff */ 4199 tmp = (CARD32 *)&stuff[1]; 4200 4201 if (stuff->which&XkbKeycodesNameMask) { 4202 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4203 if (!tmp) { 4204 client->errorValue = bad; 4205 return BadAtom; 4206 } 4207 } 4208 if (stuff->which&XkbGeometryNameMask) { 4209 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4210 if (!tmp) { 4211 client->errorValue = bad; 4212 return BadAtom; 4213 } 4214 } 4215 if (stuff->which&XkbSymbolsNameMask) { 4216 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4217 if (!tmp) { 4218 client->errorValue = bad; 4219 return BadAtom; 4220 } 4221 } 4222 if (stuff->which&XkbPhysSymbolsNameMask) { 4223 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4224 if (!tmp) { 4225 client->errorValue= bad; 4226 return BadAtom; 4227 } 4228 } 4229 if (stuff->which&XkbTypesNameMask) { 4230 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4231 if (!tmp) { 4232 client->errorValue = bad; 4233 return BadAtom; 4234 } 4235 } 4236 if (stuff->which&XkbCompatNameMask) { 4237 tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); 4238 if (!tmp) { 4239 client->errorValue = bad; 4240 return BadAtom; 4241 } 4242 } 4243 4244 /* start of device-dependent tests */ 4245 rc = _XkbSetNamesCheck(client, dev, stuff, tmp); 4246 if (rc != Success) 4247 return rc; 4248 4249 if (stuff->deviceSpec == XkbUseCoreKbd) 4250 { 4251 DeviceIntPtr other; 4252 for (other = inputInfo.devices; other; other = other->next) 4253 { 4254 if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 4255 { 4256 4257 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 4258 if (rc == Success) 4259 { 4260 rc = _XkbSetNamesCheck(client, other, stuff, tmp); 4261 if (rc != Success) 4262 return rc; 4263 } 4264 } 4265 } 4266 } 4267 4268 /* everything is okay -- update names */ 4269 4270 rc = _XkbSetNames(client, dev, stuff); 4271 if (rc != Success) 4272 return rc; 4273 4274 if (stuff->deviceSpec == XkbUseCoreKbd) 4275 { 4276 DeviceIntPtr other; 4277 for (other = inputInfo.devices; other; other = other->next) 4278 { 4279 if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 4280 { 4281 4282 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 4283 if (rc == Success) 4284 _XkbSetNames(client, other, stuff); 4285 } 4286 } 4287 } 4288 4289 /* everything is okay -- update names */ 4290 4291 return client->noClientException; 4292} 4293 4294/***====================================================================***/ 4295 4296#include "xkbgeom.h" 4297 4298#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) 4299 4300static char * 4301XkbWriteCountedString(char *wire,char *str,Bool swap) 4302{ 4303CARD16 len,*pLen; 4304 4305 len= (str?strlen(str):0); 4306 pLen= (CARD16 *)wire; 4307 *pLen= len; 4308 if (swap) { 4309 register int n; 4310 swaps(pLen,n); 4311 } 4312 memcpy(&wire[2],str,len); 4313 wire+= ((2+len+3)/4)*4; 4314 return wire; 4315} 4316 4317static int 4318XkbSizeGeomProperties(XkbGeometryPtr geom) 4319{ 4320register int i,size; 4321XkbPropertyPtr prop; 4322 4323 for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 4324 size+= XkbSizeCountedString(prop->name); 4325 size+= XkbSizeCountedString(prop->value); 4326 } 4327 return size; 4328} 4329 4330static char * 4331XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap) 4332{ 4333register int i; 4334register XkbPropertyPtr prop; 4335 4336 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 4337 wire= XkbWriteCountedString(wire,prop->name,swap); 4338 wire= XkbWriteCountedString(wire,prop->value,swap); 4339 } 4340 return wire; 4341} 4342 4343static int 4344XkbSizeGeomKeyAliases(XkbGeometryPtr geom) 4345{ 4346 return geom->num_key_aliases*(2*XkbKeyNameLength); 4347} 4348 4349static char * 4350XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap) 4351{ 4352register int sz; 4353 4354 sz= geom->num_key_aliases*(XkbKeyNameLength*2); 4355 if (sz>0) { 4356 memcpy(wire,(char *)geom->key_aliases,sz); 4357 wire+= sz; 4358 } 4359 return wire; 4360} 4361 4362static int 4363XkbSizeGeomColors(XkbGeometryPtr geom) 4364{ 4365register int i,size; 4366register XkbColorPtr color; 4367 4368 for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { 4369 size+= XkbSizeCountedString(color->spec); 4370 } 4371 return size; 4372} 4373 4374static char * 4375XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap) 4376{ 4377register int i; 4378register XkbColorPtr color; 4379 4380 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 4381 wire= XkbWriteCountedString(wire,color->spec,swap); 4382 } 4383 return wire; 4384} 4385 4386static int 4387XkbSizeGeomShapes(XkbGeometryPtr geom) 4388{ 4389register int i,size; 4390register XkbShapePtr shape; 4391 4392 for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 4393 register int n; 4394 register XkbOutlinePtr ol; 4395 size+= SIZEOF(xkbShapeWireDesc); 4396 for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 4397 size+= SIZEOF(xkbOutlineWireDesc); 4398 size+= ol->num_points*SIZEOF(xkbPointWireDesc); 4399 } 4400 } 4401 return size; 4402} 4403 4404static char * 4405XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap) 4406{ 4407int i; 4408XkbShapePtr shape; 4409xkbShapeWireDesc * shapeWire; 4410 4411 for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 4412 register int o; 4413 XkbOutlinePtr ol; 4414 xkbOutlineWireDesc * olWire; 4415 shapeWire= (xkbShapeWireDesc *)wire; 4416 shapeWire->name= shape->name; 4417 shapeWire->nOutlines= shape->num_outlines; 4418 if (shape->primary!=NULL) 4419 shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); 4420 else shapeWire->primaryNdx= XkbNoShape; 4421 if (shape->approx!=NULL) 4422 shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); 4423 else shapeWire->approxNdx= XkbNoShape; 4424 if (swap) { 4425 register int n; 4426 swapl(&shapeWire->name,n); 4427 } 4428 wire= (char *)&shapeWire[1]; 4429 for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { 4430 register int p; 4431 XkbPointPtr pt; 4432 xkbPointWireDesc * ptWire; 4433 olWire= (xkbOutlineWireDesc *)wire; 4434 olWire->nPoints= ol->num_points; 4435 olWire->cornerRadius= ol->corner_radius; 4436 wire= (char *)&olWire[1]; 4437 ptWire= (xkbPointWireDesc *)wire; 4438 for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 4439 ptWire[p].x= pt->x; 4440 ptWire[p].y= pt->y; 4441 if (swap) { 4442 register int n; 4443 swaps(&ptWire[p].x,n); 4444 swaps(&ptWire[p].y,n); 4445 } 4446 } 4447 wire= (char *)&ptWire[ol->num_points]; 4448 } 4449 } 4450 return wire; 4451} 4452 4453static int 4454XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) 4455{ 4456register int i,size; 4457 4458 for (i=size=0;i<num_doodads;i++,doodad++) { 4459 size+= SIZEOF(xkbAnyDoodadWireDesc); 4460 if (doodad->any.type==XkbTextDoodad) { 4461 size+= XkbSizeCountedString(doodad->text.text); 4462 size+= XkbSizeCountedString(doodad->text.font); 4463 } 4464 else if (doodad->any.type==XkbLogoDoodad) { 4465 size+= XkbSizeCountedString(doodad->logo.logo_name); 4466 } 4467 } 4468 return size; 4469} 4470 4471static char * 4472XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap) 4473{ 4474register int i; 4475xkbDoodadWireDesc * doodadWire; 4476 4477 for (i=0;i<num_doodads;i++,doodad++) { 4478 doodadWire= (xkbDoodadWireDesc *)wire; 4479 wire= (char *)&doodadWire[1]; 4480 bzero(doodadWire,SIZEOF(xkbDoodadWireDesc)); 4481 doodadWire->any.name= doodad->any.name; 4482 doodadWire->any.type= doodad->any.type; 4483 doodadWire->any.priority= doodad->any.priority; 4484 doodadWire->any.top= doodad->any.top; 4485 doodadWire->any.left= doodad->any.left; 4486 if (swap) { 4487 register int n; 4488 swapl(&doodadWire->any.name,n); 4489 swaps(&doodadWire->any.top,n); 4490 swaps(&doodadWire->any.left,n); 4491 } 4492 switch (doodad->any.type) { 4493 case XkbOutlineDoodad: 4494 case XkbSolidDoodad: 4495 doodadWire->shape.angle= doodad->shape.angle; 4496 doodadWire->shape.colorNdx= doodad->shape.color_ndx; 4497 doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; 4498 if (swap) { 4499 register int n; 4500 swaps(&doodadWire->shape.angle,n); 4501 } 4502 break; 4503 case XkbTextDoodad: 4504 doodadWire->text.angle= doodad->text.angle; 4505 doodadWire->text.width= doodad->text.width; 4506 doodadWire->text.height= doodad->text.height; 4507 doodadWire->text.colorNdx= doodad->text.color_ndx; 4508 if (swap) { 4509 register int n; 4510 swaps(&doodadWire->text.angle,n); 4511 swaps(&doodadWire->text.width,n); 4512 swaps(&doodadWire->text.height,n); 4513 } 4514 wire= XkbWriteCountedString(wire,doodad->text.text,swap); 4515 wire= XkbWriteCountedString(wire,doodad->text.font,swap); 4516 break; 4517 case XkbIndicatorDoodad: 4518 doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; 4519 doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; 4520 doodadWire->indicator.offColorNdx= 4521 doodad->indicator.off_color_ndx; 4522 break; 4523 case XkbLogoDoodad: 4524 doodadWire->logo.angle= doodad->logo.angle; 4525 doodadWire->logo.colorNdx= doodad->logo.color_ndx; 4526 doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; 4527 wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap); 4528 break; 4529 default: 4530 ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", 4531 doodad->any.type); 4532 ErrorF("[xkb] Ignored\n"); 4533 break; 4534 } 4535 } 4536 return wire; 4537} 4538 4539static char * 4540XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap) 4541{ 4542register int r; 4543XkbOverlayRowPtr row; 4544xkbOverlayWireDesc * olWire; 4545 4546 olWire= (xkbOverlayWireDesc *)wire; 4547 olWire->name= ol->name; 4548 olWire->nRows= ol->num_rows; 4549 if (swap) { 4550 register int n; 4551 swapl(&olWire->name,n); 4552 } 4553 wire= (char *)&olWire[1]; 4554 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 4555 unsigned int k; 4556 XkbOverlayKeyPtr key; 4557 xkbOverlayRowWireDesc * rowWire; 4558 rowWire= (xkbOverlayRowWireDesc *)wire; 4559 rowWire->rowUnder= row->row_under; 4560 rowWire->nKeys= row->num_keys; 4561 wire= (char *)&rowWire[1]; 4562 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 4563 xkbOverlayKeyWireDesc * keyWire; 4564 keyWire= (xkbOverlayKeyWireDesc *)wire; 4565 memcpy(keyWire->over,key->over.name,XkbKeyNameLength); 4566 memcpy(keyWire->under,key->under.name,XkbKeyNameLength); 4567 wire= (char *)&keyWire[1]; 4568 } 4569 } 4570 return wire; 4571} 4572 4573static int 4574XkbSizeGeomSections(XkbGeometryPtr geom) 4575{ 4576register int i,size; 4577XkbSectionPtr section; 4578 4579 for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { 4580 size+= SIZEOF(xkbSectionWireDesc); 4581 if (section->rows) { 4582 int r; 4583 XkbRowPtr row; 4584 for (r=0,row=section->rows;r<section->num_rows;row++,r++) { 4585 size+= SIZEOF(xkbRowWireDesc); 4586 size+= row->num_keys*SIZEOF(xkbKeyWireDesc); 4587 } 4588 } 4589 if (section->doodads) 4590 size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads); 4591 if (section->overlays) { 4592 int o; 4593 XkbOverlayPtr ol; 4594 for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { 4595 int r; 4596 XkbOverlayRowPtr row; 4597 size+= SIZEOF(xkbOverlayWireDesc); 4598 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 4599 size+= SIZEOF(xkbOverlayRowWireDesc); 4600 size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); 4601 } 4602 } 4603 } 4604 } 4605 return size; 4606} 4607 4608static char * 4609XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap) 4610{ 4611register int i; 4612XkbSectionPtr section; 4613xkbSectionWireDesc * sectionWire; 4614 4615 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 4616 sectionWire= (xkbSectionWireDesc *)wire; 4617 sectionWire->name= section->name; 4618 sectionWire->top= section->top; 4619 sectionWire->left= section->left; 4620 sectionWire->width= section->width; 4621 sectionWire->height= section->height; 4622 sectionWire->angle= section->angle; 4623 sectionWire->priority= section->priority; 4624 sectionWire->nRows= section->num_rows; 4625 sectionWire->nDoodads= section->num_doodads; 4626 sectionWire->nOverlays= section->num_overlays; 4627 sectionWire->pad= 0; 4628 if (swap) { 4629 register int n; 4630 swapl(§ionWire->name,n); 4631 swaps(§ionWire->top,n); 4632 swaps(§ionWire->left,n); 4633 swaps(§ionWire->width,n); 4634 swaps(§ionWire->height,n); 4635 swaps(§ionWire->angle,n); 4636 } 4637 wire= (char *)§ionWire[1]; 4638 if (section->rows) { 4639 int r; 4640 XkbRowPtr row; 4641 xkbRowWireDesc * rowWire; 4642 for (r=0,row=section->rows;r<section->num_rows;r++,row++) { 4643 rowWire= (xkbRowWireDesc *)wire; 4644 rowWire->top= row->top; 4645 rowWire->left= row->left; 4646 rowWire->nKeys= row->num_keys; 4647 rowWire->vertical= row->vertical; 4648 rowWire->pad= 0; 4649 if (swap) { 4650 register int n; 4651 swaps(&rowWire->top,n); 4652 swaps(&rowWire->left,n); 4653 } 4654 wire= (char *)&rowWire[1]; 4655 if (row->keys) { 4656 int k; 4657 XkbKeyPtr key; 4658 xkbKeyWireDesc * keyWire; 4659 keyWire= (xkbKeyWireDesc *)wire; 4660 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 4661 memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); 4662 keyWire[k].gap= key->gap; 4663 keyWire[k].shapeNdx= key->shape_ndx; 4664 keyWire[k].colorNdx= key->color_ndx; 4665 if (swap) { 4666 register int n; 4667 swaps(&keyWire[k].gap,n); 4668 } 4669 } 4670 wire= (char *)&keyWire[row->num_keys]; 4671 } 4672 } 4673 } 4674 if (section->doodads) { 4675 wire= XkbWriteGeomDoodads(wire, 4676 section->num_doodads,section->doodads, 4677 swap); 4678 } 4679 if (section->overlays) { 4680 register int o; 4681 for (o=0;o<section->num_overlays;o++) { 4682 wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap); 4683 } 4684 } 4685 } 4686 return wire; 4687} 4688 4689static Status 4690XkbComputeGetGeometryReplySize( XkbGeometryPtr geom, 4691 xkbGetGeometryReply * rep, 4692 Atom name) 4693{ 4694int len; 4695 4696 if (geom!=NULL) { 4697 len= XkbSizeCountedString(geom->label_font); 4698 len+= XkbSizeGeomProperties(geom); 4699 len+= XkbSizeGeomColors(geom); 4700 len+= XkbSizeGeomShapes(geom); 4701 len+= XkbSizeGeomSections(geom); 4702 len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads); 4703 len+= XkbSizeGeomKeyAliases(geom); 4704 rep->length= len/4; 4705 rep->found= True; 4706 rep->name= geom->name; 4707 rep->widthMM= geom->width_mm; 4708 rep->heightMM= geom->height_mm; 4709 rep->nProperties= geom->num_properties; 4710 rep->nColors= geom->num_colors; 4711 rep->nShapes= geom->num_shapes; 4712 rep->nSections= geom->num_sections; 4713 rep->nDoodads= geom->num_doodads; 4714 rep->nKeyAliases= geom->num_key_aliases; 4715 rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color); 4716 rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color); 4717 } 4718 else { 4719 rep->length= 0; 4720 rep->found= False; 4721 rep->name= name; 4722 rep->widthMM= rep->heightMM= 0; 4723 rep->nProperties= rep->nColors= rep->nShapes= 0; 4724 rep->nSections= rep->nDoodads= 0; 4725 rep->nKeyAliases= 0; 4726 rep->labelColorNdx= rep->baseColorNdx= 0; 4727 } 4728 return Success; 4729} 4730 4731static int 4732XkbSendGeometry( ClientPtr client, 4733 XkbGeometryPtr geom, 4734 xkbGetGeometryReply * rep, 4735 Bool freeGeom) 4736{ 4737 char *desc,*start; 4738 int len; 4739 4740 if (geom!=NULL) { 4741 len= rep->length*4; 4742 start= desc= (char *)xalloc(len); 4743 if (!start) 4744 return BadAlloc; 4745 desc= XkbWriteCountedString(desc,geom->label_font,client->swapped); 4746 if ( rep->nProperties>0 ) 4747 desc = XkbWriteGeomProperties(desc,geom,client->swapped); 4748 if ( rep->nColors>0 ) 4749 desc = XkbWriteGeomColors(desc,geom,client->swapped); 4750 if ( rep->nShapes>0 ) 4751 desc = XkbWriteGeomShapes(desc,geom,client->swapped); 4752 if ( rep->nSections>0 ) 4753 desc = XkbWriteGeomSections(desc,geom,client->swapped); 4754 if ( rep->nDoodads>0 ) 4755 desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads, 4756 client->swapped); 4757 if ( rep->nKeyAliases>0 ) 4758 desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped); 4759 if ((desc-start)!=(len)) { 4760 ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", 4761 len, (unsigned long)(desc-start)); 4762 } 4763 } 4764 else { 4765 len= 0; 4766 start= NULL; 4767 } 4768 if (client->swapped) { 4769 register int n; 4770 swaps(&rep->sequenceNumber,n); 4771 swapl(&rep->length,n); 4772 swapl(&rep->name,n); 4773 swaps(&rep->widthMM,n); 4774 swaps(&rep->heightMM,n); 4775 swaps(&rep->nProperties,n); 4776 swaps(&rep->nColors,n); 4777 swaps(&rep->nShapes,n); 4778 swaps(&rep->nSections,n); 4779 swaps(&rep->nDoodads,n); 4780 swaps(&rep->nKeyAliases,n); 4781 } 4782 WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep); 4783 if (len>0) 4784 WriteToClient(client, len, start); 4785 if (start!=NULL) 4786 xfree((char *)start); 4787 if (freeGeom) 4788 XkbFreeGeometry(geom,XkbGeomAllMask,True); 4789 return client->noClientException; 4790} 4791 4792int 4793ProcXkbGetGeometry(ClientPtr client) 4794{ 4795 DeviceIntPtr dev; 4796 xkbGetGeometryReply rep; 4797 XkbGeometryPtr geom; 4798 Bool shouldFree; 4799 Status status; 4800 4801 REQUEST(xkbGetGeometryReq); 4802 REQUEST_SIZE_MATCH(xkbGetGeometryReq); 4803 4804 if (!(client->xkbClientFlags&_XkbClientInitialized)) 4805 return BadAccess; 4806 4807 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 4808 CHK_ATOM_OR_NONE(stuff->name); 4809 4810 geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree); 4811 rep.type= X_Reply; 4812 rep.deviceID= dev->id; 4813 rep.sequenceNumber= client->sequence; 4814 rep.length= 0; 4815 status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name); 4816 if (status!=Success) 4817 return status; 4818 else return XkbSendGeometry(client,geom,&rep,shouldFree); 4819} 4820 4821/***====================================================================***/ 4822 4823static char * 4824_GetCountedString(char **wire_inout,Bool swap) 4825{ 4826char * wire,*str; 4827CARD16 len,*plen; 4828 4829 wire= *wire_inout; 4830 plen= (CARD16 *)wire; 4831 if (swap) { 4832 register int n; 4833 swaps(plen,n); 4834 } 4835 len= *plen; 4836 str= (char *)_XkbAlloc(len+1); 4837 if (str) { 4838 memcpy(str,&wire[2],len); 4839 str[len]= '\0'; 4840 } 4841 wire+= XkbPaddedSize(len+2); 4842 *wire_inout= wire; 4843 return str; 4844} 4845 4846static Status 4847_CheckSetDoodad( char ** wire_inout, 4848 XkbGeometryPtr geom, 4849 XkbSectionPtr section, 4850 ClientPtr client) 4851{ 4852char * wire; 4853xkbDoodadWireDesc * dWire; 4854XkbDoodadPtr doodad; 4855 4856 dWire= (xkbDoodadWireDesc *)(*wire_inout); 4857 wire= (char *)&dWire[1]; 4858 if (client->swapped) { 4859 register int n; 4860 swapl(&dWire->any.name,n); 4861 swaps(&dWire->any.top,n); 4862 swaps(&dWire->any.left,n); 4863 swaps(&dWire->any.angle,n); 4864 } 4865 CHK_ATOM_ONLY(dWire->any.name); 4866 doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); 4867 if (!doodad) 4868 return BadAlloc; 4869 doodad->any.type= dWire->any.type; 4870 doodad->any.priority= dWire->any.priority; 4871 doodad->any.top= dWire->any.top; 4872 doodad->any.left= dWire->any.left; 4873 doodad->any.angle= dWire->any.angle; 4874 switch (doodad->any.type) { 4875 case XkbOutlineDoodad: 4876 case XkbSolidDoodad: 4877 if (dWire->shape.colorNdx>=geom->num_colors) { 4878 client->errorValue= _XkbErrCode3(0x40,geom->num_colors, 4879 dWire->shape.colorNdx); 4880 return BadMatch; 4881 } 4882 if (dWire->shape.shapeNdx>=geom->num_shapes) { 4883 client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, 4884 dWire->shape.shapeNdx); 4885 return BadMatch; 4886 } 4887 doodad->shape.color_ndx= dWire->shape.colorNdx; 4888 doodad->shape.shape_ndx= dWire->shape.shapeNdx; 4889 break; 4890 case XkbTextDoodad: 4891 if (dWire->text.colorNdx>=geom->num_colors) { 4892 client->errorValue= _XkbErrCode3(0x42,geom->num_colors, 4893 dWire->text.colorNdx); 4894 return BadMatch; 4895 } 4896 if (client->swapped) { 4897 register int n; 4898 swaps(&dWire->text.width,n); 4899 swaps(&dWire->text.height,n); 4900 } 4901 doodad->text.width= dWire->text.width; 4902 doodad->text.height= dWire->text.height; 4903 doodad->text.color_ndx= dWire->text.colorNdx; 4904 doodad->text.text= _GetCountedString(&wire,client->swapped); 4905 doodad->text.font= _GetCountedString(&wire,client->swapped); 4906 break; 4907 case XkbIndicatorDoodad: 4908 if (dWire->indicator.onColorNdx>=geom->num_colors) { 4909 client->errorValue= _XkbErrCode3(0x43,geom->num_colors, 4910 dWire->indicator.onColorNdx); 4911 return BadMatch; 4912 } 4913 if (dWire->indicator.offColorNdx>=geom->num_colors) { 4914 client->errorValue= _XkbErrCode3(0x44,geom->num_colors, 4915 dWire->indicator.offColorNdx); 4916 return BadMatch; 4917 } 4918 if (dWire->indicator.shapeNdx>=geom->num_shapes) { 4919 client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, 4920 dWire->indicator.shapeNdx); 4921 return BadMatch; 4922 } 4923 doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; 4924 doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; 4925 doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; 4926 break; 4927 case XkbLogoDoodad: 4928 if (dWire->logo.colorNdx>=geom->num_colors) { 4929 client->errorValue= _XkbErrCode3(0x46,geom->num_colors, 4930 dWire->logo.colorNdx); 4931 return BadMatch; 4932 } 4933 if (dWire->logo.shapeNdx>=geom->num_shapes) { 4934 client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, 4935 dWire->logo.shapeNdx); 4936 return BadMatch; 4937 } 4938 doodad->logo.color_ndx= dWire->logo.colorNdx; 4939 doodad->logo.shape_ndx= dWire->logo.shapeNdx; 4940 doodad->logo.logo_name= _GetCountedString(&wire,client->swapped); 4941 break; 4942 default: 4943 client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); 4944 return BadValue; 4945 } 4946 *wire_inout= wire; 4947 return Success; 4948} 4949 4950static Status 4951_CheckSetOverlay( char ** wire_inout, 4952 XkbGeometryPtr geom, 4953 XkbSectionPtr section, 4954 ClientPtr client) 4955{ 4956register int r; 4957char * wire; 4958XkbOverlayPtr ol; 4959xkbOverlayWireDesc * olWire; 4960xkbOverlayRowWireDesc * rWire; 4961 4962 wire= *wire_inout; 4963 olWire= (xkbOverlayWireDesc *)wire; 4964 if (client->swapped) { 4965 register int n; 4966 swapl(&olWire->name,n); 4967 } 4968 CHK_ATOM_ONLY(olWire->name); 4969 ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); 4970 rWire= (xkbOverlayRowWireDesc *)&olWire[1]; 4971 for (r=0;r<olWire->nRows;r++) { 4972 register int k; 4973 xkbOverlayKeyWireDesc * kWire; 4974 XkbOverlayRowPtr row; 4975 4976 if (rWire->rowUnder>section->num_rows) { 4977 client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, 4978 rWire->rowUnder); 4979 return BadMatch; 4980 } 4981 row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); 4982 kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; 4983 for (k=0;k<rWire->nKeys;k++,kWire++) { 4984 if (XkbAddGeomOverlayKey(ol,row, 4985 (char *)kWire->over,(char *)kWire->under)==NULL) { 4986 client->errorValue= _XkbErrCode3(0x21,r,k); 4987 return BadMatch; 4988 } 4989 } 4990 rWire= (xkbOverlayRowWireDesc *)kWire; 4991 } 4992 olWire= (xkbOverlayWireDesc *)rWire; 4993 wire= (char *)olWire; 4994 *wire_inout= wire; 4995 return Success; 4996} 4997 4998static Status 4999_CheckSetSections( XkbGeometryPtr geom, 5000 xkbSetGeometryReq * req, 5001 char ** wire_inout, 5002 ClientPtr client) 5003{ 5004Status status; 5005register int s; 5006char * wire; 5007xkbSectionWireDesc * sWire; 5008XkbSectionPtr section; 5009 5010 wire= *wire_inout; 5011 if (req->nSections<1) 5012 return Success; 5013 sWire= (xkbSectionWireDesc *)wire; 5014 for (s=0;s<req->nSections;s++) { 5015 register int r; 5016 xkbRowWireDesc * rWire; 5017 if (client->swapped) { 5018 register int n; 5019 swapl(&sWire->name,n); 5020 swaps(&sWire->top,n); 5021 swaps(&sWire->left,n); 5022 swaps(&sWire->width,n); 5023 swaps(&sWire->height,n); 5024 swaps(&sWire->angle,n); 5025 } 5026 CHK_ATOM_ONLY(sWire->name); 5027 section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, 5028 sWire->nDoodads,sWire->nOverlays); 5029 if (!section) 5030 return BadAlloc; 5031 section->priority= sWire->priority; 5032 section->top= sWire->top; 5033 section->left= sWire->left; 5034 section->width= sWire->width; 5035 section->height= sWire->height; 5036 section->angle= sWire->angle; 5037 rWire= (xkbRowWireDesc *)&sWire[1]; 5038 for (r=0;r<sWire->nRows;r++) { 5039 register int k; 5040 XkbRowPtr row; 5041 xkbKeyWireDesc * kWire; 5042 if (client->swapped) { 5043 register int n; 5044 swaps(&rWire->top,n); 5045 swaps(&rWire->left,n); 5046 } 5047 row= XkbAddGeomRow(section,rWire->nKeys); 5048 if (!row) 5049 return BadAlloc; 5050 row->top= rWire->top; 5051 row->left= rWire->left; 5052 row->vertical= rWire->vertical; 5053 kWire= (xkbKeyWireDesc *)&rWire[1]; 5054 for (k=0;k<rWire->nKeys;k++) { 5055 XkbKeyPtr key; 5056 key= XkbAddGeomKey(row); 5057 if (!key) 5058 return BadAlloc; 5059 memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); 5060 key->gap= kWire[k].gap; 5061 key->shape_ndx= kWire[k].shapeNdx; 5062 key->color_ndx= kWire[k].colorNdx; 5063 if (key->shape_ndx>=geom->num_shapes) { 5064 client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, 5065 geom->num_shapes); 5066 return BadMatch; 5067 } 5068 if (key->color_ndx>=geom->num_colors) { 5069 client->errorValue= _XkbErrCode3(0x11,key->color_ndx, 5070 geom->num_colors); 5071 return BadMatch; 5072 } 5073 } 5074 rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; 5075 } 5076 wire= (char *)rWire; 5077 if (sWire->nDoodads>0) { 5078 register int d; 5079 for (d=0;d<sWire->nDoodads;d++) { 5080 status=_CheckSetDoodad(&wire,geom,section,client); 5081 if (status!=Success) 5082 return status; 5083 } 5084 } 5085 if (sWire->nOverlays>0) { 5086 register int o; 5087 for (o=0;o<sWire->nOverlays;o++) { 5088 status= _CheckSetOverlay(&wire,geom,section,client); 5089 if (status!=Success) 5090 return status; 5091 } 5092 } 5093 sWire= (xkbSectionWireDesc *)wire; 5094 } 5095 wire= (char *)sWire; 5096 *wire_inout= wire; 5097 return Success; 5098} 5099 5100static Status 5101_CheckSetShapes( XkbGeometryPtr geom, 5102 xkbSetGeometryReq * req, 5103 char ** wire_inout, 5104 ClientPtr client) 5105{ 5106register int i; 5107char * wire; 5108 5109 wire= *wire_inout; 5110 if (req->nShapes<1) { 5111 client->errorValue= _XkbErrCode2(0x06,req->nShapes); 5112 return BadValue; 5113 } 5114 else { 5115 xkbShapeWireDesc * shapeWire; 5116 XkbShapePtr shape; 5117 register int o; 5118 shapeWire= (xkbShapeWireDesc *)wire; 5119 for (i=0;i<req->nShapes;i++) { 5120 xkbOutlineWireDesc * olWire; 5121 XkbOutlinePtr ol; 5122 shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); 5123 if (!shape) 5124 return BadAlloc; 5125 olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); 5126 for (o=0;o<shapeWire->nOutlines;o++) { 5127 register int p; 5128 XkbPointPtr pt; 5129 xkbPointWireDesc * ptWire; 5130 5131 ol= XkbAddGeomOutline(shape,olWire->nPoints); 5132 if (!ol) 5133 return BadAlloc; 5134 ol->corner_radius= olWire->cornerRadius; 5135 ptWire= (xkbPointWireDesc *)&olWire[1]; 5136 for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { 5137 pt->x= ptWire[p].x; 5138 pt->y= ptWire[p].y; 5139 if (client->swapped) { 5140 register int n; 5141 swaps(&pt->x,n); 5142 swaps(&pt->y,n); 5143 } 5144 } 5145 ol->num_points= olWire->nPoints; 5146 olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); 5147 } 5148 if (shapeWire->primaryNdx!=XkbNoShape) 5149 shape->primary= &shape->outlines[shapeWire->primaryNdx]; 5150 if (shapeWire->approxNdx!=XkbNoShape) 5151 shape->approx= &shape->outlines[shapeWire->approxNdx]; 5152 shapeWire= (xkbShapeWireDesc *)olWire; 5153 } 5154 wire= (char *)shapeWire; 5155 } 5156 if (geom->num_shapes!=req->nShapes) { 5157 client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); 5158 return BadMatch; 5159 } 5160 5161 *wire_inout= wire; 5162 return Success; 5163} 5164 5165static Status 5166_CheckSetGeom( XkbGeometryPtr geom, 5167 xkbSetGeometryReq * req, 5168 ClientPtr client) 5169{ 5170register int i; 5171Status status; 5172char * wire; 5173 5174 wire= (char *)&req[1]; 5175 geom->label_font= _GetCountedString(&wire,client->swapped); 5176 5177 for (i=0;i<req->nProperties;i++) { 5178 char *name,*val; 5179 name= _GetCountedString(&wire,client->swapped); 5180 if (!name) 5181 return BadAlloc; 5182 val= _GetCountedString(&wire,client->swapped); 5183 if (!val) { 5184 xfree(name); 5185 return BadAlloc; 5186 } 5187 if (XkbAddGeomProperty(geom,name,val)==NULL) { 5188 xfree(name); 5189 xfree(val); 5190 return BadAlloc; 5191 } 5192 xfree(name); 5193 xfree(val); 5194 } 5195 5196 if (req->nColors<2) { 5197 client->errorValue= _XkbErrCode3(0x01,2,req->nColors); 5198 return BadValue; 5199 } 5200 if (req->baseColorNdx>req->nColors) { 5201 client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); 5202 return BadMatch; 5203 } 5204 if (req->labelColorNdx>req->nColors) { 5205 client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); 5206 return BadMatch; 5207 } 5208 if (req->labelColorNdx==req->baseColorNdx) { 5209 client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, 5210 req->labelColorNdx); 5211 return BadMatch; 5212 } 5213 5214 for (i=0;i<req->nColors;i++) { 5215 char *name; 5216 name= _GetCountedString(&wire,client->swapped); 5217 if (!name) 5218 return BadAlloc; 5219 if (!XkbAddGeomColor(geom,name,geom->num_colors)) { 5220 xfree(name); 5221 return BadAlloc; 5222 } 5223 xfree(name); 5224 } 5225 if (req->nColors!=geom->num_colors) { 5226 client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); 5227 return BadMatch; 5228 } 5229 geom->label_color= &geom->colors[req->labelColorNdx]; 5230 geom->base_color= &geom->colors[req->baseColorNdx]; 5231 5232 if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) 5233 return status; 5234 5235 if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) 5236 return status; 5237 5238 for (i=0;i<req->nDoodads;i++) { 5239 status=_CheckSetDoodad(&wire,geom,NULL,client); 5240 if (status!=Success) 5241 return status; 5242 } 5243 5244 for (i=0;i<req->nKeyAliases;i++) { 5245 if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) 5246 return BadAlloc; 5247 wire+= 2*XkbKeyNameLength; 5248 } 5249 return Success; 5250} 5251 5252static int 5253_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) 5254{ 5255 XkbDescPtr xkb; 5256 Bool new_name; 5257 xkbNewKeyboardNotify nkn; 5258 XkbGeometryPtr geom,old; 5259 XkbGeometrySizesRec sizes; 5260 Status status; 5261 5262 xkb= dev->key->xkbInfo->desc; 5263 old= xkb->geom; 5264 xkb->geom= NULL; 5265 5266 sizes.which= XkbGeomAllMask; 5267 sizes.num_properties= stuff->nProperties; 5268 sizes.num_colors= stuff->nColors; 5269 sizes.num_shapes= stuff->nShapes; 5270 sizes.num_sections= stuff->nSections; 5271 sizes.num_doodads= stuff->nDoodads; 5272 sizes.num_key_aliases= stuff->nKeyAliases; 5273 if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { 5274 xkb->geom= old; 5275 return status; 5276 } 5277 geom= xkb->geom; 5278 geom->name= stuff->name; 5279 geom->width_mm= stuff->widthMM; 5280 geom->height_mm= stuff->heightMM; 5281 if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { 5282 XkbFreeGeometry(geom,XkbGeomAllMask,True); 5283 xkb->geom= old; 5284 return status; 5285 } 5286 new_name= (xkb->names->geometry!=geom->name); 5287 xkb->names->geometry= geom->name; 5288 if (old) 5289 XkbFreeGeometry(old,XkbGeomAllMask,True); 5290 if (new_name) { 5291 xkbNamesNotify nn; 5292 bzero(&nn,sizeof(xkbNamesNotify)); 5293 nn.changed= XkbGeometryNameMask; 5294 XkbSendNamesNotify(dev,&nn); 5295 } 5296 nkn.deviceID= nkn.oldDeviceID= dev->id; 5297 nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; 5298 nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; 5299 nkn.requestMajor= XkbReqCode; 5300 nkn.requestMinor= X_kbSetGeometry; 5301 nkn.changed= XkbNKN_GeometryMask; 5302 XkbSendNewKeyboardNotify(dev,&nkn); 5303 return Success; 5304} 5305 5306int 5307ProcXkbSetGeometry(ClientPtr client) 5308{ 5309 DeviceIntPtr dev; 5310 int rc; 5311 5312 REQUEST(xkbSetGeometryReq); 5313 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 5314 5315 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5316 return BadAccess; 5317 5318 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 5319 CHK_ATOM_OR_NONE(stuff->name); 5320 5321 rc = _XkbSetGeometry(client, dev, stuff); 5322 if (rc != Success) 5323 return rc; 5324 5325 if (stuff->deviceSpec == XkbUseCoreKbd) 5326 { 5327 DeviceIntPtr other; 5328 for (other = inputInfo.devices; other; other = other->next) 5329 { 5330 if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev)) 5331 { 5332 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 5333 if (rc == Success) 5334 _XkbSetGeometry(client, other, stuff); 5335 } 5336 } 5337 } 5338 5339 return Success; 5340} 5341 5342/***====================================================================***/ 5343 5344int 5345ProcXkbPerClientFlags(ClientPtr client) 5346{ 5347 DeviceIntPtr dev; 5348 xkbPerClientFlagsReply rep; 5349 XkbInterestPtr interest; 5350 Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 5351 5352 REQUEST(xkbPerClientFlagsReq); 5353 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 5354 5355 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5356 return BadAccess; 5357 5358 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5359 CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); 5360 CHK_MASK_MATCH(0x02,stuff->change,stuff->value); 5361 5362 interest = XkbFindClientResource((DevicePtr)dev,client); 5363 rep.type= X_Reply; 5364 rep.length = 0; 5365 rep.sequenceNumber = client->sequence; 5366 if (stuff->change) { 5367 client->xkbClientFlags&= ~stuff->change; 5368 client->xkbClientFlags|= stuff->value; 5369 } 5370 if (stuff->change&XkbPCF_AutoResetControlsMask) { 5371 Bool want; 5372 want= stuff->value&XkbPCF_AutoResetControlsMask; 5373 if (interest && !want) { 5374 interest->autoCtrls= interest->autoCtrlValues= 0; 5375 } 5376 else if (want && (!interest)) { 5377 XID id = FakeClientID(client->index); 5378 AddResource(id,RT_XKBCLIENT,dev); 5379 interest= XkbAddClientResource((DevicePtr)dev,client,id); 5380 if (!interest) 5381 return BadAlloc; 5382 } 5383 if (interest && want ) { 5384 register unsigned affect; 5385 affect= stuff->ctrlsToChange; 5386 5387 CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); 5388 CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); 5389 CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); 5390 5391 interest->autoCtrls&= ~affect; 5392 interest->autoCtrlValues&= ~affect; 5393 interest->autoCtrls|= stuff->autoCtrls&affect; 5394 interest->autoCtrlValues|= stuff->autoCtrlValues&affect; 5395 } 5396 } 5397 rep.supported = XkbPCF_AllFlagsMask; 5398 rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; 5399 if (interest) { 5400 rep.autoCtrls= interest->autoCtrls; 5401 rep.autoCtrlValues= interest->autoCtrlValues; 5402 } 5403 else { 5404 rep.autoCtrls= rep.autoCtrlValues= 0; 5405 } 5406 if ( client->swapped ) { 5407 register int n; 5408 swaps(&rep.sequenceNumber, n); 5409 swapl(&rep.supported,n); 5410 swapl(&rep.value,n); 5411 swapl(&rep.autoCtrls,n); 5412 swapl(&rep.autoCtrlValues,n); 5413 } 5414 WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); 5415 return client->noClientException; 5416} 5417 5418/***====================================================================***/ 5419 5420/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 5421/* and wildcards */ 5422static unsigned char componentSpecLegal[] = { 5423 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 5424 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 5425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5426 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5427}; 5428 5429/* same as above but accepts percent, plus and bar too */ 5430static unsigned char componentExprLegal[] = { 5431 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 5432 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 5433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5434 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5435}; 5436 5437static char * 5438GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) 5439{ 5440int len; 5441register int i; 5442unsigned char *wire,*str,*tmp,*legal; 5443 5444 if (allowExpr) legal= &componentExprLegal[0]; 5445 else legal= &componentSpecLegal[0]; 5446 5447 wire= *pWire; 5448 len= (*(unsigned char *)wire++); 5449 if (len>0) { 5450 str= (unsigned char *)_XkbCalloc(1, len+1); 5451 if (str) { 5452 tmp= str; 5453 for (i=0;i<len;i++) { 5454 if (legal[(*wire)/8]&(1<<((*wire)%8))) 5455 *tmp++= *wire++; 5456 else wire++; 5457 } 5458 if (tmp!=str) 5459 *tmp++= '\0'; 5460 else { 5461 _XkbFree(str); 5462 str= NULL; 5463 } 5464 } 5465 else { 5466 *errRtrn= BadAlloc; 5467 } 5468 } 5469 else { 5470 str= NULL; 5471 } 5472 *pWire= wire; 5473 return (char *)str; 5474} 5475 5476/***====================================================================***/ 5477 5478int 5479ProcXkbListComponents(ClientPtr client) 5480{ 5481 DeviceIntPtr dev; 5482 xkbListComponentsReply rep; 5483 unsigned len; 5484 int status; 5485 unsigned char * str; 5486 XkbSrvListInfoRec list; 5487 5488 REQUEST(xkbListComponentsReq); 5489 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 5490 5491 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5492 return BadAccess; 5493 5494 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 5495 5496 status= Success; 5497 str= (unsigned char *)&stuff[1]; 5498 bzero(&list,sizeof(XkbSrvListInfoRec)); 5499 list.maxRtrn= stuff->maxNames; 5500 list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status); 5501 list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status); 5502 list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status); 5503 list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status); 5504 list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status); 5505 list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status); 5506 if (status!=Success) 5507 return status; 5508 len= str-((unsigned char *)stuff); 5509 if ((XkbPaddedSize(len)/4)!=stuff->length) 5510 return BadLength; 5511 if ((status=XkbDDXList(dev,&list,client))!=Success) { 5512 if (list.pool) { 5513 _XkbFree(list.pool); 5514 list.pool= NULL; 5515 } 5516 return status; 5517 } 5518 bzero(&rep,sizeof(xkbListComponentsReply)); 5519 rep.type= X_Reply; 5520 rep.deviceID = dev->id; 5521 rep.sequenceNumber = client->sequence; 5522 rep.length = XkbPaddedSize(list.nPool)/4; 5523 rep.nKeymaps = list.nFound[_XkbListKeymaps]; 5524 rep.nKeycodes = list.nFound[_XkbListKeycodes]; 5525 rep.nTypes = list.nFound[_XkbListTypes]; 5526 rep.nCompatMaps = list.nFound[_XkbListCompat]; 5527 rep.nSymbols = list.nFound[_XkbListSymbols]; 5528 rep.nGeometries = list.nFound[_XkbListGeometry]; 5529 rep.extra= 0; 5530 if (list.nTotal>list.maxRtrn) 5531 rep.extra = (list.nTotal-list.maxRtrn); 5532 if (client->swapped) { 5533 register int n; 5534 swaps(&rep.sequenceNumber,n); 5535 swapl(&rep.length,n); 5536 swaps(&rep.nKeymaps,n); 5537 swaps(&rep.nKeycodes,n); 5538 swaps(&rep.nTypes,n); 5539 swaps(&rep.nCompatMaps,n); 5540 swaps(&rep.nSymbols,n); 5541 swaps(&rep.nGeometries,n); 5542 swaps(&rep.extra,n); 5543 } 5544 WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); 5545 if (list.nPool && list.pool) { 5546 WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); 5547 _XkbFree(list.pool); 5548 list.pool= NULL; 5549 } 5550 return client->noClientException; 5551} 5552 5553/***====================================================================***/ 5554 5555int 5556ProcXkbGetKbdByName(ClientPtr client) 5557{ 5558 DeviceIntPtr dev; 5559 DeviceIntPtr tmpd; 5560 xkbGetKbdByNameReply rep; 5561 xkbGetMapReply mrep; 5562 xkbGetCompatMapReply crep; 5563 xkbGetIndicatorMapReply irep; 5564 xkbGetNamesReply nrep; 5565 xkbGetGeometryReply grep; 5566 XkbComponentNamesRec names; 5567 XkbDescPtr xkb, new; 5568 unsigned char * str; 5569 char mapFile[PATH_MAX]; 5570 unsigned len; 5571 unsigned fwant,fneed,reported; 5572 int status; 5573 Bool geom_changed; 5574 XkbSrvLedInfoPtr old_sli; 5575 XkbSrvLedInfoPtr sli; 5576 Mask access_mode = DixGetAttrAccess | DixManageAccess; 5577 5578 REQUEST(xkbGetKbdByNameReq); 5579 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 5580 5581 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5582 return BadAccess; 5583 5584 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5585 5586 xkb = dev->key->xkbInfo->desc; 5587 status= Success; 5588 str= (unsigned char *)&stuff[1]; 5589 names.keymap= GetComponentSpec(&str,True,&status); 5590 names.keycodes= GetComponentSpec(&str,True,&status); 5591 names.types= GetComponentSpec(&str,True,&status); 5592 names.compat= GetComponentSpec(&str,True,&status); 5593 names.symbols= GetComponentSpec(&str,True,&status); 5594 names.geometry= GetComponentSpec(&str,True,&status); 5595 if (status!=Success) 5596 return status; 5597 len= str-((unsigned char *)stuff); 5598 if ((XkbPaddedSize(len)/4)!=stuff->length) 5599 return BadLength; 5600 5601 CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); 5602 CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); 5603 5604 if (stuff->load) 5605 fwant= XkbGBN_AllComponentsMask; 5606 else fwant= stuff->want|stuff->need; 5607 if ((!names.compat)&& 5608 (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { 5609 names.compat= _XkbDupString("%"); 5610 } 5611 if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { 5612 names.types= _XkbDupString("%"); 5613 } 5614 if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { 5615 names.symbols= _XkbDupString("%"); 5616 } 5617 geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); 5618 if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { 5619 names.geometry= _XkbDupString("%"); 5620 geom_changed= False; 5621 } 5622 5623 bzero(mapFile,PATH_MAX); 5624 rep.type= X_Reply; 5625 rep.deviceID = dev->id; 5626 rep.sequenceNumber = client->sequence; 5627 rep.length = 0; 5628 rep.minKeyCode = xkb->min_key_code; 5629 rep.maxKeyCode = xkb->max_key_code; 5630 rep.loaded= False; 5631 fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask; 5632 fneed= XkbConvertGetByNameComponents(True,stuff->need); 5633 rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed); 5634 if (stuff->load) { 5635 fneed|= XkmKeymapRequired; 5636 fwant|= XkmKeymapLegal; 5637 } 5638 if ((fwant|fneed)&XkmSymbolsMask) { 5639 fneed|= XkmKeyNamesIndex|XkmTypesIndex; 5640 fwant|= XkmIndicatorsIndex; 5641 } 5642 5643 /* We pass dev in here so we can get the old names out if needed. */ 5644 rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new, 5645 mapFile,PATH_MAX); 5646 rep.newKeyboard= False; 5647 rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; 5648 5649 stuff->want|= stuff->need; 5650 if (new==NULL) 5651 rep.reported= 0; 5652 else { 5653 if (stuff->load) 5654 rep.loaded= True; 5655 if (stuff->load || 5656 ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) { 5657 XkbChangesRec changes; 5658 bzero(&changes,sizeof(changes)); 5659 XkbUpdateDescActions(new, 5660 new->min_key_code,XkbNumKeys(new), 5661 &changes); 5662 } 5663 5664 if (new->map==NULL) 5665 rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); 5666 else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { 5667 mrep.type= X_Reply; 5668 mrep.deviceID = dev->id; 5669 mrep.sequenceNumber= client->sequence; 5670 mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); 5671 mrep.minKeyCode = new->min_key_code; 5672 mrep.maxKeyCode = new->max_key_code; 5673 mrep.present = 0; 5674 mrep.totalSyms = mrep.totalActs = 5675 mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 5676 mrep.totalModMapKeys= mrep.totalVModMapKeys= 0; 5677 if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { 5678 mrep.present|= XkbKeyTypesMask; 5679 mrep.firstType = 0; 5680 mrep.nTypes = mrep.totalTypes= new->map->num_types; 5681 } 5682 else { 5683 mrep.firstType = mrep.nTypes= 0; 5684 mrep.totalTypes= 0; 5685 } 5686 if (rep.reported&XkbGBN_ClientSymbolsMask) { 5687 mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); 5688 mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code; 5689 mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new); 5690 } 5691 else { 5692 mrep.firstKeySym= mrep.firstModMapKey= 0; 5693 mrep.nKeySyms= mrep.nModMapKeys= 0; 5694 } 5695 if (rep.reported&XkbGBN_ServerSymbolsMask) { 5696 mrep.present|= XkbAllServerInfoMask; 5697 mrep.virtualMods= ~0; 5698 mrep.firstKeyAct = mrep.firstKeyBehavior = 5699 mrep.firstKeyExplicit = new->min_key_code; 5700 mrep.nKeyActs = mrep.nKeyBehaviors = 5701 mrep.nKeyExplicit = XkbNumKeys(new); 5702 mrep.firstVModMapKey= new->min_key_code; 5703 mrep.nVModMapKeys= XkbNumKeys(new); 5704 } 5705 else { 5706 mrep.virtualMods= 0; 5707 mrep.firstKeyAct= mrep.firstKeyBehavior= 5708 mrep.firstKeyExplicit = 0; 5709 mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; 5710 } 5711 XkbComputeGetMapReplySize(new,&mrep); 5712 rep.length+= SIZEOF(xGenericReply)/4+mrep.length; 5713 } 5714 if (new->compat==NULL) 5715 rep.reported&= ~XkbGBN_CompatMapMask; 5716 else if (rep.reported&XkbGBN_CompatMapMask) { 5717 crep.type= X_Reply; 5718 crep.deviceID= dev->id; 5719 crep.sequenceNumber= client->sequence; 5720 crep.length= 0; 5721 crep.groups= XkbAllGroupsMask; 5722 crep.firstSI= 0; 5723 crep.nSI= crep.nTotalSI= new->compat->num_si; 5724 XkbComputeGetCompatMapReplySize(new->compat,&crep); 5725 rep.length+= SIZEOF(xGenericReply)/4+crep.length; 5726 } 5727 if (new->indicators==NULL) 5728 rep.reported&= ~XkbGBN_IndicatorMapMask; 5729 else if (rep.reported&XkbGBN_IndicatorMapMask) { 5730 irep.type= X_Reply; 5731 irep.deviceID= dev->id; 5732 irep.sequenceNumber= client->sequence; 5733 irep.length= 0; 5734 irep.which= XkbAllIndicatorsMask; 5735 XkbComputeGetIndicatorMapReplySize(new->indicators,&irep); 5736 rep.length+= SIZEOF(xGenericReply)/4+irep.length; 5737 } 5738 if (new->names==NULL) 5739 rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); 5740 else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { 5741 nrep.type= X_Reply; 5742 nrep.deviceID= dev->id; 5743 nrep.sequenceNumber= client->sequence; 5744 nrep.length= 0; 5745 nrep.minKeyCode= new->min_key_code; 5746 nrep.maxKeyCode= new->max_key_code; 5747 if (rep.reported&XkbGBN_OtherNamesMask) { 5748 nrep.which= XkbAllNamesMask; 5749 if (new->map!=NULL) 5750 nrep.nTypes= new->map->num_types; 5751 else nrep.nTypes= 0; 5752 nrep.nKTLevels= 0; 5753 nrep.groupNames= XkbAllGroupsMask; 5754 nrep.virtualMods= XkbAllVirtualModsMask; 5755 nrep.indicators= XkbAllIndicatorsMask; 5756 nrep.nRadioGroups= new->names->num_rg; 5757 } 5758 else { 5759 nrep.which= 0; 5760 nrep.nTypes= 0; 5761 nrep.nKTLevels= 0; 5762 nrep.groupNames= 0; 5763 nrep.virtualMods= 0; 5764 nrep.indicators= 0; 5765 nrep.nRadioGroups= 0; 5766 } 5767 if (rep.reported&XkbGBN_KeyNamesMask) { 5768 nrep.which|= XkbKeyNamesMask; 5769 nrep.firstKey= new->min_key_code; 5770 nrep.nKeys= XkbNumKeys(new); 5771 nrep.nKeyAliases= new->names->num_key_aliases; 5772 if (nrep.nKeyAliases) 5773 nrep.which|= XkbKeyAliasesMask; 5774 } 5775 else { 5776 nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); 5777 nrep.firstKey= nrep.nKeys= 0; 5778 nrep.nKeyAliases= 0; 5779 } 5780 XkbComputeGetNamesReplySize(new,&nrep); 5781 rep.length+= SIZEOF(xGenericReply)/4+nrep.length; 5782 } 5783 if (new->geom==NULL) 5784 rep.reported&= ~XkbGBN_GeometryMask; 5785 else if (rep.reported&XkbGBN_GeometryMask) { 5786 grep.type= X_Reply; 5787 grep.deviceID= dev->id; 5788 grep.sequenceNumber= client->sequence; 5789 grep.length= 0; 5790 grep.found= True; 5791 grep.pad= 0; 5792 grep.widthMM= grep.heightMM= 0; 5793 grep.nProperties= grep.nColors= grep.nShapes= 0; 5794 grep.nSections= grep.nDoodads= 0; 5795 grep.baseColorNdx= grep.labelColorNdx= 0; 5796 XkbComputeGetGeometryReplySize(new->geom,&grep,None); 5797 rep.length+= SIZEOF(xGenericReply)/4+grep.length; 5798 } 5799 } 5800 5801 reported= rep.reported; 5802 if ( client->swapped ) { 5803 register int n; 5804 swaps(&rep.sequenceNumber,n); 5805 swapl(&rep.length,n); 5806 swaps(&rep.found,n); 5807 swaps(&rep.reported,n); 5808 } 5809 WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); 5810 if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) 5811 XkbSendMap(client,new,&mrep); 5812 if (reported&XkbGBN_CompatMapMask) 5813 XkbSendCompatMap(client,new->compat,&crep); 5814 if (reported&XkbGBN_IndicatorMapMask) 5815 XkbSendIndicatorMap(client,new->indicators,&irep); 5816 if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) 5817 XkbSendNames(client,new,&nrep); 5818 if (reported&XkbGBN_GeometryMask) 5819 XkbSendGeometry(client,new->geom,&grep,False); 5820 if (rep.loaded) { 5821 XkbDescPtr old_xkb; 5822 xkbNewKeyboardNotify nkn; 5823 int i,nG,nTG; 5824 old_xkb= xkb; 5825 xkb= new; 5826 dev->key->xkbInfo->desc= xkb; 5827 new= old_xkb; /* so it'll get freed automatically */ 5828 5829 *xkb->ctrls= *old_xkb->ctrls; 5830 for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 5831 nG= XkbKeyNumGroups(xkb,i); 5832 if (nG>=XkbNumKbdGroups) { 5833 nTG= XkbNumKbdGroups; 5834 break; 5835 } 5836 if (nG>nTG) { 5837 nTG= nG; 5838 } 5839 } 5840 xkb->ctrls->num_groups= nTG; 5841 5842 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 5843 if (tmpd == dev || 5844 (dev->id == inputInfo.keyboard->id && tmpd->key && 5845 tmpd->coreEvents)) { 5846 5847 memcpy(tmpd->key->modifierMap, xkb->map->modmap, 5848 xkb->max_key_code + 1); 5849 if (tmpd != dev) 5850 XkbCopyKeymap(dev->key->xkbInfo->desc, 5851 tmpd->key->xkbInfo->desc, True); 5852 XkbUpdateCoreDescription(tmpd, True); 5853 5854 if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 5855 old_sli = tmpd->kbdfeed->xkb_sli; 5856 tmpd->kbdfeed->xkb_sli = NULL; 5857 sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 5858 if (sli) { 5859 sli->explicitState = old_sli->explicitState; 5860 sli->effectiveState = old_sli->effectiveState; 5861 } 5862 tmpd->kbdfeed->xkb_sli = sli; 5863 XkbFreeSrvLedInfo(old_sli); 5864 } 5865 } 5866 } 5867 5868 /* this should be either a MN or an NKN, depending on whether or not 5869 * the keycode range changed? */ 5870 nkn.deviceID= nkn.oldDeviceID= dev->id; 5871 nkn.minKeyCode= new->min_key_code; 5872 nkn.maxKeyCode= new->max_key_code; 5873 nkn.oldMinKeyCode= xkb->min_key_code; 5874 nkn.oldMaxKeyCode= xkb->max_key_code; 5875 nkn.requestMajor= XkbReqCode; 5876 nkn.requestMinor= X_kbGetKbdByName; 5877 nkn.changed= XkbNKN_KeycodesMask; 5878 if (geom_changed) 5879 nkn.changed|= XkbNKN_GeometryMask; 5880 XkbSendNewKeyboardNotify(dev,&nkn); 5881 } 5882 if ((new!=NULL)&&(new!=xkb)) { 5883 XkbFreeKeyboard(new,XkbAllComponentsMask,True); 5884 new= NULL; 5885 } 5886 if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; } 5887 if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; } 5888 if (names.types) { _XkbFree(names.types); names.types= NULL; } 5889 if (names.compat) { _XkbFree(names.compat); names.compat= NULL; } 5890 if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; } 5891 if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; } 5892 return client->noClientException; 5893} 5894 5895/***====================================================================***/ 5896 5897static int 5898ComputeDeviceLedInfoSize( DeviceIntPtr dev, 5899 unsigned int what, 5900 XkbSrvLedInfoPtr sli) 5901{ 5902int nNames,nMaps; 5903register unsigned n,bit; 5904 5905 if (sli==NULL) 5906 return 0; 5907 nNames= nMaps= 0; 5908 if ((what&XkbXI_IndicatorNamesMask)==0) 5909 sli->namesPresent= 0; 5910 if ((what&XkbXI_IndicatorMapsMask)==0) 5911 sli->mapsPresent= 0; 5912 5913 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 5914 if (sli->names && sli->names[n]!=None) { 5915 sli->namesPresent|= bit; 5916 nNames++; 5917 } 5918 if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 5919 sli->mapsPresent|= bit; 5920 nMaps++; 5921 } 5922 } 5923 return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); 5924} 5925 5926static int 5927CheckDeviceLedFBs( DeviceIntPtr dev, 5928 int class, 5929 int id, 5930 xkbGetDeviceInfoReply * rep, 5931 ClientPtr client) 5932{ 5933int nFBs= 0; 5934int length= 0; 5935Bool classOk; 5936 5937 if (class==XkbDfltXIClass) { 5938 if (dev->kbdfeed) class= KbdFeedbackClass; 5939 else if (dev->leds) class= LedFeedbackClass; 5940 else { 5941 client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 5942 return XkbKeyboardErrorCode; 5943 } 5944 } 5945 classOk= False; 5946 if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 5947 KbdFeedbackPtr kf; 5948 classOk= True; 5949 for (kf= dev->kbdfeed;(kf);kf=kf->next) { 5950 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) 5951 continue; 5952 nFBs++; 5953 length+= SIZEOF(xkbDeviceLedsWireDesc); 5954 if (!kf->xkb_sli) 5955 kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); 5956 length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); 5957 if (id!=XkbAllXIIds) 5958 break; 5959 } 5960 } 5961 if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 5962 LedFeedbackPtr lf; 5963 classOk= True; 5964 for (lf= dev->leds;(lf);lf=lf->next) { 5965 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) 5966 continue; 5967 nFBs++; 5968 length+= SIZEOF(xkbDeviceLedsWireDesc); 5969 if (!lf->xkb_sli) 5970 lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); 5971 length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); 5972 if (id!=XkbAllXIIds) 5973 break; 5974 } 5975 } 5976 if (nFBs>0) { 5977 if (rep->supported&XkbXI_IndicatorsMask) { 5978 rep->nDeviceLedFBs= nFBs; 5979 rep->length+= (length/4); 5980 } 5981 return Success; 5982 } 5983 if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); 5984 else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 5985 return XkbKeyboardErrorCode; 5986} 5987 5988static int 5989SendDeviceLedInfo( XkbSrvLedInfoPtr sli, 5990 ClientPtr client) 5991{ 5992xkbDeviceLedsWireDesc wire; 5993int length; 5994 5995 length= 0; 5996 wire.ledClass= sli->class; 5997 wire.ledID= sli->id; 5998 wire.namesPresent= sli->namesPresent; 5999 wire.mapsPresent= sli->mapsPresent; 6000 wire.physIndicators= sli->physIndicators; 6001 wire.state= sli->effectiveState; 6002 if (client->swapped) { 6003 register int n; 6004 swaps(&wire.ledClass,n); 6005 swaps(&wire.ledID,n); 6006 swapl(&wire.namesPresent,n); 6007 swapl(&wire.mapsPresent,n); 6008 swapl(&wire.physIndicators,n); 6009 swapl(&wire.state,n); 6010 } 6011 WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); 6012 length+= SIZEOF(xkbDeviceLedsWireDesc); 6013 if (sli->namesPresent|sli->mapsPresent) { 6014 register unsigned i,bit; 6015 if (sli->namesPresent) { 6016 CARD32 awire; 6017 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 6018 if (sli->namesPresent&bit) { 6019 awire= (CARD32)sli->names[i]; 6020 if (client->swapped) { 6021 register int n; 6022 swapl(&awire,n); 6023 } 6024 WriteToClient(client,4,(char *)&awire); 6025 length+= 4; 6026 } 6027 } 6028 } 6029 if (sli->mapsPresent) { 6030 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 6031 xkbIndicatorMapWireDesc iwire; 6032 if (sli->mapsPresent&bit) { 6033 iwire.flags= sli->maps[i].flags; 6034 iwire.whichGroups= sli->maps[i].which_groups; 6035 iwire.groups= sli->maps[i].groups; 6036 iwire.whichMods= sli->maps[i].which_mods; 6037 iwire.mods= sli->maps[i].mods.mask; 6038 iwire.realMods= sli->maps[i].mods.real_mods; 6039 iwire.virtualMods= sli->maps[i].mods.vmods; 6040 iwire.ctrls= sli->maps[i].ctrls; 6041 if (client->swapped) { 6042 register int n; 6043 swaps(&iwire.virtualMods,n); 6044 swapl(&iwire.ctrls,n); 6045 } 6046 WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), 6047 (char *)&iwire); 6048 length+= SIZEOF(xkbIndicatorMapWireDesc); 6049 } 6050 } 6051 } 6052 } 6053 return length; 6054} 6055 6056static int 6057SendDeviceLedFBs( DeviceIntPtr dev, 6058 int class, 6059 int id, 6060 unsigned wantLength, 6061 ClientPtr client) 6062{ 6063int length= 0; 6064 6065 if (class==XkbDfltXIClass) { 6066 if (dev->kbdfeed) class= KbdFeedbackClass; 6067 else if (dev->leds) class= LedFeedbackClass; 6068 } 6069 if ((dev->kbdfeed)&& 6070 ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 6071 KbdFeedbackPtr kf; 6072 for (kf= dev->kbdfeed;(kf);kf=kf->next) { 6073 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { 6074 length+= SendDeviceLedInfo(kf->xkb_sli,client); 6075 if (id!=XkbAllXIIds) 6076 break; 6077 } 6078 } 6079 } 6080 if ((dev->leds)&& 6081 ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 6082 LedFeedbackPtr lf; 6083 for (lf= dev->leds;(lf);lf=lf->next) { 6084 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { 6085 length+= SendDeviceLedInfo(lf->xkb_sli,client); 6086 if (id!=XkbAllXIIds) 6087 break; 6088 } 6089 } 6090 } 6091 if (length==wantLength) 6092 return Success; 6093 else return BadLength; 6094} 6095 6096int 6097ProcXkbGetDeviceInfo(ClientPtr client) 6098{ 6099DeviceIntPtr dev; 6100xkbGetDeviceInfoReply rep; 6101int status,nDeviceLedFBs; 6102unsigned length,nameLen; 6103CARD16 ledClass,ledID; 6104unsigned wanted,supported; 6105char * str; 6106 6107 REQUEST(xkbGetDeviceInfoReq); 6108 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 6109 6110 if (!(client->xkbClientFlags&_XkbClientInitialized)) 6111 return BadAccess; 6112 6113 wanted= stuff->wanted; 6114 6115 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 6116 CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); 6117 6118 if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) 6119 wanted&= ~XkbXI_ButtonActionsMask; 6120 if ((!dev->kbdfeed)&&(!dev->leds)) 6121 wanted&= ~XkbXI_IndicatorsMask; 6122 6123 nameLen= XkbSizeCountedString(dev->name); 6124 bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply)); 6125 rep.type = X_Reply; 6126 rep.deviceID= dev->id; 6127 rep.sequenceNumber = client->sequence; 6128 rep.length = nameLen/4; 6129 rep.present = wanted; 6130 rep.supported = XkbXI_AllDeviceFeaturesMask; 6131 rep.unsupported = 0; 6132 rep.firstBtnWanted = rep.nBtnsWanted = 0; 6133 rep.firstBtnRtrn = rep.nBtnsRtrn = 0; 6134 if (dev->button) 6135 rep.totalBtns= dev->button->numButtons; 6136 else rep.totalBtns= 0; 6137 rep.devType= dev->type; 6138 rep.hasOwnState= (dev->key && dev->key->xkbInfo); 6139 rep.nDeviceLedFBs = 0; 6140 if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; 6141 else rep.dfltKbdFB= XkbXINone; 6142 if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; 6143 else rep.dfltLedFB= XkbXINone; 6144 6145 ledClass= stuff->ledClass; 6146 ledID= stuff->ledID; 6147 6148 rep.firstBtnWanted= rep.nBtnsWanted= 0; 6149 rep.firstBtnRtrn= rep.nBtnsRtrn= 0; 6150 if (wanted&XkbXI_ButtonActionsMask) { 6151 if (stuff->allBtns) { 6152 stuff->firstBtn= 0; 6153 stuff->nBtns= dev->button->numButtons; 6154 } 6155 6156 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 6157 client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, 6158 stuff->firstBtn, 6159 stuff->nBtns); 6160 return BadValue; 6161 } 6162 else { 6163 rep.firstBtnWanted= stuff->firstBtn; 6164 rep.nBtnsWanted= stuff->nBtns; 6165 if (dev->button->xkb_acts!=NULL) { 6166 XkbAction *act; 6167 register int i; 6168 6169 rep.firstBtnRtrn= stuff->firstBtn; 6170 rep.nBtnsRtrn= stuff->nBtns; 6171 act= &dev->button->xkb_acts[rep.firstBtnWanted]; 6172 for (i=0;i<rep.nBtnsRtrn;i++,act++) { 6173 if (act->type!=XkbSA_NoAction) 6174 break; 6175 } 6176 rep.firstBtnRtrn+= i; 6177 rep.nBtnsRtrn-= i; 6178 act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; 6179 for (i=0;i<rep.nBtnsRtrn;i++,act--) { 6180 if (act->type!=XkbSA_NoAction) 6181 break; 6182 } 6183 rep.nBtnsRtrn-= i; 6184 } 6185 rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; 6186 } 6187 } 6188 6189 if (wanted&XkbXI_IndicatorsMask) { 6190 status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); 6191 if (status!=Success) 6192 return status; 6193 } 6194 length= rep.length*4; 6195 supported= rep.supported; 6196 nDeviceLedFBs = rep.nDeviceLedFBs; 6197 if (client->swapped) { 6198 register int n; 6199 swaps(&rep.sequenceNumber,n); 6200 swapl(&rep.length,n); 6201 swaps(&rep.present,n); 6202 swaps(&rep.supported,n); 6203 swaps(&rep.unsupported,n); 6204 swaps(&rep.nDeviceLedFBs,n); 6205 swapl(&rep.type,n); 6206 } 6207 WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); 6208 6209 str= (char*) xalloc(nameLen); 6210 if (!str) 6211 return BadAlloc; 6212 XkbWriteCountedString(str,dev->name,client->swapped); 6213 WriteToClient(client,nameLen,str); 6214 xfree(str); 6215 length-= nameLen; 6216 6217 if (rep.nBtnsRtrn>0) { 6218 int sz; 6219 xkbActionWireDesc * awire; 6220 sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); 6221 awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; 6222 WriteToClient(client,sz,(char *)awire); 6223 length-= sz; 6224 } 6225 if (nDeviceLedFBs>0) { 6226 status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); 6227 if (status!=Success) 6228 return status; 6229 } 6230 else if (length!=0) { 6231 ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 6232 ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length); 6233 return BadLength; 6234 } 6235 if (stuff->wanted&(~supported)) { 6236 xkbExtensionDeviceNotify ed; 6237 bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 6238 ed.ledClass= ledClass; 6239 ed.ledID= ledID; 6240 ed.ledsDefined= 0; 6241 ed.ledState= 0; 6242 ed.firstBtn= ed.nBtns= 0; 6243 ed.reason= XkbXI_UnsupportedFeatureMask; 6244 ed.supported= supported; 6245 ed.unsupported= stuff->wanted&(~supported); 6246 XkbSendExtensionDeviceNotify(dev,client,&ed); 6247 } 6248 return client->noClientException; 6249} 6250 6251static char * 6252CheckSetDeviceIndicators( char * wire, 6253 DeviceIntPtr dev, 6254 int num, 6255 int * status_rtrn, 6256 ClientPtr client) 6257{ 6258xkbDeviceLedsWireDesc * ledWire; 6259int i; 6260XkbSrvLedInfoPtr sli; 6261 6262 ledWire= (xkbDeviceLedsWireDesc *)wire; 6263 for (i=0;i<num;i++) { 6264 if (client->swapped) { 6265 register int n; 6266 swaps(&ledWire->ledClass,n); 6267 swaps(&ledWire->ledID,n); 6268 swapl(&ledWire->namesPresent,n); 6269 swapl(&ledWire->mapsPresent,n); 6270 swapl(&ledWire->physIndicators,n); 6271 } 6272 6273 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 6274 XkbXI_IndicatorsMask); 6275 if (sli!=NULL) { 6276 register int n; 6277 register unsigned bit; 6278 int nMaps,nNames; 6279 CARD32 *atomWire; 6280 xkbIndicatorMapWireDesc *mapWire; 6281 6282 nMaps= nNames= 0; 6283 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6284 if (ledWire->namesPresent&bit) 6285 nNames++; 6286 if (ledWire->mapsPresent&bit) 6287 nMaps++; 6288 } 6289 atomWire= (CARD32 *)&ledWire[1]; 6290 if (nNames>0) { 6291 for (n=0;n<nNames;n++) { 6292 if (client->swapped) { 6293 register int t; 6294 swapl(atomWire,t); 6295 } 6296 CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, 6297 *status_rtrn,NULL); 6298 atomWire++; 6299 } 6300 } 6301 mapWire= (xkbIndicatorMapWireDesc *)atomWire; 6302 if (nMaps>0) { 6303 for (n=0;n<nMaps;n++) { 6304 if (client->swapped) { 6305 register int t; 6306 swaps(&mapWire->virtualMods,t); 6307 swapl(&mapWire->ctrls,t); 6308 } 6309 CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, 6310 XkbIM_UseAnyGroup, 6311 client->errorValue, 6312 *status_rtrn,NULL); 6313 CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, 6314 client->errorValue, 6315 *status_rtrn,NULL); 6316 mapWire++; 6317 } 6318 } 6319 ledWire= (xkbDeviceLedsWireDesc *)mapWire; 6320 } 6321 else { 6322 /* SHOULD NEVER HAPPEN */ 6323 return (char *)ledWire; 6324 } 6325 } 6326 return (char *)ledWire; 6327} 6328 6329static char * 6330SetDeviceIndicators( char * wire, 6331 DeviceIntPtr dev, 6332 unsigned changed, 6333 int num, 6334 int * status_rtrn, 6335 ClientPtr client, 6336 xkbExtensionDeviceNotify *ev) 6337{ 6338xkbDeviceLedsWireDesc * ledWire; 6339int i; 6340XkbEventCauseRec cause; 6341unsigned namec,mapc,statec; 6342xkbExtensionDeviceNotify ed; 6343XkbChangesRec changes; 6344DeviceIntPtr kbd; 6345 6346 bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 6347 bzero((char *)&changes,sizeof(XkbChangesRec)); 6348 XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); 6349 ledWire= (xkbDeviceLedsWireDesc *)wire; 6350 for (i=0;i<num;i++) { 6351 register int n; 6352 register unsigned bit; 6353 CARD32 * atomWire; 6354 xkbIndicatorMapWireDesc * mapWire; 6355 XkbSrvLedInfoPtr sli; 6356 6357 namec= mapc= statec= 0; 6358 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 6359 XkbXI_IndicatorMapsMask); 6360 if (!sli) { 6361 /* SHOULD NEVER HAPPEN!! */ 6362 return (char *)ledWire; 6363 } 6364 6365 atomWire= (CARD32 *)&ledWire[1]; 6366 if (changed&XkbXI_IndicatorNamesMask) { 6367 namec= sli->namesPresent|ledWire->namesPresent; 6368 bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 6369 } 6370 if (ledWire->namesPresent) { 6371 sli->namesPresent= ledWire->namesPresent; 6372 bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); 6373 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6374 if (ledWire->namesPresent&bit) { 6375 sli->names[n]= (Atom)*atomWire; 6376 if (sli->names[n]==None) 6377 ledWire->namesPresent&= ~bit; 6378 atomWire++; 6379 } 6380 } 6381 } 6382 mapWire= (xkbIndicatorMapWireDesc *)atomWire; 6383 if (changed&XkbXI_IndicatorMapsMask) { 6384 mapc= sli->mapsPresent|ledWire->mapsPresent; 6385 sli->mapsPresent= ledWire->mapsPresent; 6386 bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec)); 6387 } 6388 if (ledWire->mapsPresent) { 6389 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6390 if (ledWire->mapsPresent&bit) { 6391 sli->maps[n].flags= mapWire->flags; 6392 sli->maps[n].which_groups= mapWire->whichGroups; 6393 sli->maps[n].groups= mapWire->groups; 6394 sli->maps[n].which_mods= mapWire->whichMods; 6395 sli->maps[n].mods.mask= mapWire->mods; 6396 sli->maps[n].mods.real_mods=mapWire->realMods; 6397 sli->maps[n].mods.vmods= mapWire->virtualMods; 6398 sli->maps[n].ctrls= mapWire->ctrls; 6399 mapWire++; 6400 } 6401 } 6402 } 6403 if (changed&XkbXI_IndicatorStateMask) { 6404 statec= sli->effectiveState^ledWire->state; 6405 sli->explicitState&= ~statec; 6406 sli->explicitState|= (ledWire->state&statec); 6407 } 6408 if (namec) 6409 XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 6410 if (mapc) 6411 XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 6412 if (statec) 6413 XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 6414 6415 kbd= dev; 6416 if ((sli->flags&XkbSLI_HasOwnState)==0) 6417 kbd = inputInfo.keyboard; 6418 6419 XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 6420 ledWire= (xkbDeviceLedsWireDesc *)mapWire; 6421 } 6422 return (char *)ledWire; 6423} 6424 6425 6426static int 6427_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 6428 xkbSetDeviceInfoReq *stuff) 6429{ 6430 char *wire; 6431 6432 wire= (char *)&stuff[1]; 6433 if (stuff->change&XkbXI_ButtonActionsMask) { 6434 if (!dev->button) { 6435 client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); 6436 return XkbKeyboardErrorCode; 6437 } 6438 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 6439 client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, 6440 dev->button->numButtons); 6441 return BadMatch; 6442 } 6443 wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); 6444 } 6445 if (stuff->change&XkbXI_IndicatorsMask) { 6446 int status= Success; 6447 wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, 6448 &status,client); 6449 if (status!=Success) 6450 return status; 6451 } 6452 if (((wire-((char *)stuff))/4)!=stuff->length) 6453 return BadLength; 6454 6455 return Success; 6456} 6457 6458static int 6459_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 6460 xkbSetDeviceInfoReq *stuff) 6461{ 6462 char *wire; 6463 xkbExtensionDeviceNotify ed; 6464 6465 bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); 6466 ed.deviceID= dev->id; 6467 wire= (char *)&stuff[1]; 6468 if (stuff->change&XkbXI_ButtonActionsMask) { 6469 int nBtns,sz,i; 6470 XkbAction * acts; 6471 DeviceIntPtr kbd; 6472 6473 nBtns= dev->button->numButtons; 6474 acts= dev->button->xkb_acts; 6475 if (acts==NULL) { 6476 acts= _XkbTypedCalloc(nBtns,XkbAction); 6477 if (!acts) 6478 return BadAlloc; 6479 dev->button->xkb_acts= acts; 6480 } 6481 sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); 6482 memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); 6483 wire+= sz; 6484 ed.reason|= XkbXI_ButtonActionsMask; 6485 ed.firstBtn= stuff->firstBtn; 6486 ed.nBtns= stuff->nBtns; 6487 6488 if (dev->key) kbd= dev; 6489 else kbd= inputInfo.keyboard; 6490 acts= &dev->button->xkb_acts[stuff->firstBtn]; 6491 for (i=0;i<stuff->nBtns;i++,acts++) { 6492 if (acts->type!=XkbSA_NoAction) 6493 XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); 6494 } 6495 } 6496 if (stuff->change&XkbXI_IndicatorsMask) { 6497 int status= Success; 6498 wire= SetDeviceIndicators(wire,dev,stuff->change, 6499 stuff->nDeviceLedFBs, &status,client,&ed); 6500 if (status!=Success) 6501 return status; 6502 } 6503 if ((stuff->change)&&(ed.reason)) 6504 XkbSendExtensionDeviceNotify(dev,client,&ed); 6505 return Success; 6506} 6507 6508int 6509ProcXkbSetDeviceInfo(ClientPtr client) 6510{ 6511 DeviceIntPtr dev; 6512 int rc; 6513 6514 REQUEST(xkbSetDeviceInfoReq); 6515 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 6516 6517 if (!(client->xkbClientFlags&_XkbClientInitialized)) 6518 return BadAccess; 6519 6520 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 6521 CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask); 6522 6523 rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 6524 6525 if (rc != Success) 6526 return rc; 6527 6528 if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 6529 { 6530 DeviceIntPtr other; 6531 for (other = inputInfo.devices; other; other = other->next) 6532 { 6533 if (((other != dev) && !other->isMaster && (other->u.master == dev)) && 6534 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6535 (stuff->deviceSpec == XkbUseCorePtr && other->button))) 6536 { 6537 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 6538 if (rc == Success) 6539 { 6540 rc = _XkbSetDeviceInfoCheck(client, other, stuff); 6541 if (rc != Success) 6542 return rc; 6543 } 6544 } 6545 } 6546 } 6547 6548 /* checks done, apply */ 6549 rc = _XkbSetDeviceInfo(client, dev, stuff); 6550 if (rc != Success) 6551 return rc; 6552 6553 if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 6554 { 6555 DeviceIntPtr other; 6556 for (other = inputInfo.devices; other; other = other->next) 6557 { 6558 if (((other != dev) && !other->isMaster && (other->u.master == dev)) && 6559 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6560 (stuff->deviceSpec == XkbUseCorePtr && other->button))) 6561 { 6562 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 6563 if (rc == Success) 6564 { 6565 rc = _XkbSetDeviceInfo(client, other, stuff); 6566 if (rc != Success) 6567 return rc; 6568 } 6569 } 6570 } 6571 } 6572 6573 return client->noClientException; 6574} 6575 6576/***====================================================================***/ 6577 6578int 6579ProcXkbSetDebuggingFlags(ClientPtr client) 6580{ 6581CARD32 newFlags,newCtrls,extraLength; 6582xkbSetDebuggingFlagsReply rep; 6583int rc; 6584 6585 REQUEST(xkbSetDebuggingFlagsReq); 6586 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 6587 6588 rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 6589 if (rc != Success) 6590 return rc; 6591 6592 newFlags= xkbDebugFlags&(~stuff->affectFlags); 6593 newFlags|= (stuff->flags&stuff->affectFlags); 6594 newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); 6595 newCtrls|= (stuff->ctrls&stuff->affectCtrls); 6596 if (xkbDebugFlags || newFlags || stuff->msgLength) { 6597 ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); 6598 if (newCtrls!=xkbDebugCtrls) 6599 ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); 6600 } 6601 extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; 6602 if (stuff->msgLength>0) { 6603 char *msg; 6604 if (extraLength<XkbPaddedSize(stuff->msgLength)) { 6605 ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 6606 stuff->msgLength,(long)extraLength, 6607 XkbPaddedSize(stuff->msgLength)); 6608 return BadLength; 6609 } 6610 msg= (char *)&stuff[1]; 6611 if (msg[stuff->msgLength-1]!='\0') { 6612 ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 6613 return BadValue; 6614 } 6615 ErrorF("[xkb] XkbDebug: %s\n",msg); 6616 } 6617 xkbDebugFlags = newFlags; 6618 xkbDebugCtrls = newCtrls; 6619 6620 XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks); 6621 6622 rep.type= X_Reply; 6623 rep.length = 0; 6624 rep.sequenceNumber = client->sequence; 6625 rep.currentFlags = newFlags; 6626 rep.currentCtrls = newCtrls; 6627 rep.supportedFlags = ~0; 6628 rep.supportedCtrls = ~0; 6629 if ( client->swapped ) { 6630 register int n; 6631 swaps(&rep.sequenceNumber, n); 6632 swapl(&rep.currentFlags, n); 6633 swapl(&rep.currentCtrls, n); 6634 swapl(&rep.supportedFlags, n); 6635 swapl(&rep.supportedCtrls, n); 6636 } 6637 WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); 6638 return client->noClientException; 6639} 6640 6641/***====================================================================***/ 6642 6643static int 6644ProcXkbDispatch (ClientPtr client) 6645{ 6646 REQUEST(xReq); 6647 switch (stuff->data) 6648 { 6649 case X_kbUseExtension: 6650 return ProcXkbUseExtension(client); 6651 case X_kbSelectEvents: 6652 return ProcXkbSelectEvents(client); 6653 case X_kbBell: 6654 return ProcXkbBell(client); 6655 case X_kbGetState: 6656 return ProcXkbGetState(client); 6657 case X_kbLatchLockState: 6658 return ProcXkbLatchLockState(client); 6659 case X_kbGetControls: 6660 return ProcXkbGetControls(client); 6661 case X_kbSetControls: 6662 return ProcXkbSetControls(client); 6663 case X_kbGetMap: 6664 return ProcXkbGetMap(client); 6665 case X_kbSetMap: 6666 return ProcXkbSetMap(client); 6667 case X_kbGetCompatMap: 6668 return ProcXkbGetCompatMap(client); 6669 case X_kbSetCompatMap: 6670 return ProcXkbSetCompatMap(client); 6671 case X_kbGetIndicatorState: 6672 return ProcXkbGetIndicatorState(client); 6673 case X_kbGetIndicatorMap: 6674 return ProcXkbGetIndicatorMap(client); 6675 case X_kbSetIndicatorMap: 6676 return ProcXkbSetIndicatorMap(client); 6677 case X_kbGetNamedIndicator: 6678 return ProcXkbGetNamedIndicator(client); 6679 case X_kbSetNamedIndicator: 6680 return ProcXkbSetNamedIndicator(client); 6681 case X_kbGetNames: 6682 return ProcXkbGetNames(client); 6683 case X_kbSetNames: 6684 return ProcXkbSetNames(client); 6685 case X_kbGetGeometry: 6686 return ProcXkbGetGeometry(client); 6687 case X_kbSetGeometry: 6688 return ProcXkbSetGeometry(client); 6689 case X_kbPerClientFlags: 6690 return ProcXkbPerClientFlags(client); 6691 case X_kbListComponents: 6692 return ProcXkbListComponents(client); 6693 case X_kbGetKbdByName: 6694 return ProcXkbGetKbdByName(client); 6695 case X_kbGetDeviceInfo: 6696 return ProcXkbGetDeviceInfo(client); 6697 case X_kbSetDeviceInfo: 6698 return ProcXkbSetDeviceInfo(client); 6699 case X_kbSetDebuggingFlags: 6700 return ProcXkbSetDebuggingFlags(client); 6701 default: 6702 return BadRequest; 6703 } 6704} 6705 6706static int 6707XkbClientGone(pointer data,XID id) 6708{ 6709 DevicePtr pXDev = (DevicePtr)data; 6710 6711 if (!XkbRemoveResourceClient(pXDev,id)) { 6712 ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 6713 } 6714 return 1; 6715} 6716 6717void 6718XkbExtensionInit(void) 6719{ 6720 ExtensionEntry *extEntry; 6721 6722 if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 6723 ProcXkbDispatch, SProcXkbDispatch, 6724 NULL, StandardMinorOpcode))) { 6725 XkbReqCode = (unsigned char)extEntry->base; 6726 XkbEventBase = (unsigned char)extEntry->eventBase; 6727 XkbErrorBase = (unsigned char)extEntry->errorBase; 6728 XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; 6729 RT_XKBCLIENT = CreateNewResourceType(XkbClientGone); 6730 } 6731 return; 6732} 6733 6734 6735