keybindings: Rewrite the keymap code so that it uses libxkbcommon

This way we aren't depending on Xwayland for native key mapping support,
and are instead using the native interfaces.
This commit is contained in:
Jasper St. Pierre 2014-08-14 18:14:55 -04:00
parent 3645c63c08
commit 1af0033368
2 changed files with 57 additions and 55 deletions

View File

@ -90,14 +90,8 @@ typedef struct
typedef struct
{
Display *xdisplay;
GHashTable *key_bindings;
GHashTable *key_bindings_index;
int min_keycode;
int max_keycode;
KeySym *keymap;
int keysyms_per_keycode;
xkb_mod_mask_t ignored_modifier_mask;
xkb_mod_mask_t hyper_mask;
xkb_mod_mask_t super_mask;

View File

@ -177,18 +177,6 @@ key_binding_key (guint32 keycode,
return (key << 16) | (mask & 0xffff);
}
static void
reload_keymap (MetaKeyBindingManager *keys)
{
meta_XFree (keys->keymap);
keys->keymap = XGetKeyboardMapping (keys->xdisplay,
keys->min_keycode,
keys->max_keycode -
keys->min_keycode + 1,
&keys->keysyms_per_keycode);
}
static const char *
keysym_name (xkb_keysym_t keysym)
{
@ -238,6 +226,55 @@ reload_modmap (MetaKeyBindingManager *keys)
keys->meta_mask);
}
static gboolean
is_keycode_for_keysym (struct xkb_keymap *keymap,
xkb_keycode_t keycode,
xkb_keysym_t keysym)
{
xkb_layout_index_t num_layouts, i;
num_layouts = xkb_keymap_num_layouts_for_key (keymap, keycode);
for (i = 0; i < num_layouts; i++)
{
xkb_level_index_t num_levels, j;
num_levels = xkb_keymap_num_levels_for_key (keymap, keycode, i);
for (j = 0; j < num_levels; j++)
{
const xkb_keysym_t *syms;
int num_syms, k;
num_syms = xkb_keymap_key_get_syms_by_level (keymap, keycode, i, j, &syms);
for (k = 0; k < num_syms; k++)
{
if (syms[k] == keysym)
return TRUE;
}
}
}
return FALSE;
}
typedef struct
{
GArray *keycodes;
xkb_keysym_t keysym;
} FindKeysymData;
static void
get_keycodes_for_keysym_iter (struct xkb_keymap *keymap,
xkb_keycode_t keycode,
void *data)
{
FindKeysymData *search_data = data;
GArray *keycodes = search_data->keycodes;
xkb_keysym_t keysym = search_data->keysym;
if (is_keycode_for_keysym (keymap, keycode, keysym))
g_array_append_val (keycodes, keycode);
}
/* Original code from gdk_x11_keymap_get_entries_for_keyval() in
* gdkkeys-x11.c */
static int
@ -259,21 +296,11 @@ get_keycodes_for_keysym (MetaKeyBindingManager *keys,
goto out;
}
keycode = keys->min_keycode;
while (keycode <= keys->max_keycode)
{
const KeySym *syms = keys->keymap + (keycode - keys->min_keycode) * keys->keysyms_per_keycode;
int i = 0;
while (i < keys->keysyms_per_keycode)
{
if (syms[i] == (unsigned int)keysym)
g_array_append_val (retval, keycode);
++i;
}
++keycode;
MetaBackend *backend = meta_get_backend ();
struct xkb_keymap *keymap = meta_backend_get_keymap (backend);
FindKeysymData search_data = { retval, keysym };
xkb_keymap_key_for_each (keymap, get_keycodes_for_keysym_iter, &search_data);
}
out:
@ -861,8 +888,6 @@ on_keymap_changed (MetaBackend *backend,
ungrab_key_bindings (display);
reload_keymap (keys);
/* Deciphering the modmap depends on the loaded keysyms to find out
* what modifiers is Super and so forth, so we need to reload it
* even when only the keymap changes */
@ -1132,8 +1157,6 @@ meta_display_shutdown_keys (MetaDisplay *display)
meta_prefs_remove_listener (prefs_changed_callback, display);
meta_XFree (keys->keymap);
g_hash_table_destroy (keys->key_bindings_index);
g_hash_table_destroy (keys->key_bindings);
}
@ -4011,11 +4034,6 @@ meta_display_init_keys (MetaDisplay *display)
MetaKeyHandler *handler;
/* Keybindings */
keys->xdisplay = display->xdisplay;
keys->keymap = NULL;
keys->keysyms_per_keycode = 0;
keys->min_keycode = 0;
keys->max_keycode = 0;
keys->ignored_modifier_mask = 0;
keys->hyper_mask = 0;
keys->super_mask = 0;
@ -4024,16 +4042,6 @@ meta_display_init_keys (MetaDisplay *display)
keys->key_bindings = g_hash_table_new_full (NULL, NULL, NULL, g_free);
keys->key_bindings_index = g_hash_table_new (NULL, NULL);
XDisplayKeycodes (keys->xdisplay,
&keys->min_keycode,
&keys->max_keycode);
meta_topic (META_DEBUG_KEYBINDINGS,
"Display has keycode range %d to %d\n",
keys->min_keycode,
keys->max_keycode);
reload_keymap (keys);
reload_modmap (keys);
key_handlers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,