XKBUse.c revision 1ab64890
1/* $Xorg: XKBUse.c,v 1.3 2000/08/17 19:45:03 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/XKBUse.c,v 3.7 2003/07/07 15:34:21 eich Exp $ */ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <stdio.h> 33#include <ctype.h> 34#define NEED_REPLIES 35#define NEED_EVENTS 36#include "Xlibint.h" 37#include <X11/extensions/XKBproto.h> 38#include "XKBlibint.h" 39 40static Bool _XkbIgnoreExtension = False; 41 42void 43XkbNoteMapChanges(XkbMapChangesPtr old,XkbMapNotifyEvent *new,unsigned wanted) 44{ 45 int first,oldLast,newLast; 46 wanted&= new->changed; 47 48 if (wanted&XkbKeyTypesMask) { 49 if (old->changed&XkbKeyTypesMask) { 50 first = old->first_type; 51 oldLast = old->first_type+old->num_types-1; 52 newLast = new->first_type+new->num_types-1; 53 54 if (new->first_type<first) 55 first = new->first_type; 56 if (oldLast>newLast) 57 newLast= oldLast; 58 old->first_type = first; 59 old->num_types = newLast-first+1; 60 } 61 else { 62 old->first_type= new->first_type; 63 old->num_types = new->num_types; 64 } 65 } 66 if (wanted&XkbKeySymsMask) { 67 if (old->changed&XkbKeySymsMask) { 68 first = old->first_key_sym; 69 oldLast = old->first_key_sym+old->num_key_syms-1; 70 newLast = new->first_key_sym+new->num_key_syms-1; 71 72 if (new->first_key_sym<first) 73 first = new->first_key_sym; 74 if (oldLast>newLast) 75 newLast= oldLast; 76 old->first_key_sym = first; 77 old->num_key_syms = newLast-first+1; 78 } 79 else { 80 old->first_key_sym = new->first_key_sym; 81 old->num_key_syms = new->num_key_syms; 82 } 83 } 84 if (wanted&XkbKeyActionsMask) { 85 if (old->changed&XkbKeyActionsMask) { 86 first = old->first_key_act; 87 oldLast = old->first_key_act+old->num_key_acts-1; 88 newLast = new->first_key_act+new->num_key_acts-1; 89 90 if (new->first_key_act<first) 91 first = new->first_key_act; 92 if (oldLast>newLast) 93 newLast= oldLast; 94 old->first_key_act = first; 95 old->num_key_acts = newLast-first+1; 96 } 97 else { 98 old->first_key_act = new->first_key_act; 99 old->num_key_acts = new->num_key_acts; 100 } 101 } 102 if (wanted&XkbKeyBehaviorsMask) { 103 if (old->changed&XkbKeyBehaviorsMask) { 104 first = old->first_key_behavior; 105 oldLast = old->first_key_behavior+old->num_key_behaviors-1; 106 newLast = new->first_key_behavior+new->num_key_behaviors-1; 107 108 if (new->first_key_behavior<first) 109 first = new->first_key_behavior; 110 if (oldLast>newLast) 111 newLast= oldLast; 112 old->first_key_behavior = first; 113 old->num_key_behaviors = newLast-first+1; 114 } 115 else { 116 old->first_key_behavior = new->first_key_behavior; 117 old->num_key_behaviors = new->num_key_behaviors; 118 } 119 } 120 if (wanted&XkbVirtualModsMask) { 121 old->vmods|= new->vmods; 122 } 123 if (wanted&XkbExplicitComponentsMask) { 124 if (old->changed&XkbExplicitComponentsMask) { 125 first = old->first_key_explicit; 126 oldLast = old->first_key_explicit+old->num_key_explicit-1; 127 newLast = new->first_key_explicit+new->num_key_explicit-1; 128 129 if (new->first_key_explicit<first) 130 first = new->first_key_explicit; 131 if (oldLast>newLast) 132 newLast= oldLast; 133 old->first_key_explicit = first; 134 old->num_key_explicit = newLast-first+1; 135 } 136 else { 137 old->first_key_explicit = new->first_key_explicit; 138 old->num_key_explicit = new->num_key_explicit; 139 } 140 } 141 if (wanted&XkbModifierMapMask) { 142 if (old->changed&XkbModifierMapMask) { 143 first = old->first_modmap_key; 144 oldLast = old->first_modmap_key+old->num_modmap_keys-1; 145 newLast = new->first_modmap_key+new->num_modmap_keys-1; 146 147 if (new->first_modmap_key<first) 148 first = new->first_modmap_key; 149 if (oldLast>newLast) 150 newLast= oldLast; 151 old->first_modmap_key = first; 152 old->num_modmap_keys = newLast-first+1; 153 } 154 else { 155 old->first_modmap_key = new->first_modmap_key; 156 old->num_modmap_keys = new->num_modmap_keys; 157 } 158 } 159 if (wanted&XkbVirtualModMapMask) { 160 if (old->changed&XkbVirtualModMapMask) { 161 first = old->first_vmodmap_key; 162 oldLast = old->first_vmodmap_key+old->num_vmodmap_keys-1; 163 newLast = new->first_vmodmap_key+new->num_vmodmap_keys-1; 164 165 if (new->first_vmodmap_key<first) 166 first = new->first_vmodmap_key; 167 if (oldLast>newLast) 168 newLast= oldLast; 169 old->first_vmodmap_key = first; 170 old->num_vmodmap_keys = newLast-first+1; 171 } 172 else { 173 old->first_vmodmap_key = new->first_vmodmap_key; 174 old->num_vmodmap_keys = new->num_vmodmap_keys; 175 } 176 } 177 old->changed|= wanted; 178 return; 179} 180 181void 182_XkbNoteCoreMapChanges( XkbMapChangesPtr old, 183 XMappingEvent * new, 184 unsigned int wanted) 185{ 186 int first,oldLast,newLast; 187 188 if ((new->request==MappingKeyboard)&&(wanted&XkbKeySymsMask)) { 189 if (old->changed&XkbKeySymsMask) { 190 first = old->first_key_sym; 191 oldLast = old->first_key_sym+old->num_key_syms-1; 192 newLast = new->first_keycode+new->count-1; 193 194 if (new->first_keycode<first) 195 first = new->first_keycode; 196 if (oldLast>newLast) 197 newLast= oldLast; 198 old->first_key_sym = first; 199 old->num_key_syms = newLast-first+1; 200 } 201 else { 202 old->changed|= XkbKeySymsMask; 203 old->first_key_sym = new->first_keycode; 204 old->num_key_syms = new->count; 205 } 206 } 207 return; 208} 209 210static Bool 211wire_to_event(Display *dpy,XEvent *re,xEvent *event) 212{ 213 xkbEvent *xkbevent= (xkbEvent *)event; 214 XkbInfoPtr xkbi; 215 216 if ((dpy->flags & XlibDisplayNoXkb) || 217 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 218 return False; 219 xkbi = dpy->xkb_info; 220 if (((event->u.u.type&0x7f)-xkbi->codes->first_event)!=XkbEventCode) 221 return False; 222 223 switch (xkbevent->u.any.xkbType) { 224 case XkbStateNotify: 225 { 226 xkbStateNotify *sn = (xkbStateNotify *)event; 227 if ( xkbi->selected_events&XkbStateNotifyMask ) { 228 XkbStateNotifyEvent *sev=(XkbStateNotifyEvent *)re; 229 sev->type = XkbEventCode+xkbi->codes->first_event; 230 sev->xkb_type = XkbStateNotify; 231 sev->serial = _XSetLastRequestRead(dpy, 232 (xGenericReply *)event); 233 sev->send_event = ((event->u.u.type & 0x80) != 0); 234 sev->display = dpy; 235 sev->time = sn->time; 236 sev->device = sn->deviceID; 237 sev->keycode = sn->keycode; 238 sev->event_type = sn->eventType; 239 sev->req_major = sn->requestMajor; 240 sev->req_minor = sn->requestMinor; 241 sev->changed = sn->changed; 242 sev->group = sn->group; 243 sev->base_group = sn->baseGroup; 244 sev->latched_group = sn->latchedGroup; 245 sev->locked_group = sn->lockedGroup; 246 sev->mods = sn->mods; 247 sev->base_mods = sn->baseMods; 248 sev->latched_mods = sn->latchedMods; 249 sev->locked_mods = sn->lockedMods; 250 sev->compat_state = sn->compatState; 251 sev->grab_mods = sn->grabMods; 252 sev->compat_grab_mods = sn->compatGrabMods; 253 sev->lookup_mods = sn->lookupMods; 254 sev->compat_lookup_mods = sn->compatLookupMods; 255 sev->ptr_buttons = sn->ptrBtnState; 256 return True; 257 } 258 } 259 break; 260 case XkbMapNotify: 261 { 262 xkbMapNotify *mn = (xkbMapNotify *)event; 263 if ((xkbi->selected_events&XkbMapNotifyMask)&& 264 (xkbi->selected_map_details&mn->changed)) { 265 XkbMapNotifyEvent *mev; 266 mev =(XkbMapNotifyEvent *)re; 267 mev->type = XkbEventCode+xkbi->codes->first_event; 268 mev->xkb_type = XkbMapNotify; 269 mev->serial = _XSetLastRequestRead(dpy, 270 (xGenericReply *)event); 271 mev->send_event = ((event->u.u.type&0x80)!=0); 272 mev->display = dpy; 273 mev->time = mn->time; 274 mev->device = mn->deviceID; 275 mev->changed = mn->changed; 276 mev->min_key_code = mn->minKeyCode; 277 mev->max_key_code = mn->maxKeyCode; 278 mev->first_type = mn->firstType; 279 mev->num_types = mn->nTypes; 280 mev->first_key_sym = mn->firstKeySym; 281 mev->num_key_syms = mn->nKeySyms; 282 mev->first_key_act = mn->firstKeyAct; 283 mev->num_key_acts = mn->nKeyActs; 284 mev->first_key_behavior = mn->firstKeyBehavior; 285 mev->num_key_behaviors = mn->nKeyBehaviors; 286 mev->vmods = mn->virtualMods; 287 mev->first_key_explicit = mn->firstKeyExplicit; 288 mev->num_key_explicit = mn->nKeyExplicit; 289 mev->first_modmap_key = mn->firstModMapKey; 290 mev->num_modmap_keys = mn->nModMapKeys; 291 mev->first_vmodmap_key = mn->firstVModMapKey; 292 mev->num_vmodmap_keys = mn->nVModMapKeys; 293 XkbNoteMapChanges(&xkbi->changes,mev,XKB_XLIB_MAP_MASK); 294 if (xkbi->changes.changed) 295 xkbi->flags|= XkbMapPending; 296 return True; 297 } 298 else if (mn->nKeySyms>0) { 299 register XMappingEvent *ev = (XMappingEvent *)re; 300 ev->type = MappingNotify; 301 ev->serial = _XSetLastRequestRead(dpy, 302 (xGenericReply *)event); 303 ev->send_event = ((event->u.u.type&0x80)!=0); 304 ev->display = dpy; 305 ev->window = 0; 306 ev->first_keycode = mn->firstKeySym; 307 ev->request = MappingKeyboard; 308 ev->count = mn->nKeySyms; 309 _XkbNoteCoreMapChanges(&xkbi->changes,ev,XKB_XLIB_MAP_MASK); 310 if (xkbi->changes.changed) 311 xkbi->flags|= XkbMapPending; 312 return True; 313 } 314 } 315 break; 316 case XkbControlsNotify: 317 { 318 if (xkbi->selected_events&XkbControlsNotifyMask) { 319 xkbControlsNotify *cn =(xkbControlsNotify *)event; 320 XkbControlsNotifyEvent *cev; 321 cev =(XkbControlsNotifyEvent *)re; 322 cev->type = XkbEventCode+xkbi->codes->first_event; 323 cev->xkb_type = XkbControlsNotify; 324 cev->serial = _XSetLastRequestRead(dpy, 325 (xGenericReply *)event); 326 cev->send_event = ((event->u.u.type&0x80)!=0); 327 cev->display = dpy; 328 cev->time = cn->time; 329 cev->device = cn->deviceID; 330 cev->changed_ctrls = cn->changedControls; 331 cev->enabled_ctrls = cn->enabledControls; 332 cev->enabled_ctrl_changes = cn->enabledControlChanges; 333 cev->keycode = cn->keycode; 334 cev->num_groups = cn->numGroups; 335 cev->event_type = cn->eventType; 336 cev->req_major = cn->requestMajor; 337 cev->req_minor = cn->requestMinor; 338 return True; 339 } 340 } 341 break; 342 case XkbIndicatorMapNotify: 343 { 344 if (xkbi->selected_events&XkbIndicatorMapNotifyMask) { 345 xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; 346 XkbIndicatorNotifyEvent *iev; 347 iev =(XkbIndicatorNotifyEvent *)re; 348 iev->type = XkbEventCode+xkbi->codes->first_event; 349 iev->xkb_type = XkbIndicatorMapNotify; 350 iev->serial = _XSetLastRequestRead(dpy, 351 (xGenericReply *)event); 352 iev->send_event = ((event->u.u.type&0x80)!=0); 353 iev->display = dpy; 354 iev->time = in->time; 355 iev->device = in->deviceID; 356 iev->changed = in->changed; 357 iev->state= in->state; 358 return True; 359 } 360 } 361 break; 362 case XkbIndicatorStateNotify: 363 { 364 if (xkbi->selected_events&XkbIndicatorStateNotifyMask) { 365 xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; 366 XkbIndicatorNotifyEvent *iev; 367 iev =(XkbIndicatorNotifyEvent *)re; 368 iev->type = XkbEventCode+xkbi->codes->first_event; 369 iev->xkb_type = XkbIndicatorStateNotify; 370 iev->serial = _XSetLastRequestRead(dpy, 371 (xGenericReply *)event); 372 iev->send_event = ((event->u.u.type&0x80)!=0); 373 iev->display = dpy; 374 iev->time = in->time; 375 iev->device = in->deviceID; 376 iev->changed = in->changed; 377 iev->state= in->state; 378 return True; 379 } 380 } 381 break; 382 case XkbBellNotify: 383 { 384 if (xkbi->selected_events&XkbBellNotifyMask) { 385 xkbBellNotify *bn =(xkbBellNotify *)event; 386 XkbBellNotifyEvent *bev; 387 bev =(XkbBellNotifyEvent *)re; 388 bev->type = XkbEventCode+xkbi->codes->first_event; 389 bev->xkb_type = XkbBellNotify; 390 bev->serial = _XSetLastRequestRead(dpy, 391 (xGenericReply *)event); 392 bev->send_event = ((event->u.u.type&0x80)!=0); 393 bev->display = dpy; 394 bev->time = bn->time; 395 bev->device = bn->deviceID; 396 bev->percent = bn->percent; 397 bev->pitch = bn->pitch; 398 bev->duration = bn->duration; 399 bev->bell_class = bn->bellClass; 400 bev->bell_id = bn->bellID; 401 bev->name = bn->name; 402 bev->window = bn->window; 403 bev->event_only = bn->eventOnly; 404 return True; 405 } 406 } 407 break; 408 case XkbAccessXNotify: 409 { 410 if (xkbi->selected_events&XkbAccessXNotifyMask) { 411 xkbAccessXNotify *axn =(xkbAccessXNotify *)event; 412 XkbAccessXNotifyEvent *axev; 413 axev =(XkbAccessXNotifyEvent *)re; 414 axev->type = XkbEventCode+xkbi->codes->first_event; 415 axev->xkb_type = XkbAccessXNotify; 416 axev->serial = _XSetLastRequestRead(dpy, 417 (xGenericReply *)event); 418 axev->send_event = ((event->u.u.type&0x80)!=0); 419 axev->display = dpy; 420 axev->time = axn->time; 421 axev->device = axn->deviceID; 422 axev->detail = axn->detail; 423 axev->keycode = axn->keycode; 424 axev->sk_delay = axn->slowKeysDelay; 425 axev->debounce_delay = axn->debounceDelay; 426 return True; 427 } 428 } 429 break; 430 case XkbNamesNotify: 431 { 432 if (xkbi->selected_events&XkbNamesNotifyMask) { 433 xkbNamesNotify *nn =(xkbNamesNotify *)event; 434 XkbNamesNotifyEvent *nev; 435 nev =(XkbNamesNotifyEvent *)re; 436 nev->type = XkbEventCode+xkbi->codes->first_event; 437 nev->xkb_type = XkbNamesNotify; 438 nev->serial = _XSetLastRequestRead(dpy, 439 (xGenericReply *)event); 440 nev->send_event = ((event->u.u.type&0x80)!=0); 441 nev->display = dpy; 442 nev->time = nn->time; 443 nev->device = nn->deviceID; 444 nev->changed = nn->changed; 445 nev->first_type = nn->firstType; 446 nev->num_types = nn->nTypes; 447 nev->first_lvl = nn->firstLevelName; 448 nev->num_lvls = nn->nLevelNames; 449 nev->num_aliases = nn->nAliases; 450 nev->num_radio_groups = nn->nRadioGroups; 451 nev->changed_vmods = nn->changedVirtualMods; 452 nev->changed_groups = nn->changedGroupNames; 453 nev->changed_indicators = nn->changedIndicators; 454 nev->first_key = nn->firstKey; 455 nev->num_keys = nn->nKeys; 456 return True; 457 } 458 } 459 break; 460 case XkbCompatMapNotify: 461 { 462 if (xkbi->selected_events&XkbCompatMapNotifyMask) { 463 xkbCompatMapNotify *cmn =(xkbCompatMapNotify *)event; 464 XkbCompatMapNotifyEvent *cmev; 465 cmev =(XkbCompatMapNotifyEvent *)re; 466 cmev->type = XkbEventCode+xkbi->codes->first_event; 467 cmev->xkb_type = XkbCompatMapNotify; 468 cmev->serial = _XSetLastRequestRead(dpy, 469 (xGenericReply *)event); 470 cmev->send_event = ((event->u.u.type&0x80)!=0); 471 cmev->display = dpy; 472 cmev->time = cmn->time; 473 cmev->device = cmn->deviceID; 474 cmev->changed_groups = cmn->changedGroups; 475 cmev->first_si = cmn->firstSI; 476 cmev->num_si = cmn->nSI; 477 cmev->num_total_si = cmn->nTotalSI; 478 return True; 479 } 480 } 481 break; 482 case XkbActionMessage: 483 { 484 if (xkbi->selected_events&XkbActionMessageMask) { 485 xkbActionMessage *am= (xkbActionMessage *)event; 486 XkbActionMessageEvent *amev; 487 amev= (XkbActionMessageEvent *)re; 488 amev->type = XkbEventCode+xkbi->codes->first_event; 489 amev->xkb_type = XkbActionMessage; 490 amev->serial = _XSetLastRequestRead(dpy, 491 (xGenericReply *)event); 492 amev->send_event = ((event->u.u.type&0x80)!=0); 493 amev->display = dpy; 494 amev->time = am->time; 495 amev->device = am->deviceID; 496 amev->keycode = am->keycode; 497 amev->press = am->press; 498 amev->key_event_follows = am->keyEventFollows; 499 amev->group = am->group; 500 amev->mods = am->mods; 501 memcpy(amev->message,am->message,XkbActionMessageLength); 502 amev->message[XkbActionMessageLength]= '\0'; 503 return True; 504 } 505 } 506 break; 507 case XkbExtensionDeviceNotify: 508 { 509 if (xkbi->selected_events&XkbExtensionDeviceNotifyMask) { 510 xkbExtensionDeviceNotify *ed= 511 (xkbExtensionDeviceNotify *)event; 512 XkbExtensionDeviceNotifyEvent *edev; 513 edev= (XkbExtensionDeviceNotifyEvent *)re; 514 edev->type= XkbEventCode+xkbi->codes->first_event; 515 edev->xkb_type= XkbExtensionDeviceNotify; 516 edev->serial= _XSetLastRequestRead(dpy, 517 (xGenericReply *)event); 518 edev->send_event= ((event->u.u.type&0x80)!=0); 519 edev->display= dpy; 520 edev->time= ed->time; 521 edev->device= ed->deviceID; 522 edev->led_class= ed->ledClass; 523 edev->led_id= ed->ledID; 524 edev->reason= ed->reason; 525 edev->supported= ed->supported; 526 edev->leds_defined= ed->ledsDefined; 527 edev->led_state= ed->ledState; 528 edev->first_btn= ed->firstBtn; 529 edev->num_btns= ed->nBtns; 530 edev->unsupported= ed->unsupported; 531 return True; 532 } 533 } 534 break; 535 case XkbNewKeyboardNotify: 536 { 537 xkbNewKeyboardNotify *nkn = (xkbNewKeyboardNotify *)event; 538 if ((xkbi->selected_events&XkbNewKeyboardNotifyMask)&& 539 (xkbi->selected_nkn_details&nkn->changed)) { 540 XkbNewKeyboardNotifyEvent *nkev; 541 nkev =(XkbNewKeyboardNotifyEvent *)re; 542 nkev->type = XkbEventCode+xkbi->codes->first_event; 543 nkev->xkb_type = XkbNewKeyboardNotify; 544 nkev->serial = _XSetLastRequestRead(dpy, 545 (xGenericReply *)event); 546 nkev->send_event = ((event->u.u.type&0x80)!=0); 547 nkev->display = dpy; 548 nkev->time = nkn->time; 549 nkev->device = nkn->deviceID; 550 nkev->old_device = nkn->oldDeviceID; 551 nkev->min_key_code = nkn->minKeyCode; 552 nkev->max_key_code = nkn->maxKeyCode; 553 nkev->old_min_key_code = nkn->oldMinKeyCode; 554 nkev->old_max_key_code = nkn->oldMaxKeyCode; 555 nkev->req_major = nkn->requestMajor; 556 nkev->req_minor = nkn->requestMinor; 557 nkev->changed = nkn->changed; 558 if ((xkbi->desc)&&(nkev->send_event==0)&& 559 ((xkbi->desc->device_spec==nkev->old_device)|| 560 (nkev->device!=nkev->old_device))) { 561 xkbi->flags= XkbMapPending|XkbXlibNewKeyboard; 562 } 563 return True; 564 } 565 else if(nkn->changed&(XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask)){ 566 register XMappingEvent *ev = (XMappingEvent *)re; 567 ev->type = MappingNotify; 568 ev->serial = _XSetLastRequestRead(dpy, 569 (xGenericReply *)event); 570 ev->send_event = ((event->u.u.type&0x80)!=0); 571 ev->display = dpy; 572 ev->window = 0; 573 ev->first_keycode = dpy->min_keycode; 574 ev->request = MappingKeyboard; 575 ev->count = (dpy->max_keycode-dpy->min_keycode)+1; 576 if ((xkbi->desc)&&(ev->send_event==0)&& 577 ((xkbi->desc->device_spec==nkn->oldDeviceID)|| 578 (nkn->deviceID!=nkn->oldDeviceID))) { 579 xkbi->flags|= XkbMapPending|XkbXlibNewKeyboard; 580 } 581 return True; 582 } 583 } 584 break; 585 default: 586#ifdef DEBUG 587 fprintf(stderr,"Got unknown XKEYBOARD event (%d, base=%d)\n", 588 re->type, 589 xkbi->codes->first_event); 590#endif 591 break; 592 } 593 return False; 594} 595 596Bool 597XkbIgnoreExtension(Bool ignore) 598{ 599 if (getenv("XKB_FORCE")!=NULL) { 600#ifdef DEBUG 601 fprintf(stderr,"Forcing use of XKEYBOARD (overriding an IgnoreExtensions)\n"); 602#endif 603 return False; 604 } 605#ifdef DEBUG 606 else if (getenv("XKB_DEBUG")!=NULL) { 607 fprintf(stderr,"Explicitly %signoring XKEYBOARD\n",ignore?"":"not "); 608 } 609#endif 610 _XkbIgnoreExtension = ignore; 611 return True; 612} 613 614static void 615_XkbFreeInfo(Display *dpy) 616{ 617 XkbInfoPtr xkbi = dpy->xkb_info; 618 if (xkbi) { 619 if (xkbi->desc) 620 XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); 621 Xfree(xkbi); 622 } 623} 624 625Bool 626XkbUseExtension(Display *dpy,int *major_rtrn,int *minor_rtrn) 627{ 628 xkbUseExtensionReply rep; 629 register xkbUseExtensionReq *req; 630 XExtCodes *codes; 631 int ev_base,forceIgnore; 632 XkbInfoPtr xkbi; 633 char * str; 634 static int debugMsg; 635 static int been_here= 0; 636 637 if ( dpy->xkb_info && !(dpy->flags & XlibDisplayNoXkb)) { 638 if (major_rtrn) *major_rtrn= dpy->xkb_info->srv_major; 639 if (minor_rtrn) *minor_rtrn= dpy->xkb_info->srv_minor; 640 return True; 641 } 642 if (!been_here) { 643 debugMsg= (getenv("XKB_DEBUG")!=NULL); 644 been_here= 1; 645 } 646 647 if (major_rtrn) *major_rtrn= 0; 648 if (minor_rtrn) *minor_rtrn= 0; 649 650 if (!dpy->xkb_info) { 651 xkbi = _XkbTypedCalloc(1, XkbInfoRec); 652 if ( !xkbi ) 653 return False; 654 dpy->xkb_info = xkbi; 655 dpy->free_funcs->xkb = _XkbFreeInfo; 656 657 xkbi->xlib_ctrls|= (XkbLC_ControlFallback|XkbLC_ConsumeLookupMods); 658 if ((str=getenv("_XKB_OPTIONS_ENABLE"))!=NULL) { 659 if ((str=getenv("_XKB_LATIN1_LOOKUP"))!=NULL) { 660 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 661 xkbi->xlib_ctrls&= ~XkbLC_ForceLatin1Lookup; 662 else xkbi->xlib_ctrls|= XkbLC_ForceLatin1Lookup; 663 } 664 if ((str=getenv("_XKB_CONSUME_LOOKUP_MODS"))!=NULL) { 665 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 666 xkbi->xlib_ctrls&= ~XkbLC_ConsumeLookupMods; 667 else xkbi->xlib_ctrls|= XkbLC_ConsumeLookupMods; 668 } 669 if ((str=getenv("_XKB_CONSUME_SHIFT_AND_LOCK"))!=NULL) { 670 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 671 xkbi->xlib_ctrls&= ~XkbLC_AlwaysConsumeShiftAndLock; 672 else xkbi->xlib_ctrls|= XkbLC_AlwaysConsumeShiftAndLock; 673 } 674 if ((str=getenv("_XKB_IGNORE_NEW_KEYBOARDS"))!=NULL) { 675 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 676 xkbi->xlib_ctrls&= ~XkbLC_IgnoreNewKeyboards; 677 else xkbi->xlib_ctrls|= XkbLC_IgnoreNewKeyboards; 678 } 679 if ((str=getenv("_XKB_CONTROL_FALLBACK"))!=NULL) { 680 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 681 xkbi->xlib_ctrls&= ~XkbLC_ControlFallback; 682 else xkbi->xlib_ctrls|= XkbLC_ControlFallback; 683 } 684 if ((str=getenv("_XKB_COMP_LED"))!=NULL) { 685 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 686 xkbi->xlib_ctrls&= ~XkbLC_ComposeLED; 687 else { 688 xkbi->xlib_ctrls|= XkbLC_ComposeLED; 689 if (strlen(str)>0) 690 xkbi->composeLED= XInternAtom(dpy,str,False); 691 } 692 } 693 if ((str=getenv("_XKB_COMP_FAIL_BEEP"))!=NULL) { 694 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 695 xkbi->xlib_ctrls&= ~XkbLC_BeepOnComposeFail; 696 else xkbi->xlib_ctrls|= XkbLC_BeepOnComposeFail; 697 } 698 } 699 if ((xkbi->composeLED==None)&&((xkbi->xlib_ctrls&XkbLC_ComposeLED)!=0)) 700 xkbi->composeLED= XInternAtom(dpy,"Compose",False); 701#ifdef DEBUG 702 if (debugMsg) { 703 register unsigned c= xkbi->xlib_ctrls; 704 fprintf(stderr,"XKEYBOARD compose: beep on failure is %s, LED is %s\n", 705 ((c&XkbLC_BeepOnComposeFail)?"on":"off"), 706 ((c&XkbLC_ComposeLED)?"on":"off")); 707 fprintf(stderr,"XKEYBOARD XLookupString: %slatin-1, %s lookup modifiers\n", 708 ((c&XkbLC_ForceLatin1Lookup)?"allow non-":"force "), 709 ((c&XkbLC_ConsumeLookupMods)?"consume":"re-use")); 710 fprintf(stderr, 711 "XKEYBOARD XLookupString: %sconsume shift and lock, %scontrol fallback\n", 712 ((c&XkbLC_AlwaysConsumeShiftAndLock)?"always ":"don't "), 713 ((c&XkbLC_ControlFallback)?"":"no ")); 714 715 } 716#endif 717 } else 718 xkbi = dpy->xkb_info; 719 720 forceIgnore= (dpy->flags&XlibDisplayNoXkb)||dpy->keysyms; 721 forceIgnore= forceIgnore&&(major_rtrn==NULL)&&(minor_rtrn==NULL); 722 if ( forceIgnore || _XkbIgnoreExtension || getenv("XKB_DISABLE")) { 723 LockDisplay(dpy); 724 dpy->flags |= XlibDisplayNoXkb; 725 UnlockDisplay(dpy); 726 if (debugMsg) 727 fprintf(stderr,"XKEYBOARD extension disabled or missing\n"); 728 return False; 729 } 730 731 if ( (codes=XInitExtension(dpy,XkbName))==NULL ) { 732 LockDisplay(dpy); 733 dpy->flags |= XlibDisplayNoXkb; 734 UnlockDisplay(dpy); 735 if (debugMsg) 736 fprintf(stderr,"XKEYBOARD extension not present\n"); 737 return False; 738 } 739 xkbi->codes = codes; 740 LockDisplay(dpy); 741 742 GetReq(kbUseExtension, req); 743 req->reqType = xkbi->codes->major_opcode; 744 req->xkbReqType = X_kbUseExtension; 745 req->wantedMajor = XkbMajorVersion; 746 req->wantedMinor = XkbMinorVersion; 747 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.supported ) { 748 Bool fail; 749 fail= True; 750 if (debugMsg) 751 fprintf(stderr, 752 "XKEYBOARD version mismatch (want %d.%02d, got %d.%02d)\n", 753 XkbMajorVersion,XkbMinorVersion, 754 rep.serverMajor, rep.serverMinor); 755 756 /* pre-release 0.65 is very close to 1.00 */ 757 if ((rep.serverMajor==0)&&(rep.serverMinor==65)) { 758 if (debugMsg) 759 fprintf(stderr,"Trying to fall back to version 0.65..."); 760 GetReq(kbUseExtension, req); 761 req->reqType = xkbi->codes->major_opcode; 762 req->xkbReqType = X_kbUseExtension; 763 req->wantedMajor = 0; 764 req->wantedMinor = 65; 765 if ( _XReply(dpy, (xReply *)&rep, 0, xFalse) && rep.supported ) { 766 if (debugMsg) 767 fprintf(stderr,"succeeded\n"); 768 fail= False; 769 } 770 else if (debugMsg) fprintf(stderr,"failed\n"); 771 } 772 if (fail) { 773 dpy->flags |= XlibDisplayNoXkb; 774 UnlockDisplay(dpy); 775 SyncHandle(); 776 if (major_rtrn) *major_rtrn= rep.serverMajor; 777 if (minor_rtrn) *minor_rtrn= rep.serverMinor; 778 return False; 779 } 780 } 781#ifdef DEBUG 782 else if ( forceIgnore ) { 783 fprintf(stderr,"Internal Error! XkbUseExtension succeeded with forceIgnore set\n"); 784 } 785#endif 786 UnlockDisplay(dpy); 787 xkbi->srv_major= rep.serverMajor; 788 xkbi->srv_minor= rep.serverMinor; 789 if (major_rtrn) *major_rtrn= rep.serverMajor; 790 if (minor_rtrn) *minor_rtrn= rep.serverMinor; 791 if (debugMsg) 792 fprintf(stderr,"XKEYBOARD (version %d.%02d/%d.%02d) OK!\n", 793 XkbMajorVersion,XkbMinorVersion, 794 rep.serverMajor,rep.serverMinor); 795 796 ev_base = codes->first_event; 797 XESetWireToEvent(dpy,ev_base+XkbEventCode,wire_to_event); 798 SyncHandle(); 799 return True; 800} 801 802