From f01177d08a0a702f92ef384def53612fa116f4d8 Mon Sep 17 00:00:00 2001 From: Ferdinand Bachmann Date: Mon, 25 Dec 2023 23:06:32 +0100 Subject: [PATCH] wpctl: add set-route subcommand --- src/tools/wpctl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/tools/wpctl.c b/src/tools/wpctl.c index db5a0fd8..b798c1e7 100644 --- a/src/tools/wpctl.c +++ b/src/tools/wpctl.c @@ -68,6 +68,12 @@ static struct { gint index; } set_profile; + struct { + guint64 id; + gint index; + gint device; + } set_route; + struct { guint64 id; } clear_default; @@ -1193,6 +1199,64 @@ out: g_main_loop_quit (self->loop); } +/* set-route */ + +static gboolean +set_route_parse_positional (gint argc, gchar ** argv, GError **error) +{ + if (argc < 5) { + g_set_error (error, wpctl_error_domain_quark(), 0, + "ID, INDEX and DEVICE are required"); + return FALSE; + } + + cmdline.set_route.index = atoi (argv[3]); + cmdline.set_route.device = atoi (argv[4]); + return parse_id (true, true, argv[2], &cmdline.set_route.id, error); +} + +static gboolean +set_route_prepare (WpCtl * self, GError ** error) +{ + wp_object_manager_add_interest (self->om, WP_TYPE_GLOBAL_PROXY, NULL); + wp_object_manager_request_object_features (self->om, WP_TYPE_GLOBAL_PROXY, + WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL); + return TRUE; +} + +static void +set_route_run (WpCtl * self) +{ + g_autoptr (WpPlugin) def_nodes_api = wp_plugin_find (self->core, "default-nodes-api"); + g_autoptr (WpPipewireObject) proxy = NULL; + g_autoptr (GError) error = NULL; + guint32 node_id; + + if (!translate_id (def_nodes_api, cmdline.set_route.id, &node_id, &error)) { + fprintf(stderr, "Translate ID error: %s\n\n", error->message); + goto out; + } + + proxy = wp_object_manager_lookup (self->om, WP_TYPE_GLOBAL_PROXY, + WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", node_id, NULL); + if (!proxy) { + fprintf (stderr, "Object '%d' not found\n", node_id); + goto out; + } + wp_pipewire_object_set_param (proxy, "Route", 0, + wp_spa_pod_new_object ( + "Spa:Pod:Object:Param:Route", "Route", + "index", "i", cmdline.set_route.index, + "device", "i", cmdline.set_route.device, + NULL)); + wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self); + return; + +out: + self->exit_code = 3; + g_main_loop_quit (self->loop); +} + /* clear-default */ static gboolean @@ -1385,6 +1449,16 @@ static const struct subcommand { .prepare = set_profile_prepare, .run = set_profile_run, }, + { + .name = "set-route", + .positional_args = "ID INDEX DEVICE", + .summary = "Sets the route of ID to INDEX (integer, 0 is 'off'), DEVICE (integer, card.profile.device)", + .description = NULL, + .entries = { { NULL } }, + .parse_positional = set_route_parse_positional, + .prepare = set_route_prepare, + .run = set_route_run, + }, { .name = "clear-default", .positional_args = "[ID]",