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->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 209 u.c8 = (CARD8 *) out; 210 if (size == 2) { 211 u.c16[0] = (CARD16) affect; 212 u.c16[1] = (CARD16) details; 213 } 214 else if (size == 4) { 215 u.c32[0] = (CARD32) affect; 216 u.c32[1] = (CARD32) details; 217 } 218 else { 219 u.c8[0] = (CARD8) affect; 220 u.c8[1] = (CARD8) details; 221 } 222 } 223 UnlockDisplay(dpy); 224 SyncHandle(); 225 return True; 226} 227 228Bool 229XkbLockModifiers(Display *dpy, 230 unsigned int deviceSpec, 231 unsigned int affect, 232 unsigned int values) 233{ 234 register xkbLatchLockStateReq *req; 235 XkbInfoPtr xkbi; 236 237 if ((dpy->flags & XlibDisplayNoXkb) || 238 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 239 return False; 240 LockDisplay(dpy); 241 xkbi = dpy->xkb_info; 242 GetReq(kbLatchLockState, req); 243 req->reqType = xkbi->codes->major_opcode; 244 req->xkbReqType = X_kbLatchLockState; 245 req->deviceSpec = deviceSpec; 246 req->affectModLocks = affect; 247 req->modLocks = values; 248 req->lockGroup = False; 249 req->groupLock = 0; 250 251 req->affectModLatches = req->modLatches = 0; 252 req->latchGroup = False; 253 req->groupLatch = 0; 254 UnlockDisplay(dpy); 255 SyncHandle(); 256 return True; 257} 258 259Bool 260XkbLatchModifiers(Display *dpy, 261 unsigned int deviceSpec, 262 unsigned int affect, 263 unsigned int values) 264{ 265 register xkbLatchLockStateReq *req; 266 XkbInfoPtr xkbi; 267 268 if ((dpy->flags & XlibDisplayNoXkb) || 269 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 270 return False; 271 LockDisplay(dpy); 272 xkbi = dpy->xkb_info; 273 GetReq(kbLatchLockState, req); 274 req->reqType = xkbi->codes->major_opcode; 275 req->xkbReqType = X_kbLatchLockState; 276 req->deviceSpec = deviceSpec; 277 278 req->affectModLatches = affect; 279 req->modLatches = values; 280 req->latchGroup = False; 281 req->groupLatch = 0; 282 283 req->affectModLocks = req->modLocks = 0; 284 req->lockGroup = False; 285 req->groupLock = 0; 286 287 UnlockDisplay(dpy); 288 SyncHandle(); 289 return True; 290} 291 292Bool 293XkbLockGroup(Display *dpy, unsigned int deviceSpec, unsigned int group) 294{ 295 register xkbLatchLockStateReq *req; 296 XkbInfoPtr xkbi; 297 298 if ((dpy->flags & XlibDisplayNoXkb) || 299 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 300 return False; 301 LockDisplay(dpy); 302 xkbi = dpy->xkb_info; 303 GetReq(kbLatchLockState, req); 304 req->reqType = xkbi->codes->major_opcode; 305 req->xkbReqType = X_kbLatchLockState; 306 req->deviceSpec = deviceSpec; 307 req->affectModLocks = 0; 308 req->modLocks = 0; 309 req->lockGroup = True; 310 req->groupLock = group; 311 312 req->affectModLatches = req->modLatches = 0; 313 req->latchGroup = False; 314 req->groupLatch = 0; 315 UnlockDisplay(dpy); 316 SyncHandle(); 317 return True; 318} 319 320Bool 321XkbLatchGroup(Display *dpy, unsigned int deviceSpec, unsigned int group) 322{ 323 register xkbLatchLockStateReq *req; 324 XkbInfoPtr xkbi; 325 326 if ((dpy->flags & XlibDisplayNoXkb) || 327 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 328 return False; 329 LockDisplay(dpy); 330 xkbi = dpy->xkb_info; 331 GetReq(kbLatchLockState, req); 332 req->reqType = xkbi->codes->major_opcode; 333 req->xkbReqType = X_kbLatchLockState; 334 req->deviceSpec = deviceSpec; 335 336 req->affectModLatches = 0; 337 req->modLatches = 0; 338 req->latchGroup = True; 339 req->groupLatch = group; 340 341 req->affectModLocks = req->modLocks = 0; 342 req->lockGroup = False; 343 req->groupLock = 0; 344 345 UnlockDisplay(dpy); 346 SyncHandle(); 347 return True; 348} 349 350unsigned 351XkbSetXlibControls(Display *dpy, unsigned affect, unsigned values) 352{ 353 if (!dpy->xkb_info) 354 XkbUseExtension(dpy, NULL, NULL); 355 if (!dpy->xkb_info) 356 return 0; 357 affect &= XkbLC_AllControls; 358 dpy->xkb_info->xlib_ctrls &= ~affect; 359 dpy->xkb_info->xlib_ctrls |= (affect & values); 360 return dpy->xkb_info->xlib_ctrls; 361} 362 363unsigned 364XkbGetXlibControls(Display *dpy) 365{ 366 if (!dpy->xkb_info) 367 XkbUseExtension(dpy, NULL, NULL); 368 if (!dpy->xkb_info) 369 return 0; 370 return dpy->xkb_info->xlib_ctrls; 371} 372 373unsigned int 374XkbXlibControlsImplemented(void) 375{ 376 return XkbLC_AllControls & ~XkbLC_AllComposeControls; 377} 378 379Bool 380XkbSetDebuggingFlags(Display *dpy, 381 unsigned int mask, 382 unsigned int flags, 383 char *msg, 384 unsigned int ctrls_mask, 385 unsigned int ctrls, 386 unsigned int *rtrn_flags, 387 unsigned int *rtrn_ctrls) 388{ 389 register xkbSetDebuggingFlagsReq *req; 390 xkbSetDebuggingFlagsReply rep; 391 XkbInfoPtr xkbi; 392 393 if ((dpy->flags & XlibDisplayNoXkb) || 394 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 395 return False; 396 LockDisplay(dpy); 397 xkbi = dpy->xkb_info; 398 GetReq(kbSetDebuggingFlags, req); 399 req->reqType = xkbi->codes->major_opcode; 400 req->xkbReqType = X_kbSetDebuggingFlags; 401 req->affectFlags = mask; 402 req->flags = flags; 403 req->affectCtrls = ctrls_mask; 404 req->ctrls = ctrls; 405 406 if (msg) { 407 char *out; 408 409 req->msgLength = (CARD16) (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 415 req->msgLength = 0; 416 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 417 UnlockDisplay(dpy); 418 SyncHandle(); 419 return False; 420 } 421 if (rtrn_flags) 422 *rtrn_flags = rep.currentFlags; 423 if (rtrn_ctrls) 424 *rtrn_ctrls = rep.currentCtrls; 425 UnlockDisplay(dpy); 426 SyncHandle(); 427 return True; 428} 429 430Bool 431XkbComputeEffectiveMap(XkbDescPtr xkb, 432 XkbKeyTypePtr type, 433 unsigned char *map_rtrn) 434{ 435 register int i; 436 unsigned tmp; 437 XkbKTMapEntryPtr entry = NULL; 438 439 if ((!xkb) || (!type) || (!xkb->server)) 440 return False; 441 442 if (type->mods.vmods != 0) { 443 if (!XkbVirtualModsToReal(xkb, type->mods.vmods, &tmp)) 444 return False; 445 446 type->mods.mask = tmp | type->mods.real_mods; 447 entry = type->map; 448 for (i = 0; i < type->map_count; i++, entry++) { 449 tmp = 0; 450 if (entry->mods.vmods != 0) { 451 if (!XkbVirtualModsToReal(xkb, entry->mods.vmods, &tmp)) 452 return False; 453 if (tmp == 0) { 454 entry->active = False; 455 continue; 456 } 457 } 458 entry->active = True; 459 entry->mods.mask = (entry->mods.real_mods | tmp) & type->mods.mask; 460 } 461 } 462 else { 463 type->mods.mask = type->mods.real_mods; 464 } 465 if (map_rtrn != NULL) { 466 bzero(map_rtrn, type->mods.mask + 1); 467 for (i = 0; i < type->map_count; i++) { 468 if (entry && entry->active) { 469 map_rtrn[type->map[i].mods.mask] = type->map[i].level; 470 } 471 } 472 } 473 return True; 474} 475 476Status 477XkbGetState(Display *dpy, unsigned deviceSpec, XkbStatePtr rtrn) 478{ 479 register xkbGetStateReq *req; 480 xkbGetStateReply rep; 481 XkbInfoPtr xkbi; 482 483 if ((dpy->flags & XlibDisplayNoXkb) || 484 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 485 return BadAccess; 486 LockDisplay(dpy); 487 xkbi = dpy->xkb_info; 488 GetReq(kbGetState, req); 489 req->reqType = xkbi->codes->major_opcode; 490 req->xkbReqType = X_kbGetState; 491 req->deviceSpec = deviceSpec; 492 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 493 UnlockDisplay(dpy); 494 SyncHandle(); 495 return BadImplementation; 496 } 497 rtrn->mods = rep.mods; 498 rtrn->base_mods = rep.baseMods; 499 rtrn->latched_mods = rep.latchedMods; 500 rtrn->locked_mods = rep.lockedMods; 501 rtrn->group = rep.group; 502 rtrn->base_group = rep.baseGroup; 503 rtrn->latched_group = rep.latchedGroup; 504 rtrn->locked_group = rep.lockedGroup; 505 rtrn->compat_state = rep.compatState; 506 rtrn->grab_mods = rep.grabMods; 507 rtrn->compat_grab_mods = rep.compatGrabMods; 508 rtrn->lookup_mods = rep.lookupMods; 509 rtrn->compat_lookup_mods = rep.compatLookupMods; 510 rtrn->ptr_buttons = rep.ptrBtnState; 511 UnlockDisplay(dpy); 512 SyncHandle(); 513 return Success; 514} 515 516Bool 517XkbSetDetectableAutoRepeat(Display *dpy, Bool detectable, Bool *supported) 518{ 519 register xkbPerClientFlagsReq *req; 520 xkbPerClientFlagsReply rep; 521 XkbInfoPtr xkbi; 522 523 if ((dpy->flags & XlibDisplayNoXkb) || 524 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 525 return False; 526 LockDisplay(dpy); 527 xkbi = dpy->xkb_info; 528 GetReq(kbPerClientFlags, req); 529 req->reqType = xkbi->codes->major_opcode; 530 req->xkbReqType = X_kbPerClientFlags; 531 req->deviceSpec = XkbUseCoreKbd; 532 req->change = XkbPCF_DetectableAutoRepeatMask; 533 if (detectable) 534 req->value = XkbPCF_DetectableAutoRepeatMask; 535 else 536 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{ 553 register xkbPerClientFlagsReq *req; 554 xkbPerClientFlagsReply rep; 555 XkbInfoPtr 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{ 587 register xkbPerClientFlagsReq *req; 588 xkbPerClientFlagsReply rep; 589 XkbInfoPtr 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{ 622 register xkbPerClientFlagsReq *req; 623 xkbPerClientFlagsReply rep; 624 XkbInfoPtr 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, unsigned change, unsigned *values) 654{ 655 register xkbPerClientFlagsReq *req; 656 xkbPerClientFlagsReply rep; 657 XkbInfoPtr xkbi; 658 unsigned value_hold = *values; 659 660 if ((dpy->flags & XlibDisplayNoXkb) || 661 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || 662 (change & ~(XkbPCF_GrabsUseXKBStateMask | 663 XkbPCF_LookupStateWhenGrabbed | 664 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, unsigned *ctrls) 688{ 689 register xkbPerClientFlagsReq *req; 690 xkbPerClientFlagsReply rep; 691 XkbInfoPtr xkbi; 692 693 if ((dpy->flags & XlibDisplayNoXkb) || 694 (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || 695 (ctrls == NULL)) 696 return False; 697 LockDisplay(dpy); 698 xkbi = dpy->xkb_info; 699 GetReq(kbPerClientFlags, req); 700 req->reqType = xkbi->codes->major_opcode; 701 req->xkbReqType = X_kbPerClientFlags; 702 req->deviceSpec = XkbUseCoreKbd; 703 req->change = 0; 704 req->value = 0; 705 req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; 706 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 707 UnlockDisplay(dpy); 708 SyncHandle(); 709 return False; 710 } 711 UnlockDisplay(dpy); 712 SyncHandle(); 713 *ctrls = (rep.value & (XkbPCF_GrabsUseXKBStateMask | 714 XkbPCF_LookupStateWhenGrabbed | 715 XkbPCF_SendEventUsesXKBState)); 716 return (True); 717} 718 719Display * 720XkbOpenDisplay(_Xconst 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, 750 major_rtrn, minor_rtrn)) { 751 if (reason != NULL) { 752 if ((*major_rtrn != 0) || (*minor_rtrn != 0)) 753 *reason = XkbOD_BadServerVersion; 754 else 755 *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