keytypes: use darray for xkb_kt_map_entry's
authorRan Benita <ran234@gmail.com>
Tue, 22 May 2012 07:59:46 +0000 (10:59 +0300)
committerRan Benita <ran234@gmail.com>
Tue, 22 May 2012 11:19:24 +0000 (14:19 +0300)
Signed-off-by: Ran Benita <ran234@gmail.com>
src/alloc.c
src/alloc.h
src/darray.h
src/map.c
src/misc.c
src/xkb-priv.h
src/xkb.c
src/xkbcomp/compat.c
src/xkbcomp/keytypes.c

index e95166e..b768da0 100644 (file)
@@ -149,38 +149,33 @@ XkbcAllocServerMap(struct xkb_keymap *keymap, unsigned which,
 }
 
 int
-XkbcCopyKeyType(struct xkb_key_type * from, struct xkb_key_type * into)
+XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into)
 {
     int i;
 
     if (!from || !into)
         return BadMatch;
 
-    free(into->map);
-    into->map = NULL;
+    darray_free(into->map);
     free(into->preserve);
-    into->preserve= NULL;
     for (i = 0; i < into->num_levels; i++)
         free(UNCONSTIFY(into->level_names[i]));
     free(into->level_names);
-    into->level_names = NULL;
 
     *into = *from;
 
-    if (from->map && (into->map_count > 0)) {
-        into->map = uTypedCalloc(into->map_count, struct xkb_kt_map_entry);
-        if (!into->map)
-            return BadAlloc;
-        memcpy(into->map, from->map,
-               into->map_count * sizeof(struct xkb_kt_map_entry));
-    }
+    darray_init(into->map);
+    darray_from_items(into->map,
+                      &darray_item(from->map, 0),
+                      darray_size(from->map));
 
-    if (from->preserve && (into->map_count > 0)) {
-        into->preserve = uTypedCalloc(into->map_count, struct xkb_mods);
+    if (from->preserve && !darray_empty(into->map)) {
+        into->preserve = calloc(darray_size(into->map),
+                                sizeof(*into->preserve));
         if (!into->preserve)
             return BadAlloc;
         memcpy(into->preserve, from->preserve,
-               into->map_count * sizeof(struct xkb_mods));
+               darray_size(into->map) * sizeof(*into->preserve));
     }
 
     if (from->level_names && (into->num_levels > 0)) {
@@ -290,7 +285,7 @@ XkbcFreeClientMap(struct xkb_keymap *keymap)
 
     darray_foreach(type, map->types) {
         int j;
-        free(type->map);
+        darray_free(type->map);
         free(type->preserve);
         for (j = 0; j < type->num_levels; j++)
             free(UNCONSTIFY(type->level_names[j]));
index 0e94682..4e2bb73 100644 (file)
@@ -57,7 +57,7 @@ XkbcAllocServerMap(struct xkb_keymap *keymap, unsigned which,
                    unsigned nNewActions);
 
 extern int
-XkbcCopyKeyType(struct xkb_key_type *from, struct xkb_key_type *into);
+XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into);
 
 extern bool
 XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t key,
index b7e08db..6c21bbf 100644 (file)
  *     darray_init(foo.a);
  *     darray_free(foo.a);
  *
+ *     const struct {
+ *         darray(int) a;
+ *      } foo = {
+ *         .a = darray_lit({1, 2, 3})
+ *      };
+ *
  * Typedefs for darrays of common types:
  *
  *     darray_char, darray_schar, darray_uchar
 #define darray(type) struct {type *item; size_t size; size_t alloc;}
 
 #define darray_new() {0,0,0}
+#define darray_lit(c_array) {(c_array), sizeof(c_array) / sizeof(*(c_array)), 0}
 #define darray_init(arr) do {(arr).item=0; (arr).size=0; (arr).alloc=0;} while(0)
 #define darray_free(arr) do {free((arr).item);} while(0)
 
index fb005a5..5637dcf 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -246,14 +246,15 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t key,
 {
     struct xkb_keymap *keymap = state->keymap;
     struct xkb_key_type *type = XkbKeyType(keymap, key, group);
+    struct xkb_kt_map_entry *entry;
     unsigned int active_mods = state->mods & type->mods.mask;
-    int i;
 
-    for (i = 0; i < type->map_count; i++) {
-        if (!type->map[i].active)
+    darray_foreach(entry, type->map) {
+        if (!entry->active)
             continue;
-        if (type->map[i].mods.mask == active_mods)
-            return type->map[i].level;
+
+        if (entry->mods.mask == active_mods)
+            return entry->level;
     }
 
     return 0;
index ac54077..e7ebbbd 100644 (file)
@@ -27,51 +27,77 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "xkb-priv.h"
 #include "alloc.h"
 
-#define mapSize(m) (sizeof(m) / sizeof(struct xkb_kt_map_entry))
 static struct xkb_kt_map_entry map2Level[]= {
-    { true, ShiftMask, {1, ShiftMask, 0} }
+    {
+        .active = true,
+        .level = ShiftMask,
+        .mods = {.mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+    }
 };
 
 static struct xkb_kt_map_entry mapAlpha[]= {
-    { true, ShiftMask, { 1, ShiftMask, 0 } },
-    { true, LockMask,  { 0, LockMask,  0 } }
+    {
+        .active = true,
+        .level = ShiftMask,
+        .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+    },
+    {
+        .active = true,
+        .level = LockMask,
+        .mods = { .mask = 0, .vmods = LockMask,  .real_mods = 0 }
+    }
 };
 
 static struct xkb_mods preAlpha[]= {
-    { 0,        0,        0 },
-    { LockMask, LockMask, 0 }
+    { .mask = 0,        .vmods = 0,        .real_mods = 0 },
+    { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
 };
 
 #define NL_VMOD_MASK 0
-static  struct xkb_kt_map_entry mapKeypad[]= {
-    { true,  ShiftMask, { 1, ShiftMask, 0 } },
-    { false, 0,         { 1, 0, NL_VMOD_MASK } }
+static struct xkb_kt_map_entry mapKeypad[]= {
+    {
+        .active = true,
+        .level = ShiftMask,
+        .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
+    },
+    {
+        .active = false,
+        .level = 0,
+        .mods = { .mask = 1, .vmods = 0, .real_mods = NL_VMOD_MASK }
+    }
 };
 
-static struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
-    { { 0, 0, 0 },
-      1,        /* num_levels */
-      0,        /* map_count */
-      NULL, NULL,
-      NULL, NULL
+static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
+    {
+        .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
+        .num_levels = 1,
+        .preserve = NULL,
+        .name = NULL,
+        .level_names = NULL
     },
-    { { ShiftMask, ShiftMask, 0 },
-      2,        /* num_levels */
-      mapSize(map2Level),   /* map_count */
-      map2Level, NULL,
-      NULL,      NULL
+    {
+        .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
+        .num_levels = 2,
+        .map = darray_lit(map2Level),
+        .preserve = NULL,
+        .name = NULL,
+        .level_names = NULL
     },
-    { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
-      2,        /* num_levels */
-      mapSize(mapAlpha),    /* map_count */
-      mapAlpha, preAlpha,
-      NULL,     NULL
+    {
+        .mods = { .mask = ShiftMask|LockMask, .vmods = ShiftMask|LockMask, .real_mods = 0 },
+        .num_levels = 2,
+        .map = darray_lit(mapAlpha),
+        .preserve = preAlpha,
+        .name = NULL,
+        .level_names = NULL
     },
-    { { ShiftMask, ShiftMask, NL_VMOD_MASK },
-      2,        /* num_levels */
-      mapSize(mapKeypad),   /* map_count */
-      mapKeypad, NULL,
-      NULL,      NULL
+    {
+        .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = NL_VMOD_MASK },
+        .num_levels = 2,
+        .map = darray_lit(mapKeypad),
+        .preserve = NULL,
+        .name = NULL,
+        .level_names = NULL
     }
 };
 
@@ -80,7 +106,7 @@ XkbcInitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which,
                           int keypadVMod)
 {
     struct xkb_client_map * map;
-    struct xkb_key_type *from;
+    const struct xkb_key_type *from;
     int rtrn;
 
     if (!keymap)
@@ -118,17 +144,22 @@ XkbcInitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which,
 
         if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) &&
             (rtrn == Success)) {
+            struct xkb_kt_map_entry *entry;
             type->mods.vmods = (1 << keypadVMod);
-            type->map[0].active = true;
-            type->map[0].mods.mask = ShiftMask;
-            type->map[0].mods.real_mods = ShiftMask;
-            type->map[0].mods.vmods = 0;
-            type->map[0].level = 1;
-            type->map[1].active = false;
-            type->map[1].mods.mask = 0;
-            type->map[1].mods.real_mods = 0;
-            type->map[1].mods.vmods = (1 << keypadVMod);
-            type->map[1].level = 1;
+
+            entry = &darray_item(type->map, 0);
+            entry->active = true;
+            entry->mods.mask = ShiftMask;
+            entry->mods.real_mods = ShiftMask;
+            entry->mods.vmods = 0;
+            entry->level = 1;
+
+            entry = &darray_item(type->map, 1);
+            entry->active = false;
+            entry->mods.mask = 0;
+            entry->mods.real_mods = 0;
+            entry->mods.vmods = (1 << keypadVMod);
+            entry->level = 1;
         }
     }
 
index 4fa85c1..3d60af7 100644 (file)
@@ -248,8 +248,7 @@ struct xkb_kt_map_entry {
 struct xkb_key_type {
     struct xkb_mods             mods;
     uint16_t                num_levels;
-    unsigned char           map_count;
-    struct xkb_kt_map_entry *       map;
+    darray(struct xkb_kt_map_entry) map;
     struct xkb_mods *             preserve;
     const char              *name;
     const char              **level_names;
index 0de2037..94642e3 100644 (file)
--- a/src/xkb.c
+++ b/src/xkb.c
@@ -119,7 +119,6 @@ bool
 XkbcComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type,
                         unsigned char *map_rtrn)
 {
-    int i;
     unsigned tmp;
     struct xkb_kt_map_entry * entry = NULL;
 
@@ -131,8 +130,7 @@ XkbcComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type,
             return false;
 
         type->mods.mask = tmp | type->mods.real_mods;
-        entry = type->map;
-        for (i = 0; i < type->map_count; i++, entry++) {
+        darray_foreach(entry, type->map) {
             tmp = 0;
             if (entry->mods.vmods != 0) {
                 if (!VirtualModsToReal(keymap, entry->mods.vmods, &tmp))
@@ -152,8 +150,8 @@ XkbcComputeEffectiveMap(struct xkb_keymap *keymap, struct xkb_key_type *type,
     if (map_rtrn) {
         memset(map_rtrn, 0, type->mods.mask + 1);
         if (entry && entry->active)
-            for (i = 0; i < type->map_count; i++)
-                map_rtrn[type->map[i].mods.mask] = type->map[i].level;
+            darray_foreach(entry, type->map)
+                map_rtrn[entry->mods.mask] = entry->level;
     }
 
     return true;
index 4b5caca..51b58a6 100644 (file)
@@ -1026,6 +1026,7 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
     xkb_keycode_t key;
     int i;
     struct xkb_key_type *type;
+    struct xkb_kt_map_entry *entry;
 
     /* Find all the interprets for the key and bind them to actions,
      * which will also update the vmodmap. */
@@ -1057,10 +1058,10 @@ UpdateModifiersFromCompat(struct xkb_keymap *keymap)
                 continue;
             mask |= keymap->server->vmods[j];
         }
-        for (j = 0; j < type->map_count; j++) {
-            struct xkb_mods *mods = &type->map[j].mods;
-            mods->mask = mods->real_mods | VModsToReal(keymap, mods->vmods);
-        }
+
+        darray_foreach(entry, type->map)
+            entry->mods.mask = entry->mods.real_mods |
+                                VModsToReal(keymap, entry->mods.vmods);
     }
 
     /* Update action modifiers. */
index 5914b32..1e15812 100644 (file)
@@ -53,9 +53,7 @@ typedef struct _KeyTypeInfo
     unsigned vmask;
     bool groupInfo;
     unsigned numLevels;
-    unsigned nEntries;
-    unsigned szEntries;
-    struct xkb_kt_map_entry * entries;
+    darray(struct xkb_kt_map_entry) entries;
     PreserveInfo *preserve;
     unsigned szNames;
     xkb_atom_t *lvlNames;
@@ -122,8 +120,7 @@ InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
     info->dflt.vmask = 0;
     info->dflt.groupInfo = false;
     info->dflt.numLevels = 1;
-    info->dflt.nEntries = info->dflt.szEntries = 0;
-    info->dflt.entries = NULL;
+    darray_init(info->dflt.entries);
     info->dflt.szNames = 0;
     info->dflt.lvlNames = NULL;
     info->dflt.preserve = NULL;
@@ -131,16 +128,12 @@ InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
     if (from != NULL)
     {
         info->dflt = from->dflt;
-        if (from->dflt.entries)
-        {
-            info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
-                                              struct xkb_kt_map_entry);
-            if (info->dflt.entries)
-            {
-                unsigned sz = from->dflt.nEntries * sizeof(struct xkb_kt_map_entry);
-                memcpy(info->dflt.entries, from->dflt.entries, sz);
-            }
-        }
+
+        darray_init(info->dflt.entries);
+        darray_from_items(info->dflt.entries,
+                          &darray_item(from->dflt.entries, 0),
+                          darray_size(from->dflt.entries));
+
         if (from->dflt.lvlNames)
         {
             info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, xkb_atom_t);
@@ -175,8 +168,8 @@ InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
 static void
 FreeKeyTypeInfo(KeyTypeInfo * type)
 {
-    free(type->entries);
-    type->entries = NULL;
+    darray_free(type->entries);
+    darray_init(type->entries);
     free(type->lvlNames);
     type->lvlNames = NULL;
     if (type->preserve != NULL)
@@ -294,8 +287,7 @@ AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
             }
             FreeKeyTypeInfo(old);
             *old = *new;
-            new->szEntries = new->nEntries = 0;
-            new->entries = NULL;
+            darray_init(new->entries);
             new->preserve = NULL;
             new->lvlNames = NULL;
             old->defs.next = &next->defs;
@@ -316,8 +308,7 @@ AddKeyType(struct xkb_keymap *keymap, KeyTypesInfo *info, KeyTypeInfo *new)
         return false;
     *old = *new;
     old->defs.next = NULL;
-    new->nEntries = new->szEntries = 0;
-    new->entries = NULL;
+    darray_init(new->entries);
     new->szNames = 0;
     new->lvlNames = NULL;
     new->preserve = NULL;
@@ -441,14 +432,12 @@ HandleIncludeKeyTypes(IncludeStmt *stmt, struct xkb_keymap *keymap,
 static struct xkb_kt_map_entry *
 FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
 {
-    unsigned int i;
-    struct xkb_kt_map_entry * entry;
+    struct xkb_kt_map_entry *entry;
 
-    for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
-    {
-        if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
+    darray_foreach(entry, type->entries)
+        if (entry->mods.real_mods == mask && entry->mods.vmods == vmask)
             return entry;
-    }
+
     return NULL;
 }
 
@@ -457,54 +446,22 @@ DeleteLevel1MapEntries(KeyTypeInfo * type)
 {
     unsigned int i, n;
 
-    for (i = 0; i < type->nEntries; i++)
-    {
-        if (type->entries[i].level == 0)
-        {
-            for (n = i; n < type->nEntries - 1; n++)
-            {
-                type->entries[n] = type->entries[n + 1];
-            }
-            type->nEntries--;
+    /* TODO: Be just a bit more clever here. */
+    for (i = 0; i < darray_size(type->entries); i++) {
+        if (darray_item(type->entries, i).level == 0) {
+            for (n = i; n < darray_size(type->entries) - 1; n++)
+                darray_item(type->entries, n) =
+                    darray_item(type->entries, n + 1);
+            (void)darray_pop(type->entries);
         }
     }
 }
 
-/**
- * Return a pointer to the next free XkbcKTMapEntry, reallocating space if
- * necessary.
- */
 static struct xkb_kt_map_entry *
 NextMapEntry(struct xkb_keymap *keymap, KeyTypeInfo * type)
 {
-    if (type->entries == NULL)
-    {
-        type->entries = uTypedCalloc(2, struct xkb_kt_map_entry);
-        if (type->entries == NULL)
-        {
-            ERROR("Couldn't allocate map entries for %s\n",
-                  TypeTxt(keymap, type));
-            ACTION("Map entries lost\n");
-            return NULL;
-        }
-        type->szEntries = 2;
-        type->nEntries = 0;
-    }
-    else if (type->nEntries >= type->szEntries)
-    {
-        type->szEntries *= 2;
-        type->entries = uTypedRecalloc(type->entries,
-                                       type->nEntries, type->szEntries,
-                                       struct xkb_kt_map_entry);
-        if (type->entries == NULL)
-        {
-            ERROR("Couldn't reallocate map entries for %s\n",
-                  TypeTxt(keymap, type));
-            ACTION("Map entries lost\n");
-            return NULL;
-        }
-    }
-    return &type->entries[type->nEntries++];
+    darray_resize0(type->entries, darray_size(type->entries) + 1);
+    return &darray_item(type->entries, darray_size(type->entries) - 1);
 }
 
 static bool
@@ -930,6 +887,7 @@ HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
 {
     unsigned int i;
     KeyTypeInfo type;
+    struct xkb_kt_map_entry *entry;
 
     if (def->merge != MergeDefault)
         merge = def->merge;
@@ -943,8 +901,7 @@ HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
     type.vmask = info->dflt.vmask;
     type.groupInfo = info->dflt.groupInfo;
     type.numLevels = 1;
-    type.nEntries = type.szEntries = 0;
-    type.entries = NULL;
+    darray_init(type.entries);
     type.szNames = 0;
     type.lvlNames = NULL;
     type.preserve = NULL;
@@ -958,15 +915,10 @@ HandleKeyTypeDef(KeyTypeDef *def, struct xkb_keymap *keymap,
 
     /* now copy any appropriate map, preserve or level names from the */
     /* default type */
-    for (i = 0; i < info->dflt.nEntries; i++)
-    {
-        struct xkb_kt_map_entry * dflt;
-        dflt = &info->dflt.entries[i];
-        if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
-            ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
-        {
-            AddMapEntry(keymap, &type, dflt, false, false);
-        }
+    darray_foreach(entry, info->dflt.entries) {
+        if ((entry->mods.real_mods & type.mask) == entry->mods.real_mods &&
+            (entry->mods.vmods & type.vmask) == entry->mods.vmods)
+            AddMapEntry(keymap, &type, entry, false, false);
     }
     if (info->dflt.preserve)
     {
@@ -1088,16 +1040,15 @@ CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
             ACTION("Aborting\n");
             return false;
         }
-        pre->matchingMapIndex = match - def->entries;
+        pre->matchingMapIndex = match - &darray_item(def->entries, 0);
     }
     type->mods.real_mods = def->mask;
     type->mods.vmods = def->vmask;
     type->num_levels = def->numLevels;
-    type->map_count = def->nEntries;
-    type->map = def->entries;
+    memcpy(&type->map, &def->entries, sizeof(def->entries));
     if (def->preserve)
     {
-        type->preserve = uTypedCalloc(type->map_count, struct xkb_mods);
+        type->preserve = uTypedCalloc(darray_size(type->map), struct xkb_mods);
         if (!type->preserve)
         {
             WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
@@ -1135,8 +1086,7 @@ CopyDefToKeyType(struct xkb_keymap *keymap, struct xkb_key_type *type,
         type->level_names = NULL;
     }
 
-    def->nEntries = def->szEntries = 0;
-    def->entries = NULL;
+    darray_init(def->entries);
     return XkbcComputeEffectiveMap(keymap, type, NULL);
 }