]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: wacom: Add preliminary support for high-resolution wheel scrolling
authorJason Gerecke <jason.gerecke@wacom.com>
Tue, 30 Jul 2024 15:51:58 +0000 (08:51 -0700)
committerJiri Kosina <jkosina@suse.com>
Fri, 2 Aug 2024 11:02:46 +0000 (13:02 +0200)
Modern userspace (i.e. libinput) will make use of high-resolution
scrolling if supported. Hardware does not currently set a resolution
multiplier needed for effective high-res scrolling, but we can still
write code to support it in the future.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h

index 798c26ddaeba7d8f255a75f9740360fb13425e43..9e9cfc55b47b39e071c430cca98bdf025cd1c71e 100644 (file)
@@ -2046,10 +2046,12 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
                features->device_type |= WACOM_DEVICETYPE_PAD;
                break;
        case WACOM_HID_WD_TOUCHRING:
-               if (field->flags & HID_MAIN_ITEM_RELATIVE)
-                       wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL, 0);
-               else
+               if (field->flags & HID_MAIN_ITEM_RELATIVE) {
+                       wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);
+                       set_bit(REL_WHEEL, input->relbit);
+               } else {
                        wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
+               }
                features->device_type |= WACOM_DEVICETYPE_PAD;
                break;
        case WACOM_HID_WD_TOUCHRINGSTATUS:
@@ -2177,7 +2179,21 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
                         * userspace treats positive REL_WHEEL as a
                         * scroll *up*!
                         */
-                       value = -value;
+                       int hires_value = -value * 120 / usage->resolution_multiplier;
+                       int *ring_value = &wacom_wac->hid_data.ring_value;
+
+                       value = hires_value;
+                       *ring_value += hires_value;
+
+                       /* Emulate a legacy wheel click for every 120
+                        * units of hi-res travel.
+                        */
+                       if (*ring_value >= 120 || *ring_value <= -120) {
+                               int clicks = *ring_value / 120;
+
+                               input_event(input, usage->type, REL_WHEEL, clicks);
+                               *ring_value -= clicks * 120;
+                       }
                }
                else {
                        value = wacom_offset_rotation(input, usage, value, 1, 4);
index 6ec499841f70959d8a6cc6e3ef2e5c21cddc9761..aeba2f3082f03ddc6ee7a16b3083b53bfb46bcb0 100644 (file)
@@ -312,6 +312,7 @@ struct hid_data {
        int width;
        int height;
        int id;
+       int ring_value;
        int cc_report;
        int cc_index;
        int cc_value_index;