[PATCH libinput 2/5] evdev: fix handling of fake MT devices without ABS_X/Y

Peter Hutterer peter.hutterer at who-t.net
Tue Apr 7 16:54:30 PDT 2015


The previous code didn't handle fake MT devices without ABS_X/Y axes (like the
Razer BlackWidow keyboard). Those devices usually start at ABS_MISC and go up
to ABS_MAX, thus triggering the Android check.

Split the condition up: if the device is not a fake MT device we check for the
Android missing axes first and add them. Then we proceed, but now we know that
the ABS_X axis must exist on any valid device.

https://bugs.freedesktop.org/show_bug.cgi?id=89783

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 115dc99..16ebb9c 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1431,6 +1431,18 @@ evdev_device_get_udev_tags(struct evdev_device *device,
 	return tags;
 }
 
+/* Fake MT devices have the ABS_MT_SLOT bit set because of
+   the limited ABS_* range - they aren't MT devices, they
+   just have too many ABS_ axes */
+static inline bool
+evdev_is_fake_mt_device(struct evdev_device *device)
+{
+	struct libevdev *evdev = device->evdev;
+
+	return libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT) &&
+		libevdev_get_num_slots(evdev) == -1;
+}
+
 static inline void
 evdev_fix_android_mt(struct evdev_device *device)
 {
@@ -1441,7 +1453,8 @@ evdev_fix_android_mt(struct evdev_device *device)
 		return;
 
 	if (!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ||
-	    !libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y))
+	    !libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y) ||
+	    evdev_is_fake_mt_device(device))
 		return;
 
 	libevdev_enable_event_code(evdev, EV_ABS, ABS_X,
@@ -1611,10 +1624,10 @@ evdev_configure_device(struct evdev_device *device)
 		return -1;
 	}
 
-	if (libevdev_has_event_code(evdev, EV_ABS, ABS_X) ||
-	    libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X)) {
+	if (!evdev_is_fake_mt_device(device))
 		evdev_fix_android_mt(device);
 
+	if (libevdev_has_event_code(evdev, EV_ABS, ABS_X)) {
 		if (evdev_fix_abs_resolution(device,
 					     ABS_X,
 					     ABS_Y,
@@ -1624,11 +1637,7 @@ evdev_configure_device(struct evdev_device *device)
 		device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_X);
 		device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_Y);
 
-		/* Fake MT devices have the ABS_MT_SLOT bit set because of
-		   the limited ABS_* range - they aren't MT devices, they
-		   just have too many ABS_ axes */
-		if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_SLOT) &&
-		    libevdev_get_num_slots(evdev) == -1) {
+		if (evdev_is_fake_mt_device(device)) {
 			udev_tags &= ~EVDEV_UDEV_TAG_TOUCHSCREEN;
 		} else if (evdev_configure_mt_device(device) == -1) {
 			return -1;
-- 
2.3.4



More information about the wayland-devel mailing list