state, map: use keycodes only for the API functions
authorRan Benita <ran234@gmail.com>
Fri, 14 Sep 2012 08:02:12 +0000 (11:02 +0300)
committerRan Benita <ran234@gmail.com>
Fri, 14 Sep 2012 18:09:49 +0000 (21:09 +0300)
The policy is now consistent: every API functions which recieves a
keycode should resolve it to an xkb_key first thing, and all the
internal functions use that instead of the keycode.
To facilitate it a bit, we move the KeycodeInRange check to XkbKey
itself, which returns NULL if the keycode is illegal.

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

index 2f115dc..ff295b5 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -218,10 +218,11 @@ xkb_map_group_get_index(struct xkb_keymap *keymap, const char *name)
 XKB_EXPORT xkb_group_index_t
 xkb_key_num_groups(struct xkb_keymap *keymap, xkb_keycode_t kc)
 {
-    if (!XkbKeycodeInRange(keymap, kc))
+    struct xkb_key *key = XkbKey(keymap, kc);
+    if (!key)
         return 0;
 
-    return XkbKey(keymap, kc)->num_groups;
+    return key->num_groups;
 }
 
 /**
@@ -275,19 +276,14 @@ xkb_map_led_get_index(struct xkb_keymap *keymap, const char *name)
 }
 
 static struct xkb_kt_map_entry *
-get_entry_for_key_state(struct xkb_state *state, xkb_keycode_t kc)
+get_entry_for_key_state(struct xkb_state *state, struct xkb_key *key,
+                        xkb_group_index_t group)
 {
-    struct xkb_keymap *keymap = xkb_state_get_map(state);
-    xkb_group_index_t group;
     struct xkb_key_type *type;
     xkb_mod_mask_t active_mods;
     unsigned int i;
 
-    group = xkb_key_get_group(state, kc);
-    if (group == XKB_GROUP_INVALID)
-        return NULL;
-
-    type = XkbKeyType(keymap, XkbKey(keymap, kc), group);
+    type = XkbKeyType(xkb_state_get_map(state), key, group);
     active_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
     active_mods &= type->mods.mask;
 
@@ -303,13 +299,13 @@ get_entry_for_key_state(struct xkb_state *state, xkb_keycode_t kc)
  * XKB_LEVEL_INVALID.
  */
 xkb_level_index_t
-xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
+xkb_key_get_level(struct xkb_state *state, struct xkb_key *key,
                   xkb_group_index_t group)
 {
     struct xkb_kt_map_entry *entry;
 
     /* If we don't find an explicit match the default is 0. */
-    entry = get_entry_for_key_state(state, kc);
+    entry = get_entry_for_key_state(state, key, group);
     if (!entry)
         return 0;
 
@@ -321,14 +317,11 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
  * wrapping/clamping/etc into account, or XKB_GROUP_INVALID.
  */
 xkb_group_index_t
-xkb_key_get_group(struct xkb_state *state, xkb_keycode_t kc)
+xkb_key_get_group(struct xkb_state *state, struct xkb_key *key)
 {
-    struct xkb_keymap *keymap = xkb_state_get_map(state);
-    struct xkb_key *key;
     xkb_group_index_t ret = xkb_state_serialize_group(state,
                                                       XKB_STATE_EFFECTIVE);
 
-    key = XkbKey(keymap, kc);
     if (key->num_groups == 0)
         return XKB_GROUP_INVALID;
 
@@ -395,16 +388,15 @@ xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
     xkb_group_index_t group;
     xkb_level_index_t level;
 
-    if (!XkbKeycodeInRange(keymap, kc))
-        return -1;
-
     key = XkbKey(keymap, kc);
+    if (!key)
+        return -1;
 
-    group = xkb_key_get_group(state, kc);
+    group = xkb_key_get_group(state, key);
     if (group == XKB_GROUP_INVALID)
         goto err;
 
-    level = xkb_key_get_level(state, kc, group);
+    level = xkb_key_get_level(state, key, group);
     if (level == XKB_LEVEL_INVALID)
         goto err;
 
@@ -421,18 +413,24 @@ err:
 XKB_EXPORT int
 xkb_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
 {
-    if (!XkbKeycodeInRange(keymap, kc))
+    struct xkb_key *key = XkbKey(keymap, kc);
+    if (!key)
         return 0;
 
-    return XkbKey(keymap, kc)->repeats;
+    return key->repeats;
 }
 
 static xkb_mod_mask_t
-key_get_consumed(struct xkb_state *state, xkb_keycode_t kc)
+key_get_consumed(struct xkb_state *state, struct xkb_key *key)
 {
     struct xkb_kt_map_entry *entry;
+    xkb_group_index_t group;
 
-    entry = get_entry_for_key_state(state, kc);
+    group = xkb_key_get_group(state, key);
+    if (group == XKB_GROUP_INVALID)
+        return 0;
+
+    entry = get_entry_for_key_state(state, key, group);
     if (!entry)
         return 0;
 
@@ -455,10 +453,11 @@ XKB_EXPORT int
 xkb_key_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
                               xkb_mod_index_t idx)
 {
-    if (!XkbKeycodeInRange(xkb_state_get_map(state), kc))
+    struct xkb_key *key = XkbKey(xkb_state_get_map(state), kc);
+    if (!key)
         return 0;
 
-    return !!((1 << idx) & key_get_consumed(state, kc));
+    return !!((1 << idx) & key_get_consumed(state, key));
 }
 
 /**
@@ -473,8 +472,9 @@ 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)
 {
-    if (!XkbKeycodeInRange(xkb_state_get_map(state), kc))
-        return mask;
+    struct xkb_key *key = XkbKey(xkb_state_get_map(state), kc);
+    if (!key)
+        return 0;
 
-    return mask & ~key_get_consumed(state, kc);
+    return mask & ~key_get_consumed(state, key);
 }
index 0a26487..5b1798c 100644 (file)
 struct xkb_filter {
     struct xkb_state *state;
     union xkb_action action;
-    xkb_keycode_t kc;
+    struct xkb_key *key;
     uint32_t priv;
-    int (*func)(struct xkb_filter *filter, xkb_keycode_t kc,
+    int (*func)(struct xkb_filter *filter,
+                struct xkb_key *key,
                 enum xkb_key_direction direction);
     int refcnt;
 };
@@ -109,22 +110,19 @@ struct xkb_state {
 static const union xkb_action fake = { .type = ACTION_TYPE_NONE };
 
 static const union xkb_action *
-xkb_key_get_action(struct xkb_state *state, xkb_keycode_t kc)
+xkb_key_get_action(struct xkb_state *state, struct xkb_key *key)
 {
     xkb_group_index_t group;
     xkb_level_index_t level;
-    struct xkb_key *key;
-
-    key = XkbKey(state->keymap, kc);
 
     if (!key->actions)
         return &fake;
 
-    group = xkb_key_get_group(state, kc);
+    group = xkb_key_get_group(state, key);
     if (group == XKB_GROUP_INVALID)
         return &fake;
 
-    level = xkb_key_get_level(state, kc, group);
+    level = xkb_key_get_level(state, key, group);
     if (level == XKB_LEVEL_INVALID)
         return &fake;
 
@@ -134,7 +132,6 @@ xkb_key_get_action(struct xkb_state *state, xkb_keycode_t kc)
 static struct xkb_filter *
 xkb_filter_new(struct xkb_state *state)
 {
-    int old_size = darray_size(state->filters);
     struct xkb_filter *filter = NULL, *iter;
 
     darray_foreach(iter, state->filters) {
@@ -146,7 +143,7 @@ xkb_filter_new(struct xkb_state *state)
 
     if (!filter) {
         darray_resize0(state->filters, darray_size(state->filters) + 1);
-        filter = &darray_item(state->filters, old_size);
+        filter = &darray_item(state->filters, darray_size(state->filters) -1);
     }
 
     filter->state = state;
@@ -157,10 +154,10 @@ xkb_filter_new(struct xkb_state *state)
 /***====================================================================***/
 
 static int
-xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t kc,
+xkb_filter_group_set_func(struct xkb_filter *filter, struct xkb_key *key,
                           enum xkb_key_direction direction)
 {
-    if (kc != filter->kc) {
+    if (key != filter->key) {
         filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
         return 1;
     }
@@ -186,14 +183,14 @@ xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_group_set_new(struct xkb_state *state, struct xkb_key *key,
                          const union xkb_action *action)
 {
     struct xkb_filter *filter = xkb_filter_new(state);
-
-    if (!filter) /* WSGO */
+    if (!filter)
         return -1;
-    filter->kc = kc;
+
+    filter->key = key;
     filter->func = xkb_filter_group_set_func;
     filter->action = *action;
 
@@ -209,10 +206,10 @@ xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t kc,
+xkb_filter_group_lock_func(struct xkb_filter *filter, struct xkb_key *key,
                            enum xkb_key_direction direction)
 {
-    if (kc != filter->kc)
+    if (key != filter->key)
         return 1;
 
     if (direction == XKB_KEY_DOWN) {
@@ -227,15 +224,14 @@ xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_key *key,
                           const union xkb_action *action)
 {
     struct xkb_filter *filter = xkb_filter_new(state);
-
     if (!filter)
-        return 0;
+        return -1;
 
-    filter->kc = kc;
+    filter->key = key;
     filter->func = xkb_filter_group_lock_func;
     filter->action = *action;
 
@@ -248,10 +244,10 @@ xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t kc,
+xkb_filter_mod_set_func(struct xkb_filter *filter, struct xkb_key *key,
                         enum xkb_key_direction direction)
 {
-    if (kc != filter->kc) {
+    if (key != filter->key) {
         filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
         return 1;
     }
@@ -269,19 +265,18 @@ xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t kc,
         filter->state->locked_mods &= ~filter->action.mods.mods.mask;
 
     filter->func = NULL;
-
     return 1;
 }
 
 static int
-xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_key *key,
                        const union xkb_action *action)
 {
     struct xkb_filter *filter = xkb_filter_new(state);
-
-    if (!filter) /* WSGO */
+    if (!filter)
         return -1;
-    filter->kc = kc;
+
+    filter->key = key;
     filter->func = xkb_filter_mod_set_func;
     filter->action = *action;
 
@@ -291,10 +286,10 @@ xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t kc,
+xkb_filter_mod_lock_func(struct xkb_filter *filter, struct xkb_key *key,
                          enum xkb_key_direction direction)
 {
-    if (kc != filter->kc)
+    if (key != filter->key)
         return 1;
 
     if (direction == XKB_KEY_DOWN) {
@@ -305,24 +300,25 @@ xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t kc,
         return 0;
 
     filter->state->locked_mods &= ~filter->priv;
+
     filter->func = NULL;
     return 1;
 }
 
 static int
-xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_key *key,
                         const union xkb_action *action)
 {
     struct xkb_filter *filter = xkb_filter_new(state);
+    if (!filter)
+        return -1;
 
-    if (!filter) /* WSGO */
-        return 0;
-
-    filter->kc = kc;
+    filter->key = key;
     filter->func = xkb_filter_mod_lock_func;
     filter->action = *action;
     filter->priv = state->locked_mods & action->mods.mods.mask;
-    state->locked_mods |= action->mods.mods.mask;
+
+    filter->state->locked_mods |= action->mods.mods.mask;
 
     return 1;
 }
@@ -352,7 +348,7 @@ xkb_action_breaks_latch(const union xkb_action *action)
 }
 
 static int
-xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
+xkb_filter_mod_latch_func(struct xkb_filter *filter, struct xkb_key *key,
                           enum xkb_key_direction direction)
 {
     enum xkb_key_latch_state latch = filter->priv;
@@ -362,7 +358,7 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
          * keypress, then either break the latch if any random key is pressed,
          * or promote it to a lock or plain base set if it's the same
          * modifier. */
-        const union xkb_action *action = xkb_key_get_action(filter->state, kc);
+        const union xkb_action *action = xkb_key_get_action(filter->state, key);
         if (action->type == ACTION_TYPE_MOD_LATCH &&
             action->mods.flags == filter->action.mods.flags &&
             action->mods.mods.mask == filter->action.mods.mods.mask) {
@@ -377,7 +373,7 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
                 filter->func = xkb_filter_mod_set_func;
                 filter->state->set_mods = filter->action.mods.mods.mask;
             }
-            filter->kc = kc;
+            filter->key = key;
             filter->state->latched_mods &= ~filter->action.mods.mods.mask;
             /* XXX beep beep! */
             return 0;
@@ -390,7 +386,7 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
             return 1;
         }
     }
-    else if (direction == XKB_KEY_UP && kc == filter->kc) {
+    else if (direction == XKB_KEY_UP && key == filter->key) {
         /* Our key got released.  If we've set it to clear locks, and we
          * currently have the same modifiers locked, then release them and
          * don't actually latch.  Else we've actually hit the latching
@@ -430,15 +426,15 @@ xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t kc,
 }
 
 static int
-xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_key *key,
                          const union xkb_action *action)
 {
-    struct xkb_filter *filter = xkb_filter_new(state);
     enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
-
-    if (!filter) /* WSGO */
+    struct xkb_filter *filter = xkb_filter_new(state);
+    if (!filter)
         return -1;
-    filter->kc = kc;
+
+    filter->key = key;
     filter->priv = latch;
     filter->func = xkb_filter_mod_latch_func;
     filter->action = *action;
@@ -454,7 +450,7 @@ xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t kc,
  * apply a new filter from the key action.
  */
 static void
-xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t kc,
+xkb_filter_apply_all(struct xkb_state *state, struct xkb_key *key,
                      enum xkb_key_direction direction)
 {
     struct xkb_filter *filter;
@@ -466,25 +462,25 @@ xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t kc,
     darray_foreach(filter, state->filters) {
         if (!filter->func)
             continue;
-        send &= filter->func(filter, kc, direction);
+        send &= filter->func(filter, key, direction);
     }
 
     if (!send || direction == XKB_KEY_UP)
         return;
 
-    act = xkb_key_get_action(state, kc);
+    act = xkb_key_get_action(state, key);
     switch (act->type) {
     case ACTION_TYPE_MOD_SET:
-        send = xkb_filter_mod_set_new(state, kc, act);
+        send = xkb_filter_mod_set_new(state, key, act);
         break;
     case ACTION_TYPE_MOD_LATCH:
-        send = xkb_filter_mod_latch_new(state, kc, act);
+        send = xkb_filter_mod_latch_new(state, key, act);
         break;
     case ACTION_TYPE_MOD_LOCK:
-        send = xkb_filter_mod_lock_new(state, kc, act);
+        send = xkb_filter_mod_lock_new(state, key, act);
         break;
     case ACTION_TYPE_GROUP_SET:
-        send = xkb_filter_group_set_new(state, kc, act);
+        send = xkb_filter_group_set_new(state, key, act);
         break;
 #if 0
     case ACTION_TYPE_GROUP_LATCH:
@@ -492,7 +488,7 @@ xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t kc,
         break;
 #endif
     case ACTION_TYPE_GROUP_LOCK:
-        send = xkb_filter_group_lock_new(state, kc, act);
+        send = xkb_filter_group_lock_new(state, key, act);
         break;
     default:
         break;
@@ -605,16 +601,18 @@ XKB_EXPORT void
 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc,
                      enum xkb_key_direction direction)
 {
+    struct xkb_key *key;
     xkb_mod_index_t i;
     xkb_mod_mask_t bit;
 
-    if (!XkbKeycodeInRange(state->keymap, kc))
+    key = XkbKey(state->keymap, kc);
+    if (!key)
         return;
 
     state->set_mods = 0;
     state->clear_mods = 0;
 
-    xkb_filter_apply_all(state, kc, direction);
+    xkb_filter_apply_all(state, key, direction);
 
     for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) {
         if (state->set_mods & bit) {
index c00f8bf..c66a07e 100644 (file)
@@ -412,6 +412,8 @@ struct xkb_keymap {
 static inline struct xkb_key *
 XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
 {
+    if (kc < keymap->min_key_code || kc > keymap->max_key_code)
+        return NULL;
     return &darray_item(keymap->keys, kc);
 }
 
@@ -460,12 +462,6 @@ XkbKeyActionEntry(struct xkb_key *key, xkb_group_index_t group,
     return &key->actions[key->width * group + level];
 }
 
-static inline bool
-XkbKeycodeInRange(struct xkb_keymap *keymap, xkb_keycode_t kc)
-{
-    return kc >= keymap->min_key_code && kc <= keymap->max_key_code;
-}
-
 struct xkb_keymap *
 xkb_map_new(struct xkb_context *ctx);
 
@@ -495,10 +491,10 @@ const char *
 xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom);
 
 xkb_group_index_t
-xkb_key_get_group(struct xkb_state *state, xkb_keycode_t kc);
+xkb_key_get_group(struct xkb_state *state, struct xkb_key *key);
 
 xkb_level_index_t
-xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
+xkb_key_get_level(struct xkb_state *state, struct xkb_key *key,
                   xkb_group_index_t group);
 
 extern int