return;
if (UTERM_INPUT_HAS_MODS(ev, kmscon_conf.grab_scroll_up->mods) &&
- ev->keysym == kmscon_conf.grab_scroll_up->keysym) {
+ ev->keysyms[0] == kmscon_conf.grab_scroll_up->keysym) {
tsm_screen_sb_up(term->console, 1);
schedule_redraw(term);
ev->handled = true;
return;
}
if (UTERM_INPUT_HAS_MODS(ev, kmscon_conf.grab_scroll_down->mods) &&
- ev->keysym == kmscon_conf.grab_scroll_down->keysym) {
+ ev->keysyms[0] == kmscon_conf.grab_scroll_down->keysym) {
tsm_screen_sb_down(term->console, 1);
schedule_redraw(term);
ev->handled = true;
return;
}
if (UTERM_INPUT_HAS_MODS(ev, kmscon_conf.grab_page_up->mods) &&
- ev->keysym == kmscon_conf.grab_page_up->keysym) {
+ ev->keysyms[0] == kmscon_conf.grab_page_up->keysym) {
tsm_screen_sb_page_up(term->console, 1);
schedule_redraw(term);
ev->handled = true;
return;
}
if (UTERM_INPUT_HAS_MODS(ev, kmscon_conf.grab_page_down->mods) &&
- ev->keysym == kmscon_conf.grab_page_down->keysym) {
+ ev->keysyms[0] == kmscon_conf.grab_page_down->keysym) {
tsm_screen_sb_page_down(term->console, 1);
schedule_redraw(term);
ev->handled = true;
return;
}
- if (tsm_vte_handle_keyboard(term->vte, ev->keysym, ev->mods,
- ev->unicode)) {
+ /* TODO: xkbcommon supports multiple keysyms, but it is currently
+ * unclear how this feature will be used. There is no keymap, which
+ * uses this, yet. */
+ if (ev->num_syms > 1)
+ return;
+
+ if (tsm_vte_handle_keyboard(term->vte, ev->keysyms[0], ev->mods,
+ ev->codepoints[0])) {
tsm_screen_sb_reset(term->console);
schedule_redraw(term);
ev->handled = true;
#define UTERM_INPUT_INVALID 0xffffffff
struct uterm_input_event {
- bool handled;
+ bool handled; /* user-controlled, default is false */
uint16_t keycode; /* linux keycode - KEY_* - linux/input.h */
- uint32_t keysym; /* X keysym - XKB_KEY_* - X11/keysym.h */
unsigned int mods; /* active modifiers - uterm_modifier mask */
- uint32_t unicode; /* ucs4 unicode value or UTERM_INPUT_INVALID */
+
+ unsigned int num_syms; /* number of keysyms */
+ uint32_t *keysyms; /* XKB-common keysym-array - XKB_KEY_* */
+ uint32_t *codepoints; /* ucs4 unicode value or UTERM_INPUT_INVALID */
};
#define UTERM_INPUT_HAS_MODS(_ev, _mods) (((_ev)->mods & (_mods)) == (_mods))
int32_t value)
{
int ret;
- struct uterm_input_event ev;
if (type != EV_KEY)
return;
- memset(&ev, 0, sizeof(ev));
- ret = uxkb_dev_process(dev, value, code, &ev);
+ ret = uxkb_dev_process(dev, value, code);
if (ret)
return;
- shl_hook_call(dev->input->hook, dev->input, &ev);
+ shl_hook_call(dev->input->hook, dev->input, &dev->event);
}
static void input_data_dev(struct ev_fd *fd, int mask, void *data)
if (!dev->node)
goto err_free;
+ dev->num_syms = 1;
+ dev->event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
+ if (!dev->event.keysyms)
+ goto err_node;
+ dev->event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
+ if (!dev->event.codepoints)
+ goto err_syms;
+
ret = uxkb_dev_init(dev);
if (ret)
- goto err_node;
+ goto err_codepoints;
if (input->awake > 0) {
ret = input_wake_up_dev(dev);
err_kbd:
uxkb_dev_destroy(dev);
+err_codepoints:
+ free(dev->event.codepoints);
+err_syms:
+ free(dev->event.keysyms);
err_node:
free(dev->node);
err_free:
input_sleep_dev(dev);
shl_dlist_unlink(&dev->list);
uxkb_dev_destroy(dev);
+ free(dev->event.codepoints);
+ free(dev->event.keysyms);
free(dev->node);
free(dev);
}
char *node;
struct ev_fd *fd;
struct xkb_state *state;
+
+ struct uterm_input_event event;
+ unsigned int num_syms;
};
struct uterm_input {
void uxkb_dev_destroy(struct uterm_input_dev *dev);
int uxkb_dev_process(struct uterm_input_dev *dev,
uint16_t key_state,
- uint16_t code,
- struct uterm_input_event *out);
+ uint16_t code);
void uxkb_dev_reset(struct uterm_input_dev *dev, const unsigned long *ledbits);
#endif /* UTERM_INPUT_H */
};
int uxkb_dev_process(struct uterm_input_dev *dev,
- uint16_t key_state,
- uint16_t code,
- struct uterm_input_event *out)
+ uint16_t key_state, uint16_t code)
{
struct xkb_state *state;
struct xkb_keymap *keymap;
xkb_keycode_t keycode;
const xkb_keysym_t *keysyms;
- int num_keysyms;
+ int num_keysyms, i;
+ uint32_t *tmp;
state = dev->state;
keymap = xkb_state_get_map(state);
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;
+ if (dev->num_syms < num_keysyms) {
+ tmp = realloc(dev->event.keysyms,
+ sizeof(uint32_t) * num_keysyms);
+ if (!tmp) {
+ log_warning("cannot reallocate keysym buffer");
+ return -ENOKEY;
+ }
+ dev->event.keysyms = tmp;
+
+ tmp = realloc(dev->event.codepoints,
+ sizeof(uint32_t) * num_keysyms);
+ if (!tmp) {
+ log_warning("cannot reallocate codepoints buffer");
+ return -ENOKEY;
+ }
+ dev->event.codepoints = tmp;
+
+ dev->num_syms = num_keysyms;
+ }
+
+ dev->event.handled = false;
+ dev->event.keycode = code;
+ dev->event.mods = shl_get_xkb_mods(state);
+ dev->event.num_syms = num_keysyms;
+ memcpy(dev->event.keysyms, keysyms, sizeof(uint32_t) * num_keysyms);
+
+ for (i = 0; i < num_keysyms; ++i) {
+ dev->event.codepoints[i] = xkb_keysym_to_utf32(keysyms[i]);
+ if (!dev->event.codepoints[i])
+ dev->event.codepoints[i] = UTERM_INPUT_INVALID;
+ }
return 0;
}
id = 0;
if (SHL_HAS_BITS(ev->mods, SHL_CONTROL_MASK | SHL_ALT_MASK) &&
- ev->keysym >= XKB_KEY_F1 && ev->keysym <= XKB_KEY_F12) {
+ ev->keysyms[0] >= XKB_KEY_F1 && ev->keysyms[0] <= XKB_KEY_F12) {
ev->handled = true;
- id = ev->keysym - XKB_KEY_F1 + 1;
+ id = ev->keysyms[0] - XKB_KEY_F1 + 1;
if (id == vt->real_num)
return;
- } else if (ev->keysym >= XKB_KEY_XF86Switch_VT_1 &&
- ev->keysym <= XKB_KEY_XF86Switch_VT_12) {
+ } else if (ev->keysyms[0] >= XKB_KEY_XF86Switch_VT_1 &&
+ ev->keysyms[0] <= XKB_KEY_XF86Switch_VT_12) {
ev->handled = true;
- id = ev->keysym - XKB_KEY_XF86Switch_VT_1 + 1;
+ id = ev->keysyms[0] - XKB_KEY_XF86Switch_VT_1 + 1;
if (id == vt->real_num)
return;
}
return;
if (SHL_HAS_BITS(ev->mods, SHL_CONTROL_MASK | SHL_LOGO_MASK) &&
- ev->keysym == XKB_KEY_F12) {
+ ev->keysyms[0] == XKB_KEY_F12) {
ev->handled = true;
if (vt->active) {
log_debug("deactivating fake VT due to user input");