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