summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
Diffstat (limited to 'input')
-rw-r--r--input/input.c12
-rw-r--r--input/keycodes.c28
-rw-r--r--input/keycodes.h3
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);