This adds two new commands to pactl: set-sink-set-default set-source-set-default This command has been part of the native protocol for a long time, no reason not to expose it in the client API and pactl. --- man/pactl.1.xml.in | 10 ++++++++++ src/map-file | 2 ++ src/pulse/introspect.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/pulse/introspect.h | 6 ++++++ src/utils/pactl.c | 31 +++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+) diff --git a/man/pactl.1.xml.in b/man/pactl.1.xml.in index 1dc063d..aa3c78d 100644 --- a/man/pactl.1.xml.in +++ b/man/pactl.1.xml.in @@ -163,11 +163,21 @@ USA. </option> <option> + <p><opt>set-sink-default</opt> <arg>SINK</arg></p> + <optdesc><p>Make the specified sink (identified by its symbolic name) the default sink.</p></optdesc> + </option> + + <option> <p><opt>set-sink-port</opt> <arg>SINK</arg> <arg>PORT</arg></p> <optdesc><p>Set the specified sink (identified by its symbolic name or numerical index) to the specified port (identified by its symbolic name).</p></optdesc> </option> <option> + <p><opt>set-source-default</opt> <arg>SOURCE</arg></p> + <optdesc><p>Make the specified source (identified by its symbolic name) the default source.</p></optdesc> + </option> + + <option> <p><opt>set-source-port</opt> <arg>SOURCE</arg> <arg>PORT</arg></p> <optdesc><p>Set the specified source (identified by its symbolic name or numerical index) to the specified port (identified by its symbolic name).</p></optdesc> </option> diff --git a/src/map-file b/src/map-file index 91d61c2..b50dbdc 100644 --- a/src/map-file +++ b/src/map-file @@ -96,6 +96,7 @@ pa_context_set_sink_mute_by_index; pa_context_set_sink_mute_by_name; pa_context_set_sink_port_by_index; pa_context_set_sink_port_by_name; +pa_context_set_sink_default_by_name; pa_context_set_sink_volume_by_index; pa_context_set_sink_volume_by_name; pa_context_set_source_output_mute; @@ -104,6 +105,7 @@ pa_context_set_source_mute_by_index; pa_context_set_source_mute_by_name; pa_context_set_source_port_by_index; pa_context_set_source_port_by_name; +pa_context_set_source_default_by_name; pa_context_set_source_volume_by_index; pa_context_set_source_volume_by_name; pa_context_set_state_callback; diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 9ca3fd3..e959e96 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -405,6 +405,28 @@ pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name, return o; } +pa_operation* pa_context_set_sink_default_by_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag); + pa_tagstruct_puts(t, name); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + /*** Source info ***/ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { @@ -678,6 +700,28 @@ pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char *name return o; } +pa_operation* pa_context_set_source_default_by_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag); + pa_tagstruct_puts(t, name); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + /*** Client info ***/ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index a833471..fd6f289 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -271,6 +271,9 @@ pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, con /** Change the profile of a sink. \since 0.9.15 */ pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata); +/** Change the default sink. \since 4.0 */ +pa_operation* pa_context_set_sink_default_by_name(pa_context *c, const char*name, pa_context_success_cb_t cb, void *userdata); + /** @} */ /** @{ \name Sources */ @@ -351,6 +354,9 @@ pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, c /** Change the profile of a source. \since 0.9.15 */ pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char*name, const char*port, pa_context_success_cb_t cb, void *userdata); +/** Change the default source. \since 4.0 */ +pa_operation* pa_context_set_source_default_by_name(pa_context *c, const char*name, pa_context_success_cb_t cb, void *userdata); + /** @} */ /** @{ \name Server */ diff --git a/src/utils/pactl.c b/src/utils/pactl.c index 79b1545..b255ca2 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -114,7 +114,9 @@ static enum { SUSPEND_SOURCE, SET_CARD_PROFILE, SET_SINK_PORT, + SET_SINK_DEFAULT, SET_SOURCE_PORT, + SET_SOURCE_DEFAULT, SET_SINK_VOLUME, SET_SOURCE_VOLUME, SET_SINK_INPUT_VOLUME, @@ -1284,10 +1286,18 @@ static void context_state_callback(pa_context *c, void *userdata) { pa_operation_unref(pa_context_set_sink_port_by_name(c, sink_name, port_name, simple_callback, NULL)); break; + case SET_SINK_DEFAULT: + pa_operation_unref(pa_context_set_sink_default_by_name(c, sink_name, simple_callback, NULL)); + break; + case SET_SOURCE_PORT: pa_operation_unref(pa_context_set_source_port_by_name(c, source_name, port_name, simple_callback, NULL)); break; + case SET_SOURCE_DEFAULT: + pa_operation_unref(pa_context_set_source_default_by_name(c, source_name, simple_callback, NULL)); + break; + case SET_SINK_MUTE: if (mute == TOGGLE_MUTE) pa_operation_unref(pa_context_get_sink_info_by_name(c, sink_name, sink_toggle_mute_callback, NULL)); @@ -1491,6 +1501,7 @@ static void help(const char *argv0) { printf("%s %s %s %s\n", argv0, _("[options]"), "move-(sink-input|source-output)", _("#N SINK|SOURCE")); printf("%s %s %s %s\n", argv0, _("[options]"), "suspend-(sink|source)", _("NAME|#N 1|0")); printf("%s %s %s %s\n", argv0, _("[options]"), "set-card-profile ", _("CARD PROFILE")); + printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-default", _("NAME")); printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-port", _("NAME|#N PORT")); printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-volume", _("NAME|#N VOLUME")); printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-volume", _("#N VOLUME")); @@ -1779,6 +1790,16 @@ int main(int argc, char *argv[]) { sink_name = pa_xstrdup(argv[optind+1]); port_name = pa_xstrdup(argv[optind+2]); + } else if (pa_streq(argv[optind], "set-sink-default")) { + action = SET_SINK_DEFAULT; + + if (argc != optind+2) { + pa_log(_("You have to specify a sink name")); + goto quit; + } + + sink_name = pa_xstrdup(argv[optind+1]); + } else if (pa_streq(argv[optind], "set-source-port")) { action = SET_SOURCE_PORT; @@ -1790,6 +1811,16 @@ int main(int argc, char *argv[]) { source_name = pa_xstrdup(argv[optind+1]); port_name = pa_xstrdup(argv[optind+2]); + } else if (pa_streq(argv[optind], "set-source-default")) { + action = SET_SOURCE_DEFAULT; + + if (argc != optind+2) { + pa_log(_("You have to specify a source name")); + goto quit; + } + + source_name = pa_xstrdup(argv[optind+1]); + } else if (pa_streq(argv[optind], "set-sink-volume")) { action = SET_SINK_VOLUME; -- 1.8.1.2