mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-14 19:18:09 +02:00
proxy: refactor how PARAM_Props/PropInfo are handled
+ rename FEATURE_CONTROLS to FEATURE_PROPS + add accessor for the standard spa_param_info (info->params) + hide the low-level params API that nobody uses
This commit is contained in:
parent
b8d1f40111
commit
8a94937b2a
24 changed files with 634 additions and 675 deletions
|
|
@ -81,34 +81,37 @@ wp_device_get_properties (WpProxy * self)
|
|||
return wp_properties_new_wrap_dict (priv->info->props);
|
||||
}
|
||||
|
||||
struct spa_param_info *
|
||||
wp_device_get_param_info (WpProxy * self, guint * n_params)
|
||||
{
|
||||
WpDevicePrivate *priv = wp_device_get_instance_private (WP_DEVICE (self));
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_device_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
struct pw_device *pwp;
|
||||
int device_enum_params_result;
|
||||
struct pw_device *pwp = (struct pw_device *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_device_enum_params (pwp, 0, id, start, num,
|
||||
filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
pwp = (struct pw_device *) wp_proxy_get_pw_proxy (self);
|
||||
device_enum_params_result = pw_device_enum_params (pwp, 0, id, start, num,
|
||||
wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (device_enum_params_result >= 0);
|
||||
|
||||
return device_enum_params_result;
|
||||
static gint
|
||||
wp_device_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
struct pw_device *pwp = (struct pw_device *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_device_subscribe_params (pwp, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_device_set_param (WpProxy * self, guint32 id, guint32 flags,
|
||||
const WpSpaPod *param)
|
||||
{
|
||||
struct pw_device *pwp;
|
||||
int device_set_param_result;
|
||||
|
||||
pwp = (struct pw_device *) wp_proxy_get_pw_proxy (self);
|
||||
device_set_param_result = pw_device_set_param (pwp, id, flags,
|
||||
struct pw_device *pwp = (struct pw_device *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_device_set_param (pwp, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (device_set_param_result >= 0);
|
||||
|
||||
return device_set_param_result;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -124,6 +127,9 @@ device_event_info(void *data, const struct pw_device_info *info)
|
|||
|
||||
if (info->change_mask & PW_DEVICE_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_DEVICE_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
}
|
||||
|
||||
static const struct pw_device_events device_events = {
|
||||
|
|
@ -154,7 +160,9 @@ wp_device_class_init (WpDeviceClass * klass)
|
|||
|
||||
proxy_class->get_info = wp_device_get_info;
|
||||
proxy_class->get_properties = wp_device_get_properties;
|
||||
proxy_class->get_param_info = wp_device_get_param_info;
|
||||
proxy_class->enum_params = wp_device_enum_params;
|
||||
proxy_class->subscribe_params = wp_device_subscribe_params;
|
||||
proxy_class->set_param = wp_device_set_param;
|
||||
|
||||
proxy_class->pw_proxy_created = wp_device_pw_proxy_created;
|
||||
|
|
@ -203,7 +211,7 @@ wp_device_new_from_factory (WpCore * core,
|
|||
|
||||
struct _WpSpaDevice
|
||||
{
|
||||
WpDevice parent;
|
||||
WpProxy parent;
|
||||
struct spa_handle *handle;
|
||||
struct spa_device *interface;
|
||||
struct spa_hook listener;
|
||||
|
|
@ -336,12 +344,6 @@ wp_spa_device_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
}
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
wp_spa_device_get_info (WpProxy * proxy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static WpProperties *
|
||||
wp_spa_device_get_properties (WpProxy * proxy)
|
||||
{
|
||||
|
|
@ -354,13 +356,8 @@ wp_spa_device_enum_params (WpProxy * proxy, guint32 id, guint32 start,
|
|||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
WpSpaDevice *self = WP_SPA_DEVICE (proxy);
|
||||
int device_enum_params_result;
|
||||
|
||||
device_enum_params_result = spa_device_enum_params (self->interface,
|
||||
0, id, start, num, wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (device_enum_params_result >= 0);
|
||||
|
||||
return device_enum_params_result;
|
||||
return spa_device_enum_params (self->interface,
|
||||
0, id, start, num, filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
@ -368,13 +365,8 @@ wp_spa_device_set_param (WpProxy * proxy, guint32 id, guint32 flags,
|
|||
const WpSpaPod *param)
|
||||
{
|
||||
WpSpaDevice *self = WP_SPA_DEVICE (proxy);
|
||||
int device_set_param_result;
|
||||
|
||||
device_set_param_result = spa_device_set_param (self->interface,
|
||||
return spa_device_set_param (self->interface,
|
||||
id, flags, wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (device_set_param_result >= 0);
|
||||
|
||||
return device_set_param_result;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -387,7 +379,6 @@ wp_spa_device_class_init (WpSpaDeviceClass * klass)
|
|||
|
||||
proxy_class->augment = wp_spa_device_augment;
|
||||
|
||||
proxy_class->get_info = wp_spa_device_get_info;
|
||||
proxy_class->get_properties = wp_spa_device_get_properties;
|
||||
proxy_class->enum_params = wp_spa_device_enum_params;
|
||||
proxy_class->set_param = wp_spa_device_set_param;
|
||||
|
|
|
|||
|
|
@ -85,34 +85,32 @@ wp_endpoint_link_get_properties (WpProxy * proxy)
|
|||
return wp_properties_ref (priv->properties);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_endpoint_link_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpEndpointLink *self = WP_ENDPOINT_LINK (proxy);
|
||||
WpEndpointLinkPrivate *priv = wp_endpoint_link_get_instance_private (self);
|
||||
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_link_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
WpEndpointLinkPrivate *priv =
|
||||
wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (self));
|
||||
int endpoint_link_enum_params_result;
|
||||
|
||||
endpoint_link_enum_params_result =
|
||||
pw_endpoint_link_enum_params (priv->iface, 0, id, start, num,
|
||||
wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (endpoint_link_enum_params_result >= 0);
|
||||
|
||||
return endpoint_link_enum_params_result;
|
||||
return pw_endpoint_link_enum_params (priv->iface, 0, id, start, num,
|
||||
filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_link_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_endpoint_link_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
WpEndpointLinkPrivate *priv =
|
||||
wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (self));
|
||||
int endpoint_link_subscribe_params_result;
|
||||
|
||||
endpoint_link_subscribe_params_result =
|
||||
pw_endpoint_link_subscribe_params (priv->iface, ids, n_ids);
|
||||
g_warn_if_fail (endpoint_link_subscribe_params_result >= 0);
|
||||
|
||||
return endpoint_link_subscribe_params_result;
|
||||
return pw_endpoint_link_subscribe_params (priv->iface, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
@ -121,14 +119,8 @@ wp_endpoint_link_set_param (WpProxy * self, guint32 id, guint32 flags,
|
|||
{
|
||||
WpEndpointLinkPrivate *priv =
|
||||
wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (self));
|
||||
int endpoint_link_set_param_result;
|
||||
|
||||
endpoint_link_set_param_result =
|
||||
pw_endpoint_link_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (endpoint_link_set_param_result >= 0);
|
||||
|
||||
return endpoint_link_set_param_result;
|
||||
return pw_endpoint_link_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -152,6 +144,9 @@ endpoint_link_event_info (void *data, const struct pw_endpoint_link_info *info)
|
|||
if (info->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
if (info->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_STATE) {
|
||||
g_signal_emit (self, signals[SIGNAL_STATE_CHANGED], 0,
|
||||
old_state, info->state, info->error);
|
||||
|
|
@ -188,6 +183,7 @@ wp_endpoint_link_class_init (WpEndpointLinkClass * klass)
|
|||
|
||||
proxy_class->get_info = wp_endpoint_link_get_info;
|
||||
proxy_class->get_properties = wp_endpoint_link_get_properties;
|
||||
proxy_class->get_param_info = wp_endpoint_link_get_param_info;
|
||||
proxy_class->enum_params = wp_endpoint_link_enum_params;
|
||||
proxy_class->subscribe_params = wp_endpoint_link_subscribe_params;
|
||||
proxy_class->set_param = wp_endpoint_link_set_param;
|
||||
|
|
@ -609,6 +605,7 @@ wp_impl_endpoint_link_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
self->info.n_params = 0;
|
||||
priv->info = &self->info;
|
||||
g_object_notify (G_OBJECT (self), "info");
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
|
||||
}
|
||||
|
|
@ -644,9 +641,9 @@ wp_impl_endpoint_link_class_init (WpImplEndpointLinkClass * klass)
|
|||
object_class->get_property = wp_impl_endpoint_link_get_property;
|
||||
|
||||
proxy_class->augment = wp_impl_endpoint_link_augment;
|
||||
|
||||
proxy_class->enum_params = NULL;
|
||||
proxy_class->subscribe_params = NULL;
|
||||
proxy_class->pw_proxy_created = NULL;
|
||||
proxy_class->param = NULL;
|
||||
|
||||
g_object_class_install_property (object_class, IMPL_PROP_ITEM,
|
||||
g_param_spec_object ("item", "item", "item", WP_TYPE_SI_LINK,
|
||||
|
|
|
|||
|
|
@ -63,25 +63,6 @@ wp_endpoint_stream_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (wp_endpoint_stream_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
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_PROXY_FEATURE_CONTROLS) {
|
||||
struct pw_endpoint_stream *pw_proxy = NULL;
|
||||
uint32_t ids[] = { SPA_PARAM_Props };
|
||||
|
||||
pw_proxy = (struct pw_endpoint_stream *) wp_proxy_get_pw_proxy (proxy);
|
||||
if (!pw_proxy)
|
||||
return;
|
||||
|
||||
pw_endpoint_stream_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL);
|
||||
pw_endpoint_stream_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids));
|
||||
}
|
||||
}
|
||||
|
||||
static gconstpointer
|
||||
wp_endpoint_stream_get_info (WpProxy * proxy)
|
||||
{
|
||||
|
|
@ -100,34 +81,32 @@ wp_endpoint_stream_get_properties (WpProxy * proxy)
|
|||
return wp_properties_ref (priv->properties);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_endpoint_stream_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpEndpointStream *self = WP_ENDPOINT_STREAM (proxy);
|
||||
WpEndpointStreamPrivate *priv = wp_endpoint_stream_get_instance_private (self);
|
||||
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_stream_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
WpEndpointStreamPrivate *priv =
|
||||
wp_endpoint_stream_get_instance_private (WP_ENDPOINT_STREAM (self));
|
||||
int endpoint_stream_enum_params_result;
|
||||
|
||||
endpoint_stream_enum_params_result =
|
||||
pw_endpoint_stream_enum_params (priv->iface, 0, id, start, num,
|
||||
wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (endpoint_stream_enum_params_result >= 0);
|
||||
|
||||
return endpoint_stream_enum_params_result;
|
||||
return pw_endpoint_stream_enum_params (priv->iface, 0, id, start, num,
|
||||
filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_stream_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_endpoint_stream_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
WpEndpointStreamPrivate *priv =
|
||||
wp_endpoint_stream_get_instance_private (WP_ENDPOINT_STREAM (self));
|
||||
int endpoint_stream_subscribe_params_result;
|
||||
|
||||
endpoint_stream_subscribe_params_result =
|
||||
pw_endpoint_stream_subscribe_params (priv->iface, ids, n_ids);
|
||||
g_warn_if_fail (endpoint_stream_subscribe_params_result >= 0);
|
||||
|
||||
return endpoint_stream_subscribe_params_result;
|
||||
return pw_endpoint_stream_subscribe_params (priv->iface, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
@ -136,14 +115,8 @@ wp_endpoint_stream_set_param (WpProxy * self, guint32 id, guint32 flags,
|
|||
{
|
||||
WpEndpointStreamPrivate *priv =
|
||||
wp_endpoint_stream_get_instance_private (WP_ENDPOINT_STREAM (self));
|
||||
int endpoint_stream_set_param_result;
|
||||
|
||||
endpoint_stream_set_param_result =
|
||||
pw_endpoint_stream_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (endpoint_stream_set_param_result >= 0);
|
||||
|
||||
return endpoint_stream_set_param_result;
|
||||
return pw_endpoint_stream_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -164,6 +137,9 @@ endpoint_stream_event_info (void *data, const struct pw_endpoint_stream_info *in
|
|||
|
||||
if (info->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
}
|
||||
|
||||
static const struct pw_endpoint_stream_events endpoint_stream_events = {
|
||||
|
|
@ -201,9 +177,9 @@ wp_endpoint_stream_class_init (WpEndpointStreamClass * klass)
|
|||
proxy_class->pw_iface_type = PW_TYPE_INTERFACE_EndpointStream;
|
||||
proxy_class->pw_iface_version = PW_VERSION_ENDPOINT_STREAM;
|
||||
|
||||
proxy_class->augment = wp_endpoint_stream_augment;
|
||||
proxy_class->get_info = wp_endpoint_stream_get_info;
|
||||
proxy_class->get_properties = wp_endpoint_stream_get_properties;
|
||||
proxy_class->get_param_info = wp_endpoint_stream_get_param_info;
|
||||
proxy_class->enum_params = wp_endpoint_stream_enum_params;
|
||||
proxy_class->subscribe_params = wp_endpoint_stream_subscribe_params;
|
||||
proxy_class->set_param = wp_endpoint_stream_set_param;
|
||||
|
|
@ -294,11 +270,11 @@ impl_enum_params (void *object, int seq,
|
|||
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));
|
||||
WpSpaProps *props = wp_proxy_get_spa_props (WP_PROXY (self));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_PropInfo: {
|
||||
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (controls);
|
||||
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (props);
|
||||
|
||||
for (guint i = start; i < params->len; i++) {
|
||||
WpSpaPod *pod = g_ptr_array_index (params, i);
|
||||
|
|
@ -306,7 +282,6 @@ impl_enum_params (void *object, int seq,
|
|||
|
||||
if (spa_pod_filter (&b, &result, param, filter) == 0) {
|
||||
pw_endpoint_stream_emit_param (&self->hooks, seq, id, i, i+1, result);
|
||||
wp_proxy_handle_event_param (self, seq, id, i, i+1, result);
|
||||
if (++count == num)
|
||||
break;
|
||||
}
|
||||
|
|
@ -315,11 +290,10 @@ impl_enum_params (void *object, int seq,
|
|||
}
|
||||
case SPA_PARAM_Props: {
|
||||
if (start == 0) {
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (controls);
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (props);
|
||||
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);
|
||||
wp_proxy_handle_event_param (self, seq, id, 0, 1, result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -350,26 +324,24 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
|
|||
{
|
||||
WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object);
|
||||
g_autoptr (GPtrArray) changed_ids = NULL;
|
||||
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
|
||||
WpSpaProps *props = 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 (controls, pod, changed_ids);
|
||||
wp_spa_props_store_from_props (props, pod, changed_ids);
|
||||
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar *prop_id = g_ptr_array_index (changed_ids, i);
|
||||
g_signal_emit_by_name (self, "prop-changed", prop_id);
|
||||
}
|
||||
|
||||
/* notify subscribers */
|
||||
if (self->subscribed)
|
||||
impl_enum_params (self, 1, SPA_PARAM_Props, 0, UINT32_MAX, NULL);
|
||||
|
||||
/* notify controls locally */
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
|
||||
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
|
||||
prop_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +398,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_PROXY_FEATURE_CONTROLS);
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_PROPS);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -527,6 +499,7 @@ wp_impl_endpoint_stream_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
self->info.n_params = SPA_N_ELEMENTS (impl_param_info);
|
||||
priv->info = &self->info;
|
||||
g_object_notify (G_OBJECT (self), "info");
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
|
||||
}
|
||||
|
|
@ -562,9 +535,9 @@ wp_impl_endpoint_stream_class_init (WpImplEndpointStreamClass * klass)
|
|||
object_class->get_property = wp_impl_endpoint_stream_get_property;
|
||||
|
||||
proxy_class->augment = wp_impl_endpoint_stream_augment;
|
||||
|
||||
proxy_class->enum_params = NULL;
|
||||
proxy_class->subscribe_params = NULL;
|
||||
proxy_class->pw_proxy_created = NULL;
|
||||
proxy_class->param = NULL;
|
||||
|
||||
g_object_class_install_property (object_class, IMPL_PROP_ITEM,
|
||||
g_param_spec_object ("item", "item", "item", WP_TYPE_SI_STREAM,
|
||||
|
|
|
|||
|
|
@ -150,18 +150,6 @@ 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_PROXY_FEATURE_CONTROLS) {
|
||||
struct pw_endpoint *pw_proxy = NULL;
|
||||
uint32_t ids[] = { SPA_PARAM_Props };
|
||||
|
||||
pw_proxy = (struct pw_endpoint *) wp_proxy_get_pw_proxy (proxy);
|
||||
if (!pw_proxy)
|
||||
return;
|
||||
|
||||
pw_endpoint_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL);
|
||||
pw_endpoint_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids));
|
||||
}
|
||||
|
||||
if (features & WP_ENDPOINT_FEATURE_STREAMS) {
|
||||
priv->ft_streams_requested = TRUE;
|
||||
wp_endpoint_ensure_feature_streams (self, 0);
|
||||
|
|
@ -186,33 +174,32 @@ wp_endpoint_get_properties (WpProxy * proxy)
|
|||
return wp_properties_ref (priv->properties);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_endpoint_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpEndpoint *self = WP_ENDPOINT (proxy);
|
||||
WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self);
|
||||
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
WpEndpointPrivate *priv =
|
||||
wp_endpoint_get_instance_private (WP_ENDPOINT (self));
|
||||
int endpoint_enum_params_result;
|
||||
|
||||
endpoint_enum_params_result = pw_endpoint_enum_params (priv->iface, 0, id,
|
||||
start, num, wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (endpoint_enum_params_result >= 0);
|
||||
|
||||
return endpoint_enum_params_result;
|
||||
return pw_endpoint_enum_params (priv->iface, 0, id,
|
||||
start, num, filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_endpoint_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_endpoint_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
WpEndpointPrivate *priv =
|
||||
wp_endpoint_get_instance_private (WP_ENDPOINT (self));
|
||||
int endpoint_subscribe_params_result;
|
||||
|
||||
endpoint_subscribe_params_result = pw_endpoint_subscribe_params (priv->iface,
|
||||
ids, n_ids);
|
||||
g_warn_if_fail (endpoint_subscribe_params_result >= 0);
|
||||
|
||||
return endpoint_subscribe_params_result;
|
||||
return pw_endpoint_subscribe_params (priv->iface, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
@ -221,13 +208,8 @@ wp_endpoint_set_param (WpProxy * self, guint32 id, guint32 flags,
|
|||
{
|
||||
WpEndpointPrivate *priv =
|
||||
wp_endpoint_get_instance_private (WP_ENDPOINT (self));
|
||||
int endpoint_set_param_result;
|
||||
|
||||
endpoint_set_param_result = pw_endpoint_set_param (priv->iface, id, flags,
|
||||
return pw_endpoint_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (endpoint_set_param_result >= 0);
|
||||
|
||||
return endpoint_set_param_result;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -249,6 +231,9 @@ endpoint_event_info (void *data, const struct pw_endpoint_info *info)
|
|||
if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
wp_endpoint_ensure_feature_streams (self, 0);
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +296,7 @@ wp_endpoint_class_init (WpEndpointClass * klass)
|
|||
proxy_class->augment = wp_endpoint_augment;
|
||||
proxy_class->get_info = wp_endpoint_get_info;
|
||||
proxy_class->get_properties = wp_endpoint_get_properties;
|
||||
proxy_class->get_param_info = wp_endpoint_get_param_info;
|
||||
proxy_class->enum_params = wp_endpoint_enum_params;
|
||||
proxy_class->subscribe_params = wp_endpoint_subscribe_params;
|
||||
proxy_class->set_param = wp_endpoint_set_param;
|
||||
|
|
@ -619,10 +605,8 @@ impl_enum_params (void *object, int seq,
|
|||
for (guint i = start; i < params->len; i++) {
|
||||
WpSpaPod *pod = g_ptr_array_index (params, i);
|
||||
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, i, i+1, result);
|
||||
wp_proxy_handle_event_param (self, seq, id, i, i+1, result);
|
||||
if (++count == num)
|
||||
break;
|
||||
}
|
||||
|
|
@ -635,7 +619,6 @@ impl_enum_params (void *object, int seq,
|
|||
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);
|
||||
wp_proxy_handle_event_param (self, seq, id, 0, 1, result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -666,26 +649,24 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
|
|||
{
|
||||
WpImplEndpoint *self = WP_IMPL_ENDPOINT (object);
|
||||
g_autoptr (GPtrArray) changed_ids = NULL;
|
||||
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
|
||||
WpSpaProps *props = 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 (controls, pod, changed_ids);
|
||||
wp_spa_props_store_from_props (props, pod, changed_ids);
|
||||
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar *prop_id = g_ptr_array_index (changed_ids, i);
|
||||
g_signal_emit_by_name (self, "prop-changed", prop_id);
|
||||
}
|
||||
|
||||
/* notify subscribers */
|
||||
if (self->subscribed)
|
||||
impl_enum_params (self, 1, SPA_PARAM_Props, 0, UINT32_MAX, NULL);
|
||||
|
||||
/* notify controls locally */
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
|
||||
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
|
||||
prop_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -917,7 +898,7 @@ wp_impl_endpoint_init (WpImplEndpoint * self)
|
|||
|
||||
priv->iface = (struct pw_endpoint *) &self->iface;
|
||||
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_CONTROLS);
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_PROPS);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1025,6 +1006,7 @@ wp_impl_endpoint_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
self->info.n_params = SPA_N_ELEMENTS (impl_param_info);
|
||||
priv->info = &self->info;
|
||||
g_object_notify (G_OBJECT (self), "info");
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_INFO);
|
||||
}
|
||||
|
|
@ -1065,9 +1047,9 @@ wp_impl_endpoint_class_init (WpImplEndpointClass * klass)
|
|||
object_class->get_property = wp_impl_endpoint_get_property;
|
||||
|
||||
proxy_class->augment = wp_impl_endpoint_augment;
|
||||
|
||||
proxy_class->enum_params = NULL;
|
||||
proxy_class->subscribe_params = NULL;
|
||||
proxy_class->pw_proxy_created = NULL;
|
||||
proxy_class->param = NULL;
|
||||
|
||||
g_object_class_install_property (object_class, IMPL_PROP_ITEM,
|
||||
g_param_spec_object ("item", "item", "item", WP_TYPE_SI_ENDPOINT,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ typedef enum { /*< flags >*/
|
|||
*/
|
||||
#define WP_ENDPOINT_FEATURES_STANDARD \
|
||||
(WP_PROXY_FEATURES_STANDARD | \
|
||||
WP_PROXY_FEATURE_CONTROLS | \
|
||||
WP_PROXY_FEATURE_PROPS | \
|
||||
WP_ENDPOINT_FEATURE_STREAMS)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -147,47 +147,37 @@ wp_node_get_properties (WpProxy * self)
|
|||
return wp_properties_new_wrap_dict (priv->info->props);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_node_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpNodePrivate *priv = wp_node_get_instance_private (WP_NODE (proxy));
|
||||
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_node_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
struct pw_node *pwp;
|
||||
int node_enum_params_result;
|
||||
|
||||
pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
node_enum_params_result = pw_node_enum_params (pwp, 0, id, start, num,
|
||||
struct pw_node *pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_node_enum_params (pwp, 0, id, start, num,
|
||||
filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
g_warn_if_fail (node_enum_params_result >= 0);
|
||||
|
||||
return node_enum_params_result;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_node_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_node_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
struct pw_node *pwp;
|
||||
int node_subscribe_params_result;
|
||||
|
||||
pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
node_subscribe_params_result = pw_node_subscribe_params (pwp, ids, n_ids);
|
||||
g_warn_if_fail (node_subscribe_params_result >= 0);
|
||||
|
||||
return node_subscribe_params_result;
|
||||
struct pw_node *pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_node_subscribe_params (pwp, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_node_set_param (WpProxy * self, guint32 id, guint32 flags,
|
||||
const WpSpaPod *param)
|
||||
{
|
||||
struct pw_node *pwp;
|
||||
int node_set_param_result;
|
||||
|
||||
pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
node_set_param_result = pw_node_set_param (pwp, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (node_set_param_result >= 0);
|
||||
|
||||
return node_set_param_result;
|
||||
struct pw_node *pwp = (struct pw_node *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_node_set_param (pwp, id, flags, wp_spa_pod_get_spa_pod (param));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -206,6 +196,9 @@ node_event_info(void *data, const struct pw_node_info *info)
|
|||
if (info->change_mask & PW_NODE_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
|
||||
if (info->change_mask & PW_NODE_CHANGE_MASK_STATE)
|
||||
g_signal_emit (self, signals[SIGNAL_STATE_CHANGED], 0, old_state,
|
||||
priv->info->state);
|
||||
|
|
@ -249,6 +242,7 @@ wp_node_class_init (WpNodeClass * klass)
|
|||
proxy_class->augment = wp_node_augment;
|
||||
proxy_class->get_info = wp_node_get_info;
|
||||
proxy_class->get_properties = wp_node_get_properties;
|
||||
proxy_class->get_param_info = wp_node_get_param_info;
|
||||
proxy_class->enum_params = wp_node_enum_params;
|
||||
proxy_class->subscribe_params = wp_node_subscribe_params;
|
||||
proxy_class->set_param = wp_node_set_param;
|
||||
|
|
@ -604,11 +598,9 @@ wp_impl_node_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
PW_TYPE_INTERFACE_Node, NULL, self->pw_impl_node, 0));
|
||||
}
|
||||
|
||||
if (features & WP_NODE_FEATURE_PORTS) {
|
||||
WpNodePrivate *priv = wp_node_get_instance_private (WP_NODE (self));
|
||||
priv->ft_ports_requested = TRUE;
|
||||
wp_node_ensure_feature_ports (WP_NODE (self), 0);
|
||||
}
|
||||
/* get misc features from the parent implementation */
|
||||
features &= ~WP_PROXY_FEATURES_STANDARD;
|
||||
WP_PROXY_CLASS (wp_impl_node_parent_class)->augment (proxy, features);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -64,32 +64,28 @@ wp_port_get_properties (WpProxy * self)
|
|||
return wp_properties_new_wrap_dict (WP_PORT (self)->info->props);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_port_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpPort *self = WP_PORT (proxy);
|
||||
*n_params = self->info->n_params;
|
||||
return self->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_port_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
struct pw_port *pwp;
|
||||
int port_enum_params_result;
|
||||
|
||||
pwp = (struct pw_port *) wp_proxy_get_pw_proxy (self);
|
||||
port_enum_params_result = pw_port_enum_params (pwp, 0, id, start, num,
|
||||
wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (port_enum_params_result >= 0);
|
||||
|
||||
return port_enum_params_result;
|
||||
struct pw_port *pwp = (struct pw_port *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_port_enum_params (pwp, 0, id, start, num,
|
||||
filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_port_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_port_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
struct pw_port *pwp;
|
||||
int port_subscribe_params_result;
|
||||
|
||||
pwp = (struct pw_port *) wp_proxy_get_pw_proxy (self);
|
||||
port_subscribe_params_result = pw_port_subscribe_params (pwp, ids, n_ids);
|
||||
g_warn_if_fail (port_subscribe_params_result >= 0);
|
||||
|
||||
return port_subscribe_params_result;
|
||||
struct pw_port *pwp = (struct pw_port *) wp_proxy_get_pw_proxy (self);
|
||||
return pw_port_subscribe_params (pwp, ids, n_ids);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -104,6 +100,9 @@ port_event_info(void *data, const struct pw_port_info *info)
|
|||
|
||||
if (info->change_mask & PW_PORT_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_PORT_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
}
|
||||
|
||||
static const struct pw_port_events port_events = {
|
||||
|
|
@ -133,6 +132,7 @@ wp_port_class_init (WpPortClass * klass)
|
|||
|
||||
proxy_class->get_info = wp_port_get_info;
|
||||
proxy_class->get_properties = wp_port_get_properties;
|
||||
proxy_class->get_param_info = wp_port_get_param_info;
|
||||
proxy_class->enum_params = wp_port_enum_params;
|
||||
proxy_class->subscribe_params = wp_port_subscribe_params;
|
||||
|
||||
|
|
|
|||
446
lib/wp/proxy.c
446
lib/wp/proxy.c
|
|
@ -48,8 +48,8 @@ struct _WpProxyPrivate
|
|||
|
||||
GHashTable *async_tasks; // <int seq, GTask*>
|
||||
|
||||
/* controls */
|
||||
WpSpaProps controls;
|
||||
/* props cache */
|
||||
WpSpaProps props;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -62,6 +62,7 @@ enum {
|
|||
PROP_PW_PROXY,
|
||||
PROP_INFO,
|
||||
PROP_PROPERTIES,
|
||||
PROP_PARAM_INFO,
|
||||
PROP_BOUND_ID,
|
||||
};
|
||||
|
||||
|
|
@ -71,7 +72,7 @@ enum
|
|||
SIGNAL_PW_PROXY_DESTROYED,
|
||||
SIGNAL_BOUND,
|
||||
SIGNAL_PARAM,
|
||||
SIGNAL_CONTROL_CHANGED,
|
||||
SIGNAL_PROP_CHANGED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
|
|
@ -214,7 +215,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);
|
||||
wp_spa_props_clear (&priv->props);
|
||||
|
||||
G_OBJECT_CLASS (wp_proxy_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
@ -271,6 +272,9 @@ wp_proxy_get_gobj_property (GObject * object, guint property_id, GValue * value,
|
|||
case PROP_PROPERTIES:
|
||||
g_value_take_boxed (value, wp_proxy_get_properties (self));
|
||||
break;
|
||||
case PROP_PARAM_INFO:
|
||||
g_value_take_variant (value, wp_proxy_get_param_info (self));
|
||||
break;
|
||||
case PROP_BOUND_ID:
|
||||
g_value_set_uint (value, wp_proxy_get_bound_id (self));
|
||||
break;
|
||||
|
|
@ -304,56 +308,23 @@ wp_proxy_default_augment (WpProxy * self, WpProxyFeatures features)
|
|||
/* bind */
|
||||
wp_proxy_set_pw_proxy (self, wp_global_bind (priv->global));
|
||||
}
|
||||
}
|
||||
|
||||
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 (features & WP_PROXY_FEATURE_PROPS) {
|
||||
WpProxyClass *klass = WP_PROXY_GET_CLASS (self);
|
||||
uint32_t ids[] = { SPA_PARAM_Props };
|
||||
|
||||
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);
|
||||
if (!klass->enum_params || !klass->subscribe_params) {
|
||||
wp_proxy_augment_error (self, g_error_new (WP_DOMAIN_LIBRARY,
|
||||
WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"Proxy does not support enum/subscribe params API"));
|
||||
return;
|
||||
}
|
||||
|
||||
wp_proxy_set_feature_ready (self, WP_PROXY_FEATURE_CONTROLS);
|
||||
klass->enum_params (self, SPA_PARAM_PropInfo, 0, -1, NULL);
|
||||
klass->subscribe_params (self, ids, SPA_N_ELEMENTS (ids));
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -365,9 +336,6 @@ wp_proxy_class_init (WpProxyClass * klass)
|
|||
object_class->set_property = wp_proxy_set_gobj_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 */
|
||||
|
||||
|
|
@ -408,6 +376,11 @@ wp_proxy_class_init (WpProxyClass * klass)
|
|||
"The pipewire properties of the object", WP_TYPE_PROPERTIES,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PARAM_INFO,
|
||||
g_param_spec_variant ("param-info", "param-info",
|
||||
"The param info of the object", G_VARIANT_TYPE ("a{ss}"), NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_BOUND_ID,
|
||||
g_param_spec_uint ("bound-id", "bound-id",
|
||||
"The id that this object has on the registry", 0, G_MAXUINT, 0,
|
||||
|
|
@ -429,15 +402,9 @@ wp_proxy_class_init (WpProxyClass * klass)
|
|||
G_STRUCT_OFFSET (WpProxyClass, bound), NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
|
||||
wp_proxy_signals[SIGNAL_PARAM] = g_signal_new (
|
||||
"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);
|
||||
wp_proxy_signals[SIGNAL_PROP_CHANGED] = g_signal_new (
|
||||
"prop-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
}
|
||||
|
||||
/* private */
|
||||
|
|
@ -730,6 +697,69 @@ wp_proxy_get_property (WpProxy * self, const gchar * key)
|
|||
return props ? wp_properties_get (props, key) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_get_param_info:
|
||||
* @self: the proxy
|
||||
*
|
||||
* Returns the available parameters of this proxy. The return value is
|
||||
* a variant of type `a{ss}`, where the key of each map entry is a spa param
|
||||
* type id (the same ids that you can pass in wp_proxy_enum_params())
|
||||
* and the value is a string that can contain the following letters,
|
||||
* each of them representing a flag:
|
||||
* - `r`: the param is readable (`SPA_PARAM_INFO_READ`)
|
||||
* - `w`: the param is writable (`SPA_PARAM_INFO_WRITE`)
|
||||
* - `s`: the param was updated (`SPA_PARAM_INFO_SERIAL`)
|
||||
*
|
||||
* For params that are readable, you can query them with wp_proxy_enum_params()
|
||||
*
|
||||
* Params that are writable can be set with wp_proxy_set_param()
|
||||
*
|
||||
* Requires %WP_PROXY_FEATURE_INFO
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a variant of type `a{ss}` or %NULL
|
||||
* if the proxy does not support params at all
|
||||
*/
|
||||
GVariant *
|
||||
wp_proxy_get_param_info (WpProxy * self)
|
||||
{
|
||||
g_auto (GVariantBuilder) b =
|
||||
G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_DICTIONARY);
|
||||
guint n_params = 0;
|
||||
struct spa_param_info *info;
|
||||
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
|
||||
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_warn_if_fail (priv->ft_ready & WP_PROXY_FEATURE_INFO);
|
||||
|
||||
info = (WP_PROXY_GET_CLASS (self)->get_param_info) ?
|
||||
WP_PROXY_GET_CLASS (self)->get_param_info (self, &n_params) : NULL;
|
||||
if (!info || n_params == 0)
|
||||
return NULL;
|
||||
|
||||
for (guint i = 0; i < n_params; i++) {
|
||||
const gchar *nick = NULL;
|
||||
gchar flags[4];
|
||||
guint flags_idx = 0;
|
||||
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, info[i].id, NULL, &nick,
|
||||
NULL);
|
||||
g_return_val_if_fail (nick != NULL, NULL);
|
||||
|
||||
if (info[i].flags & SPA_PARAM_INFO_READ)
|
||||
flags[flags_idx++] = 'r';
|
||||
if (info[i].flags & SPA_PARAM_INFO_WRITE)
|
||||
flags[flags_idx++] = 'w';
|
||||
if (info[i].flags & SPA_PARAM_INFO_SERIAL)
|
||||
flags[flags_idx++] = 's';
|
||||
flags[flags_idx] = '\0';
|
||||
|
||||
g_variant_builder_add (&b, "{ss}", nick, flags);
|
||||
}
|
||||
|
||||
return g_variant_builder_end (&b);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_get_bound_id:
|
||||
* @self: the proxy
|
||||
|
|
@ -781,42 +811,6 @@ wp_proxy_find_async_task (WpProxy * self, int seq, gboolean steal)
|
|||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_enum_params:
|
||||
* @self: the proxy
|
||||
* @id: the parameter id to enum or PW_ID_ANY for all
|
||||
* @start: the start index or 0 for the first param
|
||||
* @num: the maximum number of params to retrieve
|
||||
* @filter: (nullable): a param filter or NULL
|
||||
*
|
||||
* Starts enumeration of object parameters. For each param, the
|
||||
* #WpProxy::param signal will be emited.
|
||||
*
|
||||
* This method gives access to the low level `enum_params` method of the object,
|
||||
* if it exists. For most use cases, prefer using a higher level API, such as
|
||||
* wp_proxy_enum_params_collect() or something from the subclasses of #WpProxy
|
||||
*
|
||||
* Returns: On success, this returns a sequence number that can be used
|
||||
* to track which emissions of the #WpProxy::param signal are responses
|
||||
* to this call. On failure, it returns a negative number, which could be:
|
||||
* * -EINVAL: An invalid parameter was passed
|
||||
* * -EIO: The object is not ready to receive this method call
|
||||
* * -ENOTSUP: this method is not supported on this object
|
||||
*/
|
||||
gint
|
||||
wp_proxy_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), -EINVAL);
|
||||
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_return_val_if_fail (priv->pw_proxy, -EIO);
|
||||
|
||||
return (WP_PROXY_GET_CLASS (self)->enum_params) ?
|
||||
WP_PROXY_GET_CLASS (self)->enum_params (self, id, start, num, filter) :
|
||||
-ENOTSUP;
|
||||
}
|
||||
|
||||
static void
|
||||
enum_params_done (WpCore * core, GAsyncResult * res, gpointer data)
|
||||
{
|
||||
|
|
@ -842,28 +836,26 @@ enum_params_done (WpCore * core, GAsyncResult * res, gpointer data)
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_enum_params_collect:
|
||||
* wp_proxy_enum_params:
|
||||
* @self: the proxy
|
||||
* @id: the parameter id to enum or PW_ID_ANY for all
|
||||
* @start: the start index or 0 for the first param
|
||||
* @num: the maximum number of params to retrieve
|
||||
* @filter: (nullable): a param filter or NULL
|
||||
* @id: (nullable): the parameter id to enumerate or %NULL for all parameters
|
||||
* @filter: (nullable): a param filter or %NULL
|
||||
* @cancellable: (nullable): a cancellable for the async operation
|
||||
* @callback: (scope async): a callback to call with the result
|
||||
* @user_data: (closure): data to pass to @callback
|
||||
*
|
||||
* Enumerate object parameters. This will asynchronously return the result,
|
||||
* or an error, by calling the given @callback. The result is going to
|
||||
* be a #GPtrArray containing spa_pod pointers, which can be retrieved
|
||||
* with wp_proxy_enum_params_collect_finish().
|
||||
* be a #WpIterator containing #WpSpaPod objects, which can be retrieved
|
||||
* with wp_proxy_enum_params_finish().
|
||||
*/
|
||||
void
|
||||
wp_proxy_enum_params_collect (WpProxy * self,
|
||||
guint32 id, guint32 start, guint32 num, const WpSpaPod * filter,
|
||||
GCancellable * cancellable, GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
wp_proxy_enum_params (WpProxy * self, const gchar * id,
|
||||
const WpSpaPod *filter, GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback, gpointer user_data)
|
||||
{
|
||||
g_autoptr (GTask) task = NULL;
|
||||
guint32 id_num = 0;
|
||||
int seq;
|
||||
GPtrArray *params;
|
||||
|
||||
|
|
@ -874,9 +866,18 @@ wp_proxy_enum_params_collect (WpProxy * self,
|
|||
params = g_ptr_array_new_with_free_func ((GDestroyNotify) wp_spa_pod_unref);
|
||||
g_task_set_task_data (task, params, (GDestroyNotify) g_ptr_array_unref);
|
||||
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id, &id_num,
|
||||
NULL, NULL)) {
|
||||
wp_critical_object (self, "invalid param id: %s", id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* call enum_params */
|
||||
seq = wp_proxy_enum_params (self, id, start, num, filter);
|
||||
seq = (WP_PROXY_GET_CLASS (self)->enum_params) ?
|
||||
WP_PROXY_GET_CLASS (self)->enum_params (self, id_num, 0, -1, filter) :
|
||||
-ENOTSUP;
|
||||
if (G_UNLIKELY (seq < 0)) {
|
||||
wp_message_object (self, "enum_params failed: %s", spa_strerror (seq));
|
||||
g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
|
||||
WP_LIBRARY_ERROR_OPERATION_FAILED, "enum_params failed: %s",
|
||||
spa_strerror (seq));
|
||||
|
|
@ -892,144 +893,127 @@ wp_proxy_enum_params_collect (WpProxy * self,
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_enum_params_collect_finish:
|
||||
* wp_proxy_enum_params_finish:
|
||||
* @self: the proxy
|
||||
* @res: the async result
|
||||
* @error: (out) (optional): the reported error of the operation, if any
|
||||
*
|
||||
* Returns: (transfer full) (element-type WpSpaPod*):
|
||||
* the collected params
|
||||
* Returns: (transfer full) (nullable): an iterator to iterate over the
|
||||
* collected params, or %NULL if the operation resulted in error;
|
||||
* the items in the iterator are #WpSpaPod
|
||||
*/
|
||||
GPtrArray *
|
||||
wp_proxy_enum_params_collect_finish (WpProxy * self,
|
||||
GAsyncResult * res, GError ** error)
|
||||
WpIterator *
|
||||
wp_proxy_enum_params_finish (WpProxy * self, GAsyncResult * res,
|
||||
GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
|
||||
g_return_val_if_fail (g_task_is_valid (res, self), NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (res), error);
|
||||
}
|
||||
GPtrArray *array = g_task_propagate_pointer (G_TASK (res), error);
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* wp_proxy_subscribe_params: (skip)
|
||||
* @self: the proxy
|
||||
* @n_ids: the number of IDs specified in the the variable arugments list
|
||||
*
|
||||
* Sets up the proxy to automatically emit the #WpProxy::param signal for
|
||||
* the given ids when they are changed.
|
||||
*
|
||||
* Returns: A positive number or zero on success. On failure, it returns
|
||||
* a negative number. Well known failure codes are:
|
||||
* * -EINVAL: An invalid parameter was passed
|
||||
* * -EIO: The object is not ready to receive this method call
|
||||
* * -ENOTSUP: this method is not supported on this object
|
||||
*/
|
||||
gint
|
||||
wp_proxy_subscribe_params (WpProxy * self, guint32 n_ids, ...)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), -EINVAL);
|
||||
g_return_val_if_fail (n_ids != 0, -EINVAL);
|
||||
|
||||
va_list args;
|
||||
guint32 *ids = g_alloca (n_ids * sizeof (guint32));
|
||||
|
||||
va_start (args, n_ids);
|
||||
for (gint i = 0; i < n_ids; i++)
|
||||
ids[i] = va_arg (args, guint32);
|
||||
va_end (args);
|
||||
|
||||
return wp_proxy_subscribe_params_array (self, n_ids, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_subscribe_params_array: (rename-to wp_proxy_subscribe_params)
|
||||
* @self: the proxy
|
||||
* @n_ids: the number of IDs specified in @ids
|
||||
* @ids: (array length=n_ids): a list of param IDs to subscribe to
|
||||
*
|
||||
* Sets up the proxy to automatically emit the #WpProxy::param signal for
|
||||
* the given ids when they are changed.
|
||||
*
|
||||
* Returns: A positive number or zero on success. On failure, it returns
|
||||
* a negative number. Well known failure codes are:
|
||||
* * -EINVAL: An invalid parameter was passed
|
||||
* * -EIO: The object is not ready to receive this method call
|
||||
* * -ENOTSUP: this method is not supported on this object
|
||||
*/
|
||||
gint
|
||||
wp_proxy_subscribe_params_array (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), -EINVAL);
|
||||
g_return_val_if_fail (n_ids != 0, -EINVAL);
|
||||
g_return_val_if_fail (ids != NULL, -EINVAL);
|
||||
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_return_val_if_fail (priv->pw_proxy, -EIO);
|
||||
|
||||
return (WP_PROXY_GET_CLASS (self)->subscribe_params) ?
|
||||
WP_PROXY_GET_CLASS (self)->subscribe_params (self, n_ids, ids) :
|
||||
-ENOTSUP;
|
||||
return wp_iterator_new_ptr_array (array, WP_TYPE_SPA_POD);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_set_param:
|
||||
* @self: the proxy
|
||||
* @id: the parameter id to set
|
||||
* @flags: extra parameter flags
|
||||
* @param: the parameter to set
|
||||
*
|
||||
* Sets a parameter on the object.
|
||||
*
|
||||
* Returns: A positive number or zero on success. On failure, it returns
|
||||
* a negative number. Well known failure codes are:
|
||||
* * -EINVAL: An invalid parameter was passed
|
||||
* * -EIO: The object is not ready to receive this method call
|
||||
* * -ENOTSUP: this method is not supported on this object
|
||||
*/
|
||||
gint
|
||||
wp_proxy_set_param (WpProxy * self, guint32 id, guint32 flags,
|
||||
const WpSpaPod *param)
|
||||
void
|
||||
wp_proxy_set_param (WpProxy * self, const gchar * id, const WpSpaPod *param)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), -EINVAL);
|
||||
guint32 id_num = 0;
|
||||
gint ret;
|
||||
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_return_val_if_fail (priv->pw_proxy, -EIO);
|
||||
g_return_if_fail (WP_IS_PROXY (self));
|
||||
|
||||
return (WP_PROXY_GET_CLASS (self)->set_param) ?
|
||||
WP_PROXY_GET_CLASS (self)->set_param (self, id, flags, param) :
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id, &id_num,
|
||||
NULL, NULL)) {
|
||||
wp_critical_object (self, "invalid param id: %s", id);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = (WP_PROXY_GET_CLASS (self)->set_param) ?
|
||||
WP_PROXY_GET_CLASS (self)->set_param (self, id_num, 0, param) :
|
||||
-ENOTSUP;
|
||||
if (G_UNLIKELY (ret < 0)) {
|
||||
wp_message_object (self, "set_param failed: %s", spa_strerror (ret));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_get_control:
|
||||
* wp_proxy_iterate_prop_info:
|
||||
* @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
|
||||
* Requires %WP_PROXY_FEATURE_PROPS
|
||||
*
|
||||
* Returns: (transfer full) (nullable): an iterator to iterate over the
|
||||
* `SPA_PARAM_PropInfo` params, or %NULL if the object has no props;
|
||||
* the items in the iterator are #WpSpaPod
|
||||
*/
|
||||
WpSpaPod *
|
||||
wp_proxy_get_control (WpProxy * self, const gchar * id_name)
|
||||
WpIterator *
|
||||
wp_proxy_iterate_prop_info (WpProxy * self)
|
||||
{
|
||||
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);
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_return_val_if_fail (priv->ft_ready & WP_PROXY_FEATURE_PROPS, NULL);
|
||||
|
||||
GPtrArray *array = wp_spa_props_build_propinfo (&priv->props);
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
return wp_iterator_new_ptr_array (array, WP_TYPE_SPA_POD);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_set_control:
|
||||
* wp_proxy_get_prop:
|
||||
* @self: the proxy
|
||||
* @id_name: the control id name
|
||||
* @value: the new value for this control, as a spa pod
|
||||
* @prop_name: the prop name
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE if an error occurred
|
||||
* Requires %WP_PROXY_FEATURE_PROPS
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the spa pod containing the value
|
||||
* of this prop, or %NULL if @prop_name does not exist on this proxy
|
||||
*/
|
||||
gboolean
|
||||
wp_proxy_set_control (WpProxy * self, const gchar * id_name,
|
||||
WpSpaPod *
|
||||
wp_proxy_get_prop (WpProxy * self, const gchar * prop_name)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_PROXY (self), NULL);
|
||||
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_return_val_if_fail (priv->ft_ready & WP_PROXY_FEATURE_PROPS, NULL);
|
||||
|
||||
return wp_spa_props_get_stored (&priv->props, prop_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_proxy_set_prop:
|
||||
* @self: the proxy
|
||||
* @prop_name: the prop name
|
||||
* @value: the new value for this prop, as a spa pod
|
||||
*
|
||||
* Sets a single property in the `SPA_PARAM_Props` param of this object.
|
||||
*/
|
||||
void
|
||||
wp_proxy_set_prop (WpProxy * self, const gchar * prop_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);
|
||||
g_return_if_fail (WP_IS_PROXY (self));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
return WP_PROXY_GET_CLASS (self)->set_control (self, id_name, value);
|
||||
g_autoptr (WpSpaPod) param = wp_spa_pod_new_object (
|
||||
"Props", "Props",
|
||||
prop_name, "P", value,
|
||||
NULL);
|
||||
|
||||
/* our spa_props will be updated by the param event */
|
||||
wp_proxy_set_param (self, "Props", param);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1037,22 +1021,50 @@ wp_proxy_handle_event_param (void * proxy, int seq, uint32_t id,
|
|||
uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
{
|
||||
WpProxy *self = WP_PROXY (proxy);
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
g_autoptr (WpSpaPod) w_param = wp_spa_pod_new_regular_wrap (param);
|
||||
GTask *task;
|
||||
|
||||
const gchar *id_name = NULL;
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, NULL, &id_name, NULL);
|
||||
g_return_if_fail (id_name);
|
||||
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_regular_wrap_copy (param);
|
||||
g_signal_emit (self, wp_proxy_signals[SIGNAL_PARAM], 0, seq, id_name, index,
|
||||
next, pod);
|
||||
|
||||
/* if this param event was emited because of enum_params_collect(),
|
||||
/* if this param event was emited because of enum_params(),
|
||||
* copy the param in the result array of that API */
|
||||
task = wp_proxy_find_async_task (self, seq, FALSE);
|
||||
if (task) {
|
||||
GPtrArray *array = g_task_get_task_data (task);
|
||||
g_ptr_array_add (array, g_steal_pointer (&pod));
|
||||
g_ptr_array_add (array, wp_spa_pod_copy (w_param));
|
||||
}
|
||||
/* else consider this to be a prop update, either triggered from augment()
|
||||
* or because we are subscribed to props */
|
||||
else {
|
||||
switch (id) {
|
||||
case SPA_PARAM_PropInfo:
|
||||
if (!(priv->ft_ready & WP_PROXY_FEATURE_PROPS)) {
|
||||
wp_trace_object (self, "got PropInfo");
|
||||
wp_trace_boxed (WP_TYPE_SPA_POD, w_param, "PropInfo pod");
|
||||
|
||||
wp_spa_props_register_from_prop_info (&priv->props, w_param);
|
||||
}
|
||||
break;
|
||||
case SPA_PARAM_Props: {
|
||||
g_autoptr (GPtrArray) changed_ids =
|
||||
g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
wp_trace_object (self, "got Props");
|
||||
wp_trace_boxed (WP_TYPE_SPA_POD, w_param, "Props pod");
|
||||
|
||||
wp_spa_props_store_from_props (&priv->props, w_param, changed_ids);
|
||||
wp_proxy_set_feature_ready (self, WP_PROXY_FEATURE_PROPS);
|
||||
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar *prop_id = g_ptr_array_index (changed_ids, i);
|
||||
g_signal_emit (self, wp_proxy_signals[SIGNAL_PROP_CHANGED], 0,
|
||||
prop_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* and ignore other kinds of params for now */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1060,5 +1072,5 @@ WpSpaProps *
|
|||
wp_proxy_get_spa_props (WpProxy * self)
|
||||
{
|
||||
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
|
||||
return &priv->controls;
|
||||
return &priv->props;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
struct pw_proxy;
|
||||
struct spa_param_info;
|
||||
typedef struct _WpCore WpCore;
|
||||
|
||||
/**
|
||||
|
|
@ -31,12 +32,15 @@ typedef struct _WpCore WpCore;
|
|||
* ones and they can also be enabled with wp_proxy_augment().
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
/* standard features */
|
||||
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 >*/
|
||||
/* param caching features */
|
||||
WP_PROXY_FEATURE_PROPS = (1 << 3),
|
||||
|
||||
WP_PROXY_FEATURE_LAST = (1 << 16), /*< skip >*/
|
||||
} WpProxyFeatures;
|
||||
|
||||
/**
|
||||
|
|
@ -78,24 +82,19 @@ struct _WpProxyClass
|
|||
|
||||
gconstpointer (*get_info) (WpProxy * self);
|
||||
WpProperties * (*get_properties) (WpProxy * self);
|
||||
struct spa_param_info * (*get_param_info) (WpProxy * self, guint * n_params);
|
||||
|
||||
gint (*enum_params) (WpProxy * self, guint32 id, guint32 start, guint32 num,
|
||||
const WpSpaPod * filter);
|
||||
gint (*subscribe_params) (WpProxy * self, guint32 n_ids, guint32 *ids);
|
||||
gint (*subscribe_params) (WpProxy * self, guint32 *ids, guint32 n_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 */
|
||||
|
||||
void (*pw_proxy_created) (WpProxy * self, struct pw_proxy * proxy);
|
||||
void (*pw_proxy_destroyed) (WpProxy * self);
|
||||
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);
|
||||
};
|
||||
|
||||
WP_API
|
||||
|
|
@ -144,43 +143,39 @@ WpProperties * wp_proxy_get_properties (WpProxy * self);
|
|||
WP_API
|
||||
const gchar * wp_proxy_get_property (WpProxy * self, const gchar * key);
|
||||
|
||||
WP_API
|
||||
GVariant * wp_proxy_get_param_info (WpProxy * self);
|
||||
|
||||
/* the bound id (aka global id, requires FEATURE_BOUND) */
|
||||
|
||||
WP_API
|
||||
guint32 wp_proxy_get_bound_id (WpProxy * self);
|
||||
|
||||
/* common API of most proxied objects */
|
||||
/* params API */
|
||||
|
||||
WP_API
|
||||
gint wp_proxy_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter);
|
||||
void wp_proxy_enum_params (WpProxy * self, const gchar * id,
|
||||
const WpSpaPod *filter, GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback, gpointer user_data);
|
||||
|
||||
WP_API
|
||||
void wp_proxy_enum_params_collect (WpProxy * self,
|
||||
guint32 id, guint32 start, guint32 num, const WpSpaPod *filter,
|
||||
GCancellable * cancellable, GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
WpIterator * wp_proxy_enum_params_finish (WpProxy * self, GAsyncResult * res,
|
||||
GError ** error);
|
||||
|
||||
WP_API
|
||||
GPtrArray * wp_proxy_enum_params_collect_finish (WpProxy * self,
|
||||
GAsyncResult * res, GError ** error);
|
||||
void wp_proxy_set_param (WpProxy * self, const gchar * id,
|
||||
const WpSpaPod * param);
|
||||
|
||||
/* PARAM_PropInfo - PARAM_Props */
|
||||
|
||||
WP_API
|
||||
gint wp_proxy_subscribe_params (WpProxy * self, guint32 n_ids, ...);
|
||||
WpIterator * wp_proxy_iterate_prop_info (WpProxy * self);
|
||||
|
||||
WP_API
|
||||
gint wp_proxy_subscribe_params_array (WpProxy * self, guint32 n_ids,
|
||||
guint32 *ids);
|
||||
WpSpaPod * wp_proxy_get_prop (WpProxy * self, const gchar * prop_name);
|
||||
|
||||
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,
|
||||
void wp_proxy_set_prop (WpProxy * self, const gchar * prop_name,
|
||||
const WpSpaPod * value);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
106
lib/wp/session.c
106
lib/wp/session.c
|
|
@ -196,31 +196,30 @@ wp_session_get_properties (WpProxy * proxy)
|
|||
return wp_properties_ref (priv->properties);
|
||||
}
|
||||
|
||||
static struct spa_param_info *
|
||||
wp_session_get_param_info (WpProxy * proxy, guint * n_params)
|
||||
{
|
||||
WpSession *self = WP_SESSION (proxy);
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (self);
|
||||
|
||||
*n_params = priv->info->n_params;
|
||||
return priv->info->params;
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_session_enum_params (WpProxy * self, guint32 id, guint32 start,
|
||||
guint32 num, const WpSpaPod * filter)
|
||||
{
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (WP_SESSION (self));
|
||||
int session_enum_params_result;
|
||||
|
||||
session_enum_params_result = pw_session_enum_params (priv->iface, 0, id,
|
||||
start, num, wp_spa_pod_get_spa_pod (filter));
|
||||
g_warn_if_fail (session_enum_params_result >= 0);
|
||||
|
||||
return session_enum_params_result;
|
||||
return pw_session_enum_params (priv->iface, 0, id,
|
||||
start, num, filter ? wp_spa_pod_get_spa_pod (filter) : NULL);
|
||||
}
|
||||
|
||||
static gint
|
||||
wp_session_subscribe_params (WpProxy * self, guint32 n_ids, guint32 *ids)
|
||||
wp_session_subscribe_params (WpProxy * self, guint32 *ids, guint32 n_ids)
|
||||
{
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (WP_SESSION (self));
|
||||
int session_subscribe_params_result;
|
||||
|
||||
session_subscribe_params_result = pw_session_subscribe_params (priv->iface,
|
||||
ids, n_ids);
|
||||
g_warn_if_fail (session_subscribe_params_result >= 0);
|
||||
|
||||
return session_subscribe_params_result;
|
||||
return pw_session_subscribe_params (priv->iface, ids, n_ids);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
@ -228,13 +227,8 @@ wp_session_set_param (WpProxy * self, guint32 id, guint32 flags,
|
|||
const WpSpaPod *param)
|
||||
{
|
||||
WpSessionPrivate *priv = wp_session_get_instance_private (WP_SESSION (self));
|
||||
int session_set_param_result;
|
||||
|
||||
session_set_param_result = pw_session_set_param (priv->iface, id, flags,
|
||||
return pw_session_set_param (priv->iface, id, flags,
|
||||
wp_spa_pod_get_spa_pod (param));
|
||||
g_warn_if_fail (session_set_param_result >= 0);
|
||||
|
||||
return session_set_param_result;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -255,6 +249,9 @@ session_event_info (void *data, const struct pw_session_info *info)
|
|||
|
||||
if (info->change_mask & PW_SESSION_CHANGE_MASK_PROPS)
|
||||
g_object_notify (G_OBJECT (self), "properties");
|
||||
|
||||
if (info->change_mask & PW_SESSION_CHANGE_MASK_PARAMS)
|
||||
g_object_notify (G_OBJECT (self), "param-info");
|
||||
}
|
||||
|
||||
static const struct pw_session_events session_events = {
|
||||
|
|
@ -280,18 +277,6 @@ wp_session_bound (WpProxy * proxy, guint32 id)
|
|||
wp_session_ensure_features_endpoints_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)
|
||||
{
|
||||
|
|
@ -301,18 +286,6 @@ 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_PROXY_FEATURE_CONTROLS) {
|
||||
struct pw_session *pw_proxy = NULL;
|
||||
uint32_t ids[] = { SPA_PARAM_Props };
|
||||
|
||||
pw_proxy = (struct pw_session *) wp_proxy_get_pw_proxy (proxy);
|
||||
if (!pw_proxy)
|
||||
return;
|
||||
|
||||
pw_session_enum_params (pw_proxy, 0, SPA_PARAM_PropInfo, 0, -1, NULL);
|
||||
pw_session_subscribe_params (pw_proxy, ids, SPA_N_ELEMENTS (ids));
|
||||
}
|
||||
|
||||
if (features & (WP_SESSION_FEATURE_ENDPOINTS | WP_SESSION_FEATURE_LINKS)) {
|
||||
priv->ft_endpoints_requested = (features & WP_SESSION_FEATURE_ENDPOINTS);
|
||||
priv->ft_links_requested = (features & WP_SESSION_FEATURE_LINKS);
|
||||
|
|
@ -323,7 +296,7 @@ wp_session_augment (WpProxy * proxy, WpProxyFeatures features)
|
|||
static guint32
|
||||
get_default_endpoint (WpSession * self, const gchar * id_name)
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_proxy_get_control (WP_PROXY (self), id_name);
|
||||
g_autoptr (WpSpaPod) pod = wp_proxy_get_prop (WP_PROXY (self), id_name);
|
||||
gint32 value;
|
||||
|
||||
if (pod && wp_spa_pod_get_int (pod, &value))
|
||||
|
|
@ -335,7 +308,7 @@ static void
|
|||
set_default_endpoint (WpSession * self, const gchar * id_name, guint32 id)
|
||||
{
|
||||
g_autoptr (WpSpaPod) param = wp_spa_pod_new_int (id);
|
||||
wp_proxy_set_control (WP_PROXY (self), id_name, param);
|
||||
wp_proxy_set_prop (WP_PROXY (self), id_name, param);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -352,13 +325,13 @@ wp_session_class_init (WpSessionClass * klass)
|
|||
proxy_class->augment = wp_session_augment;
|
||||
proxy_class->get_info = wp_session_get_info;
|
||||
proxy_class->get_properties = wp_session_get_properties;
|
||||
proxy_class->get_param_info = wp_session_get_param_info;
|
||||
proxy_class->enum_params = wp_session_enum_params;
|
||||
proxy_class->subscribe_params = wp_session_subscribe_params;
|
||||
proxy_class->set_param = wp_session_set_param;
|
||||
|
||||
proxy_class->pw_proxy_created = wp_session_pw_proxy_created;
|
||||
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;
|
||||
|
|
@ -772,29 +745,29 @@ impl_enum_params (void *object, int seq,
|
|||
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));
|
||||
WpSpaProps *props = wp_proxy_get_spa_props (WP_PROXY (self));
|
||||
|
||||
switch (id) {
|
||||
case SPA_PARAM_PropInfo: {
|
||||
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (controls);
|
||||
g_autoptr (GPtrArray) params = wp_spa_props_build_propinfo (props);
|
||||
|
||||
for (guint i = start; i < params->len; i++) {
|
||||
WpSpaPod *pod = g_ptr_array_index (params, i);
|
||||
const struct spa_pod *param = wp_spa_pod_get_spa_pod (pod);
|
||||
pw_session_emit_param (&self->hooks, seq, id, i, i+1, param);
|
||||
wp_proxy_handle_event_param (self, seq, id, i, i+1, param);
|
||||
if (++count == num)
|
||||
break;
|
||||
if (spa_pod_filter (&b, &result, param, filter) == 0) {
|
||||
pw_session_emit_param (&self->hooks, seq, id, i, i+1, result);
|
||||
if (++count == num)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPA_PARAM_Props: {
|
||||
if (start == 0) {
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (controls);
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_props_build_props (props);
|
||||
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);
|
||||
wp_proxy_handle_event_param (self, seq, id, 0, 1, result);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -824,26 +797,24 @@ impl_set_param (void *object, uint32_t id, uint32_t flags,
|
|||
{
|
||||
WpImplSession *self = WP_IMPL_SESSION (object);
|
||||
g_autoptr (GPtrArray) changed_ids = NULL;
|
||||
WpSpaProps *controls = wp_proxy_get_spa_props (WP_PROXY (self));
|
||||
WpSpaProps *props = 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 (controls, pod, changed_ids);
|
||||
wp_spa_props_store_from_props (props, pod, changed_ids);
|
||||
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar *prop_id = g_ptr_array_index (changed_ids, i);
|
||||
g_signal_emit_by_name (self, "prop-changed", prop_id);
|
||||
}
|
||||
|
||||
/* notify subscribers */
|
||||
if (self->subscribed)
|
||||
impl_enum_params (self, 1, SPA_PARAM_Props, 0, UINT32_MAX, NULL);
|
||||
|
||||
/* notify controls locally */
|
||||
for (guint i = 0; i < changed_ids->len; i++) {
|
||||
const gchar * prop_id = g_ptr_array_index (changed_ids, i);
|
||||
WP_PROXY_GET_CLASS (WP_PROXY (self))->control_changed (WP_PROXY (self),
|
||||
prop_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -889,7 +860,7 @@ wp_impl_session_init (WpImplSession * self)
|
|||
wp_spa_props_register (controls,
|
||||
"Wp:defaultSink", "Default Sink", wp_spa_pod_new_int (0));
|
||||
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_CONTROLS);
|
||||
wp_proxy_set_feature_ready (WP_PROXY (self), WP_PROXY_FEATURE_PROPS);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -953,8 +924,9 @@ wp_impl_session_class_init (WpImplSessionClass * klass)
|
|||
object_class->finalize = wp_impl_session_finalize;
|
||||
|
||||
proxy_class->augment = wp_impl_session_augment;
|
||||
proxy_class->enum_params = NULL;
|
||||
proxy_class->subscribe_params = NULL;
|
||||
proxy_class->pw_proxy_created = NULL;
|
||||
proxy_class->param = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ typedef enum { /*< flags >*/
|
|||
*/
|
||||
#define WP_SESSION_FEATURES_STANDARD \
|
||||
(WP_PROXY_FEATURES_STANDARD | \
|
||||
WP_PROXY_FEATURE_CONTROLS | \
|
||||
WP_PROXY_FEATURE_PROPS | \
|
||||
WP_SESSION_FEATURE_ENDPOINTS | \
|
||||
WP_SESSION_FEATURE_LINKS)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#define G_LOG_DOMAIN "wp-spa-props"
|
||||
|
||||
#include "private.h"
|
||||
#include "debug.h"
|
||||
#include <spa/pod/pod.h>
|
||||
#include <spa/pod/builder.h>
|
||||
#include <spa/pod/parser.h>
|
||||
|
|
@ -23,6 +24,7 @@ struct entry
|
|||
{
|
||||
gchar *id_name;
|
||||
gchar *description;
|
||||
WpSpaPod *type;
|
||||
WpSpaPod *value;
|
||||
};
|
||||
|
||||
|
|
@ -38,6 +40,7 @@ entry_free (struct entry *e)
|
|||
{
|
||||
g_free (e->id_name);
|
||||
g_free (e->description);
|
||||
g_clear_pointer (&e->type, wp_spa_pod_unref);
|
||||
g_clear_pointer (&e->value, wp_spa_pod_unref);
|
||||
g_slice_free (struct entry, e);
|
||||
}
|
||||
|
|
@ -57,7 +60,9 @@ wp_spa_props_register (WpSpaProps * self, const char *id_name,
|
|||
struct entry *e = entry_new ();
|
||||
e->id_name = g_strdup (id_name);
|
||||
e->description = g_strdup (description);
|
||||
e->value = pod;
|
||||
e->type = pod;
|
||||
e->value = wp_spa_pod_is_choice (e->type) ?
|
||||
wp_spa_pod_get_choice_child (e->type) : wp_spa_pod_ref (e->type);
|
||||
self->entries = g_list_append (self->entries, e);
|
||||
}
|
||||
|
||||
|
|
@ -69,14 +74,12 @@ wp_spa_props_register_from_prop_info (WpSpaProps * self,
|
|||
const gchar *id_name, *description;
|
||||
g_autoptr (WpSpaPod) type = NULL;
|
||||
|
||||
|
||||
if (!wp_spa_pod_get_object (prop_info,
|
||||
"PropInfo", NULL,
|
||||
"id", "I", &id,
|
||||
"name", "s", &description,
|
||||
"type", "P", &type,
|
||||
NULL)) {
|
||||
g_assert_true (FALSE);
|
||||
g_warning ("Bad prop info object");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -103,8 +106,7 @@ wp_spa_props_get_stored (WpSpaProps * self, const char * id_name)
|
|||
return NULL;
|
||||
|
||||
e = (struct entry *) l->data;
|
||||
return wp_spa_pod_is_choice (e->value) ?
|
||||
wp_spa_pod_get_choice_child (e->value) : wp_spa_pod_ref (e->value);
|
||||
return wp_spa_pod_ref (e->value);
|
||||
}
|
||||
|
||||
// exported set --> cache + update(variant to pod -> push)
|
||||
|
|
@ -123,10 +125,16 @@ wp_spa_props_store (WpSpaProps * self, const char * id_name,
|
|||
|
||||
e = (struct entry *) l->data;
|
||||
|
||||
pod = wp_spa_pod_is_choice (e->value) ?
|
||||
wp_spa_pod_get_choice_child (e->value) : wp_spa_pod_ref (e->value);
|
||||
wp_trace ("storing %s, entry:%p", id_name, e);
|
||||
|
||||
return !wp_spa_pod_equal (pod, value) && wp_spa_pod_set_pod (pod, value);
|
||||
/* TODO check the type */
|
||||
|
||||
if (!wp_spa_pod_equal (e->value, value)) {
|
||||
g_clear_pointer (&e->value, wp_spa_pod_unref);
|
||||
e->value = wp_spa_pod_copy (value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// exported event set --> pod to variant -> cache
|
||||
|
|
@ -174,10 +182,9 @@ wp_spa_props_build_props (WpSpaProps * self)
|
|||
for (l = self->entries; l != NULL; l = g_list_next (l)) {
|
||||
struct entry * e = (struct entry *) l->data;
|
||||
if (e->id_name && e->value) {
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_is_choice (e->value) ?
|
||||
wp_spa_pod_get_choice_child (e->value) : wp_spa_pod_ref (e->value);
|
||||
wp_trace ("building %s, entry:%p", e->id_name, e);
|
||||
wp_spa_pod_builder_add_property (b, e->id_name);
|
||||
wp_spa_pod_builder_add_pod (b, pod);
|
||||
wp_spa_pod_builder_add_pod (b, e->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +211,7 @@ wp_spa_props_build_propinfo (WpSpaProps * self)
|
|||
"PropInfo", "PropInfo",
|
||||
"id", "I", id,
|
||||
"name", "s", e->description,
|
||||
"type", "P", e->value,
|
||||
"type", "P", e->type,
|
||||
NULL));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ device_created (GObject * proxy, GAsyncResult * res, gpointer user_data)
|
|||
"Profile", "Profile",
|
||||
"index", "i", 1,
|
||||
NULL);
|
||||
wp_proxy_set_param (WP_PROXY (proxy), SPA_PARAM_Profile, 0, profile);
|
||||
wp_proxy_set_param (WP_PROXY (proxy), "Profile", profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ on_reservation_acquired (GObject *obj, GAsyncResult *res, gpointer user_data)
|
|||
"Profile", "Profile",
|
||||
"index", "i", 1,
|
||||
NULL);
|
||||
wp_proxy_set_param (device, SPA_PARAM_Profile, 0, profile);
|
||||
wp_proxy_set_param (device, "Profile", profile);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -89,7 +89,7 @@ on_reservation_release (WpMonitorDbusDeviceReservation *reservation, int forced,
|
|||
"Profile", "Profile",
|
||||
"index", "i", 0,
|
||||
NULL);
|
||||
wp_proxy_set_param (device, SPA_PARAM_Profile, 0, profile);
|
||||
wp_proxy_set_param (device, "Profile", profile);
|
||||
|
||||
/* Complete release on done */
|
||||
wp_core_sync (core, NULL, (GAsyncReadyCallback)on_device_done, self);
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ wp_session_settings_activate (WpPlugin * plugin)
|
|||
wp_object_manager_add_interest (self->sessions_om, WP_TYPE_SESSION, NULL);
|
||||
wp_object_manager_request_proxy_features (self->sessions_om, WP_TYPE_SESSION,
|
||||
WP_PROXY_FEATURES_STANDARD |
|
||||
WP_PROXY_FEATURE_CONTROLS |
|
||||
WP_PROXY_FEATURE_PROPS |
|
||||
WP_SESSION_FEATURE_ENDPOINTS);
|
||||
g_signal_connect_object (self->sessions_om, "object-added",
|
||||
G_CALLBACK (on_session_added), self, 0);
|
||||
|
|
|
|||
|
|
@ -204,11 +204,11 @@ on_node_enum_format_done (WpProxy *proxy, GAsyncResult *res,
|
|||
WpTransition * transition)
|
||||
{
|
||||
WpSiAdapter *self = wp_transition_get_source_object (transition);
|
||||
g_autoptr (GPtrArray) formats = NULL;
|
||||
g_autoptr (WpIterator) formats = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
gint pref_chan;
|
||||
|
||||
formats = wp_proxy_enum_params_collect_finish (proxy, res, &error);
|
||||
formats = wp_proxy_enum_params_finish (proxy, res, &error);
|
||||
if (error) {
|
||||
wp_transition_return_error (transition, g_steal_pointer (&error));
|
||||
return;
|
||||
|
|
@ -301,8 +301,7 @@ si_adapter_activate_execute_step (WpSessionItem * item,
|
|||
break;
|
||||
|
||||
case STEP_CHOOSE_FORMAT:
|
||||
wp_proxy_enum_params_collect (WP_PROXY (self->node),
|
||||
SPA_PARAM_EnumFormat, 0, -1, NULL, NULL,
|
||||
wp_proxy_enum_params (WP_PROXY (self->node), "EnumFormat", NULL, NULL,
|
||||
(GAsyncReadyCallback) on_node_enum_format_done, transition);
|
||||
break;
|
||||
|
||||
|
|
@ -312,7 +311,7 @@ si_adapter_activate_execute_step (WpSessionItem * item,
|
|||
|
||||
/* set the chosen device/client format on the node */
|
||||
format = format_audio_raw_build (&self->format);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), SPA_PARAM_Format, 0, format);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), "Format", format);
|
||||
|
||||
/* now choose the DSP format: keep the chanels but use F32 plannar @ 48K */
|
||||
self->format.format = SPA_AUDIO_FORMAT_F32P;
|
||||
|
|
@ -326,7 +325,7 @@ si_adapter_activate_execute_step (WpSessionItem * item,
|
|||
"control", "b", self->control_port,
|
||||
"format", "P", port_format,
|
||||
NULL);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), SPA_PARAM_PortConfig, 0, pod);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), "PortConfig", pod);
|
||||
|
||||
g_autoptr (WpCore) core = wp_proxy_get_core (WP_PROXY (self->node));
|
||||
wp_core_sync (core, NULL,
|
||||
|
|
|
|||
|
|
@ -340,22 +340,21 @@ select_channels (WpSpaPod *value, gint preference)
|
|||
}
|
||||
|
||||
gboolean
|
||||
choose_sensible_raw_audio_format (GPtrArray *formats,
|
||||
choose_sensible_raw_audio_format (WpIterator *formats,
|
||||
gint channels_preference, struct spa_audio_info_raw *result)
|
||||
{
|
||||
guint i, most_channels = 0;
|
||||
struct spa_audio_info_raw *raw;
|
||||
guint most_channels = 0;
|
||||
struct spa_audio_info_raw raw;
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
|
||||
raw = g_alloca (sizeof (struct spa_audio_info_raw) * formats->len);
|
||||
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
WpSpaPod *pod = g_ptr_array_index (formats, i);
|
||||
for (; wp_iterator_next (formats, &item); g_value_unset (&item)) {
|
||||
WpSpaPod *pod = g_value_get_boxed (&item);
|
||||
uint32_t mtype, mstype;
|
||||
|
||||
/* initialize all fields to zero (SPA_AUDIO_FORMAT_UNKNOWN etc) and set
|
||||
the unpositioned flag, which means there is no channel position array */
|
||||
spa_memzero (&raw[i], sizeof(struct spa_audio_info_raw));
|
||||
SPA_FLAG_SET(raw[i].flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
spa_memzero (&raw, sizeof(struct spa_audio_info_raw));
|
||||
SPA_FLAG_SET(raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
|
||||
if (!wp_spa_pod_is_object (pod)) {
|
||||
g_warning ("non-object POD appeared on formats list; this node is buggy");
|
||||
|
|
@ -374,7 +373,7 @@ choose_sensible_raw_audio_format (GPtrArray *formats,
|
|||
if (!(mtype == SPA_MEDIA_TYPE_audio && mstype == SPA_MEDIA_SUBTYPE_raw))
|
||||
continue;
|
||||
|
||||
/* go through the fields and populate raw[i] */
|
||||
/* go through the fields and populate raw */
|
||||
g_autoptr (WpIterator) it = wp_spa_pod_iterate (pod);
|
||||
GValue next = G_VALUE_INIT;
|
||||
while (wp_iterator_next (it, &next)) {
|
||||
|
|
@ -385,30 +384,30 @@ choose_sensible_raw_audio_format (GPtrArray *formats,
|
|||
|
||||
/* format */
|
||||
if (g_strcmp0 (key, "format") == 0) {
|
||||
raw[i].format = select_format (value);
|
||||
raw.format = select_format (value);
|
||||
}
|
||||
|
||||
/* rate */
|
||||
else if (g_strcmp0 (key, "rate") == 0) {
|
||||
raw[i].rate = select_rate (value);
|
||||
raw.rate = select_rate (value);
|
||||
}
|
||||
|
||||
/* channels */
|
||||
else if (g_strcmp0 (key, "channels") == 0) {
|
||||
raw[i].channels = select_channels (value, channels_preference);
|
||||
raw.channels = select_channels (value, channels_preference);
|
||||
}
|
||||
|
||||
/* position */
|
||||
else if (g_strcmp0 (key, "position") == 0) {
|
||||
/* just copy the array, there is no choice here */
|
||||
g_return_val_if_fail (wp_spa_pod_is_array (value), FALSE);
|
||||
SPA_FLAG_CLEAR (raw[i].flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
SPA_FLAG_CLEAR (raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED);
|
||||
g_autoptr (WpIterator) array_it = wp_spa_pod_iterate (value);
|
||||
GValue array_next = G_VALUE_INIT;
|
||||
guint j = 0;
|
||||
while (wp_iterator_next (array_it, &array_next)) {
|
||||
guint32 *pos_id = (guint32 *)g_value_get_pointer (&array_next);
|
||||
raw[i].position[j] = *pos_id;
|
||||
raw.position[j] = *pos_id;
|
||||
g_value_unset (&array_next);
|
||||
j++;
|
||||
}
|
||||
|
|
@ -418,10 +417,10 @@ choose_sensible_raw_audio_format (GPtrArray *formats,
|
|||
}
|
||||
|
||||
/* figure out if this one is the best so far */
|
||||
if (raw[i].format != SPA_AUDIO_FORMAT_UNKNOWN &&
|
||||
raw[i].channels > most_channels ) {
|
||||
most_channels = raw[i].channels;
|
||||
*result = raw[i];
|
||||
if (raw.format != SPA_AUDIO_FORMAT_UNKNOWN &&
|
||||
raw.channels > most_channels ) {
|
||||
most_channels = raw.channels;
|
||||
*result = raw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ gboolean multiport_link_create (GVariant * src_data, GVariant * sink_data,
|
|||
CreateLinkCb create_link_cb, gpointer user_data, GError ** error);
|
||||
|
||||
struct spa_audio_info_raw;
|
||||
gboolean choose_sensible_raw_audio_format (GPtrArray *formats,
|
||||
gboolean choose_sensible_raw_audio_format (WpIterator *formats,
|
||||
gint channels_preference, struct spa_audio_info_raw *result);
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ si_convert_activate_execute_step (WpSessionItem * item,
|
|||
"mode", "I", SPA_PARAM_PORT_CONFIG_MODE_dsp,
|
||||
"format", "P", format,
|
||||
NULL);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), SPA_PARAM_PortConfig, 0, pod);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), "PortConfig", pod);
|
||||
g_clear_pointer (&pod, wp_spa_pod_unref);
|
||||
|
||||
pod = wp_spa_pod_new_object ("PortConfig", "PortConfig",
|
||||
|
|
@ -300,7 +300,7 @@ si_convert_activate_execute_step (WpSessionItem * item,
|
|||
"control", "b", self->control_port,
|
||||
"format", "P", format,
|
||||
NULL);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), SPA_PARAM_PortConfig, 0, pod);
|
||||
wp_proxy_set_param (WP_PROXY (self->node), "PortConfig", pod);
|
||||
|
||||
/* handle the info callback */
|
||||
g_signal_connect_object (self->node, "state-changed",
|
||||
|
|
|
|||
|
|
@ -43,7 +43,10 @@ test_choose_sensible_raw_audio_format (void)
|
|||
NULL);
|
||||
g_assert_nonnull (param1);
|
||||
g_ptr_array_add (formats, g_steal_pointer (¶m1));
|
||||
g_assert_true (choose_sensible_raw_audio_format (formats, 34, &info));
|
||||
|
||||
g_autoptr (WpIterator) it =
|
||||
wp_iterator_new_ptr_array (g_ptr_array_ref (formats), WP_TYPE_SPA_POD);
|
||||
g_assert_true (choose_sensible_raw_audio_format (it, 34, &info));
|
||||
g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_S16);
|
||||
g_assert_cmpint (info.rate, ==, 44100);
|
||||
g_assert_cmpint (info.channels, ==, 8);
|
||||
|
|
@ -65,7 +68,10 @@ test_choose_sensible_raw_audio_format (void)
|
|||
NULL);
|
||||
g_assert_nonnull (param1);
|
||||
g_ptr_array_add (formats, g_steal_pointer (¶m1));
|
||||
g_assert_true (choose_sensible_raw_audio_format (formats, 2, &info));
|
||||
|
||||
g_autoptr (WpIterator) it =
|
||||
wp_iterator_new_ptr_array (g_ptr_array_ref (formats), WP_TYPE_SPA_POD);
|
||||
g_assert_true (choose_sensible_raw_audio_format (it, 2, &info));
|
||||
g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_S16);
|
||||
g_assert_cmpint (info.rate, ==, 44100);
|
||||
g_assert_cmpint (info.channels, ==, 2);
|
||||
|
|
@ -102,7 +108,10 @@ test_choose_sensible_raw_audio_format (void)
|
|||
NULL);
|
||||
g_assert_nonnull (param3);
|
||||
g_ptr_array_add (formats, g_steal_pointer (¶m3));
|
||||
g_assert_true (choose_sensible_raw_audio_format (formats, 34, &info));
|
||||
|
||||
g_autoptr (WpIterator) it =
|
||||
wp_iterator_new_ptr_array (g_ptr_array_ref (formats), WP_TYPE_SPA_POD);
|
||||
g_assert_true (choose_sensible_raw_audio_format (it, 34, &info));
|
||||
g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_F32);
|
||||
g_assert_cmpint (info.rate, ==, 48000);
|
||||
g_assert_cmpint (info.channels, ==, 5);
|
||||
|
|
|
|||
|
|
@ -289,7 +289,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_object_manager_request_proxy_features (fixture->export_om,
|
||||
WP_TYPE_ENDPOINT, WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
WP_TYPE_ENDPOINT, WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_PROPS);
|
||||
wp_core_install_object_manager (fixture->base.core, fixture->export_om);
|
||||
|
||||
/* set up the proxy side */
|
||||
|
|
@ -299,7 +299,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_object_manager_request_proxy_features (fixture->proxy_om, WP_TYPE_ENDPOINT,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_PROPS);
|
||||
wp_core_install_object_manager (fixture->base.client_core, fixture->proxy_om);
|
||||
|
||||
/* create session */
|
||||
|
|
@ -338,7 +338,7 @@ test_endpoint_basic (TestEndpointFixture *fixture, gconstpointer data)
|
|||
WP_PROXY_FEATURE_PW_PROXY |
|
||||
WP_PROXY_FEATURE_INFO |
|
||||
WP_PROXY_FEATURE_BOUND |
|
||||
WP_PROXY_FEATURE_CONTROLS);
|
||||
WP_PROXY_FEATURE_PROPS);
|
||||
|
||||
g_assert_cmpuint (wp_proxy_get_bound_id (fixture->proxy_endpoint), ==,
|
||||
wp_proxy_get_bound_id (fixture->impl_endpoint));
|
||||
|
|
|
|||
183
tests/wp/proxy.c
183
tests/wp/proxy.c
|
|
@ -10,21 +10,19 @@
|
|||
|
||||
typedef struct {
|
||||
WpBaseTestFixture base;
|
||||
|
||||
/* the object manager that listens for proxies */
|
||||
WpObjectManager *om;
|
||||
|
||||
} TestProxyFixture;
|
||||
} TestFixture;
|
||||
|
||||
static void
|
||||
test_proxy_setup (TestProxyFixture *self, gconstpointer user_data)
|
||||
test_proxy_setup (TestFixture *self, gconstpointer user_data)
|
||||
{
|
||||
wp_base_test_fixture_setup (&self->base, 0);
|
||||
self->om = wp_object_manager_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_proxy_teardown (TestProxyFixture *self, gconstpointer user_data)
|
||||
test_proxy_teardown (TestFixture *self, gconstpointer user_data)
|
||||
{
|
||||
g_clear_object (&self->om);
|
||||
wp_base_test_fixture_teardown (&self->base);
|
||||
|
|
@ -32,7 +30,7 @@ test_proxy_teardown (TestProxyFixture *self, gconstpointer user_data)
|
|||
|
||||
static void
|
||||
test_proxy_basic_augmented (WpProxy *proxy, GAsyncResult *res,
|
||||
TestProxyFixture *fixture)
|
||||
TestFixture *fixture)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
g_assert_true (wp_proxy_augment_finish (proxy, res, &error));
|
||||
|
|
@ -46,7 +44,7 @@ test_proxy_basic_augmented (WpProxy *proxy, GAsyncResult *res,
|
|||
|
||||
static void
|
||||
test_proxy_basic_object_added (WpObjectManager *om, WpProxy *proxy,
|
||||
TestProxyFixture *fixture)
|
||||
TestFixture *fixture)
|
||||
{
|
||||
g_assert_nonnull (proxy);
|
||||
{
|
||||
|
|
@ -76,7 +74,7 @@ test_proxy_basic_object_added (WpObjectManager *om, WpProxy *proxy,
|
|||
}
|
||||
|
||||
static void
|
||||
test_proxy_basic (TestProxyFixture *fixture, gconstpointer data)
|
||||
test_proxy_basic (TestFixture *fixture, gconstpointer data)
|
||||
{
|
||||
/* our test server should advertise exactly one
|
||||
* client: our WpRemote; use this to test WpProxy */
|
||||
|
|
@ -89,107 +87,140 @@ test_proxy_basic (TestProxyFixture *fixture, gconstpointer data)
|
|||
g_main_loop_run (fixture->base.loop);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
TestProxyFixture *fixture;
|
||||
guint n_params;
|
||||
} TestNodeParamData;
|
||||
|
||||
static void
|
||||
test_node_param (WpNode *node, int seq, guint id, guint index,
|
||||
guint next, struct spa_pod *param, TestNodeParamData *data)
|
||||
test_node_enum_params_done (WpProxy *node, GAsyncResult *res, TestFixture *f)
|
||||
{
|
||||
data->n_params++;
|
||||
}
|
||||
|
||||
static void
|
||||
test_node_enum_params_done (WpProxy *node, GAsyncResult *res,
|
||||
TestNodeParamData *data)
|
||||
{
|
||||
g_autoptr (GPtrArray) params = NULL;
|
||||
g_autoptr (WpIterator) params = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
guint i;
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
guint n_params = 0;
|
||||
|
||||
params = wp_proxy_enum_params_collect_finish (node, res, &error);
|
||||
params = wp_proxy_enum_params_finish (node, res, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (params);
|
||||
|
||||
/* the param signal must have also been fired for all params */
|
||||
g_assert_cmpint (params->len, ==, data->n_params);
|
||||
|
||||
for (i = 0; i < params->len; i++) {
|
||||
WpSpaPod *pod = g_ptr_array_index (params, i);
|
||||
for (; wp_iterator_next (params, &item); g_value_unset (&item)) {
|
||||
WpSpaPod *pod = NULL;
|
||||
g_assert_cmpuint (G_VALUE_TYPE (&item), ==, WP_TYPE_SPA_POD);
|
||||
g_assert_nonnull (pod = g_value_get_boxed (&item));
|
||||
g_assert_true (wp_spa_pod_is_object (pod));
|
||||
g_assert_cmpstr ("PropInfo", ==, wp_spa_pod_get_object_type_name (pod));
|
||||
n_params++;
|
||||
}
|
||||
g_assert_cmpint (n_params, >, 0);
|
||||
|
||||
g_main_loop_quit (data->fixture->base.loop);
|
||||
g_free (data);
|
||||
g_main_loop_quit (f->base.loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_node_object_added (WpObjectManager *om, WpProxy *proxy,
|
||||
TestProxyFixture *fixture)
|
||||
test_node (TestFixture *f, gconstpointer data)
|
||||
{
|
||||
g_autoptr (WpProxy) proxy = NULL;
|
||||
const struct pw_node_info *info;
|
||||
TestNodeParamData *param_data;
|
||||
|
||||
/* load audiotestsrc on the server side */
|
||||
{
|
||||
g_autoptr (WpTestServerLocker) lock =
|
||||
wp_test_server_locker_new (&f->base.server);
|
||||
|
||||
g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context,
|
||||
"audiotestsrc", "audiotestsrc/libspa-audiotestsrc"), ==, 0);
|
||||
g_assert_nonnull (pw_context_load_module (f->base.server.context,
|
||||
"libpipewire-module-adapter", NULL, NULL));
|
||||
}
|
||||
|
||||
proxy = (WpProxy *) wp_node_new_from_factory (f->base.core,
|
||||
"adapter",
|
||||
wp_properties_new (
|
||||
"factory.name", "audiotestsrc",
|
||||
"node.name", "audiotestsrc.adapter",
|
||||
NULL));
|
||||
g_assert_nonnull (proxy);
|
||||
wp_proxy_augment (proxy, WP_PROXY_FEATURES_STANDARD, NULL,
|
||||
(GAsyncReadyCallback) test_proxy_augment_finish_cb, f);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
/* basic tests */
|
||||
g_assert_cmphex (wp_proxy_get_features (proxy), ==, WP_PROXY_FEATURES_STANDARD);
|
||||
g_assert_nonnull (wp_proxy_get_pw_proxy (proxy));
|
||||
|
||||
g_assert_true (WP_IS_NODE (proxy));
|
||||
info = wp_proxy_get_info (proxy);
|
||||
g_assert_nonnull (info);
|
||||
g_assert_cmpint (wp_proxy_get_bound_id (proxy), ==, info->id);
|
||||
|
||||
/* info */
|
||||
{
|
||||
g_assert_nonnull (info = wp_proxy_get_info (proxy));
|
||||
g_assert_cmpint (wp_proxy_get_bound_id (proxy), ==, info->id);
|
||||
}
|
||||
|
||||
/* properties */
|
||||
{
|
||||
const gchar *id;
|
||||
g_assert_nonnull(id = wp_proxy_get_property (proxy, PW_KEY_OBJECT_ID));
|
||||
g_assert_cmpint (info->id, ==, atoi(id));
|
||||
}
|
||||
{
|
||||
const char *id;
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (proxy);
|
||||
|
||||
g_assert_nonnull (props);
|
||||
g_assert_true (wp_properties_peek_dict (props) == info->props);
|
||||
id = wp_properties_get (props, PW_KEY_OBJECT_ID);
|
||||
g_assert_nonnull (id);
|
||||
g_assert_nonnull (id = wp_properties_get (props, PW_KEY_OBJECT_ID));
|
||||
g_assert_cmpint (info->id, ==, atoi(id));
|
||||
}
|
||||
|
||||
param_data = g_new0 (TestNodeParamData, 1);
|
||||
param_data->fixture = fixture;
|
||||
/* param info */
|
||||
{
|
||||
const gchar *flags_str;
|
||||
g_autoptr (GVariant) param_info = wp_proxy_get_param_info (proxy);
|
||||
|
||||
g_signal_connect (proxy, "param", (GCallback) test_node_param,
|
||||
param_data);
|
||||
g_autoptr (WpSpaPod) filter = wp_spa_pod_new_none ();
|
||||
wp_proxy_enum_params_collect (proxy, SPA_PARAM_PropInfo, 0, -1,
|
||||
filter, NULL, (GAsyncReadyCallback) test_node_enum_params_done,
|
||||
param_data);
|
||||
}
|
||||
|
||||
static void
|
||||
test_node (TestProxyFixture *fixture, gconstpointer data)
|
||||
{
|
||||
/* load audiotestsrc on the server side */
|
||||
pw_thread_loop_lock (fixture->base.server.thread_loop);
|
||||
pw_context_add_spa_lib (fixture->base.server.context, "audiotestsrc",
|
||||
"audiotestsrc/libspa-audiotestsrc");
|
||||
if (!pw_context_load_module (fixture->base.server.context,
|
||||
"libpipewire-module-spa-node", "audiotestsrc", NULL)) {
|
||||
pw_thread_loop_unlock (fixture->base.server.thread_loop);
|
||||
g_test_skip ("audiotestsrc SPA plugin is not installed");
|
||||
return;
|
||||
g_assert_nonnull (param_info);
|
||||
g_assert_true (g_variant_is_of_type (param_info, G_VARIANT_TYPE ("a{ss}")));
|
||||
g_assert_cmpuint (g_variant_n_children (param_info), ==, info->n_params);
|
||||
g_assert_true (g_variant_lookup (param_info, "PropInfo", "&s", &flags_str));
|
||||
g_assert_cmpstr (flags_str, ==, "r");
|
||||
g_assert_true (g_variant_lookup (param_info, "Props", "&s", &flags_str));
|
||||
g_assert_cmpstr (flags_str, ==, "rws");
|
||||
}
|
||||
pw_thread_loop_unlock (fixture->base.server.thread_loop);
|
||||
|
||||
/* we should be able to see this exported audiotestsrc node on the client */
|
||||
g_signal_connect (fixture->om, "object-added",
|
||||
(GCallback) test_node_object_added, fixture);
|
||||
/* enum params */
|
||||
wp_proxy_enum_params (proxy, "PropInfo", NULL, NULL,
|
||||
(GAsyncReadyCallback) test_node_enum_params_done, f);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
/* declare interest and set default features to be ready
|
||||
when the signal is fired */
|
||||
wp_object_manager_add_interest (fixture->om, WP_TYPE_NODE, NULL);
|
||||
wp_object_manager_request_proxy_features (fixture->om, WP_TYPE_NODE,
|
||||
WP_PROXY_FEATURES_STANDARD);
|
||||
wp_core_install_object_manager (fixture->base.core, fixture->om);
|
||||
/* props */
|
||||
wp_proxy_augment (proxy, WP_PROXY_FEATURE_PROPS, NULL,
|
||||
(GAsyncReadyCallback) test_proxy_augment_finish_cb, f);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
g_main_loop_run (fixture->base.loop);
|
||||
g_assert_cmphex (wp_proxy_get_features (proxy), ==,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_PROPS);
|
||||
{
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
WpSpaPod *pod = NULL;
|
||||
|
||||
g_assert_nonnull (it = wp_proxy_iterate_prop_info (proxy));
|
||||
g_assert_true (wp_iterator_next (it, &item));
|
||||
g_assert_cmpuint (G_VALUE_TYPE (&item), ==, WP_TYPE_SPA_POD);
|
||||
g_assert_nonnull (pod = g_value_get_boxed (&item));
|
||||
g_assert_true (wp_spa_pod_is_object (pod));
|
||||
g_assert_cmpstr ("PropInfo", ==, wp_spa_pod_get_object_type_name (pod));
|
||||
}
|
||||
|
||||
{
|
||||
g_autoptr (WpSpaPod) vol = wp_spa_pod_new_float (0.8);
|
||||
wp_proxy_set_prop (proxy, "volume", vol);
|
||||
}
|
||||
|
||||
g_signal_connect_swapped (proxy, "prop-changed",
|
||||
G_CALLBACK (g_main_loop_quit), f->base.loop);
|
||||
g_main_loop_run (f->base.loop);
|
||||
|
||||
{
|
||||
float f;
|
||||
g_autoptr (WpSpaPod) vol = wp_proxy_get_prop (proxy, "volume");
|
||||
g_assert_true (wp_spa_pod_get_float (vol, &f));
|
||||
g_assert_cmpfloat_with_epsilon (f, 0.8, 0.0001);
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
|
|
@ -198,9 +229,9 @@ main (gint argc, gchar *argv[])
|
|||
g_test_init (&argc, &argv, NULL);
|
||||
wp_init (WP_INIT_ALL);
|
||||
|
||||
g_test_add ("/wp/proxy/basic", TestProxyFixture, NULL,
|
||||
g_test_add ("/wp/proxy/basic", TestFixture, NULL,
|
||||
test_proxy_setup, test_proxy_basic, test_proxy_teardown);
|
||||
g_test_add ("/wp/proxy/node", TestProxyFixture, NULL,
|
||||
g_test_add ("/wp/proxy/node", TestFixture, NULL,
|
||||
test_proxy_setup, test_node, test_proxy_teardown);
|
||||
|
||||
return g_test_run ();
|
||||
|
|
|
|||
|
|
@ -116,11 +116,11 @@ test_session_basic_export_done (WpProxy * session, GAsyncResult * res,
|
|||
}
|
||||
|
||||
static void
|
||||
test_session_basic_default_endpoint_changed (WpSession * session,
|
||||
const char *type_name, guint32 id, TestSessionFixture *fixture)
|
||||
test_session_basic_prop_changed (WpSession * session,
|
||||
const char *type_name, TestSessionFixture *fixture)
|
||||
{
|
||||
g_debug ("endpoint changed: %s (%s, %u)", G_OBJECT_TYPE_NAME (session),
|
||||
type_name, id);
|
||||
g_debug ("prop changed: %s (%s)", G_OBJECT_TYPE_NAME (session),
|
||||
type_name);
|
||||
|
||||
g_assert_true (WP_IS_SESSION (session));
|
||||
|
||||
|
|
@ -220,10 +220,10 @@ test_session_basic (TestSessionFixture *fixture, gconstpointer data)
|
|||
"Wp:defaultSource"), ==, 9);
|
||||
|
||||
/* setup change signals */
|
||||
g_signal_connect (fixture->proxy_session, "default-endpoint-changed",
|
||||
(GCallback) test_session_basic_default_endpoint_changed, fixture);
|
||||
g_signal_connect (session, "default-endpoint-changed",
|
||||
(GCallback) test_session_basic_default_endpoint_changed, fixture);
|
||||
g_signal_connect (fixture->proxy_session, "prop-changed",
|
||||
(GCallback) test_session_basic_prop_changed, fixture);
|
||||
g_signal_connect (session, "prop-changed",
|
||||
(GCallback) test_session_basic_prop_changed, fixture);
|
||||
g_signal_connect (fixture->proxy_session, "notify::properties",
|
||||
(GCallback) test_session_basic_notify_properties, fixture);
|
||||
g_signal_connect (session, "notify::properties",
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ print_dev_endpoint (WpEndpoint *ep, WpSession *session, const gchar *type_name)
|
|||
gfloat volume = 0.0;
|
||||
gboolean mute = FALSE;
|
||||
|
||||
if ((ctrl = wp_proxy_get_control (WP_PROXY (ep), "volume"))) {
|
||||
if ((ctrl = wp_proxy_get_prop (WP_PROXY (ep), "volume"))) {
|
||||
wp_spa_pod_get_float (ctrl, &volume);
|
||||
has_audio_controls = TRUE;
|
||||
}
|
||||
if ((ctrl = wp_proxy_get_control (WP_PROXY (ep), "mute"))) {
|
||||
if ((ctrl = wp_proxy_get_prop (WP_PROXY (ep), "mute"))) {
|
||||
wp_spa_pod_get_boolean (ctrl, &mute);
|
||||
has_audio_controls = TRUE;
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ set_volume (WpObjectManager * om, struct WpCliData * d)
|
|||
NULL);
|
||||
if (ep) {
|
||||
g_autoptr (WpSpaPod) vol = wp_spa_pod_new_float (d->params.set_volume.volume);
|
||||
wp_proxy_set_control (WP_PROXY (ep), "volume", vol);
|
||||
wp_proxy_set_prop (WP_PROXY (ep), "volume", vol);
|
||||
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
|
||||
return;
|
||||
}
|
||||
|
|
@ -294,7 +294,7 @@ main (gint argc, gchar **argv)
|
|||
wp_object_manager_add_interest (om, WP_TYPE_SESSION, NULL);
|
||||
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_PROXY,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_PROPS);
|
||||
func = (GCallback) set_default;
|
||||
}
|
||||
/* set-volume <id> <vol> */
|
||||
|
|
@ -310,7 +310,7 @@ main (gint argc, gchar **argv)
|
|||
data.params.set_volume.volume = volume;
|
||||
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_ENDPOINT,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_PROPS);
|
||||
func = (GCallback) set_volume;
|
||||
}
|
||||
/* device-node-props */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue