[PATCH libinput 2/2] Add libinput_event_pointer_has_axis to scroll events

Peter Hutterer peter.hutterer at who-t.net
Sun Jan 4 21:20:03 PST 2015


Right now we only have two (scroll) axes and we could easily just check both
for non-zero values. If we want to allow further axes in the future, we need
a check whether an axis is set in an event.

We also need the mask to notify of a scroll stop event, which could otherwise
be confused as a vertical-only or horizontal-only event.

Note: intentionally done as a separate patch to the previous one to aid review
and debugging.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad-edge-scroll.c |  3 +++
 src/evdev.c                         | 17 +++++++++++++++--
 src/libinput-private.h              |  1 +
 src/libinput-util.h                 |  1 +
 src/libinput.c                      | 16 ++++++++++++++++
 src/libinput.h                      | 17 +++++++++++++++++
 6 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index b82c966..8dfa97e 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -325,6 +325,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
 				if (t->scroll.direction != -1) {
 					/* Send stop scroll event */
 					pointer_notify_axis(device, time,
+						t->scroll.direction,
 						LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
 						0.0, 0.0);
 					t->scroll.direction = -1;
@@ -352,6 +353,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
 			continue;
 
 		pointer_notify_axis(device, time,
+				    AS_MASK(axis),
 				    LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
 				    dx, dy);
 		t->scroll.direction = axis;
@@ -371,6 +373,7 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
 	tp_for_each_touch(tp, t) {
 		if (t->scroll.direction != -1) {
 			pointer_notify_axis(device, time,
+					    t->scroll.direction,
 					    LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
 					    0.0, 0.0);
 			t->scroll.direction = -1;
diff --git a/src/evdev.c b/src/evdev.c
index 5d22af2..7597afc 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -539,6 +539,7 @@ evdev_process_absolute_motion(struct evdev_device *device,
 static void
 evdev_notify_axis(struct evdev_device *device,
 		  uint64_t time,
+		  uint32_t axes,
 		  enum libinput_pointer_axis_source source,
 		  double x, double y)
 {
@@ -549,6 +550,7 @@ evdev_notify_axis(struct evdev_device *device,
 
 	pointer_notify_axis(&device->base,
 			    time,
+			    axes,
 			    source,
 			    x, y);
 }
@@ -575,6 +577,7 @@ evdev_process_relative(struct evdev_device *device,
 		evdev_notify_axis(
 			device,
 			time,
+			AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
 			LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
 			0,
 			-1 * e->value * DEFAULT_AXIS_STEP_DISTANCE);
@@ -584,6 +587,7 @@ evdev_process_relative(struct evdev_device *device,
 		evdev_notify_axis(
 			device,
 			time,
+			AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
 			LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
 			e->value * DEFAULT_AXIS_STEP_DISTANCE,
 			0);
@@ -1792,6 +1796,7 @@ evdev_post_scroll(struct evdev_device *device,
 		  double dy)
 {
 	double trigger_horiz, trigger_vert;
+	uint32_t axes;
 
 	if (!evdev_is_scrolling(device,
 				LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
@@ -1829,19 +1834,26 @@ evdev_post_scroll(struct evdev_device *device,
 				      LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
 	}
 
+	axes = device->scroll.direction;
+
 	/* We use the trigger to enable, but the delta from this event for
 	 * the actual scroll movement. Otherwise we get a jump once
 	 * scrolling engages */
 	if (!evdev_is_scrolling(device,
-			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
+			       LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
 		dy = 0.0;
+		axes &= ~AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+	}
 	if (!evdev_is_scrolling(device,
-			       LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
+			       LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
 		dx = 0.0;
+		axes &= ~AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+	}
 
 	if (dx != 0.0 || dy != 0.0)
 		evdev_notify_axis(device,
 				  time,
+				  axes,
 				  source,
 				  dx,
 				  dy);
@@ -1856,6 +1868,7 @@ evdev_stop_scroll(struct evdev_device *device,
 	if (device->scroll.direction != 0)
 		pointer_notify_axis(&device->base,
 				    time,
+				    device->scroll.direction,
 				    source,
 				    0.0, 0.0);
 
diff --git a/src/libinput-private.h b/src/libinput-private.h
index 5ffab40..0cb9b25 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -278,6 +278,7 @@ pointer_notify_button(struct libinput_device *device,
 void
 pointer_notify_axis(struct libinput_device *device,
 		    uint64_t time,
+		    uint32_t axes,
 		    enum libinput_pointer_axis_source source,
 		    double x, double y);
 
diff --git a/src/libinput-util.h b/src/libinput-util.h
index 6825841..0abf6c2 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -79,6 +79,7 @@ int list_empty(const struct list *list);
 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 #define ARRAY_FOR_EACH(_arr, _elem) \
 	for (size_t _i = 0; _i < ARRAY_LENGTH(_arr) && (_elem = &_arr[_i]); _i++)
+#define AS_MASK(v) (1 << (v))
 
 #define min(a, b) (((a) < (b)) ? (a) : (b))
 #define max(a, b) (((a) > (b)) ? (a) : (b))
diff --git a/src/libinput.c b/src/libinput.c
index f43799f..09ff6ee 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -65,6 +65,7 @@ struct libinput_event_pointer {
 	uint32_t seat_button_count;
 	enum libinput_button_state state;
 	enum libinput_pointer_axis_source source;
+	uint32_t axes;
 };
 
 struct libinput_event_touch {
@@ -377,6 +378,19 @@ libinput_event_pointer_get_seat_button_count(
 	return event->seat_button_count;
 }
 
+LIBINPUT_EXPORT int
+libinput_event_pointer_has_axis(struct libinput_event_pointer *event,
+				enum libinput_pointer_axis axis)
+{
+	if (event->base.type == LIBINPUT_EVENT_POINTER_AXIS) {
+		switch (axis) {
+		case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
+		case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
+			return event->axes & (1 << axis);
+		}
+	}
+	return 0;
+}
 
 LIBINPUT_EXPORT double
 libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event,
@@ -998,6 +1012,7 @@ pointer_notify_button(struct libinput_device *device,
 void
 pointer_notify_axis(struct libinput_device *device,
 		    uint64_t time,
+		    uint32_t axes,
 		    enum libinput_pointer_axis_source source,
 		    double x, double y)
 {
@@ -1012,6 +1027,7 @@ pointer_notify_axis(struct libinput_device *device,
 		.x = x,
 		.y = y,
 		.source = source,
+		.axes = axes,
 	};
 
 	post_device_event(device, time,
diff --git a/src/libinput.h b/src/libinput.h
index 408cdcc..f9f538b 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -650,6 +650,20 @@ uint32_t
 libinput_event_pointer_get_seat_button_count(
 	struct libinput_event_pointer *event);
 
+/**
+ * @ingroup event_pointer
+ *
+ * Check if the event has a valid value for the given axis.
+ *
+ * If this function returns non-zero for an axis and
+ * libinput_event_pointer_get_axis_value() returns a value of 0, the event
+ * is a scroll stop event.
+ *
+ * @return non-zero if this event contains a value for this axis
+ */
+int
+libinput_event_pointer_has_axis(struct libinput_event_pointer *event,
+				enum libinput_pointer_axis axis);
 
 /**
  * @ingroup event_pointer
@@ -662,6 +676,9 @@ libinput_event_pointer_get_seat_button_count(
  * respectively. For the interpretation of the value, see
  * libinput_event_pointer_get_axis_source().
  *
+ * If libinput_event_pointer_has_axis() returns 0 for an axis, this function
+ * returns 0 for that axis.
+ *
  * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS,
  * this function returns 0.
  *
-- 
2.1.0



More information about the wayland-devel mailing list