Commit 7d1db12dbb34ee6da34aba9dafdceb6f09d2e8b6

Ran Benita 2012-09-21T15:39:32

state: separate group wrapping/clamping to a function We'll need this function for wrapping our global effective group as well. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/state.c b/src/state.c
index 41a719d..695db2c 100644
--- a/src/state.c
+++ b/src/state.c
@@ -142,41 +142,50 @@ xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
     return entry->level;
 }
 
-/**
- * Returns the layout to use for the given key and state, taking
- * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID.
- */
-XKB_EXPORT xkb_layout_index_t
-xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
+static xkb_layout_index_t
+wrap_group_into_range(xkb_layout_index_t group,
+                      xkb_layout_index_t num_groups,
+                      enum xkb_range_exceed_type out_of_range_group_action,
+                      xkb_layout_index_t out_of_range_group_number)
 {
-    xkb_layout_index_t ret =
-        xkb_state_serialize_layout(state, XKB_STATE_EFFECTIVE);
-    const struct xkb_key *key = XkbKey(state->keymap, kc);
-
-    if (!key || key->num_groups == 0)
+    if (num_groups == 0)
         return XKB_LAYOUT_INVALID;
 
-    if (ret < key->num_groups)
-        return ret;
+    if (group < num_groups)
+        return group;
 
-    switch (key->out_of_range_group_action) {
+    switch (out_of_range_group_action) {
     case RANGE_REDIRECT:
-        ret = key->out_of_range_group_number;
-        if (ret >= key->num_groups)
-            ret = 0;
-        break;
+        if (out_of_range_group_number >= num_groups)
+            return 0;
+        return out_of_range_group_number;
 
     case RANGE_SATURATE:
-        ret = key->num_groups - 1;
-        break;
+        return num_groups - 1;
 
     case RANGE_WRAP:
     default:
-        ret %= key->num_groups;
-        break;
+        return group % num_groups;
     }
+}
 
-    return ret;
+/**
+ * Returns the layout to use for the given key and state, taking
+ * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID.
+ */
+XKB_EXPORT xkb_layout_index_t
+xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
+{
+    xkb_layout_index_t group =
+        xkb_state_serialize_layout(state, XKB_STATE_EFFECTIVE);
+    const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+    if (!key)
+        return XKB_LAYOUT_INVALID;
+
+    return wrap_group_into_range(group, key->num_groups,
+                                 key->out_of_range_group_action,
+                                 key->out_of_range_group_number);
 }
 
 static const union xkb_action fake = { .type = ACTION_TYPE_NONE };