HID: apple: Add missing scan code event for keys handled by hid-apple
authorVincent Lefevre <vincent@vinc17.net>
Thu, 22 Jul 2021 01:25:44 +0000 (03:25 +0200)
committerJiri Kosina <jkosina@suse.cz>
Wed, 28 Jul 2021 09:53:50 +0000 (11:53 +0200)
When an EV_KEY event is generated by hid-apple due to special key
mapping, the usual associated scan code event (EV_MSC) is missing.
This issue can be seen with the evtest utility.

Add the scan code event for these special keys.

BugLink: https://bugs.debian.org/757356
Co-developed-by: Daniel Lin <ephemient@gmail.com>
Signed-off-by: Daniel Lin <ephemient@gmail.com>
Signed-off-by: Vincent Lefevre <vincent@vinc17.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-apple.c

index 6b8f0d004d3450d5b48f8fc145b855f7ef755e00..cde92de7fca74db8d5e6f0309479badb6504ad52 100644 (file)
@@ -187,6 +187,15 @@ static const struct apple_key_translation *apple_find_translation(
        return NULL;
 }
 
+static void input_event_with_scancode(struct input_dev *input,
+               __u8 type, __u16 code, unsigned int hid, __s32 value)
+{
+       if (type == EV_KEY &&
+           (!test_bit(code, input->key)) == value)
+               input_event(input, EV_MSC, MSC_SCAN, hid);
+       input_event(input, type, code, value);
+}
+
 static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                struct hid_usage *usage, __s32 value)
 {
@@ -199,7 +208,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
 
        if (usage->code == fn_keycode) {
                asc->fn_on = !!value;
-               input_event(input, usage->type, KEY_FN, value);
+               input_event_with_scancode(input, usage->type, KEY_FN,
+                               usage->hid, value);
                return 1;
        }
 
@@ -240,7 +250,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                                code = do_translate ? trans->to : trans->from;
                        }
 
-                       input_event(input, usage->type, code, value);
+                       input_event_with_scancode(input, usage->type, code,
+                                       usage->hid, value);
                        return 1;
                }
 
@@ -258,8 +269,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                                        clear_bit(usage->code,
                                                        asc->pressed_numlock);
 
-                               input_event(input, usage->type, trans->to,
-                                               value);
+                               input_event_with_scancode(input, usage->type,
+                                               trans->to, usage->hid, value);
                        }
 
                        return 1;
@@ -270,7 +281,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                if (hid->country == HID_COUNTRY_INTERNATIONAL_ISO) {
                        trans = apple_find_translation(apple_iso_keyboard, usage->code);
                        if (trans) {
-                               input_event(input, usage->type, trans->to, value);
+                               input_event_with_scancode(input, usage->type,
+                                               trans->to, usage->hid, value);
                                return 1;
                        }
                }
@@ -279,7 +291,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
        if (swap_opt_cmd) {
                trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
                if (trans) {
-                       input_event(input, usage->type, trans->to, value);
+                       input_event_with_scancode(input, usage->type,
+                                       trans->to, usage->hid, value);
                        return 1;
                }
        }
@@ -287,7 +300,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
        if (swap_fn_leftctrl) {
                trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
                if (trans) {
-                       input_event(input, usage->type, trans->to, value);
+                       input_event_with_scancode(input, usage->type,
+                                       trans->to, usage->hid, value);
                        return 1;
                }
        }
@@ -306,8 +320,8 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
 
        if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
                        usage->code == REL_HWHEEL) {
-               input_event(field->hidinput->input, usage->type, usage->code,
-                               -value);
+               input_event_with_scancode(field->hidinput->input, usage->type,
+                               usage->code, usage->hid, -value);
                return 1;
        }