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