[PATCH libinput 4/4] tablet: a tip event can replace an axis event

Peter Hutterer peter.hutterer at who-t.net
Tue Dec 22 19:48:18 PST 2015


When we're only dealing with BTN_TOUCH we can make the tip event independent
of the axis event. Now that we handle pressure thresholds to trigger tip state
this does not work, we'd have to send an axis event with the new pressure and
then a tip event. Since the pressure triggers the tip event this seems
disconnected.

Make the tip event officially capable of carrying axes. A caller can then
decide how to forward this to the next layer.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 doc/tablet-support.dox |   2 +-
 src/evdev-tablet.c     | 168 +++++++++++++++++++++++++++++++------------------
 src/libinput-private.h |   1 +
 src/libinput.c         |   4 ++
 src/libinput.h         |  28 ++++++++-
 test/tablet.c          | 101 ++++++++++++-----------------
 6 files changed, 178 insertions(+), 126 deletions(-)

diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
index a3d4d7b..7113fd1 100644
--- a/doc/tablet-support.dox
+++ b/doc/tablet-support.dox
@@ -43,7 +43,7 @@ pressure value while the tip is logically up. Most application can and
 should ignore pressure information until they receive the event of type @ref
 LIBINPUT_EVENT_TABLET_TOOL_TIP. Applications that require extremely
 fine-grained pressure sensitivity should use the pressure data instead of
-the tip events.
+the tip events to determine a logical tip down state.
 
 Note that the pressure threshold to trigger a logical tip event may be zero
 on some devices. On tools without pressure sensitivity, determining when a
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 2f57805..0c20483 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -453,13 +453,14 @@ tablet_handle_wheel(struct tablet_dispatch *tablet,
 	return tablet->axes[a];
 }
 
-static void
+static bool
 tablet_check_notify_axes(struct tablet_dispatch *tablet,
 			 struct evdev_device *device,
-			 uint64_t time,
-			 struct libinput_tablet_tool *tool)
+			 struct libinput_tablet_tool *tool,
+			 double *axes_out,
+			 size_t axes_sz,
+			 int *wheel_discrete_out)
 {
-	struct libinput_device *base = &device->base;
 	double axes[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1] = {0};
 	int wheel_discrete = 0;
 	struct device_coords point;
@@ -467,8 +468,9 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
 	const char tmp[sizeof(tablet->changed_axes)] = {0};
 
 	if (memcmp(tmp, tablet->changed_axes, sizeof(tmp)) == 0)
-		return;
+		return false;
 
+	assert(axes_sz == sizeof(axes));
 	point = tablet_handle_xy(tablet, device);
 	axes[LIBINPUT_TABLET_TOOL_AXIS_X] = point.x;
 	axes[LIBINPUT_TABLET_TOOL_AXIS_Y] = point.y;
@@ -501,41 +503,10 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
 	axes[LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL] =
 		tablet_handle_wheel(tablet, device, &wheel_discrete);
 
-	/* We need to make sure that we check that the tool is not out of
-	 * proximity before we send any axis updates. This is because many
-	 * tablets will send axis events with incorrect values if the tablet
-	 * tool is close enough so that the tablet can partially detect that
-	 * it's there, but can't properly receive any data from the tool. */
-	if (!tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY) &&
-	    !tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
-		if (tablet_has_status(tablet,
-				      TABLET_TOOL_ENTERING_PROXIMITY)) {
-			tablet_notify_proximity(&device->base,
-						time,
-						tool,
-						LIBINPUT_TABLET_TOOL_PROXIMITY_IN,
-						tablet->changed_axes,
-						axes);
-		} else {
-			enum libinput_tablet_tool_tip_state tip_state;
+	memcpy(axes_out, axes, sizeof(axes));
+	*wheel_discrete_out = wheel_discrete;
 
-			if (tablet_has_status(tablet,
-					      TABLET_TOOL_IN_CONTACT))
-				tip_state = LIBINPUT_TABLET_TOOL_TIP_DOWN;
-			else
-				tip_state = LIBINPUT_TABLET_TOOL_TIP_UP;
-
-			tablet_notify_axis(base,
-					   time,
-					   tool,
-					   tip_state,
-					   tablet->changed_axes,
-					   axes,
-					   wheel_discrete);
-		}
-	}
-
-	memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
+	return true;
 }
 
 static void
@@ -1213,6 +1184,98 @@ tablet_update_proximity_state(struct tablet_dispatch *tablet,
 }
 
 static void
+tablet_send_axis_proximity_tip_down_events(struct tablet_dispatch *tablet,
+					   struct evdev_device *device,
+					   struct libinput_tablet_tool *tool,
+					   uint64_t time)
+{
+	double axes[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1] = {0};
+	int wheel_discrete = 0;
+
+	/* We need to make sure that we check that the tool is not out of
+	 * proximity before we send any axis updates. This is because many
+	 * tablets will send axis events with incorrect values if the tablet
+	 * tool is close enough so that the tablet can partially detect that
+	 * it's there, but can't properly receive any data from the tool. */
+	if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
+		goto out;
+	else if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
+		/* Tool is leaving proximity, we can't rely on the last axis
+		 * information (it'll be mostly 0), so we just get the
+		 * current state and skip over updating the axes.
+		 */
+		static_assert(sizeof(axes) == sizeof(tablet->axes),
+			      "Mismatching array sizes");
+		memcpy(axes, tablet->axes, sizeof(axes));
+
+		/* Dont' send an axis event, but we may have a tip event
+		 * update */
+		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
+	} else if (!tablet_check_notify_axes(tablet,
+					     device,
+					     tool,
+					     axes,
+					     sizeof(axes),
+					     &wheel_discrete)) {
+		goto out;
+	}
+
+	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY)) {
+		tablet_notify_proximity(&device->base,
+					time,
+					tool,
+					LIBINPUT_TABLET_TOOL_PROXIMITY_IN,
+					tablet->changed_axes,
+					axes);
+		tablet_unset_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
+		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
+	}
+
+	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT)) {
+		tablet_notify_tip(&device->base,
+				  time,
+				  tool,
+				  LIBINPUT_TABLET_TOOL_TIP_DOWN,
+				  tablet->changed_axes,
+				  tablet->axes);
+		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
+		tablet_unset_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
+		tablet_set_status(tablet, TABLET_TOOL_IN_CONTACT);
+	} else if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT)) {
+		tablet_notify_tip(&device->base,
+				  time,
+				  tool,
+				  LIBINPUT_TABLET_TOOL_TIP_UP,
+				  tablet->changed_axes,
+				  tablet->axes);
+		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
+		tablet_unset_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
+		tablet_unset_status(tablet, TABLET_TOOL_IN_CONTACT);
+	} else if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
+		enum libinput_tablet_tool_tip_state tip_state;
+
+		if (tablet_has_status(tablet,
+				      TABLET_TOOL_IN_CONTACT))
+			tip_state = LIBINPUT_TABLET_TOOL_TIP_DOWN;
+		else
+			tip_state = LIBINPUT_TABLET_TOOL_TIP_UP;
+
+		tablet_notify_axis(&device->base,
+				   time,
+				   tool,
+				   tip_state,
+				   tablet->changed_axes,
+				   axes,
+				   wheel_discrete);
+		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
+	}
+
+out:
+	memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
+	tablet_unset_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
+}
+
+static void
 tablet_flush(struct tablet_dispatch *tablet,
 	     struct evdev_device *device,
 	     uint64_t time)
@@ -1247,21 +1310,12 @@ tablet_flush(struct tablet_dispatch *tablet,
 		detect_pressure_offset(tablet, device, tool);
 		detect_tool_contact(tablet, device, tool);
 		sanitize_tablet_axes(tablet, tool);
-		tablet_check_notify_axes(tablet, device, time, tool);
-
-		tablet_unset_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
-		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
 	}
 
-	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT)) {
-		tablet_notify_tip(&device->base,
-				  time,
-				  tool,
-				  LIBINPUT_TABLET_TOOL_TIP_DOWN,
-				  tablet->axes);
-		tablet_unset_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
-		tablet_set_status(tablet, TABLET_TOOL_IN_CONTACT);
-	}
+	tablet_send_axis_proximity_tip_down_events(tablet,
+						   device,
+						   tool,
+						   time);
 
 	if (tablet_has_status(tablet, TABLET_BUTTONS_RELEASED)) {
 		tablet_notify_buttons(tablet,
@@ -1281,16 +1335,6 @@ tablet_flush(struct tablet_dispatch *tablet,
 		tablet_unset_status(tablet, TABLET_BUTTONS_PRESSED);
 	}
 
-	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT)) {
-		tablet_notify_tip(&device->base,
-				  time,
-				  tool,
-				  LIBINPUT_TABLET_TOOL_TIP_UP,
-				  tablet->axes);
-		tablet_unset_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
-		tablet_unset_status(tablet, TABLET_TOOL_IN_CONTACT);
-	}
-
 	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
 		memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
 		tablet_notify_proximity(&device->base,
diff --git a/src/libinput-private.h b/src/libinput-private.h
index 5238e64..2dbc555 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -509,6 +509,7 @@ tablet_notify_tip(struct libinput_device *device,
 		  uint64_t time,
 		  struct libinput_tablet_tool *tool,
 		  enum libinput_tablet_tool_tip_state tip_state,
+		  unsigned char *changed_axes,
 		  double *axes);
 
 void
diff --git a/src/libinput.c b/src/libinput.c
index 3a10df4..8f84cf9 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -2226,6 +2226,7 @@ tablet_notify_tip(struct libinput_device *device,
 		  uint64_t time,
 		  struct libinput_tablet_tool *tool,
 		  enum libinput_tablet_tool_tip_state tip_state,
+		  unsigned char *changed_axes,
 		  double *axes)
 {
 	struct libinput_event_tablet_tool *tip_event;
@@ -2243,6 +2244,9 @@ tablet_notify_tip(struct libinput_device *device,
 	memcpy(tip_event->axes,
 	       axes,
 	       sizeof(tip_event->axes));
+	memcpy(tip_event->changed_axes,
+	       changed_axes,
+	       sizeof(tip_event->changed_axes));
 
 	post_device_event(device,
 			  time,
diff --git a/src/libinput.h b/src/libinput.h
index 71d2820..cc1a083 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -270,6 +270,10 @@ enum libinput_event_type {
 	 * changes from this initial state. It is possible for a tool to
 	 * enter and leave proximity without sending an event of type @ref
 	 * LIBINPUT_EVENT_TABLET_TOOL_AXIS.
+	 *
+	 * An event of type @ref LIBINPUT_EVENT_TABLET_TOOL_AXIS is sent
+	 * when the tip state does not change. See the documentation for
+	 * @ref LIBINPUT_EVENT_TABLET_TOOL_TIP for more details.
 	 */
 	LIBINPUT_EVENT_TABLET_TOOL_AXIS = 600,
 	/**
@@ -306,10 +310,30 @@ enum libinput_event_type {
 	 * LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY for the tip down event, and
 	 * immediately before for the tip up event.
 	 *
-	 * If a button and/or axis state change occurs at the same time as a
-	 * tip state change, the order of events is device-dependent.
+	 * The decision when a tip touches the surface is device-dependent
+	 * and may be derived from pressure data or other means. If the tip
+	 * state is changed by axes changing state, the
+	 * @ref LIBINPUT_EVENT_TABLET_TOOL_TIP event includes the changed
+	 * axes and no additional axis event is sent for this state change.
+	 * In other words, a caller must look at both @ref
+	 * LIBINPUT_EVENT_TABLET_TOOL_AXIS and @ref
+	 * LIBINPUT_EVENT_TABLET_TOOL_TIP events to know the current state
+	 * of the axes.
+	 *
+	 * If a button state change occurs at the same time as a tip state
+	 * change, the order of events is device-dependent.
 	 */
 	LIBINPUT_EVENT_TABLET_TOOL_TIP,
+	/**
+	 * Signals that a tool has changed a logical button state on a
+	 * device with the @ref LIBINPUT_DEVICE_CAP_TABLET_TOOL capability.
+	 *
+	 * Button state changes occur on their own and do not include axis
+	 * state changes. If button and axis state changes occur within the
+	 * same logical hardware event, the order of the @ref
+	 * LIBINPUT_EVENT_TABLET_TOOL_BUTTON and @ref
+	 * LIBINPUT_EVENT_TABLET_TOOL_AXIS event is device-specific.
+	 */
 	LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
 
 	LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800,
diff --git a/test/tablet.c b/test/tablet.c
index 0ddad77..d391c91 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2014 Red Hat, Inc.
+ * Copyright © 2014-2015 Red Hat, Inc.
  * Copyright © 2014 Stephen Chandler "Lyude" Paul
  *
  * Permission to use, copy, modify, distribute, and sell this software and
@@ -60,11 +60,6 @@ START_TEST(tip_down_up)
 
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
-	libinput_event_destroy(event);
-
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
@@ -81,11 +76,6 @@ START_TEST(tip_down_up)
 	libinput_dispatch(li);
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
-	libinput_event_destroy(event);
-
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
 			 LIBINPUT_TABLET_TOOL_TIP_UP);
@@ -125,7 +115,6 @@ START_TEST(tip_down_prox_in)
 			 LIBINPUT_TABLET_TOOL_PROXIMITY_IN);
 	libinput_event_destroy(event);
 
-	libinput_dispatch(li);
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
@@ -212,9 +201,12 @@ START_TEST(tip_up_btn_change)
 	litest_pop_event_frame(dev);
 
 	libinput_dispatch(li);
+
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
+	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
+			 LIBINPUT_TABLET_TOOL_TIP_UP);
 	libinput_event_destroy(event);
 
 	event = libinput_get_event(li);
@@ -226,13 +218,6 @@ START_TEST(tip_up_btn_change)
 			 LIBINPUT_BUTTON_STATE_PRESSED);
 	libinput_event_destroy(event);
 
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
-	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
-			 LIBINPUT_TABLET_TOOL_TIP_UP);
-	libinput_event_destroy(event);
-
 	litest_assert_empty_queue(li);
 
 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
@@ -253,9 +238,12 @@ START_TEST(tip_up_btn_change)
 	litest_pop_event_frame(dev);
 
 	libinput_dispatch(li);
+
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
+	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
+			 LIBINPUT_TABLET_TOOL_TIP_UP);
 	libinput_event_destroy(event);
 
 	event = libinput_get_event(li);
@@ -267,14 +255,6 @@ START_TEST(tip_up_btn_change)
 			 LIBINPUT_BUTTON_STATE_RELEASED);
 	libinput_event_destroy(event);
 
-	libinput_dispatch(li);
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
-	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
-			 LIBINPUT_TABLET_TOOL_TIP_UP);
-	libinput_event_destroy(event);
-
 	litest_assert_empty_queue(li);
 }
 END_TEST
@@ -303,10 +283,6 @@ START_TEST(tip_down_btn_change)
 	litest_pop_event_frame(dev);
 
 	libinput_dispatch(li);
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
-	libinput_event_destroy(event);
 
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
@@ -345,10 +321,6 @@ START_TEST(tip_down_btn_change)
 	litest_pop_event_frame(dev);
 
 	libinput_dispatch(li);
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
-	libinput_event_destroy(event);
 
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
@@ -384,9 +356,18 @@ START_TEST(tip_down_motion)
 	};
 	double x, y, last_x, last_y;
 
-	litest_tablet_proximity_in(dev, 10, 10, axes);
 	litest_drain_events(li);
 
+	litest_tablet_proximity_in(dev, 10, 10, axes);
+	libinput_dispatch(li);
+	event = libinput_get_event(li);
+	tablet_event = litest_is_tablet_event(event,
+					      LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+	last_x = libinput_event_tablet_tool_get_x(tablet_event);
+	last_y = libinput_event_tablet_tool_get_y(tablet_event);
+	libinput_event_destroy(event);
+
+	/* move x/y on tip down, make sure x/y changed */
 	litest_axis_set_value(axes, ABS_DISTANCE, 0);
 	litest_axis_set_value(axes, ABS_PRESSURE, 20);
 	litest_push_event_frame(dev);
@@ -398,21 +379,15 @@ START_TEST(tip_down_motion)
 	libinput_dispatch(li);
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
-	last_x = libinput_event_tablet_tool_get_x(tablet_event);
-	last_y = libinput_event_tablet_tool_get_y(tablet_event);
-	libinput_event_destroy(event);
-
-	libinput_dispatch(li);
-	event = libinput_get_event(li);
-	tablet_event = litest_is_tablet_event(event,
 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
 			 LIBINPUT_TABLET_TOOL_TIP_DOWN);
+	ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
+	ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
 	x = libinput_event_tablet_tool_get_x(tablet_event);
 	y = libinput_event_tablet_tool_get_y(tablet_event);
-	ck_assert_double_eq(last_x, x);
-	ck_assert_double_eq(last_y, y);
+	ck_assert_double_lt(last_x, x);
+	ck_assert_double_lt(last_y, y);
 	libinput_event_destroy(event);
 
 	litest_assert_empty_queue(li);
@@ -427,44 +402,48 @@ START_TEST(tip_up_motion)
 	struct libinput_event_tablet_tool *tablet_event;
 	struct axis_replacement axes[] = {
 		{ ABS_DISTANCE, 0 },
-		{ ABS_PRESSURE, 20 },
+		{ ABS_PRESSURE, 0 },
 		{ -1, -1 }
 	};
 	double x, y, last_x, last_y;
 
-	litest_push_event_frame(dev);
 	litest_tablet_proximity_in(dev, 10, 10, axes);
-	litest_tablet_motion(dev, 70, 70, axes);
-	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
-	litest_event(dev, EV_SYN, SYN_REPORT, 0);
-	litest_pop_event_frame(dev);
 	litest_drain_events(li);
 
-	litest_axis_set_value(axes, ABS_PRESSURE, 0);
+	litest_axis_set_value(axes, ABS_PRESSURE, 20);
 	litest_push_event_frame(dev);
 	litest_tablet_motion(dev, 70, 70, axes);
-	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
+	litest_event(dev, EV_KEY, BTN_TOUCH, 1);
 	litest_event(dev, EV_SYN, SYN_REPORT, 0);
 	litest_pop_event_frame(dev);
 
 	libinput_dispatch(li);
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
-					      LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
 	last_x = libinput_event_tablet_tool_get_x(tablet_event);
 	last_y = libinput_event_tablet_tool_get_y(tablet_event);
 	libinput_event_destroy(event);
 
+	/* move x/y on tip up, make sure x/y changed */
+	litest_axis_set_value(axes, ABS_PRESSURE, 0);
+	litest_push_event_frame(dev);
+	litest_tablet_motion(dev, 40, 40, axes);
+	litest_event(dev, EV_KEY, BTN_TOUCH, 0);
+	litest_pop_event_frame(dev);
+
 	libinput_dispatch(li);
 	event = libinput_get_event(li);
 	tablet_event = litest_is_tablet_event(event,
 					      LIBINPUT_EVENT_TABLET_TOOL_TIP);
 	ck_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tablet_event),
 			 LIBINPUT_TABLET_TOOL_TIP_UP);
+	ck_assert(libinput_event_tablet_tool_x_has_changed(tablet_event));
+	ck_assert(libinput_event_tablet_tool_y_has_changed(tablet_event));
 	x = libinput_event_tablet_tool_get_x(tablet_event);
 	y = libinput_event_tablet_tool_get_y(tablet_event);
-	ck_assert_double_eq(last_x, x);
-	ck_assert_double_eq(last_y, y);
+	ck_assert_double_ne(last_x, x);
+	ck_assert_double_ne(last_y, y);
 	libinput_event_destroy(event);
 
 	litest_assert_empty_queue(li);
@@ -2841,7 +2820,7 @@ START_TEST(tablet_pressure_offset_decrease)
 
 	event = libinput_get_event(li);
 	tev = litest_is_tablet_event(event,
-				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
 
 	pressure = libinput_event_tablet_tool_get_pressure(tev);
 
@@ -2905,7 +2884,7 @@ START_TEST(tablet_pressure_offset_increase)
 
 	event = libinput_get_event(li);
 	tev = litest_is_tablet_event(event,
-				     LIBINPUT_EVENT_TABLET_TOOL_AXIS);
+				     LIBINPUT_EVENT_TABLET_TOOL_TIP);
 
 	pressure = libinput_event_tablet_tool_get_pressure(tev);
 
-- 
2.5.0



More information about the wayland-devel mailing list