diff options
Diffstat (limited to 'src/utils/pactl.c')
| -rw-r--r-- | src/utils/pactl.c | 268 | 
1 files changed, 215 insertions, 53 deletions
| diff --git a/src/utils/pactl.c b/src/utils/pactl.c index c8c3a437..141ab5b1 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -50,7 +50,6 @@ static pa_context *context = NULL;  static pa_mainloop_api *mainloop_api = NULL;  static char -    *device = NULL,      *sample_name = NULL,      *sink_name = NULL,      *source_name = NULL, @@ -66,6 +65,8 @@ static uint32_t  static uint32_t module_index;  static pa_bool_t suspend; +static pa_bool_t mute; +static pa_volume_t volume;  static pa_proplist *proplist = NULL; @@ -74,7 +75,6 @@ static pa_stream *sample_stream = NULL;  static pa_sample_spec sample_spec;  static pa_channel_map channel_map;  static size_t sample_length = 0; -  static int actions = 1;  static pa_bool_t nl = FALSE; @@ -95,7 +95,13 @@ static enum {      SUSPEND_SOURCE,      SET_CARD_PROFILE,      SET_SINK_PORT, -    SET_SOURCE_PORT +    SET_SOURCE_PORT, +    SET_SINK_VOLUME, +    SET_SOURCE_VOLUME, +    SET_SINK_INPUT_VOLUME, +    SET_SINK_MUTE, +    SET_SOURCE_MUTE, +    SET_SINK_INPUT_MUTE  } action = NONE;  static void quit(int ret) { @@ -109,6 +115,7 @@ static void context_drain_complete(pa_context *c, void *userdata) {  static void drain(void) {      pa_operation *o; +      if (!(o = pa_context_drain(context, context_drain_complete, NULL)))          pa_context_disconnect(context);      else @@ -123,9 +130,9 @@ static void complete_action(void) {  }  static void stat_callback(pa_context *c, const pa_stat_info *i, void *userdata) { -    char s[128]; +    char s[PA_BYTES_SNPRINT_MAX];      if (!i) { -        pa_log(_("Failed to get statistics: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get statistics: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -146,7 +153,7 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi      char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];      if (!i) { -        pa_log(_("Failed to get server information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get server information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -195,7 +202,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get sink information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get sink information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -287,7 +294,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get source information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get source information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -365,7 +372,7 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get module information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get module information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -402,7 +409,7 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get client information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get client information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -437,7 +444,7 @@ static void get_card_info_callback(pa_context *c, const pa_card_info *i, int is_      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get card information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get card information: %s"), pa_strerror(pa_context_errno(c)));          complete_action();          return;      } @@ -486,7 +493,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get sink input information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get sink input information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -544,7 +551,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get source output information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get source output information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -591,11 +598,11 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu  }  static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int is_last, void *userdata) { -    char t[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; +    char t[PA_BYTES_SNPRINT_MAX], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];      char *pl;      if (is_last < 0) { -        pa_log(_("Failed to get sample information: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failed to get sample information: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -643,7 +650,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int  static void simple_callback(pa_context *c, int success, void *userdata) {      if (!success) { -        pa_log(_("Failure: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failure: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -653,7 +660,7 @@ static void simple_callback(pa_context *c, int success, void *userdata) {  static void index_callback(pa_context *c, uint32_t idx, void *userdata) {      if (idx == PA_INVALID_INDEX) { -        pa_log(_("Failure: %s\n"), pa_strerror(pa_context_errno(c))); +        pa_log(_("Failure: %s"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -677,7 +684,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {          case PA_STREAM_FAILED:          default: -            pa_log(_("Failed to upload sample: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s)))); +            pa_log(_("Failed to upload sample: %s"), pa_strerror(pa_context_errno(pa_stream_get_context(s))));              quit(1);      }  } @@ -694,7 +701,7 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {      if ((sf_readf_float(sndfile, d, l)) != l) {          pa_xfree(d); -        pa_log(_("Premature end of file\n")); +        pa_log(_("Premature end of file"));          quit(1);          return;      } @@ -726,7 +733,7 @@ static void context_state_callback(pa_context *c, void *userdata) {                      break;                  case PLAY_SAMPLE: -                    pa_operation_unref(pa_context_play_sample(c, sample_name, device, PA_VOLUME_NORM, simple_callback, NULL)); +                    pa_operation_unref(pa_context_play_sample(c, sample_name, sink_name, PA_VOLUME_NORM, simple_callback, NULL));                      break;                  case REMOVE_SAMPLE: @@ -800,6 +807,42 @@ static void context_state_callback(pa_context *c, void *userdata) {                      pa_operation_unref(pa_context_set_source_port_by_name(c, source_name, port_name, simple_callback, NULL));                      break; +                case SET_SINK_MUTE: +                    pa_operation_unref(pa_context_set_sink_mute_by_name(c, sink_name, mute, simple_callback, NULL)); +                    break; + +                case SET_SOURCE_MUTE: +                    pa_operation_unref(pa_context_set_source_mute_by_name(c, source_name, mute, simple_callback, NULL)); +                    break; + +                case SET_SINK_INPUT_MUTE: +                    pa_operation_unref(pa_context_set_sink_input_mute(c, sink_input_idx, mute, simple_callback, NULL)); +                    break; + +                case SET_SINK_VOLUME: { +                    pa_cvolume v; + +                    pa_cvolume_set(&v, 1, volume); +                    pa_operation_unref(pa_context_set_sink_volume_by_name(c, sink_name, &v, simple_callback, NULL)); +                    break; +                } + +                case SET_SOURCE_VOLUME: { +                    pa_cvolume v; + +                    pa_cvolume_set(&v, 1, volume); +                    pa_operation_unref(pa_context_set_source_volume_by_name(c, source_name, &v, simple_callback, NULL)); +                    break; +                } + +                case SET_SINK_INPUT_VOLUME: { +                    pa_cvolume v; + +                    pa_cvolume_set(&v, 1, volume); +                    pa_operation_unref(pa_context_set_sink_input_volume(c, sink_input_idx, &v, simple_callback, NULL)); +                    break; +                } +                  default:                      pa_assert_not_reached();              } @@ -811,13 +854,13 @@ static void context_state_callback(pa_context *c, void *userdata) {          case PA_CONTEXT_FAILED:          default: -            pa_log(_("Connection failure: %s\n"), pa_strerror(pa_context_errno(c))); +            pa_log(_("Connection failure: %s"), pa_strerror(pa_context_errno(c)));              quit(1);      }  }  static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { -    pa_log(_("Got SIGINT, exiting.\n")); +    pa_log(_("Got SIGINT, exiting."));      quit(0);  } @@ -829,20 +872,30 @@ static void help(const char *argv0) {               "%s [options] upload-sample FILENAME [NAME]\n"               "%s [options] play-sample NAME [SINK]\n"               "%s [options] remove-sample NAME\n" -             "%s [options] move-sink-input ID SINK\n" -             "%s [options] move-source-output ID SOURCE\n" +             "%s [options] move-sink-input SINKINPUT SINK\n" +             "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"               "%s [options] load-module NAME [ARGS ...]\n" -             "%s [options] unload-module ID\n" -             "%s [options] suspend-sink [SINK] 1|0\n" -             "%s [options] suspend-source [SOURCE] 1|0\n" -             "%s [options] set-card-profile [CARD] [PROFILE] \n" -             "%s [options] set-sink-port [SINK] [PORT] \n" -             "%s [options] set-source-port [SOURCE] [PORT] \n\n" +             "%s [options] unload-module MODULE\n" +             "%s [options] suspend-sink SINK 1|0\n" +             "%s [options] suspend-source SOURCE 1|0\n" +             "%s [options] set-card-profile CARD PROFILE\n" +             "%s [options] set-sink-port SINK PORT\n" +             "%s [options] set-source-port SOURCE PORT\n" +             "%s [options] set-sink-volume SINK VOLUME\n" +             "%s [options] set-source-volume SOURCE VOLUME\n" +             "%s [options] set-sink-input-volume SINKINPUT VOLUME\n" +             "%s [options] set-sink-mute SINK 1|0\n" +             "%s [options] set-source-mute SOURCE 1|0\n" +             "%s [options] set-sink-input-mute SINKINPUT 1|0\n\n"               "  -h, --help                            Show this help\n"               "      --version                         Show version\n\n"               "  -s, --server=SERVER                   The name of the server to connect to\n"               "  -n, --client-name=NAME                How to call this client on the server\n"), -           argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); +           argv0, argv0, argv0, argv0, argv0, +           argv0, argv0, argv0, argv0, argv0, +           argv0, argv0, argv0, argv0, argv0, +           argv0, argv0, argv0, argv0, argv0, +           argv0);  }  enum { @@ -897,7 +950,7 @@ int main(int argc, char *argv[]) {                  if (!(t = pa_locale_to_utf8(optarg)) ||                      pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, t) < 0) { -                    pa_log(_("Invalid client name '%s'\n"), t ? t : optarg); +                    pa_log(_("Invalid client name '%s'"), t ? t : optarg);                      pa_xfree(t);                      goto quit;                  } @@ -923,7 +976,7 @@ int main(int argc, char *argv[]) {              action = UPLOAD_SAMPLE;              if (optind+1 >= argc) { -                pa_log(_("Please specify a sample file to load\n")); +                pa_log(_("Please specify a sample file to load"));                  goto quit;              } @@ -936,19 +989,19 @@ int main(int argc, char *argv[]) {              pa_zero(sfi);              if (!(sndfile = sf_open(argv[optind+1], SFM_READ, &sfi))) { -                pa_log(_("Failed to open sound file.\n")); +                pa_log(_("Failed to open sound file."));                  goto quit;              }              if (pa_sndfile_read_sample_spec(sndfile, &sample_spec) < 0) { -                pa_log(_("Failed to determine sample specification from file.\n")); +                pa_log(_("Failed to determine sample specification from file."));                  goto quit;              }              sample_spec.format = PA_SAMPLE_FLOAT32;              if (pa_sndfile_read_channel_map(sndfile, &channel_map) < 0) {                  if (sample_spec.channels > 2) -                     pa_log(_("Warning: Failed to determine sample specification from file.\n")); +                     pa_log(_("Warning: Failed to determine sample specification from file."));                  pa_channel_map_init_extend(&channel_map, sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);              } @@ -958,19 +1011,19 @@ int main(int argc, char *argv[]) {          } else if (pa_streq(argv[optind], "play-sample")) {              action = PLAY_SAMPLE;              if (argc != optind+2 && argc != optind+3) { -                pa_log(_("You have to specify a sample name to play\n")); +                pa_log(_("You have to specify a sample name to play"));                  goto quit;              }              sample_name = pa_xstrdup(argv[optind+1]);              if (optind+2 < argc) -                device = pa_xstrdup(argv[optind+2]); +                sink_name = pa_xstrdup(argv[optind+2]);          } else if (pa_streq(argv[optind], "remove-sample")) {              action = REMOVE_SAMPLE;              if (argc != optind+2) { -                pa_log(_("You have to specify a sample name to remove\n")); +                pa_log(_("You have to specify a sample name to remove"));                  goto quit;              } @@ -979,7 +1032,7 @@ int main(int argc, char *argv[]) {          } else if (pa_streq(argv[optind], "move-sink-input")) {              action = MOVE_SINK_INPUT;              if (argc != optind+3) { -                pa_log(_("You have to specify a sink input index and a sink\n")); +                pa_log(_("You have to specify a sink input index and a sink"));                  goto quit;              } @@ -989,7 +1042,7 @@ int main(int argc, char *argv[]) {          } else if (pa_streq(argv[optind], "move-source-output")) {              action = MOVE_SOURCE_OUTPUT;              if (argc != optind+3) { -                pa_log(_("You have to specify a source output index and a source\n")); +                pa_log(_("You have to specify a source output index and a source"));                  goto quit;              } @@ -1004,7 +1057,7 @@ int main(int argc, char *argv[]) {              action = LOAD_MODULE;              if (argc <= optind+1) { -                pa_log(_("You have to specify a module name and arguments.\n")); +                pa_log(_("You have to specify a module name and arguments."));                  goto quit;              } @@ -1024,7 +1077,7 @@ int main(int argc, char *argv[]) {              action = UNLOAD_MODULE;              if (argc != optind+2) { -                pa_log(_("You have to specify a module index\n")); +                pa_log(_("You have to specify a module index"));                  goto quit;              } @@ -1034,7 +1087,7 @@ int main(int argc, char *argv[]) {              action = SUSPEND_SINK;              if (argc > optind+3 || optind+1 >= argc) { -                pa_log(_("You may not specify more than one sink. You have to specify a boolean value.\n")); +                pa_log(_("You may not specify more than one sink. You have to specify a boolean value."));                  goto quit;              } @@ -1047,7 +1100,7 @@ int main(int argc, char *argv[]) {              action = SUSPEND_SOURCE;              if (argc > optind+3 || optind+1 >= argc) { -                pa_log(_("You may not specify more than one source. You have to specify a boolean value.\n")); +                pa_log(_("You may not specify more than one source. You have to specify a boolean value."));                  goto quit;              } @@ -1059,7 +1112,7 @@ int main(int argc, char *argv[]) {              action = SET_CARD_PROFILE;              if (argc != optind+3) { -                pa_log(_("You have to specify a card name/index and a profile name\n")); +                pa_log(_("You have to specify a card name/index and a profile name"));                  goto quit;              } @@ -1070,7 +1123,7 @@ int main(int argc, char *argv[]) {              action = SET_SINK_PORT;              if (argc != optind+3) { -                pa_log(_("You have to specify a sink name/index and a port name\n")); +                pa_log(_("You have to specify a sink name/index and a port name"));                  goto quit;              } @@ -1081,13 +1134,123 @@ int main(int argc, char *argv[]) {              action = SET_SOURCE_PORT;              if (argc != optind+3) { -                pa_log(_("You have to specify a source name/index and a port name\n")); +                pa_log(_("You have to specify a source name/index and a port name"));                  goto quit;              }              source_name = pa_xstrdup(argv[optind+1]);              port_name = pa_xstrdup(argv[optind+2]); +        } else if (pa_streq(argv[optind], "set-sink-volume")) { +            uint32_t v; +            action = SET_SINK_VOLUME; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a sink name/index and a volume")); +                goto quit; +            } + +            if (pa_atou(argv[optind+2], &v) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            sink_name = pa_xstrdup(argv[optind+1]); +            volume = (pa_volume_t) v; + +        } else if (pa_streq(argv[optind], "set-source-volume")) { +            uint32_t v; +            action = SET_SOURCE_VOLUME; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a source name/index and a volume")); +                goto quit; +            } + +            if (pa_atou(argv[optind+2], &v) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            source_name = pa_xstrdup(argv[optind+1]); +            volume = (pa_volume_t) v; + +        } else if (pa_streq(argv[optind], "set-sink-input-volume")) { +            uint32_t v; +            action = SET_SINK_INPUT_VOLUME; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a sink input index and a volume")); +                goto quit; +            } + +            if (pa_atou(argv[optind+1], &sink_input_idx) < 0) { +                pa_log(_("Invalid sink input index")); +                goto quit; +            } + +            if (pa_atou(argv[optind+2], &v) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            volume = (pa_volume_t) v; + +        } else if (pa_streq(argv[optind], "set-sink-mute")) { +            int b; +            action = SET_SINK_MUTE; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a sink name/index and a mute boolean")); +                goto quit; +            } + +            if ((b = pa_parse_boolean(argv[optind+2])) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            sink_name = pa_xstrdup(argv[optind+1]); +            mute = b; + +        } else if (pa_streq(argv[optind], "set-source-mute")) { +            int b; +            action = SET_SOURCE_MUTE; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a source name/index and a mute boolean")); +                goto quit; +            } + +            if ((b = pa_parse_boolean(argv[optind+2])) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            source_name = pa_xstrdup(argv[optind+1]); +            mute = b; + +        } else if (pa_streq(argv[optind], "set-sink-input-mute")) { +            int b; +            action = SET_SINK_INPUT_MUTE; + +            if (argc != optind+3) { +                pa_log(_("You have to specify a sink input index and a mute boolean")); +                goto quit; +            } + +            if (pa_atou(argv[optind+1], &sink_input_idx) < 0) { +                pa_log(_("Invalid sink input index specification")); +                goto quit; +            } + +            if ((b = pa_parse_boolean(argv[optind+2])) < 0) { +                pa_log(_("Invalid volume specification")); +                goto quit; +            } + +            mute = b; +          } else if (pa_streq(argv[optind], "help")) {              help(bn);              ret = 0; @@ -1096,12 +1259,12 @@ int main(int argc, char *argv[]) {      }      if (action == NONE) { -        pa_log(_("No valid command specified.\n")); +        pa_log(_("No valid command specified."));          goto quit;      }      if (!(m = pa_mainloop_new())) { -        pa_log(_("pa_mainloop_new() failed.\n")); +        pa_log(_("pa_mainloop_new() failed."));          goto quit;      } @@ -1113,7 +1276,7 @@ int main(int argc, char *argv[]) {      pa_disable_sigpipe();      if (!(context = pa_context_new_with_proplist(mainloop_api, NULL, proplist))) { -        pa_log(_("pa_context_new() failed.\n")); +        pa_log(_("pa_context_new() failed."));          goto quit;      } @@ -1124,7 +1287,7 @@ int main(int argc, char *argv[]) {      }      if (pa_mainloop_run(m, &ret) < 0) { -        pa_log(_("pa_mainloop_run() failed.\n")); +        pa_log(_("pa_mainloop_run() failed."));          goto quit;      } @@ -1141,7 +1304,6 @@ quit:      }      pa_xfree(server); -    pa_xfree(device);      pa_xfree(sample_name);      pa_xfree(sink_name);      pa_xfree(source_name); | 
