From d5845928222f24be91fc27f68e846c1b8bcd9a93 Mon Sep 17 00:00:00 2001
From: Simon McVittie <[EMAIL REDACTED]>
Date: Fri, 16 Jun 2023 15:16:44 +0100
Subject: [PATCH] linux: If the kernel specifically tells us the device type,
trust it
If a device is positively identified as an accelerometer, pointing stick
or clickpad, then we don't need to second-guess it.
In practice this does not change the result for any device in our
test data, so add some artificial records that exercise this.
Signed-off-by: Simon McVittie <smcv@collabora.com>
---
src/core/linux/SDL_evdev_capabilities.c | 19 +++++++++++++++-
test/testevdev.c | 30 +++++++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/core/linux/SDL_evdev_capabilities.c b/src/core/linux/SDL_evdev_capabilities.c
index 233426da4482..96653f6465aa 100644
--- a/src/core/linux/SDL_evdev_capabilities.c
+++ b/src/core/linux/SDL_evdev_capabilities.c
@@ -58,6 +58,22 @@ SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_props[NBITS(INPUT_PROP_MA
int devclass = 0;
unsigned long keyboard_mask;
+ /* If the kernel specifically says it's an accelerometer, believe it */
+ if (test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props)) {
+ return SDL_UDEV_DEVICE_ACCELEROMETER;
+ }
+
+ /* We treat pointing sticks as indistinguishable from mice */
+ if (test_bit(INPUT_PROP_POINTING_STICK, bitmask_props)) {
+ return SDL_UDEV_DEVICE_MOUSE;
+ }
+
+ /* We treat buttonpads as equivalent to touchpads */
+ if (test_bit(INPUT_PROP_TOPBUTTONPAD, bitmask_props) ||
+ test_bit(INPUT_PROP_BUTTONPAD, bitmask_props)) {
+ return SDL_UDEV_DEVICE_TOUCHPAD;
+ }
+
/* X, Y, Z axes but no buttons probably means an accelerometer */
if (test_bit(EV_ABS, bitmask_ev) &&
test_bit(ABS_X, bitmask_abs) &&
@@ -67,7 +83,8 @@ SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_props[NBITS(INPUT_PROP_MA
return SDL_UDEV_DEVICE_ACCELEROMETER;
}
- /* RX, RY, RZ axes but no buttons also probably means an accelerometer */
+ /* RX, RY, RZ axes but no buttons probably means a gyro or
+ * accelerometer (we don't distinguish) */
if (test_bit(EV_ABS, bitmask_ev) &&
test_bit(ABS_RX, bitmask_abs) &&
test_bit(ABS_RY, bitmask_abs) &&
diff --git a/test/testevdev.c b/test/testevdev.c
index e8315b1baff5..3fd6dc91abb3 100644
--- a/test/testevdev.c
+++ b/test/testevdev.c
@@ -1758,6 +1758,36 @@ static const GuessTest guess_tests[] =
.hid_report_descriptor_length = sizeof (fanatec_handbrake_hid_report_descriptor),
.hid_report_descriptor = &fanatec_handbrake_hid_report_descriptor[0],
},
+ { /* Artificial test data, not a real device */
+ .name = "Fake accelerometer with fewer than usual axes reported",
+ .expected = SDL_UDEV_DEVICE_ACCELEROMETER,
+ /* SYN, ABS */
+ .ev = { 0x09 },
+ /* X only */
+ .abs = { 0x01 },
+ /* ACCELEROMETER */
+ .props = { 0x40 },
+ },
+ { /* Artificial test data, not a real device */
+ .name = "Fake pointing stick with no buttons",
+ .expected = SDL_UDEV_DEVICE_MOUSE,
+ /* SYN, REL */
+ .ev = { 0x05 },
+ /* X,Y */
+ .rel = { 0x03 },
+ /* POINTER, POINTING_STICK */
+ .props = { 0x21 },
+ },
+ { /* Artificial test data, not a real device */
+ .name = "Fake buttonpad",
+ .expected = SDL_UDEV_DEVICE_TOUCHPAD,
+ /* SYN, ABS */
+ .ev = { 0x09 },
+ /* X,Y */
+ .abs = { 0x03 },
+ /* POINTER, BUTTONPAD */
+ .props = { 0x05 },
+ },
{
.name = "No information",
.expected = SDL_UDEV_DEVICE_UNKNOWN,