xdg-desktop-portal/SOURCES/0001-PipeWire-update-to-0.3...

556 lines
20 KiB
Diff

From 18dc92eac270a50fb40607602352efb4d3db8207 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
(cherry picked from commit a38901e5e7f835efe7b7a06c55790c8c20bc91a2)
---
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 a/configure.ac b/configure.ac
index 89902fa..62d7960 100644
--- a/configure.ac
+++ b/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 a/src/camera.c b/src/camera.c
index c2b392c..20fe3aa 100644
--- a/src/camera.c
+++ b/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 a/src/pipewire.c b/src/pipewire.c
index 793a378..162cd55 100644
--- a/src/pipewire.c
+++ b/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,
- &registry_events,
- remote);
+ registry = pw_core_get_registry (remote->core, PW_VERSION_REGISTRY, 0);
+ pw_registry_add_listener (registry,
+ &remote->registry_listener,
+ &registry_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 a/src/pipewire.h b/src/pipewire.h
index 0f1bf54..bf48d5e 100644
--- a/src/pipewire.h
+++ b/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 a/src/screen-cast.c b/src/screen-cast.c
index 7881ddc..1677050 100644
--- a/src/screen-cast.c
+++ b/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);
--
2.26.2