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