Add keycode min/max and iteration API
[platform/upstream/libxkbcommon.git] / src / keymap.c
index 480a4ce..8205bab 100644 (file)
@@ -102,7 +102,7 @@ xkb_keymap_unref(struct xkb_keymap *keymap)
         free(keymap->keys);
     }
     for (i = 0; i < keymap->num_types; i++) {
-        free(keymap->types[i].map);
+        free(keymap->types[i].entries);
         free(keymap->types[i].level_names);
     }
     free(keymap->types);
@@ -153,13 +153,24 @@ xkb_keymap_new_from_names(struct xkb_context *ctx,
         return NULL;
     }
 
-    rmlvo = *rmlvo_in;
+    if (rmlvo_in)
+        rmlvo = *rmlvo_in;
+    else
+        memset(&rmlvo, 0, sizeof(rmlvo));
+
     if (isempty(rmlvo.rules))
-        rmlvo.rules = DEFAULT_XKB_RULES;
+        rmlvo.rules = xkb_context_get_default_rules(ctx);
     if (isempty(rmlvo.model))
-        rmlvo.model = DEFAULT_XKB_MODEL;
-    if (isempty(rmlvo.layout))
-        rmlvo.layout = DEFAULT_XKB_LAYOUT;
+        rmlvo.model = xkb_context_get_default_model(ctx);
+    /* Layout and variant are tied together, so don't try to use one from
+     * the caller and one from the environment. */
+    if (isempty(rmlvo.layout)) {
+        rmlvo.layout = xkb_context_get_default_layout(ctx);
+        rmlvo.variant = xkb_context_get_default_variant(ctx);
+    }
+    /* Options can be empty, so respect that if passed in. */
+    if (rmlvo.options == NULL)
+        rmlvo.options = xkb_context_get_default_options(ctx);
 
     keymap = xkb_keymap_new(ctx, format, flags);
     if (!keymap)
@@ -179,6 +190,15 @@ xkb_keymap_new_from_string(struct xkb_context *ctx,
                            enum xkb_keymap_format format,
                            enum xkb_keymap_compile_flags flags)
 {
+    return xkb_keymap_new_from_buffer(ctx, string, SIZE_MAX, format, flags);
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_keymap_new_from_buffer(struct xkb_context *ctx,
+                           const char *buffer, size_t length,
+                           enum xkb_keymap_format format,
+                           enum xkb_keymap_compile_flags flags)
+{
     struct xkb_keymap *keymap;
     const struct xkb_keymap_format_ops *ops;
 
@@ -193,8 +213,8 @@ xkb_keymap_new_from_string(struct xkb_context *ctx,
         return NULL;
     }
 
-    if (!string) {
-        log_err_func1(ctx, "no string specified\n");
+    if (!buffer) {
+        log_err_func1(ctx, "no buffer specified\n");
         return NULL;
     }
 
@@ -202,7 +222,7 @@ xkb_keymap_new_from_string(struct xkb_context *ctx,
     if (!keymap)
         return NULL;
 
-    if (!ops->keymap_new_from_string(keymap, string)) {
+    if (!ops->keymap_new_from_string(keymap, buffer, length)) {
         xkb_keymap_unref(keymap);
         return NULL;
     }
@@ -464,6 +484,28 @@ err:
     return 0;
 }
 
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap)
+{
+    return keymap->min_key_code;
+}
+
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap)
+{
+    return keymap->max_key_code;
+}
+
+XKB_EXPORT void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+                        void *data)
+{
+    struct xkb_key *key;
+
+    xkb_foreach_key(key, keymap)
+        iter(keymap, key->keycode, data);
+}
+
 /**
  * Simple boolean specifying whether or not the key should repeat.
  */