[PATCH libinput 6/6] tablet: add touch arbitration

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 22 06:14:58 UTC 2016


So far we've relied on the wacom kernel module to do touch arbitration for us
but that won't be the case in upcoming kernels. Implement touch arbitration in
userspace by pairing the two devices and suspending the touch device whenever
a tool comes into proximity.

In the future more sophisticated arbitration can be done (e.g. only touches
which are close to the pen) but let's burn that bridge when we have to cross
it.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 doc/tablet-support.dox  |  12 ++
 src/evdev-mt-touchpad.c |  18 +++
 src/evdev-tablet-pad.c  |   1 +
 src/evdev-tablet.c      |  80 ++++++++++-
 src/evdev-tablet.h      |   3 +
 src/evdev.c             |  15 +++
 src/evdev.h             |   4 +
 test/tablet.c           | 352 ++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 482 insertions(+), 3 deletions(-)

diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
index cda0d70..839924b 100644
--- a/doc/tablet-support.dox
+++ b/doc/tablet-support.dox
@@ -331,4 +331,16 @@ button and ring events on the right. When one of the three mode toggle
 buttons on the right is pressed, the right mode switches to that button's
 mode but the left mode remains unchanged.
 
+ at section tablet-touch-arbitration Tablet touch arbitration
+
+"Touch arbitration" is the terminology used when touch events are suppressed
+while the pen is in proximity. Since it is almost impossible to use a stylus
+or other tool without triggering touches with the hand holding the tool,
+touch arbitration serves to reduce the number of accidental inputs.
+The wacom kernel driver provides touch arbitration but for other devices
+arbitration has to be done in userspace.
+
+libinput uses the @ref libinput_device_group to decide on touch arbitration
+and automatically discards touch events whenever a tool is in proximity.
+
 */
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 3baed09..cbcac8a 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1679,6 +1679,23 @@ evdev_tag_touchpad(struct evdev_device *device,
 	}
 }
 
+static void
+tp_interface_toggle_touch(struct evdev_dispatch *dispatch,
+			  struct evdev_device *device,
+			  bool enable)
+{
+	struct tp_dispatch *tp = (struct tp_dispatch*)dispatch;
+
+	if (enable != tp->device->is_suspended)
+		return;
+
+	if (enable)
+		tp_resume(tp, device);
+	else
+		tp_suspend(tp, device);
+
+}
+
 static struct evdev_dispatch_interface tp_interface = {
 	tp_interface_process,
 	tp_interface_suspend,
@@ -1689,6 +1706,7 @@ static struct evdev_dispatch_interface tp_interface = {
 	tp_interface_device_removed, /* device_suspended, treat as remove */
 	tp_interface_device_added,   /* device_resumed, treat as add */
 	NULL,                        /* post_added */
+	tp_interface_toggle_touch,
 };
 
 static void
diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c
index 0e95408..82542bc 100644
--- a/src/evdev-tablet-pad.c
+++ b/src/evdev-tablet-pad.c
@@ -512,6 +512,7 @@ static struct evdev_dispatch_interface pad_interface = {
 	NULL, /* device_suspended */
 	NULL, /* device_resumed */
 	NULL, /* post_added */
+	NULL, /* toggle_touch */
 };
 
 static void
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 8f24555..4a2cae5 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -1422,6 +1422,39 @@ tablet_flush(struct tablet_dispatch *tablet,
 }
 
 static inline void
+tablet_set_touch_device_enabled(struct evdev_device *touch_device,
+				bool enable)
+{
+	struct evdev_dispatch *dispatch;
+
+	if (touch_device == NULL)
+		return;
+
+	dispatch = touch_device->dispatch;
+	if (dispatch->interface->toggle_touch)
+		dispatch->interface->toggle_touch(dispatch,
+						  touch_device,
+						  enable);
+}
+
+static inline void
+tablet_toggle_touch_device(struct tablet_dispatch *tablet,
+			   struct evdev_device *tablet_device)
+{
+	bool enable_events;
+
+	enable_events = tablet_has_status(tablet,
+					  TABLET_TOOL_OUT_OF_RANGE) ||
+			tablet_has_status(tablet, TABLET_NONE) ||
+			tablet_has_status(tablet,
+					  TABLET_TOOL_LEAVING_PROXIMITY) ||
+			tablet_has_status(tablet,
+					  TABLET_TOOL_OUT_OF_PROXIMITY);
+
+	tablet_set_touch_device_enabled(tablet->touch_device, enable_events);
+}
+
+static inline void
 tablet_reset_state(struct tablet_dispatch *tablet)
 {
 	/* Update state */
@@ -1454,6 +1487,7 @@ tablet_process(struct evdev_dispatch *dispatch,
 		break;
 	case EV_SYN:
 		tablet_flush(tablet, device, time);
+		tablet_toggle_touch_device(tablet, device);
 		tablet_reset_state(tablet);
 		break;
 	default:
@@ -1466,6 +1500,16 @@ tablet_process(struct evdev_dispatch *dispatch,
 }
 
 static void
+tablet_suspend(struct evdev_dispatch *dispatch,
+	       struct evdev_device *device)
+{
+	struct tablet_dispatch *tablet =
+		(struct tablet_dispatch *)dispatch;
+
+	tablet_set_touch_device_enabled(tablet->touch_device, true);
+}
+
+static void
 tablet_destroy(struct evdev_dispatch *dispatch)
 {
 	struct tablet_dispatch *tablet =
@@ -1480,6 +1524,35 @@ tablet_destroy(struct evdev_dispatch *dispatch)
 }
 
 static void
+tablet_device_added(struct evdev_device *device,
+		    struct evdev_device *added_device)
+{
+	struct tablet_dispatch *tablet =
+		(struct tablet_dispatch*)device->dispatch;
+
+	if (libinput_device_get_device_group(&device->base) !=
+	    libinput_device_get_device_group(&added_device->base))
+		return;
+
+	/* Touch screens or external touchpads only */
+	if (evdev_device_has_capability(added_device, LIBINPUT_DEVICE_CAP_TOUCH) ||
+	    (evdev_device_has_capability(added_device, LIBINPUT_DEVICE_CAP_POINTER) &&
+	     (added_device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)))
+	    tablet->touch_device = added_device;
+}
+
+static void
+tablet_device_removed(struct evdev_device *device,
+		      struct evdev_device *removed_device)
+{
+	struct tablet_dispatch *tablet =
+		(struct tablet_dispatch*)device->dispatch;
+
+	if (tablet->touch_device == removed_device)
+		tablet->touch_device = NULL;
+}
+
+static void
 tablet_check_initial_proximity(struct evdev_device *device,
 			       struct evdev_dispatch *dispatch)
 {
@@ -1520,14 +1593,15 @@ tablet_check_initial_proximity(struct evdev_device *device,
 
 static struct evdev_dispatch_interface tablet_interface = {
 	tablet_process,
-	NULL, /* suspend */
+	tablet_suspend,
 	NULL, /* remove */
 	tablet_destroy,
-	NULL, /* device_added */
-	NULL, /* device_removed */
+	tablet_device_added,
+	tablet_device_removed,
 	NULL, /* device_suspended */
 	NULL, /* device_resumed */
 	tablet_check_initial_proximity,
+	NULL, /* toggle_touch */
 };
 
 static void
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index f66de5d..2279e03 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -71,6 +71,9 @@ struct tablet_dispatch {
 	uint32_t cursor_proximity_threshold;
 
 	struct libinput_device_config_calibration calibration;
+
+	/* The paired touch device on devices with both pen & touch */
+	struct evdev_device *touch_device;
 };
 
 static inline enum libinput_tablet_tool_axis
diff --git a/src/evdev.c b/src/evdev.c
index 0e506bc..f9697ae 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -319,6 +319,20 @@ evdev_device_transform_y(struct evdev_device *device,
 	return scale_axis(device->abs.absinfo_y, y, height);
 }
 
+static void
+fallback_toggle_touch(struct evdev_dispatch *evdev_dispatch,
+		      struct evdev_device *device,
+		      bool enable)
+{
+	if (enable != device->is_suspended)
+		return;
+
+	if (enable)
+		evdev_device_resume(device);
+	else
+		evdev_device_suspend(device);
+}
+
 static inline void
 normalize_delta(struct evdev_device *device,
 		const struct device_coords *delta,
@@ -1232,6 +1246,7 @@ struct evdev_dispatch_interface fallback_interface = {
 	NULL, /* device_suspended */
 	NULL, /* device_resumed */
 	NULL, /* post_added */
+	fallback_toggle_touch, /* toggle_touch */
 };
 
 static uint32_t
diff --git a/src/evdev.h b/src/evdev.h
index 1a2f1ff..805cb6a 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -264,6 +264,10 @@ struct evdev_dispatch_interface {
 	 * was sent */
 	void (*post_added)(struct evdev_device *device,
 			   struct evdev_dispatch *dispatch);
+
+	void (*toggle_touch)(struct evdev_dispatch *dispatch,
+			     struct evdev_device *device,
+			     bool enable);
 };
 
 struct evdev_dispatch {
diff --git a/test/tablet.c b/test/tablet.c
index c6886b0..d2f710f 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -3670,6 +3670,348 @@ START_TEST(relative_calibration)
 }
 END_TEST
 
+START_TEST(intuos_touch_arbitration)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	finger = litest_add_device(li, LITEST_WACOM_FINGER);
+	litest_drain_events(li);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	litest_touch_up(finger, 0);
+	litest_assert_empty_queue(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+
+	litest_delete_device(finger);
+}
+END_TEST
+
+START_TEST(intuos_touch_arbitration_stop_touch)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	finger = litest_add_device(li, LITEST_WACOM_FINGER);
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_touch_move_to(finger, 0, 80, 80, 30, 30, 10, 1);
+	litest_assert_empty_queue(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+	litest_tablet_proximity_out(dev);
+	litest_drain_events(li);
+
+	/* Finger needs to be lifted for events to happen*/
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	litest_assert_empty_queue(li);
+	litest_touch_up(finger, 0);
+
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	litest_touch_up(finger, 0);
+
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_POINTER_MOTION);
+
+	litest_delete_device(finger);
+}
+END_TEST
+
+START_TEST(intuos_touch_arbitration_remove_touch)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	finger = litest_add_device(li, LITEST_WACOM_FINGER);
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	litest_delete_device(finger);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+}
+END_TEST
+
+START_TEST(intuos_touch_arbitration_remove_tablet)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *tablet;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	tablet = litest_add_device(li, LITEST_WACOM_INTUOS);
+	libinput_dispatch(li);
+	litest_tablet_proximity_in(tablet, 10, 10, axes);
+	litest_tablet_motion(tablet, 10, 10, axes);
+	litest_tablet_motion(tablet, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_touch_down(dev, 0, 30, 30);
+	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10, 1);
+	litest_assert_empty_queue(li);
+
+	litest_delete_device(tablet);
+	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
+
+	/* Touch is still down, don't enable */
+	litest_touch_move_to(dev, 0, 80, 80, 30, 30, 10, 1);
+	litest_touch_up(dev, 0);
+	litest_assert_empty_queue(li);
+
+	litest_touch_down(dev, 0, 30, 30);
+	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10, 1);
+	litest_touch_up(dev, 0);
+	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+}
+END_TEST
+
+START_TEST(cintiq_touch_arbitration)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	finger = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_FINGER);
+	litest_drain_events(li);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	litest_touch_up(finger, 0);
+	litest_assert_empty_queue(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+
+	litest_delete_device(finger);
+}
+END_TEST
+
+START_TEST(cintiq_touch_arbitration_stop_touch)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct libinput_event *event;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	finger = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_FINGER);
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_drain_events(li);
+
+	litest_touch_move_to(finger, 0, 80, 80, 30, 30, 10, 1);
+	litest_assert_empty_queue(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+	litest_tablet_proximity_out(dev);
+	litest_drain_events(li);
+
+	/* Finger needs to be lifted for events to happen*/
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	litest_assert_empty_queue(li);
+	litest_touch_up(finger, 0);
+
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
+	libinput_event_destroy(event);
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+	libinput_event_destroy(event);
+
+	while ((event = libinput_get_event(li)) != NULL) {
+		litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
+		libinput_event_destroy(event);
+		event = libinput_get_event(li);
+		litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+		libinput_event_destroy(event);
+	}
+
+	litest_touch_up(finger, 0);
+	libinput_dispatch(li);
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_UP);
+	libinput_event_destroy(event);
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+	libinput_event_destroy(event);
+
+	litest_delete_device(finger);
+}
+END_TEST
+
+START_TEST(cintiq_touch_arbitration_remove_touch)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *finger;
+	struct libinput *li = dev->libinput;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	finger = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_FINGER);
+	litest_touch_down(finger, 0, 30, 30);
+	litest_touch_move_to(finger, 0, 30, 30, 80, 80, 10, 1);
+
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	litest_drain_events(li);
+
+	litest_delete_device(finger);
+	litest_drain_events(li);
+
+	litest_tablet_motion(dev, 10, 10, axes);
+	litest_tablet_motion(dev, 20, 40, axes);
+
+	litest_assert_only_typed_events(li,
+					LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+}
+END_TEST
+
+START_TEST(cintiq_touch_arbitration_remove_tablet)
+{
+	struct litest_device *dev = litest_current_device();
+	struct litest_device *tablet;
+	struct libinput *li = dev->libinput;
+	struct libinput_event *event;
+	struct axis_replacement axes[] = {
+		{ ABS_DISTANCE, 10 },
+		{ ABS_PRESSURE, 0 },
+		{ -1, -1 }
+	};
+
+	tablet = litest_add_device(li, LITEST_WACOM_CINTIQ_13HDT_PEN);
+	litest_touch_down(dev, 0, 30, 30);
+	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10, 1);
+
+	litest_tablet_proximity_in(tablet, 10, 10, axes);
+	litest_tablet_motion(tablet, 10, 10, axes);
+	litest_drain_events(li);
+
+	litest_delete_device(tablet);
+	litest_assert_only_typed_events(li, LIBINPUT_EVENT_DEVICE_REMOVED);
+
+	/* Touch is still down, don't enable */
+	litest_touch_move_to(dev, 0, 80, 80, 30, 30, 10, 1);
+	litest_touch_up(dev, 0);
+	litest_assert_empty_queue(li);
+
+	litest_touch_down(dev, 0, 30, 30);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
+	libinput_event_destroy(event);
+
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+	libinput_event_destroy(event);
+
+	litest_touch_move_to(dev, 0, 30, 30, 80, 80, 10, 1);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
+	libinput_event_destroy(event);
+
+	event = libinput_get_event(li);
+	litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+	libinput_event_destroy(event);
+}
+END_TEST
+
 void
 litest_setup_tests_tablet(void)
 {
@@ -3746,4 +4088,14 @@ litest_setup_tests_tablet(void)
 	litest_add("tablet:relative", relative_no_delta_prox_in, LITEST_TABLET, LITEST_ANY);
 	litest_add("tablet:relative", relative_delta, LITEST_TABLET, LITEST_ANY);
 	litest_add("tablet:relative", relative_calibration, LITEST_TABLET, LITEST_ANY);
+
+	litest_add_for_device("tablet:touch-arbitration", intuos_touch_arbitration, LITEST_WACOM_INTUOS);
+	litest_add_for_device("tablet:touch-arbitration", intuos_touch_arbitration_stop_touch, LITEST_WACOM_INTUOS);
+	litest_add_for_device("tablet:touch-arbitration", intuos_touch_arbitration_remove_touch, LITEST_WACOM_INTUOS);
+	litest_add_for_device("tablet:touch-arbitration", intuos_touch_arbitration_remove_tablet, LITEST_WACOM_FINGER);
+
+	litest_add_for_device("tablet:touch-arbitration", cintiq_touch_arbitration, LITEST_WACOM_CINTIQ_13HDT_PEN);
+	litest_add_for_device("tablet:touch-arbitration", cintiq_touch_arbitration_stop_touch, LITEST_WACOM_CINTIQ_13HDT_PEN);
+	litest_add_for_device("tablet:touch-arbitration", cintiq_touch_arbitration_remove_touch, LITEST_WACOM_CINTIQ_13HDT_PEN);
+	litest_add_for_device("tablet:touch-arbitration", cintiq_touch_arbitration_remove_tablet, LITEST_WACOM_CINTIQ_13HDT_FINGER);
 }
-- 
2.7.4



More information about the wayland-devel mailing list