Commit ccc047c4e08e6c7a229d5e9fdee91451e0b07ef2

Ran Benita 2012-05-22T18:00:56

compat: use darray for acts and key_acts in the server map Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/alloc.c b/src/alloc.c
index 3106a08..c1d575f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -94,36 +94,8 @@ XkbcAllocServerMap(struct xkb_keymap *keymap, unsigned which,
     if (nNewActions < 1)
         nNewActions = 1;
 
-    if (!map->acts) {
-        map->acts = uTypedCalloc(nNewActions + 1, union xkb_action);
-        if (!map->acts)
-            return BadAlloc;
-        map->num_acts = 1;
-        map->size_acts = nNewActions + 1;
-    }
-    else if ((map->size_acts - map->num_acts) < (int)nNewActions) {
-        unsigned need;
-        union xkb_action *prev_acts = map->acts;
-
-        need = map->num_acts + nNewActions;
-        map->acts = uTypedRealloc(map->acts, need, union xkb_action);
-        if (!map->acts) {
-            free(prev_acts);
-            map->num_acts = map->size_acts = 0;
-            return BadAlloc;
-        }
-
-        map->size_acts = need;
-        memset(&map->acts[map->num_acts], 0,
-               (map->size_acts - map->num_acts) * sizeof(union xkb_action));
-    }
-
-    if (!map->key_acts) {
-        i = keymap->max_key_code + 1;
-        map->key_acts = uTypedCalloc(i, unsigned short);
-        if (!map->key_acts)
-            return BadAlloc;
-    }
+    darray_resize0(map->acts, darray_size(map->acts) + nNewActions + 1);
+    darray_resize0(map->key_acts, keymap->max_key_code + 1);
 
     if (!map->behaviors) {
         i = keymap->max_key_code + 1;
@@ -208,61 +180,41 @@ union xkb_action *
 XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t key,
                      uint32_t needed)
 {
-    xkb_keycode_t i, nActs;
-    union xkb_action *newActs;
+    size_t old_ndx, old_num_acts, new_ndx;
 
     if (needed == 0) {
-        keymap->server->key_acts[key] = 0;
+        darray_item(keymap->server->key_acts, key) = 0;
         return NULL;
     }
 
     if (XkbKeyHasActions(keymap, key) &&
-        (XkbKeyGroupsWidth(keymap, key) >= needed))
+        XkbKeyGroupsWidth(keymap, key) >= needed)
         return XkbKeyActionsPtr(keymap, key);
 
-    if (keymap->server->size_acts - keymap->server->num_acts >= (int)needed) {
-        keymap->server->key_acts[key] = keymap->server->num_acts;
-        keymap->server->num_acts += needed;
-
-        return &keymap->server->acts[keymap->server->key_acts[key]];
-    }
-
-    keymap->server->size_acts = keymap->server->num_acts + needed + 8;
-    newActs = uTypedCalloc(keymap->server->size_acts, union xkb_action);
-    if (!newActs)
-        return NULL;
-    newActs[0].type = XkbSA_NoAction;
-    nActs = 1;
-
-    for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
-        xkb_keycode_t nKeyActs, nCopy;
-
-        if ((keymap->server->key_acts[i] == 0) && (i != key))
-            continue;
-
-        nCopy = nKeyActs = XkbKeyNumActions(keymap, i);
-        if (i == key) {
-            nKeyActs= needed;
-            if (needed < nCopy)
-                nCopy = needed;
-        }
-
-        if (nCopy > 0)
-            memcpy(&newActs[nActs], XkbKeyActionsPtr(keymap, i),
-                   nCopy * sizeof(union xkb_action));
-        if (nCopy < nKeyActs)
-            memset(&newActs[nActs + nCopy], 0,
-                   (nKeyActs - nCopy) * sizeof(union xkb_action));
-
-        keymap->server->key_acts[i] = nActs;
-        nActs += nKeyActs;
-    }
-
-    free(keymap->server->acts);
-    keymap->server->acts = newActs;
-    keymap->server->num_acts = nActs;
-
-    return &keymap->server->acts[keymap->server->key_acts[key]];
+    /*
+     * The key may already be in the array, but without enough space.
+     * This should not happen often, so in order to avoid moving and
+     * copying stuff from acts and key_acts, we just allocate new
+     * space for the key at the end, and leave the old space alone.
+     */
+
+    old_ndx = darray_item(keymap->server->key_acts, key);
+    old_num_acts = XkbKeyNumActions(keymap, key);
+    new_ndx = darray_size(keymap->server->acts);
+
+    darray_resize0(keymap->server->acts, new_ndx + needed);
+    darray_item(keymap->server->key_acts, key) = new_ndx;
+
+    /*
+     * The key was already in the array, copy the old actions to the
+     * new space.
+     */
+    if (old_ndx != 0)
+        memcpy(&darray_item(keymap->server->acts, new_ndx),
+               &darray_item(keymap->server->acts, old_ndx),
+               old_num_acts * sizeof(union xkb_action));
+
+    return XkbKeyActionsPtr(keymap, key);
 }
 
 void
@@ -311,8 +263,8 @@ XkbcFreeServerMap(struct xkb_keymap *keymap)
     map = keymap->server;
 
     free(map->explicit);
-    free(map->key_acts);
-    free(map->acts);
+    darray_free(map->key_acts);
+    darray_free(map->acts);
     free(map->behaviors);
     free(map->vmodmap);
     free(keymap->server);
diff --git a/src/xkb-priv.h b/src/xkb-priv.h
index 0d6f137..e8838d3 100644
--- a/src/xkb-priv.h
+++ b/src/xkb-priv.h
@@ -290,14 +290,11 @@ struct xkb_behavior {
 };
 
 struct xkb_server_map {
-    unsigned short      num_acts;
-    unsigned short      size_acts;
-
     unsigned char *     explicit;
 
-    union xkb_action          *acts;
+    darray(union xkb_action) acts;
+    darray(size_t ) key_acts;           /* acts[key_acts[keycode]] */
     struct xkb_behavior         *behaviors;
-    unsigned short      *key_acts;
     uint32_t            vmods[XkbNumVirtualMods]; /* vmod -> mod mapping */
     uint32_t            *vmodmap; /* key -> vmod mapping */
 };
@@ -398,13 +395,13 @@ struct xkb_keymap {
 #define XkbKeySymEntry(d, k, g, sl) \
     (XkbKeySym(d, k, XkbKeySymOffset(d, k, g, sl)))
 #define XkbKeyHasActions(d, k) \
-    ((d)->server->key_acts[k] != 0)
+    (darray_item((d)->server->key_acts, k) != 0)
 #define XkbKeyNumActions(d, k) \
     (XkbKeyHasActions(d, k) ? \
      (XkbKeyGroupsWidth(d, k) * XkbKeyNumGroups(d, k)) : \
      1)
 #define XkbKeyActionsPtr(d, k) \
-    (&(d)->server->acts[(d)->server->key_acts[k]])
+    (&darray_item((d)->server->acts, darray_item((d)->server->key_acts, k)))
 #define XkbKeyAction(d, k, n) \
     (XkbKeyHasActions(d, k) ? &XkbKeyActionsPtr(d, k)[n] : NULL)
 #define XkbKeyActionEntry(d, k, sl, g) \