[PATCH libinput 5/7] tablet: add support for relative x/y motion deltas

Peter Hutterer peter.hutterer at who-t.net
Thu Jan 14 16:26:39 PST 2016


Instead of an explicit tablet mode that device must be changed into, let the
caller decide which coordinates are preferred. The tablet mode may be
application-specific and usually depends on the tool as well.

This patch adds an interface to get a motion delta for the x/y axes in
pixel-like coordinates and as raw unaccelerated delta. In the former case,
libinput will provide some magic to convert the tablet data into something
that resembles pixels from a mouse motion. In the latter case, we normalize
to the x resolution so the caller doesn't have to account for uneven
resolutions, but otherwise leave the data untouched.
A caller can either query the x resolution and base the rest on that, or just
guess a magic factor to apply.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 doc/normalization-of-relative-motion.dox |  4 ++
 doc/tablet-support.dox                   | 29 +++++++++++++++
 src/libinput-private.h                   |  2 +
 src/libinput.c                           | 52 ++++++++++++++++++++++++++
 src/libinput.h                           | 63 ++++++++++++++++++++++++++++++++
 src/libinput.sym                         |  4 ++
 6 files changed, 154 insertions(+)

diff --git a/doc/normalization-of-relative-motion.dox b/doc/normalization-of-relative-motion.dox
index 31596a9..478e727 100644
--- a/doc/normalization-of-relative-motion.dox
+++ b/doc/normalization-of-relative-motion.dox
@@ -38,6 +38,10 @@ libinput scales unaccelerated touchpad motion to the resolution of the
 touchpad's x axis, i.e. the unaccelerated value for the y axis is:
      y = (x / resolution_x) * resolution_y
 
+ at section motion_normalization_tablet Normalization of tablet coordinates
+
+See @ref tablet-relative-motion
+
 @section Setting custom DPI settings
 
 Devices usually do not advertise their resolution and libinput relies on
diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
index 7207a47..1bc8733 100644
--- a/doc/tablet-support.dox
+++ b/doc/tablet-support.dox
@@ -52,6 +52,35 @@ 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
 tip is down is device-specific.
 
+ at section tablet-relative-motion Relative motion for tablet tools
+
+libinput calculates the relative motion vector for each event and converts
+it to the same coordinate space that a normal mouse device would use. For
+the caller, this means that the delta coordinates returned by
+libinput_event_tablet_tool_get_dx() and
+libinput_event_tablet_tool_get_dy() can be used identical to the delta
+coordinates from any other pointer event. Any resolution differences between
+the x and y axes are accommodated for, a delta of N/N represents a 45 degree
+diagonal move on the tablet.
+
+The delta coordinates are available for all tablet events, it is up to the
+caller to decide when a tool should be used in relative mode. It is
+recommended that mouse and lens cursor tool default to relative mode and
+all pen-like tools to absolute mode.
+
+If a tool in relative mode must not use pointer acceleration, a caller
+should use the delta coordinates returned by
+libinput_event_tablet_tool_get_dx_unaccelerated() and
+libinput_event_tablet_tool_get_dy_unaccelerated() instead. These
+deltas are in raw device coordinates, it is up to the caller to map the raw
+device units into pixel movements. libinput normalizes the coordinates to
+the resolution of the x axis. Thus, an unaccelerated delta of N/N represents
+a 45 degree diagonal move on the tablet.
+
+Callers that require exact physical distance should use the
+absolute coordinates provided by libinput_event_tablet_tool_get_x() and
+libinput_event_tablet_tool_get_y() and calculate the delta themselves.
+
 @section tablet-axes Special axes on tablet tools
 
 A tablet tool usually provides additional information beyond x/y positional
diff --git a/src/libinput-private.h b/src/libinput-private.h
index ff43d00..1e6ae90 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -71,6 +71,8 @@ struct threshold {
 
 struct tablet_axes {
 	struct device_coords point;
+	struct normalized_coords delta;
+	struct device_float_coords delta_raw;
 	double distance;
 	double pressure;
 	struct normalized_range_coords tilt;
diff --git a/src/libinput.c b/src/libinput.c
index 2f80f03..2b09cff 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -1090,6 +1090,58 @@ libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event)
 }
 
 LIBINPUT_EXPORT double
+libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event)
+{
+	require_event_type(libinput_event_get_context(&event->base),
+			   event->base.type,
+			   0,
+			   LIBINPUT_EVENT_TABLET_TOOL_AXIS,
+			   LIBINPUT_EVENT_TABLET_TOOL_TIP,
+			   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+
+	return event->axes.delta.x;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event)
+{
+	require_event_type(libinput_event_get_context(&event->base),
+			   event->base.type,
+			   0,
+			   LIBINPUT_EVENT_TABLET_TOOL_AXIS,
+			   LIBINPUT_EVENT_TABLET_TOOL_TIP,
+			   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+
+	return event->axes.delta.y;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_tablet_tool_get_dx_unaccelerated(struct libinput_event_tablet_tool *event)
+{
+	require_event_type(libinput_event_get_context(&event->base),
+			   event->base.type,
+			   0,
+			   LIBINPUT_EVENT_TABLET_TOOL_AXIS,
+			   LIBINPUT_EVENT_TABLET_TOOL_TIP,
+			   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+
+	return event->axes.delta_raw.x;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_tablet_tool_get_dy_unaccelerated(struct libinput_event_tablet_tool *event)
+{
+	require_event_type(libinput_event_get_context(&event->base),
+			   event->base.type,
+			   0,
+			   LIBINPUT_EVENT_TABLET_TOOL_AXIS,
+			   LIBINPUT_EVENT_TABLET_TOOL_TIP,
+			   LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+
+	return event->axes.delta_raw.y;
+}
+
+LIBINPUT_EXPORT double
 libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool *event)
 {
 	require_event_type(libinput_event_get_context(&event->base),
diff --git a/src/libinput.h b/src/libinput.h
index 3b90f0b..2e838f6 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1583,6 +1583,69 @@ libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event);
 /**
  * @ingroup event_tablet
  *
+ * Return the delta between the last event and the current event.
+ * If the tool employs pointer acceleration, the delta returned by this
+ * function is the accelerated delta.
+ *
+ * This value is in screen coordinate space, the delta is to be interpreted
+ * like the return value of libinput_event_pointer_get_dx().
+ * See @ref tablet-relative-motion for more details.
+ *
+ * @param event The libinput tablet event
+ * @return The relative x movement since the last event
+ */
+double
+libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event);
+
+/**
+ * Return the unaccelerated delta between the last event and the current
+ * event.
+ *
+ * Relative unaccelerated motion deltas are raw device coordinates in the X
+ * resolution of the device.
+ * See @ref tablet-relative-motion for more details.
+ *
+ * @param event The libinput tablet event
+ * @return The unaccelerated relative x movement since the last event
+ */
+double
+libinput_event_tablet_tool_get_dx_unaccelerated(
+				struct libinput_event_tablet_tool *event);
+
+/**
+ * @ingroup event_tablet
+ *
+ * Return the delta between the last event and the current event.
+ * If the tool employs pointer acceleration, the delta returned by this
+ * function is the accelerated delta.
+ *
+ * This value is in screen coordinate space, the delta is to be interpreted
+ * like the return value of libinput_event_pointer_get_dx().
+ * See @ref tablet-relative-motion for more details.
+ *
+ * @param event The libinput tablet event
+ * @return The relative y movement since the last event
+ */
+double
+libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event);
+
+/**
+ * Return the unaccelerated delta between the last event and the current
+ * event.
+ *
+ * Relative unaccelerated motion deltas are raw device coordinates in the X
+ * resolution of the device.
+ * See @ref tablet-relative-motion for more details.
+ *
+ * @param event The libinput tablet event
+ * @return The unaccelerated relative y movement since the last event
+ */
+double
+libinput_event_tablet_tool_get_dy_unaccelerated(
+				struct libinput_event_tablet_tool *event);
+/**
+ * @ingroup event_tablet
+ *
  * Returns the current pressure being applied on the tool in use, normalized
  * to the range [0, 1].
  *
diff --git a/src/libinput.sym b/src/libinput.sym
index 22a8dd8..0c40b1b 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -194,6 +194,10 @@ LIBINPUT_TABLET_SUPPORT {
 	libinput_event_tablet_tool_tilt_y_has_changed;
 	libinput_event_tablet_tool_wheel_has_changed;
 	libinput_event_tablet_tool_slider_has_changed;
+	libinput_event_tablet_tool_get_dx;
+	libinput_event_tablet_tool_get_dy;
+	libinput_event_tablet_tool_get_dx_unaccelerated;
+	libinput_event_tablet_tool_get_dy_unaccelerated;
 	libinput_event_tablet_tool_get_x;
 	libinput_event_tablet_tool_get_y;
 	libinput_event_tablet_tool_get_pressure;
-- 
2.5.0



More information about the wayland-devel mailing list