From b703c01d4cf9e68cd26fd59e236b33fa06823a1e Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Tue, 6 Feb 2024 10:55:52 -0500 Subject: [PATCH] wpctl: show persistent settings and add sub-command to clear them --- src/tools/wpctl.c | 91 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/src/tools/wpctl.c b/src/tools/wpctl.c index a04f25b7..13abe5db 100644 --- a/src/tools/wpctl.c +++ b/src/tools/wpctl.c @@ -80,6 +80,10 @@ static struct { guint64 id; } clear_default; + struct { + const gchar *key; + } clear_persistent; + struct { guint64 id; const char *level; @@ -212,6 +216,7 @@ status_prepare (WpCtl * self, GError ** error) wp_object_manager_add_interest (self->om, WP_TYPE_LINK, NULL); wp_object_manager_request_object_features (self->om, WP_TYPE_GLOBAL_PROXY, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL); + wp_object_manager_add_interest (self->om, WP_TYPE_METADATA, NULL); return TRUE; } @@ -301,7 +306,7 @@ print_filter_node (const GValue *item, gpointer data) return; /* Print all nodes for this link_group */ - printf (TREE_INDENT_LINE " - %-60s\n", link_group); + printf (TREE_INDENT_LINE " - %-60s\n", link_group); it = wp_object_manager_new_filtered_iterator (context->self->om, WP_TYPE_NODE, WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_NODE_LINK_GROUP, "=s", link_group, @@ -320,7 +325,7 @@ print_filter_node (const GValue *item, gpointer data) name = wp_pipewire_object_get_property (node, PW_KEY_NODE_DESCRIPTION); media_class = wp_pipewire_object_get_property (node, PW_KEY_MEDIA_CLASS); - printf (TREE_INDENT_LINE "%c %4u. %-60s [%s]\n", + printf (TREE_INDENT_LINE "%c %4u. %-60s [%s]\n", context->default_node == id ? '*' : ' ', id, name, media_class); } g_clear_pointer (&it, wp_iterator_unref); @@ -388,6 +393,7 @@ status_run (WpCtl * self) g_autoptr (WpIterator) it = NULL; g_auto (GValue) val = G_VALUE_INIT; g_autoptr (WpPlugin) def_nodes_api = NULL; + g_autoptr (WpMetadata) persistent_settings = NULL; struct print_context context = { .self = self }; def_nodes_api = wp_plugin_find (self->core, "default-nodes-api"); @@ -509,8 +515,25 @@ status_run (WpCtl * self) /* Settings */ printf ("Settings\n"); + persistent_settings = wp_object_manager_lookup (self->om, WP_TYPE_METADATA, + WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, + "metadata.name", "=s", "persistent-sm-settings", + NULL); + printf (TREE_INDENT_NODE "Persistent:\n"); + if (persistent_settings) { + it = wp_metadata_new_iterator (persistent_settings, 0); + for (; wp_iterator_next (it, &val); g_value_unset (&val)) { + const gchar *key, *value; + wp_metadata_iterator_item_extract (&val, NULL, &key, NULL, &value); + printf (TREE_INDENT_LINE " - %s: %s\n", key, value); + } + g_clear_pointer (&it, wp_iterator_unref); + } + + printf (TREE_INDENT_LINE "\n"); + + printf (TREE_INDENT_END "Default Configured Devices:\n"); if (def_nodes_api) { - printf (TREE_INDENT_END "Default Configured Node Names:\n"); for (guint i = 0; i < G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES); i++) { const gchar *name = NULL; g_signal_emit_by_name (def_nodes_api, "get-default-configured-node-name", @@ -1308,7 +1331,6 @@ static void clear_default_run (WpCtl * self) { g_autoptr (WpPlugin) def_nodes_api = NULL; - g_autoptr (GError) error = NULL; gboolean res = FALSE; def_nodes_api = wp_plugin_find (self->core, "default-nodes-api"); @@ -1346,6 +1368,57 @@ out: g_main_loop_quit (self->loop); } +/* clear-persistent */ + +static gboolean +clear_persistent_parse_positional (gint argc, gchar ** argv, GError **error) +{ + if (argc >= 3) + cmdline.clear_persistent.key = argv[2]; + else + cmdline.clear_persistent.key = NULL; + + return TRUE; +} + +static gboolean +clear_persistent_prepare (WpCtl * self, GError ** error) +{ + wp_object_manager_add_interest (self->om, WP_TYPE_METADATA, NULL); + wp_object_manager_request_object_features (self->om, WP_TYPE_METADATA, + WP_OBJECT_FEATURES_ALL); + return TRUE; +} + +static void +clear_persistent_run (WpCtl * self) +{ + g_autoptr (WpMetadata) persistent_settings = NULL; + + persistent_settings = wp_object_manager_lookup (self->om, WP_TYPE_METADATA, + WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, + "metadata.name", "=s", "persistent-sm-settings", + NULL); + if (!persistent_settings) { + fprintf (stderr, "Persistent settings metadata not found\n"); + goto out; + } + + if (cmdline.clear_persistent.key) + wp_metadata_set (persistent_settings, 0, cmdline.clear_persistent.key, NULL, + NULL); + else + wp_metadata_clear (persistent_settings); + + + wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self); + return; + +out: + self->exit_code = 3; + g_main_loop_quit (self->loop); +} + /* set-log-level */ static gboolean @@ -1573,6 +1646,16 @@ static const struct subcommand { .prepare = clear_default_prepare, .run = clear_default_run, }, + { + .name = "clear-persistent", + .positional_args = "[KEY]", + .summary = "Clears the persistent setting (no KEY means 'all')", + .description = NULL, + .entries = { { NULL } }, + .parse_positional = clear_persistent_parse_positional, + .prepare = clear_persistent_prepare, + .run = clear_persistent_run, + }, { .name = "set-log-level", .positional_args = "[ID] LEVEL",