lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
/* WirePlumber
|
|
|
|
|
*
|
|
|
|
|
* Copyright © 2020 Collabora Ltd.
|
|
|
|
|
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define G_LOG_DOMAIN "wp-pw-obj-mixin"
|
|
|
|
|
|
|
|
|
|
#include "private/pipewire-object-mixin.h"
|
|
|
|
|
#include "core.h"
|
2020-11-25 14:02:33 +02:00
|
|
|
#include "spa-type.h"
|
|
|
|
|
#include "spa-pod.h"
|
2021-05-06 15:45:13 +03:00
|
|
|
#include "log.h"
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
#include "error.h"
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
#include <spa/utils/result.h>
|
|
|
|
|
|
|
|
|
|
G_DEFINE_INTERFACE (WpPwObjectMixinPriv, wp_pw_object_mixin_priv, WP_TYPE_PROXY)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wp_pw_object_mixin_priv_default_init (WpPwObjectMixinPrivInterface * iface)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct spa_param_info *
|
|
|
|
|
find_param_info (gpointer instance, guint32 id)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
|
|
|
|
|
/* offsets are 0 on objects that don't support params */
|
|
|
|
|
if (d->info && iface->n_params_offset && iface->param_info_offset) {
|
|
|
|
|
struct spa_param_info * param_info =
|
|
|
|
|
G_STRUCT_MEMBER (struct spa_param_info *, d->info, iface->param_info_offset);
|
|
|
|
|
guint32 n_params =
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->n_params_offset);
|
|
|
|
|
|
|
|
|
|
for (guint i = 0; i < n_params; i++) {
|
|
|
|
|
if (param_info[i].id == id)
|
|
|
|
|
return ¶m_info[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************/
|
|
|
|
|
/* INTERFACE */
|
|
|
|
|
|
|
|
|
|
static gconstpointer
|
|
|
|
|
wp_pw_object_mixin_get_native_info (WpPipewireObject * obj)
|
|
|
|
|
{
|
|
|
|
|
return wp_pw_object_mixin_get_data (obj)->info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static WpProperties *
|
|
|
|
|
wp_pw_object_mixin_get_properties (WpPipewireObject * obj)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (obj);
|
|
|
|
|
return d->properties ? wp_properties_ref (d->properties) : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GVariant *
|
|
|
|
|
wp_pw_object_mixin_get_param_info (WpPipewireObject * obj)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (obj);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
|
|
|
|
struct spa_param_info *info;
|
|
|
|
|
guint32 n_params;
|
|
|
|
|
g_auto (GVariantBuilder) b =
|
|
|
|
|
G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_DICTIONARY);
|
|
|
|
|
|
|
|
|
|
if (!d->info ||
|
|
|
|
|
iface->param_info_offset == 0 ||
|
|
|
|
|
iface->n_params_offset == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
info = G_STRUCT_MEMBER (struct spa_param_info *, d->info, iface->param_info_offset);
|
|
|
|
|
n_params = G_STRUCT_MEMBER (guint32, d->info, iface->n_params_offset);
|
|
|
|
|
|
|
|
|
|
g_variant_builder_init (&b, G_VARIANT_TYPE ("a{ss}"));
|
|
|
|
|
|
|
|
|
|
for (guint i = 0; i < n_params; i++) {
|
2021-01-13 20:11:41 +02:00
|
|
|
WpSpaIdValue idval;
|
2020-11-25 14:02:33 +02:00
|
|
|
const gchar *nick = NULL;
|
|
|
|
|
gchar flags[3];
|
|
|
|
|
guint flags_idx = 0;
|
|
|
|
|
|
2021-01-13 20:11:41 +02:00
|
|
|
idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", info[i].id);
|
|
|
|
|
nick = wp_spa_id_value_short_name (idval);
|
2020-11-25 14:02:33 +02:00
|
|
|
g_return_val_if_fail (nick != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if (info[i].flags & SPA_PARAM_INFO_READ)
|
|
|
|
|
flags[flags_idx++] = 'r';
|
|
|
|
|
if (info[i].flags & SPA_PARAM_INFO_WRITE)
|
|
|
|
|
flags[flags_idx++] = 'w';
|
|
|
|
|
flags[flags_idx] = '\0';
|
|
|
|
|
|
|
|
|
|
g_variant_builder_add (&b, "{ss}", nick, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return g_variant_builder_end (&b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
enum_params_done (WpCore * core, GAsyncResult * res, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr (GTask) task = G_TASK (data);
|
2021-05-18 15:23:50 -04:00
|
|
|
GList *taskl = NULL;
|
2020-11-25 14:02:33 +02:00
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
gpointer instance = g_task_get_source_object (G_TASK (data));
|
|
|
|
|
GPtrArray *params = g_task_get_task_data (task);
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
|
|
|
|
|
/* finish the sync task */
|
|
|
|
|
wp_core_sync_finish (core, res, &error);
|
|
|
|
|
|
2021-05-18 15:23:50 -04:00
|
|
|
/* return if task was previously removed from the list */
|
|
|
|
|
taskl = g_list_find (d->enum_params_tasks, task);
|
|
|
|
|
if (!taskl)
|
2021-04-28 21:58:03 +03:00
|
|
|
return;
|
|
|
|
|
|
2021-05-18 15:23:50 -04:00
|
|
|
/* remove the task from the stored list; ref is held by the g_autoptr */
|
2021-05-24 12:06:38 -04:00
|
|
|
d->enum_params_tasks = g_list_delete_link (d->enum_params_tasks, taskl);
|
2021-05-18 15:23:50 -04:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_debug_object (instance, "got %u params, %s, task " WP_OBJECT_FORMAT,
|
|
|
|
|
params->len, error ? "with error" : "ok", WP_OBJECT_ARGS (task));
|
|
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
|
g_task_return_error (task, g_steal_pointer (&error));
|
|
|
|
|
else {
|
|
|
|
|
g_task_return_pointer (task, g_ptr_array_ref (params),
|
|
|
|
|
(GDestroyNotify) g_ptr_array_unref);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-28 21:58:03 +03:00
|
|
|
static void
|
|
|
|
|
enum_params_error (WpProxy * proxy, int seq, int res, const gchar *msg,
|
|
|
|
|
GTask * task)
|
|
|
|
|
{
|
2021-05-18 15:23:50 -04:00
|
|
|
gint t_seq = GPOINTER_TO_INT (g_task_get_source_tag (task));
|
2021-04-28 21:58:03 +03:00
|
|
|
|
2021-05-18 15:23:50 -04:00
|
|
|
if (SPA_RESULT_ASYNC_SEQ (t_seq) == SPA_RESULT_ASYNC_SEQ (seq)) {
|
|
|
|
|
gpointer instance = g_task_get_source_object (task);
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
GList *taskl = NULL;
|
|
|
|
|
|
|
|
|
|
taskl = g_list_find (d->enum_params_tasks, task);
|
|
|
|
|
if (taskl) {
|
2021-05-24 12:06:38 -04:00
|
|
|
d->enum_params_tasks = g_list_delete_link (d->enum_params_tasks, taskl);
|
2021-05-18 15:23:50 -04:00
|
|
|
g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
|
|
|
|
|
WP_LIBRARY_ERROR_OPERATION_FAILED, "%s", msg);
|
|
|
|
|
}
|
2021-04-28 21:58:03 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
static void
|
|
|
|
|
wp_pw_object_mixin_enum_params_unchecked (gpointer obj,
|
|
|
|
|
guint32 id, WpSpaPod *filter, GCancellable * cancellable,
|
|
|
|
|
GAsyncReadyCallback callback, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (obj);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
|
|
|
|
g_autoptr (GTask) task = NULL;
|
|
|
|
|
gint seq = 0;
|
|
|
|
|
GPtrArray *params = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (iface->enum_params_sync || iface->enum_params);
|
|
|
|
|
|
|
|
|
|
if (iface->enum_params_sync) {
|
|
|
|
|
params = iface->enum_params_sync (obj, id, 0, -1, filter);
|
|
|
|
|
} else {
|
|
|
|
|
seq = iface->enum_params (obj, id, 0, -1, filter);
|
|
|
|
|
|
|
|
|
|
/* return early if seq contains an error */
|
|
|
|
|
if (G_UNLIKELY (SPA_RESULT_IS_ERROR (seq))) {
|
|
|
|
|
wp_message_object (obj, "enum_params failed: %s", spa_strerror (seq));
|
|
|
|
|
g_task_report_new_error (obj, callback, user_data, NULL,
|
|
|
|
|
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
|
|
|
|
"enum_params failed: %s", spa_strerror (seq));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!params)
|
|
|
|
|
params = g_ptr_array_new_with_free_func ((GDestroyNotify) wp_spa_pod_unref);
|
|
|
|
|
|
|
|
|
|
/* create task */
|
|
|
|
|
task = g_task_new (obj, cancellable, callback, user_data);
|
|
|
|
|
|
|
|
|
|
/* debug */
|
|
|
|
|
if (wp_log_level_is_enabled (G_LOG_LEVEL_DEBUG)) {
|
|
|
|
|
const gchar *name = NULL;
|
2021-01-13 20:11:41 +02:00
|
|
|
name = wp_spa_id_value_short_name (
|
|
|
|
|
wp_spa_id_value_from_number ("Spa:Enum:ParamId", id));
|
2020-11-25 14:02:33 +02:00
|
|
|
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" : "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iface->enum_params_sync) {
|
|
|
|
|
g_task_return_pointer (task, params, (GDestroyNotify) g_ptr_array_unref);
|
|
|
|
|
} else {
|
|
|
|
|
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (obj));
|
|
|
|
|
|
2021-04-28 21:58:03 +03:00
|
|
|
/* watch for errors */
|
|
|
|
|
g_signal_connect_object (obj, "error", G_CALLBACK (enum_params_error),
|
|
|
|
|
task, 0);
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/* store */
|
|
|
|
|
g_task_set_task_data (task, params, (GDestroyNotify) g_ptr_array_unref);
|
|
|
|
|
g_task_set_source_tag (task, GINT_TO_POINTER (seq));
|
|
|
|
|
d->enum_params_tasks = g_list_append (d->enum_params_tasks, task);
|
|
|
|
|
|
|
|
|
|
/* call sync */
|
|
|
|
|
wp_core_sync (core, cancellable, (GAsyncReadyCallback) enum_params_done,
|
|
|
|
|
g_object_ref (task));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wp_pw_object_mixin_enum_params (WpPipewireObject * obj, const gchar * id,
|
|
|
|
|
WpSpaPod *filter, GCancellable * cancellable,
|
|
|
|
|
GAsyncReadyCallback callback, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
2021-01-13 20:11:41 +02:00
|
|
|
WpSpaIdValue param_id;
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
if (!(iface->enum_params || iface->enum_params_sync)) {
|
|
|
|
|
g_task_report_new_error (obj, callback, user_data, NULL,
|
|
|
|
|
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVARIANT,
|
|
|
|
|
"enum_params is not supported on this object");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* translate the id */
|
2021-01-13 20:11:41 +02:00
|
|
|
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
|
|
|
|
if (!param_id) {
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_critical_object (obj, "invalid param id: %s", id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 20:11:41 +02:00
|
|
|
wp_pw_object_mixin_enum_params_unchecked (obj,
|
|
|
|
|
wp_spa_id_value_number (param_id), filter,
|
2020-11-25 14:02:33 +02:00
|
|
|
cancellable, callback, user_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static WpIterator *
|
|
|
|
|
wp_pw_object_mixin_enum_params_finish (WpPipewireObject * obj,
|
|
|
|
|
GAsyncResult * res, GError ** error)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (g_task_is_valid (res, obj), NULL);
|
|
|
|
|
|
|
|
|
|
GPtrArray *array = g_task_propagate_pointer (G_TASK (res), error);
|
|
|
|
|
if (!array)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return wp_iterator_new_ptr_array (array, WP_TYPE_SPA_POD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static WpIterator *
|
|
|
|
|
wp_pw_object_mixin_enum_params_sync (WpPipewireObject * obj, const gchar * id,
|
|
|
|
|
WpSpaPod * filter)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface = WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (obj);
|
|
|
|
|
GPtrArray *params = NULL;
|
2021-01-13 20:11:41 +02:00
|
|
|
WpSpaIdValue param_id;
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
/* translate the id */
|
2021-01-13 20:11:41 +02:00
|
|
|
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
|
|
|
|
if (!param_id) {
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_critical_object (obj, "invalid param id: %s", id);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iface->enum_params_sync) {
|
|
|
|
|
/* use enum_params_sync if supported */
|
2021-01-13 20:11:41 +02:00
|
|
|
params = iface->enum_params_sync (obj, wp_spa_id_value_number (param_id),
|
|
|
|
|
0, -1, filter);
|
2020-11-25 14:02:33 +02:00
|
|
|
} else {
|
|
|
|
|
/* otherwise, find and return the cached params */
|
|
|
|
|
WpPwObjectMixinData *data = wp_pw_object_mixin_get_data (obj);
|
2021-01-13 20:11:41 +02:00
|
|
|
params = wp_pw_object_mixin_get_stored_params (data,
|
|
|
|
|
wp_spa_id_value_number (param_id));
|
2020-11-25 14:02:33 +02:00
|
|
|
/* TODO filter */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return params ? wp_iterator_new_ptr_array (params, WP_TYPE_SPA_POD) : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
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);
|
2021-06-08 09:07:46 -04:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (obj);
|
2021-01-13 20:11:41 +02:00
|
|
|
WpSpaIdValue param_id;
|
2020-11-25 14:02:33 +02:00
|
|
|
gint ret;
|
|
|
|
|
|
2021-06-08 09:07:46 -04:00
|
|
|
if (!d->iface) {
|
|
|
|
|
wp_message_object (obj, "ignoring set_param on already destroyed objects");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (!iface->set_param) {
|
|
|
|
|
wp_warning_object (obj, "set_param is not supported on this object");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 20:11:41 +02:00
|
|
|
param_id = wp_spa_id_value_from_short_name ("Spa:Enum:ParamId", id);
|
|
|
|
|
if (!param_id) {
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_critical_object (obj, "invalid param id: %s", id);
|
|
|
|
|
wp_spa_pod_unref (param);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 20:11:41 +02:00
|
|
|
ret = iface->set_param (obj, wp_spa_id_value_number (param_id), flags, param);
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
if (G_UNLIKELY (SPA_RESULT_IS_ERROR (ret))) {
|
|
|
|
|
wp_message_object (obj, "set_param failed: %s", spa_strerror (ret));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
|
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_object_interface_init (WpPipewireObjectInterface * iface)
|
|
|
|
|
{
|
|
|
|
|
iface->get_native_info = wp_pw_object_mixin_get_native_info;
|
|
|
|
|
iface->get_properties = wp_pw_object_mixin_get_properties;
|
|
|
|
|
iface->get_param_info = wp_pw_object_mixin_get_param_info;
|
|
|
|
|
iface->enum_params = wp_pw_object_mixin_enum_params;
|
|
|
|
|
iface->enum_params_finish = wp_pw_object_mixin_enum_params_finish;
|
|
|
|
|
iface->enum_params_sync = wp_pw_object_mixin_enum_params_sync;
|
|
|
|
|
iface->set_param = wp_pw_object_mixin_set_param;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/********/
|
|
|
|
|
/* DATA */
|
|
|
|
|
|
|
|
|
|
G_DEFINE_QUARK (WpPwObjectMixinData, wp_pw_object_mixin_data)
|
|
|
|
|
|
|
|
|
|
static void wp_pw_object_mixin_param_store_free (gpointer data);
|
|
|
|
|
|
|
|
|
|
static WpPwObjectMixinData *
|
|
|
|
|
wp_pw_object_mixin_data_new (void)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = g_slice_new0 (WpPwObjectMixinData);
|
|
|
|
|
spa_hook_list_init (&d->hooks);
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wp_pw_object_mixin_data_free (gpointer data)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = data;
|
|
|
|
|
g_clear_pointer (&d->properties, wp_properties_unref);
|
|
|
|
|
g_list_free_full (d->params, wp_pw_object_mixin_param_store_free);
|
|
|
|
|
g_clear_pointer (&d->subscribed_ids, g_array_unref);
|
|
|
|
|
g_warn_if_fail (d->enum_params_tasks == NULL);
|
|
|
|
|
g_slice_free (WpPwObjectMixinData, d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WpPwObjectMixinData *
|
|
|
|
|
wp_pw_object_mixin_get_data (gpointer instance)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = g_object_get_qdata (G_OBJECT (instance),
|
|
|
|
|
wp_pw_object_mixin_data_quark ());
|
|
|
|
|
if (G_UNLIKELY (!d)) {
|
|
|
|
|
d = wp_pw_object_mixin_data_new ();
|
|
|
|
|
g_object_set_qdata_full (G_OBJECT (instance),
|
|
|
|
|
wp_pw_object_mixin_data_quark (), d, wp_pw_object_mixin_data_free);
|
|
|
|
|
}
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************/
|
|
|
|
|
/* PARAMS STORE */
|
|
|
|
|
|
|
|
|
|
typedef struct _WpPwObjectMixinParamStore WpPwObjectMixinParamStore;
|
|
|
|
|
struct _WpPwObjectMixinParamStore
|
|
|
|
|
{
|
|
|
|
|
guint32 param_id;
|
|
|
|
|
GPtrArray *params;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static WpPwObjectMixinParamStore *
|
|
|
|
|
wp_pw_object_mixin_param_store_new (void)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinParamStore *d = g_slice_new0 (WpPwObjectMixinParamStore);
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wp_pw_object_mixin_param_store_free (gpointer data)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinParamStore * p = data;
|
|
|
|
|
g_clear_pointer (&p->params, g_ptr_array_unref);
|
|
|
|
|
g_slice_free (WpPwObjectMixinParamStore, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gint
|
|
|
|
|
param_store_has_id (gconstpointer param, gconstpointer id)
|
|
|
|
|
{
|
|
|
|
|
guint32 param_id = ((const WpPwObjectMixinParamStore *) param)->param_id;
|
|
|
|
|
return (param_id == GPOINTER_TO_UINT (id)) ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPtrArray *
|
|
|
|
|
wp_pw_object_mixin_get_stored_params (WpPwObjectMixinData * data, guint32 id)
|
|
|
|
|
{
|
|
|
|
|
GList *link = g_list_find_custom (data->params, GUINT_TO_POINTER (id),
|
|
|
|
|
param_store_has_id);
|
|
|
|
|
WpPwObjectMixinParamStore *s = link ? link->data : NULL;
|
|
|
|
|
return (s && s->params) ? g_ptr_array_ref (s->params) : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
wp_pw_object_mixin_store_param (WpPwObjectMixinData * data, guint32 id,
|
|
|
|
|
guint32 flags, gpointer param)
|
|
|
|
|
{
|
|
|
|
|
GList *link = g_list_find_custom (data->params, GUINT_TO_POINTER (id),
|
|
|
|
|
param_store_has_id);
|
|
|
|
|
WpPwObjectMixinParamStore *s = link ? link->data : NULL;
|
|
|
|
|
gint16 index = (gint16) (flags & 0xffff);
|
|
|
|
|
|
|
|
|
|
/* if the link exists, data must also exist */
|
|
|
|
|
g_warn_if_fail (!link || link->data);
|
|
|
|
|
|
|
|
|
|
if (!s) {
|
|
|
|
|
if (flags & WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE)
|
|
|
|
|
return;
|
|
|
|
|
s = wp_pw_object_mixin_param_store_new ();
|
|
|
|
|
s->param_id = id;
|
|
|
|
|
data->params = g_list_append (data->params, s);
|
|
|
|
|
}
|
|
|
|
|
else if (s && (flags & WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE)) {
|
|
|
|
|
wp_pw_object_mixin_param_store_free (s);
|
2021-05-24 12:06:38 -04:00
|
|
|
data->params = g_list_delete_link (data->params, link);
|
2020-11-25 14:02:33 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags & WP_PW_OBJECT_MIXIN_STORE_PARAM_CLEAR)
|
|
|
|
|
g_clear_pointer (&s->params, g_ptr_array_unref);
|
|
|
|
|
|
|
|
|
|
if (!param)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (flags & WP_PW_OBJECT_MIXIN_STORE_PARAM_ARRAY) {
|
|
|
|
|
if (!s->params)
|
|
|
|
|
s->params = (GPtrArray *) param;
|
|
|
|
|
else
|
|
|
|
|
g_ptr_array_extend_and_steal (s->params, (GPtrArray *) param);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WpSpaPod *param_pod = param;
|
|
|
|
|
|
|
|
|
|
if (!s->params)
|
|
|
|
|
s->params =
|
|
|
|
|
g_ptr_array_new_with_free_func ((GDestroyNotify) wp_spa_pod_unref);
|
|
|
|
|
|
|
|
|
|
/* copy if necessary to make sure we don't reference
|
|
|
|
|
`const struct spa_pod *` data allocated on the stack */
|
|
|
|
|
param_pod = wp_spa_pod_ensure_unique_owner (param_pod);
|
|
|
|
|
g_ptr_array_insert (s->params, index, param_pod);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************/
|
|
|
|
|
/* PROPERTIES API */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
wp_pw_object_mixin_get_property (GObject * object, guint property_id,
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
GValue * value, GParamSpec * pspec)
|
|
|
|
|
{
|
|
|
|
|
switch (property_id) {
|
2020-11-25 14:02:33 +02:00
|
|
|
case WP_PW_OBJECT_MIXIN_PROP_NATIVE_INFO:
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
g_value_set_pointer (value, (gpointer)
|
|
|
|
|
wp_pipewire_object_get_native_info (WP_PIPEWIRE_OBJECT (object)));
|
|
|
|
|
break;
|
2020-11-25 14:02:33 +02:00
|
|
|
case WP_PW_OBJECT_MIXIN_PROP_PROPERTIES:
|
2021-06-03 11:09:03 -04:00
|
|
|
g_value_take_boxed (value,
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (object)));
|
|
|
|
|
break;
|
2020-11-25 14:02:33 +02:00
|
|
|
case WP_PW_OBJECT_MIXIN_PROP_PARAM_INFO:
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
g_value_set_variant (value,
|
|
|
|
|
wp_pipewire_object_get_param_info (WP_PIPEWIRE_OBJECT (object)));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_class_override_properties (GObjectClass * klass)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
|
|
|
|
g_object_class_override_property (klass,
|
2020-11-25 14:02:33 +02:00
|
|
|
WP_PW_OBJECT_MIXIN_PROP_NATIVE_INFO, "native-info");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
g_object_class_override_property (klass,
|
2020-11-25 14:02:33 +02:00
|
|
|
WP_PW_OBJECT_MIXIN_PROP_PROPERTIES, "properties");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
g_object_class_override_property (klass,
|
2020-11-25 14:02:33 +02:00
|
|
|
WP_PW_OBJECT_MIXIN_PROP_PARAM_INFO, "param-info");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/****************/
|
|
|
|
|
/* FEATURES API */
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
static const struct {
|
|
|
|
|
WpObjectFeatures feature;
|
2020-11-25 14:02:33 +02:00
|
|
|
guint32 param_ids[2];
|
|
|
|
|
} params_features[] = {
|
|
|
|
|
{ WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, { SPA_PARAM_PropInfo, SPA_PARAM_Props } },
|
|
|
|
|
{ WP_PIPEWIRE_OBJECT_FEATURE_PARAM_FORMAT, { SPA_PARAM_EnumFormat, SPA_PARAM_Format } },
|
|
|
|
|
{ WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROFILE, { SPA_PARAM_EnumProfile, SPA_PARAM_Profile } },
|
|
|
|
|
{ WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PORT_CONFIG, { SPA_PARAM_EnumPortConfig, SPA_PARAM_PortConfig } },
|
|
|
|
|
{ WP_PIPEWIRE_OBJECT_FEATURE_PARAM_ROUTE, { SPA_PARAM_EnumRoute, SPA_PARAM_Route } },
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
static WpObjectFeatures
|
|
|
|
|
get_feature_for_param_id (guint32 param_id)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (params_features); i++) {
|
|
|
|
|
if (params_features[i].param_ids[0] == param_id ||
|
|
|
|
|
params_features[i].param_ids[1] == param_id)
|
|
|
|
|
return params_features[i].feature;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
WpObjectFeatures
|
|
|
|
|
wp_pw_object_mixin_get_supported_features (WpObject * object)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (object);
|
|
|
|
|
WpObjectFeatures ft =
|
|
|
|
|
WP_PROXY_FEATURE_BOUND | WP_PIPEWIRE_OBJECT_FEATURE_INFO;
|
|
|
|
|
|
|
|
|
|
if (d->info && iface->n_params_offset && iface->param_info_offset) {
|
|
|
|
|
struct spa_param_info * param_info =
|
|
|
|
|
G_STRUCT_MEMBER (struct spa_param_info *, d->info, iface->param_info_offset);
|
|
|
|
|
guint32 n_params =
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->n_params_offset);
|
|
|
|
|
|
|
|
|
|
for (guint i = 0; i < n_params; i++)
|
|
|
|
|
ft |= get_feature_for_param_id (param_info[i].id);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
return ft;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guint
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_activate_get_next_step (WpObject * object,
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
WpFeatureActivationTransition * transition, guint step,
|
|
|
|
|
WpObjectFeatures missing)
|
|
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object);
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
/* bind if not already bound */
|
2020-11-25 14:02:33 +02:00
|
|
|
if (missing & WP_PROXY_FEATURE_BOUND || !d->iface)
|
|
|
|
|
return WP_PW_OBJECT_MIXIN_STEP_BIND;
|
|
|
|
|
/* wait for info before proceeding, if necessary */
|
|
|
|
|
else if ((missing & WP_PIPEWIRE_OBJECT_FEATURES_ALL) && !d->info)
|
|
|
|
|
return WP_PW_OBJECT_MIXIN_STEP_WAIT_INFO;
|
|
|
|
|
/* then cache params */
|
|
|
|
|
else if (missing & WP_PIPEWIRE_OBJECT_FEATURES_ALL)
|
|
|
|
|
return WP_PW_OBJECT_MIXIN_STEP_CACHE_PARAMS;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
else
|
2020-11-25 14:02:33 +02:00
|
|
|
return WP_PW_OBJECT_MIXIN_STEP_CUSTOM_START;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
|
|
|
|
/* returning to STEP_NONE is handled by WpFeatureActivationTransition */
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
static void
|
|
|
|
|
enum_params_for_cache_done (GObject * object, GAsyncResult * res, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object);
|
|
|
|
|
guint32 param_id = GPOINTER_TO_UINT (data);
|
|
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
g_autoptr (GPtrArray) params = NULL;
|
2021-06-09 13:29:34 +03:00
|
|
|
const gchar *name = NULL;
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
params = g_task_propagate_pointer (G_TASK (res), &error);
|
|
|
|
|
if (error) {
|
2021-04-28 22:00:35 +03:00
|
|
|
wp_debug_object (object, "enum params failed: %s", error->message);
|
2020-11-25 14:02:33 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 13:29:34 +03:00
|
|
|
name = wp_spa_id_value_short_name (wp_spa_id_value_from_number (
|
|
|
|
|
"Spa:Enum:ParamId", param_id));
|
|
|
|
|
|
|
|
|
|
wp_debug_object (object, "cached params id:%u (%s), n_params:%u", param_id,
|
|
|
|
|
name, params->len);
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
wp_pw_object_mixin_store_param (d, param_id,
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_ARRAY |
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_CLEAR |
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_APPEND,
|
|
|
|
|
g_steal_pointer (¶ms));
|
|
|
|
|
|
2021-06-09 13:29:34 +03:00
|
|
|
g_signal_emit_by_name (object, "params-changed", name);
|
2020-11-25 14:02:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
G_DEFINE_QUARK (WpPwObjectMixinParamCacheActivatedFeatures, activated_features)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
param_cache_features_enabled (WpCore * core, GAsyncResult * res, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
WpObject *object = WP_OBJECT (data);
|
|
|
|
|
WpObjectFeatures activated = GPOINTER_TO_UINT (
|
|
|
|
|
g_object_get_qdata (G_OBJECT (object), activated_features_quark ()));
|
|
|
|
|
wp_object_update_features (object, activated, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
wp_pw_object_mixin_cache_params (WpObject * object, WpObjectFeatures missing)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (object);
|
|
|
|
|
g_autoptr (WpCore) core = wp_object_get_core (object);
|
|
|
|
|
struct spa_param_info * param_info;
|
|
|
|
|
WpObjectFeatures activated = 0;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (!(iface->flags & WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE));
|
|
|
|
|
|
2020-12-21 18:58:20 +02:00
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (params_features); i++) {
|
2020-11-25 14:02:33 +02:00
|
|
|
if (missing & params_features[i].feature) {
|
|
|
|
|
param_info = find_param_info (object, params_features[i].param_ids[0]);
|
|
|
|
|
if (param_info && param_info->flags & SPA_PARAM_INFO_READ) {
|
|
|
|
|
wp_pw_object_mixin_enum_params_unchecked (object,
|
|
|
|
|
param_info->id, NULL, NULL, enum_params_for_cache_done,
|
|
|
|
|
GUINT_TO_POINTER (param_info->id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
param_info = find_param_info (object, params_features[i].param_ids[1]);
|
|
|
|
|
if (param_info && param_info->flags & SPA_PARAM_INFO_READ) {
|
|
|
|
|
wp_pw_object_mixin_enum_params_unchecked (object,
|
|
|
|
|
param_info->id, NULL, NULL, enum_params_for_cache_done,
|
|
|
|
|
GUINT_TO_POINTER (param_info->id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
activated |= params_features[i].feature;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_set_qdata (G_OBJECT (object),
|
|
|
|
|
activated_features_quark (), GUINT_TO_POINTER (activated));
|
|
|
|
|
wp_core_sync (core, NULL,
|
|
|
|
|
(GAsyncReadyCallback) param_cache_features_enabled, object);
|
|
|
|
|
}
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_deactivate (WpObject * object, WpObjectFeatures features)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (object);
|
|
|
|
|
|
|
|
|
|
/* deactivate param caching */
|
|
|
|
|
if (!(iface->flags & WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE)) {
|
2020-12-21 18:58:20 +02:00
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (params_features); i++) {
|
2020-11-25 14:02:33 +02:00
|
|
|
if (features & params_features[i].feature) {
|
|
|
|
|
wp_pw_object_mixin_store_param (d, params_features[i].param_ids[0],
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE, NULL);
|
|
|
|
|
wp_pw_object_mixin_store_param (d, params_features[i].param_ids[1],
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE, NULL);
|
|
|
|
|
wp_object_update_features (object, 0, params_features[i].feature);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/************************/
|
|
|
|
|
/* PROXY EVENT HANDLERS */
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_handle_pw_proxy_destroyed (WpProxy * proxy)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (proxy);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (proxy);
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&d->properties, wp_properties_unref);
|
|
|
|
|
g_clear_pointer (&d->info, iface->free_info);
|
|
|
|
|
d->iface = NULL;
|
|
|
|
|
|
|
|
|
|
/* deactivate param caching */
|
|
|
|
|
if (!(iface->flags & WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE)) {
|
2020-12-21 18:58:20 +02:00
|
|
|
for (guint i = 0; i < G_N_ELEMENTS (params_features); i++) {
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_store_param (d, params_features[i].param_ids[0],
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE, NULL);
|
|
|
|
|
wp_pw_object_mixin_store_param (d, params_features[i].param_ids[1],
|
|
|
|
|
WP_PW_OBJECT_MIXIN_STORE_PARAM_REMOVE, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* cancel enum_params tasks */
|
|
|
|
|
{
|
|
|
|
|
GList *link;
|
|
|
|
|
for (link = g_list_first (d->enum_params_tasks);
|
|
|
|
|
link; link = g_list_first (d->enum_params_tasks)) {
|
2021-05-24 12:06:38 -04:00
|
|
|
GTask *task = G_TASK (link->data);
|
|
|
|
|
d->enum_params_tasks = g_list_delete_link (d->enum_params_tasks, link);
|
|
|
|
|
g_task_return_new_error (task,
|
2020-11-25 14:02:33 +02:00
|
|
|
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
|
|
|
|
"pipewire proxy destroyed before finishing");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wp_object_update_features (WP_OBJECT (proxy), 0,
|
|
|
|
|
WP_PIPEWIRE_OBJECT_FEATURES_ALL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***************************/
|
|
|
|
|
/* PIPEWIRE EVENT HANDLERS */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
wp_pw_object_mixin_handle_event_info (gpointer instance, gconstpointer update)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
guint32 change_mask =
|
|
|
|
|
G_STRUCT_MEMBER (guint32, update, iface->change_mask_offset);
|
|
|
|
|
guint32 process_info_change_mask =
|
|
|
|
|
change_mask & ~(iface->CHANGE_MASK_PROPS | iface->CHANGE_MASK_PARAMS);
|
|
|
|
|
gpointer old_info = NULL;
|
|
|
|
|
|
|
|
|
|
wp_debug_object (instance, "info, change_mask:0x%x [%s%s]", change_mask,
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_PROPS) ? "props," : "",
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_PARAMS) ? "params," : "");
|
|
|
|
|
|
|
|
|
|
/* make a copy of d->info for process_info() */
|
|
|
|
|
if (iface->process_info && d->info && process_info_change_mask) {
|
|
|
|
|
/* copy everything that changed except props and params, for efficiency;
|
|
|
|
|
process_info() is only interested in variables that are not PROPS & PARAMS */
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) =
|
|
|
|
|
process_info_change_mask;
|
|
|
|
|
old_info = iface->update_info (NULL, d->info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* update params */
|
|
|
|
|
if (!(iface->flags & WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE) &&
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_PARAMS) && d->info) {
|
|
|
|
|
struct spa_param_info * old_param_info =
|
|
|
|
|
G_STRUCT_MEMBER (struct spa_param_info *, d->info, iface->param_info_offset);
|
|
|
|
|
struct spa_param_info * param_info =
|
|
|
|
|
G_STRUCT_MEMBER (struct spa_param_info *, update, iface->param_info_offset);
|
|
|
|
|
guint32 old_n_params =
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->n_params_offset);
|
|
|
|
|
guint32 n_params =
|
|
|
|
|
G_STRUCT_MEMBER (guint32, update, iface->n_params_offset);
|
|
|
|
|
WpObjectFeatures active_ft =
|
|
|
|
|
wp_object_get_active_features (WP_OBJECT (instance));
|
|
|
|
|
|
|
|
|
|
for (guint i = 0; i < n_params; i++) {
|
|
|
|
|
/* param changes when flags change */
|
|
|
|
|
if (i >= old_n_params || old_param_info[i].flags != param_info[i].flags) {
|
|
|
|
|
/* update cached params if the relevant feature is active */
|
|
|
|
|
if (active_ft & get_feature_for_param_id (param_info[i].id) &&
|
|
|
|
|
param_info[i].flags & SPA_PARAM_INFO_READ)
|
|
|
|
|
{
|
|
|
|
|
wp_pw_object_mixin_enum_params_unchecked (instance,
|
|
|
|
|
param_info[i].id, NULL, NULL, enum_params_for_cache_done,
|
|
|
|
|
GUINT_TO_POINTER (param_info[i].id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* update our info struct */
|
|
|
|
|
d->info = iface->update_info (d->info, update);
|
|
|
|
|
wp_object_update_features (WP_OBJECT (instance),
|
|
|
|
|
WP_PIPEWIRE_OBJECT_FEATURE_INFO, 0);
|
|
|
|
|
|
|
|
|
|
/* update properties */
|
|
|
|
|
if (change_mask & iface->CHANGE_MASK_PROPS) {
|
|
|
|
|
const struct spa_dict * props =
|
|
|
|
|
G_STRUCT_MEMBER (const struct spa_dict *, d->info, iface->props_offset);
|
|
|
|
|
|
|
|
|
|
g_clear_pointer (&d->properties, wp_properties_unref);
|
|
|
|
|
d->properties = wp_properties_new_wrap_dict (props);
|
|
|
|
|
|
|
|
|
|
g_object_notify (G_OBJECT (instance), "properties");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (change_mask & iface->CHANGE_MASK_PARAMS)
|
|
|
|
|
g_object_notify (G_OBJECT (instance), "param-info");
|
|
|
|
|
|
|
|
|
|
/* custom handling, if required */
|
|
|
|
|
if (iface->process_info && process_info_change_mask) {
|
|
|
|
|
iface->process_info (instance, old_info, d->info);
|
|
|
|
|
g_clear_pointer (&old_info, iface->free_info);
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gint
|
|
|
|
|
task_has_seq (gconstpointer task, gconstpointer seq)
|
|
|
|
|
{
|
|
|
|
|
gpointer t_seq = g_task_get_source_tag (G_TASK (task));
|
|
|
|
|
return (GPOINTER_TO_INT (t_seq) == GPOINTER_TO_INT (seq)) ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_handle_event_param (gpointer instance, int seq,
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param)
|
|
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
g_autoptr (WpSpaPod) w_param = wp_spa_pod_new_wrap_const (param);
|
|
|
|
|
GList *list;
|
|
|
|
|
GTask *task;
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
list = g_list_find_custom (d->enum_params_tasks, GINT_TO_POINTER (seq),
|
|
|
|
|
task_has_seq);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
task = list ? G_TASK (list->data) : NULL;
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_trace_boxed (WP_TYPE_SPA_POD, w_param,
|
|
|
|
|
WP_OBJECT_FORMAT " param id:%u, index:%u",
|
|
|
|
|
WP_OBJECT_ARGS (instance), id, index);
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
if (task) {
|
|
|
|
|
GPtrArray *array = g_task_get_task_data (task);
|
|
|
|
|
g_ptr_array_add (array, wp_spa_pod_copy (w_param));
|
2020-11-25 14:02:33 +02:00
|
|
|
} else {
|
|
|
|
|
/* this should never happen */
|
|
|
|
|
wp_warning_object (instance,
|
|
|
|
|
"param event was received without calling enum_params");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/***********************************/
|
|
|
|
|
/* PIPEWIRE METHOD IMPLEMENTATIONS */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
wp_pw_object_mixin_impl_add_listener (gpointer instance,
|
|
|
|
|
struct spa_hook *listener, gconstpointer events, gpointer data)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
struct spa_hook_list save;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
spa_hook_list_isolate (&d->hooks, &save, listener, events, data);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) = iface->CHANGE_MASK_ALL;
|
|
|
|
|
iface->emit_info (&d->hooks, d->info);
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) = 0;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
spa_hook_list_join (&d->hooks, &save);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
int
|
|
|
|
|
wp_pw_object_mixin_impl_enum_params (gpointer instance, int seq,
|
|
|
|
|
guint32 id, guint32 start, guint32 num, const struct spa_pod *filter)
|
|
|
|
|
{
|
|
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
g_autoptr (GPtrArray) params = NULL;
|
|
|
|
|
g_autoptr (WpSpaPod) filter_pod = NULL;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (!iface->enum_params_sync)
|
|
|
|
|
return -ENOTSUP;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
struct spa_param_info * info = find_param_info (instance, id);
|
|
|
|
|
if (!info || !(info->flags & SPA_PARAM_INFO_READ))
|
|
|
|
|
return -EINVAL;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
filter_pod = filter ? wp_spa_pod_new_wrap_const (filter) : NULL;
|
|
|
|
|
params = iface->enum_params_sync (instance, id, start, num, filter_pod);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (params) {
|
|
|
|
|
for (guint i = 0; i < params->len; i++) {
|
|
|
|
|
WpSpaPod *pod = g_ptr_array_index (params, i);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_trace_boxed (WP_TYPE_SPA_POD, pod,
|
|
|
|
|
WP_OBJECT_FORMAT " emit param id:%u, index:%u",
|
|
|
|
|
WP_OBJECT_ARGS (instance), id, start+i);
|
|
|
|
|
|
|
|
|
|
iface->emit_param (&d->hooks, seq, id, start+i, start+i+1,
|
|
|
|
|
wp_spa_pod_get_spa_pod (pod));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
int
|
|
|
|
|
wp_pw_object_mixin_impl_subscribe_params (gpointer instance,
|
|
|
|
|
guint32 *ids, guint32 n_ids)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
|
|
|
|
|
if (!iface->enum_params_sync)
|
|
|
|
|
return -ENOTSUP;
|
|
|
|
|
|
|
|
|
|
for (guint i = 0; i < n_ids; i++)
|
|
|
|
|
wp_pw_object_mixin_impl_enum_params (instance, 1, ids[i], 0, -1, NULL);
|
|
|
|
|
|
|
|
|
|
if (!d->subscribed_ids)
|
|
|
|
|
d->subscribed_ids = g_array_new (FALSE, FALSE, sizeof (guint32));
|
|
|
|
|
|
|
|
|
|
/* FIXME: deduplicate stored ids */
|
|
|
|
|
g_array_append_vals (d->subscribed_ids, ids, n_ids);
|
|
|
|
|
return 0;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
int
|
|
|
|
|
wp_pw_object_mixin_impl_set_param (gpointer instance, guint32 id,
|
|
|
|
|
guint32 flags, const struct spa_pod *param)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
|
|
|
|
|
if (!iface->set_param)
|
|
|
|
|
return -ENOTSUP;
|
|
|
|
|
|
|
|
|
|
struct spa_param_info * info = find_param_info (instance, id);
|
|
|
|
|
if (!info || !(info->flags & SPA_PARAM_INFO_WRITE))
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
WpSpaPod *param_pod = wp_spa_pod_new_wrap_const (param);
|
|
|
|
|
|
|
|
|
|
wp_trace_boxed (WP_TYPE_SPA_POD, param_pod,
|
|
|
|
|
WP_OBJECT_FORMAT " set_param id:%u flags:0x%x",
|
|
|
|
|
WP_OBJECT_ARGS (instance), id, flags);
|
|
|
|
|
|
|
|
|
|
return iface->set_param (instance, id, flags, param_pod);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/**********************/
|
|
|
|
|
/* NOTIFIERS */
|
|
|
|
|
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_notify_info (gpointer instance, guint32 change_mask)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_debug_object (instance, "notify info, change_mask:0x%x [%s%s]",
|
|
|
|
|
change_mask,
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_PROPS) ? "props," : "",
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_PARAMS) ? "params," : "");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) =
|
|
|
|
|
(change_mask & iface->CHANGE_MASK_ALL);
|
|
|
|
|
iface->emit_info (&d->hooks, d->info);
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) = 0;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (change_mask & iface->CHANGE_MASK_PROPS)
|
|
|
|
|
g_object_notify (G_OBJECT (instance), "properties");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (change_mask & iface->CHANGE_MASK_PARAMS)
|
|
|
|
|
g_object_notify (G_OBJECT (instance), "param-info");
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-11-25 14:02:33 +02:00
|
|
|
wp_pw_object_mixin_notify_params_changed (gpointer instance, guint32 id)
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
{
|
2020-11-25 14:02:33 +02:00
|
|
|
WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance);
|
|
|
|
|
WpPwObjectMixinPrivInterface *iface =
|
|
|
|
|
WP_PW_OBJECT_MIXIN_PRIV_GET_IFACE (instance);
|
|
|
|
|
gboolean subscribed = FALSE;
|
2021-06-09 13:29:34 +03:00
|
|
|
const gchar *name = NULL;
|
2020-11-25 14:02:33 +02:00
|
|
|
|
|
|
|
|
struct spa_param_info * info = find_param_info (instance, id);
|
|
|
|
|
g_return_if_fail (info);
|
|
|
|
|
|
|
|
|
|
if (d->subscribed_ids) {
|
|
|
|
|
for (guint i = 0; i < d->subscribed_ids->len; i++) {
|
|
|
|
|
if (g_array_index (d->subscribed_ids, guint32, i) == id) {
|
|
|
|
|
subscribed = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2021-06-09 13:29:34 +03:00
|
|
|
name = wp_spa_id_value_short_name (wp_spa_id_value_from_number (
|
2021-01-13 20:11:41 +02:00
|
|
|
"Spa:Enum:ParamId", id));
|
2021-06-09 13:29:34 +03:00
|
|
|
|
|
|
|
|
wp_debug_object (instance, "notify param id:%u (%s)", id, name);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
/* toggle the serial flag; this notifies that there is a data change */
|
|
|
|
|
info->flags ^= SPA_PARAM_INFO_SERIAL;
|
|
|
|
|
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) =
|
|
|
|
|
iface->CHANGE_MASK_PARAMS;
|
|
|
|
|
iface->emit_info (&d->hooks, d->info);
|
|
|
|
|
G_STRUCT_MEMBER (guint32, d->info, iface->change_mask_offset) = 0;
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
|
2020-11-25 14:02:33 +02:00
|
|
|
if (subscribed)
|
|
|
|
|
wp_pw_object_mixin_impl_enum_params (instance, 1, id, 0, -1, NULL);
|
2021-06-09 13:29:34 +03:00
|
|
|
|
|
|
|
|
g_signal_emit_by_name (instance, "params-changed", name);
|
lib: refactor WpProxy
This is an attempt to unclutter the API of WpProxy and
split functionality into smaller pieces, making it easier
to work with.
In this new class layout, we have the following classes:
- WpObject: base class for everything; handles activating
| and deactivating "features"
|- WpProxy: base class for anything that wraps a pw_proxy;
| handles events from pw_proxy and nothing more
|- WpGlobalProxy: handles integration with the registry
All the other classes derive from WpGlobalProxy. The reason
for separating WpGlobalProxy from WpProxy, though, is that
classes such as WpImplNode / WpSpaDevice can also derive from
WpProxy now, without interfacing with the registry.
All objects that come with an "info" structure and have properties
and/or params also implement the WpPipewireObject interface. This
provides the API to query properties and get/set params. Essentially,
this is implemented by all classes except WpMetadata (pw_metadata
does not have info)
This interface is implemented on each object separately, using
a private "mixin", which is a set of vfunc implementations and helper
functions (and macros) to facilitate the implementation of this interface.
A notable difference to the old WpProxy is that now features can be
deactivated, so it is possible to enable something and later disable
it again.
This commit disables modules, tests, tools, etc, to avoid growing the
patch more, while ensuring that the project compiles.
2020-11-10 19:17:02 +02:00
|
|
|
}
|