KeySym XkbKeycodeToKeysym(Display *dpy, #if NeedWidePrototypes unsigned int kc, #else KeyCode kc, #endif int group, int level) { XkbDescRec *xkb; if (_XkbUnavailable(dpy)) return NoSymbol; _XkbCheckPendingRefresh(dpy,dpy->xkb_info); xkb = dpy->xkb_info->desc; if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) return NoSymbol; if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc))) return NoSymbol; if (level>=XkbKeyGroupWidth(xkb,kc,group)) { /* for compatibility with the core protocol, _always_ allow */ /* two symbols in the first two groups. If either of the */ /* two is of type ONE_LEVEL, just replicate the first symbol */ if ((group>XkbGroup2Index)||(XkbKeyGroupWidth(xkb,kc,group)!=1)|| (level!=1)) { return NoSymbol; } level= 0; } return XkbKeySymEntry(xkb,kc,level,group); }
KeySym XKeycodeToKeysym(Display *dpy, #if NeedWidePrototypes unsigned int kc, #else KeyCode kc, #endif int col) { XkbDescRec *xkb; if (_XkbUnavailable(dpy)) return _XKeycodeToKeysym(dpy, kc, col); _XkbCheckPendingRefresh(dpy,dpy->xkb_info); xkb = dpy->xkb_info->desc; if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code)) return NoSymbol; if (col>3) { int lastSym,tmp,nGrp; lastSym= 3; nGrp= XkbKeyNumGroups(xkb,kc); if ((nGrp>0)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup1Index))>2)) { if (col<=(lastSym+tmp-2)) return XkbKeycodeToKeysym(dpy,kc,XkbGroup1Index,col-lastSym+2); lastSym+= tmp-2; } if ((nGrp>1)&&((tmp=XkbKeyGroupWidth(xkb,kc,XkbGroup2Index))>2)) { if (col<=(lastSym+tmp-2)) return XkbKeycodeToKeysym(dpy,kc,XkbGroup2Index,col-lastSym+2); lastSym+= tmp-2; } if (nGrp>2) { tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup3Index); if (col<=lastSym+tmp) return XkbKeycodeToKeysym(dpy,kc,XkbGroup3Index,col-lastSym); lastSym+= tmp; } if (nGrp>3) { tmp= XkbKeyGroupWidth(xkb,kc,XkbGroup4Index); if (col<=lastSym+tmp) return XkbKeycodeToKeysym(dpy,kc,XkbGroup4Index,col-lastSym); } return NoSymbol; } return XkbKeycodeToKeysym(dpy,kc,(col>>1),(col&1)); }
static void window_handle_key(void *data, struct wl_input_device *input_device, uint32_t time, uint32_t key, uint32_t state) { struct input *input = data; struct window *window = input->keyboard_focus; struct display *d = window->display; uint32_t code, sym, level; code = key + d->xkb->min_key_code; if (window->keyboard_device != input) return; level = 0; if (input->modifiers & XKB_COMMON_SHIFT_MASK && XkbKeyGroupWidth(d->xkb, code, 0) > 1) level = 1; sym = XkbKeySymEntry(d->xkb, code, level, 0); if (state) input->modifiers |= d->xkb->map->modmap[code]; else input->modifiers &= ~d->xkb->map->modmap[code]; if (window->key_handler) (*window->key_handler)(window, input, time, key, sym, state, window->user_data); }
void QWaylandInputDevice::inputHandleKey(void *data, struct wl_input_device *input_device, uint32_t time, uint32_t key, uint32_t state) { #ifndef QT_NO_WAYLAND_XKB Q_UNUSED(input_device); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mKeyboardFocus; uint32_t code, sym, level; Qt::KeyboardModifiers modifiers; QEvent::Type type; char s[2]; if (window == NULL) { /* We destroyed the keyboard focus surface, but the server * didn't get the message yet. */ return; } code = key + inputDevice->mXkb->min_key_code; level = 0; if (inputDevice->mModifiers & Qt::ShiftModifier && XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1) level = 1; sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0); modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]); if (state) { inputDevice->mModifiers |= modifiers; type = QEvent::KeyPress; } else { inputDevice->mModifiers &= ~modifiers; type = QEvent::KeyRelease; } sym = translateKey(sym, s, sizeof s); if (window) { QWindowSystemInterface::handleKeyEvent(window->widget(), time, type, sym, inputDevice->mModifiers, QString::fromLatin1(s)); } #endif }
XKB_EXPORT void xkb_keymap_unref(struct xkb_keymap *keymap) { if (!keymap || --keymap->refcnt > 0) return; if (keymap->keys) { struct xkb_key *key; xkb_keys_foreach(key, keymap) { if (key->groups) { for (unsigned i = 0; i < key->num_groups; i++) { if (key->groups[i].levels) { for (unsigned j = 0; j < XkbKeyGroupWidth(key, i); j++) if (key->groups[i].levels[j].num_syms > 1) free(key->groups[i].levels[j].u.syms); free(key->groups[i].levels); } } free(key->groups); } } free(keymap->keys); } if (keymap->types) { for (unsigned i = 0; i < keymap->num_types; i++) { free(keymap->types[i].entries); free(keymap->types[i].level_names); } free(keymap->types); } free(keymap->sym_interprets); free(keymap->key_aliases); free(keymap->group_names); free(keymap->keycodes_section_name); free(keymap->symbols_section_name); free(keymap->types_section_name); free(keymap->compat_section_name); xkb_context_unref(keymap->ctx); free(keymap); }
void handle_key(struct xkb_desc *xkb, struct input_event *evp, uint32_t *modifiers) { uint32_t code = evp->code + xkb->min_key_code; uint32_t level = 0; uint32_t sym; if ((*modifiers & XKB_COMMON_SHIFT_MASK) && XkbKeyGroupWidth(xkb, code, 0) > 1) level = 1; sym = XkbKeySymEntry(xkb, code, level, 0); if (evp->value) *modifiers |= xkb->map->modmap[code]; else *modifiers &= xkb->map->modmap[code]; printf("Code: %d, Sym: %d, Modifiers: %d, Ascii: %c, State: %s\n", evp->code, sym, *modifiers, sym, evp->value ? "up" : "down"); }
void KeyboardLayoutWidget::drawKeyLabel(QPainter* painter, uint keycode, int angle, int xkb_origin_x, int xkb_origin_y, int xkb_width, int xkb_height, bool is_pressed) { int x, y, width, height; int padding; int g, l, glp; if (!xkb) return; padding = 23 * ratio; /* 2.3mm */ x = xkbToPixmapCoord (xkb_origin_x); y = xkbToPixmapCoord (xkb_origin_y); width = xkbToPixmapCoord (xkb_origin_x + xkb_width) - x; height = xkbToPixmapCoord (xkb_origin_y + xkb_height) - y; for (glp = KEYBOARD_DRAWING_POS_TOPLEFT; glp < KEYBOARD_DRAWING_POS_TOTAL; glp++) { if (groupLevels[glp] == NULL) continue; g = groupLevels[glp]->group; l = groupLevels[glp]->level; if (g < 0 || g >= XkbKeyNumGroups (xkb, keycode)) continue; if (l < 0 || l >= XkbKeyGroupWidth (xkb, keycode, g)) continue; /* Skip "exotic" levels like the "Ctrl" level in PC_SYSREQ */ if (l > 0) { uint mods = XkbKeyKeyType (xkb, keycode, g)->mods.mask; if ((mods & (ShiftMask | l3mod)) == 0) continue; } if (trackModifiers) { uint mods_rtrn; KeySym keysym; if (XkbTranslateKeyCode (xkb, keycode, XkbBuildCoreState(mods, g), &mods_rtrn, &keysym)) { drawKeyLabelHelper (painter, keysym, angle, glp, x, y, width, height, padding, is_pressed); /* reverse y order */ } } else { KeySym keysym; keysym = XkbKeySymEntry (xkb, keycode, l, g); drawKeyLabelHelper (painter, keysym, angle, glp, x, y, width, height, padding, is_pressed); /* reverse y order */ } } }