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 clutter_wayland_handle_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t _time, uint32_t key, uint32_t state) { ClutterInputDeviceWayland *device = data; ClutterStageCogl *stage_cogl = device->keyboard_focus; ClutterEvent *event; if (!device->xkb) return; event = _clutter_key_event_new_from_evdev ((ClutterInputDevice *) device, stage_cogl->wrapper, device->xkb, _time, key, state); _clutter_event_push (event, FALSE); if (!xkb_key_repeats (xkb_state_get_map (device->xkb), key)) return; if (state) { if (device->repeat_key != XKB_KEYCODE_INVALID) g_source_remove (device->repeat_source); device->repeat_key = key; device->repeat_time = _time + KEY_REPEAT_DELAY; device->repeat_source = g_timeout_add (KEY_REPEAT_DELAY, clutter_wayland_repeat_key, device); device->is_initial_repeat = TRUE; } else if (device->repeat_key == key) { g_source_remove (device->repeat_source); device->repeat_key = XKB_KEYCODE_INVALID; } }