217 lines
5.0 KiB
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);
|
|
}
|