Implement the zwp_input_timestamps_v1.get_keyboard_timestamps request to
subscribe to timestamp events for wl_keyboard resources.

Signed-off-by: Alexandros Frantzis <[email protected]>
---
 libweston/compositor.h |  2 ++
 libweston/input.c      | 38 +++++++++++++++++++++++++++++++++++---
 tests/keyboard-test.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/libweston/compositor.h b/libweston/compositor.h
index dffcba89..85f59d45 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -605,6 +605,8 @@ struct weston_keyboard {
                enum weston_led leds;
        } xkb_state;
        struct xkb_keymap *pending_keymap;
+
+       struct wl_list timestamps_list;
 };
 
 struct weston_seat {
diff --git a/libweston/input.c b/libweston/input.c
index a682fa94..8a27fc08 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -904,8 +904,12 @@ weston_keyboard_send_key(struct weston_keyboard *keyboard,
        resource_list = &keyboard->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,
+                                                  &keyboard->timestamps_list,
+                                                  time);
                wl_keyboard_send_key(resource, serial, msecs, key, state);
+       }
 };
 
 static void
@@ -1171,6 +1175,7 @@ weston_keyboard_create(void)
        keyboard->default_grab.keyboard = keyboard;
        keyboard->grab = &keyboard->default_grab;
        wl_signal_init(&keyboard->focus_signal);
+       wl_list_init(&keyboard->timestamps_list);
 
        return keyboard;
 }
@@ -2453,6 +2458,16 @@ seat_get_pointer(struct wl_client *client, struct 
wl_resource *resource,
        }
 }
 
+static void
+destroy_keyboard_resource(struct wl_resource *resource)
+{
+       struct weston_seat *seat = wl_resource_get_user_data(resource);
+       struct wl_list *timestamps_list = 
&seat->keyboard_state->timestamps_list;
+
+       wl_list_remove(wl_resource_get_link(resource));
+       remove_input_resource_from_timestamps(resource, timestamps_list);
+}
+
 static void
 keyboard_release(struct wl_client *client, struct wl_resource *resource)
 {
@@ -2516,7 +2531,7 @@ seat_get_keyboard(struct wl_client *client, struct 
wl_resource *resource,
         * focused */
        wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
        wl_resource_set_implementation(cr, &keyboard_interface,
-                                      seat, unbind_resource);
+                                      seat, destroy_keyboard_resource);
 
        if (wl_resource_get_version(cr) >= 
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
                wl_keyboard_send_repeat_info(cr,
@@ -4555,7 +4570,24 @@ input_timestamps_manager_get_keyboard_timestamps(struct 
wl_client *client,
                                                 uint32_t id,
                                                 struct wl_resource 
*keyboard_resource)
 {
-       wl_client_post_no_memory(client);
+       struct weston_seat *seat = wl_resource_get_user_data(keyboard_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,
+                                      keyboard_resource,
+                                      unbind_resource);
+
+       wl_list_insert(&seat->keyboard_state->timestamps_list,
+                      wl_resource_get_link(input_ts));
 }
 
 static void
diff --git a/tests/keyboard-test.c b/tests/keyboard-test.c
index 722bfd32..daad8e81 100644
--- a/tests/keyboard-test.c
+++ b/tests/keyboard-test.c
@@ -27,6 +27,7 @@
 
 #include <stdint.h>
 
+#include "input-timestamps-helper.h"
 #include "shared/timespec-util.h"
 #include "weston-test-client-helper.h"
 
@@ -97,10 +98,54 @@ TEST(keyboard_key_event_time)
 {
        struct client *client = create_client_with_keyboard_focus();
        struct keyboard *keyboard = client->input->keyboard;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_keyboard(client);
 
        send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
        assert(keyboard->key_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&keyboard->key_time_timespec, &t1));
 
        send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
        assert(keyboard->key_time_msec == timespec_to_msec(&t2));
+       assert(timespec_eq(&keyboard->key_time_timespec, &t2));
+
+       input_timestamps_destroy(input_ts);
+}
+
+TEST(keyboard_timestamps_stop_after_input_timestamps_object_is_destroyed)
+{
+       struct client *client = create_client_with_keyboard_focus();
+       struct keyboard *keyboard = client->input->keyboard;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_keyboard(client);
+
+       send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
+       assert(keyboard->key_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&keyboard->key_time_timespec, &t1));
+
+       input_timestamps_destroy(input_ts);
+
+       send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
+       assert(keyboard->key_time_msec == timespec_to_msec(&t2));
+       assert(timespec_is_zero(&keyboard->key_time_timespec));
+}
+
+TEST(keyboard_timestamps_stop_after_client_releases_wl_keyboard)
+{
+       struct client *client = create_client_with_keyboard_focus();
+       struct keyboard *keyboard = client->input->keyboard;
+       struct input_timestamps *input_ts =
+               input_timestamps_create_for_keyboard(client);
+
+       send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
+       assert(keyboard->key_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&keyboard->key_time_timespec, &t1));
+
+       wl_keyboard_release(client->input->keyboard->wl_keyboard);
+
+       send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
+       assert(keyboard->key_time_msec == timespec_to_msec(&t1));
+       assert(timespec_eq(&keyboard->key_time_timespec, &t1));
+
+       input_timestamps_destroy(input_ts);
 }
-- 
2.14.1

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to