Support Wacom Intuos Pro 3rd by mapping the dial to a ring (RHEL-104952)

Resolves: RHEL-104952
This commit is contained in:
Peter Hutterer 2025-07-23 15:38:53 +10:00
parent f5e7897a07
commit 57458bd0ae
3 changed files with 284 additions and 1 deletions

View File

@ -0,0 +1,33 @@
From 7ea1d8501fb5cfb4221a5f4647e8fde05092e613 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Mon, 29 Jul 2024 22:46:57 +0000
Subject: [PATCH] tablet: Remove unnecessary scale factor on REL_HWHEEL_HI_RES
The two high-res axes should already be scaled appropriately by the
kernel. This unnecessary scale factor causes 1 click of the dial to
produce an event delta of +-14400 rather than the expected +-120.
Fixes: beca99812208 ("tablet: add API for relative dials")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1029>
(cherry picked from commit 66106b9746a46d5c1a112d8eae74acf0469a7cf6)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
src/evdev-tablet-pad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c
index 3aa92a4a4c69..90614c5dae91 100644
--- a/src/evdev-tablet-pad.c
+++ b/src/evdev-tablet-pad.c
@@ -129,7 +129,7 @@ pad_process_relative(struct pad_dispatch *pad,
pad_set_status(pad, PAD_AXES_UPDATED);
break;
case REL_HWHEEL_HI_RES:
- pad->dials.dial2 = e->value * 120;
+ pad->dials.dial2 = e->value;
pad->changed_axes |= PAD_AXIS_DIAL2;
pad_set_status(pad, PAD_AXES_UPDATED);
break;
--
2.50.1

View File

@ -0,0 +1,244 @@
From 52bd7e03558c2a5f2356e34cc1fdc9486712d378 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 22 Jul 2025 14:22:34 +1000
Subject: [PATCH] RHEL: map dials to rings on the Intuos Pro 3rd Gen devices
These devices have relative dials but our userspace stack
(mutter/gnome-shell and Wayland) do not have support for relative dials.
This means they can't be configured and any events cannot be
passed through to the client.
Work around this for this set of devices by mapping the relative dials
to a ring. This isn't a perfect emulation - the last value is simply
remembered but we only get so much data from a dial.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
quirks/30-vendor-wacom.quirks | 42 +++++++++++++++++++++
src/evdev-tablet-pad.c | 71 ++++++++++++++++++++++++++++++-----
src/evdev-tablet-pad.h | 5 +++
src/quirks.c | 1 +
src/quirks.h | 1 +
5 files changed, 110 insertions(+), 10 deletions(-)
diff --git a/quirks/30-vendor-wacom.quirks b/quirks/30-vendor-wacom.quirks
index 51211684c821..79c860efca39 100644
--- a/quirks/30-vendor-wacom.quirks
+++ b/quirks/30-vendor-wacom.quirks
@@ -33,3 +33,45 @@ MatchBus=usb
MatchVendor=0x2D1F
MatchProduct=0x524C
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
+
+[Wacom Intuos Pro 3rd L (0x03F9)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03F9
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd L (0x03FA)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03FA
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd L (0x0401)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x0401
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd M (0x03F7)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03F7
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd M (0x03F9)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03F9
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd S (0x03F6)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03F6
+ModelWacomIntuosPro3rd=1
+
+[Wacom Intuos Pro 3rd S (0x03F5)]
+MatchUdevType=tablet
+MatchVendor=0x056A
+MatchProduct=0x03F5
+ModelWacomIntuosPro3rd=1
diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c
index 90614c5dae91..f7b2117c3a56 100644
--- a/src/evdev-tablet-pad.c
+++ b/src/evdev-tablet-pad.c
@@ -335,7 +335,7 @@ pad_check_notify_axes(struct pad_dispatch *pad,
/* Unlike the ring axis we don't get an event when we release
* so we can't set a source */
- if (pad->changed_axes & PAD_AXIS_DIAL1) {
+ if (pad->changed_axes & PAD_AXIS_DIAL1 && !pad->dials.map_to_ring) {
group = pad_dial_get_mode_group(pad, 0);
tablet_pad_notify_dial(base,
time,
@@ -344,7 +344,7 @@ pad_check_notify_axes(struct pad_dispatch *pad,
group);
}
- if (pad->changed_axes & PAD_AXIS_DIAL2) {
+ if (pad->changed_axes & PAD_AXIS_DIAL2 && !pad->dials.map_to_ring) {
group = pad_dial_get_mode_group(pad, 1);
tablet_pad_notify_dial(base,
time,
@@ -353,6 +353,40 @@ pad_check_notify_axes(struct pad_dispatch *pad,
group);
}
+ if (pad->changed_axes & PAD_AXIS_DIAL1 && pad->dials.map_to_ring) {
+ pad->dials.abs_dial1_value += pad->dials.dial1;
+
+ /* Map one dial detent (in v120) to 15 degrees */
+ double value = fmod(pad->dials.abs_dial1_value / 8, 360);
+ if (device->left_handed.enabled)
+ value = fmod(value + 180, 360);
+
+ group = pad_ring_get_mode_group(pad, 0);
+ tablet_pad_notify_ring(base,
+ time,
+ 0,
+ value,
+ LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN,
+ group);
+ }
+
+ if (pad->changed_axes & PAD_AXIS_DIAL2 && pad->dials.map_to_ring) {
+ pad->dials.abs_dial2_value += pad->dials.dial2;
+
+ /* Map one dial detent (in v120) to 15 degrees */
+ double value = fmod(pad->dials.abs_dial2_value / 8, 360);
+ if (device->left_handed.enabled)
+ value = fmod(value + 180, 360);
+
+ group = pad_ring_get_mode_group(pad, 1);
+ tablet_pad_notify_ring(base,
+ time,
+ 1,
+ value,
+ LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN,
+ group);
+ }
+
if (pad->changed_axes & PAD_AXIS_RING1) {
value = pad_handle_ring(pad, device, ABS_WHEEL);
if (send_finger_up)
@@ -780,6 +814,9 @@ pad_init(struct pad_dispatch *pad, struct evdev_device *device)
pad->status = PAD_NONE;
pad->changed_axes = PAD_AXIS_NONE;
+ /* RHEL dial-to-ring special */
+ pad->dials.map_to_ring = evdev_device_has_model_quirk(device, QUIRK_MODEL_WACOM_INTUOS_PRO_3RD);
+
/* We expect the kernel to either give us both axes as hires or neither.
* Getting one is a kernel bug we don't need to care about */
pad->dials.has_hires_dial = libevdev_has_event_code(device->evdev, EV_REL, REL_WHEEL_HI_RES) ||
@@ -886,18 +923,15 @@ evdev_device_tablet_pad_get_num_buttons(struct evdev_device *device)
return pad->nbuttons;
}
-int
-evdev_device_tablet_pad_get_num_dials(struct evdev_device *device)
+static int
+count_dials(struct libevdev *evdev)
{
int ndials = 0;
- if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
- return -1;
-
- if (libevdev_has_event_code(device->evdev, EV_REL, REL_WHEEL) ||
- libevdev_has_event_code(device->evdev, EV_REL, REL_DIAL)) {
+ if (libevdev_has_event_code(evdev, EV_REL, REL_WHEEL) ||
+ libevdev_has_event_code(evdev, EV_REL, REL_DIAL)) {
ndials++;
- if (libevdev_has_event_code(device->evdev,
+ if (libevdev_has_event_code(evdev,
EV_REL,
REL_HWHEEL))
ndials++;
@@ -906,6 +940,19 @@ evdev_device_tablet_pad_get_num_dials(struct evdev_device *device)
return ndials;
}
+int
+evdev_device_tablet_pad_get_num_dials(struct evdev_device *device)
+{
+ if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
+ return -1;
+
+ /* RHEL dial-to-ring special */
+ if (evdev_device_has_model_quirk(device, QUIRK_MODEL_WACOM_INTUOS_PRO_3RD))
+ return 0;
+
+ return count_dials(device->evdev);
+}
+
int
evdev_device_tablet_pad_get_num_rings(struct evdev_device *device)
{
@@ -914,6 +961,10 @@ evdev_device_tablet_pad_get_num_rings(struct evdev_device *device)
if (!(device->seat_caps & EVDEV_DEVICE_TABLET_PAD))
return -1;
+ /* RHEL dial-to-ring special */
+ if (evdev_device_has_model_quirk(device, QUIRK_MODEL_WACOM_INTUOS_PRO_3RD))
+ return count_dials(device->evdev);
+
if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_WHEEL)) {
nrings++;
if (libevdev_has_event_code(device->evdev,
diff --git a/src/evdev-tablet-pad.h b/src/evdev-tablet-pad.h
index fe7aa8b79ff0..c9c23583c714 100644
--- a/src/evdev-tablet-pad.h
+++ b/src/evdev-tablet-pad.h
@@ -79,6 +79,11 @@ struct pad_dispatch {
bool has_hires_dial;
double dial1;
double dial2;
+
+ /* RHEL: map the dial to ring on selected devices */
+ bool map_to_ring;
+ double abs_dial1_value;
+ double abs_dial2_value;
} dials;
struct {
diff --git a/src/quirks.c b/src/quirks.c
index 01065d5eaa21..1151caac1d9d 100644
--- a/src/quirks.c
+++ b/src/quirks.c
@@ -272,6 +272,7 @@ quirk_get_name(enum quirk q)
case QUIRK_MODEL_TOUCHPAD_PHANTOM_CLICKS: return "ModelTouchpadPhantomClicks";
case QUIRK_MODEL_TRACKBALL: return "ModelTrackball";
case QUIRK_MODEL_WACOM_TOUCHPAD: return "ModelWacomTouchpad";
+ case QUIRK_MODEL_WACOM_INTUOS_PRO_3RD: return "ModelWacomIntuosPro3rd";
case QUIRK_MODEL_PRESSURE_PAD: return "ModelPressurePad";
case QUIRK_ATTR_SIZE_HINT: return "AttrSizeHint";
diff --git a/src/quirks.h b/src/quirks.h
index 340d04635b9f..ff0ac94e424f 100644
--- a/src/quirks.h
+++ b/src/quirks.h
@@ -86,6 +86,7 @@ enum quirk {
QUIRK_MODEL_TOUCHPAD_VISIBLE_MARKER,
QUIRK_MODEL_TRACKBALL,
QUIRK_MODEL_WACOM_TOUCHPAD,
+ QUIRK_MODEL_WACOM_INTUOS_PRO_3RD,
QUIRK_MODEL_PRESSURE_PAD,
QUIRK_MODEL_TOUCHPAD_PHANTOM_CLICKS,
--
2.50.1

View File

@ -5,7 +5,7 @@
Name: libinput
Version: 1.26.1
Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Release: 3%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Summary: Input device library
# SPDX
@ -19,6 +19,9 @@ Source2: commitid
Source0: https://gitlab.freedesktop.org/libinput/libinput/-/archive/%{version}/libinput-%{version}.tar.bz2
%endif
Patch0001: 0001-tablet-Remove-unnecessary-scale-factor-on-REL_HWHEEL.patch
Patch0002: 0002-RHEL-map-dials-to-rings-on-the-Intuos-Pro-3rd-Gen-de.patch
BuildRequires: git-core
BuildRequires: gcc
BuildRequires: meson
@ -157,6 +160,9 @@ intended to be run by users.
%changelog
* Wed Jul 23 2025 Peter Hutterer <peter.hutterer@redhat.com> - 1.26.1-3
- Support Wacom Intuos Pro 3rd by mapping the dial to a ring (RHEL-104952)
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1.26.1-2
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018