static int uxkb_dev_fill_event(struct uterm_input_dev *dev, struct uterm_input_event *ev, xkb_keycode_t code, int num_syms, const xkb_keysym_t *syms) { int ret, i; ret = uxkb_dev_resize_event(dev, num_syms); if (ret) return ret; ev->keycode = code; ev->ascii = shl_get_ascii(dev->state, code, syms, num_syms); ev->mods = shl_get_xkb_mods(dev->state); ev->num_syms = num_syms; memcpy(ev->keysyms, syms, sizeof(uint32_t) * num_syms); for (i = 0; i < num_syms; ++i) { ev->codepoints[i] = xkb_keysym_to_utf32(syms[i]); if (!ev->codepoints[i]) ev->codepoints[i] = UTERM_INPUT_INVALID; } return 0; }
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; }