[gtk+/saved/mir: 9/47] Flesh out keymap
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/saved/mir: 9/47] Flesh out keymap
- Date: Wed, 22 Oct 2014 16:20:35 +0000 (UTC)
commit 8b7b8994e7ba55dc24ca4bcad93627798399db68
Author: Robert Ancell <robert ancell canonical com>
Date: Tue May 27 10:18:47 2014 +0200
Flesh out keymap
gdk/mir/gdkmirkeymap.c | 352 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 322 insertions(+), 30 deletions(-)
---
diff --git a/gdk/mir/gdkmirkeymap.c b/gdk/mir/gdkmirkeymap.c
index 0a247fb..9bfe5bf 100644
--- a/gdk/mir/gdkmirkeymap.c
+++ b/gdk/mir/gdkmirkeymap.c
@@ -17,6 +17,8 @@
#include "config.h"
+#include <xkbcommon/xkbcommon.h>
+
#include "gdkkeysprivate.h"
typedef struct GdkMirKeymap GdkMirKeymap;
@@ -32,6 +34,12 @@ typedef struct GdkMirKeymapClass GdkMirKeymapClass;
struct GdkMirKeymap
{
GdkKeymap parent_instance;
+
+ struct xkb_keymap *xkb_keymap;
+ struct xkb_state *xkb_state;
+
+ PangoDirection *direction;
+ gboolean bidi;
};
struct GdkMirKeymapClass
@@ -50,29 +58,38 @@ _gdk_mir_keymap_new (void)
static PangoDirection
gdk_mir_keymap_get_direction (GdkKeymap *keymap)
{
- g_printerr ("gdk_mir_keymap_get_direction\n");
- return PANGO_DIRECTION_LTR;
+ //g_printerr ("gdk_mir_keymap_get_direction\n");
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ gint i;
+
+ for (i = 0; i < xkb_keymap_num_layouts (mir_keymap->xkb_keymap); i++)
+ {
+ if (xkb_state_layout_index_is_active (mir_keymap->xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE))
+ return mir_keymap->direction[i];
+ }
+
+ return PANGO_DIRECTION_NEUTRAL;
}
static gboolean
gdk_mir_keymap_have_bidi_layouts (GdkKeymap *keymap)
{
- g_printerr ("gdk_mir_keymap_have_bidi_layouts\n");
+ //g_printerr ("gdk_mir_keymap_have_bidi_layouts\n");
return FALSE;
}
static gboolean
gdk_mir_keymap_get_caps_lock_state (GdkKeymap *keymap)
{
- g_printerr ("gdk_mir_keymap_get_caps_lock_state\n");
- return FALSE; // FIXME
+ //g_printerr ("gdk_mir_keymap_get_caps_lock_state\n");
+ return xkb_state_led_name_is_active (GDK_MIR_KEYMAP (keymap)->xkb_state, XKB_LED_NAME_CAPS);
}
static gboolean
gdk_mir_keymap_get_num_lock_state (GdkKeymap *keymap)
{
- g_printerr ("gdk_mir_keymap_get_num_lock_state\n");
- return FALSE; // FIXME
+ //g_printerr ("gdk_mir_keymap_get_num_lock_state\n");
+ return xkb_state_led_name_is_active (GDK_MIR_KEYMAP (keymap)->xkb_state, XKB_LED_NAME_NUM);
}
static gboolean
@@ -81,8 +98,50 @@ gdk_mir_keymap_get_entries_for_keyval (GdkKeymap *keymap,
GdkKeymapKey **keys,
gint *n_keys)
{
- g_printerr ("gdk_mir_keymap_get_entries_for_keyval\n");
- return FALSE; // FIXME
+ //g_printerr ("gdk_mir_keymap_get_entries_for_keyval\n");
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ GArray *key_array;
+ guint keycode;
+
+ key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
+
+ for (keycode = 8; keycode < 255; keycode++) /* FIXME: min/max keycode */
+ {
+ gint num_layouts, layout;
+
+ num_layouts = xkb_keymap_num_layouts_for_key (mir_keymap->xkb_keymap, keycode);
+ for (layout = 0; layout < num_layouts; layout++)
+ {
+ gint num_levels, level;
+
+ num_levels = xkb_keymap_num_levels_for_key (mir_keymap->xkb_keymap, keycode, layout);
+ for (level = 0; level < num_levels; level++)
+ {
+ const xkb_keysym_t *syms;
+ gint num_syms, sym;
+
+ num_syms = xkb_keymap_key_get_syms_by_level (mir_keymap->xkb_keymap, keycode, layout, level,
&syms);
+ for (sym = 0; sym < num_syms; sym++)
+ {
+ if (syms[sym] == keyval)
+ {
+ GdkKeymapKey key;
+
+ key.keycode = keycode;
+ key.group = layout;
+ key.level = level;
+
+ g_array_append_val (key_array, key);
+ }
+ }
+ }
+ }
+ }
+
+ *n_keys = key_array->len;
+ *keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
+
+ return TRUE;
}
static gboolean
@@ -92,16 +151,122 @@ gdk_mir_keymap_get_entries_for_keycode (GdkKeymap *keymap,
guint **keyvals,
gint *n_entries)
{
- g_printerr ("gdk_mir_keymap_get_entries_for_keycode\n");
- return FALSE; // FIXME
+ //g_printerr ("gdk_mir_keymap_get_entries_for_keycode\n");
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ gint num_layouts, layout;
+ gint num_entries;
+ gint i;
+
+ num_layouts = xkb_keymap_num_layouts_for_key (mir_keymap->xkb_keymap, hardware_keycode);
+
+ num_entries = 0;
+ for (layout = 0; layout < num_layouts; layout++)
+ num_entries += xkb_keymap_num_levels_for_key (mir_keymap->xkb_keymap, hardware_keycode, layout);
+
+ if (n_entries)
+ *n_entries = num_entries;
+ if (keys)
+ *keys = g_new0 (GdkKeymapKey, num_entries);
+ if (keyvals)
+ *keyvals = g_new0 (guint, num_entries);
+
+ i = 0;
+ for (layout = 0; layout < num_layouts; layout++)
+ {
+ gint num_levels, level;
+ num_levels = xkb_keymap_num_levels_for_key (mir_keymap->xkb_keymap, hardware_keycode, layout);
+ for (level = 0; level < num_levels; level++)
+ {
+ const xkb_keysym_t *syms;
+ int num_syms;
+
+ num_syms = xkb_keymap_key_get_syms_by_level (mir_keymap->xkb_keymap, hardware_keycode, layout, 0,
&syms);
+ if (keys)
+ {
+ (*keys)[i].keycode = hardware_keycode;
+ (*keys)[i].group = layout;
+ (*keys)[i].level = level;
+ }
+ if (keyvals && num_syms > 0)
+ (*keyvals)[i] = syms[0];
+
+ i++;
+ }
+ }
+
+ return num_entries > 0;
}
static guint
gdk_mir_keymap_lookup_key (GdkKeymap *keymap,
const GdkKeymapKey *key)
{
- g_printerr ("gdk_mir_keymap_lookup_key\n");
- return 0; // FIXME
+ //g_printerr ("gdk_mir_keymap_lookup_key\n");
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ const xkb_keysym_t *syms;
+ int num_syms;
+
+ num_syms = xkb_keymap_key_get_syms_by_level (mir_keymap->xkb_keymap,
+ key->keycode,
+ key->group,
+ key->level,
+ &syms);
+ if (num_syms > 0)
+ return syms[0];
+ else
+ return XKB_KEY_NoSymbol;
+}
+
+static guint32
+get_xkb_modifiers (struct xkb_keymap *xkb_keymap,
+ GdkModifierType state)
+{
+ guint32 mods = 0;
+
+ if (state & GDK_SHIFT_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT);
+ if (state & GDK_LOCK_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS);
+ if (state & GDK_CONTROL_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL);
+ if (state & GDK_MOD1_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT);
+ if (state & GDK_MOD2_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2");
+ if (state & GDK_MOD3_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3");
+ if (state & GDK_MOD4_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO);
+ if (state & GDK_MOD5_MASK)
+ mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5");
+
+ return mods;
+}
+
+static GdkModifierType
+get_gdk_modifiers (struct xkb_keymap *xkb_keymap,
+ guint32 mods)
+{
+ GdkModifierType state = 0;
+
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT)))
+ state |= GDK_SHIFT_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS)))
+ state |= GDK_LOCK_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL)))
+ state |= GDK_CONTROL_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT)))
+ state |= GDK_MOD1_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")))
+ state |= GDK_MOD2_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3")))
+ state |= GDK_MOD3_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO)))
+ state |= GDK_MOD4_MASK;
+ if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5")))
+ state |= GDK_MOD5_MASK;
+
+ return state;
}
static gboolean
@@ -111,54 +276,182 @@ gdk_mir_keymap_translate_keyboard_state (GdkKeymap *keymap,
gint group,
guint *keyval,
gint *effective_group,
- gint *level,
+ gint *effective_level,
GdkModifierType *consumed_modifiers)
{
- g_printerr ("gdk_mir_keymap_translate_keyboard_state\n");
- return FALSE; // FIXME
+ //g_printerr ("gdk_mir_keymap_translate_keyboard_state\n");
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ struct xkb_state *xkb_state;
+ guint32 modifiers;
+ guint32 consumed;
+ xkb_layout_index_t layout;
+ xkb_level_index_t level;
+ xkb_keysym_t sym;
+
+ modifiers = get_xkb_modifiers (mir_keymap->xkb_keymap, state);
+
+ xkb_state = xkb_state_new (mir_keymap->xkb_keymap);
+
+ xkb_state_update_mask (xkb_state, modifiers, 0, 0, group, 0, 0);
+
+ layout = xkb_state_key_get_layout (xkb_state, hardware_keycode);
+ level = xkb_state_key_get_level (xkb_state, hardware_keycode, layout);
+ sym = xkb_state_key_get_one_sym (xkb_state, hardware_keycode);
+ consumed = modifiers & ~xkb_state_mod_mask_remove_consumed (xkb_state, hardware_keycode, modifiers);
+
+ xkb_state_unref (xkb_state);
+
+ if (keyval)
+ *keyval = sym;
+ if (effective_group)
+ *effective_group = layout;
+ if (effective_level)
+ *effective_level = level;
+ if (consumed_modifiers)
+ *consumed_modifiers = get_gdk_modifiers (mir_keymap->xkb_keymap, consumed);
+
+ return TRUE;
}
static void
gdk_mir_keymap_add_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state)
{
- g_printerr ("gdk_mir_keymap_add_virtual_modifiers\n");
- // FIXME
+ //g_printerr ("gdk_mir_keymap_add_virtual_modifiers\n");
+ // FIXME: What is this?
}
static gboolean
gdk_mir_keymap_map_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state)
{
- g_printerr ("gdk_mir_keymap_map_virtual_modifiers\n");
- return FALSE; // FIXME
-}
-
-static GdkModifierType
-gdk_mir_keymap_get_modifier_mask (GdkKeymap *keymap,
- GdkModifierIntent intent)
-{
- g_printerr ("gdk_mir_keymap_get_modifier_mask\n");
- return 0; // FIXME GDK_MODIFIER_TYPE_
+ //g_printerr ("gdk_mir_keymap_map_virtual_modifiers\n");
+ // FIXME: What is this?
+ return TRUE;
}
static guint
gdk_mir_keymap_get_modifier_state (GdkKeymap *keymap)
{
g_printerr ("gdk_mir_keymap_get_modifier_state\n");
- return 0; // FIXME
+ GdkMirKeymap *mir_keymap = GDK_MIR_KEYMAP (keymap);
+ xkb_mod_mask_t mods;
+
+ mods = xkb_state_serialize_mods (mir_keymap->xkb_state, XKB_STATE_MODS_EFFECTIVE);
+
+ return get_gdk_modifiers (mir_keymap->xkb_keymap, mods);
+}
+
+static void
+update_direction (GdkMirKeymap *keymap)
+{
+ gint num_layouts;
+ gint *rtl;
+ guint key;
+ gboolean have_rtl, have_ltr;
+ gint i;
+
+ num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap);
+
+ g_free (keymap->direction);
+ keymap->direction = g_new0 (PangoDirection, num_layouts);
+
+ rtl = g_new0 (gint, num_layouts);
+
+ for (key = 8; key < 255; key++) /* FIXME: min/max keycode */
+ {
+ gint layouts;
+ gint layout;
+
+ layouts = xkb_keymap_num_layouts_for_key (keymap->xkb_keymap, key);
+ for (layout = 0; layout < layouts; layout++)
+ {
+ const xkb_keysym_t *syms;
+ gint num_syms;
+ gint sym;
+
+ num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms);
+ for (sym = 0; sym < num_syms; sym++)
+ {
+ PangoDirection dir;
+ dir = pango_unichar_direction (xkb_keysym_to_utf32 (syms[sym]));
+ switch (dir)
+ {
+ case PANGO_DIRECTION_RTL:
+ rtl[layout]++;
+ break;
+ case PANGO_DIRECTION_LTR:
+ rtl[layout]--;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ have_rtl = have_ltr = FALSE;
+ for (i = 0; i < num_layouts; i++)
+ {
+ if (rtl[i] > 0)
+ {
+ keymap->direction[i] = PANGO_DIRECTION_RTL;
+ have_rtl = TRUE;
+ }
+ else
+ {
+ keymap->direction[i] = PANGO_DIRECTION_LTR;
+ have_ltr = TRUE;
+ }
+ }
+
+ if (have_rtl && have_ltr)
+ keymap->bidi = TRUE;
+
+ g_free (rtl);
}
static void
gdk_mir_keymap_init (GdkMirKeymap *keymap)
{
+ struct xkb_context *context;
+ struct xkb_rule_names names;
+
+ context = xkb_context_new (0);
+
+ names.rules = "evdev";
+ names.model = "pc105";
+ names.layout = "us";
+ names.variant = "";
+ names.options = "";
+ keymap->xkb_keymap = xkb_keymap_new_from_names (context, &names, 0);
+ keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
+
+ xkb_context_unref (context);
+
+ update_direction (keymap);
+}
+
+static void
+gdk_mir_keymap_finalize (GObject *object)
+{
+ GdkMirKeymap *keymap = GDK_MIR_KEYMAP (object);
+
+ xkb_keymap_unref (keymap->xkb_keymap);
+ xkb_state_unref (keymap->xkb_state);
+ g_free (keymap->direction);
+
+ G_OBJECT_CLASS (gdk_mir_keymap_parent_class)->finalize (object);
}
static void
gdk_mir_keymap_class_init (GdkMirKeymapClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
+ object_class->finalize = gdk_mir_keymap_finalize;
+
keymap_class->get_direction = gdk_mir_keymap_get_direction;
keymap_class->have_bidi_layouts = gdk_mir_keymap_have_bidi_layouts;
keymap_class->get_caps_lock_state = gdk_mir_keymap_get_caps_lock_state;
@@ -169,6 +462,5 @@ gdk_mir_keymap_class_init (GdkMirKeymapClass *klass)
keymap_class->translate_keyboard_state = gdk_mir_keymap_translate_keyboard_state;
keymap_class->add_virtual_modifiers = gdk_mir_keymap_add_virtual_modifiers;
keymap_class->map_virtual_modifiers = gdk_mir_keymap_map_virtual_modifiers;
- keymap_class->get_modifier_mask = gdk_mir_keymap_get_modifier_mask;
keymap_class->get_modifier_state = gdk_mir_keymap_get_modifier_state;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]