Implement the zwp_input_timestamps_v1.get_touch_timestamps request to
subscribe to timestamp events for wl_touch resources.

Signed-off-by: Alexandros Frantzis <alexandros.frant...@collabora.com>
---
 libweston/compositor.h |  2 ++
 libweston/input.c      | 53 +++++++++++++++++++++++++++++++++++++++++++-------
 tests/touch-test.c     | 46 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/libweston/compositor.h b/libweston/compositor.h
index 7fa88800..71d5892c 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -415,6 +415,8 @@ struct weston_touch {
        wl_fixed_t grab_x, grab_y;
        uint32_t grab_serial;
        struct timespec grab_time;
+
+       struct wl_list timestamps_list;
 };
 
 void
diff --git a/libweston/input.c b/libweston/input.c
index 9aceccb1..72b53dba 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -745,10 +745,14 @@ weston_touch_send_down(struct weston_touch *touch, const 
struct timespec *time,
        resource_list = &touch->focus_resource_list;
        serial = wl_display_next_serial(display);
        msecs = timespec_to_msec(time);
-       wl_resource_for_each(resource, resource_list)
-                       wl_touch_send_down(resource, serial, msecs,
-                                          touch->focus->surface->resource,
-                                          touch_id, sx, sy);
+       wl_resource_for_each(resource, resource_list) {
+               send_timestamps_for_input_resource(resource,
+                                                  &touch->timestamps_list,
+                                                  time);
+               wl_touch_send_down(resource, serial, msecs,
+                                  touch->focus->surface->resource,
+                                  touch_id, sx, sy);
+       }
 }
 
 static void
@@ -785,8 +789,12 @@ weston_touch_send_up(struct weston_touch *touch, const 
struct timespec *time,
        resource_list = &touch->focus_resource_list;
        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,
+                                                  &touch->timestamps_list,
+                                                  time);
                wl_touch_send_up(resource, serial, msecs, touch_id);
+       }
 }
 
 static void
@@ -826,6 +834,9 @@ weston_touch_send_motion(struct weston_touch *touch,
        resource_list = &touch->focus_resource_list;
        msecs = timespec_to_msec(time);
        wl_resource_for_each(resource, resource_list) {
+               send_timestamps_for_input_resource(resource,
+                                                  &touch->timestamps_list,
+                                                  time);
                wl_touch_send_motion(resource, msecs,
                                     touch_id, sx, sy);
        }
@@ -1244,6 +1255,7 @@ weston_touch_create(void)
        touch->default_grab.touch = touch;
        touch->grab = &touch->default_grab;
        wl_signal_init(&touch->focus_signal);
+       wl_list_init(&touch->timestamps_list);
 
        return touch;
 }
@@ -2591,6 +2603,16 @@ seat_get_keyboard(struct wl_client *client, struct 
wl_resource *resource,
        }
 }
 
+static void
+destroy_touch_resource(struct wl_resource *resource)
+{
+       struct weston_seat *seat = wl_resource_get_user_data(resource);
+       struct wl_list *timestamps_list = &seat->touch_state->timestamps_list;
+
+       wl_list_remove(wl_resource_get_link(resource));
+       remove_input_resource_from_timestamps(resource, timestamps_list);
+}
+
 static void
 touch_release(struct wl_client *client, struct wl_resource *resource)
 {
@@ -2636,7 +2658,7 @@ seat_get_touch(struct wl_client *client, struct 
wl_resource *resource,
                               wl_resource_get_link(cr));
        }
        wl_resource_set_implementation(cr, &touch_interface,
-                                      seat, unbind_resource);
+                                      seat, destroy_touch_resource);
 }
 
 static void
@@ -4643,7 +4665,24 @@ input_timestamps_manager_get_touch_timestamps(struct 
wl_client *client,
                                              uint32_t id,
                                              struct wl_resource 
*touch_resource)
 {
-       wl_client_post_no_memory(client);
+       struct weston_seat *seat = wl_resource_get_user_data(touch_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,
+                                      touch_resource,
+                                      unbind_resource);
+
+       wl_list_insert(&seat->touch_state->timestamps_list,
+                      wl_resource_get_link(input_ts));
 }
 
 static const struct zwp_input_timestamps_manager_v1_interface
diff --git a/tests/touch-test.c b/tests/touch-test.c
index 9635257f..4011585a 100644
--- a/tests/touch-test.c
+++ b/tests/touch-test.c
@@ -27,6 +27,7 @@
 
 #include <time.h>
 
+#include "input-timestamps-helper.h"
 #include "shared/timespec-util.h"
 #include "weston-test-client-helper.h"
 #include "wayland-server-protocol.h"
@@ -59,13 +60,58 @@ TEST(touch_events)
 {
        struct client *client = create_touch_test_client();
        struct touch *touch = client->input->touch;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_touch(client);
 
        send_touch(client, &t1, WL_TOUCH_DOWN);
        assert(touch->down_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&touch->down_time_timespec, &t1));
 
        send_touch(client, &t2, WL_TOUCH_MOTION);
        assert(touch->motion_time_msec == timespec_to_msec(&t2));
+       assert(timespec_eq(&touch->motion_time_timespec, &t2));
 
        send_touch(client, &t3, WL_TOUCH_UP);
        assert(touch->up_time_msec == timespec_to_msec(&t3));
+       assert(timespec_eq(&touch->up_time_timespec, &t3));
+
+       input_timestamps_destroy(input_ts);
+}
+
+TEST(touch_timestamps_stop_after_input_timestamps_object_is_destroyed)
+{
+       struct client *client = create_touch_test_client();
+       struct touch *touch = client->input->touch;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_touch(client);
+
+       send_touch(client, &t1, WL_TOUCH_DOWN);
+       assert(touch->down_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&touch->down_time_timespec, &t1));
+
+       input_timestamps_destroy(input_ts);
+
+       send_touch(client, &t2, WL_TOUCH_UP);
+       assert(touch->up_time_msec == timespec_to_msec(&t2));
+       assert(timespec_is_zero(&touch->up_time_timespec));
+}
+
+TEST(touch_timestamps_stop_after_client_releases_wl_touch)
+{
+       struct client *client = create_touch_test_client();
+       struct touch *touch = client->input->touch;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_touch(client);
+
+       send_touch(client, &t1, WL_TOUCH_DOWN);
+       assert(touch->down_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&touch->down_time_timespec, &t1));
+
+       wl_touch_release(client->input->touch->wl_touch);
+
+       send_touch(client, &t2, WL_TOUCH_UP);
+       assert(touch->up_time_msec == 0);
+       assert(timespec_is_zero(&touch->up_time_timespec));
+
+       input_timestamps_destroy(input_ts);
 }
-- 
2.14.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to