Skip to content

Commit

Permalink
Wire up Compose support in libuterm
Browse files Browse the repository at this point in the history
Feed all key events into the Compose state and use the resulting
keysyms.
  • Loading branch information
viccie30 committed Feb 6, 2022
1 parent d4e3041 commit cb3effb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/uterm_input_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct uterm_input_dev {
char *node;
struct ev_fd *fd;
struct xkb_state *state;
struct xkb_compose_state *compose_state;
/* Used in sleep/wake up to store the key's pressed/released state. */
char key_state_bits[SHL_DIV_ROUND_UP(KEY_CNT, CHAR_BIT)];

Expand Down
38 changes: 38 additions & 0 deletions src/uterm_input_uxkb.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ int uxkb_dev_init(struct uterm_input_dev *dev)
goto err_timer;
}

if (dev->input->compose_table) {
dev->compose_state = xkb_compose_state_new(
dev->input->compose_table,
0);
if (!dev->compose_state)
llog_warn(dev->input, "cannot create compose state, "
"disabling compose support");
}

return 0;

err_timer:
Expand All @@ -251,6 +260,7 @@ int uxkb_dev_init(struct uterm_input_dev *dev)

void uxkb_dev_destroy(struct uterm_input_dev *dev)
{
xkb_compose_state_unref(dev->compose_state);
xkb_state_unref(dev->state);
ev_eloop_rm_timer(dev->repeat_timer);
}
Expand Down Expand Up @@ -427,19 +437,40 @@ int uxkb_dev_process(struct uterm_input_dev *dev,
uint16_t key_state, uint16_t code)
{
struct xkb_state *state;
struct xkb_compose_state *compose_state;
xkb_keycode_t keycode;
const xkb_keysym_t *keysyms;
xkb_keysym_t one_sym;
int num_keysyms, ret;
enum xkb_compose_status compose_status;
enum xkb_state_component changed;

if (key_state == KEY_REPEATED)
return -ENOKEY;

state = dev->state;
compose_state = dev->compose_state;
keycode = code + EVDEV_KEYCODE_OFFSET;

num_keysyms = xkb_state_key_get_syms(state, keycode, &keysyms);

one_sym = XKB_KEY_NoSymbol;
if (num_keysyms == 1) {
/* See: https://bugs.freedesktop.org/show_bug.cgi?id=67167 */
one_sym = xkb_state_key_get_one_sym(state, keycode);
keysyms = &one_sym;
}

compose_status = XKB_COMPOSE_NOTHING;
if (compose_state && key_state == KEY_PRESSED) {
/* XKB_KEY_NoSymbol cancels the current compose sequence. */
xkb_compose_state_feed(compose_state, one_sym);

compose_status = xkb_compose_state_get_status(compose_state);
if (compose_status == XKB_COMPOSE_COMPOSED)
one_sym = xkb_compose_state_get_one_sym(compose_state);
}

changed = 0;
if (key_state == KEY_PRESSED)
changed = xkb_state_update_key(state, keycode, XKB_KEY_DOWN);
Expand All @@ -452,6 +483,10 @@ int uxkb_dev_process(struct uterm_input_dev *dev,
if (num_keysyms <= 0)
return -ENOKEY;

if (compose_status == XKB_COMPOSE_COMPOSING ||
compose_status == XKB_COMPOSE_CANCELLED)
return -ENOKEY;

ret = uxkb_dev_fill_event(dev, &dev->event, keycode, num_keysyms,
keysyms);
if (ret)
Expand Down Expand Up @@ -524,4 +559,7 @@ void uxkb_dev_wake_up(struct uterm_input_dev *dev)
}

uxkb_dev_update_keyboard_leds(dev);

if (dev->compose_state)
xkb_compose_state_reset(dev->compose_state);
}

0 comments on commit cb3effb

Please sign in to comment.