aboutsummaryrefslogtreecommitdiff
path: root/pavolctld.c
diff options
context:
space:
mode:
authorTim Keller <tjk@tjkeller.xyz>2024-10-05 13:27:20 -0500
committerTim Keller <tjk@tjkeller.xyz>2024-10-05 13:27:20 -0500
commit23d702cdbf81d4ced47e28b7d8a33bc83083e1e3 (patch)
tree7d7cf484e23e508cd0da83c0555620b9bb52fb94 /pavolctld.c
parente9879d6ad81f04ba396c46b187c0ba63c8a340e4 (diff)
downloadpavolctld-23d702cdbf81d4ced47e28b7d8a33bc83083e1e3.tar.xz
pavolctld-23d702cdbf81d4ced47e28b7d8a33bc83083e1e3.zip
add errors and default sink changes plus a little bit of refactoring
Diffstat (limited to 'pavolctld.c')
-rw-r--r--pavolctld.c58
1 files changed, 50 insertions, 8 deletions
diff --git a/pavolctld.c b/pavolctld.c
index 3a2dd19..c8a4c5a 100644
--- a/pavolctld.c
+++ b/pavolctld.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <pulse/pulseaudio.h>
+#define APPLICATION_NAME "pavolctld"
#define ROUND_POS(x) ((int)((x) + 0.5f))
#define VOLUME_MAX (PA_VOLUME_NORM + (PA_VOLUME_NORM / 2)) // 150% max
@@ -9,7 +10,7 @@
/* context vars */
static int default_sink_index; // should always point to default sink
-static int command_sink_index; // commands will modify this sink
+static int command_sink_index = -1; // commands will modify this sink
/* output callbacks */
@@ -31,6 +32,10 @@ static void sink_info_sink_desc_callback(pa_context *c, const pa_sink_info *i, i
static void sink_info_default_index_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
if (eol) return;
default_sink_index = i->index;
+ // set command sink equal to the default sink on startup
+ if (command_sink_index == -1)
+ command_sink_index = default_sink_index;
+
printf("f%d\n", default_sink_index);
fflush(stdout);
}
@@ -71,9 +76,6 @@ static void context_state_callback(pa_context *c, void *userdata) {
// output initial default sink
pa_context_get_server_info(c, server_info_default_sink_callback, userdata);
- // set command sink equal to the default sink on startup
- command_sink_index = default_sink_index;
-
// output initial sink descriptions for each sink
pa_context_get_sink_info_list(c, sink_info_sink_desc_callback, userdata);
@@ -93,7 +95,7 @@ static void sink_info_change_command_sink_callback(pa_context *c, const pa_sink_
// callbacks are called twice if successful, with eol set the 2nd time
// so this is the easiest way to check if cmd was successful
if (useridx != command_sink_index) {
- printf("e0,sink %d does not exist\n", useridx);
+ printf("e2,sink %d does not exist\n", useridx);
fflush(stdout);
}
return;
@@ -112,12 +114,34 @@ static void change_command_sink(pa_context *c, char *cmd) {
useridx = atoi(&cmd[1]);
- if (useridx == default_sink_index)
+ if (useridx == command_sink_index)
return;
pa_context_get_sink_info_by_index(c, useridx, sink_info_change_command_sink_callback, (void *)&useridx);
}
+static void sink_info_change_default_sink_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
+ int useridx = *(int *)userdata;
+ if (eol) {
+ if (useridx != default_sink_index) {
+ printf("e3,sink %d does not exist\n", useridx); // same as sink_info_change_command_sink_callback
+ fflush(stdout);
+ }
+ return;
+ }
+
+ pa_context_set_default_sink(c, i->name, NULL, NULL);
+}
+
+static void change_default_sink(pa_context *c, char *cmd) {
+ int useridx = cmd[1] == '\n' ? command_sink_index : atoi(&cmd[1]);
+
+ if (useridx == default_sink_index)
+ return;
+
+ pa_context_get_sink_info_by_index(c, useridx, sink_info_change_default_sink_callback, (void *)&useridx);
+}
+
static void sink_info_set_volume_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
char *cmd = (char *)userdata;
pa_cvolume *cvol;
@@ -158,12 +182,30 @@ static void sink_info_set_mute_callback(pa_context *c, const pa_sink_info *i, in
}
/* handle stdin commands */
+static char *no_newline(char *s) {
+ uint8_t i; // stdin buffer is 256 char long at most so this is sufficient
+ for(i = 0; s[i] != '\n' && s[i] != '\0'; i++);
+ s[i] = '\0';
+ return s;
+}
+
static void handle_command(pa_context *c, char *cmd) {
+ if (command_sink_index == -1) {
+ printf("e0,command '%s' sent while "APPLICATION_NAME" still initializing\n", no_newline(cmd));
+ fflush(stdout);
+ return;
+ }
+
// send the command to each callback using userdata
switch (cmd[0]) {
case 's': change_command_sink(c, cmd); break;
+ case 'f': change_default_sink(c, cmd); break;
case 'v': pa_context_get_sink_info_by_index(c, command_sink_index, sink_info_set_volume_callback, (void *)cmd); break;
case 'm': pa_context_get_sink_info_by_index(c, command_sink_index, sink_info_set_mute_callback, (void *)cmd); break;
+ default:
+ printf("e1,unrecognized command '%s'\n", no_newline(cmd));
+ fflush(stdout);
+ break;
}
}
@@ -172,8 +214,8 @@ int main() {
// initialize threaded pulse mainloop
pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new();
pa_mainloop_api *mainloop_api = pa_threaded_mainloop_get_api(mainloop);
- pa_context *context = pa_context_new(mainloop_api, "pavolctld");
- char stdin_buffer[256];
+ pa_context *context = pa_context_new(mainloop_api, APPLICATION_NAME);
+ char stdin_buffer[256]; // don't change buf len unless you change the no_newline func
pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);