update to the latest pipewire API

This commit is contained in:
Julian Bouzas
2020-01-09 12:39:45 -05:00
parent cf768e9b20
commit a9ac1fdc06
32 changed files with 397 additions and 540 deletions

View File

@@ -10,7 +10,6 @@ build:
script: script:
# Build pipewire # Build pipewire
- cd pipewire - cd pipewire
- git reset --hard b0932e687fc47e0872ca291531f2291d99042d70
- meson . _build --prefix=/usr - meson . _build --prefix=/usr
-Dpipewire-alsa=false -Dpipewire-pulseaudio=false -Dpipewire-jack=false -Dpipewire-alsa=false -Dpipewire-pulseaudio=false -Dpipewire-jack=false
-Djack=false -Dvulkan=false -Dgstreamer=false -Dbluez5=false -Dman=false -Djack=false -Dvulkan=false -Dgstreamer=false -Dbluez5=false -Dman=false

View File

@@ -14,6 +14,8 @@
#include "private.h" #include "private.h"
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/impl.h>
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <spa/debug/types.h> #include <spa/debug/types.h>
@@ -86,16 +88,13 @@ struct _WpCore
WpProperties *properties; WpProperties *properties;
/* pipewire main objects */ /* pipewire main objects */
struct pw_context *pw_context;
struct pw_core *pw_core; struct pw_core *pw_core;
struct pw_remote *pw_remote; struct pw_registry *pw_registry;
struct spa_hook remote_listener;
/* remote core */ /* pipewire main listeners */
struct pw_core_proxy *core_proxy;
struct spa_hook core_listener; struct spa_hook core_listener;
struct spa_hook proxy_core_listener;
/* remote registry */
struct pw_registry_proxy *registry_proxy;
struct spa_hook registry_listener; struct spa_hook registry_listener;
GPtrArray *globals; // elementy-type: WpGlobal* GPtrArray *globals; // elementy-type: WpGlobal*
@@ -108,23 +107,24 @@ enum {
PROP_0, PROP_0,
PROP_CONTEXT, PROP_CONTEXT,
PROP_PROPERTIES, PROP_PROPERTIES,
PROP_PW_CONTEXT,
PROP_PW_CORE, PROP_PW_CORE,
PROP_PW_REMOTE,
PROP_REMOTE_STATE,
}; };
enum { enum {
SIGNAL_REMOTE_STATE_CHANGED, SIGNAL_CONNECTED,
SIGNAL_DISCONNECTED,
NUM_SIGNALS NUM_SIGNALS
}; };
static guint32 signals[NUM_SIGNALS]; static guint32 signals[NUM_SIGNALS];
G_DEFINE_TYPE (WpCore, wp_core, G_TYPE_OBJECT) G_DEFINE_TYPE (WpCore, wp_core, G_TYPE_OBJECT)
static void static void
registry_global (void *data, uint32_t id, uint32_t permissions, registry_global (void *data, uint32_t id, uint32_t permissions,
uint32_t type, uint32_t version, const struct spa_dict *props) const char *type, uint32_t version, const struct spa_dict *props)
{ {
WpCore *self = WP_CORE (data); WpCore *self = WP_CORE (data);
WpGlobal *global = NULL; WpGlobal *global = NULL;
@@ -133,14 +133,13 @@ registry_global (void *data, uint32_t id, uint32_t permissions,
g_return_if_fail (self->globals->len <= id || g_return_if_fail (self->globals->len <= id ||
g_ptr_array_index (self->globals, id) == NULL); g_ptr_array_index (self->globals, id) == NULL);
g_debug ("registry global:%u perm:0x%x type:%u/%u (%s)", g_debug ("registry global:%u perm:0x%x type:%s version:%u",
id, permissions, type, version, id, permissions, type, version);
spa_debug_type_find_name (pw_type_info (), type));
/* construct & store the global */ /* construct & store the global */
global = wp_global_new (); global = wp_global_new ();
global->id = id; global->id = id;
global->type = type; global->type = g_strdup (type);
global->version = version; global->version = version;
global->permissions = permissions; global->permissions = permissions;
global->properties = wp_properties_new_copy_dict (props); global->properties = wp_properties_new_copy_dict (props);
@@ -166,9 +165,8 @@ registry_global_remove (void *data, uint32_t id)
global = g_steal_pointer (&g_ptr_array_index (self->globals, id)); global = g_steal_pointer (&g_ptr_array_index (self->globals, id));
g_debug ("registry global removed:%u type:%u/%u (%s)", id, g_debug ("registry global removed:%u type:%s/%u", id,
global->type, global->version, global->type, global->version);
spa_debug_type_find_name (pw_type_info (), global->type));
/* notify object managers */ /* notify object managers */
for (i = 0; i < self->object_managers->len; i++) { for (i = 0; i < self->object_managers->len; i++) {
@@ -177,8 +175,8 @@ registry_global_remove (void *data, uint32_t id)
} }
} }
static const struct pw_registry_proxy_events registry_proxy_events = { static const struct pw_registry_events registry_events = {
PW_VERSION_REGISTRY_PROXY_EVENTS, PW_VERSION_REGISTRY_EVENTS,
.global = registry_global, .global = registry_global,
.global_remove = registry_global_remove, .global_remove = registry_global_remove,
}; };
@@ -195,49 +193,24 @@ core_done (void *data, uint32_t id, int seq)
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
} }
static const struct pw_core_proxy_events core_events = { static const struct pw_core_events core_events = {
PW_VERSION_CORE_EVENTS, PW_VERSION_CORE_EVENTS,
.done = core_done, .done = core_done,
}; };
static void static void
registry_init (WpCore *self) proxy_core_destroy (void *data)
{ {
/* Get the core proxy */ WpCore *self = WP_CORE (data);
self->core_proxy = pw_remote_get_core_proxy (self->pw_remote); self->pw_core = NULL;
pw_core_proxy_add_listener(self->core_proxy, &self->core_listener,
&core_events, self);
/* Registry */ /* Emit the disconnected signal */
self->registry_proxy = pw_core_proxy_get_registry (self->core_proxy, g_signal_emit (self, signals[SIGNAL_DISCONNECTED], 0);
PW_VERSION_REGISTRY_PROXY, 0);
pw_registry_proxy_add_listener(self->registry_proxy, &self->registry_listener,
&registry_proxy_events, self);
} }
static void static const struct pw_proxy_events proxy_core_events = {
on_remote_state_changed (void *d, enum pw_remote_state old_state, PW_VERSION_PROXY_EVENTS,
enum pw_remote_state new_state, const char *error) .destroy = proxy_core_destroy,
{
WpCore *self = d;
GQuark detail;
g_debug ("pipewire remote state changed, old:%s new:%s",
pw_remote_state_as_string (old_state),
pw_remote_state_as_string (new_state));
/* Init the registry when connected */
if (!self->registry_proxy && new_state == PW_REMOTE_STATE_CONNECTED)
registry_init (self);
/* enum pw_remote_state matches values with WpRemoteState */
detail = g_quark_from_static_string (pw_remote_state_as_string (new_state));
g_signal_emit (self, signals[SIGNAL_REMOTE_STATE_CHANGED], detail, new_state);
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_remote_state_changed,
}; };
/* wrapper around wp_global_unref because /* wrapper around wp_global_unref because
@@ -264,18 +237,15 @@ wp_core_constructed (GObject *object)
{ {
WpCore *self = WP_CORE (object); WpCore *self = WP_CORE (object);
g_autoptr (GSource) source = NULL; g_autoptr (GSource) source = NULL;
struct pw_properties *p; struct pw_properties *p = NULL;
/* loop */
source = wp_loop_source_new (); source = wp_loop_source_new ();
g_source_attach (source, self->context); g_source_attach (source, self->context);
/* context */
p = self->properties ? wp_properties_to_pw_properties (self->properties) : NULL; p = self->properties ? wp_properties_to_pw_properties (self->properties) : NULL;
self->pw_core = pw_core_new (WP_LOOP_SOURCE (source)->loop, p, 0); self->pw_context = pw_context_new (WP_LOOP_SOURCE(source)->loop, p, 0);
p = self->properties ? wp_properties_to_pw_properties (self->properties) : NULL;
self->pw_remote = pw_remote_new (self->pw_core, p, 0);
pw_remote_add_listener (self->pw_remote, &self->remote_listener,
&remote_events, self);
G_OBJECT_CLASS (wp_core_parent_class)->constructed (object); G_OBJECT_CLASS (wp_core_parent_class)->constructed (object);
} }
@@ -346,10 +316,10 @@ wp_core_finalize (GObject * obj)
{ {
WpCore *self = WP_CORE (obj); WpCore *self = WP_CORE (obj);
g_clear_pointer (&self->pw_remote, pw_remote_destroy); wp_core_disconnect (self);
self->core_proxy= NULL;
self->registry_proxy = NULL; g_clear_pointer (&self->pw_context, pw_context_destroy);
g_clear_pointer (&self->pw_core, pw_core_destroy);
g_clear_pointer (&self->properties, wp_properties_unref); g_clear_pointer (&self->properties, wp_properties_unref);
g_clear_pointer (&self->context, g_main_context_unref); g_clear_pointer (&self->context, g_main_context_unref);
g_clear_pointer (&self->async_tasks, g_hash_table_unref); g_clear_pointer (&self->async_tasks, g_hash_table_unref);
@@ -372,15 +342,12 @@ wp_core_get_property (GObject * object, guint property_id,
case PROP_PROPERTIES: case PROP_PROPERTIES:
g_value_set_boxed (value, self->properties); g_value_set_boxed (value, self->properties);
break; break;
case PROP_PW_CONTEXT:
g_value_set_pointer (value, self->pw_context);
break;
case PROP_PW_CORE: case PROP_PW_CORE:
g_value_set_pointer (value, self->pw_core); g_value_set_pointer (value, self->pw_core);
break; break;
case PROP_PW_REMOTE:
g_value_set_pointer (value, self->pw_remote);
break;
case PROP_REMOTE_STATE:
g_value_set_enum (value, wp_core_get_remote_state (self, NULL));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@@ -429,24 +396,21 @@ wp_core_class_init (WpCoreClass * klass)
WP_TYPE_PROPERTIES, WP_TYPE_PROPERTIES,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PW_CONTEXT,
g_param_spec_pointer ("pw-context", "pw-context", "The pipewire context",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PW_CORE, g_object_class_install_property (object_class, PROP_PW_CORE,
g_param_spec_pointer ("pw-core", "pw-core", "The pipewire core", g_param_spec_pointer ("pw-core", "pw-core", "The pipewire core",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PW_REMOTE,
g_param_spec_pointer ("pw-remote", "pw-remote", "The pipewire remote",
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_REMOTE_STATE,
g_param_spec_enum ("remote-state", "remote-state",
"The state of the remote",
WP_TYPE_REMOTE_STATE, WP_REMOTE_STATE_UNCONNECTED,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/* Signals */ /* Signals */
signals[SIGNAL_REMOTE_STATE_CHANGED] = g_signal_new ("remote-state-changed", signals[SIGNAL_CONNECTED] = g_signal_new ("connected",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_REMOTE_STATE); G_TYPE_NONE, 0);
signals[SIGNAL_DISCONNECTED] = g_signal_new ("disconnected",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
} }
WpCore * WpCore *
@@ -465,6 +429,77 @@ wp_core_get_context (WpCore * self)
return self->context; return self->context;
} }
struct pw_context *
wp_core_get_pw_context (WpCore * self)
{
g_return_val_if_fail (WP_IS_CORE (self), NULL);
return self->pw_context;
}
struct pw_registry *
wp_core_get_pw_registry (WpCore * self)
{
g_return_val_if_fail (WP_IS_CORE (self), NULL);
return self->pw_registry;
}
gboolean
wp_core_connect (WpCore *self)
{
struct pw_properties *p = NULL;
g_return_val_if_fail (WP_IS_CORE (self), FALSE);
/* Don't do anything if core is already connected */
if (self->pw_core)
return TRUE;
g_return_val_if_fail (!self->pw_registry, FALSE);
/* Connect */
p = self->properties ? wp_properties_to_pw_properties (self->properties) : NULL;
self->pw_core = pw_context_connect (self->pw_context, p, 0);
if (!self->pw_core)
return FALSE;
/* Add the core listeners */
pw_core_add_listener (self->pw_core, &self->core_listener, &core_events, self);
pw_proxy_add_listener((struct pw_proxy*)self->pw_core,
&self->proxy_core_listener, &proxy_core_events, self);
/* Add the registry listener */
self->pw_registry = pw_core_get_registry (self->pw_core,
PW_VERSION_REGISTRY, 0);
pw_registry_add_listener(self->pw_registry, &self->registry_listener,
&registry_events, self);
/* Emit the connected signal */
g_signal_emit (self, signals[SIGNAL_CONNECTED], 0);
return TRUE;
}
void
wp_core_disconnect (WpCore *self)
{
if (self->pw_registry) {
pw_proxy_destroy ((struct pw_proxy *)self->pw_registry);
self->pw_registry = NULL;
}
g_clear_pointer (&self->pw_core, pw_core_disconnect);
/* Emit the disconnected signal */
g_signal_emit (self, signals[SIGNAL_DISCONNECTED], 0);
}
gboolean
wp_core_is_connected (WpCore * self)
{
g_return_val_if_fail (WP_IS_CORE (self), FALSE);
return self->pw_core != NULL;
}
guint guint
wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data, wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data,
GDestroyNotify destroy) GDestroyNotify destroy)
@@ -490,17 +525,17 @@ wp_core_sync (WpCore * self, GCancellable * cancellable,
task = g_task_new (self, cancellable, callback, user_data); task = g_task_new (self, cancellable, callback, user_data);
if (G_UNLIKELY (!self->core_proxy)) { if (G_UNLIKELY (!self->pw_core)) {
g_warn_if_reached (); g_warn_if_reached ();
g_task_return_new_error (task, WP_DOMAIN_LIBRARY, g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_INVARIANT, "No core proxy"); WP_LIBRARY_ERROR_INVARIANT, "No pipewire core");
return FALSE; return FALSE;
} }
seq = pw_core_proxy_sync (self->core_proxy, 0, 0); seq = pw_core_sync (self->pw_core, 0, 0);
if (G_UNLIKELY (seq < 0)) { if (G_UNLIKELY (seq < 0)) {
g_task_return_new_error (task, WP_DOMAIN_LIBRARY, g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED, "pw_core_proxy_sync failed: %s", WP_LIBRARY_ERROR_OPERATION_FAILED, "pw_core_sync failed: %s",
g_strerror (-seq)); g_strerror (-seq));
return FALSE; return FALSE;
} }
@@ -510,47 +545,19 @@ wp_core_sync (WpCore * self, GCancellable * cancellable,
return TRUE; return TRUE;
} }
struct pw_core *
wp_core_get_pw_core (WpCore * self)
{
g_return_val_if_fail (WP_IS_CORE (self), NULL);
return self->pw_core;
}
gboolean
wp_core_connect (WpCore *self)
{
g_return_val_if_fail (WP_IS_CORE (self), FALSE);
return pw_remote_connect (self->pw_remote) >= 0;
}
WpRemoteState
wp_core_get_remote_state (WpCore * self, const gchar ** error)
{
g_return_val_if_fail (WP_IS_CORE (self), WP_REMOTE_STATE_UNCONNECTED);
/* enum pw_remote_state matches values with WpRemoteState */
G_STATIC_ASSERT ((gint) WP_REMOTE_STATE_ERROR == (gint) PW_REMOTE_STATE_ERROR);
G_STATIC_ASSERT ((gint) WP_REMOTE_STATE_UNCONNECTED == (gint) PW_REMOTE_STATE_UNCONNECTED);
G_STATIC_ASSERT ((gint) WP_REMOTE_STATE_CONNECTING == (gint) PW_REMOTE_STATE_CONNECTING);
G_STATIC_ASSERT ((gint) WP_REMOTE_STATE_CONNECTED == (gint) PW_REMOTE_STATE_CONNECTED);
return (WpRemoteState) pw_remote_get_state (self->pw_remote, error);
}
WpProxy * WpProxy *
wp_core_export_object (WpCore * self, guint32 interface_type, wp_core_export_object (WpCore * self, const gchar * interface_type,
gpointer local_object, WpProperties * properties) gpointer local_object, WpProperties * properties)
{ {
struct pw_proxy *proxy = NULL; struct pw_proxy *proxy = NULL;
guint32 type; const char *type;
guint32 version; guint32 version;
g_return_val_if_fail (WP_IS_CORE (self), NULL); g_return_val_if_fail (WP_IS_CORE (self), NULL);
g_return_val_if_fail (self->pw_remote, NULL); g_return_val_if_fail (self->pw_core, NULL);
proxy = pw_remote_export (self->pw_remote, interface_type, proxy = pw_core_export (self->pw_core, interface_type,
properties ? wp_properties_to_pw_properties (properties) : NULL, properties ? wp_properties_peek_dict (properties) : NULL,
local_object, 0); local_object, 0);
if (!proxy) if (!proxy)
return NULL; return NULL;
@@ -560,23 +567,22 @@ wp_core_export_object (WpCore * self, guint32 interface_type,
} }
WpProxy * WpProxy *
wp_core_create_local_object (WpCore * self, const gchar *factory_name, wp_core_create_local_object (WpCore * self, const gchar * factory_name,
guint32 interface_type, guint32 interface_version, const gchar *interface_type, guint32 interface_version,
WpProperties * properties) WpProperties * properties)
{ {
struct pw_proxy *pw_proxy = NULL; struct pw_proxy *pw_proxy = NULL;
struct pw_factory *factory = NULL; struct pw_impl_factory *factory = NULL;
gpointer local_object = NULL; gpointer local_object = NULL;
g_return_val_if_fail (WP_IS_CORE (self), NULL); g_return_val_if_fail (WP_IS_CORE (self), NULL);
g_return_val_if_fail (self->pw_core, NULL); g_return_val_if_fail (self->pw_core, NULL);
g_return_val_if_fail (self->pw_remote, NULL);
factory = pw_core_find_factory (self->pw_core, factory_name); factory = pw_context_find_factory (self->pw_context, factory_name);
if (!factory) if (!factory)
return NULL; return NULL;
local_object = pw_factory_create_object (factory, local_object = pw_impl_factory_create_object (factory,
NULL, NULL,
interface_type, interface_type,
interface_version, interface_version,
@@ -585,9 +591,9 @@ wp_core_create_local_object (WpCore * self, const gchar *factory_name,
if (!local_object) if (!local_object)
return NULL; return NULL;
pw_proxy = pw_remote_export (self->pw_remote, pw_proxy = pw_core_export (self->pw_core,
interface_type, interface_type,
properties ? wp_properties_to_pw_properties (properties) : NULL, properties ? wp_properties_peek_dict (properties) : NULL,
local_object, local_object,
0); 0);
if (!pw_proxy) { if (!pw_proxy) {
@@ -601,28 +607,21 @@ wp_core_create_local_object (WpCore * self, const gchar *factory_name,
WpProxy * WpProxy *
wp_core_create_remote_object (WpCore *self, wp_core_create_remote_object (WpCore *self,
const gchar *factory_name, guint32 interface_type, const gchar *factory_name, const gchar * interface_type,
guint32 interface_version, WpProperties * properties) guint32 interface_version, WpProperties * properties)
{ {
struct pw_proxy *pw_proxy; struct pw_proxy *pw_proxy;
g_return_val_if_fail (WP_IS_CORE (self), NULL); g_return_val_if_fail (WP_IS_CORE (self), NULL);
g_return_val_if_fail (self->core_proxy, NULL); g_return_val_if_fail (self->pw_core, NULL);
pw_proxy = pw_core_proxy_create_object (self->core_proxy, factory_name, pw_proxy = pw_core_create_object (self->pw_core, factory_name,
interface_type, interface_version, interface_type, interface_version,
properties ? wp_properties_peek_dict (properties) : NULL, 0); properties ? wp_properties_peek_dict (properties) : NULL, 0);
return wp_proxy_new_wrap (self, pw_proxy, interface_type, interface_version, return wp_proxy_new_wrap (self, pw_proxy, interface_type, interface_version,
NULL); NULL);
} }
struct pw_registry_proxy *
wp_core_get_pw_registry_proxy (WpCore * self)
{
g_return_val_if_fail (WP_IS_CORE (self), NULL);
return self->registry_proxy;
}
/** /**
* wp_core_find_object: (skip) * wp_core_find_object: (skip)
* @self: the core * @self: the core

View File

@@ -15,48 +15,38 @@
G_BEGIN_DECLS G_BEGIN_DECLS
struct pw_core; struct pw_context;
/**
* WpRemoteState:
* @WP_REMOTE_STATE_ERROR: remote is in error
* @WP_REMOTE_STATE_UNCONNECTED: not connected
* @WP_REMOTE_STATE_CONNECTING: connecting to remote service
* @WP_REMOTE_STATE_CONNECTED: remote is connected and ready
*
* The different states the remote can be
*/
typedef enum {
WP_REMOTE_STATE_ERROR = -1,
WP_REMOTE_STATE_UNCONNECTED = 0,
WP_REMOTE_STATE_CONNECTING = 1,
WP_REMOTE_STATE_CONNECTED = 2,
} WpRemoteState;
#define WP_TYPE_CORE (wp_core_get_type ()) #define WP_TYPE_CORE (wp_core_get_type ())
G_DECLARE_FINAL_TYPE (WpCore, wp_core, WP, CORE, GObject) G_DECLARE_FINAL_TYPE (WpCore, wp_core, WP, CORE, GObject)
/* Basic */
WpCore * wp_core_new (GMainContext *context, WpProperties * properties); WpCore * wp_core_new (GMainContext *context, WpProperties * properties);
GMainContext * wp_core_get_context (WpCore * self); GMainContext * wp_core_get_context (WpCore * self);
struct pw_context * wp_core_get_pw_context (WpCore * self);
/* Connection */
gboolean wp_core_connect (WpCore *self);
void wp_core_disconnect (WpCore *self);
gboolean wp_core_is_connected (WpCore * self);
/* Callback */
guint wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data, guint wp_core_idle_add (WpCore * self, GSourceFunc function, gpointer data,
GDestroyNotify destroy); GDestroyNotify destroy);
gboolean wp_core_sync (WpCore * self, GCancellable * cancellable, gboolean wp_core_sync (WpCore * self, GCancellable * cancellable,
GAsyncReadyCallback callback, gpointer user_data); GAsyncReadyCallback callback, gpointer user_data);
struct pw_core * wp_core_get_pw_core (WpCore * self);
gboolean wp_core_connect (WpCore * self); /* Object */
WpRemoteState wp_core_get_remote_state (WpCore * self, const gchar ** error); WpProxy * wp_core_export_object (WpCore * self, const gchar * interface_type,
WpProxy * wp_core_export_object (WpCore * self, guint32 interface_type,
gpointer local_object, WpProperties * properties); gpointer local_object, WpProperties * properties);
WpProxy * wp_core_create_local_object (WpCore * self, WpProxy * wp_core_create_local_object (WpCore * self,
const gchar *factory_name, guint32 interface_type, const gchar *factory_name, const gchar * interface_type,
guint32 interface_version, WpProperties * properties); guint32 interface_version, WpProperties * properties);
WpProxy * wp_core_create_remote_object (WpCore * self, WpProxy * wp_core_create_remote_object (WpCore * self,
const gchar * factory_name, guint32 interface_type, const gchar * factory_name, const gchar * interface_type,
guint32 interface_version, WpProperties * properties); guint32 interface_version, WpProperties * properties);
/* Object Manager */
void wp_core_install_object_manager (WpCore * self, WpObjectManager * om); void wp_core_install_object_manager (WpCore * self, WpObjectManager * om);
G_END_DECLS G_END_DECLS

View File

@@ -314,8 +314,8 @@ endpoint_event_param (void *data, int seq, uint32_t id, uint32_t index,
} }
} }
static const struct pw_endpoint_proxy_events endpoint_events = { static const struct pw_endpoint_events endpoint_events = {
PW_VERSION_ENDPOINT_PROXY_EVENTS, PW_VERSION_ENDPOINT_EVENTS,
.info = endpoint_event_info, .info = endpoint_event_info,
.param = endpoint_event_param, .param = endpoint_event_param,
}; };
@@ -324,7 +324,7 @@ static void
wp_proxy_endpoint_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_endpoint_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyEndpoint *self = WP_PROXY_ENDPOINT (proxy); WpProxyEndpoint *self = WP_PROXY_ENDPOINT (proxy);
pw_endpoint_proxy_add_listener ((struct pw_endpoint_proxy *) pw_proxy, pw_endpoint_add_listener ((struct pw_endpoint *) pw_proxy,
&self->listener, &endpoint_events, self); &self->listener, &endpoint_events, self);
} }
@@ -335,15 +335,15 @@ wp_proxy_endpoint_augment (WpProxy * proxy, WpProxyFeatures features)
WP_PROXY_CLASS (wp_proxy_endpoint_parent_class)->augment (proxy, features); WP_PROXY_CLASS (wp_proxy_endpoint_parent_class)->augment (proxy, features);
if (features & WP_PROXY_ENDPOINT_FEATURE_CONTROLS) { if (features & WP_PROXY_ENDPOINT_FEATURE_CONTROLS) {
struct pw_endpoint_proxy *pw_proxy = NULL; struct pw_endpoint *pw_proxy = NULL;
uint32_t ids[] = { SPA_PARAM_Props }; uint32_t ids[] = { SPA_PARAM_Props };
pw_proxy = (struct pw_endpoint_proxy *) wp_proxy_get_pw_proxy (proxy); pw_proxy = (struct pw_endpoint *) wp_proxy_get_pw_proxy (proxy);
if (!pw_proxy) if (!pw_proxy)
return; return;
pw_endpoint_proxy_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL); pw_endpoint_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL);
pw_endpoint_proxy_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids)); pw_endpoint_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids));
} }
} }
@@ -389,16 +389,16 @@ wp_proxy_endpoint_set_control (WpEndpoint * endpoint, guint32 control_id,
WpProxyEndpoint *self = WP_PROXY_ENDPOINT (endpoint); WpProxyEndpoint *self = WP_PROXY_ENDPOINT (endpoint);
char buf[1024]; char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf)); struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct pw_endpoint_proxy *pw_proxy = NULL; struct pw_endpoint *pw_proxy = NULL;
/* set the default endpoint id as a property param on the endpoint; /* set the default endpoint id as a property param on the endpoint;
our spa_props will be updated by the param event */ our spa_props will be updated by the param event */
pw_proxy = (struct pw_endpoint_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pw_proxy = (struct pw_endpoint *) wp_proxy_get_pw_proxy (WP_PROXY (self));
if (!pw_proxy) if (!pw_proxy)
return FALSE; return FALSE;
pw_endpoint_proxy_set_param (pw_proxy, pw_endpoint_set_param (pw_proxy,
SPA_PARAM_Props, 0, SPA_PARAM_Props, 0,
spa_pod_builder_add_object (&b, spa_pod_builder_add_object (&b,
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
@@ -523,11 +523,11 @@ client_endpoint_update (WpExportedEndpoint * self, guint32 change_mask,
wp_exported_endpoint_get_instance_private (self); wp_exported_endpoint_get_instance_private (self);
char buf[1024]; char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf)); struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct pw_client_endpoint_proxy *pw_proxy = NULL; struct pw_client_endpoint *pw_proxy = NULL;
struct pw_endpoint_info *info = NULL; struct pw_endpoint_info *info = NULL;
g_autoptr (GPtrArray) params = NULL; g_autoptr (GPtrArray) params = NULL;
pw_proxy = (struct pw_client_endpoint_proxy *) wp_proxy_get_pw_proxy ( pw_proxy = (struct pw_client_endpoint *) wp_proxy_get_pw_proxy (
priv->client_ep); priv->client_ep);
if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS) { if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS) {
@@ -538,7 +538,7 @@ client_endpoint_update (WpExportedEndpoint * self, guint32 change_mask,
info->change_mask = info_change_mask; info->change_mask = info_change_mask;
} }
pw_client_endpoint_proxy_update (pw_proxy, pw_client_endpoint_update (pw_proxy,
change_mask, change_mask,
params ? params->len : 0, params ? params->len : 0,
(const struct spa_pod **) (params ? params->pdata : NULL), (const struct spa_pod **) (params ? params->pdata : NULL),
@@ -585,8 +585,8 @@ client_endpoint_proxy_bound (void *object, uint32_t global_id)
wp_exported_notify_export_done (WP_EXPORTED (self), NULL); wp_exported_notify_export_done (WP_EXPORTED (self), NULL);
} }
static struct pw_client_endpoint_proxy_events client_endpoint_events = { static struct pw_client_endpoint_events client_endpoint_events = {
PW_VERSION_CLIENT_ENDPOINT_PROXY_EVENTS, PW_VERSION_CLIENT_ENDPOINT_EVENTS,
.set_param = client_endpoint_set_param, .set_param = client_endpoint_set_param,
}; };
@@ -601,7 +601,7 @@ wp_exported_endpoint_export (WpExported * self)
WpExportedEndpointPrivate *priv = WpExportedEndpointPrivate *priv =
wp_exported_endpoint_get_instance_private (WP_EXPORTED_ENDPOINT (self)); wp_exported_endpoint_get_instance_private (WP_EXPORTED_ENDPOINT (self));
g_autoptr (WpCore) core = wp_exported_get_core (self); g_autoptr (WpCore) core = wp_exported_get_core (self);
struct pw_client_endpoint_proxy *pw_proxy = NULL; struct pw_client_endpoint *pw_proxy = NULL;
/* make sure these props are not present; they are added by the server */ /* make sure these props are not present; they are added by the server */
wp_properties_set (priv->properties, PW_KEY_OBJECT_ID, NULL); wp_properties_set (priv->properties, PW_KEY_OBJECT_ID, NULL);
@@ -613,13 +613,13 @@ wp_exported_endpoint_export (WpExported * self)
wp_properties_set (priv->properties, PW_KEY_MEDIA_CLASS, priv->info.media_class); wp_properties_set (priv->properties, PW_KEY_MEDIA_CLASS, priv->info.media_class);
priv->client_ep = wp_core_create_remote_object (core, "client-endpoint", priv->client_ep = wp_core_create_remote_object (core, "client-endpoint",
PW_TYPE_INTERFACE_ClientEndpoint, PW_VERSION_CLIENT_ENDPOINT_PROXY, PW_TYPE_INTERFACE_ClientEndpoint, PW_VERSION_CLIENT_ENDPOINT,
priv->properties); priv->properties);
pw_proxy = (struct pw_client_endpoint_proxy *) wp_proxy_get_pw_proxy ( pw_proxy = (struct pw_client_endpoint *) wp_proxy_get_pw_proxy (
priv->client_ep); priv->client_ep);
pw_client_endpoint_proxy_add_listener (pw_proxy, &priv->listener, pw_client_endpoint_add_listener (pw_proxy, &priv->listener,
&client_endpoint_events, self); &client_endpoint_events, self);
pw_proxy_add_listener ((struct pw_proxy *) pw_proxy, &priv->proxy_listener, pw_proxy_add_listener ((struct pw_proxy *) pw_proxy, &priv->proxy_listener,
&client_ep_proxy_events, self); &client_ep_proxy_events, self);

View File

@@ -136,28 +136,6 @@ wp_exported_get_core (WpExported * self)
return g_weak_ref_get (&priv->core); return g_weak_ref_get (&priv->core);
} }
static void
on_remote_state_changed (WpCore * core, WpRemoteState state, WpExported * self)
{
WpExportedPrivate *priv = wp_exported_get_instance_private (self);
if (g_task_return_error_if_cancelled (priv->task)) {
g_clear_object (&priv->task);
g_signal_handlers_disconnect_by_func (core, on_remote_state_changed, self);
}
else if (state == WP_REMOTE_STATE_CONNECTED) {
WP_EXPORTED_GET_CLASS (self)->export (self);
g_signal_handlers_disconnect_by_func (core, on_remote_state_changed, self);
}
else if (state == WP_REMOTE_STATE_ERROR) {
g_task_return_new_error (priv->task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED,
"WirePlumber core connection error");
g_clear_object (&priv->task);
g_signal_handlers_disconnect_by_func (core, on_remote_state_changed, self);
}
}
void void
wp_exported_export (WpExported * self, GCancellable * cancellable, wp_exported_export (WpExported * self, GCancellable * cancellable,
GAsyncReadyCallback callback, gpointer user_data) GAsyncReadyCallback callback, gpointer user_data)
@@ -172,20 +150,15 @@ wp_exported_export (WpExported * self, GCancellable * cancellable,
priv->task = g_task_new (self, cancellable, callback, user_data); priv->task = g_task_new (self, cancellable, callback, user_data);
core = g_weak_ref_get (&priv->core); core = g_weak_ref_get (&priv->core);
if (!core || wp_core_get_remote_state (core, NULL) == WP_REMOTE_STATE_ERROR) { if (!core || !wp_core_is_connected (core)) {
g_task_return_new_error (priv->task, WP_DOMAIN_LIBRARY, g_task_return_new_error (priv->task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED, WP_LIBRARY_ERROR_OPERATION_FAILED,
"WirePlumber core not available or in error"); "WirePlumber core not available or disconnected");
g_clear_object (&priv->task); g_clear_object (&priv->task);
return; return;
} }
if (wp_core_get_remote_state (core, NULL) == WP_REMOTE_STATE_CONNECTED) { WP_EXPORTED_GET_CLASS (self)->export (self);
WP_EXPORTED_GET_CLASS (self)->export (self);
} else {
g_signal_connect_object (core, "remote-state-changed",
(GCallback) on_remote_state_changed, self, 0);
}
} }
gboolean gboolean

View File

@@ -12,6 +12,8 @@
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include "proxy-node.h"
#include "proxy-device.h"
#include "monitor.h" #include "monitor.h"
#include "error.h" #include "error.h"
#include "wpenums.h" #include "wpenums.h"
@@ -39,7 +41,7 @@ struct _WpMonitor
struct object struct object
{ {
guint32 id; guint32 id;
guint32 type; GType type;
WpProxy *proxy; WpProxy *proxy;
WpProperties *properties; WpProperties *properties;
@@ -107,23 +109,24 @@ device_object_info (void *data, uint32_t id,
/* new object, construct... */ /* new object, construct... */
if (info && !child) { if (info && !child) {
switch (info->type) { /* Device */
case SPA_TYPE_INTERFACE_Device: if (g_strcmp0 (info->type, SPA_TYPE_INTERFACE_Device) == 0) {
if (!(child = device_new (self, id, info->factory_name, if (!(child = device_new (self, id, info->factory_name,
wp_properties_new_wrap_dict (info->props), &err))) { wp_properties_new_wrap_dict (info->props), &err)))
g_debug ("WpMonitor:%p:%s %s", self, self->factory_name, err->message); g_debug ("WpMonitor:%p:%s %s", self, self->factory_name, err->message);
return; return;
} }
break; /* Node */
case SPA_TYPE_INTERFACE_Node: else if (g_strcmp0 (info->type, SPA_TYPE_INTERFACE_Node) == 0) {
if (!(child = node_new (obj, id, info))) if (!(child = node_new (obj, id, info)))
return;
break;
default:
g_debug ("WpMonitor:%p:%s got device_object_info for unknown object "
"type %u", self, self->factory_name, info->type);
return; return;
} }
/* Default */
else {
g_debug ("WpMonitor:%p:%s got device_object_info for unknown object "
"type %s", self, self->factory_name, info->type);
return;
}
obj->children = g_list_append (obj->children, child); obj->children = g_list_append (obj->children, child);
} }
/* object removed, delete... */ /* object removed, delete... */
@@ -163,14 +166,14 @@ wp_spa_object_unref (WpSpaObject *self)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WpSpaObject, wp_spa_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (WpSpaObject, wp_spa_object_unref)
static WpSpaObject * static WpSpaObject *
load_spa_object (WpCore *core, const gchar *factory, guint32 iface_type, load_spa_object (WpCore *core, const gchar *factory, const char * iface_type,
WpProperties *props, GError **error) WpProperties *props, GError **error)
{ {
g_autoptr (WpSpaObject) self = g_rc_box_new0 (WpSpaObject); g_autoptr (WpSpaObject) self = g_rc_box_new0 (WpSpaObject);
gint res; gint res;
/* Load the monitor handle */ /* Load the monitor handle */
self->handle = pw_core_load_spa_handle (wp_core_get_pw_core (core), self->handle = pw_context_load_spa_handle (wp_core_get_pw_context (core),
factory, props ? wp_properties_peek_dict (props) : NULL); factory, props ? wp_properties_peek_dict (props) : NULL);
if (!self->handle) { if (!self->handle) {
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
@@ -184,7 +187,7 @@ load_spa_object (WpCore *core, const gchar *factory, guint32 iface_type,
(gpointer *)&self->interface); (gpointer *)&self->interface);
if (res < 0) { if (res < 0) {
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
"Could not get interface 0x%x from SPA handle", iface_type); "Could not get interface %s from SPA handle", iface_type);
return NULL; return NULL;
} }
@@ -221,7 +224,7 @@ node_new (struct object *dev, uint32_t id,
struct object *node = NULL; struct object *node = NULL;
const gchar *pw_factory_name = "spa-node-factory"; const gchar *pw_factory_name = "spa-node-factory";
g_return_val_if_fail (info->type == SPA_TYPE_INTERFACE_Node, NULL); g_return_val_if_fail (g_strcmp0 (info->type, SPA_TYPE_INTERFACE_Node) == 0, NULL);
g_debug ("WpMonitor:%p:%s new node %u", self, self->factory_name, id); g_debug ("WpMonitor:%p:%s new node %u", self, self->factory_name, id);
@@ -249,9 +252,9 @@ node_new (struct object *dev, uint32_t id,
/* create the node locally or remotely */ /* create the node locally or remotely */
proxy = (self->flags & WP_MONITOR_FLAG_LOCAL_NODES) ? proxy = (self->flags & WP_MONITOR_FLAG_LOCAL_NODES) ?
wp_core_create_local_object (core, pw_factory_name, wp_core_create_local_object (core, pw_factory_name,
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props) : PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, props) :
wp_core_create_remote_object (core, pw_factory_name, wp_core_create_remote_object (core, pw_factory_name,
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props); PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, props);
if (!proxy) { if (!proxy) {
g_warning ("WpMonitor:%p: failed to create node: %s", self, g_warning ("WpMonitor:%p: failed to create node: %s", self,
g_strerror (errno)); g_strerror (errno));
@@ -261,7 +264,7 @@ node_new (struct object *dev, uint32_t id,
node = g_slice_new0 (struct object); node = g_slice_new0 (struct object);
node->self = self; node->self = self;
node->id = id; node->id = id;
node->type = SPA_TYPE_INTERFACE_Node; node->type = WP_TYPE_PROXY_NODE;
node->proxy = g_steal_pointer (&proxy); node->proxy = g_steal_pointer (&proxy);
return node; return node;
@@ -326,7 +329,7 @@ device_new (WpMonitor *self, uint32_t id, const gchar *factory_name,
dev = g_slice_new0 (struct object); dev = g_slice_new0 (struct object);
dev->self = self; dev->self = self;
dev->id = id; dev->id = id;
dev->type = SPA_TYPE_INTERFACE_Device; dev->type = WP_TYPE_PROXY_DEVICE;
dev->spa_obj = g_steal_pointer (&spa_dev); dev->spa_obj = g_steal_pointer (&spa_dev);
dev->properties = g_steal_pointer (&props); dev->properties = g_steal_pointer (&props);
dev->proxy = g_steal_pointer (&proxy); dev->proxy = g_steal_pointer (&proxy);
@@ -352,7 +355,7 @@ static void
object_free (struct object *obj) object_free (struct object *obj)
{ {
g_debug ("WpMonitor:%p:%s free %s %u", obj->self, obj->self->factory_name, g_debug ("WpMonitor:%p:%s free %s %u", obj->self, obj->self->factory_name,
(obj->type == SPA_TYPE_INTERFACE_Node) ? "node" : "device", obj->id); g_type_name (obj->type), obj->id);
g_list_free_full (obj->children, (GDestroyNotify) object_free); g_list_free_full (obj->children, (GDestroyNotify) object_free);
g_clear_object (&obj->proxy); g_clear_object (&obj->proxy);

View File

@@ -12,7 +12,10 @@
struct interest struct interest
{ {
gsize type; union {
char * proxy_type;
GType g_type;
};
gboolean for_proxy; gboolean for_proxy;
WpProxyFeatures wanted_features; WpProxyFeatures wanted_features;
GVariant *constraints; // aa{sv} GVariant *constraints; // aa{sv}
@@ -67,8 +70,11 @@ wp_object_manager_finalize (GObject * object)
g_clear_pointer (&self->objects, g_ptr_array_unref); g_clear_pointer (&self->objects, g_ptr_array_unref);
pw_array_for_each (i, &self->interests) pw_array_for_each (i, &self->interests) {
if (i->for_proxy)
g_clear_pointer (&i->proxy_type, g_free);
g_clear_pointer (&i->constraints, g_variant_unref); g_clear_pointer (&i->constraints, g_variant_unref);
}
pw_array_clear (&self->interests); pw_array_clear (&self->interests);
g_weak_ref_clear (&self->core); g_weak_ref_clear (&self->core);
@@ -144,7 +150,8 @@ wp_object_manager_new (void)
void void
wp_object_manager_add_proxy_interest (WpObjectManager *self, wp_object_manager_add_proxy_interest (WpObjectManager *self,
guint32 iface_type, GVariant * constraints, WpProxyFeatures wanted_features) const gchar * iface_type, GVariant * constraints,
WpProxyFeatures wanted_features)
{ {
struct interest *i; struct interest *i;
@@ -155,7 +162,7 @@ wp_object_manager_add_proxy_interest (WpObjectManager *self,
/* grow the array by 1 struct interest and fill it in */ /* grow the array by 1 struct interest and fill it in */
i = pw_array_add (&self->interests, sizeof (struct interest)); i = pw_array_add (&self->interests, sizeof (struct interest));
i->type = iface_type; i->proxy_type = g_strdup (iface_type);
i->for_proxy = TRUE; i->for_proxy = TRUE;
i->wanted_features = wanted_features; i->wanted_features = wanted_features;
i->constraints = constraints ? g_variant_ref_sink (constraints) : NULL; i->constraints = constraints ? g_variant_ref_sink (constraints) : NULL;
@@ -174,7 +181,7 @@ wp_object_manager_add_object_interest (WpObjectManager *self,
/* grow the array by 1 struct interest and fill it in */ /* grow the array by 1 struct interest and fill it in */
i = pw_array_add (&self->interests, sizeof (struct interest)); i = pw_array_add (&self->interests, sizeof (struct interest));
i->type = gtype; i->g_type = gtype;
i->for_proxy = FALSE; i->for_proxy = FALSE;
i->wanted_features = 0; i->wanted_features = 0;
i->constraints = constraints ? g_variant_ref_sink (constraints) : NULL; i->constraints = constraints ? g_variant_ref_sink (constraints) : NULL;
@@ -328,7 +335,7 @@ wp_object_manager_is_interested_in_object (WpObjectManager * self,
pw_array_for_each (i, &self->interests) { pw_array_for_each (i, &self->interests) {
if (!i->for_proxy if (!i->for_proxy
&& g_type_is_a (G_OBJECT_TYPE (object), i->type) && g_type_is_a (G_OBJECT_TYPE (object), i->g_type)
&& (!i->constraints || && (!i->constraints ||
check_constraints (i->constraints, NULL, object))) check_constraints (i->constraints, NULL, object)))
{ {
@@ -347,7 +354,7 @@ wp_object_manager_is_interested_in_global (WpObjectManager * self,
pw_array_for_each (i, &self->interests) { pw_array_for_each (i, &self->interests) {
if (i->for_proxy if (i->for_proxy
&& i->type == global->type && g_strcmp0 (i->proxy_type, global->type) == 0
&& (!i->constraints || && (!i->constraints ||
check_constraints (i->constraints, global->properties, NULL))) check_constraints (i->constraints, global->properties, NULL)))
{ {

View File

@@ -26,7 +26,7 @@ G_DECLARE_FINAL_TYPE (WpObjectManager, wp_object_manager, WP, OBJECT_MANAGER, GO
WpObjectManager * wp_object_manager_new (void); WpObjectManager * wp_object_manager_new (void);
void wp_object_manager_add_proxy_interest (WpObjectManager *self, void wp_object_manager_add_proxy_interest (WpObjectManager *self,
guint32 iface_type, GVariant * constraints, const gchar * iface_type, GVariant * constraints,
WpProxyFeatures wanted_features); WpProxyFeatures wanted_features);
void wp_object_manager_add_object_interest (WpObjectManager *self, void wp_object_manager_add_object_interest (WpObjectManager *self,
GType gtype, GVariant * constraints); GType gtype, GVariant * constraints);

View File

@@ -18,9 +18,9 @@ G_BEGIN_DECLS
/* core */ /* core */
struct pw_registry_proxy; struct pw_registry;
struct pw_registry_proxy * wp_core_get_pw_registry_proxy (WpCore * self); struct pw_registry * wp_core_get_pw_registry (WpCore * self);
gpointer wp_core_find_object (WpCore * self, GEqualFunc func, gpointer wp_core_find_object (WpCore * self, GEqualFunc func,
gconstpointer data); gconstpointer data);
@@ -37,7 +37,7 @@ typedef struct _WpGlobal WpGlobal;
struct _WpGlobal struct _WpGlobal
{ {
guint32 id; guint32 id;
guint32 type; char *type;
guint32 version; guint32 version;
guint32 permissions; guint32 permissions;
WpProperties *properties; WpProperties *properties;
@@ -55,6 +55,7 @@ wp_global_new (void)
static inline void static inline void
wp_global_clear (WpGlobal * self) wp_global_clear (WpGlobal * self)
{ {
g_clear_pointer (&self->type, g_free);
g_clear_pointer (&self->properties, wp_properties_unref); g_clear_pointer (&self->properties, wp_properties_unref);
g_weak_ref_clear (&self->proxy); g_weak_ref_clear (&self->proxy);
} }
@@ -83,7 +84,7 @@ void wp_object_manager_rm_object (WpObjectManager * self, GObject * object);
/* proxy */ /* proxy */
void wp_proxy_local_object_destroy_for_type (guint32 type, void wp_proxy_local_object_destroy_for_type (const char * type,
gpointer local_object); gpointer local_object);
WpProxy * wp_proxy_new_global (WpCore * core, WpGlobal * global); WpProxy * wp_proxy_new_global (WpCore * core, WpGlobal * global);

View File

@@ -76,8 +76,8 @@ client_event_info(void *data, const struct pw_client_info *info)
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO); wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
} }
static const struct pw_client_proxy_events client_events = { static const struct pw_client_events client_events = {
PW_VERSION_CLIENT_PROXY_EVENTS, PW_VERSION_CLIENT_EVENTS,
.info = client_event_info, .info = client_event_info,
}; };
@@ -85,7 +85,7 @@ static void
wp_proxy_client_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_client_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyClient *self = WP_PROXY_CLIENT (proxy); WpProxyClient *self = WP_PROXY_CLIENT (proxy);
pw_client_proxy_add_listener ((struct pw_client_proxy *) pw_proxy, pw_client_add_listener ((struct pw_client *) pw_proxy,
&self->listener, &client_events, self); &self->listener, &client_events, self);
} }
@@ -144,15 +144,15 @@ void
wp_proxy_client_update_permissions_array (WpProxyClient * self, wp_proxy_client_update_permissions_array (WpProxyClient * self,
guint n_perm, const struct pw_permission *permissions) guint n_perm, const struct pw_permission *permissions)
{ {
struct pw_client_proxy *pwp; struct pw_client *pwp;
int client_update_permissions_result; int client_update_permissions_result;
g_return_if_fail (WP_IS_PROXY_CLIENT (self)); g_return_if_fail (WP_IS_PROXY_CLIENT (self));
pwp = (struct pw_client_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_client *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_if_fail (pwp != NULL); g_return_if_fail (pwp != NULL);
client_update_permissions_result = pw_client_proxy_update_permissions ( client_update_permissions_result = pw_client_update_permissions (
pwp, n_perm, permissions); pwp, n_perm, permissions);
g_warn_if_fail (client_update_permissions_result >= 0); g_warn_if_fail (client_update_permissions_result >= 0);
} }

View File

@@ -77,8 +77,8 @@ device_event_info(void *data, const struct pw_device_info *info)
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO); wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
} }
static const struct pw_device_proxy_events device_events = { static const struct pw_device_events device_events = {
PW_VERSION_DEVICE_PROXY_EVENTS, PW_VERSION_DEVICE_EVENTS,
.info = device_event_info, .info = device_event_info,
}; };
@@ -86,7 +86,7 @@ static void
wp_proxy_device_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_device_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyDevice *self = WP_PROXY_DEVICE (proxy); WpProxyDevice *self = WP_PROXY_DEVICE (proxy);
pw_device_proxy_add_listener ((struct pw_device_proxy *) pw_proxy, pw_device_add_listener ((struct pw_device *) pw_proxy,
&self->listener, &device_events, self); &self->listener, &device_events, self);
} }

View File

@@ -76,8 +76,8 @@ link_event_info(void *data, const struct pw_link_info *info)
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO); wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
} }
static const struct pw_link_proxy_events link_events = { static const struct pw_link_events link_events = {
PW_VERSION_LINK_PROXY_EVENTS, PW_VERSION_LINK_EVENTS,
.info = link_event_info, .info = link_event_info,
}; };
@@ -85,7 +85,7 @@ static void
wp_proxy_link_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_link_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyLink *self = WP_PROXY_LINK (proxy); WpProxyLink *self = WP_PROXY_LINK (proxy);
pw_link_proxy_add_listener ((struct pw_link_proxy *) pw_proxy, pw_link_add_listener ((struct pw_link *) pw_proxy,
&self->listener, &link_events, self); &self->listener, &link_events, self);
} }

View File

@@ -103,8 +103,8 @@ node_event_param (void *data, int seq, uint32_t id, uint32_t index,
} }
} }
static const struct pw_node_proxy_events node_events = { static const struct pw_node_events node_events = {
PW_VERSION_NODE_PROXY_EVENTS, PW_VERSION_NODE_EVENTS,
.info = node_event_info, .info = node_event_info,
.param = node_event_param, .param = node_event_param,
}; };
@@ -113,7 +113,7 @@ static void
wp_proxy_node_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_node_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyNode *self = WP_PROXY_NODE (proxy); WpProxyNode *self = WP_PROXY_NODE (proxy);
pw_node_proxy_add_listener ((struct pw_node_proxy *) pw_proxy, pw_node_add_listener ((struct pw_node *) pw_proxy,
&self->listener, &node_events, self); &self->listener, &node_events, self);
} }
@@ -229,15 +229,15 @@ gint
wp_proxy_node_enum_params (WpProxyNode * self, wp_proxy_node_enum_params (WpProxyNode * self,
guint32 id, const struct spa_pod *filter) guint32 id, const struct spa_pod *filter)
{ {
struct pw_node_proxy *pwp; struct pw_node *pwp;
int enum_params_result; int enum_params_result;
g_return_val_if_fail (WP_IS_PROXY_NODE (self), -EINVAL); g_return_val_if_fail (WP_IS_PROXY_NODE (self), -EINVAL);
pwp = (struct pw_node_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_node *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_val_if_fail (pwp != NULL, -EINVAL); g_return_val_if_fail (pwp != NULL, -EINVAL);
enum_params_result = pw_node_proxy_enum_params (pwp, 0, id, 0, -1, filter); enum_params_result = pw_node_enum_params (pwp, 0, id, 0, -1, filter);
g_warn_if_fail (enum_params_result >= 0); g_warn_if_fail (enum_params_result >= 0);
return enum_params_result; return enum_params_result;
@@ -261,15 +261,15 @@ void
wp_proxy_node_subscribe_params_array (WpProxyNode * self, guint32 n_ids, wp_proxy_node_subscribe_params_array (WpProxyNode * self, guint32 n_ids,
guint32 *ids) guint32 *ids)
{ {
struct pw_node_proxy *pwp; struct pw_node *pwp;
int node_subscribe_params_result; int node_subscribe_params_result;
g_return_if_fail (WP_IS_PROXY_NODE (self)); g_return_if_fail (WP_IS_PROXY_NODE (self));
pwp = (struct pw_node_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_node *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_if_fail (pwp != NULL); g_return_if_fail (pwp != NULL);
node_subscribe_params_result = pw_node_proxy_subscribe_params ( node_subscribe_params_result = pw_node_subscribe_params (
pwp, ids, n_ids); pwp, ids, n_ids);
g_warn_if_fail (node_subscribe_params_result >= 0); g_warn_if_fail (node_subscribe_params_result >= 0);
} }
@@ -278,15 +278,14 @@ void
wp_proxy_node_set_param (WpProxyNode * self, guint32 id, wp_proxy_node_set_param (WpProxyNode * self, guint32 id,
guint32 flags, const struct spa_pod *param) guint32 flags, const struct spa_pod *param)
{ {
struct pw_node_proxy *pwp; struct pw_node *pwp;
int node_set_param_result; int node_set_param_result;
g_return_if_fail (WP_IS_PROXY_NODE (self)); g_return_if_fail (WP_IS_PROXY_NODE (self));
pwp = (struct pw_node_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_node *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_if_fail (pwp != NULL); g_return_if_fail (pwp != NULL);
node_set_param_result = pw_node_proxy_set_param ( node_set_param_result = pw_node_set_param (pwp, id, flags, param);
pwp, id, flags, param);
g_warn_if_fail (node_set_param_result >= 0); g_warn_if_fail (node_set_param_result >= 0);
} }

View File

@@ -104,8 +104,8 @@ port_event_param(void *data, int seq, uint32_t id, uint32_t index,
} }
} }
static const struct pw_port_proxy_events port_events = { static const struct pw_port_events port_events = {
PW_VERSION_PORT_PROXY_EVENTS, PW_VERSION_PORT_EVENTS,
.info = port_event_info, .info = port_event_info,
.param = port_event_param, .param = port_event_param,
}; };
@@ -114,7 +114,7 @@ static void
wp_proxy_port_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_port_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxyPort *self = WP_PROXY_PORT (proxy); WpProxyPort *self = WP_PROXY_PORT (proxy);
pw_port_proxy_add_listener ((struct pw_port_proxy *) pw_proxy, pw_port_add_listener ((struct pw_port *) pw_proxy,
&self->listener, &port_events, self); &self->listener, &port_events, self);
} }
@@ -230,15 +230,15 @@ gint
wp_proxy_port_enum_params (WpProxyPort * self, wp_proxy_port_enum_params (WpProxyPort * self,
guint32 id, const struct spa_pod *filter) guint32 id, const struct spa_pod *filter)
{ {
struct pw_port_proxy *pwp; struct pw_port *pwp;
int enum_params_result; int enum_params_result;
g_return_val_if_fail (WP_IS_PROXY_PORT (self), -EINVAL); g_return_val_if_fail (WP_IS_PROXY_PORT (self), -EINVAL);
pwp = (struct pw_port_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_port *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_val_if_fail (pwp != NULL, -EINVAL); g_return_val_if_fail (pwp != NULL, -EINVAL);
enum_params_result = pw_port_proxy_enum_params (pwp, 0, id, 0, -1, filter); enum_params_result = pw_port_enum_params (pwp, 0, id, 0, -1, filter);
g_warn_if_fail (enum_params_result >= 0); g_warn_if_fail (enum_params_result >= 0);
return enum_params_result; return enum_params_result;
@@ -262,15 +262,14 @@ void
wp_proxy_port_subscribe_params_array (WpProxyPort * self, guint32 n_ids, wp_proxy_port_subscribe_params_array (WpProxyPort * self, guint32 n_ids,
guint32 *ids) guint32 *ids)
{ {
struct pw_port_proxy *pwp; struct pw_port *pwp;
int port_subscribe_params_result; int port_subscribe_params_result;
g_return_if_fail (WP_IS_PROXY_PORT (self)); g_return_if_fail (WP_IS_PROXY_PORT (self));
pwp = (struct pw_port_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pwp = (struct pw_port *) wp_proxy_get_pw_proxy (WP_PROXY (self));
g_return_if_fail (pwp != NULL); g_return_if_fail (pwp != NULL);
port_subscribe_params_result = pw_port_proxy_subscribe_params ( port_subscribe_params_result = pw_port_subscribe_params (pwp, ids, n_ids);
pwp, ids, n_ids);
g_warn_if_fail (port_subscribe_params_result >= 0); g_warn_if_fail (port_subscribe_params_result >= 0);
} }

View File

@@ -22,6 +22,11 @@
#include "session.h" #include "session.h"
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/impl.h>
#include <pipewire/extensions/metadata.h>
#include <pipewire/extensions/client-node.h>
#include <pipewire/extensions/session-manager.h>
#include <spa/debug/types.h> #include <spa/debug/types.h>
typedef struct _WpProxyPrivate WpProxyPrivate; typedef struct _WpProxyPrivate WpProxyPrivate;
@@ -32,7 +37,7 @@ struct _WpProxyPrivate
WpGlobal *global; WpGlobal *global;
guint32 iface_type; char *iface_type;
guint32 iface_version; guint32 iface_version;
gpointer local_object; gpointer local_object;
@@ -56,7 +61,6 @@ enum {
PROP_GLOBAL_PERMISSIONS, PROP_GLOBAL_PERMISSIONS,
PROP_GLOBAL_PROPERTIES, PROP_GLOBAL_PROPERTIES,
PROP_INTERFACE_TYPE, PROP_INTERFACE_TYPE,
PROP_INTERFACE_NAME,
PROP_INTERFACE_QUARK, PROP_INTERFACE_QUARK,
PROP_INTERFACE_VERSION, PROP_INTERFACE_VERSION,
PROP_LOCAL_OBJECT, PROP_LOCAL_OBJECT,
@@ -96,7 +100,7 @@ G_DEFINE_QUARK (client-endpoint, wp_proxy_client_endpoint)
static struct { static struct {
/* the pipewire interface type */ /* the pipewire interface type */
guint32 pw_type; const char * pw_type;
/* the minimum interface version that the remote object must support */ /* the minimum interface version that the remote object must support */
guint32 req_version; guint32 req_version;
/* the _get_type() function of the subclass */ /* the _get_type() function of the subclass */
@@ -108,28 +112,28 @@ static struct {
} types_assoc[] = { } types_assoc[] = {
{ PW_TYPE_INTERFACE_Core, 0, wp_proxy_get_type, wp_proxy_core_quark, NULL }, { PW_TYPE_INTERFACE_Core, 0, wp_proxy_get_type, wp_proxy_core_quark, NULL },
{ PW_TYPE_INTERFACE_Registry, 0, wp_proxy_get_type, wp_proxy_registry_quark, NULL }, { PW_TYPE_INTERFACE_Registry, 0, wp_proxy_get_type, wp_proxy_registry_quark, NULL },
{ PW_TYPE_INTERFACE_Node, 0, wp_proxy_node_get_type, wp_proxy_node_quark, (GDestroyNotify)pw_node_destroy }, { PW_TYPE_INTERFACE_Node, 0, wp_proxy_node_get_type, wp_proxy_node_quark, (GDestroyNotify)pw_impl_node_destroy },
{ PW_TYPE_INTERFACE_Port, 0, wp_proxy_port_get_type, wp_proxy_port_quark, NULL, }, { PW_TYPE_INTERFACE_Port, 0, wp_proxy_port_get_type, wp_proxy_port_quark, NULL },
{ PW_TYPE_INTERFACE_Factory, 0, wp_proxy_get_type, wp_proxy_factory_quark, (GDestroyNotify)pw_factory_destroy }, { PW_TYPE_INTERFACE_Factory, 0, wp_proxy_get_type, wp_proxy_factory_quark, (GDestroyNotify)pw_impl_factory_destroy },
{ PW_TYPE_INTERFACE_Link, 0, wp_proxy_link_get_type, wp_proxy_link_quark, (GDestroyNotify)pw_link_destroy }, { PW_TYPE_INTERFACE_Link, 0, wp_proxy_link_get_type, wp_proxy_link_quark, (GDestroyNotify)pw_impl_link_destroy },
{ PW_TYPE_INTERFACE_Client, 0, wp_proxy_client_get_type, wp_proxy_client_quark, (GDestroyNotify)pw_client_destroy }, { PW_TYPE_INTERFACE_Client, 0, wp_proxy_client_get_type, wp_proxy_client_quark, (GDestroyNotify)pw_impl_client_destroy },
{ PW_TYPE_INTERFACE_Module, 0, wp_proxy_get_type, wp_proxy_module_quark, (GDestroyNotify)pw_module_destroy }, { PW_TYPE_INTERFACE_Module, 0, wp_proxy_get_type, wp_proxy_module_quark, (GDestroyNotify)pw_impl_module_destroy },
{ PW_TYPE_INTERFACE_Device, 0, wp_proxy_device_get_type, wp_proxy_device_quark, (GDestroyNotify)pw_device_destroy }, { PW_TYPE_INTERFACE_Device, 0, wp_proxy_device_get_type, wp_proxy_device_quark, (GDestroyNotify)pw_impl_device_destroy },
{ PW_TYPE_INTERFACE_Metadata, 0, wp_proxy_get_type, wp_proxy_metadata_quark, NULL }, { PW_TYPE_INTERFACE_Metadata, 0, wp_proxy_get_type, wp_proxy_metadata_quark, NULL },
{ PW_TYPE_INTERFACE_Session, 0, wp_proxy_session_get_type, wp_proxy_session_quark, NULL }, { PW_TYPE_INTERFACE_Session, 0, wp_proxy_session_get_type, wp_proxy_session_quark, NULL },
{ PW_TYPE_INTERFACE_Endpoint, 0, wp_proxy_endpoint_get_type, wp_proxy_endpoint_quark, NULL }, { PW_TYPE_INTERFACE_Endpoint, 0, wp_proxy_endpoint_get_type, wp_proxy_endpoint_quark, NULL },
{ PW_TYPE_INTERFACE_EndpointStream, 0, wp_proxy_get_type, wp_proxy_endpoint_stream_quark, NULL, }, { PW_TYPE_INTERFACE_EndpointStream, 0, wp_proxy_get_type, wp_proxy_endpoint_stream_quark, NULL },
{ PW_TYPE_INTERFACE_EndpointLink, 0, wp_proxy_get_type, wp_proxy_endpoint_link_quark, NULL, }, { PW_TYPE_INTERFACE_EndpointLink, 0, wp_proxy_get_type, wp_proxy_endpoint_link_quark, NULL },
{ PW_TYPE_INTERFACE_ClientNode, 0, wp_proxy_get_type, wp_proxy_client_node_quark, NULL }, { PW_TYPE_INTERFACE_ClientNode, 0, wp_proxy_get_type, wp_proxy_client_node_quark, NULL },
{ PW_TYPE_INTERFACE_ClientSession, 0, wp_proxy_get_type, wp_proxy_client_session_quark, NULL }, { PW_TYPE_INTERFACE_ClientSession, 0, wp_proxy_get_type, wp_proxy_client_session_quark, NULL },
{ PW_TYPE_INTERFACE_ClientEndpoint, 0, wp_proxy_get_type, wp_proxy_client_endpoint_quark, NULL }, { PW_TYPE_INTERFACE_ClientEndpoint, 0, wp_proxy_get_type, wp_proxy_client_endpoint_quark, NULL },
}; };
static inline GType static inline GType
wp_proxy_find_instance_type (guint32 type, guint32 version) wp_proxy_find_instance_type (const char * type, guint32 version)
{ {
for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) { for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) {
if (types_assoc[i].pw_type == type && if (g_strcmp0 (types_assoc[i].pw_type, type) == 0 &&
types_assoc[i].req_version <= version) types_assoc[i].req_version <= version)
return types_assoc[i].get_type (); return types_assoc[i].get_type ();
} }
@@ -138,10 +142,10 @@ wp_proxy_find_instance_type (guint32 type, guint32 version)
} }
static inline GQuark static inline GQuark
wp_proxy_find_quark_for_type (guint32 type) wp_proxy_find_quark_for_type (const char *type)
{ {
for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) { for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) {
if (types_assoc[i].pw_type == type) if (g_strcmp0 (types_assoc[i].pw_type, type) == 0)
return types_assoc[i].get_quark (); return types_assoc[i].get_quark ();
} }
@@ -149,12 +153,12 @@ wp_proxy_find_quark_for_type (guint32 type)
} }
void void
wp_proxy_local_object_destroy_for_type (guint32 type, gpointer local_object) wp_proxy_local_object_destroy_for_type (const char *type, gpointer local_object)
{ {
g_return_if_fail (local_object); g_return_if_fail (local_object);
for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) { for (gint i = 0; i < SPA_N_ELEMENTS (types_assoc); i++) {
if (types_assoc[i].pw_type == type) { if (g_strcmp0 (types_assoc[i].pw_type, type) == 0) {
if (types_assoc[i].local_object_destroy) if (types_assoc[i].local_object_destroy)
types_assoc[i].local_object_destroy (local_object); types_assoc[i].local_object_destroy (local_object);
return; return;
@@ -173,8 +177,7 @@ proxy_event_destroy (void *data)
GTask *task; GTask *task;
g_debug ("%s:%p destroyed pw_proxy %p (%s; %s; %u)", g_debug ("%s:%p destroyed pw_proxy %p (%s; %s; %u)",
G_OBJECT_TYPE_NAME (self), self, priv->pw_proxy, G_OBJECT_TYPE_NAME (self), self, priv->pw_proxy, priv->iface_type,
spa_debug_type_find_name (pw_type_info(), priv->iface_type),
priv->global ? "global" : "not global", priv->global ? "global" : "not global",
priv->global ? priv->global->id : 0); priv->global ? priv->global->id : 0);
priv->pw_proxy = NULL; priv->pw_proxy = NULL;
@@ -283,6 +286,7 @@ wp_proxy_finalize (GObject * object)
priv->local_object = NULL; priv->local_object = NULL;
} }
g_clear_pointer (&priv->iface_type, g_free);
g_clear_pointer (&priv->augment_tasks, g_ptr_array_unref); g_clear_pointer (&priv->augment_tasks, g_ptr_array_unref);
g_clear_pointer (&priv->global, wp_global_unref); g_clear_pointer (&priv->global, wp_global_unref);
g_weak_ref_clear (&priv->core); g_weak_ref_clear (&priv->core);
@@ -305,7 +309,7 @@ wp_proxy_set_property (GObject * object, guint property_id,
priv->global = g_value_dup_boxed (value); priv->global = g_value_dup_boxed (value);
break; break;
case PROP_INTERFACE_TYPE: case PROP_INTERFACE_TYPE:
priv->iface_type = g_value_get_uint (value); priv->iface_type = g_value_dup_string (value);
break; break;
case PROP_INTERFACE_VERSION: case PROP_INTERFACE_VERSION:
priv->iface_version = g_value_get_uint (value); priv->iface_version = g_value_get_uint (value);
@@ -342,11 +346,7 @@ wp_proxy_get_property (GObject * object, guint property_id, GValue * value,
g_value_set_boxed (value, priv->global ? priv->global->properties : NULL); g_value_set_boxed (value, priv->global ? priv->global->properties : NULL);
break; break;
case PROP_INTERFACE_TYPE: case PROP_INTERFACE_TYPE:
g_value_set_uint (value, priv->iface_type); g_value_set_string (value, priv->iface_type);
break;
case PROP_INTERFACE_NAME:
g_value_set_static_string (value,
spa_debug_type_find_name (pw_type_info(), priv->iface_type));
break; break;
case PROP_INTERFACE_QUARK: case PROP_INTERFACE_QUARK:
g_value_set_uint (value, wp_proxy_find_quark_for_type (priv->iface_type)); g_value_set_uint (value, wp_proxy_find_quark_for_type (priv->iface_type));
@@ -395,8 +395,8 @@ wp_proxy_default_augment (WpProxy * self, WpProxyFeatures features)
g_return_if_fail (core); g_return_if_fail (core);
/* bind */ /* bind */
priv->pw_proxy = pw_registry_proxy_bind ( priv->pw_proxy = pw_registry_bind (
wp_core_get_pw_registry_proxy (core), priv->global->id, wp_core_get_pw_registry (core), priv->global->id,
priv->iface_type, priv->iface_version, 0); priv->iface_type, priv->iface_version, 0);
wp_proxy_got_pw_proxy (self); wp_proxy_got_pw_proxy (self);
} }
@@ -442,15 +442,10 @@ wp_proxy_class_init (WpProxyClass * klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_INTERFACE_TYPE, g_object_class_install_property (object_class, PROP_INTERFACE_TYPE,
g_param_spec_uint ("interface-type", "interface-type", g_param_spec_string ("interface-type", "interface-type",
"The pipewire interface type", 0, G_MAXUINT, 0, "The pipewire interface type", NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_INTERFACE_NAME,
g_param_spec_string ("interface-name", "interface-name",
"The name of the pipewire interface", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_INTERFACE_QUARK, g_object_class_install_property (object_class, PROP_INTERFACE_QUARK,
g_param_spec_uint ("interface-quark", "interface-quark", g_param_spec_uint ("interface-quark", "interface-quark",
"A quark identifying the pipewire interface", 0, G_MAXUINT, 0, "A quark identifying the pipewire interface", 0, G_MAXUINT, 0,
@@ -500,7 +495,7 @@ wp_proxy_new_global (WpCore * core, WpGlobal * global)
} }
WpProxy * WpProxy *
wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy, guint32 type, wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy, const char *type,
guint32 version, gpointer local_object) guint32 version, gpointer local_object)
{ {
GType gtype = wp_proxy_find_instance_type (type, version); GType gtype = wp_proxy_find_instance_type (type, version);
@@ -689,7 +684,7 @@ wp_proxy_get_global_properties (WpProxy * self)
return wp_properties_ref (priv->global->properties); return wp_properties_ref (priv->global->properties);
} }
guint32 const char *
wp_proxy_get_interface_type (WpProxy * self) wp_proxy_get_interface_type (WpProxy * self)
{ {
WpProxyPrivate *priv; WpProxyPrivate *priv;
@@ -700,17 +695,6 @@ wp_proxy_get_interface_type (WpProxy * self)
return priv->iface_type; return priv->iface_type;
} }
const gchar *
wp_proxy_get_interface_name (WpProxy * self)
{
const gchar *name = NULL;
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
g_object_get (self, "interface-name", &name, NULL);
return name;
}
GQuark GQuark
wp_proxy_get_interface_quark (WpProxy * self) wp_proxy_get_interface_quark (WpProxy * self)
{ {

View File

@@ -41,7 +41,7 @@ struct _WpProxyClass
}; };
WpProxy * wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy, WpProxy * wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy,
guint32 type, guint32 version, gpointer local_object); const char *type, guint32 version, gpointer local_object);
void wp_proxy_augment (WpProxy *self, void wp_proxy_augment (WpProxy *self,
WpProxyFeatures wanted_features, GCancellable * cancellable, WpProxyFeatures wanted_features, GCancellable * cancellable,
@@ -58,8 +58,7 @@ guint32 wp_proxy_get_global_id (WpProxy * self);
guint32 wp_proxy_get_global_permissions (WpProxy * self); guint32 wp_proxy_get_global_permissions (WpProxy * self);
WpProperties * wp_proxy_get_global_properties (WpProxy * self); WpProperties * wp_proxy_get_global_properties (WpProxy * self);
guint32 wp_proxy_get_interface_type (WpProxy * self); const char * wp_proxy_get_interface_type (WpProxy * self);
const gchar * wp_proxy_get_interface_name (WpProxy * self);
GQuark wp_proxy_get_interface_quark (WpProxy * self); GQuark wp_proxy_get_interface_quark (WpProxy * self);
guint32 wp_proxy_get_interface_version (WpProxy * self); guint32 wp_proxy_get_interface_version (WpProxy * self);

View File

@@ -226,8 +226,8 @@ session_event_param (void *data, int seq, uint32_t id, uint32_t index,
} }
} }
static const struct pw_session_proxy_events session_events = { static const struct pw_session_events session_events = {
PW_VERSION_SESSION_PROXY_EVENTS, PW_VERSION_SESSION_EVENTS,
.info = session_event_info, .info = session_event_info,
.param = session_event_param, .param = session_event_param,
}; };
@@ -236,7 +236,7 @@ static void
wp_proxy_session_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) wp_proxy_session_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
{ {
WpProxySession *self = WP_PROXY_SESSION (proxy); WpProxySession *self = WP_PROXY_SESSION (proxy);
pw_session_proxy_add_listener ((struct pw_session_proxy *) pw_proxy, pw_session_add_listener ((struct pw_session *) pw_proxy,
&self->listener, &session_events, self); &self->listener, &session_events, self);
} }
@@ -247,15 +247,15 @@ wp_proxy_session_augment (WpProxy * proxy, WpProxyFeatures features)
WP_PROXY_CLASS (wp_proxy_session_parent_class)->augment (proxy, features); WP_PROXY_CLASS (wp_proxy_session_parent_class)->augment (proxy, features);
if (features & WP_PROXY_SESSION_FEATURE_DEFAULT_ENDPOINT) { if (features & WP_PROXY_SESSION_FEATURE_DEFAULT_ENDPOINT) {
struct pw_session_proxy *pw_proxy = NULL; struct pw_session *pw_proxy = NULL;
uint32_t ids[] = { SPA_PARAM_Props }; uint32_t ids[] = { SPA_PARAM_Props };
pw_proxy = (struct pw_session_proxy *) wp_proxy_get_pw_proxy (proxy); pw_proxy = (struct pw_session *) wp_proxy_get_pw_proxy (proxy);
if (!pw_proxy) if (!pw_proxy)
return; return;
pw_session_proxy_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL); pw_session_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL);
pw_session_proxy_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids)); pw_session_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids));
} }
} }
@@ -287,13 +287,13 @@ wp_proxy_session_set_default_endpoint (WpSession * session,
WpProxySession *self = WP_PROXY_SESSION (session); WpProxySession *self = WP_PROXY_SESSION (session);
char buf[1024]; char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf)); struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct pw_session_proxy *pw_proxy = NULL; struct pw_session *pw_proxy = NULL;
/* set the default endpoint id as a property param on the session; /* set the default endpoint id as a property param on the session;
our spa_props cache will be updated by the param event */ our spa_props cache will be updated by the param event */
pw_proxy = (struct pw_session_proxy *) wp_proxy_get_pw_proxy (WP_PROXY (self)); pw_proxy = (struct pw_session *) wp_proxy_get_pw_proxy (WP_PROXY (self));
pw_session_proxy_set_param (pw_proxy, pw_session_set_param (pw_proxy,
SPA_PARAM_Props, 0, SPA_PARAM_Props, 0,
spa_pod_builder_add_object (&b, spa_pod_builder_add_object (&b,
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
@@ -418,11 +418,11 @@ client_session_update (WpExportedSession * self, guint32 change_mask,
wp_exported_session_get_instance_private (self); wp_exported_session_get_instance_private (self);
char buf[1024]; char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf)); struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct pw_client_session_proxy *pw_proxy = NULL; struct pw_client_session *pw_proxy = NULL;
struct pw_session_info *info = NULL; struct pw_session_info *info = NULL;
g_autoptr (GPtrArray) params = NULL; g_autoptr (GPtrArray) params = NULL;
pw_proxy = (struct pw_client_session_proxy *) wp_proxy_get_pw_proxy ( pw_proxy = (struct pw_client_session *) wp_proxy_get_pw_proxy (
priv->client_sess); priv->client_sess);
if (change_mask & PW_CLIENT_SESSION_UPDATE_PARAMS) { if (change_mask & PW_CLIENT_SESSION_UPDATE_PARAMS) {
@@ -433,7 +433,7 @@ client_session_update (WpExportedSession * self, guint32 change_mask,
info->change_mask = info_change_mask; info->change_mask = info_change_mask;
} }
pw_client_session_proxy_update (pw_proxy, pw_client_session_update (pw_proxy,
change_mask, change_mask,
params ? params->len : 0, params ? params->len : 0,
(const struct spa_pod **) (params ? params->pdata : NULL), (const struct spa_pod **) (params ? params->pdata : NULL),
@@ -485,8 +485,8 @@ client_session_proxy_bound (void *object, uint32_t global_id)
wp_exported_notify_export_done (WP_EXPORTED (self), NULL); wp_exported_notify_export_done (WP_EXPORTED (self), NULL);
} }
static struct pw_client_session_proxy_events client_session_events = { static struct pw_client_session_events client_session_events = {
PW_VERSION_CLIENT_SESSION_PROXY_EVENTS, PW_VERSION_CLIENT_SESSION_EVENTS,
.set_param = client_session_set_param, .set_param = client_session_set_param,
}; };
@@ -501,7 +501,7 @@ wp_exported_session_export (WpExported * self)
WpExportedSessionPrivate *priv = WpExportedSessionPrivate *priv =
wp_exported_session_get_instance_private (WP_EXPORTED_SESSION (self)); wp_exported_session_get_instance_private (WP_EXPORTED_SESSION (self));
g_autoptr (WpCore) core = wp_exported_get_core (self); g_autoptr (WpCore) core = wp_exported_get_core (self);
struct pw_client_session_proxy *pw_proxy = NULL; struct pw_client_session *pw_proxy = NULL;
/* make sure these props are not present; they are added by the server */ /* make sure these props are not present; they are added by the server */
wp_properties_set (priv->properties, PW_KEY_OBJECT_ID, NULL); wp_properties_set (priv->properties, PW_KEY_OBJECT_ID, NULL);
@@ -509,13 +509,13 @@ wp_exported_session_export (WpExported * self)
wp_properties_set (priv->properties, PW_KEY_FACTORY_ID, NULL); wp_properties_set (priv->properties, PW_KEY_FACTORY_ID, NULL);
priv->client_sess = wp_core_create_remote_object (core, "client-session", priv->client_sess = wp_core_create_remote_object (core, "client-session",
PW_TYPE_INTERFACE_ClientSession, PW_VERSION_CLIENT_SESSION_PROXY, PW_TYPE_INTERFACE_ClientSession, PW_VERSION_CLIENT_SESSION,
priv->properties); priv->properties);
pw_proxy = (struct pw_client_session_proxy *) wp_proxy_get_pw_proxy ( pw_proxy = (struct pw_client_session *) wp_proxy_get_pw_proxy (
priv->client_sess); priv->client_sess);
pw_client_session_proxy_add_listener (pw_proxy, &priv->listener, pw_client_session_add_listener (pw_proxy, &priv->listener,
&client_session_events, self); &client_session_events, self);
pw_proxy_add_listener ((struct pw_proxy *) pw_proxy, &priv->proxy_listener, pw_proxy_add_listener ((struct pw_proxy *) pw_proxy, &priv->proxy_listener,
&client_sess_proxy_events, self); &client_sess_proxy_events, self);

View File

@@ -50,9 +50,9 @@ wp_config_static_nodes_context_create_node (WpConfigStaticNodesContext *self,
/* Create the node */ /* Create the node */
node_proxy = node_data->n.local ? node_proxy = node_data->n.local ?
wp_core_create_local_object (core, node_data->n.factory, wp_core_create_local_object (core, node_data->n.factory,
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, node_data->n.props) : PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, node_data->n.props) :
wp_core_create_remote_object (core, node_data->n.factory, wp_core_create_remote_object (core, node_data->n.factory,
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, node_data->n.props); PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, node_data->n.props);
if (!node_proxy) { if (!node_proxy) {
g_warning ("WpConfigStaticNodesContext:%p: failed to create node: %s", self, g_warning ("WpConfigStaticNodesContext:%p: failed to create node: %s", self,
g_strerror (errno)); g_strerror (errno));
@@ -133,8 +133,8 @@ wp_config_static_nodes_context_constructed (GObject * object)
wp_core_install_object_manager (core, self->devices_om); wp_core_install_object_manager (core, self->devices_om);
/* Start creating static nodes when the connected callback is triggered */ /* Start creating static nodes when the connected callback is triggered */
g_signal_connect_object (core, "remote-state-changed::connected", g_signal_connect_object (core, "connected", (GCallback) start_static_nodes,
(GCallback) start_static_nodes, self, G_CONNECT_SWAPPED); self, G_CONNECT_SWAPPED);
G_OBJECT_CLASS (wp_config_static_nodes_context_parent_class)->constructed (object); G_OBJECT_CLASS (wp_config_static_nodes_context_parent_class)->constructed (object);
} }

View File

@@ -11,6 +11,7 @@
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <spa/utils/keys.h> #include <spa/utils/keys.h>
#include <spa/monitor/device.h>
static void static void
setup_device_props (WpMonitor *self, WpProperties *p, WpModule *module) setup_device_props (WpMonitor *self, WpProperties *p, WpModule *module)
@@ -244,6 +245,6 @@ wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args)
wp_module_set_destroy_callback (module, g_object_unref, monitor); wp_module_set_destroy_callback (module, g_object_unref, monitor);
/* Start the monitor when the connected callback is triggered */ /* Start the monitor when the connected callback is triggered */
g_signal_connect_object (core, "remote-state-changed::connected", g_signal_connect_object (core, "connected",
(GCallback) start_monitor, monitor, G_CONNECT_SWAPPED); (GCallback) start_monitor, monitor, G_CONNECT_SWAPPED);
} }

View File

@@ -24,11 +24,6 @@ audio_softdsp_endpoint_factory (WpFactory * factory, GType type,
void void
wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args)
{ {
struct pw_core *pw_core = wp_core_get_pw_core (core);
pw_module_load (pw_core, "libpipewire-module-client-device", NULL, NULL);
pw_module_load (pw_core, "libpipewire-module-adapter", NULL, NULL);
/* Register simple-endpoint-link and audio-softdsp-endpoint */ /* Register simple-endpoint-link and audio-softdsp-endpoint */
wp_factory_new (core, "pipewire-simple-endpoint-link", wp_factory_new (core, "pipewire-simple-endpoint-link",
simple_endpoint_link_factory); simple_endpoint_link_factory);

View File

@@ -58,7 +58,7 @@ create_link_cb (WpProperties *props, gpointer user_data)
/* Create the link */ /* Create the link */
proxy = wp_core_create_remote_object(core, "link-factory", proxy = wp_core_create_remote_object(core, "link-factory",
PW_TYPE_INTERFACE_Link, PW_VERSION_LINK_PROXY, props); PW_TYPE_INTERFACE_Link, PW_VERSION_LINK, props);
g_return_if_fail (proxy); g_return_if_fail (proxy);
g_ptr_array_add(self->link_proxies, proxy); g_ptr_array_add(self->link_proxies, proxy);
} }
@@ -178,7 +178,7 @@ wp_audio_convert_init_async (GAsyncInitable *initable, int io_priority,
/* Create the proxy */ /* Create the proxy */
proxy = wp_core_create_remote_object (core, "spa-node-factory", proxy = wp_core_create_remote_object (core, "spa-node-factory",
PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props); PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, props);
g_return_if_fail (proxy); g_return_if_fail (proxy);
g_object_set (self, "proxy-node", proxy, NULL); g_object_set (self, "proxy-node", proxy, NULL);

View File

@@ -177,7 +177,7 @@ create_link_cb (WpProperties *props, gpointer user_data)
/* Create the link */ /* Create the link */
proxy = wp_core_create_remote_object(core, "link-factory", proxy = wp_core_create_remote_object(core, "link-factory",
PW_TYPE_INTERFACE_Link, PW_VERSION_LINK_PROXY, props); PW_TYPE_INTERFACE_Link, PW_VERSION_LINK, props);
g_return_if_fail (proxy); g_return_if_fail (proxy);
g_ptr_array_add(self->link_proxies, proxy); g_ptr_array_add(self->link_proxies, proxy);

View File

@@ -10,6 +10,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <glib-unix.h> #include <glib-unix.h>
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/impl.h>
static GOptionEntry entries[] = static GOptionEntry entries[] =
{ {
@@ -67,25 +68,15 @@ signal_handler (gpointer data)
} }
static void static void
remote_state_changed (WpCore *core, WpRemoteState state, on_disconnected (WpCore *core, struct WpDaemonData * d)
struct WpDaemonData * d)
{ {
/* something else triggered the exit; we will certainly get a state /* something else triggered the exit; we will certainly get a state
* change while destroying the remote, but let's not change the message */ * change while destroying the remote, but let's not change the message */
if (d->exit_message) if (d->exit_message)
return; return;
switch (state) { daemon_exit_static_str (d, WP_CODE_DISCONNECTED,
case WP_REMOTE_STATE_UNCONNECTED: "disconnected from pipewire");
daemon_exit_static_str (d, WP_CODE_DISCONNECTED,
"disconnected from pipewire");
break;
case WP_REMOTE_STATE_ERROR:
daemon_exit (d, WP_CODE_OPERATION_FAILED, "pipewire remote error");
break;
default:
break;
}
} }
static gboolean static gboolean
@@ -186,8 +177,8 @@ parse_commands_file (struct WpDaemonData *d, GInputStream * stream,
module = strtok_r (NULL, " ", &saveptr); module = strtok_r (NULL, " ", &saveptr);
props = module + strlen(module) + 1; props = module + strlen(module) + 1;
if (!pw_module_load (wp_core_get_pw_core (d->core), module, props, if (!pw_context_load_module (wp_core_get_pw_context (d->core), module,
NULL)) { props, NULL)) {
g_set_error (error, WP_DOMAIN_DAEMON, WP_CODE_OPERATION_FAILED, g_set_error (error, WP_DOMAIN_DAEMON, WP_CODE_OPERATION_FAILED,
"failed to load pipewire module '%s': %s", module, "failed to load pipewire module '%s': %s", module,
g_strerror (errno)); g_strerror (errno));
@@ -208,7 +199,8 @@ parse_commands_file (struct WpDaemonData *d, GInputStream * stream,
return FALSE; return FALSE;
} }
ret = pw_core_add_spa_lib (wp_core_get_pw_core (d->core), regex, lib); ret = pw_context_add_spa_lib (wp_core_get_pw_context (d->core), regex,
lib);
if (ret < 0) { if (ret < 0) {
g_set_error (error, WP_DOMAIN_DAEMON, WP_CODE_OPERATION_FAILED, g_set_error (error, WP_DOMAIN_DAEMON, WP_CODE_OPERATION_FAILED,
"failed to add spa lib ('%s' on '%s'): %s", regex, lib, "failed to add spa lib ('%s' on '%s'): %s", regex, lib,
@@ -273,7 +265,8 @@ load_commands_file (struct WpDaemonData *d)
} }
/* connect to pipewire */ /* connect to pipewire */
wp_core_connect (d->core); if (!wp_core_connect (d->core))
daemon_exit_static_str (d, WP_CODE_DISCONNECTED, "failed to connect");
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
@@ -300,8 +293,7 @@ main (gint argc, gchar **argv)
/* init wireplumber */ /* init wireplumber */
data.core = core = wp_core_new (NULL, NULL); data.core = core = wp_core_new (NULL, NULL);
g_signal_connect (core, "remote-state-changed", g_signal_connect (core, "disconnected", (GCallback) on_disconnected, &data);
(GCallback) remote_state_changed, &data);
/* init configuration */ /* init configuration */

View File

@@ -49,10 +49,10 @@ static void
create_audiotestsrc (TestConfigEndpointFixture *self) create_audiotestsrc (TestConfigEndpointFixture *self)
{ {
pw_thread_loop_lock (self->server.thread_loop); pw_thread_loop_lock (self->server.thread_loop);
pw_core_add_spa_lib (self->server.core, "audiotestsrc", pw_context_add_spa_lib (self->server.context, "audiotestsrc",
"audiotestsrc/libspa-audiotestsrc"); "audiotestsrc/libspa-audiotestsrc");
if (!pw_module_load (self->server.core, "libpipewire-module-spa-node", if (!pw_context_load_module (self->server.context,
"audiotestsrc", NULL)) { "libpipewire-module-spa-node", "audiotestsrc", NULL)) {
pw_thread_loop_unlock (self->server.thread_loop); pw_thread_loop_unlock (self->server.thread_loop);
g_test_skip ("audiotestsrc SPA plugin is not installed"); g_test_skip ("audiotestsrc SPA plugin is not installed");
return; return;
@@ -60,21 +60,6 @@ create_audiotestsrc (TestConfigEndpointFixture *self)
pw_thread_loop_unlock (self->server.thread_loop); pw_thread_loop_unlock (self->server.thread_loop);
} }
static void
on_connected (WpCore *core, enum pw_remote_state new_state,
TestConfigEndpointFixture *self)
{
/* Register the wp-endpoint-audiotestsrc */
wp_factory_new (self->core, "wp-endpoint-audiotestsrc",
wp_endpoint_audiotestsrc_factory);
/* Create the audiotestsrc node */
create_audiotestsrc (self);
/* Signal we are done */
signal_created (self);
}
static void * static void *
loop_thread_start (void *d) loop_thread_start (void *d)
{ {
@@ -91,9 +76,17 @@ loop_thread_start (void *d)
g_autoptr (WpProperties) props = NULL; g_autoptr (WpProperties) props = NULL;
props = wp_properties_new (PW_KEY_REMOTE_NAME, self->server.name, NULL); props = wp_properties_new (PW_KEY_REMOTE_NAME, self->server.name, NULL);
self->core = wp_core_new (self->context, props); self->core = wp_core_new (self->context, props);
g_signal_connect (self->core, "remote-state-changed::connected", g_assert_true (wp_core_connect (self->core));
(GCallback) on_connected, self);
wp_core_connect (self->core); /* Register the wp-endpoint-audiotestsrc */
wp_factory_new (self->core, "wp-endpoint-audiotestsrc",
wp_endpoint_audiotestsrc_factory);
/* Create the audiotestsrc node */
create_audiotestsrc (self);
/* Signal we are done */
signal_created (self);
/* Run the main loop */ /* Run the main loop */
g_main_loop_run (self->loop); g_main_loop_run (self->loop);

View File

@@ -27,17 +27,6 @@ typedef struct {
WpCore *core; WpCore *core;
} TestConfigPolicyFixture; } TestConfigPolicyFixture;
static void
on_connected (WpCore *core, enum pw_remote_state new_state,
TestConfigPolicyFixture *self)
{
/* Notify the main thread that we are done */
g_mutex_lock (&self->mutex);
self->created = TRUE;
g_cond_signal (&self->cond);
g_mutex_unlock (&self->mutex);
}
static void * static void *
loop_thread_start (void *d) loop_thread_start (void *d)
{ {
@@ -54,9 +43,13 @@ loop_thread_start (void *d)
g_autoptr (WpProperties) props = NULL; g_autoptr (WpProperties) props = NULL;
props = wp_properties_new (PW_KEY_REMOTE_NAME, self->server.name, NULL); props = wp_properties_new (PW_KEY_REMOTE_NAME, self->server.name, NULL);
self->core = wp_core_new (self->context, props); self->core = wp_core_new (self->context, props);
g_signal_connect (self->core, "remote-state-changed::connected", g_assert_true (wp_core_connect (self->core));
(GCallback) on_connected, self);
wp_core_connect (self->core); /* Notify the main thread that we are done */
g_mutex_lock (&self->mutex);
self->created = TRUE;
g_cond_signal (&self->cond);
g_mutex_unlock (&self->mutex);
/* Run the main loop */ /* Run the main loop */
g_main_loop_run (self->loop); g_main_loop_run (self->loop);

View File

@@ -57,7 +57,7 @@ loop_thread_start (void *d)
wp_test_server_setup (&self->server); wp_test_server_setup (&self->server);
/* Add the audioconvert SPA library */ /* Add the audioconvert SPA library */
pw_core_add_spa_lib(self->server.core, "audio.convert*", pw_context_add_spa_lib (self->server.context, "audio.convert*",
"audioconvert/libspa-audioconvert"); "audioconvert/libspa-audioconvert");
/* Create the core and connect to the server */ /* Create the core and connect to the server */
@@ -141,7 +141,7 @@ basic (TestConfigStaticNodesFixture *f, gconstpointer data)
g_signal_connect (ctx, "node-created", (GCallback) on_node_created, f); g_signal_connect (ctx, "node-created", (GCallback) on_node_created, f);
/* Connect */ /* Connect */
wp_core_connect (f->core); g_assert_true (wp_core_connect (f->core));
/* Wait for the node to be created */ /* Wait for the node to be created */
wait_for_created (f); wait_for_created (f);

View File

@@ -8,6 +8,7 @@
#include <wp/wp.h> #include <wp/wp.h>
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/extensions/session-manager.h>
#include "test-server.h" #include "test-server.h"
@@ -46,21 +47,11 @@ timeout_callback (TestEndpointFixture *fixture)
} }
static void static void
test_endpoint_remote_state_changed (WpCore *core, WpRemoteState state, test_endpoint_disconnected (WpCore *core, TestEndpointFixture *fixture)
TestEndpointFixture *fixture)
{ {
const gchar * msg = NULL; g_message ("core disconnected");
g_test_fail ();
switch (state) { g_main_loop_quit (fixture->loop);
case WP_REMOTE_STATE_ERROR:
wp_core_get_remote_state (core, &msg);
g_message ("remote error: %s", msg);
g_test_fail ();
g_main_loop_quit (fixture->loop);
break;
default:
break;
}
} }
static void static void
@@ -70,8 +61,8 @@ test_endpoint_setup (TestEndpointFixture *self, gconstpointer user_data)
wp_test_server_setup (&self->server); wp_test_server_setup (&self->server);
pw_thread_loop_lock (self->server.thread_loop); pw_thread_loop_lock (self->server.thread_loop);
if (!pw_module_load (self->server.core, "libpipewire-module-session-manager", if (!pw_context_load_module (self->server.context,
NULL, NULL)) { "libpipewire-module-session-manager", NULL, NULL)) {
pw_thread_loop_unlock (self->server.thread_loop); pw_thread_loop_unlock (self->server.thread_loop);
g_test_skip ("libpipewire-module-session-manager is not installed"); g_test_skip ("libpipewire-module-session-manager is not installed");
return; return;
@@ -91,10 +82,10 @@ test_endpoint_setup (TestEndpointFixture *self, gconstpointer user_data)
g_main_context_push_thread_default (self->context); g_main_context_push_thread_default (self->context);
/* watchdogs */ /* watchdogs */
g_signal_connect (self->export_core, "remote-state-changed", g_signal_connect (self->export_core, "disconnected",
(GCallback) test_endpoint_remote_state_changed, self); (GCallback) test_endpoint_disconnected, self);
g_signal_connect (self->proxy_core, "remote-state-changed", g_signal_connect (self->proxy_core, "disconnected",
(GCallback) test_endpoint_remote_state_changed, self); (GCallback) test_endpoint_disconnected, self);
self->timeout_source = g_timeout_source_new_seconds (3); self->timeout_source = g_timeout_source_new_seconds (3);
g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback, g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback,
@@ -226,7 +217,6 @@ test_endpoint_basic_notify_properties (WpEndpoint * endpoint, GParamSpec * param
static void static void
test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data) test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
{ {
WpRemoteState state;
g_autoptr (WpExportedEndpoint) endpoint = NULL; g_autoptr (WpExportedEndpoint) endpoint = NULL;
gfloat float_value; gfloat float_value;
gboolean boolean_value; gboolean boolean_value;
@@ -241,11 +231,6 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
wp_core_install_object_manager (fixture->export_core, fixture->export_om); wp_core_install_object_manager (fixture->export_core, fixture->export_om);
g_assert_true (wp_core_connect (fixture->export_core)); g_assert_true (wp_core_connect (fixture->export_core));
do {
g_main_context_iteration (fixture->context, FALSE);
state = wp_core_get_remote_state (fixture->export_core, NULL);
g_assert_cmpint (state, !=, WP_REMOTE_STATE_ERROR);
} while (state != WP_REMOTE_STATE_CONNECTED);
/* set up the proxy side */ /* set up the proxy side */
g_signal_connect (fixture->proxy_om, "object-added", g_signal_connect (fixture->proxy_om, "object-added",
@@ -258,11 +243,6 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
wp_core_install_object_manager (fixture->proxy_core, fixture->proxy_om); wp_core_install_object_manager (fixture->proxy_core, fixture->proxy_om);
g_assert_true (wp_core_connect (fixture->proxy_core)); g_assert_true (wp_core_connect (fixture->proxy_core));
do {
g_main_context_iteration (fixture->context, FALSE);
state = wp_core_get_remote_state (fixture->proxy_core, NULL);
g_assert_cmpint (state, !=, WP_REMOTE_STATE_ERROR);
} while (state != WP_REMOTE_STATE_CONNECTED);
/* create endpoint */ /* create endpoint */
endpoint = wp_exported_endpoint_new (fixture->export_core); endpoint = wp_exported_endpoint_new (fixture->export_core);

View File

@@ -40,21 +40,11 @@ timeout_callback (TestProxyFixture *fixture)
} }
static void static void
test_proxy_remote_state_changed (WpCore *core, WpRemoteState state, test_proxy_disconnected (WpCore *core, TestProxyFixture *fixture)
TestProxyFixture *fixture)
{ {
const gchar * msg = NULL; g_message ("core disconnected");
g_test_fail ();
switch (state) { g_main_loop_quit (fixture->loop);
case WP_REMOTE_STATE_ERROR:
wp_core_get_remote_state (core, &msg);
g_message ("remote error: %s", msg);
g_test_fail ();
g_main_loop_quit (fixture->loop);
break;
default:
break;
}
} }
static void static void
@@ -73,8 +63,8 @@ test_proxy_setup (TestProxyFixture *self, gconstpointer user_data)
g_main_context_push_thread_default (self->context); g_main_context_push_thread_default (self->context);
/* watchdogs */ /* watchdogs */
g_signal_connect (self->core, "remote-state-changed", g_signal_connect (self->core, "disconnected",
(GCallback) test_proxy_remote_state_changed, self); (GCallback) test_proxy_disconnected, self);
self->timeout_source = g_timeout_source_new_seconds (3); self->timeout_source = g_timeout_source_new_seconds (3);
g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback, g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback,
@@ -139,10 +129,8 @@ test_proxy_basic_object_added (WpObjectManager *om, WpProxy *proxy,
g_assert_true (wp_proxy_is_global (proxy)); g_assert_true (wp_proxy_is_global (proxy));
g_assert_cmpuint (wp_proxy_get_interface_quark (proxy), ==, g_assert_cmpuint (wp_proxy_get_interface_quark (proxy), ==,
g_quark_from_string ("client")); g_quark_from_string ("client"));
g_assert_cmpuint (wp_proxy_get_interface_type (proxy), ==, g_assert_cmpstr (wp_proxy_get_interface_type (proxy), ==,
PW_TYPE_INTERFACE_Client); PW_TYPE_INTERFACE_Client);
g_assert_cmpstr (wp_proxy_get_interface_name (proxy), ==,
"PipeWire:Interface:Client");
g_assert_cmphex (wp_proxy_get_global_permissions (proxy), ==, PW_PERM_RWX); g_assert_cmphex (wp_proxy_get_global_permissions (proxy), ==, PW_PERM_RWX);
g_assert_true (WP_IS_PROXY_CLIENT (proxy)); g_assert_true (WP_IS_PROXY_CLIENT (proxy));
@@ -221,7 +209,7 @@ test_proxy_node_object_added (WpObjectManager *om, WpProxy *proxy,
g_assert_nonnull (proxy); g_assert_nonnull (proxy);
g_assert_true (wp_proxy_is_global (proxy)); g_assert_true (wp_proxy_is_global (proxy));
g_assert_cmpuint (wp_proxy_get_interface_type (proxy), ==, g_assert_cmpstr (wp_proxy_get_interface_type (proxy), ==,
PW_TYPE_INTERFACE_Node); PW_TYPE_INTERFACE_Node);
g_assert_cmphex (wp_proxy_get_features (proxy), ==, g_assert_cmphex (wp_proxy_get_features (proxy), ==,
WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO); WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO);
@@ -259,10 +247,10 @@ test_proxy_node (TestProxyFixture *fixture, gconstpointer data)
{ {
/* load audiotestsrc on the server side */ /* load audiotestsrc on the server side */
pw_thread_loop_lock (fixture->server.thread_loop); pw_thread_loop_lock (fixture->server.thread_loop);
pw_core_add_spa_lib (fixture->server.core, "audiotestsrc", pw_context_add_spa_lib (fixture->server.context, "audiotestsrc",
"audiotestsrc/libspa-audiotestsrc"); "audiotestsrc/libspa-audiotestsrc");
if (!pw_module_load (fixture->server.core, "libpipewire-module-spa-node", if (!pw_context_load_module (fixture->server.context,
"audiotestsrc", NULL)) { "libpipewire-module-spa-node", "audiotestsrc", NULL)) {
pw_thread_loop_unlock (fixture->server.thread_loop); pw_thread_loop_unlock (fixture->server.thread_loop);
g_test_skip ("audiotestsrc SPA plugin is not installed"); g_test_skip ("audiotestsrc SPA plugin is not installed");
return; return;

View File

@@ -8,6 +8,7 @@
#include <wp/wp.h> #include <wp/wp.h>
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/extensions/session-manager.h>
#include "test-server.h" #include "test-server.h"
@@ -46,21 +47,11 @@ timeout_callback (TestSessionFixture *fixture)
} }
static void static void
test_session_remote_state_changed (WpCore *core, WpRemoteState state, test_session_disconnected (WpCore *core, TestSessionFixture *fixture)
TestSessionFixture *fixture)
{ {
const gchar * msg = NULL; g_message ("core disconnected");
g_test_fail ();
switch (state) { g_main_loop_quit (fixture->loop);
case WP_REMOTE_STATE_ERROR:
wp_core_get_remote_state (core, &msg);
g_message ("remote error: %s", msg);
g_test_fail ();
g_main_loop_quit (fixture->loop);
break;
default:
break;
}
} }
static void static void
@@ -70,8 +61,8 @@ test_session_setup (TestSessionFixture *self, gconstpointer user_data)
wp_test_server_setup (&self->server); wp_test_server_setup (&self->server);
pw_thread_loop_lock (self->server.thread_loop); pw_thread_loop_lock (self->server.thread_loop);
if (!pw_module_load (self->server.core, "libpipewire-module-session-manager", if (!pw_context_load_module (self->server.context,
NULL, NULL)) { "libpipewire-module-session-manager", NULL, NULL)) {
pw_thread_loop_unlock (self->server.thread_loop); pw_thread_loop_unlock (self->server.thread_loop);
g_test_skip ("libpipewire-module-session-manager is not installed"); g_test_skip ("libpipewire-module-session-manager is not installed");
return; return;
@@ -91,10 +82,10 @@ test_session_setup (TestSessionFixture *self, gconstpointer user_data)
g_main_context_push_thread_default (self->context); g_main_context_push_thread_default (self->context);
/* watchdogs */ /* watchdogs */
g_signal_connect (self->export_core, "remote-state-changed", g_signal_connect (self->export_core, "disconnected",
(GCallback) test_session_remote_state_changed, self); (GCallback) test_session_disconnected, self);
g_signal_connect (self->proxy_core, "remote-state-changed", g_signal_connect (self->proxy_core, "disconnected",
(GCallback) test_session_remote_state_changed, self); (GCallback) test_session_disconnected, self);
self->timeout_source = g_timeout_source_new_seconds (3); self->timeout_source = g_timeout_source_new_seconds (3);
g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback, g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback,
@@ -226,7 +217,6 @@ test_session_basic_notify_properties (WpSession * session, GParamSpec * param,
static void static void
test_session_basic (TestSessionFixture *fixture, gconstpointer data) test_session_basic (TestSessionFixture *fixture, gconstpointer data)
{ {
WpRemoteState state;
g_autoptr (WpExportedSession) session = NULL; g_autoptr (WpExportedSession) session = NULL;
/* set up the export side */ /* set up the export side */
@@ -239,11 +229,6 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
wp_core_install_object_manager (fixture->export_core, fixture->export_om); wp_core_install_object_manager (fixture->export_core, fixture->export_om);
g_assert_true (wp_core_connect (fixture->export_core)); g_assert_true (wp_core_connect (fixture->export_core));
do {
g_main_context_iteration (fixture->context, FALSE);
state = wp_core_get_remote_state (fixture->export_core, NULL);
g_assert_cmpint (state, !=, WP_REMOTE_STATE_ERROR);
} while (state != WP_REMOTE_STATE_CONNECTED);
/* set up the proxy side */ /* set up the proxy side */
g_signal_connect (fixture->proxy_om, "object-added", g_signal_connect (fixture->proxy_om, "object-added",
@@ -256,11 +241,6 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
wp_core_install_object_manager (fixture->proxy_core, fixture->proxy_om); wp_core_install_object_manager (fixture->proxy_core, fixture->proxy_om);
g_assert_true (wp_core_connect (fixture->proxy_core)); g_assert_true (wp_core_connect (fixture->proxy_core));
do {
g_main_context_iteration (fixture->context, FALSE);
state = wp_core_get_remote_state (fixture->proxy_core, NULL);
g_assert_cmpint (state, !=, WP_REMOTE_STATE_ERROR);
} while (state != WP_REMOTE_STATE_CONNECTED);
/* create session */ /* create session */
session = wp_exported_session_new (fixture->export_core); session = wp_exported_session_new (fixture->export_core);

View File

@@ -100,10 +100,8 @@ test_spa_props_build_all (void)
g_assert_cmpuint (id, ==, SPA_PROP_volume); g_assert_cmpuint (id, ==, SPA_PROP_volume);
g_assert_cmpstr (string_value, ==, "Volume"); g_assert_cmpstr (string_value, ==, "Volume");
g_assert_nonnull (pod); g_assert_nonnull (pod);
/* https://gitlab.freedesktop.org/pipewire/pipewire/issues/196
g_assert_true (spa_pod_is_choice (pod)); g_assert_true (spa_pod_is_choice (pod));
g_assert_true (SPA_POD_CHOICE_VALUE_TYPE (pod) == SPA_TYPE_Float); */ g_assert_true (SPA_POD_CHOICE_VALUE_TYPE (pod) == SPA_TYPE_Float);
g_assert_true (SPA_POD_TYPE (pod) == SPA_TYPE_Float);
pod = g_ptr_array_index (arr, 2); pod = g_ptr_array_index (arr, 2);
g_assert_nonnull (pod); g_assert_nonnull (pod);
@@ -224,10 +222,8 @@ test_spa_props_register_from_prop_info (void)
g_assert_cmpuint (id, ==, SPA_PROP_volume); g_assert_cmpuint (id, ==, SPA_PROP_volume);
g_assert_cmpstr (string_value, ==, "Volume"); g_assert_cmpstr (string_value, ==, "Volume");
g_assert_nonnull (pod); g_assert_nonnull (pod);
/* https://gitlab.freedesktop.org/pipewire/pipewire/issues/196
g_assert_true (spa_pod_is_choice (pod)); g_assert_true (spa_pod_is_choice (pod));
g_assert_true (SPA_POD_CHOICE_VALUE_TYPE (pod) == SPA_TYPE_Float); */ g_assert_true (SPA_POD_CHOICE_VALUE_TYPE (pod) == SPA_TYPE_Float);
g_assert_true (SPA_POD_TYPE (pod) == SPA_TYPE_Float);
pod = g_ptr_array_index (arr, 2); pod = g_ptr_array_index (arr, 2);
g_assert_nonnull (pod); g_assert_nonnull (pod);

View File

@@ -7,12 +7,12 @@
*/ */
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/impl.h>
typedef struct { typedef struct {
gchar *name; gchar *name;
struct pw_core *core;
struct pw_loop *loop;
struct pw_thread_loop *thread_loop; struct pw_thread_loop *thread_loop;
struct pw_context *context;
} WpTestServer; } WpTestServer;
static inline void static inline void
@@ -27,12 +27,10 @@ wp_test_server_setup (WpTestServer *self)
PW_KEY_CORE_NAME, self->name, PW_KEY_CORE_NAME, self->name,
NULL); NULL);
self->loop = pw_loop_new (NULL); self->thread_loop = pw_thread_loop_new ("wp-test-server", NULL);
self->thread_loop = pw_thread_loop_new (self->loop, "wp-test-server"); self->context = pw_context_new (pw_thread_loop_get_loop (self->thread_loop), properties, 0);
self->core = pw_core_new (self->loop, properties, 0);
pw_module_load (self->core, "libpipewire-module-protocol-native", NULL, NULL); pw_context_load_module (self->context, "libpipewire-module-access", NULL, NULL);
pw_module_load (self->core, "libpipewire-module-access", NULL, NULL);
pw_thread_loop_start (self->thread_loop); pw_thread_loop_start (self->thread_loop);
} }
@@ -41,7 +39,6 @@ static inline void
wp_test_server_teardown (WpTestServer *self) wp_test_server_teardown (WpTestServer *self)
{ {
pw_thread_loop_stop (self->thread_loop); pw_thread_loop_stop (self->thread_loop);
pw_core_destroy (self->core); pw_context_destroy (self->context);
pw_thread_loop_destroy (self->thread_loop); pw_thread_loop_destroy (self->thread_loop);
pw_loop_destroy (self->loop);
} }

View File

@@ -8,6 +8,7 @@
#include <wp/wp.h> #include <wp/wp.h>
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/extensions/session-manager/interfaces.h>
static GOptionEntry entries[] = static GOptionEntry entries[] =
{ {
@@ -221,20 +222,9 @@ device_node_props (WpObjectManager * om, struct WpCliData * d)
} }
static void static void
remote_state_changed (WpCore *core, WpRemoteState state, on_disconnected (WpCore *core, struct WpCliData * d)
struct WpCliData * d)
{ {
switch (state) { g_main_loop_quit (d->loop);
case WP_REMOTE_STATE_UNCONNECTED:
g_main_loop_quit (d->loop);
break;
case WP_REMOTE_STATE_ERROR:
g_message ("pipewire remote error");
g_main_loop_quit (d->loop);
break;
default:
break;
}
} }
static const gchar * const usage_string = static const gchar * const usage_string =
@@ -264,8 +254,7 @@ main (gint argc, gchar **argv)
data.loop = loop = g_main_loop_new (NULL, FALSE); data.loop = loop = g_main_loop_new (NULL, FALSE);
data.core = core = wp_core_new (NULL, NULL); data.core = core = wp_core_new (NULL, NULL);
g_signal_connect (core, "remote-state-changed", g_signal_connect (core, "disconnected", (GCallback) on_disconnected, &data);
(GCallback) remote_state_changed, &data);
om = wp_object_manager_new (); om = wp_object_manager_new ();