[RFC PATCH weston 1/2] Support axis source events

Peter Hutterer peter.hutterer at who-t.net
Sun Mar 8 20:28:05 PDT 2015


Extend notify_axis to take source, step_distance and flags and pass them down
to the client. We don't do much there with it other than using it to print
"stop" in the event demo when the last event comes in.
---
 clients/cliptest.c       |  5 ++++-
 clients/eventdemo.c      | 38 ++++++++++++++++++++++++++++++++----
 clients/image.c          |  5 ++++-
 clients/terminal.c       |  2 ++
 clients/window.c         | 20 +++++++++++++++++++
 clients/window.h         |  2 ++
 src/compositor-wayland.c |  6 +++++-
 src/compositor-x11.c     | 16 ++++++++++++++--
 src/compositor.h         |  3 ++-
 src/input.c              | 17 +++++++++++-----
 src/libinput-device.c    | 50 ++++++++++++++++++++++++++++++++++++------------
 11 files changed, 137 insertions(+), 27 deletions(-)

diff --git a/clients/cliptest.c b/clients/cliptest.c
index f8e5dd1..5303e5d 100644
--- a/clients/cliptest.c
+++ b/clients/cliptest.c
@@ -410,7 +410,10 @@ button_handler(struct widget *widget, struct input *input,
 
 static void
 axis_handler(struct widget *widget, struct input *input, uint32_t time,
-	     uint32_t axis, wl_fixed_t value, void *data)
+	     uint32_t axis, wl_fixed_t value,
+	     enum wl_pointer_axis_source source,
+	     enum wl_pointer_axis_source_flags flags,
+	     void *data)
 {
 	struct cliptest *cliptest = data;
 	struct geometry *geom = &cliptest->geometry;
diff --git a/clients/eventdemo.c b/clients/eventdemo.c
index 50a9cb4..57aa716 100644
--- a/clients/eventdemo.c
+++ b/clients/eventdemo.c
@@ -244,17 +244,47 @@ button_handler(struct widget *widget, struct input *input, uint32_t time,
  * \param data user data associated to the widget
  */
 static void
-axis_handler(struct widget *widget, struct input *input, uint32_t time,
-	     uint32_t axis, wl_fixed_t value, void *data)
+axis_handler(struct widget *widget,
+	     struct input *input, uint32_t time,
+	     uint32_t axis,
+	     wl_fixed_t value,
+	     enum wl_pointer_axis_source source,
+	     enum wl_pointer_axis_source_flags flags,
+	     void *data)
 {
+	const char *axis_source;
+	const char *stop_scroll;
+
 	if (!log_axis)
 		return;
 
-	printf("axis time: %d, axis: %s, value: %f\n",
+	switch (source) {
+	case WL_POINTER_AXIS_SOURCE_UNKNOWN:
+		axis_source = "unknown";
+		break;
+	case WL_POINTER_AXIS_SOURCE_WHEEL:
+		axis_source = "wheel";
+		break;
+	case WL_POINTER_AXIS_SOURCE_FINGER:
+		axis_source = "finger";
+		break;
+	case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
+		axis_source = "continuous";
+		break;
+	}
+
+	if (flags & WL_POINTER_AXIS_SOURCE_FLAGS_STOP_SCROLL)
+		stop_scroll = " stop";
+	else
+		stop_scroll = "";
+
+	printf("axis time: %d, axis: %s (%s), value: %f%s\n",
 	       time,
 	       axis == WL_POINTER_AXIS_VERTICAL_SCROLL ? "vertical" :
 							 "horizontal",
-	       wl_fixed_to_double(value));
+	       axis_source,
+	       wl_fixed_to_double(value),
+	       stop_scroll);
 }
 
 /**
diff --git a/clients/image.c b/clients/image.c
index aee8112..1797dad 100644
--- a/clients/image.c
+++ b/clients/image.c
@@ -310,7 +310,10 @@ key_handler(struct window *window, struct input *input, uint32_t time,
 
 static void
 axis_handler(struct widget *widget, struct input *input, uint32_t time,
-	     uint32_t axis, wl_fixed_t value, void *data)
+	     uint32_t axis, wl_fixed_t value,
+	     enum wl_pointer_axis_source source,
+	     enum wl_pointer_axis_source_flags flags,
+	     void *data)
 {
 	struct image *image = data;
 
diff --git a/clients/terminal.c b/clients/terminal.c
index 7c37101..e556349 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -2795,6 +2795,8 @@ axis_handler(struct widget *widget,
 	     struct input *input, uint32_t time,
 	     uint32_t axis,
 	     wl_fixed_t value,
+	     enum wl_pointer_axis_source source,
+	     enum wl_pointer_axis_source_flags flags,
 	     void *data)
 {
 	struct terminal *terminal = data;
diff --git a/clients/window.c b/clients/window.c
index 1399fa4..e23a6f1 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -355,6 +355,9 @@ struct input {
 	uint32_t repeat_sym;
 	uint32_t repeat_key;
 	uint32_t repeat_time;
+
+	enum wl_pointer_axis_source axis_source;
+	enum wl_pointer_axis_source_flags axis_flags;
 };
 
 struct output {
@@ -2784,15 +2787,32 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
 		(*widget->axis_handler)(widget,
 					input, time,
 					axis, value,
+					input->axis_source,
+					input->axis_flags,
 					widget->user_data);
 }
 
+static void
+pointer_handle_axis_source(void *data, struct wl_pointer *pointer,
+			   uint32_t time, uint32_t axis,
+			   enum wl_pointer_axis_source source,
+			   enum wl_pointer_axis_source_flags flags,
+			   uint32_t step_distance)
+{
+	struct input *input = data;
+
+	input->axis_source = source;
+	input->axis_flags = flags;
+
+}
+
 static const struct wl_pointer_listener pointer_listener = {
 	pointer_handle_enter,
 	pointer_handle_leave,
 	pointer_handle_motion,
 	pointer_handle_button,
 	pointer_handle_axis,
+	pointer_handle_axis_source,
 };
 
 static void
diff --git a/clients/window.h b/clients/window.h
index 5247f19..5e48da7 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -269,6 +269,8 @@ typedef void (*widget_axis_handler_t)(struct widget *widget,
 				      struct input *input, uint32_t time,
 				      uint32_t axis,
 				      wl_fixed_t value,
+				      enum wl_pointer_axis_source source,
+				      enum wl_pointer_axis_source_flags flags,
 				      void *data);
 
 struct window *
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 04a2331..45fc411 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -1394,7 +1394,11 @@ input_handle_axis(void *data, struct wl_pointer *pointer,
 {
 	struct wayland_input *input = data;
 
-	notify_axis(&input->base, time, axis, value);
+	/* FIXME: */
+	notify_axis(&input->base, time, axis, value,
+		    WL_POINTER_AXIS_SOURCE_UNKNOWN,
+		    WL_POINTER_AXIS_SOURCE_FLAGS_NONE,
+		    0);
 }
 
 static const struct wl_pointer_listener pointer_listener = {
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index aa1e519..3f8fbb7 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -1046,13 +1046,19 @@ x11_compositor_deliver_button_event(struct x11_compositor *c,
 			notify_axis(&c->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_VERTICAL_SCROLL,
-				    -DEFAULT_AXIS_STEP_DISTANCE);
+				    -DEFAULT_AXIS_STEP_DISTANCE,
+				    WL_POINTER_AXIS_SOURCE_WHEEL,
+				    WL_POINTER_AXIS_SOURCE_FLAGS_NONE,
+				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 5:
 		if (state)
 			notify_axis(&c->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_VERTICAL_SCROLL,
+				    DEFAULT_AXIS_STEP_DISTANCE,
+				    WL_POINTER_AXIS_SOURCE_WHEEL,
+				    WL_POINTER_AXIS_SOURCE_FLAGS_NONE,
 				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 6:
@@ -1060,13 +1066,19 @@ x11_compositor_deliver_button_event(struct x11_compositor *c,
 			notify_axis(&c->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
-				    -DEFAULT_AXIS_STEP_DISTANCE);
+				    -DEFAULT_AXIS_STEP_DISTANCE,
+				    WL_POINTER_AXIS_SOURCE_WHEEL,
+				    WL_POINTER_AXIS_SOURCE_FLAGS_NONE,
+				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	case 7:
 		if (state)
 			notify_axis(&c->core_seat,
 				    weston_compositor_get_time(),
 				    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
+				    DEFAULT_AXIS_STEP_DISTANCE,
+				    WL_POINTER_AXIS_SOURCE_WHEEL,
+				    WL_POINTER_AXIS_SOURCE_FLAGS_NONE,
 				    DEFAULT_AXIS_STEP_DISTANCE);
 		return;
 	default:
diff --git a/src/compositor.h b/src/compositor.h
index f4ba7a5..a43aa0b 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1050,7 +1050,8 @@ notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
 	      enum wl_pointer_button_state state);
 void
 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
-	    wl_fixed_t value);
+	    wl_fixed_t value, uint32_t source, uint32_t flags,
+	    uint32_t step_distance);
 void
 notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
 	   enum wl_keyboard_key_state state,
diff --git a/src/input.c b/src/input.c
index 3867de2..b1c4962 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1042,7 +1042,8 @@ notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
 
 WL_EXPORT void
 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
-	    wl_fixed_t value)
+	    wl_fixed_t value, uint32_t source, uint32_t flags,
+	    uint32_t step_distance)
 {
 	struct weston_compositor *compositor = seat->compositor;
 	struct weston_pointer *pointer = seat->pointer;
@@ -1051,17 +1052,23 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
 
 	weston_compositor_wake(compositor);
 
-	if (!value)
-		return;
-
 	if (weston_compositor_run_axis_binding(compositor, seat,
 						   time, axis, value))
 		return;
 
 	resource_list = &pointer->focus_resource_list;
-	wl_resource_for_each(resource, resource_list)
+	wl_resource_for_each(resource, resource_list) {
+		if (wl_resource_get_version(resource) >=
+		    WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
+			wl_pointer_send_axis_source(resource, time, axis,
+						    source, flags,
+						    step_distance);
+		} else if (!value)
+			continue;
+
 		wl_pointer_send_axis(resource, time, axis,
 				     value);
+	}
 }
 
 WL_EXPORT int
diff --git a/src/libinput-device.c b/src/libinput-device.c
index 567e5ea..6fd5132 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -148,15 +148,31 @@ handle_pointer_button(struct libinput_device *libinput_device,
 		      libinput_event_pointer_get_button_state(pointer_event));
 }
 
-static double
+static uint32_t
+scroll_source_get_flags(struct libinput_event_pointer *pointer_event,
+			enum libinput_pointer_axis axis)
+{
+	if (libinput_event_pointer_has_axis(pointer_event, axis) &&
+	    libinput_event_pointer_get_axis_value(pointer_event,
+						  axis) == 0.0)
+		return WL_POINTER_AXIS_SOURCE_FLAGS_STOP_SCROLL;
+	else
+		return WL_POINTER_AXIS_SOURCE_FLAGS_NONE;
+}
+
+static bool
 normalize_scroll(struct libinput_event_pointer *pointer_event,
-		 enum libinput_pointer_axis axis)
+		 enum libinput_pointer_axis axis,
+		 double *value, uint32_t *step_distance)
 {
 	static int warned;
 	enum libinput_pointer_axis_source source;
-	double value;
+	double axis_val;
 
 	source = libinput_event_pointer_get_axis_source(pointer_event);
+	axis_val = libinput_event_pointer_get_axis_value(pointer_event,
+							 axis);
+
 	/* libinput < 0.8 sent wheel click events with value 10. Since 0.8
 	   the value is the angle of the click in degrees. To keep
 	   backwards-compat with existing clients, we just send multiples of
@@ -164,17 +180,19 @@ normalize_scroll(struct libinput_event_pointer *pointer_event,
 	 */
 	switch (source) {
 	case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
-		value = 10 * libinput_event_pointer_get_axis_value_discrete(
+		*value = 10 * libinput_event_pointer_get_axis_value_discrete(
 								   pointer_event,
 								   axis);
+		*step_distance = 10;
 		break;
 	case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
 	case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
-		value = libinput_event_pointer_get_axis_value(pointer_event,
-							      axis);
+		*value = axis_val;
+		*step_distance = 0;
 		break;
 	default:
-		value = 0;
+		*value = 0;
+		*step_distance = 0;
 		if (warned < 5) {
 			weston_log("Unknown scroll source %d. Event discarded\n",
 				   source);
@@ -183,7 +201,7 @@ normalize_scroll(struct libinput_event_pointer *pointer_event,
 		break;
 	}
 
-	return value;
+	return axis_val == 0.0;
 }
 
 static void
@@ -193,24 +211,32 @@ handle_pointer_axis(struct libinput_device *libinput_device,
 	struct evdev_device *device =
 		libinput_device_get_user_data(libinput_device);
 	double value;
+	uint32_t step_distance;
 	enum libinput_pointer_axis axis;
+	enum libinput_pointer_axis_source source;
+	uint32_t flags;
 
+	source = libinput_event_pointer_get_axis_source(pointer_event);
 	axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
 	if (libinput_event_pointer_has_axis(pointer_event, axis)) {
-		value = normalize_scroll(pointer_event, axis);
+		normalize_scroll(pointer_event, axis, &value, &step_distance);
+		flags = scroll_source_get_flags(pointer_event, axis);
 		notify_axis(device->seat,
 			    libinput_event_pointer_get_time(pointer_event),
 			    WL_POINTER_AXIS_VERTICAL_SCROLL,
-			    wl_fixed_from_double(value));
+			    wl_fixed_from_double(value),
+			    source, flags, step_distance);
 	}
 
 	axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
 	if (libinput_event_pointer_has_axis(pointer_event, axis)) {
-		value = normalize_scroll(pointer_event, axis);
+		normalize_scroll(pointer_event, axis, &value, &step_distance);
+		flags = scroll_source_get_flags(pointer_event, axis);
 		notify_axis(device->seat,
 			    libinput_event_pointer_get_time(pointer_event),
 			    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
-			    wl_fixed_from_double(value));
+			    wl_fixed_from_double(value),
+			    source, flags, step_distance);
 	}
 }
 
-- 
2.1.0



More information about the wayland-devel mailing list