[PATCH libinput] tablet: don't set rotation on a tool if we don't have ABS_Z

Peter Hutterer peter.hutterer at who-t.net
Tue Feb 6 01:07:00 UTC 2018

Rotation on a tool can either ABS_Z or in the case of the mouse/lens tools a
combination of ABS_TILT_X/Y. The code assumes that if the rotation on a stylus
(not mouse/lense) changes, we need to fetch it from ABS_Z. This happens on the
very first event from the tablet, proximity in invalidates all axes so we can
send the current state to the caller.

On libwacom-recognized tablets we never set the rotation bit on the stylus, so
that's all fine. On tablets without libwacom support, the stylus may have a
rotation bit copied because we have it set thanks to mouse+tilt on the tablet.
When that first event is handled, we try to access ABS_Z. On tablets without
ABS_Z like Aipteks, we go boom.

Fix this by checking for ABS_Z during tablet init, if we don't have that axis
then never set the rotation bit on the tool. That's the only axis where we
need this, all other axes have a single cause only and thus the tablet bits
are accurate anyway.


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
 src/evdev-tablet.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 2f6b64da..771e7775 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -933,7 +933,17 @@ tool_set_bits(const struct tablet_dispatch *tablet,
 		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
 		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
 		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
-		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
+		/* Rotation is special, it can be either ABS_Z or
+		 * BTN_TOOL_MOUSE+ABS_TILT_X/Y. Aiptek tablets have
+		 * mouse+tilt (and thus rotation), but they do not have
+		 * ABS_Z. So let's not copy the axis bit if we don't have
+		 * ABS_Z, otherwise we try to get the value from it later on
+		 * proximity in and go boom because the absinfo isn't there.
+		 */
+		if (libevdev_has_event_code(tablet->device->evdev, EV_ABS,
+					    ABS_Z))
+			copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);

More information about the wayland-devel mailing list