Handle BTN_STYLUS3 (RHEL-148126)

Resolves: RHEL-148126
This commit is contained in:
Peter Hutterer 2026-02-10 13:29:55 +10:00
parent 2a5953d210
commit 6c1a2b5217
3 changed files with 308 additions and 1 deletions

View File

@ -0,0 +1,170 @@
From 61b088af3be02f13272f7b57fa0a539510cfe981 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 23 Jan 2024 20:09:04 +1000
Subject: [PATCH] tablet: handle BTN_STYLUS3
And add a test to make sure the tool we know that has three buttons (Pro
Pen 3) can send all those. Enough to run that test one one compatible
device, no real benefit of running it on all tablet devices.
(cherry picked from commit 8bb53150a994acf65925ce091dd8b9619a74e43a)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
src/evdev-tablet.c | 4 +++
test/test-tablet.c | 61 +++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 3b77b47c817e..9c32ce5a78c6 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -766,6 +766,7 @@ tablet_update_button(struct tablet_dispatch *tablet,
case BTN_TASK:
case BTN_STYLUS:
case BTN_STYLUS2:
+ case BTN_STYLUS3:
break;
default:
evdev_log_info(tablet->device,
@@ -952,6 +953,8 @@ tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
code++)
copy_button_cap(tablet, tool, code);
} else {
+ if (libwacom_stylus_get_num_buttons(s) >= 3)
+ copy_button_cap(tablet, tool, BTN_STYLUS3);
if (libwacom_stylus_get_num_buttons(s) >= 2)
copy_button_cap(tablet, tool, BTN_STYLUS2);
if (libwacom_stylus_get_num_buttons(s) >= 1)
@@ -1050,6 +1053,7 @@ tool_set_bits(const struct tablet_dispatch *tablet,
case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
copy_button_cap(tablet, tool, BTN_STYLUS);
copy_button_cap(tablet, tool, BTN_STYLUS2);
+ copy_button_cap(tablet, tool, BTN_STYLUS3);
break;
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
case LIBINPUT_TABLET_TOOL_TYPE_LENS:
diff --git a/test/test-tablet.c b/test/test-tablet.c
index 91ffc071ac2f..f3c7bc9f977a 100644
--- a/test/test-tablet.c
+++ b/test/test-tablet.c
@@ -1101,32 +1101,33 @@ START_TEST(proximity_out_clear_buttons)
struct libinput *li = dev->libinput;
struct libinput_event_tablet_tool *tablet_event;
struct libinput_event *event;
- uint32_t button;
struct axis_replacement axes[] = {
{ ABS_DISTANCE, 10 },
{ ABS_PRESSURE, 0 },
{ -1, -1 }
};
+ uint32_t stylus_buttons[] = {BTN_STYLUS, BTN_STYLUS2, BTN_STYLUS3};
bool have_proximity = false;
double x = 50, y = 50;
+ uint32_t *button;
litest_drain_events(li);
/* Test that proximity out events send button releases for any currently
* pressed stylus buttons
*/
- for (button = BTN_STYLUS; button <= BTN_STYLUS2; button++) {
+ ARRAY_FOR_EACH(stylus_buttons, button) {
bool button_released = false;
uint32_t event_button = 0;
enum libinput_button_state state;
- if (!libevdev_has_event_code(dev->evdev, EV_KEY, button))
+ if (!libevdev_has_event_code(dev->evdev, EV_KEY, *button))
continue;
litest_tablet_proximity_in(dev, x++, y++, axes);
litest_drain_events(li);
- litest_event(dev, EV_KEY, button, 1);
+ litest_event(dev, EV_KEY, *button, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_tablet_proximity_out(dev);
libinput_dispatch(li);
@@ -1149,7 +1150,7 @@ START_TEST(proximity_out_clear_buttons)
event_button = libinput_event_tablet_tool_get_button(tablet_event);
state = libinput_event_tablet_tool_get_button_state(tablet_event);
- if (event_button == button &&
+ if (event_button == *button &&
state == LIBINPUT_BUTTON_STATE_RELEASED)
button_released = true;
}
@@ -1159,7 +1160,7 @@ START_TEST(proximity_out_clear_buttons)
ck_assert_msg(button_released,
"Button %s (%d) was not released.",
- libevdev_event_code_get_name(EV_KEY, button),
+ libevdev_event_code_get_name(EV_KEY, *button),
event_button);
litest_assert(have_proximity);
litest_assert_empty_queue(li);
@@ -3165,6 +3166,53 @@ START_TEST(tool_direct_switch_with_forced_proxout)
}
END_TEST
+START_TEST(stylus_buttons)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct libinput_event *event;
+ struct libinput_event_tablet_tool *tev;
+ struct libinput_tablet_tool *tool;
+ uint32_t stylus_buttons[] = {BTN_STYLUS, BTN_STYLUS2, BTN_STYLUS3};
+ uint32_t *code;
+
+ litest_drain_events(li);
+
+ litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
+ litest_event(dev, EV_ABS, ABS_MISC, 0x200); /* 3-button stylus tool_id */
+ litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+
+ event = libinput_get_event(li);
+ tev = litest_is_tablet_event(event,
+ LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+ tool = libinput_event_tablet_tool_get_tool(tev);
+ ck_assert_notnull(tool);
+ libinput_tablet_tool_ref(tool);
+
+ libinput_event_destroy(event);
+
+ ARRAY_FOR_EACH(stylus_buttons, code) {
+ litest_event(dev, EV_KEY, *code, 1);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+ litest_event(dev, EV_KEY, *code, 0);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+
+ litest_assert_tablet_button_event(li,
+ *code,
+ LIBINPUT_BUTTON_STATE_PRESSED);
+ litest_assert_tablet_button_event(li,
+ *code,
+ LIBINPUT_BUTTON_STATE_RELEASED);
+ }
+
+ libinput_tablet_tool_unref(tool);
+}
+END_TEST
+
START_TEST(mouse_tool)
{
struct litest_device *dev = litest_current_device();
@@ -6212,6 +6260,7 @@ TEST_COLLECTION(tablet)
litest_add_for_device(left_handed_artpen_rotation, LITEST_WACOM_INTUOS);
litest_add_for_device(no_left_handed, LITEST_WACOM_CINTIQ);
litest_add(pad_buttons_ignored, LITEST_TABLET, LITEST_TOTEM);
+ litest_add_for_device(stylus_buttons, LITEST_WACOM_CINTIQ_PRO16_PEN);
litest_add(mouse_tool, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
litest_add(mouse_buttons, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
litest_add(mouse_rotation, LITEST_TABLET | LITEST_TOOL_MOUSE, LITEST_ANY);
--
2.52.0

View File

@ -0,0 +1,132 @@
From 32335472dcba6ec22328ef9b017727c00e537940 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 14 Oct 2024 19:29:15 +1000
Subject: [PATCH] test: fix uinput creation for the slotted devices with too
many slots
Kernel commit 206f533a0a7c
"Input: uinput - reject requests with unreasonable number of slots"
limits the number of slots to 99 - let's manually adjust that so we can
keep creating uinput devices.
Since these are just a test device and we don't use the slots here
anyway (they're all fake MT devices) we can manually work around this.
The real devices won't be affected by this since this is a limitation
in uinput, not the input subsystem.
Also move the comment one line up in the ms-surface device, the previous
comment referred to the wrong event code.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1061>
(cherry picked from commit aecfcf3d1ba25954ff44a8ff39a1ac40d828c5f8)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
test/litest-device-anker-mouse-kbd.c | 5 ++++-
test/litest-device-keyboard-razer-blackwidow.c | 5 ++++-
test/litest-device-keyboard-razer-blade-stealth.c | 5 ++++-
test/litest-device-ms-surface-cover.c | 7 +++++--
test/litest.c | 13 ++++++++++++-
5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/test/litest-device-anker-mouse-kbd.c b/test/litest-device-anker-mouse-kbd.c
index ef515364ccbb..1e315e3eafbc 100644
--- a/test/litest-device-anker-mouse-kbd.c
+++ b/test/litest-device-anker-mouse-kbd.c
@@ -193,7 +193,10 @@ static struct input_absinfo absinfo[] = {
{ 0x2c, 0, 255, 0, 0, 0 },
{ 0x2d, 0, 255, 0, 0, 0 },
{ 0x2e, 0, 255, 0, 0, 0 },
- { ABS_MT_SLOT, 0, 255, 0, 0, 0 },
+ /* Note: slot count artificially reduced for kernel
+ * commit 206f533a0a7c ("Input: uinput - reject requests with unreasonable number of slots")
+ */
+ { ABS_MT_SLOT, 0, 64, 0, 0, 0 },
{ ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0, 0 },
{ ABS_MT_TOUCH_MINOR, 0, 255, 0, 0, 0 },
{ ABS_MT_WIDTH_MINOR, 0, 255, 0, 0, 0 },
diff --git a/test/litest-device-keyboard-razer-blackwidow.c b/test/litest-device-keyboard-razer-blackwidow.c
index 5dee7f469afd..5585ea4633d8 100644
--- a/test/litest-device-keyboard-razer-blackwidow.c
+++ b/test/litest-device-keyboard-razer-blackwidow.c
@@ -309,7 +309,10 @@ static struct input_absinfo absinfo[] = {
{ 0x2c, 0, 255, 0, 0, 0 },
{ 0x2d, 0, 255, 0, 0, 0 },
{ 0x2e, 0, 255, 0, 0, 0 },
- { 0x2f, 0, 255, 0, 0, 0 },
+ /* Note: slot count artificially reduced for kernel
+ * commit 206f533a0a7c ("Input: uinput - reject requests with unreasonable number of slots")
+ */
+ { 0x2f, 0, 64, 0, 0, 0 },
{ 0x30, 0, 255, 0, 0, 0 },
{ 0x31, 0, 255, 0, 0, 0 },
{ 0x32, 0, 255, 0, 0, 0 },
diff --git a/test/litest-device-keyboard-razer-blade-stealth.c b/test/litest-device-keyboard-razer-blade-stealth.c
index b08ee43365c5..b27af149a2f4 100644
--- a/test/litest-device-keyboard-razer-blade-stealth.c
+++ b/test/litest-device-keyboard-razer-blade-stealth.c
@@ -307,7 +307,10 @@ static struct input_absinfo absinfo[] = {
{ 0x2c, 0, 255, 0, 0, 0 },
{ 0x2d, 0, 255, 0, 0, 0 },
{ 0x2e, 0, 255, 0, 0, 0 },
- { 0x2f, 0, 255, 0, 0, 0 },
+ /* Note: slot count artificially reduced for kernel
+ * commit 206f533a0a7c ("Input: uinput - reject requests with unreasonable number of slots")
+ */
+ { 0x2f, 0, 64, 0, 0, 0 },
{ 0x30, 0, 255, 0, 0, 0 },
{ 0x31, 0, 255, 0, 0, 0 },
{ 0x32, 0, 255, 0, 0, 0 },
diff --git a/test/litest-device-ms-surface-cover.c b/test/litest-device-ms-surface-cover.c
index 311472113912..77306fb5aafd 100644
--- a/test/litest-device-ms-surface-cover.c
+++ b/test/litest-device-ms-surface-cover.c
@@ -63,9 +63,12 @@ static struct input_absinfo absinfo[] = {
{ 44, -127, 127, 0, 0, 0 },
{ 45, -127, 127, 0, 0, 0 },
{ 46, -127, 127, 0, 0, 0 },
- { 47, -127, 127, 0, 0, 0 },
/* ABS_MT range overlap starts here */
- { 48, -127, 127, 0, 0, 0 }, /* ABS_MT_SLOT */
+ /* Note: slot count artificially reduced for kernel
+ * commit 206f533a0a7c ("Input: uinput - reject requests with unreasonable number of slots")
+ */
+ { 47, 0, 64, 0, 0, 0 }, /* ABS_MT_SLOT */
+ { 48, -127, 127, 0, 0, 0 },
{ 49, -127, 127, 0, 0, 0 },
{ 50, -127, 127, 0, 0, 0 },
{ 51, -127, 127, 0, 0, 0 },
diff --git a/test/litest.c b/test/litest.c
index 187dd3455451..5a7cb80a0fec 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -3370,6 +3370,15 @@ litest_create_uinput(const char *name,
.flat = 0,
.resolution = 100
};
+ /* See kernel commit 206f533a0a7c ("Input: uinput - reject requests with unreasonable number of slots") */
+ const struct input_absinfo default_abs_mt_slot = {
+ .value = 0,
+ .minimum = 0,
+ .maximum = 64,
+ .fuzz = 0,
+ .flat = 0,
+ .resolution = 100
+ };
char buf[512];
const char *devnode;
@@ -3403,8 +3412,10 @@ litest_create_uinput(const char *name,
if (type == INPUT_PROP_MAX) {
rc = libevdev_enable_property(dev, code);
} else {
+ const struct input_absinfo *abs =
+ (code == ABS_MT_SLOT) ? &default_abs_mt_slot : &default_abs;
rc = libevdev_enable_event_code(dev, type, code,
- type == EV_ABS ? &default_abs : NULL);
+ type == EV_ABS ? abs : NULL);
}
litest_assert_int_eq(rc, 0);
}
--
2.52.0

View File

@ -5,7 +5,7 @@
Name: libinput
Version: 1.19.3
Release: 7%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Release: 8%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Summary: Input device library
License: MIT
@ -25,6 +25,8 @@ Patch0004: 0004-quirks-add-quirk-for-Dell-Haptics-Touchpad.patch
Patch0005: 0005-quirks-add-quirks-for-Dell-laptop-with-Goodix-Touchp.patch
Patch0006: 0006-RHEL-map-dials-to-rings-on-the-Intuos-Pro-3rd-Gen-de.patch
Patch0007: 0007-pad-don-t-assert-when-unable-to-find-the-mode-group-.patch
Patch0008: 0008-tablet-handle-BTN_STYLUS3.patch
Patch0009: 0009-test-fix-uinput-creation-for-the-slotted-devices-wit.patch
BuildRequires: git-core
BuildRequires: gcc
@ -154,6 +156,9 @@ pathfix.py -i %{__python3} -p -n $(git grep -l '#!/usr/bin/.*python3')
%{_mandir}/man1/libinput-test-suite.1*
%changelog
* Tue Feb 10 2026 Peter Hutterer <peter.hutterer@redhat.com> - 1.19.3-8
- Handle BTN_STYLUS3 (RHEL-147703)
* Mon Aug 04 2025 Peter Hutterer <peter.hutterer@redhat.com> - 1.19.3-7
- Fix crash when the Wacom Intuos Pro 3rd gen sends absolute wheel events