summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaroslaw Kubik <jarek@froglogic.com>2020-02-05 17:42:06 +0100
committerRan Benita <ran234@gmail.com>2020-03-20 19:20:36 +0200
commitd92a248c48227d09f6fdcfafaf339a5ff586e042 (patch)
treeebe2a8a30a6db5d6c4ebf10f786983515521eef3 /src
parent0345aba082c83e9950f9dd8b7ea3bf91fe566a02 (diff)
downloadxorg-lib-libxkbcommon-d92a248c48227d09f6fdcfafaf339a5ff586e042.tar.gz
API to query modifier set required to type a keysym
The new API is useful to implement features like auto-type and desktop automation. Since the inputs for these features is usually specified in terms of the symbols that need to be typed, the implementation needs to be able to invert the keycode->keysym transformation and produce a sequence of keycodes that can be used to type the requested character(s).
Diffstat (limited to 'src')
-rw-r--r--src/keymap.c33
-rw-r--r--src/keymap.h11
-rw-r--r--src/state.c11
3 files changed, 44 insertions, 11 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 8e6cb67..54ac7c0 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -409,6 +409,39 @@ xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
return XKB_LED_INVALID;
}
+XKB_EXPORT size_t
+xkb_keymap_key_get_mods_for_level(struct xkb_keymap *keymap,
+ xkb_keycode_t kc,
+ xkb_layout_index_t layout,
+ xkb_level_index_t level,
+ xkb_mod_mask_t *masks_out,
+ size_t masks_size)
+{
+ const struct xkb_key *key = XkbKey(keymap, kc);
+ if (!key)
+ return 0;
+
+ layout = XkbWrapGroupIntoRange(layout, key->num_groups,
+ key->out_of_range_group_action,
+ key->out_of_range_group_number);
+ if (layout == XKB_LAYOUT_INVALID)
+ return 0;
+
+ if (level >= XkbKeyNumLevels(key, layout))
+ return 0;
+
+ const struct xkb_key_type *type = key->groups[layout].type;
+
+ size_t count = 0;
+ for (unsigned i = 0; i < type->num_entries && count < masks_size; i++)
+ if (entry_is_active(&type->entries[i]) &&
+ type->entries[i].level == level) {
+ masks_out[count] = type->entries[i].mods.mask;
+ ++count;
+ }
+ return count;
+}
+
/**
* As below, but takes an explicit layout/level rather than state.
*/
diff --git a/src/keymap.h b/src/keymap.h
index c15052b..7c5341d 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -438,6 +438,17 @@ XkbKeyNumLevels(const struct xkb_key *key, xkb_layout_index_t layout)
return key->groups[layout].type->num_levels;
}
+/*
+ * If the virtual modifiers are not bound to anything, the entry
+ * is not active and should be skipped. xserver does this with
+ * cached entry->active field.
+ */
+static inline bool
+entry_is_active(const struct xkb_key_type_entry *entry)
+{
+ return entry->mods.mods == 0 || entry->mods.mask != 0;
+}
+
struct xkb_keymap *
xkb_keymap_new(struct xkb_context *ctx,
enum xkb_keymap_format format,
diff --git a/src/state.c b/src/state.c
index 2d07be4..b269e6d 100644
--- a/src/state.c
+++ b/src/state.c
@@ -118,17 +118,6 @@ struct xkb_state {
struct xkb_keymap *keymap;
};
-/*
- * If the virtual modifiers are not bound to anything, the entry
- * is not active and should be skipped. xserver does this with
- * cached entry->active field.
- */
-static bool
-entry_is_active(const struct xkb_key_type_entry *entry)
-{
- return entry->mods.mods == 0 || entry->mods.mask != 0;
-}
-
static const struct xkb_key_type_entry *
get_entry_for_mods(const struct xkb_key_type *type, xkb_mod_mask_t mods)
{