552 lines
19 KiB
Diff
552 lines
19 KiB
Diff
From a38901e5e7f835efe7b7a06c55790c8c20bc91a2 Mon Sep 17 00:00:00 2001
|
|
From: Wim Taymans <wtaymans@redhat.com>
|
|
Date: Tue, 14 Jan 2020 09:37:09 +0100
|
|
Subject: [PATCH] PipeWire: update to 0.3 API
|
|
|
|
---
|
|
configure.ac | 2 +-
|
|
src/camera.c | 24 ++++----
|
|
src/pipewire.c | 141 +++++++++++++---------------------------------
|
|
src/pipewire.h | 10 ++--
|
|
src/screen-cast.c | 98 ++++++--------------------------
|
|
5 files changed, 72 insertions(+), 203 deletions(-)
|
|
|
|
diff --git configure.ac configure.ac
|
|
index 89902fa..62d7960 100644
|
|
--- configure.ac
|
|
+++ configure.ac
|
|
@@ -97,7 +97,7 @@ AC_ARG_ENABLE(pipewire,
|
|
[AS_HELP_STRING([--enable-pipewire],[Enable PipeWire support. Needed for screen cast portal])],
|
|
enable_pipewire=$enableval, enable_pipewire=yes)
|
|
if test x$enable_pipewire = xyes ; then
|
|
- PKG_CHECK_MODULES(PIPEWIRE, [libpipewire-0.2 >= 0.2.6])
|
|
+ PKG_CHECK_MODULES(PIPEWIRE, [libpipewire-0.3 >= 0.2.90])
|
|
AC_DEFINE([HAVE_PIPEWIRE],[1], [Define to enable PipeWire support])
|
|
fi
|
|
AM_CONDITIONAL([HAVE_PIPEWIRE],[test "$enable_pipewire" = "yes"])
|
|
diff --git src/camera.c src/camera.c
|
|
index c2b392c..20fe3aa 100644
|
|
--- src/camera.c
|
|
+++ src/camera.c
|
|
@@ -141,7 +141,7 @@ open_pipewire_camera_remote (const char *app_id,
|
|
GError **error)
|
|
{
|
|
PipeWireRemote *remote;
|
|
- struct spa_dict_item permission_items[1];
|
|
+ struct pw_permission permission_items[2];
|
|
struct pw_properties *pipewire_properties;
|
|
|
|
pipewire_properties =
|
|
@@ -158,12 +158,12 @@ open_pipewire_camera_remote (const char *app_id,
|
|
* Hide all existing and future nodes by default. PipeWire will use the
|
|
* permission store to set up permissions.
|
|
*/
|
|
- permission_items[0].key = PW_CORE_PROXY_PERMISSIONS_DEFAULT;
|
|
- permission_items[0].value = "---";
|
|
+ permission_items[0] = PW_PERMISSION_INIT (PW_ID_CORE, PW_PERM_RWX);
|
|
+ permission_items[1] = PW_PERMISSION_INIT (PW_ID_ANY, 0);
|
|
|
|
- pw_core_proxy_permissions (pw_remote_get_core_proxy (remote->remote),
|
|
- &SPA_DICT_INIT (permission_items,
|
|
- G_N_ELEMENTS (permission_items)));
|
|
+ pw_client_update_permissions (pw_core_get_client(remote->core),
|
|
+ G_N_ELEMENTS (permission_items),
|
|
+ permission_items);
|
|
|
|
pipewire_remote_roundtrip (remote);
|
|
|
|
@@ -219,7 +219,7 @@ handle_open_pipewire_remote (XdpCamera *object,
|
|
}
|
|
|
|
out_fd_list = g_unix_fd_list_new ();
|
|
- fd = pw_remote_steal_fd (remote->remote);
|
|
+ fd = pw_core_steal_fd (remote->core);
|
|
fd_id = g_unix_fd_list_append (out_fd_list, fd, &error);
|
|
close (fd);
|
|
pipewire_remote_destroy (remote);
|
|
@@ -250,29 +250,28 @@ camera_iface_init (XdpCameraIface *iface)
|
|
static void
|
|
global_added_cb (PipeWireRemote *remote,
|
|
uint32_t id,
|
|
- uint32_t type,
|
|
+ const char *type,
|
|
const struct spa_dict *props,
|
|
gpointer user_data)
|
|
{
|
|
Camera *camera = user_data;
|
|
- struct pw_type *core_type = pw_core_get_type (remote->core);
|
|
const struct spa_dict_item *media_class;
|
|
const struct spa_dict_item *media_role;
|
|
|
|
- if (type != core_type->node)
|
|
+ if (strcmp(type, PW_TYPE_INTERFACE_Node) != 0)
|
|
return;
|
|
|
|
if (!props)
|
|
return;
|
|
|
|
- media_class = spa_dict_lookup_item (props, "media.class");
|
|
+ media_class = spa_dict_lookup_item (props, PW_KEY_MEDIA_CLASS);
|
|
if (!media_class)
|
|
return;
|
|
|
|
if (g_strcmp0 (media_class->value, "Video/Source") != 0)
|
|
return;
|
|
|
|
- media_role = spa_dict_lookup_item (props, "media.role");
|
|
+ media_role = spa_dict_lookup_item (props, PW_KEY_MEDIA_ROLE);
|
|
if (!media_role)
|
|
return;
|
|
|
|
@@ -342,6 +341,7 @@ create_pipewire_remote (Camera *camera,
|
|
}
|
|
|
|
pipewire_properties = pw_properties_new ("pipewire.access.portal.is_portal", "true",
|
|
+ "portal.monitor", "Camera",
|
|
NULL);
|
|
camera->pipewire_remote = pipewire_remote_new_sync (pipewire_properties,
|
|
global_added_cb,
|
|
diff --git src/pipewire.c src/pipewire.c
|
|
index 793a378..162cd55 100644
|
|
--- src/pipewire.c
|
|
+++ src/pipewire.c
|
|
@@ -21,6 +21,7 @@
|
|
#include <errno.h>
|
|
#include <glib.h>
|
|
#include <pipewire/pipewire.h>
|
|
+#include <spa/utils/result.h>
|
|
|
|
#include "pipewire.h"
|
|
|
|
@@ -36,27 +37,25 @@ static gboolean is_pipewire_initialized = FALSE;
|
|
static void
|
|
registry_event_global (void *user_data,
|
|
uint32_t id,
|
|
- uint32_t parent_id,
|
|
uint32_t permissions,
|
|
- uint32_t type,
|
|
+ const char *type,
|
|
uint32_t version,
|
|
const struct spa_dict *props)
|
|
{
|
|
PipeWireRemote *remote = user_data;
|
|
- struct pw_type *core_type = pw_core_get_type (remote->core);
|
|
const struct spa_dict_item *factory_object_type;
|
|
PipeWireGlobal *global;
|
|
|
|
global = g_new0 (PipeWireGlobal, 1);
|
|
*global = (PipeWireGlobal) {
|
|
- .parent_id = parent_id,
|
|
+ .parent_id = id,
|
|
};
|
|
|
|
g_hash_table_insert (remote->globals, GINT_TO_POINTER (id), global);
|
|
if (remote->global_added_cb)
|
|
remote->global_added_cb (remote, id, type, props, remote->user_data);
|
|
|
|
- if (type != core_type->factory)
|
|
+ if (strcmp(type, PW_TYPE_INTERFACE_Factory) != 0)
|
|
return;
|
|
|
|
factory_object_type = spa_dict_lookup_item (props, "factory.type.name");
|
|
@@ -81,8 +80,8 @@ registry_event_global_remove (void *user_data,
|
|
g_hash_table_remove (remote->globals, GINT_TO_POINTER (id));
|
|
}
|
|
|
|
-static const struct pw_registry_proxy_events registry_events = {
|
|
- PW_VERSION_REGISTRY_PROXY_EVENTS,
|
|
+static const struct pw_registry_events registry_events = {
|
|
+ PW_VERSION_REGISTRY_EVENTS,
|
|
.global = registry_event_global,
|
|
.global_remove = registry_event_global_remove,
|
|
};
|
|
@@ -90,7 +89,7 @@ static const struct pw_registry_proxy_events registry_events = {
|
|
void
|
|
pipewire_remote_roundtrip (PipeWireRemote *remote)
|
|
{
|
|
- pw_core_proxy_sync (remote->core_proxy, ++remote->sync_seq);
|
|
+ remote->sync_seq = pw_core_sync (remote->core, PW_ID_CORE, remote->sync_seq);
|
|
pw_main_loop_run (remote->loop);
|
|
}
|
|
|
|
@@ -98,16 +97,13 @@ static gboolean
|
|
discover_node_factory_sync (PipeWireRemote *remote,
|
|
GError **error)
|
|
{
|
|
- struct pw_type *core_type = pw_core_get_type (remote->core);
|
|
- struct pw_registry_proxy *registry_proxy;
|
|
+ struct pw_registry *registry;
|
|
|
|
- registry_proxy = pw_core_proxy_get_registry (remote->core_proxy,
|
|
- core_type->registry,
|
|
- PW_VERSION_REGISTRY, 0);
|
|
- pw_registry_proxy_add_listener (registry_proxy,
|
|
- &remote->registry_listener,
|
|
- ®istry_events,
|
|
- remote);
|
|
+ registry = pw_core_get_registry (remote->core, PW_VERSION_REGISTRY, 0);
|
|
+ pw_registry_add_listener (registry,
|
|
+ &remote->registry_listener,
|
|
+ ®istry_events,
|
|
+ remote);
|
|
|
|
pipewire_remote_roundtrip (remote);
|
|
|
|
@@ -122,59 +118,35 @@ discover_node_factory_sync (PipeWireRemote *remote,
|
|
}
|
|
|
|
static void
|
|
-on_state_changed (void *user_data,
|
|
- enum pw_remote_state old,
|
|
- enum pw_remote_state state,
|
|
- const char *error)
|
|
+core_event_error (void *user_data,
|
|
+ uint32_t id,
|
|
+ int seq,
|
|
+ int res,
|
|
+ const char *message)
|
|
{
|
|
PipeWireRemote *remote = user_data;
|
|
|
|
- switch (state)
|
|
+ if (id == PW_ID_CORE)
|
|
{
|
|
- case PW_REMOTE_STATE_ERROR:
|
|
- if (!remote->error)
|
|
- {
|
|
- g_set_error (&remote->error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "%s", error);
|
|
- }
|
|
+ g_set_error (&remote->error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "%s", message);
|
|
pw_main_loop_quit (remote->loop);
|
|
- break;
|
|
- case PW_REMOTE_STATE_UNCONNECTED:
|
|
- if (!remote->error)
|
|
- {
|
|
- g_set_error (&remote->error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Disconnected");
|
|
- }
|
|
- pw_main_loop_quit (remote->loop);
|
|
- break;
|
|
- case PW_REMOTE_STATE_CONNECTING:
|
|
- break;
|
|
- case PW_REMOTE_STATE_CONNECTED:
|
|
- pw_main_loop_quit (remote->loop);
|
|
- break;
|
|
- default:
|
|
- g_warning ("Unknown PipeWire state");
|
|
- break;
|
|
}
|
|
}
|
|
|
|
-static const struct pw_remote_events remote_events = {
|
|
- PW_VERSION_REMOTE_EVENTS,
|
|
- .state_changed = on_state_changed,
|
|
-};
|
|
-
|
|
static void
|
|
core_event_done (void *user_data,
|
|
- uint32_t seq)
|
|
+ uint32_t id, int seq)
|
|
{
|
|
PipeWireRemote *remote = user_data;
|
|
|
|
- if (remote->sync_seq == seq)
|
|
+ if (id == PW_ID_CORE && remote->sync_seq == seq)
|
|
pw_main_loop_quit (remote->loop);
|
|
}
|
|
|
|
-static const struct pw_core_proxy_events core_events = {
|
|
- PW_VERSION_CORE_PROXY_EVENTS,
|
|
+static const struct pw_core_events core_events = {
|
|
+ PW_VERSION_CORE_EVENTS,
|
|
+ .error = core_event_error,
|
|
.done = core_event_done,
|
|
};
|
|
|
|
@@ -237,8 +209,8 @@ void
|
|
pipewire_remote_destroy (PipeWireRemote *remote)
|
|
{
|
|
g_clear_pointer (&remote->globals, g_hash_table_destroy);
|
|
- g_clear_pointer (&remote->remote, pw_remote_destroy);
|
|
- g_clear_pointer (&remote->core, pw_core_destroy);
|
|
+ g_clear_pointer (&remote->core, pw_core_disconnect);
|
|
+ g_clear_pointer (&remote->context, pw_context_destroy);
|
|
g_clear_pointer (&remote->loop, pw_main_loop_destroy);
|
|
g_clear_error (&remote->error);
|
|
|
|
@@ -307,68 +279,31 @@ pipewire_remote_new_sync (struct pw_properties *pipewire_properties,
|
|
return NULL;
|
|
}
|
|
|
|
- remote->core = pw_core_new (pw_main_loop_get_loop (remote->loop), NULL);
|
|
- if (!remote->core)
|
|
+ remote->context = pw_context_new (pw_main_loop_get_loop (remote->loop), NULL, 0);
|
|
+ if (!remote->context)
|
|
{
|
|
pipewire_remote_destroy (remote);
|
|
pw_properties_free (pipewire_properties);
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Couldn't create PipeWire core");
|
|
+ "Couldn't create PipeWire context");
|
|
return NULL;
|
|
}
|
|
|
|
- remote->remote = pw_remote_new (remote->core, pipewire_properties, 0);
|
|
- if (!remote->remote)
|
|
+ remote->core = pw_context_connect (remote->context, pipewire_properties, 0);
|
|
+ if (!remote->core)
|
|
{
|
|
pipewire_remote_destroy (remote);
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Couldn't create PipeWire remote");
|
|
+ "Couldn't connect to PipeWire");
|
|
return NULL;
|
|
}
|
|
|
|
remote->globals = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
|
|
|
- pw_remote_add_listener (remote->remote,
|
|
- &remote->remote_listener,
|
|
- &remote_events,
|
|
- remote);
|
|
-
|
|
- if (pw_remote_connect (remote->remote) != 0)
|
|
- {
|
|
- pipewire_remote_destroy (remote);
|
|
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Couldn't connect PipeWire remote");
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- pw_main_loop_run (remote->loop);
|
|
-
|
|
- switch (pw_remote_get_state (remote->remote, NULL))
|
|
- {
|
|
- case PW_REMOTE_STATE_ERROR:
|
|
- case PW_REMOTE_STATE_UNCONNECTED:
|
|
- *error = g_steal_pointer (&remote->error);
|
|
- pipewire_remote_destroy (remote);
|
|
- return NULL;
|
|
- case PW_REMOTE_STATE_CONNECTING:
|
|
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "PipeWire loop stopped unexpectedly");
|
|
- pipewire_remote_destroy (remote);
|
|
- return NULL;
|
|
- case PW_REMOTE_STATE_CONNECTED:
|
|
- break;
|
|
- default:
|
|
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Unexpected PipeWire state");
|
|
- pipewire_remote_destroy (remote);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- remote->core_proxy = pw_remote_get_core_proxy (remote->remote);
|
|
- pw_core_proxy_add_listener (remote->core_proxy,
|
|
- &remote->core_listener,
|
|
- &core_events,
|
|
- remote);
|
|
+ pw_core_add_listener (remote->core,
|
|
+ &remote->core_listener,
|
|
+ &core_events,
|
|
+ remote);
|
|
|
|
if (!discover_node_factory_sync (remote, error))
|
|
{
|
|
diff --git src/pipewire.h src/pipewire.h
|
|
index 0f1bf54..bf48d5e 100644
|
|
--- src/pipewire.h
|
|
+++ src/pipewire.h
|
|
@@ -32,7 +32,7 @@ typedef struct _PipeWireGlobal
|
|
|
|
typedef void (* PipeWireGlobalAddedCallback) (PipeWireRemote *remote,
|
|
uint32_t id,
|
|
- uint32_t type,
|
|
+ const char *type,
|
|
const struct spa_dict *props,
|
|
gpointer user_data);
|
|
|
|
@@ -43,13 +43,11 @@ typedef void (* PipeWireGlobalRemovedCallback) (PipeWireRemote *remote,
|
|
struct _PipeWireRemote
|
|
{
|
|
struct pw_main_loop *loop;
|
|
+ struct pw_context *context;
|
|
struct pw_core *core;
|
|
- struct pw_remote *remote;
|
|
- struct spa_hook remote_listener;
|
|
-
|
|
- struct pw_core_proxy *core_proxy;
|
|
struct spa_hook core_listener;
|
|
- uint32_t sync_seq;
|
|
+
|
|
+ int sync_seq;
|
|
|
|
struct spa_hook registry_listener;
|
|
|
|
diff --git src/screen-cast.c src/screen-cast.c
|
|
index 7881ddc..1677050 100644
|
|
--- src/screen-cast.c
|
|
+++ src/screen-cast.c
|
|
@@ -31,10 +31,10 @@
|
|
#include "xdp-impl-dbus.h"
|
|
#include "xdp-utils.h"
|
|
|
|
-#define PERMISSION_ITEM(item_key, item_value) \
|
|
- ((struct spa_dict_item) { \
|
|
- .key = item_key, \
|
|
- .value = item_value \
|
|
+#define PERMISSION_ITEM(item_id, item_permissions) \
|
|
+ ((struct pw_permission) { \
|
|
+ .id = item_id, \
|
|
+ .permissions = item_permissions \
|
|
})
|
|
|
|
typedef struct _ScreenCast ScreenCast;
|
|
@@ -517,42 +517,9 @@ screen_cast_stream_get_pipewire_node_id (ScreenCastStream *stream)
|
|
return stream->id;
|
|
}
|
|
|
|
-static void
|
|
-append_parent_permissions (PipeWireRemote *remote,
|
|
- GArray *permission_items,
|
|
- GList **string_stash,
|
|
- PipeWireGlobal *global,
|
|
- const char *permission)
|
|
-{
|
|
- PipeWireGlobal *parent;
|
|
- char *parent_permission_value;
|
|
-
|
|
- if (global->parent_id == 0)
|
|
- return;
|
|
-
|
|
- parent = g_hash_table_lookup (remote->globals, GINT_TO_POINTER (global->parent_id));
|
|
-
|
|
- if (parent->permission_set)
|
|
- return;
|
|
- parent->permission_set = TRUE;
|
|
-
|
|
- append_parent_permissions (remote, permission_items, string_stash,
|
|
- parent, permission);
|
|
-
|
|
- parent_permission_value = g_strdup_printf ("%u:%s",
|
|
- global->parent_id,
|
|
- permission);
|
|
- *string_stash = g_list_prepend (*string_stash, parent_permission_value);
|
|
-
|
|
- g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_GLOBAL,
|
|
- parent_permission_value));
|
|
-}
|
|
-
|
|
static void
|
|
append_stream_permissions (PipeWireRemote *remote,
|
|
GArray *permission_items,
|
|
- GList **string_stash,
|
|
GList *streams)
|
|
{
|
|
GList *l;
|
|
@@ -561,21 +528,10 @@ append_stream_permissions (PipeWireRemote *remote,
|
|
{
|
|
ScreenCastStream *stream = l->data;
|
|
uint32_t stream_id;
|
|
- PipeWireGlobal *stream_global;
|
|
- char *stream_permission_value;
|
|
|
|
stream_id = screen_cast_stream_get_pipewire_node_id (stream);
|
|
- stream_global = g_hash_table_lookup (remote->globals,
|
|
- GINT_TO_POINTER (stream_id));
|
|
-
|
|
- append_parent_permissions (remote, permission_items, string_stash,
|
|
- stream_global, "r--");
|
|
-
|
|
- stream_permission_value = g_strdup_printf ("%u:rwx", stream_id);
|
|
- *string_stash = g_list_prepend (*string_stash, stream_permission_value);
|
|
g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_GLOBAL,
|
|
- stream_permission_value));
|
|
+ PERMISSION_ITEM (stream_id, PW_PERM_RWX));
|
|
}
|
|
}
|
|
|
|
@@ -587,9 +543,6 @@ open_pipewire_screen_cast_remote (const char *app_id,
|
|
struct pw_properties *pipewire_properties;
|
|
PipeWireRemote *remote;
|
|
g_autoptr(GArray) permission_items = NULL;
|
|
- char *node_factory_permission_string;
|
|
- GList *string_stash = NULL;
|
|
- struct spa_dict *permission_dict;
|
|
PipeWireGlobal *node_global;
|
|
|
|
pipewire_properties = pw_properties_new ("pipewire.access.portal.app_id", app_id,
|
|
@@ -603,48 +556,31 @@ open_pipewire_screen_cast_remote (const char *app_id,
|
|
|
|
permission_items = g_array_new (FALSE, TRUE, sizeof (struct spa_dict_item));
|
|
|
|
- /*
|
|
- * Hide all existing and future nodes (except the ones we explicitly list below.
|
|
- */
|
|
- g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_EXISTING,
|
|
- "---"));
|
|
- g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_DEFAULT,
|
|
- "---"));
|
|
-
|
|
/*
|
|
* PipeWire:Interface:Core
|
|
* Needs rwx to be able create the sink node using the create-object method
|
|
*/
|
|
g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_GLOBAL,
|
|
- "0:rwx"));
|
|
+ PERMISSION_ITEM (PW_ID_CORE, PW_PERM_RWX));
|
|
|
|
/*
|
|
* PipeWire:Interface:NodeFactory
|
|
* Needs r-- so it can be passed to create-object when creating the sink node.
|
|
*/
|
|
- node_factory_permission_string = g_strdup_printf ("%d:r--",
|
|
- remote->node_factory_id);
|
|
- string_stash = g_list_prepend (string_stash, node_factory_permission_string);
|
|
g_array_append_val (permission_items,
|
|
- PERMISSION_ITEM (PW_CORE_PROXY_PERMISSIONS_GLOBAL,
|
|
- node_factory_permission_string));
|
|
- node_global = g_hash_table_lookup (remote->globals,
|
|
- GINT_TO_POINTER (remote->node_factory_id));
|
|
- append_parent_permissions (remote, permission_items, &string_stash,
|
|
- node_global, "r--");
|
|
+ PERMISSION_ITEM (remote->node_factory_id, PW_PERM_R));
|
|
|
|
- append_stream_permissions (remote, permission_items, &string_stash, streams);
|
|
+ append_stream_permissions (remote, permission_items, streams);
|
|
|
|
- permission_dict =
|
|
- &SPA_DICT_INIT ((struct spa_dict_item *) permission_items->data,
|
|
- permission_items->len);
|
|
- pw_core_proxy_permissions (pw_remote_get_core_proxy (remote->remote),
|
|
- permission_dict);
|
|
+ /*
|
|
+ * Hide all existing and future nodes (except the ones we explicitly list above).
|
|
+ */
|
|
+ g_array_append_val (permission_items,
|
|
+ PERMISSION_ITEM (PW_ID_ANY, 0));
|
|
|
|
- g_list_free_full (string_stash, g_free);
|
|
+ pw_client_update_permissions (pw_core_get_client(remote->core),
|
|
+ permission_items->len,
|
|
+ (const struct pw_permission *)permission_items->data);
|
|
|
|
pipewire_remote_roundtrip (remote);
|
|
|
|
@@ -943,7 +879,7 @@ handle_open_pipewire_remote (XdpScreenCast *object,
|
|
}
|
|
|
|
out_fd_list = g_unix_fd_list_new ();
|
|
- fd = pw_remote_steal_fd (remote->remote);
|
|
+ fd = pw_core_steal_fd (remote->core);
|
|
fd_id = g_unix_fd_list_append (out_fd_list, fd, &error);
|
|
close (fd);
|
|
pipewire_remote_destroy (remote);
|