lib: remove the session-manager object and register endpoints as globals
This commit is contained in:
@@ -88,12 +88,6 @@
|
||||
#include "error.h"
|
||||
#include "factory.h"
|
||||
|
||||
/* private api in session-manager */
|
||||
void wp_session_manager_add_endpoint (WpSessionManager * self,
|
||||
WpEndpoint * ep);
|
||||
void wp_session_manager_remove_endpoint (WpSessionManager * self,
|
||||
WpEndpoint * ep);
|
||||
|
||||
typedef struct _WpEndpointPrivate WpEndpointPrivate;
|
||||
struct _WpEndpointPrivate
|
||||
{
|
||||
@@ -102,7 +96,7 @@ struct _WpEndpointPrivate
|
||||
GPtrArray *streams;
|
||||
GPtrArray *controls;
|
||||
GPtrArray *links;
|
||||
GWeakRef sm;
|
||||
WpCore *core;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -125,7 +119,6 @@ wp_endpoint_init (WpEndpoint * self)
|
||||
{
|
||||
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
|
||||
|
||||
g_weak_ref_init (&priv->sm, NULL);
|
||||
priv->streams =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_unref);
|
||||
priv->controls =
|
||||
@@ -155,7 +148,6 @@ wp_endpoint_finalize (GObject * object)
|
||||
WpEndpointPrivate *priv =
|
||||
wp_endpoint_get_instance_private (WP_ENDPOINT (object));
|
||||
|
||||
g_weak_ref_clear (&priv->sm);
|
||||
g_ptr_array_unref (priv->streams);
|
||||
g_ptr_array_unref (priv->controls);
|
||||
g_ptr_array_unref (priv->links);
|
||||
@@ -246,25 +238,26 @@ wp_endpoint_class_init (WpEndpointClass * klass)
|
||||
/**
|
||||
* wp_endpoint_register:
|
||||
* @self: the endpoint
|
||||
* @sm: the session manager
|
||||
* @core: the core
|
||||
*
|
||||
* Registers the endpoint on the @sm.
|
||||
* Registers the endpoint on the @core.
|
||||
*/
|
||||
void
|
||||
wp_endpoint_register (WpEndpoint * self, WpSessionManager * sm)
|
||||
wp_endpoint_register (WpEndpoint * self, WpCore * core)
|
||||
{
|
||||
WpEndpointPrivate *priv;
|
||||
|
||||
g_return_if_fail (WP_IS_ENDPOINT (self));
|
||||
g_return_if_fail (WP_IS_SESSION_MANAGER (sm));
|
||||
g_return_if_fail (WP_IS_CORE (core));
|
||||
|
||||
priv = wp_endpoint_get_instance_private (self);
|
||||
|
||||
g_info ("WpEndpoint:%p registering '%s' (%s)", self, priv->name,
|
||||
priv->media_class);
|
||||
|
||||
g_weak_ref_set (&priv->sm, sm);
|
||||
wp_session_manager_add_endpoint (sm, self);
|
||||
priv->core = core;
|
||||
wp_core_register_global (core, WP_GLOBAL_ENDPOINT, g_object_ref (self),
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,21 +271,83 @@ void
|
||||
wp_endpoint_unregister (WpEndpoint * self)
|
||||
{
|
||||
WpEndpointPrivate *priv;
|
||||
g_autoptr (WpSessionManager) sm = NULL;
|
||||
|
||||
g_return_if_fail (WP_IS_ENDPOINT (self));
|
||||
|
||||
priv = wp_endpoint_get_instance_private (self);
|
||||
sm = g_weak_ref_get (&priv->sm);
|
||||
if (sm) {
|
||||
if (priv->core) {
|
||||
g_info ("WpEndpoint:%p unregistering '%s' (%s)", self, priv->name,
|
||||
priv->media_class);
|
||||
|
||||
g_weak_ref_set (&priv->sm, NULL);
|
||||
wp_session_manager_remove_endpoint (sm, self);
|
||||
priv->core = NULL;
|
||||
wp_core_remove_global (priv->core, WP_GLOBAL_ENDPOINT, self);
|
||||
}
|
||||
}
|
||||
|
||||
struct endpoints_foreach_data
|
||||
{
|
||||
GPtrArray *result;
|
||||
const gchar *lookup;
|
||||
};
|
||||
|
||||
static inline gboolean
|
||||
media_class_matches (const gchar * media_class, const gchar * lookup)
|
||||
{
|
||||
const gchar *c1 = media_class, *c2 = lookup;
|
||||
|
||||
/* empty lookup matches all classes */
|
||||
if (!lookup)
|
||||
return TRUE;
|
||||
|
||||
/* compare until we reach the end of the lookup string */
|
||||
for (; *c2 != '\0'; c1++, c2++) {
|
||||
if (*c1 != *c2)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the lookup may not end in a slash, however it must match up
|
||||
* to the end of a submedia_class. i.e.:
|
||||
* match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Source
|
||||
*
|
||||
* NO match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Sou
|
||||
*
|
||||
* if *c1 is not /, also check the previous char, because the lookup
|
||||
* may actually end in a slash:
|
||||
*
|
||||
* match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Source/
|
||||
*/
|
||||
if (!(*c1 == '/' || *c1 == '\0' || *(c1 - 1) == '/'))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_endpoints (GQuark key, gpointer global, gpointer user_data)
|
||||
{
|
||||
struct endpoints_foreach_data * data = user_data;
|
||||
|
||||
if (key == WP_GLOBAL_ENDPOINT &&
|
||||
media_class_matches (wp_endpoint_get_media_class (WP_ENDPOINT (global)),
|
||||
data->lookup))
|
||||
g_ptr_array_add (data->result, g_object_ref (global));
|
||||
|
||||
return WP_CORE_FOREACH_GLOBAL_CONTINUE;
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
wp_endpoint_find (WpCore * core, const gchar * media_class_lookup)
|
||||
{
|
||||
struct endpoints_foreach_data data;
|
||||
data.result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
data.lookup = media_class_lookup;
|
||||
wp_core_foreach_global (core, find_endpoints, &data);
|
||||
return data.result;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
wp_endpoint_get_name (WpEndpoint * self)
|
||||
{
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#define __WIREPLUMBER_ENDPOINT_H__
|
||||
|
||||
#include "core.h"
|
||||
#include "session-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -35,8 +34,9 @@ struct _WpEndpointClass
|
||||
const gchar * (*get_endpoint_link_factory) (WpEndpoint * self);
|
||||
};
|
||||
|
||||
void wp_endpoint_register (WpEndpoint * self, WpSessionManager * sm);
|
||||
void wp_endpoint_register (WpEndpoint * self, WpCore * core);
|
||||
void wp_endpoint_unregister (WpEndpoint * self);
|
||||
GPtrArray * wp_endpoint_find (WpCore * core, const gchar * media_class_lookup);
|
||||
|
||||
const gchar * wp_endpoint_get_name (WpEndpoint * self);
|
||||
const gchar * wp_endpoint_get_media_class (WpEndpoint * self);
|
||||
|
@@ -4,7 +4,6 @@ wp_lib_sources = [
|
||||
'error.c',
|
||||
'factory.c',
|
||||
'module.c',
|
||||
'session-manager.c',
|
||||
]
|
||||
|
||||
wp_lib_headers = [
|
||||
@@ -13,7 +12,6 @@ wp_lib_headers = [
|
||||
'error.h',
|
||||
'factory.h',
|
||||
'module.h',
|
||||
'session-manager.h',
|
||||
]
|
||||
|
||||
enums = gnome.mkenums_simple('wpenums', sources: wp_lib_headers)
|
||||
|
@@ -1,137 +0,0 @@
|
||||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2019 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "session-manager.h"
|
||||
#include "endpoint.h"
|
||||
|
||||
struct _WpSessionManager
|
||||
{
|
||||
GObject parent;
|
||||
GPtrArray *endpoints;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_ENDPOINT_ADDED,
|
||||
SIGNAL_ENDPOINT_REMOVED,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
static guint32 signals[NUM_SIGNALS];
|
||||
|
||||
G_DEFINE_TYPE (WpSessionManager, wp_session_manager, G_TYPE_OBJECT)
|
||||
G_DEFINE_QUARK (WP_GLOBAL_SESSION_MANAGER, wp_global_session_manager)
|
||||
|
||||
static void
|
||||
wp_session_manager_init (WpSessionManager * self)
|
||||
{
|
||||
self->endpoints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_session_manager_finalize (GObject * obj)
|
||||
{
|
||||
WpSessionManager * self = WP_SESSION_MANAGER (obj);
|
||||
|
||||
g_ptr_array_unref (self->endpoints);
|
||||
|
||||
G_OBJECT_CLASS (wp_session_manager_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_session_manager_class_init (WpSessionManagerClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
object_class->finalize = wp_session_manager_finalize;
|
||||
|
||||
signals[SIGNAL_ENDPOINT_ADDED] = g_signal_new ("endpoint-added",
|
||||
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, WP_TYPE_ENDPOINT);
|
||||
|
||||
signals[SIGNAL_ENDPOINT_REMOVED] = g_signal_new ("endpoint-removed",
|
||||
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, WP_TYPE_ENDPOINT);
|
||||
}
|
||||
|
||||
WpSessionManager *
|
||||
wp_session_manager_new (void)
|
||||
{
|
||||
return g_object_new (WP_TYPE_SESSION_MANAGER, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
wp_session_manager_add_endpoint (WpSessionManager * self, WpEndpoint * ep)
|
||||
{
|
||||
g_ptr_array_add (self->endpoints, g_object_ref (ep));
|
||||
g_signal_emit (self, signals[SIGNAL_ENDPOINT_ADDED], 0, ep);
|
||||
}
|
||||
|
||||
void
|
||||
wp_session_manager_remove_endpoint (WpSessionManager * self, WpEndpoint * ep)
|
||||
{
|
||||
g_signal_emit (self, signals[SIGNAL_ENDPOINT_REMOVED], 0, ep);
|
||||
g_ptr_array_remove_fast (self->endpoints, ep);
|
||||
}
|
||||
|
||||
struct endpoints_foreach_data
|
||||
{
|
||||
GPtrArray *result;
|
||||
const gchar *lookup;
|
||||
};
|
||||
|
||||
static inline gboolean
|
||||
media_class_matches (const gchar * media_class, const gchar * lookup)
|
||||
{
|
||||
const gchar *c1 = media_class, *c2 = lookup;
|
||||
|
||||
/* empty lookup matches all classes */
|
||||
if (!lookup)
|
||||
return TRUE;
|
||||
|
||||
/* compare until we reach the end of the lookup string */
|
||||
for (; *c2 != '\0'; c1++, c2++) {
|
||||
if (*c1 != *c2)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the lookup may not end in a slash, however it must match up
|
||||
* to the end of a submedia_class. i.e.:
|
||||
* match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Source
|
||||
*
|
||||
* NO match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Sou
|
||||
*
|
||||
* if *c1 is not /, also check the previous char, because the lookup
|
||||
* may actually end in a slash:
|
||||
*
|
||||
* match: media_class: Audio/Source/Virtual
|
||||
* lookup: Audio/Source/
|
||||
*/
|
||||
if (!(*c1 == '/' || *c1 == '\0' || *(c1 - 1) == '/'))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
find_endpoints (WpEndpoint * endpoint, struct endpoints_foreach_data * data)
|
||||
{
|
||||
if (media_class_matches (wp_endpoint_get_media_class (endpoint), data->lookup))
|
||||
g_ptr_array_add (data->result, g_object_ref (endpoint));
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
wp_session_manager_find_endpoints (WpSessionManager * self,
|
||||
const gchar * media_class_lookup)
|
||||
{
|
||||
struct endpoints_foreach_data data;
|
||||
data.result = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
data.lookup = media_class_lookup;
|
||||
g_ptr_array_foreach (self->endpoints, (GFunc) find_endpoints, &data);
|
||||
return data.result;
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2019 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __WIREPLUMBER_SESSION_MANAGER_H__
|
||||
#define __WIREPLUMBER_SESSION_MANAGER_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define WP_TYPE_SESSION_MANAGER (wp_session_manager_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (WpSessionManager, wp_session_manager, WP, SESSION_MANAGER, GObject)
|
||||
|
||||
#define WP_GLOBAL_SESSION_MANAGER (wp_global_session_manager_quark ())
|
||||
GQuark wp_global_session_manager_quark (void);
|
||||
|
||||
WpSessionManager * wp_session_manager_new (void);
|
||||
|
||||
GPtrArray * wp_session_manager_find_endpoints (WpSessionManager * self,
|
||||
const gchar * media_class_lookup);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
@@ -11,4 +11,3 @@
|
||||
#include "error.h"
|
||||
#include "factory.h"
|
||||
#include "module.h"
|
||||
#include "session-manager.h"
|
||||
|
@@ -50,7 +50,6 @@ registry_global (void * d, uint32_t id, uint32_t parent_id,
|
||||
g_autoptr (GVariant) endpoint_props = NULL;
|
||||
g_autoptr (WpCore) core = NULL;
|
||||
g_autoptr (WpEndpoint) endpoint = NULL;
|
||||
WpSessionManager *sm = NULL;
|
||||
|
||||
/* listen for client "Stream" nodes and create endpoints for them */
|
||||
if (type == PW_TYPE_INTERFACE_Node &&
|
||||
@@ -79,12 +78,10 @@ registry_global (void * d, uint32_t id, uint32_t parent_id,
|
||||
|
||||
core = wp_module_get_core (data->module);
|
||||
g_return_if_fail (core != NULL);
|
||||
sm = wp_core_get_global (core, WP_GLOBAL_SESSION_MANAGER);
|
||||
g_return_if_fail (sm != NULL);
|
||||
|
||||
endpoint = wp_factory_make (core, "pipewire-simple-endpoint",
|
||||
WP_TYPE_ENDPOINT, endpoint_props);
|
||||
wp_endpoint_register (endpoint, sm);
|
||||
wp_endpoint_register (endpoint, core);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -385,7 +385,8 @@ static const struct pw_proxy_events proxy_events = {
|
||||
};
|
||||
|
||||
static void
|
||||
endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
|
||||
endpoint_added (WpCore *core, GQuark key, WpEndpoint *ep,
|
||||
struct pw_remote * remote)
|
||||
{
|
||||
struct pw_core_proxy *core_proxy;
|
||||
struct pw_client_endpoint_proxy *client_ep_proxy;
|
||||
@@ -396,6 +397,8 @@ endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
|
||||
struct spa_dict props_dict = SPA_DICT_INIT(props, SPA_N_ELEMENTS (props));
|
||||
struct proxy_priv *priv;
|
||||
|
||||
g_return_if_fail (key == WP_GLOBAL_ENDPOINT);
|
||||
|
||||
core_proxy = pw_remote_get_core_proxy (remote);
|
||||
client_ep_proxy = pw_core_proxy_create_object (core_proxy,
|
||||
"client-endpoint",
|
||||
@@ -419,9 +422,12 @@ endpoint_added (WpSessionManager *sm, WpEndpoint *ep, struct pw_remote * remote)
|
||||
}
|
||||
|
||||
static void
|
||||
endpoint_removed (WpSessionManager *sm, WpEndpoint *ep, gpointer _unused)
|
||||
endpoint_removed (WpCore *sm, GQuark key, WpEndpoint *ep, gpointer _unused)
|
||||
{
|
||||
struct pw_proxy *p;
|
||||
|
||||
g_return_if_fail (key == WP_GLOBAL_ENDPOINT);
|
||||
|
||||
p = g_object_get_qdata (G_OBJECT (ep), remote_endpoint_data_quark ());
|
||||
if (p)
|
||||
pw_proxy_destroy (p);
|
||||
@@ -431,13 +437,11 @@ void
|
||||
remote_endpoint_init (WpCore * core, struct pw_core *pw_core,
|
||||
struct pw_remote * remote)
|
||||
{
|
||||
WpSessionManager *sm;
|
||||
|
||||
pw_module_load (pw_core, "libpipewire-module-endpoint", NULL, NULL, NULL,
|
||||
NULL);
|
||||
|
||||
sm = wp_core_get_global (core, WP_GLOBAL_SESSION_MANAGER);
|
||||
g_return_if_fail (sm != NULL);
|
||||
g_signal_connect (sm, "endpoint-added", (GCallback) endpoint_added, remote);
|
||||
g_signal_connect (sm, "endpoint-removed", (GCallback) endpoint_removed, NULL);
|
||||
g_signal_connect (core, "global-added::endpoint",
|
||||
(GCallback) endpoint_added, remote);
|
||||
g_signal_connect (core, "global-removed::endpoint",
|
||||
(GCallback) endpoint_removed, NULL);
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||
GVariantBuilder b;
|
||||
g_autoptr(GVariant) endpoint_props = NULL;
|
||||
g_autoptr (WpEndpoint) endpoint = NULL;
|
||||
WpSessionManager *sm;
|
||||
|
||||
/* Make sure the node has properties */
|
||||
if (!props) {
|
||||
@@ -64,13 +63,10 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||
"node-proxy", g_variant_new_uint64 ((guint64) proxy));
|
||||
endpoint_props = g_variant_builder_end (&b);
|
||||
|
||||
sm = wp_core_get_global (impl->wp_core, WP_GLOBAL_SESSION_MANAGER);
|
||||
g_return_if_fail (sm != NULL);
|
||||
|
||||
/* Create the endpoint */
|
||||
endpoint = wp_factory_make (impl->wp_core, "pw-audio-softdsp-endpoint",
|
||||
WP_TYPE_ENDPOINT, endpoint_props);
|
||||
wp_endpoint_register (endpoint, sm);
|
||||
wp_endpoint_register (endpoint, impl->wp_core);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -195,14 +195,9 @@ main (gint argc, gchar **argv)
|
||||
}
|
||||
|
||||
/* init wireplumber */
|
||||
|
||||
data.core = core = wp_core_new ();
|
||||
|
||||
wp_core_register_global (core, WP_GLOBAL_SESSION_MANAGER,
|
||||
wp_session_manager_new (), g_object_unref);
|
||||
|
||||
/* init main loop */
|
||||
|
||||
data.loop = loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* watch for exit signals */
|
||||
|
Reference in New Issue
Block a user