XKBUse.c revision b4ee4795
11.171Speter/************************************************************ 21.161SlukemCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 31.161Slukem 41.161SlukemPermission to use, copy, modify, and distribute this 51.161Slukemsoftware and its documentation for any purpose and without 61.161Slukemfee is hereby granted, provided that the above copyright 71.161Slukemnotice appear in all copies and that both that copyright 81.161Slukemnotice and this permission notice appear in supporting 91.161Slukemdocumentation, and that the name of Silicon Graphics not be 101.161Slukemused in advertising or publicity pertaining to distribution 111.135Slukemof the software without specific prior written permission. 121.135SlukemSilicon Graphics makes no representation about the suitability 131.135Slukemof this software for any purpose. It is provided "as is" 141.135Slukemwithout any express or implied warranty. 151.135Slukem 161.135SlukemSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 171.135SlukemSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 181.135SlukemAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 191.135SlukemGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 201.169SgdamoreDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 211.169SgdamoreDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 221.169SgdamoreOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 231.169SgdamoreTHE USE OR PERFORMANCE OF THIS SOFTWARE. 241.135Slukem 251.135Slukem********************************************************/ 261.135Slukem 271.135Slukem#ifdef HAVE_CONFIG_H 281.135Slukem#include <config.h> 291.135Slukem#endif 301.135Slukem#include <stdio.h> 311.135Slukem#include <ctype.h> 321.135Slukem#define NEED_REPLIES 331.135Slukem#define NEED_EVENTS 341.163Sjwise#include "Xlibint.h" 351.135Slukem#include <X11/extensions/XKBproto.h> 361.135Slukem#include "XKBlibint.h" 371.135Slukem 381.135Slukemstatic Bool _XkbIgnoreExtension = False; 391.135Slukem 401.135Slukemvoid 411.135SlukemXkbNoteMapChanges(XkbMapChangesPtr old,XkbMapNotifyEvent *new,unsigned wanted) 421.135Slukem{ 431.135Slukem int first,oldLast,newLast; 441.135Slukem wanted&= new->changed; 451.135Slukem 461.135Slukem if (wanted&XkbKeyTypesMask) { 471.135Slukem if (old->changed&XkbKeyTypesMask) { 481.135Slukem first = old->first_type; 491.135Slukem oldLast = old->first_type+old->num_types-1; 501.135Slukem newLast = new->first_type+new->num_types-1; 511.135Slukem 521.135Slukem if (new->first_type<first) 531.135Slukem first = new->first_type; 541.135Slukem if (oldLast>newLast) 551.135Slukem newLast= oldLast; 561.135Slukem old->first_type = first; 571.135Slukem old->num_types = newLast-first+1; 581.135Slukem } 591.135Slukem else { 601.135Slukem old->first_type= new->first_type; 611.135Slukem old->num_types = new->num_types; 621.135Slukem } 631.170Smrg } 641.170Smrg if (wanted&XkbKeySymsMask) { 651.135Slukem if (old->changed&XkbKeySymsMask) { 661.135Slukem first = old->first_key_sym; 671.140Sitohy oldLast = old->first_key_sym+old->num_key_syms-1; 681.135Slukem newLast = new->first_key_sym+new->num_key_syms-1; 691.167Stron 701.135Slukem if (new->first_key_sym<first) 711.135Slukem first = new->first_key_sym; 721.135Slukem if (oldLast>newLast) 731.135Slukem newLast= oldLast; 741.135Slukem old->first_key_sym = first; 751.135Slukem old->num_key_syms = newLast-first+1; 761.135Slukem } 771.135Slukem else { 781.135Slukem old->first_key_sym = new->first_key_sym; 791.138Slukem old->num_key_syms = new->num_key_syms; 801.135Slukem } 811.159Stron } 821.135Slukem if (wanted&XkbKeyActionsMask) { 831.135Slukem if (old->changed&XkbKeyActionsMask) { 841.135Slukem first = old->first_key_act; 851.135Slukem oldLast = old->first_key_act+old->num_key_acts-1; 861.135Slukem newLast = new->first_key_act+new->num_key_acts-1; 871.135Slukem 881.135Slukem if (new->first_key_act<first) 891.135Slukem first = new->first_key_act; 901.135Slukem if (oldLast>newLast) 911.135Slukem newLast= oldLast; 921.135Slukem old->first_key_act = first; 931.135Slukem old->num_key_acts = newLast-first+1; 941.135Slukem } 951.135Slukem else { 961.135Slukem old->first_key_act = new->first_key_act; 971.135Slukem old->num_key_acts = new->num_key_acts; 981.147Slukem } 991.150Sthorpej } 1001.147Slukem if (wanted&XkbKeyBehaviorsMask) { 1011.147Slukem if (old->changed&XkbKeyBehaviorsMask) { 1021.147Slukem first = old->first_key_behavior; 1031.147Slukem oldLast = old->first_key_behavior+old->num_key_behaviors-1; 1041.147Slukem newLast = new->first_key_behavior+new->num_key_behaviors-1; 1051.147Slukem 1061.147Slukem if (new->first_key_behavior<first) 1071.147Slukem first = new->first_key_behavior; 1081.151Schristos if (oldLast>newLast) 1091.147Slukem newLast= oldLast; 1101.147Slukem old->first_key_behavior = first; 1111.147Slukem old->num_key_behaviors = newLast-first+1; 1121.147Slukem } 1131.147Slukem else { 1141.147Slukem old->first_key_behavior = new->first_key_behavior; 1151.147Slukem old->num_key_behaviors = new->num_key_behaviors; 1161.152Schristos } 1171.135Slukem } 1181.135Slukem if (wanted&XkbVirtualModsMask) { 1191.163Sjwise old->vmods|= new->vmods; 1201.163Sjwise } 1211.135Slukem if (wanted&XkbExplicitComponentsMask) { 1221.145Smatt if (old->changed&XkbExplicitComponentsMask) { 1231.145Smatt first = old->first_key_explicit; 1241.145Smatt oldLast = old->first_key_explicit+old->num_key_explicit-1; 1251.145Smatt newLast = new->first_key_explicit+new->num_key_explicit-1; 1261.145Smatt 1271.145Smatt if (new->first_key_explicit<first) 1281.155Swiz first = new->first_key_explicit; 1291.135Slukem if (oldLast>newLast) 1301.135Slukem newLast= oldLast; 1311.135Slukem old->first_key_explicit = first; 1321.135Slukem old->num_key_explicit = newLast-first+1; 1331.135Slukem } 1341.135Slukem else { 1351.135Slukem old->first_key_explicit = new->first_key_explicit; 1361.135Slukem old->num_key_explicit = new->num_key_explicit; 1371.135Slukem } 1381.135Slukem } 1391.135Slukem if (wanted&XkbModifierMapMask) { 1401.135Slukem if (old->changed&XkbModifierMapMask) { 1411.135Slukem first = old->first_modmap_key; 1421.135Slukem oldLast = old->first_modmap_key+old->num_modmap_keys-1; 1431.135Slukem newLast = new->first_modmap_key+new->num_modmap_keys-1; 1441.135Slukem 1451.135Slukem if (new->first_modmap_key<first) 1461.135Slukem first = new->first_modmap_key; 1471.135Slukem if (oldLast>newLast) 1481.135Slukem newLast= oldLast; 1491.135Slukem old->first_modmap_key = first; 1501.169Sgdamore old->num_modmap_keys = newLast-first+1; 1511.169Sgdamore } 1521.135Slukem else { 1531.135Slukem old->first_modmap_key = new->first_modmap_key; 1541.135Slukem old->num_modmap_keys = new->num_modmap_keys; 1551.135Slukem } 1561.135Slukem } 1571.135Slukem if (wanted&XkbVirtualModMapMask) { 1581.135Slukem if (old->changed&XkbVirtualModMapMask) { 1591.135Slukem first = old->first_vmodmap_key; 1601.135Slukem oldLast = old->first_vmodmap_key+old->num_vmodmap_keys-1; 1611.141Sdbj newLast = new->first_vmodmap_key+new->num_vmodmap_keys-1; 1621.135Slukem 1631.135Slukem if (new->first_vmodmap_key<first) 1641.157Speter first = new->first_vmodmap_key; 1651.164Srpaulo if (oldLast>newLast) 1661.135Slukem newLast= oldLast; 1671.142Sitojun old->first_vmodmap_key = first; 1681.135Slukem old->num_vmodmap_keys = newLast-first+1; 1691.135Slukem } 1701.171Speter else { 1711.171Speter old->first_vmodmap_key = new->first_vmodmap_key; 1721.171Speter old->num_vmodmap_keys = new->num_vmodmap_keys; 1731.171Speter } 1741.135Slukem } 1751.165Srpaulo old->changed|= wanted; 1761.162Sagc return; 1771.135Slukem} 1781.135Slukem 1791.135Slukemvoid 1801.135Slukem_XkbNoteCoreMapChanges( XkbMapChangesPtr old, 1811.135Slukem XMappingEvent * new, 1821.135Slukem unsigned int wanted) 1831.135Slukem{ 1841.135Slukem int first,oldLast,newLast; 1851.135Slukem 1861.135Slukem if ((new->request==MappingKeyboard)&&(wanted&XkbKeySymsMask)) { 1871.135Slukem if (old->changed&XkbKeySymsMask) { 1881.135Slukem first = old->first_key_sym; 1891.135Slukem oldLast = old->first_key_sym+old->num_key_syms-1; 1901.135Slukem newLast = new->first_keycode+new->count-1; 1911.135Slukem 1921.135Slukem if (new->first_keycode<first) 1931.135Slukem first = new->first_keycode; 1941.135Slukem if (oldLast>newLast) 1951.135Slukem newLast= oldLast; 1961.135Slukem old->first_key_sym = first; 1971.135Slukem old->num_key_syms = newLast-first+1; 1981.135Slukem } 1991.135Slukem else { 2001.135Slukem old->changed|= XkbKeySymsMask; 2011.135Slukem old->first_key_sym = new->first_keycode; 2021.135Slukem old->num_key_syms = new->count; 2031.143Sitojun } 2041.158Speter } 2051.143Sitojun return; 2061.135Slukem} 2071.135Slukem 2081.135Slukemstatic Bool 2091.135Slukemwire_to_event(Display *dpy,XEvent *re,xEvent *event) 2101.135Slukem{ 2111.135Slukem xkbEvent *xkbevent= (xkbEvent *)event; 2121.135Slukem XkbInfoPtr xkbi; 2131.135Slukem 2141.135Slukem if ((dpy->flags & XlibDisplayNoXkb) || 2151.135Slukem (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 2161.135Slukem return False; 2171.135Slukem xkbi = dpy->xkb_info; 2181.135Slukem if (((event->u.u.type&0x7f)-xkbi->codes->first_event)!=XkbEventCode) 2191.135Slukem return False; 2201.135Slukem 2211.135Slukem switch (xkbevent->u.any.xkbType) { 2221.135Slukem case XkbStateNotify: 2231.135Slukem { 2241.135Slukem xkbStateNotify *sn = (xkbStateNotify *)event; 2251.135Slukem if ( xkbi->selected_events&XkbStateNotifyMask ) { 2261.135Slukem XkbStateNotifyEvent *sev=(XkbStateNotifyEvent *)re; 2271.169Sgdamore sev->type = XkbEventCode+xkbi->codes->first_event; 2281.135Slukem sev->xkb_type = XkbStateNotify; 2291.135Slukem sev->serial = _XSetLastRequestRead(dpy, 2301.135Slukem (xGenericReply *)event); 2311.135Slukem sev->send_event = ((event->u.u.type & 0x80) != 0); 2321.135Slukem sev->display = dpy; 2331.135Slukem sev->time = sn->time; 2341.135Slukem sev->device = sn->deviceID; 2351.135Slukem sev->keycode = sn->keycode; 2361.135Slukem sev->event_type = sn->eventType; 2371.135Slukem sev->req_major = sn->requestMajor; 2381.135Slukem sev->req_minor = sn->requestMinor; 2391.135Slukem sev->changed = sn->changed; 2401.137Sblymn sev->group = sn->group; 2411.135Slukem sev->base_group = sn->baseGroup; 2421.135Slukem sev->latched_group = sn->latchedGroup; 2431.135Slukem sev->locked_group = sn->lockedGroup; 2441.135Slukem sev->mods = sn->mods; 2451.135Slukem sev->base_mods = sn->baseMods; 2461.135Slukem sev->latched_mods = sn->latchedMods; 2471.135Slukem sev->locked_mods = sn->lockedMods; 2481.135Slukem sev->compat_state = sn->compatState; 2491.135Slukem sev->grab_mods = sn->grabMods; 2501.135Slukem sev->compat_grab_mods = sn->compatGrabMods; 2511.135Slukem sev->lookup_mods = sn->lookupMods; 2521.135Slukem sev->compat_lookup_mods = sn->compatLookupMods; 2531.135Slukem sev->ptr_buttons = sn->ptrBtnState; 2541.135Slukem return True; 2551.135Slukem } 2561.135Slukem } 2571.144Swiz break; 2581.135Slukem case XkbMapNotify: 2591.135Slukem { 2601.135Slukem xkbMapNotify *mn = (xkbMapNotify *)event; 2611.135Slukem if ((xkbi->selected_events&XkbMapNotifyMask)&& 2621.135Slukem (xkbi->selected_map_details&mn->changed)) { 2631.135Slukem XkbMapNotifyEvent *mev; 2641.135Slukem mev =(XkbMapNotifyEvent *)re; 2651.135Slukem mev->type = XkbEventCode+xkbi->codes->first_event; 2661.135Slukem mev->xkb_type = XkbMapNotify; 2671.135Slukem mev->serial = _XSetLastRequestRead(dpy, 2681.135Slukem (xGenericReply *)event); 2691.135Slukem mev->send_event = ((event->u.u.type&0x80)!=0); 2701.156Speter mev->display = dpy; 2711.135Slukem mev->time = mn->time; 2721.135Slukem mev->device = mn->deviceID; 2731.142Sitojun mev->changed = mn->changed; 2741.135Slukem mev->min_key_code = mn->minKeyCode; 2751.135Slukem mev->max_key_code = mn->maxKeyCode; 2761.135Slukem mev->first_type = mn->firstType; 2771.135Slukem mev->num_types = mn->nTypes; 2781.135Slukem mev->first_key_sym = mn->firstKeySym; 2791.135Slukem mev->num_key_syms = mn->nKeySyms; 2801.135Slukem mev->first_key_act = mn->firstKeyAct; 2811.135Slukem mev->num_key_acts = mn->nKeyActs; 2821.135Slukem mev->first_key_behavior = mn->firstKeyBehavior; 2831.135Slukem mev->num_key_behaviors = mn->nKeyBehaviors; 2841.135Slukem mev->vmods = mn->virtualMods; 2851.135Slukem mev->first_key_explicit = mn->firstKeyExplicit; 2861.135Slukem mev->num_key_explicit = mn->nKeyExplicit; 2871.135Slukem mev->first_modmap_key = mn->firstModMapKey; 2881.135Slukem mev->num_modmap_keys = mn->nModMapKeys; 2891.135Slukem mev->first_vmodmap_key = mn->firstVModMapKey; 2901.135Slukem mev->num_vmodmap_keys = mn->nVModMapKeys; 2911.135Slukem XkbNoteMapChanges(&xkbi->changes,mev,XKB_XLIB_MAP_MASK); 2921.135Slukem if (xkbi->changes.changed) 2931.135Slukem xkbi->flags|= XkbMapPending; 2941.135Slukem return True; 2951.135Slukem } 2961.135Slukem else if (mn->nKeySyms>0) { 2971.135Slukem register XMappingEvent *ev = (XMappingEvent *)re; 2981.135Slukem ev->type = MappingNotify; 2991.135Slukem ev->serial = _XSetLastRequestRead(dpy, 3001.135Slukem (xGenericReply *)event); 3011.135Slukem ev->send_event = ((event->u.u.type&0x80)!=0); 3021.135Slukem ev->display = dpy; 3031.135Slukem ev->window = 0; 3041.135Slukem ev->first_keycode = mn->firstKeySym; 3051.135Slukem ev->request = MappingKeyboard; 3061.135Slukem ev->count = mn->nKeySyms; 3071.135Slukem _XkbNoteCoreMapChanges(&xkbi->changes,ev,XKB_XLIB_MAP_MASK); 3081.135Slukem if (xkbi->changes.changed) 3091.135Slukem xkbi->flags|= XkbMapPending; 3101.153Skleink return True; 3111.135Slukem } 3121.135Slukem } 3131.135Slukem break; 3141.135Slukem case XkbControlsNotify: 3151.166Schristos { 3161.135Slukem if (xkbi->selected_events&XkbControlsNotifyMask) { 3171.135Slukem xkbControlsNotify *cn =(xkbControlsNotify *)event; 3181.135Slukem XkbControlsNotifyEvent *cev; 3191.135Slukem cev =(XkbControlsNotifyEvent *)re; 3201.135Slukem cev->type = XkbEventCode+xkbi->codes->first_event; 3211.135Slukem cev->xkb_type = XkbControlsNotify; 3221.135Slukem cev->serial = _XSetLastRequestRead(dpy, 3231.135Slukem (xGenericReply *)event); 324 cev->send_event = ((event->u.u.type&0x80)!=0); 325 cev->display = dpy; 326 cev->time = cn->time; 327 cev->device = cn->deviceID; 328 cev->changed_ctrls = cn->changedControls; 329 cev->enabled_ctrls = cn->enabledControls; 330 cev->enabled_ctrl_changes = cn->enabledControlChanges; 331 cev->keycode = cn->keycode; 332 cev->num_groups = cn->numGroups; 333 cev->event_type = cn->eventType; 334 cev->req_major = cn->requestMajor; 335 cev->req_minor = cn->requestMinor; 336 return True; 337 } 338 } 339 break; 340 case XkbIndicatorMapNotify: 341 { 342 if (xkbi->selected_events&XkbIndicatorMapNotifyMask) { 343 xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; 344 XkbIndicatorNotifyEvent *iev; 345 iev =(XkbIndicatorNotifyEvent *)re; 346 iev->type = XkbEventCode+xkbi->codes->first_event; 347 iev->xkb_type = XkbIndicatorMapNotify; 348 iev->serial = _XSetLastRequestRead(dpy, 349 (xGenericReply *)event); 350 iev->send_event = ((event->u.u.type&0x80)!=0); 351 iev->display = dpy; 352 iev->time = in->time; 353 iev->device = in->deviceID; 354 iev->changed = in->changed; 355 iev->state= in->state; 356 return True; 357 } 358 } 359 break; 360 case XkbIndicatorStateNotify: 361 { 362 if (xkbi->selected_events&XkbIndicatorStateNotifyMask) { 363 xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; 364 XkbIndicatorNotifyEvent *iev; 365 iev =(XkbIndicatorNotifyEvent *)re; 366 iev->type = XkbEventCode+xkbi->codes->first_event; 367 iev->xkb_type = XkbIndicatorStateNotify; 368 iev->serial = _XSetLastRequestRead(dpy, 369 (xGenericReply *)event); 370 iev->send_event = ((event->u.u.type&0x80)!=0); 371 iev->display = dpy; 372 iev->time = in->time; 373 iev->device = in->deviceID; 374 iev->changed = in->changed; 375 iev->state= in->state; 376 return True; 377 } 378 } 379 break; 380 case XkbBellNotify: 381 { 382 if (xkbi->selected_events&XkbBellNotifyMask) { 383 xkbBellNotify *bn =(xkbBellNotify *)event; 384 XkbBellNotifyEvent *bev; 385 bev =(XkbBellNotifyEvent *)re; 386 bev->type = XkbEventCode+xkbi->codes->first_event; 387 bev->xkb_type = XkbBellNotify; 388 bev->serial = _XSetLastRequestRead(dpy, 389 (xGenericReply *)event); 390 bev->send_event = ((event->u.u.type&0x80)!=0); 391 bev->display = dpy; 392 bev->time = bn->time; 393 bev->device = bn->deviceID; 394 bev->percent = bn->percent; 395 bev->pitch = bn->pitch; 396 bev->duration = bn->duration; 397 bev->bell_class = bn->bellClass; 398 bev->bell_id = bn->bellID; 399 bev->name = bn->name; 400 bev->window = bn->window; 401 bev->event_only = bn->eventOnly; 402 return True; 403 } 404 } 405 break; 406 case XkbAccessXNotify: 407 { 408 if (xkbi->selected_events&XkbAccessXNotifyMask) { 409 xkbAccessXNotify *axn =(xkbAccessXNotify *)event; 410 XkbAccessXNotifyEvent *axev; 411 axev =(XkbAccessXNotifyEvent *)re; 412 axev->type = XkbEventCode+xkbi->codes->first_event; 413 axev->xkb_type = XkbAccessXNotify; 414 axev->serial = _XSetLastRequestRead(dpy, 415 (xGenericReply *)event); 416 axev->send_event = ((event->u.u.type&0x80)!=0); 417 axev->display = dpy; 418 axev->time = axn->time; 419 axev->device = axn->deviceID; 420 axev->detail = axn->detail; 421 axev->keycode = axn->keycode; 422 axev->sk_delay = axn->slowKeysDelay; 423 axev->debounce_delay = axn->debounceDelay; 424 return True; 425 } 426 } 427 break; 428 case XkbNamesNotify: 429 { 430 if (xkbi->selected_events&XkbNamesNotifyMask) { 431 xkbNamesNotify *nn =(xkbNamesNotify *)event; 432 XkbNamesNotifyEvent *nev; 433 nev =(XkbNamesNotifyEvent *)re; 434 nev->type = XkbEventCode+xkbi->codes->first_event; 435 nev->xkb_type = XkbNamesNotify; 436 nev->serial = _XSetLastRequestRead(dpy, 437 (xGenericReply *)event); 438 nev->send_event = ((event->u.u.type&0x80)!=0); 439 nev->display = dpy; 440 nev->time = nn->time; 441 nev->device = nn->deviceID; 442 nev->changed = nn->changed; 443 nev->first_type = nn->firstType; 444 nev->num_types = nn->nTypes; 445 nev->first_lvl = nn->firstLevelName; 446 nev->num_lvls = nn->nLevelNames; 447 nev->num_aliases = nn->nAliases; 448 nev->num_radio_groups = nn->nRadioGroups; 449 nev->changed_vmods = nn->changedVirtualMods; 450 nev->changed_groups = nn->changedGroupNames; 451 nev->changed_indicators = nn->changedIndicators; 452 nev->first_key = nn->firstKey; 453 nev->num_keys = nn->nKeys; 454 return True; 455 } 456 } 457 break; 458 case XkbCompatMapNotify: 459 { 460 if (xkbi->selected_events&XkbCompatMapNotifyMask) { 461 xkbCompatMapNotify *cmn =(xkbCompatMapNotify *)event; 462 XkbCompatMapNotifyEvent *cmev; 463 cmev =(XkbCompatMapNotifyEvent *)re; 464 cmev->type = XkbEventCode+xkbi->codes->first_event; 465 cmev->xkb_type = XkbCompatMapNotify; 466 cmev->serial = _XSetLastRequestRead(dpy, 467 (xGenericReply *)event); 468 cmev->send_event = ((event->u.u.type&0x80)!=0); 469 cmev->display = dpy; 470 cmev->time = cmn->time; 471 cmev->device = cmn->deviceID; 472 cmev->changed_groups = cmn->changedGroups; 473 cmev->first_si = cmn->firstSI; 474 cmev->num_si = cmn->nSI; 475 cmev->num_total_si = cmn->nTotalSI; 476 return True; 477 } 478 } 479 break; 480 case XkbActionMessage: 481 { 482 if (xkbi->selected_events&XkbActionMessageMask) { 483 xkbActionMessage *am= (xkbActionMessage *)event; 484 XkbActionMessageEvent *amev; 485 amev= (XkbActionMessageEvent *)re; 486 amev->type = XkbEventCode+xkbi->codes->first_event; 487 amev->xkb_type = XkbActionMessage; 488 amev->serial = _XSetLastRequestRead(dpy, 489 (xGenericReply *)event); 490 amev->send_event = ((event->u.u.type&0x80)!=0); 491 amev->display = dpy; 492 amev->time = am->time; 493 amev->device = am->deviceID; 494 amev->keycode = am->keycode; 495 amev->press = am->press; 496 amev->key_event_follows = am->keyEventFollows; 497 amev->group = am->group; 498 amev->mods = am->mods; 499 memcpy(amev->message,am->message,XkbActionMessageLength); 500 amev->message[XkbActionMessageLength]= '\0'; 501 return True; 502 } 503 } 504 break; 505 case XkbExtensionDeviceNotify: 506 { 507 if (xkbi->selected_events&XkbExtensionDeviceNotifyMask) { 508 xkbExtensionDeviceNotify *ed= 509 (xkbExtensionDeviceNotify *)event; 510 XkbExtensionDeviceNotifyEvent *edev; 511 edev= (XkbExtensionDeviceNotifyEvent *)re; 512 edev->type= XkbEventCode+xkbi->codes->first_event; 513 edev->xkb_type= XkbExtensionDeviceNotify; 514 edev->serial= _XSetLastRequestRead(dpy, 515 (xGenericReply *)event); 516 edev->send_event= ((event->u.u.type&0x80)!=0); 517 edev->display= dpy; 518 edev->time= ed->time; 519 edev->device= ed->deviceID; 520 edev->led_class= ed->ledClass; 521 edev->led_id= ed->ledID; 522 edev->reason= ed->reason; 523 edev->supported= ed->supported; 524 edev->leds_defined= ed->ledsDefined; 525 edev->led_state= ed->ledState; 526 edev->first_btn= ed->firstBtn; 527 edev->num_btns= ed->nBtns; 528 edev->unsupported= ed->unsupported; 529 return True; 530 } 531 } 532 break; 533 case XkbNewKeyboardNotify: 534 { 535 xkbNewKeyboardNotify *nkn = (xkbNewKeyboardNotify *)event; 536 if ((xkbi->selected_events&XkbNewKeyboardNotifyMask)&& 537 (xkbi->selected_nkn_details&nkn->changed)) { 538 XkbNewKeyboardNotifyEvent *nkev; 539 nkev =(XkbNewKeyboardNotifyEvent *)re; 540 nkev->type = XkbEventCode+xkbi->codes->first_event; 541 nkev->xkb_type = XkbNewKeyboardNotify; 542 nkev->serial = _XSetLastRequestRead(dpy, 543 (xGenericReply *)event); 544 nkev->send_event = ((event->u.u.type&0x80)!=0); 545 nkev->display = dpy; 546 nkev->time = nkn->time; 547 nkev->device = nkn->deviceID; 548 nkev->old_device = nkn->oldDeviceID; 549 nkev->min_key_code = nkn->minKeyCode; 550 nkev->max_key_code = nkn->maxKeyCode; 551 nkev->old_min_key_code = nkn->oldMinKeyCode; 552 nkev->old_max_key_code = nkn->oldMaxKeyCode; 553 nkev->req_major = nkn->requestMajor; 554 nkev->req_minor = nkn->requestMinor; 555 nkev->changed = nkn->changed; 556 if ((xkbi->desc)&&(nkev->send_event==0)&& 557 ((xkbi->desc->device_spec==nkev->old_device)|| 558 (nkev->device!=nkev->old_device))) { 559 xkbi->flags= XkbMapPending|XkbXlibNewKeyboard; 560 } 561 return True; 562 } 563 else if(nkn->changed&(XkbNKN_KeycodesMask|XkbNKN_DeviceIDMask)){ 564 register XMappingEvent *ev = (XMappingEvent *)re; 565 ev->type = MappingNotify; 566 ev->serial = _XSetLastRequestRead(dpy, 567 (xGenericReply *)event); 568 ev->send_event = ((event->u.u.type&0x80)!=0); 569 ev->display = dpy; 570 ev->window = 0; 571 ev->first_keycode = dpy->min_keycode; 572 ev->request = MappingKeyboard; 573 ev->count = (dpy->max_keycode-dpy->min_keycode)+1; 574 if ((xkbi->desc)&&(ev->send_event==0)&& 575 ((xkbi->desc->device_spec==nkn->oldDeviceID)|| 576 (nkn->deviceID!=nkn->oldDeviceID))) { 577 xkbi->flags|= XkbMapPending|XkbXlibNewKeyboard; 578 } 579 return True; 580 } 581 } 582 break; 583 default: 584#ifdef DEBUG 585 fprintf(stderr,"Got unknown XKEYBOARD event (%d, base=%d)\n", 586 re->type, 587 xkbi->codes->first_event); 588#endif 589 break; 590 } 591 return False; 592} 593 594Bool 595XkbIgnoreExtension(Bool ignore) 596{ 597 if (getenv("XKB_FORCE")!=NULL) { 598#ifdef DEBUG 599 fprintf(stderr,"Forcing use of XKEYBOARD (overriding an IgnoreExtensions)\n"); 600#endif 601 return False; 602 } 603#ifdef DEBUG 604 else if (getenv("XKB_DEBUG")!=NULL) { 605 fprintf(stderr,"Explicitly %signoring XKEYBOARD\n",ignore?"":"not "); 606 } 607#endif 608 _XkbIgnoreExtension = ignore; 609 return True; 610} 611 612static void 613_XkbFreeInfo(Display *dpy) 614{ 615 XkbInfoPtr xkbi = dpy->xkb_info; 616 if (xkbi) { 617 if (xkbi->desc) 618 XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); 619 Xfree(xkbi); 620 } 621} 622 623Bool 624XkbUseExtension(Display *dpy,int *major_rtrn,int *minor_rtrn) 625{ 626 xkbUseExtensionReply rep; 627 register xkbUseExtensionReq *req; 628 XExtCodes *codes; 629 int ev_base,forceIgnore; 630 XkbInfoPtr xkbi; 631 char * str; 632 static int debugMsg; 633 static int been_here= 0; 634 635 if ( dpy->xkb_info && !(dpy->flags & XlibDisplayNoXkb)) { 636 if (major_rtrn) *major_rtrn= dpy->xkb_info->srv_major; 637 if (minor_rtrn) *minor_rtrn= dpy->xkb_info->srv_minor; 638 return True; 639 } 640 if (!been_here) { 641 debugMsg= (getenv("XKB_DEBUG")!=NULL); 642 been_here= 1; 643 } 644 645 if (major_rtrn) *major_rtrn= 0; 646 if (minor_rtrn) *minor_rtrn= 0; 647 648 if (!dpy->xkb_info) { 649 xkbi = _XkbTypedCalloc(1, XkbInfoRec); 650 if ( !xkbi ) 651 return False; 652 dpy->xkb_info = xkbi; 653 dpy->free_funcs->xkb = _XkbFreeInfo; 654 655 xkbi->xlib_ctrls|= (XkbLC_ControlFallback|XkbLC_ConsumeLookupMods); 656 if ((str=getenv("_XKB_OPTIONS_ENABLE"))!=NULL) { 657 if ((str=getenv("_XKB_LATIN1_LOOKUP"))!=NULL) { 658 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 659 xkbi->xlib_ctrls&= ~XkbLC_ForceLatin1Lookup; 660 else xkbi->xlib_ctrls|= XkbLC_ForceLatin1Lookup; 661 } 662 if ((str=getenv("_XKB_CONSUME_LOOKUP_MODS"))!=NULL) { 663 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 664 xkbi->xlib_ctrls&= ~XkbLC_ConsumeLookupMods; 665 else xkbi->xlib_ctrls|= XkbLC_ConsumeLookupMods; 666 } 667 if ((str=getenv("_XKB_CONSUME_SHIFT_AND_LOCK"))!=NULL) { 668 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 669 xkbi->xlib_ctrls&= ~XkbLC_AlwaysConsumeShiftAndLock; 670 else xkbi->xlib_ctrls|= XkbLC_AlwaysConsumeShiftAndLock; 671 } 672 if ((str=getenv("_XKB_IGNORE_NEW_KEYBOARDS"))!=NULL) { 673 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 674 xkbi->xlib_ctrls&= ~XkbLC_IgnoreNewKeyboards; 675 else xkbi->xlib_ctrls|= XkbLC_IgnoreNewKeyboards; 676 } 677 if ((str=getenv("_XKB_CONTROL_FALLBACK"))!=NULL) { 678 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 679 xkbi->xlib_ctrls&= ~XkbLC_ControlFallback; 680 else xkbi->xlib_ctrls|= XkbLC_ControlFallback; 681 } 682 if ((str=getenv("_XKB_COMP_LED"))!=NULL) { 683 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 684 xkbi->xlib_ctrls&= ~XkbLC_ComposeLED; 685 else { 686 xkbi->xlib_ctrls|= XkbLC_ComposeLED; 687 if (strlen(str)>0) 688 xkbi->composeLED= XInternAtom(dpy,str,False); 689 } 690 } 691 if ((str=getenv("_XKB_COMP_FAIL_BEEP"))!=NULL) { 692 if ((strcmp(str,"off")==0)||(strcmp(str,"0")==0)) 693 xkbi->xlib_ctrls&= ~XkbLC_BeepOnComposeFail; 694 else xkbi->xlib_ctrls|= XkbLC_BeepOnComposeFail; 695 } 696 } 697 if ((xkbi->composeLED==None)&&((xkbi->xlib_ctrls&XkbLC_ComposeLED)!=0)) 698 xkbi->composeLED= XInternAtom(dpy,"Compose",False); 699#ifdef DEBUG 700 if (debugMsg) { 701 register unsigned c= xkbi->xlib_ctrls; 702 fprintf(stderr,"XKEYBOARD compose: beep on failure is %s, LED is %s\n", 703 ((c&XkbLC_BeepOnComposeFail)?"on":"off"), 704 ((c&XkbLC_ComposeLED)?"on":"off")); 705 fprintf(stderr,"XKEYBOARD XLookupString: %slatin-1, %s lookup modifiers\n", 706 ((c&XkbLC_ForceLatin1Lookup)?"allow non-":"force "), 707 ((c&XkbLC_ConsumeLookupMods)?"consume":"re-use")); 708 fprintf(stderr, 709 "XKEYBOARD XLookupString: %sconsume shift and lock, %scontrol fallback\n", 710 ((c&XkbLC_AlwaysConsumeShiftAndLock)?"always ":"don't "), 711 ((c&XkbLC_ControlFallback)?"":"no ")); 712 713 } 714#endif 715 } else 716 xkbi = dpy->xkb_info; 717 718 forceIgnore= (dpy->flags&XlibDisplayNoXkb)||dpy->keysyms; 719 forceIgnore= forceIgnore&&(major_rtrn==NULL)&&(minor_rtrn==NULL); 720 if ( forceIgnore || _XkbIgnoreExtension || getenv("XKB_DISABLE")) { 721 LockDisplay(dpy); 722 dpy->flags |= XlibDisplayNoXkb; 723 UnlockDisplay(dpy); 724 if (debugMsg) 725 fprintf(stderr,"XKEYBOARD extension disabled or missing\n"); 726 return False; 727 } 728 729 if ( (codes=XInitExtension(dpy,XkbName))==NULL ) { 730 LockDisplay(dpy); 731 dpy->flags |= XlibDisplayNoXkb; 732 UnlockDisplay(dpy); 733 if (debugMsg) 734 fprintf(stderr,"XKEYBOARD extension not present\n"); 735 return False; 736 } 737 xkbi->codes = codes; 738 LockDisplay(dpy); 739 740 GetReq(kbUseExtension, req); 741 req->reqType = xkbi->codes->major_opcode; 742 req->xkbReqType = X_kbUseExtension; 743 req->wantedMajor = XkbMajorVersion; 744 req->wantedMinor = XkbMinorVersion; 745 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.supported ) { 746 Bool fail; 747 fail= True; 748 if (debugMsg) 749 fprintf(stderr, 750 "XKEYBOARD version mismatch (want %d.%02d, got %d.%02d)\n", 751 XkbMajorVersion,XkbMinorVersion, 752 rep.serverMajor, rep.serverMinor); 753 754 /* pre-release 0.65 is very close to 1.00 */ 755 if ((rep.serverMajor==0)&&(rep.serverMinor==65)) { 756 if (debugMsg) 757 fprintf(stderr,"Trying to fall back to version 0.65..."); 758 GetReq(kbUseExtension, req); 759 req->reqType = xkbi->codes->major_opcode; 760 req->xkbReqType = X_kbUseExtension; 761 req->wantedMajor = 0; 762 req->wantedMinor = 65; 763 if ( _XReply(dpy, (xReply *)&rep, 0, xFalse) && rep.supported ) { 764 if (debugMsg) 765 fprintf(stderr,"succeeded\n"); 766 fail= False; 767 } 768 else if (debugMsg) fprintf(stderr,"failed\n"); 769 } 770 if (fail) { 771 dpy->flags |= XlibDisplayNoXkb; 772 UnlockDisplay(dpy); 773 SyncHandle(); 774 if (major_rtrn) *major_rtrn= rep.serverMajor; 775 if (minor_rtrn) *minor_rtrn= rep.serverMinor; 776 return False; 777 } 778 } 779#ifdef DEBUG 780 else if ( forceIgnore ) { 781 fprintf(stderr,"Internal Error! XkbUseExtension succeeded with forceIgnore set\n"); 782 } 783#endif 784 UnlockDisplay(dpy); 785 xkbi->srv_major= rep.serverMajor; 786 xkbi->srv_minor= rep.serverMinor; 787 if (major_rtrn) *major_rtrn= rep.serverMajor; 788 if (minor_rtrn) *minor_rtrn= rep.serverMinor; 789 if (debugMsg) 790 fprintf(stderr,"XKEYBOARD (version %d.%02d/%d.%02d) OK!\n", 791 XkbMajorVersion,XkbMinorVersion, 792 rep.serverMajor,rep.serverMinor); 793 794 ev_base = codes->first_event; 795 XESetWireToEvent(dpy,ev_base+XkbEventCode,wire_to_event); 796 SyncHandle(); 797 return True; 798} 799 800