Commit 955ed8c4693b00845b24396aa21ba16c290bc87b

Ran Benita 2012-06-06T10:38:45

state: use darray for filters For the darray we need to specify the explicit struct xkb_filter type instead of void*, so we move the definition of struct xkb_state into state.c thus making it opaque even from the rest of the files. It has enough getters to get going and is otherwise good style. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/map.c b/src/map.c
index 5637dcf..d4c8f3d 100644
--- a/src/map.c
+++ b/src/map.c
@@ -244,10 +244,13 @@ _X_EXPORT unsigned int
 xkb_key_get_level(struct xkb_state *state, xkb_keycode_t key,
                   unsigned int group)
 {
-    struct xkb_keymap *keymap = state->keymap;
+    struct xkb_keymap *keymap = xkb_state_get_map(state);
     struct xkb_key_type *type = XkbKeyType(keymap, key, group);
     struct xkb_kt_map_entry *entry;
-    unsigned int active_mods = state->mods & type->mods.mask;
+    unsigned int active_mods;
+
+    active_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
+    active_mods &= type->mods.mask;
 
     darray_foreach(entry, type->map) {
         if (!entry->active)
@@ -267,10 +270,10 @@ xkb_key_get_level(struct xkb_state *state, xkb_keycode_t key,
 _X_EXPORT unsigned int
 xkb_key_get_group(struct xkb_state *state, xkb_keycode_t key)
 {
-    struct xkb_keymap *keymap = state->keymap;
+    struct xkb_keymap *keymap = xkb_state_get_map(state);
     unsigned int info = XkbKeyGroupInfo(keymap, key);
     unsigned int num_groups = XkbKeyNumGroups(keymap, key);
-    unsigned int ret = state->group;
+    unsigned int ret = xkb_state_serialize_group(state, XKB_STATE_EFFECTIVE);
 
     if (ret < XkbKeyNumGroups(keymap, key))
         return ret;
@@ -328,7 +331,7 @@ _X_EXPORT int
 xkb_key_get_syms(struct xkb_state *state, xkb_keycode_t key,
                  const xkb_keysym_t **syms_out)
 {
-    struct xkb_keymap *keymap = state->keymap;
+    struct xkb_keymap *keymap = xkb_state_get_map(state);
     int group;
     int level;
 
diff --git a/src/state.c b/src/state.c
index 63c7f11..9ba4d43 100644
--- a/src/state.c
+++ b/src/state.c
@@ -74,6 +74,24 @@ struct xkb_filter {
     struct xkb_filter *next;
 };
 
+struct xkb_state {
+    xkb_group_index_t base_group; /**< depressed */
+    xkb_group_index_t latched_group;
+    xkb_group_index_t locked_group;
+    xkb_group_index_t group; /**< effective */
+
+    xkb_mod_mask_t base_mods; /**< depressed */
+    xkb_mod_mask_t latched_mods;
+    xkb_mod_mask_t locked_mods;
+    xkb_mod_mask_t mods; /**< effective */
+
+    uint32_t leds;
+
+    int refcnt;
+    darray(struct xkb_filter) filters;
+    struct xkb_keymap *keymap;
+};
+
 static union xkb_action *
 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
 {
@@ -96,35 +114,24 @@ xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
 static struct xkb_filter *
 xkb_filter_new(struct xkb_state *state)
 {
-    int i;
-    int old_size = state->num_filters;
-    struct xkb_filter *filters = state->filters;
+    int old_size = darray_size(state->filters);
+    struct xkb_filter *filter = NULL, *iter;
 
-    for (i = 0; i < state->num_filters; i++) {
-        if (filters[i].func)
+    darray_foreach(iter, state->filters) {
+        if (iter->func)
             continue;
-        filters[i].state = state;
-        filters[i].refcnt = 1;
-        return &filters[i];
+        filter = iter;
+        break;
     }
 
-    if (state->num_filters > 0)
-        state->num_filters *= 2;
-    else
-        state->num_filters = 4;
-    filters = realloc(filters, state->num_filters * sizeof(*filters));
-    if (!filters) { /* WSGO */
-        state->num_filters = old_size;
-        return NULL;
+    if (!filter) {
+        darray_resize0(state->filters, darray_size(state->filters) + 1);
+        filter = &darray_item(state->filters, old_size);
     }
-    state->filters = filters;
-    memset(&filters[old_size], 0,
-           (state->num_filters - old_size) * sizeof(*filters));
-
-    filters[old_size].state = state;
-    filters[old_size].refcnt = 1;
 
-    return &filters[old_size];
+    filter->state = state;
+    filter->refcnt = 1;
+    return filter;
 }
 
 /***====================================================================***/
@@ -412,17 +419,16 @@ static void
 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
                      enum xkb_key_direction direction)
 {
-    struct xkb_filter *filters = state->filters;
+    struct xkb_filter *filter;
     union xkb_action *act = NULL;
     int send = 1;
-    int i;
 
     /* First run through all the currently active filters and see if any of
      * them have claimed this event. */
-    for (i = 0; i < state->num_filters; i++) {
-        if (!filters[i].func)
+    darray_foreach(filter, state->filters) {
+        if (!filter->func)
             continue;
-        send &= (*filters[i].func)(&filters[i], key, direction);
+        send &= filter->func(filter, key, direction);
     }
 
     if (!send || direction == XKB_KEY_UP)
@@ -489,7 +495,7 @@ xkb_state_unref(struct xkb_state *state)
         return;
 
     xkb_map_unref(state->keymap);
-    free(state->filters);
+    darray_free(state->filters);
     free(state);
 }
 
diff --git a/src/xkb-priv.h b/src/xkb-priv.h
index e421fd9..48e4355 100644
--- a/src/xkb-priv.h
+++ b/src/xkb-priv.h
@@ -411,24 +411,7 @@ struct xkb_keymap {
 #define XkbKeycodeInRange(d, k) \
     (((k) >= (d)->min_key_code) && ((k) <= (d)->max_key_code))
 
-struct xkb_state {
-	xkb_group_index_t base_group; /**< depressed */
-	xkb_group_index_t latched_group;
-	xkb_group_index_t locked_group;
-        xkb_group_index_t group; /**< effective */
-
-	xkb_mod_mask_t base_mods; /**< depressed */
-	xkb_mod_mask_t latched_mods;
-	xkb_mod_mask_t locked_mods;
-	xkb_mod_mask_t mods; /**< effective */
-
-        uint32_t        leds;
-
-        int refcnt;
-        void *filters;
-        int num_filters;
-        struct xkb_keymap *keymap;
-};
+struct xkb_state;
 
 typedef uint32_t xkb_atom_t;
 
diff --git a/test/state.c b/test/state.c
index ab1524b..2409a23 100644
--- a/test/state.c
+++ b/test/state.c
@@ -39,20 +39,26 @@
 static void
 print_state(struct xkb_state *state)
 {
+    struct xkb_keymap *keymap;
     xkb_group_index_t group;
     xkb_mod_index_t mod;
     xkb_led_index_t led;
 
-    if (!state->group && !state->mods && !state->leds) {
+    group = xkb_state_serialize_group(state, XKB_STATE_EFFECTIVE);
+    mod = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
+    /* led = xkb_state_serialize_leds(state, XKB_STATE_EFFECTIVE); */
+    if (!group && !mod /* && !led */) {
         fprintf(stderr, "\tno state\n");
         return;
     }
 
-    for (group = 0; group < xkb_map_num_groups(state->keymap); group++) {
+    keymap = xkb_state_get_map(state);
+
+    for (group = 0; group < xkb_map_num_groups(keymap); group++) {
         if (!xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE))
             continue;
         fprintf(stderr, "\tgroup %s (%d): %s%s%s%s\n",
-                xkb_map_group_get_name(state->keymap, group),
+                xkb_map_group_get_name(keymap, group),
                 group,
                 xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE) ?
                     "effective " : "",
@@ -64,11 +70,11 @@ print_state(struct xkb_state *state)
                     "locked " : "");
     }
 
-    for (mod = 0; mod < xkb_map_num_mods(state->keymap); mod++) {
+    for (mod = 0; mod < xkb_map_num_mods(keymap); mod++) {
         if (!xkb_state_mod_index_is_active(state, mod, XKB_STATE_EFFECTIVE))
             continue;
         fprintf(stderr, "\tmod %s (%d): %s%s%s\n",
-                xkb_map_mod_get_name(state->keymap, mod),
+                xkb_map_mod_get_name(keymap, mod),
                 mod,
                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_DEPRESSED) ?
                     "depressed " : "",
@@ -78,11 +84,11 @@ print_state(struct xkb_state *state)
                     "locked " : "");
     }
 
-    for (led = 0; led < xkb_map_num_leds(state->keymap); led++) {
+    for (led = 0; led < xkb_map_num_leds(keymap); led++) {
         if (!xkb_state_led_index_is_active(state, led))
             continue;
         fprintf(stderr, "\tled %s (%d): active\n",
-                xkb_map_led_get_name(state->keymap, led),
+                xkb_map_led_get_name(keymap, led),
                 led);
     }
 }
@@ -183,11 +189,11 @@ test_serialisation(struct xkb_keymap *keymap)
 
     assert(state);
 
-    caps = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
+    caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
     assert(caps != XKB_MOD_INVALID);
-    shift = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_SHIFT);
+    shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
     assert(shift != XKB_MOD_INVALID);
-    ctrl = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL);
+    ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
     assert(ctrl != XKB_MOD_INVALID);
 
     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);