--- man/pactl.1.xml.in | 15 +++++++++ shell-completion/bash/pulseaudio | 19 ++++++++++- shell-completion/zsh/_pulseaudio | 70 ++++++++++++++++++++++++---------------- src/utils/pactl.c | 26 ++++++++++++++- 4 files changed, 100 insertions(+), 30 deletions(-) diff --git a/man/pactl.1.xml.in b/man/pactl.1.xml.in index e59f44a..398b1ae 100644 --- a/man/pactl.1.xml.in +++ b/man/pactl.1.xml.in @@ -282,6 +282,21 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. not been implemented yet.</p></optdesc> </option> + <option> + <p><opt>device-manager-reorder-devices-for-role</opt> <arg>ROLE</arg> + <arg>DEVICE [DEVICE ...]</arg></p> + <optdesc><p>Reorder the device priority list of a role. The priorities + are assigned to the listed devices in descending order (i.e. the first + device gets the highest priority). If the database contains devices that + are not listed, they will keep their priorities in relation to each + other, but all unlisted devices will have lower priority than any of the + listed devices.</p> + + <p>DEVICE has format TYPE:NAME, where TYPE is "sink" or "source" and NAME + is the sink or source name. This command works only if + module-device-manager is loaded.</p></optdesc> + </option> + </section> <section name="Authors"> diff --git a/shell-completion/bash/pulseaudio b/shell-completion/bash/pulseaudio index e641419..b9fc41b 100644 --- a/shell-completion/bash/pulseaudio +++ b/shell-completion/bash/pulseaudio @@ -130,7 +130,8 @@ _pactl() { device-manager-list-devices device-manager-set-device-description device-manager-delete-entries - device-manager-set-routing-enabled) + device-manager-set-routing-enabled + device-manager-reorder-devices-for-role) _init_completion -n = || return preprev=${words[$cword-2]} @@ -179,6 +180,7 @@ _pactl() { comps=$(__ports) COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur")) ;; + --server) compopt +o nospace _known_hosts_real "$cur" @@ -249,6 +251,11 @@ _pactl() { COMPREPLY=($(compgen -W 'true false' -- "$cur")) ;; + device-manager-reorder-devices-for-role) + # TODO: Complete the role. Requires implementing + # "pactl device-manager-list-roles" first. + ;; + -s) _known_hosts_real "$cur" ;; esac @@ -260,6 +267,16 @@ _pactl() { return 0 fi + # device-manager-reorder-devices-for-role takes a role and a list of + # devices. This completes the device list. "$command" != "$prev" means that + # if we're completing the first argument (which should be a role), then we + # shouldn't offer devices. + if [[ "$command" == device-manager-reorder-devices-for-role && "$command" != "$prev" ]] ; then + comps=$(__device_manager_devices) + COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur")) + return 0 + fi + case $cur in --server=*) cur=${cur#*=} diff --git a/shell-completion/zsh/_pulseaudio b/shell-completion/zsh/_pulseaudio index bbdd8cb..34444df 100644 --- a/shell-completion/zsh/_pulseaudio +++ b/shell-completion/zsh/_pulseaudio @@ -290,6 +290,7 @@ _pactl_completion() { 'device-manager-set-device-description: set the description of a device' 'device-manager-delete-entries: delete device entries from the device-manager database' 'device-manager-set-routing-enabled: enable or disable routing in device-manager' + 'device-manager-reorder-devices-for-role: reorder the device priority list of a role' ) _describe 'pactl commands' _pactl_commands @@ -490,37 +491,50 @@ _pactl_completion() { fi } + _device_manager_reorder_devices_for_role() { + if ((CURRENT == 2)); then + # We're completing the first parameter after + # "device-manager-reorder-devices-for-role". TODO: Complete the + # role. Requires implementing "pactl device-manager-list-roles" + # first. + else + # The rest of the parameters are just devices. + _device_manager_devices + fi + } + _command=$words[1] case $_command in - list) _list_parameter;; - upload-sample) if ((CURRENT == 2)); then _files; fi;; - play-sample) _play_sample_parameter;; - remove-sample) ;; # TODO: Implement sample name completion. - load-module) _load_module_parameter;; - unload-module) if ((CURRENT == 2)); then _loaded_modules; fi;; - move-sink-input) _move_sink_input_parameter;; - move-source-output) _move_source_output_parameter;; - suspend-sink) _suspend_sink_parameter;; - suspend-source) _suspend_source_parameter;; - set-card-profile) _set_card_profile_parameter;; - set-default-sink) if ((CURRENT == 2)); then _devices; fi;; - set-default-source) if ((CURRENT == 2)); then _devices; fi;; - set-sink-port) _set_sink_port_parameter;; - set-source-port) _set_source_port_parameter;; - set-sink-volume) if ((CURRENT == 2)); then _devices; fi;; - set-source-volume) if ((CURRENT == 2)); then _devices; fi;; - set-sink-input-volume) if ((CURRENT == 2)); then _devices; fi;; - set-source-output-volume) if ((CURRENT == 2)); then _devices; fi;; - set-sink-mute) _set_sink_mute_parameter;; - set-source-mute) _set_source_mute_parameter;; - set-sink-input-mute) _set_sink_input_mute_parameter;; - set-source-output-mute) _set_source_output_mute_parameter;; - set-sink-formats) if ((CURRENT == 2)); then _devices; fi;; - set-port-latency-offset) _set_port_latency_offset_parameter;; - device-manager-set-device-description) if ((CURRENT == 2)); then _device_manager_devices; fi;; - device-manager-delete-entries) _device_manager_devices;; - device-manager-set-routing-enabled) if ((CURRENT == 2)); then compadd true false; fi;; + list) _list_parameter;; + upload-sample) if ((CURRENT == 2)); then _files; fi;; + play-sample) _play_sample_parameter;; + remove-sample) ;; # TODO: Implement sample name completion. + load-module) _load_module_parameter;; + unload-module) if ((CURRENT == 2)); then _loaded_modules; fi;; + move-sink-input) _move_sink_input_parameter;; + move-source-output) _move_source_output_parameter;; + suspend-sink) _suspend_sink_parameter;; + suspend-source) _suspend_source_parameter;; + set-card-profile) _set_card_profile_parameter;; + set-default-sink) if ((CURRENT == 2)); then _devices; fi;; + set-default-source) if ((CURRENT == 2)); then _devices; fi;; + set-sink-port) _set_sink_port_parameter;; + set-source-port) _set_source_port_parameter;; + set-sink-volume) if ((CURRENT == 2)); then _devices; fi;; + set-source-volume) if ((CURRENT == 2)); then _devices; fi;; + set-sink-input-volume) if ((CURRENT == 2)); then _devices; fi;; + set-source-output-volume) if ((CURRENT == 2)); then _devices; fi;; + set-sink-mute) _set_sink_mute_parameter;; + set-source-mute) _set_source_mute_parameter;; + set-sink-input-mute) _set_sink_input_mute_parameter;; + set-source-output-mute) _set_source_output_mute_parameter;; + set-sink-formats) if ((CURRENT == 2)); then _devices; fi;; + set-port-latency-offset) _set_port_latency_offset_parameter;; + device-manager-set-device-description) if ((CURRENT == 2)); then _device_manager_devices; fi;; + device-manager-delete-entries) _device_manager_devices;; + device-manager-set-routing-enabled) if ((CURRENT == 2)); then compadd true false; fi;; + device-manager-reorder-devices-for-role) _device_manager_reorder_devices_for_role;; esac } diff --git a/src/utils/pactl.c b/src/utils/pactl.c index 81c8851..a8266ac 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -59,7 +59,8 @@ static char *port_name = NULL, *formats = NULL, *device = NULL, - *description = NULL; + *description = NULL, + *role = NULL; static int n_devices = 0; static char **devices = NULL; @@ -143,6 +144,7 @@ static enum { DEVICE_MANAGER_SET_DEVICE_DESCRIPTION, DEVICE_MANAGER_DELETE_ENTRIES, DEVICE_MANAGER_SET_ROUTING_ENABLED, + DEVICE_MANAGER_REORDER_DEVICES_FOR_ROLE, } action = NONE; static void quit(int ret) { @@ -1512,6 +1514,11 @@ static void context_state_callback(pa_context *c, void *userdata) { (void *) false); break; + case DEVICE_MANAGER_REORDER_DEVICES_FOR_ROLE: + o = pa_ext_device_manager_reorder_devices_for_role(c, role, (const char **) devices, simple_callback, + (void *) false); + break; + case NONE: pa_assert_not_reached(); } @@ -1670,6 +1677,7 @@ static void help(const char *argv0) { printf("%s %s %s %s\n", argv0, _("[options]"), "device-manager-set-device-description", _("DEVICE DESCRIPTION")); printf("%s %s %s %s\n", argv0, _("[options]"), "device-manager-delete-entries", _("DEVICE [DEVICE ...]")); printf("%s %s %s %s\n", argv0, _("[options]"), "device-manager-set-routing-enabled", "1|0"); + printf("%s %s %s %s\n", argv0, _("[options]"), "device-manager-reorder-devices-for-role", _("ROLE DEVICE [DEVICE ...]")); printf(_("\nThe special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n" "can be used to specify the default sink, source and monitor.\n")); @@ -2197,6 +2205,21 @@ int main(int argc, char *argv[]) { goto quit; } + } else if (pa_streq(argv[optind], "device-manager-reorder-devices-for-role")) { + action = DEVICE_MANAGER_REORDER_DEVICES_FOR_ROLE; + + if (argc < optind + 3) { + pa_log(_("Too few arguments. You have to specify the role and at least one device.")); + goto quit; + } + + role = pa_xstrdup(argv[optind + 1]); + n_devices = argc - optind - 2; + devices = pa_xnew0(char *, n_devices + 1); + + for (i = 0; i < n_devices; i++) + devices[i] = pa_xstrdup(argv[optind + 2 + i]); + } else if (pa_streq(argv[optind], "help")) { help(bn); ret = 0; @@ -2261,6 +2284,7 @@ quit: pa_xfree(formats); pa_xfree(device); pa_xfree(description); + pa_xfree(role); for (i = 0; i < n_devices; i++) pa_xfree(devices[i]); -- 1.9.3