diff --git a/lib/wp/core.c b/lib/wp/core.c index 6f98b9be..486016fe 100644 --- a/lib/wp/core.c +++ b/lib/wp/core.c @@ -7,14 +7,95 @@ */ #include "core.h" +#include "proxy.h" +#include "wpenums.h" -enum { - SIGNAL_GLOBAL_ADDED, - SIGNAL_GLOBAL_REMOVED, - NUM_SIGNALS +#include + +/* + * Integration between the PipeWire main loop and GMainLoop + */ + +#define WP_LOOP_SOURCE(x) ((WpLoopSource *) x) + +typedef struct _WpLoopSource WpLoopSource; +struct _WpLoopSource +{ + GSource parent; + struct pw_loop *loop; }; -static guint32 signals[NUM_SIGNALS]; +static gboolean +wp_loop_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data) +{ + int result; + + pw_loop_enter (WP_LOOP_SOURCE(s)->loop); + result = pw_loop_iterate (WP_LOOP_SOURCE(s)->loop, 0); + pw_loop_leave (WP_LOOP_SOURCE(s)->loop); + + if (G_UNLIKELY (result < 0)) + g_warning ("pw_loop_iterate failed: %s", spa_strerror (result)); + + return G_SOURCE_CONTINUE; +} + +static void +wp_loop_source_finalize (GSource * s) +{ + pw_loop_destroy (WP_LOOP_SOURCE(s)->loop); +} + +static GSourceFuncs source_funcs = { + NULL, + NULL, + wp_loop_source_dispatch, + wp_loop_source_finalize +}; + +static GSource * +wp_loop_source_new (void) +{ + GSource *s = g_source_new (&source_funcs, sizeof (WpLoopSource)); + WP_LOOP_SOURCE(s)->loop = pw_loop_new (NULL); + + g_source_add_unix_fd (s, + pw_loop_get_fd (WP_LOOP_SOURCE(s)->loop), + G_IO_IN | G_IO_ERR | G_IO_HUP); + + return (GSource *) s; +} + +/** + * WpCore + */ + +struct _WpCore +{ + GObject parent; + + /* main loop integration */ + GMainContext *context; + + /* pipewire main objects */ + struct pw_core *pw_core; + struct pw_remote *pw_remote; + struct spa_hook remote_listener; + + /* remote core */ + struct pw_core_proxy *core_proxy; + + /* remote registry */ + struct pw_registry_proxy *registry_proxy; + struct spa_hook registry_listener; + + /* local proxies */ + GHashTable *proxies; + GHashTable *default_features; + + /* local global objects */ + GPtrArray *global_objects; +}; struct global_object { @@ -23,14 +104,121 @@ struct global_object GDestroyNotify destroy; }; -struct _WpCore -{ - GObject parent; - GPtrArray *global_objects; +enum { + PROP_0, + PROP_CONTEXT, + PROP_PW_CORE, + PROP_PW_REMOTE, + PROP_REMOTE_STATE, }; +enum { + SIGNAL_REMOTE_STATE_CHANGED, + SIGNAL_GLOBAL_ADDED, + SIGNAL_GLOBAL_REMOVED, + SIGNAL_REMOTE_GLOBAL_ADDED, + SIGNAL_REMOTE_GLOBAL_REMOVED, + NUM_SIGNALS +}; + +static guint32 signals[NUM_SIGNALS]; + G_DEFINE_TYPE (WpCore, wp_core, G_TYPE_OBJECT) +static void +on_proxy_ready (GObject * obj, GAsyncResult * res, gpointer data) +{ + WpCore *self = WP_CORE (data); + WpProxy *proxy = WP_PROXY (obj); + g_autoptr (GError) error = NULL; + + if (!wp_proxy_augment_finish (proxy, res, &error)) { + g_warning ("Failed to augment WpProxy (%p): %s", obj, error->message); + } + + g_signal_emit (self, signals[SIGNAL_REMOTE_GLOBAL_ADDED], + wp_proxy_get_interface_quark (proxy), proxy); +} + +static void +registry_global (void *data, uint32_t id, uint32_t permissions, + uint32_t type, uint32_t version, const struct spa_dict *props) +{ + WpCore *self = WP_CORE (data); + WpProxy *proxy; + WpProxyFeatures features; + g_autoptr (WpProperties) properties = wp_properties_new_copy_dict (props); + + /* construct & store WpProxy */ + proxy = wp_proxy_new_global (self, id, permissions, properties, + type, version); + g_hash_table_insert (self->proxies, GUINT_TO_POINTER (id), proxy); + + g_debug ("registry global:%u perm:0x%x type:%u/%u -> WpProxy:%p", + id, permissions, type, version, proxy); + + /* augment */ + features = GPOINTER_TO_UINT (g_hash_table_lookup (self->default_features, + GUINT_TO_POINTER (G_TYPE_FROM_INSTANCE (proxy)))); + wp_proxy_augment (proxy, features, NULL, on_proxy_ready, self); +} + +static void +registry_global_remove (void *data, uint32_t id) +{ + WpCore *self = WP_CORE (data); + g_autoptr (WpProxy) proxy = NULL; + + if (g_hash_table_steal_extended (self->proxies, GUINT_TO_POINTER (id), NULL, + (gpointer *) &proxy)) + g_signal_emit (data, signals[SIGNAL_REMOTE_GLOBAL_REMOVED], + wp_proxy_get_interface_quark (proxy), proxy); +} + +static const struct pw_registry_proxy_events registry_proxy_events = { + PW_VERSION_REGISTRY_PROXY_EVENTS, + .global = registry_global, + .global_remove = registry_global_remove, +}; + +static void +registry_init (WpCore *self) +{ + /* Get the core proxy */ + self->core_proxy = pw_remote_get_core_proxy (self->pw_remote); + + /* Registry */ + self->registry_proxy = pw_core_proxy_get_registry (self->core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(self->registry_proxy, &self->registry_listener, + ®istry_proxy_events, self); +} + +static void +on_remote_state_changed (void *d, enum pw_remote_state old_state, + enum pw_remote_state new_state, const char *error) +{ + 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, +}; + static void free_global_object (gpointer p) { @@ -46,9 +234,29 @@ free_global_object (gpointer p) static void wp_core_init (WpCore * self) { + self->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, + g_object_unref); + self->default_features = g_hash_table_new (g_direct_hash, g_direct_equal); self->global_objects = g_ptr_array_new_with_free_func (free_global_object); } +static void +wp_core_constructed (GObject *object) +{ + WpCore *self = WP_CORE (object); + g_autoptr (GSource) source = NULL; + + source = wp_loop_source_new (); + g_source_attach (source, self->context); + + self->pw_core = pw_core_new (WP_LOOP_SOURCE (source)->loop, NULL, 0); + self->pw_remote = pw_remote_new (self->pw_core, NULL, 0); + pw_remote_add_listener (self->pw_remote, &self->remote_listener, + &remote_events, self); + + G_OBJECT_CLASS (wp_core_parent_class)->constructed (object); +} + static void wp_core_dispose (GObject * obj) { @@ -73,18 +281,98 @@ wp_core_dispose (GObject * obj) static void wp_core_finalize (GObject * obj) { + WpCore *self = WP_CORE (obj); + + g_clear_pointer (&self->proxies, g_hash_table_unref); + g_clear_pointer (&self->default_features, g_hash_table_unref); + g_clear_pointer (&self->pw_remote, pw_remote_destroy); + self->core_proxy= NULL; + self->registry_proxy = NULL; + g_clear_pointer (&self->pw_core, pw_core_destroy); + g_clear_pointer (&self->context, g_main_context_unref); + g_debug ("WpCore destroyed"); G_OBJECT_CLASS (wp_core_parent_class)->finalize (obj); } +static void +wp_core_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + WpCore *self = WP_CORE (object); + + switch (property_id) { + case PROP_CONTEXT: + g_value_set_boxed (value, self->context); + break; + case PROP_PW_CORE: + g_value_set_pointer (value, self->pw_core); + 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: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +wp_core_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + WpCore *self = WP_CORE (object); + + switch (property_id) { + case PROP_CONTEXT: + self->context = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + static void wp_core_class_init (WpCoreClass * klass) { GObjectClass *object_class = (GObjectClass *) klass; + pw_init (NULL, NULL); + + object_class->constructed = wp_core_constructed; object_class->dispose = wp_core_dispose; object_class->finalize = wp_core_finalize; + object_class->get_property = wp_core_get_property; + object_class->set_property = wp_core_set_property; + + g_object_class_install_property (object_class, PROP_CONTEXT, + g_param_spec_boxed ("context", "context", "A GMainContext to attach to", + G_TYPE_MAIN_CONTEXT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_PW_CORE, + g_param_spec_pointer ("pw-core", "pw-core", "The pipewire core", + 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[SIGNAL_REMOTE_STATE_CHANGED] = g_signal_new ("remote-state-changed", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_REMOTE_STATE); signals[SIGNAL_GLOBAL_ADDED] = g_signal_new ("global-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, 0, NULL, @@ -93,12 +381,117 @@ wp_core_class_init (WpCoreClass * klass) signals[SIGNAL_GLOBAL_REMOVED] = g_signal_new ("global-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER); + + signals[SIGNAL_REMOTE_GLOBAL_ADDED] = g_signal_new ("remote-global-added", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_PROXY); + + signals[SIGNAL_REMOTE_GLOBAL_REMOVED] = g_signal_new ("remote-global-removed", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_PROXY); } WpCore * -wp_core_new (void) +wp_core_new (GMainContext *context) { - return g_object_new (WP_TYPE_CORE, NULL); + return g_object_new (WP_TYPE_CORE, "context", context, NULL); +} + +GMainContext * +wp_core_get_context (WpCore * self) +{ + g_return_val_if_fail (WP_IS_CORE (self), NULL); + return self->context; +} + +struct pw_core * +wp_core_get_pw_core (WpCore * self) +{ + g_return_val_if_fail (WP_IS_CORE (self), NULL); + return self->pw_core; +} + +struct pw_remote * +wp_core_get_pw_remote (WpCore * self) +{ + g_return_val_if_fail (WP_IS_CORE (self), NULL); + return self->pw_remote; +} + +static gboolean +connect_in_idle (WpCore *self) +{ + pw_remote_connect (self->pw_remote); + return G_SOURCE_REMOVE; +} + +gboolean +wp_core_connect (WpCore *self) +{ + g_autoptr (GSource) source = NULL; + + g_return_val_if_fail (WP_IS_CORE (self), FALSE); + + source = g_idle_source_new (); + g_source_set_callback (source, (GSourceFunc) connect_in_idle, self, NULL); + g_source_attach (source, self->context); + + return TRUE; +} + +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); +} + +void +wp_core_set_default_proxy_features (WpCore * self, + GType proxy_type, WpProxyFeatures features) +{ + g_return_if_fail (WP_IS_CORE (self)); + + g_hash_table_insert (self->default_features, GUINT_TO_POINTER (proxy_type), + GUINT_TO_POINTER (features)); +} + +WpProxy * +wp_core_create_remote_object (WpCore *self, + const gchar *factory_name, guint32 interface_type, + guint32 interface_version, WpProperties * properties) +{ + struct pw_proxy *pw_proxy; + + g_return_val_if_fail (WP_IS_CORE (self), NULL); + g_return_val_if_fail (self->core_proxy, NULL); + + pw_proxy = pw_core_proxy_create_object (self->core_proxy, factory_name, + interface_type, interface_version, + properties ? wp_properties_peek_dict (properties) : NULL, 0); + return wp_proxy_new_wrap (self, pw_proxy, interface_type, + interface_version); +} + +struct pw_core_proxy * +wp_core_get_pw_core_proxy (WpCore * self) +{ + g_return_val_if_fail (WP_IS_CORE (self), NULL); + return self->core_proxy; +} + +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; } /** @@ -229,4 +622,3 @@ G_DEFINE_QUARK (endpoint, wp_global_endpoint) G_DEFINE_QUARK (factory, wp_global_factory) G_DEFINE_QUARK (module, wp_global_module) G_DEFINE_QUARK (policy-manager, wp_global_policy_manager) -G_DEFINE_QUARK (remote-pipewire, wp_global_remote_pipewire) diff --git a/lib/wp/core.h b/lib/wp/core.h index d647cfa5..8f80ed05 100644 --- a/lib/wp/core.h +++ b/lib/wp/core.h @@ -10,12 +10,57 @@ #define __WIREPLUMBER_CORE_H__ #include +#include "proxy.h" G_BEGIN_DECLS +struct pw_core; +struct pw_remote; + +/** + * 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 ()) G_DECLARE_FINAL_TYPE (WpCore, wp_core, WP, CORE, GObject) +WpCore * wp_core_new (GMainContext *context); + +GMainContext * wp_core_get_context (WpCore * self); +struct pw_core * wp_core_get_pw_core (WpCore * self); +struct pw_remote * wp_core_get_pw_remote (WpCore * self); + +gboolean wp_core_connect (WpCore * self); +WpRemoteState wp_core_get_remote_state (WpCore * self, const gchar ** error); + +void wp_core_set_default_proxy_features ( + WpCore * self, GType proxy_type, WpProxyFeatures features); + +WpProxy * wp_core_create_remote_object (WpCore * self, + const gchar * factory_name, guint32 interface_type, + guint32 interface_version, WpProperties * properties); + + +/* private */ + +struct pw_core_proxy; +struct pw_registry_proxy; + +struct pw_core_proxy * wp_core_get_pw_core_proxy (WpCore * self); +struct pw_registry_proxy * wp_core_get_pw_registry_proxy (WpCore * self); + enum { WP_CORE_FOREACH_GLOBAL_DONE = FALSE, WP_CORE_FOREACH_GLOBAL_CONTINUE = TRUE, @@ -24,8 +69,6 @@ enum { typedef gboolean (*WpCoreForeachGlobalFunc) (GQuark key, gpointer global, gpointer user_data); -WpCore * wp_core_new (void); - gpointer wp_core_get_global (WpCore * self, GQuark key); void wp_core_foreach_global (WpCore * self, WpCoreForeachGlobalFunc callback, gpointer user_data); @@ -46,14 +89,6 @@ GQuark wp_global_module_quark (void); #define WP_GLOBAL_POLICY_MANAGER (wp_global_policy_manager_quark ()) GQuark wp_global_policy_manager_quark (void); -/** - * WP_GLOBAL_REMOTE_PIPEWIRE: - * The key to access the #WpRemote global object that maintains - * the connection to pipewire - */ -#define WP_GLOBAL_REMOTE_PIPEWIRE (wp_global_remote_pipewire_quark ()) -GQuark wp_global_remote_pipewire_quark (void); - G_END_DECLS #endif diff --git a/lib/wp/meson.build b/lib/wp/meson.build index aafe6922..969a5471 100644 --- a/lib/wp/meson.build +++ b/lib/wp/meson.build @@ -11,8 +11,6 @@ wp_lib_sources = [ 'proxy-link.c', 'proxy-node.c', 'proxy-port.c', - 'remote.c', - 'remote-pipewire.c', ] wp_lib_headers = [ @@ -28,8 +26,6 @@ wp_lib_headers = [ 'proxy-node.h', 'proxy-port.h', 'proxy-link.h', - 'remote.h', - 'remote-pipewire.h', 'wp.h', ] diff --git a/lib/wp/proxy.c b/lib/wp/proxy.c index 66781c8e..16c8b205 100644 --- a/lib/wp/proxy.c +++ b/lib/wp/proxy.c @@ -8,8 +8,8 @@ */ #include "proxy.h" +#include "core.h" #include "error.h" -#include "remote-pipewire.h" #include "wpenums.h" #include "proxy-client.h" @@ -24,7 +24,7 @@ typedef struct _WpProxyPrivate WpProxyPrivate; struct _WpProxyPrivate { /* properties */ - GWeakRef remote; + GWeakRef core; guint32 global_id; guint32 global_perm; @@ -48,7 +48,7 @@ struct _WpProxyPrivate enum { PROP_0, - PROP_REMOTE, + PROP_CORE, PROP_GLOBAL_ID, PROP_GLOBAL_PERMISSIONS, PROP_GLOBAL_PROPERTIES, @@ -194,7 +194,7 @@ wp_proxy_init (WpProxy * self) { WpProxyPrivate *priv = wp_proxy_get_instance_private (self); - g_weak_ref_init (&priv->remote, NULL); + g_weak_ref_init (&priv->core, NULL); priv->async_tasks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); } @@ -221,7 +221,7 @@ wp_proxy_finalize (GObject * object) g_clear_object (&priv->task); g_clear_pointer (&priv->global_props, wp_properties_unref); g_clear_pointer (&priv->pw_proxy, pw_proxy_destroy); - g_weak_ref_clear (&priv->remote); + g_weak_ref_clear (&priv->core); g_clear_pointer (&priv->async_tasks, g_hash_table_unref); G_OBJECT_CLASS (wp_proxy_parent_class)->finalize (object); @@ -234,8 +234,8 @@ wp_proxy_set_property (GObject * object, guint property_id, WpProxyPrivate *priv = wp_proxy_get_instance_private (WP_PROXY(object)); switch (property_id) { - case PROP_REMOTE: - g_weak_ref_set (&priv->remote, g_value_get_object (value)); + case PROP_CORE: + g_weak_ref_set (&priv->core, g_value_get_object (value)); break; case PROP_GLOBAL_ID: priv->global_id = g_value_get_uint (value); @@ -268,8 +268,8 @@ wp_proxy_get_property (GObject * object, guint property_id, GValue * value, WpProxyPrivate *priv = wp_proxy_get_instance_private (WP_PROXY(object)); switch (property_id) { - case PROP_REMOTE: - g_value_take_object (value, g_weak_ref_get (&priv->remote)); + case PROP_CORE: + g_value_take_object (value, g_weak_ref_get (&priv->core)); break; case PROP_GLOBAL_ID: g_value_set_uint (value, priv->global_id); @@ -309,7 +309,7 @@ static void wp_proxy_default_augment (WpProxy * self, WpProxyFeatures features) { WpProxyPrivate *priv = wp_proxy_get_instance_private (self); - g_autoptr (WpRemote) remote = NULL; + g_autoptr (WpCore) core = NULL; /* ensure we have a pw_proxy, as we can't have * any other feature without first having that */ @@ -327,13 +327,13 @@ wp_proxy_default_augment (WpProxy * self, WpProxyFeatures features) return; } - remote = g_weak_ref_get (&priv->remote); - g_return_if_fail (remote); + core = g_weak_ref_get (&priv->core); + g_return_if_fail (core); /* bind */ - priv->pw_proxy = wp_remote_pipewire_proxy_bind ( - WP_REMOTE_PIPEWIRE (remote), - priv->global_id, priv->iface_type); + priv->pw_proxy = pw_registry_proxy_bind ( + wp_core_get_pw_registry_proxy (core), priv->global_id, + priv->iface_type, priv->iface_version, 0); wp_proxy_got_pw_proxy (self); } } @@ -352,9 +352,8 @@ wp_proxy_class_init (WpProxyClass * klass) /* Install the properties */ - g_object_class_install_property (object_class, PROP_REMOTE, - g_param_spec_object ("remote", "remote", - "The pipewire connection WpRemote", WP_TYPE_REMOTE, + g_object_class_install_property (object_class, PROP_CORE, + g_param_spec_object ("core", "core", "The WpCore", WP_TYPE_CORE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_GLOBAL_ID, @@ -414,13 +413,13 @@ wp_proxy_class_init (WpProxyClass * klass) } WpProxy * -wp_proxy_new_global (WpRemote * remote, +wp_proxy_new_global (WpCore * core, guint32 id, guint32 permissions, WpProperties * properties, guint32 type, guint32 version) { GType gtype = wp_proxy_find_instance_type (type, version); return g_object_new (gtype, - "remote", remote, + "core", core, "global-id", id, "global-permissions", permissions, "global-properties", properties, @@ -430,12 +429,12 @@ wp_proxy_new_global (WpRemote * remote, } WpProxy * -wp_proxy_new_wrap (WpRemote * remote, +wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy, guint32 type, guint32 version) { GType gtype = wp_proxy_find_instance_type (type, version); return g_object_new (gtype, - "remote", remote, + "core", core, "pw-proxy", proxy, "interface-type", type, "interface-version", version, @@ -544,20 +543,20 @@ wp_proxy_get_features (WpProxy * self) } /** - * wp_proxy_get_remote: + * wp_proxy_get_core: * @self: the proxy * - * Returns: (transfer full): the remote that created this proxy + * Returns: (transfer full): the core that created this proxy */ -WpRemote * -wp_proxy_get_remote (WpProxy * self) +WpCore * +wp_proxy_get_core (WpProxy * self) { WpProxyPrivate *priv; g_return_val_if_fail (WP_IS_PROXY (self), NULL); priv = wp_proxy_get_instance_private (self); - return g_weak_ref_get (&priv->remote); + return g_weak_ref_get (&priv->core); } gboolean diff --git a/lib/wp/proxy.h b/lib/wp/proxy.h index 800d760b..46e2b2ad 100644 --- a/lib/wp/proxy.h +++ b/lib/wp/proxy.h @@ -12,12 +12,12 @@ #include -#include "remote.h" #include "properties.h" G_BEGIN_DECLS struct pw_proxy; +typedef struct _WpCore WpCore; typedef enum { /*< flags >*/ WP_PROXY_FEATURE_PW_PROXY = (1 << 0), @@ -40,10 +40,10 @@ struct _WpProxyClass void (*pw_proxy_destroyed) (WpProxy * self); }; -WpProxy * wp_proxy_new_global (WpRemote * remote, +WpProxy * wp_proxy_new_global (WpCore * core, guint32 id, guint32 permissions, WpProperties * properties, guint32 type, guint32 version); -WpProxy * wp_proxy_new_wrap (WpRemote * remote, +WpProxy * wp_proxy_new_wrap (WpCore * core, struct pw_proxy * proxy, guint32 type, guint32 version); void wp_proxy_augment (WpProxy *self, @@ -54,7 +54,7 @@ gboolean wp_proxy_augment_finish (WpProxy * self, GAsyncResult * res, WpProxyFeatures wp_proxy_get_features (WpProxy * self); -WpRemote * wp_proxy_get_remote (WpProxy * self); +WpCore * wp_proxy_get_core (WpProxy * self); gboolean wp_proxy_is_global (WpProxy * self); guint32 wp_proxy_get_global_id (WpProxy * self); diff --git a/lib/wp/remote-pipewire.c b/lib/wp/remote-pipewire.c deleted file mode 100644 index 3d158a0b..00000000 --- a/lib/wp/remote-pipewire.c +++ /dev/null @@ -1,453 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#include "remote-pipewire.h" - -#include - -/* - * Integration between the PipeWire main loop and GMainLoop - */ - -#define WP_LOOP_SOURCE(x) ((WpLoopSource *) x) - -typedef struct _WpLoopSource WpLoopSource; -struct _WpLoopSource -{ - GSource parent; - struct pw_loop *loop; -}; - -static gboolean -wp_loop_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data) -{ - int result; - - pw_loop_enter (WP_LOOP_SOURCE(s)->loop); - result = pw_loop_iterate (WP_LOOP_SOURCE(s)->loop, 0); - pw_loop_leave (WP_LOOP_SOURCE(s)->loop); - - if (G_UNLIKELY (result < 0)) - g_warning ("pw_loop_iterate failed: %s", spa_strerror (result)); - - return G_SOURCE_CONTINUE; -} - -static void -wp_loop_source_finalize (GSource * s) -{ - pw_loop_destroy (WP_LOOP_SOURCE(s)->loop); -} - -static GSourceFuncs source_funcs = { - NULL, - NULL, - wp_loop_source_dispatch, - wp_loop_source_finalize -}; - -static GSource * -wp_loop_source_new (void) -{ - GSource *s = g_source_new (&source_funcs, sizeof (WpLoopSource)); - WP_LOOP_SOURCE(s)->loop = pw_loop_new (NULL); - - g_source_add_unix_fd (s, - pw_loop_get_fd (WP_LOOP_SOURCE(s)->loop), - G_IO_IN | G_IO_ERR | G_IO_HUP); - - return (GSource *) s; -} - -/** - * WpRemotePipewire - */ - -struct _WpRemotePipewire -{ - WpRemote parent; - - struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; - - /* Registry */ - struct pw_registry_proxy *registry_proxy; - struct spa_hook registry_listener; - - GMainContext *context; - - GHashTable *proxies; - GHashTable *default_features; - GQueue created_obj_proxies; -}; - -enum { - PROP_0, - PROP_STATE, - PROP_ERROR_MESSAGE, - PROP_PW_CORE, - PROP_PW_REMOTE, - PROP_CONTEXT, -}; - -enum -{ - SIGNAL_GLOBAL_ADDED, - SIGNAL_GLOBAL_REMOVED, - LAST_SIGNAL, -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (WpRemotePipewire, wp_remote_pipewire, WP_TYPE_REMOTE) - -static void -on_proxy_ready (GObject * obj, GAsyncResult * res, gpointer data) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (data); - WpProxy *proxy = WP_PROXY (obj); - g_autoptr (GError) error = NULL; - - if (!wp_proxy_augment_finish (proxy, res, &error)) { - g_warning ("Failed to augment WpProxy (%p): %s", obj, error->message); - } - - g_signal_emit (self, signals[SIGNAL_GLOBAL_ADDED], - wp_proxy_get_interface_quark (proxy), proxy); -} - -static void -registry_global(void *data, uint32_t id, uint32_t permissions, - uint32_t type, uint32_t version, const struct spa_dict *props) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (data); - WpProxy *proxy; - WpProxyFeatures features; - g_autoptr (WpProperties) properties = wp_properties_new_copy_dict (props); - - /* construct & store WpProxy */ - proxy = wp_proxy_new_global (WP_REMOTE (self), id, permissions, properties, - type, version); - g_hash_table_insert (self->proxies, GUINT_TO_POINTER (id), proxy); - - g_debug ("registry global:%u perm:0x%x type:%u/%u -> WpProxy:%p", - id, permissions, type, version, proxy); - - /* augment */ - features = GPOINTER_TO_UINT (g_hash_table_lookup (self->default_features, - GUINT_TO_POINTER (G_TYPE_FROM_INSTANCE (proxy)))); - wp_proxy_augment (proxy, features, NULL, on_proxy_ready, self); -} - -static void -registry_global_remove (void *data, uint32_t id) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (data); - g_autoptr (WpProxy) proxy = NULL; - - if (g_hash_table_steal_extended (self->proxies, GUINT_TO_POINTER (id), NULL, - (gpointer *) &proxy)) - g_signal_emit (data, signals[SIGNAL_GLOBAL_REMOVED], - wp_proxy_get_interface_quark (proxy), proxy); -} - -static const struct pw_registry_proxy_events registry_proxy_events = { - PW_VERSION_REGISTRY_PROXY_EVENTS, - .global = registry_global, - .global_remove = registry_global_remove, -}; - -static void -registry_init (WpRemotePipewire *self) -{ - /* Get the core proxy */ - self->core_proxy = pw_remote_get_core_proxy (self->remote); - - /* Registry */ - self->registry_proxy = pw_core_proxy_get_registry (self->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(self->registry_proxy, &self->registry_listener, - ®istry_proxy_events, self); -} - -static void -on_remote_state_changed (void *d, enum pw_remote_state old_state, - enum pw_remote_state new_state, const char *error) -{ - WpRemotePipewire *self = d; - - 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); - - g_object_notify (G_OBJECT (self), "state"); -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, -}; - -static void -wp_remote_pipewire_init (WpRemotePipewire *self) -{ - self->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - g_object_unref); - self->default_features = g_hash_table_new (g_direct_hash, g_direct_equal); -} - -static void -wp_remote_pipewire_constructed (GObject *object) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (object); - GSource *source; - - source = wp_loop_source_new (); - g_source_attach (source, self->context); - - self->core = pw_core_new (WP_LOOP_SOURCE (source)->loop, NULL, 0); - - self->remote = pw_remote_new (self->core, NULL, 0); - pw_remote_add_listener (self->remote, &self->remote_listener, &remote_events, - self); - - G_OBJECT_CLASS (wp_remote_pipewire_parent_class)->constructed (object); -} - -static void -wp_remote_pipewire_finalize (GObject *object) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (object); - - g_clear_pointer (&self->proxies, g_hash_table_unref); - g_clear_pointer (&self->default_features, g_hash_table_unref); - pw_remote_destroy (self->remote); - pw_core_destroy (self->core); - g_clear_pointer (&self->context, g_main_context_unref); - self->core_proxy= NULL; - self->registry_proxy = NULL; - - G_OBJECT_CLASS (wp_remote_pipewire_parent_class)->finalize (object); -} - -static void -wp_remote_pipewire_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (object); - - switch (property_id) { - case PROP_STATE: - /* enum pw_remote_state matches values with WpRemoteState */ - g_value_set_enum (value, pw_remote_get_state (self->remote, NULL)); - break; - case PROP_ERROR_MESSAGE: - { - const gchar *msg; - (void) pw_remote_get_state (self->remote, &msg); - g_value_set_string (value, msg); - break; - } - case PROP_PW_CORE: - g_value_set_pointer (value, self->core); - break; - case PROP_PW_REMOTE: - g_value_set_pointer (value, self->remote); - break; - case PROP_CONTEXT: - g_value_set_boxed (value, self->context); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_remote_pipewire_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (object); - - switch (property_id) { - case PROP_CONTEXT: - self->context = g_value_dup_boxed (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gboolean -connect_in_idle (WpRemotePipewire *self) -{ - pw_remote_connect (self->remote); - return G_SOURCE_REMOVE; -} - -static gboolean -wp_remote_pipewire_connect (WpRemote *remote) -{ - WpRemotePipewire *self = WP_REMOTE_PIPEWIRE (remote); - g_autoptr (GSource) source; - - source = g_idle_source_new (); - g_source_set_callback (source, (GSourceFunc) connect_in_idle, self, NULL); - g_source_attach (source, self->context); - - return TRUE; -} - -static void -wp_remote_pipewire_class_init (WpRemotePipewireClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpRemoteClass *remote_class = (WpRemoteClass *) klass; - - pw_init (NULL, NULL); - - object_class->constructed = wp_remote_pipewire_constructed; - object_class->finalize = wp_remote_pipewire_finalize; - object_class->get_property = wp_remote_pipewire_get_property; - object_class->set_property = wp_remote_pipewire_set_property; - - remote_class->connect = wp_remote_pipewire_connect; - - g_object_class_override_property (object_class, PROP_STATE, "state"); - g_object_class_override_property (object_class, PROP_ERROR_MESSAGE, - "error-message"); - - g_object_class_install_property (object_class, PROP_CONTEXT, - g_param_spec_boxed ("context", "context", "A GMainContext to attach to", - G_TYPE_MAIN_CONTEXT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_PW_CORE, - g_param_spec_pointer ("pw-core", "pw-core", "The pipewire core", - 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)); - - /* Signals */ - signals[SIGNAL_GLOBAL_ADDED] = g_signal_new ("global-added", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_PROXY); - signals[SIGNAL_GLOBAL_REMOVED] = g_signal_new ("global-removed", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_PROXY); -} - -WpRemote * -wp_remote_pipewire_new (WpCore *core, GMainContext *context) -{ - WpRemote *remote; - - g_return_val_if_fail (WP_IS_CORE (core), NULL); - - remote = g_object_new (WP_TYPE_REMOTE_PIPEWIRE, - "core", core, - "context", context, - NULL); - wp_core_register_global (core, WP_GLOBAL_REMOTE_PIPEWIRE, - g_object_ref (remote), g_object_unref); - - return remote; -} - -void -wp_remote_pipewire_set_default_features (WpRemotePipewire * self, - GType proxy_type, WpProxyFeatures features) -{ - g_return_if_fail (WP_IS_REMOTE_PIPEWIRE (self)); - - g_hash_table_insert (self->default_features, GUINT_TO_POINTER (proxy_type), - GUINT_TO_POINTER (features)); -} - -WpProxy * -wp_remote_pipewire_create_object (WpRemotePipewire *self, - const gchar *factory_name, guint32 interface_type, - guint32 interface_version, WpProperties * properties) -{ - struct pw_proxy *pw_proxy; - - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE (self), NULL); - g_return_val_if_fail (self->core_proxy, NULL); - - pw_proxy = pw_core_proxy_create_object (self->core_proxy, factory_name, - interface_type, interface_version, - properties ? wp_properties_peek_dict (properties) : NULL, 0); - return wp_proxy_new_wrap (WP_REMOTE (self), pw_proxy, interface_type, - interface_version); -} - -gpointer -wp_remote_pipewire_proxy_bind (WpRemotePipewire *self, guint global_id, - guint global_type) -{ - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE(self), NULL); - g_return_val_if_fail (self->registry_proxy, NULL); - - return pw_registry_proxy_bind (self->registry_proxy, global_id, global_type, - 0, 0); -} - -gpointer -wp_remote_pipewire_find_factory (WpRemotePipewire *self, - const char *factory_name) -{ - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE(self), NULL); - g_return_val_if_fail (self->core, NULL); - - return pw_core_find_factory(self->core, factory_name); -} - -void -wp_remote_pipewire_add_spa_lib (WpRemotePipewire *self, - const char *factory_regexp, const char *lib) -{ - g_return_if_fail (WP_IS_REMOTE_PIPEWIRE(self)); - - pw_core_add_spa_lib (self->core, factory_regexp, lib); -} - -gpointer -wp_remote_pipewire_load_spa_handle(WpRemotePipewire *self, - const char *factory_name, gconstpointer info) -{ - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE(self), NULL); - - return pw_core_load_spa_handle (self->core, factory_name, info); -} - -gpointer -wp_remote_pipewire_export (WpRemotePipewire *self, guint type, - gpointer props, gpointer object, size_t user_data_size) -{ - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE(self), NULL); - - return pw_remote_export (self->remote, type, props, object, user_data_size); -} - -gpointer -wp_remote_pipewire_module_load (WpRemotePipewire *self, const char *name, - const char *args, gpointer properties) -{ - g_return_val_if_fail (WP_IS_REMOTE_PIPEWIRE(self), NULL); - - return pw_module_load (self->core, name, args, properties); -} diff --git a/lib/wp/remote-pipewire.h b/lib/wp/remote-pipewire.h deleted file mode 100644 index 31fe4591..00000000 --- a/lib/wp/remote-pipewire.h +++ /dev/null @@ -1,45 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_REMOTE_PIPEWIRE_H__ -#define __WIREPLUMBER_REMOTE_PIPEWIRE_H__ - -#include "remote.h" -#include "proxy.h" - -G_BEGIN_DECLS - -#define WP_TYPE_REMOTE_PIPEWIRE (wp_remote_pipewire_get_type ()) -G_DECLARE_FINAL_TYPE (WpRemotePipewire, wp_remote_pipewire, - WP, REMOTE_PIPEWIRE, WpRemote) - -WpRemote *wp_remote_pipewire_new (WpCore *core, GMainContext *context); - -void wp_remote_pipewire_set_default_features ( - WpRemotePipewire * self, GType proxy_type, WpProxyFeatures features); - -WpProxy * wp_remote_pipewire_create_object (WpRemotePipewire *self, - const gchar *factory_name, guint32 interface_type, - guint32 interface_version, WpProperties * properties); - -gpointer wp_remote_pipewire_proxy_bind (WpRemotePipewire *self, guint global_id, - guint global_type); -gpointer wp_remote_pipewire_find_factory (WpRemotePipewire *self, - const char *factory_name); -void wp_remote_pipewire_add_spa_lib (WpRemotePipewire *self, - const char *factory_regexp, const char *lib); -gpointer wp_remote_pipewire_load_spa_handle(WpRemotePipewire *self, - const char *factory_name, gconstpointer info); -gpointer wp_remote_pipewire_export (WpRemotePipewire *self, guint type, - gpointer props, gpointer object, size_t user_data_size); -gpointer wp_remote_pipewire_module_load (WpRemotePipewire *self, - const char *name, const char *args, gpointer properties); - -G_END_DECLS - -#endif diff --git a/lib/wp/remote.c b/lib/wp/remote.c deleted file mode 100644 index a6b18323..00000000 --- a/lib/wp/remote.c +++ /dev/null @@ -1,153 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#include "remote.h" -#include "wpenums.h" - -enum { - PROP_0, - PROP_CORE, - PROP_STATE, - PROP_ERROR_MESSAGE, -}; - -enum { - SIGNAL_STATE_CHANGED, - N_SIGNALS -}; - -static guint signals[N_SIGNALS]; - -typedef struct _WpRemotePrivate WpRemotePrivate; -struct _WpRemotePrivate -{ - GWeakRef core; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (WpRemote, wp_remote, G_TYPE_OBJECT) - -static void -wp_remote_init (WpRemote *self) -{ - WpRemotePrivate *priv = wp_remote_get_instance_private (self); - g_weak_ref_init (&priv->core, NULL); -} - -static void -wp_remote_finalize (GObject *object) -{ - WpRemotePrivate *priv = wp_remote_get_instance_private (WP_REMOTE (object)); - - g_weak_ref_clear (&priv->core); - - g_debug ("%s destroyed", G_OBJECT_TYPE_NAME (object)); - - G_OBJECT_CLASS (wp_remote_parent_class)->finalize (object); -} - -static void -wp_remote_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - WpRemotePrivate *priv = wp_remote_get_instance_private (WP_REMOTE (object)); - - switch (property_id) { - case PROP_CORE: - g_weak_ref_set (&priv->core, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_remote_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpRemotePrivate *priv = wp_remote_get_instance_private (WP_REMOTE (object)); - - switch (property_id) { - case PROP_CORE: - g_value_take_object (value, g_weak_ref_get (&priv->core)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_remote_notify (GObject *object, GParamSpec *param) -{ - if (!g_strcmp0 (param->name, "state")) { - WpRemoteState state; - GParamSpecEnum *param_enum = (GParamSpecEnum *) param; - GEnumValue *value; - GQuark detail; - - g_object_get (object, "state", &state, NULL); - value = g_enum_get_value (param_enum->enum_class, state); - detail = g_quark_from_static_string (value->value_nick); - g_signal_emit (object, signals[SIGNAL_STATE_CHANGED], detail, state); - } - - if (G_OBJECT_CLASS (wp_remote_parent_class)->notify) - G_OBJECT_CLASS (wp_remote_parent_class)->notify (object, param); -} - -static void -wp_remote_class_init (WpRemoteClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - - object_class->finalize = wp_remote_finalize; - object_class->set_property = wp_remote_set_property; - object_class->get_property = wp_remote_get_property; - object_class->notify = wp_remote_notify; - - g_object_class_install_property (object_class, PROP_CORE, - g_param_spec_object ("core", "core", "The wireplumber core", - WP_TYPE_CORE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_enum ("state", "state", "The state of the remote", - WP_TYPE_REMOTE_STATE, WP_REMOTE_STATE_UNCONNECTED, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, PROP_ERROR_MESSAGE, - g_param_spec_string ("error-message", "error-message", - "The last error message of the remote", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - signals[SIGNAL_STATE_CHANGED] = g_signal_new ("state-changed", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_DETAILED | G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, G_TYPE_NONE, 1, WP_TYPE_REMOTE_STATE); -} - -/** - * wp_remote_get_core: - * @self: the remote - * - * Returns: (transfer full): the core of the remote - */ -WpCore * -wp_remote_get_core (WpRemote *self) -{ - WpRemotePrivate *priv = wp_remote_get_instance_private (self); - return g_weak_ref_get (&priv->core); -} - -gboolean -wp_remote_connect (WpRemote *self) -{ - if (WP_REMOTE_GET_CLASS (self)->connect) - return WP_REMOTE_GET_CLASS (self)->connect (self); - return FALSE; -} diff --git a/lib/wp/remote.h b/lib/wp/remote.h deleted file mode 100644 index af39adcc..00000000 --- a/lib/wp/remote.h +++ /dev/null @@ -1,47 +0,0 @@ -/* WirePlumber - * - * Copyright © 2019 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_REMOTE_H__ -#define __WIREPLUMBER_REMOTE_H__ - -#include "core.h" - -G_BEGIN_DECLS - -/** - * 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_REMOTE (wp_remote_get_type ()) -G_DECLARE_DERIVABLE_TYPE (WpRemote, wp_remote, WP, REMOTE, GObject) - -struct _WpRemoteClass -{ - GObjectClass parent_class; - - gboolean (*connect) (WpRemote *self); -}; - -WpCore *wp_remote_get_core (WpRemote *self); -gboolean wp_remote_connect (WpRemote *self); - -G_END_DECLS - -#endif diff --git a/lib/wp/wp.h b/lib/wp/wp.h index f9474a35..863ae2be 100644 --- a/lib/wp/wp.h +++ b/lib/wp/wp.h @@ -18,5 +18,3 @@ #include "proxy-link.h" #include "proxy-node.h" #include "proxy-port.h" -#include "remote.h" -#include "remote-pipewire.h" diff --git a/modules/module-client-permissions.c b/modules/module-client-permissions.c index ea5f4abc..456571f8 100644 --- a/modules/module-client-permissions.c +++ b/modules/module-client-permissions.c @@ -10,7 +10,7 @@ #include static void -client_added (WpRemote * remote, WpProxyClient *client, gpointer data) +client_added (WpCore * core, WpProxyClient *client, gpointer data) { g_autoptr (WpProperties) properties = NULL; const char *access; @@ -30,12 +30,9 @@ client_added (WpRemote * remote, WpProxyClient *client, gpointer data) void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { - WpRemote *remote = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - g_return_if_fail (remote != NULL); + wp_core_set_default_proxy_features (core, WP_TYPE_PROXY_CLIENT, + WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO); - wp_remote_pipewire_set_default_features (WP_REMOTE_PIPEWIRE (remote), - WP_TYPE_PROXY_CLIENT, WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO); - - g_signal_connect(remote, "global-added::client", (GCallback) client_added, - NULL); + g_signal_connect(core, "remote-global-added::client", + (GCallback) client_added, NULL); } diff --git a/modules/module-mixer.c b/modules/module-mixer.c index ccaa9890..f58f373f 100644 --- a/modules/module-mixer.c +++ b/modules/module-mixer.c @@ -298,9 +298,8 @@ mixer_endpoint_class_init (WpMixerEndpointClass * klass) } static void -remote_connected (WpRemote *remote, WpRemoteState state, GVariant *streams) +remote_connected (WpCore *core, WpRemoteState state, GVariant *streams) { - g_autoptr (WpCore) core = wp_remote_get_core (remote); g_autoptr (WpEndpoint) ep = g_object_new (mixer_endpoint_get_type (), "core", core, "name", "Mixer", @@ -313,15 +312,11 @@ remote_connected (WpRemote *remote, WpRemoteState state, GVariant *streams) void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { - WpRemote *remote; GVariant *streams; - remote = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - g_return_if_fail (remote != NULL); - streams = g_variant_lookup_value (args, "streams", G_VARIANT_TYPE ("as")); - g_signal_connect_data (remote, "state-changed::connected", + g_signal_connect_data (core, "remote-state-changed::connected", (GCallback) remote_connected, streams, (GClosureNotify) g_variant_unref, 0); } diff --git a/modules/module-pipewire.c b/modules/module-pipewire.c index 89356c60..9d16f19b 100644 --- a/modules/module-pipewire.c +++ b/modules/module-pipewire.c @@ -23,20 +23,10 @@ void simple_endpoint_link_factory (WpFactory * factory, GType type, void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { - WpRemotePipewire *rp; + struct pw_core *pw_core = wp_core_get_pw_core (core); - /* Get the remote pipewire */ - rp = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - if (!rp) { - g_critical ("module-pipewire cannot be loaded without a registered " - "WpRemotePipewire object"); - return; - } - - /* Load the client-device and adapter modules */ - wp_remote_pipewire_module_load(rp, "libpipewire-module-client-device", NULL, - NULL); - wp_remote_pipewire_module_load(rp, "libpipewire-module-adapter", NULL, NULL); + pw_module_load (pw_core, "libpipewire-module-client-device", NULL, NULL); + pw_module_load (pw_core, "libpipewire-module-adapter", NULL, NULL); /* Register simple-endpoint and simple-endpoint-link */ wp_factory_new (core, "pipewire-simple-endpoint", diff --git a/modules/module-pipewire/simple-endpoint-link.c b/modules/module-pipewire/simple-endpoint-link.c index ed636d24..0fe5a3c4 100644 --- a/modules/module-pipewire/simple-endpoint-link.c +++ b/modules/module-pipewire/simple-endpoint-link.c @@ -167,7 +167,6 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data, { WpPipewireSimpleEndpointLink *self = WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK(epl); g_autoptr (WpCore) core = NULL; - WpRemotePipewire *remote_pipewire; guint32 output_node_id, input_node_id; GVariant *src_ports, *sink_ports; GVariantIter *out_iter, *in_iter; @@ -179,10 +178,6 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data, core = g_weak_ref_get (&self->core); g_return_val_if_fail (core, FALSE); - /* Get the remote pipewire */ - remote_pipewire = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - g_return_val_if_fail (remote_pipewire, FALSE); - /* Get the node ids and port ids */ if (!g_variant_lookup (src_data, "node-id", "u", &output_node_id)) return FALSE; @@ -226,7 +221,7 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data, wp_properties_setf(props, PW_KEY_LINK_INPUT_PORT, "%d", in_id); /* Create the link */ - proxy = wp_remote_pipewire_create_object(remote_pipewire, "link-factory", + proxy = wp_core_create_remote_object(core, "link-factory", PW_TYPE_INTERFACE_Link, PW_VERSION_LINK_PROXY, props); g_return_val_if_fail (proxy, FALSE); g_ptr_array_add(self->link_proxies, proxy); diff --git a/modules/module-pipewire/simple-endpoint.c b/modules/module-pipewire/simple-endpoint.c index 7f282969..953290ae 100644 --- a/modules/module-pipewire/simple-endpoint.c +++ b/modules/module-pipewire/simple-endpoint.c @@ -32,9 +32,6 @@ struct _WpPipewireSimpleEndpoint /* The task to signal the endpoint is initialized */ GTask *init_task; - /* The remote pipewire */ - WpRemotePipewire *remote_pipewire; - /* Proxies */ WpProxyNode *proxy_node; GPtrArray *proxies_port; @@ -175,7 +172,7 @@ on_proxy_port_augmented (WpProxy *proxy, GAsyncResult *res, } static void -on_port_added(WpRemotePipewire *rp, WpProxy *proxy, gpointer d) +on_port_added (WpCore *core, WpProxy *proxy, gpointer d) { WpPipewireSimpleEndpoint *self = d; const char *s; @@ -287,10 +284,8 @@ wp_simple_endpoint_init_async (GAsyncInitable *initable, int io_priority, self->init_task = g_task_new (initable, cancellable, callback, data); /* Register a port_added callback */ - self->remote_pipewire = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - g_return_if_fail(self->remote_pipewire); - g_signal_connect_object(self->remote_pipewire, "global-added::port", - (GCallback)on_port_added, self, 0); + g_signal_connect_object (core, "remote-global-added::port", + (GCallback) on_port_added, self, 0); /* Augment to get the info */ wp_proxy_augment (WP_PROXY (self->proxy_node), diff --git a/modules/module-pw-alsa-udev.c b/modules/module-pw-alsa-udev.c index 191880c0..e51645c7 100644 --- a/modules/module-pw-alsa-udev.c +++ b/modules/module-pw-alsa-udev.c @@ -26,7 +26,6 @@ struct monitor { struct impl { WpModule *module; - WpRemotePipewire *remote_pipewire; GHashTable *registered_endpoints; GVariant *streams; @@ -171,9 +170,8 @@ is_alsa_node (WpProperties * props) } static void -on_node_added(WpRemotePipewire *rp, WpProxy *proxy, struct impl *impl) +on_node_added(WpCore *core, WpProxy *proxy, struct impl *impl) { - g_autoptr (WpCore) core = wp_module_get_core (impl->module); const gchar *media_class, *name; enum pw_direction direction; GVariantBuilder b; @@ -214,7 +212,7 @@ on_node_added(WpRemotePipewire *rp, WpProxy *proxy, struct impl *impl) } static void -on_global_removed (WpRemotePipewire *rp, WpProxy *proxy, struct impl *impl) +on_node_removed (WpCore *core, WpProxy *proxy, struct impl *impl) { WpEndpoint *endpoint = NULL; guint32 id = wp_proxy_get_global_id (proxy); @@ -237,6 +235,7 @@ create_node(struct impl *impl, struct device *dev, uint32_t id, struct node *node; const char *name; g_autoptr (WpProperties) props = NULL; + g_autoptr (WpCore) core = wp_module_get_core (impl->module); /* Check if the type is a node */ if (info->type != SPA_TYPE_INTERFACE_Node) @@ -264,8 +263,8 @@ create_node(struct impl *impl, struct device *dev, uint32_t id, node->impl = impl; node->device = dev; node->id = id; - node->proxy = wp_remote_pipewire_create_object (impl->remote_pipewire, - "adapter", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props); + node->proxy = wp_core_create_remote_object (core, "adapter", + PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props); if (!node->proxy) { g_slice_free (struct node, node); return NULL; @@ -348,8 +347,9 @@ static const struct spa_device_events device_events = { static struct device* create_device(struct impl *impl, uint32_t id, - const struct spa_monitor_object_info *info) { - + const struct spa_monitor_object_info *info) +{ + g_autoptr (WpCore) core = wp_module_get_core (impl->module); struct device *dev; struct spa_handle *handle; int res; @@ -360,8 +360,8 @@ create_device(struct impl *impl, uint32_t id, return NULL; /* Load the device handle */ - handle = (struct spa_handle *)wp_remote_pipewire_load_spa_handle ( - impl->remote_pipewire, info->factory_name, info->props); + handle = pw_core_load_spa_handle (wp_core_get_pw_core (core), + info->factory_name, info->props); if (!handle) return NULL; @@ -379,7 +379,8 @@ create_device(struct impl *impl, uint32_t id, dev->handle = handle; dev->device = iface; dev->props = pw_properties_new_dict(info->props); - dev->proxy = wp_remote_pipewire_export (impl->remote_pipewire, info->type, dev->props, dev->device, 0); + dev->proxy = pw_remote_export (wp_core_get_pw_remote (core), + info->type, dev->props, dev->device, 0); if (!dev->proxy) { pw_unload_spa_handle(handle); return NULL; @@ -482,7 +483,7 @@ static const struct spa_monitor_callbacks monitor_callbacks = }; static void -start_monitor (WpRemotePipewire *remote, WpRemoteState state, gpointer data) +start_monitor (WpCore *core, WpRemoteState state, gpointer data) { struct impl *impl = data; struct spa_handle *handle; @@ -490,8 +491,8 @@ start_monitor (WpRemotePipewire *remote, WpRemoteState state, gpointer data) void *iface; /* Load the monitor handle */ - handle = (struct spa_handle *)wp_remote_pipewire_load_spa_handle ( - impl->remote_pipewire, SPA_NAME_API_ALSA_MONITOR, NULL); + handle = pw_core_load_spa_handle (wp_core_get_pw_core (core), + SPA_NAME_API_ALSA_MONITOR, NULL); g_return_if_fail (handle); /* Get the handle interface */ @@ -516,9 +517,8 @@ module_destroy (gpointer data) { struct impl *impl = data; - /* Set to NULL module and remote pipewire as we don't own the reference */ + /* Set to NULL as we don't own the reference */ impl->module = NULL; - impl->remote_pipewire = NULL; /* Destroy the registered endpoints table */ g_hash_table_unref(impl->registered_endpoints); @@ -534,20 +534,10 @@ void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { struct impl *impl; - WpRemotePipewire *rp; - - /* Make sure the remote pipewire is valid */ - rp = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - if (!rp) { - g_critical ("module-pw-alsa-udev cannot be loaded without a registered " - "WpRemotePipewire object"); - return; - } /* Create the module data */ impl = g_slice_new0(struct impl); impl->module = module; - impl->remote_pipewire = rp; impl->registered_endpoints = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref); impl->streams = g_variant_lookup_value (args, "streams", @@ -557,12 +547,16 @@ wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) wp_module_set_destroy_callback (module, module_destroy, impl); /* Add the spa lib */ - wp_remote_pipewire_add_spa_lib (rp, "api.alsa.*", "alsa/libspa-alsa"); + pw_core_add_spa_lib (wp_core_get_pw_core (core), + "api.alsa.*", "alsa/libspa-alsa"); /* Start the monitor when the connected callback is triggered */ - g_signal_connect(rp, "state-changed::connected", (GCallback)start_monitor, impl); + g_signal_connect(core, "remote-state-changed::connected", + (GCallback) start_monitor, impl); /* Register the global addded/removed callbacks */ - g_signal_connect(rp, "global-added::node", (GCallback)on_node_added, impl); - g_signal_connect(rp, "global-removed", (GCallback)on_global_removed, impl); + g_signal_connect(core, "remote-global-added::node", + (GCallback) on_node_added, impl); + g_signal_connect(core, "remote-global-removed::node", + (GCallback) on_node_removed, impl); } diff --git a/modules/module-pw-audio-client.c b/modules/module-pw-audio-client.c index 2e30a9ea..089d4eb5 100644 --- a/modules/module-pw-audio-client.c +++ b/modules/module-pw-audio-client.c @@ -16,8 +16,6 @@ struct module_data { - WpModule *module; - WpRemotePipewire *remote_pipewire; GHashTable *registered_endpoints; }; @@ -50,10 +48,9 @@ on_endpoint_created(GObject *initable, GAsyncResult *res, gpointer d) } static void -on_node_added (WpRemotePipewire *rp, WpProxy *proxy, gpointer d) +on_node_added (WpCore *core, WpProxy *proxy, gpointer d) { struct module_data *data = d; - g_autoptr (WpCore) core = wp_module_get_core (data->module); const gchar *name, *media_class; enum pw_direction direction; GVariantBuilder b; @@ -103,7 +100,7 @@ on_node_added (WpRemotePipewire *rp, WpProxy *proxy, gpointer d) } static void -on_global_removed (WpRemotePipewire *rp, WpProxy *proxy, gpointer d) +on_node_removed (WpCore *core, WpProxy *proxy, gpointer d) { struct module_data *data = d; WpEndpoint *endpoint = NULL; @@ -125,10 +122,6 @@ module_destroy (gpointer d) { struct module_data *data = d; - /* Set to NULL module and remote pipewire as we don't own the reference */ - data->module = NULL; - data->remote_pipewire = NULL; - /* Destroy the registered endpoints table */ g_clear_pointer (&data->registered_endpoints, g_hash_table_unref); @@ -140,20 +133,9 @@ void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { struct module_data *data; - WpRemotePipewire *rp; - - /* Make sure the remote pipewire is valid */ - rp = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - if (!rp) { - g_critical ("module-pipewire cannot be loaded without a registered " - "WpRemotePipewire object"); - return; - } /* Create the module data */ data = g_slice_new0 (struct module_data); - data->module = module; - data->remote_pipewire = rp; data->registered_endpoints = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref); @@ -161,6 +143,8 @@ wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) wp_module_set_destroy_callback (module, module_destroy, data); /* Register the global added/removed callbacks */ - g_signal_connect(rp, "global-added::node", (GCallback)on_node_added, data); - g_signal_connect(rp, "global-removed", (GCallback)on_global_removed, data); + g_signal_connect(core, "remote-global-added::node", + (GCallback) on_node_added, data); + g_signal_connect(core, "remote-global-removed::node", + (GCallback) on_node_removed, data); } diff --git a/modules/module-pw-audio-softdsp-endpoint/convert.c b/modules/module-pw-audio-softdsp-endpoint/convert.c index fd0f8bef..5c41d235 100644 --- a/modules/module-pw-audio-softdsp-endpoint/convert.c +++ b/modules/module-pw-audio-softdsp-endpoint/convert.c @@ -41,7 +41,7 @@ G_DEFINE_TYPE_WITH_CODE (WpAudioConvert, wp_audio_convert, WP_TYPE_AUDIO_STREAM, static void on_audio_convert_running(WpAudioConvert *self) { - WpRemotePipewire *rp = wp_audio_stream_get_remote (WP_AUDIO_STREAM (self)); + g_autoptr (WpCore) core = wp_audio_stream_get_core (WP_AUDIO_STREAM (self)); enum pw_direction direction = wp_audio_stream_get_direction (WP_AUDIO_STREAM (self)); g_autoptr (WpProperties) props = NULL; @@ -77,7 +77,7 @@ on_audio_convert_running(WpAudioConvert *self) g_debug ("%p linking audio convert to target", self); /* Create the link */ - self->link_proxy = wp_remote_pipewire_create_object (rp, "link-factory", + self->link_proxy = wp_core_create_remote_object (core, "link-factory", PW_TYPE_INTERFACE_Link, PW_VERSION_LINK_PROXY, props); } @@ -150,8 +150,7 @@ wp_audio_convert_init_async (GAsyncInitable *initable, int io_priority, WpAudioConvert *self = WP_AUDIO_CONVERT (initable); g_autoptr (WpProxy) proxy = NULL; g_autoptr (WpProperties) props = NULL; - WpRemotePipewire *remote = - wp_audio_stream_get_remote (WP_AUDIO_STREAM (self)); + g_autoptr (WpCore) core = wp_audio_stream_get_core (WP_AUDIO_STREAM (self)); /* Create the properties */ props = wp_properties_copy (wp_proxy_node_get_properties (self->target)); @@ -161,7 +160,7 @@ wp_audio_convert_init_async (GAsyncInitable *initable, int io_priority, wp_properties_set (props, "factory.name", SPA_NAME_AUDIO_CONVERT); /* Create the proxy */ - proxy = wp_remote_pipewire_create_object (remote, "spa-node-factory", + proxy = wp_core_create_remote_object (core, "spa-node-factory", PW_TYPE_INTERFACE_Node, PW_VERSION_NODE_PROXY, props); g_return_if_fail (proxy); diff --git a/modules/module-pw-audio-softdsp-endpoint/stream.c b/modules/module-pw-audio-softdsp-endpoint/stream.c index 97303663..01994591 100644 --- a/modules/module-pw-audio-softdsp-endpoint/stream.c +++ b/modules/module-pw-audio-softdsp-endpoint/stream.c @@ -151,8 +151,7 @@ on_port_config_done (WpProxy *proxy, GAsyncResult *res, WpAudioStream *self) /* called multiple times after we set the PortConfig */ static void -on_audio_stream_port_added(WpRemotePipewire *rp, WpProxy *proxy, - WpAudioStream *self) +on_audio_stream_port_added (WpCore *core, WpProxy *proxy, WpAudioStream *self) { WpAudioStreamPrivate *priv = wp_audio_stream_get_instance_private (self); g_autoptr (WpProperties) props = wp_proxy_get_global_properties (proxy); @@ -326,6 +325,7 @@ wp_audio_stream_init_async (GAsyncInitable *initable, int io_priority, WpAudioStream *self = WP_AUDIO_STREAM(initable); WpAudioStreamPrivate *priv = wp_audio_stream_get_instance_private (self); g_autoptr (WpEndpoint) ep = g_weak_ref_get (&priv->endpoint); + g_autoptr (WpCore) core = wp_audio_stream_get_core (self); GVariantDict d; g_debug ("WpEndpoint:%p init stream %s (%s:%p)", ep, priv->name, @@ -362,8 +362,8 @@ wp_audio_stream_init_async (GAsyncInitable *initable, int io_priority, (GAsyncReadyCallback) on_node_proxy_augmented, self); /* Register a port_added callback */ - g_signal_connect_object(wp_audio_stream_get_remote (self), - "global-added::port", (GCallback)on_audio_stream_port_added, self, 0); + g_signal_connect_object(core, "remote-global-added::port", + (GCallback) on_audio_stream_port_added, self, 0); } static gboolean @@ -560,8 +560,8 @@ wp_audio_stream_set_control_value (WpAudioStream * self, guint32 control_id, return TRUE; } -WpRemotePipewire * -wp_audio_stream_get_remote (WpAudioStream * self) +WpCore * +wp_audio_stream_get_core (WpAudioStream * self) { WpAudioStreamPrivate *priv = wp_audio_stream_get_instance_private (self); g_autoptr (WpEndpoint) ep = NULL; @@ -569,9 +569,7 @@ wp_audio_stream_get_remote (WpAudioStream * self) ep = g_weak_ref_get (&priv->endpoint); core = wp_endpoint_get_core (ep); - - /* FIXME this is theoretically not safe */ - return wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); + return g_steal_pointer (&core); } void diff --git a/modules/module-pw-audio-softdsp-endpoint/stream.h b/modules/module-pw-audio-softdsp-endpoint/stream.h index 9d1e9af3..a2539b06 100644 --- a/modules/module-pw-audio-softdsp-endpoint/stream.h +++ b/modules/module-pw-audio-softdsp-endpoint/stream.h @@ -41,7 +41,7 @@ gboolean wp_audio_stream_set_control_value (WpAudioStream * self, /* for subclasses */ -WpRemotePipewire *wp_audio_stream_get_remote (WpAudioStream * self); +WpCore *wp_audio_stream_get_core (WpAudioStream * self); void wp_audio_stream_init_task_finish (WpAudioStream * self, GError * error); void wp_audio_stream_set_port_config (WpAudioStream * self, const struct spa_pod * param); diff --git a/modules/module-pw-bluez.c b/modules/module-pw-bluez.c index e53af151..a86dfd35 100644 --- a/modules/module-pw-bluez.c +++ b/modules/module-pw-bluez.c @@ -31,7 +31,6 @@ struct monitor { struct impl { WpModule *module; - WpRemotePipewire *remote_pipewire; GHashTable *registered_endpoints; /* The bluez monitor */ @@ -204,9 +203,8 @@ is_bluez_node (WpProperties *props) } static void -on_node_added (WpRemotePipewire *rp, WpProxy *proxy, struct impl *data) +on_node_added (WpCore *core, WpProxy *proxy, struct impl *data) { - g_autoptr (WpCore) core = wp_module_get_core (data->module); const gchar *name, *media_class; enum pw_direction direction; GVariantBuilder b; @@ -246,7 +244,7 @@ on_node_added (WpRemotePipewire *rp, WpProxy *proxy, struct impl *data) } static void -on_global_removed (WpRemotePipewire *rp, WpProxy *proxy, struct impl *data) +on_node_removed (WpCore *core, WpProxy *proxy, struct impl *data) { WpEndpoint *endpoint = NULL; guint32 id = wp_proxy_get_global_id (proxy); @@ -266,6 +264,7 @@ static struct node * create_node(struct impl *impl, struct device *dev, uint32_t id, const struct spa_device_object_info *info) { + g_autoptr (WpCore) core = wp_module_get_core (impl->module); struct node *node; const char *name, *profile; struct pw_properties *props = NULL; @@ -293,7 +292,7 @@ create_node(struct impl *impl, struct device *dev, uint32_t id, profile = "null"; /* Find the factory */ - factory = wp_remote_pipewire_find_factory(impl->remote_pipewire, "adapter"); + factory = pw_core_find_factory (wp_core_get_pw_core (core), "adapter"); g_return_val_if_fail (factory, NULL); /* Create the properties */ @@ -317,7 +316,7 @@ create_node(struct impl *impl, struct device *dev, uint32_t id, node->id = id; node->props = props; node->adapter = adapter; - node->proxy = wp_remote_pipewire_export(impl->remote_pipewire, + node->proxy = pw_remote_export (wp_core_get_pw_remote (core), PW_TYPE_INTERFACE_Node, props, adapter, 0); if (!node->proxy) { pw_properties_free(props); @@ -396,8 +395,9 @@ static const struct spa_device_events device_events = { static struct device* create_device(struct impl *impl, uint32_t id, - const struct spa_monitor_object_info *info) { - + const struct spa_monitor_object_info *info) +{ + g_autoptr (WpCore) core = wp_module_get_core (impl->module); struct device *dev; struct spa_handle *handle; int res; @@ -408,8 +408,8 @@ create_device(struct impl *impl, uint32_t id, return NULL; /* Load the device handle */ - handle = (struct spa_handle *)wp_remote_pipewire_load_spa_handle ( - impl->remote_pipewire, info->factory_name, info->props); + handle = pw_core_load_spa_handle (wp_core_get_pw_core (core), + info->factory_name, info->props); if (!handle) return NULL; @@ -427,7 +427,8 @@ create_device(struct impl *impl, uint32_t id, dev->handle = handle; dev->device = iface; dev->props = pw_properties_new_dict(info->props); - dev->proxy = wp_remote_pipewire_export (impl->remote_pipewire, info->type, dev->props, dev->device, 0); + dev->proxy = pw_remote_export (wp_core_get_pw_remote (core), + info->type, dev->props, dev->device, 0); if (!dev->proxy) { pw_unload_spa_handle(handle); return NULL; @@ -526,7 +527,7 @@ static const struct spa_monitor_callbacks monitor_callbacks = }; static void -start_monitor (WpRemotePipewire *remote, WpRemoteState state, gpointer data) +start_monitor (WpCore *core, WpRemoteState state, gpointer data) { struct impl *impl = data; struct spa_handle *handle; @@ -534,8 +535,8 @@ start_monitor (WpRemotePipewire *remote, WpRemoteState state, gpointer data) void *iface; /* Load the monitor handle */ - handle = (struct spa_handle *)wp_remote_pipewire_load_spa_handle ( - impl->remote_pipewire, SPA_NAME_API_BLUEZ5_MONITOR, NULL); + handle = pw_core_load_spa_handle (wp_core_get_pw_core (core), + SPA_NAME_API_BLUEZ5_MONITOR, NULL); if (!handle) { g_message ("SPA bluez5 plugin could not be loaded; is it installed?"); return; @@ -563,9 +564,8 @@ module_destroy (gpointer data) { struct impl *impl = data; - /* Set to NULL module and remote pipewire as we don't own the reference */ + /* Set to NULL as we don't own the reference */ impl->module = NULL; - impl->remote_pipewire = NULL; /* Destroy the registered endpoints table */ g_hash_table_unref(impl->registered_endpoints); @@ -579,20 +579,10 @@ void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { struct impl *impl; - WpRemotePipewire *rp; - - /* Make sure the remote pipewire is valid */ - rp = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); - if (!rp) { - g_critical ("module-pw-bluez cannot be loaded without a registered " - "WpRemotePipewire object"); - return; - } /* Create the module data */ impl = g_slice_new0(struct impl); impl->module = module; - impl->remote_pipewire = rp; impl->registered_endpoints = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_object_unref); @@ -600,12 +590,16 @@ wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) wp_module_set_destroy_callback (module, module_destroy, impl); /* Add the spa lib */ - wp_remote_pipewire_add_spa_lib (rp, "api.bluez5.*", "bluez5/libspa-bluez5"); + pw_core_add_spa_lib (wp_core_get_pw_core (core), + "api.bluez5.*", "bluez5/libspa-bluez5"); /* Start the monitor when the connected callback is triggered */ - g_signal_connect(rp, "state-changed::connected", (GCallback)start_monitor, impl); + g_signal_connect(core, "remote-state-changed::connected", + (GCallback) start_monitor, impl); - /* Register the global added/removed callbacks */ - g_signal_connect(rp, "global-added::node", (GCallback)on_node_added, impl); - g_signal_connect(rp, "global-removed", (GCallback)on_global_removed, impl); + /* Register the global addded/removed callbacks */ + g_signal_connect(core, "remote-global-added::node", + (GCallback) on_node_added, impl); + g_signal_connect(core, "remote-global-removed::node", + (GCallback) on_node_removed, impl); } diff --git a/src/main.c b/src/main.c index a52b22cc..494bc014 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,6 @@ enum WpExitCode struct WpDaemonData { WpCore *core; - WpRemote *remote; GMainLoop *loop; gint exit_code; @@ -67,7 +66,7 @@ signal_handler (gpointer data) } static void -remote_state_changed (WpRemote *remote, WpRemoteState state, +remote_state_changed (WpCore *core, WpRemoteState state, struct WpDaemonData * d) { /* something else triggered the exit; we will certainly get a state @@ -82,7 +81,7 @@ remote_state_changed (WpRemote *remote, WpRemoteState state, break; case WP_REMOTE_STATE_ERROR: { g_autofree gchar *error; - g_object_get (remote, "error-message", &error, NULL); + g_object_get (core, "error-message", &error, NULL); daemon_exit (d, WP_CODE_OPERATION_FAILED, "pipewire remote error: %s", error); break; @@ -240,7 +239,7 @@ load_commands_file (struct WpDaemonData *d) } /* connect to pipewire */ - wp_remote_connect (d->remote); + wp_core_connect (d->core); return G_SOURCE_REMOVE; } @@ -251,7 +250,6 @@ main (gint argc, gchar **argv) struct WpDaemonData data = {0}; g_autoptr (GOptionContext) context = NULL; g_autoptr (GError) error = NULL; - g_autoptr (WpRemote) remote = NULL; g_autoptr (WpCore) core = NULL; g_autoptr (GMainLoop) loop = NULL; @@ -265,10 +263,9 @@ main (gint argc, gchar **argv) /* init wireplumber */ - data.core = core = wp_core_new (); - data.remote = remote = wp_remote_pipewire_new (core, NULL); - g_signal_connect (remote, "state-changed", (GCallback) remote_state_changed, - &data); + data.core = core = wp_core_new (NULL); + g_signal_connect (core, "remote-state-changed", + (GCallback) remote_state_changed, &data); /* init main loop */ diff --git a/tests/proxy.c b/tests/proxy.c index e8ccdc95..6e317359 100644 --- a/tests/proxy.c +++ b/tests/proxy.c @@ -20,9 +20,8 @@ typedef struct { GMainLoop *loop; GSource *timeout_source; - /* the client wireplumber objects */ + /* the client wireplumber core */ WpCore *core; - WpRemote *remote; } TestProxyFixture; @@ -37,14 +36,14 @@ timeout_callback (TestProxyFixture *fixture) } static void -test_proxy_state_changed (WpRemote *remote, WpRemoteState state, +test_proxy_remote_state_changed (WpCore *core, WpRemoteState state, TestProxyFixture *fixture) { - g_autofree gchar * msg = NULL; + const gchar * msg = NULL; switch (state) { case WP_REMOTE_STATE_ERROR: - g_object_get (remote, "error-message", &msg, NULL); + wp_core_get_remote_state (core, &msg); g_message ("remote error: %s", msg); g_test_fail (); g_main_loop_quit (fixture->loop); @@ -61,14 +60,13 @@ test_proxy_setup (TestProxyFixture *self, gconstpointer user_data) g_setenv ("PIPEWIRE_REMOTE", self->server.name, TRUE); self->context = g_main_context_new (); self->loop = g_main_loop_new (self->context, FALSE); - self->core = wp_core_new (); - self->remote = wp_remote_pipewire_new (self->core, self->context); + self->core = wp_core_new (self->context); g_main_context_push_thread_default (self->context); /* watchdogs */ - g_signal_connect (self->remote, "state-changed", - (GCallback) test_proxy_state_changed, self); + g_signal_connect (self->core, "remote-state-changed", + (GCallback) test_proxy_remote_state_changed, self); self->timeout_source = g_timeout_source_new_seconds (3); g_source_set_callback (self->timeout_source, (GSourceFunc) timeout_callback, @@ -81,7 +79,6 @@ test_proxy_teardown (TestProxyFixture *self, gconstpointer user_data) { g_main_context_pop_thread_default (self->context); - g_clear_object (&self->remote); g_clear_object (&self->core); g_clear_pointer (&self->timeout_source, g_source_unref); g_clear_pointer (&self->loop, g_main_loop_unref); @@ -117,13 +114,14 @@ test_proxy_basic_augmented (WpProxy *proxy, GAsyncResult *res, } static void -test_proxy_basic_global_added (WpRemote *remote, WpProxy *proxy, +test_proxy_basic_remote_global_added (WpCore *core, WpProxy *proxy, TestProxyFixture *fixture) { g_assert_nonnull (proxy); { - g_autoptr (WpRemote) remote = wp_proxy_get_remote (proxy); - g_assert_nonnull (remote); + g_autoptr (WpCore) pcore = wp_proxy_get_core (proxy); + g_assert_nonnull (pcore); + g_assert_true (pcore == core); } g_assert_cmpuint (wp_proxy_get_global_id (proxy), !=, 0); g_assert_true (wp_proxy_is_global (proxy)); @@ -155,10 +153,10 @@ test_proxy_basic (TestProxyFixture *fixture, gconstpointer data) { /* our test server should advertise exactly one * client: our WpRemote; use this to test WpProxy */ - g_signal_connect (fixture->remote, "global-added::client", - (GCallback) test_proxy_basic_global_added, fixture); + g_signal_connect (fixture->core, "remote-global-added::client", + (GCallback) test_proxy_basic_remote_global_added, fixture); - g_assert_true (wp_remote_connect (fixture->remote)); + g_assert_true (wp_core_connect (fixture->core)); g_main_loop_run (fixture->loop); } @@ -199,7 +197,7 @@ test_proxy_node_enum_params_done (WpProxyNode *node, GAsyncResult *res, } static void -test_proxy_node_global_added (WpRemote *remote, WpProxy *proxy, +test_proxy_node_remote_global_added (WpCore *core, WpProxy *proxy, TestProxyFixture *fixture) { const struct pw_node_info *info; @@ -256,14 +254,14 @@ test_proxy_node (TestProxyFixture *fixture, gconstpointer data) pw_thread_loop_unlock (fixture->server.thread_loop); /* we should be able to see this exported audiotestsrc node on the client */ - g_signal_connect (fixture->remote, "global-added::node", - (GCallback) test_proxy_node_global_added, fixture); + g_signal_connect (fixture->core, "remote-global-added::node", + (GCallback) test_proxy_node_remote_global_added, fixture); /* tell the remote to call global-added only when these features are ready */ - wp_remote_pipewire_set_default_features (WP_REMOTE_PIPEWIRE (fixture->remote), + wp_core_set_default_proxy_features (fixture->core, WP_TYPE_PROXY_NODE, WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO); - g_assert_true (wp_remote_connect (fixture->remote)); + g_assert_true (wp_core_connect (fixture->core)); g_main_loop_run (fixture->loop); }