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>
This commit is contained in:
Jonas Ådahl 2021-07-31 20:46:23 +02:00 committed by Marge Bot
parent 764c75d2fb
commit 70c6d28fca
2 changed files with 79 additions and 0 deletions

View File

@ -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

View File

@ -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,