static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { struct vo_wayland_state *wl = data; uint32_t code, num_syms; int mpkey; const xkb_keysym_t *syms; xkb_keysym_t sym; code = key + 8; num_syms = xkb_key_get_syms(wl->input.xkb.state, code, &syms); sym = XKB_KEY_NoSymbol; if (num_syms == 1) sym = syms[0]; if (sym != XKB_KEY_NoSymbol && (mpkey = lookupkey(sym))) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) mp_input_put_key(wl->vo->input_ctx, mpkey | MP_KEY_STATE_DOWN); else mp_input_put_key(wl->vo->input_ctx, mpkey | MP_KEY_STATE_UP); } }
static void input_method_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w) { struct simple_im *keyboard = data; uint32_t code; uint32_t num_syms; const xkb_keysym_t *syms; xkb_keysym_t sym; enum wl_keyboard_key_state state = state_w; if (!keyboard->state) return; code = key + 8; num_syms = xkb_key_get_syms(keyboard->state, code, &syms); sym = XKB_KEY_NoSymbol; if (num_syms == 1) sym = syms[0]; if (keyboard->key_handler) (*keyboard->key_handler)(keyboard, serial, time, key, sym, state); }
/* * _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent * @device: a ClutterInputDevice * @stage: the stage the event should be delivered to * @xkb: XKB rules to translate the event * @_time: timestamp of the event * @key: a key code coming from a Linux input device * @state: TRUE if a press event, FALSE if a release event * @modifer_state: in/out * * Translate @key to a #ClutterKeyEvent using rules from xbbcommon. * * Return value: the new #ClutterEvent */ ClutterEvent * _clutter_key_event_new_from_evdev (ClutterInputDevice *device, ClutterInputDevice *core_device, ClutterStage *stage, struct xkb_state *xkb_state, uint32_t button_state, uint32_t _time, xkb_keycode_t key, uint32_t state) { ClutterEvent *event; xkb_keysym_t sym; const xkb_keysym_t *syms; char buffer[8]; int n; if (state) event = clutter_event_new (CLUTTER_KEY_PRESS); else event = clutter_event_new (CLUTTER_KEY_RELEASE); /* We use a fixed offset of 8 because evdev starts KEY_* numbering from * 0, whereas X11's minimum keycode, for really stupid reasons, is 8. * So the evdev XKB rules are based on the keycodes all being shifted * upwards by 8. */ key += 8; n = xkb_key_get_syms (xkb_state, key, &syms); if (n == 1) sym = syms[0]; else sym = XKB_KEY_NoSymbol; event->key.device = core_device; event->key.stage = stage; event->key.time = _time; _clutter_xkb_translate_state (event, xkb_state, button_state); event->key.hardware_keycode = key; event->key.keyval = sym; clutter_event_set_source_device (event, device); n = xkb_keysym_to_utf8 (sym, buffer, sizeof (buffer)); if (n == 0) { /* not printable */ event->key.unicode_value = (gunichar) '\0'; } else { event->key.unicode_value = g_utf8_get_char_validated (buffer, n); if (event->key.unicode_value == -1 || event->key.unicode_value == -2) event->key.unicode_value = (gunichar) '\0'; } return event; }
static int uxkb_dev_process(struct kbd_dev *kbd, uint16_t key_state, uint16_t code, struct uterm_input_event *out) { struct xkb_state *state; struct xkb_keymap *keymap; xkb_keycode_t keycode; const xkb_keysym_t *keysyms; int num_keysyms; if (!kbd) return -EINVAL; state = kbd->uxkb.state; keymap = xkb_state_get_map(state); keycode = code + EVDEV_KEYCODE_OFFSET; num_keysyms = xkb_key_get_syms(state, keycode, &keysyms); if (key_state == KEY_PRESSED) xkb_state_update_key(state, keycode, XKB_KEY_DOWN); else if (key_state == KEY_RELEASED) xkb_state_update_key(state, keycode, XKB_KEY_UP); if (key_state == KEY_RELEASED) return -ENOKEY; if (key_state == KEY_REPEATED && !xkb_key_repeats(keymap, keycode)) return -ENOKEY; if (num_keysyms <= 0) return -ENOKEY; /* * TODO: xkbcommon actually supports multiple keysyms * per key press. Here we're just using the first one, * but we might want to support this feature. */ out->keycode = code; out->keysym = keysyms[0]; out->mods = shl_get_xkb_mods(state); out->unicode = xkb_keysym_to_utf32(out->keysym) ? : UTERM_INPUT_INVALID; return 0; }
static void keyboardHandleKey(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { uint32_t code, num_syms; long cp; int keyCode; int action; const xkb_keysym_t *syms; _GLFWwindow* window = _glfw.wl.keyboardFocus; if (!window) return; keyCode = toGLFWKeyCode(key); action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; _glfwInputKey(window, keyCode, key, action, _glfw.wl.xkb.modifiers); code = key + 8; num_syms = xkb_key_get_syms(_glfw.wl.xkb.state, code, &syms); if (num_syms == 1) { cp = _glfwKeySym2Unicode(syms[0]); if (cp != -1) { const int mods = _glfw.wl.xkb.modifiers; const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); _glfwInputChar(window, cp, mods, plain); } } }