/* keyhash.c * Copyright (C) 2012 Red Hat, Inc12 Red Hat, Inc * Authors: Matthias Clasen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library. If not, see . */ #include #include #include "../../gtk/gtkkeyhash.h" #include "../../gtk/gtkprivate.h" static gint count; static void counting_destroy (gpointer data) { count++; } static void test_basic (void) { GdkKeymap *keymap; GtkKeyHash *hash; GSList *keys; keymap = gdk_display_get_keymap (gdk_display_get_default ()); count = 0; hash = _gtk_key_hash_new (keymap, counting_destroy); keys = _gtk_key_hash_lookup (hash, 0, 0, 0, 0); g_assert (keys == NULL); _gtk_key_hash_add_entry (hash, 1, 0, NULL); _gtk_key_hash_add_entry (hash, 1, 1, NULL); _gtk_key_hash_add_entry (hash, 2, 0, NULL); _gtk_key_hash_add_entry (hash, 3, 0, NULL); _gtk_key_hash_add_entry (hash, 4, 0, NULL); _gtk_key_hash_free (hash); g_assert_cmpint (count, ==, 5); } #if 0 typedef struct { guint keyval; GdkModifierType modifiers; } Entry; static void test_lookup (GtkKeyHash *hash, guint keyval, GdkModifierType modifiers, GdkModifierType mask, gint n_results, ...) { GdkKeymap *keymap; va_list ap; gint d; GSList *res, *l; gint i; GdkKeymapKey *keys; gint n_keys; keymap = gdk_display_get_keymap (gdk_display_get_default ()); gdk_keymap_get_entries_for_keyval (keymap, keyval, &keys, &n_keys); if (n_keys == 0) return; res = _gtk_key_hash_lookup (hash, keys[0].keycode, modifiers, mask, keys[0].group); g_free (keys); g_assert_cmpint (g_slist_length (res), ==, n_results); va_start (ap, n_results); for (i = 0, l = res; i < n_results; i++, l = l->next) { d = va_arg (ap, int); g_assert_cmpint (d, ==, GPOINTER_TO_INT (l->data)); } va_end (ap); g_slist_free (res); } static void add_entries (GtkKeyHash *hash, Entry *entries) { gint i; for (i = 0; entries[i].keyval; i++) _gtk_key_hash_add_entry (hash, entries[i].keyval, entries[i].modifiers, GINT_TO_POINTER (i+1)); } #define DEFAULT_MASK (GDK_CONTROL_MASK \ | GDK_SHIFT_MASK \ | GDK_MOD1_MASK \ | GDK_SUPER_MASK \ | GDK_HYPER_MASK \ | GDK_META_MASK) static void test_match (void) { GdkKeymap *keymap; GtkKeyHash *hash; static Entry entries[] = { { GDK_KEY_a, GDK_CONTROL_MASK }, { GDK_KEY_a, GDK_CONTROL_MASK|GDK_SHIFT_MASK } , { GDK_KEY_b, GDK_MOD1_MASK|GDK_CONTROL_MASK }, { GDK_KEY_F10, 0 }, { 0, 0 } }; keymap = gdk_display_get_keymap (gdk_display_get_default ()); hash = _gtk_key_hash_new (keymap, NULL); add_entries (hash, entries); test_lookup (hash, GDK_KEY_a, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2); test_lookup (hash, GDK_KEY_A, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2); test_lookup (hash, GDK_KEY_a, GDK_MOD1_MASK, DEFAULT_MASK, 0); test_lookup (hash, GDK_KEY_F10, 0, DEFAULT_MASK, 4, 4, 4, 4, 4); test_lookup (hash, GDK_KEY_F10, GDK_SHIFT_MASK, DEFAULT_MASK, 4, 4, 4, 4, 4); _gtk_key_hash_free (hash); } static gboolean hyper_equals_super (void) { GdkKeymap *keymap; GdkModifierType mods1, mods2; keymap = gdk_display_get_keymap (gdk_display_get_default ()); mods1 = GDK_HYPER_MASK; gdk_keymap_map_virtual_modifiers (keymap, &mods1); mods1 = mods1 & ~GDK_HYPER_MASK; mods2 = GDK_SUPER_MASK; gdk_keymap_map_virtual_modifiers (keymap, &mods2); mods2 = mods2 & ~GDK_SUPER_MASK; return mods1 == mods2; } static void test_virtual (void) { GdkKeymap *keymap; GtkKeyHash *hash; static Entry entries[] = { { GDK_KEY_a, GDK_SUPER_MASK }, { GDK_KEY_b, GDK_HYPER_MASK } , { GDK_KEY_c, GDK_META_MASK }, { GDK_KEY_d, GDK_SUPER_MASK|GDK_HYPER_MASK }, { 0, 0 } }; keymap = gdk_display_get_keymap (gdk_display_get_default ()); hash = _gtk_key_hash_new (keymap, NULL); add_entries (hash, entries); test_lookup (hash, GDK_KEY_a, GDK_SUPER_MASK, DEFAULT_MASK, 2, 1, 1); test_lookup (hash, GDK_KEY_a, GDK_HYPER_MASK, DEFAULT_MASK, 0); test_lookup (hash, GDK_KEY_b, GDK_HYPER_MASK, DEFAULT_MASK, 2, 2, 2); test_lookup (hash, GDK_KEY_c, GDK_META_MASK, DEFAULT_MASK, 2, 3, 3); if (hyper_equals_super ()) { GdkModifierType mods; /* test that colocated virtual modifiers don't count twice */ test_lookup (hash, GDK_KEY_d, GDK_SUPER_MASK, DEFAULT_MASK, 0); test_lookup (hash, GDK_KEY_d, GDK_HYPER_MASK, DEFAULT_MASK, 0); mods = GDK_HYPER_MASK; gdk_keymap_map_virtual_modifiers (keymap, &mods); test_lookup (hash, GDK_KEY_d, mods, DEFAULT_MASK, 0); } _gtk_key_hash_free (hash); } #endif int main (int argc, char **argv) { /* initialize test program */ gtk_test_init (&argc, &argv); g_test_add_func ("/keyhash/basic", test_basic); #if 0 /* FIXME: need to make these independent of xkb configuration */ g_test_add_func ("/keyhash/match", test_match); g_test_add_func ("/keyhash/virtual", test_virtual); #endif return g_test_run(); }