diff --git a/src/Makefile.am b/src/Makefile.am index 5bbac70e8..aaf7c9c80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -161,6 +161,9 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \ backends/meta-renderer.h \ backends/meta-renderer-view.c \ backends/meta-renderer-view.h \ + backends/meta-remote-access-controller.c \ + backends/meta-remote-access-controller-private.h \ + meta/meta-remote-access-controller.h \ backends/edid-parse.c \ backends/edid.h \ backends/gsm-inhibitor-flag.h \ @@ -546,6 +549,7 @@ libmutterinclude_headers = \ meta/meta-idle-monitor.h \ meta/meta-plugin.h \ meta/meta-monitor-manager.h \ + meta/meta-remote-access-controller.h \ meta/meta-settings.h \ meta/meta-shaped-texture.h \ meta/meta-shadow-factory.h \ diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 9348aa1bb..888e51cd9 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -39,6 +39,7 @@ #ifdef HAVE_REMOTE_DESKTOP #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-screen-cast.h" +#include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-desktop.h" #endif @@ -92,6 +93,7 @@ struct _MetaBackendPrivate MetaEgl *egl; MetaSettings *settings; #ifdef HAVE_REMOTE_DESKTOP + MetaRemoteAccessController *remote_access_controller; MetaDbusSessionWatcher *dbus_session_watcher; MetaScreenCast *screen_cast; MetaRemoteDesktop *remote_desktop; @@ -139,6 +141,7 @@ meta_backend_finalize (GObject *object) g_clear_object (&priv->remote_desktop); g_clear_object (&priv->screen_cast); g_clear_object (&priv->dbus_session_watcher); + g_clear_object (&priv->remote_access_controller); #endif g_object_unref (priv->up_client); @@ -450,6 +453,8 @@ meta_backend_real_post_init (MetaBackend *backend) priv->input_settings = meta_backend_create_input_settings (backend); #ifdef HAVE_REMOTE_DESKTOP + priv->remote_access_controller = + g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL); priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL); priv->screen_cast = meta_screen_cast_new (priv->dbus_session_watcher); priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher); @@ -777,6 +782,24 @@ meta_backend_get_remote_desktop (MetaBackend *backend) } #endif /* HAVE_REMOTE_DESKTOP */ +/** + * meta_backend_get_remote_access_controller: + * @backend: A #MetaBackend + * + * Return Value: (transfer none): The #MetaRemoteAccessController + */ +MetaRemoteAccessController * +meta_backend_get_remote_access_controller (MetaBackend *backend) +{ +#ifdef HAVE_REMOTE_DESKTOP + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->remote_access_controller; +#else + return NULL; +#endif +} + /** * meta_backend_grab_device: (skip) */ diff --git a/src/backends/meta-remote-access-controller-private.h b/src/backends/meta-remote-access-controller-private.h new file mode 100644 index 000000000..fce2082bf --- /dev/null +++ b/src/backends/meta-remote-access-controller-private.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H +#define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H + +#include "meta/meta-remote-access-controller.h" + +void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, + MetaRemoteAccessHandle *handle); + +void meta_remote_access_handle_notify_stopped (MetaRemoteAccessHandle *handle); + +#endif /* META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H */ diff --git a/src/backends/meta-remote-access-controller.c b/src/backends/meta-remote-access-controller.c new file mode 100644 index 000000000..0e0ebe2bd --- /dev/null +++ b/src/backends/meta-remote-access-controller.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-remote-access-controller-private.h" + +enum +{ + HANDLE_STOPPED, + + N_HANDLE_SIGNALS +}; + +static int handle_signals[N_HANDLE_SIGNALS]; + +enum +{ + CONTROLLER_NEW_HANDLE, + + N_CONTROLLER_SIGNALS +}; + +static int controller_signals[N_CONTROLLER_SIGNALS]; + +typedef struct _MetaRemoteAccessHandlePrivate +{ + gboolean has_stopped; +} MetaRemoteAccessHandlePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle, + meta_remote_access_handle, + G_TYPE_OBJECT) + +struct _MetaRemoteAccessController +{ + GObject parent; +}; + +G_DEFINE_TYPE (MetaRemoteAccessController, + meta_remote_access_controller, + G_TYPE_OBJECT) + +/** + * meta_remote_access_handle_stop: + * @handle: A #MetaRemoteAccessHandle + * + * Stop the associated remote access session. + */ +void +meta_remote_access_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + if (priv->has_stopped) + return; + + META_REMOTE_ACCESS_HANDLE_GET_CLASS (handle)->stop (handle); +} + +void +meta_remote_access_handle_notify_stopped (MetaRemoteAccessHandle *handle) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + priv->has_stopped = TRUE; + g_signal_emit (handle, handle_signals[HANDLE_STOPPED], 0); +} + +void +meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, + MetaRemoteAccessHandle *handle) +{ + g_signal_emit (controller, controller_signals[CONTROLLER_NEW_HANDLE], 0, + handle); +} + +static void +meta_remote_access_handle_init (MetaRemoteAccessHandle *handle) +{ +} + +static void +meta_remote_access_handle_class_init (MetaRemoteAccessHandleClass *klass) +{ + handle_signals[HANDLE_STOPPED] = + g_signal_new ("stopped", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_remote_access_controller_init (MetaRemoteAccessController *controller) +{ +} + +static void +meta_remote_access_controller_class_init (MetaRemoteAccessControllerClass *klass) +{ + controller_signals[CONTROLLER_NEW_HANDLE] = + g_signal_new ("new-handle", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_REMOTE_ACCESS_HANDLE); +} diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index 821b16724..73bcf663b 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -30,6 +30,7 @@ #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-screen-cast-session.h" +#include "backends/meta-remote-access-controller-private.h" #include "backends/native/meta-backend-native.h" #include "backends/x11/meta-backend-x11.h" #include "cogl/cogl.h" @@ -59,6 +60,8 @@ struct _MetaRemoteDesktopSession ClutterVirtualInputDevice *virtual_pointer; ClutterVirtualInputDevice *virtual_keyboard; ClutterVirtualInputDevice *virtual_touchscreen; + + MetaRemoteDesktopSessionHandle *handle; }; static void @@ -75,12 +78,41 @@ G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktopSession, G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, meta_dbus_session_init_iface)) +struct _MetaRemoteDesktopSessionHandle +{ + MetaRemoteAccessHandle parent; + + MetaRemoteDesktopSession *session; +}; + +G_DEFINE_TYPE (MetaRemoteDesktopSessionHandle, + meta_remote_desktop_session_handle, + META_TYPE_REMOTE_ACCESS_HANDLE) + +static MetaRemoteDesktopSessionHandle * +meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session); + static gboolean meta_remote_desktop_session_is_running (MetaRemoteDesktopSession *session) { return !!session->virtual_pointer; } +static void +init_remote_access_handle (MetaRemoteDesktopSession *session) +{ + MetaBackend *backend = meta_get_backend (); + MetaRemoteAccessController *remote_access_controller; + MetaRemoteAccessHandle *remote_access_handle; + + session->handle = meta_remote_desktop_session_handle_new (session); + + remote_access_controller = meta_backend_get_remote_access_controller (backend); + remote_access_handle = META_REMOTE_ACCESS_HANDLE (session->handle); + meta_remote_access_controller_notify_new_handle (remote_access_controller, + remote_access_handle); +} + static gboolean meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, GError **error) @@ -107,6 +139,8 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, clutter_device_manager_create_virtual_device (device_manager, CLUTTER_TOUCHSCREEN_DEVICE); + init_remote_access_handle (session); + return TRUE; } @@ -131,6 +165,14 @@ meta_remote_desktop_session_close (MetaRemoteDesktopSession *session) meta_dbus_remote_desktop_session_emit_closed (skeleton); g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (session)); + if (session->handle) + { + MetaRemoteAccessHandle *remote_access_handle = + META_REMOTE_ACCESS_HANDLE (session->handle); + + meta_remote_access_handle_notify_stopped (remote_access_handle); + } + g_object_unref (session); } @@ -729,6 +771,7 @@ meta_remote_desktop_session_finalize (GObject *object) g_assert (!meta_remote_desktop_session_is_running (session)); + g_clear_object (&session->handle); g_free (session->peer_name); g_free (session->session_id); g_free (session->object_path); @@ -763,3 +806,40 @@ meta_remote_desktop_session_class_init (MetaRemoteDesktopSessionClass *klass) object_class->finalize = meta_remote_desktop_session_finalize; } + +static MetaRemoteDesktopSessionHandle * +meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session) +{ + MetaRemoteDesktopSessionHandle *handle; + + handle = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION_HANDLE, NULL); + handle->session = session; + + return handle; +} + +static void +meta_remote_desktop_session_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaRemoteDesktopSession *session; + + session = META_REMOTE_DESKTOP_SESSION_HANDLE (handle)->session; + if (!session) + return; + + meta_remote_desktop_session_close (session); +} + +static void +meta_remote_desktop_session_handle_init (MetaRemoteDesktopSessionHandle *handle) +{ +} + +static void +meta_remote_desktop_session_handle_class_init (MetaRemoteDesktopSessionHandleClass *klass) +{ + MetaRemoteAccessHandleClass *remote_access_handle_class = + META_REMOTE_ACCESS_HANDLE_CLASS (klass); + + remote_access_handle_class->stop = meta_remote_desktop_session_handle_stop; +} diff --git a/src/backends/meta-remote-desktop-session.h b/src/backends/meta-remote-desktop-session.h index 54dce4119..1edb3739b 100644 --- a/src/backends/meta-remote-desktop-session.h +++ b/src/backends/meta-remote-desktop-session.h @@ -33,6 +33,12 @@ G_DECLARE_FINAL_TYPE (MetaRemoteDesktopSession, meta_remote_desktop_session, META, REMOTE_DESKTOP_SESSION, MetaDBusRemoteDesktopSessionSkeleton) +#define META_TYPE_REMOTE_DESKTOP_SESSION_HANDLE (meta_remote_desktop_session_handle_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRemoteDesktopSessionHandle, + meta_remote_desktop_session_handle, + META, REMOTE_DESKTOP_SESSION_HANDLE, + MetaRemoteAccessHandle) + char * meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session); char * meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session); diff --git a/src/backends/meta-screen-cast-session.c b/src/backends/meta-screen-cast-session.c index b95ce514d..e1b6393e8 100644 --- a/src/backends/meta-screen-cast-session.c +++ b/src/backends/meta-screen-cast-session.c @@ -28,6 +28,7 @@ #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-screen-cast-monitor-stream.h" #include "backends/meta-screen-cast-stream.h" +#include "backends/meta-remote-access-controller-private.h" #define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session" @@ -41,6 +42,8 @@ struct _MetaScreenCastSession char *object_path; GList *streams; + + MetaScreenCastSessionHandle *handle; }; static void @@ -57,6 +60,35 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastSession, G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, meta_dbus_session_init_iface)) +struct _MetaScreenCastSessionHandle +{ + MetaRemoteAccessHandle parent; + + MetaScreenCastSession *session; +}; + +G_DEFINE_TYPE (MetaScreenCastSessionHandle, + meta_screen_cast_session_handle, + META_TYPE_REMOTE_ACCESS_HANDLE) + +static MetaScreenCastSessionHandle * +meta_screen_cast_session_handle_new (MetaScreenCastSession *session); + +static void +init_remote_access_handle (MetaScreenCastSession *session) +{ + MetaBackend *backend = meta_get_backend (); + MetaRemoteAccessController *remote_access_controller; + MetaRemoteAccessHandle *remote_access_handle; + + session->handle = meta_screen_cast_session_handle_new (session); + + remote_access_controller = meta_backend_get_remote_access_controller (backend); + remote_access_handle = META_REMOTE_ACCESS_HANDLE (session->handle); + meta_remote_access_controller_notify_new_handle (remote_access_controller, + remote_access_handle); +} + gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, GError **error) @@ -71,6 +103,8 @@ meta_screen_cast_session_start (MetaScreenCastSession *session, return FALSE; } + init_remote_access_handle (session); + return TRUE; } @@ -94,6 +128,14 @@ meta_screen_cast_session_close (MetaScreenCastSession *session) g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (session)); + if (session->handle) + { + MetaRemoteAccessHandle *remote_access_handle = + META_REMOTE_ACCESS_HANDLE (session->handle); + + meta_remote_access_handle_notify_stopped (remote_access_handle); + } + g_object_unref (session); } @@ -361,6 +403,7 @@ meta_screen_cast_session_finalize (GObject *object) { MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object); + g_clear_object (&session->handle); g_free (session->peer_name); g_free (session->object_path); @@ -379,3 +422,40 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass) object_class->finalize = meta_screen_cast_session_finalize; } + +static MetaScreenCastSessionHandle * +meta_screen_cast_session_handle_new (MetaScreenCastSession *session) +{ + MetaScreenCastSessionHandle *handle; + + handle = g_object_new (META_TYPE_SCREEN_CAST_SESSION_HANDLE, NULL); + handle->session = session; + + return handle; +} + +static void +meta_screen_cast_session_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaScreenCastSession *session; + + session = META_SCREEN_CAST_SESSION_HANDLE (handle)->session; + if (!session) + return; + + meta_screen_cast_session_close (session); +} + +static void +meta_screen_cast_session_handle_init (MetaScreenCastSessionHandle *handle) +{ +} + +static void +meta_screen_cast_session_handle_class_init (MetaScreenCastSessionHandleClass *klass) +{ + MetaRemoteAccessHandleClass *remote_access_handle_class = + META_REMOTE_ACCESS_HANDLE_CLASS (klass); + + remote_access_handle_class->stop = meta_screen_cast_session_handle_stop; +} diff --git a/src/backends/meta-screen-cast-session.h b/src/backends/meta-screen-cast-session.h index c877912cf..ac0a31a16 100644 --- a/src/backends/meta-screen-cast-session.h +++ b/src/backends/meta-screen-cast-session.h @@ -26,6 +26,7 @@ #include "backends/meta-screen-cast.h" #include "backends/meta-screen-cast-stream.h" +#include "meta/meta-remote-access-controller.h" typedef enum _MetaScreenCastSessionType { @@ -38,6 +39,12 @@ G_DECLARE_FINAL_TYPE (MetaScreenCastSession, meta_screen_cast_session, META, SCREEN_CAST_SESSION, MetaDBusScreenCastSessionSkeleton) +#define META_TYPE_SCREEN_CAST_SESSION_HANDLE (meta_screen_cast_session_handle_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastSessionHandle, + meta_screen_cast_session_handle, + META, SCREEN_CAST_SESSION_HANDLE, + MetaRemoteAccessHandle) + char * meta_screen_cast_session_get_object_path (MetaScreenCastSession *session); MetaScreenCastSession * meta_screen_cast_session_new (MetaScreenCast *screen_cast, diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h index 8db2360cc..0e5947dc1 100644 --- a/src/meta/meta-backend.h +++ b/src/meta/meta-backend.h @@ -29,6 +29,7 @@ #include #include "meta/meta-dnd.h" +#include "meta/meta-remote-access-controller.h" typedef struct _MetaBackend MetaBackend; typedef struct _MetaBackendClass MetaBackendClass; @@ -54,6 +55,8 @@ MetaDnd *meta_backend_get_dnd (MetaBackend *backend); MetaSettings *meta_backend_get_settings (MetaBackend *backend); +MetaRemoteAccessController * meta_backend_get_remote_access_controller (MetaBackend *backend); + void meta_clutter_init (void); #endif /* META_BACKEND_H */ diff --git a/src/meta/meta-remote-access-controller.h b/src/meta/meta-remote-access-controller.h new file mode 100644 index 000000000..1b66f518c --- /dev/null +++ b/src/meta/meta-remote-access-controller.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_ACCESS_CONTROLLER_H +#define META_REMOTE_ACCESS_CONTROLLER_H + +#include + +#define META_TYPE_REMOTE_ACCESS_HANDLE meta_remote_access_handle_get_type () +G_DECLARE_DERIVABLE_TYPE (MetaRemoteAccessHandle, + meta_remote_access_handle, + META, REMOTE_ACCESS_HANDLE, + GObject) + +struct _MetaRemoteAccessHandleClass +{ + GObjectClass parent_class; + + void (*stop) (MetaRemoteAccessHandle *handle); +}; + +void meta_remote_access_handle_stop (MetaRemoteAccessHandle *handle); + +#define META_TYPE_REMOTE_ACCESS_CONTROLLER meta_remote_access_controller_get_type () +G_DECLARE_FINAL_TYPE (MetaRemoteAccessController, + meta_remote_access_controller, + META, REMOTE_ACCESS_CONTROLLER, + GObject) + +#endif /* META_REMOTE_ACCESS_CONTROLLER_H */