diff options
-rw-r--r-- | input/input.c | 12 | ||||
-rw-r--r-- | input/keycodes.c | 28 | ||||
-rw-r--r-- | input/keycodes.h | 3 |
3 files changed, 30 insertions, 13 deletions
diff --git a/input/input.c b/input/input.c index 1dd029219f..e85d16ccd2 100644 --- a/input/input.c +++ b/input/input.c @@ -613,15 +613,6 @@ static struct mp_cmd *resolve_key(struct input_ctx *ictx, int code) static void interpret_key(struct input_ctx *ictx, int code, double scale) { - /* On normal keyboards shift changes the character code of non-special - * keys, so don't count the modifier separately for those. In other words - * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate - * shift modifier is still kept for special keys like arrow keys. - */ - int unmod = code & ~MP_KEY_MODIFIER_MASK; - if (unmod >= 32 && unmod < MP_KEY_BASE) - code &= ~MP_KEY_MODIFIER_SHIFT; - int state = code & (MP_KEY_STATE_DOWN | MP_KEY_STATE_UP); code = code & ~(unsigned)state; @@ -633,7 +624,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale) talloc_free(key); } - if (MP_KEY_DEPENDS_ON_MOUSE_POS(unmod)) + if (MP_KEY_DEPENDS_ON_MOUSE_POS(code & ~MP_KEY_MODIFIER_MASK)) ictx->mouse_event_counter++; mp_input_wakeup(ictx); @@ -687,6 +678,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale) static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale) { + code = mp_normalize_keycode(code); int unmod = code & ~MP_KEY_MODIFIER_MASK; if (code == MP_INPUT_RELEASE_ALL) { MP_DBG(ictx, "release all\n"); diff --git a/input/keycodes.c b/input/keycodes.c index 078e29f361..00f983e140 100644 --- a/input/keycodes.c +++ b/input/keycodes.c @@ -239,14 +239,14 @@ found: struct bstr rest; int code = bstr_decode_utf8(bname, &rest); if (code >= 0 && rest.len == 0) - return code + modifiers; + return mp_normalize_keycode(code + modifiers); if (bstr_startswith0(bname, "0x")) - return strtol(name, NULL, 16) + modifiers; + return mp_normalize_keycode(strtol(name, NULL, 16) + modifiers); for (int i = 0; key_names[i].name != NULL; i++) { if (strcasecmp(key_names[i].name, name) == 0) - return key_names[i].key + modifiers; + return mp_normalize_keycode(key_names[i].key + modifiers); } return -1; @@ -330,3 +330,25 @@ void mp_print_key_list(struct mp_log *out) for (int i = 0; key_names[i].name != NULL; i++) mp_info(out, "%s\n", key_names[i].name); } + +int mp_normalize_keycode(int keycode) +{ + if (keycode <= 0) + return keycode; + int code = keycode & ~MP_KEY_MODIFIER_MASK; + int mod = keycode & MP_KEY_MODIFIER_MASK; + /* On normal keyboards shift changes the character code of non-special + * keys, so don't count the modifier separately for those. In other words + * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate + * shift modifier is still kept for special keys like arrow keys. */ + if (code >= 32 && code < MP_KEY_BASE) { + /* Still try to support ASCII case-modifications properly. For example, + * we want to change "Shift+a" to "A", not "a". Doing this for unicode + * in general would require huge lookup tables, or a libc with proper + * unicode support, so we don't do that. */ + if (code >= 'a' && code <= 'z' && (mod & MP_KEY_MODIFIER_SHIFT)) + code &= 0x5F; + mod &= ~MP_KEY_MODIFIER_SHIFT; + } + return code | mod; +} diff --git a/input/keycodes.h b/input/keycodes.h index 4d13c653a3..53fb682e46 100644 --- a/input/keycodes.h +++ b/input/keycodes.h @@ -256,6 +256,9 @@ MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META | \ MP_KEY_STATE_DOWN | MP_KEY_STATE_UP) +// Makes adjustments like turning "shift+z" into "Z" +int mp_normalize_keycode(int keycode); + // Get input key from its name. int mp_input_get_key_from_name(const char *name); |