[PATCH weston v2 5/6] libweston: Implement pointer timestamps for input_timestamps_unstable_v1
Alexandros Frantzis
alexandros.frantzis at collabora.com
Fri Feb 16 16:44:18 UTC 2018
Implement the zwp_input_timestamps_manager_v1.get_pointer_timestamps
request to subscribe to timestamp events for wl_pointer resources.
Ensure that the request handling code can gracefully handle inert
pointer resources.
Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
Changes in v2:
- Remove the head of timestamps_list in weston_pointer_destroy.
- Gracefully handle inert pointer resources in
input_timestamps_manager_get_pointer_timestamps.
libweston/compositor.h | 2 ++
libweston/input.c | 53 +++++++++++++++++++++++++++++++++++-----
tests/pointer-test.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 6 deletions(-)
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 1566677f..78d2668e 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 8028ec20..632c9c3c 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -226,6 +226,8 @@ unbind_pointer_client_resource(struct wl_resource *resource)
pointer_client = weston_pointer_get_pointer_client(pointer,
client);
assert(pointer_client);
+ remove_input_resource_from_timestamps(resource,
+ &pointer->timestamps_list);
weston_pointer_cleanup_pointer_client(pointer, pointer_client);
}
}
@@ -446,8 +448,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
@@ -528,8 +534,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
@@ -586,14 +596,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);
+ }
}
}
@@ -1128,6 +1145,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;
@@ -1165,6 +1183,7 @@ weston_pointer_destroy(struct weston_pointer *pointer)
wl_list_remove(&pointer->focus_resource_listener.link);
wl_list_remove(&pointer->focus_view_listener.link);
wl_list_remove(&pointer->output_destroy_listener.link);
+ wl_list_remove(&pointer->timestamps_list);
free(pointer);
}
@@ -4681,7 +4700,29 @@ 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;
+ }
+
+ if (pointer) {
+ wl_list_insert(&pointer->timestamps_list,
+ wl_resource_get_link(input_ts));
+ } else {
+ wl_list_init(wl_resource_get_link(input_ts));
+ }
+
+ wl_resource_set_implementation(input_ts,
+ &input_timestamps_interface,
+ pointer_resource,
+ unbind_resource);
}
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