mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-01 15:07:58 +02:00
spa-type: refactor
* Use a more complete API to introspect SPA types * Avoid the need for the Tables enumeration; the tables are now registered with a string * Avoid the need for initialization, work directly on spa_types and other static data * Allow working with Object pods that are not Params; the PARAMS table was previously hardcoded in the pod implementation * Add a different dynamic type registration system, closer to how spa type works. The only regression is that we can no longer register additional custom object fields (custom SPA_PROP_* for example), but this feature can be re-added later
This commit is contained in:
parent
7488ec0e25
commit
3762388831
23 changed files with 1422 additions and 818 deletions
|
|
@ -535,19 +535,20 @@ wp_impl_endpoint_stream_set_param (gpointer instance, guint32 id, guint32 flags,
|
|||
WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (instance);
|
||||
g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy (
|
||||
WP_SESSION_ITEM (self->item), WP_TYPE_NODE);
|
||||
const gchar *idstr = NULL;
|
||||
|
||||
if (!node) {
|
||||
wp_warning_object (self, "associated node is no longer available");
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, NULL, &idstr, NULL)) {
|
||||
WpSpaIdValue idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", id);
|
||||
if (!idval) {
|
||||
wp_critical_object (self, "invalid param id: %u", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return wp_pipewire_object_set_param (node, idstr, flags, param) ? 0 : -EIO;
|
||||
return wp_pipewire_object_set_param (node, wp_spa_id_value_short_name (idval),
|
||||
flags, param) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
#define pw_endpoint_stream_emit(hooks,method,version,...) \
|
||||
|
|
|
|||
|
|
@ -1081,19 +1081,20 @@ wp_impl_endpoint_set_param (gpointer instance, guint32 id, guint32 flags,
|
|||
WpImplEndpoint *self = WP_IMPL_ENDPOINT (instance);
|
||||
g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy (
|
||||
WP_SESSION_ITEM (self->item), WP_TYPE_NODE);
|
||||
const gchar *idstr = NULL;
|
||||
|
||||
if (!node) {
|
||||
wp_warning_object (self, "associated node is no longer available");
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, NULL, &idstr, NULL)) {
|
||||
WpSpaIdValue idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", id);
|
||||
if (!idval) {
|
||||
wp_critical_object (self, "invalid param id: %u", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return wp_pipewire_object_set_param (node, idstr, flags, param) ? 0 : -EIO;
|
||||
return wp_pipewire_object_set_param (node, wp_spa_id_value_short_name (idval),
|
||||
flags, param) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
#define pw_endpoint_emit(hooks,method,version,...) \
|
||||
|
|
|
|||
|
|
@ -83,12 +83,13 @@ wp_pw_object_mixin_get_param_info (WpPipewireObject * obj)
|
|||
g_variant_builder_init (&b, G_VARIANT_TYPE ("a{ss}"));
|
||||
|
||||
for (guint i = 0; i < n_params; i++) {
|
||||
WpSpaIdValue idval;
|
||||
const gchar *nick = NULL;
|
||||
gchar flags[3];
|
||||
guint flags_idx = 0;
|
||||
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, info[i].id, NULL, &nick,
|
||||
NULL);
|
||||
idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", info[i].id);
|
||||
nick = wp_spa_id_value_short_name (idval);
|
||||
g_return_val_if_fail (nick != NULL, NULL);
|
||||
|
||||
if (info[i].flags & SPA_PARAM_INFO_READ)
|
||||
|
|
@ -170,8 +171,8 @@ wp_pw_object_mixin_enum_params_unchecked (gpointer obj,
|
|||
/* debug */
|
||||
if (wp_log_level_is_enabled (G_LOG_LEVEL_DEBUG)) {
|
||||
const gchar *name = NULL;
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, &name, NULL, NULL);
|
||||
|
||||
name = wp_spa_id_value_short_name (
|
||||
wp_spa_id_value_from_number ("Spa:Enum:ParamId", id));
|
||||
wp_debug_object (obj, "enum id %u (%s), seq 0x%x (%u), task "
|
||||
WP_OBJECT_FORMAT "%s", id, name, seq, seq, WP_OBJECT_ARGS (task),
|
||||
iface->enum_params_sync ? ", sync" : "");
|
||||
|
|
@ -199,7 +200,7 @@ wp_pw_object_mixin_enum_params (WpPipewireObject * obj, const gchar * id,
|
|||
GAsyncReadyCallback callback, gpointer user_data)
|
||||
{
|
||||
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
||||
guint32 param_id = 0;
|
||||
WpSpaIdValue param_id;
|
||||
|
||||
if (!(iface->enum_params || iface->enum_params_sync)) {
|
||||
g_task_report_new_error (obj, callback, user_data, NULL,
|
||||
|
|
@ -209,13 +210,14 @@ wp_pw_object_mixin_enum_params (WpPipewireObject * obj, const gchar * id,
|
|||
}
|
||||
|
||||
/* translate the id */
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id, ¶m_id,
|
||||
NULL, NULL)) {
|
||||
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
||||
if (!param_id) {
|
||||
wp_critical_object (obj, "invalid param id: %s", id);
|
||||
return;
|
||||
}
|
||||
|
||||
wp_pw_object_mixin_enum_params_unchecked (obj, param_id, filter,
|
||||
wp_pw_object_mixin_enum_params_unchecked (obj,
|
||||
wp_spa_id_value_number (param_id), filter,
|
||||
cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
|
|
@ -238,22 +240,24 @@ wp_pw_object_mixin_enum_params_sync (WpPipewireObject * obj, const gchar * id,
|
|||
{
|
||||
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
||||
GPtrArray *params = NULL;
|
||||
guint32 param_id = 0;
|
||||
WpSpaIdValue param_id;
|
||||
|
||||
/* translate the id */
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id, ¶m_id,
|
||||
NULL, NULL)) {
|
||||
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
||||
if (!param_id) {
|
||||
wp_critical_object (obj, "invalid param id: %s", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iface->enum_params_sync) {
|
||||
/* use enum_params_sync if supported */
|
||||
params = iface->enum_params_sync (obj, param_id, 0, -1, filter);
|
||||
params = iface->enum_params_sync (obj, wp_spa_id_value_number (param_id),
|
||||
0, -1, filter);
|
||||
} else {
|
||||
/* otherwise, find and return the cached params */
|
||||
WpPwObjectMixinData *data = wp_pw_object_mixin_get_data (obj);
|
||||
params = wp_pw_object_mixin_get_stored_params (data, param_id);
|
||||
params = wp_pw_object_mixin_get_stored_params (data,
|
||||
wp_spa_id_value_number (param_id));
|
||||
/* TODO filter */
|
||||
}
|
||||
|
||||
|
|
@ -265,7 +269,7 @@ wp_pw_object_mixin_set_param (WpPipewireObject * obj, const gchar * id,
|
|||
guint32 flags, WpSpaPod * param)
|
||||
{
|
||||
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
||||
guint32 param_id = 0;
|
||||
WpSpaIdValue param_id;
|
||||
gint ret;
|
||||
|
||||
if (!iface->set_param) {
|
||||
|
|
@ -273,14 +277,14 @@ wp_pw_object_mixin_set_param (WpPipewireObject * obj, const gchar * id,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id, ¶m_id,
|
||||
NULL, NULL)) {
|
||||
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
||||
if (!param_id) {
|
||||
wp_critical_object (obj, "invalid param id: %s", id);
|
||||
wp_spa_pod_unref (param);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = iface->set_param (obj, param_id, flags, param);
|
||||
ret = iface->set_param (obj, wp_spa_id_value_number (param_id), flags, param);
|
||||
|
||||
if (G_UNLIKELY (SPA_RESULT_IS_ERROR (ret))) {
|
||||
wp_message_object (obj, "set_param failed: %s", spa_strerror (ret));
|
||||
|
|
@ -940,7 +944,8 @@ wp_pw_object_mixin_notify_params_changed (gpointer instance, guint32 id)
|
|||
|
||||
if (wp_log_level_is_enabled (G_LOG_LEVEL_DEBUG)) {
|
||||
const gchar *name = NULL;
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, &name, NULL, NULL);
|
||||
name = wp_spa_id_value_short_name (wp_spa_id_value_from_number (
|
||||
"Spa:Enum:ParamId", id));
|
||||
wp_debug_object (instance, "notify param id:%u (%s)", id, name);
|
||||
}
|
||||
|
||||
|
|
|
|||
351
lib/wp/spa-pod.c
351
lib/wp/spa-pod.c
|
|
@ -52,13 +52,13 @@ struct _WpSpaPod
|
|||
struct spa_pod_rectangle pod_rectangle;
|
||||
struct spa_pod_fraction pod_fraction;
|
||||
struct wp_property_data {
|
||||
WpSpaTypeTable table;
|
||||
WpSpaIdTable table;
|
||||
guint32 key;
|
||||
guint32 flags;
|
||||
} data_property; /* Only used for property pods */
|
||||
struct wp_control_data {
|
||||
guint32 offset;
|
||||
guint32 type;
|
||||
enum spa_control_type type;
|
||||
} data_control; /* Only used for control pods */
|
||||
} static_pod; /* Only used for statically allocated pods */
|
||||
WpSpaPodBuilder *builder; /* Only used for dynamically allocated pods */
|
||||
|
|
@ -69,12 +69,11 @@ G_DEFINE_BOXED_TYPE (WpSpaPod, wp_spa_pod, wp_spa_pod_ref, wp_spa_pod_unref)
|
|||
|
||||
struct _WpSpaPodBuilder
|
||||
{
|
||||
struct spa_pod_builder builder;
|
||||
struct spa_pod_frame frame;
|
||||
WpSpaType type;
|
||||
size_t size;
|
||||
guint8 *buf;
|
||||
struct spa_pod_builder builder;
|
||||
uint32_t type;
|
||||
struct spa_pod_frame frame;
|
||||
WpSpaTypeTable prop_table; /* Only used when parsing properties */
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (WpSpaPodBuilder, wp_spa_pod_builder,
|
||||
|
|
@ -82,11 +81,10 @@ G_DEFINE_BOXED_TYPE (WpSpaPodBuilder, wp_spa_pod_builder,
|
|||
|
||||
struct _WpSpaPodParser
|
||||
{
|
||||
guint32 type;
|
||||
struct spa_pod_parser parser;
|
||||
WpSpaPod *pod;
|
||||
struct spa_pod_frame frame;
|
||||
WpSpaTypeTable prop_table; /* Only used when parsing properties */
|
||||
WpSpaType type;
|
||||
WpSpaPod *pod;
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (WpSpaPodParser, wp_spa_pod_parser,
|
||||
|
|
@ -111,7 +109,7 @@ static const struct spa_pod_builder_callbacks builder_callbacks = {
|
|||
};
|
||||
|
||||
static WpSpaPodBuilder *
|
||||
wp_spa_pod_builder_new (size_t size, uint32_t type)
|
||||
wp_spa_pod_builder_new (size_t size, WpSpaType type)
|
||||
{
|
||||
WpSpaPodBuilder *self = g_rc_box_new0 (WpSpaPodBuilder);
|
||||
self->size = size;
|
||||
|
|
@ -180,10 +178,8 @@ wp_spa_pod_new (const struct spa_pod *pod, WpSpaPodType type, guint32 flags)
|
|||
|
||||
/* Set the prop table if it is an object */
|
||||
if (pod->type == SPA_TYPE_Object) {
|
||||
WpSpaTypeTable prop_table = 0;
|
||||
wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC,
|
||||
((struct spa_pod_object *) pod)->body.type, NULL, NULL, &prop_table);
|
||||
self->static_pod.data_property.table = prop_table;
|
||||
self->static_pod.data_property.table =
|
||||
wp_spa_type_get_values_table (((struct spa_pod_object *) pod)->body.type);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
@ -220,7 +216,7 @@ wp_spa_pod_new_wrap_const (const struct spa_pod *pod)
|
|||
}
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_property_wrap (WpSpaTypeTable table, guint32 key, guint32 flags,
|
||||
wp_spa_pod_new_property_wrap (WpSpaIdTable table, guint32 key, guint32 flags,
|
||||
struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_PROPERTY, FLAG_NO_OWNERSHIP);
|
||||
|
|
@ -231,7 +227,7 @@ wp_spa_pod_new_property_wrap (WpSpaTypeTable table, guint32 key, guint32 flags,
|
|||
}
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_control_wrap (guint32 offset, guint32 type,
|
||||
wp_spa_pod_new_control_wrap (guint32 offset, enum spa_control_type type,
|
||||
struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_CONTROL, FLAG_NO_OWNERSHIP);
|
||||
|
|
@ -244,7 +240,7 @@ wp_spa_pod_new_control_wrap (guint32 offset, guint32 type,
|
|||
/* there is no use for these _const variants, but let's keep them just in case */
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_property_wrap_const (WpSpaTypeTable table, guint32 key,
|
||||
wp_spa_pod_new_property_wrap_const (WpSpaIdTable table, guint32 key,
|
||||
guint32 flags, const struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_PROPERTY,
|
||||
|
|
@ -256,7 +252,7 @@ wp_spa_pod_new_property_wrap_const (WpSpaTypeTable table, guint32 key,
|
|||
}
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_control_wrap_const (guint32 offset, guint32 type,
|
||||
wp_spa_pod_new_control_wrap_const (guint32 offset, enum spa_control_type type,
|
||||
const struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_CONTROL,
|
||||
|
|
@ -274,7 +270,7 @@ wp_spa_pod_new_wrap_copy (const struct spa_pod *pod)
|
|||
}
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_property_wrap_copy (WpSpaTypeTable table, guint32 key,
|
||||
wp_spa_pod_new_property_wrap_copy (WpSpaIdTable table, guint32 key,
|
||||
guint32 flags, const struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_PROPERTY, 0);
|
||||
|
|
@ -285,7 +281,7 @@ wp_spa_pod_new_property_wrap_copy (WpSpaTypeTable table, guint32 key,
|
|||
}
|
||||
|
||||
static WpSpaPod *
|
||||
wp_spa_pod_new_control_wrap_copy (guint32 offset, guint32 type,
|
||||
wp_spa_pod_new_control_wrap_copy (guint32 offset, enum spa_control_type type,
|
||||
const struct spa_pod *pod)
|
||||
{
|
||||
WpSpaPod *self = wp_spa_pod_new (pod, WP_SPA_POD_CONTROL, 0);
|
||||
|
|
@ -311,45 +307,43 @@ wp_spa_pod_get_spa_pod (const WpSpaPod *self)
|
|||
}
|
||||
|
||||
/**
|
||||
* wp_spa_pod_get_type_name:
|
||||
* @self: a spa pod object
|
||||
* wp_spa_pod_get_spa_type:
|
||||
* @self: a spa pod
|
||||
*
|
||||
* Gets the type name of the spa pod object
|
||||
* Gets the SPA type of the spa pod.
|
||||
* If the pod is an object or pointer, this will return the derived
|
||||
* object/pointer type directly.
|
||||
* If the pod is an object property or a control, this will return the type
|
||||
* of the contained value.
|
||||
*
|
||||
* Returns: the type name of the spa pod object
|
||||
* Returns: the type of the spa pod
|
||||
*/
|
||||
const char *
|
||||
wp_spa_pod_get_type_name (WpSpaPod *self)
|
||||
WpSpaType
|
||||
wp_spa_pod_get_spa_type (WpSpaPod *self)
|
||||
{
|
||||
const char *nick = NULL;
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, SPA_POD_TYPE (self->pod),
|
||||
NULL, &nick, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
return nick;
|
||||
g_return_val_if_fail (self != NULL, WP_SPA_TYPE_INVALID);
|
||||
|
||||
if (wp_spa_pod_is_object (self) || wp_spa_pod_is_pointer (self))
|
||||
return SPA_POD_OBJECT_TYPE (self->pod);
|
||||
else
|
||||
return SPA_POD_TYPE (self->pod);
|
||||
}
|
||||
|
||||
const char *
|
||||
wp_spa_pod_get_choice_type_name (WpSpaPod *self)
|
||||
/**
|
||||
* wp_spa_pod_get_choice_type:
|
||||
* @self: a choice pod
|
||||
*
|
||||
* If the pod is a Choice, this gets the choice type
|
||||
* (Range, Step, Enum, ...)
|
||||
*
|
||||
* Returns: the choice type of the choice pod
|
||||
*/
|
||||
WpSpaIdValue
|
||||
wp_spa_pod_get_choice_type (WpSpaPod *self)
|
||||
{
|
||||
g_return_val_if_fail (wp_spa_pod_is_choice (self), NULL);
|
||||
|
||||
const char *nick = NULL;
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_CHOICE,
|
||||
SPA_POD_CHOICE_TYPE (self->pod), NULL, &nick, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
return nick;
|
||||
}
|
||||
|
||||
const char *
|
||||
wp_spa_pod_get_object_type_name (WpSpaPod *self)
|
||||
{
|
||||
g_return_val_if_fail (wp_spa_pod_is_object (self), NULL);
|
||||
|
||||
const char *nick = NULL;
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC,
|
||||
SPA_POD_OBJECT_TYPE (self->pod), NULL, &nick, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
return nick;
|
||||
return wp_spa_id_value_from_number (
|
||||
SPA_TYPE_INFO_Choice, SPA_POD_CHOICE_TYPE (self->pod));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -609,7 +603,7 @@ wp_spa_pod_new_bytes (gconstpointer value, guint32 len)
|
|||
|
||||
/**
|
||||
* wp_spa_pod_new_pointer:
|
||||
* @type_name: the type name the pointer points to
|
||||
* @type_name: the name of the type of the pointer
|
||||
* @value: the pointer value
|
||||
*
|
||||
* Creates a spa pod of type pointer
|
||||
|
|
@ -619,13 +613,12 @@ wp_spa_pod_new_bytes (gconstpointer value, guint32 len)
|
|||
WpSpaPod *
|
||||
wp_spa_pod_new_pointer (const char *type_name, gconstpointer value)
|
||||
{
|
||||
WpSpaType type = wp_spa_type_from_name (type_name);
|
||||
g_return_val_if_fail (type != WP_SPA_TYPE_INVALID, NULL);
|
||||
|
||||
WpSpaPod *self = g_slice_new0 (WpSpaPod);
|
||||
g_ref_count_init (&self->ref);
|
||||
self->type = WP_SPA_POD_REGULAR;
|
||||
guint32 type = 0;
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, type_name, &type,
|
||||
NULL, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
self->static_pod.pod_pointer = SPA_POD_INIT_Pointer (type, value);
|
||||
self->pod = &self->static_pod.pod_pointer.pod;
|
||||
return self;
|
||||
|
|
@ -694,7 +687,7 @@ wp_spa_pod_new_fraction (guint32 num, guint32 denom)
|
|||
|
||||
/**
|
||||
* wp_spa_pod_new_choice:
|
||||
* @type_name: the type name of the choice type
|
||||
* @choice_type: the name of the choice type ("Range", "Step", ...)
|
||||
* @...: a list of choice values, followed by %NULL
|
||||
*
|
||||
* Creates a spa pod of type choice
|
||||
|
|
@ -702,13 +695,13 @@ wp_spa_pod_new_fraction (guint32 num, guint32 denom)
|
|||
* Returns: (transfer full): The new spa pod
|
||||
*/
|
||||
WpSpaPod *
|
||||
wp_spa_pod_new_choice (const char *type_name, ...)
|
||||
wp_spa_pod_new_choice (const char *choice_type, ...)
|
||||
{
|
||||
WpSpaPod *self;
|
||||
va_list args;
|
||||
|
||||
va_start (args, type_name);
|
||||
self = wp_spa_pod_new_choice_valist (type_name, args);
|
||||
va_start (args, choice_type);
|
||||
self = wp_spa_pod_new_choice_valist (choice_type, args);
|
||||
va_end (args);
|
||||
|
||||
return self;
|
||||
|
|
@ -716,7 +709,7 @@ wp_spa_pod_new_choice (const char *type_name, ...)
|
|||
|
||||
/**
|
||||
* wp_spa_pod_new_choice_valist:
|
||||
* @type_name: the type name of the choice type
|
||||
* @choice_type: the name of the choice type ("Range", "Step", ...)
|
||||
* @args: the variable arguments passed to wp_spa_pod_new_choice()
|
||||
*
|
||||
* This is the `va_list` version of wp_spa_pod_new_choice()
|
||||
|
|
@ -724,9 +717,9 @@ wp_spa_pod_new_choice (const char *type_name, ...)
|
|||
* Returns: (transfer full): The new spa pod
|
||||
*/
|
||||
WpSpaPod *
|
||||
wp_spa_pod_new_choice_valist (const char *type_name, va_list args)
|
||||
wp_spa_pod_new_choice_valist (const char *choice_type, va_list args)
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_choice (type_name);
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_choice (choice_type);
|
||||
wp_spa_pod_builder_add_valist (b, args);
|
||||
return wp_spa_pod_builder_end (b);
|
||||
}
|
||||
|
|
@ -838,8 +831,7 @@ wp_spa_pod_is_none (WpSpaPod *self)
|
|||
gboolean
|
||||
wp_spa_pod_is_boolean (WpSpaPod *self)
|
||||
{
|
||||
return self->type == WP_SPA_POD_REGULAR &&
|
||||
spa_pod_is_bool (self->pod) ? TRUE : FALSE;
|
||||
return self->type == WP_SPA_POD_REGULAR && spa_pod_is_bool (self->pod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1241,7 +1233,6 @@ wp_spa_pod_get_bytes (WpSpaPod *self, gconstpointer *value, guint32 *len)
|
|||
/**
|
||||
* wp_spa_pod_get_pointer:
|
||||
* @self: the spa pod object
|
||||
* @type_name: (out): the type name of the pointer value
|
||||
* @value: (out): the pointer value
|
||||
*
|
||||
* Gets the pointer value and its type name of a spa pod object
|
||||
|
|
@ -1249,21 +1240,13 @@ wp_spa_pod_get_bytes (WpSpaPod *self, gconstpointer *value, guint32 *len)
|
|||
* Returns: TRUE if the value was obtained, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_pod_get_pointer (WpSpaPod *self, const char **type_name,
|
||||
gconstpointer *value)
|
||||
wp_spa_pod_get_pointer (WpSpaPod *self, gconstpointer *value)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (self, FALSE);
|
||||
g_return_val_if_fail (type_name, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
guint32 type = 0;
|
||||
res = spa_pod_get_pointer (self->pod, &type, value) >= 0;
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, type, NULL, type_name,
|
||||
NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
return res;
|
||||
return spa_pod_get_pointer (self->pod, &type, value) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1440,7 +1423,7 @@ wp_spa_pod_set_double (WpSpaPod *self, double value)
|
|||
/**
|
||||
* wp_spa_pod_set_pointer:
|
||||
* @self: the spa pod object
|
||||
* @type_name: the type name the pointer points to
|
||||
* @type_name: the name of the type of the pointer
|
||||
* @value: the pointer value
|
||||
*
|
||||
* Sets a pointer value with its type name in the spa pod object.
|
||||
|
|
@ -1451,16 +1434,13 @@ gboolean
|
|||
wp_spa_pod_set_pointer (WpSpaPod *self, const char *type_name,
|
||||
gconstpointer value)
|
||||
{
|
||||
guint32 id = 0;
|
||||
WpSpaType type = wp_spa_type_from_name (type_name);
|
||||
|
||||
g_return_val_if_fail (wp_spa_pod_is_pointer (self), FALSE);
|
||||
g_return_val_if_fail (!(self->flags & FLAG_CONSTANT), FALSE);
|
||||
g_return_val_if_fail (type != WP_SPA_TYPE_INVALID, FALSE);
|
||||
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, type_name, &id, NULL,
|
||||
NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
((struct spa_pod_pointer *)self->pod)->body.type = id;
|
||||
((struct spa_pod_pointer *)self->pod)->body.type = type;
|
||||
((struct spa_pod_pointer *)self->pod)->body.value = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1679,7 +1659,7 @@ wp_spa_pod_equal (WpSpaPod *self, WpSpaPod *pod)
|
|||
switch (self->type) {
|
||||
case WP_SPA_POD_PROPERTY:
|
||||
if (self->static_pod.data_property.table != pod->static_pod.data_property.table ||
|
||||
self->static_pod.data_property.table != pod->static_pod.data_property.table ||
|
||||
self->static_pod.data_property.key != pod->static_pod.data_property.key ||
|
||||
self->static_pod.data_property.flags != pod->static_pod.data_property.flags)
|
||||
return FALSE;
|
||||
break;
|
||||
|
|
@ -1699,7 +1679,6 @@ wp_spa_pod_equal (WpSpaPod *self, WpSpaPod *pod)
|
|||
/**
|
||||
* wp_spa_pod_get_object:
|
||||
* @self: the spa pod object
|
||||
* @type_name: the type name of the object type
|
||||
* @id_name: (out): the id name of the object
|
||||
* @...: (out): the list of the object properties values, followed by %NULL
|
||||
*
|
||||
|
|
@ -1708,13 +1687,12 @@ wp_spa_pod_equal (WpSpaPod *self, WpSpaPod *pod)
|
|||
* Returns: TRUE if the object properties values were obtained, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_pod_get_object (WpSpaPod *self, const char *type_name,
|
||||
const char **id_name, ...)
|
||||
wp_spa_pod_get_object (WpSpaPod *self, const char **id_name, ...)
|
||||
{
|
||||
va_list args;
|
||||
gboolean res;
|
||||
va_start (args, id_name);
|
||||
res = wp_spa_pod_get_object_valist (self, type_name, id_name, args);
|
||||
res = wp_spa_pod_get_object_valist (self, id_name, args);
|
||||
va_end (args);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1722,7 +1700,6 @@ wp_spa_pod_get_object (WpSpaPod *self, const char *type_name,
|
|||
/**
|
||||
* wp_spa_pod_get_object_valist:
|
||||
* @self: the spa pod object
|
||||
* @type_name: the type name of the object type
|
||||
* @id_name: (out): the id name of the object
|
||||
* @args: (out): the variable arguments passed to wp_spa_pod_get_object()
|
||||
*
|
||||
|
|
@ -1731,13 +1708,11 @@ wp_spa_pod_get_object (WpSpaPod *self, const char *type_name,
|
|||
* Returns: TRUE if the object properties values were obtained, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_pod_get_object_valist (WpSpaPod *self, const char *type_name,
|
||||
const char **id_name, va_list args)
|
||||
wp_spa_pod_get_object_valist (WpSpaPod *self, const char **id_name, va_list args)
|
||||
{
|
||||
g_return_val_if_fail (self, FALSE);
|
||||
g_return_val_if_fail (wp_spa_pod_is_object (self), FALSE);
|
||||
g_autoptr (WpSpaPodParser) p = wp_spa_pod_parser_new_object (self, type_name,
|
||||
id_name);
|
||||
g_autoptr (WpSpaPodParser) p = wp_spa_pod_parser_new_object (self, id_name);
|
||||
const gboolean res = wp_spa_pod_parser_get_valist (p, args);
|
||||
wp_spa_pod_parser_end (p);
|
||||
return res;
|
||||
|
|
@ -1800,9 +1775,13 @@ wp_spa_pod_get_property (WpSpaPod *self, const char **key,
|
|||
g_return_val_if_fail (self, FALSE);
|
||||
g_return_val_if_fail (wp_spa_pod_is_property (self), FALSE);
|
||||
|
||||
if (key && !wp_spa_type_get_by_id (self->static_pod.data_property.table,
|
||||
self->static_pod.data_property.key, NULL, key, NULL))
|
||||
return FALSE;
|
||||
if (key) {
|
||||
WpSpaIdValue key_val = wp_spa_id_table_find_value (
|
||||
self->static_pod.data_property.table,
|
||||
self->static_pod.data_property.key);
|
||||
g_return_val_if_fail (key_val != NULL, FALSE);
|
||||
*key = wp_spa_id_value_short_name (key_val);
|
||||
}
|
||||
if (value)
|
||||
*value = wp_spa_pod_new_wrap (self->pod);
|
||||
|
||||
|
|
@ -1813,7 +1792,7 @@ wp_spa_pod_get_property (WpSpaPod *self, const char **key,
|
|||
* wp_spa_pod_get_control:
|
||||
* @self: the spa pod object
|
||||
* @offset: (out) (optional): the offset of the control
|
||||
* @type_name: (out) (optional): the type name of the control
|
||||
* @ctl_type: (out) (optional): the control type (Properties, Midi, ...)
|
||||
* @value: (out) (optional): the spa pod value of the control
|
||||
*
|
||||
* Gets the offset, type name and spa pod value of a spa pod control
|
||||
|
|
@ -1821,7 +1800,7 @@ wp_spa_pod_get_property (WpSpaPod *self, const char **key,
|
|||
* Returns: TRUE if the value was obtained, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_pod_get_control (WpSpaPod *self, guint32 *offset, const char **type_name,
|
||||
wp_spa_pod_get_control (WpSpaPod *self, guint32 *offset, const char **ctl_type,
|
||||
WpSpaPod **value)
|
||||
{
|
||||
g_return_val_if_fail (self, FALSE);
|
||||
|
|
@ -1829,9 +1808,12 @@ wp_spa_pod_get_control (WpSpaPod *self, guint32 *offset, const char **type_name,
|
|||
|
||||
if (offset)
|
||||
*offset = self->static_pod.data_control.offset;
|
||||
if (type_name && !wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_CONTROL,
|
||||
self->static_pod.data_control.type, NULL, type_name, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (ctl_type) {
|
||||
WpSpaIdValue type_val = wp_spa_id_value_from_number (
|
||||
SPA_TYPE_INFO_Control, self->static_pod.data_control.type);
|
||||
g_return_val_if_fail (type_val != NULL, FALSE);
|
||||
*ctl_type = wp_spa_id_value_short_name (type_val);
|
||||
}
|
||||
if (value)
|
||||
*value = wp_spa_pod_new_wrap (self->pod);
|
||||
|
||||
|
|
@ -1917,30 +1899,27 @@ wp_spa_pod_builder_new_array (void)
|
|||
|
||||
/**
|
||||
* wp_spa_pod_builder_new_choice:
|
||||
* @type_name: the type name of the choice type
|
||||
* @choice_type: the name of the choice type ("Range", "Step", ...)
|
||||
*
|
||||
* Creates a spa pod builder of type choice
|
||||
*
|
||||
* Returns: (transfer full): the new spa pod builder
|
||||
*/
|
||||
WpSpaPodBuilder *
|
||||
wp_spa_pod_builder_new_choice (const char *type_name)
|
||||
wp_spa_pod_builder_new_choice (const char *choice_type)
|
||||
{
|
||||
WpSpaPodBuilder *self = NULL;
|
||||
guint32 type = 0;
|
||||
WpSpaIdValue type = wp_spa_id_value_from_short_name (
|
||||
SPA_TYPE_INFO_Choice, choice_type);
|
||||
g_return_val_if_fail (type != NULL, NULL);
|
||||
|
||||
/* Construct the builder */
|
||||
self = wp_spa_pod_builder_new (WP_SPA_POD_BUILDER_REALLOC_STEP_SIZE,
|
||||
SPA_TYPE_Choice);
|
||||
|
||||
/* Find the choice type */
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_CHOICE, type_name, &type,
|
||||
NULL, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
/* Push the array */
|
||||
spa_pod_builder_push_choice (&self->builder, &self->frame, type,
|
||||
WP_SPA_TYPE_TABLE_CHOICE);
|
||||
spa_pod_builder_push_choice (&self->builder, &self->frame,
|
||||
wp_spa_id_value_number (type), 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -1958,25 +1937,27 @@ WpSpaPodBuilder *
|
|||
wp_spa_pod_builder_new_object (const char *type_name, const char *id_name)
|
||||
{
|
||||
WpSpaPodBuilder *self = NULL;
|
||||
guint32 type = 0;
|
||||
guint32 id = 0;
|
||||
|
||||
/* Construct the builder */
|
||||
self = wp_spa_pod_builder_new (WP_SPA_POD_BUILDER_REALLOC_STEP_SIZE,
|
||||
SPA_TYPE_Object);
|
||||
WpSpaType type;
|
||||
WpSpaIdTable table;
|
||||
WpSpaIdValue id;
|
||||
|
||||
/* Find the type */
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, type_name, &type,
|
||||
NULL, &self->prop_table))
|
||||
g_return_val_if_reached (NULL);
|
||||
type = wp_spa_type_from_name (type_name);
|
||||
g_return_val_if_fail (wp_spa_type_is_object (type), NULL);
|
||||
|
||||
/* Find the id */
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_PARAM, id_name, &id, NULL,
|
||||
NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
table = wp_spa_type_get_object_id_values_table (type);
|
||||
g_return_val_if_fail (table != NULL, NULL);
|
||||
|
||||
id = wp_spa_id_table_find_value_from_short_name (table, id_name);
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
|
||||
/* Construct the builder */
|
||||
self = wp_spa_pod_builder_new (WP_SPA_POD_BUILDER_REALLOC_STEP_SIZE, type);
|
||||
|
||||
/* Push the object */
|
||||
spa_pod_builder_push_object (&self->builder, &self->frame, type, id);
|
||||
spa_pod_builder_push_object (&self->builder, &self->frame, type,
|
||||
wp_spa_id_value_number (id));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -2145,10 +2126,8 @@ void
|
|||
wp_spa_pod_builder_add_pointer (WpSpaPodBuilder *self, const char *type_name,
|
||||
gconstpointer value)
|
||||
{
|
||||
guint32 type = 0;
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, type_name, &type,
|
||||
NULL, NULL))
|
||||
g_return_if_reached ();
|
||||
WpSpaType type = wp_spa_type_from_name (type_name);
|
||||
g_return_if_fail (wp_spa_type_parent (type) == SPA_TYPE_Pointer);
|
||||
spa_pod_builder_pointer (&self->builder, type, value);
|
||||
}
|
||||
|
||||
|
|
@ -2218,10 +2197,10 @@ wp_spa_pod_builder_add_pod (WpSpaPodBuilder *self, WpSpaPod *pod)
|
|||
void
|
||||
wp_spa_pod_builder_add_property (WpSpaPodBuilder *self, const char *key)
|
||||
{
|
||||
guint32 id = 0;
|
||||
if (!wp_spa_type_get_by_nick (self->prop_table, key, &id, NULL, NULL))
|
||||
g_return_if_reached ();
|
||||
spa_pod_builder_prop (&self->builder, id, 0);
|
||||
WpSpaIdTable table = wp_spa_type_get_values_table (self->type);
|
||||
WpSpaIdValue id = wp_spa_id_table_find_value_from_short_name (table, key);
|
||||
g_return_if_fail (id != NULL);
|
||||
spa_pod_builder_prop (&self->builder, wp_spa_id_value_number (id), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2249,11 +2228,10 @@ void
|
|||
wp_spa_pod_builder_add_control (WpSpaPodBuilder *self, guint32 offset,
|
||||
const char *type_name)
|
||||
{
|
||||
guint type = 0;
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_CONTROL, type_name, &type,
|
||||
NULL, NULL))
|
||||
g_return_if_reached ();
|
||||
spa_pod_builder_control (&self->builder, offset, type);
|
||||
WpSpaIdValue id = wp_spa_id_value_from_short_name (
|
||||
SPA_TYPE_INFO_Control, type_name);
|
||||
g_return_if_fail (id != NULL);
|
||||
spa_pod_builder_control (&self->builder, offset, wp_spa_id_value_number (id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2288,41 +2266,30 @@ wp_spa_pod_builder_add_valist (WpSpaPodBuilder *self, va_list args)
|
|||
struct spa_pod_frame f;
|
||||
gboolean choice;
|
||||
|
||||
switch (self->type) {
|
||||
case SPA_TYPE_Object:
|
||||
{
|
||||
guint32 key = 0;
|
||||
if (wp_spa_type_is_object (self->type)) {
|
||||
const char *key_name = va_arg(args, const char *);
|
||||
if (!key_name)
|
||||
return;
|
||||
if (!wp_spa_type_get_by_nick (self->prop_table, key_name, &key, NULL,
|
||||
NULL))
|
||||
g_return_if_reached ();
|
||||
if (key == 0)
|
||||
return;
|
||||
WpSpaIdTable table = wp_spa_type_get_values_table (self->type);
|
||||
WpSpaIdValue key =
|
||||
wp_spa_id_table_find_value_from_short_name (table, key_name);
|
||||
g_return_if_fail (key != NULL);
|
||||
|
||||
spa_pod_builder_prop (&self->builder, key, 0);
|
||||
break;
|
||||
spa_pod_builder_prop (&self->builder, wp_spa_id_value_number (key), 0);
|
||||
}
|
||||
case SPA_TYPE_Sequence:
|
||||
{
|
||||
else if (self->type == SPA_TYPE_Sequence) {
|
||||
guint32 offset = va_arg(args, uint32_t);
|
||||
guint32 type = 0;
|
||||
if (offset == 0)
|
||||
return;
|
||||
const char *control_name = va_arg(args, const char *);
|
||||
if (!control_name)
|
||||
return;
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_CONTROL, control_name,
|
||||
&type, NULL, NULL))
|
||||
g_return_if_reached ();
|
||||
if (type == 0)
|
||||
return;
|
||||
WpSpaIdValue type = wp_spa_id_value_from_short_name (
|
||||
SPA_TYPE_INFO_Control, control_name);
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
spa_pod_builder_control (&self->builder, offset, type);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
spa_pod_builder_control (&self->builder, offset,
|
||||
wp_spa_id_value_number (type));
|
||||
}
|
||||
|
||||
if ((format = va_arg(args, const char *)) == NULL)
|
||||
|
|
@ -2376,9 +2343,10 @@ wp_spa_pod_builder_end (WpSpaPodBuilder *self)
|
|||
ret->pod = spa_pod_builder_pop (&self->builder, &self->frame);
|
||||
ret->builder = wp_spa_pod_builder_ref (self);
|
||||
|
||||
/* Also copy the property table if it is an object type */
|
||||
if (ret->builder->type == SPA_TYPE_Object)
|
||||
ret->static_pod.data_property.table = ret->builder->prop_table;
|
||||
/* Also copy the specific object type if it is an object */
|
||||
if (spa_pod_is_object (ret->pod))
|
||||
ret->static_pod.data_property.table =
|
||||
wp_spa_type_get_values_table (ret->builder->type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2427,7 +2395,6 @@ wp_spa_pod_parser_new (WpSpaPod *pod, guint32 type)
|
|||
/**
|
||||
* wp_spa_pod_parser_new:
|
||||
* @pod: the object spa pod to parse
|
||||
* @type_name: the type name of the object type
|
||||
* @id_name: the Id name of the object
|
||||
*
|
||||
* Creates an object spa pod parser. The @pod object must be valid for the
|
||||
|
|
@ -2436,22 +2403,21 @@ wp_spa_pod_parser_new (WpSpaPod *pod, guint32 type)
|
|||
* Returns: (transfer full): The new spa pod parser
|
||||
*/
|
||||
WpSpaPodParser *
|
||||
wp_spa_pod_parser_new_object (WpSpaPod *pod, const char *type_name,
|
||||
const char **id_name)
|
||||
wp_spa_pod_parser_new_object (WpSpaPod *pod, const char **id_name)
|
||||
{
|
||||
WpSpaPodParser *self = NULL;
|
||||
guint32 type = 0;
|
||||
guint32 id = 0;
|
||||
WpSpaType type = wp_spa_pod_get_spa_type (pod);
|
||||
guint32 id = SPA_ID_INVALID;
|
||||
|
||||
g_return_val_if_fail (wp_spa_pod_is_object (pod), NULL);
|
||||
|
||||
self = wp_spa_pod_parser_new (pod, SPA_TYPE_Object);
|
||||
if (!wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, type_name, &type,
|
||||
NULL, &self->prop_table))
|
||||
g_return_val_if_reached (NULL);
|
||||
self = wp_spa_pod_parser_new (pod, type);
|
||||
spa_pod_parser_push_object (&self->parser, &self->frame, type, &id);
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, id, NULL, id_name, NULL))
|
||||
g_return_val_if_reached (NULL);
|
||||
if (id_name) {
|
||||
WpSpaIdTable table = wp_spa_type_get_object_id_values_table (type);
|
||||
*id_name = wp_spa_id_value_short_name (
|
||||
wp_spa_id_table_find_value (table, id));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -2611,7 +2577,6 @@ wp_spa_pod_parser_get_bytes (WpSpaPodParser *self, gconstpointer *value,
|
|||
/**
|
||||
* wp_spa_pod_parser_get_pointer:
|
||||
* @self: the spa pod parser object
|
||||
* @type_name: (out): the type name of the pointer value
|
||||
* @value: (out): the pointer value
|
||||
*
|
||||
* Gets the pointer value and its type name from a spa pod parser object
|
||||
|
|
@ -2619,20 +2584,11 @@ wp_spa_pod_parser_get_bytes (WpSpaPodParser *self, gconstpointer *value,
|
|||
* Returns: TRUE if the value was obtained, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_pod_parser_get_pointer (WpSpaPodParser *self, const char **type_name,
|
||||
gconstpointer *value)
|
||||
wp_spa_pod_parser_get_pointer (WpSpaPodParser *self, gconstpointer *value)
|
||||
{
|
||||
guint32 type = 0;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
|
||||
res = spa_pod_parser_get_pointer (&self->parser, &type, value) >= 0;
|
||||
|
||||
if (!wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, type, NULL, type_name,
|
||||
NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
return res;
|
||||
guint32 type = 0;
|
||||
return spa_pod_parser_get_pointer (&self->parser, &type, value) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2759,20 +2715,19 @@ wp_spa_pod_parser_get_valist (WpSpaPodParser *self, va_list args)
|
|||
const struct spa_pod *pod = NULL;
|
||||
const char *format;
|
||||
|
||||
if (self->type == SPA_TYPE_Object) {
|
||||
guint32 key = 0;
|
||||
const struct spa_pod_object *object;
|
||||
if (wp_spa_type_is_object (self->type)) {
|
||||
const char *key_name = va_arg(args, const char *);
|
||||
if (!key_name)
|
||||
break;
|
||||
if (!wp_spa_type_get_by_nick (self->prop_table, key_name, &key, NULL, NULL))
|
||||
g_return_val_if_reached (FALSE);
|
||||
if (key == 0)
|
||||
break;
|
||||
WpSpaIdTable table = wp_spa_type_get_values_table (self->type);
|
||||
WpSpaIdValue key =
|
||||
wp_spa_id_table_find_value_from_short_name (table, key_name);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
object = (const struct spa_pod_object *)spa_pod_parser_frame (
|
||||
&self->parser, &self->frame);
|
||||
prop = spa_pod_object_find_prop (object, prop, key);
|
||||
const struct spa_pod_object *object = (const struct spa_pod_object *)
|
||||
spa_pod_parser_frame (&self->parser, &self->frame);
|
||||
prop = spa_pod_object_find_prop (object, prop,
|
||||
wp_spa_id_value_number (key));
|
||||
pod = prop ? &prop->value : NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2884,7 +2839,6 @@ wp_spa_pod_iterator_next_object (WpSpaPodIterator *self, GValue *item)
|
|||
{
|
||||
const struct spa_pod_object *pod_obj =
|
||||
(const struct spa_pod_object *) self->pod->pod;
|
||||
g_autoptr (WpSpaPod) pod = NULL;
|
||||
|
||||
if (!self->curr.prop)
|
||||
self->curr.prop = spa_pod_prop_first (&pod_obj->body);
|
||||
|
|
@ -2928,7 +2882,6 @@ wp_spa_pod_iterator_next_sequence (WpSpaPodIterator *self, GValue *item)
|
|||
{
|
||||
const struct spa_pod_sequence *pod_seq =
|
||||
(const struct spa_pod_sequence *) self->pod->pod;
|
||||
g_autoptr (WpSpaPod) pod = NULL;
|
||||
|
||||
if (!self->curr.control)
|
||||
self->curr.control = spa_pod_control_first (&pod_seq->body);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "defs.h"
|
||||
#include "iterator.h"
|
||||
#include "spa-type.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -45,19 +46,16 @@ WP_API
|
|||
const struct spa_pod * wp_spa_pod_get_spa_pod (const WpSpaPod *self);
|
||||
|
||||
WP_API
|
||||
const char *wp_spa_pod_get_type_name (WpSpaPod *self);
|
||||
WpSpaType wp_spa_pod_get_spa_type (WpSpaPod *self);
|
||||
|
||||
WP_API
|
||||
const char *wp_spa_pod_get_choice_type_name (WpSpaPod *self);
|
||||
|
||||
WP_API
|
||||
const char *wp_spa_pod_get_object_type_name (WpSpaPod *self);
|
||||
WpSpaIdValue wp_spa_pod_get_choice_type (WpSpaPod *self);
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_copy (WpSpaPod *other);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_is_unique_owner ( WpSpaPod *self);
|
||||
gboolean wp_spa_pod_is_unique_owner (WpSpaPod *self);
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_ensure_unique_owner (WpSpaPod *self);
|
||||
|
|
@ -102,11 +100,11 @@ WP_API
|
|||
WpSpaPod *wp_spa_pod_new_fraction (guint32 num, guint32 denom);
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_new_choice (const char *type_name, ...)
|
||||
WpSpaPod *wp_spa_pod_new_choice (const char *choice_type, ...)
|
||||
G_GNUC_NULL_TERMINATED;
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_new_choice_valist (const char *type_name, va_list args);
|
||||
WpSpaPod *wp_spa_pod_new_choice_valist (const char *choice_type, va_list args);
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_new_object (const char *type_name, const char *id_name,
|
||||
|
|
@ -208,8 +206,7 @@ gboolean wp_spa_pod_get_bytes (WpSpaPod *self, gconstpointer *value,
|
|||
guint32 *len);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_get_pointer (WpSpaPod *self, const char **type_name,
|
||||
gconstpointer *value);
|
||||
gboolean wp_spa_pod_get_pointer (WpSpaPod *self, gconstpointer *value);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_get_fd (WpSpaPod *self, gint64 *value);
|
||||
|
|
@ -260,11 +257,11 @@ WP_API
|
|||
gboolean wp_spa_pod_equal (WpSpaPod *self, WpSpaPod *pod);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_get_object (WpSpaPod *self, const char *type_name,
|
||||
gboolean wp_spa_pod_get_object (WpSpaPod *self,
|
||||
const char **id_name, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_get_object_valist (WpSpaPod *self, const char *type_name,
|
||||
gboolean wp_spa_pod_get_object_valist (WpSpaPod *self,
|
||||
const char **id_name, va_list args);
|
||||
|
||||
WP_API
|
||||
|
|
@ -279,7 +276,7 @@ gboolean wp_spa_pod_get_property (WpSpaPod *self, const char **key,
|
|||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_get_control (WpSpaPod *self, guint32 *offset,
|
||||
const char **type_name, WpSpaPod **value);
|
||||
const char **ctl_type, WpSpaPod **value);
|
||||
|
||||
WP_API
|
||||
WpSpaPod *wp_spa_pod_get_choice_child (WpSpaPod *self);
|
||||
|
|
@ -314,7 +311,7 @@ WP_API
|
|||
WpSpaPodBuilder *wp_spa_pod_builder_new_array (void);
|
||||
|
||||
WP_API
|
||||
WpSpaPodBuilder *wp_spa_pod_builder_new_choice (const char *type_name);
|
||||
WpSpaPodBuilder *wp_spa_pod_builder_new_choice (const char *choice_type);
|
||||
|
||||
WP_API
|
||||
WpSpaPodBuilder *wp_spa_pod_builder_new_object (const char *type_name,
|
||||
|
|
@ -380,7 +377,7 @@ void wp_spa_pod_builder_add_property_id (WpSpaPodBuilder *self, guint32 id);
|
|||
|
||||
WP_API
|
||||
void wp_spa_pod_builder_add_control (WpSpaPodBuilder *self, guint32 offset,
|
||||
const char *type_name);
|
||||
const char *ctl_type);
|
||||
|
||||
WP_API
|
||||
void wp_spa_pod_builder_add (WpSpaPodBuilder *self, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
|
@ -413,7 +410,7 @@ void wp_spa_pod_parser_unref (WpSpaPodParser *self);
|
|||
|
||||
WP_API
|
||||
WpSpaPodParser *wp_spa_pod_parser_new_object (WpSpaPod *pod,
|
||||
const char *type_name, const char **id_name);
|
||||
const char **id_name);
|
||||
|
||||
WP_API
|
||||
WpSpaPodParser *wp_spa_pod_parser_new_struct (WpSpaPod *pod);
|
||||
|
|
@ -446,7 +443,7 @@ gboolean wp_spa_pod_parser_get_bytes (WpSpaPodParser *self,
|
|||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_parser_get_pointer (WpSpaPodParser *self,
|
||||
const char **type_name, gconstpointer *value);
|
||||
gconstpointer *value);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_pod_parser_get_fd (WpSpaPodParser *self, gint64 *value);
|
||||
|
|
|
|||
|
|
@ -6,336 +6,706 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "wp-spa-type"
|
||||
/**
|
||||
* SECTION: spa-type
|
||||
* @title: Spa Type Information
|
||||
*
|
||||
* Spa has a type system that is represented by a set of arrays that contain
|
||||
* `spa_type_info` structures. This type system is simple, yet complex to
|
||||
* work with for a couple of reasons.
|
||||
*
|
||||
* WirePlumber uses this API to access the spa type system, which makes some
|
||||
* things easier to understand and work with. The main benefit of using this
|
||||
* API is that it makes it easy to work with string representations of the
|
||||
* types, allowing easier access from script bindings.
|
||||
*
|
||||
* ### Type hierarchy
|
||||
*
|
||||
* On the top level, there is a list of types like Int, Bool, String, Id, Object.
|
||||
* These are called fundamental types (terms borrowed from #GType).
|
||||
* Fundamental types can be derived and therefore we can have other types
|
||||
* that represent specific enums or objects, for instance.
|
||||
*
|
||||
* Enum and flag types are all derived directly from `SPA_TYPE_Id`. These types
|
||||
* may have a list of possible values that one can select from (enums)
|
||||
* or combine (flags). These values are accessed with the #WpSpaIdValue API.
|
||||
*
|
||||
* Object types can have fields. All objects always have a special "id" field,
|
||||
* whose type can be given by wp_spa_object_type_get_id_type() and optionally,
|
||||
* they can also have other object-specific fields, which are also accessed
|
||||
* with the #WpSpaIdValue API.
|
||||
*/
|
||||
|
||||
#include <spa/utils/type-info.h>
|
||||
#define G_LOG_DOMAIN "wp-spa-type"
|
||||
|
||||
#include "spa-type.h"
|
||||
|
||||
static gboolean
|
||||
name_equal_func (gconstpointer a, gconstpointer b) {
|
||||
const struct spa_type_info *ti = a;
|
||||
const char *name = b;
|
||||
return g_strcmp0 (ti->name, name) == 0;
|
||||
#include <spa/utils/type-info.h>
|
||||
#include <spa/debug/types.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
static const WpSpaType SPA_TYPE_VENDOR_WirePlumber = 0x03000000;
|
||||
static GArray *extra_types = NULL;
|
||||
static GArray *extra_id_tables = NULL;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const struct spa_type_info *values;
|
||||
} WpSpaIdTableInfo;
|
||||
|
||||
static const WpSpaIdTableInfo static_id_tables[] = {
|
||||
{ SPA_TYPE_INFO_Choice, spa_type_choice },
|
||||
{ SPA_TYPE_INFO_Direction, spa_type_direction },
|
||||
{ SPA_TYPE_INFO_ParamId, spa_type_param },
|
||||
{ SPA_TYPE_INFO_MediaType, spa_type_media_type },
|
||||
{ SPA_TYPE_INFO_MediaSubtype, spa_type_media_subtype },
|
||||
{ SPA_TYPE_INFO_ParamAvailability, spa_type_param_availability },
|
||||
{ SPA_TYPE_INFO_ParamPortConfigMode, spa_type_param_port_config_mode },
|
||||
{ SPA_TYPE_INFO_VideoFormat, spa_type_video_format },
|
||||
{ SPA_TYPE_INFO_AudioFormat, spa_type_audio_format },
|
||||
{ SPA_TYPE_INFO_AudioFlags, spa_type_audio_flags },
|
||||
{ SPA_TYPE_INFO_AudioChannel, spa_type_audio_channel },
|
||||
{ SPA_TYPE_INFO_IO, spa_type_io },
|
||||
{ SPA_TYPE_INFO_Control, spa_type_control },
|
||||
{ SPA_TYPE_INFO_Data, spa_type_data_type },
|
||||
{ SPA_TYPE_INFO_Meta, spa_type_meta_type },
|
||||
{ SPA_TYPE_INFO_NodeEvent, spa_type_node_event_id },
|
||||
{ SPA_TYPE_INFO_NodeCommand, spa_type_node_command_id },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* WpSpaType:
|
||||
*/
|
||||
GType wp_spa_type_get_type (void)
|
||||
{
|
||||
static volatile gsize id__volatile = 0;
|
||||
if (g_once_init_enter (&id__volatile)) {
|
||||
GType id = g_type_register_static_simple (
|
||||
G_TYPE_UINT, g_intern_static_string ("WpSpaType"),
|
||||
0, NULL, 0, NULL, 0);
|
||||
g_once_init_leave (&id__volatile, id);
|
||||
}
|
||||
return id__volatile;
|
||||
}
|
||||
|
||||
/**
|
||||
* WpSpaIdTable:
|
||||
*/
|
||||
G_DEFINE_POINTER_TYPE (WpSpaIdTable, wp_spa_id_table)
|
||||
|
||||
/**
|
||||
* WpSpaIdValue:
|
||||
*/
|
||||
G_DEFINE_POINTER_TYPE (WpSpaIdValue, wp_spa_id_value)
|
||||
|
||||
|
||||
static const struct spa_type_info *
|
||||
spa_type_find (const struct spa_type_info *table, GEqualFunc func,
|
||||
gconstpointer data)
|
||||
wp_spa_type_info_find_by_type (WpSpaType type)
|
||||
{
|
||||
for (guint32 i = 0; table[i].name; i++)
|
||||
if (func (table + i, data))
|
||||
return table + i;
|
||||
const struct spa_type_info *info;
|
||||
|
||||
g_return_val_if_fail (type != WP_SPA_TYPE_INVALID, NULL);
|
||||
g_return_val_if_fail (type != 0, NULL);
|
||||
|
||||
if (extra_types)
|
||||
info = spa_debug_type_find (
|
||||
(const struct spa_type_info *) extra_types->data, type);
|
||||
else
|
||||
info = spa_debug_type_find (SPA_TYPE_ROOT, type);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/* similar to spa_debug_type_find() and unlike spa_debug_type_find_type(),
|
||||
which steps into id values / object fields */
|
||||
static const struct spa_type_info *
|
||||
_spa_type_find_by_name (const struct spa_type_info * info, const char * name)
|
||||
{
|
||||
const struct spa_type_info * res;
|
||||
|
||||
while (info->name) {
|
||||
if (info->type == SPA_ID_INVALID) {
|
||||
if (info->values && (res = _spa_type_find_by_name (info->values, name)))
|
||||
return res;
|
||||
}
|
||||
if (strcmp (info->name, name) == 0)
|
||||
return info;
|
||||
info++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct spa_type_info *
|
||||
spa_type_find_by_name (const struct spa_type_info *table, const char *name)
|
||||
wp_spa_type_info_find_by_name (const gchar *name)
|
||||
{
|
||||
return spa_type_find (table, name_equal_func, name);
|
||||
const struct spa_type_info *info = NULL;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
if (extra_types)
|
||||
info = _spa_type_find_by_name (
|
||||
(const struct spa_type_info *) extra_types->data, name);
|
||||
else
|
||||
info = _spa_type_find_by_name (SPA_TYPE_ROOT, name);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
struct type_info {
|
||||
gboolean is_spa_type;
|
||||
union {
|
||||
const struct spa_type_info *spa;
|
||||
struct {
|
||||
guint32 type;
|
||||
char *name;
|
||||
} custom;
|
||||
} info;
|
||||
char *nick;
|
||||
/**
|
||||
* wp_spa_type_from_name:
|
||||
* @name: the name to look up
|
||||
*
|
||||
* Looks up the type id from a given type name
|
||||
*
|
||||
* Returns: the corresponding type id or %WP_SPA_TYPE_INVALID if not found
|
||||
*/
|
||||
WpSpaType
|
||||
wp_spa_type_from_name (const gchar *name)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_name (name);
|
||||
return info ? info->type : WP_SPA_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_parent:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: the direct parent type of the given @type; if the type is
|
||||
* fundamental (i.e. has no parent), the returned type is the same as @type
|
||||
*/
|
||||
WpSpaType
|
||||
wp_spa_type_parent (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
return info ? info->parent : WP_SPA_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_name:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: the complete name of the given @type or %NULL if @type is invalid
|
||||
*/
|
||||
const gchar *
|
||||
wp_spa_type_name (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
return info ? info->name : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_is_fundamental:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: %TRUE if the @type has no parent, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_is_fundamental (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
return info ? (info->type == info->parent) : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_is_id:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: %TRUE if the @type is a SPA_TYPE_Id, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_is_id (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
return info ? (info->parent == SPA_TYPE_Id) : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_is_object:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: %TRUE if the @type is a SPA_TYPE_Object, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_is_object (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
return info ? (info->parent == SPA_TYPE_Object) : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_get_object_id_values_table:
|
||||
* @type: the type id of an object type
|
||||
*
|
||||
* Object pods (see #WpSpaPod) always have a special "id" field along with
|
||||
* other fields that can be defined. This "id" field can only store values
|
||||
* of a specific `SPA_TYPE_Id` type. This function returns the table that
|
||||
* contains the possible values for that field.
|
||||
*
|
||||
* Returns: the table with the values that can be stored in the special "id"
|
||||
* field of an object of the given @type
|
||||
*/
|
||||
WpSpaIdTable
|
||||
wp_spa_type_get_object_id_values_table (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (info->parent == SPA_TYPE_Object, NULL);
|
||||
g_return_val_if_fail (info->values != NULL, NULL);
|
||||
g_return_val_if_fail (info->values->name != NULL, NULL);
|
||||
g_return_val_if_fail (info->values->parent == SPA_TYPE_Id, NULL);
|
||||
|
||||
return info->values->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_get_values_table:
|
||||
* @type: a type id
|
||||
*
|
||||
* Returns: the associated #WpSpaIdTable that contains possible
|
||||
* values or object fields for this type, or %NULL
|
||||
*/
|
||||
WpSpaIdTable
|
||||
wp_spa_type_get_values_table (WpSpaType type)
|
||||
{
|
||||
const struct spa_type_info *info = wp_spa_type_info_find_by_type (type);
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
return info->values;
|
||||
}
|
||||
|
||||
|
||||
struct spa_type_info_iterator_data
|
||||
{
|
||||
const struct spa_type_info *base;
|
||||
const struct spa_type_info *cur;
|
||||
};
|
||||
|
||||
static struct type_info *
|
||||
type_info_new_spa (const struct spa_type_info *info, const char* nick) {
|
||||
struct type_info *ti = g_slice_new0 (struct type_info);
|
||||
ti->is_spa_type = TRUE;
|
||||
ti->info.spa = info;
|
||||
ti->nick = g_strdup (nick);
|
||||
return ti;
|
||||
}
|
||||
|
||||
static struct type_info *
|
||||
type_info_new_custom (uint32_t type, const char *name, const char* nick) {
|
||||
struct type_info *ti = g_slice_new0 (struct type_info);
|
||||
ti->is_spa_type = FALSE;
|
||||
ti->info.custom.type = type;
|
||||
ti->info.custom.name = g_strdup (name);
|
||||
ti->nick = g_strdup (nick);
|
||||
return ti;
|
||||
}
|
||||
|
||||
static void
|
||||
type_info_free (struct type_info *ti) {
|
||||
g_return_if_fail (ti);
|
||||
if (!ti->is_spa_type)
|
||||
g_clear_pointer (&ti->info.custom.name, g_free);
|
||||
g_clear_pointer (&ti->nick, g_free);
|
||||
g_slice_free (struct type_info, ti);
|
||||
spa_type_info_iterator_reset (WpIterator *it)
|
||||
{
|
||||
struct spa_type_info_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
it_data->cur = it_data->base;
|
||||
}
|
||||
|
||||
struct spa_type_table_data {
|
||||
const struct spa_type_info *spa_table;
|
||||
guint32 last_id;
|
||||
GPtrArray *info_array;
|
||||
GHashTable *id_table;
|
||||
GHashTable *nick_table;
|
||||
};
|
||||
|
||||
static struct spa_type_table_data s_tables [WP_SPA_TYPE_TABLE_LAST] = {
|
||||
[WP_SPA_TYPE_TABLE_BASIC] = {spa_types, SPA_TYPE_VENDOR_Other, NULL, NULL, NULL },
|
||||
[WP_SPA_TYPE_TABLE_PARAM] = {spa_type_param, SPA_N_ELEMENTS (spa_type_param), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_PROPS] = {spa_type_props, SPA_PROP_START_CUSTOM, NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_PROP_INFO] = {spa_type_prop_info, SPA_N_ELEMENTS (spa_type_prop_info), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_FORMAT] = {spa_type_format, SPA_N_ELEMENTS (spa_type_format), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_PARAM_PORT_CONFIG] = {spa_type_param_port_config, SPA_N_ELEMENTS (spa_type_param_port_config), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_PARAM_PROFILE] = {spa_type_param_profile, SPA_N_ELEMENTS (spa_type_param_profile), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_CONTROL] = {spa_type_control, SPA_CONTROL_LAST, NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_CHOICE] = {spa_type_choice, SPA_N_ELEMENTS (spa_type_choice), NULL, NULL, NULL, },
|
||||
[WP_SPA_TYPE_TABLE_AUDIO_CHANNEL] = {spa_type_audio_channel, SPA_N_ELEMENTS (spa_type_audio_channel), NULL, NULL, NULL, },
|
||||
};
|
||||
|
||||
static WpSpaTypeTable
|
||||
wp_spa_type_table_find_by_spa_table (const struct spa_type_info *spa_table)
|
||||
static gboolean
|
||||
spa_type_info_iterator_next (WpIterator *it, GValue *item)
|
||||
{
|
||||
for (guint32 i = 0; i < WP_SPA_TYPE_TABLE_LAST; i++)
|
||||
if (s_tables[i].spa_table == spa_table)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
struct spa_type_info_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
|
||||
/**
|
||||
* wp_spa_type_init:
|
||||
* @register_spa: whether spa types will be registered or not
|
||||
*
|
||||
* Initializes the spa type registry
|
||||
*/
|
||||
void
|
||||
wp_spa_type_init (gboolean register_spa)
|
||||
{
|
||||
/* Init the array and hash tables */
|
||||
for (guint32 i = 0; i < WP_SPA_TYPE_TABLE_LAST; i++) {
|
||||
struct spa_type_table_data *td = s_tables + i;
|
||||
if (!td->info_array)
|
||||
td->info_array = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||
type_info_free);
|
||||
if (!td->id_table)
|
||||
td->id_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
NULL, NULL);
|
||||
if (!td->nick_table)
|
||||
td->nick_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
if (it_data->cur->name) {
|
||||
g_value_init (item, WP_TYPE_SPA_ID_VALUE);
|
||||
g_value_set_pointer (item, (gpointer) it_data->cur);
|
||||
it_data->cur++;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Register the spa types if requested */
|
||||
if (register_spa) {
|
||||
for (guint32 i = 0; i < WP_SPA_TYPE_TABLE_LAST; i++) {
|
||||
struct spa_type_table_data *td = s_tables + i;
|
||||
for (guint32 j = 0; td->spa_table && td->spa_table[j].name; j++) {
|
||||
const struct spa_type_info *t = td->spa_table + j;
|
||||
const char *nick = strrchr (t->name, ':');
|
||||
if (nick && strlen (nick) > 1)
|
||||
wp_spa_type_register (i, t->name, nick + 1);
|
||||
}
|
||||
static gboolean
|
||||
spa_type_info_iterator_fold (WpIterator *it, WpIteratorFoldFunc func,
|
||||
GValue *ret, gpointer data)
|
||||
{
|
||||
struct spa_type_info_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
const struct spa_type_info *cur, *base;
|
||||
|
||||
cur = base = it_data->base;
|
||||
|
||||
while (cur->name) {
|
||||
g_auto (GValue) item = G_VALUE_INIT;
|
||||
g_value_init (&item, WP_TYPE_SPA_ID_VALUE);
|
||||
g_value_set_pointer (&item, (gpointer) cur);
|
||||
if (!func (&item, ret, data))
|
||||
return FALSE;
|
||||
cur++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const WpIteratorMethods spa_type_info_iterator_methods = {
|
||||
.version = WP_ITERATOR_METHODS_VERSION,
|
||||
.reset = spa_type_info_iterator_reset,
|
||||
.next = spa_type_info_iterator_next,
|
||||
.fold = spa_type_info_iterator_fold,
|
||||
};
|
||||
|
||||
WpSpaIdTable
|
||||
wp_spa_id_table_from_name (const gchar *name)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
const WpSpaIdTableInfo *info = NULL;
|
||||
|
||||
/* first look in dynamic id tables */
|
||||
if (extra_id_tables) {
|
||||
info = (const WpSpaIdTableInfo *) extra_id_tables->data;
|
||||
while (info && info->name) {
|
||||
if (strcmp (info->name, name) == 0)
|
||||
return info->values;
|
||||
info++;
|
||||
}
|
||||
}
|
||||
|
||||
/* then look at the well-known static ones */
|
||||
info = static_id_tables;
|
||||
while (info && info->name) {
|
||||
if (strcmp (info->name, name) == 0)
|
||||
return info->values;
|
||||
info++;
|
||||
}
|
||||
|
||||
/* then look into types, hoping to find an object type */
|
||||
const struct spa_type_info *tinfo = wp_spa_type_info_find_by_name (name);
|
||||
return tinfo ? tinfo->values : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_deinit:
|
||||
* wp_spa_id_table_iterate:
|
||||
* @type: the id table
|
||||
*
|
||||
* Deinitializes the spa type registry
|
||||
* This function returns an iterator that allows you to iterate through the
|
||||
* values associated with this table.
|
||||
* The items in the iterator are of type #WpSpaIdValue.
|
||||
*
|
||||
* Returns: a #WpIterator that iterates over #WpSpaIdValue items
|
||||
*/
|
||||
WpIterator *
|
||||
wp_spa_id_table_iterate (WpSpaIdTable table)
|
||||
{
|
||||
g_return_val_if_fail (table != NULL, NULL);
|
||||
|
||||
WpIterator *it = wp_iterator_new (&spa_type_info_iterator_methods,
|
||||
sizeof (struct spa_type_info_iterator_data));
|
||||
struct spa_type_info_iterator_data *it_data = wp_iterator_get_user_data (it);
|
||||
it_data->base = (const struct spa_type_info *) table;
|
||||
it_data->cur = it_data->base;
|
||||
return it;
|
||||
}
|
||||
|
||||
WpSpaIdValue
|
||||
wp_spa_id_table_find_value (WpSpaIdTable table, guint value)
|
||||
{
|
||||
g_return_val_if_fail (table != NULL, NULL);
|
||||
|
||||
const struct spa_type_info *info = table;
|
||||
while (info && info->name) {
|
||||
if (info->type == value)
|
||||
return info;
|
||||
info++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WpSpaIdValue
|
||||
wp_spa_id_table_find_value_from_name (WpSpaIdTable table, const gchar * name)
|
||||
{
|
||||
g_return_val_if_fail (table != NULL, NULL);
|
||||
|
||||
const struct spa_type_info *info = table;
|
||||
while (info && info->name) {
|
||||
if (!strcmp (info->name, name))
|
||||
return info;
|
||||
info++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WpSpaIdValue
|
||||
wp_spa_id_table_find_value_from_short_name (WpSpaIdTable table,
|
||||
const gchar * short_name)
|
||||
{
|
||||
g_return_val_if_fail (table != NULL, NULL);
|
||||
|
||||
const struct spa_type_info *info = table;
|
||||
while (info && info->name) {
|
||||
if (!strcmp (spa_debug_type_short_name (info->name), short_name))
|
||||
return info;
|
||||
info++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static WpSpaIdTable
|
||||
wp_spa_id_name_find_id_table (const gchar * name)
|
||||
{
|
||||
WpSpaIdTable table = NULL;
|
||||
g_autofree gchar *parent_name = g_strdup (name);
|
||||
gchar *h;
|
||||
|
||||
if ((h = strrchr(parent_name, ':')) != NULL) {
|
||||
/* chop the enum name to get the type, ex:
|
||||
Spa:Enum:Direction:Input -> Spa:Enum:Direction */
|
||||
*h = '\0';
|
||||
table = wp_spa_id_table_from_name (parent_name);
|
||||
|
||||
/* in some cases, the parent name is one layer further up, ex:
|
||||
Spa:Pod:Object:Param:Format:Audio:rate -> Spa:Pod:Object:Param:Format */
|
||||
if (!table && (h = strrchr(parent_name, ':')) != NULL) {
|
||||
*h = '\0';
|
||||
table = wp_spa_id_table_from_name (parent_name);
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_from_name:
|
||||
* @name: the full name of an id value
|
||||
*
|
||||
* Looks up an id value (enum, flag or object field) directly from its full
|
||||
* name. For instance, "Spa:Enum:Direction:Input" will resolve to the
|
||||
* id value that represents "Input" in the "Spa:Enum:Direction" enum.
|
||||
*
|
||||
* Returns: the id value for @name, or %NULL if no such id value was found
|
||||
*/
|
||||
WpSpaIdValue
|
||||
wp_spa_id_value_from_name (const gchar * name)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
WpSpaIdTable table = wp_spa_id_name_find_id_table (name);
|
||||
return wp_spa_id_table_find_value_from_name (table, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_from_short_name:
|
||||
* @table_name: the name of the #WpSpaIdTable to look up the value in
|
||||
* @short_name: the short name of the value to look up
|
||||
*
|
||||
* Looks up an id value given its container @table_name and its @short_name
|
||||
*
|
||||
* Returns: the id value or %NULL if it was not found
|
||||
*/
|
||||
WpSpaIdValue
|
||||
wp_spa_id_value_from_short_name (const gchar * table_name,
|
||||
const gchar * short_name)
|
||||
{
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
g_return_val_if_fail (short_name != NULL, NULL);
|
||||
|
||||
WpSpaIdTable table = wp_spa_id_table_from_name (table_name);
|
||||
return wp_spa_id_table_find_value_from_short_name (table, short_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_from_number:
|
||||
* @table_name: the name of the #WpSpaIdTable to look up the value in
|
||||
* @id: the numeric representation of the value to look up
|
||||
*
|
||||
* Looks up an id value given its container @table_name and its numeric
|
||||
* representation, @id
|
||||
*
|
||||
* Returns: the id value or %NULL if it was not found
|
||||
*/
|
||||
WpSpaIdValue
|
||||
wp_spa_id_value_from_number (const gchar * table_name, guint id)
|
||||
{
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
|
||||
WpSpaIdTable table = wp_spa_id_table_from_name (table_name);
|
||||
return wp_spa_id_table_find_value (table, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_number:
|
||||
* @id: an id value
|
||||
*
|
||||
* Returns: the numeric representation of this id value
|
||||
*/
|
||||
guint
|
||||
wp_spa_id_value_number (WpSpaIdValue id)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, -1);
|
||||
|
||||
const struct spa_type_info *info = id;
|
||||
return info->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_name:
|
||||
* @id: an id value
|
||||
*
|
||||
* Returns: the full name of this id value
|
||||
*/
|
||||
const gchar *
|
||||
wp_spa_id_value_name (WpSpaIdValue id)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
|
||||
const struct spa_type_info *info = id;
|
||||
return info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_short_name:
|
||||
* @id: an id value
|
||||
*
|
||||
* Returns: the short name of this id value
|
||||
*/
|
||||
const gchar *
|
||||
wp_spa_id_value_short_name (WpSpaIdValue id)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
|
||||
const struct spa_type_info *info = id;
|
||||
return spa_debug_type_short_name (info->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_get_value_type
|
||||
* @id: an id value
|
||||
* @table: (out) (optional): the associated #WpSpaIdTable
|
||||
*
|
||||
* Returns the value type associated with this #WpSpaIdValue. This information
|
||||
* is useful when @id represents an object field, which can take a value
|
||||
* of an arbitrary type.
|
||||
*
|
||||
* When the returned type is (or is derived from) `SPA_TYPE_Id` or
|
||||
* `SPA_TYPE_Object`, @table is set to point to the #WpSpaIdTable that contains
|
||||
* the possible Id values / object fields.
|
||||
*
|
||||
* Returns: the value type associated with @id
|
||||
*/
|
||||
WpSpaType
|
||||
wp_spa_id_value_get_value_type (WpSpaIdValue id, WpSpaIdTable * table)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, WP_SPA_TYPE_INVALID);
|
||||
|
||||
const struct spa_type_info *info = id;
|
||||
|
||||
if (table) {
|
||||
/* info->values has different semantics on Array types */
|
||||
if (info->values && info->parent != SPA_TYPE_Array) {
|
||||
*table = info->values;
|
||||
}
|
||||
/* derived object types normally don't have info->values directly set,
|
||||
so we need to look them up */
|
||||
else if (wp_spa_type_is_object (info->parent)) {
|
||||
WpSpaIdTable t = wp_spa_type_get_values_table (info->parent);
|
||||
if (t) *table = t;
|
||||
}
|
||||
}
|
||||
|
||||
return info->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_id_value_array_get_item_type:
|
||||
* @id: an id value
|
||||
* @table: (out) (optional): the associated #WpSpaIdTable
|
||||
*
|
||||
* If the value type of @id is `SPA_TYPE_Array`, this function returns the
|
||||
* type that is allowed to be contained inside the array.
|
||||
*
|
||||
* When the returned type is (or is derived from) `SPA_TYPE_Id` or
|
||||
* `SPA_TYPE_Object`, @table is set to point to the #WpSpaIdTable that contains
|
||||
* the possible Id values / object fields.
|
||||
*
|
||||
* Returns: the type that is allowed in the array, if @id represents
|
||||
* an object field that takes an array as value
|
||||
*/
|
||||
WpSpaType
|
||||
wp_spa_id_value_array_get_item_type (WpSpaIdValue id, WpSpaIdTable * table)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, WP_SPA_TYPE_INVALID);
|
||||
|
||||
const struct spa_type_info *info = id;
|
||||
g_return_val_if_fail (info->parent == SPA_TYPE_Array, WP_SPA_TYPE_INVALID);
|
||||
|
||||
return info->values ?
|
||||
wp_spa_id_value_get_value_type (info->values, table) :
|
||||
WP_SPA_TYPE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wp_spa_dynamic_type_init:
|
||||
*
|
||||
* Initializes the spa dynamic type registry.
|
||||
* This allows registering new spa types at runtime. The spa type system
|
||||
* still works if this function is not called.
|
||||
*
|
||||
* Normally called by wp_init() when %WP_INIT_SPA_TYPES is passed in its flags.
|
||||
*/
|
||||
void
|
||||
wp_spa_type_deinit (void)
|
||||
wp_spa_dynamic_type_init (void)
|
||||
{
|
||||
for (guint32 i = 0; i < WP_SPA_TYPE_TABLE_LAST; i++) {
|
||||
struct spa_type_table_data *td = s_tables + i;
|
||||
g_clear_pointer (&td->info_array, g_ptr_array_unref);
|
||||
g_clear_pointer (&td->id_table, g_hash_table_unref);
|
||||
g_clear_pointer (&td->nick_table, g_hash_table_unref);
|
||||
}
|
||||
extra_types = g_array_new (TRUE, FALSE, sizeof (struct spa_type_info));
|
||||
extra_id_tables = g_array_new (TRUE, FALSE, sizeof (WpSpaIdTableInfo));
|
||||
|
||||
/* init to chain up to spa types */
|
||||
struct spa_type_info info = {
|
||||
SPA_ID_INVALID, SPA_ID_INVALID, "spa_types", SPA_TYPE_ROOT
|
||||
};
|
||||
g_array_append_val (extra_types, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_get_table_size:
|
||||
* @table: the table
|
||||
* wp_spa_dynamic_type_deinit:
|
||||
*
|
||||
* Gets the number of registered types in a given table
|
||||
*
|
||||
* Returns: The number of registered types
|
||||
* Deinitializes the spa type registry.
|
||||
* You do not need to ever call this, unless you want to free memory at the
|
||||
* end of the execution of a test, so that it doesn't show as leaked in
|
||||
* the memory profiler.
|
||||
*/
|
||||
size_t
|
||||
wp_spa_type_get_table_size (WpSpaTypeTable table)
|
||||
void
|
||||
wp_spa_dynamic_type_deinit (void)
|
||||
{
|
||||
struct spa_type_table_data *td = NULL;
|
||||
|
||||
g_return_val_if_fail (table < WP_SPA_TYPE_TABLE_LAST, 0);
|
||||
|
||||
/* Get the table data */
|
||||
td = s_tables + table;
|
||||
|
||||
return td->info_array->len;
|
||||
g_clear_pointer (&extra_types, g_array_unref);
|
||||
g_clear_pointer (&extra_id_tables, g_array_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_register:
|
||||
* @table: the table
|
||||
* wp_spa_dynamic_type_register:
|
||||
* @name: the name of the type
|
||||
* @nick: the nick name of the type
|
||||
* @parent: the parent type
|
||||
* @values: an array of `spa_type_info` that contains the values of the type,
|
||||
* used only for Object types
|
||||
*
|
||||
* Registers a type name with a nickname in the registry
|
||||
* Registers an additional type in the spa type system.
|
||||
* This is useful to add a custom pod object type.
|
||||
*
|
||||
* Returns: TRUE if the type could be registered, FALSE otherwise
|
||||
* Note that both @name and @values must be statically allocated, or
|
||||
* otherwise guaranteed to be kept in memory until wp_spa_dynamic_type_deinit()
|
||||
* is called. No memory copy is done by this function.
|
||||
*
|
||||
* Returns: the new type
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_register (WpSpaTypeTable table, const char *name, const char *nick)
|
||||
WpSpaType
|
||||
wp_spa_dynamic_type_register (const gchar *name, WpSpaType parent,
|
||||
const struct spa_type_info * values)
|
||||
{
|
||||
struct spa_type_table_data *td = NULL;
|
||||
const struct spa_type_info *spa_info = NULL;
|
||||
struct type_info *info = NULL;
|
||||
guint32 id;
|
||||
|
||||
g_return_val_if_fail (table < WP_SPA_TYPE_TABLE_LAST, FALSE);
|
||||
g_return_val_if_fail (name, FALSE);
|
||||
g_return_val_if_fail (nick, FALSE);
|
||||
|
||||
/* Get the table data */
|
||||
td = s_tables + table;
|
||||
|
||||
/* Return false if the nick already exists in the nick table */
|
||||
if (g_hash_table_contains (td->nick_table, nick))
|
||||
return FALSE;
|
||||
|
||||
/* Add the type in the custom table */
|
||||
spa_info = spa_type_find_by_name (td->spa_table, name);
|
||||
if (spa_info) {
|
||||
id = spa_info->type;
|
||||
info = type_info_new_spa (spa_info, nick);
|
||||
} else {
|
||||
id = ++td->last_id;
|
||||
info = type_info_new_custom (id, name, nick);
|
||||
}
|
||||
g_ptr_array_add (td->info_array, info);
|
||||
|
||||
/* Insert the id and nick in the hash tables */
|
||||
return g_hash_table_insert (td->id_table, GUINT_TO_POINTER (id), info) &&
|
||||
g_hash_table_insert (td->nick_table, g_strdup (nick), info);
|
||||
struct spa_type_info info;
|
||||
info.type = SPA_TYPE_VENDOR_WirePlumber + extra_types->len;
|
||||
info.name = name;
|
||||
info.parent = parent;
|
||||
info.values = values;
|
||||
g_array_append_val (extra_types, info);
|
||||
return info.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_unregister:
|
||||
* @table: the table
|
||||
* @nick: the nick name of the type
|
||||
* wp_spa_dynamic_id_table_register:
|
||||
* @name: the name of the id table
|
||||
* @values: an array of `spa_type_info` that contains the values of the table
|
||||
*
|
||||
* Unregisters a type given its nick name
|
||||
* Registers an additional #WpSpaIdTable in the spa type system.
|
||||
* This is useful to add custom enumeration types.
|
||||
*
|
||||
* Note that both @name and @values must be statically allocated, or
|
||||
* otherwise guaranteed to be kept in memory until wp_spa_dynamic_type_deinit()
|
||||
* is called. No memory copy is done by this function.
|
||||
*
|
||||
* Returns: the new table
|
||||
*/
|
||||
void
|
||||
wp_spa_type_unregister (WpSpaTypeTable table, const char *nick)
|
||||
WpSpaIdTable
|
||||
wp_spa_dynamic_id_table_register (const gchar *name,
|
||||
const struct spa_type_info * values)
|
||||
{
|
||||
struct spa_type_table_data *td = NULL;
|
||||
struct type_info *info = NULL;
|
||||
guint32 id;
|
||||
|
||||
g_return_if_fail (table < WP_SPA_TYPE_TABLE_LAST);
|
||||
g_return_if_fail (nick);
|
||||
|
||||
/* Get the table data */
|
||||
td = s_tables + table;
|
||||
|
||||
/* Lookup the info by nick */
|
||||
info = g_hash_table_lookup (td->nick_table, nick);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
/* Get id */
|
||||
id = info->is_spa_type ? info->info.spa->type : info->info.custom.type;
|
||||
|
||||
/* Remove info from hash tables */
|
||||
g_hash_table_remove (td->nick_table, nick);
|
||||
g_hash_table_remove (td->id_table, GUINT_TO_POINTER (id));
|
||||
|
||||
/* Remove info from array */
|
||||
g_ptr_array_remove_fast (td->info_array, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_get_by_nick:
|
||||
* @table: the table
|
||||
* @nick: the nick name of the type
|
||||
* @id: (out) (optional): the id of the type
|
||||
* @name: (out) (optional): the name of the type
|
||||
* @values_table: (out) (optional): the values table of the type
|
||||
*
|
||||
* Gets the id and name of the registered type given its nick name
|
||||
*
|
||||
* Returns: TRUE if the type was found, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_get_by_nick (WpSpaTypeTable table, const char *nick,
|
||||
guint32 *id, const char **name, WpSpaTypeTable *values_table)
|
||||
{
|
||||
struct spa_type_table_data *td = NULL;
|
||||
const struct type_info *info = NULL;
|
||||
|
||||
g_return_val_if_fail (table < WP_SPA_TYPE_TABLE_LAST, FALSE);
|
||||
|
||||
/* Make sure nick is valid */
|
||||
if (!nick)
|
||||
return FALSE;
|
||||
|
||||
/* Get the table data */
|
||||
td = s_tables + table;
|
||||
|
||||
/* Lookup the info by nick */
|
||||
info = g_hash_table_lookup (td->nick_table, nick);
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
if (id)
|
||||
*id = info->is_spa_type ? info->info.spa->type : info->info.custom.type;
|
||||
if (name)
|
||||
*name = info->is_spa_type ? info->info.spa->name : info->info.custom.name;
|
||||
if (values_table && info->is_spa_type)
|
||||
*values_table = wp_spa_type_table_find_by_spa_table (info->info.spa->values);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_spa_type_get_by_id:
|
||||
* @table: the table
|
||||
* @id: the id of the type
|
||||
* @name: (out) (optional): the name of the type
|
||||
* @nick: (out) (optional): the nick name of the type
|
||||
* @values_table: (out) (optional): the values table of the type
|
||||
*
|
||||
* Gets the name and nick name of the registered type given its id
|
||||
*
|
||||
* Returns: TRUE if the type was found, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
wp_spa_type_get_by_id (WpSpaTypeTable table, guint32 id,
|
||||
const char **name, const char **nick, WpSpaTypeTable *values_table)
|
||||
{
|
||||
struct spa_type_table_data *td = NULL;
|
||||
const struct type_info *info = NULL;
|
||||
|
||||
g_return_val_if_fail (table < WP_SPA_TYPE_TABLE_LAST, FALSE);
|
||||
|
||||
/* Get the table data */
|
||||
td = s_tables + table;
|
||||
|
||||
/* Lookup the info by id */
|
||||
info = g_hash_table_lookup (td->id_table, GUINT_TO_POINTER (id));
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
if (name)
|
||||
*name = info->is_spa_type ? info->info.spa->name : info->info.custom.name;
|
||||
if (nick)
|
||||
*nick = info->nick;
|
||||
if (values_table && info->is_spa_type)
|
||||
*values_table = wp_spa_type_table_find_by_spa_table (info->info.spa->values);
|
||||
return TRUE;
|
||||
WpSpaIdTableInfo info;
|
||||
info.name = name;
|
||||
info.values = values;
|
||||
g_array_append_val (extra_id_tables, info);
|
||||
return values;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,63 +9,121 @@
|
|||
#ifndef __WIREPLUMBER_SPA_TYPE_H__
|
||||
#define __WIREPLUMBER_SPA_TYPE_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include "defs.h"
|
||||
#include "iterator.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* WpSpaTypeTable:
|
||||
* @WP_SPA_TYPE_TABLE_BASIC: The basic type table
|
||||
* @WP_SPA_TYPE_TABLE_PARAM: The param type table (used as object id)
|
||||
* @WP_SPA_TYPE_TABLE_PROPS: The object properties type table
|
||||
* @WP_SPA_TYPE_TABLE_PROP_INFO: The object property info type table
|
||||
* @WP_SPA_TYPE_TABLE_CONTROL: The sequence control type table
|
||||
* @WP_SPA_TYPE_TABLE_CHOICE: The choice type table
|
||||
* @WP_SPA_TYPE_TABLE_FORMAT: The object format type table
|
||||
* @WP_SPA_TYPE_TABLE_PARAM_PORT_CONFIG: The object param port config type table
|
||||
* @WP_SPA_TYPE_TABLE_PARAM_PROFILE: The sequence control type table
|
||||
* @WP_SPA_TYPE_TABLE_AUDIO_CHANNEL: The audio channel type table
|
||||
*
|
||||
* The diferent tables (namespaces) the registry has.
|
||||
*/
|
||||
typedef enum {
|
||||
WP_SPA_TYPE_TABLE_BASIC = 0,
|
||||
WP_SPA_TYPE_TABLE_PARAM,
|
||||
WP_SPA_TYPE_TABLE_PROPS,
|
||||
WP_SPA_TYPE_TABLE_PROP_INFO,
|
||||
WP_SPA_TYPE_TABLE_CONTROL,
|
||||
WP_SPA_TYPE_TABLE_CHOICE,
|
||||
WP_SPA_TYPE_TABLE_FORMAT,
|
||||
WP_SPA_TYPE_TABLE_PARAM_PORT_CONFIG,
|
||||
WP_SPA_TYPE_TABLE_PARAM_PROFILE,
|
||||
WP_SPA_TYPE_TABLE_AUDIO_CHANNEL,
|
||||
WP_SPA_TYPE_TABLE_LAST,
|
||||
} WpSpaTypeTable;
|
||||
typedef guint32 WpSpaType;
|
||||
typedef gconstpointer WpSpaIdTable;
|
||||
typedef gconstpointer WpSpaIdValue;
|
||||
struct spa_type_info;
|
||||
|
||||
/* WpSpaType */
|
||||
|
||||
#define WP_TYPE_SPA_TYPE (wp_spa_type_get_type ())
|
||||
WP_API
|
||||
GType wp_spa_type_get_type (void);
|
||||
|
||||
static const WpSpaType WP_SPA_TYPE_INVALID = 0xffffffff;
|
||||
|
||||
WP_API
|
||||
void wp_spa_type_init (gboolean register_spa);
|
||||
WpSpaType wp_spa_type_from_name (const gchar *name);
|
||||
|
||||
WP_API
|
||||
void wp_spa_type_deinit (void);
|
||||
WpSpaType wp_spa_type_parent (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
size_t wp_spa_type_get_table_size (WpSpaTypeTable table);
|
||||
const gchar * wp_spa_type_name (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_type_register (WpSpaTypeTable table, const char *name,
|
||||
const char *nick);
|
||||
gboolean wp_spa_type_is_fundamental (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
void wp_spa_type_unregister (WpSpaTypeTable table, const char *nick);
|
||||
gboolean wp_spa_type_is_id (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_type_get_by_nick (WpSpaTypeTable table, const char *nick,
|
||||
guint32 *id, const char **name, WpSpaTypeTable *values_table);
|
||||
gboolean wp_spa_type_is_object (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
gboolean wp_spa_type_get_by_id (WpSpaTypeTable table, guint32 id,
|
||||
const char **name, const char **nick, WpSpaTypeTable *values_table);
|
||||
WpSpaIdTable wp_spa_type_get_object_id_values_table (WpSpaType type);
|
||||
|
||||
WP_API
|
||||
WpSpaIdTable wp_spa_type_get_values_table (WpSpaType type);
|
||||
|
||||
|
||||
/* WpSpaIdTable */
|
||||
|
||||
#define WP_TYPE_SPA_ID_TABLE (wp_spa_id_table_get_type ())
|
||||
WP_API
|
||||
GType wp_spa_id_table_get_type (void);
|
||||
|
||||
WP_API
|
||||
WpSpaIdTable wp_spa_id_table_from_name (const gchar *name);
|
||||
|
||||
WP_API
|
||||
WpIterator * wp_spa_id_table_iterate (WpSpaIdTable table);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_table_find_value (WpSpaIdTable table, guint value);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_table_find_value_from_name (WpSpaIdTable table,
|
||||
const gchar * name);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_table_find_value_from_short_name (WpSpaIdTable table,
|
||||
const gchar * short_name);
|
||||
|
||||
|
||||
/* WpSpaIdValue */
|
||||
|
||||
#define WP_TYPE_SPA_ID_VALUE (wp_spa_id_value_get_type ())
|
||||
WP_API
|
||||
GType wp_spa_id_value_get_type (void);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_value_from_name (const gchar * name);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_value_from_short_name (const gchar * table_name,
|
||||
const gchar * short_name);
|
||||
|
||||
WP_API
|
||||
WpSpaIdValue wp_spa_id_value_from_number (const gchar * table_name, guint id);
|
||||
|
||||
WP_API
|
||||
guint wp_spa_id_value_number (WpSpaIdValue id);
|
||||
|
||||
WP_API
|
||||
const gchar * wp_spa_id_value_name (WpSpaIdValue id);
|
||||
|
||||
WP_API
|
||||
const gchar * wp_spa_id_value_short_name (WpSpaIdValue id);
|
||||
|
||||
WP_API
|
||||
WpSpaType wp_spa_id_value_get_value_type (WpSpaIdValue id, WpSpaIdTable *table);
|
||||
|
||||
WP_API
|
||||
WpSpaType wp_spa_id_value_array_get_item_type (WpSpaIdValue id,
|
||||
WpSpaIdTable *table);
|
||||
|
||||
|
||||
/* Dynamic type registration */
|
||||
|
||||
WP_API
|
||||
void wp_spa_dynamic_type_init (void);
|
||||
|
||||
WP_API
|
||||
void wp_spa_dynamic_type_deinit (void);
|
||||
|
||||
WP_API
|
||||
WpSpaType wp_spa_dynamic_type_register (const gchar *name, WpSpaType parent,
|
||||
const struct spa_type_info * values);
|
||||
|
||||
WP_API
|
||||
WpSpaIdTable wp_spa_dynamic_id_table_register (const gchar *name,
|
||||
const struct spa_type_info * values);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ wp_init (WpInitFlags flags)
|
|||
pw_log_set_level (lvl);
|
||||
|
||||
if (flags & WP_INIT_SPA_TYPES)
|
||||
wp_spa_type_init (TRUE);
|
||||
wp_spa_dynamic_type_init ();
|
||||
|
||||
/* ensure WpProxy subclasses are loaded, which is needed to be able
|
||||
to autodetect the GType of proxies created through wp_proxy_new_global() */
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ set_device_profile (WpPipewireObject *device, gint index)
|
|||
{
|
||||
g_return_if_fail (device);
|
||||
g_autoptr (WpSpaPod) profile = wp_spa_pod_new_object (
|
||||
"Profile", "Profile",
|
||||
"Spa:Pod:Object:Param:Profile", "Profile",
|
||||
"index", "i", index,
|
||||
NULL);
|
||||
wp_debug_object (device, "set profile %d", index);
|
||||
|
|
|
|||
|
|
@ -63,8 +63,7 @@ find_device_profile (WpPipewireObject *device, const gchar *lookup_name)
|
|||
const gchar *name = NULL;
|
||||
|
||||
/* Parse */
|
||||
if (!wp_spa_pod_get_object (pod,
|
||||
"Profile", NULL,
|
||||
if (!wp_spa_pod_get_object (pod, NULL,
|
||||
"index", "i", &index,
|
||||
"name", "s", &name,
|
||||
NULL)) {
|
||||
|
|
@ -191,8 +190,7 @@ on_device_profile_notified (WpPipewireObject *device, GAsyncResult *res,
|
|||
|
||||
/* Parse the profile */
|
||||
WpSpaPod *pod = g_value_get_boxed (&item);
|
||||
if (!wp_spa_pod_get_object (pod,
|
||||
"Profile", NULL,
|
||||
if (!wp_spa_pod_get_object (pod, NULL,
|
||||
"index", "i", &index,
|
||||
"name", "s", &name,
|
||||
NULL)) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ set_device_profile (WpDeviceActivation *self,
|
|||
/* Set profile */
|
||||
wp_pipewire_object_set_param (device, "Profile", 0,
|
||||
wp_spa_pod_new_object (
|
||||
"Profile", "Profile",
|
||||
"Spa:Pod:Object:Param:Profile", "Profile",
|
||||
"index", "i", index,
|
||||
NULL));
|
||||
|
||||
|
|
@ -72,8 +72,7 @@ on_device_enum_profile_done (WpPipewireObject *proxy, GAsyncResult *res,
|
|||
const gchar *n = NULL;
|
||||
|
||||
/* Parse */
|
||||
if (!wp_spa_pod_get_object (pod,
|
||||
"Profile", NULL,
|
||||
if (!wp_spa_pod_get_object (pod, NULL,
|
||||
"index", "i", &i,
|
||||
"name", "s", &n,
|
||||
NULL)) {
|
||||
|
|
|
|||
|
|
@ -207,8 +207,7 @@ on_device_enum_profile_done (WpPipewireObject *proxy, GAsyncResult *res,
|
|||
|
||||
/* Parse profile */
|
||||
{
|
||||
g_autoptr (WpSpaPodParser) pp = wp_spa_pod_parser_new_object (pod,
|
||||
"Profile", NULL);
|
||||
g_autoptr (WpSpaPodParser) pp = wp_spa_pod_parser_new_object (pod, NULL);
|
||||
g_return_if_fail (pp);
|
||||
g_return_if_fail (wp_spa_pod_parser_get (pp, "index", "i", &index, NULL));
|
||||
if (index == 0) {
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ static WpSpaPod *
|
|||
format_audio_raw_build (const struct spa_audio_info_raw *info)
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_object (
|
||||
"Format", "Format");
|
||||
"Spa:Pod:Object:Param:Format", "Format");
|
||||
wp_spa_pod_builder_add (builder,
|
||||
"mediaType", "I", SPA_MEDIA_TYPE_audio,
|
||||
"mediaSubtype", "I", SPA_MEDIA_SUBTYPE_raw,
|
||||
|
|
@ -327,7 +327,8 @@ si_adapter_activate_execute_step (WpSessionItem * item,
|
|||
self->format.channels, self->format.rate);
|
||||
|
||||
port_format = format_audio_raw_build (&self->format);
|
||||
pod = wp_spa_pod_new_object ("PortConfig", "PortConfig",
|
||||
pod = wp_spa_pod_new_object (
|
||||
"Spa:Pod:Object:Param:PortConfig", "PortConfig",
|
||||
"direction", "I", self->direction,
|
||||
"mode", "I", SPA_PARAM_PORT_CONFIG_MODE_dsp,
|
||||
"monitor", "b", self->monitor,
|
||||
|
|
@ -543,8 +544,12 @@ si_adapter_get_ports (WpSiPortInfo * item, const gchar * context)
|
|||
/* try to find the audio channel; if channel is NULL, this will silently
|
||||
leave the channel_id to its default value, 0 */
|
||||
channel = wp_properties_get (props, PW_KEY_AUDIO_CHANNEL);
|
||||
wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_AUDIO_CHANNEL, channel,
|
||||
&channel_id, NULL, NULL);
|
||||
if (channel) {
|
||||
WpSpaIdValue idval = wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:AudioChannel", channel);
|
||||
if (idval)
|
||||
channel_id = wp_spa_id_value_number (idval);
|
||||
}
|
||||
|
||||
g_variant_builder_add (&b, "(uuu)", node_id, port_id, channel_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,16 +84,17 @@ select_format (WpSpaPod *value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
const gchar * choice_type_name = wp_spa_pod_get_choice_type_name (value);
|
||||
guint32 choice_type =
|
||||
wp_spa_id_value_number (wp_spa_pod_get_choice_type (value));
|
||||
|
||||
/* None */
|
||||
if (g_strcmp0 ("None", choice_type_name) == 0) {
|
||||
if (choice_type == SPA_CHOICE_None) {
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (value);
|
||||
wp_spa_pod_get_id (child, &ret);
|
||||
}
|
||||
|
||||
/* Enum */
|
||||
else if (g_strcmp0 ("Enum", choice_type_name) == 0) {
|
||||
else if (choice_type == SPA_CHOICE_Enum) {
|
||||
g_autoptr (WpIterator) it = wp_spa_pod_iterate (value);
|
||||
GValue next = G_VALUE_INIT;
|
||||
while (wp_iterator_next (it, &next)) {
|
||||
|
|
@ -125,16 +126,17 @@ select_rate (WpSpaPod *value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
const gchar * choice_type_name = wp_spa_pod_get_choice_type_name (value);
|
||||
guint32 choice_type =
|
||||
wp_spa_id_value_number (wp_spa_pod_get_choice_type (value));
|
||||
|
||||
/* None */
|
||||
if (g_strcmp0 ("None", choice_type_name) == 0) {
|
||||
if (choice_type == SPA_CHOICE_None) {
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (value);
|
||||
wp_spa_pod_get_int (child, &ret);
|
||||
}
|
||||
|
||||
/* Enum */
|
||||
else if (g_strcmp0 ("Enum", choice_type_name) == 0) {
|
||||
else if (choice_type == SPA_CHOICE_Enum) {
|
||||
/* pick the one closest to 48Khz */
|
||||
g_autoptr (WpIterator) it = wp_spa_pod_iterate (value);
|
||||
GValue next = G_VALUE_INIT;
|
||||
|
|
@ -147,7 +149,7 @@ select_rate (WpSpaPod *value)
|
|||
}
|
||||
|
||||
/* Range */
|
||||
else if (g_strcmp0 ("Range", choice_type_name) == 0) {
|
||||
else if (choice_type == SPA_CHOICE_Range) {
|
||||
/* a range is typically 3 items: default, min, max;
|
||||
however, sometimes ALSA drivers give bad min & max values
|
||||
and pipewire picks a bad default... try to fix that here;
|
||||
|
|
@ -180,16 +182,17 @@ select_channels (WpSpaPod *value, gint preference)
|
|||
return ret;
|
||||
}
|
||||
|
||||
const gchar * choice_type_name = wp_spa_pod_get_choice_type_name (value);
|
||||
guint32 choice_type =
|
||||
wp_spa_id_value_number (wp_spa_pod_get_choice_type (value));
|
||||
|
||||
/* None */
|
||||
if (g_strcmp0 ("None", choice_type_name) == 0) {
|
||||
if (choice_type == SPA_CHOICE_None) {
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (value);
|
||||
wp_spa_pod_get_int (child, &ret);
|
||||
}
|
||||
|
||||
/* Enum */
|
||||
else if (g_strcmp0 ("Enum", choice_type_name) == 0) {
|
||||
else if (choice_type == SPA_CHOICE_Enum) {
|
||||
/* choose the most channels */
|
||||
g_autoptr (WpIterator) it = wp_spa_pod_iterate (value);
|
||||
GValue next = G_VALUE_INIT;
|
||||
|
|
@ -205,7 +208,7 @@ select_channels (WpSpaPod *value, gint preference)
|
|||
}
|
||||
|
||||
/* Range */
|
||||
else if (g_strcmp0 ("Range", choice_type_name) == 0) {
|
||||
else if (choice_type == SPA_CHOICE_Range) {
|
||||
/* a range is typically 3 items: default, min, max;
|
||||
we want the most channels, but let's not trust max
|
||||
to really be the max... ALSA drivers can be broken */
|
||||
|
|
@ -247,8 +250,7 @@ choose_sensible_raw_audio_format (WpIterator *formats,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!wp_spa_pod_get_object (pod,
|
||||
"Format", NULL,
|
||||
if (!wp_spa_pod_get_object (pod, NULL,
|
||||
"mediaType", "I", &mtype,
|
||||
"mediaSubtype", "I", &mstype,
|
||||
NULL)) {
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ set_device_profile (WpDevice *device, gint index)
|
|||
{
|
||||
g_return_if_fail (device);
|
||||
g_autoptr (WpSpaPod) profile = wp_spa_pod_new_object (
|
||||
"Profile", "Profile",
|
||||
"Spa:Pod:Object:Param:Profile", "Profile",
|
||||
"index", "i", index,
|
||||
NULL);
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (device),
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ si_convert_activate_execute_step (WpSessionItem * item,
|
|||
g_steal_pointer (&props));
|
||||
|
||||
format = wp_spa_pod_new_object (
|
||||
"Format", "Format",
|
||||
"Spa:Pod:Object:Param:Format", "Format",
|
||||
"mediaType", "I", SPA_MEDIA_TYPE_audio,
|
||||
"mediaSubtype", "I", SPA_MEDIA_SUBTYPE_raw,
|
||||
"format", "I", SPA_AUDIO_FORMAT_F32P,
|
||||
|
|
@ -303,7 +303,8 @@ si_convert_activate_execute_step (WpSessionItem * item,
|
|||
as doing merge + split is heavy for our needs */
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (self->node),
|
||||
"PortConfig", 0,
|
||||
wp_spa_pod_new_object ("PortConfig", "PortConfig",
|
||||
wp_spa_pod_new_object (
|
||||
"Spa:Pod:Object:Param:PortConfig", "PortConfig",
|
||||
"direction", "I", pw_direction_reverse (self->direction),
|
||||
"mode", "I", SPA_PARAM_PORT_CONFIG_MODE_dsp,
|
||||
"format", "P", format,
|
||||
|
|
@ -311,7 +312,8 @@ si_convert_activate_execute_step (WpSessionItem * item,
|
|||
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (self->node),
|
||||
"PortConfig", 0,
|
||||
wp_spa_pod_new_object ("PortConfig", "PortConfig",
|
||||
wp_spa_pod_new_object (
|
||||
"Spa:Pod:Object:Param:PortConfig", "PortConfig",
|
||||
"direction", "I", self->direction,
|
||||
"mode", "I", SPA_PARAM_PORT_CONFIG_MODE_dsp,
|
||||
"control", "b", self->control_port,
|
||||
|
|
@ -460,8 +462,12 @@ si_convert_get_ports (WpSiPortInfo * item, const gchar * context)
|
|||
leave the channel_id to its default value, 0 */
|
||||
props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (port));
|
||||
channel = wp_properties_get (props, PW_KEY_AUDIO_CHANNEL);
|
||||
wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_AUDIO_CHANNEL, channel,
|
||||
&channel_id, NULL, NULL);
|
||||
if (channel) {
|
||||
WpSpaIdValue idval = wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:AudioChannel", channel);
|
||||
if (idval)
|
||||
channel_id = wp_spa_id_value_number (idval);
|
||||
}
|
||||
|
||||
g_variant_builder_add (&b, "(uuu)", node_id, port_id, channel_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,8 +396,12 @@ si_simple_node_endpoint_get_ports (WpSiPortInfo * item, const gchar * context)
|
|||
/* try to find the audio channel; if channel is NULL, this will silently
|
||||
leave the channel_id to its default value, 0 */
|
||||
channel = wp_properties_get (props, PW_KEY_AUDIO_CHANNEL);
|
||||
wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_AUDIO_CHANNEL, channel,
|
||||
&channel_id, NULL, NULL);
|
||||
if (channel) {
|
||||
WpSpaIdValue idval = wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:AudioChannel", channel);
|
||||
if (idval)
|
||||
channel_id = wp_spa_id_value_number (idval);
|
||||
}
|
||||
|
||||
g_variant_builder_add (&b, "(uuu)", node_id, port_id, channel_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
static void
|
||||
test_choose_sensible_raw_audio_format (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
uint32_t layout[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR,
|
||||
SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
|
||||
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR };
|
||||
|
|
@ -31,7 +29,7 @@ test_choose_sensible_raw_audio_format (void)
|
|||
{
|
||||
g_ptr_array_remove_range (formats, 0, formats->len);
|
||||
g_autoptr (WpSpaPod) param1 = wp_spa_pod_new_object (
|
||||
"Format", "Format",
|
||||
"Spa:Pod:Object:Param:Format", "Format",
|
||||
"mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
"mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
"format", SPA_POD_CHOICE_ENUM_Id(3,
|
||||
|
|
@ -56,7 +54,7 @@ test_choose_sensible_raw_audio_format (void)
|
|||
{
|
||||
g_ptr_array_remove_range (formats, 0, formats->len);
|
||||
g_autoptr (WpSpaPod) param1 = wp_spa_pod_new_object (
|
||||
"Format", "Format",
|
||||
"Spa:Pod:Object:Param:Format", "Format",
|
||||
"mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
"mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
"format", SPA_POD_CHOICE_ENUM_Id(3,
|
||||
|
|
@ -81,7 +79,7 @@ test_choose_sensible_raw_audio_format (void)
|
|||
{
|
||||
g_ptr_array_remove_range (formats, 0, formats->len);
|
||||
g_autoptr (WpSpaPod) param2 = wp_spa_pod_new_object (
|
||||
"Format", "Format",
|
||||
"Spa:Pod:Object:Param:Format", "Format",
|
||||
"mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
"mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
"format", SPA_POD_CHOICE_ENUM_Id(3,
|
||||
|
|
@ -95,7 +93,7 @@ test_choose_sensible_raw_audio_format (void)
|
|||
g_assert_nonnull (param2);
|
||||
g_ptr_array_add (formats, g_steal_pointer (¶m2));
|
||||
g_autoptr (WpSpaPod) param3 = wp_spa_pod_new_object (
|
||||
"Format", "Format",
|
||||
"Spa:Pod:Object:Param:Format", "Format",
|
||||
"mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
"mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
"format", SPA_POD_CHOICE_ENUM_Id(3,
|
||||
|
|
@ -123,8 +121,6 @@ test_choose_sensible_raw_audio_format (void)
|
|||
g_assert_cmpint (info.position[4], ==, layout[4]);
|
||||
g_assert_cmpint (info.position[5], ==, 0);
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -527,7 +527,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -547,7 +547,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
fixture->n_events = 0;
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (fixture->proxy_endpoint),
|
||||
"Props", 0,
|
||||
wp_spa_pod_new_object ("Props", "Props",
|
||||
wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props",
|
||||
"volume", "f", 0.7f, NULL));
|
||||
|
||||
/* run until the change is on all sides */
|
||||
|
|
@ -569,7 +569,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -590,7 +590,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -611,7 +611,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -623,7 +623,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
fixture->n_events = 0;
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (fixture->impl_endpoint),
|
||||
"Props", 0,
|
||||
wp_spa_pod_new_object ("Props", "Props",
|
||||
wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props",
|
||||
"mute", "b", TRUE, NULL));
|
||||
|
||||
/* run until the change is on all sides */
|
||||
|
|
@ -645,7 +645,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -666,7 +666,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -687,7 +687,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -699,7 +699,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
fixture->n_events = 0;
|
||||
wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (endpoint->node),
|
||||
"Props", 0,
|
||||
wp_spa_pod_new_object ("Props", "Props",
|
||||
wp_spa_pod_new_object ("Spa:Pod:Object:Param:Props", "Props",
|
||||
"volume", "f", 0.2f, NULL));
|
||||
|
||||
/* run until the change is on all sides */
|
||||
|
|
@ -721,7 +721,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -742,7 +742,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
@ -763,7 +763,7 @@ test_endpoint_with_props (TestEndpointFixture *fixture, gconstpointer data)
|
|||
g_assert_true (wp_iterator_next (iterator, &item));
|
||||
g_assert_nonnull ((pod = g_value_dup_boxed (&item)));
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (pod, "Props", NULL,
|
||||
g_assert_true (wp_spa_pod_get_object (pod, NULL,
|
||||
"volume", "f", &float_value,
|
||||
"mute", "b", &boolean_value,
|
||||
NULL));
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ test_node_enum_params_done (WpPipewireObject *node, GAsyncResult *res,
|
|||
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_assert_cmpuint (wp_spa_type_from_name ("Spa:Pod:Object:Param:PropInfo"),
|
||||
==, wp_spa_pod_get_spa_type (pod));
|
||||
n_params++;
|
||||
}
|
||||
g_assert_cmpint (n_params, >, 0);
|
||||
|
|
|
|||
|
|
@ -11,15 +11,14 @@
|
|||
static void
|
||||
test_spa_pod_basic (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* None */
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_none ();
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_none (pod));
|
||||
g_assert_false (wp_spa_pod_is_id (pod));
|
||||
g_assert_cmpstr ("None", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:None", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_none ();
|
||||
g_assert_true (wp_spa_pod_equal (pod, other));
|
||||
}
|
||||
|
|
@ -36,7 +35,8 @@ test_spa_pod_basic (void)
|
|||
gboolean value = FALSE;
|
||||
g_assert_true (wp_spa_pod_get_boolean (pod, &value));
|
||||
g_assert_true (value);
|
||||
g_assert_cmpstr ("Bool", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Bool", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_boolean (pod, FALSE));
|
||||
g_assert_true (wp_spa_pod_get_boolean (pod, &value));
|
||||
g_assert_false (value);
|
||||
|
|
@ -49,7 +49,8 @@ test_spa_pod_basic (void)
|
|||
gboolean value = FALSE;
|
||||
g_assert_true (wp_spa_pod_get_boolean (copy, &value));
|
||||
g_assert_false (value);
|
||||
g_assert_cmpstr ("Bool", ==, wp_spa_pod_get_type_name (copy));
|
||||
g_assert_cmpstr ("Spa:Bool", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (copy)));
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_boolean (TRUE);
|
||||
g_assert_true (wp_spa_pod_set_pod (copy, other));
|
||||
g_assert_true (wp_spa_pod_get_boolean (copy, &value));
|
||||
|
|
@ -65,7 +66,8 @@ test_spa_pod_basic (void)
|
|||
guint32 value = 0;
|
||||
g_assert_true (wp_spa_pod_get_id (pod, &value));
|
||||
g_assert_cmpuint (value, ==, 5);
|
||||
g_assert_cmpstr ("Id", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Id", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_id (pod, 10));
|
||||
g_assert_true (wp_spa_pod_get_id (pod, &value));
|
||||
g_assert_cmpuint (value, ==, 10);
|
||||
|
|
@ -84,7 +86,8 @@ test_spa_pod_basic (void)
|
|||
gint value = 0;
|
||||
g_assert_true (wp_spa_pod_get_int (pod, &value));
|
||||
g_assert_cmpint (value, ==, -12);
|
||||
g_assert_cmpstr ("Int", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Int", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_int (pod, 9999));
|
||||
g_assert_true (wp_spa_pod_get_int (pod, &value));
|
||||
g_assert_cmpint (value, ==, 9999);
|
||||
|
|
@ -103,7 +106,8 @@ test_spa_pod_basic (void)
|
|||
long value = 0;
|
||||
g_assert_true (wp_spa_pod_get_long (pod, &value));
|
||||
g_assert_cmpint (value, ==, LONG_MAX);
|
||||
g_assert_cmpstr ("Long", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Long", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_long (pod, LONG_MIN));
|
||||
g_assert_true (wp_spa_pod_get_long (pod, &value));
|
||||
g_assert_cmpuint (value, ==, LONG_MIN);
|
||||
|
|
@ -122,7 +126,8 @@ test_spa_pod_basic (void)
|
|||
float value = 0;
|
||||
g_assert_true (wp_spa_pod_get_float (pod, &value));
|
||||
g_assert_cmpfloat_with_epsilon (value, 3.14, 0.001);
|
||||
g_assert_cmpstr ("Float", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Float", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_float (pod, 1.0));
|
||||
g_assert_true (wp_spa_pod_get_float (pod, &value));
|
||||
g_assert_cmpfloat_with_epsilon (value, 1.0, 0.001);
|
||||
|
|
@ -141,7 +146,8 @@ test_spa_pod_basic (void)
|
|||
double value = 0;
|
||||
g_assert_true (wp_spa_pod_get_double (pod, &value));
|
||||
g_assert_cmpfloat_with_epsilon (value, 2.718281828, 0.0000000001);
|
||||
g_assert_cmpstr ("Double", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Double", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_double (pod, 2.0));
|
||||
g_assert_true (wp_spa_pod_get_double (pod, &value));
|
||||
g_assert_cmpfloat_with_epsilon (value, 2.0, 0.0000000001);
|
||||
|
|
@ -161,7 +167,8 @@ test_spa_pod_basic (void)
|
|||
g_assert_true (wp_spa_pod_get_string (pod, &value));
|
||||
g_assert_nonnull (value);
|
||||
g_assert_cmpstr (value, ==, "WirePlumber");
|
||||
g_assert_cmpstr ("String", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:String", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_string ("Other");
|
||||
g_assert_nonnull (other);
|
||||
g_assert_true (wp_spa_pod_set_pod (pod, other));
|
||||
|
|
@ -182,7 +189,8 @@ test_spa_pod_basic (void)
|
|||
g_assert_nonnull (value);
|
||||
g_assert_cmpmem (value, len, "bytes", 5);
|
||||
g_assert_cmpuint (len, ==, 5);
|
||||
g_assert_cmpstr ("Bytes", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Bytes", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_bytes ("pod", 3);
|
||||
g_assert_true (wp_spa_pod_set_pod (pod, other));
|
||||
g_assert_true (wp_spa_pod_get_bytes (pod, &value, &len));
|
||||
|
|
@ -195,35 +203,26 @@ test_spa_pod_basic (void)
|
|||
/* Pointer */
|
||||
{
|
||||
gint i = 3;
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_pointer ("Int", &i);
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_pointer ("Spa:Pointer:Buffer", &i);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_pointer (pod));
|
||||
const char *type_name = NULL;
|
||||
gconstpointer p = NULL;
|
||||
g_assert_true (wp_spa_pod_get_pointer (pod, &type_name, &p));
|
||||
g_assert_nonnull (type_name);
|
||||
g_assert_true (wp_spa_pod_get_pointer (pod, &p));
|
||||
g_assert_nonnull (p);
|
||||
g_assert_cmpstr (type_name, ==, "Int");
|
||||
g_assert_true (p == &i);
|
||||
g_assert_cmpint (*(gint *)p, ==, 3);
|
||||
g_assert_cmpstr ("Pointer", ==, wp_spa_pod_get_type_name (pod));
|
||||
gboolean b = TRUE;
|
||||
g_assert_true (wp_spa_pod_set_pointer (pod, "Bool", &b));
|
||||
g_assert_true (wp_spa_pod_get_pointer (pod, &type_name, &p));
|
||||
g_assert_nonnull (type_name);
|
||||
g_assert_nonnull (p);
|
||||
g_assert_cmpstr (type_name, ==, "Bool");
|
||||
g_assert_true (p == &b);
|
||||
g_assert_cmpint (*(gboolean *)p, ==, TRUE);
|
||||
g_assert_cmpstr ("Spa:Pointer:Buffer", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
|
||||
float f = 1.1;
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_pointer ("Float", &f);
|
||||
g_autoptr (WpSpaPod) other = wp_spa_pod_new_pointer ("Spa:Pointer:Meta", &f);
|
||||
g_assert_true (wp_spa_pod_set_pod (pod, other));
|
||||
g_assert_true (wp_spa_pod_get_pointer (pod, &type_name, &p));
|
||||
g_assert_nonnull (type_name);
|
||||
g_assert_true (wp_spa_pod_get_pointer (pod, &p));
|
||||
g_assert_nonnull (p);
|
||||
g_assert_cmpstr (type_name, ==, "Float");
|
||||
g_assert_true (p == &f);
|
||||
g_assert_cmpfloat_with_epsilon (*(float *)p, 1.1, 0.01);
|
||||
g_assert_cmpstr ("Spa:Pointer:Meta", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_equal (pod, other));
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +234,8 @@ test_spa_pod_basic (void)
|
|||
gint64 value = 0;
|
||||
g_assert_true (wp_spa_pod_get_fd (pod, &value));
|
||||
g_assert_cmpint (value, ==, 4);
|
||||
g_assert_cmpstr ("Fd", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Fd", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_fd (pod, 1));
|
||||
g_assert_true (wp_spa_pod_get_fd (pod, &value));
|
||||
g_assert_cmpuint (value, ==, 1);
|
||||
|
|
@ -256,7 +256,8 @@ test_spa_pod_basic (void)
|
|||
g_assert_true (wp_spa_pod_get_rectangle (pod, &width, &height));
|
||||
g_assert_cmpint (width, ==, 1920);
|
||||
g_assert_cmpint (height, ==, 1080);
|
||||
g_assert_cmpstr ("Rectangle", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Rectangle", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_rectangle (pod, 640, 480));
|
||||
g_assert_true (wp_spa_pod_get_rectangle (pod, &width, &height));
|
||||
g_assert_cmpint (width, ==, 640);
|
||||
|
|
@ -279,7 +280,8 @@ test_spa_pod_basic (void)
|
|||
g_assert_true (wp_spa_pod_get_fraction (pod, &num, &denom));
|
||||
g_assert_cmpint (num, ==, 16);
|
||||
g_assert_cmpint (denom, ==, 9);
|
||||
g_assert_cmpstr ("Fraction", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Fraction", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_true (wp_spa_pod_set_fraction (pod, 4, 3));
|
||||
g_assert_true (wp_spa_pod_get_fraction (pod, &num, &denom));
|
||||
g_assert_cmpint (num, ==, 4);
|
||||
|
|
@ -291,27 +293,26 @@ test_spa_pod_basic (void)
|
|||
g_assert_cmpint (denom, ==, 1);
|
||||
g_assert_true (wp_spa_pod_equal (pod, other));
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_choice (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Static Enum */
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_choice (
|
||||
"Enum", "i", 0, "i", 1, "i", 2, NULL);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_choice (pod));
|
||||
g_assert_cmpstr ("Choice", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Enum", ==, wp_spa_pod_get_choice_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Choice", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
g_assert_cmpstr ("Enum", ==,
|
||||
wp_spa_id_value_short_name (wp_spa_pod_get_choice_type (pod)));
|
||||
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod);
|
||||
g_assert_nonnull (child);
|
||||
g_assert_cmpstr ("Int", ==, wp_spa_pod_get_type_name (child));
|
||||
g_assert_cmpstr ("Spa:Int", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (child)));
|
||||
gint value = 1;
|
||||
g_assert_true (wp_spa_pod_get_int (child, &value));
|
||||
g_assert_cmpint (value, ==, 0);
|
||||
|
|
@ -326,12 +327,14 @@ test_spa_pod_choice (void)
|
|||
"default value", NULL);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_choice (pod));
|
||||
g_assert_cmpstr ("Choice", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Choice", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
|
||||
{
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod);
|
||||
g_assert_nonnull (child);
|
||||
g_assert_cmpstr ("String", ==, wp_spa_pod_get_type_name (child));
|
||||
g_assert_cmpstr ("Spa:String", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (child)));
|
||||
const char *value = NULL;
|
||||
g_assert_true (wp_spa_pod_get_string (child, &value));
|
||||
g_assert_nonnull (value);
|
||||
|
|
@ -345,7 +348,8 @@ test_spa_pod_choice (void)
|
|||
{
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_choice_child (pod);
|
||||
g_assert_nonnull (child);
|
||||
g_assert_cmpstr ("String", ==, wp_spa_pod_get_type_name (child));
|
||||
g_assert_cmpstr ("Spa:String", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (child)));
|
||||
const char *value = NULL;
|
||||
g_assert_true (wp_spa_pod_get_string (child, &value));
|
||||
g_assert_nonnull (value);
|
||||
|
|
@ -362,21 +366,18 @@ test_spa_pod_choice (void)
|
|||
g_autoptr (WpSpaPod) pod = wp_spa_pod_builder_end (b);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_choice (pod));
|
||||
g_assert_cmpstr ("Choice", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Choice", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
}
|
||||
|
||||
/* It is not possible to use the parser to get the contents of a choice, you
|
||||
* need to use the iterator API to achieve that. This is because there is no
|
||||
* `spa_pod_parser_get_choice` API in the SPA library */
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_array (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Dynamic */
|
||||
{
|
||||
WpSpaPodBuilder *b = wp_spa_pod_builder_new_array ();
|
||||
|
|
@ -388,13 +389,15 @@ test_spa_pod_array (void)
|
|||
g_autoptr (WpSpaPod) pod = wp_spa_pod_builder_end (b);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_array (pod));
|
||||
g_assert_cmpstr ("Array", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Array", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
wp_spa_pod_builder_unref (b);
|
||||
g_assert_true (wp_spa_pod_is_array (pod));
|
||||
|
||||
g_autoptr (WpSpaPod) child = wp_spa_pod_get_array_child (pod);
|
||||
g_assert_nonnull (child);
|
||||
g_assert_cmpstr ("Bool", ==, wp_spa_pod_get_type_name (child));
|
||||
g_assert_cmpstr ("Spa:Bool", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (child)));
|
||||
gboolean value = TRUE;
|
||||
g_assert_true (wp_spa_pod_get_boolean (child, &value));
|
||||
g_assert_false (value);
|
||||
|
|
@ -403,19 +406,15 @@ test_spa_pod_array (void)
|
|||
/* It is not possible to use the parser to get the contents of an array, you
|
||||
* need to use the iterator API to achieve that. This is because there is no
|
||||
* `spa_pod_parser_get_array` API in the SPA library. */
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_object (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Static */
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_object (
|
||||
"Props", "Props",
|
||||
"Spa:Pod:Object:Param:Props", "Props",
|
||||
"mute", "b", FALSE,
|
||||
"volume", "f", 0.5,
|
||||
"frequency", "i", 440,
|
||||
|
|
@ -424,8 +423,8 @@ test_spa_pod_object (void)
|
|||
NULL);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_object (pod));
|
||||
g_assert_cmpstr ("Object", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Props", ==, wp_spa_pod_get_object_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Object:Param:Props", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
|
||||
const char *id_name;
|
||||
gboolean mute = TRUE;
|
||||
|
|
@ -434,7 +433,7 @@ test_spa_pod_object (void)
|
|||
const char *device;
|
||||
gint64 device_fd;
|
||||
g_assert_true (wp_spa_pod_get_object (pod,
|
||||
"Props", &id_name,
|
||||
&id_name,
|
||||
"mute", "b", &mute,
|
||||
"volume", "f", &vol,
|
||||
"frequency", "i", &frequency,
|
||||
|
|
@ -452,7 +451,7 @@ test_spa_pod_object (void)
|
|||
/* Dynamic */
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_object (
|
||||
"Props", "Props");
|
||||
"Spa:Pod:Object:Param:Props", "Props");
|
||||
wp_spa_pod_builder_add_property (b, "mute");
|
||||
wp_spa_pod_builder_add_boolean (b, FALSE);
|
||||
wp_spa_pod_builder_add_property (b, "volume");
|
||||
|
|
@ -466,7 +465,8 @@ test_spa_pod_object (void)
|
|||
g_autoptr (WpSpaPod) pod = wp_spa_pod_builder_end (b);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_object (pod));
|
||||
g_assert_cmpstr ("Object", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Object:Param:Props", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
|
||||
const char *id_name;
|
||||
gboolean mute = TRUE;
|
||||
|
|
@ -474,8 +474,7 @@ test_spa_pod_object (void)
|
|||
gint frequency;
|
||||
const char *device;
|
||||
gint64 device_fd;
|
||||
g_autoptr (WpSpaPodParser) p = wp_spa_pod_parser_new_object (pod,
|
||||
"Props", &id_name);
|
||||
g_autoptr (WpSpaPodParser) p = wp_spa_pod_parser_new_object (pod, &id_name);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_parser_get (p, "mute", "b", &mute, NULL));
|
||||
g_assert_true (wp_spa_pod_parser_get (p, "volume", "f", &vol, NULL));
|
||||
|
|
@ -490,15 +489,11 @@ test_spa_pod_object (void)
|
|||
g_assert_cmpstr (device, ==, "device-name");
|
||||
g_assert_cmpint (device_fd, ==, 5);
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_struct (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Dynamic */
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_struct ();
|
||||
|
|
@ -510,7 +505,7 @@ test_spa_pod_struct (void)
|
|||
wp_spa_pod_builder_add_double (b, 2.718281828);
|
||||
wp_spa_pod_builder_add_string (b, "WirePlumber");
|
||||
wp_spa_pod_builder_add_bytes (b, "bytes", 5);
|
||||
wp_spa_pod_builder_add_pointer (b, "Struct", b);
|
||||
wp_spa_pod_builder_add_pointer (b, "Spa:Pointer:Buffer", b);
|
||||
wp_spa_pod_builder_add_fd (b, 4);
|
||||
wp_spa_pod_builder_add_rectangle (b, 1920, 1080);
|
||||
wp_spa_pod_builder_add_fraction (b, 16, 9);
|
||||
|
|
@ -520,7 +515,7 @@ test_spa_pod_struct (void)
|
|||
}
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_object (
|
||||
"Props", "Props",
|
||||
"Spa:Pod:Object:Param:Props", "Props",
|
||||
"mute", "b", FALSE,
|
||||
NULL);
|
||||
wp_spa_pod_builder_add (b, "P", pod, NULL);
|
||||
|
|
@ -528,7 +523,8 @@ test_spa_pod_struct (void)
|
|||
g_autoptr (WpSpaPod) pod = wp_spa_pod_builder_end (b);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_struct (pod));
|
||||
g_assert_cmpstr ("Struct", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Struct", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
|
||||
g_autoptr (WpSpaPodParser) p = wp_spa_pod_parser_new_struct (pod);
|
||||
g_assert_nonnull (pod);
|
||||
|
|
@ -568,11 +564,8 @@ test_spa_pod_struct (void)
|
|||
g_assert_cmpuint (len_bytes, ==, 5);
|
||||
|
||||
gconstpointer value_pointer;
|
||||
const char *type_pointer;
|
||||
g_assert_true (wp_spa_pod_parser_get_pointer (p, &type_pointer, &value_pointer));
|
||||
g_assert_nonnull (type_pointer);
|
||||
g_assert_true (wp_spa_pod_parser_get_pointer (p, &value_pointer));
|
||||
g_assert_nonnull (value_pointer);
|
||||
g_assert_cmpstr (type_pointer, ==, "Struct");
|
||||
g_assert_true (value_pointer == b);
|
||||
|
||||
gint64 value_fd;
|
||||
|
|
@ -604,28 +597,25 @@ test_spa_pod_struct (void)
|
|||
gboolean mute = TRUE;
|
||||
|
||||
g_assert_true (wp_spa_pod_get_object (value_object,
|
||||
"Props", &id_name,
|
||||
&id_name,
|
||||
"mute", "b", &mute,
|
||||
NULL));
|
||||
g_assert_cmpstr (id_name, ==, "Props");
|
||||
g_assert_false (mute);
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_sequence (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Static */
|
||||
{
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_sequence (0,
|
||||
10, "Properties", "l", 9999, NULL);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_sequence (pod));
|
||||
g_assert_cmpstr ("Sequence", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Sequence", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
}
|
||||
|
||||
/* Dynamic */
|
||||
|
|
@ -636,14 +626,13 @@ test_spa_pod_sequence (void)
|
|||
g_autoptr (WpSpaPod) pod = wp_spa_pod_builder_end (b);
|
||||
g_assert_nonnull (pod);
|
||||
g_assert_true (wp_spa_pod_is_sequence (pod));
|
||||
g_assert_cmpstr ("Sequence", ==, wp_spa_pod_get_type_name (pod));
|
||||
g_assert_cmpstr ("Spa:Pod:Sequence", ==,
|
||||
wp_spa_type_name (wp_spa_pod_get_spa_type (pod)));
|
||||
}
|
||||
|
||||
/* It is not possible to use the parser to get the contents of a sequence, you
|
||||
* need to use the iterator API to achieve that. This is because there is no
|
||||
* `spa_pod_parser_get_sequence` API in the SPA library. */
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -692,8 +681,6 @@ sequence_foreach (const GValue *item, gpointer data)
|
|||
static void
|
||||
test_spa_pod_iterator (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Choice */
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_choice ("Enum");
|
||||
|
|
@ -794,7 +781,7 @@ test_spa_pod_iterator (void)
|
|||
/* Object */
|
||||
{
|
||||
g_autoptr (WpSpaPodBuilder) b = wp_spa_pod_builder_new_object (
|
||||
"Props", "Props");
|
||||
"Spa:Pod:Object:Param:Props", "Props");
|
||||
wp_spa_pod_builder_add_property (b, "mute");
|
||||
wp_spa_pod_builder_add_boolean (b, FALSE);
|
||||
wp_spa_pod_builder_add_property (b, "device");
|
||||
|
|
@ -957,18 +944,14 @@ test_spa_pod_iterator (void)
|
|||
g_assert_true (wp_iterator_foreach (it, sequence_foreach, &offset_total));
|
||||
g_assert_cmpuint (offset_total, ==, 50);
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_unique_owner (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
/* Create an object */
|
||||
WpSpaPod *pod = wp_spa_pod_new_object (
|
||||
"PropInfo", "PropInfo",
|
||||
"Spa:Pod:Object:Param:PropInfo", "PropInfo",
|
||||
"id", "I", 1,
|
||||
"name", "s", "prop-info-name",
|
||||
NULL);
|
||||
|
|
@ -1024,21 +1007,17 @@ test_spa_pod_unique_owner (void)
|
|||
|
||||
/* Destroy the property */
|
||||
g_value_unset (&next);
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_pod_port_config (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
|
||||
const gint rate = 48000;
|
||||
const gint channels = 2;
|
||||
|
||||
/* Build the format to make sure the types exist */
|
||||
g_autoptr (WpSpaPodBuilder) builder = wp_spa_pod_builder_new_object (
|
||||
"Format", "Format");
|
||||
"Spa:Pod:Object:Param:Format", "Format");
|
||||
wp_spa_pod_builder_add (builder,
|
||||
"mediaType", "I", 0,
|
||||
"mediaSubtype", "I", 0,
|
||||
|
|
@ -1056,7 +1035,8 @@ test_spa_pod_port_config (void)
|
|||
g_assert_nonnull (format);
|
||||
|
||||
/* Build the port config to make sure the types exist */
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_object ("PortConfig", "PortConfig",
|
||||
g_autoptr (WpSpaPod) pod = wp_spa_pod_new_object (
|
||||
"Spa:Pod:Object:Param:PortConfig", "PortConfig",
|
||||
"direction", "I", 0,
|
||||
"mode", "I", 0,
|
||||
"monitor", "b", FALSE,
|
||||
|
|
@ -1064,8 +1044,6 @@ test_spa_pod_port_config (void)
|
|||
"format", "P", format,
|
||||
NULL);
|
||||
g_assert_nonnull (pod);
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -12,143 +12,369 @@
|
|||
static void
|
||||
test_spa_type_basic (void)
|
||||
{
|
||||
wp_spa_type_init (TRUE);
|
||||
g_assert_cmpuint (WP_SPA_TYPE_INVALID, ==, SPA_ID_INVALID);
|
||||
|
||||
/* Make sure table sizes are not 0 */
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), >, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_PARAM), >, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_PROPS), >, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_PROP_INFO), >, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_CONTROL), >, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_CHOICE), >, 0);
|
||||
|
||||
/* Make sure SPA_TYPE_OBJECT_Props type from WP_SPA_TYPE_TABLE_BASIC is registered */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
WpSpaTypeTable table = WP_SPA_TYPE_TABLE_BASIC;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, SPA_TYPE_OBJECT_Props,
|
||||
&name, &nick, &table));
|
||||
g_assert_cmpstr (name, ==, "Spa:Pod:Object:Param:Props");
|
||||
g_assert_cmpstr (nick, ==, "Props");
|
||||
g_assert_cmpuint (table, ==, WP_SPA_TYPE_TABLE_PROPS);
|
||||
WpSpaType type = SPA_TYPE_Int;
|
||||
g_assert_cmpstr (wp_spa_type_name (type), ==, "Spa:Int");
|
||||
g_assert_true (wp_spa_type_is_fundamental (type));
|
||||
g_assert_cmpuint (wp_spa_type_parent (type), ==, SPA_TYPE_Int);
|
||||
}
|
||||
|
||||
/* Make sure SPA_PARAM_Props type from WP_SPA_TYPE_TABLE_PARAM is registered */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PARAM, SPA_PARAM_Props, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Enum:ParamId:Props");
|
||||
g_assert_cmpstr (nick, ==, "Props");
|
||||
WpSpaType type = wp_spa_type_from_name ("Spa:Enum:ParamId");
|
||||
g_assert_cmpuint (type, ==, WP_SPA_TYPE_INVALID);
|
||||
|
||||
WpSpaIdTable table = wp_spa_id_table_from_name ("Spa:Enum:ParamId");
|
||||
g_assert_nonnull (table);
|
||||
}
|
||||
|
||||
/* Make sure SPA_PROP_mute type from WP_SPA_TYPE_TABLE_PROPS is registered */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PROPS, SPA_PROP_mute, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Pod:Object:Param:Props:mute");
|
||||
g_assert_cmpstr (nick, ==, "mute");
|
||||
WpSpaType type = SPA_TYPE_OBJECT_Props;
|
||||
g_assert_cmpstr (wp_spa_type_name (type), ==, "Spa:Pod:Object:Param:Props");
|
||||
g_assert_cmpuint (wp_spa_type_from_name (SPA_TYPE_INFO_Props), ==, type);
|
||||
g_assert_true (wp_spa_type_is_object (type));
|
||||
g_assert_false (wp_spa_type_is_fundamental (type));
|
||||
g_assert_cmpuint (wp_spa_type_parent (type), ==, SPA_TYPE_Object);
|
||||
g_assert_nonnull (wp_spa_type_get_object_id_values_table (type));
|
||||
g_assert_true (wp_spa_type_get_object_id_values_table (type) ==
|
||||
wp_spa_id_table_from_name ("Spa:Enum:ParamId"));
|
||||
}
|
||||
|
||||
/* Make sure SPA_PROP_INFO_id type from WP_SPA_TYPE_TABLE_PROP_INFO is registered */
|
||||
/* enums */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_PROP_INFO, SPA_PROP_INFO_id, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Pod:Object:Param:PropInfo:id");
|
||||
g_assert_cmpstr (nick, ==, "id");
|
||||
WpSpaIdValue id = wp_spa_id_value_from_name ("Spa:Enum:ParamId:Props");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==, "Spa:Enum:ParamId:Props");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Props");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PARAM_Props);
|
||||
|
||||
g_assert_true (id == wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:ParamId", "Props"));
|
||||
g_assert_true (id == wp_spa_id_value_from_number (
|
||||
"Spa:Enum:ParamId", SPA_PARAM_Props));
|
||||
}
|
||||
|
||||
/* Make sure SPA_CONTROL_Properties type from WP_SPA_TYPE_TABLE_CONTROL is registered */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_CONTROL, SPA_CONTROL_Properties, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Enum:Control:Properties");
|
||||
g_assert_cmpstr (nick, ==, "Properties");
|
||||
WpSpaIdValue id =
|
||||
wp_spa_id_value_from_name ("Spa:Enum:Control:Properties");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==,
|
||||
"Spa:Enum:Control:Properties");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Properties");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CONTROL_Properties);
|
||||
|
||||
g_assert_true (id == wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:Control", "Properties"));
|
||||
g_assert_true (id == wp_spa_id_value_from_number (
|
||||
"Spa:Enum:Control", SPA_CONTROL_Properties));
|
||||
}
|
||||
|
||||
/* Make sure SPA_CHOICE_Enum type from WP_SPA_TYPE_TABLE_CHOICE is registered */
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_CHOICE, SPA_CHOICE_Enum, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Enum:Choice:Enum");
|
||||
g_assert_cmpstr (nick, ==, "Enum");
|
||||
WpSpaIdValue id = wp_spa_id_value_from_name ("Spa:Enum:Choice:Enum");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==, "Spa:Enum:Choice:Enum");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Enum");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_Enum);
|
||||
|
||||
g_assert_true (id == wp_spa_id_value_from_short_name (
|
||||
"Spa:Enum:Choice", "Enum"));
|
||||
g_assert_true (id == wp_spa_id_value_from_number (
|
||||
"Spa:Enum:Choice", SPA_CHOICE_Enum));
|
||||
}
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
/* objects */
|
||||
{
|
||||
WpSpaIdValue id =
|
||||
wp_spa_id_value_from_name ("Spa:Pod:Object:Param:Props:mute");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==,
|
||||
"Spa:Pod:Object:Param:Props:mute");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "mute");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_mute);
|
||||
|
||||
g_assert_true (id == wp_spa_id_value_from_short_name (
|
||||
SPA_TYPE_INFO_Props, "mute"));
|
||||
g_assert_true (id == wp_spa_id_value_from_number (
|
||||
SPA_TYPE_INFO_Props, SPA_PROP_mute));
|
||||
}
|
||||
|
||||
{
|
||||
WpSpaIdValue id =
|
||||
wp_spa_id_value_from_name ("Spa:Pod:Object:Param:PropInfo:id");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==,
|
||||
"Spa:Pod:Object:Param:PropInfo:id");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "id");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_id);
|
||||
|
||||
/* WpSpaIdValue is a pointer to static spa_type_info,
|
||||
so it should be the same on all queries */
|
||||
g_assert_true (id == wp_spa_id_value_from_short_name (
|
||||
SPA_TYPE_INFO_PropInfo, "id"));
|
||||
g_assert_true (id == wp_spa_id_value_from_number (
|
||||
SPA_TYPE_INFO_PropInfo, SPA_PROP_INFO_id));
|
||||
}
|
||||
|
||||
/* array value type check */
|
||||
{
|
||||
WpSpaIdValue id =
|
||||
wp_spa_id_value_from_name ("Spa:Pod:Object:Param:Props:channelVolumes");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==,
|
||||
"Spa:Pod:Object:Param:Props:channelVolumes");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "channelVolumes");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_channelVolumes);
|
||||
|
||||
g_assert_cmpuint (wp_spa_id_value_array_get_item_type (id, NULL), ==,
|
||||
SPA_TYPE_Float);
|
||||
}
|
||||
|
||||
{
|
||||
WpSpaIdValue id =
|
||||
wp_spa_id_value_from_name ("Spa:Pod:Object:Param:Props:channelMap");
|
||||
g_assert_nonnull (id);
|
||||
g_assert_cmpstr (wp_spa_id_value_name (id), ==,
|
||||
"Spa:Pod:Object:Param:Props:channelMap");
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "channelMap");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_channelMap);
|
||||
|
||||
WpSpaIdTable table = NULL;
|
||||
g_assert_cmpuint (wp_spa_id_value_array_get_item_type (id, &table), ==,
|
||||
SPA_TYPE_Id);
|
||||
g_assert_nonnull (table);
|
||||
g_assert_true (table == wp_spa_id_table_from_name ("Spa:Enum:AudioChannel"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_type_iterate (void)
|
||||
{
|
||||
{
|
||||
WpSpaType type = wp_spa_type_from_name (SPA_TYPE_INFO_PropInfo);
|
||||
g_assert_cmpuint (type, !=, WP_SPA_TYPE_INVALID);
|
||||
g_assert_true (wp_spa_type_is_object (type));
|
||||
|
||||
WpSpaIdTable table = wp_spa_type_get_values_table (type);
|
||||
g_autoptr (WpIterator) it = wp_spa_id_table_iterate (table);
|
||||
g_auto (GValue) value = G_VALUE_INIT;
|
||||
WpSpaIdValue id = NULL;
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_START);
|
||||
table = NULL;
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_Id);
|
||||
g_assert_nonnull (table);
|
||||
g_assert_true (table == wp_spa_id_table_from_name ("Spa:Enum:ParamId"));
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "id");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_id);
|
||||
table = NULL;
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_Id);
|
||||
g_assert_nonnull (table);
|
||||
g_assert_true (table ==
|
||||
wp_spa_id_table_from_name ("Spa:Pod:Object:Param:Props"));
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "name");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_name);
|
||||
table = NULL;
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_String);
|
||||
g_assert_null (table);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "type");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_type);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_Pod);
|
||||
g_assert_null (table);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "labels");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_labels);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_Struct);
|
||||
g_assert_null (table);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "container");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_PROP_INFO_container);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, &table), ==, SPA_TYPE_Id);
|
||||
g_assert_null (table);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
{
|
||||
WpSpaIdTable table = wp_spa_id_table_from_name ("Spa:Enum:Choice");
|
||||
g_assert_nonnull (table);
|
||||
|
||||
g_autoptr (WpIterator) it = wp_spa_id_table_iterate (table);
|
||||
g_auto (GValue) value = G_VALUE_INIT;
|
||||
WpSpaIdValue id = NULL;
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "None");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_None);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Range");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_Range);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Step");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_Step);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Enum");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_Enum);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Flags");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, SPA_CHOICE_Flags);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_type_register (void)
|
||||
{
|
||||
wp_spa_type_init (FALSE);
|
||||
static const struct spa_type_info custom_enum_info[] = {
|
||||
{ 0, SPA_TYPE_Int, "Spa:Enum:CustomEnum:Invalid", NULL },
|
||||
{ 1, SPA_TYPE_Int, "Spa:Enum:CustomEnum:Valid", NULL },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/* Make sure no types are registered */
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_PARAM), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_PROPS), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_CONTROL), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_CHOICE), ==, 0);
|
||||
static const struct spa_type_info custom_obj_info[] = {
|
||||
{ 0, SPA_TYPE_Id, "Spa:Pod:Object:CustomObj:", custom_enum_info },
|
||||
{ 1, SPA_TYPE_Int, "Spa:Pod:Object:CustomObj:id", NULL },
|
||||
{ 2, SPA_TYPE_String, "Spa:Pod:Object:CustomObj:name", NULL },
|
||||
{ 3, SPA_TYPE_Float, "Spa:Pod:Object:CustomObj:volume", NULL },
|
||||
{ 4, SPA_TYPE_Rectangle, "Spa:Pod:Object:CustomObj:box", NULL },
|
||||
{ 5, SPA_TYPE_Bytes, "Spa:Pod:Object:CustomObj:data", NULL },
|
||||
{ 0, 0, NULL, NULL },
|
||||
};
|
||||
|
||||
wp_spa_dynamic_type_init ();
|
||||
|
||||
WpSpaIdTable enum_table =
|
||||
wp_spa_dynamic_id_table_register ("Spa:Enum:CustomEnum", custom_enum_info);
|
||||
WpSpaType obj_type = wp_spa_dynamic_type_register ("Spa:Pod:Object:CustomObj",
|
||||
SPA_TYPE_Object, custom_obj_info);
|
||||
|
||||
g_assert_nonnull (enum_table);
|
||||
g_assert_true (obj_type != WP_SPA_TYPE_INVALID);
|
||||
|
||||
g_assert_true (enum_table ==
|
||||
wp_spa_id_table_from_name ("Spa:Enum:CustomEnum"));
|
||||
|
||||
/* Register SPA_TYPE_Bool */
|
||||
{
|
||||
g_assert_true (wp_spa_type_register (WP_SPA_TYPE_TABLE_BASIC, "Spa:Bool", "spa-bool"));
|
||||
g_autoptr (WpIterator) it = wp_spa_id_table_iterate (enum_table);
|
||||
g_auto (GValue) value = G_VALUE_INIT;
|
||||
WpSpaIdValue id = NULL;
|
||||
|
||||
guint32 id = 0;
|
||||
const char *name = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "spa-bool", &id, &name, NULL));
|
||||
g_assert_cmpuint (id, ==, SPA_TYPE_Bool);
|
||||
g_assert_cmpstr (name, ==, "Spa:Bool");
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Invalid");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, id, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Spa:Bool");
|
||||
g_assert_cmpstr (nick, ==, "spa-bool");
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "Valid");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 1);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_false (wp_spa_type_register (WP_SPA_TYPE_TABLE_BASIC, "Spa:Bool", "spa-bool"));
|
||||
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), ==, 1);
|
||||
g_assert_false (wp_iterator_next (it, &value));
|
||||
}
|
||||
|
||||
/* Register Custom */
|
||||
g_assert_cmpstr (wp_spa_type_name (obj_type), ==, "Spa:Pod:Object:CustomObj");
|
||||
g_assert_true (wp_spa_type_is_object (obj_type));
|
||||
g_assert_false (wp_spa_type_is_fundamental (obj_type));
|
||||
g_assert_cmpuint (wp_spa_type_parent (obj_type), ==, SPA_TYPE_Object);
|
||||
g_assert_cmpuint (obj_type, ==,
|
||||
wp_spa_type_from_name ("Spa:Pod:Object:CustomObj"));
|
||||
g_assert_true (enum_table ==
|
||||
wp_spa_type_get_object_id_values_table (obj_type));
|
||||
|
||||
{
|
||||
g_assert_true (wp_spa_type_register (WP_SPA_TYPE_TABLE_BASIC, "Wp:Bool", "wp-bool"));
|
||||
WpSpaIdTable table = wp_spa_type_get_values_table (obj_type);
|
||||
g_autoptr (WpIterator) it = wp_spa_id_table_iterate (table);
|
||||
g_auto (GValue) value = G_VALUE_INIT;
|
||||
WpSpaIdValue id = NULL;
|
||||
|
||||
guint32 id = 0;
|
||||
const char *name = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "wp-bool", &id, &name, NULL));
|
||||
g_assert_cmpuint (id, ==, SPA_TYPE_VENDOR_Other + 1);
|
||||
g_assert_cmpstr (name, ==, "Wp:Bool");
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 0);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Id);
|
||||
g_value_unset (&value);
|
||||
|
||||
name = NULL;
|
||||
const char *nick = NULL;
|
||||
g_assert_true (wp_spa_type_get_by_id (WP_SPA_TYPE_TABLE_BASIC, id, &name, &nick, NULL));
|
||||
g_assert_cmpstr (name, ==, "Wp:Bool");
|
||||
g_assert_cmpstr (nick, ==, "wp-bool");
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "id");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 1);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Int);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_false (wp_spa_type_register (WP_SPA_TYPE_TABLE_BASIC, "Wp:Bool", "wp-bool"));
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "name");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 2);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_String);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), ==, 2);
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "volume");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 3);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Float);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "box");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 4);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Rectangle);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_true (wp_iterator_next (it, &value));
|
||||
id = g_value_get_pointer (&value);
|
||||
g_assert_cmpstr (wp_spa_id_value_short_name (id), ==, "data");
|
||||
g_assert_cmpuint (wp_spa_id_value_number (id), ==, 5);
|
||||
g_assert_cmpuint (wp_spa_id_value_get_value_type (id, NULL), ==, SPA_TYPE_Bytes);
|
||||
g_value_unset (&value);
|
||||
|
||||
g_assert_false (wp_iterator_next (it, &value));
|
||||
}
|
||||
|
||||
/* Unregister SPA_TYPE_Bool */
|
||||
g_assert_true (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "spa-bool", NULL, NULL, NULL));
|
||||
wp_spa_type_unregister (WP_SPA_TYPE_TABLE_BASIC, "spa-bool");
|
||||
g_assert_false (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "spa-bool", NULL, NULL, NULL));
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), ==, 1);
|
||||
|
||||
/* Unregister Custom */
|
||||
g_assert_true (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "wp-bool", NULL, NULL, NULL));
|
||||
wp_spa_type_unregister (WP_SPA_TYPE_TABLE_BASIC, "wp-bool");
|
||||
g_assert_false (wp_spa_type_get_by_nick (WP_SPA_TYPE_TABLE_BASIC, "wp-bool", NULL, NULL, NULL));
|
||||
g_assert_cmpuint (wp_spa_type_get_table_size (WP_SPA_TYPE_TABLE_BASIC), ==, 0);
|
||||
|
||||
wp_spa_type_deinit ();
|
||||
wp_spa_dynamic_type_deinit ();
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -158,6 +384,7 @@ main (int argc, char *argv[])
|
|||
g_log_set_writer_func (wp_log_writer_default, NULL, NULL);
|
||||
|
||||
g_test_add_func ("/wp/spa-type/basic", test_spa_type_basic);
|
||||
g_test_add_func ("/wp/spa-type/iterate", test_spa_type_iterate);
|
||||
g_test_add_func ("/wp/spa-type/register", test_spa_type_register);
|
||||
|
||||
return g_test_run ();
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ print_controls (WpPipewireObject * pwobj)
|
|||
|
||||
it = wp_pipewire_object_enum_params_sync (pwobj, "Props", NULL);
|
||||
if (!it || !wp_iterator_next (it, &value) ||
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), "Props", NULL,
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), NULL,
|
||||
"volume", "f", &volume,
|
||||
"mute", "b", &mute,
|
||||
NULL))
|
||||
|
|
@ -654,14 +654,16 @@ set_volume_run (WpCtl * self)
|
|||
|
||||
it = wp_pipewire_object_enum_params_sync (proxy, "Props", NULL);
|
||||
if (!it || !wp_iterator_next (it, &value) ||
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), "Props", NULL,
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), NULL,
|
||||
"volume", "f", &volume, NULL)) {
|
||||
printf ("Object '%d' does not support volume\n", cmdline.set_volume.id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wp_pipewire_object_set_param (proxy, "Props", 0, wp_spa_pod_new_object (
|
||||
"Props", "Props", "volume", "f", cmdline.set_volume.volume, NULL));
|
||||
"Spa:Pod:Object:Param:Props", "Props",
|
||||
"volume", "f", cmdline.set_volume.volume,
|
||||
NULL));
|
||||
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self);
|
||||
return;
|
||||
|
||||
|
|
@ -741,7 +743,7 @@ set_mute_run (WpCtl * self)
|
|||
|
||||
it = wp_pipewire_object_enum_params_sync (proxy, "Props", NULL);
|
||||
if (!it || !wp_iterator_next (it, &value) ||
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), "Props", NULL,
|
||||
!wp_spa_pod_get_object (g_value_get_boxed (&value), NULL,
|
||||
"mute", "b", &mute, NULL)) {
|
||||
printf ("Object '%d' does not support mute\n", cmdline.set_mute.id);
|
||||
goto out;
|
||||
|
|
@ -753,7 +755,9 @@ set_mute_run (WpCtl * self)
|
|||
mute = !!cmdline.set_mute.mute;
|
||||
|
||||
wp_pipewire_object_set_param (proxy, "Props", 0, wp_spa_pod_new_object (
|
||||
"Props", "Props", "mute", "b", mute, NULL));
|
||||
"Spa:Pod:Object:Param:Props", "Props",
|
||||
"mute", "b", mute,
|
||||
NULL));
|
||||
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self);
|
||||
return;
|
||||
|
||||
|
|
@ -810,7 +814,7 @@ set_profile_run (WpCtl * self)
|
|||
}
|
||||
wp_pipewire_object_set_param (proxy, "Profile", 0,
|
||||
wp_spa_pod_new_object (
|
||||
"Profile", "Profile",
|
||||
"Spa:Pod:Object:Param:Profile", "Profile",
|
||||
"index", "i", cmdline.set_profile.index,
|
||||
NULL));
|
||||
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue