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-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-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-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-client.c b/src/backends/meta-eis-client.c index 592d9f8bee..6eb171a861 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -20,11 +20,10 @@ #include "config.h" -#include "backends/meta-backend-private.h" #include "backends/meta-eis-client.h" -#include "backends/meta-monitor-manager-private.h" -#include "backends/meta-viewport-info.h" +#include "backends/meta-backend-private.h" +#include "backends/meta-monitor-manager-private.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]; }; @@ -45,19 +46,21 @@ struct _MetaEisDevice struct _MetaEisClient { GObject parent_instance; - MetaEis *meta_eis; + 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) -typedef void (* MetaEisDeviceConfigFunc) (MetaEisClient *meta_eis_client, - struct eis_device *device); +typedef void (* MetaEisDeviceConfigFunc) (MetaEisClient *client, + struct eis_device *device, + gpointer user_data); static bool bit_is_set (const guchar *array, @@ -81,39 +84,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 +128,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 +140,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,8 +169,9 @@ meta_eis_device_free (MetaEisDevice *device) } static void -configure_rel (MetaEisClient *meta_eis_client, - struct eis_device *eis_device) +configure_rel (MetaEisClient *client, + 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); @@ -175,8 +179,9 @@ configure_rel (MetaEisClient *meta_eis_client, } static void -configure_keyboard (MetaEisClient *meta_eis_client, - struct eis_device *eis_device) +configure_keyboard (MetaEisClient *client, + struct eis_device *eis_device, + gpointer user_data) { size_t len; MetaAnonymousFile *f; @@ -187,7 +192,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; @@ -216,112 +221,203 @@ configure_keyboard (MetaEisClient *meta_eis_client, } } -static void -configure_abs (MetaEisClient *meta_eis_client, - struct eis_device *eis_device) +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 (!meta_eis_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); + 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); + 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 (meta_eis_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 -add_device (MetaEisClient *meta_eis_client, +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, const char *name_suffix, - MetaEisDeviceConfigFunc extra_config_func) + MetaEisDeviceConfigFunc extra_config_func, + gpointer extra_config_user_data) { - 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, extra_config_user_data); - 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); g_free (name); + + return device; } 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 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 *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); + 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 (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 +425,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 +438,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 +446,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 +463,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 +471,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 +487,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 +495,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 +504,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 +512,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 +522,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 +551,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 +577,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 +604,70 @@ 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); + 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 *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,60 +678,58 @@ 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, - eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual pointer", - configure_rel); + { + add_device (client, + eis_seat, + CLUTTER_POINTER_DEVICE, + "virtual pointer", + configure_rel, NULL); + } 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); + configure_keyboard, NULL); - g_signal_connect (meta_eis_get_backend (meta_eis_client->meta_eis), - "keymap-changed", - G_CALLBACK (on_keymap_changed), - meta_eis_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 (meta_eis_client, - eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual absolute pointer", - configure_abs); + + add_abs_pointer_devices (client); break; /* 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,67 +760,43 @@ drop_abs_devices (gpointer key, } static void -meta_eis_client_set_viewports (MetaEisClient *meta_eis_client, - MetaViewportInfo *viewports) +update_viewports (MetaEisClient *client) { - /* 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); - - g_clear_object (&meta_eis_client->viewports); - meta_eis_client->viewports = g_object_ref (viewports); - - add_device (meta_eis_client, - meta_eis_client->eis_seat, - CLUTTER_POINTER_DEVICE, - "virtual absolute pointer", - configure_abs); + client); + add_abs_pointer_devices (client); } static void -on_monitors_changed (MetaMonitorManager *monitor_manager, - MetaEisClient *meta_eis_client) +on_viewports_changed (MetaEis *eis, + MetaEisClient *client) { - MetaViewportInfo *viewports; - - viewports = meta_monitor_manager_get_viewports (monitor_manager); - meta_eis_client_set_viewports (meta_eis_client, viewports); + update_viewports (client); } static void -meta_eis_client_disconnect (MetaEisClient *meta_eis_client) -{ - MetaBackend *backend = meta_eis_get_backend (meta_eis_client->meta_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); +meta_eis_client_disconnect (MetaEisClient *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); } MetaEisClient * -meta_eis_client_new (MetaEis *meta_eis, +meta_eis_client_new (MetaEis *eis, struct eis_client *eis_client) { - MetaEisClient *meta_eis_client; - MetaBackend *backend; - MetaMonitorManager *monitor_manager; - MetaViewportInfo *viewports; + MetaEisClient *client; 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); @@ -692,45 +808,51 @@ meta_eis_client_new (MetaEis *meta_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); - 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); - 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); - g_signal_connect (monitor_manager, "monitors-changed", - G_CALLBACK (on_monitors_changed), - meta_eis_client); + client->viewports_changed_handler_id = + g_signal_connect (eis, "viewports-changed", + G_CALLBACK (on_viewports_changed), + client); + update_viewports (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..0f79a3d7f3 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -27,13 +27,22 @@ #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 { GSource source; - MetaEis *meta_eis; + MetaEis *eis; GPollFD event_poll_fd; }; @@ -45,86 +54,143 @@ struct _MetaEis struct eis *eis; MetaEventSource *event_source; + MetaEisDeviceTypes device_types; + + GList *viewports; + GHashTable *eis_clients; /* eis_client => MetaEisClient */ }; G_DEFINE_TYPE (MetaEis, meta_eis, G_TYPE_OBJECT) -MetaBackend * -meta_eis_get_backend (MetaEis *meta_eis) +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); +} + +const char * +meta_eis_viewport_get_mapping_id (MetaEisViewport *viewport) { - return meta_eis->backend; + return META_EIS_VIEWPORT_GET_IFACE (viewport)->get_mapping_id (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_remove_all_clients (MetaEis *meta_eis) +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) { - g_hash_table_remove_all (meta_eis->eis_clients); + return eis->backend; } 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 +201,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 +233,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 +264,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; } @@ -228,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: @@ -238,78 +304,52 @@ eis_logger (struct eis *eis, } int -meta_eis_add_client_get_fd (MetaEis *meta_eis) -{ - return eis_backend_fd_add_client (meta_eis->eis); -} - -static int -try_and_find_free_eis_socket (MetaEis *meta_eis) +meta_eis_add_client_get_fd (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 (meta_eis->eis, socketname); - if (rc == 0) - { - g_info ("Using EIS socket: %s", socketname); - return 0; - } - } - - return rc; + return eis_backend_fd_add_client (eis->eis); } MetaEis * -meta_eis_new (MetaBackend *backend) +meta_eis_new (MetaBackend *backend, + MetaEisDeviceTypes device_types) { - MetaEis *meta_eis; + MetaEis *eis; int fd; - int rc; - meta_eis = g_object_new (META_TYPE_EIS, NULL); - meta_eis->backend = backend; - - meta_eis->eis = eis_new (meta_eis); - rc = try_and_find_free_eis_socket (meta_eis); - if (rc != 0) - { - g_warning ("Failed to initialize the EIS socket: %s", g_strerror (-rc)); - g_clear_pointer (&meta_eis->eis, eis_unref); - return NULL; - } + eis = g_object_new (META_TYPE_EIS, NULL); + eis->backend = backend; + eis->device_types = device_types; - eis_log_set_handler (meta_eis->eis, eis_logger); - eis_log_set_priority (meta_eis->eis, EIS_LOG_PRIORITY_DEBUG); + eis->eis = eis_new (eis); + 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 (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) +meta_eis_dispose (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->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); - G_OBJECT_CLASS (meta_eis_parent_class)->finalize (object); + G_OBJECT_CLASS (meta_eis_parent_class)->dispose (object); } static void @@ -317,5 +357,56 @@ 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; + + 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 +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); +} + +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) +{ + return eis->viewports; } diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index a1c8094e59..87a0481fac 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -23,13 +23,86 @@ #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_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) -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); +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); + +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); + +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); + +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); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index c9288d76cc..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" @@ -88,6 +89,7 @@ struct _MetaRemoteDesktopSession gulong screen_cast_session_closed_handler_id; guint started : 1; + MetaEis *eis; ClutterVirtualInputDevice *virtual_pointer; ClutterVirtualInputDevice *virtual_keyboard; ClutterVirtualInputDevice *virtual_touchscreen; @@ -101,6 +103,10 @@ struct _MetaRemoteDesktopSession MetaSelectionSourceRemote *current_source; GHashTable *transfer_requests; guint transfer_request_timeout_id; + + GHashTable *mapping_ids; + + gulong monitors_changed_handler_id; }; static void initable_init_iface (GInitableIface *iface); @@ -132,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) { @@ -200,6 +321,96 @@ 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 +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) +{ + 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); + } + 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 meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, GError **error) @@ -212,6 +423,9 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, return FALSE; } + if (session->eis) + initialize_viewports (session); + init_remote_access_handle (session); session->started = TRUE; @@ -223,10 +437,12 @@ 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); + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); session->started = FALSE; @@ -241,9 +457,13 @@ 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); + g_clear_object (&session->eis); meta_dbus_session_notify_closed (META_DBUS_SESSION (session)); meta_dbus_remote_desktop_session_emit_closed (skeleton); @@ -257,8 +477,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); } @@ -281,6 +499,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, @@ -298,6 +523,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) @@ -1628,6 +1872,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,11 +1900,32 @@ 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) + { + 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 (meis); + if (session->started) + initialize_viewports (session); + } + + fd = meta_eis_add_client_get_fd (session->eis); if (fd < 0) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, @@ -1699,6 +1979,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; } @@ -1752,6 +2034,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); 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 ()) 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-session.c b/src/backends/meta-screen-cast-session.c index e19cea47b6..46ba71b2f3 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" @@ -37,11 +38,21 @@ #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, - PROP_SESSION_TYPE, + PROP_REMOTE_DESKTOP_SESSION, N_PROPS }; @@ -66,6 +77,8 @@ struct _MetaScreenCastSession gboolean is_active; gboolean disable_animations; + + MetaRemoteDesktopSession *remote_desktop_session; }; static void initable_init_iface (GInitableIface *iface); @@ -181,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) @@ -230,6 +249,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 +273,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); @@ -349,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) @@ -375,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, @@ -467,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, @@ -799,8 +841,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 +874,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,15 +907,31 @@ 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); + + 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 ee8514ea32..b3be279ea2 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,11 +49,15 @@ 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); 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); 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) { 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)) {