From 3822e7fb03a6d92ce8c03074a01423bbbcf33c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 15 Aug 2023 12:49:16 +0200 Subject: [PATCH 01/17] eis: Remove meta_ prefix from variables This is more or less never used elsewhere, so don't start here. --- src/backends/meta-eis-client.c | 260 ++++++++++++++++----------------- src/backends/meta-eis-client.h | 4 +- src/backends/meta-eis.c | 104 ++++++------- src/backends/meta-eis.h | 6 +- 4 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 592d9f8bee..8f4f943744 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -45,7 +45,7 @@ struct _MetaEisDevice struct _MetaEisClient { GObject parent_instance; - MetaEis *meta_eis; + MetaEis *eis; MetaViewportInfo *viewports; struct eis_client *eis_client; @@ -56,7 +56,7 @@ struct _MetaEisClient G_DEFINE_TYPE (MetaEisClient, meta_eis_client, G_TYPE_OBJECT) -typedef void (* MetaEisDeviceConfigFunc) (MetaEisClient *meta_eis_client, +typedef void (* MetaEisDeviceConfigFunc) (MetaEisClient *client, struct eis_device *device); static bool @@ -81,39 +81,39 @@ bit_clear (guchar *array, } static void -notify_key (MetaEisDevice *meta_eis_device, +notify_key (MetaEisDevice *device, uint32_t key, gboolean is_press) { ClutterKeyState state; state = is_press ? CLUTTER_KEY_STATE_PRESSED : CLUTTER_KEY_STATE_RELEASED; - clutter_virtual_input_device_notify_key (meta_eis_device->device, + clutter_virtual_input_device_notify_key (device->device, g_get_monotonic_time (), key, state); } static void -notify_button (MetaEisDevice *meta_eis_device, +notify_button (MetaEisDevice *device, uint32_t button, gboolean is_press) { ClutterButtonState state; state = is_press ? CLUTTER_BUTTON_STATE_PRESSED : CLUTTER_BUTTON_STATE_RELEASED; - clutter_virtual_input_device_notify_button (meta_eis_device->device, + clutter_virtual_input_device_notify_button (device->device, g_get_monotonic_time (), button, state); } static void -remove_device (MetaEisClient *meta_eis_client, +remove_device (MetaEisClient *client, struct eis_device *eis_device, gboolean remove_from_hashtable) { - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); struct eis_keymap *eis_keymap = eis_device_keyboard_get_keymap (eis_device); if (eis_keymap) @@ -125,11 +125,11 @@ remove_device (MetaEisClient *meta_eis_client, eis_device_pause (eis_device); eis_device_remove (eis_device); - g_clear_pointer (&meta_eis_device->eis_device, eis_device_unref); - g_clear_object (&meta_eis_device->device); + g_clear_pointer (&device->eis_device, eis_device_unref); + g_clear_object (&device->device); if (remove_from_hashtable) - g_hash_table_remove (meta_eis_client->eis_devices, eis_device); + g_hash_table_remove (client->eis_devices, eis_device); } static gboolean @@ -137,24 +137,24 @@ drop_device (gpointer htkey, gpointer value, gpointer data) { - MetaEisClient *meta_eis_client = data; + MetaEisClient *client = data; struct eis_device *eis_device = htkey; - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); uint32_t key, button; for (key = 0; key < MAX_KEY; key++) { - if (bit_is_set (meta_eis_device->key_state, key)) - notify_key (meta_eis_device, key, FALSE); + if (bit_is_set (device->key_state, key)) + notify_key (device, key, FALSE); } for (button = 0; button < MAX_BUTTON; button++) { - if (bit_is_set (meta_eis_device->button_state, key)) - notify_button (meta_eis_device, button, FALSE); + if (bit_is_set (device->button_state, key)) + notify_button (device, button, FALSE); } - remove_device (meta_eis_client, eis_device, FALSE); + remove_device (client, eis_device, FALSE); return TRUE; } @@ -166,7 +166,7 @@ meta_eis_device_free (MetaEisDevice *device) } static void -configure_rel (MetaEisClient *meta_eis_client, +configure_rel (MetaEisClient *client, struct eis_device *eis_device) { eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_POINTER); @@ -175,7 +175,7 @@ configure_rel (MetaEisClient *meta_eis_client, } static void -configure_keyboard (MetaEisClient *meta_eis_client, +configure_keyboard (MetaEisClient *client, struct eis_device *eis_device) { size_t len; @@ -187,7 +187,7 @@ configure_keyboard (MetaEisClient *meta_eis_client, eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_KEYBOARD); xkb_keymap = - meta_backend_get_keymap (meta_eis_get_backend (meta_eis_client->meta_eis)); + meta_backend_get_keymap (meta_eis_get_backend (client->eis)); if (!xkb_keymap) return; @@ -217,21 +217,21 @@ configure_keyboard (MetaEisClient *meta_eis_client, } static void -configure_abs (MetaEisClient *meta_eis_client, +configure_abs (MetaEisClient *client, struct eis_device *eis_device) { int idx = 0; cairo_rectangle_int_t rect; float scale; - if (!meta_eis_client->viewports) + if (!client->viewports) return; /* FIXME: should be an error */ eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_BUTTON); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_SCROLL); - while (meta_viewport_info_get_view_info (meta_eis_client->viewports, idx++, &rect, &scale)) + while (meta_viewport_info_get_view_info (client->viewports, idx++, &rect, &scale)) { struct eis_region *r = eis_device_new_region (eis_device); eis_region_set_offset (r, rect.x, rect.y); @@ -243,35 +243,35 @@ configure_abs (MetaEisClient *meta_eis_client, } static void -add_device (MetaEisClient *meta_eis_client, +add_device (MetaEisClient *client, struct eis_seat *eis_seat, ClutterInputDeviceType type, const char *name_suffix, MetaEisDeviceConfigFunc extra_config_func) { - MetaBackend *backend = meta_eis_get_backend (meta_eis_client->meta_eis); - MetaEisDevice *meta_eis_device; + MetaBackend *backend = meta_eis_get_backend (client->eis); + MetaEisDevice *device; ClutterSeat *seat = meta_backend_get_default_seat (backend); - ClutterVirtualInputDevice *device; + ClutterVirtualInputDevice *virtual_device; struct eis_device *eis_device; gchar *name; - device = clutter_seat_create_virtual_device (seat, type); + virtual_device = clutter_seat_create_virtual_device (seat, type); eis_device = eis_seat_new_device (eis_seat); - name = g_strdup_printf ("%s %s", eis_client_get_name (meta_eis_client->eis_client), + name = g_strdup_printf ("%s %s", eis_client_get_name (client->eis_client), name_suffix); eis_device_configure_name (eis_device, name); if (extra_config_func) - extra_config_func (meta_eis_client, eis_device); + extra_config_func (client, eis_device); - meta_eis_device = g_new0 (MetaEisDevice, 1); - meta_eis_device->eis_device = eis_device_ref (eis_device); - meta_eis_device->device = device; - eis_device_set_user_data (eis_device, meta_eis_device); + device = g_new0 (MetaEisDevice, 1); + device->eis_device = eis_device_ref (eis_device); + device->device = virtual_device; + eis_device_set_user_data (eis_device, device); - g_hash_table_insert (meta_eis_client->eis_devices, + g_hash_table_insert (client->eis_devices, eis_device, /* owns the initial ref now */ - meta_eis_device); + device); eis_device_add (eis_device); eis_device_resume (eis_device); @@ -279,49 +279,49 @@ add_device (MetaEisClient *meta_eis_client, } static void -handle_motion_relative (MetaEisClient *meta_eis_client, +handle_motion_relative (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); double dx, dy; dx = eis_event_pointer_get_dx (event); dy = eis_event_pointer_get_dy (event); - clutter_virtual_input_device_notify_relative_motion (meta_eis_device->device, + clutter_virtual_input_device_notify_relative_motion (device->device, g_get_monotonic_time (), dx, dy); } static void -handle_motion_absolute (MetaEisClient *meta_eis_client, +handle_motion_absolute (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); double x, y; x = eis_event_pointer_get_absolute_x (event); y = eis_event_pointer_get_absolute_y (event); - clutter_virtual_input_device_notify_absolute_motion (meta_eis_device->device, + clutter_virtual_input_device_notify_absolute_motion (device->device, g_get_monotonic_time (), x, y); } static void -handle_scroll (MetaEisClient *meta_eis_client, +handle_scroll (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); double dx, dy; dx = eis_event_scroll_get_dx (event); dy = eis_event_scroll_get_dy (event); - clutter_virtual_input_device_notify_scroll_continuous (meta_eis_device->device, + clutter_virtual_input_device_notify_scroll_continuous (device->device, g_get_monotonic_time (), dx, dy, CLUTTER_SCROLL_SOURCE_UNKNOWN, @@ -329,11 +329,11 @@ handle_scroll (MetaEisClient *meta_eis_client, } static void -handle_scroll_stop (MetaEisClient *meta_eis_client, +handle_scroll_stop (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; if (eis_event_scroll_get_stop_x (event)) @@ -342,7 +342,7 @@ handle_scroll_stop (MetaEisClient *meta_eis_client, finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; if (finish_flags != CLUTTER_SCROLL_FINISHED_NONE) - clutter_virtual_input_device_notify_scroll_continuous (meta_eis_device->device, + clutter_virtual_input_device_notify_scroll_continuous (device->device, g_get_monotonic_time (), 0.0, 0.0, CLUTTER_SCROLL_SOURCE_UNKNOWN, @@ -350,11 +350,11 @@ handle_scroll_stop (MetaEisClient *meta_eis_client, } static void -handle_scroll_cancel (MetaEisClient *meta_eis_client, - struct eis_event *event) +handle_scroll_cancel (MetaEisClient *client, + struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); double dx = 0.0, dy = 0.0; /* There's no real match for the EIS scroll cancel event, so let's just send a @@ -367,7 +367,7 @@ handle_scroll_cancel (MetaEisClient *meta_eis_client, dy = 0.01; if (dx != 0.0 || dy != 0.0) - clutter_virtual_input_device_notify_scroll_continuous (meta_eis_device->device, + clutter_virtual_input_device_notify_scroll_continuous (device->device, g_get_monotonic_time (), dx, dy, CLUTTER_SCROLL_SOURCE_UNKNOWN, @@ -375,11 +375,11 @@ handle_scroll_cancel (MetaEisClient *meta_eis_client, } static void -handle_scroll_discrete (MetaEisClient *meta_eis_client, +handle_scroll_discrete (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); int dx, dy; /* FIXME: need to handle the remainders here for high-resolution scrolling */ @@ -391,7 +391,7 @@ handle_scroll_discrete (MetaEisClient *meta_eis_client, { if (dx > 0) { - clutter_virtual_input_device_notify_discrete_scroll (meta_eis_device->device, + clutter_virtual_input_device_notify_discrete_scroll (device->device, g_get_monotonic_time (), CLUTTER_SCROLL_RIGHT, CLUTTER_SCROLL_SOURCE_UNKNOWN); @@ -399,7 +399,7 @@ handle_scroll_discrete (MetaEisClient *meta_eis_client, } else if (dx < 0) { - clutter_virtual_input_device_notify_discrete_scroll (meta_eis_device->device, + clutter_virtual_input_device_notify_discrete_scroll (device->device, g_get_monotonic_time (), CLUTTER_SCROLL_LEFT, CLUTTER_SCROLL_SOURCE_UNKNOWN); @@ -408,7 +408,7 @@ handle_scroll_discrete (MetaEisClient *meta_eis_client, if (dy > 0) { - clutter_virtual_input_device_notify_discrete_scroll (meta_eis_device->device, + clutter_virtual_input_device_notify_discrete_scroll (device->device, g_get_monotonic_time (), CLUTTER_SCROLL_DOWN, CLUTTER_SCROLL_SOURCE_UNKNOWN); @@ -416,7 +416,7 @@ handle_scroll_discrete (MetaEisClient *meta_eis_client, } else if (dy < 0) { - clutter_virtual_input_device_notify_discrete_scroll (meta_eis_device->device, + clutter_virtual_input_device_notify_discrete_scroll (device->device, g_get_monotonic_time (), CLUTTER_SCROLL_UP, CLUTTER_SCROLL_SOURCE_UNKNOWN); @@ -426,11 +426,11 @@ handle_scroll_discrete (MetaEisClient *meta_eis_client, } static void -handle_button (MetaEisClient *meta_eis_client, +handle_button (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); uint32_t button; gboolean is_press = eis_event_button_get_is_press (event); @@ -455,24 +455,24 @@ handle_button (MetaEisClient *meta_eis_client, if (button > MAX_BUTTON) return; - if (is_press && !bit_is_set (meta_eis_device->button_state, button)) - bit_set (meta_eis_device->button_state, button); - else if (!is_press && bit_is_set (meta_eis_device->button_state, button)) - bit_clear (meta_eis_device->button_state, button); + if (is_press && !bit_is_set (device->button_state, button)) + bit_set (device->button_state, button); + else if (!is_press && bit_is_set (device->button_state, button)) + bit_clear (device->button_state, button); else return; /* Duplicate press/release, should've been filtered by libeis */ - notify_button (meta_eis_device, + notify_button (device, button, eis_event_button_get_is_press (event)); } static void -handle_key (MetaEisClient *meta_eis_client, +handle_key (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); - MetaEisDevice *meta_eis_device = eis_device_get_user_data (eis_device); + MetaEisDevice *device = eis_device_get_user_data (eis_device); uint32_t key; gboolean is_press = eis_event_keyboard_get_key_is_press (event); @@ -481,14 +481,14 @@ handle_key (MetaEisClient *meta_eis_client, if (key > MAX_KEY) return; - if (is_press && !bit_is_set (meta_eis_device->key_state, key)) - bit_set (meta_eis_device->key_state, key); - else if (!is_press && bit_is_set (meta_eis_device->key_state, key)) - bit_clear (meta_eis_device->key_state, key); + if (is_press && !bit_is_set (device->key_state, key)) + bit_set (device->key_state, key); + else if (!is_press && bit_is_set (device->key_state, key)) + bit_clear (device->key_state, key); else return; /* Duplicate press/release, should've been filtered by libeis */ - notify_key (meta_eis_device, key, is_press); + notify_key (device, key, is_press); } static gboolean @@ -508,24 +508,24 @@ static void on_keymap_changed (MetaBackend *backend, gpointer data) { - MetaEisClient *meta_eis_client = data; + MetaEisClient *client = data; /* Changing the keymap means we have to remove our device and recreate it * with the new keymap. */ - g_hash_table_foreach_remove (meta_eis_client->eis_devices, + g_hash_table_foreach_remove (client->eis_devices, drop_kbd_devices, - meta_eis_client); + client); - add_device (meta_eis_client, - meta_eis_client->eis_seat, + add_device (client, + client->eis_seat, CLUTTER_KEYBOARD_DEVICE, "virtual keyboard", configure_keyboard); } gboolean -meta_eis_client_process_event (MetaEisClient *meta_eis_client, +meta_eis_client_process_event (MetaEisClient *client, struct eis_event *event) { enum eis_event_type type = eis_event_get_type (event); @@ -536,26 +536,26 @@ meta_eis_client_process_event (MetaEisClient *meta_eis_client, case EIS_EVENT_SEAT_BIND: eis_seat = eis_event_get_seat (event); if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER)) - add_device (meta_eis_client, + add_device (client, eis_seat, CLUTTER_POINTER_DEVICE, "virtual pointer", configure_rel); if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_KEYBOARD)) { - add_device (meta_eis_client, + add_device (client, eis_seat, CLUTTER_KEYBOARD_DEVICE, "virtual keyboard", configure_keyboard); - g_signal_connect (meta_eis_get_backend (meta_eis_client->meta_eis), + g_signal_connect (meta_eis_get_backend (client->eis), "keymap-changed", G_CALLBACK (on_keymap_changed), - meta_eis_client); + client); } if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) - add_device (meta_eis_client, + add_device (client, eis_seat, CLUTTER_POINTER_DEVICE, "virtual absolute pointer", @@ -565,31 +565,31 @@ meta_eis_client_process_event (MetaEisClient *meta_eis_client, /* We only have one seat, so if the client unbinds from that * just disconnect it, no point keeping it alive */ case EIS_EVENT_DEVICE_CLOSED: - remove_device (meta_eis_client, eis_event_get_device (event), TRUE); + remove_device (client, eis_event_get_device (event), TRUE); break; case EIS_EVENT_POINTER_MOTION: - handle_motion_relative (meta_eis_client, event); + handle_motion_relative (client, event); break; case EIS_EVENT_POINTER_MOTION_ABSOLUTE: - handle_motion_absolute (meta_eis_client, event); + handle_motion_absolute (client, event); break; case EIS_EVENT_BUTTON_BUTTON: - handle_button (meta_eis_client, event); + handle_button (client, event); break; case EIS_EVENT_SCROLL_DELTA: - handle_scroll (meta_eis_client, event); + handle_scroll (client, event); break; case EIS_EVENT_SCROLL_STOP: - handle_scroll_stop (meta_eis_client, event); + handle_scroll_stop (client, event); break; case EIS_EVENT_SCROLL_CANCEL: - handle_scroll_cancel (meta_eis_client, event); + handle_scroll_cancel (client, event); break; case EIS_EVENT_SCROLL_DISCRETE: - handle_scroll_discrete (meta_eis_client, event); + handle_scroll_discrete (client, event); break; case EIS_EVENT_KEYBOARD_KEY: - handle_key (meta_eis_client, event); + handle_key (client, event); break; case EIS_EVENT_FRAME: /* FIXME: we should be accumulating the above events */ @@ -620,21 +620,21 @@ drop_abs_devices (gpointer key, } static void -meta_eis_client_set_viewports (MetaEisClient *meta_eis_client, +meta_eis_client_set_viewports (MetaEisClient *client, MetaViewportInfo *viewports) { /* Updating viewports means we have to recreate our absolute pointer * devices. */ - g_hash_table_foreach_remove (meta_eis_client->eis_devices, + g_hash_table_foreach_remove (client->eis_devices, drop_abs_devices, - meta_eis_client); + client); - g_clear_object (&meta_eis_client->viewports); - meta_eis_client->viewports = g_object_ref (viewports); + g_clear_object (&client->viewports); + client->viewports = g_object_ref (viewports); - add_device (meta_eis_client, - meta_eis_client->eis_seat, + add_device (client, + client->eis_seat, CLUTTER_POINTER_DEVICE, "virtual absolute pointer", configure_abs); @@ -642,45 +642,45 @@ meta_eis_client_set_viewports (MetaEisClient *meta_eis_client, static void on_monitors_changed (MetaMonitorManager *monitor_manager, - MetaEisClient *meta_eis_client) + MetaEisClient *client) { MetaViewportInfo *viewports; viewports = meta_monitor_manager_get_viewports (monitor_manager); - meta_eis_client_set_viewports (meta_eis_client, viewports); + meta_eis_client_set_viewports (client, viewports); } static void -meta_eis_client_disconnect (MetaEisClient *meta_eis_client) +meta_eis_client_disconnect (MetaEisClient *client) { - MetaBackend *backend = meta_eis_get_backend (meta_eis_client->meta_eis); + MetaBackend *backend = meta_eis_get_backend (client->eis); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); g_signal_handlers_disconnect_by_func (monitor_manager, on_monitors_changed, - meta_eis_client); - g_hash_table_foreach_remove (meta_eis_client->eis_devices, drop_device, meta_eis_client); - g_clear_pointer (&meta_eis_client->eis_seat, eis_seat_unref); - if (meta_eis_client->eis_client) - eis_client_disconnect (meta_eis_client->eis_client); - g_clear_pointer (&meta_eis_client->eis_client, eis_client_unref); - g_clear_object (&meta_eis_client->viewports); + client); + g_hash_table_foreach_remove (client->eis_devices, drop_device, client); + g_clear_pointer (&client->eis_seat, eis_seat_unref); + if (client->eis_client) + eis_client_disconnect (client->eis_client); + g_clear_pointer (&client->eis_client, eis_client_unref); + g_clear_object (&client->viewports); } MetaEisClient * -meta_eis_client_new (MetaEis *meta_eis, +meta_eis_client_new (MetaEis *eis, struct eis_client *eis_client) { - MetaEisClient *meta_eis_client; + MetaEisClient *client; MetaBackend *backend; MetaMonitorManager *monitor_manager; MetaViewportInfo *viewports; struct eis_seat *eis_seat; - meta_eis_client = g_object_new (META_TYPE_EIS_CLIENT, NULL); - meta_eis_client->meta_eis = meta_eis; - meta_eis_client->eis_client = eis_client_ref (eis_client); - eis_client_set_user_data (meta_eis_client->eis_client, meta_eis_client); + client = g_object_new (META_TYPE_EIS_CLIENT, NULL); + client->eis = eis; + client->eis_client = eis_client_ref (eis_client); + eis_client_set_user_data (client->eis_client, client); /* We're relying on some third party to filter clients for us */ eis_client_connect (eis_client); @@ -700,37 +700,37 @@ meta_eis_client_new (MetaEis *meta_eis, eis_seat_add (eis_seat); eis_seat_unref (eis_seat); - meta_eis_client->eis_seat = eis_seat_ref (eis_seat); + client->eis_seat = eis_seat_ref (eis_seat); - meta_eis_client->eis_devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, - (GDestroyNotify) eis_device_unref, - (GDestroyNotify) meta_eis_device_free); + client->eis_devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) eis_device_unref, + (GDestroyNotify) meta_eis_device_free); - backend = meta_eis_get_backend (meta_eis); + backend = meta_eis_get_backend (eis); monitor_manager = meta_backend_get_monitor_manager (backend); viewports = meta_monitor_manager_get_viewports (monitor_manager); - meta_eis_client_set_viewports (meta_eis_client, viewports); + meta_eis_client_set_viewports (client, viewports); g_signal_connect (monitor_manager, "monitors-changed", G_CALLBACK (on_monitors_changed), - meta_eis_client); + client); - return meta_eis_client; + return client; } static void -meta_eis_client_init (MetaEisClient *meta_eis_client) +meta_eis_client_init (MetaEisClient *client) { } static void meta_eis_client_finalize (GObject *object) { - MetaEisClient *meta_eis_client = META_EIS_CLIENT (object); + MetaEisClient *client = META_EIS_CLIENT (object); - g_signal_handlers_disconnect_by_func (meta_eis_get_backend (meta_eis_client->meta_eis), + g_signal_handlers_disconnect_by_func (meta_eis_get_backend (client->eis), on_keymap_changed, - meta_eis_client); - meta_eis_client_disconnect (meta_eis_client); + client); + meta_eis_client_disconnect (client); G_OBJECT_CLASS (meta_eis_client_parent_class)->finalize (object); } diff --git a/src/backends/meta-eis-client.h b/src/backends/meta-eis-client.h index da4fc85a5c..b1695e988d 100644 --- a/src/backends/meta-eis-client.h +++ b/src/backends/meta-eis-client.h @@ -31,8 +31,8 @@ G_DECLARE_FINAL_TYPE (MetaEisClient, meta_eis_client, META, EIS_CLIENT, GObject) -MetaEisClient *meta_eis_client_new (MetaEis *meta_eis, +MetaEisClient *meta_eis_client_new (MetaEis *eis, struct eis_client *eis_client); -gboolean meta_eis_client_process_event (MetaEisClient *meta_eis_client, +gboolean meta_eis_client_process_event (MetaEisClient *client, struct eis_event *eis_event); diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index f21c6c3e4f..12b385f07e 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -33,7 +33,7 @@ struct _MetaEventSource { GSource source; - MetaEis *meta_eis; + MetaEis *eis; GPollFD event_poll_fd; }; @@ -51,80 +51,80 @@ struct _MetaEis G_DEFINE_TYPE (MetaEis, meta_eis, G_TYPE_OBJECT) MetaBackend * -meta_eis_get_backend (MetaEis *meta_eis) +meta_eis_get_backend (MetaEis *eis) { - return meta_eis->backend; + return eis->backend; } void -meta_eis_remove_all_clients (MetaEis *meta_eis) +meta_eis_remove_all_clients (MetaEis *eis) { - g_hash_table_remove_all (meta_eis->eis_clients); + g_hash_table_remove_all (eis->eis_clients); } static void -meta_eis_remove_client (MetaEis *meta_eis, +meta_eis_remove_client (MetaEis *eis, struct eis_client *eis_client) { - g_hash_table_remove (meta_eis->eis_clients, eis_client); + g_hash_table_remove (eis->eis_clients, eis_client); } static void -meta_eis_add_client (MetaEis *meta_eis, +meta_eis_add_client (MetaEis *eis, struct eis_client *eis_client) { - MetaEisClient *meta_eis_client; + MetaEisClient *client; - meta_eis_client = meta_eis_client_new (meta_eis, eis_client); + client = meta_eis_client_new (eis, eis_client); - g_hash_table_insert (meta_eis->eis_clients, + g_hash_table_insert (eis->eis_clients, eis_client_ref (eis_client), - meta_eis_client); + client); } static void -process_event (MetaEis *meta_eis, +process_event (MetaEis *eis, struct eis_event *event) { enum eis_event_type type = eis_event_get_type (event); struct eis_client *eis_client = eis_event_get_client (event); - MetaEisClient *meta_eis_client; + MetaEisClient *client; switch (type) { case EIS_EVENT_CLIENT_CONNECT: - meta_eis_add_client (meta_eis, eis_client); + meta_eis_add_client (eis, eis_client); break; case EIS_EVENT_CLIENT_DISCONNECT: - meta_eis_remove_client (meta_eis, eis_client); + meta_eis_remove_client (eis, eis_client); break; default: - meta_eis_client = g_hash_table_lookup (meta_eis->eis_clients, eis_client); - if (!meta_eis_client) + client = g_hash_table_lookup (eis->eis_clients, eis_client); + if (!client) { g_warning ("Event for unknown EIS client: %s", eis_client_get_name (eis_client)); return; } - meta_eis_client_process_event (meta_eis_client, event); + meta_eis_client_process_event (client, event); break; } } static void -process_events (MetaEis *meta_eis) +process_events (MetaEis *eis) { struct eis_event *e; - while ((e = eis_get_event (meta_eis->eis))) + while ((e = eis_get_event (eis->eis))) { - process_event (meta_eis, e); + process_event (eis, e); eis_event_unref (e); } } static MetaEventSource * -meta_event_source_new (MetaEis *meta_eis, +meta_event_source_new (MetaEis *eis, int fd, GSourceFuncs *event_funcs) { @@ -135,7 +135,7 @@ meta_event_source_new (MetaEis *meta_eis, event_source = (MetaEventSource *) source; /* setup the source */ - event_source->meta_eis = meta_eis; + event_source->eis = eis; event_source->event_poll_fd.fd = fd; event_source->event_poll_fd.events = G_IO_IN; @@ -167,12 +167,12 @@ meta_event_prepare (GSource *g_source, int *timeout_ms) { MetaEventSource *source = (MetaEventSource *) g_source; - MetaEis *meta_eis = source->meta_eis; + MetaEis *eis = source->eis; struct eis_event *e; *timeout_ms = -1; - e = eis_peek_event (meta_eis->eis); + e = eis_peek_event (eis->eis); if (e) { eis_event_unref (e); @@ -198,10 +198,10 @@ meta_event_dispatch (GSource *g_source, gpointer user_data) { MetaEventSource *source = (MetaEventSource *) g_source; - MetaEis *meta_eis = source->meta_eis; + MetaEis *eis = source->eis; - eis_dispatch (meta_eis->eis); - process_events (meta_eis); + eis_dispatch (eis->eis); + process_events (eis); return TRUE; } @@ -238,13 +238,13 @@ eis_logger (struct eis *eis, } int -meta_eis_add_client_get_fd (MetaEis *meta_eis) +meta_eis_add_client_get_fd (MetaEis *eis) { - return eis_backend_fd_add_client (meta_eis->eis); + return eis_backend_fd_add_client (eis->eis); } static int -try_and_find_free_eis_socket (MetaEis *meta_eis) +try_and_find_free_eis_socket (MetaEis *eis) { int rc; int n; @@ -253,7 +253,7 @@ try_and_find_free_eis_socket (MetaEis *meta_eis) for (n = 0; n < 100; n++) { g_snprintf (socketname, sizeof (socketname), "eis-%d", n); - rc = eis_setup_backend_socket (meta_eis->eis, socketname); + rc = eis_setup_backend_socket (eis->eis, socketname); if (rc == 0) { g_info ("Using EIS socket: %s", socketname); @@ -267,47 +267,47 @@ try_and_find_free_eis_socket (MetaEis *meta_eis) MetaEis * meta_eis_new (MetaBackend *backend) { - MetaEis *meta_eis; + MetaEis *eis; int fd; int rc; - meta_eis = g_object_new (META_TYPE_EIS, NULL); - meta_eis->backend = backend; + eis = g_object_new (META_TYPE_EIS, NULL); + eis->backend = backend; - meta_eis->eis = eis_new (meta_eis); - rc = try_and_find_free_eis_socket (meta_eis); + eis->eis = eis_new (eis); + rc = try_and_find_free_eis_socket (eis); if (rc != 0) { g_warning ("Failed to initialize the EIS socket: %s", g_strerror (-rc)); - g_clear_pointer (&meta_eis->eis, eis_unref); + g_clear_pointer (&eis->eis, eis_unref); return NULL; } - eis_log_set_handler (meta_eis->eis, eis_logger); - eis_log_set_priority (meta_eis->eis, EIS_LOG_PRIORITY_DEBUG); + eis_log_set_handler (eis->eis, eis_logger); + eis_log_set_priority (eis->eis, EIS_LOG_PRIORITY_DEBUG); - fd = eis_get_fd (meta_eis->eis); - meta_eis->event_source = meta_event_source_new (meta_eis, fd, &eis_event_funcs); + fd = eis_get_fd (eis->eis); + eis->event_source = meta_event_source_new (eis, fd, &eis_event_funcs); - return meta_eis; + return eis; } static void -meta_eis_init (MetaEis *meta_eis) +meta_eis_init (MetaEis *eis) { - meta_eis->eis_clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, - (GDestroyNotify) eis_client_unref, - (GDestroyNotify) g_object_unref); + eis->eis_clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) eis_client_unref, + (GDestroyNotify) g_object_unref); } static void meta_eis_finalize (GObject *object) { - MetaEis *meta_eis = META_EIS (object); + MetaEis *eis = META_EIS (object); - g_clear_pointer (&meta_eis->event_source, meta_event_source_free); - g_clear_pointer (&meta_eis->eis, eis_unref); - g_clear_pointer (&meta_eis->eis_clients, g_hash_table_destroy); + g_clear_pointer (&eis->event_source, meta_event_source_free); + g_clear_pointer (&eis->eis, eis_unref); + g_clear_pointer (&eis->eis_clients, g_hash_table_destroy); G_OBJECT_CLASS (meta_eis_parent_class)->finalize (object); } diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index a1c8094e59..a2d0263e9f 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -30,6 +30,6 @@ G_DECLARE_FINAL_TYPE (MetaEis, meta_eis, META, EIS, GObject) MetaEis * meta_eis_new (MetaBackend *backend); -MetaBackend * meta_eis_get_backend (MetaEis *meta_eis); -int meta_eis_add_client_get_fd (MetaEis *meta_eis); -void meta_eis_remove_all_clients (MetaEis *meta_eis); +MetaBackend * meta_eis_get_backend (MetaEis *eis); +int meta_eis_add_client_get_fd (MetaEis *eis); +void meta_eis_remove_all_clients (MetaEis *eis); From 51230a70ea424bf26fca16aafad712058aa31d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 16:49:48 +0200 Subject: [PATCH 02/17] eis: Don't expose global socket How EIS will be used depends on its context, meaning we'll have multiple EIS contexts that expose different things. To prepare for this remove the global socket since that won't work with multiple contexts. --- src/backends/meta-eis.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 12b385f07e..e6b35610b1 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -243,48 +243,19 @@ meta_eis_add_client_get_fd (MetaEis *eis) return eis_backend_fd_add_client (eis->eis); } -static int -try_and_find_free_eis_socket (MetaEis *eis) -{ - int rc; - int n; - char socketname[16]; - - for (n = 0; n < 100; n++) - { - g_snprintf (socketname, sizeof (socketname), "eis-%d", n); - rc = eis_setup_backend_socket (eis->eis, socketname); - if (rc == 0) - { - g_info ("Using EIS socket: %s", socketname); - return 0; - } - } - - return rc; -} - MetaEis * meta_eis_new (MetaBackend *backend) { MetaEis *eis; int fd; - int rc; eis = g_object_new (META_TYPE_EIS, NULL); eis->backend = backend; eis->eis = eis_new (eis); - rc = try_and_find_free_eis_socket (eis); - if (rc != 0) - { - g_warning ("Failed to initialize the EIS socket: %s", g_strerror (-rc)); - g_clear_pointer (&eis->eis, eis_unref); - return NULL; - } - eis_log_set_handler (eis->eis, eis_logger); eis_log_set_priority (eis->eis, EIS_LOG_PRIORITY_DEBUG); + eis_setup_backend_fd (eis->eis); fd = eis_get_fd (eis->eis); eis->event_source = meta_event_source_new (eis, fd, &eis_event_funcs); From 6e0b658aaa13ce6d82a15a0050692db14a189b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 17:01:03 +0200 Subject: [PATCH 03/17] remote-desktop/session: Take over EIS context This means there will be an EIS context per session, which will enable per session devices and region. --- src/backends/meta-backend-private.h | 2 -- src/backends/meta-backend.c | 14 -------------- src/backends/meta-eis.c | 6 ------ src/backends/meta-eis.h | 1 - src/backends/meta-remote-desktop-session.c | 12 +++++------- 5 files changed, 5 insertions(+), 30 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 592f855578..be6abc0ced 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -143,8 +143,6 @@ MetaDbusSessionWatcher * meta_backend_get_dbus_session_watcher (MetaBackend *bac MetaRemoteDesktop * meta_backend_get_remote_desktop (MetaBackend *backend); MetaScreenCast * meta_backend_get_screen_cast (MetaBackend *backend); - -MetaEis * meta_backend_get_eis (MetaBackend *backend); #endif MetaInputCapture * meta_backend_get_input_capture (MetaBackend *backend); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 904d2a89be..1a40caf530 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -78,7 +78,6 @@ #ifdef HAVE_REMOTE_DESKTOP #include "backends/meta-dbus-session-watcher.h" -#include "backends/meta-eis.h" #include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-desktop.h" #include "backends/meta-screen-cast.h" @@ -140,7 +139,6 @@ struct _MetaBackendPrivate #ifdef HAVE_REMOTE_DESKTOP MetaScreenCast *screen_cast; MetaRemoteDesktop *remote_desktop; - MetaEis *eis; #endif MetaInputCapture *input_capture; @@ -210,7 +208,6 @@ meta_backend_dispose (GObject *object) #ifdef HAVE_REMOTE_DESKTOP g_clear_object (&priv->remote_desktop); g_clear_object (&priv->screen_cast); - g_clear_object (&priv->eis); #endif g_clear_object (&priv->input_capture); g_clear_object (&priv->dbus_session_watcher); @@ -584,7 +581,6 @@ meta_backend_real_post_init (MetaBackend *backend) meta_remote_access_controller_add ( priv->remote_access_controller, META_DBUS_SESSION_MANAGER (priv->remote_desktop)); - priv->eis = meta_eis_new (backend); #endif /* HAVE_REMOTE_DESKTOP */ priv->input_capture = meta_input_capture_new (backend); @@ -1443,16 +1439,6 @@ meta_backend_get_screen_cast (MetaBackend *backend) return priv->screen_cast; } - -/** - * meta_backend_get_eis: (skip) - */ -MetaEis * -meta_backend_get_eis (MetaBackend *backend) -{ - MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - return priv->eis; -} #endif /* HAVE_REMOTE_DESKTOP */ MetaInputCapture * diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index e6b35610b1..45a11a6e11 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -56,12 +56,6 @@ meta_eis_get_backend (MetaEis *eis) return eis->backend; } -void -meta_eis_remove_all_clients (MetaEis *eis) -{ - g_hash_table_remove_all (eis->eis_clients); -} - static void meta_eis_remove_client (MetaEis *eis, struct eis_client *eis_client) diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index a2d0263e9f..5b2f1c4fc7 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -32,4 +32,3 @@ G_DECLARE_FINAL_TYPE (MetaEis, meta_eis, MetaEis * meta_eis_new (MetaBackend *backend); MetaBackend * meta_eis_get_backend (MetaEis *eis); int meta_eis_add_client_get_fd (MetaEis *eis); -void meta_eis_remove_all_clients (MetaEis *eis); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index c9288d76cc..90b4f6cd48 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -88,6 +88,7 @@ struct _MetaRemoteDesktopSession gulong screen_cast_session_closed_handler_id; guint started : 1; + MetaEis *eis; ClutterVirtualInputDevice *virtual_pointer; ClutterVirtualInputDevice *virtual_keyboard; ClutterVirtualInputDevice *virtual_touchscreen; @@ -223,8 +224,6 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) { MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (dbus_session); - MetaBackend *backend = - meta_dbus_session_manager_get_backend (session->session_manager); MetaDBusRemoteDesktopSession *skeleton = META_DBUS_REMOTE_DESKTOP_SESSION (session); @@ -244,6 +243,7 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) g_clear_object (&session->virtual_pointer); g_clear_object (&session->virtual_keyboard); g_clear_object (&session->virtual_touchscreen); + g_clear_object (&session->eis); meta_dbus_session_notify_closed (META_DBUS_SESSION (session)); meta_dbus_remote_desktop_session_emit_closed (skeleton); @@ -257,8 +257,6 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) meta_remote_access_handle_notify_stopped (remote_access_handle); } - meta_eis_remove_all_clients (meta_backend_get_eis (backend)); - g_object_unref (session); } @@ -1641,11 +1639,11 @@ handle_connect_to_eis (MetaDBusRemoteDesktopSession *skeleton, int fd_idx; GVariant *fd_variant; int fd; - MetaEis *meis; - meis = meta_backend_get_eis (backend); + if (!session->eis) + session->eis = meta_eis_new (backend); - fd = meta_eis_add_client_get_fd (meis); + fd = meta_eis_add_client_get_fd (session->eis); if (fd < 0) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, From 51443d16a57f4f839f6aa6cd2a5a5b0419b6b0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 17:16:58 +0200 Subject: [PATCH 04/17] eis/client: Fix indentation --- src/backends/meta-eis-client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 8f4f943744..8a6745f446 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -549,10 +549,10 @@ meta_eis_client_process_event (MetaEisClient *client, "virtual keyboard", configure_keyboard); - g_signal_connect (meta_eis_get_backend (client->eis), - "keymap-changed", - G_CALLBACK (on_keymap_changed), - client); + g_signal_connect (meta_eis_get_backend (client->eis), + "keymap-changed", + G_CALLBACK (on_keymap_changed), + client); } if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) add_device (client, From 52ae2b4f699adbfa042c32646b6c3d222504d972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 17:18:31 +0200 Subject: [PATCH 05/17] eis/client: Fix minor coding style issues --- src/backends/meta-eis-client.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 8a6745f446..cad6fb4e90 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -536,11 +536,13 @@ meta_eis_client_process_event (MetaEisClient *client, case EIS_EVENT_SEAT_BIND: eis_seat = eis_event_get_seat (event); if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER)) - add_device (client, - eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual pointer", - configure_rel); + { + add_device (client, + eis_seat, + CLUTTER_POINTER_DEVICE, + "virtual pointer", + configure_rel); + } if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_KEYBOARD)) { add_device (client, @@ -555,11 +557,13 @@ meta_eis_client_process_event (MetaEisClient *client, client); } if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) + { add_device (client, eis_seat, CLUTTER_POINTER_DEVICE, "virtual absolute pointer", configure_abs); + } break; /* We only have one seat, so if the client unbinds from that From bdb33fd9a6d4b60c9089ea21d98648b670757170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 17:21:35 +0200 Subject: [PATCH 06/17] remote-desktop/session: Limit device type access when using libei The portal could limit access to certain device types, but this was not forwarded to the EIS context. Add a way to do this, and make use of it. --- .../org.gnome.Mutter.RemoteDesktop.xml | 4 +++ src/backends/meta-eis-client.c | 18 +++++++--- src/backends/meta-eis.c | 12 ++++++- src/backends/meta-eis.h | 14 ++++++-- src/backends/meta-remote-desktop-session.c | 35 ++++++++++++++++++- src/backends/meta-remote-desktop.c | 8 ----- src/backends/meta-remote-desktop.h | 8 +++++ 7 files changed, 82 insertions(+), 17 deletions(-) diff --git a/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml b/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml index 64f8f82d97..c309beb0c3 100644 --- a/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml +++ b/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml @@ -352,6 +352,10 @@ ConnectToEIS: Request a connection to an EIS implementation. + + Available @options include: + + * "device-types" u: Bitmask of device types to expose (see SupportedDeviceTypes) --> diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index cad6fb4e90..35ac6260b3 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -696,11 +696,19 @@ meta_eis_client_new (MetaEis *eis, * of the seat in the process. */ eis_seat = eis_client_new_seat (eis_client, "mutter default seat"); - eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_KEYBOARD); - eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_POINTER); - eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE); - eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_BUTTON); - eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_SCROLL); + + if (meta_eis_get_device_types (eis) & META_EIS_DEVICE_TYPE_KEYBOARD) + { + eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_KEYBOARD); + } + + if (meta_eis_get_device_types (eis) & META_EIS_DEVICE_TYPE_POINTER) + { + eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_POINTER); + eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE); + eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_BUTTON); + eis_seat_configure_capability (eis_seat, EIS_DEVICE_CAP_SCROLL); + } eis_seat_add (eis_seat); eis_seat_unref (eis_seat); diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 45a11a6e11..9086f70b6c 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -45,6 +45,8 @@ struct _MetaEis struct eis *eis; MetaEventSource *event_source; + MetaEisDeviceTypes device_types; + GHashTable *eis_clients; /* eis_client => MetaEisClient */ }; @@ -238,13 +240,15 @@ meta_eis_add_client_get_fd (MetaEis *eis) } MetaEis * -meta_eis_new (MetaBackend *backend) +meta_eis_new (MetaBackend *backend, + MetaEisDeviceTypes device_types) { MetaEis *eis; int fd; eis = g_object_new (META_TYPE_EIS, NULL); eis->backend = backend; + eis->device_types = device_types; eis->eis = eis_new (eis); eis_log_set_handler (eis->eis, eis_logger); @@ -284,3 +288,9 @@ meta_eis_class_init (MetaEisClass *klass) object_class->finalize = meta_eis_finalize; } + +MetaEisDeviceTypes +meta_eis_get_device_types (MetaEis *eis) +{ + return eis->device_types; +} diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index 5b2f1c4fc7..d1b54f35ac 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -23,12 +23,22 @@ #include #include "backends/meta-backend-types.h" -#include "backends/meta-viewport-info.h" + +typedef enum _MetaEisDeviceTypes +{ + META_EIS_DEVICE_TYPE_NONE = 0, + META_EIS_DEVICE_TYPE_KEYBOARD = 1 << 0, + META_EIS_DEVICE_TYPE_POINTER = 1 << 1, + META_EIS_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, +} MetaEisDeviceTypes; #define META_TYPE_EIS (meta_eis_get_type ()) G_DECLARE_FINAL_TYPE (MetaEis, meta_eis, META, EIS, GObject) -MetaEis * meta_eis_new (MetaBackend *backend); +MetaEis * meta_eis_new (MetaBackend *backend, + MetaEisDeviceTypes device_types); MetaBackend * meta_eis_get_backend (MetaEis *eis); int meta_eis_add_client_get_fd (MetaEis *eis); + +MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index 90b4f6cd48..9b6de2e70b 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -1626,6 +1626,21 @@ handle_selection_read (MetaDBusRemoteDesktopSession *skeleton, return TRUE; } +static MetaEisDeviceTypes +device_types_to_eis_device_types (MetaRemoteDesktopDeviceTypes device_types) +{ + MetaEisDeviceTypes eis_device_types = META_EIS_DEVICE_TYPE_NONE; + + if (device_types & META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD) + eis_device_types |= META_EIS_DEVICE_TYPE_KEYBOARD; + if (device_types & META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER) + eis_device_types |= META_EIS_DEVICE_TYPE_POINTER; + if (device_types & META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN) + eis_device_types |= META_EIS_DEVICE_TYPE_TOUCHSCREEN; + + return eis_device_types; +} + static gboolean handle_connect_to_eis (MetaDBusRemoteDesktopSession *skeleton, GDBusMethodInvocation *invocation, @@ -1641,7 +1656,25 @@ handle_connect_to_eis (MetaDBusRemoteDesktopSession *skeleton, int fd; if (!session->eis) - session->eis = meta_eis_new (backend); + { + uint32_t device_types_bitmask; + MetaRemoteDesktopDeviceTypes device_types; + MetaEisDeviceTypes eis_device_types; + + if (!g_variant_lookup (arg_options, "device-types", "u", &device_types_bitmask)) + { + device_types = (META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD | + META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER | + META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN); + } + else + { + device_types = device_types_bitmask; + } + + eis_device_types = device_types_to_eis_device_types (device_types); + session->eis = meta_eis_new (backend, eis_device_types); + } fd = meta_eis_add_client_get_fd (session->eis); if (fd < 0) diff --git a/src/backends/meta-remote-desktop.c b/src/backends/meta-remote-desktop.c index 44e51c5554..3f6a7dc99a 100644 --- a/src/backends/meta-remote-desktop.c +++ b/src/backends/meta-remote-desktop.c @@ -40,14 +40,6 @@ #define META_REMOTE_DESKTOP_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop" #define META_REMOTE_DESKTOP_API_VERSION 1 -typedef enum _MetaRemoteDesktopDeviceTypes -{ - META_REMOTE_DESKTOP_DEVICE_TYPE_NONE = 0, - META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD = 1 << 0, - META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER = 1 << 1, - META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, -} MetaRemoteDesktopDeviceTypes; - struct _MetaRemoteDesktop { MetaDbusSessionManager parent; diff --git a/src/backends/meta-remote-desktop.h b/src/backends/meta-remote-desktop.h index 5bb8de15d5..9a6e33a41f 100644 --- a/src/backends/meta-remote-desktop.h +++ b/src/backends/meta-remote-desktop.h @@ -28,6 +28,14 @@ #include "meta-dbus-remote-desktop.h" +typedef enum _MetaRemoteDesktopDeviceTypes +{ + META_REMOTE_DESKTOP_DEVICE_TYPE_NONE = 0, + META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD = 1 << 0, + META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER = 1 << 1, + META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, +} MetaRemoteDesktopDeviceTypes; + typedef struct _MetaRemoteDesktopSession MetaRemoteDesktopSession; #define META_TYPE_REMOTE_DESKTOP (meta_remote_desktop_get_type ()) From 7e353c89036c29a7f78dc6301b00469994396dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 17:28:58 +0200 Subject: [PATCH 07/17] eis: Add some spacing in API declarations --- src/backends/meta-eis.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index d1b54f35ac..8160222be3 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -38,7 +38,9 @@ G_DECLARE_FINAL_TYPE (MetaEis, meta_eis, MetaEis * meta_eis_new (MetaBackend *backend, MetaEisDeviceTypes device_types); + MetaBackend * meta_eis_get_backend (MetaEis *eis); + int meta_eis_add_client_get_fd (MetaEis *eis); MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); From bfe5e5e88344dcfe33ed524dd75706206b12abac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 22:14:53 +0200 Subject: [PATCH 08/17] eis/client: Add user_data to add-device helper This will allow passing extra context to the configure function. Currently all NULL, but preparing for the future. --- src/backends/meta-eis-client.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 35ac6260b3..84c6bab005 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -57,7 +57,8 @@ struct _MetaEisClient G_DEFINE_TYPE (MetaEisClient, meta_eis_client, G_TYPE_OBJECT) typedef void (* MetaEisDeviceConfigFunc) (MetaEisClient *client, - struct eis_device *device); + struct eis_device *device, + gpointer user_data); static bool bit_is_set (const guchar *array, @@ -167,7 +168,8 @@ meta_eis_device_free (MetaEisDevice *device) static void configure_rel (MetaEisClient *client, - struct eis_device *eis_device) + struct eis_device *eis_device, + gpointer user_data) { eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_POINTER); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_BUTTON); @@ -176,7 +178,8 @@ configure_rel (MetaEisClient *client, static void configure_keyboard (MetaEisClient *client, - struct eis_device *eis_device) + struct eis_device *eis_device, + gpointer user_data) { size_t len; MetaAnonymousFile *f; @@ -218,7 +221,8 @@ configure_keyboard (MetaEisClient *client, static void configure_abs (MetaEisClient *client, - struct eis_device *eis_device) + struct eis_device *eis_device, + gpointer user_data) { int idx = 0; cairo_rectangle_int_t rect; @@ -247,7 +251,8 @@ add_device (MetaEisClient *client, struct eis_seat *eis_seat, ClutterInputDeviceType type, const char *name_suffix, - MetaEisDeviceConfigFunc extra_config_func) + MetaEisDeviceConfigFunc extra_config_func, + gpointer extra_config_user_data) { MetaBackend *backend = meta_eis_get_backend (client->eis); MetaEisDevice *device; @@ -262,7 +267,7 @@ add_device (MetaEisClient *client, name_suffix); eis_device_configure_name (eis_device, name); if (extra_config_func) - extra_config_func (client, eis_device); + extra_config_func (client, eis_device, extra_config_user_data); device = g_new0 (MetaEisDevice, 1); device->eis_device = eis_device_ref (eis_device); @@ -521,7 +526,7 @@ on_keymap_changed (MetaBackend *backend, client->eis_seat, CLUTTER_KEYBOARD_DEVICE, "virtual keyboard", - configure_keyboard); + configure_keyboard, NULL); } gboolean @@ -541,7 +546,7 @@ meta_eis_client_process_event (MetaEisClient *client, eis_seat, CLUTTER_POINTER_DEVICE, "virtual pointer", - configure_rel); + configure_rel, NULL); } if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_KEYBOARD)) { @@ -549,7 +554,7 @@ meta_eis_client_process_event (MetaEisClient *client, eis_seat, CLUTTER_KEYBOARD_DEVICE, "virtual keyboard", - configure_keyboard); + configure_keyboard, NULL); g_signal_connect (meta_eis_get_backend (client->eis), "keymap-changed", @@ -562,7 +567,8 @@ meta_eis_client_process_event (MetaEisClient *client, eis_seat, CLUTTER_POINTER_DEVICE, "virtual absolute pointer", - configure_abs); + configure_abs, + NULL); } break; @@ -641,7 +647,8 @@ meta_eis_client_set_viewports (MetaEisClient *client, client->eis_seat, CLUTTER_POINTER_DEVICE, "virtual absolute pointer", - configure_abs); + configure_abs, + NULL); } static void From e8bf36010e860b4ed4af7e24507fe73614329508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 22:16:06 +0200 Subject: [PATCH 09/17] eis: Add "viewport" interface A MetaEisViewport represents an absolute region backend by e.g. a pointer device. There are two kinds: a standalone viewport, which corresponds to a viewport that has no neighbours, and a non-standalone, which represents a region of a global coordinate space. The reason for having non-standalone viewports is to allow to mirror the logical monitor layout of a desktop, while the standalone are meant to represent things that are not part of the logical monitor layout. --- src/backends/meta-eis.c | 53 +++++++++++++++++++++++++++++++++++++++++ src/backends/meta-eis.h | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 9086f70b6c..905da3f6ce 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -52,6 +52,59 @@ struct _MetaEis G_DEFINE_TYPE (MetaEis, meta_eis, G_TYPE_OBJECT) +G_DEFINE_INTERFACE (MetaEisViewport, meta_eis_viewport, G_TYPE_OBJECT) + +static void +meta_eis_viewport_default_init (MetaEisViewportInterface *iface) +{ +} + +gboolean +meta_eis_viewport_is_standalone (MetaEisViewport *viewport) +{ + return META_EIS_VIEWPORT_GET_IFACE (viewport)->is_standalone (viewport); +} + +gboolean +meta_eis_viewport_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + return META_EIS_VIEWPORT_GET_IFACE (viewport)->get_position (viewport, + out_x, + out_y); +} + +void +meta_eis_viewport_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + META_EIS_VIEWPORT_GET_IFACE (viewport)->get_size (viewport, + out_width, + out_height); +} + +double +meta_eis_viewport_get_physical_scale (MetaEisViewport *viewport) +{ + return META_EIS_VIEWPORT_GET_IFACE (viewport)->get_physical_scale (viewport); +} + +gboolean +meta_eis_viewport_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + return META_EIS_VIEWPORT_GET_IFACE (viewport)->transform_coordinate (viewport, + x, + y, + out_x, + out_y); +} + MetaBackend * meta_eis_get_backend (MetaEis *eis) { diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index 8160222be3..fc48c60610 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -32,10 +32,39 @@ typedef enum _MetaEisDeviceTypes META_EIS_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, } MetaEisDeviceTypes; +#define META_TYPE_EIS_VIEWPORT (meta_eis_viewport_get_type ()) +G_DECLARE_INTERFACE (MetaEisViewport, meta_eis_viewport, + META, EIS_VIEWPORT, GObject) + #define META_TYPE_EIS (meta_eis_get_type ()) G_DECLARE_FINAL_TYPE (MetaEis, meta_eis, META, EIS, GObject) +struct _MetaEisViewportInterface +{ + GTypeInterface parent_iface; + + gboolean (* is_standalone) (MetaEisViewport *viewport); + + const char * (* get_mapping_id) (MetaEisViewport *viewport); + + gboolean (* get_position) (MetaEisViewport *viewport, + int *out_x, + int *out_y); + + void (* get_size) (MetaEisViewport *viewport, + int *out_width, + int *out_height); + + double (* get_physical_scale) (MetaEisViewport *viewport); + + gboolean (* transform_coordinate) (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y); +}; + MetaEis * meta_eis_new (MetaBackend *backend, MetaEisDeviceTypes device_types); @@ -44,3 +73,23 @@ MetaBackend * meta_eis_get_backend (MetaEis *eis); int meta_eis_add_client_get_fd (MetaEis *eis); MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); + +gboolean meta_eis_viewport_is_standalone (MetaEisViewport *viewport); + +const char * meta_eis_viewport_get_mapping_id (MetaEisViewport *viewport); + +gboolean meta_eis_viewport_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y); + +void meta_eis_viewport_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height); + +double meta_eis_viewport_get_physical_scale (MetaEisViewport *viewport); + +gboolean meta_eis_viewport_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y); From 5ecd2758055e956b5417e17ed9a13300c300dcb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 22:18:48 +0200 Subject: [PATCH 10/17] eis: Fix header include style --- src/backends/meta-eis-client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 84c6bab005..9d2074accc 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -20,11 +20,11 @@ #include "config.h" -#include "backends/meta-backend-private.h" #include "backends/meta-eis-client.h" + +#include "backends/meta-backend-private.h" #include "backends/meta-monitor-manager-private.h" #include "backends/meta-viewport-info.h" - #include "clutter/clutter-mutter.h" #include "core/meta-anonymous-file.h" From dfd4262a3f635c175bc6b6b0ad256c81432f3e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 29 Aug 2023 20:22:10 +0200 Subject: [PATCH 11/17] screen-cast: Pass remote desktop session on construction We already have the remote desktop session ID, and we'll soon need the actual remote desktop session in the screen cast session, so pass it on construction. The old screen cast type is set implicitly instead. --- src/backends/meta-backend-types.h | 1 + src/backends/meta-screen-cast-session.c | 44 +++++++++++++------ src/backends/meta-screen-cast-session.h | 3 ++ src/backends/meta-screen-cast.c | 57 +++++++++---------------- 4 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h index 134374d4ba..15244fb653 100644 --- a/src/backends/meta-backend-types.h +++ b/src/backends/meta-backend-types.h @@ -62,6 +62,7 @@ typedef struct _MetaRenderer MetaRenderer; typedef struct _MetaRendererView MetaRendererView; typedef struct _MetaRemoteDesktop MetaRemoteDesktop; +typedef struct _MetaRemoteDesktopSession MetaRemoteDesktopSession; typedef struct _MetaScreenCast MetaScreenCast; typedef struct _MetaScreenCastSession MetaScreenCastSession; typedef struct _MetaScreenCastStream MetaScreenCastStream; diff --git a/src/backends/meta-screen-cast-session.c b/src/backends/meta-screen-cast-session.c index e19cea47b6..2454f28386 100644 --- a/src/backends/meta-screen-cast-session.c +++ b/src/backends/meta-screen-cast-session.c @@ -26,6 +26,7 @@ #include "backends/meta-dbus-session-manager.h" #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-remote-access-controller-private.h" +#include "backends/meta-remote-desktop-session.h" #include "backends/meta-screen-cast-area-stream.h" #include "backends/meta-screen-cast-monitor-stream.h" #include "backends/meta-screen-cast-stream.h" @@ -41,7 +42,7 @@ enum { PROP_0, - PROP_SESSION_TYPE, + PROP_REMOTE_DESKTOP_SESSION, N_PROPS }; @@ -66,6 +67,8 @@ struct _MetaScreenCastSession gboolean is_active; gboolean disable_animations; + + MetaRemoteDesktopSession *remote_desktop_session; }; static void initable_init_iface (GInitableIface *iface); @@ -230,6 +233,12 @@ meta_screen_cast_session_get_session_type (MetaScreenCastSession *session) return session->session_type; } +MetaRemoteDesktopSession * +meta_screen_cast_session_get_remote_desktop_session (MetaScreenCastSession *session) +{ + return session->remote_desktop_session; +} + static gboolean check_permission (MetaScreenCastSession *session, GDBusMethodInvocation *invocation) @@ -248,6 +257,14 @@ meta_screen_cast_session_initable_init (GInitable *initable, GDBusConnection *connection; static unsigned int global_session_number = 0; + if (session->remote_desktop_session) + { + if (!meta_remote_desktop_session_register_screen_cast (session->remote_desktop_session, + session, + error)) + return FALSE; + } + session->object_path = g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u", ++global_session_number); @@ -799,8 +816,12 @@ meta_screen_cast_session_set_property (GObject *object, switch (prop_id) { - case PROP_SESSION_TYPE: - session->session_type = g_value_get_enum (value); + case PROP_REMOTE_DESKTOP_SESSION: + session->remote_desktop_session = g_value_get_object (value); + if (session->remote_desktop_session) + session->session_type = META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP; + else + session->session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL; break; case N_PROPS + META_DBUS_SESSION_PROP_SESSION_MANAGER: @@ -828,8 +849,8 @@ meta_screen_cast_session_get_property (GObject *object, switch (prop_id) { - case PROP_SESSION_TYPE: - g_value_set_enum (value, session->session_type); + case PROP_REMOTE_DESKTOP_SESSION: + g_value_set_object (value, session->remote_desktop_session); break; case N_PROPS + META_DBUS_SESSION_PROP_SESSION_MANAGER: @@ -861,13 +882,12 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass) object_class->set_property = meta_screen_cast_session_set_property; object_class->get_property = meta_screen_cast_session_get_property; - obj_props[PROP_SESSION_TYPE] = - g_param_spec_enum ("session-type", NULL, NULL, - META_TYPE_SCREEN_CAST_SESSION_TYPE, - META_SCREEN_CAST_SESSION_TYPE_NORMAL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + obj_props[PROP_REMOTE_DESKTOP_SESSION] = + g_param_spec_object ("remote-desktop-session", NULL, NULL, + META_TYPE_REMOTE_DESKTOP_SESSION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); meta_dbus_session_install_properties (object_class, N_PROPS); } diff --git a/src/backends/meta-screen-cast-session.h b/src/backends/meta-screen-cast-session.h index ee8514ea32..765fc3cb99 100644 --- a/src/backends/meta-screen-cast-session.h +++ b/src/backends/meta-screen-cast-session.h @@ -22,6 +22,7 @@ #include "backends/meta-screen-cast.h" +#include "backends/meta-backend-types.h" #include "backends/meta-screen-cast-stream.h" #include "meta/meta-remote-access-controller.h" @@ -48,6 +49,8 @@ char * meta_screen_cast_session_get_peer_name (MetaScreenCastSession *session); MetaScreenCastSessionType meta_screen_cast_session_get_session_type (MetaScreenCastSession *session); +MetaRemoteDesktopSession * meta_screen_cast_session_get_remote_desktop_session (MetaScreenCastSession *session); + gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, GError **error); diff --git a/src/backends/meta-screen-cast.c b/src/backends/meta-screen-cast.c index 904363ed32..786074b89c 100644 --- a/src/backends/meta-screen-cast.c +++ b/src/backends/meta-screen-cast.c @@ -93,22 +93,17 @@ meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast, return dmabuf_handle; } -static gboolean -register_remote_desktop_screen_cast_session (MetaScreenCastSession *session, - const char *remote_desktop_session_id, - GError **error) +static MetaRemoteDesktopSession * +find_remote_desktop_session (MetaDbusSessionManager *session_manager, + const char *remote_desktop_session_id, + GError **error) { - MetaScreenCast *screen_cast = - meta_screen_cast_session_get_screen_cast (session); - MetaDbusSessionManager *session_manager = - META_DBUS_SESSION_MANAGER (screen_cast); MetaBackend *backend = meta_dbus_session_manager_get_backend (session_manager); MetaRemoteDesktop *remote_desktop = meta_backend_get_remote_desktop (backend); MetaDbusSessionManager *remote_desktop_session_manager = META_DBUS_SESSION_MANAGER (remote_desktop); MetaDbusSession *remote_desktop_dbus_session; - MetaRemoteDesktopSession *remote_desktop_session; remote_desktop_dbus_session = meta_dbus_session_manager_get_session (remote_desktop_session_manager, @@ -117,17 +112,10 @@ register_remote_desktop_screen_cast_session (MetaScreenCastSession *session, { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No remote desktop session found"); - return FALSE; + return NULL; } - remote_desktop_session = - META_REMOTE_DESKTOP_SESSION (remote_desktop_dbus_session); - if (!meta_remote_desktop_session_register_screen_cast (remote_desktop_session, - session, - error)) - return FALSE; - - return TRUE; + return META_REMOTE_DESKTOP_SESSION (remote_desktop_dbus_session); } static gboolean @@ -139,7 +127,7 @@ handle_create_session (MetaDBusScreenCast *skeleton, MetaDbusSessionManager *session_manager = META_DBUS_SESSION_MANAGER (screen_cast); char *remote_desktop_session_id = NULL; - MetaScreenCastSessionType session_type; + MetaRemoteDesktopSession *remote_desktop_session = NULL; MetaDbusSession *dbus_session; MetaScreenCastSession *session; g_autoptr (GError) error = NULL; @@ -150,15 +138,24 @@ handle_create_session (MetaDBusScreenCast *skeleton, &remote_desktop_session_id); if (remote_desktop_session_id) - session_type = META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP; - else - session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL; + { + remote_desktop_session = find_remote_desktop_session (session_manager, + remote_desktop_session_id, + &error); + if (!remote_desktop_session) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "%s", error->message); + return G_DBUS_METHOD_INVOCATION_HANDLED; + } + } dbus_session = meta_dbus_session_manager_create_session (session_manager, invocation, &error, - "session-type", session_type, + "remote-desktop-session", remote_desktop_session, NULL); if (!dbus_session) { @@ -169,20 +166,6 @@ handle_create_session (MetaDBusScreenCast *skeleton, } session = META_SCREEN_CAST_SESSION (dbus_session); - if (remote_desktop_session_id) - { - if (!register_remote_desktop_screen_cast_session (session, - remote_desktop_session_id, - &error)) - { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, - G_DBUS_ERROR_FAILED, - "%s", error->message); - meta_dbus_session_close (dbus_session); - return G_DBUS_METHOD_INVOCATION_HANDLED; - } - } - if (g_variant_lookup (properties, "disable-animations", "b", &disable_animations)) { From cac54fa694968d0dfcaa57d797ef54daae731e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 29 Aug 2023 20:28:24 +0200 Subject: [PATCH 12/17] eis: Tear down in dispose This means clients can disconnect signals without warnings being logged. --- src/backends/meta-eis.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 905da3f6ce..5f20c682e2 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -323,7 +323,7 @@ meta_eis_init (MetaEis *eis) } static void -meta_eis_finalize (GObject *object) +meta_eis_dispose (GObject *object) { MetaEis *eis = META_EIS (object); @@ -331,7 +331,7 @@ meta_eis_finalize (GObject *object) g_clear_pointer (&eis->eis, eis_unref); g_clear_pointer (&eis->eis_clients, g_hash_table_destroy); - G_OBJECT_CLASS (meta_eis_parent_class)->finalize (object); + G_OBJECT_CLASS (meta_eis_parent_class)->dispose (object); } static void @@ -339,7 +339,7 @@ meta_eis_class_init (MetaEisClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = meta_eis_finalize; + object_class->dispose = meta_eis_dispose; } MetaEisDeviceTypes From 44e11a1e9b6a0154cf62e2d836a72b7f7fedae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 29 Aug 2023 20:31:30 +0200 Subject: [PATCH 13/17] remote-desktop/session: Add API to acquire new mapping ID They are guaranteed to be unique per session, and never reused. --- src/backends/meta-remote-desktop-session.c | 25 ++++++++++++++++++++++ src/backends/meta-remote-desktop-session.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index 9b6de2e70b..c3addd34dc 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -102,6 +102,8 @@ struct _MetaRemoteDesktopSession MetaSelectionSourceRemote *current_source; GHashTable *transfer_requests; guint transfer_request_timeout_id; + + GHashTable *mapping_ids; }; static void initable_init_iface (GInitableIface *iface); @@ -296,6 +298,25 @@ meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *ses return TRUE; } +const char * +meta_remote_desktop_session_acquire_mapping_id (MetaRemoteDesktopSession *session) +{ + while (TRUE) + { + char *mapping_id; + + mapping_id = g_uuid_string_random (); + if (g_hash_table_contains (session->mapping_ids, mapping_id)) + { + g_free (mapping_id); + continue; + } + + g_hash_table_add (session->mapping_ids, mapping_id); + return mapping_id; + } +} + static gboolean check_permission (MetaRemoteDesktopSession *session, GDBusMethodInvocation *invocation) @@ -1730,6 +1751,8 @@ meta_remote_desktop_session_initable_init (GInitable *initable, session, "num-lock-state", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); + session->mapping_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + return TRUE; } @@ -1783,6 +1806,8 @@ meta_remote_desktop_session_finalize (GObject *object) cancel_selection_read (session); g_hash_table_unref (session->transfer_requests); + g_clear_pointer (&session->mapping_ids, g_hash_table_unref); + g_clear_object (&session->handle); g_free (session->peer_name); g_free (session->session_id); diff --git a/src/backends/meta-remote-desktop-session.h b/src/backends/meta-remote-desktop-session.h index efbe127308..6555fc3100 100644 --- a/src/backends/meta-remote-desktop-session.h +++ b/src/backends/meta-remote-desktop-session.h @@ -42,6 +42,8 @@ gboolean meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSess MetaScreenCastSession *screen_cast_session, GError **error); +const char * meta_remote_desktop_session_acquire_mapping_id (MetaRemoteDesktopSession *session); + void meta_remote_desktop_session_request_transfer (MetaRemoteDesktopSession *session, const char *mime_type, GTask *task); From 51e2a434ee9b989747b36091fa9ea73189e680df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 29 Aug 2023 20:34:05 +0200 Subject: [PATCH 14/17] screen-cast: Implement MetaEisViewport in all stream types This will be used to describe a eis_region in a eis_device. --- src/backends/meta-screen-cast-area-stream.c | 93 ++++++++++++++- .../meta-screen-cast-monitor-stream.c | 86 +++++++++++++- src/backends/meta-screen-cast-stream.c | 28 +++++ src/backends/meta-screen-cast-stream.h | 1 + .../meta-screen-cast-virtual-stream-src.c | 12 ++ .../meta-screen-cast-virtual-stream-src.h | 2 + .../meta-screen-cast-virtual-stream.c | 106 +++++++++++++++++- src/backends/meta-screen-cast-window-stream.c | 78 ++++++++++++- 8 files changed, 393 insertions(+), 13 deletions(-) diff --git a/src/backends/meta-screen-cast-area-stream.c b/src/backends/meta-screen-cast-area-stream.c index f2995f12f1..84b2184631 100644 --- a/src/backends/meta-screen-cast-area-stream.c +++ b/src/backends/meta-screen-cast-area-stream.c @@ -20,6 +20,7 @@ #include "backends/meta-screen-cast-area-stream.h" +#include "backends/meta-eis.h" #include "backends/meta-screen-cast-area-stream-src.h" struct _MetaScreenCastAreaStream @@ -32,9 +33,13 @@ struct _MetaScreenCastAreaStream float scale; }; -G_DEFINE_TYPE (MetaScreenCastAreaStream, - meta_screen_cast_area_stream, - META_TYPE_SCREEN_CAST_STREAM) +static void meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastAreaStream, + meta_screen_cast_area_stream, + META_TYPE_SCREEN_CAST_STREAM, + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_iface_init)) ClutterStage * meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream) @@ -116,6 +121,85 @@ meta_screen_cast_area_stream_new (MetaScreenCastSession *session, return area_stream; } +static gboolean +meta_screen_cast_area_stream_is_standalone (MetaEisViewport *viewport) +{ + return TRUE; +} + +static const char * +meta_screen_cast_area_stream_get_mapping_id (MetaEisViewport *viewport) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (viewport); + + return meta_screen_cast_stream_get_mapping_id (stream); +} + +static gboolean +meta_screen_cast_area_stream_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + return FALSE; +} + +static void +meta_screen_cast_area_stream_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaScreenCastAreaStream *area_stream = + META_SCREEN_CAST_AREA_STREAM (viewport); + + *out_width = (int) roundf (area_stream->area.width * area_stream->scale); + *out_height = (int) roundf (area_stream->area.height * area_stream->scale); +} + +static double +meta_screen_cast_area_stream_get_physical_scale (MetaEisViewport *viewport) +{ + MetaScreenCastAreaStream *area_stream = + META_SCREEN_CAST_AREA_STREAM (viewport); + + return area_stream->scale; +} + +static void +transform_position (MetaScreenCastAreaStream *area_stream, + double x, + double y, + double *out_x, + double *out_y) +{ + *out_x = area_stream->area.x + (int) roundf (x / area_stream->scale); + *out_y = area_stream->area.y + (int) roundf (y / area_stream->scale); +} + +static gboolean +meta_screen_cast_area_stream_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + MetaScreenCastAreaStream *area_stream = + META_SCREEN_CAST_AREA_STREAM (viewport); + + transform_position (area_stream, x, y, out_x, out_y); + return TRUE; +} + +static void +meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_screen_cast_area_stream_is_standalone; + eis_viewport_iface->get_mapping_id = meta_screen_cast_area_stream_get_mapping_id; + eis_viewport_iface->get_position = meta_screen_cast_area_stream_get_position; + eis_viewport_iface->get_size = meta_screen_cast_area_stream_get_size; + eis_viewport_iface->get_physical_scale = meta_screen_cast_area_stream_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_screen_cast_area_stream_transform_coordinate; +} + static MetaScreenCastStreamSrc * meta_screen_cast_area_stream_create_src (MetaScreenCastStream *stream, GError **error) @@ -156,8 +240,7 @@ meta_screen_cast_area_stream_transform_position (MetaScreenCastStream *stream, MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream); - *x = area_stream->area.x + (int) roundf (stream_x / area_stream->scale); - *y = area_stream->area.y + (int) roundf (stream_y / area_stream->scale); + transform_position (area_stream, stream_x, stream_y, x, y); return TRUE; } diff --git a/src/backends/meta-screen-cast-monitor-stream.c b/src/backends/meta-screen-cast-monitor-stream.c index 88015a6aad..c3f6f52e53 100644 --- a/src/backends/meta-screen-cast-monitor-stream.c +++ b/src/backends/meta-screen-cast-monitor-stream.c @@ -22,6 +22,7 @@ #include "backends/meta-screen-cast-monitor-stream.h" +#include "backends/meta-eis.h" #include "backends/meta-logical-monitor.h" #include "backends/meta-screen-cast-monitor-stream-src.h" @@ -42,9 +43,13 @@ struct _MetaScreenCastMonitorStream MetaLogicalMonitor *logical_monitor; }; -G_DEFINE_TYPE (MetaScreenCastMonitorStream, - meta_screen_cast_monitor_stream, - META_TYPE_SCREEN_CAST_STREAM) +static void meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastMonitorStream, + meta_screen_cast_monitor_stream, + META_TYPE_SCREEN_CAST_STREAM, + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_iface_init)) static gboolean update_monitor (MetaScreenCastMonitorStream *monitor_stream, @@ -214,6 +219,81 @@ meta_screen_cast_monitor_stream_transform_position (MetaScreenCastStream *stream return TRUE; } +static gboolean +meta_screen_cast_monitor_stream_is_standalone (MetaEisViewport *viewport) +{ + return FALSE; +} + +static const char * +meta_screen_cast_monitor_stream_get_mapping_id (MetaEisViewport *viewport) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (viewport); + + return meta_screen_cast_stream_get_mapping_id (stream); +} + +static gboolean +meta_screen_cast_monitor_stream_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (viewport); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (monitor_stream->logical_monitor); + *out_x = layout.x; + *out_y = layout.y; + return TRUE; +} + +static void +meta_screen_cast_monitor_stream_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (viewport); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (monitor_stream->logical_monitor); + *out_width = layout.width; + *out_height = layout.height; +} + +static double +meta_screen_cast_monitor_stream_get_physical_scale (MetaEisViewport *viewport) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (viewport); + + return meta_logical_monitor_get_scale (monitor_stream->logical_monitor); +} + +static gboolean +meta_screen_cast_monitor_stream_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + *out_x = x; + *out_y = y; + return TRUE; +} + +static void +meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_screen_cast_monitor_stream_is_standalone; + eis_viewport_iface->get_mapping_id = meta_screen_cast_monitor_stream_get_mapping_id; + eis_viewport_iface->get_position = meta_screen_cast_monitor_stream_get_position; + eis_viewport_iface->get_size = meta_screen_cast_monitor_stream_get_size; + eis_viewport_iface->get_physical_scale = meta_screen_cast_monitor_stream_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_screen_cast_monitor_stream_transform_coordinate; +} + static void meta_screen_cast_monitor_stream_set_property (GObject *object, guint prop_id, diff --git a/src/backends/meta-screen-cast-stream.c b/src/backends/meta-screen-cast-stream.c index 7417fcc691..3176e5ae1c 100644 --- a/src/backends/meta-screen-cast-stream.c +++ b/src/backends/meta-screen-cast-stream.c @@ -22,6 +22,7 @@ #include "backends/meta-screen-cast-stream.h" +#include "backends/meta-remote-desktop-session.h" #include "backends/meta-screen-cast-session.h" #include "meta-private-enum-types.h" @@ -59,6 +60,8 @@ typedef struct _MetaScreenCastStreamPrivate MetaScreenCastFlag flags; MetaScreenCastStreamSrc *src; + + char *mapping_id; } MetaScreenCastStreamPrivate; static void @@ -217,6 +220,15 @@ meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream) return priv->flags; } +const char * +meta_screen_cast_stream_get_mapping_id (MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + return priv->mapping_id; +} + static void meta_screen_cast_stream_set_property (GObject *object, guint prop_id, @@ -286,6 +298,7 @@ meta_screen_cast_stream_finalize (GObject *object) meta_screen_cast_stream_close (stream); g_clear_pointer (&priv->object_path, g_free); + g_clear_pointer (&priv->mapping_id, g_free); G_OBJECT_CLASS (meta_screen_cast_stream_parent_class)->finalize (object); } @@ -358,6 +371,7 @@ meta_screen_cast_stream_initable_init (GInitable *initable, MetaDBusScreenCastStream *skeleton = META_DBUS_SCREEN_CAST_STREAM (stream); MetaScreenCastStreamPrivate *priv = meta_screen_cast_stream_get_instance_private (stream); + MetaRemoteDesktopSession *remote_desktop_session; GVariantBuilder parameters_builder; GVariant *parameters_variant; static unsigned int global_stream_number = 0; @@ -365,6 +379,20 @@ meta_screen_cast_stream_initable_init (GInitable *initable, g_variant_builder_init (¶meters_builder, G_VARIANT_TYPE_VARDICT); meta_screen_cast_stream_set_parameters (stream, ¶meters_builder); + remote_desktop_session = + meta_screen_cast_session_get_remote_desktop_session (priv->session); + if (remote_desktop_session) + { + const char *mapping_id; + + mapping_id = + meta_remote_desktop_session_acquire_mapping_id (remote_desktop_session); + priv->mapping_id = g_strdup (mapping_id); + g_variant_builder_add (¶meters_builder, "{sv}", + "mapping-id", + g_variant_new ("s", priv->mapping_id)); + } + parameters_variant = g_variant_builder_end (¶meters_builder); meta_dbus_screen_cast_stream_set_parameters (skeleton, parameters_variant); diff --git a/src/backends/meta-screen-cast-stream.h b/src/backends/meta-screen-cast-stream.h index 7e966c9962..dd85b069fb 100644 --- a/src/backends/meta-screen-cast-stream.h +++ b/src/backends/meta-screen-cast-stream.h @@ -68,3 +68,4 @@ MetaScreenCastCursorMode meta_screen_cast_stream_get_cursor_mode (MetaScreenCast MetaScreenCastFlag meta_screen_cast_stream_get_flags (MetaScreenCastStream *stream); +const char * meta_screen_cast_stream_get_mapping_id (MetaScreenCastStream *stream); diff --git a/src/backends/meta-screen-cast-virtual-stream-src.c b/src/backends/meta-screen-cast-virtual-stream-src.c index e2517a23a5..5bad18232e 100644 --- a/src/backends/meta-screen-cast-virtual-stream-src.c +++ b/src/backends/meta-screen-cast-virtual-stream-src.c @@ -22,6 +22,8 @@ #include "backends/meta-crtc-mode.h" #include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-monitor.h" +#include "backends/meta-output.h" #include "backends/meta-screen-cast-session.h" #include "backends/meta-stage-private.h" #include "backends/meta-virtual-monitor.h" @@ -108,6 +110,16 @@ meta_screen_cast_virtual_stream_src_get_view (MetaScreenCastVirtualStreamSrc *vi return view_from_src (META_SCREEN_CAST_STREAM_SRC (virtual_src)); } +MetaLogicalMonitor * +meta_screen_cast_virtual_stream_src_logical_monitor (MetaScreenCastVirtualStreamSrc *virtual_src) +{ + MetaVirtualMonitor *virtual_monitor = virtual_src->virtual_monitor; + MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor); + MetaMonitor *monitor = meta_output_get_monitor (output); + + return meta_monitor_get_logical_monitor (monitor); +} + static void sync_cursor_state (MetaScreenCastVirtualStreamSrc *virtual_src) { diff --git a/src/backends/meta-screen-cast-virtual-stream-src.h b/src/backends/meta-screen-cast-virtual-stream-src.h index d46f8bafa1..075d727e4f 100644 --- a/src/backends/meta-screen-cast-virtual-stream-src.h +++ b/src/backends/meta-screen-cast-virtual-stream-src.h @@ -31,3 +31,5 @@ MetaScreenCastVirtualStreamSrc * meta_screen_cast_virtual_stream_src_new (MetaSc GError **error); ClutterStageView * meta_screen_cast_virtual_stream_src_get_view (MetaScreenCastVirtualStreamSrc *virtual_src); + +MetaLogicalMonitor * meta_screen_cast_virtual_stream_src_logical_monitor (MetaScreenCastVirtualStreamSrc *virtual_src); diff --git a/src/backends/meta-screen-cast-virtual-stream.c b/src/backends/meta-screen-cast-virtual-stream.c index e049869eec..ea4c57e5f7 100644 --- a/src/backends/meta-screen-cast-virtual-stream.c +++ b/src/backends/meta-screen-cast-virtual-stream.c @@ -20,18 +20,23 @@ #include "backends/meta-screen-cast-virtual-stream.h" +#include "backends/meta-eis.h" +#include "backends/meta-logical-monitor.h" #include "backends/meta-screen-cast-virtual-stream-src.h" #include "backends/meta-virtual-monitor.h" - struct _MetaScreenCastVirtualStream { MetaScreenCastStream parent; }; -G_DEFINE_TYPE (MetaScreenCastVirtualStream, - meta_screen_cast_virtual_stream, - META_TYPE_SCREEN_CAST_STREAM) +static void meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastVirtualStream, + meta_screen_cast_virtual_stream, + META_TYPE_SCREEN_CAST_STREAM, + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_iface_init)) MetaScreenCastVirtualStream * meta_screen_cast_virtual_stream_new (MetaScreenCastSession *session, @@ -56,6 +61,99 @@ meta_screen_cast_virtual_stream_new (MetaScreenCastSession *session, return virtual_stream; } +static gboolean +meta_screen_cast_virtual_stream_is_standalone (MetaEisViewport *viewport) +{ + return FALSE; +} + +static const char * +meta_screen_cast_virtual_stream_get_mapping_id (MetaEisViewport *viewport) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (viewport); + + return meta_screen_cast_stream_get_mapping_id (stream); +} + +static gboolean +meta_screen_cast_virtual_stream_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + MetaScreenCastVirtualStream *virtual_stream = + META_SCREEN_CAST_VIRTUAL_STREAM (viewport); + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (virtual_stream); + MetaScreenCastStreamSrc *src = meta_screen_cast_stream_get_src (stream); + MetaScreenCastVirtualStreamSrc *virtual_src = + META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src); + MetaLogicalMonitor *logical_monitor = + meta_screen_cast_virtual_stream_src_logical_monitor (virtual_src); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor); + *out_x = layout.x; + *out_y = layout.y; + return TRUE; +} + +static void +meta_screen_cast_virtual_stream_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaScreenCastVirtualStream *virtual_stream = + META_SCREEN_CAST_VIRTUAL_STREAM (viewport); + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (virtual_stream); + MetaScreenCastStreamSrc *src = meta_screen_cast_stream_get_src (stream); + MetaScreenCastVirtualStreamSrc *virtual_src = + META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src); + MetaLogicalMonitor *logical_monitor = + meta_screen_cast_virtual_stream_src_logical_monitor (virtual_src); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor); + *out_width = layout.width; + *out_height = layout.height; +} + +static double +meta_screen_cast_virtual_stream_get_physical_scale (MetaEisViewport *viewport) +{ + MetaScreenCastVirtualStream *virtual_stream = + META_SCREEN_CAST_VIRTUAL_STREAM (viewport); + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (virtual_stream); + MetaScreenCastStreamSrc *src = meta_screen_cast_stream_get_src (stream); + MetaScreenCastVirtualStreamSrc *virtual_src = + META_SCREEN_CAST_VIRTUAL_STREAM_SRC (src); + MetaLogicalMonitor *logical_monitor = + meta_screen_cast_virtual_stream_src_logical_monitor (virtual_src); + + return meta_logical_monitor_get_scale (logical_monitor); +} + +static gboolean +meta_screen_cast_virtual_stream_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + *out_x = x; + *out_y = y; + return TRUE; +} + +static void +meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_screen_cast_virtual_stream_is_standalone; + eis_viewport_iface->get_mapping_id = meta_screen_cast_virtual_stream_get_mapping_id; + eis_viewport_iface->get_position = meta_screen_cast_virtual_stream_get_position; + eis_viewport_iface->get_size = meta_screen_cast_virtual_stream_get_size; + eis_viewport_iface->get_physical_scale = meta_screen_cast_virtual_stream_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_screen_cast_virtual_stream_transform_coordinate; +} + static MetaScreenCastStreamSrc * meta_screen_cast_virtual_stream_create_src (MetaScreenCastStream *stream, GError **error) diff --git a/src/backends/meta-screen-cast-window-stream.c b/src/backends/meta-screen-cast-window-stream.c index 8cde039140..1c53497146 100644 --- a/src/backends/meta-screen-cast-window-stream.c +++ b/src/backends/meta-screen-cast-window-stream.c @@ -20,6 +20,7 @@ #include "backends/meta-screen-cast-window-stream.h" +#include "backends/meta-eis.h" #include "backends/meta-logical-monitor.h" #include "backends/meta-monitor-manager-private.h" #include "backends/meta-screen-cast-session.h" @@ -54,11 +55,15 @@ static GInitableIface *initable_parent_iface; static void meta_screen_cast_window_stream_init_initable_iface (GInitableIface *iface); +static void meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface); + G_DEFINE_TYPE_WITH_CODE (MetaScreenCastWindowStream, meta_screen_cast_window_stream, META_TYPE_SCREEN_CAST_STREAM, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - meta_screen_cast_window_stream_init_initable_iface)) + meta_screen_cast_window_stream_init_initable_iface) + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_iface_init)) MetaWindow * meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream) @@ -271,6 +276,77 @@ meta_screen_cast_window_stream_init_initable_iface (GInitableIface *iface) iface->init = meta_screen_cast_window_stream_initable_init; } +static gboolean +meta_screen_cast_window_stream_is_standalone (MetaEisViewport *viewport) +{ + return TRUE; +} + +static const char * +meta_screen_cast_window_stream_get_mapping_id (MetaEisViewport *viewport) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (viewport); + + return meta_screen_cast_stream_get_mapping_id (stream); +} + +static gboolean +meta_screen_cast_window_stream_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + return FALSE; +} + +static void +meta_screen_cast_window_stream_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (viewport); + + *out_width = window_stream->stream_width; + *out_height = window_stream->stream_height; +} + +static double +meta_screen_cast_window_stream_get_physical_scale (MetaEisViewport *viewport) +{ + return 1.0; +} + +static gboolean +meta_screen_cast_window_stream_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (viewport); + MetaScreenCastWindow *screen_cast_window = + META_SCREEN_CAST_WINDOW (meta_window_actor_from_window (window_stream->window)); + + meta_screen_cast_window_transform_relative_position (screen_cast_window, + x, + y, + out_x, + out_y); + return TRUE; +} + +static void +meta_eis_viewport_iface_init (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_screen_cast_window_stream_is_standalone; + eis_viewport_iface->get_mapping_id = meta_screen_cast_window_stream_get_mapping_id; + eis_viewport_iface->get_position = meta_screen_cast_window_stream_get_position; + eis_viewport_iface->get_size = meta_screen_cast_window_stream_get_size; + eis_viewport_iface->get_physical_scale = meta_screen_cast_window_stream_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_screen_cast_window_stream_transform_coordinate; +} + static void meta_screen_cast_window_stream_init (MetaScreenCastWindowStream *window_stream) { From a327c23e13172b163a533e143c3aa9cb6078e932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 28 Aug 2023 23:13:16 +0200 Subject: [PATCH 15/17] eis: Use either standalone or shared devices for absolute input Sometimes it makes no sense to have a shared pointer device, for example when they have no set region occupying the global stage coordinate space. This applies to for example window screen cast based pointer device regions - they are always local to the window, and have no position. We do need shared absolute devices in some cases though, primarily multi-head remote desktop, where it must be possible to keep a button reliably pressed when crossing monitors that have their own corresponding regions. To handle this, outsource all this policy to the one who drives the emulated input devices. Remote desktop sessions where the screen casts correspond to specific monitors (physical or virtual), we need to make sure they map to the stage coordinate space, while for window screencast or area screencasts, we create standalone absolute pointer devices with a single region each. --- src/backends/meta-eis-client.c | 237 +++++++++++++++------ src/backends/meta-eis.c | 48 +++++ src/backends/meta-eis.h | 8 + src/backends/meta-remote-desktop-session.c | 57 +++++ src/backends/meta-screen-cast-session.c | 48 ++++- src/backends/meta-screen-cast-session.h | 2 + 6 files changed, 330 insertions(+), 70 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 9d2074accc..ec67c67ddd 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -24,7 +24,6 @@ #include "backends/meta-backend-private.h" #include "backends/meta-monitor-manager-private.h" -#include "backends/meta-viewport-info.h" #include "clutter/clutter-mutter.h" #include "core/meta-anonymous-file.h" @@ -38,6 +37,8 @@ struct _MetaEisDevice struct eis_device *eis_device; ClutterVirtualInputDevice *device; + MetaEisViewport *viewport; + guchar button_state[(MAX_BUTTON + 7) / 8]; guchar key_state[(MAX_KEY + 7) / 8]; }; @@ -47,11 +48,12 @@ struct _MetaEisClient GObject parent_instance; MetaEis *eis; - MetaViewportInfo *viewports; struct eis_client *eis_client; struct eis_seat *eis_seat; GHashTable *eis_devices; /* eis_device => MetaEisDevice*/ + + gulong viewports_changed_handler_id; }; G_DEFINE_TYPE (MetaEisClient, meta_eis_client, G_TYPE_OBJECT) @@ -219,34 +221,94 @@ configure_keyboard (MetaEisClient *client, } } -static void -configure_abs (MetaEisClient *client, - struct eis_device *eis_device, - gpointer user_data) +static gboolean +has_region (struct eis_device *eis_device, + int x, + int y, + int width, + int height) { - int idx = 0; - cairo_rectangle_int_t rect; - float scale; + int i = 0; - if (!client->viewports) - return; /* FIXME: should be an error */ + while (TRUE) + { + struct eis_region *region; + + region = eis_device_get_region (eis_device, i); + if (!region) + return FALSE; + + if (eis_region_get_x (region) == x && + eis_region_get_y (region) == y && + eis_region_get_width (region) == width && + eis_region_get_height (region) == height) + return TRUE; + } +} + +static void +add_viewport_region (struct eis_device *eis_device, + MetaEisViewport *viewport) +{ + gboolean has_position; + int x, y; + int width, height; + double scale; + const char *mapping_id; + struct eis_region *eis_region; + + if (meta_eis_viewport_get_position (viewport, &x, &y)) + has_position = TRUE; + meta_eis_viewport_get_size (viewport, &width, &height); + scale = meta_eis_viewport_get_physical_scale (viewport); + + if (has_region (eis_device, x, y, width, height)) + return; + + eis_region = eis_device_new_region (eis_device); + if (has_position) + eis_region_set_offset (eis_region, x, y); + eis_region_set_size (eis_region, width, height); + eis_region_set_physical_scale (eis_region, scale); + + mapping_id = meta_eis_viewport_get_mapping_id (viewport); + g_warn_if_fail (mapping_id); + eis_region_set_mapping_id (eis_region, mapping_id); + + eis_region_set_user_data (eis_region, viewport); + eis_region_add (eis_region); + eis_region_unref (eis_region); +} + +static void +configure_abs_shared (MetaEisClient *client, + struct eis_device *eis_device, + gpointer user_data) +{ + MetaEisViewport *viewport = META_EIS_VIEWPORT (user_data); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_BUTTON); eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_SCROLL); - while (meta_viewport_info_get_view_info (client->viewports, idx++, &rect, &scale)) - { - struct eis_region *r = eis_device_new_region (eis_device); - eis_region_set_offset (r, rect.x, rect.y); - eis_region_set_size (r, rect.width, rect.height); - eis_region_set_physical_scale (r, scale); - eis_region_add (r); - eis_region_unref (r); - } + add_viewport_region (eis_device, viewport); } static void +configure_abs_standalone (MetaEisClient *client, + struct eis_device *eis_device, + gpointer user_data) +{ + MetaEisViewport *viewport = META_EIS_VIEWPORT (user_data); + + eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_POINTER_ABSOLUTE); + eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_BUTTON); + eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_SCROLL); + + add_viewport_region (eis_device, viewport); +} + +static MetaEisDevice * add_device (MetaEisClient *client, struct eis_seat *eis_seat, ClutterInputDeviceType type, @@ -281,6 +343,8 @@ add_device (MetaEisClient *client, eis_device_add (eis_device); eis_device_resume (eis_device); g_free (name); + + return device; } static void @@ -299,16 +363,43 @@ handle_motion_relative (MetaEisClient *client, dx, dy); } +static MetaEisViewport * +find_viewport (struct eis_event *event) +{ + struct eis_device *eis_device = eis_event_get_device (event); + MetaEisDevice *device = eis_device_get_user_data (eis_device); + double x, y; + struct eis_region *region; + + if (device->viewport) + return device->viewport; + + x = eis_event_pointer_get_absolute_x (event); + y = eis_event_pointer_get_absolute_y (event); + region = eis_device_get_region_at (eis_device, x, y); + if (!region) + return NULL; + + return META_EIS_VIEWPORT (eis_region_get_user_data (region)); +} + static void handle_motion_absolute (MetaEisClient *client, struct eis_event *event) { struct eis_device *eis_device = eis_event_get_device (event); MetaEisDevice *device = eis_device_get_user_data (eis_device); + MetaEisViewport *viewport; double x, y; + viewport = find_viewport (event); + if (!viewport) + return; + x = eis_event_pointer_get_absolute_x (event); y = eis_event_pointer_get_absolute_y (event); + if (!meta_eis_viewport_transform_coordinate (viewport, x, y, &x, &y)) + return; clutter_virtual_input_device_notify_absolute_motion (device->device, g_get_monotonic_time (), @@ -529,6 +620,52 @@ on_keymap_changed (MetaBackend *backend, configure_keyboard, NULL); } +static void +add_abs_pointer_devices (MetaEisClient *client) +{ + MetaEisDevice *shared_device = NULL; + GList *viewports; + GList *l; + + viewports = meta_eis_peek_viewports (client->eis); + if (!viewports) + return; /* FIXME: should be an error */ + + for (l = viewports; l; l = l->next) + { + MetaEisViewport *viewport = l->data; + + if (meta_eis_viewport_is_standalone (viewport)) + { + MetaEisDevice *device; + + device = add_device (client, + client->eis_seat, + CLUTTER_POINTER_DEVICE, + "standalone virtual absolute pointer", + configure_abs_standalone, + viewport); + device->viewport = viewport; + } + else + { + if (!shared_device) + { + shared_device = add_device (client, + client->eis_seat, + CLUTTER_POINTER_DEVICE, + "shared virtual absolute pointer", + configure_abs_shared, + viewport); + } + else + { + add_viewport_region (shared_device->eis_device, viewport); + } + } + } +} + gboolean meta_eis_client_process_event (MetaEisClient *client, struct eis_event *event) @@ -561,15 +698,8 @@ meta_eis_client_process_event (MetaEisClient *client, G_CALLBACK (on_keymap_changed), client); } - if (eis_event_seat_has_capability (event, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) - { - add_device (client, - eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual absolute pointer", - configure_abs, - NULL); - } + + add_abs_pointer_devices (client); break; /* We only have one seat, so if the client unbinds from that @@ -630,52 +760,30 @@ drop_abs_devices (gpointer key, } static void -meta_eis_client_set_viewports (MetaEisClient *client, - MetaViewportInfo *viewports) +update_viewports (MetaEisClient *client) { - /* Updating viewports means we have to recreate our absolute pointer - * devices. */ - g_hash_table_foreach_remove (client->eis_devices, drop_abs_devices, client); - - g_clear_object (&client->viewports); - client->viewports = g_object_ref (viewports); - - add_device (client, - client->eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual absolute pointer", - configure_abs, - NULL); + add_abs_pointer_devices (client); } static void -on_monitors_changed (MetaMonitorManager *monitor_manager, - MetaEisClient *client) +on_viewports_changed (MetaEis *eis, + MetaEisClient *client) { - MetaViewportInfo *viewports; - - viewports = meta_monitor_manager_get_viewports (monitor_manager); - meta_eis_client_set_viewports (client, viewports); + update_viewports (client); } static void meta_eis_client_disconnect (MetaEisClient *client) { - MetaBackend *backend = meta_eis_get_backend (client->eis); - MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); - - g_signal_handlers_disconnect_by_func (monitor_manager, - on_monitors_changed, - client); + g_clear_signal_handler (&client->viewports_changed_handler_id, client->eis); g_hash_table_foreach_remove (client->eis_devices, drop_device, client); g_clear_pointer (&client->eis_seat, eis_seat_unref); if (client->eis_client) eis_client_disconnect (client->eis_client); g_clear_pointer (&client->eis_client, eis_client_unref); - g_clear_object (&client->viewports); } MetaEisClient * @@ -683,9 +791,6 @@ meta_eis_client_new (MetaEis *eis, struct eis_client *eis_client) { MetaEisClient *client; - MetaBackend *backend; - MetaMonitorManager *monitor_manager; - MetaViewportInfo *viewports; struct eis_seat *eis_seat; client = g_object_new (META_TYPE_EIS_CLIENT, NULL); @@ -725,13 +830,11 @@ meta_eis_client_new (MetaEis *eis, (GDestroyNotify) eis_device_unref, (GDestroyNotify) meta_eis_device_free); - backend = meta_eis_get_backend (eis); - monitor_manager = meta_backend_get_monitor_manager (backend); - viewports = meta_monitor_manager_get_viewports (monitor_manager); - meta_eis_client_set_viewports (client, viewports); - g_signal_connect (monitor_manager, "monitors-changed", - G_CALLBACK (on_monitors_changed), - client); + client->viewports_changed_handler_id = + g_signal_connect (eis, "viewports-changed", + G_CALLBACK (on_viewports_changed), + client); + update_viewports (client); return client; } diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 5f20c682e2..978d4d47bd 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -27,6 +27,15 @@ #include "clutter/clutter-mutter.h" #include "meta/util.h" +enum +{ + VIEWPORTS_CHANGED, + + N_SIGNALS +}; + +static int signals[N_SIGNALS]; + typedef struct _MetaEventSource MetaEventSource; struct _MetaEventSource @@ -47,6 +56,8 @@ struct _MetaEis MetaEisDeviceTypes device_types; + GList *viewports; + GHashTable *eis_clients; /* eis_client => MetaEisClient */ }; @@ -65,6 +76,12 @@ meta_eis_viewport_is_standalone (MetaEisViewport *viewport) return META_EIS_VIEWPORT_GET_IFACE (viewport)->is_standalone (viewport); } +const char * +meta_eis_viewport_get_mapping_id (MetaEisViewport *viewport) +{ + return META_EIS_VIEWPORT_GET_IFACE (viewport)->get_mapping_id (viewport); +} + gboolean meta_eis_viewport_get_position (MetaEisViewport *viewport, int *out_x, @@ -327,6 +344,7 @@ meta_eis_dispose (GObject *object) { MetaEis *eis = META_EIS (object); + g_clear_pointer (&eis->viewports, g_list_free); g_clear_pointer (&eis->event_source, meta_event_source_free); g_clear_pointer (&eis->eis, eis_unref); g_clear_pointer (&eis->eis_clients, g_hash_table_destroy); @@ -340,6 +358,14 @@ meta_eis_class_init (MetaEisClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = meta_eis_dispose; + + signals[VIEWPORTS_CHANGED] = + g_signal_new ("viewports-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); } MetaEisDeviceTypes @@ -347,3 +373,25 @@ meta_eis_get_device_types (MetaEis *eis) { return eis->device_types; } + +void +meta_eis_add_viewport (MetaEis *eis, + MetaEisViewport *viewport) +{ + eis->viewports = g_list_append (eis->viewports, viewport); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + +void +meta_eis_remove_viewport (MetaEis *eis, + MetaEisViewport *viewport) +{ + eis->viewports = g_list_remove (eis->viewports, viewport); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + +GList * +meta_eis_peek_viewports (MetaEis *eis) +{ + return eis->viewports; +} diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index fc48c60610..8cc9a1c9c0 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -72,6 +72,14 @@ MetaBackend * meta_eis_get_backend (MetaEis *eis); int meta_eis_add_client_get_fd (MetaEis *eis); +void meta_eis_add_viewport (MetaEis *eis, + MetaEisViewport *viewport); + +void meta_eis_remove_viewport (MetaEis *eis, + MetaEisViewport *viewport); + +GList * meta_eis_peek_viewports (MetaEis *eis); + MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); gboolean meta_eis_viewport_is_standalone (MetaEisViewport *viewport); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index c3addd34dc..4a14e41d40 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -203,6 +203,50 @@ ensure_virtual_device (MetaRemoteDesktopSession *session, *virtual_device_ptr = clutter_seat_create_virtual_device (seat, device_type); } +static void +on_stream_added (MetaScreenCastSession *screen_cast_session, + MetaScreenCastStream *stream, + MetaRemoteDesktopSession *session) +{ + meta_eis_add_viewport (session->eis, META_EIS_VIEWPORT (stream)); +} + +static void +on_stream_removed (MetaScreenCastSession *screen_cast_session, + MetaScreenCastStream *stream, + MetaRemoteDesktopSession *session) +{ + meta_eis_remove_viewport (session->eis, META_EIS_VIEWPORT (stream)); +} + +static void +initialize_viewports (MetaRemoteDesktopSession *session) +{ + if (session->screen_cast_session) + { + GList *streams; + GList *l; + + streams = + meta_screen_cast_session_peek_streams (session->screen_cast_session); + for (l = streams; l; l = l->next) + { + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (l->data); + + meta_eis_add_viewport (session->eis, META_EIS_VIEWPORT (stream)); + } + + g_signal_connect (session->screen_cast_session, + "stream-added", + G_CALLBACK (on_stream_added), + session); + g_signal_connect (session->screen_cast_session, + "stream-removed", + G_CALLBACK (on_stream_removed), + session); + } +} + static gboolean meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, GError **error) @@ -215,6 +259,9 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, return FALSE; } + if (session->eis) + initialize_viewports (session); + init_remote_access_handle (session); session->started = TRUE; @@ -281,6 +328,13 @@ meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *ses MetaScreenCastSession *screen_cast_session, GError **error) { + if (session->started) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Remote desktop session already started"); + return FALSE; + } + if (session->screen_cast_session) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -1695,6 +1749,9 @@ handle_connect_to_eis (MetaDBusRemoteDesktopSession *skeleton, eis_device_types = device_types_to_eis_device_types (device_types); session->eis = meta_eis_new (backend, eis_device_types); + + if (session->started) + initialize_viewports (session); } fd = meta_eis_add_client_get_fd (session->eis); diff --git a/src/backends/meta-screen-cast-session.c b/src/backends/meta-screen-cast-session.c index 2454f28386..46ba71b2f3 100644 --- a/src/backends/meta-screen-cast-session.c +++ b/src/backends/meta-screen-cast-session.c @@ -38,6 +38,16 @@ #define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session" +enum +{ + STREAM_ADDED, + STREAM_REMOVED, + + N_SIGNALS, +}; + +static int signals[N_SIGNALS]; + enum { PROP_0, @@ -184,6 +194,12 @@ meta_screen_cast_session_close (MetaDbusSession *dbus_session) g_object_unref (session); } +GList * +meta_screen_cast_session_peek_streams (MetaScreenCastSession *session) +{ + return session->streams; +} + MetaScreenCastStream * meta_screen_cast_session_get_stream (MetaScreenCastSession *session, const char *path) @@ -366,6 +382,7 @@ on_stream_closed (MetaScreenCastStream *stream, MetaScreenCastSession *session) { session->streams = g_list_remove (session->streams, stream); + g_signal_emit (session, signals[STREAM_REMOVED], 0, stream); g_object_unref (stream); switch (session->session_type) @@ -392,6 +409,16 @@ is_valid_cursor_mode (MetaScreenCastCursorMode cursor_mode) return FALSE; } +static void +add_stream (MetaScreenCastSession *session, + MetaScreenCastStream *stream) +{ + session->streams = g_list_append (session->streams, stream); + g_signal_emit (session, signals[STREAM_ADDED], 0, stream); + + g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session); +} + static gboolean handle_record_monitor (MetaDBusScreenCastSession *skeleton, GDBusMethodInvocation *invocation, @@ -484,9 +511,7 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton, stream = META_SCREEN_CAST_STREAM (monitor_stream); stream_path = meta_screen_cast_stream_get_object_path (stream); - session->streams = g_list_append (session->streams, stream); - - g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session); + add_stream (session, stream); meta_dbus_screen_cast_session_complete_record_monitor (skeleton, invocation, @@ -890,6 +915,23 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); meta_dbus_session_install_properties (object_class, N_PROPS); + + signals[STREAM_ADDED] = + g_signal_new ("stream-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_SCREEN_CAST_STREAM); + signals[STREAM_REMOVED] = + g_signal_new ("stream-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_SCREEN_CAST_STREAM); } static gboolean diff --git a/src/backends/meta-screen-cast-session.h b/src/backends/meta-screen-cast-session.h index 765fc3cb99..b3be279ea2 100644 --- a/src/backends/meta-screen-cast-session.h +++ b/src/backends/meta-screen-cast-session.h @@ -56,6 +56,8 @@ gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, gboolean meta_screen_cast_session_is_active (MetaScreenCastSession *session); +GList * meta_screen_cast_session_peek_streams (MetaScreenCastSession *session); + MetaScreenCastStream * meta_screen_cast_session_get_stream (MetaScreenCastSession *session, const char *path); From df32cd5060dd1c2053b7190eb15b4e5bbe128ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 30 Aug 2023 16:20:14 +0200 Subject: [PATCH 16/17] eis: Don't treat EIS errors as fatal g_error() is fatal, but EIS errors are not necessarily that. --- src/backends/meta-eis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 978d4d47bd..ca2c3896bb 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -294,7 +294,7 @@ eis_logger (struct eis *eis, g_warning ("%s", message); break; case EIS_LOG_PRIORITY_ERROR: - g_error ("%s", message); + g_critical ("%s", message); break; case EIS_LOG_PRIORITY_INFO: default: From ae8df67f5eb668c80855848dac582eba05f189ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 30 Aug 2023 21:37:44 +0200 Subject: [PATCH 17/17] remote-desktop/session: Add regions for all monitors if input-only If we're a input-only remote desktop session, create libei regions on an absolute pointer device corresponding to all logical monitors. This allows absolute pointer motions without screen casting. --- src/backends/meta-eis-client.c | 4 +- src/backends/meta-eis.c | 15 ++ src/backends/meta-eis.h | 5 + src/backends/meta-remote-desktop-session.c | 171 +++++++++++++++++++++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index ec67c67ddd..6eb171a861 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -272,8 +272,8 @@ add_viewport_region (struct eis_device *eis_device, eis_region_set_physical_scale (eis_region, scale); mapping_id = meta_eis_viewport_get_mapping_id (viewport); - g_warn_if_fail (mapping_id); - eis_region_set_mapping_id (eis_region, mapping_id); + if (mapping_id) + eis_region_set_mapping_id (eis_region, mapping_id); eis_region_set_user_data (eis_region, viewport); eis_region_add (eis_region); diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index ca2c3896bb..0f79a3d7f3 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -390,6 +390,21 @@ meta_eis_remove_viewport (MetaEis *eis, g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); } +void +meta_eis_take_viewports (MetaEis *eis, + GList *viewports) +{ + eis->viewports = g_list_concat (eis->viewports, viewports); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + +void +meta_eis_remove_all_viewports (MetaEis *eis) +{ + g_clear_pointer (&eis->viewports, g_list_free); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + GList * meta_eis_peek_viewports (MetaEis *eis) { diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index 8cc9a1c9c0..87a0481fac 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -78,6 +78,11 @@ void meta_eis_add_viewport (MetaEis *eis, void meta_eis_remove_viewport (MetaEis *eis, MetaEisViewport *viewport); +void meta_eis_take_viewports (MetaEis *eis, + GList *viewports); + +void meta_eis_remove_all_viewports (MetaEis *eis); + GList * meta_eis_peek_viewports (MetaEis *eis); MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index 4a14e41d40..70ec60535e 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -34,6 +34,7 @@ #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-manager.h" #include "backends/meta-eis.h" +#include "backends/meta-logical-monitor.h" #include "backends/meta-screen-cast-session.h" #include "backends/meta-remote-access-controller-private.h" #include "backends/x11/meta-backend-x11.h" @@ -104,6 +105,8 @@ struct _MetaRemoteDesktopSession guint transfer_request_timeout_id; GHashTable *mapping_ids; + + gulong monitors_changed_handler_id; }; static void initable_init_iface (GInitableIface *iface); @@ -135,9 +138,124 @@ G_DEFINE_TYPE (MetaRemoteDesktopSessionHandle, meta_remote_desktop_session_handle, META_TYPE_REMOTE_ACCESS_HANDLE) +struct _MetaLogicalMonitorViewport +{ + GObject parent; + + MetaLogicalMonitor *logical_monitor; +}; + +#define META_TYPE_LOGICAL_MONITOR_VIEWPORT (meta_logical_monitor_viewport_get_type ()) +G_DECLARE_FINAL_TYPE (MetaLogicalMonitorViewport, meta_logical_monitor_viewport, + META, LOGICAL_MONITOR_VIEWPORT, + GObject) + +static void meta_eis_viewport_init_iface (MetaEisViewportInterface *iface); + +G_DEFINE_FINAL_TYPE_WITH_CODE (MetaLogicalMonitorViewport, + meta_logical_monitor_viewport, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_init_iface)) + static MetaRemoteDesktopSessionHandle * meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session); +static gboolean +meta_logical_monitor_viewport_is_standalone (MetaEisViewport *viewport) +{ + return FALSE; +} + +static const char * +meta_logical_monitor_viewport_get_mapping_id (MetaEisViewport *viewport) +{ + return NULL; +} + +static gboolean +meta_logical_monitor_viewport_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor_viewport->logical_monitor); + *out_x = layout.x; + *out_y = layout.y; + return TRUE; +} + +static void +meta_logical_monitor_viewport_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + MetaRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor_viewport->logical_monitor); + *out_width = layout.width; + *out_height = layout.height; +} + +static double +meta_logical_monitor_viewport_get_physical_scale (MetaEisViewport *viewport) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + + return meta_logical_monitor_get_scale (logical_monitor_viewport->logical_monitor); +} + +static gboolean +meta_logical_monitor_viewport_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + *out_x = x; + *out_y = y; + return TRUE; +} + +static void +meta_eis_viewport_init_iface (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_logical_monitor_viewport_is_standalone; + eis_viewport_iface->get_mapping_id = meta_logical_monitor_viewport_get_mapping_id; + eis_viewport_iface->get_position = meta_logical_monitor_viewport_get_position; + eis_viewport_iface->get_size = meta_logical_monitor_viewport_get_size; + eis_viewport_iface->get_physical_scale = meta_logical_monitor_viewport_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_logical_monitor_viewport_transform_coordinate; +} + +static void +meta_logical_monitor_viewport_class_init (MetaLogicalMonitorViewportClass *klass) +{ +} + +static void +meta_logical_monitor_viewport_init (MetaLogicalMonitorViewport *logical_monitor_viewport) +{ +} + +static MetaLogicalMonitorViewport * +meta_logical_monitor_viewport_new (MetaLogicalMonitor *logical_monitor) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport; + + logical_monitor_viewport = g_object_new (META_TYPE_LOGICAL_MONITOR_VIEWPORT, + NULL); + logical_monitor_viewport->logical_monitor = logical_monitor; + + return logical_monitor_viewport; +} + static MetaDisplay * display_from_session (MetaRemoteDesktopSession *session) { @@ -219,6 +337,40 @@ on_stream_removed (MetaScreenCastSession *screen_cast_session, meta_eis_remove_viewport (session->eis, META_EIS_VIEWPORT (stream)); } +static void +add_logical_monitor_viewports (MetaRemoteDesktopSession *session) +{ + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors; + GList *l; + GList *viewports = NULL; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaLogicalMonitorViewport *logical_monitor_viewport; + + logical_monitor_viewport = + meta_logical_monitor_viewport_new (logical_monitor); + viewports = g_list_append (viewports, logical_monitor_viewport); + } + + meta_eis_remove_all_viewports (session->eis); + meta_eis_take_viewports (session->eis, viewports); +} + +static void +on_monitors_changed (MetaMonitorManager *monitor_manager, + MetaRemoteDesktopSession *session) +{ + add_logical_monitor_viewports (session); +} + static void initialize_viewports (MetaRemoteDesktopSession *session) { @@ -245,6 +397,18 @@ initialize_viewports (MetaRemoteDesktopSession *session) G_CALLBACK (on_stream_removed), session); } + else + { + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + add_logical_monitor_viewports (session); + session->monitors_changed_handler_id = + g_signal_connect (monitor_manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), session); + } } static gboolean @@ -275,6 +439,10 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) META_REMOTE_DESKTOP_SESSION (dbus_session); MetaDBusRemoteDesktopSession *skeleton = META_DBUS_REMOTE_DESKTOP_SESSION (session); + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); session->started = FALSE; @@ -289,6 +457,9 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) session->screen_cast_session = NULL; } + g_clear_signal_handler (&session->monitors_changed_handler_id, + monitor_manager); + g_clear_object (&session->virtual_pointer); g_clear_object (&session->virtual_keyboard); g_clear_object (&session->virtual_touchscreen);