static void print_keycode(struct keyboard *kbd, xkb_keycode_t keycode) { unsigned int i; struct xkb_keymap *keymap; struct xkb_state *state; const xkb_keysym_t *syms; unsigned int nsyms; char s[16]; uint32_t unicode; xkb_layout_index_t layout; xkb_mod_index_t mod; xkb_led_index_t led; state = kbd->state; keymap = xkb_state_get_keymap(state); nsyms = xkb_state_key_get_syms(state, keycode, &syms); if (nsyms <= 0) return; printf("keysyms [ "); for (i = 0; i < nsyms; i++) { xkb_keysym_get_name(syms[i], s, sizeof(s)); printf("%-*s ", (int)sizeof(s), s); } printf("] "); /* * Only do this if wchar_t is UCS-4, so we can be lazy and print * with %lc. */ #ifdef __STDC_ISO_10646__ printf("unicode [ "); for (i = 0; i < nsyms; i++) { unicode = xkb_keysym_to_utf32(syms[i]); printf("%lc ", (int)(unicode ? unicode : L' ')); } printf("] "); #endif layout = xkb_state_key_get_layout(state, keycode); printf("layout [ %s (%d) ] ", xkb_keymap_layout_get_name(keymap, layout), layout); printf("level [ %d ] ", xkb_state_key_get_level(state, keycode, layout)); printf("mods [ "); for (mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) { if (xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_EFFECTIVE) <= 0) continue; if (xkb_state_mod_index_is_consumed(state, keycode, mod)) printf("-%s ", xkb_keymap_mod_get_name(keymap, mod)); else printf("%s ", xkb_keymap_mod_get_name(keymap, mod)); } printf("] "); printf("leds [ "); for (led = 0; led < xkb_keymap_num_leds(keymap); led++) { if (xkb_state_led_index_is_active(state, led) <= 0) continue; printf("%s ", xkb_keymap_led_get_name(keymap, led)); } printf("] "); printf("\n"); }
static void test_ctrl_string_transformation(struct xkb_keymap *keymap) { char buf[256]; struct xkb_state *state = xkb_state_new(keymap); xkb_mod_index_t ctrl; assert(state); /* See xkb_state_key_get_utf8() for what's this all about. */ ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL); assert(ctrl != XKB_MOD_INVALID); /* First without. */ TEST_KEY(KEY_A, "a", 0x61); TEST_KEY(KEY_B, "b", 0x62); TEST_KEY(KEY_C, "c", 0x63); TEST_KEY(KEY_ESC, "\x1B", 0x1B); TEST_KEY(KEY_1, "1", 0x31); /* And with. */ xkb_state_update_key(state, KEY_RIGHTCTRL + EVDEV_OFFSET, XKB_KEY_DOWN); assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0); TEST_KEY(KEY_A, "\x01", 0x01); TEST_KEY(KEY_B, "\x02", 0x02); TEST_KEY(KEY_C, "\x03", 0x03); TEST_KEY(KEY_ESC, "\x1B", 0x1B); TEST_KEY(KEY_1, "1", 0x31); xkb_state_update_key(state, KEY_RIGHTCTRL + EVDEV_OFFSET, XKB_KEY_UP); /* Switch to ru layout */ xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_DOWN); xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_UP); assert(xkb_state_key_get_layout(state, KEY_A + 8) == 1); /* Non ASCII. */ xkb_state_update_key(state, KEY_RIGHTCTRL + EVDEV_OFFSET, XKB_KEY_DOWN); assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0); TEST_KEY(KEY_A, "\x01", 0x01); TEST_KEY(KEY_B, "\x02", 0x02); xkb_state_update_key(state, KEY_RIGHTCTRL + EVDEV_OFFSET, XKB_KEY_UP); xkb_state_unref(state); }
static void test_get_utf8_utf32(struct xkb_keymap *keymap) { char buf[256]; struct xkb_state *state = xkb_state_new(keymap); assert(state); #define TEST_KEY(key, expected_utf8, expected_utf32) do { \ assert(xkb_state_key_get_utf8(state, key + 8, NULL, 0) == strlen(expected_utf8)); \ assert(xkb_state_key_get_utf8(state, key + 8, buf, sizeof(buf)) == strlen(expected_utf8)); \ assert(memcmp(buf, expected_utf8, sizeof(expected_utf8)) == 0); \ assert(xkb_state_key_get_utf32(state, key + 8) == expected_utf32); \ } while (0) /* Simple ASCII. */ TEST_KEY(KEY_A, "a", 0x61); TEST_KEY(KEY_ESC, "\x1B", 0x1B); TEST_KEY(KEY_1, "1", 0x31); /* Invalid. */ TEST_KEY(XKB_KEYCODE_INVALID - 8, "", 0); TEST_KEY(300, "", 0); /* No string. */ TEST_KEY(KEY_LEFTCTRL, "", 0); TEST_KEY(KEY_NUMLOCK, "", 0); /* Multiple keysyms. */ TEST_KEY(KEY_6, "HELLO", 0); TEST_KEY(KEY_7, "YES THIS IS DOG", 0); /* Check truncation. */ memset(buf, 'X', sizeof(buf)); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 0) == strlen("HELLO")); assert(memcmp(buf, "X", 1) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 1) == strlen("HELLO")); assert(memcmp(buf, "", 1) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 2) == strlen("HELLO")); assert(memcmp(buf, "H", 2) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 3) == strlen("HELLO")); assert(memcmp(buf, "HE", 3) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 5) == strlen("HELLO")); assert(memcmp(buf, "HELL", 5) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 6) == strlen("HELLO")); assert(memcmp(buf, "HELLO", 6) == 0); assert(xkb_state_key_get_utf8(state, KEY_6 + 8, buf, 7) == strlen("HELLO")); assert(memcmp(buf, "HELLO\0X", 7) == 0); /* Switch to ru layout */ xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_DOWN); xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_UP); assert(xkb_state_key_get_layout(state, KEY_A + 8) == 1); /* Non ASCII. */ TEST_KEY(KEY_ESC, "\x1B", 0x1B); TEST_KEY(KEY_A, "ф", 0x0444); TEST_KEY(KEY_Z, "я", 0x044F); /* Switch back to us layout */ xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_DOWN); xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_UP); assert(xkb_state_key_get_layout(state, KEY_A + 8) == 0); xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_DOWN); TEST_KEY(KEY_A, "A", 0x41); TEST_KEY(KEY_ESC, "\x1B", 0x1B); TEST_KEY(KEY_1, "!", 0x21); xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_UP); TEST_KEY(KEY_6, "HELLO", 0); TEST_KEY(KEY_7, "YES THIS IS DOG", 0); xkb_state_unref(state); }
static void test_caps_keysym_transformation(struct xkb_keymap *keymap) { struct xkb_state *state = xkb_state_new(keymap); xkb_mod_index_t caps, shift; int nsyms; xkb_keysym_t sym; const xkb_keysym_t *syms; assert(state); /* See xkb_state_key_get_one_sym() for what's this all about. */ caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS); shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT); assert(caps != XKB_MOD_INVALID && shift != XKB_MOD_INVALID); assert(xkb_state_key_get_layout(state, KEY_A + 8) == 0); assert(xkb_state_key_get_layout(state, KEY_SEMICOLON + 8) == 0); /* Without caps, no transformation. */ assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) == 0); assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0); assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 0); sym = xkb_state_key_get_one_sym(state, KEY_A + 8); assert(sym == XKB_KEY_a); assert(xkb_state_key_get_level(state, KEY_SEMICOLON + 8, 0) == 0); sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8); assert(sym == XKB_KEY_eacute); nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms); assert(nsyms == 1 && syms[0] == XKB_KEY_eacute); /* With shift, no transformation (only different level). */ xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_DOWN); assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) == 0); assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) > 0); assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 1); sym = xkb_state_key_get_one_sym(state, KEY_A + 8); assert(sym == XKB_KEY_A); sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8); assert(sym == XKB_KEY_odiaeresis); nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms); assert(nsyms == 1 && syms[0] == XKB_KEY_odiaeresis); xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_UP); assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0); /* With caps, transform in same level, only with _get_one_sym(). */ xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_DOWN); xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_UP); assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0); assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0); assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 1); sym = xkb_state_key_get_one_sym(state, KEY_A + 8); assert(sym == XKB_KEY_A); assert(xkb_state_key_get_level(state, KEY_SEMICOLON + 8, 0) == 0); sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8); assert(sym == XKB_KEY_Eacute); nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms); assert(nsyms == 1 && syms[0] == XKB_KEY_eacute); xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_UP); assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0); xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_DOWN); xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_UP); xkb_state_unref(state); }