static XkbDescPtr get_xkb (ClutterKeymapX11 *keymap_x11) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); if (keymap_x11->max_keycode == 0) XDisplayKeycodes (backend_x11->xdpy, &keymap_x11->min_keycode, &keymap_x11->max_keycode); if (keymap_x11->xkb_desc == NULL) { int flags = XkbKeySymsMask | XkbKeyTypesMask | XkbModifierMapMask | XkbVirtualModsMask; keymap_x11->xkb_desc = XkbGetMap (backend_x11->xdpy, flags, XkbUseCoreKbd); if (G_UNLIKELY (keymap_x11->xkb_desc == NULL)) { g_error ("Failed to get the keymap from XKB"); return NULL; } flags = XkbGroupNamesMask | XkbVirtualModNamesMask; XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc); update_modmap (backend_x11->xdpy, keymap_x11); } else if (keymap_x11->xkb_map_serial != backend_x11->keymap_serial) { int flags = XkbKeySymsMask | XkbKeyTypesMask | XkbModifierMapMask | XkbVirtualModsMask; CLUTTER_NOTE (BACKEND, "Updating XKB keymap"); XkbGetUpdatedMap (backend_x11->xdpy, flags, keymap_x11->xkb_desc); flags = XkbGroupNamesMask | XkbVirtualModNamesMask; XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc); update_modmap (backend_x11->xdpy, keymap_x11); keymap_x11->xkb_map_serial = backend_x11->keymap_serial; } if (keymap_x11->num_lock_mask == 0) keymap_x11->num_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy, XK_Num_Lock); if (keymap_x11->scroll_lock_mask == 0) keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy, XK_Scroll_Lock); return keymap_x11->xkb_desc; }
KeyboardLayoutWidget::KeyboardLayoutWidget(QWidget* parent): QWidget(parent), ratio(1.0), trackModifiers(false ) { uint i = 0; for (i = 0; i < sizeof(deadMapData) / sizeof(deadMapData[0]); i ++) deadMap[deadMapData[i].dead] = deadMapData[i].nondead; xkb = XkbGetKeyboard (QX11Info::display(), XkbGBN_GeometryMask | XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask | XkbGBN_SymbolsMask | XkbGBN_IndicatorMapMask, XkbUseCoreKbd); if (!xkb) return; groupLevels = pGroupsLevels; XkbGetNames (QX11Info::display(), XkbAllNamesMask, xkb); l3mod = XkbKeysymToModifiers (QX11Info::display(), XK_ISO_Level3_Shift); XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd, XkbIndicatorStateNotify, xkb->indicators->phys_indicators, xkb->indicators->phys_indicators); xkbOnDisplay = true; int mask = (XkbStateNotifyMask | XkbNamesNotifyMask | XkbControlsNotifyMask | XkbIndicatorMapNotifyMask | XkbNewKeyboardNotifyMask); XkbSelectEvents (QX11Info::display(), XkbUseCoreKbd, mask, mask); mask = XkbGroupStateMask | XkbModifierStateMask; XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd, XkbStateNotify, mask, mask); mask = (XkbGroupNamesMask | XkbIndicatorNamesMask); XkbSelectEventDetails (QX11Info::display(), XkbUseCoreKbd, XkbNamesNotify, mask, mask); alloc (); init(); initColors(); setFocusPolicy(Qt::StrongFocus); }
/* * given a list of modifiers, computes the mask necessary for later matching. * This routine must lookup the key in the Keymap and then search to see * what modifier it is bound to, if any. Sets the AnyModifier bit if it * can't map some keysym to a modifier. */ static void ComputeMaskFromKeytrans( Display *dpy, register struct _XKeytrans *p) { register int i; p->state = AnyModifier; for (i = 0; i < p->mlen; i++) { p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); } p->state &= AllMods; }
static void setup_modifiers (void) { if (gsd_used_mods == 0 || gsd_ignored_mods == 0) { GdkModifierType dynmods; /* default modifiers */ gsd_ignored_mods = \ 0x2000 /*Xkb modifier*/ | GDK_LOCK_MASK | GDK_HYPER_MASK; gsd_used_mods = \ GDK_SHIFT_MASK | GDK_CONTROL_MASK |\ GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK |\ GDK_MOD5_MASK | GDK_SUPER_MASK | GDK_META_MASK; /* NumLock can be assigned to varying keys so we need to * resolve and ignore it specially */ dynmods = XkbKeysymToModifiers (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_KEY_Num_Lock); gsd_ignored_mods |= dynmods; gsd_used_mods &= ~dynmods; } }
static void accessx_status_applet_init_modifiers(AccessxStatusApplet* sapplet) { int i; unsigned int hyper_mask, super_mask, alt_gr_mask; unsigned int alt_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Alt_L); unsigned int meta_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Meta_L); g_assert(sapplet->meta_indicator); if (meta_mask && (meta_mask != alt_mask)) { gtk_widget_show(sapplet->meta_indicator); } else { gtk_widget_hide(sapplet->meta_indicator); } hyper_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Hyper_L); if (hyper_mask) { gtk_widget_show(sapplet->hyper_indicator); } else { gtk_widget_hide(sapplet->hyper_indicator); } super_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Super_L); if (super_mask) { gtk_widget_show(sapplet->super_indicator); } else { gtk_widget_hide(sapplet->super_indicator); } alt_gr_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Mode_switch) | XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Shift) | XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Latch) | XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Lock); if (alt_gr_mask) { gtk_widget_show(sapplet->alt_graph_indicator); } else { gtk_widget_hide(sapplet->alt_graph_indicator); } for (i = 0; i < G_N_ELEMENTS(modifiers); ++i) { if (modifiers[i].mask == ShiftMask) { modifiers[i].indicator = sapplet->shift_indicator; } else if (modifiers[i].mask == ControlMask) { modifiers[i].indicator = sapplet->ctrl_indicator; } else if (modifiers[i].mask == alt_mask) { modifiers[i].indicator = sapplet->alt_indicator; } else if (modifiers[i].mask == meta_mask) { modifiers[i].indicator = sapplet->meta_indicator; } else if (modifiers[i].mask == hyper_mask) { modifiers[i].indicator = sapplet->hyper_indicator; } else if (modifiers[i].mask == super_mask) { modifiers[i].indicator = sapplet->super_indicator; } else if (modifiers[i].mask == alt_gr_mask) { modifiers[i].indicator = sapplet->alt_graph_indicator; } } }
int XRefreshKeyboardMapping(register XMappingEvent *event) { XkbEvent *xkbevent = (XkbEvent *)event; Display *dpy = event->display; XkbMapChangesRec changes; XkbInfoPtr xkbi; /* always do this for input methods, which still use the old keymap */ (void) _XRefreshKeyboardMapping(event); if (_XkbUnavailable(dpy)) return 1; xkbi = dpy->xkb_info; if (((event->type&0x7f)-xkbi->codes->first_event)==XkbEventCode) return XkbRefreshKeyboardMapping(&xkbevent->map); if (xkbi->flags&XkbXlibNewKeyboard) { _XkbReloadDpy(dpy); return 1; } if ((xkbi->flags&XkbMapPending)||(event->request==MappingKeyboard)) { if (xkbi->flags&XkbMapPending) { changes= xkbi->changes; _XkbNoteCoreMapChanges(&changes,event,XKB_XLIB_MAP_MASK); } else { bzero(&changes,sizeof(changes)); changes.changed= XkbKeySymsMask; if (xkbi->desc->min_key_code<xkbi->desc->max_key_code) { changes.first_key_sym= xkbi->desc->min_key_code; changes.num_key_syms= xkbi->desc->max_key_code- xkbi->desc->min_key_code+1; } else { changes.first_key_sym= event->first_keycode; changes.num_key_syms= event->count; } } if (XkbGetMapChanges(dpy,xkbi->desc, &changes)!=Success) { #ifdef DEBUG fprintf(stderr,"Internal Error! XkbGetMapChanges failed:\n"); if (changes.changed&XkbKeyTypesMask) { int first= changes.first_type; int last= changes.first_type+changes.num_types-1; fprintf(stderr," types: %d..%d\n",first,last); } if (changes.changed&XkbKeySymsMask) { int first= changes.first_key_sym; int last= changes.first_key_sym+changes.num_key_syms-1; fprintf(stderr," symbols: %d..%d\n",first,last); } if (changes.changed&XkbKeyActionsMask) { int last,first= changes.first_key_act; last= changes.first_key_act+changes.num_key_acts-1; fprintf(stderr," acts: %d..%d\n",first,last); } if (changes.changed&XkbKeyBehaviorsMask) { int last,first= changes.first_key_behavior; last= first+changes.num_key_behaviors-1; fprintf(stderr," behaviors: %d..%d\n",first,last); } if (changes.changed&XkbVirtualModsMask) { fprintf(stderr,"virtual mods: 0x%04x\n", changes.vmods); } if (changes.changed&XkbExplicitComponentsMask) { int last,first= changes.first_key_explicit; last= first+changes.num_key_explicit-1; fprintf(stderr," explicit: %d..%d\n",first,last); } #endif } LockDisplay(dpy); if (xkbi->flags&XkbMapPending) { xkbi->flags&= ~XkbMapPending; bzero(&xkbi->changes,sizeof(XkbMapChangesRec)); } UnlockDisplay(dpy); } if (event->request==MappingModifier) { LockDisplay(dpy); if (xkbi->desc->map->modmap) { _XkbFree(xkbi->desc->map->modmap); xkbi->desc->map->modmap= NULL; } if (dpy->key_bindings) { register struct _XKeytrans *p; for (p = dpy->key_bindings; p; p = p->next) { register int i; p->state= 0; if (p->mlen>0) { for (i = 0; i < p->mlen; i++) { p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); } if (p->state) p->state &= AllMods; else p->state = AnyModifier; } } } UnlockDisplay(dpy); } return 1; }
static void spi_controller_register_with_devices (SpiDEController *controller) { DEControllerPrivateData *priv; int event_base, error_base, major_version, minor_version; priv = controller->priv; if (XTestQueryExtension (spi_get_display(), &event_base, &error_base, &major_version, &minor_version)) { XTestGrabControl (spi_get_display (), True); } /* calls to device-specific implementations and routines go here */ /* register with: keyboard hardware code handler */ /* register with: (translated) keystroke handler */ priv->have_xkb = XkbQueryExtension (spi_get_display (), &priv->xkb_major_extension_opcode, &priv->xkb_base_event_code, &priv->xkb_base_error_code, NULL, NULL); if (priv->have_xkb) { gint i; guint64 reserved = 0; priv->xkb_desc = XkbGetMap (spi_get_display (), XkbKeySymsMask, XkbUseCoreKbd); XkbSelectEvents (spi_get_display (), XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); _numlock_physical_mask = XkbKeysymToModifiers (spi_get_display (), XK_Num_Lock); for (i = priv->xkb_desc->max_key_code; i >= priv->xkb_desc->min_key_code; --i) { if (priv->xkb_desc->map->key_sym_map[i].kt_index[0] == XkbOneLevelIndex) { if (XkbKeycodeToKeysym (spi_get_display (), i, 0, 0) != 0) { /* don't use this one if there's a grab client! */ /* Runtime errors are generated from these functions, * that are then quashed. Equivalent to: * try * {Blah} * except * {;} */ spi_x_error_trap (); XGrabKey (spi_get_display (), i, 0, spi_get_root_window (), TRUE, GrabModeSync, GrabModeSync); XSync (spi_get_display (), TRUE); XUngrabKey (spi_get_display (), i, 0, spi_get_root_window ()); if (!spi_x_error_release ()) { reserved = i; break; } } } } if (reserved) { priv->reserved_keycode = reserved; priv->reserved_keysym = XkbKeycodeToKeysym (spi_get_display (), reserved, 0, 0); } else { priv->reserved_keycode = XKeysymToKeycode (spi_get_display (), XK_numbersign); priv->reserved_keysym = XK_numbersign; } #ifdef SPI_RESERVED_DEBUG unsigned sym = 0; sym = XKeycodeToKeysym (spi_get_display (), reserved, 0); fprintf (stderr, "%x\n", sym); fprintf (stderr, "setting the reserved keycode to %d (%s)\n", reserved, XKeysymToString (XKeycodeToKeysym (spi_get_display (), reserved, 0))); #endif } spi_set_filter (global_filter_fn, controller); spi_set_events (KeyPressMask | KeyReleaseMask); x_default_error_handler = XSetErrorHandler (_spi_controller_device_error_handler); }
static gboolean spi_dec_x11_synth_keystring (SpiDEController *controller, guint synth_type, gint keycode, const char *keystring) { /* probably we need to create and inject an XIM handler eventually. */ /* for now, try to match the string to existing * keycode+modifier states. */ KeySym *keysyms; gint maxlen = 0; gunichar unichar = 0; gint i = 0; gboolean retval = TRUE; const gchar *c; KeySym keysym; maxlen = strlen (keystring) + 1; keysyms = g_new0 (KeySym, maxlen); if (!(keystring && *keystring && g_utf8_validate (keystring, -1, &c))) { retval = FALSE; } else { #ifdef SPI_DEBUG fprintf (stderr, "[keystring synthesis attempted on %s]\n", keystring); #endif while (keystring && (unichar = g_utf8_get_char (keystring))) { char bytes[6]; gint mbytes; mbytes = g_unichar_to_utf8 (unichar, bytes); bytes[mbytes] = '\0'; #ifdef SPI_DEBUG fprintf (stderr, "[unichar %s]", bytes); #endif keysym = keysym_for_unichar (controller, unichar); if (keysym == NoSymbol) { #ifdef SPI_DEBUG fprintf (stderr, "no keysym for %s", bytes); #endif retval = FALSE; break; } keysyms[i++] = keysym; keystring = g_utf8_next_char (keystring); } keysyms[i++] = 0; XSynchronize (spi_get_display (), TRUE); for (i = 0; keysyms[i]; ++i) { if (!spi_dec_synth_keysym (controller, keysyms[i])) { #ifdef SPI_DEBUG fprintf (stderr, "could not synthesize %c\n", (int) keysyms[i]); #endif retval = FALSE; break; } } XSynchronize (spi_get_display (), FALSE); } g_free (keysyms); if (synth_type == Accessibility_KEY_SYM) { keysym = keycode; } else { keysym = XkbKeycodeToKeysym (spi_get_display (), keycode, 0, 0); } if (XkbKeysymToModifiers (spi_get_display (), keysym) == 0) { spi_dec_clear_unlatch_pending (controller); } return retval; }