[PATCH weston 5/6] libweston: Implement pointer timestamps for input_timestamps_unstable_v1

Alexandros Frantzis alexandros.frantzis at collabora.com
Wed Dec 20 14:18:00 UTC 2017


Implement the zwp_input_timestamps_v1.get_pointer_timestamps request to
subscribe to timestamp events for wl_pointer resources.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
 libweston/compositor.h |  2 ++
 libweston/input.c      | 50 +++++++++++++++++++++++++++++++++-----
 tests/pointer-test.c   | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/libweston/compositor.h b/libweston/compositor.h
index 85f59d45..7fa88800 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -391,6 +391,8 @@ struct weston_pointer {
 	uint32_t button_count;
 
 	struct wl_listener output_destroy_listener;
+
+	struct wl_list timestamps_list;
 };
 
 
diff --git a/libweston/input.c b/libweston/input.c
index 8a27fc08..9aceccb1 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -205,12 +205,14 @@ unbind_pointer_client_resource(struct wl_resource *resource)
 {
 	struct weston_pointer *pointer = wl_resource_get_user_data(resource);
 	struct wl_client *client = wl_resource_get_client(resource);
+	struct wl_list *timestamps_list = &pointer->timestamps_list;
 	struct weston_pointer_client *pointer_client;
 
 	pointer_client = weston_pointer_get_pointer_client(pointer, client);
 	assert(pointer_client);
 
 	wl_list_remove(wl_resource_get_link(resource));
+	remove_input_resource_from_timestamps(resource, timestamps_list);
 	weston_pointer_cleanup_pointer_client(pointer, pointer_client);
 }
 
@@ -407,6 +409,9 @@ pointer_send_relative_motion(struct weston_pointer *pointer,
 	dyf_unaccel = wl_fixed_from_double(dy_unaccel);
 
 	wl_resource_for_each(resource, resource_list) {
+		send_timestamps_for_input_resource(resource,
+                                                   &pointer->timestamps_list,
+                                                   time);
 		zwp_relative_pointer_v1_send_relative_motion(
 			resource,
 			(uint32_t) (time_usec >> 32),
@@ -430,8 +435,12 @@ pointer_send_motion(struct weston_pointer *pointer,
 
 	resource_list = &pointer->focus_client->pointer_resources;
 	msecs = timespec_to_msec(time);
-	wl_resource_for_each(resource, resource_list)
+	wl_resource_for_each(resource, resource_list) {
+		send_timestamps_for_input_resource(resource,
+                                                   &pointer->timestamps_list,
+                                                   time);
 		wl_pointer_send_motion(resource, msecs, sx, sy);
+	}
 }
 
 WL_EXPORT void
@@ -512,8 +521,12 @@ weston_pointer_send_button(struct weston_pointer *pointer,
 	resource_list = &pointer->focus_client->pointer_resources;
 	serial = wl_display_next_serial(display);
 	msecs = timespec_to_msec(time);
-	wl_resource_for_each(resource, resource_list)
+	wl_resource_for_each(resource, resource_list) {
+		send_timestamps_for_input_resource(resource,
+                                                   &pointer->timestamps_list,
+                                                   time);
 		wl_pointer_send_button(resource, serial, msecs, button, state);
+	}
 }
 
 static void
@@ -570,14 +583,21 @@ weston_pointer_send_axis(struct weston_pointer *pointer,
 			wl_pointer_send_axis_discrete(resource, event->axis,
 						      event->discrete);
 
-		if (event->value)
+		if (event->value) {
+			send_timestamps_for_input_resource(resource,
+							   &pointer->timestamps_list,
+							   time);
 			wl_pointer_send_axis(resource, msecs,
 					     event->axis,
 					     wl_fixed_from_double(event->value));
-		else if (wl_resource_get_version(resource) >=
-			 WL_POINTER_AXIS_STOP_SINCE_VERSION)
+		} else if (wl_resource_get_version(resource) >=
+			 WL_POINTER_AXIS_STOP_SINCE_VERSION) {
+			send_timestamps_for_input_resource(resource,
+							   &pointer->timestamps_list,
+							   time);
 			wl_pointer_send_axis_stop(resource, msecs,
 						  event->axis);
+		}
 	}
 }
 
@@ -1112,6 +1132,7 @@ weston_pointer_create(struct weston_seat *seat)
 	wl_signal_init(&pointer->focus_signal);
 	wl_list_init(&pointer->focus_view_listener.link);
 	wl_signal_init(&pointer->destroy_signal);
+	wl_list_init(&pointer->timestamps_list);
 
 	pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
 
@@ -4596,7 +4617,24 @@ input_timestamps_manager_get_pointer_timestamps(struct wl_client *client,
 						uint32_t id,
 						struct wl_resource *pointer_resource)
 {
-	wl_client_post_no_memory(client);
+	struct weston_pointer *pointer = wl_resource_get_user_data(pointer_resource);
+	struct wl_resource *input_ts;
+
+	input_ts = wl_resource_create(client,
+				      &zwp_input_timestamps_v1_interface,
+				      1, id);
+	if (!input_ts) {
+		wl_client_post_no_memory(client);
+		return;
+	}
+
+	wl_resource_set_implementation(input_ts,
+				       &input_timestamps_interface,
+				       pointer_resource,
+				       unbind_resource);
+
+	wl_list_insert(&pointer->timestamps_list,
+		       wl_resource_get_link(input_ts));
 }
 
 static void
diff --git a/tests/pointer-test.c b/tests/pointer-test.c
index 4c438a22..58c862f4 100644
--- a/tests/pointer-test.c
+++ b/tests/pointer-test.c
@@ -28,6 +28,7 @@
 
 #include <linux/input.h>
 
+#include "input-timestamps-helper.h"
 #include "shared/timespec-util.h"
 #include "weston-test-client-helper.h"
 
@@ -341,11 +342,16 @@ TEST(pointer_motion_events)
 	struct client *client = create_client_with_pointer_focus(100, 100,
 								 100, 100);
 	struct pointer *pointer = client->input->pointer;
+	struct input_timestamps *input_ts =
+		input_timestamps_create_for_pointer(client);
 
 	send_motion(client, &t1, 150, 150);
 	assert(pointer->x == 50);
 	assert(pointer->y == 50);
 	assert(pointer->motion_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->motion_time_timespec, &t1));
+
+	input_timestamps_destroy(input_ts);
 }
 
 TEST(pointer_button_events)
@@ -353,6 +359,8 @@ TEST(pointer_button_events)
 	struct client *client = create_client_with_pointer_focus(100, 100,
 								 100, 100);
 	struct pointer *pointer = client->input->pointer;
+	struct input_timestamps *input_ts =
+		input_timestamps_create_for_pointer(client);
 
 	assert(pointer->button == 0);
 	assert(pointer->state == 0);
@@ -361,11 +369,15 @@ TEST(pointer_button_events)
 	assert(pointer->button == BTN_LEFT);
 	assert(pointer->state == WL_POINTER_BUTTON_STATE_PRESSED);
 	assert(pointer->button_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->button_time_timespec, &t1));
 
 	send_button(client, &t2, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
 	assert(pointer->button == BTN_LEFT);
 	assert(pointer->state == WL_POINTER_BUTTON_STATE_RELEASED);
 	assert(pointer->button_time_msec == timespec_to_msec(&t2));
+	assert(timespec_eq(&pointer->button_time_timespec, &t2));
+
+	input_timestamps_destroy(input_ts);
 }
 
 TEST(pointer_axis_events)
@@ -373,13 +385,67 @@ TEST(pointer_axis_events)
 	struct client *client = create_client_with_pointer_focus(100, 100,
 								 100, 100);
 	struct pointer *pointer = client->input->pointer;
+	struct input_timestamps *input_ts =
+		input_timestamps_create_for_pointer(client);
 
 	send_axis(client, &t1, 1, 1.0);
 	assert(pointer->axis == 1);
 	assert(pointer->axis_value == 1.0);
 	assert(pointer->axis_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->axis_time_timespec, &t1));
 
 	send_axis(client, &t2, 2, 0.0);
 	assert(pointer->axis == 2);
 	assert(pointer->axis_stop_time_msec == timespec_to_msec(&t2));
+	assert(timespec_eq(&pointer->axis_stop_time_timespec, &t2));
+
+	input_timestamps_destroy(input_ts);
+}
+
+TEST(pointer_timestamps_stop_after_input_timestamps_object_is_destroyed)
+{
+	struct client *client = create_client_with_pointer_focus(100, 100,
+								 100, 100);
+	struct pointer *pointer = client->input->pointer;
+	struct input_timestamps *input_ts =
+		input_timestamps_create_for_pointer(client);
+
+	send_button(client, &t1, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
+	assert(pointer->button == BTN_LEFT);
+	assert(pointer->state == WL_POINTER_BUTTON_STATE_PRESSED);
+	assert(pointer->button_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->button_time_timespec, &t1));
+
+	input_timestamps_destroy(input_ts);
+
+	send_button(client, &t2, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
+	assert(pointer->button == BTN_LEFT);
+	assert(pointer->state == WL_POINTER_BUTTON_STATE_RELEASED);
+	assert(pointer->button_time_msec == timespec_to_msec(&t2));
+	assert(timespec_is_zero(&pointer->button_time_timespec));
+}
+
+TEST(pointer_timestamps_stop_after_client_releases_wl_pointer)
+{
+	struct client *client = create_client_with_pointer_focus(100, 100,
+								 100, 100);
+	struct pointer *pointer = client->input->pointer;
+	struct input_timestamps *input_ts =
+		input_timestamps_create_for_pointer(client);
+
+	send_motion(client, &t1, 150, 150);
+	assert(pointer->x == 50);
+	assert(pointer->y == 50);
+	assert(pointer->motion_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->motion_time_timespec, &t1));
+
+	wl_pointer_release(client->input->pointer->wl_pointer);
+
+	send_motion(client, &t2, 175, 175);
+	assert(pointer->x == 50);
+	assert(pointer->y == 50);
+	assert(pointer->motion_time_msec == timespec_to_msec(&t1));
+	assert(timespec_eq(&pointer->motion_time_timespec, &t1));
+
+	input_timestamps_destroy(input_ts);
 }
-- 
2.14.1



More information about the wayland-devel mailing list