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); }
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); }
/* the code to retrieve the keymap direction and cache it * is taken from GDK: * gdk/x11/gdkkeys-x11.c */ static PangoDirection get_direction (XkbDescPtr xkb, int group) { int rtl_minus_ltr = 0; /* total number of RTL keysyms minus LTR ones */ int code; for (code = xkb->min_key_code; code <= xkb->max_key_code; code += 1) { int level = 0; KeySym sym = XkbKeySymEntry (xkb, code, level, group); PangoDirection dir = pango_unichar_direction (clutter_keysym_to_unicode (sym)); switch (dir) { case PANGO_DIRECTION_RTL: rtl_minus_ltr++; break; case PANGO_DIRECTION_LTR: rtl_minus_ltr--; break; default: break; } } if (rtl_minus_ltr > 0) return PANGO_DIRECTION_RTL; return PANGO_DIRECTION_LTR; }
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 }
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 */ } } }