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