diff --git a/input.c b/input.c index 30353661..d8fbd4cd 100644 --- a/input.c +++ b/input.c @@ -4,10 +4,12 @@ #include #include #include +#include #include #include #include +#include #define LOG_MODULE "input" #define LOG_ENABLE_DBG 0 @@ -37,6 +39,12 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, term->kbd.mod_alt = xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Mod1") ; term->kbd.mod_ctrl = xkb_keymap_mod_get_index(term->kbd.xkb_keymap, "Control"); + /* Compose (dead keys) */ + term->kbd.xkb_compose_table = xkb_compose_table_new_from_locale( + term->kbd.xkb, setlocale(LC_CTYPE, NULL), XKB_COMPOSE_COMPILE_NO_FLAGS); + term->kbd.xkb_compose_state = xkb_compose_state_new( + term->kbd.xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS); + munmap(map_str, size); close(fd); } @@ -172,6 +180,13 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, key += 8; xkb_keysym_t sym = xkb_state_key_get_one_sym(term->kbd.xkb_state, key); + xkb_compose_state_feed(term->kbd.xkb_compose_state, sym); + enum xkb_compose_status compose_status = xkb_compose_state_get_status( + term->kbd.xkb_compose_state); + + if (compose_status == XKB_COMPOSE_COMPOSING) + return; + xkb_mod_mask_t mods = xkb_state_serialize_mods( term->kbd.xkb_state, XKB_STATE_MODS_DEPRESSED); //xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods(term->kbd.xkb_state, key); @@ -221,11 +236,18 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, } else if (sym == XKB_KEY_Escape){ write(term->ptmx, "\x1b", 1); } else { - /* TODO: composing */ char buf[64] = {0}; - int count = xkb_state_key_get_utf8( - term->kbd.xkb_state, key, buf, sizeof(buf)); + int count = 0; + + if (compose_status == XKB_COMPOSE_COMPOSED) { + count = xkb_compose_state_get_utf8( + term->kbd.xkb_compose_state, buf, sizeof(buf)); + xkb_compose_state_reset(term->kbd.xkb_compose_state); + } else { + count = xkb_state_key_get_utf8( + term->kbd.xkb_state, key, buf, sizeof(buf)); + } if (count > 0) { if (effective_mods & alt) diff --git a/main.c b/main.c index 8efade1a..4dd6afbc 100644 --- a/main.c +++ b/main.c @@ -13,6 +13,7 @@ #include #include #include +#include #define LOG_MODULE "main" #define LOG_ENABLE_DBG 0 @@ -612,6 +613,10 @@ out: wl_registry_destroy(term.wl.registry); if (term.wl.display != NULL) wl_display_disconnect(term.wl.display); + if (term.kbd.xkb_compose_state != NULL) + xkb_compose_state_unref(term.kbd.xkb_compose_state); + if (term.kbd.xkb_compose_table != NULL) + xkb_compose_table_unref(term.kbd.xkb_compose_table); if (term.kbd.xkb_keymap != NULL) xkb_keymap_unref(term.kbd.xkb_keymap); if (term.kbd.xkb_state != NULL) diff --git a/terminal.h b/terminal.h index a0ad718a..5dd0db09 100644 --- a/terminal.h +++ b/terminal.h @@ -145,6 +145,8 @@ struct kbd { struct xkb_context *xkb; struct xkb_keymap *xkb_keymap; struct xkb_state *xkb_state; + struct xkb_compose_table *xkb_compose_table; + struct xkb_compose_state *xkb_compose_state; struct { mtx_t mutex; cnd_t cond;