diff options
author | Ran Benita <ran234@gmail.com> | 2012-11-11 00:22:46 +0200 |
---|---|---|
committer | Ran Benita <ran234@gmail.com> | 2012-11-11 00:32:16 +0200 |
commit | 60bd92021b63ecd3f8396704c841a0bf0fdab72b (patch) | |
tree | 65163ad722b934323a02a6eac51ebe6b0a37cc9b /src | |
parent | 324d4dbd99f5fb409e8466165481fe2d56c8eb8c (diff) | |
download | xorg-lib-libxkbcommon-60bd92021b63ecd3f8396704c841a0bf0fdab72b.tar.gz |
keymap: wrap the layout parameter if it is out of range for the key
The functions num_levels_for_key() and get_syms_by_level() have a
'layout' parameter. Currently it is expected that this value is always
legal for the key, as determined by num_layouts_for_key(). However,
there are legitimate use cases for passing an out-of-range layout there,
most probably passing the effective layout, and expecting to get the
keysyms/levels for just this layout. So we wrap it just as we do in the
xkb_state_* functions.
This is also useful for stuff like this:
http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-lookup-key
If this behavior is not desired, the user has the option to check
against num_layouts_for_key herself.
https://bugs.freedesktop.org/show_bug.cgi?id=56866
Reported-by: Gatis Paeglis <gatis.paeglis@digia.com>
Signed-off-by: Ran Benita <ran234@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/keymap.c | 13 | ||||
-rw-r--r-- | src/keymap.h | 6 | ||||
-rw-r--r-- | src/state.c | 2 |
3 files changed, 19 insertions, 2 deletions
diff --git a/src/keymap.c b/src/keymap.c index 6736c2c..87694cf 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -227,6 +227,12 @@ xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc, if (!key) return 0; + layout = wrap_group_into_range(layout, key->num_groups, + key->out_of_range_group_action, + key->out_of_range_group_number); + if (layout == XKB_LAYOUT_INVALID) + return 0; + return XkbKeyGroupWidth(key, layout); } @@ -287,8 +293,13 @@ xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, if (!key) goto err; - if (layout >= key->num_groups) + + layout = wrap_group_into_range(layout, key->num_groups, + key->out_of_range_group_action, + key->out_of_range_group_number); + if (layout == XKB_LAYOUT_INVALID) goto err; + if (level >= XkbKeyGroupWidth(key, layout)) goto err; diff --git a/src/keymap.h b/src/keymap.h index 483ee90..cb035b0 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -427,4 +427,10 @@ xkb_keymap_new(struct xkb_context *ctx, enum xkb_keymap_format format, enum xkb_keymap_compile_flags); +xkb_layout_index_t +wrap_group_into_range(int32_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); + #endif diff --git a/src/state.c b/src/state.c index 48b2132..19b372a 100644 --- a/src/state.c +++ b/src/state.c @@ -151,7 +151,7 @@ xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc, return entry->level; } -static xkb_layout_index_t +xkb_layout_index_t wrap_group_into_range(int32_t group, xkb_layout_index_t num_groups, enum xkb_range_exceed_type out_of_range_group_action, |