diff --git a/src/core/linux/SDL_evdev_capabilities.c b/src/core/linux/SDL_evdev_capabilities.c index 233426da44..96653f6465 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 e8315b1baf..3fd6dc91ab 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,