Port screen cast and remote desktop to MetaDbusSessionManager

This eliminates some code duplication related to managing D-Bus session
objects.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2713>
This commit is contained in:
Jonas Ådahl 2022-03-11 09:39:07 +01:00 committed by Marge Bot
parent 122fea2dc4
commit 5731268087
13 changed files with 501 additions and 593 deletions

View File

@ -206,9 +206,9 @@ meta_backend_dispose (GObject *object)
#ifdef HAVE_REMOTE_DESKTOP #ifdef HAVE_REMOTE_DESKTOP
g_clear_object (&priv->remote_desktop); g_clear_object (&priv->remote_desktop);
g_clear_object (&priv->screen_cast); g_clear_object (&priv->screen_cast);
#endif
g_clear_object (&priv->dbus_session_watcher); g_clear_object (&priv->dbus_session_watcher);
g_clear_object (&priv->remote_access_controller); g_clear_object (&priv->remote_access_controller);
#endif
#ifdef HAVE_LIBWACOM #ifdef HAVE_LIBWACOM
g_clear_pointer (&priv->wacom_db, libwacom_database_destroy); g_clear_pointer (&priv->wacom_db, libwacom_database_destroy);
@ -557,14 +557,20 @@ meta_backend_real_post_init (MetaBackend *backend)
input_settings); input_settings);
} }
#ifdef HAVE_REMOTE_DESKTOP
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
priv->screen_cast = meta_screen_cast_new (backend,
priv->dbus_session_watcher);
priv->remote_desktop = meta_remote_desktop_new (backend,
priv->dbus_session_watcher);
priv->remote_access_controller = priv->remote_access_controller =
meta_remote_access_controller_new (priv->remote_desktop, priv->screen_cast); meta_remote_access_controller_new ();
priv->dbus_session_watcher =
g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
#ifdef HAVE_REMOTE_DESKTOP
priv->screen_cast = meta_screen_cast_new (backend);
meta_remote_access_controller_add (
priv->remote_access_controller,
META_DBUS_SESSION_MANAGER (priv->screen_cast));
priv->remote_desktop = meta_remote_desktop_new (backend);
meta_remote_access_controller_add (
priv->remote_access_controller,
META_DBUS_SESSION_MANAGER (priv->remote_desktop));
#endif /* HAVE_REMOTE_DESKTOP */ #endif /* HAVE_REMOTE_DESKTOP */
if (!meta_monitor_manager_is_headless (priv->monitor_manager)) if (!meta_monitor_manager_is_headless (priv->monitor_manager))

View File

@ -24,8 +24,10 @@
#include "backends/meta-backend-types.h" #include "backends/meta-backend-types.h"
#include "meta/meta-remote-access-controller.h" #include "meta/meta-remote-access-controller.h"
MetaRemoteAccessController * meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop, MetaRemoteAccessController * meta_remote_access_controller_new (void);
MetaScreenCast *screen_cast);
void meta_remote_access_controller_add (MetaRemoteAccessController *controller,
MetaDbusSessionManager *session_manager);
void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller,
MetaRemoteAccessHandle *handle); MetaRemoteAccessHandle *handle);

View File

@ -22,6 +22,8 @@
#include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-access-controller-private.h"
#include "backends/meta-dbus-session-manager.h"
#ifdef HAVE_REMOTE_DESKTOP #ifdef HAVE_REMOTE_DESKTOP
#include "backends/meta-remote-desktop.h" #include "backends/meta-remote-desktop.h"
#include "backends/meta-screen-cast.h" #include "backends/meta-screen-cast.h"
@ -73,8 +75,7 @@ struct _MetaRemoteAccessController
{ {
GObject parent; GObject parent;
MetaRemoteDesktop *remote_desktop; GList *session_managers;
MetaScreenCast *screen_cast;
}; };
G_DEFINE_TYPE (MetaRemoteAccessController, G_DEFINE_TYPE (MetaRemoteAccessController,
@ -153,10 +154,14 @@ meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *con
void void
meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller) meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller)
{ {
#ifdef HAVE_REMOTE_DESKTOP GList *l;
meta_remote_desktop_inhibit (controller->remote_desktop);
meta_screen_cast_inhibit (controller->screen_cast); for (l = controller->session_managers; l; l = l->next)
#endif {
MetaDbusSessionManager *session_manager = l->data;
meta_dbus_session_manager_inhibit (session_manager);
}
} }
/** /**
@ -170,24 +175,28 @@ meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController
void void
meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller) meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller)
{ {
#ifdef HAVE_REMOTE_DESKTOP GList *l;
meta_screen_cast_uninhibit (controller->screen_cast);
meta_remote_desktop_uninhibit (controller->remote_desktop); for (l = controller->session_managers; l; l = l->next)
#endif {
MetaDbusSessionManager *session_manager = l->data;
meta_dbus_session_manager_uninhibit (session_manager);
}
} }
MetaRemoteAccessController * MetaRemoteAccessController *
meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop, meta_remote_access_controller_new (void)
MetaScreenCast *screen_cast)
{ {
MetaRemoteAccessController *remote_access_controller; return g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL);
}
remote_access_controller = g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, void
NULL); meta_remote_access_controller_add (MetaRemoteAccessController *controller,
remote_access_controller->remote_desktop = remote_desktop; MetaDbusSessionManager *session_manager)
remote_access_controller->screen_cast = screen_cast; {
controller->session_managers = g_list_append (controller->session_managers,
return remote_access_controller; session_manager);
} }
static void static void

View File

@ -34,6 +34,7 @@
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-watcher.h"
#include "backends/meta-dbus-session-manager.h"
#include "backends/meta-screen-cast-session.h" #include "backends/meta-screen-cast-session.h"
#include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-access-controller-private.h"
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
@ -49,6 +50,19 @@
#define TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS (s2ms (15)) #define TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS (s2ms (15))
enum
{
PROP_0,
PROP_SESSION_MANAGER,
PROP_PEER_NAME,
PROP_ID,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS];
typedef enum _MetaRemoteDesktopNotifyAxisFlags typedef enum _MetaRemoteDesktopNotifyAxisFlags
{ {
META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE = 0, META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_NONE = 0,
@ -69,7 +83,7 @@ struct _MetaRemoteDesktopSession
{ {
MetaDBusRemoteDesktopSessionSkeleton parent; MetaDBusRemoteDesktopSessionSkeleton parent;
MetaRemoteDesktop *remote_desktop; MetaDbusSessionManager *session_manager;
GDBusConnection *connection; GDBusConnection *connection;
char *peer_name; char *peer_name;
@ -96,6 +110,8 @@ struct _MetaRemoteDesktopSession
guint transfer_request_timeout_id; guint transfer_request_timeout_id;
}; };
static void initable_init_iface (GInitableIface *iface);
static void static void
meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface); meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface);
@ -105,6 +121,8 @@ meta_dbus_session_init_iface (MetaDbusSessionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktopSession, G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktopSession,
meta_remote_desktop_session, meta_remote_desktop_session,
META_DBUS_TYPE_REMOTE_DESKTOP_SESSION_SKELETON, META_DBUS_TYPE_REMOTE_DESKTOP_SESSION_SKELETON,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_init_iface)
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP_SESSION, G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP_SESSION,
meta_remote_desktop_session_init_iface) meta_remote_desktop_session_init_iface)
G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION,
@ -127,8 +145,8 @@ meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session);
static MetaDisplay * static MetaDisplay *
display_from_session (MetaRemoteDesktopSession *session) display_from_session (MetaRemoteDesktopSession *session)
{ {
MetaRemoteDesktop *remote_desktop = session->remote_desktop; MetaBackend *backend =
MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop); meta_dbus_session_manager_get_backend (session->session_manager);
MetaContext *context = meta_backend_get_context (backend); MetaContext *context = meta_backend_get_context (backend);
return meta_context_get_display (context); return meta_context_get_display (context);
@ -143,8 +161,8 @@ meta_remote_desktop_session_is_running (MetaRemoteDesktopSession *session)
static void static void
init_remote_access_handle (MetaRemoteDesktopSession *session) init_remote_access_handle (MetaRemoteDesktopSession *session)
{ {
MetaRemoteDesktop *remote_desktop = session->remote_desktop; MetaBackend *backend =
MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop); meta_dbus_session_manager_get_backend (session->session_manager);
MetaRemoteAccessController *remote_access_controller; MetaRemoteAccessController *remote_access_controller;
MetaRemoteAccessHandle *remote_access_handle; MetaRemoteAccessHandle *remote_access_handle;
@ -160,8 +178,8 @@ static void
ensure_virtual_device (MetaRemoteDesktopSession *session, ensure_virtual_device (MetaRemoteDesktopSession *session,
ClutterInputDeviceType device_type) ClutterInputDeviceType device_type)
{ {
MetaRemoteDesktop *remote_desktop = session->remote_desktop; MetaBackend *backend =
MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop); meta_dbus_session_manager_get_backend (session->session_manager);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
ClutterVirtualInputDevice **virtual_device_ptr = NULL; ClutterVirtualInputDevice **virtual_device_ptr = NULL;
@ -247,18 +265,20 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session)
g_object_unref (session); g_object_unref (session);
} }
static const char *
meta_remote_desktop_session_get_id (MetaDbusSession *dbus_session)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (dbus_session);
return session->session_id;
}
char * char *
meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session) meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session)
{ {
return session->object_path; return session->object_path;
} }
char *
meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session)
{
return session->session_id;
}
static void static void
on_screen_cast_session_closed (MetaScreenCastSession *screen_cast_session, on_screen_cast_session_closed (MetaScreenCastSession *screen_cast_session,
MetaRemoteDesktopSession *session) MetaRemoteDesktopSession *session)
@ -289,44 +309,6 @@ meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *ses
return TRUE; return TRUE;
} }
MetaRemoteDesktopSession *
meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
const char *peer_name,
GError **error)
{
MetaBackend *backend = meta_remote_desktop_get_backend (remote_desktop);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
ClutterKeymap *keymap = clutter_seat_get_keymap (seat);
GDBusInterfaceSkeleton *interface_skeleton;
MetaRemoteDesktopSession *session;
session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL);
session->remote_desktop = remote_desktop;
session->peer_name = g_strdup (peer_name);
interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
session->connection = meta_remote_desktop_get_connection (remote_desktop);
if (!g_dbus_interface_skeleton_export (interface_skeleton,
session->connection,
session->object_path,
error))
{
g_object_unref (session);
return NULL;
}
g_object_bind_property (keymap, "caps-lock-state",
session, "caps-lock-state",
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
g_object_bind_property (keymap, "num-lock-state",
session, "num-lock-state",
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
return session;
}
static gboolean static gboolean
check_permission (MetaRemoteDesktopSession *session, check_permission (MetaRemoteDesktopSession *session,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
@ -1657,6 +1639,46 @@ handle_selection_read (MetaDBusRemoteDesktopSession *skeleton,
return TRUE; return TRUE;
} }
static gboolean
meta_remote_desktop_session_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (initable);
MetaBackend *backend =
meta_dbus_session_manager_get_backend (session->session_manager);
ClutterSeat *seat = meta_backend_get_default_seat (backend);
ClutterKeymap *keymap = clutter_seat_get_keymap (seat);
GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
MetaDBusRemoteDesktopSession *skeleton =
META_DBUS_REMOTE_DESKTOP_SESSION (interface_skeleton);
meta_dbus_remote_desktop_session_set_session_id (skeleton, session->session_id);
session->connection =
meta_dbus_session_manager_get_connection (session->session_manager);
if (!g_dbus_interface_skeleton_export (interface_skeleton,
session->connection,
session->object_path,
error))
return FALSE;
g_object_bind_property (keymap, "caps-lock-state",
session, "caps-lock-state",
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
g_object_bind_property (keymap, "num-lock-state",
session, "num-lock-state",
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
return TRUE;
}
static void
initable_init_iface (GInitableIface *iface)
{
iface->init = meta_remote_desktop_session_initable_init;
}
static void static void
meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface) meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface)
{ {
@ -1684,6 +1706,7 @@ static void
meta_dbus_session_init_iface (MetaDbusSessionInterface *iface) meta_dbus_session_init_iface (MetaDbusSessionInterface *iface)
{ {
iface->close = meta_remote_desktop_session_close; iface->close = meta_remote_desktop_session_close;
iface->get_id = meta_remote_desktop_session_get_id;
} }
static void static void
@ -1708,20 +1731,61 @@ meta_remote_desktop_session_finalize (GObject *object)
G_OBJECT_CLASS (meta_remote_desktop_session_parent_class)->finalize (object); G_OBJECT_CLASS (meta_remote_desktop_session_parent_class)->finalize (object);
} }
static void
meta_remote_desktop_session_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (object);
switch (prop_id)
{
case PROP_SESSION_MANAGER:
session->session_manager = g_value_get_object (value);
break;
case PROP_PEER_NAME:
session->peer_name = g_value_dup_string (value);
break;
case PROP_ID:
session->session_id = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_remote_desktop_session_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (object);
switch (prop_id)
{
case PROP_SESSION_MANAGER:
g_value_set_object (value, session->session_manager);
break;
case PROP_PEER_NAME:
g_value_set_string (value, session->peer_name);
break;
case PROP_ID:
g_value_set_string (value, session->session_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void static void
meta_remote_desktop_session_init (MetaRemoteDesktopSession *session) meta_remote_desktop_session_init (MetaRemoteDesktopSession *session)
{ {
MetaDBusRemoteDesktopSession *skeleton =
META_DBUS_REMOTE_DESKTOP_SESSION (session);
GRand *rand;
static unsigned int global_session_number = 0; static unsigned int global_session_number = 0;
rand = g_rand_new ();
session->session_id = meta_generate_random_id (rand, 32);
g_rand_free (rand);
meta_dbus_remote_desktop_session_set_session_id (skeleton, session->session_id);
session->object_path = session->object_path =
g_strdup_printf (META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/u%u", g_strdup_printf (META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/u%u",
++global_session_number); ++global_session_number);
@ -1736,6 +1800,34 @@ meta_remote_desktop_session_class_init (MetaRemoteDesktopSessionClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_remote_desktop_session_finalize; object_class->finalize = meta_remote_desktop_session_finalize;
object_class->set_property = meta_remote_desktop_session_set_property;
object_class->get_property = meta_remote_desktop_session_get_property;
obj_props[PROP_SESSION_MANAGER] =
g_param_spec_object ("session-manager",
"session manager",
"D-Bus session manager",
META_TYPE_DBUS_SESSION_MANAGER,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_PEER_NAME] =
g_param_spec_string ("peer-name",
"peer name",
"D-Bus peer name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_ID] =
g_param_spec_string ("id",
"session id",
"Unique ID of the session",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
} }
static MetaRemoteDesktopSessionHandle * static MetaRemoteDesktopSessionHandle *

View File

@ -41,8 +41,6 @@ G_DECLARE_FINAL_TYPE (MetaRemoteDesktopSessionHandle,
char * meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session); char * meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session);
char * meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session);
gboolean meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *session, gboolean meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *session,
MetaScreenCastSession *screen_cast_session, MetaScreenCastSession *screen_cast_session,
GError **error); GError **error);
@ -51,8 +49,4 @@ void meta_remote_desktop_session_request_transfer (MetaRemoteDesktopSession *se
const char *mime_type, const char *mime_type,
GTask *task); GTask *task);
MetaRemoteDesktopSession * meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
const char *peer_name,
GError **error);
#endif /* META_REMOTE_DESKTOP_SESSION_H */ #endif /* META_REMOTE_DESKTOP_SESSION_H */

View File

@ -52,256 +52,49 @@ typedef enum _MetaRemoteDesktopDeviceTypes
struct _MetaRemoteDesktop struct _MetaRemoteDesktop
{ {
MetaDBusRemoteDesktopSkeleton parent; MetaDbusSessionManager parent;
MetaBackend *backend;
int dbus_name_id;
int inhibit_count;
GHashTable *sessions;
MetaDbusSessionWatcher *session_watcher;
}; };
static void G_DEFINE_TYPE (MetaRemoteDesktop, meta_remote_desktop,
meta_remote_desktop_init_iface (MetaDBusRemoteDesktopIface *iface); META_TYPE_DBUS_SESSION_MANAGER)
G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktop,
meta_remote_desktop,
META_DBUS_TYPE_REMOTE_DESKTOP_SKELETON,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP,
meta_remote_desktop_init_iface));
void
meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop)
{
remote_desktop->inhibit_count++;
if (remote_desktop->inhibit_count == 1)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, remote_desktop->sessions);
while (g_hash_table_iter_next (&iter, &key, &value))
{
MetaRemoteDesktopSession *session = value;
g_hash_table_iter_steal (&iter);
meta_dbus_session_close (META_DBUS_SESSION (session));
}
}
}
void
meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop)
{
g_return_if_fail (remote_desktop->inhibit_count > 0);
remote_desktop->inhibit_count--;
}
MetaBackend *
meta_remote_desktop_get_backend (MetaRemoteDesktop *remote_desktop)
{
return remote_desktop->backend;
}
GDBusConnection *
meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop)
{
GDBusInterfaceSkeleton *interface_skeleton =
G_DBUS_INTERFACE_SKELETON (remote_desktop);
return g_dbus_interface_skeleton_get_connection (interface_skeleton);
}
MetaRemoteDesktopSession *
meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop,
const char *session_id)
{
return g_hash_table_lookup (remote_desktop->sessions, session_id);
}
static void
on_session_closed (MetaRemoteDesktopSession *session,
MetaRemoteDesktop *remote_desktop)
{
char *session_id;
session_id = meta_remote_desktop_session_get_session_id (session);
g_hash_table_remove (remote_desktop->sessions, session_id);
}
static gboolean static gboolean
handle_create_session (MetaDBusRemoteDesktop *skeleton, handle_create_session (MetaDBusRemoteDesktop *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation,
MetaRemoteDesktop *remote_desktop)
{ {
MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (skeleton); MetaDbusSessionManager *session_manager =
const char *peer_name; META_DBUS_SESSION_MANAGER (remote_desktop);
MetaDbusSession *dbus_session;
MetaRemoteDesktopSession *session; MetaRemoteDesktopSession *session;
GError *error = NULL; g_autoptr (GError) error = NULL;
char *session_id;
char *session_path; char *session_path;
const char *client_dbus_name;
if (remote_desktop->inhibit_count > 0) dbus_session =
meta_dbus_session_manager_create_session (session_manager,
invocation,
&error,
NULL);
if (!dbus_session)
{ {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Session creation inhibited");
return TRUE;
}
peer_name = g_dbus_method_invocation_get_sender (invocation);
session = meta_remote_desktop_session_new (remote_desktop,
peer_name,
&error);
if (!session)
{
g_warning ("Failed to create remote desktop session: %s",
error->message);
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED, G_DBUS_ERROR_FAILED,
"Failed to create session: %s",
error->message); error->message);
g_error_free (error); return G_DBUS_METHOD_INVOCATION_HANDLED;
return TRUE;
} }
session_id = meta_remote_desktop_session_get_session_id (session); session = META_REMOTE_DESKTOP_SESSION (dbus_session);
g_hash_table_insert (remote_desktop->sessions,
session_id,
session);
client_dbus_name = g_dbus_method_invocation_get_sender (invocation);
meta_dbus_session_watcher_watch_session (remote_desktop->session_watcher,
client_dbus_name,
META_DBUS_SESSION (session));
session_path = meta_remote_desktop_session_get_object_path (session); session_path = meta_remote_desktop_session_get_object_path (session);
meta_dbus_remote_desktop_complete_create_session (skeleton, meta_dbus_remote_desktop_complete_create_session (skeleton,
invocation, invocation,
session_path); session_path);
return G_DBUS_METHOD_INVOCATION_HANDLED;
g_signal_connect (session, "session-closed",
G_CALLBACK (on_session_closed),
remote_desktop);
return TRUE;
}
static void
meta_remote_desktop_init_iface (MetaDBusRemoteDesktopIface *iface)
{
iface->handle_create_session = handle_create_session;
}
static void
on_bus_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
MetaRemoteDesktop *remote_desktop = user_data;
GDBusInterfaceSkeleton *interface_skeleton =
G_DBUS_INTERFACE_SKELETON (remote_desktop);
g_autoptr (GError) error = NULL;
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
META_REMOTE_DESKTOP_DBUS_PATH,
&error))
g_warning ("Failed to export remote desktop object: %s", error->message);
}
static void
on_name_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_info ("Acquired name %s", name);
}
static void
on_name_lost (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_warning ("Lost or failed to acquire name %s", name);
}
static void
meta_remote_desktop_constructed (GObject *object)
{
MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object);
remote_desktop->dbus_name_id =
g_bus_own_name (G_BUS_TYPE_SESSION,
META_REMOTE_DESKTOP_DBUS_SERVICE,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
remote_desktop,
NULL);
}
static void
on_prepare_shutdown (MetaBackend *backend,
MetaRemoteDesktop *remote_desktop)
{
GHashTableIter iter;
gpointer value;
g_hash_table_iter_init (&iter, remote_desktop->sessions);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
MetaRemoteDesktopSession *session = value;
g_hash_table_iter_steal (&iter);
meta_dbus_session_close (META_DBUS_SESSION (session));
}
}
static void
meta_remote_desktop_finalize (GObject *object)
{
MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object);
if (remote_desktop->dbus_name_id != 0)
g_bus_unown_name (remote_desktop->dbus_name_id);
g_assert (g_hash_table_size (remote_desktop->sessions) == 0);
g_hash_table_destroy (remote_desktop->sessions);
G_OBJECT_CLASS (meta_remote_desktop_parent_class)->finalize (object);
}
MetaRemoteDesktop *
meta_remote_desktop_new (MetaBackend *backend,
MetaDbusSessionWatcher *session_watcher)
{
MetaRemoteDesktop *remote_desktop;
remote_desktop = g_object_new (META_TYPE_REMOTE_DESKTOP, NULL);
remote_desktop->backend = backend;
remote_desktop->session_watcher = session_watcher;
g_signal_connect (backend, "prepare-shutdown",
G_CALLBACK (on_prepare_shutdown),
remote_desktop);
return remote_desktop;
} }
static MetaRemoteDesktopDeviceTypes static MetaRemoteDesktopDeviceTypes
calculate_supported_device_types (void) calculate_supported_device_types (MetaBackend *backend)
{ {
ClutterBackend *backend = clutter_get_default_backend (); ClutterSeat *seat = meta_backend_get_default_seat (backend);
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
ClutterVirtualDeviceType device_types; ClutterVirtualDeviceType device_types;
MetaRemoteDesktopDeviceTypes supported_devices = MetaRemoteDesktopDeviceTypes supported_devices =
META_REMOTE_DESKTOP_DEVICE_TYPE_NONE; META_REMOTE_DESKTOP_DEVICE_TYPE_NONE;
@ -320,16 +113,52 @@ calculate_supported_device_types (void)
} }
static void static void
meta_remote_desktop_init (MetaRemoteDesktop *remote_desktop) meta_remote_desktop_constructed (GObject *object)
{ {
remote_desktop->sessions = g_hash_table_new (g_str_hash, g_str_equal); MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object);
MetaDbusSessionManager *session_manager =
META_DBUS_SESSION_MANAGER (remote_desktop);
GDBusInterfaceSkeleton *interface_skeleton =
meta_dbus_session_manager_get_interface_skeleton (session_manager);
MetaDBusRemoteDesktop *interface =
META_DBUS_REMOTE_DESKTOP (interface_skeleton);
MetaBackend *backend = meta_dbus_session_manager_get_backend (session_manager);
g_signal_connect (interface, "handle-create-session",
G_CALLBACK (handle_create_session), remote_desktop);
meta_dbus_remote_desktop_set_supported_device_types ( meta_dbus_remote_desktop_set_supported_device_types (
META_DBUS_REMOTE_DESKTOP (remote_desktop), interface,
calculate_supported_device_types ()); calculate_supported_device_types (backend));
meta_dbus_remote_desktop_set_version ( meta_dbus_remote_desktop_set_version (
META_DBUS_REMOTE_DESKTOP (remote_desktop), interface,
META_REMOTE_DESKTOP_API_VERSION); META_REMOTE_DESKTOP_API_VERSION);
G_OBJECT_CLASS (meta_remote_desktop_parent_class)->constructed (object);
}
MetaRemoteDesktop *
meta_remote_desktop_new (MetaBackend *backend)
{
MetaRemoteDesktop *remote_desktop;
g_autoptr (MetaDBusRemoteDesktop) skeleton = NULL;
skeleton = meta_dbus_remote_desktop_skeleton_new ();
remote_desktop =
g_object_new (META_TYPE_REMOTE_DESKTOP,
"backend", backend,
"service-name", META_REMOTE_DESKTOP_DBUS_SERVICE,
"service-path", META_REMOTE_DESKTOP_DBUS_PATH,
"session-gtype", META_TYPE_REMOTE_DESKTOP_SESSION,
"interface-skeleton", skeleton,
NULL);
return remote_desktop;
}
static void
meta_remote_desktop_init (MetaRemoteDesktop *remote_desktop)
{
} }
static void static void
@ -338,5 +167,4 @@ meta_remote_desktop_class_init (MetaRemoteDesktopClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_remote_desktop_constructed; object_class->constructed = meta_remote_desktop_constructed;
object_class->finalize = meta_remote_desktop_finalize;
} }

View File

@ -26,6 +26,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "backends/meta-backend-types.h" #include "backends/meta-backend-types.h"
#include "backends/meta-dbus-session-manager.h"
#include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-watcher.h"
#include "meta-dbus-remote-desktop.h" #include "meta-dbus-remote-desktop.h"
@ -35,20 +36,8 @@ typedef struct _MetaRemoteDesktopSession MetaRemoteDesktopSession;
#define META_TYPE_REMOTE_DESKTOP (meta_remote_desktop_get_type ()) #define META_TYPE_REMOTE_DESKTOP (meta_remote_desktop_get_type ())
G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop, G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop,
META, REMOTE_DESKTOP, META, REMOTE_DESKTOP,
MetaDBusRemoteDesktopSkeleton) MetaDbusSessionManager)
void meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop); MetaRemoteDesktop * meta_remote_desktop_new (MetaBackend *backend);
void meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop);
MetaBackend * meta_remote_desktop_get_backend (MetaRemoteDesktop *remote_desktop);
MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop,
const char *session_id);
GDBusConnection * meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop);
MetaRemoteDesktop * meta_remote_desktop_new (MetaBackend *backend,
MetaDbusSessionWatcher *session_watcher);
#endif /* META_REMOTE_DESKTOP_H */ #endif /* META_REMOTE_DESKTOP_H */

View File

@ -26,6 +26,7 @@
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-cursor-tracker-private.h" #include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-dbus-session-manager.h"
#include "backends/meta-screen-cast-area-stream.h" #include "backends/meta-screen-cast-area-stream.h"
#include "backends/meta-screen-cast-session.h" #include "backends/meta-screen-cast-session.h"
#include "backends/meta-stage-private.h" #include "backends/meta-stage-private.h"

View File

@ -25,6 +25,7 @@
#include "backends/meta-screen-cast-session.h" #include "backends/meta-screen-cast-session.h"
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-dbus-session-manager.h"
#include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-watcher.h"
#include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-access-controller-private.h"
#include "backends/meta-screen-cast-area-stream.h" #include "backends/meta-screen-cast-area-stream.h"
@ -34,18 +35,35 @@
#include "backends/meta-screen-cast-window-stream.h" #include "backends/meta-screen-cast-window-stream.h"
#include "core/display-private.h" #include "core/display-private.h"
#include "meta-private-enum-types.h"
#define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session" #define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session"
enum
{
PROP_0,
PROP_SESSION_MANAGER,
PROP_PEER_NAME,
PROP_ID,
PROP_SESSION_TYPE,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS];
struct _MetaScreenCastSession struct _MetaScreenCastSession
{ {
MetaDBusScreenCastSessionSkeleton parent; MetaDBusScreenCastSessionSkeleton parent;
MetaScreenCast *screen_cast; MetaDbusSessionManager *session_manager;
char *peer_name; char *peer_name;
MetaScreenCastSessionType session_type; MetaScreenCastSessionType session_type;
char *object_path; char *object_path;
char *session_id;
GList *streams; GList *streams;
@ -55,6 +73,8 @@ struct _MetaScreenCastSession
gboolean disable_animations; gboolean disable_animations;
}; };
static void initable_init_iface (GInitableIface *iface);
static void static void
meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface); meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface);
@ -64,6 +84,8 @@ meta_dbus_session_init_iface (MetaDbusSessionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaScreenCastSession, G_DEFINE_TYPE_WITH_CODE (MetaScreenCastSession,
meta_screen_cast_session, meta_screen_cast_session,
META_DBUS_TYPE_SCREEN_CAST_SESSION_SKELETON, META_DBUS_TYPE_SCREEN_CAST_SESSION_SKELETON,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_init_iface)
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST_SESSION, G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST_SESSION,
meta_screen_cast_session_init_iface) meta_screen_cast_session_init_iface)
G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION,
@ -87,7 +109,7 @@ static void
init_remote_access_handle (MetaScreenCastSession *session) init_remote_access_handle (MetaScreenCastSession *session)
{ {
MetaBackend *backend = MetaBackend *backend =
meta_screen_cast_get_backend (session->screen_cast); meta_dbus_session_manager_get_backend (session->session_manager);
MetaRemoteAccessController *remote_access_controller; MetaRemoteAccessController *remote_access_controller;
MetaRemoteAccessHandle *remote_access_handle; MetaRemoteAccessHandle *remote_access_handle;
@ -164,6 +186,14 @@ meta_screen_cast_session_close (MetaDbusSession *dbus_session)
g_object_unref (session); g_object_unref (session);
} }
static const char *
meta_screen_cast_session_get_id (MetaDbusSession *dbus_session)
{
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (dbus_session);
return session->session_id;
}
MetaScreenCastStream * MetaScreenCastStream *
meta_screen_cast_session_get_stream (MetaScreenCastSession *session, meta_screen_cast_session_get_stream (MetaScreenCastSession *session,
const char *path) const char *path)
@ -185,7 +215,7 @@ meta_screen_cast_session_get_stream (MetaScreenCastSession *session,
MetaScreenCast * MetaScreenCast *
meta_screen_cast_session_get_screen_cast (MetaScreenCastSession *session) meta_screen_cast_session_get_screen_cast (MetaScreenCastSession *session)
{ {
return session->screen_cast; return META_SCREEN_CAST (session->session_manager);
} }
void void
@ -221,6 +251,38 @@ check_permission (MetaScreenCastSession *session,
g_dbus_method_invocation_get_sender (invocation)) == 0; g_dbus_method_invocation_get_sender (invocation)) == 0;
} }
static gboolean
meta_screen_cast_session_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (initable);
GDBusInterfaceSkeleton *interface_skeleton;
GDBusConnection *connection;
static unsigned int global_session_number = 0;
session->object_path =
g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u",
++global_session_number);
interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
connection =
meta_dbus_session_manager_get_connection (session->session_manager);
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
session->object_path,
error))
return FALSE;
return TRUE;
}
static void
initable_init_iface (GInitableIface *iface)
{
iface->init = meta_screen_cast_session_initable_init;
}
static gboolean static gboolean
handle_start (MetaDBusScreenCastSession *skeleton, handle_start (MetaDBusScreenCastSession *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
@ -326,7 +388,7 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton,
GDBusInterfaceSkeleton *interface_skeleton; GDBusInterfaceSkeleton *interface_skeleton;
GDBusConnection *connection; GDBusConnection *connection;
MetaBackend *backend = MetaBackend *backend =
meta_screen_cast_get_backend (session->screen_cast); meta_dbus_session_manager_get_backend (session->session_manager);
MetaMonitorManager *monitor_manager = MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend); meta_backend_get_monitor_manager (backend);
MetaMonitor *monitor; MetaMonitor *monitor;
@ -426,7 +488,7 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
{ {
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
MetaBackend *backend = MetaBackend *backend =
meta_screen_cast_get_backend (session->screen_cast); meta_dbus_session_manager_get_backend (session->session_manager);
MetaContext *context = meta_backend_get_context (backend); MetaContext *context = meta_backend_get_context (backend);
MetaDisplay *display = meta_context_get_display (context); MetaDisplay *display = meta_context_get_display (context);
GDBusInterfaceSkeleton *interface_skeleton; GDBusInterfaceSkeleton *interface_skeleton;
@ -580,7 +642,7 @@ handle_record_area (MetaDBusScreenCastSession *skeleton,
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton); interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton); connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
backend = meta_screen_cast_get_backend (session->screen_cast); backend = meta_dbus_session_manager_get_backend (session->session_manager);
stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
flags = META_SCREEN_CAST_FLAG_NONE; flags = META_SCREEN_CAST_FLAG_NONE;
@ -715,36 +777,7 @@ static void
meta_dbus_session_init_iface (MetaDbusSessionInterface *iface) meta_dbus_session_init_iface (MetaDbusSessionInterface *iface)
{ {
iface->close = meta_screen_cast_session_close; iface->close = meta_screen_cast_session_close;
} iface->get_id = meta_screen_cast_session_get_id;
MetaScreenCastSession *
meta_screen_cast_session_new (MetaScreenCast *screen_cast,
MetaScreenCastSessionType session_type,
const char *peer_name,
GError **error)
{
GDBusInterfaceSkeleton *interface_skeleton;
MetaScreenCastSession *session;
GDBusConnection *connection;
static unsigned int global_session_number = 0;
session = g_object_new (META_TYPE_SCREEN_CAST_SESSION, NULL);
session->screen_cast = screen_cast;
session->session_type = session_type;
session->peer_name = g_strdup (peer_name);
session->object_path =
g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u",
++global_session_number);
interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
connection = meta_screen_cast_get_connection (screen_cast);
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
session->object_path,
error))
return NULL;
return session;
} }
static void static void
@ -755,10 +788,67 @@ meta_screen_cast_session_finalize (GObject *object)
g_clear_object (&session->handle); g_clear_object (&session->handle);
g_free (session->peer_name); g_free (session->peer_name);
g_free (session->object_path); g_free (session->object_path);
g_free (session->session_id);
G_OBJECT_CLASS (meta_screen_cast_session_parent_class)->finalize (object); G_OBJECT_CLASS (meta_screen_cast_session_parent_class)->finalize (object);
} }
static void
meta_screen_cast_session_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object);
switch (prop_id)
{
case PROP_SESSION_MANAGER:
session->session_manager = g_value_get_object (value);
break;
case PROP_PEER_NAME:
session->peer_name = g_value_dup_string (value);
break;
case PROP_ID:
session->session_id = g_value_dup_string (value);
break;
case PROP_SESSION_TYPE:
session->session_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_screen_cast_session_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object);
switch (prop_id)
{
case PROP_SESSION_MANAGER:
g_value_set_object (value, session->session_manager);
break;
case PROP_PEER_NAME:
g_value_set_string (value, session->peer_name);
break;
case PROP_ID:
g_value_set_string (value, session->session_id);
break;
case PROP_SESSION_TYPE:
g_value_set_enum (value, session->session_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void static void
meta_screen_cast_session_init (MetaScreenCastSession *session) meta_screen_cast_session_init (MetaScreenCastSession *session)
{ {
@ -770,6 +860,43 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_screen_cast_session_finalize; object_class->finalize = meta_screen_cast_session_finalize;
object_class->set_property = meta_screen_cast_session_set_property;
object_class->get_property = meta_screen_cast_session_get_property;
obj_props[PROP_SESSION_MANAGER] =
g_param_spec_object ("session-manager",
"session manager",
"D-Bus session manager",
META_TYPE_DBUS_SESSION_MANAGER,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_PEER_NAME] =
g_param_spec_string ("peer-name",
"peer name",
"D-Bus peer name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_ID] =
g_param_spec_string ("id",
"session id",
"Unique ID of the session",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_SESSION_TYPE] =
g_param_spec_enum ("session-type",
"session type",
"The type of screen cast session",
META_TYPE_SCREEN_CAST_SESSION_TYPE,
META_SCREEN_CAST_SESSION_TYPE_NORMAL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
} }
static gboolean static gboolean

View File

@ -51,11 +51,6 @@ char * meta_screen_cast_session_get_peer_name (MetaScreenCastSession *session);
MetaScreenCastSessionType meta_screen_cast_session_get_session_type (MetaScreenCastSession *session); MetaScreenCastSessionType meta_screen_cast_session_get_session_type (MetaScreenCastSession *session);
MetaScreenCastSession * meta_screen_cast_session_new (MetaScreenCast *screen_cast,
MetaScreenCastSessionType session_type,
const char *peer_name,
GError **error);
gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, gboolean meta_screen_cast_session_start (MetaScreenCastSession *session,
GError **error); GError **error);

View File

@ -36,64 +36,20 @@
struct _MetaScreenCast struct _MetaScreenCast
{ {
MetaDBusScreenCastSkeleton parent; MetaDbusSessionManager parent;
int dbus_name_id;
int inhibit_count;
GList *sessions;
MetaDbusSessionWatcher *session_watcher;
MetaBackend *backend;
gboolean disable_dma_bufs; gboolean disable_dma_bufs;
}; };
static void G_DEFINE_TYPE (MetaScreenCast, meta_screen_cast,
meta_screen_cast_init_iface (MetaDBusScreenCastIface *iface); META_TYPE_DBUS_SESSION_MANAGER)
G_DEFINE_TYPE_WITH_CODE (MetaScreenCast, meta_screen_cast,
META_DBUS_TYPE_SCREEN_CAST_SKELETON,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST,
meta_screen_cast_init_iface))
void
meta_screen_cast_inhibit (MetaScreenCast *screen_cast)
{
screen_cast->inhibit_count++;
if (screen_cast->inhibit_count == 1)
{
while (screen_cast->sessions)
{
MetaScreenCastSession *session = screen_cast->sessions->data;
meta_dbus_session_close (META_DBUS_SESSION (session));
}
}
}
void
meta_screen_cast_uninhibit (MetaScreenCast *screen_cast)
{
g_return_if_fail (screen_cast->inhibit_count > 0);
screen_cast->inhibit_count--;
}
GDBusConnection *
meta_screen_cast_get_connection (MetaScreenCast *screen_cast)
{
GDBusInterfaceSkeleton *interface_skeleton =
G_DBUS_INTERFACE_SKELETON (screen_cast);
return g_dbus_interface_skeleton_get_connection (interface_skeleton);
}
MetaBackend * MetaBackend *
meta_screen_cast_get_backend (MetaScreenCast *screen_cast) meta_screen_cast_get_backend (MetaScreenCast *screen_cast)
{ {
return screen_cast->backend; MetaDbusSessionManager *session_manager = META_DBUS_SESSION_MANAGER (screen_cast);
return meta_dbus_session_manager_get_backend (session_manager);
} }
void void
@ -107,8 +63,12 @@ meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast,
int width, int width,
int height) int height)
{ {
MetaDbusSessionManager *session_manager =
META_DBUS_SESSION_MANAGER (screen_cast);
MetaBackend *backend =
meta_dbus_session_manager_get_backend (session_manager);
ClutterBackend *clutter_backend = ClutterBackend *clutter_backend =
meta_backend_get_clutter_backend (screen_cast->backend); meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = CoglContext *cogl_context =
clutter_backend_get_cogl_context (clutter_backend); clutter_backend_get_cogl_context (clutter_backend);
CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context); CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
@ -140,19 +100,28 @@ register_remote_desktop_screen_cast_session (MetaScreenCastSession *session,
{ {
MetaScreenCast *screen_cast = MetaScreenCast *screen_cast =
meta_screen_cast_session_get_screen_cast (session); meta_screen_cast_session_get_screen_cast (session);
MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); 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); 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; MetaRemoteDesktopSession *remote_desktop_session;
remote_desktop_session = remote_desktop_dbus_session =
meta_remote_desktop_get_session (remote_desktop, remote_desktop_session_id); meta_dbus_session_manager_get_session (remote_desktop_session_manager,
if (!remote_desktop_session) remote_desktop_session_id);
if (!remote_desktop_dbus_session)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"No remote desktop session found"); "No remote desktop session found");
return FALSE; return FALSE;
} }
remote_desktop_session =
META_REMOTE_DESKTOP_SESSION (remote_desktop_dbus_session);
if (!meta_remote_desktop_session_register_screen_cast (remote_desktop_session, if (!meta_remote_desktop_session_register_screen_cast (remote_desktop_session,
session, session,
error)) error))
@ -161,36 +130,21 @@ register_remote_desktop_screen_cast_session (MetaScreenCastSession *session,
return TRUE; return TRUE;
} }
static void
on_session_closed (MetaScreenCastSession *session,
MetaScreenCast *screen_cast)
{
screen_cast->sessions = g_list_remove (screen_cast->sessions, session);
}
static gboolean static gboolean
handle_create_session (MetaDBusScreenCast *skeleton, handle_create_session (MetaDBusScreenCast *skeleton,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
GVariant *properties) GVariant *properties,
MetaScreenCast *screen_cast)
{ {
MetaScreenCast *screen_cast = META_SCREEN_CAST (skeleton); MetaDbusSessionManager *session_manager =
const char *peer_name; META_DBUS_SESSION_MANAGER (screen_cast);
MetaScreenCastSession *session;
GError *error = NULL;
const char *session_path;
const char *client_dbus_name;
char *remote_desktop_session_id = NULL; char *remote_desktop_session_id = NULL;
gboolean disable_animations;
MetaScreenCastSessionType session_type; MetaScreenCastSessionType session_type;
MetaDbusSession *dbus_session;
if (screen_cast->inhibit_count > 0) MetaScreenCastSession *session;
{ g_autoptr (GError) error = NULL;
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, gboolean disable_animations;
G_DBUS_ERROR_ACCESS_DENIED, const char *session_path;
"Session creation inhibited");
return TRUE;
}
g_variant_lookup (properties, "remote-desktop-session-id", "s", g_variant_lookup (properties, "remote-desktop-session-id", "s",
&remote_desktop_session_id); &remote_desktop_session_id);
@ -200,24 +154,20 @@ handle_create_session (MetaDBusScreenCast *skeleton,
else else
session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL; session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL;
peer_name = g_dbus_method_invocation_get_sender (invocation); dbus_session =
session = meta_screen_cast_session_new (screen_cast, meta_dbus_session_manager_create_session (session_manager,
session_type, invocation,
peer_name, &error,
&error); "session-type", session_type,
if (!session) NULL);
if (!dbus_session)
{ {
g_warning ("Failed to create screen cast session: %s", g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
error->message);
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED, G_DBUS_ERROR_FAILED,
"Failed to create session: %s",
error->message); error->message);
g_error_free (error); return G_DBUS_METHOD_INVOCATION_HANDLED;
return TRUE;
} }
session = META_SCREEN_CAST_SESSION (dbus_session);
if (remote_desktop_session_id) if (remote_desktop_session_id)
{ {
@ -228,9 +178,8 @@ handle_create_session (MetaDBusScreenCast *skeleton,
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED, G_DBUS_ERROR_FAILED,
"%s", error->message); "%s", error->message);
g_error_free (error); meta_dbus_session_close (dbus_session);
g_object_unref (session); return G_DBUS_METHOD_INVOCATION_HANDLED;
return TRUE;
} }
} }
@ -240,121 +189,46 @@ handle_create_session (MetaDBusScreenCast *skeleton,
meta_screen_cast_session_set_disable_animations (session, meta_screen_cast_session_set_disable_animations (session,
disable_animations); disable_animations);
} }
client_dbus_name = g_dbus_method_invocation_get_sender (invocation);
meta_dbus_session_watcher_watch_session (screen_cast->session_watcher,
client_dbus_name,
META_DBUS_SESSION (session));
session_path = meta_screen_cast_session_get_object_path (session); session_path = meta_screen_cast_session_get_object_path (session);
meta_dbus_screen_cast_complete_create_session (skeleton, meta_dbus_screen_cast_complete_create_session (skeleton,
invocation, invocation,
session_path); session_path);
return G_DBUS_METHOD_INVOCATION_HANDLED;
screen_cast->sessions = g_list_append (screen_cast->sessions, session);
g_signal_connect (session, "session-closed",
G_CALLBACK (on_session_closed),
screen_cast);
return TRUE;
}
static void
meta_screen_cast_init_iface (MetaDBusScreenCastIface *iface)
{
iface->handle_create_session = handle_create_session;
}
static void
on_bus_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
MetaScreenCast *screen_cast = user_data;
GDBusInterfaceSkeleton *interface_skeleton =
G_DBUS_INTERFACE_SKELETON (screen_cast);
g_autoptr (GError) error = NULL;
if (!g_dbus_interface_skeleton_export (interface_skeleton,
connection,
META_SCREEN_CAST_DBUS_PATH,
&error))
g_warning ("Failed to export screen cast object: %s", error->message);
}
static void
on_name_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_info ("Acquired name %s", name);
}
static void
on_name_lost (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
g_warning ("Lost or failed to acquire name %s", name);
} }
static void static void
meta_screen_cast_constructed (GObject *object) meta_screen_cast_constructed (GObject *object)
{ {
MetaScreenCast *screen_cast = META_SCREEN_CAST (object); MetaScreenCast *screen_cast = META_SCREEN_CAST (object);
MetaDbusSessionManager *session_manager =
META_DBUS_SESSION_MANAGER (screen_cast);
GDBusInterfaceSkeleton *interface_skeleton =
meta_dbus_session_manager_get_interface_skeleton (session_manager);
MetaDBusScreenCast *skeleton = META_DBUS_SCREEN_CAST (interface_skeleton);
screen_cast->dbus_name_id = g_signal_connect (interface_skeleton, "handle-create-session",
g_bus_own_name (G_BUS_TYPE_SESSION, G_CALLBACK (handle_create_session), screen_cast);
META_SCREEN_CAST_DBUS_SERVICE,
G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
screen_cast,
NULL);
}
static void meta_dbus_screen_cast_set_version (skeleton, META_SCREEN_CAST_API_VERSION);
meta_screen_cast_finalize (GObject *object)
{
MetaScreenCast *screen_cast = META_SCREEN_CAST (object);
if (screen_cast->dbus_name_id) G_OBJECT_CLASS (meta_screen_cast_parent_class)->constructed (object);
g_bus_unown_name (screen_cast->dbus_name_id);
g_assert (!screen_cast->sessions);
G_OBJECT_CLASS (meta_screen_cast_parent_class)->finalize (object);
}
static void
on_prepare_shutdown (MetaBackend *backend,
MetaScreenCast *screen_cast)
{
while (screen_cast->sessions)
{
MetaScreenCastSession *session = screen_cast->sessions->data;
if (meta_screen_cast_session_get_session_type (session) !=
META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP)
meta_dbus_session_close (META_DBUS_SESSION (session));
}
} }
MetaScreenCast * MetaScreenCast *
meta_screen_cast_new (MetaBackend *backend, meta_screen_cast_new (MetaBackend *backend)
MetaDbusSessionWatcher *session_watcher)
{ {
MetaScreenCast *screen_cast; MetaScreenCast *screen_cast;
g_autoptr (MetaDBusScreenCast) skeleton = NULL;
screen_cast = g_object_new (META_TYPE_SCREEN_CAST, NULL); skeleton = meta_dbus_screen_cast_skeleton_new ();
screen_cast->backend = backend; screen_cast =
screen_cast->session_watcher = session_watcher; g_object_new (META_TYPE_SCREEN_CAST,
"backend", backend,
g_signal_connect (backend, "prepare-shutdown", "service-name", META_SCREEN_CAST_DBUS_SERVICE,
G_CALLBACK (on_prepare_shutdown), "service-path", META_SCREEN_CAST_DBUS_PATH,
screen_cast); "session-gtype", META_TYPE_SCREEN_CAST_SESSION,
"interface-skeleton", skeleton,
NULL);
return screen_cast; return screen_cast;
} }
@ -369,9 +243,6 @@ meta_screen_cast_init (MetaScreenCast *screen_cast)
pw_init (NULL, NULL); pw_init (NULL, NULL);
is_pipewire_initialized = TRUE; is_pipewire_initialized = TRUE;
} }
meta_dbus_screen_cast_set_version (META_DBUS_SCREEN_CAST (screen_cast),
META_SCREEN_CAST_API_VERSION);
} }
static void static void
@ -380,5 +251,4 @@ meta_screen_cast_class_init (MetaScreenCastClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_screen_cast_constructed; object_class->constructed = meta_screen_cast_constructed;
object_class->finalize = meta_screen_cast_finalize;
} }

View File

@ -26,6 +26,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-dbus-session-manager.h"
#include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-watcher.h"
#include "meta-dbus-screen-cast.h" #include "meta-dbus-screen-cast.h"
@ -47,13 +48,7 @@ typedef enum _MetaScreenCastFlag
#define META_TYPE_SCREEN_CAST (meta_screen_cast_get_type ()) #define META_TYPE_SCREEN_CAST (meta_screen_cast_get_type ())
G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast, G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
META, SCREEN_CAST, META, SCREEN_CAST,
MetaDBusScreenCastSkeleton) MetaDbusSessionManager)
void meta_screen_cast_inhibit (MetaScreenCast *screen_cast);
void meta_screen_cast_uninhibit (MetaScreenCast *screen_cast);
GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast); MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);
@ -63,7 +58,6 @@ CoglDmaBufHandle * meta_screen_cast_create_dma_buf_handle (MetaScreenCast *scree
int width, int width,
int height); int height);
MetaScreenCast * meta_screen_cast_new (MetaBackend *backend, MetaScreenCast * meta_screen_cast_new (MetaBackend *backend);
MetaDbusSessionWatcher *session_watcher);
#endif /* META_SCREEN_CAST_H */ #endif /* META_SCREEN_CAST_H */

View File

@ -845,6 +845,7 @@ mutter_private_enum_sources = []
if have_remote_desktop if have_remote_desktop
mutter_private_enum_sources += [ mutter_private_enum_sources += [
'backends/meta-screen-cast.h', 'backends/meta-screen-cast.h',
'backends/meta-screen-cast-session.h',
] ]
endif endif