diff options
author | Tim Keller <tjk@tjkeller.xyz> | 2024-10-05 13:27:20 -0500 |
---|---|---|
committer | Tim Keller <tjk@tjkeller.xyz> | 2024-10-05 13:27:20 -0500 |
commit | 23d702cdbf81d4ced47e28b7d8a33bc83083e1e3 (patch) | |
tree | 7d7cf484e23e508cd0da83c0555620b9bb52fb94 | |
parent | e9879d6ad81f04ba396c46b187c0ba63c8a340e4 (diff) | |
download | pavolctld-23d702cdbf81d4ced47e28b7d8a33bc83083e1e3.tar.xz pavolctld-23d702cdbf81d4ced47e28b7d8a33bc83083e1e3.zip |
add errors and default sink changes plus a little bit of refactoring
-rw-r--r-- | pavolctld.c | 58 |
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); |