Files
wireplumber/lib/wp/proxy.c

217 lines
5.0 KiB
C

/* WirePlumber
*
* Copyright © 2019 Collabora Ltd.
* @author Julian Bouzas <julian.bouzas@collabora.com>
*
* SPDX-License-Identifier: MIT
*/
#include <pipewire/pipewire.h>
#include "proxy.h"
typedef struct _WpProxyPrivate WpProxyPrivate;
struct _WpProxyPrivate
{
/* The global id */
guint global_id;
/* The proxy */
struct pw_proxy *proxy;
/* The proxy listener */
struct spa_hook listener;
};
enum {
PROP_0,
PROP_GLOBAL_ID,
PROP_PROXY,
};
enum
{
SIGNAL_DONE,
LAST_SIGNAL,
};
static guint wp_proxy_signals[LAST_SIGNAL] = { 0 };
static void wp_proxy_async_initable_init (gpointer iface, gpointer iface_data);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (WpProxy, wp_proxy, G_TYPE_OBJECT,
G_ADD_PRIVATE (WpProxy)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, wp_proxy_async_initable_init))
static void
proxy_event_destroy (void *data)
{
WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(data));
/* Set the proxy to NULL */
self->proxy = NULL;
/* Call the destroy method */
if (WP_PROXY_GET_CLASS (data)->destroy)
WP_PROXY_GET_CLASS (data)->destroy (data);
}
static void
proxy_event_done (void *data, int seq)
{
/* Emit the done signal */
g_signal_emit (data, wp_proxy_signals[SIGNAL_DONE], 0);
}
static const struct pw_proxy_events proxy_events = {
PW_VERSION_PROXY_EVENTS,
.destroy = proxy_event_destroy,
.done = proxy_event_done,
};
static void
wp_proxy_constructed (GObject * object)
{
WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(object));
/* Add the event listener */
pw_proxy_add_listener (self->proxy, &self->listener, &proxy_events, object);
}
static void
wp_proxy_finalize (GObject * object)
{
WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(object));
g_debug ("%s:%p destroyed (pw proxy %p)", G_OBJECT_TYPE_NAME (object),
object, self->proxy);
/* Destroy the proxy */
if (self->proxy) {
pw_proxy_destroy (self->proxy);
self->proxy = NULL;
}
G_OBJECT_CLASS (wp_proxy_parent_class)->finalize (object);
}
static void
wp_proxy_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
{
WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(object));
switch (property_id) {
case PROP_GLOBAL_ID:
self->global_id = g_value_get_uint (value);
break;
case PROP_PROXY:
self->proxy = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
wp_proxy_get_property (GObject * object, guint property_id, GValue * value,
GParamSpec * pspec)
{
WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(object));
switch (property_id) {
case PROP_GLOBAL_ID:
g_value_set_uint (value, self->global_id);
break;
case PROP_PROXY:
g_value_set_pointer (value, self->proxy);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
wp_proxy_init_finish (GAsyncInitable *initable, GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, initable), FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
static void
wp_proxy_async_initable_init (gpointer iface, gpointer iface_data)
{
GAsyncInitableIface *ai_iface = iface;
/* The init_async must be implemented in the derived classes */
ai_iface->init_finish = wp_proxy_init_finish;
}
static void
wp_proxy_init (WpProxy * self)
{
}
static void
wp_proxy_class_init (WpProxyClass * klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
object_class->constructed = wp_proxy_constructed;
object_class->finalize = wp_proxy_finalize;
object_class->get_property = wp_proxy_get_property;
object_class->set_property = wp_proxy_set_property;
/* Install the properties */
g_object_class_install_property (object_class, PROP_GLOBAL_ID,
g_param_spec_uint ("global-id", "global-id", "The pipewire global id",
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PROXY,
g_param_spec_pointer ("pw-proxy", "pw-proxy", "The pipewire proxy",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
/* Signals */
wp_proxy_signals[SIGNAL_DONE] =
g_signal_new ("done", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (WpProxyClass, done), NULL, NULL, NULL, G_TYPE_NONE, 0);
}
guint
wp_proxy_get_global_id (WpProxy * self)
{
WpProxyPrivate *priv;
g_return_val_if_fail (WP_IS_PROXY (self), 0);
priv = wp_proxy_get_instance_private (self);
return priv->global_id;
}
gpointer
wp_proxy_get_pw_proxy (WpProxy * self)
{
WpProxyPrivate *priv;
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
priv = wp_proxy_get_instance_private (self);
return priv->proxy;
}
void wp_proxy_sync (WpProxy * self)
{
WpProxyPrivate *priv;
g_return_if_fail (WP_IS_PROXY (self));
priv = wp_proxy_get_instance_private (self);
/* Trigger the done callback */
pw_proxy_sync(priv->proxy, 0);
}