Pass around xkb_key's instead of keycodes
authorRan Benita <ran234@gmail.com>
Sun, 15 Jul 2012 12:55:34 +0000 (15:55 +0300)
committerRan Benita <ran234@gmail.com>
Wed, 18 Jul 2012 09:47:29 +0000 (12:47 +0300)
This way we don't need to look up the key every time. We now only deal
with keycodes in the public API and in keycodes.c.

Also adds an xkb_foreach_key macro, which is used a lot.

Signed-off-by: Ran Benita <ran234@gmail.com>
13 files changed:
src/alloc.c
src/alloc.h
src/darray.h
src/keymap-dump.c
src/map.c
src/state.c
src/xkb-priv.h
src/xkbcomp/action.c
src/xkbcomp/alias.c
src/xkbcomp/compat.c
src/xkbcomp/misc.c
src/xkbcomp/symbols.c
src/xkbcomp/xkbcomp-priv.h

index d2e5f5e..2013750 100644 (file)
@@ -67,23 +67,18 @@ XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into)
 }
 
 union xkb_action *
-XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t kc,
+XkbcResizeKeyActions(struct xkb_keymap *keymap, struct xkb_key *key,
                      uint32_t needed)
 {
-    struct xkb_key *key;
     size_t old_ndx, old_num_acts, new_ndx;
 
-    key = XkbKey(keymap, kc);
-
     if (needed == 0) {
         key->acts_index = 0;
         return NULL;
     }
 
-    key = XkbKey(keymap, kc);
-
-    if (XkbKeyHasActions(keymap, kc) && key->width >= needed)
-        return XkbKeyActionsPtr(keymap, kc);
+    if (XkbKeyHasActions(key) && key->width >= needed)
+        return XkbKeyActionsPtr(keymap, key);
 
     /*
      * The key may already be in the array, but without enough space.
@@ -93,7 +88,7 @@ XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t kc,
      */
 
     old_ndx = key->acts_index;
-    old_num_acts = XkbKeyNumActions(keymap, kc);
+    old_num_acts = XkbKeyNumActions(key);
     new_ndx = darray_size(keymap->acts);
 
     darray_resize0(keymap->acts, new_ndx + needed);
@@ -108,7 +103,7 @@ XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t kc,
                darray_mem(keymap->acts, old_ndx),
                old_num_acts * sizeof(union xkb_action));
 
-    return XkbKeyActionsPtr(keymap, kc);
+    return XkbKeyActionsPtr(keymap, key);
 }
 
 static void
index 7da3447..e6df2c5 100644 (file)
@@ -39,7 +39,7 @@ extern int
 XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into);
 
 extern union xkb_action *
-XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t kc,
+XkbcResizeKeyActions(struct xkb_keymap *keymap, struct xkb_key *key,
                      uint32_t needed);
 
 #endif /* ALLOC_H */
index 9a076ea..18f8959 100644 (file)
@@ -340,6 +340,9 @@ darray_next_alloc(size_t alloc, size_t need)
 #define darray_foreach(i, arr) \
     for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
 
+#define darray_foreach_from(i, arr, from) \
+       for ((i) = &(arr).item[from]; (i) < &(arr).item[(arr).size]; (i)++)
+
 /*
  * darray_foreach_reverse(T *&i, darray(T) arr) {...}
  *
index 27a0759..071996a 100644 (file)
@@ -309,7 +309,6 @@ static bool
 write_keycodes(struct xkb_keymap *keymap, char **buf, size_t *size,
                size_t *offset)
 {
-    xkb_keycode_t kc;
     struct xkb_key *key;
     struct xkb_key_alias *alias;
     int i;
@@ -325,13 +324,12 @@ write_keycodes(struct xkb_keymap *keymap, char **buf, size_t *size,
     write_buf(keymap, buf, size, offset, "\t\tmaximum = %d;\n",
               keymap->max_key_code);
 
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-        key = XkbKey(keymap, kc);
+    xkb_foreach_key(key, keymap) {
         if (key->name[0] == '\0')
             continue;
 
         write_buf(keymap, buf, size, offset, "\t\t%6s = %d;\n",
-                  XkbcKeyNameText(key->name), kc);
+                  XkbcKeyNameText(key->name), XkbKeyGetKeycode(keymap, key));
     }
 
     for (i = 0; i < XkbNumIndicators; i++) {
@@ -741,17 +739,17 @@ write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
 
 static bool
 write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
-              size_t *offset, xkb_keycode_t kc, unsigned int group)
+              size_t *offset, struct xkb_key *key, unsigned int group)
 {
     const xkb_keysym_t *syms;
     int num_syms, level;
 #define OUT_BUF_LEN 128
     char out_buf[OUT_BUF_LEN];
 
-    for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group); level++) {
+    for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
         if (level != 0)
             write_buf(keymap, buf, size, offset, ", ");
-        num_syms = xkb_key_get_syms_by_level(keymap, kc, group, level,
+        num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
                                              &syms);
         if (num_syms == 0) {
             write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
@@ -782,7 +780,6 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
               size_t *offset)
 {
     struct xkb_key *key;
-    xkb_keycode_t kc;
     int group, tmp;
     bool showActions;
 
@@ -803,11 +800,10 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
     if (tmp > 0)
         write_buf(keymap, buf, size, offset, "\n");
 
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
+    xkb_foreach_key(key, keymap) {
         bool simple = true;
-        key = XkbKey(keymap, kc);
 
-        if (xkb_key_num_groups(keymap, kc) == 0)
+        if (key->num_groups == 0)
             continue;
 
         write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
@@ -815,25 +811,22 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
 
         if (key->explicit & XkbExplicitKeyTypesMask) {
             bool multi_type = false;
-            int type = XkbKeyTypeIndex(keymap, kc, 0);
+            int type = XkbKeyTypeIndex(key, 0);
 
             simple = false;
 
-            for (group = 0; group < xkb_key_num_groups(keymap, kc);
-                 group++) {
-                if (XkbKeyTypeIndex(keymap, kc, group) != type) {
+            for (group = 0; group < key->num_groups; group++) {
+                if (XkbKeyTypeIndex(key, group) != type) {
                     multi_type = true;
                     break;
                 }
             }
 
             if (multi_type) {
-                for (group = 0;
-                     group < xkb_key_num_groups(keymap, kc);
-                     group++) {
+                for (group = 0; group < key->num_groups; group++) {
                     if (!(key->explicit & (1 << group)))
                         continue;
-                    type = XkbKeyTypeIndex(keymap, kc, group);
+                    type = XkbKeyTypeIndex(key, group);
                     write_buf(keymap, buf, size, offset,
                               "\n\t\t\ttype[group%d]= \"%s\",",
                               group + 1,
@@ -875,16 +868,16 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
         }
 
         if (key->explicit & XkbExplicitInterpretMask)
-            showActions = XkbKeyHasActions(keymap, kc);
+            showActions = XkbKeyHasActions(key);
         else
             showActions = false;
 
-        if (xkb_key_num_groups(keymap, kc) > 1 || showActions)
+        if (key->num_groups > 1 || showActions)
             simple = false;
 
         if (simple) {
             write_buf(keymap, buf, size, offset, "\t[ ");
-            if (!write_keysyms(keymap, buf, size, offset, kc, 0))
+            if (!write_keysyms(keymap, buf, size, offset, key, 0))
                 return false;
             write_buf(keymap, buf, size, offset, " ] };\n");
         }
@@ -892,20 +885,20 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
             union xkb_action *acts;
             int level;
 
-            acts = XkbKeyActionsPtr(keymap, kc);
-            for (group = 0; group < xkb_key_num_groups(keymap, kc); group++) {
+            acts = XkbKeyActionsPtr(keymap, key);
+            for (group = 0; group < key->num_groups; group++) {
                 if (group != 0)
                     write_buf(keymap, buf, size, offset, ",");
                 write_buf(keymap, buf, size, offset,
                           "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
-                if (!write_keysyms(keymap, buf, size, offset, kc, group))
+                if (!write_keysyms(keymap, buf, size, offset, key, group))
                     return false;
                 write_buf(keymap, buf, size, offset, " ]");
                 if (showActions) {
                     write_buf(keymap, buf, size, offset,
                               ",\n\t\t\tactions[Group%d]= [ ", group + 1);
                     for (level = 0;
-                         level < XkbKeyGroupWidth(keymap, kc, group);
+                         level < XkbKeyGroupWidth(keymap, key, group);
                          level++) {
                         if (level != 0)
                             write_buf(keymap, buf, size, offset, ", ");
@@ -920,9 +913,8 @@ write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
         }
     }
 
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
+    xkb_foreach_key(key, keymap) {
         int mod;
-        key = XkbKey(keymap, kc);
 
         if (key->modmap == 0)
             continue;
index a91eba4..00d38d4 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -254,7 +254,7 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
     if (!XkbKeycodeInRange(keymap, kc))
         return 0;
 
-    type = XkbKeyType(keymap, kc, group);
+    type = XkbKeyType(keymap, XkbKey(keymap, kc), group);
     active_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
     active_mods &= type->mods.mask;
 
@@ -308,23 +308,22 @@ xkb_key_get_group(struct xkb_state *state, xkb_keycode_t kc)
  * As below, but takes an explicit group/level rather than state.
  */
 int
-xkb_key_get_syms_by_level(struct xkb_keymap *keymap, xkb_keycode_t kc,
+xkb_key_get_syms_by_level(struct xkb_keymap *keymap, struct xkb_key *key,
                           unsigned int group, unsigned int level,
                           const xkb_keysym_t **syms_out)
 {
     int num_syms;
-    struct xkb_key *key = XkbKey(keymap, kc);
 
     if (group >= key->num_groups)
         goto err;
-    if (level >= XkbKeyGroupWidth(keymap, kc, group))
+    if (level >= XkbKeyGroupWidth(keymap, key, group))
         goto err;
 
-    num_syms = XkbKeyNumSyms(keymap, kc, group, level);
+    num_syms = XkbKeyNumSyms(key, group, level);
     if (num_syms == 0)
         goto err;
 
-    *syms_out = XkbKeySymEntry(keymap, kc, group, level);
+    *syms_out = XkbKeySymEntry(key, group, level);
     return num_syms;
 
 err:
@@ -341,20 +340,23 @@ xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
                  const xkb_keysym_t **syms_out)
 {
     struct xkb_keymap *keymap = xkb_state_get_map(state);
-    int group;
-    int level;
+    struct xkb_key *key;
+    int group, level;
 
     if (!state || !XkbKeycodeInRange(keymap, kc))
         return -1;
 
+    key = XkbKey(keymap, kc);
+
     group = xkb_key_get_group(state, kc);
     if (group == -1)
         goto err;
+
     level = xkb_key_get_level(state, kc, group);
     if (level == -1)
         goto err;
 
-    return xkb_key_get_syms_by_level(keymap, kc, group, level, syms_out);
+    return xkb_key_get_syms_by_level(keymap, key, group, level, syms_out);
 
 err:
     *syms_out = NULL;
index a94f3fd..94bff55 100644 (file)
@@ -110,9 +110,12 @@ static union xkb_action *
 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t kc)
 {
     unsigned int group, level;
+    struct xkb_key *key = NULL;
 
-    if (!XkbKeyHasActions(state->keymap, kc) ||
-        !XkbKeycodeInRange(state->keymap, kc)) {
+    if (XkbKeycodeInRange(state->keymap, kc))
+        key = XkbKey(state->keymap, kc);
+
+    if (!key || !XkbKeyHasActions(key)) {
         static union xkb_action fake;
         memset(&fake, 0, sizeof(fake));
         fake.type = XkbSA_NoAction;
@@ -122,7 +125,7 @@ xkb_key_get_action(struct xkb_state *state, xkb_keycode_t kc)
     group = xkb_key_get_group(state, kc);
     level = xkb_key_get_level(state, kc, group);
 
-    return XkbKeyActionEntry(state->keymap, kc, group, level);
+    return XkbKeyActionEntry(state->keymap, key, group, level);
 }
 
 static struct xkb_filter *
index 822ee44..90b540b 100644 (file)
@@ -372,84 +372,88 @@ XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
     return &darray_item(keymap->keys, kc);
 }
 
+static inline xkb_keycode_t
+XkbKeyGetKeycode(struct xkb_keymap *keymap, struct xkb_key *key)
+{
+    /* Hack to avoid having to keep the keycode inside the xkb_key. */
+    return (xkb_keycode_t)(key - keymap->keys.item);
+}
+
+#define xkb_foreach_key_from(iter, keymap, from) \
+    darray_foreach_from(iter, keymap->keys, from)
+
+#define xkb_foreach_key(iter, keymap) \
+    xkb_foreach_key_from(iter, keymap, keymap->min_key_code)
+
 static inline unsigned char
-XkbKeyTypeIndex(struct xkb_keymap *keymap, xkb_keycode_t kc,
-                unsigned int group)
+XkbKeyTypeIndex(struct xkb_key *key, unsigned int group)
 {
-    return XkbKey(keymap, kc)->kt_index[group & 0x3];
+    return key->kt_index[group & 0x3];
 }
 
 static inline struct xkb_key_type *
-XkbKeyType(struct xkb_keymap *keymap, xkb_keycode_t kc, unsigned int group)
+XkbKeyType(struct xkb_keymap *keymap, struct xkb_key *key, unsigned int group)
 {
-    return &darray_item(keymap->types, XkbKeyTypeIndex(keymap, kc, group));
+    return &darray_item(keymap->types, XkbKeyTypeIndex(key, group));
 }
 
 static inline uint16_t
-XkbKeyGroupWidth(struct xkb_keymap *keymap, xkb_keycode_t kc,
+XkbKeyGroupWidth(struct xkb_keymap *keymap, struct xkb_key *key,
                  unsigned int group)
 {
-    return XkbKeyType(keymap, kc, group)->num_levels;
+    return XkbKeyType(keymap, key, group)->num_levels;
 }
 
 static inline unsigned int
-XkbKeyNumSyms(struct xkb_keymap *keymap, xkb_keycode_t kc,
-              unsigned int group, unsigned int level)
+XkbKeyNumSyms(struct xkb_key *key, unsigned int group, unsigned int level)
 {
-    struct xkb_key *key = XkbKey(keymap, kc);
     return key->num_syms[group * key->width + level];
 }
 
 static inline xkb_keysym_t *
-XkbKeySym(struct xkb_keymap *keymap, xkb_keycode_t kc, int ndx)
+XkbKeySym(struct xkb_key *key, int ndx)
 {
-    return &darray_item(XkbKey(keymap, kc)->syms, ndx);
+    return &darray_item(key->syms, ndx);
 }
 
 static inline int
-XkbKeySymOffset(struct xkb_keymap *keymap, xkb_keycode_t kc,
-                unsigned group, unsigned int level)
+XkbKeySymOffset(struct xkb_key *key, unsigned group, unsigned int level)
 {
-    struct xkb_key *key = XkbKey(keymap, kc);
     return key->sym_index[group * key->width + level];
 }
 
 static inline xkb_keysym_t *
-XkbKeySymEntry(struct xkb_keymap *keymap, xkb_keycode_t kc,
-               unsigned group, unsigned int level)
+XkbKeySymEntry(struct xkb_key *key, unsigned group, unsigned int level)
 {
-    return XkbKeySym(keymap, kc, XkbKeySymOffset(keymap, kc, group, level));
+    return XkbKeySym(key, XkbKeySymOffset(key, group, level));
 }
 
 static inline bool
-XkbKeyHasActions(struct xkb_keymap *keymap, xkb_keycode_t kc)
+XkbKeyHasActions(struct xkb_key *key)
 {
-    return XkbKey(keymap, kc)->acts_index != 0;
+    return key->acts_index != 0;
 }
 
 static inline unsigned char
-XkbKeyNumActions(struct xkb_keymap *keymap, xkb_keycode_t kc)
+XkbKeyNumActions(struct xkb_key *key)
 {
-    struct xkb_key *key = XkbKey(keymap, kc);
-    if (XkbKeyHasActions(keymap, kc))
+    if (XkbKeyHasActions(key))
         return key->width * key->num_groups;
     return 1;
 }
 
 static inline union xkb_action *
-XkbKeyActionsPtr(struct xkb_keymap *keymap, xkb_keycode_t kc)
+XkbKeyActionsPtr(struct xkb_keymap *keymap, struct xkb_key *key)
 {
-    struct xkb_key *key = XkbKey(keymap, kc);
     return darray_mem(keymap->acts, key->acts_index);
 }
 
 static inline union xkb_action *
-XkbKeyActionEntry(struct xkb_keymap *keymap, xkb_keycode_t kc,
+XkbKeyActionEntry(struct xkb_keymap *keymap, struct xkb_key *key,
                   unsigned int group, unsigned int level)
 {
-    struct xkb_key *key = XkbKey(keymap, kc);
-    if (XkbKeyHasActions(keymap, kc))
-        return &XkbKeyActionsPtr(keymap, kc)[key->width * group + level];
+    if (XkbKeyHasActions(key))
+        return &XkbKeyActionsPtr(keymap, key)[key->width * group + level];
     return NULL;
 }
 
@@ -480,7 +484,7 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
                   unsigned int group);
 
 extern int
-xkb_key_get_syms_by_level(struct xkb_keymap *keymap, xkb_keycode_t kc,
+xkb_key_get_syms_by_level(struct xkb_keymap *keymap, struct xkb_key *key,
                           unsigned int group, unsigned int level,
                           const xkb_keysym_t **syms_out);
 
index 964b777..4f0a6e9 100644 (file)
@@ -799,9 +799,9 @@ HandleRedirectKey(struct xkb_keymap *keymap, struct xkb_any_action *action,
                   unsigned field, ExprDef *array_ndx, ExprDef *value)
 {
     ExprResult rtrn;
+    struct xkb_key *key;
     struct xkb_redirect_key_action *act;
     unsigned t1, t2;
-    xkb_keycode_t kc;
     unsigned long tmp;
 
     if (array_ndx != NULL)
@@ -812,13 +812,13 @@ HandleRedirectKey(struct xkb_keymap *keymap, struct xkb_any_action *action,
     case F_Keycode:
         if (!ExprResolveKeyName(keymap->ctx, value, &rtrn))
             return ReportMismatch(action->type, field, "key name");
+
         tmp = KeyNameToLong(rtrn.name);
-        if (!FindNamedKey(keymap, tmp, &kc, true, CreateKeyNames(keymap),
-                          0)) {
+        key = FindNamedKey(keymap, tmp, true, CreateKeyNames(keymap), 0);
+        if (!key)
             return ReportNotFound(action->type, field, "Key",
                                   XkbcKeyNameText(rtrn.name));
-        }
-        act->new_kc = kc;
+        act->new_kc = XkbKeyGetKeycode(keymap, key);
         return true;
 
     case F_ModsToClear:
index 4be638c..6d57511 100644 (file)
@@ -142,22 +142,21 @@ int
 ApplyAliases(struct xkb_keymap *keymap, AliasInfo ** info_in)
 {
     int i;
+    struct xkb_key *key;
     struct xkb_key_alias *old, *a;
     AliasInfo *info;
     int nNew, nOld;
 
-    if (*info_in == NULL)
-        return true;
-    nOld = (keymap ? darray_size(keymap->key_aliases) : 0);
-    old = (keymap ? &darray_item(keymap->key_aliases, 0) : NULL);
-    for (nNew = 0, info = *info_in; info != NULL;
-         info = (AliasInfo *) info->def.next) {
+    nOld = darray_size(keymap->key_aliases);
+    old = &darray_item(keymap->key_aliases, 0);
+
+    for (nNew = 0, info = *info_in; info;
+         info = (AliasInfo *)info->def.next) {
         unsigned long lname;
-        xkb_keycode_t kc;
 
         lname = KeyNameToLong(info->real);
-        if (!FindNamedKey(keymap, lname, &kc, false, CreateKeyNames(keymap),
-                          0)) {
+        key = FindNamedKey(keymap, lname, false, CreateKeyNames(keymap), 0);
+        if (!key) {
             if (warningLevel > 4) {
                 WARN("Attempt to alias %s to non-existent key %s\n",
                      XkbcKeyNameText(info->alias), XkbcKeyNameText(info->real));
@@ -166,8 +165,10 @@ ApplyAliases(struct xkb_keymap *keymap, AliasInfo ** info_in)
             info->alias[0] = '\0';
             continue;
         }
+
         lname = KeyNameToLong(info->alias);
-        if (FindNamedKey(keymap, lname, &kc, false, false, 0)) {
+        key = FindNamedKey(keymap, lname, false, false, 0);
+        if (key) {
             if (warningLevel > 4) {
                 WARN("Attempt to create alias with the name of a real key\n");
                 ACTION("Alias \"%s = %s\" ignored\n",
@@ -177,44 +178,42 @@ ApplyAliases(struct xkb_keymap *keymap, AliasInfo ** info_in)
             info->alias[0] = '\0';
             continue;
         }
+
         nNew++;
-        if (old) {
-            for (i = 0, a = old; i < nOld; i++, a++) {
-                if (strncmp(a->alias, info->alias, XkbKeyNameLength) == 0) {
-                    AliasInfo old_info;
-                    InitAliasInfo(&old_info, MERGE_AUGMENT, 0, a->alias,
-                                  a->real);
-                    HandleCollision(&old_info, info);
-                    memcpy(old_info.real, a->real, XkbKeyNameLength);
-                    info->alias[0] = '\0';
-                    nNew--;
-                    break;
-                }
-            }
+
+        if (!old)
+            continue;
+
+        for (i = 0, a = old; i < nOld; i++, a++) {
+            AliasInfo old_info;
+
+            if (strncmp(a->alias, info->alias, XkbKeyNameLength) != 0)
+                continue;
+
+            InitAliasInfo(&old_info, MERGE_AUGMENT, 0, a->alias, a->real);
+            HandleCollision(&old_info, info);
+            memcpy(old_info.real, a->real, XkbKeyNameLength);
+            info->alias[0] = '\0';
+            nNew--;
+            break;
         }
     }
-    if (nNew == 0) {
-        ClearCommonInfo(&(*info_in)->def);
-        *info_in = NULL;
-        return true;
-    }
+
+    if (nNew == 0)
+        goto out;
 
     darray_resize0(keymap->key_aliases, nOld + nNew);
 
-    a = keymap ? &darray_item(keymap->key_aliases, nOld) : NULL;
-    for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next) {
+    a = &darray_item(keymap->key_aliases, nOld);
+    for (info = *info_in; info; info = (AliasInfo *)info->def.next) {
         if (info->alias[0] != '\0') {
             strncpy(a->alias, info->alias, XkbKeyNameLength);
             strncpy(a->real, info->real, XkbKeyNameLength);
             a++;
         }
     }
-#ifdef DEBUG
-    if ((a - old) != (nOld + nNew)) {
-        WSGO("Expected %d aliases total but created %d\n", nOld + nNew,
-             a - old);
-    }
-#endif
+
+out:
     ClearCommonInfo(&(*info_in)->def);
     *info_in = NULL;
     return true;
index d06dae6..8d492db 100644 (file)
@@ -826,7 +826,7 @@ UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act,
  * generic XKB_KEY_NoSymbol match.
  */
 static struct xkb_sym_interpret *
-FindInterpForKey(struct xkb_keymap *keymap, xkb_keycode_t kc,
+FindInterpForKey(struct xkb_keymap *keymap, struct xkb_key *key,
                  uint32_t group, uint32_t level)
 {
     struct xkb_sym_interpret *ret = NULL;
@@ -834,7 +834,7 @@ FindInterpForKey(struct xkb_keymap *keymap, xkb_keycode_t kc,
     const xkb_keysym_t *syms;
     int num_syms;
 
-    num_syms = xkb_key_get_syms_by_level(keymap, kc, group, level, &syms);
+    num_syms = xkb_key_get_syms_by_level(keymap, key, group, level, &syms);
     if (num_syms == 0)
         return NULL;
 
@@ -847,7 +847,7 @@ FindInterpForKey(struct xkb_keymap *keymap, xkb_keycode_t kc,
             continue;
 
         if (level == 0 || !(interp->match & XkbSI_LevelOneOnly))
-            mods = XkbKey(keymap, kc)->modmap;
+            mods = key->modmap;
         else
             mods = 0;
 
@@ -884,7 +884,7 @@ FindInterpForKey(struct xkb_keymap *keymap, xkb_keycode_t kc,
 /**
  */
 static bool
-ApplyInterpsToKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
+ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
 {
 #define INTERP_SIZE (8 * 4)
     struct xkb_sym_interpret *interps[INTERP_SIZE];
@@ -892,11 +892,8 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
     uint32_t vmodmask = 0;
     int num_acts = 0;
     int group, level;
-    struct xkb_key *key;
     int i;
 
-    key = XkbKey(keymap, kc);
-
     /* If we've been told not to bind interps to this key, then don't. */
     if (key->explicit & XkbExplicitInterpretMask)
         return true;
@@ -905,12 +902,12 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
         interps[i] = NULL;
 
     for (group = 0; group < key->num_groups; group++) {
-        for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
+        for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
              level++) {
             i = (group * key->width) + level;
             if (i >= INTERP_SIZE) /* XXX FIXME */
                 return false;
-            interps[i] = FindInterpForKey(keymap, kc, group, level);
+            interps[i] = FindInterpForKey(keymap, key, group, level);
             if (interps[i])
                 num_acts++;
         }
@@ -918,12 +915,12 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
 
     if (num_acts)
         num_acts = key->num_groups * key->width;
-    acts = XkbcResizeKeyActions(keymap, kc, num_acts);
+    acts = XkbcResizeKeyActions(keymap, key, num_acts);
     if (num_acts && !acts)
         return false;
 
     for (group = 0; group < key->num_groups; group++) {
-        for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
+        for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
              level++) {
             struct xkb_sym_interpret *interp;
 
@@ -968,7 +965,6 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
 bool
 UpdateModifiersFromCompat(struct xkb_keymap *keymap)
 {
-    xkb_keycode_t kc;
     struct xkb_key *key;
     int i;
     struct xkb_key_type *type;
@@ -976,17 +972,17 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
 
     /* Find all the interprets for the key and bind them to actions,
      * which will also update the vmodmap. */
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++)
-        if (!ApplyInterpsToKey(keymap, kc))
+    xkb_foreach_key(key, keymap)
+        if (!ApplyInterpsToKey(keymap, key))
             return false;
 
     /* Update keymap->vmods, the virtual -> real mod mapping. */
     for (i = 0; i < XkbNumVirtualMods; i++)
         keymap->vmods[i] = 0;
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-        key = XkbKey(keymap, kc);
+    xkb_foreach_key(key, keymap) {
         if (!key->vmodmap)
             continue;
+
         for (i = 0; i < XkbNumVirtualMods; i++) {
             if (!(key->vmodmap & (1 << i)))
                 continue;
@@ -1012,10 +1008,9 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
     }
 
     /* Update action modifiers. */
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-        union xkb_action *acts = XkbKeyActionsPtr(keymap, kc);
-        key = XkbKey(keymap, kc);
-        for (i = 0; i < XkbKeyNumActions(keymap, kc); i++) {
+    xkb_foreach_key(key, keymap) {
+        union xkb_action *acts = XkbKeyActionsPtr(keymap, key);
+        for (i = 0; i < XkbKeyNumActions(key); i++) {
             if (acts[i].any.type == XkbSA_NoAction)
                 continue;
             UpdateActionMods(keymap, &acts[i], key->modmap);
index 94a5e19..7d1d380 100644 (file)
@@ -200,66 +200,51 @@ AddCommonInfo(CommonInfo * old, CommonInfo * new)
 /***====================================================================***/
 
 /**
- * Find the key with the given name and return its keycode in kc_rtrn.
+ * Find the key with the given name.
  *
  * @param keymap The keymap to search in.
  * @param name The 4-letter name of the key as a long.
- * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
  * @param use_aliases true if the key aliases should be searched too.
  * @param create If true and the key is not found, it is added to the
  *        keymap->names at the first free keycode.
  * @param start_from Keycode to start searching from.
  *
- * @return true if found, false otherwise.
+ * @return the key if it is found, NULL otherwise.
  */
-bool
+struct xkb_key *
 FindNamedKey(struct xkb_keymap *keymap, unsigned long name,
-             xkb_keycode_t *kc_rtrn, bool use_aliases, bool create,
-             xkb_keycode_t start_from)
+             bool use_aliases, bool create, xkb_keycode_t start_from)
 {
-    xkb_keycode_t kc;
     struct xkb_key *key;
 
     if (start_from < keymap->min_key_code)
         start_from = keymap->min_key_code;
     else if (start_from > keymap->max_key_code)
-        return false;
-
-    *kc_rtrn = 0;               /* some callers rely on this */
+        return NULL;
 
-    for (kc = start_from; kc <= keymap->max_key_code; kc++) {
-        unsigned long tmp;
-        key = XkbKey(keymap, kc);
-
-        tmp = KeyNameToLong(key->name);
-        if (tmp == name) {
-            *kc_rtrn = kc;
-            return true;
-        }
-    }
+    xkb_foreach_key_from(key, keymap, start_from)
+        if (KeyNameToLong(key->name) == name)
+            return key;
 
     if (use_aliases) {
         unsigned long new_name;
         if (FindKeyNameForAlias(keymap, name, &new_name))
-            return FindNamedKey(keymap, new_name, kc_rtrn, false,
-                                create, 0);
+            return FindNamedKey(keymap, new_name, false, create, 0);
     }
 
     if (create) {
-        /* Find first unused keycode and store our key here */
-        for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-            key = XkbKey(keymap, kc);
-
+        /* Find first unused key and store our key here */
+        xkb_foreach_key(key, keymap) {
             if (key->name[0] == '\0') {
                 char buf[XkbKeyNameLength + 1];
                 LongToKeyName(name, buf);
                 memcpy(key->name, buf, XkbKeyNameLength);
-                *kc_rtrn = kc;
-                return true;
+                return key;
             }
         }
     }
-    return false;
+
+    return NULL;
 }
 
 bool
index f81c532..d766cd0 100644 (file)
@@ -1422,9 +1422,8 @@ HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
 }
 
 /**
- * Given a keysym @sym, find the keycode which generates it
- * (returned in @kc_rtrn). This is used for example in a modifier
- * map definition, such as:
+ * Given a keysym @sym, return a key which generates it, or NULL.
+ * This is used for example in a modifier map definition, such as:
  *      modifier_map Lock           { Caps_Lock };
  * where we want to add the Lock modifier to the modmap of the key
  * which matches the keysym Caps_Lock.
@@ -1432,22 +1431,18 @@ HandleSymbolsFile(XkbFile *file, struct xkb_keymap *keymap,
  * is chosen first by lowest group in which the keysym appears, than
  * by lowest level and than by lowest key code.
  */
-static bool
-FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
-                 xkb_keycode_t *kc_rtrn)
+static struct xkb_key *
+FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym)
 {
-    xkb_keycode_t kc;
-    struct xkb_key *key;
+    struct xkb_key *key, *ret = NULL;
     unsigned int group, level, min_group = UINT_MAX, min_level = UINT_MAX;
 
-    for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-        key = XkbKey(keymap, kc);
-
+    xkb_foreach_key(key, keymap) {
         for (group = 0; group < key->num_groups; group++) {
-            for (level = 0; level < XkbKeyGroupWidth(keymap, kc, group);
+            for (level = 0; level < XkbKeyGroupWidth(keymap, key, group);
                  level++) {
-                if (XkbKeyNumSyms(keymap, kc, group, level) != 1 ||
-                    (XkbKeySymEntry(keymap, kc, group, level))[0] != sym)
+                if (XkbKeyNumSyms(key, group, level) != 1 ||
+                    (XkbKeySymEntry(key, group, level))[0] != sym)
                     continue;
 
                 /*
@@ -1457,9 +1452,9 @@ FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
                  */
                 if (group < min_group ||
                     (group == min_group && level < min_level)) {
-                    *kc_rtrn = kc;
+                    ret = key;
                     if (group == 0 && level == 0) {
-                        return true;
+                        return ret;
                     }
                     else {
                         min_group = group;
@@ -1470,7 +1465,7 @@ FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym,
         }
     }
 
-    return min_group != UINT_MAX;
+    return ret;
 }
 
 /**
@@ -1696,17 +1691,16 @@ CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *keyi, int start_from)
 
     useAlias = (start_from == 0);
 
-    /* get the keycode for the key. */
-    if (!FindNamedKey(keymap, keyi->name, &kc, useAlias,
-                      CreateKeyNames(keymap), start_from)) {
-        if ((start_from == 0) && (warningLevel >= 5)) {
+    key = FindNamedKey(keymap, keyi->name, useAlias,
+                       CreateKeyNames(keymap), start_from);
+    if (!key) {
+        if (start_from == 0 && warningLevel >= 5) {
             WARN("Key %s not found in keycodes\n", longText(keyi->name));
             ACTION("Symbols ignored\n");
         }
         return false;
     }
-
-    key = XkbKey(keymap, kc);
+    kc = XkbKeyGetKeycode(keymap, key);
 
     haveActions = false;
     for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) {
@@ -1768,7 +1762,7 @@ CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *keyi, int start_from)
     darray_resize0(key->syms, sizeSyms);
 
     if (haveActions) {
-        outActs = XkbcResizeKeyActions(keymap, kc, width * nGroups);
+        outActs = XkbcResizeKeyActions(keymap, key, width * nGroups);
         if (outActs == NULL) {
             WSGO("Could not enlarge actions for %s (key %d)\n",
                  longText(keyi->name), kc);
@@ -1852,31 +1846,35 @@ CopySymbolsDef(struct xkb_keymap *keymap, KeyInfo *keyi, int start_from)
 static bool
 CopyModMapDef(struct xkb_keymap *keymap, ModMapEntry *entry)
 {
-    xkb_keycode_t kc;
+    struct xkb_key *key;
 
-    if (!entry->haveSymbol &&
-        !FindNamedKey(keymap, entry->u.keyName, &kc, true,
-                      CreateKeyNames(keymap), 0)) {
-        if (warningLevel >= 5) {
-            WARN("Key %s not found in keycodes\n",
-                 longText(entry->u.keyName));
-            ACTION("Modifier map entry for %s not updated\n",
-                   XkbcModIndexText(entry->modifier));
+    if (!entry->haveSymbol) {
+        key = FindNamedKey(keymap, entry->u.keyName, true,
+                           CreateKeyNames(keymap), 0);
+        if (!key) {
+            if (warningLevel >= 5) {
+                WARN("Key %s not found in keycodes\n",
+                     longText(entry->u.keyName));
+                ACTION("Modifier map entry for %s not updated\n",
+                       XkbcModIndexText(entry->modifier));
+            }
+            return false;
         }
-        return false;
     }
-    else if (entry->haveSymbol &&
-             !FindKeyForSymbol(keymap, entry->u.keySym, &kc)) {
-        if (warningLevel > 5) {
-            WARN("Key \"%s\" not found in symbol map\n",
-                 XkbcKeysymText(entry->u.keySym));
-            ACTION("Modifier map entry for %s not updated\n",
-                   XkbcModIndexText(entry->modifier));
+    else {
+        key = FindKeyForSymbol(keymap, entry->u.keySym);
+        if (!key) {
+            if (warningLevel > 5) {
+                WARN("Key \"%s\" not found in symbol map\n",
+                     XkbcKeysymText(entry->u.keySym));
+                ACTION("Modifier map entry for %s not updated\n",
+                       XkbcModIndexText(entry->modifier));
+            }
+            return false;
         }
-        return false;
     }
 
-    XkbKey(keymap, kc)->modmap |= (1 << entry->modifier);
+    key->modmap |= (1 << entry->modifier);
     return true;
 }
 
@@ -1892,7 +1890,6 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
                enum merge_mode merge)
 {
     int i;
-    xkb_keycode_t kc;
     struct xkb_key *key;
     SymbolsInfo info;
     KeyInfo *keyi;
@@ -1934,14 +1931,13 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
             info.errorCount++;
 
     if (warningLevel > 3) {
-        for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) {
-            key = XkbKey(keymap, kc);
+        xkb_foreach_key(key, keymap) {
             if (key->name[0] == '\0')
                 continue;
 
             if (key->num_groups < 1)
                 WARN("No symbols defined for <%.4s> (keycode %d)\n",
-                     key->name, kc);
+                     key->name, XkbKeyGetKeycode(keymap, key));
         }
     }
 
index d998bb1..8322fdf 100644 (file)
@@ -67,10 +67,9 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
                    enum xkb_file_type file_type, XkbFile **file_rtrn,
                    enum merge_mode *merge_rtrn);
 
-extern bool
+struct xkb_key *
 FindNamedKey(struct xkb_keymap *keymap, unsigned long name,
-             xkb_keycode_t *kc_rtrn, bool use_aliases, bool create,
-             xkb_keycode_t start_from);
+             bool use_aliases, bool create, xkb_keycode_t start_from);
 
 extern bool
 FindKeyNameForAlias(struct xkb_keymap *keymap, unsigned long lname,