XKB.c revision e9fcaa8a
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_CONFIG_H 28#include <config.h> 29#endif 30#include <stdio.h> 31#include "Xlibint.h" 32#include <X11/extensions/XKBproto.h> 33#include "XKBlibint.h" 34 35XkbInternAtomFunc _XkbInternAtomFunc= XInternAtom; 36XkbGetAtomNameFunc _XkbGetAtomNameFunc= XGetAtomName; 37 38Bool 39XkbQueryExtension( Display *dpy, 40 int * opcodeReturn, 41 int * eventBaseReturn, 42 int * errorBaseReturn, 43 int * majorReturn, 44 int * minorReturn) 45{ 46 if (!XkbUseExtension(dpy,majorReturn,minorReturn)) 47 return False; 48 if (opcodeReturn) 49 *opcodeReturn = dpy->xkb_info->codes->major_opcode; 50 if (eventBaseReturn) 51 *eventBaseReturn = dpy->xkb_info->codes->first_event; 52 if (errorBaseReturn) 53 *errorBaseReturn = dpy->xkb_info->codes->first_error; 54 if (majorReturn) 55 *majorReturn = dpy->xkb_info->srv_major; 56 if (minorReturn) 57 *minorReturn = dpy->xkb_info->srv_minor; 58 return True; 59} 60 61Bool 62XkbLibraryVersion(int *libMajorRtrn,int *libMinorRtrn) 63{ 64int supported; 65 66 if (*libMajorRtrn != XkbMajorVersion) { 67 /* version 0.65 is (almost) compatible with 1.00 */ 68 if ((XkbMajorVersion==1)&&(((*libMajorRtrn)==0)&&((*libMinorRtrn)==65))) 69 supported= True; 70 else supported= False; 71 } 72 else { 73 supported = True; 74 } 75 76 *libMajorRtrn = XkbMajorVersion; 77 *libMinorRtrn = XkbMinorVersion; 78 return supported; 79} 80 81Bool 82XkbSelectEvents( Display * dpy, 83 unsigned int deviceSpec, 84 unsigned int affect, 85 unsigned int selectAll) 86{ 87 register xkbSelectEventsReq *req; 88 XkbInfoPtr xkbi; 89 90 if ((dpy->flags & XlibDisplayNoXkb) || 91 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 92 return False; 93 LockDisplay(dpy); 94 xkbi = dpy->xkb_info; 95 xkbi->selected_events&= ~affect; 96 xkbi->selected_events|= (affect&selectAll); 97 GetReq(kbSelectEvents, req); 98 req->reqType = xkbi->codes->major_opcode; 99 req->xkbReqType = X_kbSelectEvents; 100 req->deviceSpec = deviceSpec; 101 req->affectWhich = (CARD16)affect; 102 req->clear = affect&(~selectAll); 103 req->selectAll = affect&selectAll; 104 if (affect&XkbMapNotifyMask) { 105 req->affectMap= XkbAllMapComponentsMask; 106 /* the implicit support needs the client info */ 107 /* even if the client itself doesn't want it */ 108 if (selectAll&XkbMapNotifyMask) 109 req->map= XkbAllMapEventsMask; 110 else req->map= XkbAllClientInfoMask; 111 if (selectAll&XkbMapNotifyMask) 112 xkbi->selected_map_details= XkbAllMapEventsMask; 113 else xkbi->selected_map_details= 0; 114 } 115 if (affect&XkbNewKeyboardNotifyMask) { 116 if (selectAll&XkbNewKeyboardNotifyMask) 117 xkbi->selected_nkn_details= XkbAllNewKeyboardEventsMask; 118 else xkbi->selected_nkn_details= 0; 119 if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) { 120 /* we want it, even if the client doesn't. Don't mess */ 121 /* around with details -- ask for all of them and throw */ 122 /* away the ones we don't need */ 123 req->selectAll|= XkbNewKeyboardNotifyMask; 124 } 125 } 126 UnlockDisplay(dpy); 127 SyncHandle(); 128 return True; 129} 130 131Bool 132XkbSelectEventDetails( Display * dpy, 133 unsigned deviceSpec, 134 unsigned eventType, 135 unsigned long int affect, 136 unsigned long int details) 137{ 138 register xkbSelectEventsReq *req; 139 XkbInfoPtr xkbi; 140 int size = 0; 141 char *out; 142 union { 143 CARD8 *c8; 144 CARD16 *c16; 145 CARD32 *c32; 146 } u; 147 148 if ((dpy->flags & XlibDisplayNoXkb) || 149 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 150 return False; 151 LockDisplay(dpy); 152 xkbi = dpy->xkb_info; 153 if (affect&details) xkbi->selected_events|= (1<<eventType); 154 else xkbi->selected_events&= ~(1<<eventType); 155 GetReq(kbSelectEvents, req); 156 req->reqType = xkbi->codes->major_opcode; 157 req->xkbReqType = X_kbSelectEvents; 158 req->deviceSpec = deviceSpec; 159 req->clear= req->selectAll= 0; 160 if (eventType==XkbMapNotify) { 161 /* we need all of the client info, even if the application */ 162 /* doesn't. Make sure that we always request the stuff */ 163 /* that the implicit support needs, and just filter out anything */ 164 /* the client doesn't want later */ 165 req->affectWhich = 0; 166 req->selectAll = 0; 167 req->clear = 0; 168 req->affectMap = (CARD16)affect; 169 req->map = (CARD16)details|(XkbAllClientInfoMask&affect); 170 req->affectWhich = XkbMapNotifyMask; 171 xkbi->selected_map_details&= ~affect; 172 xkbi->selected_map_details|= (details&affect); 173 } 174 else { 175 req->affectMap = req->map = 0; 176 req->affectWhich= (1<<eventType); 177 switch (eventType) { 178 case XkbNewKeyboardNotify: 179 xkbi->selected_nkn_details&= ~affect; 180 xkbi->selected_nkn_details|= (details&affect); 181 if (!(xkbi->xlib_ctrls&XkbLC_IgnoreNewKeyboards)) 182 details= (affect&XkbAllNewKeyboardEventsMask); 183 case XkbStateNotify: 184 case XkbNamesNotify: 185 case XkbAccessXNotify: 186 case XkbExtensionDeviceNotify: 187 size= 2; 188 req->length+= 1; 189 break; 190 case XkbControlsNotify: 191 case XkbIndicatorStateNotify: 192 case XkbIndicatorMapNotify: 193 size= 4; 194 req->length+= 2; 195 break; 196 case XkbBellNotify: 197 case XkbActionMessage: 198 case XkbCompatMapNotify: 199 size= 1; 200 req->length+= 1; 201 break; 202 } 203 BufAlloc(char *,out,(((size*2)+(unsigned)3)/4)*4); 204 u.c8= (CARD8 *)out; 205 if (size==2) { 206 u.c16[0]= (CARD16)affect; 207 u.c16[1]= (CARD16)details; 208 } 209 else if (size==4) { 210 u.c32[0]= (CARD32)affect; 211 u.c32[1]= (CARD32)details; 212 } 213 else { 214 u.c8[0]= (CARD8)affect; 215 u.c8[1]= (CARD8)details; 216 } 217 } 218 UnlockDisplay(dpy); 219 SyncHandle(); 220 return True; 221} 222 223Bool 224XkbLockModifiers( Display * dpy, 225 unsigned int deviceSpec, 226 unsigned int affect, 227 unsigned int values) 228{ 229 register xkbLatchLockStateReq *req; 230 XkbInfoPtr xkbi; 231 232 if ((dpy->flags & XlibDisplayNoXkb) || 233 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 234 return False; 235 LockDisplay(dpy); 236 xkbi = dpy->xkb_info; 237 GetReq(kbLatchLockState, req); 238 req->reqType = xkbi->codes->major_opcode; 239 req->xkbReqType = X_kbLatchLockState; 240 req->deviceSpec = deviceSpec; 241 req->affectModLocks= affect; 242 req->modLocks = values; 243 req->lockGroup = False; 244 req->groupLock = 0; 245 246 req->affectModLatches = req->modLatches = 0; 247 req->latchGroup = False; 248 req->groupLatch = 0; 249 UnlockDisplay(dpy); 250 SyncHandle(); 251 return True; 252} 253 254Bool 255XkbLatchModifiers( Display * dpy, 256 unsigned int deviceSpec, 257 unsigned int affect, 258 unsigned int values) 259{ 260 register xkbLatchLockStateReq *req; 261 XkbInfoPtr xkbi; 262 263 if ((dpy->flags & XlibDisplayNoXkb) || 264 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 265 return False; 266 LockDisplay(dpy); 267 xkbi = dpy->xkb_info; 268 GetReq(kbLatchLockState, req); 269 req->reqType = xkbi->codes->major_opcode; 270 req->xkbReqType = X_kbLatchLockState; 271 req->deviceSpec = deviceSpec; 272 273 req->affectModLatches= affect; 274 req->modLatches = values; 275 req->latchGroup = False; 276 req->groupLatch = 0; 277 278 req->affectModLocks = req->modLocks = 0; 279 req->lockGroup = False; 280 req->groupLock = 0; 281 282 UnlockDisplay(dpy); 283 SyncHandle(); 284 return True; 285} 286 287Bool 288XkbLockGroup(Display *dpy,unsigned int deviceSpec,unsigned int group) 289{ 290 register xkbLatchLockStateReq *req; 291 XkbInfoPtr xkbi; 292 293 if ((dpy->flags & XlibDisplayNoXkb) || 294 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 295 return False; 296 LockDisplay(dpy); 297 xkbi = dpy->xkb_info; 298 GetReq(kbLatchLockState, req); 299 req->reqType = xkbi->codes->major_opcode; 300 req->xkbReqType = X_kbLatchLockState; 301 req->deviceSpec = deviceSpec; 302 req->affectModLocks= 0; 303 req->modLocks = 0; 304 req->lockGroup = True; 305 req->groupLock = group; 306 307 req->affectModLatches = req->modLatches = 0; 308 req->latchGroup = False; 309 req->groupLatch = 0; 310 UnlockDisplay(dpy); 311 SyncHandle(); 312 return True; 313} 314 315Bool 316XkbLatchGroup(Display *dpy,unsigned int deviceSpec,unsigned int group) 317{ 318 register xkbLatchLockStateReq *req; 319 XkbInfoPtr xkbi; 320 321 if ((dpy->flags & XlibDisplayNoXkb) || 322 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 323 return False; 324 LockDisplay(dpy); 325 xkbi = dpy->xkb_info; 326 GetReq(kbLatchLockState, req); 327 req->reqType = xkbi->codes->major_opcode; 328 req->xkbReqType = X_kbLatchLockState; 329 req->deviceSpec = deviceSpec; 330 331 req->affectModLatches= 0; 332 req->modLatches = 0; 333 req->latchGroup = True; 334 req->groupLatch = group; 335 336 req->affectModLocks = req->modLocks = 0; 337 req->lockGroup = False; 338 req->groupLock = 0; 339 340 UnlockDisplay(dpy); 341 SyncHandle(); 342 return True; 343} 344 345unsigned 346XkbSetXlibControls(Display *dpy,unsigned affect,unsigned values) 347{ 348 if (!dpy->xkb_info) 349 XkbUseExtension(dpy,NULL,NULL); 350 if (!dpy->xkb_info) 351 return 0; 352 affect&= XkbLC_AllControls; 353 dpy->xkb_info->xlib_ctrls&= ~affect; 354 dpy->xkb_info->xlib_ctrls|= (affect&values); 355 return dpy->xkb_info->xlib_ctrls; 356} 357 358unsigned 359XkbGetXlibControls(Display *dpy) 360{ 361 if (!dpy->xkb_info) 362 XkbUseExtension(dpy,NULL,NULL); 363 if (!dpy->xkb_info) 364 return 0; 365 return dpy->xkb_info->xlib_ctrls; 366} 367 368unsigned int 369XkbXlibControlsImplemented(void) 370{ 371#ifdef __sgi 372 return XkbLC_AllControls; 373#else 374 return XkbLC_AllControls&~XkbLC_AllComposeControls; 375#endif 376} 377 378Bool 379XkbSetDebuggingFlags( Display * dpy, 380 unsigned int mask, 381 unsigned int flags, 382 char * msg, 383 unsigned int ctrls_mask, 384 unsigned int ctrls, 385 unsigned int * rtrn_flags, 386 unsigned int * rtrn_ctrls) 387{ 388 register xkbSetDebuggingFlagsReq *req; 389 xkbSetDebuggingFlagsReply rep; 390 XkbInfoPtr xkbi; 391 392 if ((dpy->flags & XlibDisplayNoXkb) || 393 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 394 return False; 395 LockDisplay(dpy); 396 xkbi = dpy->xkb_info; 397 GetReq(kbSetDebuggingFlags, req); 398 req->reqType= xkbi->codes->major_opcode; 399 req->xkbReqType= X_kbSetDebuggingFlags; 400 req->affectFlags= mask; 401 req->flags= flags; 402 req->affectCtrls= ctrls_mask; 403 req->ctrls= ctrls; 404 405 if (msg) { 406 char *out; 407 req->msgLength= (unsigned short)strlen(msg)+1; 408 req->length+= (req->msgLength+(unsigned)3)>>2; 409 BufAlloc(char *,out,((req->msgLength+(unsigned)3)/4)*4); 410 memcpy(out,msg,req->msgLength); 411 } 412 else req->msgLength= 0; 413 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 414 UnlockDisplay(dpy); 415 SyncHandle(); 416 return False; 417 } 418 if (rtrn_flags) 419 *rtrn_flags= rep.currentFlags; 420 if (rtrn_ctrls) 421 *rtrn_ctrls= rep.currentCtrls; 422 UnlockDisplay(dpy); 423 SyncHandle(); 424 return True; 425} 426 427Bool 428XkbComputeEffectiveMap( XkbDescPtr xkb, 429 XkbKeyTypePtr type, 430 unsigned char * map_rtrn) 431{ 432register int i; 433unsigned tmp; 434XkbKTMapEntryPtr entry = NULL; 435 436 if ((!xkb)||(!type)||(!xkb->server)) 437 return False; 438 439 if (type->mods.vmods!=0) { 440 if (!XkbVirtualModsToReal(xkb,type->mods.vmods,&tmp)) 441 return False; 442 443 type->mods.mask= tmp|type->mods.real_mods; 444 entry= type->map; 445 for (i=0;i<type->map_count;i++,entry++) { 446 tmp= 0; 447 if (entry->mods.vmods!=0) { 448 if (!XkbVirtualModsToReal(xkb,entry->mods.vmods,&tmp)) 449 return False; 450 if (tmp==0) { 451 entry->active= False; 452 continue; 453 } 454 } 455 entry->active= True; 456 entry->mods.mask= (entry->mods.real_mods|tmp)&type->mods.mask; 457 } 458 } 459 else { 460 type->mods.mask= type->mods.real_mods; 461 } 462 if (map_rtrn!=NULL) { 463 bzero(map_rtrn,type->mods.mask+1); 464 for (i=0;i<type->map_count;i++) { 465 if (entry->active) { 466 map_rtrn[type->map[i].mods.mask]= type->map[i].level; 467 } 468 } 469 } 470 return True; 471} 472 473Status 474XkbGetState(Display *dpy,unsigned deviceSpec,XkbStatePtr rtrn) 475{ 476 register xkbGetStateReq *req; 477 xkbGetStateReply rep; 478 XkbInfoPtr xkbi; 479 480 if ((dpy->flags & XlibDisplayNoXkb) || 481 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 482 return BadAccess; 483 LockDisplay(dpy); 484 xkbi = dpy->xkb_info; 485 GetReq(kbGetState, req); 486 req->reqType = xkbi->codes->major_opcode; 487 req->xkbReqType = X_kbGetState; 488 req->deviceSpec = deviceSpec; 489 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 490 UnlockDisplay(dpy); 491 SyncHandle(); 492 return BadImplementation; 493 } 494 rtrn->mods= rep.mods; 495 rtrn->base_mods= rep.baseMods; 496 rtrn->latched_mods= rep.latchedMods; 497 rtrn->locked_mods= rep.lockedMods; 498 rtrn->group= rep.group; 499 rtrn->base_group= rep.baseGroup; 500 rtrn->latched_group= rep.latchedGroup; 501 rtrn->locked_group= rep.lockedGroup; 502 rtrn->compat_state= rep.compatState; 503 rtrn->grab_mods= rep.grabMods; 504 rtrn->compat_grab_mods= rep.compatGrabMods; 505 rtrn->lookup_mods= rep.lookupMods; 506 rtrn->compat_lookup_mods= rep.compatLookupMods; 507 rtrn->ptr_buttons= rep.ptrBtnState; 508 UnlockDisplay(dpy); 509 SyncHandle(); 510 return Success; 511} 512 513Bool 514XkbSetDetectableAutoRepeat(Display *dpy,Bool detectable,Bool *supported) 515{ 516register xkbPerClientFlagsReq * req; 517xkbPerClientFlagsReply rep; 518XkbInfoPtr xkbi; 519 520 if ((dpy->flags & XlibDisplayNoXkb) || 521 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 522 return False; 523 LockDisplay(dpy); 524 xkbi = dpy->xkb_info; 525 GetReq(kbPerClientFlags, req); 526 req->reqType = xkbi->codes->major_opcode; 527 req->xkbReqType = X_kbPerClientFlags; 528 req->deviceSpec = XkbUseCoreKbd; 529 req->change = XkbPCF_DetectableAutoRepeatMask; 530 if (detectable) 531 req->value = XkbPCF_DetectableAutoRepeatMask; 532 else req->value = 0; 533 req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; 534 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 535 UnlockDisplay(dpy); 536 SyncHandle(); 537 return False; 538 } 539 UnlockDisplay(dpy); 540 SyncHandle(); 541 if (supported!=NULL) 542 *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0); 543 return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0); 544} 545 546Bool 547XkbGetDetectableAutoRepeat(Display *dpy,Bool *supported) 548{ 549register xkbPerClientFlagsReq * req; 550xkbPerClientFlagsReply rep; 551XkbInfoPtr xkbi; 552 553 if ((dpy->flags & XlibDisplayNoXkb) || 554 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 555 return False; 556 LockDisplay(dpy); 557 xkbi = dpy->xkb_info; 558 GetReq(kbPerClientFlags, req); 559 req->reqType = xkbi->codes->major_opcode; 560 req->xkbReqType = X_kbPerClientFlags; 561 req->deviceSpec = XkbUseCoreKbd; 562 req->change = 0; 563 req->value = 0; 564 req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; 565 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 566 UnlockDisplay(dpy); 567 SyncHandle(); 568 return False; 569 } 570 UnlockDisplay(dpy); 571 SyncHandle(); 572 if (supported!=NULL) 573 *supported= ((rep.supported&XkbPCF_DetectableAutoRepeatMask)!=0); 574 return ((rep.value&XkbPCF_DetectableAutoRepeatMask)!=0); 575} 576 577Bool 578XkbSetAutoResetControls( Display * dpy, 579 unsigned changes, 580 unsigned * auto_ctrls, 581 unsigned * auto_values) 582{ 583register xkbPerClientFlagsReq * req; 584xkbPerClientFlagsReply rep; 585XkbInfoPtr xkbi; 586 587 if ((dpy->flags & XlibDisplayNoXkb) || 588 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 589 return False; 590 LockDisplay(dpy); 591 xkbi = dpy->xkb_info; 592 GetReq(kbPerClientFlags, req); 593 req->reqType = xkbi->codes->major_opcode; 594 req->xkbReqType = X_kbPerClientFlags; 595 req->change = XkbPCF_AutoResetControlsMask; 596 req->deviceSpec = XkbUseCoreKbd; 597 req->value = XkbPCF_AutoResetControlsMask; 598 req->ctrlsToChange= changes; 599 req->autoCtrls= *auto_ctrls; 600 req->autoCtrlValues= *auto_values; 601 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 602 UnlockDisplay(dpy); 603 SyncHandle(); 604 return False; 605 } 606 UnlockDisplay(dpy); 607 SyncHandle(); 608 *auto_ctrls= rep.autoCtrls; 609 *auto_values= rep.autoCtrlValues; 610 return ((rep.value&XkbPCF_AutoResetControlsMask)!=0); 611} 612 613Bool 614XkbGetAutoResetControls( Display * dpy, 615 unsigned * auto_ctrls, 616 unsigned * auto_ctrl_values) 617{ 618register xkbPerClientFlagsReq * req; 619xkbPerClientFlagsReply rep; 620XkbInfoPtr xkbi; 621 622 if ((dpy->flags & XlibDisplayNoXkb) || 623 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 624 return False; 625 LockDisplay(dpy); 626 xkbi = dpy->xkb_info; 627 GetReq(kbPerClientFlags, req); 628 req->reqType = xkbi->codes->major_opcode; 629 req->xkbReqType = X_kbPerClientFlags; 630 req->deviceSpec = XkbUseCoreKbd; 631 req->change = 0; 632 req->value = 0; 633 req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; 634 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 635 UnlockDisplay(dpy); 636 SyncHandle(); 637 return False; 638 } 639 UnlockDisplay(dpy); 640 SyncHandle(); 641 if (auto_ctrls) 642 *auto_ctrls= rep.autoCtrls; 643 if (auto_ctrl_values) 644 *auto_ctrl_values= rep.autoCtrlValues; 645 return ((rep.value&XkbPCF_AutoResetControlsMask)!=0); 646} 647 648Bool 649XkbSetPerClientControls( Display * dpy, 650 unsigned change, 651 unsigned * values) 652{ 653register xkbPerClientFlagsReq * req; 654xkbPerClientFlagsReply rep; 655XkbInfoPtr xkbi; 656unsigned value_hold = *values; 657 658 if ((dpy->flags & XlibDisplayNoXkb) || 659 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || 660 (change & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState))) 661 return False; 662 LockDisplay(dpy); 663 xkbi = dpy->xkb_info; 664 GetReq(kbPerClientFlags, req); 665 req->reqType = xkbi->codes->major_opcode; 666 req->xkbReqType = X_kbPerClientFlags; 667 req->change = change; 668 req->deviceSpec = XkbUseCoreKbd; 669 req->value = *values; 670 req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues= 0; 671 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 672 UnlockDisplay(dpy); 673 SyncHandle(); 674 return False; 675 } 676 UnlockDisplay(dpy); 677 SyncHandle(); 678 *values = rep.value; 679 return ((rep.value&value_hold)!=0); 680} 681 682Bool 683XkbGetPerClientControls( Display * dpy, 684 unsigned * ctrls) 685{ 686register xkbPerClientFlagsReq * req; 687xkbPerClientFlagsReply rep; 688XkbInfoPtr xkbi; 689 690 if ((dpy->flags & XlibDisplayNoXkb) || 691 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) || 692 (*ctrls & ~(XkbPCF_GrabsUseXKBStateMask|XkbPCF_LookupStateWhenGrabbed|XkbPCF_SendEventUsesXKBState))) 693 return False; 694 LockDisplay(dpy); 695 xkbi = dpy->xkb_info; 696 GetReq(kbPerClientFlags, req); 697 req->reqType = xkbi->codes->major_opcode; 698 req->xkbReqType = X_kbPerClientFlags; 699 req->deviceSpec = XkbUseCoreKbd; 700 req->change = 0; 701 req->value = 0; 702 req->ctrlsToChange = req->autoCtrls= req->autoCtrlValues= 0; 703 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 704 UnlockDisplay(dpy); 705 SyncHandle(); 706 return False; 707 } 708 UnlockDisplay(dpy); 709 SyncHandle(); 710 if (ctrls) 711 *ctrls= (rep.value & (XkbPCF_GrabsUseXKBStateMask | 712 XkbPCF_LookupStateWhenGrabbed | 713 XkbPCF_SendEventUsesXKBState)); 714 return (True); 715} 716 717Display * 718XkbOpenDisplay( char * name, 719 int * ev_rtrn, 720 int * err_rtrn, 721 int * major_rtrn, 722 int * minor_rtrn, 723 int * reason) 724{ 725 Display* dpy; 726 int major_num,minor_num; 727 728 if ((major_rtrn!=NULL) && (minor_rtrn!=NULL)) { 729 if (!XkbLibraryVersion(major_rtrn,minor_rtrn)) { 730 if (reason!=NULL) 731 *reason= XkbOD_BadLibraryVersion; 732 return NULL; 733 } 734 } 735 else { 736 major_num= XkbMajorVersion; 737 minor_num= XkbMinorVersion; 738 major_rtrn= &major_num; 739 minor_rtrn= &minor_num; 740 } 741 dpy= XOpenDisplay(name); 742 if (dpy==NULL) { 743 if (reason!=NULL) 744 *reason= XkbOD_ConnectionRefused; 745 return NULL; 746 } 747 if (!XkbQueryExtension(dpy,NULL,ev_rtrn,err_rtrn,major_rtrn,minor_rtrn)) { 748 if (reason!=NULL) { 749 if ((*major_rtrn!=0)||(*minor_rtrn!=0)) 750 *reason= XkbOD_BadServerVersion; 751 else *reason= XkbOD_NonXkbServer; 752 } 753 XCloseDisplay(dpy); 754 return NULL; 755 } 756 if (reason!=NULL) 757 *reason= XkbOD_Success; 758 return dpy; 759} 760 761void 762XkbSetAtomFuncs(XkbInternAtomFunc getAtom,XkbGetAtomNameFunc getName) 763{ 764 _XkbInternAtomFunc= (getAtom?getAtom:XInternAtom); 765 _XkbGetAtomNameFunc= (getName?getName:XGetAtomName); 766 return; 767} 768