xkb.c revision 1e26616a
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 Status 4843_GetCountedString(char **wire_inout, ClientPtr client, char **str) 4844{ 4845 char *wire, *next; 4846 CARD16 len; 4847 4848 wire = *wire_inout; 4849 len = *(CARD16 *) wire; 4850 if (client->swapped) { 4851 int n; 4852 swaps(&len, n); 4853 } 4854 next = wire + XkbPaddedSize(len + 2); 4855 /* Check we're still within the size of the request */ 4856 if (client->req_len < 4857 bytes_to_int32(next - (char *) client->requestBuffer)) 4858 return BadValue; 4859 *str = malloc(len + 1); 4860 if (!*str) 4861 return BadAlloc; 4862 memcpy(*str, &wire[2], len); 4863 *(*str + len) = '\0'; 4864 *wire_inout = next; 4865 return Success; 4866} 4867 4868static Status 4869_CheckSetDoodad( char ** wire_inout, 4870 XkbGeometryPtr geom, 4871 XkbSectionPtr section, 4872 ClientPtr client) 4873{ 4874char * wire; 4875xkbDoodadWireDesc * dWire; 4876XkbDoodadPtr doodad; 4877 Status status; 4878 4879 dWire= (xkbDoodadWireDesc *)(*wire_inout); 4880 wire= (char *)&dWire[1]; 4881 if (client->swapped) { 4882 register int n; 4883 swapl(&dWire->any.name,n); 4884 swaps(&dWire->any.top,n); 4885 swaps(&dWire->any.left,n); 4886 swaps(&dWire->any.angle,n); 4887 } 4888 CHK_ATOM_ONLY(dWire->any.name); 4889 doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); 4890 if (!doodad) 4891 return BadAlloc; 4892 doodad->any.type= dWire->any.type; 4893 doodad->any.priority= dWire->any.priority; 4894 doodad->any.top= dWire->any.top; 4895 doodad->any.left= dWire->any.left; 4896 doodad->any.angle= dWire->any.angle; 4897 switch (doodad->any.type) { 4898 case XkbOutlineDoodad: 4899 case XkbSolidDoodad: 4900 if (dWire->shape.colorNdx>=geom->num_colors) { 4901 client->errorValue= _XkbErrCode3(0x40,geom->num_colors, 4902 dWire->shape.colorNdx); 4903 return BadMatch; 4904 } 4905 if (dWire->shape.shapeNdx>=geom->num_shapes) { 4906 client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, 4907 dWire->shape.shapeNdx); 4908 return BadMatch; 4909 } 4910 doodad->shape.color_ndx= dWire->shape.colorNdx; 4911 doodad->shape.shape_ndx= dWire->shape.shapeNdx; 4912 break; 4913 case XkbTextDoodad: 4914 if (dWire->text.colorNdx>=geom->num_colors) { 4915 client->errorValue= _XkbErrCode3(0x42,geom->num_colors, 4916 dWire->text.colorNdx); 4917 return BadMatch; 4918 } 4919 if (client->swapped) { 4920 register int n; 4921 swaps(&dWire->text.width,n); 4922 swaps(&dWire->text.height,n); 4923 } 4924 doodad->text.width= dWire->text.width; 4925 doodad->text.height= dWire->text.height; 4926 doodad->text.color_ndx= dWire->text.colorNdx; 4927 status = _GetCountedString(&wire, client, &doodad->text.text); 4928 if (status != Success) 4929 return status; 4930 status = _GetCountedString(&wire, client, &doodad->text.font); 4931 if (status != Success) { 4932 free (doodad->text.text); 4933 return status; 4934 } 4935 break; 4936 case XkbIndicatorDoodad: 4937 if (dWire->indicator.onColorNdx>=geom->num_colors) { 4938 client->errorValue= _XkbErrCode3(0x43,geom->num_colors, 4939 dWire->indicator.onColorNdx); 4940 return BadMatch; 4941 } 4942 if (dWire->indicator.offColorNdx>=geom->num_colors) { 4943 client->errorValue= _XkbErrCode3(0x44,geom->num_colors, 4944 dWire->indicator.offColorNdx); 4945 return BadMatch; 4946 } 4947 if (dWire->indicator.shapeNdx>=geom->num_shapes) { 4948 client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, 4949 dWire->indicator.shapeNdx); 4950 return BadMatch; 4951 } 4952 doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; 4953 doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; 4954 doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; 4955 break; 4956 case XkbLogoDoodad: 4957 if (dWire->logo.colorNdx>=geom->num_colors) { 4958 client->errorValue= _XkbErrCode3(0x46,geom->num_colors, 4959 dWire->logo.colorNdx); 4960 return BadMatch; 4961 } 4962 if (dWire->logo.shapeNdx>=geom->num_shapes) { 4963 client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, 4964 dWire->logo.shapeNdx); 4965 return BadMatch; 4966 } 4967 doodad->logo.color_ndx= dWire->logo.colorNdx; 4968 doodad->logo.shape_ndx= dWire->logo.shapeNdx; 4969 status = _GetCountedString(&wire, client, &doodad->logo.logo_name); 4970 if (status != Success) 4971 return status; 4972 break; 4973 default: 4974 client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); 4975 return BadValue; 4976 } 4977 *wire_inout= wire; 4978 return Success; 4979} 4980 4981static Status 4982_CheckSetOverlay( char ** wire_inout, 4983 XkbGeometryPtr geom, 4984 XkbSectionPtr section, 4985 ClientPtr client) 4986{ 4987register int r; 4988char * wire; 4989XkbOverlayPtr ol; 4990xkbOverlayWireDesc * olWire; 4991xkbOverlayRowWireDesc * rWire; 4992 4993 wire= *wire_inout; 4994 olWire= (xkbOverlayWireDesc *)wire; 4995 if (client->swapped) { 4996 register int n; 4997 swapl(&olWire->name,n); 4998 } 4999 CHK_ATOM_ONLY(olWire->name); 5000 ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); 5001 rWire= (xkbOverlayRowWireDesc *)&olWire[1]; 5002 for (r=0;r<olWire->nRows;r++) { 5003 register int k; 5004 xkbOverlayKeyWireDesc * kWire; 5005 XkbOverlayRowPtr row; 5006 5007 if (rWire->rowUnder>section->num_rows) { 5008 client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, 5009 rWire->rowUnder); 5010 return BadMatch; 5011 } 5012 row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); 5013 kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; 5014 for (k=0;k<rWire->nKeys;k++,kWire++) { 5015 if (XkbAddGeomOverlayKey(ol,row, 5016 (char *)kWire->over,(char *)kWire->under)==NULL) { 5017 client->errorValue= _XkbErrCode3(0x21,r,k); 5018 return BadMatch; 5019 } 5020 } 5021 rWire= (xkbOverlayRowWireDesc *)kWire; 5022 } 5023 olWire= (xkbOverlayWireDesc *)rWire; 5024 wire= (char *)olWire; 5025 *wire_inout= wire; 5026 return Success; 5027} 5028 5029static Status 5030_CheckSetSections( XkbGeometryPtr geom, 5031 xkbSetGeometryReq * req, 5032 char ** wire_inout, 5033 ClientPtr client) 5034{ 5035Status status; 5036register int s; 5037char * wire; 5038xkbSectionWireDesc * sWire; 5039XkbSectionPtr section; 5040 5041 wire= *wire_inout; 5042 if (req->nSections<1) 5043 return Success; 5044 sWire= (xkbSectionWireDesc *)wire; 5045 for (s=0;s<req->nSections;s++) { 5046 register int r; 5047 xkbRowWireDesc * rWire; 5048 if (client->swapped) { 5049 register int n; 5050 swapl(&sWire->name,n); 5051 swaps(&sWire->top,n); 5052 swaps(&sWire->left,n); 5053 swaps(&sWire->width,n); 5054 swaps(&sWire->height,n); 5055 swaps(&sWire->angle,n); 5056 } 5057 CHK_ATOM_ONLY(sWire->name); 5058 section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, 5059 sWire->nDoodads,sWire->nOverlays); 5060 if (!section) 5061 return BadAlloc; 5062 section->priority= sWire->priority; 5063 section->top= sWire->top; 5064 section->left= sWire->left; 5065 section->width= sWire->width; 5066 section->height= sWire->height; 5067 section->angle= sWire->angle; 5068 rWire= (xkbRowWireDesc *)&sWire[1]; 5069 for (r=0;r<sWire->nRows;r++) { 5070 register int k; 5071 XkbRowPtr row; 5072 xkbKeyWireDesc * kWire; 5073 if (client->swapped) { 5074 register int n; 5075 swaps(&rWire->top,n); 5076 swaps(&rWire->left,n); 5077 } 5078 row= XkbAddGeomRow(section,rWire->nKeys); 5079 if (!row) 5080 return BadAlloc; 5081 row->top= rWire->top; 5082 row->left= rWire->left; 5083 row->vertical= rWire->vertical; 5084 kWire= (xkbKeyWireDesc *)&rWire[1]; 5085 for (k=0;k<rWire->nKeys;k++) { 5086 XkbKeyPtr key; 5087 key= XkbAddGeomKey(row); 5088 if (!key) 5089 return BadAlloc; 5090 memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); 5091 key->gap= kWire[k].gap; 5092 key->shape_ndx= kWire[k].shapeNdx; 5093 key->color_ndx= kWire[k].colorNdx; 5094 if (key->shape_ndx>=geom->num_shapes) { 5095 client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, 5096 geom->num_shapes); 5097 return BadMatch; 5098 } 5099 if (key->color_ndx>=geom->num_colors) { 5100 client->errorValue= _XkbErrCode3(0x11,key->color_ndx, 5101 geom->num_colors); 5102 return BadMatch; 5103 } 5104 } 5105 rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; 5106 } 5107 wire= (char *)rWire; 5108 if (sWire->nDoodads>0) { 5109 register int d; 5110 for (d=0;d<sWire->nDoodads;d++) { 5111 status=_CheckSetDoodad(&wire,geom,section,client); 5112 if (status!=Success) 5113 return status; 5114 } 5115 } 5116 if (sWire->nOverlays>0) { 5117 register int o; 5118 for (o=0;o<sWire->nOverlays;o++) { 5119 status= _CheckSetOverlay(&wire,geom,section,client); 5120 if (status!=Success) 5121 return status; 5122 } 5123 } 5124 sWire= (xkbSectionWireDesc *)wire; 5125 } 5126 wire= (char *)sWire; 5127 *wire_inout= wire; 5128 return Success; 5129} 5130 5131static Status 5132_CheckSetShapes( XkbGeometryPtr geom, 5133 xkbSetGeometryReq * req, 5134 char ** wire_inout, 5135 ClientPtr client) 5136{ 5137register int i; 5138char * wire; 5139 5140 wire= *wire_inout; 5141 if (req->nShapes<1) { 5142 client->errorValue= _XkbErrCode2(0x06,req->nShapes); 5143 return BadValue; 5144 } 5145 else { 5146 xkbShapeWireDesc * shapeWire; 5147 XkbShapePtr shape; 5148 register int o; 5149 shapeWire= (xkbShapeWireDesc *)wire; 5150 for (i=0;i<req->nShapes;i++) { 5151 xkbOutlineWireDesc * olWire; 5152 XkbOutlinePtr ol; 5153 shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); 5154 if (!shape) 5155 return BadAlloc; 5156 olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); 5157 for (o=0;o<shapeWire->nOutlines;o++) { 5158 register int p; 5159 XkbPointPtr pt; 5160 xkbPointWireDesc * ptWire; 5161 5162 ol= XkbAddGeomOutline(shape,olWire->nPoints); 5163 if (!ol) 5164 return BadAlloc; 5165 ol->corner_radius= olWire->cornerRadius; 5166 ptWire= (xkbPointWireDesc *)&olWire[1]; 5167 for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { 5168 pt->x= ptWire[p].x; 5169 pt->y= ptWire[p].y; 5170 if (client->swapped) { 5171 register int n; 5172 swaps(&pt->x,n); 5173 swaps(&pt->y,n); 5174 } 5175 } 5176 ol->num_points= olWire->nPoints; 5177 olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); 5178 } 5179 if (shapeWire->primaryNdx!=XkbNoShape) 5180 shape->primary= &shape->outlines[shapeWire->primaryNdx]; 5181 if (shapeWire->approxNdx!=XkbNoShape) 5182 shape->approx= &shape->outlines[shapeWire->approxNdx]; 5183 shapeWire= (xkbShapeWireDesc *)olWire; 5184 } 5185 wire= (char *)shapeWire; 5186 } 5187 if (geom->num_shapes!=req->nShapes) { 5188 client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); 5189 return BadMatch; 5190 } 5191 5192 *wire_inout= wire; 5193 return Success; 5194} 5195 5196static Status 5197_CheckSetGeom( XkbGeometryPtr geom, 5198 xkbSetGeometryReq * req, 5199 ClientPtr client) 5200{ 5201register int i; 5202Status status; 5203char * wire; 5204 5205 wire= (char *)&req[1]; 5206 status = _GetCountedString(&wire, client, &geom->label_font); 5207 if (status != Success) 5208 return status; 5209 5210 for (i = 0; i < req->nProperties; i++) { 5211 char *name, *val; 5212 5213 status = _GetCountedString(&wire, client, &name); 5214 if (status != Success) 5215 return status; 5216 status = _GetCountedString(&wire, client, &val); 5217 if (status != Success) { 5218 free(name); 5219 return status; 5220 } 5221 if (XkbAddGeomProperty(geom,name,val)==NULL) { 5222 free(name); 5223 free(val); 5224 return BadAlloc; 5225 } 5226 free(name); 5227 free(val); 5228 } 5229 5230 if (req->nColors<2) { 5231 client->errorValue= _XkbErrCode3(0x01,2,req->nColors); 5232 return BadValue; 5233 } 5234 if (req->baseColorNdx>req->nColors) { 5235 client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); 5236 return BadMatch; 5237 } 5238 if (req->labelColorNdx>req->nColors) { 5239 client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); 5240 return BadMatch; 5241 } 5242 if (req->labelColorNdx==req->baseColorNdx) { 5243 client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, 5244 req->labelColorNdx); 5245 return BadMatch; 5246 } 5247 5248 for (i = 0; i < req->nColors; i++) { 5249 char *name; 5250 status = _GetCountedString(&wire, client, &name); 5251 if (status != Success) 5252 return status; 5253 if (!XkbAddGeomColor(geom,name,geom->num_colors)) { 5254 free(name); 5255 return BadAlloc; 5256 } 5257 free(name); 5258 } 5259 if (req->nColors!=geom->num_colors) { 5260 client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); 5261 return BadMatch; 5262 } 5263 geom->label_color= &geom->colors[req->labelColorNdx]; 5264 geom->base_color= &geom->colors[req->baseColorNdx]; 5265 5266 if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) 5267 return status; 5268 5269 if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) 5270 return status; 5271 5272 for (i=0;i<req->nDoodads;i++) { 5273 status=_CheckSetDoodad(&wire,geom,NULL,client); 5274 if (status!=Success) 5275 return status; 5276 } 5277 5278 for (i=0;i<req->nKeyAliases;i++) { 5279 if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) 5280 return BadAlloc; 5281 wire+= 2*XkbKeyNameLength; 5282 } 5283 return Success; 5284} 5285 5286static int 5287_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) 5288{ 5289 XkbDescPtr xkb; 5290 Bool new_name; 5291 xkbNewKeyboardNotify nkn; 5292 XkbGeometryPtr geom,old; 5293 XkbGeometrySizesRec sizes; 5294 Status status; 5295 5296 xkb= dev->key->xkbInfo->desc; 5297 old= xkb->geom; 5298 xkb->geom= NULL; 5299 5300 sizes.which= XkbGeomAllMask; 5301 sizes.num_properties= stuff->nProperties; 5302 sizes.num_colors= stuff->nColors; 5303 sizes.num_shapes= stuff->nShapes; 5304 sizes.num_sections= stuff->nSections; 5305 sizes.num_doodads= stuff->nDoodads; 5306 sizes.num_key_aliases= stuff->nKeyAliases; 5307 if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { 5308 xkb->geom= old; 5309 return status; 5310 } 5311 geom= xkb->geom; 5312 geom->name= stuff->name; 5313 geom->width_mm= stuff->widthMM; 5314 geom->height_mm= stuff->heightMM; 5315 if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { 5316 XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); 5317 xkb->geom= old; 5318 return status; 5319 } 5320 new_name= (xkb->names->geometry!=geom->name); 5321 xkb->names->geometry= geom->name; 5322 if (old) 5323 XkbFreeGeometry(old,XkbGeomAllMask,TRUE); 5324 if (new_name) { 5325 xkbNamesNotify nn; 5326 memset(&nn, 0, sizeof(xkbNamesNotify)); 5327 nn.changed= XkbGeometryNameMask; 5328 XkbSendNamesNotify(dev,&nn); 5329 } 5330 nkn.deviceID= nkn.oldDeviceID= dev->id; 5331 nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; 5332 nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; 5333 nkn.requestMajor= XkbReqCode; 5334 nkn.requestMinor= X_kbSetGeometry; 5335 nkn.changed= XkbNKN_GeometryMask; 5336 XkbSendNewKeyboardNotify(dev,&nkn); 5337 return Success; 5338} 5339 5340int 5341ProcXkbSetGeometry(ClientPtr client) 5342{ 5343 DeviceIntPtr dev; 5344 int rc; 5345 5346 REQUEST(xkbSetGeometryReq); 5347 REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); 5348 5349 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5350 return BadAccess; 5351 5352 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 5353 CHK_ATOM_OR_NONE(stuff->name); 5354 5355 rc = _XkbSetGeometry(client, dev, stuff); 5356 if (rc != Success) 5357 return rc; 5358 5359 if (stuff->deviceSpec == XkbUseCoreKbd) 5360 { 5361 DeviceIntPtr other; 5362 for (other = inputInfo.devices; other; other = other->next) 5363 { 5364 if ((other != dev) && other->key && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) 5365 { 5366 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 5367 if (rc == Success) 5368 _XkbSetGeometry(client, other, stuff); 5369 } 5370 } 5371 } 5372 5373 return Success; 5374} 5375 5376/***====================================================================***/ 5377 5378int 5379ProcXkbPerClientFlags(ClientPtr client) 5380{ 5381 DeviceIntPtr dev; 5382 xkbPerClientFlagsReply rep; 5383 XkbInterestPtr interest; 5384 Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; 5385 5386 REQUEST(xkbPerClientFlagsReq); 5387 REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); 5388 5389 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5390 return BadAccess; 5391 5392 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5393 CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); 5394 CHK_MASK_MATCH(0x02,stuff->change,stuff->value); 5395 5396 interest = XkbFindClientResource((DevicePtr)dev,client); 5397 memset(&rep, 0, sizeof(xkbPerClientFlagsReply)); 5398 rep.type= X_Reply; 5399 rep.length = 0; 5400 rep.sequenceNumber = client->sequence; 5401 if (stuff->change) { 5402 client->xkbClientFlags&= ~stuff->change; 5403 client->xkbClientFlags|= stuff->value; 5404 } 5405 if (stuff->change&XkbPCF_AutoResetControlsMask) { 5406 Bool want; 5407 want= stuff->value&XkbPCF_AutoResetControlsMask; 5408 if (interest && !want) { 5409 interest->autoCtrls= interest->autoCtrlValues= 0; 5410 } 5411 else if (want && (!interest)) { 5412 XID id = FakeClientID(client->index); 5413 if (!AddResource(id,RT_XKBCLIENT,dev)) 5414 return BadAlloc; 5415 interest= XkbAddClientResource((DevicePtr)dev,client,id); 5416 if (!interest) 5417 return BadAlloc; 5418 } 5419 if (interest && want ) { 5420 register unsigned affect; 5421 affect= stuff->ctrlsToChange; 5422 5423 CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); 5424 CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); 5425 CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); 5426 5427 interest->autoCtrls&= ~affect; 5428 interest->autoCtrlValues&= ~affect; 5429 interest->autoCtrls|= stuff->autoCtrls&affect; 5430 interest->autoCtrlValues|= stuff->autoCtrlValues&affect; 5431 } 5432 } 5433 rep.supported = XkbPCF_AllFlagsMask; 5434 rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; 5435 if (interest) { 5436 rep.autoCtrls= interest->autoCtrls; 5437 rep.autoCtrlValues= interest->autoCtrlValues; 5438 } 5439 else { 5440 rep.autoCtrls= rep.autoCtrlValues= 0; 5441 } 5442 if ( client->swapped ) { 5443 register int n; 5444 swaps(&rep.sequenceNumber, n); 5445 swapl(&rep.supported,n); 5446 swapl(&rep.value,n); 5447 swapl(&rep.autoCtrls,n); 5448 swapl(&rep.autoCtrlValues,n); 5449 } 5450 WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); 5451 return Success; 5452} 5453 5454/***====================================================================***/ 5455 5456/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ 5457/* and wildcards */ 5458static unsigned char componentSpecLegal[] = { 5459 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, 5460 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, 5461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5462 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5463}; 5464 5465/* same as above but accepts percent, plus and bar too */ 5466static unsigned char componentExprLegal[] = { 5467 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, 5468 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, 5469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5470 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff 5471}; 5472 5473static char * 5474GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) 5475{ 5476int len; 5477register int i; 5478unsigned char *wire,*str,*tmp,*legal; 5479 5480 if (allowExpr) legal= &componentExprLegal[0]; 5481 else legal= &componentSpecLegal[0]; 5482 5483 wire= *pWire; 5484 len= (*(unsigned char *)wire++); 5485 if (len>0) { 5486 str= calloc(1, len+1); 5487 if (str) { 5488 tmp= str; 5489 for (i=0;i<len;i++) { 5490 if (legal[(*wire)/8]&(1<<((*wire)%8))) 5491 *tmp++= *wire++; 5492 else wire++; 5493 } 5494 if (tmp!=str) 5495 *tmp++= '\0'; 5496 else { 5497 free(str); 5498 str= NULL; 5499 } 5500 } 5501 else { 5502 *errRtrn= BadAlloc; 5503 } 5504 } 5505 else { 5506 str= NULL; 5507 } 5508 *pWire= wire; 5509 return (char *)str; 5510} 5511 5512/***====================================================================***/ 5513 5514int 5515ProcXkbListComponents(ClientPtr client) 5516{ 5517 DeviceIntPtr dev; 5518 xkbListComponentsReply rep; 5519 unsigned len; 5520 int status; 5521 unsigned char * str; 5522 XkbSrvListInfoRec list; 5523 5524 REQUEST(xkbListComponentsReq); 5525 REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); 5526 5527 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5528 return BadAccess; 5529 5530 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 5531 5532 status= Success; 5533 str= (unsigned char *)&stuff[1]; 5534 memset(&list, 0, sizeof(XkbSrvListInfoRec)); 5535 list.maxRtrn= stuff->maxNames; 5536 list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status); 5537 list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status); 5538 list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status); 5539 list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status); 5540 list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status); 5541 if (status!=Success) 5542 return status; 5543 len= str-((unsigned char *)stuff); 5544 if ((XkbPaddedSize(len)/4)!=stuff->length) 5545 return BadLength; 5546 if ((status=XkbDDXList(dev,&list,client))!=Success) { 5547 free(list.pool); 5548 list.pool = NULL; 5549 return status; 5550 } 5551 memset(&rep, 0, sizeof(xkbListComponentsReply)); 5552 rep.type= X_Reply; 5553 rep.deviceID = dev->id; 5554 rep.sequenceNumber = client->sequence; 5555 rep.length = XkbPaddedSize(list.nPool)/4; 5556 rep.nKeymaps = 0; 5557 rep.nKeycodes = list.nFound[_XkbListKeycodes]; 5558 rep.nTypes = list.nFound[_XkbListTypes]; 5559 rep.nCompatMaps = list.nFound[_XkbListCompat]; 5560 rep.nSymbols = list.nFound[_XkbListSymbols]; 5561 rep.nGeometries = list.nFound[_XkbListGeometry]; 5562 rep.extra= 0; 5563 if (list.nTotal>list.maxRtrn) 5564 rep.extra = (list.nTotal-list.maxRtrn); 5565 if (client->swapped) { 5566 register int n; 5567 swaps(&rep.sequenceNumber,n); 5568 swapl(&rep.length,n); 5569 swaps(&rep.nKeymaps,n); 5570 swaps(&rep.nKeycodes,n); 5571 swaps(&rep.nTypes,n); 5572 swaps(&rep.nCompatMaps,n); 5573 swaps(&rep.nSymbols,n); 5574 swaps(&rep.nGeometries,n); 5575 swaps(&rep.extra,n); 5576 } 5577 WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); 5578 if (list.nPool && list.pool) { 5579 WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); 5580 free(list.pool); 5581 list.pool= NULL; 5582 } 5583 return Success; 5584} 5585 5586/***====================================================================***/ 5587 5588int 5589ProcXkbGetKbdByName(ClientPtr client) 5590{ 5591 DeviceIntPtr dev; 5592 DeviceIntPtr tmpd; 5593 xkbGetKbdByNameReply rep = {0}; 5594 xkbGetMapReply mrep = {0}; 5595 xkbGetCompatMapReply crep = {0}; 5596 xkbGetIndicatorMapReply irep = {0}; 5597 xkbGetNamesReply nrep = {0}; 5598 xkbGetGeometryReply grep = {0}; 5599 XkbComponentNamesRec names = {0}; 5600 XkbDescPtr xkb, new; 5601 unsigned char * str; 5602 char mapFile[PATH_MAX]; 5603 unsigned len; 5604 unsigned fwant,fneed,reported; 5605 int status; 5606 Bool geom_changed; 5607 XkbSrvLedInfoPtr old_sli; 5608 XkbSrvLedInfoPtr sli; 5609 Mask access_mode = DixGetAttrAccess | DixManageAccess; 5610 5611 REQUEST(xkbGetKbdByNameReq); 5612 REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); 5613 5614 if (!(client->xkbClientFlags&_XkbClientInitialized)) 5615 return BadAccess; 5616 5617 CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); 5618 5619 xkb = dev->key->xkbInfo->desc; 5620 status= Success; 5621 str= (unsigned char *)&stuff[1]; 5622 if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */ 5623 return BadMatch; 5624 names.keycodes= GetComponentSpec(&str,TRUE,&status); 5625 names.types= GetComponentSpec(&str,TRUE,&status); 5626 names.compat= GetComponentSpec(&str,TRUE,&status); 5627 names.symbols= GetComponentSpec(&str,TRUE,&status); 5628 names.geometry= GetComponentSpec(&str,TRUE,&status); 5629 if (status!=Success) 5630 return status; 5631 len= str-((unsigned char *)stuff); 5632 if ((XkbPaddedSize(len)/4)!=stuff->length) 5633 return BadLength; 5634 5635 CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); 5636 CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); 5637 5638 if (stuff->load) 5639 fwant= XkbGBN_AllComponentsMask; 5640 else fwant= stuff->want|stuff->need; 5641 if ((!names.compat)&& 5642 (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { 5643 names.compat= _XkbDupString("%"); 5644 } 5645 if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { 5646 names.types= _XkbDupString("%"); 5647 } 5648 if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { 5649 names.symbols= _XkbDupString("%"); 5650 } 5651 geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); 5652 if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { 5653 names.geometry= _XkbDupString("%"); 5654 geom_changed= FALSE; 5655 } 5656 5657 memset(mapFile, 0, PATH_MAX); 5658 rep.type= X_Reply; 5659 rep.deviceID = dev->id; 5660 rep.sequenceNumber = client->sequence; 5661 rep.length = 0; 5662 rep.minKeyCode = xkb->min_key_code; 5663 rep.maxKeyCode = xkb->max_key_code; 5664 rep.loaded= FALSE; 5665 fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask; 5666 fneed= XkbConvertGetByNameComponents(TRUE,stuff->need); 5667 rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed); 5668 if (stuff->load) { 5669 fneed|= XkmKeymapRequired; 5670 fwant|= XkmKeymapLegal; 5671 } 5672 if ((fwant|fneed)&XkmSymbolsMask) { 5673 fneed|= XkmKeyNamesIndex|XkmTypesIndex; 5674 fwant|= XkmIndicatorsIndex; 5675 } 5676 5677 /* We pass dev in here so we can get the old names out if needed. */ 5678 rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new, 5679 mapFile,PATH_MAX); 5680 rep.newKeyboard= FALSE; 5681 rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; 5682 5683 stuff->want|= stuff->need; 5684 if (new==NULL) 5685 rep.reported= 0; 5686 else { 5687 if (stuff->load) 5688 rep.loaded= TRUE; 5689 if (stuff->load || 5690 ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) { 5691 XkbChangesRec changes; 5692 memset(&changes, 0, sizeof(changes)); 5693 XkbUpdateDescActions(new, 5694 new->min_key_code,XkbNumKeys(new), 5695 &changes); 5696 } 5697 5698 if (new->map==NULL) 5699 rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); 5700 else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { 5701 mrep.type= X_Reply; 5702 mrep.deviceID = dev->id; 5703 mrep.sequenceNumber= client->sequence; 5704 mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); 5705 mrep.minKeyCode = new->min_key_code; 5706 mrep.maxKeyCode = new->max_key_code; 5707 mrep.present = 0; 5708 mrep.totalSyms = mrep.totalActs = 5709 mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 5710 mrep.totalModMapKeys= mrep.totalVModMapKeys= 0; 5711 if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { 5712 mrep.present|= XkbKeyTypesMask; 5713 mrep.firstType = 0; 5714 mrep.nTypes = mrep.totalTypes= new->map->num_types; 5715 } 5716 else { 5717 mrep.firstType = mrep.nTypes= 0; 5718 mrep.totalTypes= 0; 5719 } 5720 if (rep.reported&XkbGBN_ClientSymbolsMask) { 5721 mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); 5722 mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code; 5723 mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new); 5724 } 5725 else { 5726 mrep.firstKeySym= mrep.firstModMapKey= 0; 5727 mrep.nKeySyms= mrep.nModMapKeys= 0; 5728 } 5729 if (rep.reported&XkbGBN_ServerSymbolsMask) { 5730 mrep.present|= XkbAllServerInfoMask; 5731 mrep.virtualMods= ~0; 5732 mrep.firstKeyAct = mrep.firstKeyBehavior = 5733 mrep.firstKeyExplicit = new->min_key_code; 5734 mrep.nKeyActs = mrep.nKeyBehaviors = 5735 mrep.nKeyExplicit = XkbNumKeys(new); 5736 mrep.firstVModMapKey= new->min_key_code; 5737 mrep.nVModMapKeys= XkbNumKeys(new); 5738 } 5739 else { 5740 mrep.virtualMods= 0; 5741 mrep.firstKeyAct= mrep.firstKeyBehavior= 5742 mrep.firstKeyExplicit = 0; 5743 mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; 5744 } 5745 XkbComputeGetMapReplySize(new,&mrep); 5746 rep.length+= SIZEOF(xGenericReply)/4+mrep.length; 5747 } 5748 if (new->compat==NULL) 5749 rep.reported&= ~XkbGBN_CompatMapMask; 5750 else if (rep.reported&XkbGBN_CompatMapMask) { 5751 crep.type= X_Reply; 5752 crep.deviceID= dev->id; 5753 crep.sequenceNumber= client->sequence; 5754 crep.length= 0; 5755 crep.groups= XkbAllGroupsMask; 5756 crep.firstSI= 0; 5757 crep.nSI= crep.nTotalSI= new->compat->num_si; 5758 XkbComputeGetCompatMapReplySize(new->compat,&crep); 5759 rep.length+= SIZEOF(xGenericReply)/4+crep.length; 5760 } 5761 if (new->indicators==NULL) 5762 rep.reported&= ~XkbGBN_IndicatorMapMask; 5763 else if (rep.reported&XkbGBN_IndicatorMapMask) { 5764 irep.type= X_Reply; 5765 irep.deviceID= dev->id; 5766 irep.sequenceNumber= client->sequence; 5767 irep.length= 0; 5768 irep.which= XkbAllIndicatorsMask; 5769 XkbComputeGetIndicatorMapReplySize(new->indicators,&irep); 5770 rep.length+= SIZEOF(xGenericReply)/4+irep.length; 5771 } 5772 if (new->names==NULL) 5773 rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); 5774 else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { 5775 nrep.type= X_Reply; 5776 nrep.deviceID= dev->id; 5777 nrep.sequenceNumber= client->sequence; 5778 nrep.length= 0; 5779 nrep.minKeyCode= new->min_key_code; 5780 nrep.maxKeyCode= new->max_key_code; 5781 if (rep.reported&XkbGBN_OtherNamesMask) { 5782 nrep.which= XkbAllNamesMask; 5783 if (new->map!=NULL) 5784 nrep.nTypes= new->map->num_types; 5785 else nrep.nTypes= 0; 5786 nrep.nKTLevels= 0; 5787 nrep.groupNames= XkbAllGroupsMask; 5788 nrep.virtualMods= XkbAllVirtualModsMask; 5789 nrep.indicators= XkbAllIndicatorsMask; 5790 nrep.nRadioGroups= new->names->num_rg; 5791 } 5792 else { 5793 nrep.which= 0; 5794 nrep.nTypes= 0; 5795 nrep.nKTLevels= 0; 5796 nrep.groupNames= 0; 5797 nrep.virtualMods= 0; 5798 nrep.indicators= 0; 5799 nrep.nRadioGroups= 0; 5800 } 5801 if (rep.reported&XkbGBN_KeyNamesMask) { 5802 nrep.which|= XkbKeyNamesMask; 5803 nrep.firstKey= new->min_key_code; 5804 nrep.nKeys= XkbNumKeys(new); 5805 nrep.nKeyAliases= new->names->num_key_aliases; 5806 if (nrep.nKeyAliases) 5807 nrep.which|= XkbKeyAliasesMask; 5808 } 5809 else { 5810 nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); 5811 nrep.firstKey= nrep.nKeys= 0; 5812 nrep.nKeyAliases= 0; 5813 } 5814 XkbComputeGetNamesReplySize(new,&nrep); 5815 rep.length+= SIZEOF(xGenericReply)/4+nrep.length; 5816 } 5817 if (new->geom==NULL) 5818 rep.reported&= ~XkbGBN_GeometryMask; 5819 else if (rep.reported&XkbGBN_GeometryMask) { 5820 grep.type= X_Reply; 5821 grep.deviceID= dev->id; 5822 grep.sequenceNumber= client->sequence; 5823 grep.length= 0; 5824 grep.found= TRUE; 5825 grep.pad= 0; 5826 grep.widthMM= grep.heightMM= 0; 5827 grep.nProperties= grep.nColors= grep.nShapes= 0; 5828 grep.nSections= grep.nDoodads= 0; 5829 grep.baseColorNdx= grep.labelColorNdx= 0; 5830 XkbComputeGetGeometryReplySize(new->geom,&grep,None); 5831 rep.length+= SIZEOF(xGenericReply)/4+grep.length; 5832 } 5833 } 5834 5835 reported= rep.reported; 5836 if ( client->swapped ) { 5837 register int n; 5838 swaps(&rep.sequenceNumber,n); 5839 swapl(&rep.length,n); 5840 swaps(&rep.found,n); 5841 swaps(&rep.reported,n); 5842 } 5843 WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); 5844 if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) 5845 XkbSendMap(client,new,&mrep); 5846 if (reported&XkbGBN_CompatMapMask) 5847 XkbSendCompatMap(client,new->compat,&crep); 5848 if (reported&XkbGBN_IndicatorMapMask) 5849 XkbSendIndicatorMap(client,new->indicators,&irep); 5850 if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) 5851 XkbSendNames(client,new,&nrep); 5852 if (reported&XkbGBN_GeometryMask) 5853 XkbSendGeometry(client,new->geom,&grep,FALSE); 5854 if (rep.loaded) { 5855 XkbDescPtr old_xkb; 5856 xkbNewKeyboardNotify nkn; 5857 int i,nG,nTG; 5858 old_xkb= xkb; 5859 xkb= new; 5860 dev->key->xkbInfo->desc= xkb; 5861 new= old_xkb; /* so it'll get freed automatically */ 5862 5863 *xkb->ctrls= *old_xkb->ctrls; 5864 for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 5865 nG= XkbKeyNumGroups(xkb,i); 5866 if (nG>=XkbNumKbdGroups) { 5867 nTG= XkbNumKbdGroups; 5868 break; 5869 } 5870 if (nG>nTG) { 5871 nTG= nG; 5872 } 5873 } 5874 xkb->ctrls->num_groups= nTG; 5875 5876 for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { 5877 if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) { 5878 if (tmpd != dev) 5879 XkbCopyDeviceKeymap(tmpd, dev); 5880 5881 if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { 5882 old_sli = tmpd->kbdfeed->xkb_sli; 5883 tmpd->kbdfeed->xkb_sli = NULL; 5884 sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); 5885 if (sli) { 5886 sli->explicitState = old_sli->explicitState; 5887 sli->effectiveState = old_sli->effectiveState; 5888 } 5889 tmpd->kbdfeed->xkb_sli = sli; 5890 XkbFreeSrvLedInfo(old_sli); 5891 } 5892 } 5893 } 5894 5895 nkn.deviceID= nkn.oldDeviceID= dev->id; 5896 nkn.minKeyCode= new->min_key_code; 5897 nkn.maxKeyCode= new->max_key_code; 5898 nkn.oldMinKeyCode= xkb->min_key_code; 5899 nkn.oldMaxKeyCode= xkb->max_key_code; 5900 nkn.requestMajor= XkbReqCode; 5901 nkn.requestMinor= X_kbGetKbdByName; 5902 nkn.changed= XkbNKN_KeycodesMask; 5903 if (geom_changed) 5904 nkn.changed|= XkbNKN_GeometryMask; 5905 XkbSendNewKeyboardNotify(dev,&nkn); 5906 5907 if (!IsMaster(dev) && dev->u.master) 5908 { 5909 DeviceIntPtr master = dev->u.master; 5910 if (master->u.lastSlave == dev) 5911 { 5912 XkbCopyDeviceKeymap(dev->u.master, dev); 5913 XkbSendNewKeyboardNotify(dev,&nkn); 5914 } 5915 } 5916 } 5917 if ((new!=NULL)&&(new!=xkb)) { 5918 XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); 5919 new= NULL; 5920 } 5921 XkbFreeComponentNames(&names, FALSE); 5922 return Success; 5923} 5924 5925/***====================================================================***/ 5926 5927static int 5928ComputeDeviceLedInfoSize( DeviceIntPtr dev, 5929 unsigned int what, 5930 XkbSrvLedInfoPtr sli) 5931{ 5932int nNames,nMaps; 5933register unsigned n,bit; 5934 5935 if (sli==NULL) 5936 return 0; 5937 nNames= nMaps= 0; 5938 if ((what&XkbXI_IndicatorNamesMask)==0) 5939 sli->namesPresent= 0; 5940 if ((what&XkbXI_IndicatorMapsMask)==0) 5941 sli->mapsPresent= 0; 5942 5943 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 5944 if (sli->names && sli->names[n]!=None) { 5945 sli->namesPresent|= bit; 5946 nNames++; 5947 } 5948 if (sli->maps && XkbIM_InUse(&sli->maps[n])) { 5949 sli->mapsPresent|= bit; 5950 nMaps++; 5951 } 5952 } 5953 return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); 5954} 5955 5956static int 5957CheckDeviceLedFBs( DeviceIntPtr dev, 5958 int class, 5959 int id, 5960 xkbGetDeviceInfoReply * rep, 5961 ClientPtr client) 5962{ 5963int nFBs= 0; 5964int length= 0; 5965Bool classOk; 5966 5967 if (class==XkbDfltXIClass) { 5968 if (dev->kbdfeed) class= KbdFeedbackClass; 5969 else if (dev->leds) class= LedFeedbackClass; 5970 else { 5971 client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 5972 return XkbKeyboardErrorCode; 5973 } 5974 } 5975 classOk= FALSE; 5976 if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 5977 KbdFeedbackPtr kf; 5978 classOk= TRUE; 5979 for (kf= dev->kbdfeed;(kf);kf=kf->next) { 5980 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) 5981 continue; 5982 nFBs++; 5983 length+= SIZEOF(xkbDeviceLedsWireDesc); 5984 if (!kf->xkb_sli) 5985 kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); 5986 length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); 5987 if (id!=XkbAllXIIds) 5988 break; 5989 } 5990 } 5991 if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 5992 LedFeedbackPtr lf; 5993 classOk= TRUE; 5994 for (lf= dev->leds;(lf);lf=lf->next) { 5995 if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) 5996 continue; 5997 nFBs++; 5998 length+= SIZEOF(xkbDeviceLedsWireDesc); 5999 if (!lf->xkb_sli) 6000 lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); 6001 length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); 6002 if (id!=XkbAllXIIds) 6003 break; 6004 } 6005 } 6006 if (nFBs>0) { 6007 rep->nDeviceLedFBs= nFBs; 6008 rep->length+= (length/4); 6009 return Success; 6010 } 6011 if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); 6012 else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); 6013 return XkbKeyboardErrorCode; 6014} 6015 6016static int 6017SendDeviceLedInfo( XkbSrvLedInfoPtr sli, 6018 ClientPtr client) 6019{ 6020xkbDeviceLedsWireDesc wire; 6021int length; 6022 6023 length= 0; 6024 wire.ledClass= sli->class; 6025 wire.ledID= sli->id; 6026 wire.namesPresent= sli->namesPresent; 6027 wire.mapsPresent= sli->mapsPresent; 6028 wire.physIndicators= sli->physIndicators; 6029 wire.state= sli->effectiveState; 6030 if (client->swapped) { 6031 register int n; 6032 swaps(&wire.ledClass,n); 6033 swaps(&wire.ledID,n); 6034 swapl(&wire.namesPresent,n); 6035 swapl(&wire.mapsPresent,n); 6036 swapl(&wire.physIndicators,n); 6037 swapl(&wire.state,n); 6038 } 6039 WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); 6040 length+= SIZEOF(xkbDeviceLedsWireDesc); 6041 if (sli->namesPresent|sli->mapsPresent) { 6042 register unsigned i,bit; 6043 if (sli->namesPresent) { 6044 CARD32 awire; 6045 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 6046 if (sli->namesPresent&bit) { 6047 awire= (CARD32)sli->names[i]; 6048 if (client->swapped) { 6049 register int n; 6050 swapl(&awire,n); 6051 } 6052 WriteToClient(client,4,(char *)&awire); 6053 length+= 4; 6054 } 6055 } 6056 } 6057 if (sli->mapsPresent) { 6058 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 6059 xkbIndicatorMapWireDesc iwire; 6060 if (sli->mapsPresent&bit) { 6061 iwire.flags= sli->maps[i].flags; 6062 iwire.whichGroups= sli->maps[i].which_groups; 6063 iwire.groups= sli->maps[i].groups; 6064 iwire.whichMods= sli->maps[i].which_mods; 6065 iwire.mods= sli->maps[i].mods.mask; 6066 iwire.realMods= sli->maps[i].mods.real_mods; 6067 iwire.virtualMods= sli->maps[i].mods.vmods; 6068 iwire.ctrls= sli->maps[i].ctrls; 6069 if (client->swapped) { 6070 register int n; 6071 swaps(&iwire.virtualMods,n); 6072 swapl(&iwire.ctrls,n); 6073 } 6074 WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), 6075 (char *)&iwire); 6076 length+= SIZEOF(xkbIndicatorMapWireDesc); 6077 } 6078 } 6079 } 6080 } 6081 return length; 6082} 6083 6084static int 6085SendDeviceLedFBs( DeviceIntPtr dev, 6086 int class, 6087 int id, 6088 unsigned wantLength, 6089 ClientPtr client) 6090{ 6091int length= 0; 6092 6093 if (class==XkbDfltXIClass) { 6094 if (dev->kbdfeed) class= KbdFeedbackClass; 6095 else if (dev->leds) class= LedFeedbackClass; 6096 } 6097 if ((dev->kbdfeed)&& 6098 ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { 6099 KbdFeedbackPtr kf; 6100 for (kf= dev->kbdfeed;(kf);kf=kf->next) { 6101 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { 6102 length+= SendDeviceLedInfo(kf->xkb_sli,client); 6103 if (id!=XkbAllXIIds) 6104 break; 6105 } 6106 } 6107 } 6108 if ((dev->leds)&& 6109 ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { 6110 LedFeedbackPtr lf; 6111 for (lf= dev->leds;(lf);lf=lf->next) { 6112 if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { 6113 length+= SendDeviceLedInfo(lf->xkb_sli,client); 6114 if (id!=XkbAllXIIds) 6115 break; 6116 } 6117 } 6118 } 6119 if (length==wantLength) 6120 return Success; 6121 else return BadLength; 6122} 6123 6124int 6125ProcXkbGetDeviceInfo(ClientPtr client) 6126{ 6127DeviceIntPtr dev; 6128xkbGetDeviceInfoReply rep; 6129int status,nDeviceLedFBs; 6130unsigned length,nameLen; 6131CARD16 ledClass,ledID; 6132unsigned wanted; 6133char * str; 6134 6135 REQUEST(xkbGetDeviceInfoReq); 6136 REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); 6137 6138 if (!(client->xkbClientFlags&_XkbClientInitialized)) 6139 return BadAccess; 6140 6141 wanted= stuff->wanted; 6142 6143 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); 6144 CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); 6145 6146 if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) 6147 wanted&= ~XkbXI_ButtonActionsMask; 6148 if ((!dev->kbdfeed)&&(!dev->leds)) 6149 wanted&= ~XkbXI_IndicatorsMask; 6150 6151 nameLen= XkbSizeCountedString(dev->name); 6152 memset((char *)&rep, 0, SIZEOF(xkbGetDeviceInfoReply)); 6153 rep.type = X_Reply; 6154 rep.deviceID= dev->id; 6155 rep.sequenceNumber = client->sequence; 6156 rep.length = nameLen/4; 6157 rep.present = wanted; 6158 rep.supported = XkbXI_AllDeviceFeaturesMask; 6159 rep.unsupported = 0; 6160 rep.firstBtnWanted = rep.nBtnsWanted = 0; 6161 rep.firstBtnRtrn = rep.nBtnsRtrn = 0; 6162 if (dev->button) 6163 rep.totalBtns= dev->button->numButtons; 6164 else rep.totalBtns= 0; 6165 rep.devType= dev->xinput_type; 6166 rep.hasOwnState= (dev->key && dev->key->xkbInfo); 6167 rep.nDeviceLedFBs = 0; 6168 if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; 6169 else rep.dfltKbdFB= XkbXINone; 6170 if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; 6171 else rep.dfltLedFB= XkbXINone; 6172 6173 ledClass= stuff->ledClass; 6174 ledID= stuff->ledID; 6175 6176 rep.firstBtnWanted= rep.nBtnsWanted= 0; 6177 rep.firstBtnRtrn= rep.nBtnsRtrn= 0; 6178 if (wanted&XkbXI_ButtonActionsMask) { 6179 if (stuff->allBtns) { 6180 stuff->firstBtn= 0; 6181 stuff->nBtns= dev->button->numButtons; 6182 } 6183 6184 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 6185 client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, 6186 stuff->firstBtn, 6187 stuff->nBtns); 6188 return BadValue; 6189 } 6190 else { 6191 rep.firstBtnWanted= stuff->firstBtn; 6192 rep.nBtnsWanted= stuff->nBtns; 6193 if (dev->button->xkb_acts!=NULL) { 6194 XkbAction *act; 6195 register int i; 6196 6197 rep.firstBtnRtrn= stuff->firstBtn; 6198 rep.nBtnsRtrn= stuff->nBtns; 6199 act= &dev->button->xkb_acts[rep.firstBtnWanted]; 6200 for (i=0;i<rep.nBtnsRtrn;i++,act++) { 6201 if (act->type!=XkbSA_NoAction) 6202 break; 6203 } 6204 rep.firstBtnRtrn+= i; 6205 rep.nBtnsRtrn-= i; 6206 act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; 6207 for (i=0;i<rep.nBtnsRtrn;i++,act--) { 6208 if (act->type!=XkbSA_NoAction) 6209 break; 6210 } 6211 rep.nBtnsRtrn-= i; 6212 } 6213 rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; 6214 } 6215 } 6216 6217 if (wanted&XkbXI_IndicatorsMask) { 6218 status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); 6219 if (status!=Success) 6220 return status; 6221 } 6222 length= rep.length*4; 6223 nDeviceLedFBs = rep.nDeviceLedFBs; 6224 if (client->swapped) { 6225 register int n; 6226 swaps(&rep.sequenceNumber,n); 6227 swapl(&rep.length,n); 6228 swaps(&rep.present,n); 6229 swaps(&rep.supported,n); 6230 swaps(&rep.unsupported,n); 6231 swaps(&rep.nDeviceLedFBs,n); 6232 swapl(&rep.type,n); 6233 swaps(&rep.dfltKbdFB, n); 6234 swaps(&rep.dfltLedFB, n); 6235 swapl(&rep.devType, n); 6236 } 6237 WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); 6238 6239 str= malloc(nameLen); 6240 if (!str) 6241 return BadAlloc; 6242 XkbWriteCountedString(str,dev->name,client->swapped); 6243 WriteToClient(client,nameLen,str); 6244 free(str); 6245 length-= nameLen; 6246 6247 if (rep.nBtnsRtrn>0) { 6248 int sz; 6249 xkbActionWireDesc * awire; 6250 sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); 6251 awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; 6252 WriteToClient(client,sz,(char *)awire); 6253 length-= sz; 6254 } 6255 if (nDeviceLedFBs>0) { 6256 status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); 6257 if (status!=Success) 6258 return status; 6259 } 6260 else if (length!=0) { 6261 ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); 6262 ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length); 6263 return BadLength; 6264 } 6265 return Success; 6266} 6267 6268static char * 6269CheckSetDeviceIndicators( char * wire, 6270 DeviceIntPtr dev, 6271 int num, 6272 int * status_rtrn, 6273 ClientPtr client) 6274{ 6275xkbDeviceLedsWireDesc * ledWire; 6276int i; 6277XkbSrvLedInfoPtr sli; 6278 6279 ledWire= (xkbDeviceLedsWireDesc *)wire; 6280 for (i=0;i<num;i++) { 6281 if (client->swapped) { 6282 register int n; 6283 swaps(&ledWire->ledClass,n); 6284 swaps(&ledWire->ledID,n); 6285 swapl(&ledWire->namesPresent,n); 6286 swapl(&ledWire->mapsPresent,n); 6287 swapl(&ledWire->physIndicators,n); 6288 } 6289 6290 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 6291 XkbXI_IndicatorsMask); 6292 if (sli!=NULL) { 6293 register int n; 6294 register unsigned bit; 6295 int nMaps,nNames; 6296 CARD32 *atomWire; 6297 xkbIndicatorMapWireDesc *mapWire; 6298 6299 nMaps= nNames= 0; 6300 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6301 if (ledWire->namesPresent&bit) 6302 nNames++; 6303 if (ledWire->mapsPresent&bit) 6304 nMaps++; 6305 } 6306 atomWire= (CARD32 *)&ledWire[1]; 6307 if (nNames>0) { 6308 for (n=0;n<nNames;n++) { 6309 if (client->swapped) { 6310 register int t; 6311 swapl(atomWire,t); 6312 } 6313 CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, 6314 *status_rtrn,NULL); 6315 atomWire++; 6316 } 6317 } 6318 mapWire= (xkbIndicatorMapWireDesc *)atomWire; 6319 if (nMaps>0) { 6320 for (n=0;n<nMaps;n++) { 6321 if (client->swapped) { 6322 register int t; 6323 swaps(&mapWire->virtualMods,t); 6324 swapl(&mapWire->ctrls,t); 6325 } 6326 CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, 6327 XkbIM_UseAnyGroup, 6328 client->errorValue, 6329 *status_rtrn,NULL); 6330 CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, 6331 client->errorValue, 6332 *status_rtrn,NULL); 6333 mapWire++; 6334 } 6335 } 6336 ledWire= (xkbDeviceLedsWireDesc *)mapWire; 6337 } 6338 else { 6339 /* SHOULD NEVER HAPPEN */ 6340 return (char *)ledWire; 6341 } 6342 } 6343 return (char *)ledWire; 6344} 6345 6346static char * 6347SetDeviceIndicators( char * wire, 6348 DeviceIntPtr dev, 6349 unsigned changed, 6350 int num, 6351 int * status_rtrn, 6352 ClientPtr client, 6353 xkbExtensionDeviceNotify *ev) 6354{ 6355xkbDeviceLedsWireDesc * ledWire; 6356int i; 6357XkbEventCauseRec cause; 6358unsigned namec,mapc,statec; 6359xkbExtensionDeviceNotify ed; 6360XkbChangesRec changes; 6361DeviceIntPtr kbd; 6362 6363 memset((char *)&ed, 0, sizeof(xkbExtensionDeviceNotify)); 6364 memset((char *)&changes, 0, sizeof(XkbChangesRec)); 6365 XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); 6366 ledWire= (xkbDeviceLedsWireDesc *)wire; 6367 for (i=0;i<num;i++) { 6368 register int n; 6369 register unsigned bit; 6370 CARD32 * atomWire; 6371 xkbIndicatorMapWireDesc * mapWire; 6372 XkbSrvLedInfoPtr sli; 6373 6374 namec= mapc= statec= 0; 6375 sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, 6376 XkbXI_IndicatorMapsMask); 6377 if (!sli) { 6378 /* SHOULD NEVER HAPPEN!! */ 6379 return (char *)ledWire; 6380 } 6381 6382 atomWire= (CARD32 *)&ledWire[1]; 6383 if (changed&XkbXI_IndicatorNamesMask) { 6384 namec= sli->namesPresent|ledWire->namesPresent; 6385 memset((char *)sli->names, 0, XkbNumIndicators*sizeof(Atom)); 6386 } 6387 if (ledWire->namesPresent) { 6388 sli->namesPresent= ledWire->namesPresent; 6389 memset((char *)sli->names, 0, XkbNumIndicators*sizeof(Atom)); 6390 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6391 if (ledWire->namesPresent&bit) { 6392 sli->names[n]= (Atom)*atomWire; 6393 if (sli->names[n]==None) 6394 ledWire->namesPresent&= ~bit; 6395 atomWire++; 6396 } 6397 } 6398 } 6399 mapWire= (xkbIndicatorMapWireDesc *)atomWire; 6400 if (changed&XkbXI_IndicatorMapsMask) { 6401 mapc= sli->mapsPresent|ledWire->mapsPresent; 6402 sli->mapsPresent= ledWire->mapsPresent; 6403 memset((char*)sli->maps, 0, XkbNumIndicators*sizeof(XkbIndicatorMapRec)); 6404 } 6405 if (ledWire->mapsPresent) { 6406 for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { 6407 if (ledWire->mapsPresent&bit) { 6408 sli->maps[n].flags= mapWire->flags; 6409 sli->maps[n].which_groups= mapWire->whichGroups; 6410 sli->maps[n].groups= mapWire->groups; 6411 sli->maps[n].which_mods= mapWire->whichMods; 6412 sli->maps[n].mods.mask= mapWire->mods; 6413 sli->maps[n].mods.real_mods=mapWire->realMods; 6414 sli->maps[n].mods.vmods= mapWire->virtualMods; 6415 sli->maps[n].ctrls= mapWire->ctrls; 6416 mapWire++; 6417 } 6418 } 6419 } 6420 if (changed&XkbXI_IndicatorStateMask) { 6421 statec= sli->effectiveState^ledWire->state; 6422 sli->explicitState&= ~statec; 6423 sli->explicitState|= (ledWire->state&statec); 6424 } 6425 if (namec) 6426 XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); 6427 if (mapc) 6428 XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); 6429 if (statec) 6430 XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); 6431 6432 kbd= dev; 6433 if ((sli->flags&XkbSLI_HasOwnState)==0) 6434 kbd = inputInfo.keyboard; 6435 6436 XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); 6437 ledWire= (xkbDeviceLedsWireDesc *)mapWire; 6438 } 6439 return (char *)ledWire; 6440} 6441 6442 6443static int 6444_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, 6445 xkbSetDeviceInfoReq *stuff) 6446{ 6447 char *wire; 6448 6449 wire= (char *)&stuff[1]; 6450 if (stuff->change&XkbXI_ButtonActionsMask) { 6451 if (!dev->button) { 6452 client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); 6453 return XkbKeyboardErrorCode; 6454 } 6455 if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { 6456 client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, 6457 dev->button->numButtons); 6458 return BadMatch; 6459 } 6460 wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); 6461 } 6462 if (stuff->change&XkbXI_IndicatorsMask) { 6463 int status= Success; 6464 wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, 6465 &status,client); 6466 if (status!=Success) 6467 return status; 6468 } 6469 if (((wire-((char *)stuff))/4)!=stuff->length) 6470 return BadLength; 6471 6472 return Success; 6473} 6474 6475static int 6476_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, 6477 xkbSetDeviceInfoReq *stuff) 6478{ 6479 char *wire; 6480 xkbExtensionDeviceNotify ed; 6481 6482 memset((char *)&ed, 0, SIZEOF(xkbExtensionDeviceNotify)); 6483 ed.deviceID= dev->id; 6484 wire= (char *)&stuff[1]; 6485 if (stuff->change&XkbXI_ButtonActionsMask) { 6486 int nBtns,sz,i; 6487 XkbAction * acts; 6488 DeviceIntPtr kbd; 6489 6490 nBtns= dev->button->numButtons; 6491 acts= dev->button->xkb_acts; 6492 if (acts==NULL) { 6493 acts= calloc(nBtns, sizeof(XkbAction)); 6494 if (!acts) 6495 return BadAlloc; 6496 dev->button->xkb_acts= acts; 6497 } 6498 sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); 6499 memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); 6500 wire+= sz; 6501 ed.reason|= XkbXI_ButtonActionsMask; 6502 ed.firstBtn= stuff->firstBtn; 6503 ed.nBtns= stuff->nBtns; 6504 6505 if (dev->key) kbd= dev; 6506 else kbd= inputInfo.keyboard; 6507 acts= &dev->button->xkb_acts[stuff->firstBtn]; 6508 for (i=0;i<stuff->nBtns;i++,acts++) { 6509 if (acts->type!=XkbSA_NoAction) 6510 XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); 6511 } 6512 } 6513 if (stuff->change&XkbXI_IndicatorsMask) { 6514 int status= Success; 6515 wire= SetDeviceIndicators(wire,dev,stuff->change, 6516 stuff->nDeviceLedFBs, &status,client,&ed); 6517 if (status!=Success) 6518 return status; 6519 } 6520 if ((stuff->change)&&(ed.reason)) 6521 XkbSendExtensionDeviceNotify(dev,client,&ed); 6522 return Success; 6523} 6524 6525int 6526ProcXkbSetDeviceInfo(ClientPtr client) 6527{ 6528 DeviceIntPtr dev; 6529 int rc; 6530 6531 REQUEST(xkbSetDeviceInfoReq); 6532 REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); 6533 6534 if (!(client->xkbClientFlags&_XkbClientInitialized)) 6535 return BadAccess; 6536 6537 CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); 6538 CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask); 6539 6540 rc = _XkbSetDeviceInfoCheck(client, dev, stuff); 6541 6542 if (rc != Success) 6543 return rc; 6544 6545 if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 6546 { 6547 DeviceIntPtr other; 6548 for (other = inputInfo.devices; other; other = other->next) 6549 { 6550 if (((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) && 6551 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6552 (stuff->deviceSpec == XkbUseCorePtr && other->button))) 6553 { 6554 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 6555 if (rc == Success) 6556 { 6557 rc = _XkbSetDeviceInfoCheck(client, other, stuff); 6558 if (rc != Success) 6559 return rc; 6560 } 6561 } 6562 } 6563 } 6564 6565 /* checks done, apply */ 6566 rc = _XkbSetDeviceInfo(client, dev, stuff); 6567 if (rc != Success) 6568 return rc; 6569 6570 if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) 6571 { 6572 DeviceIntPtr other; 6573 for (other = inputInfo.devices; other; other = other->next) 6574 { 6575 if (((other != dev) && !IsMaster(other) && GetMaster(other, MASTER_KEYBOARD) == dev) && 6576 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || 6577 (stuff->deviceSpec == XkbUseCorePtr && other->button))) 6578 { 6579 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); 6580 if (rc == Success) 6581 { 6582 rc = _XkbSetDeviceInfo(client, other, stuff); 6583 if (rc != Success) 6584 return rc; 6585 } 6586 } 6587 } 6588 } 6589 6590 return Success; 6591} 6592 6593/***====================================================================***/ 6594 6595int 6596ProcXkbSetDebuggingFlags(ClientPtr client) 6597{ 6598CARD32 newFlags,newCtrls,extraLength; 6599xkbSetDebuggingFlagsReply rep; 6600int rc; 6601 6602 REQUEST(xkbSetDebuggingFlagsReq); 6603 REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); 6604 6605 rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); 6606 if (rc != Success) 6607 return rc; 6608 6609 newFlags= xkbDebugFlags&(~stuff->affectFlags); 6610 newFlags|= (stuff->flags&stuff->affectFlags); 6611 newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); 6612 newCtrls|= (stuff->ctrls&stuff->affectCtrls); 6613 if (xkbDebugFlags || newFlags || stuff->msgLength) { 6614 ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); 6615 if (newCtrls!=xkbDebugCtrls) 6616 ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); 6617 } 6618 extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; 6619 if (stuff->msgLength>0) { 6620 char *msg; 6621 if (extraLength<XkbPaddedSize(stuff->msgLength)) { 6622 ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", 6623 stuff->msgLength,(long)extraLength, 6624 XkbPaddedSize(stuff->msgLength)); 6625 return BadLength; 6626 } 6627 msg= (char *)&stuff[1]; 6628 if (msg[stuff->msgLength-1]!='\0') { 6629 ErrorF("[xkb] XkbDebug: message not null-terminated\n"); 6630 return BadValue; 6631 } 6632 ErrorF("[xkb] XkbDebug: %s\n",msg); 6633 } 6634 xkbDebugFlags = newFlags; 6635 xkbDebugCtrls = newCtrls; 6636 6637 rep.type= X_Reply; 6638 rep.length = 0; 6639 rep.sequenceNumber = client->sequence; 6640 rep.currentFlags = newFlags; 6641 rep.currentCtrls = newCtrls; 6642 rep.supportedFlags = ~0; 6643 rep.supportedCtrls = ~0; 6644 if ( client->swapped ) { 6645 register int n; 6646 swaps(&rep.sequenceNumber, n); 6647 swapl(&rep.currentFlags, n); 6648 swapl(&rep.currentCtrls, n); 6649 swapl(&rep.supportedFlags, n); 6650 swapl(&rep.supportedCtrls, n); 6651 } 6652 WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); 6653 return Success; 6654} 6655 6656/***====================================================================***/ 6657 6658static int 6659ProcXkbDispatch (ClientPtr client) 6660{ 6661 REQUEST(xReq); 6662 switch (stuff->data) 6663 { 6664 case X_kbUseExtension: 6665 return ProcXkbUseExtension(client); 6666 case X_kbSelectEvents: 6667 return ProcXkbSelectEvents(client); 6668 case X_kbBell: 6669 return ProcXkbBell(client); 6670 case X_kbGetState: 6671 return ProcXkbGetState(client); 6672 case X_kbLatchLockState: 6673 return ProcXkbLatchLockState(client); 6674 case X_kbGetControls: 6675 return ProcXkbGetControls(client); 6676 case X_kbSetControls: 6677 return ProcXkbSetControls(client); 6678 case X_kbGetMap: 6679 return ProcXkbGetMap(client); 6680 case X_kbSetMap: 6681 return ProcXkbSetMap(client); 6682 case X_kbGetCompatMap: 6683 return ProcXkbGetCompatMap(client); 6684 case X_kbSetCompatMap: 6685 return ProcXkbSetCompatMap(client); 6686 case X_kbGetIndicatorState: 6687 return ProcXkbGetIndicatorState(client); 6688 case X_kbGetIndicatorMap: 6689 return ProcXkbGetIndicatorMap(client); 6690 case X_kbSetIndicatorMap: 6691 return ProcXkbSetIndicatorMap(client); 6692 case X_kbGetNamedIndicator: 6693 return ProcXkbGetNamedIndicator(client); 6694 case X_kbSetNamedIndicator: 6695 return ProcXkbSetNamedIndicator(client); 6696 case X_kbGetNames: 6697 return ProcXkbGetNames(client); 6698 case X_kbSetNames: 6699 return ProcXkbSetNames(client); 6700 case X_kbGetGeometry: 6701 return ProcXkbGetGeometry(client); 6702 case X_kbSetGeometry: 6703 return ProcXkbSetGeometry(client); 6704 case X_kbPerClientFlags: 6705 return ProcXkbPerClientFlags(client); 6706 case X_kbListComponents: 6707 return ProcXkbListComponents(client); 6708 case X_kbGetKbdByName: 6709 return ProcXkbGetKbdByName(client); 6710 case X_kbGetDeviceInfo: 6711 return ProcXkbGetDeviceInfo(client); 6712 case X_kbSetDeviceInfo: 6713 return ProcXkbSetDeviceInfo(client); 6714 case X_kbSetDebuggingFlags: 6715 return ProcXkbSetDebuggingFlags(client); 6716 default: 6717 return BadRequest; 6718 } 6719} 6720 6721static int 6722XkbClientGone(pointer data,XID id) 6723{ 6724 DevicePtr pXDev = (DevicePtr)data; 6725 6726 if (!XkbRemoveResourceClient(pXDev,id)) { 6727 ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); 6728 } 6729 return 1; 6730} 6731 6732void 6733XkbExtensionInit(void) 6734{ 6735 ExtensionEntry *extEntry; 6736 6737 RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); 6738 if (!RT_XKBCLIENT) 6739 return; 6740 6741 if (!XkbInitPrivates()) 6742 return; 6743 6744 if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, 6745 ProcXkbDispatch, SProcXkbDispatch, 6746 NULL, StandardMinorOpcode))) { 6747 XkbReqCode = (unsigned char)extEntry->base; 6748 XkbEventBase = (unsigned char)extEntry->eventBase; 6749 XkbErrorBase = (unsigned char)extEntry->errorBase; 6750 XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; 6751 } 6752 return; 6753} 6754 6755 6756