--- man/pactl.1.xml.in | 8 ++++++++ shell-completion/bash/pulseaudio | 14 +++++++++++++- shell-completion/zsh/_pulseaudio | 24 ++++++++++++++++++++++++ src/utils/pactl.c | 28 +++++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/man/pactl.1.xml.in b/man/pactl.1.xml.in index 6b93661..c4be220 100644 --- a/man/pactl.1.xml.in +++ b/man/pactl.1.xml.in @@ -256,6 +256,14 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. works only if module-device-manager is loaded.</p></optdesc> </option> + <option> + <p><opt>device-manager-set-device-description</opt> <arg>DEVICE</arg> + <arg>DESCRIPTION</arg></p> + <optdesc><p>Set the description of a device. 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 ac06603..45a705c 100644 --- a/shell-completion/bash/pulseaudio +++ b/shell-completion/bash/pulseaudio @@ -101,6 +101,12 @@ _pacat_file_formats () { done < <(pacat --list-file-formats 2> /dev/null) } +__device_manager_devices () { + while read _ name; do + echo "$name" + done < <(pactl device-manager-list-devices 2> /dev/null | grep "^Device ") +} + in_array() { local i for i in "${@:2}"; do @@ -121,7 +127,8 @@ _pactl() { set-sink-input-volume set-source-output-volume set-sink-mute set-source-mute set-sink-input-mute set-source-output-mute set-sink-formats set-port-latency-offset subscribe help - device-manager-list-devices) + device-manager-list-devices + device-manager-set-device-description) _init_completion -n = || return preprev=${words[$cword-2]} @@ -231,6 +238,11 @@ _pactl() { COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur")) ;; + device-manager-set-device-description) + comps=$(__device_manager_devices) + COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur")) + ;; + -s) _known_hosts_real "$cur" ;; esac diff --git a/shell-completion/zsh/_pulseaudio b/shell-completion/zsh/_pulseaudio index 908e49d..569fae1 100644 --- a/shell-completion/zsh/_pulseaudio +++ b/shell-completion/zsh/_pulseaudio @@ -219,6 +219,28 @@ _clients() { _describe 'client list' _client_list } +_device_manager_devices() { + local -a _device_list + local _device _device_description + + for device_info in ${(ps:\n\n:)"$(_call_program device_manager_devices_tag "pactl $remote device-manager-list-devices 2> /dev/null")"}; do + for line in ${(f)device_info}; do + if [[ $line == Device\ * ]]; then + _device=${line#Device\ } + + # Replace colons in device names with escaped colons, because + # otherwise _describe thinks that the part after the colon is + # the description for the completion. + _device=${(S)_device//:/\\:} + elif [[ $line == *Description:\ * ]]; then + _device_description=${line#*Description:\ } + fi + done + _device_list+=($_device:$_device_description) + done + _describe 'device-manager device list' _device_list +} + _pacat_file_formats() { local -a _file_format_list for format in ${(f)"$(_call_program fformats_tag "pacat --list-file-formats")"}; do @@ -265,6 +287,7 @@ _pactl_completion() { 'set-sink-formats: set supported formats of a sink' 'subscribe: subscribe to events' 'device-manager-list-devices: list devices in the device-manager database' + 'device-manager-set-device-description: set the description of a device' ) _describe 'pactl commands' _pactl_commands @@ -493,6 +516,7 @@ _pactl_completion() { 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;; esac } diff --git a/src/utils/pactl.c b/src/utils/pactl.c index ecaa4dc..f460a93 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -57,7 +57,9 @@ static char *card_name = NULL, *profile_name = NULL, *port_name = NULL, - *formats = NULL; + *formats = NULL, + *device = NULL, + *description = NULL; static uint32_t sink_input_idx = PA_INVALID_INDEX, @@ -133,6 +135,7 @@ static enum { SET_PORT_LATENCY_OFFSET, SUBSCRIBE, DEVICE_MANAGER_LIST_DEVICES, + DEVICE_MANAGER_SET_DEVICE_DESCRIPTION, } action = NONE; static void quit(int ret) { @@ -1489,6 +1492,10 @@ static void context_state_callback(pa_context *c, void *userdata) { o = pa_ext_device_manager_read(c, device_manager_read_callback, NULL); break; + case DEVICE_MANAGER_SET_DEVICE_DESCRIPTION: + o = pa_ext_device_manager_set_device_description(c, device, description, simple_callback, (void *) false); + break; + case NONE: pa_assert_not_reached(); } @@ -1644,6 +1651,7 @@ static void help(const char *argv0) { printf("%s %s %s %s\n", argv0, _("[options]"), "set-port-latency-offset", _("CARD-NAME|CARD-#N PORT OFFSET")); printf("%s %s %s\n", argv0, _("[options]"), "subscribe"); printf("%s %s %s\n", argv0, _("[options]"), "device-manager-list-devices"); + printf("%s %s %s %s\n", argv0, _("[options]"), "device-manager-set-device-description", _("DEVICE DESCRIPTION")); printf(_("\nThe special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n" "can be used to specify the default sink, source and monitor.\n")); @@ -2117,6 +2125,22 @@ int main(int argc, char *argv[]) { goto quit; } + } else if (pa_streq(argv[optind], "device-manager-set-device-description")) { + action = DEVICE_MANAGER_SET_DEVICE_DESCRIPTION; + + if (argc < optind + 3) { + pa_log(_("Too few arguments. You have to specify a device entry identifier and the new description.")); + goto quit; + } + + if (argc > optind + 3) { + pa_log(_("Too many arguments.")); + goto quit; + } + + device = pa_xstrdup(argv[optind + 1]); + description = pa_xstrdup(argv[optind + 2]); + } else if (pa_streq(argv[optind], "help")) { help(bn); ret = 0; @@ -2179,6 +2203,8 @@ quit: pa_xfree(profile_name); pa_xfree(port_name); pa_xfree(formats); + pa_xfree(device); + pa_xfree(description); if (sndfile) sf_close(sndfile); -- 1.9.3