summaryrefslogtreecommitdiff
path: root/src/state.c
diff options
context:
space:
mode:
authorRan Benita <ran234@gmail.com>2013-08-13 18:57:43 +0300
committerRan Benita <ran234@gmail.com>2013-08-15 09:58:50 +0300
commit2a2a8d7da117803667f1eaee0519db5d5e99271c (patch)
treeed006c534be8d4ed5d16538eb2318fd7fed1996d /src/state.c
parent9e92319db443b28674c75edac452f5dd3ae264c5 (diff)
downloadxorg-lib-libxkbcommon-2a2a8d7da117803667f1eaee0519db5d5e99271c.tar.gz
state: apply capitalization transformation on keysyms
The xkbproto spec says: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier If the Lock modifier is not consumed by the symbol lookup process, routines that determine the symbol and string that correspond to an event should capitalize the result. This was not an issue until now, because most xkeyboard-config keymaps do not utilize this "feature", and specify the keysyms for the Lock modifier explicitly instead. However, some keymaps do depend on it, e.g. ch(fr) for eacute and others. The spec goes on to describe two options for doing this transformation: locale-sensitive and locale-insensitive. We opt for the latter; it is less desirable but we don't want *that* headache. Also, only xkb_state_key_get_one_sym() is changed; xkb_state_key_get_syms() is left as-is, and always reports the untransformed keysyms. This is for the following reasons: - The API doesn't allow it, since we return a const pointer directly to the keymap keysyms table and we can't transform that. - The transformation doesn't make sense for multiple-keysyms. - It can be useful for an application to get the "raw" keysyms if it wants to (e.g. maybe it wants to do the transformation itself). Finally, note that xkb_state_mod_index_is_consumed() does *not* report Lock as consumed even if it was used in the transformation. This is what Xlib does. This definitely doesn't fall under the "hard to misuse" API rule but it's the best we can do. https://bugs.freedesktop.org/show_bug.cgi?id=67167 Reported-By: Gatis Paeglis <gatis.paeglis@digia.com> Signed-off-by: Ran Benita <ran234@gmail.com>
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/state.c b/src/state.c
index bfcf1d4..e13d1fd 100644
--- a/src/state.c
+++ b/src/state.c
@@ -60,6 +60,7 @@
*/
#include "keymap.h"
+#include "keysym.h"
struct xkb_filter {
union xkb_action action;
@@ -832,13 +833,26 @@ XKB_EXPORT xkb_keysym_t
xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
{
const xkb_keysym_t *syms;
+ xkb_keysym_t sym;
int num_syms;
+ xkb_mod_index_t caps;
num_syms = xkb_state_key_get_syms(state, kc, &syms);
if (num_syms != 1)
return XKB_KEY_NoSymbol;
- return syms[0];
+ sym = syms[0];
+
+ /*
+ * Perform capitalization transformation, see:
+ * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
+ */
+ caps = xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
+ if (xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
+ xkb_state_mod_index_is_consumed(state, kc, caps) == 0)
+ sym = xkb_keysym_to_upper(sym);
+
+ return sym;
}
/**