From 1914f533b81dbb83852a344a43865635ad82ad88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 2 Mar 2022 11:54:38 +0100 Subject: [PATCH] tests/screen-cast: Add input injection tests to screen cast client This tests that cursor metadata are handled properly, and that the display server handles input events correctly, including ones that are sent too early. Part-of: --- src/tests/screen-cast-client.c | 88 +++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/src/tests/screen-cast-client.c b/src/tests/screen-cast-client.c index 84ce89132..cdf0d7dcf 100644 --- a/src/tests/screen-cast-client.c +++ b/src/tests/screen-cast-client.c @@ -31,6 +31,23 @@ #include "meta-dbus-remote-desktop.h" #include "meta-dbus-screen-cast.h" +#define assert_cursor_position(stream, x, y) \ +{ \ + g_assert_cmpint (stream->cursor_x, ==, (x)); \ + g_assert_cmpint (stream->cursor_y, ==, (y)); \ +} + +#define CURSOR_META_SIZE(width, height) \ + (sizeof(struct spa_meta_cursor) + \ + sizeof(struct spa_meta_bitmap) + width * height * 4) + +enum + { + CURSOR_MODE_HIDDEN = 0, + CURSOR_MODE_EMBEDDED = 1, + CURSOR_MODE_METADATA = 2, + }; + typedef struct _Stream { MetaDBusScreenCastStream *proxy; @@ -43,6 +60,9 @@ typedef struct _Stream int target_width; int target_height; + + int cursor_x; + int cursor_y; } Stream; typedef struct _Session @@ -209,7 +229,7 @@ on_stream_param_changed (void *user_data, Stream *stream = user_data; uint8_t params_buffer[1024]; struct spa_pod_builder pod_builder; - const struct spa_pod *params[2]; + const struct spa_pod *params[3]; if (!format || id != SPA_PARAM_Format) return; @@ -233,10 +253,37 @@ on_stream_param_changed (void *user_data, SPA_PARAM_META_size, SPA_POD_Int (sizeof (struct spa_meta_header)), 0); + params[2] = spa_pod_builder_add_object ( + &pod_builder, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id (SPA_META_Cursor), + SPA_PARAM_META_size, SPA_POD_CHOICE_RANGE_Int (CURSOR_META_SIZE (384, 384), + CURSOR_META_SIZE (1, 1), + CURSOR_META_SIZE (384, 384)), + 0); + pw_stream_update_params (stream->pipewire_stream, params, G_N_ELEMENTS (params)); } +static void +process_buffer_metadata (Stream *stream, + struct spa_buffer *buffer) +{ + struct spa_meta_cursor *spa_meta_cursor; + + spa_meta_cursor = spa_buffer_find_meta_data (buffer, SPA_META_Cursor, + sizeof *spa_meta_cursor); + if (!spa_meta_cursor) + return; + + if (!spa_meta_cursor_is_valid (spa_meta_cursor)) + return; + + stream->cursor_x = spa_meta_cursor->position.x; + stream->cursor_y = spa_meta_cursor->position.y; +} + static void sanity_check_memfd (struct spa_buffer *buffer) { @@ -265,6 +312,8 @@ static void process_buffer (Stream *stream, struct spa_buffer *buffer) { + process_buffer_metadata (stream, buffer); + if (buffer->datas[0].chunk->size == 0) g_assert_not_reached (); else if (buffer->datas[0].type == SPA_DATA_MemFd) @@ -366,6 +415,16 @@ stream_wait_for_node (Stream *stream) g_main_context_iteration (NULL, TRUE); } +static void +stream_wait_for_cursor_position (Stream *stream, + int x, + int y) +{ + while (stream->cursor_x != x && + stream->cursor_y != y) + g_main_context_iteration (NULL, TRUE); +} + static G_GNUC_UNUSED void stream_wait_for_streaming (Stream *stream) { @@ -455,6 +514,21 @@ stream_free (Stream *stream) g_free (stream); } +static void +session_notify_absolute_pointer (Session *session, + Stream *stream, + double x, + double y) +{ + GError *error = NULL; + + if (!meta_dbus_remote_desktop_session_call_notify_pointer_motion_absolute_sync ( + session->remote_desktop_session_proxy, + g_dbus_proxy_get_object_path (G_DBUS_PROXY (stream->proxy)), + x, y, NULL, &error)) + g_error ("Failed to send absolute pointer motion event: %s", error->message); +} + static void session_start (Session *session) { @@ -491,6 +565,9 @@ session_record_virtual (Session *session, Stream *stream; g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&properties_builder, "{sv}", + "cursor-mode", + g_variant_new_uint32 (CURSOR_MODE_METADATA)); properties_variant = g_variant_builder_end (&properties_builder); if (!meta_dbus_screen_cast_session_call_record_virtual_sync ( @@ -664,11 +741,18 @@ main (int argc, session_start (session); + /* Check that the display server handles events being emitted too early. */ + session_notify_absolute_pointer (session, stream, 2, 3); + /* Check that we receive the initial frame */ stream_wait_for_node (stream); - stream_wait_for_streaming (stream); stream_wait_for_render (stream); + stream_wait_for_streaming (stream); + session_notify_absolute_pointer (session, stream, 6, 5); + session_notify_absolute_pointer (session, stream, 5, 6); + stream_wait_for_render (stream); + stream_wait_for_cursor_position (stream, 5, 6); g_assert_cmpint (stream->spa_format.size.width, ==, 50); g_assert_cmpint (stream->spa_format.size.height, ==, 40);