aboutsummaryrefslogtreecommitdiff
path: root/pkgs/patches/0002-wpctl-allow-modifying-volume-levels-using-percentage.patch
blob: 9e51797098b7e9c4d98bd5408758171758592810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
From 43d8753c5ef4cbd4d2f6558182b290d083644521 Mon Sep 17 00:00:00 2001
From: Varnit Singh <varnitcls@gmail.com>
Date: Wed, 8 Jun 2022 09:25:45 +0000
Subject: [PATCH 2/2] wpctl: allow modifying volume levels using
 percentage/step amount.

---
 src/tools/wpctl.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/tools/wpctl.c b/src/tools/wpctl.c
index 9f7c6bb..0f5bc8c 100644
--- a/src/tools/wpctl.c
+++ b/src/tools/wpctl.c
@@ -45,6 +45,7 @@ static struct {
       guint64 id;
       gfloat volume;
       gboolean is_pid;
+      gchar type;
     } set_volume;
 
     struct {
@@ -846,11 +847,38 @@ set_volume_parse_positional (gint argc, gchar ** argv, GError **error)
 {
   if (argc < 4) {
     g_set_error (error, wpctl_error_domain_quark(), 0,
-        "ID and VOL are required");
+        "ID and VOL[%%][-/+] are required");
+    return FALSE;
+  }
+
+  GRegex *regex = g_regex_new ("^(\\d*\\.?\\d*)(%?)([-+]?)$", 0, 0, NULL);
+  GMatchInfo *info = NULL;
+
+  if (g_regex_match(regex, argv[3], 0, &info)) {
+    cmdline.set_volume.volume = strtof(g_match_info_fetch(info, 1), NULL);
+    cmdline.set_volume.type = 'a';
+    
+    if (g_strcmp0(g_match_info_fetch(info, 2), "%") == 0) {
+      cmdline.set_volume.type = 'p';
+    }
+
+    if (g_strcmp0(g_match_info_fetch(info, 3), "-") == 0) {
+      cmdline.set_volume.volume = -(cmdline.set_volume.volume);
+      if (cmdline.set_volume.type != 'p') {
+        cmdline.set_volume.type = 's';
+      }
+    } else if (g_strcmp0(g_match_info_fetch(info, 3), "+") == 0 && cmdline.set_volume.type != 'p') {
+      cmdline.set_volume.type = 's';
+    }
+    g_match_info_free (info);
+    g_regex_unref (regex);
+  } else {
+    g_regex_unref (regex);
+    g_set_error (error, wpctl_error_domain_quark(), 0,
+        "Invalid volume argument. See wpctl set-volume --help");
     return FALSE;
   }
 
-  cmdline.set_volume.volume = strtof (argv[3], NULL);
   return parse_id (!cmdline.set_volume.is_pid, false, argv[2],
       &cmdline.set_volume.id, error);
 }
@@ -874,6 +902,7 @@ do_set_volume (WpCtl * self, WpPipewireObject *proxy)
   g_autoptr (GError) error = NULL;
   GVariant *variant = NULL;
   gboolean res = FALSE;
+  gdouble curr_volume = 1.0;
   guint32 id = wp_proxy_get_bound_id (WP_PROXY (proxy));
 
   if (WP_IS_ENDPOINT (proxy)) {
@@ -885,6 +914,27 @@ do_set_volume (WpCtl * self, WpPipewireObject *proxy)
     id = atoi (str);
   }
 
+  g_signal_emit_by_name (mixer_api, "get-volume", id, &variant);
+    if (!variant) {
+    fprintf (stderr, "Node %d does not support volume\n", id);
+    g_clear_pointer (&variant, g_variant_unref);
+    return FALSE;
+  }
+  g_variant_lookup (variant, "volume", "d", &curr_volume);
+  g_clear_pointer (&variant, g_variant_unref);
+
+  if (cmdline.set_volume.type == 'a') {
+    cmdline.set_volume.volume = cmdline.set_volume.volume;
+  } else if (cmdline.set_volume.type == 's') {
+    cmdline.set_volume.volume = (cmdline.set_volume.volume + curr_volume);
+  } else if (cmdline.set_volume.type == 'p') {
+    gfloat delta = (cmdline.set_volume.volume) * (curr_volume);
+    cmdline.set_volume.volume = (curr_volume + delta);
+  }
+  if (cmdline.set_volume.volume < 0) {
+    cmdline.set_volume.volume = 0.0;
+  }
+
   g_variant_builder_add (&b, "{sv}", "volume",
       g_variant_new_double (cmdline.set_volume.volume));
   variant = g_variant_builder_end (&b);
@@ -1266,8 +1316,13 @@ static const struct subcommand {
   },
   {
     .name = "set-volume",
-    .positional_args = "ID VOL",
-    .summary = "Sets the volume of ID to VOL (floating point, 1.0 is 100%%)",
+    .positional_args = "ID VOL[%%][-/+]",
+    .summary = "Sets the volume of ID from specified argument. "
+               "(floating point, 1.0 is 100%%)\n  VOL%%[-/+] - "
+               "Step up/down volume by specified percent (Example:"
+               " 0.5%%+)\n  VOL[-/+] - Step up/down volume by"
+               " specified value (Example: 0.5+)\n  VOL - Set "
+               "volume as the specified value (Example: 0.5)",
     .description = NULL,
     .entries = {
       { "pid", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
-- 
2.36.1