static ClutterTranslateReturn clutter_keymap_x11_translate_event (ClutterEventTranslator *translator, gpointer native, ClutterEvent *event) { ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (translator); ClutterBackendX11 *backend_x11; ClutterTranslateReturn retval; XEvent *xevent; backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); if (!backend_x11->use_xkb) return CLUTTER_TRANSLATE_CONTINUE; xevent = native; retval = CLUTTER_TRANSLATE_CONTINUE; #ifdef HAVE_XKB if (xevent->type == keymap_x11->xkb_event_base) { XkbEvent *xkb_event = (XkbEvent *) xevent; switch (xkb_event->any.xkb_type) { case XkbStateNotify: CLUTTER_NOTE (EVENT, "Updating keyboard state"); update_direction (keymap_x11, XkbStateGroup (&xkb_event->state)); update_locked_mods (keymap_x11, xkb_event->state.locked_mods); retval = CLUTTER_TRANSLATE_REMOVE; break; case XkbNewKeyboardNotify: case XkbMapNotify: CLUTTER_NOTE (EVENT, "Updating keyboard mapping"); XkbRefreshKeyboardMapping (&xkb_event->map); backend_x11->keymap_serial += 1; retval = CLUTTER_TRANSLATE_REMOVE; break; default: break; } } #endif /* HAVE_XKB */ return retval; }
void XWindow::OnKeymap(WindowEventKeymap *e) { XkbRefreshKeyboardMapping(e->Handle()); DelegationOnKeymap().Execute(e); }
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; }