int main(void) { struct xkb_context *context = test_get_context(0); struct xkb_keymap *keymap; assert(context); /* Make sure these are allowed. */ xkb_context_unref(NULL); xkb_keymap_unref(NULL); xkb_state_unref(NULL); keymap = test_compile_rules(context, "evdev", "pc104", "us,ru", NULL, "grp:menu_toggle"); assert(keymap); test_update_key(keymap); test_serialisation(keymap); test_repeat(keymap); test_consume(keymap); test_range(keymap); test_get_utf8_utf32(keymap); test_ctrl_string_transformation(keymap); xkb_keymap_unref(keymap); keymap = test_compile_rules(context, "evdev", NULL, "ch", "fr", NULL); assert(keymap); test_caps_keysym_transformation(keymap); xkb_keymap_unref(keymap); xkb_context_unref(context); }
int main(int argc, char *argv[]) { struct xkb_context *ctx; struct xkb_keymap *keymap; struct bench_timer timer; char *elapsed; int i; ctx = test_get_context(0); assert(ctx); xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL); xkb_context_set_log_verbosity(ctx, 0); bench_timer_reset(&timer); bench_timer_start(&timer); for (i = 0; i < BENCHMARK_ITERATIONS; i++) { keymap = test_compile_rules(ctx, "evdev", "evdev", "us", "", ""); assert(keymap); xkb_keymap_unref(keymap); } bench_timer_stop(&timer); elapsed = bench_timer_get_elapsed_time_str(&timer); fprintf(stderr, "compiled %d keymaps in %ss\n", BENCHMARK_ITERATIONS, elapsed); free(elapsed); xkb_context_unref(ctx); return 0; }
int main(void) { struct xkb_context *ctx; struct xkb_keymap *keymap; struct xkb_state *state; struct bench bench; char *elapsed; ctx = test_get_context(0); assert(ctx); keymap = test_compile_rules(ctx, "evdev", "pc104", "us,ru,il,de", ",,,neo", "grp:menu_toggle"); assert(keymap); state = xkb_state_new(keymap); assert(state); xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL); xkb_context_set_log_verbosity(ctx, 0); srand(time(NULL)); bench_start(&bench); bench_key_proc(state); bench_stop(&bench); elapsed = bench_elapsed_str(&bench); fprintf(stderr, "ran %d iterations in %ss\n", BENCHMARK_ITERATIONS, elapsed); free(elapsed); xkb_state_unref(state); xkb_keymap_unref(keymap); xkb_context_unref(ctx); return 0; }
int main(int argc, char *argv[]) { struct xkb_context *ctx = test_get_context(0); struct xkb_keymap *keymap; char *original, *dump; assert(ctx); /* Load in a prebuilt keymap, make sure we can compile it from a string, * then compare it to make sure we get the same result when dumping it * to a string. */ original = test_read_file(DATA_PATH); assert(original); keymap = test_compile_string(ctx, original); assert(keymap); dump = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT); assert(dump); if (!streq(original, dump)) { fprintf(stderr, "round-trip test failed: dumped map differs from original\n"); fprintf(stderr, "path to original file: %s\n", test_get_path(DATA_PATH)); fprintf(stderr, "length: dumped %lu, original %lu\n", (unsigned long) strlen(dump), (unsigned long) strlen(original)); fprintf(stderr, "dumped map:\n"); fprintf(stderr, "%s\n", dump); fflush(stderr); assert(0); } free(original); free(dump); xkb_keymap_unref(keymap); /* Make sure we can't (falsely claim to) compile an empty string. */ keymap = test_compile_string(ctx, ""); assert(!keymap); /* Make sure we can recompile our output for a normal keymap from rules. */ keymap = test_compile_rules(ctx, NULL, NULL, "ru,ca,de,us", ",multix,neo,intl", NULL); assert(keymap); dump = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT); assert(dump); xkb_keymap_unref(keymap); keymap = test_compile_string(ctx, dump); assert(keymap); /* Test response to invalid formats and flags. */ assert(!xkb_keymap_new_from_string(ctx, dump, 0, 0)); assert(!xkb_keymap_new_from_string(ctx, dump, -1, 0)); assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1+1, 0)); assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1, -1)); assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1, 1414)); assert(!xkb_keymap_get_as_string(keymap, 0)); assert(!xkb_keymap_get_as_string(keymap, 4893)); xkb_keymap_unref(keymap); free(dump); xkb_context_unref(ctx); return 0; }
int main(int argc, char *argv[]) { int ret; int opt; struct keyboard *kbds; struct xkb_context *ctx; struct xkb_keymap *keymap; 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; struct sigaction act; setlocale(LC_ALL, ""); while ((opt = getopt(argc, argv, "r:m:l:v:o:k:n:c")) != -1) { switch (opt) { case 'r': rules = optarg; break; case 'm': model = optarg; break; case 'l': layout = optarg; break; case 'v': variant = optarg; break; case 'o': options = optarg; break; case 'k': keymap_path = optarg; break; case 'n': errno = 0; evdev_offset = strtol(optarg, NULL, 10); if (errno) { fprintf(stderr, "error: -n option expects a number\n"); exit(EXIT_FAILURE); } break; case 'c': report_state_changes = true; break; case '?': fprintf(stderr, " Usage: %s [-r <rules>] [-m <model>] " "[-l <layout>] [-v <variant>] [-o <options>]\n", argv[0]); fprintf(stderr, " or: %s -k <path to keymap file>\n", argv[0]); fprintf(stderr, "For both: -n <evdev keycode offset>\n" " -c (to report changes to the state)\n"); exit(EX_USAGE); } } ctx = test_get_context(0); if (!ctx) { ret = -1; fprintf(stderr, "Couldn't create xkb context\n"); goto err_out; } if (keymap_path) { FILE *file = fopen(keymap_path, "r"); if (!file) { ret = EXIT_FAILURE; fprintf(stderr, "Couldn't open '%s': %s\n", keymap_path, strerror(errno)); goto err_ctx; } keymap = xkb_keymap_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0); fclose(file); } else { keymap = test_compile_rules(ctx, rules, model, layout, variant, options); } if (!keymap) { ret = -1; fprintf(stderr, "Couldn't create xkb keymap\n"); goto err_ctx; } kbds = get_keyboards(keymap); if (!kbds) { ret = -1; goto err_xkb; } act.sa_handler = sigintr_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); /* Instead of fiddling with termios.. */ system("stty -echo"); ret = loop(kbds); if (ret) goto err_stty; err_stty: system("stty echo"); free_keyboards(kbds); err_xkb: xkb_keymap_unref(keymap); err_ctx: xkb_context_unref(ctx); err_out: exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
int main(void) { struct xkb_context *ctx = test_get_context(0); struct xkb_keymap *keymap; assert(ctx); keymap = test_compile_rules(ctx, "evdev", "evdev", "us,il,ru,de", ",,phonetic,neo", "grp:alt_shift_toggle,grp:menu_toggle"); assert(keymap); assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_E, BOTH, XKB_KEY_e, NEXT, KEY_L, BOTH, XKB_KEY_l, NEXT, KEY_L, BOTH, XKB_KEY_l, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); /* Simple shifted level. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_L, BOTH, XKB_KEY_l, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); /* Key repeat shifted and unshifted in the middle. */ assert(test_key_seq(keymap, KEY_H, DOWN, XKB_KEY_h, NEXT, KEY_H, REPEAT, XKB_KEY_h, NEXT, KEY_H, REPEAT, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_H, REPEAT, XKB_KEY_H, NEXT, KEY_H, REPEAT, XKB_KEY_H, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, REPEAT, XKB_KEY_h, NEXT, KEY_H, REPEAT, XKB_KEY_h, NEXT, KEY_H, UP, XKB_KEY_h, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); /* Base modifier cleared on key release... */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_O, BOTH, XKB_KEY_O, FINISH)); /* ... But only by the keycode that set it. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_O, BOTH, XKB_KEY_O, FINISH)); /* * A base modifier should only be cleared when no other key affecting * the modifier is down. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); /* * Two key presses from the same key (e.g. if two keyboards use the * same xkb_state) should only be released after two releases. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); /* Same as above with locked modifiers. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); /* Group switching / locking. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_E, BOTH, XKB_KEY_e, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_K, BOTH, XKB_KEY_hebrew_lamed, NEXT, KEY_F, BOTH, XKB_KEY_hebrew_kaph, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); assert(test_key_seq(keymap, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_LEFTALT, DOWN, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTALT, UP, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH)); assert(test_key_seq(keymap, KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH)); /* Locked modifiers. */ assert(test_key_seq(keymap, KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_H, BOTH, XKB_KEY_H, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_O, BOTH, XKB_KEY_O, FINISH)); assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_E, BOTH, XKB_KEY_e, NEXT, KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, KEY_E, BOTH, XKB_KEY_E, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_L, BOTH, XKB_KEY_L, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, KEY_O, BOTH, XKB_KEY_O, FINISH)); assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_E, BOTH, XKB_KEY_e, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, KEY_L, BOTH, XKB_KEY_l, NEXT, KEY_L, BOTH, XKB_KEY_l, NEXT, KEY_O, BOTH, XKB_KEY_o, FINISH)); /* * A key release affecting a locked modifier should clear it * regardless of the key press. */ /* assert(test_key_seq(keymap, */ /* KEY_H, BOTH, XKB_KEY_h, NEXT, */ /* KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, */ /* KEY_E, BOTH, XKB_KEY_E, NEXT, */ /* KEY_L, BOTH, XKB_KEY_L, NEXT, */ /* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */ /* KEY_L, BOTH, XKB_KEY_L, NEXT, */ /* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */ /* KEY_O, BOTH, XKB_KEY_o, FINISH)); */ /* Simple Num Lock sanity check. */ assert(test_key_seq(keymap, KEY_KP1, BOTH, XKB_KEY_KP_End, NEXT, KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT, KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT, KEY_KP2, BOTH, XKB_KEY_KP_2, NEXT, KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT, KEY_KP2, BOTH, XKB_KEY_KP_Down, FINISH)); /* Test that the aliases in the ru(phonetic) symbols map work. */ assert(test_key_seq(keymap, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_1, BOTH, XKB_KEY_1, NEXT, KEY_Q, BOTH, XKB_KEY_Cyrillic_ya, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_1, BOTH, XKB_KEY_exclam, NEXT, KEY_Q, BOTH, XKB_KEY_Cyrillic_YA, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT, KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_1, BOTH, XKB_KEY_1, NEXT, KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, NEXT, KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT, KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT, KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT, KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, FINISH)); #define KS(name) xkb_keysym_from_name(name, 0) /* Test that levels (1-5) in de(neo) symbols map work. */ assert(test_key_seq(keymap, /* Switch to the group. */ KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, /* Level 1. */ KEY_1, BOTH, XKB_KEY_1, NEXT, KEY_Q, BOTH, XKB_KEY_x, NEXT, KEY_KP7, BOTH, XKB_KEY_KP_7, NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, /* Level 2 with Shift. */ KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_1, BOTH, XKB_KEY_degree, NEXT, KEY_Q, BOTH, XKB_KEY_X, NEXT, KEY_KP7, BOTH, KS("U2714"), NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, /* * XXX: de(neo) uses shift(both_capslock) which causes * the interesting result in the next line. Since it's * a key release, it doesn't actually lock the modifier, * and applications by-and-large ignore the keysym on * release(?). Is this a problem? */ KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, /* Level 2 with the Lock modifier. */ KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, KEY_6, BOTH, XKB_KEY_6, NEXT, KEY_H, BOTH, XKB_KEY_S, NEXT, KEY_KP3, BOTH, XKB_KEY_KP_3, NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, /* Level 3. */ KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_6, BOTH, XKB_KEY_cent, NEXT, KEY_Q, BOTH, XKB_KEY_ellipsis, NEXT, KEY_KP7, BOTH, KS("U2195"), NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT, /* Level 4. */ KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_5, BOTH, XKB_KEY_malesymbol, NEXT, KEY_E, BOTH, XKB_KEY_Greek_lambda, NEXT, KEY_SPACE, BOTH, XKB_KEY_nobreakspace, NEXT, KEY_KP8, BOTH, XKB_KEY_intersection, NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT, /* Level 5. */ KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT, /* XXX: xkeyboard-config is borked when de(neo) is * not the first group - not our fault. We test * Level5 seprately below with only de(neo). */ /* KEY_5, BOTH, XKB_KEY_periodcentered, NEXT, */ /* KEY_E, BOTH, XKB_KEY_Up, NEXT, */ /* KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT, */ /* KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT, */ KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_V, BOTH, XKB_KEY_p, FINISH)); xkb_keymap_unref(keymap); keymap = test_compile_rules(ctx, "evdev", "", "de", "neo", ""); assert(keymap); assert(test_key_seq(keymap, /* Level 5. */ KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_5, BOTH, XKB_KEY_periodcentered, NEXT, KEY_E, BOTH, XKB_KEY_Up, NEXT, KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT, KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT, /* Level 6. */ KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT, KEY_5, BOTH, XKB_KEY_NoSymbol, NEXT, KEY_8, BOTH, XKB_KEY_ISO_Left_Tab, NEXT, KEY_E, BOTH, XKB_KEY_Up, NEXT, KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT, KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_RIGHTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT, /* Level 7. */ KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_5, BOTH, KS("U2221"), NEXT, KEY_E, BOTH, XKB_KEY_Greek_LAMBDA, NEXT, KEY_SPACE, BOTH, KS("U202F"), NEXT, KEY_KP8, BOTH, KS("U22C2"), NEXT, KEY_ESC, BOTH, XKB_KEY_Escape, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT, /* Level 8. */ KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT, /* This doesn't actually lock Level5. Not our fault. */ KEY_TAB, BOTH, XKB_KEY_ISO_Level5_Lock, NEXT, KEY_RIGHTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT, KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT, KEY_V, BOTH, XKB_KEY_p, FINISH)); xkb_keymap_unref(keymap); keymap = test_compile_rules(ctx, "evdev", "", "us,il,ru", "", "grp:alt_shift_toggle_bidir,grp:menu_toggle"); assert(keymap); assert(test_key_seq(keymap, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_LEFTALT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTALT, UP, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH)); assert(test_key_seq(keymap, KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH)); /* Check backwards (negative) group switching and wrapping. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT, KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT, KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT, KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); xkb_keymap_unref(keymap); keymap = test_compile_rules(ctx, "evdev", "", "us,il,ru", "", "grp:switch,grp:lswitch,grp:menu_toggle"); assert(keymap); /* Test depressed group works (Mode_switch). */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); /* Test locked+depressed group works, with wrapping and accumulation. */ assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT, KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT, /* Should wrap back to first group. */ KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT, KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT, KEY_H, BOTH, XKB_KEY_h, NEXT, /* Two SetGroup(+1)'s should add up. */ KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT, KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT, KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT, KEY_H, BOTH, XKB_KEY_h, FINISH)); xkb_keymap_unref(keymap); keymap = test_compile_file(ctx, "keymaps/unbound-vmod.xkb"); assert(keymap); assert(test_key_seq(keymap, KEY_H, BOTH, XKB_KEY_h, NEXT, KEY_Z, BOTH, XKB_KEY_y, NEXT, KEY_MINUS, BOTH, XKB_KEY_ssharp, NEXT, KEY_Z, BOTH, XKB_KEY_y, FINISH)); xkb_keymap_unref(keymap); xkb_context_unref(ctx); return 0; }