diff options
author | Jason Gerecke <jason.gerecke@wacom.com> | 2024-07-30 08:51:57 -0700 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.com> | 2024-08-02 13:02:46 +0200 |
commit | 7525a0bd928e3a5d6dcea6a38cc5ce88f45d27a9 (patch) | |
tree | 4e6e6ddeaada8531bdf63585d1d722dec1fc21c6 | |
parent | 3152301ff28872255461484b3dc831e2bf0f28db (diff) |
HID: wacom: Support touchrings with relative motion
If a touchring is configured to send relative events (e.g. +1 or -1 every
time some bit of rotational distance is covered), we should similarly
send relative events up to userspace. Previous non-HID tablets used
REL_WHEEL to send this kind of information, so we opt to use this same
axis since userspace (xf86-input-wacom and libinput) already expects
this kind of behavior from the Wacom kernel driver.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
-rw-r--r-- | drivers/hid/wacom_wac.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index b753b2f111fb..798c26ddaeba 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1909,6 +1909,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, } input_abs_set_res(input, code, resolution); break; + case EV_REL: case EV_KEY: case EV_MSC: case EV_SW: @@ -2045,7 +2046,10 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHRING: - wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); + if (field->flags & HID_MAIN_ITEM_RELATIVE) + wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL, 0); + else + wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHRINGSTATUS: @@ -2110,7 +2114,10 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field return; if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { - if (usage->hid != WACOM_HID_WD_TOUCHRING) + bool is_abs_touchring = usage->hid == WACOM_HID_WD_TOUCHRING && + !(field->flags & HID_MAIN_ITEM_RELATIVE); + + if (!is_abs_touchring) wacom_wac->hid_data.inrange_state |= value; } @@ -2163,6 +2170,15 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field hdev->product == 0x3AA) value = wacom_offset_rotation(input, usage, value, 1, 2); } + else if (field->flags & HID_MAIN_ITEM_RELATIVE) { + /* We must invert the sign for vertical + * relative scrolling. Clockwise rotation + * produces positive values from HW, but + * userspace treats positive REL_WHEEL as a + * scroll *up*! + */ + value = -value; + } else { value = wacom_offset_rotation(input, usage, value, 1, 4); } |