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