proxy: add set and get control vmethods, and remove them from sub-classes

This commit is contained in:
Julian Bouzas 2020-04-16 15:18:53 -04:00
parent e08af1baa3
commit 0045fe03c9
13 changed files with 193 additions and 378 deletions

View file

@ -32,12 +32,6 @@
#include <spa/pod/parser.h>
#include <spa/pod/filter.h>
enum {
SIGNAL_CONTROL_CHANGED,
N_SIGNALS,
};
static guint32 signals[N_SIGNALS] = {0};
/* WpEndpointStream */
@ -45,7 +39,6 @@ typedef struct _WpEndpointStreamPrivate WpEndpointStreamPrivate;
struct _WpEndpointStreamPrivate
{
WpProperties *properties;
WpSpaProps spa_props;
struct pw_endpoint_stream_info *info;
struct pw_endpoint_stream *iface;
struct spa_hook listener;
@ -66,7 +59,6 @@ wp_endpoint_stream_finalize (GObject * object)
g_clear_pointer (&priv->properties, wp_properties_unref);
g_clear_pointer (&priv->info, pw_endpoint_stream_info_free);
wp_spa_props_clear (&priv->spa_props);
G_OBJECT_CLASS (wp_endpoint_stream_parent_class)->finalize (object);
}
@ -77,7 +69,7 @@ wp_endpoint_stream_augment (WpProxy * proxy, WpProxyFeatures features)
/* call the parent impl first to ensure we have a pw proxy if necessary */
WP_PROXY_CLASS (wp_endpoint_stream_parent_class)->augment (proxy, features);
if (features & WP_ENDPOINT_STREAM_FEATURE_CONTROLS) {
if (features & WP_PROXY_FEATURE_CONTROLS) {
struct pw_endpoint_stream *pw_proxy = NULL;
uint32_t ids[] = { SPA_PARAM_Props };
@ -191,33 +183,6 @@ wp_endpoint_stream_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy
&endpoint_stream_events, self);
}
static void
wp_endpoint_stream_param (WpProxy * proxy, gint seq, const gchar * id_name,
guint32 index, guint32 next, const WpSpaPod *param)
{
WpEndpointStream *self = WP_ENDPOINT_STREAM (proxy);
WpEndpointStreamPrivate *priv = wp_endpoint_stream_get_instance_private (self);
g_autoptr (GPtrArray) changed_ids = NULL;
const gchar * prop_id;
if (g_strcmp0 ("PropInfo", id_name) == 0) {
wp_spa_props_register_from_prop_info (&priv->spa_props, param);
}
else if (g_strcmp0 ("Props", id_name) == 0) {
changed_ids = g_ptr_array_new_with_free_func (g_free);
wp_spa_props_store_from_props (&priv->spa_props, param, changed_ids);
for (guint i = 0; i < changed_ids->len; i++) {
prop_id = g_ptr_array_index (changed_ids, i);
g_signal_emit (self, signals[SIGNAL_CONTROL_CHANGED], 0, prop_id);
}
wp_proxy_set_feature_ready (WP_PROXY (self),
WP_ENDPOINT_STREAM_FEATURE_CONTROLS);
}
}
static const gchar *
get_name (WpEndpointStream * self)
{
@ -225,30 +190,6 @@ get_name (WpEndpointStream * self)
return priv->info->name;
}
WpSpaPod *
get_control (WpEndpointStream * self, const gchar * id_name)
{
WpEndpointStreamPrivate *priv = wp_endpoint_stream_get_instance_private (self);
return wp_spa_props_get_stored (&priv->spa_props, id_name);
}
static gboolean
set_control (WpEndpointStream * self, const gchar * id_name,
const WpSpaPod * pod)
{
g_autoptr (WpSpaPod) param = wp_spa_pod_new_object (
"Props", "Props",
id_name, "P", pod,
NULL);
/* our spa_props will be updated by the param event */
WP_PROXY_GET_CLASS (self)->set_param (WP_PROXY (self), SPA_PARAM_Props, 0,
param);
return TRUE;
}
static void
wp_endpoint_stream_class_init (WpEndpointStreamClass * klass)
{
@ -268,22 +209,8 @@ wp_endpoint_stream_class_init (WpEndpointStreamClass * klass)
proxy_class->set_param = wp_endpoint_stream_set_param;
proxy_class->pw_proxy_created = wp_endpoint_stream_pw_proxy_created;
proxy_class->param = wp_endpoint_stream_param;
klass->get_name = get_name;
klass->get_control = get_control;
klass->set_control = set_control;
/**
* WpEndpointStream::control-changed:
* @self: the endpoint stream
* @control: the control that changed (a #WpEndpointControl)
*
* Emitted when an endpoint stream control changes value
*/
signals[SIGNAL_CONTROL_CHANGED] = g_signal_new (
"control-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
}
/**
@ -301,43 +228,6 @@ wp_endpoint_stream_get_name (WpEndpointStream * self)
return WP_ENDPOINT_STREAM_GET_CLASS (self)->get_name (self);
}
/**
* wp_endpoint_stream_get_control:
* @self: the endpoint stream
* @id_name: the control id (a #WpEndpointControl)
*
* Returns: (transfer full) (nullable): the `spa_pod` containing the value
* of this control, or %NULL if @control_id does not exist on this endpoint
* stream
*/
WpSpaPod *
wp_endpoint_stream_get_control (WpEndpointStream * self, const gchar * id_name)
{
g_return_val_if_fail (WP_IS_ENDPOINT_STREAM (self), NULL);
g_return_val_if_fail (WP_ENDPOINT_STREAM_GET_CLASS (self)->get_control, NULL);
return WP_ENDPOINT_STREAM_GET_CLASS (self)->get_control (self, id_name);
}
/**
* wp_endpoint_stream_set_control:
* @self: the endpoint stream
* @id_name: the control id (a #WpEndpointControl)
* @value: the new value for this control, as a `spa_pod`
*
* Returns: %TRUE on success, %FALSE if an error occurred
*/
gboolean
wp_endpoint_stream_set_control (WpEndpointStream * self, const gchar * id_name,
const WpSpaPod * value)
{
g_return_val_if_fail (WP_IS_ENDPOINT_STREAM (self), FALSE);
g_return_val_if_fail (WP_ENDPOINT_STREAM_GET_CLASS (self)->set_control, FALSE);
return WP_ENDPOINT_STREAM_GET_CLASS (self)->set_control (self, id_name,
value);
}
/* WpImplEndpointStream */
@ -400,17 +290,15 @@ impl_enum_params (void *object, int seq,
const struct spa_pod *filter)
{
WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object);
WpEndpointStreamPrivate *priv =
wp_endpoint_stream_get_instance_private (WP_ENDPOINT_STREAM (self));
char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct spa_pod *result;
guint count = 0;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
switch (id) {
case SPA_PARAM_PropInfo: {
g_autoptr (GPtrArray) params =
wp_spa_props_build_propinfo (&priv->spa_props);
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (controls);
for (guint i = start; i < params->len; i++) {
WpSpaPod *pod = g_ptr_array_index (params, i);
@ -427,7 +315,7 @@ impl_enum_params (void *object, int seq,
}
case SPA_PARAM_Props: {
if (start == 0) {
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (&priv->spa_props);
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (controls);
const struct spa_pod *param = wp_spa_pod_get_spa_pod (pod);
if (spa_pod_filter (&b, &result, param, filter) == 0) {
pw_endpoint_stream_emit_param (&self->hooks, seq, id, 0, 1, result);
@ -461,16 +349,15 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
const struct spa_pod *param)
{
WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object);
WpEndpointStreamPrivate *priv =
wp_endpoint_stream_get_instance_private (WP_ENDPOINT_STREAM (self));
g_autoptr (GPtrArray) changed_ids = NULL;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
if (id != SPA_PARAM_Props)
return -ENOENT;
changed_ids = g_ptr_array_new_with_free_func (g_free);
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_regular_wrap_copy (param);
wp_spa_props_store_from_props (&priv->spa_props, pod, changed_ids);
wp_spa_props_store_from_props (controls, pod, changed_ids);
/* notify subscribers */
if (self->subscribed)
@ -479,7 +366,8 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
/* notify controls locally */
for (guint i = 0; i < changed_ids->len; i++) {
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
g_signal_emit (self, signals[SIGNAL_CONTROL_CHANGED], 0, prop_id);
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
prop_id);
}
return 0;
@ -536,7 +424,7 @@ wp_impl_endpoint_stream_init (WpImplEndpointStream * self)
priv->iface = (struct pw_endpoint_stream *) &self->iface;
wp_proxy_set_feature_ready (WP_PROXY (self), WP_ENDPOINT_STREAM_FEATURE_CONTROLS);
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_CONTROLS);
}
static void

View file

@ -14,19 +14,6 @@
G_BEGIN_DECLS
/**
* WpEndpointStreamFeatures:
* @WP_ENDPOINT_STREAM_FEATURE_CONTROLS: enables the use of the
* wp_endpoint_stream_get_control() and wp_endpoint_stream_set_control()
* families of functions to be able to work with endpoint-stream-specific
* controls
*
* An extension of #WpProxyFeatures
*/
typedef enum { /*< flags >*/
WP_ENDPOINT_STREAM_FEATURE_CONTROLS = WP_PROXY_FEATURE_LAST,
} WpEndpointStreamFeatures;
/**
* WP_TYPE_ENDPOINT_STREAM:
*
@ -42,23 +29,11 @@ struct _WpEndpointStreamClass
WpProxyClass parent_class;
const gchar * (*get_name) (WpEndpointStream * self);
WpSpaPod * (*get_control) (WpEndpointStream * self, const gchar * id_name);
gboolean (*set_control) (WpEndpointStream * self, const gchar * id_name,
const WpSpaPod * value);
};
WP_API
const gchar * wp_endpoint_stream_get_name (WpEndpointStream * self);
WP_API
WpSpaPod * wp_endpoint_stream_get_control (WpEndpointStream * self,
const gchar *id_name);
WP_API
gboolean wp_endpoint_stream_set_control (WpEndpointStream * self,
const gchar *id_name, const WpSpaPod * value);
G_END_DECLS
#endif

View file

@ -35,12 +35,6 @@
#include <spa/pod/parser.h>
#include <spa/pod/filter.h>
enum {
SIGNAL_CONTROL_CHANGED,
N_SIGNALS,
};
static guint32 signals[N_SIGNALS] = {0};
/* WpEndpoint */
@ -48,7 +42,6 @@ typedef struct _WpEndpointPrivate WpEndpointPrivate;
struct _WpEndpointPrivate
{
WpProperties *properties;
WpSpaProps spa_props;
struct pw_endpoint_info *info;
struct pw_endpoint *iface;
struct spa_hook listener;
@ -71,7 +64,6 @@ wp_endpoint_finalize (GObject * object)
g_clear_object (&priv->streams_om);
g_clear_pointer (&priv->properties, wp_properties_unref);
g_clear_pointer (&priv->info, pw_endpoint_info_free);
wp_spa_props_clear (&priv->spa_props);
G_OBJECT_CLASS (wp_endpoint_parent_class)->finalize (object);
}
@ -125,7 +117,7 @@ wp_endpoint_augment (WpProxy * proxy, WpProxyFeatures features)
/* call the parent impl first to ensure we have a pw proxy if necessary */
WP_PROXY_CLASS (wp_endpoint_parent_class)->augment (proxy, features);
if (features & WP_ENDPOINT_FEATURE_CONTROLS) {
if (features & WP_PROXY_FEATURE_CONTROLS) {
struct pw_endpoint *pw_proxy = NULL;
uint32_t ids[] = { SPA_PARAM_Props };
@ -261,33 +253,6 @@ wp_endpoint_bound (WpProxy * proxy, guint32 id)
wp_endpoint_enable_feature_streams (self, id);
}
static void
wp_endpoint_param (WpProxy * proxy, gint seq, const gchar * id_name,
guint32 index, guint32 next, const WpSpaPod *param)
{
WpEndpoint *self = WP_ENDPOINT (proxy);
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
g_autoptr (GPtrArray) changed_ids = NULL;
const gchar * prop_id;
if (g_strcmp0 ("PropInfo", id_name) == 0) {
wp_spa_props_register_from_prop_info (&priv->spa_props, param);
}
else if (g_strcmp0 ("Props", id_name) == 0) {
changed_ids = g_ptr_array_new_with_free_func (g_free);
wp_spa_props_store_from_props (&priv->spa_props, param, changed_ids);
for (guint i = 0; i < changed_ids->len; i++) {
prop_id = g_ptr_array_index (changed_ids, i);
g_signal_emit (self, signals[SIGNAL_CONTROL_CHANGED], 0, prop_id);
}
wp_proxy_set_feature_ready (WP_PROXY (self),
WP_ENDPOINT_FEATURE_CONTROLS);
}
}
static const gchar *
get_name (WpEndpoint * self)
{
@ -309,29 +274,6 @@ get_direction (WpEndpoint * self)
return priv->info->direction;
}
static WpSpaPod *
get_control (WpEndpoint * self, const gchar * id_name)
{
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
return wp_spa_props_get_stored (&priv->spa_props, id_name);
}
static gboolean
set_control (WpEndpoint * self, const gchar * id_name, const WpSpaPod * pod)
{
g_autoptr (WpSpaPod) param = wp_spa_pod_new_object (
"Props", "Props",
id_name, "P", pod,
NULL);
/* our spa_props will be updated by the param event */
WP_PROXY_GET_CLASS (self)->set_param (WP_PROXY (self), SPA_PARAM_Props, 0,
param);
return TRUE;
}
static void
wp_endpoint_class_init (WpEndpointClass * klass)
{
@ -352,24 +294,10 @@ wp_endpoint_class_init (WpEndpointClass * klass)
proxy_class->pw_proxy_created = wp_endpoint_pw_proxy_created;
proxy_class->bound = wp_endpoint_bound;
proxy_class->param = wp_endpoint_param;
klass->get_name = get_name;
klass->get_media_class = get_media_class;
klass->get_direction = get_direction;
klass->get_control = get_control;
klass->set_control = set_control;
/**
* WpEndpoint::control-changed:
* @self: the endpoint
* @control: the control that changed (a #WpEndpointControl)
*
* Emitted when an endpoint control changes value
*/
signals[SIGNAL_CONTROL_CHANGED] = g_signal_new (
"control-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
}
/**
@ -417,41 +345,6 @@ wp_endpoint_get_direction (WpEndpoint * self)
return WP_ENDPOINT_GET_CLASS (self)->get_direction (self);
}
/**
* wp_endpoint_get_control:
* @self: the endpoint
* @id_name: the control id name
*
* Returns: (transfer full) (nullable): the spa pod containing the value
* of this control, or %NULL if @control_id does not exist on this endpoint
*/
WpSpaPod *
wp_endpoint_get_control (WpEndpoint * self, const gchar * id_name)
{
g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL);
g_return_val_if_fail (WP_ENDPOINT_GET_CLASS (self)->get_control, NULL);
return WP_ENDPOINT_GET_CLASS (self)->get_control (self, id_name);
}
/**
* wp_endpoint_set_control:
* @self: the endpoint
* @id_name: the control id name
* @value: the new value for this control, as a `spa_pod`
*
* Returns: %TRUE on success, %FALSE if an error occurred
*/
gboolean
wp_endpoint_set_control (WpEndpoint * self, const gchar * id_name,
const WpSpaPod * value)
{
g_return_val_if_fail (WP_IS_ENDPOINT (self), FALSE);
g_return_val_if_fail (WP_ENDPOINT_GET_CLASS (self)->set_control, FALSE);
return WP_ENDPOINT_GET_CLASS (self)->set_control (self, id_name, value);
}
/**
* wp_endpoint_get_n_streams:
* @self: the endpoint
@ -565,17 +458,15 @@ impl_enum_params (void *object, int seq,
const struct spa_pod *filter)
{
WpImplEndpoint *self = WP_IMPL_ENDPOINT (object);
WpEndpointPrivate *priv =
wp_endpoint_get_instance_private (WP_ENDPOINT (self));
char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct spa_pod *result;
guint count = 0;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
switch (id) {
case SPA_PARAM_PropInfo: {
g_autoptr (GPtrArray) params =
wp_spa_props_build_propinfo (&priv->spa_props);
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (controls);
for (guint i = start; i < params->len; i++) {
WpSpaPod *pod = g_ptr_array_index (params, i);
@ -592,7 +483,7 @@ impl_enum_params (void *object, int seq,
}
case SPA_PARAM_Props: {
if (start == 0) {
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (&priv->spa_props);
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (controls);
const struct spa_pod *param = wp_spa_pod_get_spa_pod (pod);
if (spa_pod_filter (&b, &result, param, filter) == 0) {
pw_endpoint_emit_param (&self->hooks, seq, id, 0, 1, result);
@ -626,16 +517,15 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
const struct spa_pod *param)
{
WpImplEndpoint *self = WP_IMPL_ENDPOINT (object);
WpEndpointPrivate *priv =
wp_endpoint_get_instance_private (WP_ENDPOINT (self));
g_autoptr (GPtrArray) changed_ids = NULL;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
if (id != SPA_PARAM_Props)
return -ENOENT;
changed_ids = g_ptr_array_new_with_free_func (g_free);
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_regular_wrap_copy (param);
wp_spa_props_store_from_props (&priv->spa_props, pod, changed_ids);
wp_spa_props_store_from_props (controls, pod, changed_ids);
/* notify subscribers */
if (self->subscribed)
@ -644,7 +534,8 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
/* notify controls locally */
for (guint i = 0; i < changed_ids->len; i++) {
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
g_signal_emit (self, signals[SIGNAL_CONTROL_CHANGED], 0, prop_id);
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
prop_id);
}
return 0;
@ -874,7 +765,7 @@ wp_impl_endpoint_init (WpImplEndpoint * self)
priv->iface = (struct pw_endpoint *) &self->iface;
wp_proxy_set_feature_ready (WP_PROXY (self), WP_ENDPOINT_FEATURE_CONTROLS);
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_CONTROLS);
}
static void

View file

@ -30,9 +30,6 @@ typedef enum {
/**
* WpEndpointFeatures:
* @WP_ENDPOINT_FEATURE_CONTROLS: enables the use of the
* wp_endpoint_get_control() and wp_endpoint_set_control() families of
* functions to be able to work with endpoint-specific controls
* @WP_ENDPOINT_FEATURE_STREAMS: caches information about streams, enabling
* the use of wp_endpoint_get_n_streams(), wp_endpoint_find_stream() and
* wp_endpoint_iterate_streams()
@ -40,8 +37,7 @@ typedef enum {
* An extension of #WpProxyFeatures
*/
typedef enum { /*< flags >*/
WP_ENDPOINT_FEATURE_CONTROLS = WP_PROXY_FEATURE_LAST,
WP_ENDPOINT_FEATURE_STREAMS,
WP_ENDPOINT_FEATURE_STREAMS = WP_PROXY_FEATURE_LAST,
} WpEndpointFeatures;
/**
@ -52,7 +48,7 @@ typedef enum { /*< flags >*/
*/
#define WP_ENDPOINT_FEATURES_STANDARD \
(WP_PROXY_FEATURES_STANDARD | \
WP_ENDPOINT_FEATURE_CONTROLS | \
WP_PROXY_FEATURE_CONTROLS | \
WP_ENDPOINT_FEATURE_STREAMS)
/**
@ -71,10 +67,6 @@ struct _WpEndpointClass
const gchar * (*get_name) (WpEndpoint * self);
const gchar * (*get_media_class) (WpEndpoint * self);
WpDirection (*get_direction) (WpEndpoint * self);
WpSpaPod * (*get_control) (WpEndpoint * self, const gchar * id_name);
gboolean (*set_control) (WpEndpoint * self, const gchar * id_name,
const WpSpaPod * value);
};
WP_API
@ -86,13 +78,6 @@ const gchar * wp_endpoint_get_media_class (WpEndpoint * self);
WP_API
WpDirection wp_endpoint_get_direction (WpEndpoint * self);
WP_API
WpSpaPod * wp_endpoint_get_control (WpEndpoint * self, const gchar * id_name);
WP_API
gboolean wp_endpoint_set_control (WpEndpoint * self, const gchar * id_name,
const WpSpaPod * value);
WP_API
guint wp_endpoint_get_n_streams (WpEndpoint * self);

View file

@ -131,7 +131,7 @@ wp_policy_manager_get_instance (WpCore *core)
/* install the object manager to listen to changed sessions */
wp_object_manager_add_interest (mgr->sessions_om,
WP_TYPE_IMPL_SESSION, NULL,
WP_PROXY_FEATURES_STANDARD | WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
wp_core_install_object_manager (core, mgr->sessions_om);
wp_registry_register_object (wp_core_get_registry (core),

View file

@ -119,6 +119,8 @@ void wp_proxy_augment_error (WpProxy * self, GError * error);
void wp_proxy_handle_event_param (void * proxy, int seq, uint32_t id,
uint32_t index, uint32_t next, const struct spa_pod *param);
WpSpaProps *wp_proxy_get_spa_props (WpProxy * self);
/* iterator */
struct _WpIteratorMethods {

View file

@ -47,6 +47,9 @@ struct _WpProxyPrivate
GPtrArray *augment_tasks; // element-type: GTask*
GHashTable *async_tasks; // <int seq, GTask*>
/* controls */
WpSpaProps controls;
};
enum {
@ -68,6 +71,7 @@ enum
SIGNAL_PW_PROXY_DESTROYED,
SIGNAL_BOUND,
SIGNAL_PARAM,
SIGNAL_CONTROL_CHANGED,
LAST_SIGNAL,
};
@ -202,6 +206,7 @@ wp_proxy_finalize (GObject * object)
g_clear_pointer (&priv->global, wp_global_unref);
g_weak_ref_clear (&priv->core);
g_clear_pointer (&priv->async_tasks, g_hash_table_unref);
wp_spa_props_clear (&priv->controls);
G_OBJECT_CLASS (wp_proxy_parent_class)->finalize (object);
}
@ -293,6 +298,54 @@ wp_proxy_default_augment (WpProxy * self, WpProxyFeatures features)
}
}
static void
wp_proxy_default_param (WpProxy * self, gint seq, const gchar * id_name,
guint32 index, guint32 next, const WpSpaPod *param)
{
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
g_autoptr (GPtrArray) changed_ids = NULL;
const gchar * prop_id;
if (g_strcmp0 ("PropInfo", id_name) == 0) {
wp_spa_props_register_from_prop_info (&priv->controls, param);
}
else if (g_strcmp0 ("Props", id_name) == 0) {
changed_ids = g_ptr_array_new_with_free_func (g_free);
wp_spa_props_store_from_props (&priv->controls, param, changed_ids);
for (guint i = 0; i < changed_ids->len; i++) {
prop_id = g_ptr_array_index (changed_ids, i);
g_signal_emit (self, wp_proxy_signals[SIGNAL_CONTROL_CHANGED], 0, prop_id);
}
wp_proxy_set_feature_ready (self, WP_PROXY_FEATURE_CONTROLS);
}
}
static WpSpaPod *
wp_proxy_default_get_control (WpProxy * self, const gchar * id_name)
{
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
return wp_spa_props_get_stored (&priv->controls, id_name);
}
static gboolean
wp_proxy_default_set_control (WpProxy * self, const gchar * id_name,
const WpSpaPod * value)
{
g_return_val_if_fail (WP_PROXY_GET_CLASS (self)->set_param, FALSE);
g_autoptr (WpSpaPod) param = wp_spa_pod_new_object (
"Props", "Props",
id_name, "P", value,
NULL);
/* our spa_props will be updated by the param event */
return WP_PROXY_GET_CLASS (self)->set_param (self, SPA_PARAM_Props, 0,
param) >= 0;
}
static void
wp_proxy_class_init (WpProxyClass * klass)
{
@ -304,6 +357,9 @@ wp_proxy_class_init (WpProxyClass * klass)
object_class->set_property = wp_proxy_set_property;
klass->augment = wp_proxy_default_augment;
klass->param = wp_proxy_default_param;
klass->get_control = wp_proxy_default_get_control;
klass->set_control = wp_proxy_default_set_control;
/* Install the properties */
@ -369,6 +425,11 @@ wp_proxy_class_init (WpProxyClass * klass)
"param", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (WpProxyClass, param), NULL, NULL, NULL, G_TYPE_NONE, 5,
G_TYPE_INT, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, WP_TYPE_SPA_POD);
wp_proxy_signals[SIGNAL_CONTROL_CHANGED] = g_signal_new (
"control-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (WpProxyClass, control_changed), NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_STRING);
}
void
@ -859,6 +920,41 @@ wp_proxy_set_param (WpProxy * self, guint32 id, guint32 flags,
-ENOTSUP;
}
/**
* wp_proxy_get_control:
* @self: the proxy
* @id_name: the control id name
*
* Returns: (transfer full) (nullable): the spa pod containing the value
* of this control, or %NULL if @control_id does not exist on this proxy
*/
WpSpaPod *
wp_proxy_get_control (WpProxy * self, const gchar * id_name)
{
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
g_return_val_if_fail (WP_PROXY_GET_CLASS (self)->get_control, NULL);
return WP_PROXY_GET_CLASS (self)->get_control (self, id_name);
}
/**
* wp_proxy_set_control:
* @self: the proxy
* @id_name: the control id name
* @value: the new value for this control, as a spa pod
*
* Returns: %TRUE on success, %FALSE if an error occurred
*/
gboolean
wp_proxy_set_control (WpProxy * self, const gchar * id_name,
const WpSpaPod * value)
{
g_return_val_if_fail (WP_IS_PROXY (self), FALSE);
g_return_val_if_fail (WP_PROXY_GET_CLASS (self)->set_control, FALSE);
return WP_PROXY_GET_CLASS (self)->set_control (self, id_name, value);
}
void
wp_proxy_handle_event_param (void * proxy, int seq, uint32_t id,
uint32_t index, uint32_t next, const struct spa_pod *param)
@ -882,3 +978,10 @@ wp_proxy_handle_event_param (void * proxy, int seq, uint32_t id,
g_ptr_array_add (array, g_steal_pointer (&pod));
}
}
WpSpaProps *
wp_proxy_get_spa_props (WpProxy * self)
{
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
return &priv->controls;
}

View file

@ -34,6 +34,7 @@ typedef enum { /*< flags >*/
WP_PROXY_FEATURE_PW_PROXY = (1 << 0),
WP_PROXY_FEATURE_INFO = (1 << 1),
WP_PROXY_FEATURE_BOUND = (1 << 2),
WP_PROXY_FEATURE_CONTROLS = (1 << 3),
WP_PROXY_FEATURE_LAST = (1 << 5), /*< skip >*/
} WpProxyFeatures;
@ -83,6 +84,9 @@ struct _WpProxyClass
gint (*subscribe_params) (WpProxy * self, guint32 n_ids, guint32 *ids);
gint (*set_param) (WpProxy * self, guint32 id, guint32 flags,
const WpSpaPod * param);
WpSpaPod * (*get_control) (WpProxy * self, const gchar * id_name);
gboolean (*set_control) (WpProxy * self, const gchar * id_name,
const WpSpaPod * value);
/* signals */
@ -91,6 +95,7 @@ struct _WpProxyClass
void (*bound) (WpProxy * self, guint32 id);
void (*param) (WpProxy * self, gint seq, const gchar * id_name, guint32 index,
guint32 next, const WpSpaPod *param);
void (*control_changed) (WpProxy * self, const char * id_name);
};
/* features API */
@ -165,6 +170,13 @@ WP_API
gint wp_proxy_set_param (WpProxy * self, guint32 id, guint32 flags,
const WpSpaPod *param);
WP_API
WpSpaPod * wp_proxy_get_control (WpProxy * self, const gchar * id_name);
WP_API
gboolean wp_proxy_set_control (WpProxy * self, const gchar * id_name,
const WpSpaPod * value);
G_END_DECLS
#endif

View file

@ -50,7 +50,6 @@ typedef struct _WpSessionPrivate WpSessionPrivate;
struct _WpSessionPrivate
{
WpProperties *properties;
WpSpaProps spa_props;
struct pw_session_info *info;
struct pw_session *iface;
struct spa_hook listener;
@ -75,7 +74,6 @@ wp_session_finalize (GObject * object)
g_clear_object (&priv->links_om);
g_clear_pointer (&priv->info, pw_session_info_free);
g_clear_pointer (&priv->properties, wp_properties_unref);
wp_spa_props_clear (&priv->spa_props);
G_OBJECT_CLASS (wp_session_parent_class)->finalize (object);
}
@ -175,38 +173,6 @@ wp_session_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy)
pw_session_add_listener (priv->iface, &priv->listener, &session_events, self);
}
static void
wp_session_param (WpProxy * proxy, gint seq, const gchar * id_name,
guint32 index, guint32 next, const WpSpaPod *param)
{
WpSession *self = WP_SESSION (proxy);
WpSessionPrivate *priv = wp_session_get_instance_private (self);
g_autoptr (GPtrArray) changed_ids = NULL;
g_autoptr (WpSpaPod) stored = NULL;
const gchar * prop_id;
gint32 value;
if (g_strcmp0 ("PropInfo", id_name) == 0) {
wp_spa_props_register_from_prop_info (&priv->spa_props, param);
}
else if (g_strcmp0 ("Props", id_name) == 0) {
changed_ids = g_ptr_array_new_with_free_func (g_free);
wp_spa_props_store_from_props (&priv->spa_props, param, changed_ids);
for (guint i = 0; i < changed_ids->len; i++) {
prop_id = g_ptr_array_index (changed_ids, i);
stored = wp_spa_props_get_stored (&priv->spa_props, prop_id);
wp_spa_pod_get_int (stored, &value);
g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0, prop_id,
value);
}
wp_proxy_set_feature_ready (WP_PROXY (self),
WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
}
}
static void
wp_session_enable_feature_endpoints (WpSession * self, guint32 bound_id)
{
@ -305,6 +271,18 @@ wp_session_bound (WpProxy * proxy, guint32 id)
wp_session_enable_feature_links (self, id);
}
static void
wp_session_control_changed (WpProxy * proxy, const char * id_name)
{
WpSession *self = WP_SESSION (proxy);
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
g_autoptr (WpSpaPod) pod = wp_spa_props_get_stored (controls, id_name);
gint value;
if (wp_spa_pod_get_int (pod, &value))
g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0, id_name,
value);
}
static void
wp_session_augment (WpProxy * proxy, WpProxyFeatures features)
{
@ -313,7 +291,7 @@ wp_session_augment (WpProxy * proxy, WpProxyFeatures features)
/* call the parent impl first to ensure we have a pw proxy if necessary */
WP_PROXY_CLASS (wp_session_parent_class)->augment (proxy, features);
if (features & WP_SESSION_FEATURE_DEFAULT_ENDPOINT) {
if (features & WP_PROXY_FEATURE_CONTROLS) {
struct pw_session *pw_proxy = NULL;
uint32_t ids[] = { SPA_PARAM_Props };
@ -349,31 +327,21 @@ wp_session_augment (WpProxy * proxy, WpProxyFeatures features)
}
static guint32
get_default_endpoint (WpSession * self, const gchar * type_name)
get_default_endpoint (WpSession * self, const gchar * id_name)
{
WpSessionPrivate *priv = wp_session_get_instance_private (self);
g_autoptr (WpSpaPod) pod = NULL;
g_autoptr (WpSpaPod) pod = wp_proxy_get_control (WP_PROXY (self), id_name);
gint32 value;
pod = wp_spa_props_get_stored (&priv->spa_props, type_name);
if (pod && wp_spa_pod_get_int (pod, &value))
return (guint32) value;
return 0;
}
static void
set_default_endpoint (WpSession * self, const gchar * type_name, guint32 id)
set_default_endpoint (WpSession * self, const gchar * id_name, guint32 id)
{
g_autoptr (WpSpaPod) param = wp_spa_pod_new_object (
"Props", "Props",
type_name, "i", id,
NULL);
/* set the default endpoint id as a property param on the session;
our spa_props cache will be updated by the param event */
WP_PROXY_GET_CLASS (self)->set_param (WP_PROXY (self), SPA_PARAM_Props, 0,
param);
g_autoptr (WpSpaPod) param = wp_spa_pod_new_int (id);
wp_proxy_set_control (WP_PROXY (self), id_name, param);
}
static void
@ -406,8 +374,8 @@ wp_session_class_init (WpSessionClass * klass)
proxy_class->set_param = wp_session_set_param;
proxy_class->pw_proxy_created = wp_session_pw_proxy_created;
proxy_class->param = wp_session_param;
proxy_class->bound = wp_session_bound;
proxy_class->control_changed = wp_session_control_changed;
klass->get_default_endpoint = get_default_endpoint;
klass->set_default_endpoint = set_default_endpoint;
@ -431,37 +399,37 @@ wp_session_class_init (WpSessionClass * klass)
/**
* wp_session_get_default_endpoint:
* @self: the session
* @type_name: the endpoint type name
* @id_name: the endpoint id name
*
* Returns: the bound id of the default endpoint of this @type
*/
guint32
wp_session_get_default_endpoint (WpSession * self,
const gchar * type_name)
const gchar * id_name)
{
g_return_val_if_fail (WP_IS_SESSION (self), SPA_ID_INVALID);
g_return_val_if_fail (WP_SESSION_GET_CLASS (self)->get_default_endpoint,
SPA_ID_INVALID);
return WP_SESSION_GET_CLASS (self)->get_default_endpoint (self, type_name);
return WP_SESSION_GET_CLASS (self)->get_default_endpoint (self, id_name);
}
/**
* wp_session_set_default_endpoint:
* @self: the session
* @type_name: the endpoint type name
* @id_name: the endpoint id name
* @id: the bound id of the endpoint to set as the default for this @type
*
* Sets the default endpoint for this @type to be the one identified with @id
*/
void
wp_session_set_default_endpoint (WpSession * self, const char * type_name,
wp_session_set_default_endpoint (WpSession * self, const char * id_name,
guint32 id)
{
g_return_if_fail (WP_IS_SESSION (self));
g_return_if_fail (WP_SESSION_GET_CLASS (self)->set_default_endpoint);
WP_SESSION_GET_CLASS (self)->set_default_endpoint (self, type_name, id);
WP_SESSION_GET_CLASS (self)->set_default_endpoint (self, id_name, id);
}
/**
@ -626,17 +594,15 @@ impl_enum_params (void *object, int seq,
const struct spa_pod *filter)
{
WpImplSession *self = WP_IMPL_SESSION (object);
WpSessionPrivate *priv =
wp_session_get_instance_private (WP_SESSION (self));
char buf[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT (buf, sizeof (buf));
struct spa_pod *result;
guint count = 0;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
switch (id) {
case SPA_PARAM_PropInfo: {
g_autoptr (GPtrArray) params =
wp_spa_props_build_propinfo (&priv->spa_props);
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (controls);
for (guint i = start; i < params->len; i++) {
WpSpaPod *pod = g_ptr_array_index (params, i);
@ -650,7 +616,7 @@ impl_enum_params (void *object, int seq,
}
case SPA_PARAM_Props: {
if (start == 0) {
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (&priv->spa_props);
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (controls);
const struct spa_pod *param = wp_spa_pod_get_spa_pod (pod);
if (spa_pod_filter (&b, &result, param, filter) == 0) {
pw_session_emit_param (&self->hooks, seq, id, 0, 1, result);
@ -683,15 +649,15 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
const struct spa_pod *param)
{
WpImplSession *self = WP_IMPL_SESSION (object);
WpSessionPrivate *priv = wp_session_get_instance_private (WP_SESSION (self));
g_autoptr (GPtrArray) changed_ids = NULL;
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
if (id != SPA_PARAM_Props)
return -ENOENT;
changed_ids = g_ptr_array_new_with_free_func (g_free);
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_regular_wrap_copy (param);
wp_spa_props_store_from_props (&priv->spa_props, pod, changed_ids);
wp_spa_props_store_from_props (controls, pod, changed_ids);
/* notify subscribers */
if (self->subscribed)
@ -700,12 +666,8 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
/* notify controls locally */
for (guint i = 0; i < changed_ids->len; i++) {
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
g_autoptr (WpSpaPod) pod = wp_spa_props_get_stored (&priv->spa_props,
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
prop_id);
gint value;
if (wp_spa_pod_get_int (pod, &value))
g_signal_emit (self, signals[SIGNAL_DEFAULT_ENDPOINT_CHANGED], 0, prop_id,
value);
}
return 0;
@ -724,8 +686,8 @@ wp_impl_session_init (WpImplSession * self)
{
/* reuse the parent's private to optimize memory usage and to be able
to re-use some of the parent's methods without reimplementing them */
WpSessionPrivate *priv =
wp_session_get_instance_private (WP_SESSION (self));
WpSessionPrivate *priv = wp_session_get_instance_private (WP_SESSION (self));
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
self->iface = SPA_INTERFACE_INIT (
PW_TYPE_INTERFACE_Session,
@ -748,18 +710,18 @@ wp_impl_session_init (WpImplSession * self)
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
/* prepare default endpoint */
wp_spa_props_register (&priv->spa_props,
wp_spa_props_register (controls,
"wp-session-default-endpoint-audio-source",
"Default Audio Source", wp_spa_pod_new_int (0));
wp_spa_props_register (&priv->spa_props,
wp_spa_props_register (controls,
"wp-session-default-endpoint-audio-sink",
"Default Audio Sink", wp_spa_pod_new_int (0));
wp_spa_props_register (&priv->spa_props,
wp_spa_props_register (controls,
"wp-session-default-endpoint-video-source",
"Default Video Source", wp_spa_pod_new_int (0));
wp_proxy_set_feature_ready (WP_PROXY (self),
WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
WP_PROXY_FEATURE_CONTROLS);
}
static void

View file

@ -17,9 +17,6 @@ G_BEGIN_DECLS
/**
* WpSessionFeatures:
* @WP_SESSION_FEATURE_DEFAULT_ENDPOINT: enables the use of
* wp_session_get_default_endpoint() and wp_session_set_default_endpoint()
* to store default endpoint preferences on the session
* @WP_SESSION_FEATURE_ENDPOINTS: caches information about endpoints, enabling
* the use of wp_session_get_n_endpoints(), wp_session_find_endpoint() and
* wp_session_iterate_endpoints()
@ -30,8 +27,7 @@ G_BEGIN_DECLS
* An extension of #WpProxyFeatures
*/
typedef enum { /*< flags >*/
WP_SESSION_FEATURE_DEFAULT_ENDPOINT = WP_PROXY_FEATURE_LAST,
WP_SESSION_FEATURE_ENDPOINTS,
WP_SESSION_FEATURE_ENDPOINTS = WP_PROXY_FEATURE_LAST,
WP_SESSION_FEATURE_LINKS,
} WpSessionFeatures;
@ -43,7 +39,7 @@ typedef enum { /*< flags >*/
*/
#define WP_SESSION_FEATURES_STANDARD \
(WP_PROXY_FEATURES_STANDARD | \
WP_SESSION_FEATURE_DEFAULT_ENDPOINT | \
WP_PROXY_FEATURE_CONTROLS | \
WP_SESSION_FEATURE_ENDPOINTS | \
WP_SESSION_FEATURE_LINKS)
@ -60,17 +56,17 @@ struct _WpSessionClass
{
WpProxyClass parent_class;
guint32 (*get_default_endpoint) (WpSession * self, const gchar * type_name);
void (*set_default_endpoint) (WpSession * self, const gchar * type_name,
guint32 (*get_default_endpoint) (WpSession * self, const gchar * id_name);
void (*set_default_endpoint) (WpSession * self, const gchar * id_name,
guint32 id);
};
WP_API
guint32 wp_session_get_default_endpoint (WpSession * self,
const gchar * type_name);
const gchar * id_name);
WP_API
void wp_session_set_default_endpoint (WpSession * self, const gchar * type_name,
void wp_session_set_default_endpoint (WpSession * self, const gchar * id_name,
guint32 id);
WP_API

View file

@ -363,7 +363,7 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
(GCallback) test_endpoint_basic_impl_object_removed, fixture);
wp_object_manager_add_interest (fixture->export_om,
WP_TYPE_ENDPOINT, NULL,
WP_PROXY_FEATURES_STANDARD | WP_ENDPOINT_FEATURE_CONTROLS);
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
wp_core_install_object_manager (fixture->export_core, fixture->export_om);
g_assert_true (wp_core_connect (fixture->export_core));
@ -375,7 +375,7 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
(GCallback) test_endpoint_basic_proxy_object_removed, fixture);
wp_object_manager_add_interest (fixture->proxy_om,
WP_TYPE_ENDPOINT, NULL,
WP_PROXY_FEATURES_STANDARD | WP_ENDPOINT_FEATURE_CONTROLS);
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
wp_core_install_object_manager (fixture->proxy_core, fixture->proxy_om);
g_assert_true (wp_core_connect (fixture->proxy_core));
@ -416,7 +416,7 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
WP_PROXY_FEATURE_PW_PROXY |
WP_PROXY_FEATURE_INFO |
WP_PROXY_FEATURE_BOUND |
WP_ENDPOINT_FEATURE_CONTROLS);
WP_PROXY_FEATURE_CONTROLS);
g_assert_cmpuint (wp_proxy_get_bound_id (fixture->proxy_endpoint), ==,
wp_proxy_get_bound_id (fixture->impl_endpoint));

View file

@ -282,7 +282,8 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
WP_PROXY_FEATURE_PW_PROXY |
WP_PROXY_FEATURE_INFO |
WP_PROXY_FEATURE_BOUND |
WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
WP_PROXY_FEATURE_CONTROLS |
WP_SESSION_FEATURE_ENDPOINTS);
g_assert_cmpuint (wp_proxy_get_bound_id (fixture->proxy_session), ==,
wp_proxy_get_bound_id (WP_PROXY (session)));

View file

@ -47,9 +47,9 @@ print_dev_endpoint (WpEndpoint *ep, WpSession *session, const gchar *type_name)
gfloat volume = 0.0;
gboolean mute = FALSE;
ctrl = wp_endpoint_get_control (ep, "volume");
ctrl = wp_proxy_get_control (WP_PROXY (ep), "volume");
wp_spa_pod_get_float (ctrl, &volume);
ctrl = wp_endpoint_get_control (ep, "mute");
ctrl = wp_proxy_get_control (WP_PROXY (ep), "mute");
wp_spa_pod_get_boolean (ctrl, &mute);
g_print (" %c %4u. %60s\tvol: %.2f %s\n", is_default ? '*' : ' ', id,
@ -189,7 +189,7 @@ set_volume (WpObjectManager * om, struct WpCliData * d)
if (id == d->params.set_volume.id) {
g_autoptr (WpSpaPod) vol = wp_spa_pod_new_float (d->params.set_volume.volume);
wp_endpoint_set_control (ep, "volume", vol);
wp_proxy_set_control (WP_PROXY (ep), "volume", vol);
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
return;
}
@ -305,10 +305,10 @@ main (gint argc, gchar **argv)
if (argc == 2 && !g_strcmp0 (argv[1], "ls-endpoints")) {
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT,
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
WP_ENDPOINT_FEATURE_CONTROLS);
WP_PROXY_FEATURE_CONTROLS);
wp_object_manager_add_interest (om, WP_TYPE_SESSION,
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
WP_PROXY_FEATURE_CONTROLS);
g_signal_connect (om, "objects-changed", (GCallback) list_endpoints, &data);
}
@ -323,7 +323,7 @@ main (gint argc, gchar **argv)
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND);
wp_object_manager_add_interest (om, WP_TYPE_SESSION,
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
WP_SESSION_FEATURE_DEFAULT_ENDPOINT);
WP_PROXY_FEATURE_CONTROLS);
data.params.set_default.id = id;
g_signal_connect (om, "objects-changed", (GCallback) set_default, &data);
@ -339,7 +339,7 @@ main (gint argc, gchar **argv)
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT,
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
WP_ENDPOINT_FEATURE_CONTROLS);
WP_PROXY_FEATURE_CONTROLS);
data.params.set_volume.id = id;
data.params.set_volume.volume = volume;