
After discussing things at the AGL May 2019 F2F meeting and reflecting on the initial design of WirePlumber, it became clear that it needed a fresh start.
121 lines
2.9 KiB
C
121 lines
2.9 KiB
C
/* WirePlumber
|
|
*
|
|
* Copyright © 2019 Collabora Ltd.
|
|
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*/
|
|
|
|
#include "session-manager.h"
|
|
|
|
struct _WpSessionManager
|
|
{
|
|
GObject parent;
|
|
GPtrArray *endpoints;
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
WpSessionManager *
|
|
wp_session_manager_new (void)
|
|
{
|
|
return g_object_new (WP_TYPE_SESSION_MANAGER, NULL);
|
|
}
|
|
|
|
void
|
|
wp_session_manager_register_endpoint (WpSessionManager * self,
|
|
WpEndpoint * ep)
|
|
{
|
|
g_ptr_array_add (self->endpoints, g_object_ref (ep));
|
|
}
|
|
|
|
void
|
|
wp_session_manager_remove_endpoint (WpSessionManager * self,
|
|
WpEndpoint * 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;
|
|
}
|