#include #include #include #include #include "keyboard-shortcuts.h" #define NUM_LAYOUTS 4 typedef struct _shortcut_test { guint16 keycode; GdkModifierType modifiers; char *expected_results[NUM_LAYOUTS]; } shortcut_test; /* keycodes taken from /usr/share/X11/xkb/keycodes/evdev */ shortcut_test shortcut_tests[] = { { 24 /* first key after tab in first letter row */, GDK_SHIFT_MASK | GDK_SUPER_MASK, { "q" /* us */, "apostrophe" /* us+dvorak */, "a" /* fr+azerty */, "Cyrillic_shorti" /* ru */ /* "q" would be valid, too */, }, }, { 13 /* fifth key in num row */, GDK_SUPER_MASK, { "4" /* us */, "4" /* us+dvorak */, "4" /* fr+azerty */, "4" /* ru */, }, }, { 13 /* fifth key in num row */, GDK_SHIFT_MASK | GDK_SUPER_MASK, { "4" /* us */, "4" /* us+dvorak */, "4" /* fr+azerty */, "4" /* ru */, }, }, { 65 /* space key */, GDK_SHIFT_MASK | GDK_SUPER_MASK, { "space" /* us */, "space" /* us+dvorak */, "space" /* fr+azerty */, "space" /* ru */, }, }, { 23 /* tab key */, GDK_SHIFT_MASK | GDK_SUPER_MASK, { "Tab" /* us */, "Tab" /* us+dvorak */, "Tab" /* fr+azerty */, "Tab" /* ru */, }, }, { 107 /* print screen/sysrq key */, GDK_ALT_MASK, { "Print" /* us */, "Print" /* us+dvorak */, "Print" /* fr+azerty */, "Print" /* ru */, }, }, }; static void test_event_translation (shortcut_test *shortcut_test) { g_autofree char *translated_name = NULL; guint keyval; GdkModifierType modifiers; for (int group = 0; group < NUM_LAYOUTS; group++) { if (!shortcut_test->expected_results[group]) continue; normalize_keyval_and_mask (shortcut_test->keycode, shortcut_test->modifiers, group, &keyval, &modifiers); translated_name = gtk_accelerator_name (keyval, modifiers); if (g_strcmp0 (translated_name, shortcut_test->expected_results[group]) != 0) { g_error ("Result for keycode %u with modifieres %u for " "group %d doesn't match '%s' (got: '%s')", shortcut_test->keycode, shortcut_test->modifiers, group, shortcut_test->expected_results[group], translated_name); g_test_fail (); } } } static void set_keyboard_layouts (char *layouts, char *variants, char *options) { GSubprocess *proc; GError *error = NULL; proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, &error, "setxkbmap", "-layout", layouts, "-variant", variants, "-option", options, "-model", "pc105", NULL); if (!proc || !g_subprocess_wait_check(proc, NULL, &error)) { g_critical ("Failed to set layout: %s", error->message); exit (1); } g_object_unref (proc); } static void run_shortcut_tests (void) { set_keyboard_layouts ("us,us,fr,ru", ",dvorak,azerty,", ""); for (int i = 0; i < G_N_ELEMENTS(shortcut_tests); i++) test_event_translation (&shortcut_tests[i]); } int main (int argc, char **argv) { g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GDK_BACKEND", "x11", TRUE); g_setenv ("LC_ALL", "C", TRUE); gtk_test_init (&argc, &argv, NULL); g_test_add_func ("/keyboard/shortcut-translation", run_shortcut_tests); return g_test_run (); }