From 5cefa5c5d09a89c902967c2ec5d4dcb3a6592781 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Wed, 29 Jan 2014 13:46:42 +0200 Subject: [PATCH] test/interactive-evdev: add compose support To try, do e.g.: sudo ./test/interactive-evdev -l us -v intl -o compose:ralt -d Signed-off-by: Ran Benita --- test/common.c | 43 +++++++++++++++++++++--------- test/interactive-evdev.c | 68 +++++++++++++++++++++++++++++++++++++++++------- test/interactive-x11.c | 2 +- test/test.h | 5 +++- 4 files changed, 94 insertions(+), 24 deletions(-) diff --git a/test/common.c b/test/common.c index e6cd1c3..0bacba0 100644 --- a/test/common.c +++ b/test/common.c @@ -347,14 +347,18 @@ test_compile_rules(struct xkb_context *context, const char *rules, } void -test_print_keycode_state(struct xkb_state *state, xkb_keycode_t keycode) +test_print_keycode_state(struct xkb_state *state, + struct xkb_compose_state *compose_state, + xkb_keycode_t keycode) { struct xkb_keymap *keymap; + xkb_keysym_t sym; const xkb_keysym_t *syms; int nsyms; char s[16]; xkb_layout_index_t layout; + enum xkb_compose_status status; keymap = xkb_state_get_keymap(state); @@ -363,21 +367,34 @@ test_print_keycode_state(struct xkb_state *state, xkb_keycode_t keycode) if (nsyms <= 0) return; - if (nsyms == 1) { - xkb_keysym_t sym = xkb_state_key_get_one_sym(state, keycode); - xkb_keysym_get_name(sym, s, sizeof(s)); - printf("keysym [ %-*s ] ", (int) sizeof(s), s); + status = XKB_COMPOSE_NOTHING; + if (compose_state) + status = xkb_compose_state_get_status(compose_state); + + if (status == XKB_COMPOSE_COMPOSING || status == XKB_COMPOSE_CANCELLED) + return; + + if (status == XKB_COMPOSE_COMPOSED) { + sym = xkb_compose_state_get_one_sym(compose_state); + syms = &sym; + nsyms = 1; } - else { - printf("keysyms [ "); - for (int i = 0; i < nsyms; i++) { - xkb_keysym_get_name(syms[i], s, sizeof(s)); - printf("%-*s ", (int) sizeof(s), s); - } - printf("] "); + else if (nsyms == 1) { + sym = xkb_state_key_get_one_sym(state, keycode); + syms = &sym; } - xkb_state_key_get_utf8(state, keycode, s, sizeof(s)); + printf("keysyms [ "); + for (int i = 0; i < nsyms; i++) { + xkb_keysym_get_name(syms[i], s, sizeof(s)); + printf("%-*s ", (int) sizeof(s), s); + } + printf("] "); + + if (status == XKB_COMPOSE_COMPOSED) + xkb_compose_state_get_utf8(compose_state, s, sizeof(s)); + else + xkb_state_key_get_utf8(state, keycode, s, sizeof(s)); printf("unicode [ %s ] ", s); layout = xkb_state_key_get_layout(state, keycode); diff --git a/test/interactive-evdev.c b/test/interactive-evdev.c index c3c4965..04a347f 100644 --- a/test/interactive-evdev.c +++ b/test/interactive-evdev.c @@ -40,12 +40,14 @@ struct keyboard { char *path; int fd; struct xkb_state *state; + struct xkb_compose_state *compose_state; struct keyboard *next; }; static bool terminate; static int evdev_offset = 8; static bool report_state_changes; +static bool with_compose; #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT) @@ -85,12 +87,13 @@ is_keyboard(int fd) static int keyboard_new(struct dirent *ent, struct xkb_keymap *keymap, - struct keyboard **out) + struct xkb_compose_table *compose_table, struct keyboard **out) { int ret; char *path; int fd; struct xkb_state *state; + struct xkb_compose_state *compose_state = NULL; struct keyboard *kbd; ret = asprintf(&path, "/dev/input/%s", ent->d_name); @@ -116,18 +119,31 @@ keyboard_new(struct dirent *ent, struct xkb_keymap *keymap, goto err_fd; } + if (with_compose) { + compose_state = xkb_compose_state_new(compose_table, + XKB_COMPOSE_STATE_NO_FLAGS); + if (!compose_state) { + fprintf(stderr, "Couldn't create compose state for %s\n", path); + ret = -EFAULT; + goto err_state; + } + } + kbd = calloc(1, sizeof(*kbd)); if (!kbd) { ret = -ENOMEM; - goto err_state; + goto err_compose_state; } kbd->path = path; kbd->fd = fd; kbd->state = state; + kbd->compose_state = compose_state; *out = kbd; return 0; +err_compose_state: + xkb_compose_state_unref(compose_state); err_state: xkb_state_unref(state); err_fd: @@ -146,6 +162,7 @@ keyboard_free(struct keyboard *kbd) close(kbd->fd); free(kbd->path); xkb_state_unref(kbd->state); + xkb_compose_state_unref(kbd->compose_state); free(kbd); } @@ -156,7 +173,8 @@ filter_device_name(const struct dirent *ent) } static struct keyboard * -get_keyboards(struct xkb_keymap *keymap) +get_keyboards(struct xkb_keymap *keymap, + struct xkb_compose_table *compose_table) { int ret, i, nents; struct dirent **ents; @@ -169,7 +187,7 @@ get_keyboards(struct xkb_keymap *keymap) } for (i = 0; i < nents; i++) { - ret = keyboard_new(ents[i], keymap, &kbd); + ret = keyboard_new(ents[i], keymap, compose_table, &kbd); if (ret) { if (ret == -EACCES) { fprintf(stderr, "Couldn't open /dev/input/%s: %s. " @@ -225,6 +243,7 @@ process_event(struct keyboard *kbd, uint16_t type, uint16_t code, int32_t value) xkb_keycode_t keycode; struct xkb_keymap *keymap; enum xkb_state_component changed; + enum xkb_compose_status status; if (type != EV_KEY) return; @@ -235,8 +254,19 @@ process_event(struct keyboard *kbd, uint16_t type, uint16_t code, int32_t value) if (value == KEY_STATE_REPEAT && !xkb_keymap_key_repeats(keymap, keycode)) return; + if (with_compose && value != KEY_STATE_RELEASE) { + xkb_keysym_t keysym = xkb_state_key_get_one_sym(kbd->state, keycode); + xkb_compose_state_feed(kbd->compose_state, keysym); + } + if (value != KEY_STATE_RELEASE) - test_print_keycode_state(kbd->state, keycode); + test_print_keycode_state(kbd->state, kbd->compose_state, keycode); + + if (with_compose) { + status = xkb_compose_state_get_status(kbd->compose_state); + if (status == XKB_COMPOSE_CANCELLED || status == XKB_COMPOSE_COMPOSED) + xkb_compose_state_reset(kbd->compose_state); + } if (value == KEY_STATE_RELEASE) changed = xkb_state_update_key(kbd->state, keycode, XKB_KEY_UP); @@ -339,17 +369,19 @@ main(int argc, char *argv[]) struct keyboard *kbds; struct xkb_context *ctx; struct xkb_keymap *keymap; + struct xkb_compose_table *compose_table = NULL; const char *rules = NULL; const char *model = NULL; const char *layout = NULL; const char *variant = NULL; const char *options = NULL; const char *keymap_path = NULL; + const char *locale; struct sigaction act; setlocale(LC_ALL, ""); - while ((opt = getopt(argc, argv, "r:m:l:v:o:k:n:c")) != -1) { + while ((opt = getopt(argc, argv, "r:m:l:v:o:k:n:cd")) != -1) { switch (opt) { case 'r': rules = optarg; @@ -380,6 +412,9 @@ main(int argc, char *argv[]) case 'c': report_state_changes = true; break; + case 'd': + with_compose = true; + break; case '?': fprintf(stderr, " Usage: %s [-r ] [-m ] " "[-l ] [-v ] [-o ]\n", @@ -387,7 +422,8 @@ main(int argc, char *argv[]) fprintf(stderr, " or: %s -k \n", argv[0]); fprintf(stderr, "For both: -n \n" - " -c (to report changes to the state)\n"); + " -c (to report changes to the state)\n" + " -d (to enable compose)\n"); exit(2); } } @@ -422,10 +458,22 @@ main(int argc, char *argv[]) goto err_ctx; } - kbds = get_keyboards(keymap); + if (with_compose) { + locale = setlocale(LC_CTYPE, NULL); + compose_table = + xkb_compose_table_new_from_locale(ctx, locale, + XKB_COMPOSE_COMPILE_NO_FLAGS); + if (!compose_table) { + ret = -1; + fprintf(stderr, "Couldn't create compose from locale\n"); + goto err_xkb; + } + } + + kbds = get_keyboards(keymap, compose_table); if (!kbds) { ret = -1; - goto err_xkb; + goto err_compose; } act.sa_handler = sigintr_handler; @@ -444,6 +492,8 @@ main(int argc, char *argv[]) err_stty: system("stty echo"); free_keyboards(kbds); +err_compose: + xkb_compose_table_unref(compose_table); err_xkb: xkb_keymap_unref(keymap); err_ctx: diff --git a/test/interactive-x11.c b/test/interactive-x11.c index 8679dda..d720004 100644 --- a/test/interactive-x11.c +++ b/test/interactive-x11.c @@ -236,7 +236,7 @@ process_event(xcb_generic_event_t *gevent, struct keyboard *kbd) xcb_key_press_event_t *event = (xcb_key_press_event_t *) gevent; xkb_keycode_t keycode = event->detail; - test_print_keycode_state(kbd->state, keycode); + test_print_keycode_state(kbd->state, NULL, keycode); /* Exit on ESC. */ if (keycode == 9) diff --git a/test/test.h b/test/test.h index d0104ce..628ec18 100644 --- a/test/test.h +++ b/test/test.h @@ -28,6 +28,7 @@ /* Don't use compat names in internal code. */ #define _XKBCOMMON_COMPAT_H #include "xkbcommon/xkbcommon.h" +#include "xkbcommon/xkbcommon-compose.h" #include "utils.h" /* Automake test exit code to signify SKIP (à la PASS, FAIL, etc). */ @@ -81,7 +82,9 @@ test_compile_rules(struct xkb_context *context, const char *rules, const char *options); void -test_print_keycode_state(struct xkb_state *state, xkb_keycode_t keycode); +test_print_keycode_state(struct xkb_state *state, + struct xkb_compose_state *compose_state, + xkb_keycode_t keycode); void test_print_state_changes(enum xkb_state_component changed); -- 2.7.4