m-default-nodes-api: add API to get and set default configured node name

This commit is contained in:
Julian Bouzas
2022-01-21 10:37:02 -05:00
committed by George Kiagiadakis
parent 10531e95b5
commit 95e7c4abe8
3 changed files with 90 additions and 32 deletions

View File

@@ -10,16 +10,25 @@
#include <pipewire/keys.h> #include <pipewire/keys.h>
#include "module-default-nodes/common.h" #include "module-default-nodes/common.h"
typedef struct _WpDefaultNode WpDefaultNode;
struct _WpDefaultNode
{
gchar *value;
gchar *config_value;
};
struct _WpDefaultNodesApi struct _WpDefaultNodesApi
{ {
WpPlugin parent; WpPlugin parent;
gchar *defaults[N_DEFAULT_NODES]; WpDefaultNode defaults[N_DEFAULT_NODES];
WpObjectManager *om; WpObjectManager *om;
}; };
enum { enum {
ACTION_GET_DEFAULT_NODE, ACTION_GET_DEFAULT_NODE,
ACTION_GET_DEFAULT_CONFIGURED_NODE_NAME,
ACTION_SET_DEFAULT_CONFIGURED_NODE_NAME,
SIGNAL_CHANGED, SIGNAL_CHANGED,
N_SIGNALS N_SIGNALS
}; };
@@ -63,31 +72,33 @@ on_metadata_changed (WpMetadata *m, guint32 subject,
const gchar *key, const gchar *type, const gchar *value, gpointer d) const gchar *key, const gchar *type, const gchar *value, gpointer d)
{ {
WpDefaultNodesApi * self = WP_DEFAULT_NODES_API (d); WpDefaultNodesApi * self = WP_DEFAULT_NODES_API (d);
gint node_t = -1;
gchar name[1024];
if (subject == 0) { if (subject != 0)
for (gint i = 0; i < N_DEFAULT_NODES; i++) { return;
if (!g_strcmp0 (key, DEFAULT_KEY[i])) {
node_t = i; for (gint i = 0; i < N_DEFAULT_NODES; i++) {
break; gchar name[1024];
} if (!g_strcmp0 (key, DEFAULT_KEY[i])) {
g_clear_pointer (&self->defaults[i].value, g_free);
if (value && !g_strcmp0 (type, "Spa:String:JSON") &&
json_object_find (value, "name", name, sizeof(name)) == 0)
self->defaults[i].value = g_strdup (name);
wp_debug_object (m, "changed '%s' -> '%s'", key,
self->defaults[i].value);
schedule_changed_notification (self);
break;
} else if (!g_strcmp0 (key, DEFAULT_CONFIG_KEY[i])) {
g_clear_pointer (&self->defaults[i].config_value, g_free);
if (value && !g_strcmp0 (type, "Spa:String:JSON") &&
json_object_find (value, "name", name, sizeof(name)) == 0)
self->defaults[i].config_value = g_strdup (name);
wp_debug_object (m, "changed '%s' -> '%s'", key,
self->defaults[i].config_value);
} }
} }
if (node_t != -1) {
g_clear_pointer (&self->defaults[node_t], g_free);
if (value && !g_strcmp0 (type, "Spa:String:JSON") &&
json_object_find (value, "name", name, sizeof(name)) == 0)
{
self->defaults[node_t] = g_strdup (name);
}
wp_debug_object (m, "changed '%s' -> '%s'", key, self->defaults[node_t]);
schedule_changed_notification (self);
}
} }
static void static void
@@ -144,8 +155,10 @@ wp_default_nodes_api_disable (WpPlugin * plugin)
{ {
WpDefaultNodesApi * self = WP_DEFAULT_NODES_API (plugin); WpDefaultNodesApi * self = WP_DEFAULT_NODES_API (plugin);
for (guint i = 0; i < N_DEFAULT_NODES; i++) for (guint i = 0; i < N_DEFAULT_NODES; i++) {
g_clear_pointer (&self->defaults[i], g_free); g_clear_pointer (&self->defaults[i].value, g_free);
g_clear_pointer (&self->defaults[i].config_value, g_free);
}
g_clear_object (&self->om); g_clear_object (&self->om);
} }
@@ -161,13 +174,13 @@ wp_default_nodes_api_get_default_node (WpDefaultNodesApi * self,
} }
} }
if (node_t != -1 && self->defaults[node_t]) { if (node_t != -1 && self->defaults[node_t].value) {
g_autoptr (WpIterator) it = NULL; g_autoptr (WpIterator) it = NULL;
g_auto (GValue) val = G_VALUE_INIT; g_auto (GValue) val = G_VALUE_INIT;
it = wp_object_manager_new_filtered_iterator (self->om, it = wp_object_manager_new_filtered_iterator (self->om,
WP_TYPE_NODE, WP_TYPE_NODE,
WP_CONSTRAINT_TYPE_PW_PROPERTY, WP_CONSTRAINT_TYPE_PW_PROPERTY,
PW_KEY_NODE_NAME, "=s", self->defaults[node_t], PW_KEY_NODE_NAME, "=s", self->defaults[node_t].value,
NULL); NULL);
for (; wp_iterator_next (it, &val); g_value_unset (&val)) { for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
WpNode *node = g_value_get_object (&val); WpNode *node = g_value_get_object (&val);
@@ -180,6 +193,42 @@ wp_default_nodes_api_get_default_node (WpDefaultNodesApi * self,
return SPA_ID_INVALID; return SPA_ID_INVALID;
} }
static gchar *
wp_default_nodes_api_get_default_configured_node_name (WpDefaultNodesApi * self,
const gchar * media_class)
{
for (gint i = 0; i < N_DEFAULT_NODES; i++)
if (!g_strcmp0 (media_class, NODE_TYPE_STR[i]) &&
self->defaults[i].config_value)
return g_strdup (self->defaults[i].config_value);
return NULL;
}
static gboolean
wp_default_nodes_api_set_default_configured_node_name (WpDefaultNodesApi * self,
const gchar * media_class, const gchar * name)
{
g_autoptr (WpMetadata) m = wp_object_manager_lookup (self->om,
WP_TYPE_METADATA, NULL);
if (!m)
return FALSE;
for (gint i = 0; i < N_DEFAULT_NODES; i++) {
if (!g_strcmp0 (media_class, NODE_TYPE_STR[i])) {
if (name) {
g_autofree gchar *v = g_strdup_printf ("{ \"name\": \"%s\" }", name);
wp_metadata_set (m, 0, DEFAULT_CONFIG_KEY[i], "Spa:String:JSON", v);
} else {
wp_metadata_set (m, 0, DEFAULT_CONFIG_KEY[i], NULL, NULL);
}
return TRUE;
}
}
return FALSE;
}
static void static void
wp_default_nodes_api_class_init (WpDefaultNodesApiClass * klass) wp_default_nodes_api_class_init (WpDefaultNodesApiClass * klass)
{ {
@@ -195,6 +244,20 @@ wp_default_nodes_api_class_init (WpDefaultNodesApiClass * klass)
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_UINT, 1, G_TYPE_STRING); G_TYPE_UINT, 1, G_TYPE_STRING);
signals[ACTION_GET_DEFAULT_CONFIGURED_NODE_NAME] = g_signal_new_class_handler (
"get-default-configured-node-name", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
(GCallback) wp_default_nodes_api_get_default_configured_node_name,
NULL, NULL, NULL,
G_TYPE_STRING, 1, G_TYPE_STRING);
signals[ACTION_SET_DEFAULT_CONFIGURED_NODE_NAME] = g_signal_new_class_handler (
"set-default-configured-node-name", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
(GCallback) wp_default_nodes_api_set_default_configured_node_name,
NULL, NULL, NULL,
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_STRING);
signals[SIGNAL_CHANGED] = g_signal_new ( signals[SIGNAL_CHANGED] = g_signal_new (
"changed", G_TYPE_FROM_CLASS (klass), "changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);

View File

@@ -11,7 +11,6 @@
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <pipewire/keys.h> #include <pipewire/keys.h>
#define COMPILING_MODULE_DEFAULT_NODES 1
#include "module-default-nodes/common.h" #include "module-default-nodes/common.h"
#define NAME "default-nodes" #define NAME "default-nodes"

View File

@@ -29,16 +29,12 @@ static const gchar * NODE_TYPE_STR[N_DEFAULT_NODES] = {
[VIDEO_SOURCE] = "Video/Source", [VIDEO_SOURCE] = "Video/Source",
}; };
#if COMPILING_MODULE_DEFAULT_NODES
static const gchar * DEFAULT_CONFIG_KEY[N_DEFAULT_NODES] = { static const gchar * DEFAULT_CONFIG_KEY[N_DEFAULT_NODES] = {
[AUDIO_SINK] = "default.configured.audio.sink", [AUDIO_SINK] = "default.configured.audio.sink",
[AUDIO_SOURCE] = "default.configured.audio.source", [AUDIO_SOURCE] = "default.configured.audio.source",
[VIDEO_SOURCE] = "default.configured.video.source", [VIDEO_SOURCE] = "default.configured.video.source",
}; };
#endif
static int static int
json_object_find (const char *obj, const char *key, char *value, size_t len) json_object_find (const char *obj, const char *key, char *value, size_t len)
{ {