map: share some code
authorRan Benita <ran234@gmail.com>
Fri, 10 Aug 2012 07:17:32 +0000 (10:17 +0300)
committerRan Benita <ran234@gmail.com>
Fri, 10 Aug 2012 10:49:19 +0000 (13:49 +0300)
Make more extensive use of get_entry_for_key_state, and add
key_get_consumed to use in the other consume functions.

There's also a slight change in the consumed mods calculations, where
we use entry->mods.mask instead of type->mods.mask. The original was
copied from what libX11 does but what we do now is more logically
correct. The result is exactly the same though because:
type->mods.mask ⊇ entry->mods.mask ⊇ entry->preserve.mask

Signed-off-by: Ran Benita <ran234@gmail.com>
src/map.c

index fdb51c9..fa64246 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -210,21 +210,18 @@ xkb_map_led_get_index(struct xkb_keymap *keymap, const char *name)
     return XKB_LED_INVALID;
 }
 
-/**
- * Returns the level to use for the given key and state, or
- * XKB_LEVEL_INVALID.
- */
-xkb_level_index_t
-xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
-                  xkb_group_index_t group)
+static struct xkb_kt_map_entry *
+get_entry_for_key_state(struct xkb_state *state, xkb_keycode_t kc)
 {
     struct xkb_keymap *keymap = xkb_state_get_map(state);
+    xkb_group_index_t group;
     struct xkb_key_type *type;
-    unsigned int i;
     xkb_mod_mask_t active_mods;
+    unsigned int i;
 
-    if (!XkbKeycodeInRange(keymap, kc))
-        return XKB_LEVEL_INVALID;
+    group = xkb_key_get_group(state, kc);
+    if (group == XKB_GROUP_INVALID)
+        return NULL;
 
     type = XkbKeyType(keymap, XkbKey(keymap, kc), group);
     active_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
@@ -232,10 +229,31 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
 
     for (i = 0; i < type->num_entries; i++)
         if (type->map[i].mods.mask == active_mods)
-            return type->map[i].level;
+            return &type->map[i];
+
+    return NULL;
+}
+
+/**
+ * Returns the level to use for the given key and state, or
+ * XKB_LEVEL_INVALID.
+ */
+xkb_level_index_t
+xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
+                  xkb_group_index_t group)
+{
+    struct xkb_kt_map_entry *entry;
+
+    if (!XkbKeycodeInRange(xkb_state_get_map(state), kc))
+        return XKB_LEVEL_INVALID;
+
+    entry = get_entry_for_key_state(state, kc);
 
     /* If we don't find an explicit match the default is 0. */
-    return 0;
+    if (!entry)
+        return 0;
+
+    return entry->level;
 }
 
 /**
@@ -351,22 +369,16 @@ xkb_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
     return XkbKey(keymap, kc)->repeats;
 }
 
-static struct xkb_kt_map_entry *
-get_entry_for_key_state(struct xkb_state *state, struct xkb_key_type *type,
-                        xkb_keycode_t kc)
+static xkb_mod_mask_t
+key_get_consumed(struct xkb_state *state, xkb_keycode_t kc)
 {
-    xkb_mod_mask_t active_mods;
-    unsigned int i;
-
-    active_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
-    active_mods &= type->mods.mask;
+    struct xkb_kt_map_entry *entry;
 
-    for (i = 0; i < type->num_entries; i++) {
-        if (type->map[i].mods.mask == active_mods)
-            return &type->map[i];
-    }
+    entry = get_entry_for_key_state(state, kc);
+    if (!entry)
+        return 0;
 
-    return NULL;
+    return entry->mods.mask & ~entry->preserve.mask;
 }
 
 /**
@@ -385,24 +397,10 @@ XKB_EXPORT int
 xkb_key_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
                               xkb_mod_index_t idx)
 {
-    struct xkb_keymap *keymap = xkb_state_get_map(state);
-    struct xkb_key_type *type;
-    struct xkb_kt_map_entry *entry;
-    xkb_group_index_t group;
-
-    if (!XkbKeycodeInRange(keymap, kc))
+    if (!XkbKeycodeInRange(xkb_state_get_map(state), kc))
         return 0;
 
-    group = xkb_key_get_group(state, kc);
-    if (group == XKB_GROUP_INVALID)
-        return 0;
-
-    type = XkbKeyType(keymap, XkbKey(keymap, kc), group);
-    entry = get_entry_for_key_state(state, type, kc);
-    if (!entry)
-        return 0;
-
-    return !!((type->mods.mask & (~entry->preserve.mask)) & (1 << idx));
+    return !!((1 << idx) & key_get_consumed(state, kc));
 }
 
 /**
@@ -417,22 +415,8 @@ XKB_EXPORT xkb_mod_mask_t
 xkb_key_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
                                  xkb_mod_mask_t mask)
 {
-    struct xkb_keymap *keymap = xkb_state_get_map(state);
-    struct xkb_key_type *type;
-    struct xkb_kt_map_entry *entry;
-    xkb_group_index_t group;
-
-    if (!XkbKeycodeInRange(keymap, kc))
-        return mask;
-
-    group = xkb_key_get_group(state, kc);
-    if (group == XKB_GROUP_INVALID)
-        return mask;
-
-    type = XkbKeyType(keymap, XkbKey(keymap, kc), group);
-    entry = get_entry_for_key_state(state, type, kc);
-    if (!entry)
+    if (!XkbKeycodeInRange(xkb_state_get_map(state), kc))
         return mask;
 
-    return mask & ~(type->mods.mask & ~entry->preserve.mask);
+    return mask & ~key_get_consumed(state, kc);
 }