[mutter] ScreenCast: Allow recording new streams on active sessions



commit 70c6d28fca0768415277d4e6556212d068910ced
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Sat Jul 31 20:46:23 2021 +0200

    ScreenCast: Allow recording new streams on active sessions
    
    This is useful if you have a session, and want to "hot-plug" new sources
    over time; there is no point in having to create separate sessions for this.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2131>

 .../org.gnome.Mutter.ScreenCast.xml                |  8 +++
 src/backends/meta-screen-cast-stream.c             | 71 ++++++++++++++++++++++
 2 files changed, 79 insertions(+)
---
diff --git a/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml 
b/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml
index d9f1f4435d..afc09c61b0 100644
--- a/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml
+++ b/data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml
@@ -190,6 +190,14 @@
   -->
   <interface name="org.gnome.Mutter.ScreenCast.Stream">
 
+    <!--
+       Start:
+       @short_description: Start new stream
+
+       Start a stream of an already started session.
+    -->
+    <method name="Start"/>
+
     <!--
        PipeWireStreamAdded:
        @short_description: Pipewire stream added
diff --git a/src/backends/meta-screen-cast-stream.c b/src/backends/meta-screen-cast-stream.c
index b8ab5abd57..bf8648ab6f 100644
--- a/src/backends/meta-screen-cast-stream.c
+++ b/src/backends/meta-screen-cast-stream.c
@@ -63,12 +63,17 @@ typedef struct _MetaScreenCastStreamPrivate
   MetaScreenCastStreamSrc *src;
 } MetaScreenCastStreamPrivate;
 
+static void
+meta_screen_cast_stream_init_iface (MetaDBusScreenCastStreamIface *iface);
+
 static void
 meta_screen_cast_stream_init_initable_iface (GInitableIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStream,
                          meta_screen_cast_stream,
                          META_DBUS_TYPE_SCREEN_CAST_STREAM_SKELETON,
+                         G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST_STREAM,
+                                                meta_screen_cast_stream_init_iface)
                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                 meta_screen_cast_stream_init_initable_iface)
                          G_ADD_PRIVATE (MetaScreenCastStream))
@@ -137,6 +142,13 @@ meta_screen_cast_stream_start (MetaScreenCastStream  *stream,
     meta_screen_cast_stream_get_instance_private (stream);
   MetaScreenCastStreamSrc *src;
 
+  if (priv->src)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Stream already started");
+      return FALSE;
+    }
+
   src = meta_screen_cast_stream_create_src (stream, error);
   if (!src)
     return FALSE;
@@ -280,6 +292,65 @@ meta_screen_cast_stream_finalize (GObject *object)
   G_OBJECT_CLASS (meta_screen_cast_stream_parent_class)->finalize (object);
 }
 
+static gboolean
+check_permission (MetaScreenCastStream  *stream,
+                  GDBusMethodInvocation *invocation)
+{
+  MetaScreenCastStreamPrivate *priv =
+    meta_screen_cast_stream_get_instance_private (stream);
+  char *peer_name;
+
+  peer_name = meta_screen_cast_session_get_peer_name (priv->session);
+  return g_strcmp0 (peer_name,
+                    g_dbus_method_invocation_get_sender (invocation)) == 0;
+}
+
+static gboolean
+handle_start (MetaDBusScreenCastStream *skeleton,
+              GDBusMethodInvocation    *invocation)
+{
+  MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (skeleton);
+  MetaScreenCastStreamPrivate *priv =
+    meta_screen_cast_stream_get_instance_private (stream);
+  g_autoptr (GError) error = NULL;
+
+  if (!check_permission (stream, invocation))
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_ACCESS_DENIED,
+                                             "Permission denied");
+      return TRUE;
+    }
+
+  if (!meta_screen_cast_session_is_active (priv->session))
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_FAILED,
+                                             "Failed to start stream: "
+                                             "session not started");
+      return TRUE;
+    }
+
+  if (!meta_screen_cast_stream_start (stream, &error))
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_FAILED,
+                                             "Failed to start stream: %s",
+                                             error->message);
+      return TRUE;
+    }
+
+  meta_dbus_screen_cast_stream_complete_start (skeleton, invocation);
+
+  return TRUE;
+}
+
+static void
+meta_screen_cast_stream_init_iface (MetaDBusScreenCastStreamIface *iface)
+{
+  iface->handle_start = handle_start;
+}
+
 static gboolean
 meta_screen_cast_stream_initable_init (GInitable     *initable,
                                        GCancellable  *cancellable,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]