Remove unused old features 84/112384/2 accepted/tizen/3.0/common/20170202.151046 accepted/tizen/3.0/ivi/20170202.085711 accepted/tizen/3.0/mobile/20170202.085622 accepted/tizen/3.0/tv/20170202.085640 accepted/tizen/3.0/wearable/20170202.085654 submit/tizen_3.0/20170201.113021
authorSeungbae Shin <seungbae.shin@samsung.com>
Tue, 31 Jan 2017 13:54:00 +0000 (22:54 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Wed, 1 Feb 2017 11:04:36 +0000 (20:04 +0900)
[Version] 5.0-107
[Profile] Common
[Issue Type] Cleanup

Change-Id: I5dbaa41232b72f3d21e53ab2ec5fd507b78fe1d9

36 files changed:
Makefile.am
packaging/pulseaudio.spec
src/Makefile.am
src/daemon/default.pa.in
src/modules/audio-groups/audio-groups.conf.example [deleted file]
src/modules/audio-groups/module-audio-groups.c [deleted file]
src/modules/main-volume-policy/main-volume-context.c [deleted file]
src/modules/main-volume-policy/main-volume-context.h [deleted file]
src/modules/main-volume-policy/main-volume-policy.c [deleted file]
src/modules/main-volume-policy/main-volume-policy.conf.example [deleted file]
src/modules/main-volume-policy/main-volume-policy.h [deleted file]
src/modules/main-volume-policy/module-main-volume-policy.c [deleted file]
src/modules/volume-api/PROTOCOL [deleted file]
src/modules/volume-api/audio-group.c [deleted file]
src/modules/volume-api/audio-group.h [deleted file]
src/modules/volume-api/bvolume.h [deleted file]
src/modules/volume-api/device-creator.c [deleted file]
src/modules/volume-api/device-creator.h [deleted file]
src/modules/volume-api/device.c [deleted file]
src/modules/volume-api/device.h [deleted file]
src/modules/volume-api/inidb.c [deleted file]
src/modules/volume-api/inidb.h [deleted file]
src/modules/volume-api/module-volume-api.c [deleted file]
src/modules/volume-api/mute-control.c [deleted file]
src/modules/volume-api/mute-control.h [deleted file]
src/modules/volume-api/sstream.c [deleted file]
src/modules/volume-api/sstream.h [deleted file]
src/modules/volume-api/stream-creator.c [deleted file]
src/modules/volume-api/stream-creator.h [deleted file]
src/modules/volume-api/volume-api-common.h [deleted file]
src/modules/volume-api/volume-api.c [deleted file]
src/modules/volume-api/volume-api.h [deleted file]
src/modules/volume-api/volume-control.c [deleted file]
src/modules/volume-api/volume-control.h [deleted file]
src/pulse/ext-volume-api.c [deleted file]
src/pulse/ext-volume-api.h [deleted file]

index 7616e15..aea1802 100644 (file)
@@ -58,12 +58,6 @@ moduledevdir   = $(includedir)/pulsemodule/pulsecore
 moduledevinternal_DATA = src/pulse/internal.h src/pulse/client-conf.h src/pulse/fork-detect.h
 moduledevinternaldir   = $(includedir)/pulsemodule/pulse
 
-moduledevvolumeapi_DATA = src/modules/volume-api/*.h
-moduledevvolumeapidir   = $(includedir)/pulsemodule/modules/volume-api
-
-moduledevmainvolumepolicy_DATA = src/modules/main-volume-policy/*.h
-moduledevmainvolumepolicydir   = $(includedir)/pulsemodule/modules/main-volume-policy
-
 filterdir = /etc/pulse/filter
 filter_DATA = filter/filter_44100_48000.dat \
              filter/filter_44100_8000.dat \
index 1c3636c..30cca25 100644 (file)
@@ -11,7 +11,7 @@
 Name:             pulseaudio
 Summary:          Improved Linux sound server
 Version:          5.0
-Release:          106
+Release:          107
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
 URL:              http://pulseaudio.org
@@ -459,11 +459,6 @@ fi
 %else
 %{_unitdir}/multi-user.target.wants/pulseaudio.service
 %endif
-%{_libdir}/pulse-%{version}/modules/libvolume-api.so
-%{_libdir}/pulse-%{version}/modules/libmain-volume-policy.so
-%{_libdir}/pulse-%{version}/modules/module-volume-api.so
-%{_libdir}/pulse-%{version}/modules/module-main-volume-policy.so
-%{_libdir}/pulse-%{version}/modules/module-audio-groups.so
 
 %exclude %config(noreplace) /etc/bash_completion.d/pulseaudio-bash-completion.sh
 
@@ -554,8 +549,6 @@ fi
 %config(noreplace) %{_sysconfdir}/pulse/default.pa
 %config(noreplace) %{_sysconfdir}/pulse/client.conf
 %config(noreplace) %{_sysconfdir}/pulse/system.pa
-%config(noreplace) %{_sysconfdir}/pulse/audio-groups.conf
-%config(noreplace) %{_sysconfdir}/pulse/main-volume-policy.conf
 
 %{_datadir}/pulseaudio/alsa-mixer/paths/*
 %{_datadir}/pulseaudio/alsa-mixer/profile-sets/*
@@ -571,8 +564,6 @@ fi
 %defattr(-,root,root)
 %{_includedir}/pulsemodule/pulsecore/*.h
 %{_includedir}/pulsemodule/pulse/*.h
-%{_includedir}/pulsemodule/modules/main-volume-policy/*.h
-%{_includedir}/pulsemodule/modules/volume-api/*.h
 %{_libdir}/pkgconfig/pulseaudio-module-devel.pc
 
 %files vala-bindings
index fb4a523..ac6a211 100644 (file)
@@ -95,8 +95,6 @@ EXTRA_DIST = \
                daemon/cascaded.pa \
                pulse/client.conf.in \
                pulse/version.h.in \
-               tizen-ivi/audio-groups.conf \
-               tizen-ivi/main-volume-policy.conf \
                daemon/daemon.conf.in \
                daemon/default.pa.in \
                daemon/system.pa.in \
@@ -126,25 +124,6 @@ pulseconf_DATA = \
                daemon.conf \
                client.conf
 
-# Add some Tizen specific configuration files.
-#
-# FIXME: These configuration files should be installed only if explicitly
-# requested, because they define policy which may not be the desired policy in
-# every Tizen profile. Currently default.pa loads module-audio-groups and
-# module-main-volume-policy only if module-murphy-ivi is installed in the
-# system, which helps with this issue, because non-IVI profiles don't
-# currently use module-murphy-ivi, so these configuration files won't have any
-# effect outside the IVI profile, but this is pretty hacky solution. It would
-# be better to load module-audio-groups and module-main-volume-policy
-# unconditionally, since they're not really tied to the Murphy module in any
-# way. We use this hack, because otherwise we'd need a configure switch for
-# enabling the example IVI configuration, and a new configure switch would also
-# require a new switch in the Tizen IVI image configuration. That's an extra
-# hurdle that we decided to avoid for now.
-pulseconf_DATA += \
-               tizen-ivi/audio-groups.conf \
-               tizen-ivi/main-volume-policy.conf
-
 if HAVE_DBUS
 dbuspolicy_DATA = \
                daemon/pulseaudio-system.conf
@@ -951,7 +930,6 @@ pulseinclude_HEADERS = \
                pulse/ext-stream-restore.h \
                pulse/ext-echo-cancel.h \
                pulse/ext-node-manager.h \
-               pulse/ext-volume-api.h \
                pulse/format.h \
                pulse/gccmacro.h \
                pulse/introspect.h \
@@ -1000,7 +978,6 @@ libpulse_la_SOURCES = \
                pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
                pulse/ext-echo-cancel.c pulse/ext-echo-cancel.h \
                pulse/ext-node-manager.c pulse/ext-node-manager.h \
-               pulse/ext-volume-api.c pulse/ext-volume-api.h modules/volume-api/volume-api-common.h \
                pulse/format.c pulse/format.h \
                pulse/gccmacro.h \
                pulse/internal.h \
@@ -1193,12 +1170,10 @@ libpulsecore_foreign_la_CFLAGS = $(AM_CFLAGS) $(FOREIGN_CFLAGS)
 
 modlibexec_LTLIBRARIES = \
                libcli.la \
-               libmain-volume-policy.la \
                libprotocol-cli.la \
                libprotocol-simple.la \
                libprotocol-http.la \
-               libprotocol-native.la \
-               libvolume-api.la
+               libprotocol-native.la
 
 if HAVE_SYSTEMD_LOGIN
 modlibexec_LTLIBRARIES += \
@@ -1242,12 +1217,6 @@ liblogind_la_SOURCES = modules/logind/logind.c modules/logind/logind.h
 liblogind_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
 liblogind_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
-libmain_volume_policy_la_SOURCES = \
-               modules/main-volume-policy/main-volume-context.c modules/main-volume-policy/main-volume-context.h \
-               modules/main-volume-policy/main-volume-policy.c modules/main-volume-policy/main-volume-policy.h
-libmain_volume_policy_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
-libmain_volume_policy_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libvolume-api.la
-
 libprotocol_cli_la_SOURCES = pulsecore/protocol-cli.c pulsecore/protocol-cli.h
 libprotocol_cli_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
 libprotocol_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libcli.la
@@ -1279,26 +1248,6 @@ if HAVE_SYSTEMD_LOGIN
 libtunnel_manager_la_LIBADD += liblogind.la
 endif
 
-libvolume_api_la_SOURCES = \
-               modules/volume-api/audio-group.c modules/volume-api/audio-group.h \
-               modules/volume-api/bvolume.h \
-               modules/volume-api/device.c modules/volume-api/device.h \
-               modules/volume-api/device-creator.c modules/volume-api/device-creator.h \
-               modules/volume-api/inidb.c modules/volume-api/inidb.h \
-               modules/volume-api/mute-control.c modules/volume-api/mute-control.h \
-               modules/volume-api/sstream.c modules/volume-api/sstream.h \
-               modules/volume-api/stream-creator.c modules/volume-api/stream-creator.h \
-               modules/volume-api/volume-api.c modules/volume-api/volume-api.h \
-               modules/volume-api/volume-control.c modules/volume-api/volume-control.h
-libvolume_api_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
-libvolume_api_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
-
-# Audio Groups
-module_audio_groups_la_SOURCES = modules/audio-groups/module-audio-groups.c
-module_audio_groups_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_audio_groups_la_LIBADD = $(MODULE_LIBADD) libvolume-api.la
-module_audio_groups_la_CFLAGS = $(AM_CFLAGS)
-
 if HAVE_ESOUND
 libprotocol_esound_la_SOURCES = pulsecore/protocol-esound.c pulsecore/protocol-esound.h pulsecore/esound.h
 libprotocol_esound_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
@@ -1339,10 +1288,8 @@ endif
 modlibexec_LTLIBRARIES += \
                module-cli.la \
                module-cli-protocol-tcp.la \
-               module-main-volume-policy.la \
                module-simple-protocol-tcp.la \
                module-tunnel-manager.la \
-               module-volume-api.la \
                module-null-sink.la \
                module-null-source.la \
                module-sine-source.la \
@@ -1382,8 +1329,7 @@ modlibexec_LTLIBRARIES += \
                module-switch-on-port-available.la \
                module-filter-apply.la \
                module-filter-heuristics.la \
-               module-role-ducking.la \
-               module-audio-groups.la
+               module-role-ducking.la
 
 if HAVE_ESOUND
 modlibexec_LTLIBRARIES += \
@@ -1634,13 +1580,11 @@ SYMDEF_FILES = \
                module-cli-symdef.h \
                module-cli-protocol-tcp-symdef.h \
                module-cli-protocol-unix-symdef.h \
-               module-main-volume-policy-symdef.h \
                module-pipe-sink-symdef.h \
                module-pipe-source-symdef.h \
                module-simple-protocol-tcp-symdef.h \
                module-simple-protocol-unix-symdef.h \
                module-tunnel-manager-symdef.h \
-               module-volume-api-symdef.h \
                module-native-protocol-tcp-symdef.h \
                module-native-protocol-unix-symdef.h \
                module-native-protocol-fd-symdef.h \
@@ -1722,8 +1666,7 @@ SYMDEF_FILES = \
                module-switch-on-connect-symdef.h \
                module-switch-on-port-available-symdef.h \
                module-filter-apply-symdef.h \
-               module-filter-heuristics-symdef.h \
-               module-audio-groups-symdef.h
+               module-filter-heuristics-symdef.h
 
 if HAVE_ESOUND
 SYMDEF_FILES += \
@@ -1763,14 +1706,6 @@ module_tunnel_manager_la_SOURCES = modules/tunnel-manager/module-tunnel-manager.
 module_tunnel_manager_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_tunnel_manager_la_LIBADD = $(MODULE_LIBADD) libtunnel-manager.la
 
-# Volume API
-
-module_volume_api_la_SOURCES = \
-               modules/volume-api/module-volume-api.c \
-               modules/volume-api/volume-api-common.h
-module_volume_api_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_volume_api_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la libvolume-api.la
-
 # CLI protocol
 
 module_cli_la_SOURCES = modules/module-cli.c
@@ -1787,12 +1722,6 @@ module_cli_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_CLI $(AM_
 module_cli_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_cli_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-cli.la
 
-# Main volume and mute policy
-
-module_main_volume_policy_la_SOURCES = modules/main-volume-policy/module-main-volume-policy.c
-module_main_volume_policy_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_main_volume_policy_la_LIBADD = $(MODULE_LIBADD) libmain-volume-policy.la libvolume-api.la
-
 # HTTP protocol
 
 module_http_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
index 34eee41..122211a 100755 (executable)
@@ -178,9 +178,6 @@ load-module module-stream-restore restore_device=false on_hotplug=false on_rescu
 load-module module-native-protocol-tcp listen=127.0.0.1
 .fail
 
-load-module module-volume-api
-load-module module-audio-groups
-load-module module-main-volume-policy
 .else
 ### Automatically restore the volume of streams and devices
 load-module module-device-restore
diff --git a/src/modules/audio-groups/audio-groups.conf.example b/src/modules/audio-groups/audio-groups.conf.example
deleted file mode 100644 (file)
index 6aa6989..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-[General]
-stream-rules = phone-output music-output default-output
-
-[AudioGroup x-example-call-downlink-audio-group]
-volume-control = create:call-downlink-volume-control
-mute-control = create:call-downlink-mute-control
-
-[AudioGroup x-example-default-output-audio-group]
-volume-control = create:default-output-volume-control
-mute-control = create:call-downlink-mute-control
-
-[AudioGroup x-example-music-output-audio-group]
-volume-control = bind:AudioGroup:x-example-default-output-audio-group
-mute-control = bind:AudioGroup:x-example-default-output-audio-group
-
-[StreamRule phone-output]
-match = (direction output AND property media.role=phone)
-audio-group-for-volume = x-example-call-downlink-audio-group
-audio-group-for-mute = x-example-call-downlink-audio-group
-
-[StreamRule music-output]
-match = (direction output AND property media.role=music)
-audio-group-for-volume = x-example-music-output-audio-group
-audio-group-for-mute = x-example-music-output-audio-group
-
-[StreamRule default-output]
-match = (direction output)
-audio-group-for-volume = x-example-default-output-audio-group
-audio-group-for-mute = x-example-default-output-audio-group
diff --git a/src/modules/audio-groups/module-audio-groups.c b/src/modules/audio-groups/module-audio-groups.c
deleted file mode 100644 (file)
index e37a24e..0000000
+++ /dev/null
@@ -1,2078 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/dynarray.h>
-#include <pulsecore/module.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/conf-parser.h>
-#include <pulsecore/hashmap.h>
-
-#include <modules/volume-api/sstream.h>
-#include <modules/volume-api/volume-control.h>
-#include <modules/volume-api/audio-group.h>
-
-#include "module-audio-groups-symdef.h"
-
-#define AUDIOGROUP_START "AudioGroup "
-#define STREAM_RULE_START "StreamRule "
-#define NONE_KEYWORD "none"
-#define CREATE_PREFIX "create:"
-#define BIND_PREFIX "bind:"
-#define BIND_AUDIO_GROUP_PREFIX BIND_PREFIX "AudioGroup:"
-
-PA_MODULE_AUTHOR("Ismo Puustinen");
-PA_MODULE_DESCRIPTION("Create audio groups and classify streams to them");
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(true);
-
-enum match_direction {
-    match_direction_unknown = 0,
-    match_direction_input,
-    match_direction_output,
-};
-
-/* logical expressions */
-
-struct literal {
-
-    /* TODO: this might be parsed to some faster-to-check format? */
-
-    char *property_name;
-    char *property_value;
-    enum match_direction stream_direction;
-
-    bool negation;
-    PA_LLIST_FIELDS(struct literal);
-};
-
-struct conjunction {
-    /* a conjunction of literals */
-    PA_LLIST_HEAD(struct literal, literals);
-    PA_LLIST_FIELDS(struct conjunction);
-};
-
-struct expression {
-    /* this is in disjunctive normal form, so a disjunction of conjunctions */
-    PA_LLIST_HEAD(struct conjunction, conjunctions);
-};
-
-struct group {
-    struct userdata *userdata;
-    pa_audio_group *audio_group;
-    struct control *volume_control;
-    struct control *mute_control;
-    char *own_volume_control_name;
-    char *own_mute_control_name;
-    struct group *volume_master;
-    struct group *mute_master;
-    char *volume_master_name;
-    char *mute_master_name;
-
-    pa_hashmap *volume_slaves; /* struct group -> struct group (hashmap-as-a-set) */
-    pa_hashmap *mute_slaves; /* struct group -> struct group (hashmap-as-a-set) */
-    pa_hashmap *volume_stream_rules; /* struct stream_rule -> struct stream_rule (hashmap-as-a-set) */
-    pa_hashmap *mute_stream_rules; /* struct stream_rule -> struct stream_rule (hashmap-as-a-set) */
-
-    bool unlinked;
-};
-
-enum control_type {
-    CONTROL_TYPE_VOLUME,
-    CONTROL_TYPE_MUTE,
-};
-
-struct control {
-    struct userdata *userdata;
-    enum control_type type;
-
-    union {
-        pa_volume_control *volume_control;
-        pa_mute_control *mute_control;
-    };
-
-    /* Controls that are created for streams don't own their pa_volume_control
-     * and pa_mute_control objects, because they're owned by the streams. */
-    bool own_control;
-
-    /* If non-NULL, then this control mirrors the state of the master
-     * control. If someone changes the master state, the state of this control
-     * is also updated, and also if someone changes this control's state, the
-     * change is applied also to the master. */
-    struct control *master;
-
-    /* struct control -> struct control (hashmap-as-a-set)
-     * Contains the controls that have this control as their master. */
-    pa_hashmap *slaves;
-
-    /* Set to true when the master control's state has been copied to this
-     * control. */
-    bool synced_with_master;
-
-    bool acquired;
-    bool unlinked;
-};
-
-struct stream_rule {
-    struct userdata *userdata;
-    char *name;
-    enum match_direction direction;
-    char *audio_group_name_for_volume;
-    char *audio_group_name_for_mute;
-    struct group *group_for_volume;
-    struct group *group_for_mute;
-    struct expression *match_expression;
-};
-
-struct userdata {
-    pa_volume_api *volume_api;
-    pa_hashmap *groups; /* name -> struct group */
-    pa_hashmap *stream_rules; /* name -> struct stream_rule */
-    pa_dynarray *stream_rules_list; /* struct stream_rule */
-
-    /* pas_stream -> struct stream_rule
-     * When a stream matches with a rule, it's added here. */
-    pa_hashmap *rules_by_stream;
-
-    /* pas_stream -> struct control
-     * Contains proxy controls for all relative volume controls of streams. */
-    pa_hashmap *stream_volume_controls;
-
-    /* pas_stream -> struct control
-     * Contains proxy controls for all mute controls of streams. */
-    pa_hashmap *stream_mute_controls;
-
-    pa_hook_slot *stream_put_slot;
-    pa_hook_slot *stream_unlink_slot;
-    pa_hook_slot *volume_control_implementation_initialized_slot;
-    pa_hook_slot *mute_control_implementation_initialized_slot;
-    pa_hook_slot *volume_control_set_initial_volume_slot;
-    pa_hook_slot *mute_control_set_initial_mute_slot;
-    pa_hook_slot *volume_control_volume_changed_slot;
-    pa_hook_slot *mute_control_mute_changed_slot;
-    pa_hook_slot *volume_control_unlink_slot;
-    pa_hook_slot *mute_control_unlink_slot;
-
-    pa_dynarray *stream_rule_names; /* Only used during initialization. */
-};
-
-static const char* const valid_modargs[] = {
-    "filename",
-    NULL
-};
-
-static void control_free(struct control *control);
-static void control_set_master(struct control *control, struct control *master);
-static void control_add_slave(struct control *control, struct control *slave);
-static void control_remove_slave(struct control *control, struct control *slave);
-
-static void group_free(struct group *group);
-static void group_set_master(struct group *group, enum control_type type, struct group *master);
-static int group_set_master_name(struct group *group, enum control_type type, const char *name);
-static void group_disable_control(struct group *group, enum control_type type);
-static void group_add_slave(struct group *group, enum control_type type, struct group *slave);
-static void group_remove_slave(struct group *group, enum control_type type, struct group *slave);
-
-static void stream_rule_set_group(struct stream_rule *rule, enum control_type type, struct group *group);
-static void stream_rule_set_group_name(struct stream_rule *rule, enum control_type type, const char *name);
-
-static bool literal_match(struct literal *literal, pas_stream *stream);
-
-static struct expression *expression_new(void);
-static void expression_free(struct expression *expression);
-
-static int volume_control_set_volume_cb(pa_volume_control *volume_control, const pa_bvolume *original_volume,
-                                        const pa_bvolume *remapped_volume, bool set_volume, bool set_balance) {
-    struct control *control;
-    struct control *slave;
-    void *state;
-
-    pa_assert(volume_control);
-    pa_assert(original_volume);
-    pa_assert(remapped_volume);
-
-    control = volume_control->userdata;
-
-    /* There are four cases that need to be considered:
-     *
-     * 1) The master control is propagating the volume to this control. We need
-     * to propagate the volume downstream.
-     *
-     * 2) This control was just assigned a master control and the volume hasn't
-     * yet been synchronized. In this case the volume that is now being set for
-     * this control is the master control's volume. We need to propagate the
-     * volume downstream.
-     *
-     * 3) Someone set the volume directly for this control, and this control
-     * has a master control. We need to propagate the volume upstream, and wait
-     * for another call that will fall under the case 1.
-     *
-     * 4) Someone set the volume directly for this control, and this control
-     * doesn't have a master control. We need to propagate the volume
-     * downstream.
-     *
-     * As we can see, the action is the same in cases 1, 2 and 4. */
-
-    /* Case 3. */
-    if (control->synced_with_master && !control->master->volume_control->set_volume_in_progress) {
-        pa_volume_control_set_volume(control->master->volume_control, original_volume, set_volume, set_balance);
-        return 0;
-    }
-
-    /* Cases 1, 2 and 4. */
-    PA_HASHMAP_FOREACH(slave, control->slaves, state)
-        pa_volume_control_set_volume(slave->volume_control, original_volume, set_volume, set_balance);
-
-    return 0;
-}
-
-static int mute_control_set_mute_cb(pa_mute_control *mute_control, bool mute) {
-    struct control *control;
-    struct control *slave;
-    void *state;
-
-    pa_assert(mute_control);
-
-    control = mute_control->userdata;
-
-    /* There are four cases that need to be considered:
-     *
-     * 1) The master control is propagating the mute to this control. We need
-     * to propagate the mute downstream.
-     *
-     * 2) This control was just assigned a master control and the mute hasn't
-     * yet been synchronized. In this case the mute that is now being set for
-     * this control is the master control's mute. We need to propagate the mute
-     * downstream.
-     *
-     * 3) Someone set the mute directly for this control, and this control has
-     * a master control. We need to propagate the mute upstream, and wait for
-     * another call that will fall under the case 1.
-     *
-     * 4) Someone set the mute directly for this control, and this control
-     * doesn't have a master control. We need to propagate the mute downstream.
-     *
-     * As we can see, the action is the same in cases 1, 2 and 4. */
-
-    /* Case 3. */
-    if (control->synced_with_master && !control->master->mute_control->set_mute_in_progress) {
-        pa_mute_control_set_mute(control->master->mute_control, mute);
-        return 0;
-    }
-
-    /* Cases 1, 2 and 4. */
-    PA_HASHMAP_FOREACH(slave, control->slaves, state)
-        pa_mute_control_set_mute(slave->mute_control, mute);
-
-    return 0;
-}
-
-static int control_new_for_group(struct group *group, enum control_type type, const char *name, bool persistent, struct control **_r) {
-    struct control *control = NULL;
-    int r = 0;
-
-    pa_assert(group);
-    pa_assert(name);
-    pa_assert(_r);
-
-    control = pa_xnew0(struct control, 1);
-    control->userdata = group->userdata;
-    control->type = type;
-    control->slaves = pa_hashmap_new(NULL, NULL);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            if (persistent)
-                control->volume_control = pa_hashmap_get(control->userdata->volume_api->volume_controls, name);
-
-            if (!control->volume_control) {
-                r = pa_volume_control_new(control->userdata->volume_api, name, persistent, &control->volume_control);
-                if (r < 0)
-                    goto fail;
-            }
-
-            pa_volume_control_set_convertible_to_dB(control->volume_control, true);
-
-            if (persistent) {
-                r = pa_volume_control_acquire_for_audio_group(control->volume_control, group->audio_group,
-                                                              volume_control_set_volume_cb, control);
-                if (r < 0)
-                    goto fail;
-
-                control->acquired = true;
-            } else {
-                control->volume_control->set_volume = volume_control_set_volume_cb;
-                control->volume_control->userdata = control;
-            }
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (persistent)
-                control->mute_control = pa_hashmap_get(control->userdata->volume_api->mute_controls, name);
-
-            if (!control->mute_control) {
-                r = pa_mute_control_new(control->userdata->volume_api, name, persistent, &control->mute_control);
-                if (r < 0)
-                    goto fail;
-            }
-
-            if (persistent) {
-                r = pa_mute_control_acquire_for_audio_group(control->mute_control, group->audio_group,
-                                                            mute_control_set_mute_cb, control);
-                if (r < 0)
-                    goto fail;
-
-                control->acquired = true;
-            } else {
-                control->mute_control->set_mute = mute_control_set_mute_cb;
-                control->mute_control->userdata = control;
-            }
-            break;
-    }
-
-    control->own_control = true;
-
-    *_r = control;
-    return 0;
-
-fail:
-    if (control)
-        control_free(control);
-
-    return r;
-}
-
-static struct control *control_new_for_stream(struct userdata *u, enum control_type type, pas_stream *stream) {
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    control = pa_xnew0(struct control, 1);
-    control->userdata = u;
-    control->type = type;
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            control->volume_control = stream->relative_volume_control;
-            pa_assert(control->volume_control);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            control->mute_control = stream->mute_control;
-            pa_assert(control->mute_control);
-            break;
-    }
-
-    return control;
-}
-
-static void control_put(struct control *control) {
-    pa_assert(control);
-
-    switch (control->type) {
-        case CONTROL_TYPE_VOLUME:
-            if (control->own_control && !control->volume_control->linked)
-                pa_volume_control_put(control->volume_control);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (control->own_control && !control->mute_control->linked)
-                pa_mute_control_put(control->mute_control);
-            break;
-    }
-}
-
-static void control_unlink(struct control *control) {
-    pa_assert(control);
-
-    if (control->unlinked)
-        return;
-
-    control->unlinked = true;
-
-    if (control->slaves) {
-        struct control *slave;
-
-        while ((slave = pa_hashmap_first(control->slaves)))
-            control_set_master(slave, NULL);
-    }
-
-    control_set_master(control, NULL);
-
-    switch (control->type) {
-        case CONTROL_TYPE_VOLUME:
-            if (control->own_control && control->volume_control && !control->volume_control->persistent)
-                pa_volume_control_unlink(control->volume_control);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (control->own_control && control->mute_control && !control->mute_control->persistent)
-                pa_mute_control_unlink(control->mute_control);
-            break;
-    }
-}
-
-static void control_free(struct control *control) {
-    pa_assert(control);
-
-    if (!control->unlinked)
-        control_unlink(control);
-
-    if (control->slaves) {
-        pa_assert(pa_hashmap_isempty(control->slaves));
-        pa_hashmap_free(control->slaves);
-    }
-
-    switch (control->type) {
-        case CONTROL_TYPE_VOLUME:
-            if (control->acquired)
-                pa_volume_control_release(control->volume_control);
-
-            if (control->own_control && control->volume_control && !control->volume_control->persistent)
-                pa_volume_control_free(control->volume_control);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (control->acquired)
-                pa_mute_control_release(control->mute_control);
-
-            if (control->own_control && control->mute_control && !control->mute_control->persistent)
-                pa_mute_control_free(control->mute_control);
-            break;
-    }
-
-    pa_xfree(control);
-}
-
-static void control_set_master(struct control *control, struct control *master) {
-    struct control *old_master;
-
-    pa_assert(control);
-    pa_assert(!master || master->type == control->type);
-
-    old_master = control->master;
-
-    if (master == old_master)
-        return;
-
-    if (old_master) {
-        control_remove_slave(old_master, control);
-        control->synced_with_master = false;
-    }
-
-    control->master = master;
-
-    if (master) {
-        control_add_slave(master, control);
-
-        switch (control->type) {
-            case CONTROL_TYPE_VOLUME:
-                pa_volume_control_set_volume(control->volume_control, &master->volume_control->volume, true, true);
-                break;
-
-            case CONTROL_TYPE_MUTE:
-                pa_mute_control_set_mute(control->mute_control, master->mute_control->mute);
-                break;
-        }
-
-        control->synced_with_master = true;
-    }
-}
-
-static void control_add_slave(struct control *control, struct control *slave) {
-    pa_assert(control);
-    pa_assert(slave);
-
-    pa_assert_se(pa_hashmap_put(control->slaves, slave, slave) >= 0);
-}
-
-static void control_remove_slave(struct control *control, struct control *slave) {
-    pa_assert(control);
-    pa_assert(slave);
-
-    pa_assert_se(pa_hashmap_remove(control->slaves, slave));
-}
-
-static int group_new(struct userdata *u, const char *name, struct group **_r) {
-    struct group *group = NULL;
-    int r;
-    struct group *slave;
-    struct stream_rule *rule;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(name);
-    pa_assert(_r);
-
-    group = pa_xnew0(struct group, 1);
-    group->userdata = u;
-
-    r = pa_audio_group_new(u->volume_api, name, &group->audio_group);
-    if (r < 0)
-        goto fail;
-
-    group->volume_slaves = pa_hashmap_new(NULL, NULL);
-    group->mute_slaves = pa_hashmap_new(NULL, NULL);
-    group->volume_stream_rules = pa_hashmap_new(NULL, NULL);
-    group->mute_stream_rules = pa_hashmap_new(NULL, NULL);
-
-    PA_HASHMAP_FOREACH(slave, u->groups, state) {
-        if (slave == group)
-            continue;
-
-        if (pa_safe_streq(slave->volume_master_name, group->audio_group->name))
-            group_set_master(slave, CONTROL_TYPE_VOLUME, group);
-
-        if (pa_safe_streq(slave->mute_master_name, group->audio_group->name))
-            group_set_master(slave, CONTROL_TYPE_MUTE, group);
-    }
-
-    PA_HASHMAP_FOREACH(rule, u->stream_rules, state) {
-        if (pa_safe_streq(rule->audio_group_name_for_volume, group->audio_group->name))
-            stream_rule_set_group(rule, CONTROL_TYPE_VOLUME, group);
-
-        if (pa_safe_streq(rule->audio_group_name_for_mute, group->audio_group->name))
-            stream_rule_set_group(rule, CONTROL_TYPE_MUTE, group);
-    }
-
-    *_r = group;
-    return 0;
-
-fail:
-    if (group)
-        group_free(group);
-
-    return r;
-}
-
-static void group_put(struct group *group) {
-    pa_assert(group);
-
-    pa_audio_group_put(group->audio_group);
-
-    if (group->volume_control)
-        control_put(group->volume_control);
-
-    if (group->mute_control)
-        control_put(group->mute_control);
-}
-
-static void group_unlink(struct group *group) {
-    struct stream_rule *rule;
-    struct group *slave;
-    void *state;
-
-    pa_assert(group);
-
-    if (group->unlinked)
-        return;
-
-    group->unlinked = true;
-
-    PA_HASHMAP_FOREACH(rule, group->volume_stream_rules, state)
-        stream_rule_set_group(rule, CONTROL_TYPE_VOLUME, NULL);
-
-    PA_HASHMAP_FOREACH(rule, group->mute_stream_rules, state)
-        stream_rule_set_group(rule, CONTROL_TYPE_MUTE, NULL);
-
-    PA_HASHMAP_FOREACH(slave, group->volume_slaves, state)
-        group_set_master(slave, CONTROL_TYPE_VOLUME, NULL);
-
-    PA_HASHMAP_FOREACH(slave, group->mute_slaves, state)
-        group_set_master(slave, CONTROL_TYPE_MUTE, NULL);
-
-    group_disable_control(group, CONTROL_TYPE_MUTE);
-    group_disable_control(group, CONTROL_TYPE_VOLUME);
-
-    if (group->audio_group)
-        pa_audio_group_unlink(group->audio_group);
-}
-
-static void group_free(struct group *group) {
-    pa_assert(group);
-
-    group_unlink(group);
-
-    if (group->mute_stream_rules) {
-        pa_assert(pa_hashmap_isempty(group->mute_stream_rules));
-        pa_hashmap_free(group->mute_stream_rules);
-    }
-
-    if (group->volume_stream_rules) {
-        pa_assert(pa_hashmap_isempty(group->volume_stream_rules));
-        pa_hashmap_free(group->volume_stream_rules);
-    }
-
-    if (group->mute_slaves) {
-        pa_assert(pa_hashmap_isempty(group->mute_slaves));
-        pa_hashmap_free(group->mute_slaves);
-    }
-
-    if (group->volume_slaves) {
-        pa_assert(pa_hashmap_isempty(group->volume_slaves));
-        pa_hashmap_free(group->volume_slaves);
-    }
-
-    pa_assert(!group->mute_master_name);
-    pa_assert(!group->volume_master_name);
-    pa_assert(!group->mute_master);
-    pa_assert(!group->volume_master);
-    pa_assert(!group->mute_control);
-    pa_assert(!group->volume_control);
-
-    if (group->audio_group)
-        pa_audio_group_free(group->audio_group);
-
-    pa_xfree(group);
-}
-
-static void group_set_own_control_name(struct group *group, enum control_type type, const char *name) {
-    struct group *slave;
-    void *state;
-
-    pa_assert(group);
-
-    if (name)
-        group_set_master_name(group, type, NULL);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            if (pa_safe_streq(name, group->own_volume_control_name))
-                return;
-
-            if (group->volume_control) {
-                control_free(group->volume_control);
-                group->volume_control = NULL;
-            }
-
-            pa_xfree(group->own_volume_control_name);
-            group->own_volume_control_name = pa_xstrdup(name);
-
-            if (name) {
-                control_new_for_group(group, CONTROL_TYPE_VOLUME, name, true, &group->volume_control);
-
-                PA_HASHMAP_FOREACH(slave, group->volume_slaves, state) {
-                    if (slave->volume_control)
-                        control_set_master(slave->volume_control, group->volume_control);
-                }
-            }
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (pa_safe_streq(name, group->own_mute_control_name))
-                return;
-
-            if (group->mute_control) {
-                control_free(group->mute_control);
-                group->mute_control = NULL;
-            }
-
-            pa_xfree(group->own_mute_control_name);
-            group->own_mute_control_name = pa_xstrdup(name);
-
-            if (name) {
-                control_new_for_group(group, CONTROL_TYPE_MUTE, name, true, &group->mute_control);
-
-                PA_HASHMAP_FOREACH(slave, group->mute_slaves, state) {
-                    if (slave->mute_control)
-                        control_set_master(slave->mute_control, group->mute_control);
-                }
-            }
-            break;
-    }
-}
-
-static void group_set_master(struct group *group, enum control_type type, struct group *master) {
-    struct group *old_master;
-    struct control *master_control = NULL;
-
-    pa_assert(group);
-    pa_assert(master != group);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            old_master = group->volume_master;
-
-            if (master == old_master)
-                return;
-
-            if (old_master)
-                group_remove_slave(old_master, CONTROL_TYPE_VOLUME, group);
-
-            group->volume_master = master;
-
-            if (master)
-                group_add_slave(master, CONTROL_TYPE_VOLUME, group);
-
-            if (group->volume_control) {
-                if (master)
-                    master_control = master->volume_control;
-
-                control_set_master(group->volume_control, master_control);
-            }
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            old_master = group->mute_master;
-
-            if (master == old_master)
-                return;
-
-            if (old_master)
-                group_remove_slave(old_master, CONTROL_TYPE_MUTE, group);
-
-            group->mute_master = master;
-
-            if (master)
-                group_add_slave(master, CONTROL_TYPE_MUTE, group);
-
-            if (group->mute_control) {
-                if (master)
-                    master_control = master->volume_control;
-
-                control_set_master(group->volume_control, master_control);
-            }
-            break;
-    }
-}
-
-static int group_set_master_name(struct group *group, enum control_type type, const char *name) {
-    struct group *slave;
-    void *state;
-    struct group *master = NULL;
-
-    pa_assert(group);
-
-    if (pa_safe_streq(name, group->audio_group->name)) {
-        pa_log("Can't bind audio group control to itself.");
-        return -PA_ERR_INVALID;
-    }
-
-    if (name)
-        group_set_own_control_name(group, type, NULL);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            if (pa_safe_streq(name, group->volume_master_name))
-                return 0;
-
-            pa_xfree(group->volume_master_name);
-            group->volume_master_name = pa_xstrdup(name);
-
-            if (name && !group->volume_control) {
-                control_new_for_group(group, CONTROL_TYPE_VOLUME, "audio-group-volume-control", false, &group->volume_control);
-
-                PA_HASHMAP_FOREACH(slave, group->volume_slaves, state) {
-                    if (slave->volume_control)
-                        control_set_master(slave->volume_control, group->volume_control);
-                }
-
-            } else if (!name && group->volume_control) {
-                control_free(group->volume_control);
-                group->volume_control = NULL;
-            }
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (pa_safe_streq(name, group->mute_master_name))
-                return 0;
-
-            pa_xfree(group->mute_master_name);
-            group->mute_master_name = pa_xstrdup(name);
-
-            if (name && !group->mute_control) {
-                control_new_for_group(group, CONTROL_TYPE_MUTE, "audio-group-mute-control", false, &group->mute_control);
-
-                PA_HASHMAP_FOREACH(slave, group->mute_slaves, state) {
-                    if (slave->mute_control)
-                        control_set_master(slave->mute_control, group->mute_control);
-                }
-
-            } else if (!name && group->mute_control) {
-                control_free(group->mute_control);
-                group->mute_control = NULL;
-            }
-            break;
-    }
-
-    if (name)
-        master = pa_hashmap_get(group->userdata->groups, name);
-
-    group_set_master(group, type, master);
-
-    return 0;
-}
-
-static void group_disable_control(struct group *group, enum control_type type) {
-    pa_assert(group);
-
-    group_set_own_control_name(group, type, NULL);
-    group_set_master_name(group, type, NULL);
-}
-
-static void group_add_slave(struct group *group, enum control_type type, struct group *slave) {
-    pa_assert(group);
-    pa_assert(slave);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            pa_assert_se(pa_hashmap_put(group->volume_slaves, slave, slave) >= 0);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            pa_assert_se(pa_hashmap_put(group->mute_slaves, slave, slave) >= 0);
-            break;
-    }
-}
-
-static void group_remove_slave(struct group *group, enum control_type type, struct group *slave) {
-    pa_assert(group);
-    pa_assert(slave);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            pa_assert_se(pa_hashmap_remove(group->volume_slaves, slave));
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            pa_assert_se(pa_hashmap_remove(group->mute_slaves, slave));
-    }
-}
-
-static void group_add_stream_rule(struct group *group, enum control_type type, struct stream_rule *rule) {
-    pa_assert(group);
-    pa_assert(rule);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            pa_assert_se(pa_hashmap_put(group->volume_stream_rules, rule, rule) >= 0);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            pa_assert_se(pa_hashmap_put(group->mute_stream_rules, rule, rule) >= 0);
-            break;
-    }
-}
-
-static void group_remove_stream_rule(struct group *group, enum control_type type, struct stream_rule *rule) {
-    pa_assert(group);
-    pa_assert(rule);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            pa_assert_se(pa_hashmap_remove(group->volume_stream_rules, rule));
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            pa_assert_se(pa_hashmap_remove(group->mute_stream_rules, rule));
-            break;
-    }
-}
-
-static struct stream_rule *stream_rule_new(struct userdata *u, const char *name) {
-    struct stream_rule *rule;
-
-    pa_assert(u);
-    pa_assert(name);
-
-    rule = pa_xnew0(struct stream_rule, 1);
-    rule->userdata = u;
-    rule->name = pa_xstrdup(name);
-    rule->direction = match_direction_unknown;
-    rule->match_expression = expression_new();
-
-    return rule;
-}
-
-static void stream_rule_free(struct stream_rule *rule) {
-    pa_assert(rule);
-
-    if (rule->match_expression)
-        expression_free(rule->match_expression);
-
-    stream_rule_set_group_name(rule, CONTROL_TYPE_MUTE, NULL);
-    stream_rule_set_group_name(rule, CONTROL_TYPE_VOLUME, NULL);
-    pa_xfree(rule->name);
-    pa_xfree(rule);
-}
-
-static void stream_rule_set_match_expression(struct stream_rule *rule, struct expression *expression) {
-    pa_assert(rule);
-    pa_assert(expression);
-
-    if (rule->match_expression)
-        expression_free(rule->match_expression);
-
-    rule->match_expression = expression;
-}
-
-static void stream_rule_set_group(struct stream_rule *rule, enum control_type type, struct group *group) {
-    pa_assert(rule);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            if (group == rule->group_for_volume)
-                return;
-
-            if (rule->group_for_volume)
-                group_remove_stream_rule(rule->group_for_volume, CONTROL_TYPE_VOLUME, rule);
-
-            rule->group_for_volume = group;
-
-            if (group)
-                group_add_stream_rule(group, CONTROL_TYPE_VOLUME, rule);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            if (group == rule->group_for_mute)
-                return;
-
-            if (rule->group_for_mute)
-                group_remove_stream_rule(rule->group_for_mute, CONTROL_TYPE_MUTE, rule);
-
-            rule->group_for_mute = group;
-
-            if (group)
-                group_add_stream_rule(group, CONTROL_TYPE_MUTE, rule);
-            break;
-    }
-}
-
-static void stream_rule_set_group_name(struct stream_rule *rule, enum control_type type, const char *name) {
-    struct group *group = NULL;
-
-    pa_assert(rule);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            pa_xfree(rule->audio_group_name_for_volume);
-            rule->audio_group_name_for_volume = pa_xstrdup(name);
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            pa_xfree(rule->audio_group_name_for_mute);
-            rule->audio_group_name_for_mute = pa_xstrdup(name);
-            break;
-    }
-
-    if (name)
-        group = pa_hashmap_get(rule->userdata->groups, name);
-
-    stream_rule_set_group(rule, type, group);
-}
-
-static bool stream_rule_match(struct stream_rule *rule, pas_stream *stream) {
-    struct conjunction *c;
-
-    PA_LLIST_FOREACH(c, rule->match_expression->conjunctions) {
-        struct literal *l;
-        bool and_success = true;
-        PA_LLIST_FOREACH(l, c->literals) {
-            if (!literal_match(l, stream)) {
-                /* at least one fail for conjunction */
-                and_success = false;
-                break;
-            }
-        }
-
-        if (and_success) {
-            /* at least one match for disjunction */
-            return true;
-        }
-    }
-
-    /* no matches */
-    return false;
-}
-
-/* stream classification */
-
-static bool literal_match(struct literal *literal, pas_stream *stream) {
-
-    if (literal->stream_direction != match_direction_unknown) {
-        /* check the stream direction; _sink inputs_ are always _outputs_ */
-
-        if ((stream->direction == PA_DIRECTION_OUTPUT && literal->stream_direction == match_direction_output) ||
-            (stream->direction == PA_DIRECTION_INPUT && literal->stream_direction == match_direction_input)) {
-            return literal->negation ? false : true;
-        }
-    }
-    else if (literal->property_name && literal->property_value) {
-        /* check the property from the property list */
-
-        if (pa_proplist_contains(stream->proplist, literal->property_name)) {
-            const char *prop = pa_proplist_gets(stream->proplist, literal->property_name);
-
-            if (prop && strcmp(prop, literal->property_value) == 0)
-                return literal->negation ? false : true;
-        }
-    }
-
-    /* no match */
-    return literal->negation ? true : false;
-}
-
-static pa_hook_result_t stream_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pas_stream *stream = call_data;
-    struct stream_rule *rule;
-    unsigned idx;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    PA_DYNARRAY_FOREACH(rule, u->stream_rules_list, idx) {
-        if (stream_rule_match(rule, stream)) {
-            pa_hashmap_put(u->rules_by_stream, stream, rule);
-            break;
-        }
-    }
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t stream_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pas_stream *stream = call_data;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    pa_hashmap_remove(u->rules_by_stream, stream);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t volume_control_implementation_initialized_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *volume_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(volume_control);
-
-    if (volume_control->purpose != PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME)
-        return PA_HOOK_OK;
-
-    control = control_new_for_stream(u, CONTROL_TYPE_VOLUME, volume_control->owner_stream);
-    control_put(control);
-    pa_assert_se(pa_hashmap_put(u->stream_volume_controls, volume_control->owner_stream, control) >= 0);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_implementation_initialized_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *mute_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(mute_control);
-
-    if (mute_control->purpose != PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE)
-        return PA_HOOK_OK;
-
-    control = control_new_for_stream(u, CONTROL_TYPE_MUTE, mute_control->owner_stream);
-    control_put(control);
-    pa_assert_se(pa_hashmap_put(u->stream_mute_controls, mute_control->owner_stream, control) >= 0);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t volume_control_set_initial_volume_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *volume_control = call_data;
-    struct stream_rule *rule;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(volume_control);
-
-    if (volume_control->purpose != PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME)
-        return PA_HOOK_OK;
-
-    rule = pa_hashmap_get(u->rules_by_stream, volume_control->owner_stream);
-    if (!rule)
-        return PA_HOOK_OK;
-
-    if (!rule->group_for_volume)
-        return PA_HOOK_OK;
-
-    if (!rule->group_for_volume->volume_control)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_get(u->stream_volume_controls, volume_control->owner_stream);
-    pa_assert(control);
-    pa_assert(control->volume_control == volume_control);
-
-    /* This will set the volume for volume_control. */
-    control_set_master(control, rule->group_for_volume->volume_control);
-
-    return PA_HOOK_STOP;
-}
-
-static pa_hook_result_t mute_control_set_initial_mute_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *mute_control = call_data;
-    struct stream_rule *rule;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(mute_control);
-
-    if (mute_control->purpose != PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE)
-        return PA_HOOK_OK;
-
-    rule = pa_hashmap_get(u->rules_by_stream, mute_control->owner_stream);
-    if (!rule)
-        return PA_HOOK_OK;
-
-    if (!rule->group_for_mute)
-        return PA_HOOK_OK;
-
-    if (!rule->group_for_mute->mute_control)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_get(u->stream_mute_controls, mute_control->owner_stream);
-    pa_assert(control);
-    pa_assert(control->mute_control == mute_control);
-
-    /* This will set the mute for mute_control. */
-    control_set_master(control, rule->group_for_mute->mute_control);
-
-    return PA_HOOK_STOP;
-}
-
-static pa_hook_result_t volume_control_volume_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *volume_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(volume_control);
-
-    if (volume_control->purpose != PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_get(u->stream_volume_controls, volume_control->owner_stream);
-    if (!control)
-        return PA_HOOK_OK;
-
-    if (!control->master)
-        return PA_HOOK_OK;
-
-    pa_volume_control_set_volume(control->master->volume_control, &volume_control->volume, true, true);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_mute_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *mute_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(mute_control);
-
-    if (mute_control->purpose != PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_get(u->stream_mute_controls, mute_control->owner_stream);
-    if (!control)
-        return PA_HOOK_OK;
-
-    if (!control->master)
-        return PA_HOOK_OK;
-
-    pa_mute_control_set_mute(control->master->mute_control, mute_control->mute);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t volume_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *volume_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(volume_control);
-
-    if (volume_control->purpose != PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_remove(u->stream_volume_controls, volume_control->owner_stream);
-    if (!control)
-        return PA_HOOK_OK;
-
-    control_free(control);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *mute_control = call_data;
-    struct control *control;
-
-    pa_assert(u);
-    pa_assert(mute_control);
-
-    if (mute_control->purpose != PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE)
-        return PA_HOOK_OK;
-
-    control = pa_hashmap_remove(u->stream_mute_controls, mute_control->owner_stream);
-    if (!control)
-        return PA_HOOK_OK;
-
-    control_free(control);
-
-    return PA_HOOK_OK;
-}
-
-/* parser for configuration file */
-
-/*
-    Parse the match expression. The syntax is this:
-
-    OPER           := "AND" | "OR"
-    OPEN_BRACE     := "("
-    CLOSE_BRACE    := ")"
-    EXPR           := OPEN_BRACE EXPR OPER EXPR CLOSE_BRACE | VAR
-    VAR            := LIT | "NEG" LIT
-    LIT            := PREDICATE (defined by rule semantics)
-
-    In addition there is a requirement that the expressions need to be in
-    disjunctive normal form. It means that if there is an expression that
-    has AND operator, there may not be any OR operators in its subexpressions.
-
-    Example expressions:
-
-    (foo)
-    (foo AND bar)
-    (foo OR (bar AND xxx))
-    (NEG foo OR (bar AND NEG xxx))
-
-    The predicate here is the single rule that is matched against the new sink
-    input. The syntax is this:
-
-    PREDICATE      := "direction" DIRECTION  | "property" PROPERTY
-    DIRECTION      := "input" | "output"
-    PROPERTY       := PROPERTY_NAME "=" PROPERTY_VALUE
-    PROPERTY_NAME  := STRING
-    PROPERTY_VALUE := STRING
-
-    The allowed characters for STRING are standard ascii characters. Not
-    allowed substrings are the reserved words "AND", "OR", "(", ")", "NEG" and
-    "=".
-
-    Complete examples:
-
-    (property application.process.binary=paplay)
-
-    (property media.role=music AND direction input)
-
-    (property application.process.binary=paplay OR (direction input OR direction output))
-*/
-
-#if 0
-static void print_literal(struct literal *l) {
-    if (l->stream_direction != match_direction_unknown) {
-        pa_log_info("       %sstream direction %s",
-                l->negation ? "NEG " : "",
-                l->stream_direction == match_direction_input ? "input" : "output");
-    }
-    else {
-        pa_log_info("       %sproperty %s == %s",
-                l->negation ? "NEG " : "",
-                l->property_name ? l->property_name : "NULL",
-                l->property_value ? l->property_value : "NULL");
-    }
-}
-
-static void print_conjunction(struct conjunction *c) {
-    struct literal *l;
-    pa_log_info("   conjunction for literals:");
-    PA_LLIST_FOREACH(l, c->literals) {
-        print_literal(l);
-    }
-}
-
-static void print_expression(struct expression *e) {
-    struct conjunction *c;
-    pa_log_info("disjunction for conjunctions:");
-    PA_LLIST_FOREACH(c, e->conjunctions) {
-        print_conjunction(c);
-    }
-}
-#endif
-
-static void delete_literal(struct literal *l) {
-
-    if (!l)
-        return;
-
-    pa_xfree(l->property_name);
-    pa_xfree(l->property_value);
-    pa_xfree(l);
-}
-
-static void delete_conjunction(struct conjunction *c) {
-    struct literal *l;
-
-    if (!c)
-        return;
-
-    PA_LLIST_FOREACH(l, c->literals) {
-        delete_literal(l);
-    }
-
-    pa_xfree(c);
-}
-
-static struct expression *expression_new(void) {
-    struct expression *expression;
-
-    expression = pa_xnew0(struct expression, 1);
-
-    return expression;
-}
-
-static void expression_free(struct expression *expression) {
-    struct conjunction *c;
-
-    pa_assert(expression);
-
-    PA_LLIST_FOREACH(c, expression->conjunctions)
-        delete_conjunction(c);
-
-    pa_xfree(expression);
-}
-
-enum logic_operator {
-    operator_not_set = 0,
-    operator_and,
-    operator_or,
-};
-
-struct expression_token {
-    struct expression_token *left;
-    struct expression_token *right;
-
-    enum logic_operator oper;
-
-    struct literal_token *lit;
-};
-
-struct literal_token {
-    bool negation;
-    char *var;
-};
-
-static void delete_literal_token(struct literal_token *l) {
-
-    if (!l)
-        return;
-
-    pa_xfree(l->var);
-    pa_xfree(l);
-}
-
-static void delete_expression_token(struct expression_token *e) {
-
-    if (!e)
-        return;
-
-    delete_expression_token(e->left);
-    delete_expression_token(e->right);
-    delete_literal_token(e->lit);
-
-    e->left = NULL;
-    e->right = NULL;
-    e->lit = NULL;
-
-    pa_xfree(e);
-}
-
-static struct expression_token *parse_rule_internal(const char *rule, bool disjunction_allowed) {
-
-    int len = strlen(rule);
-    struct expression_token *et;
-    char *p;
-    int brace_count = 0;
-    bool braces_present = false;
-    char left_buf[len+1];
-    char right_buf[len+1];
-
-    et = pa_xnew0(struct expression_token, 1);
-
-    if (!et)
-        return NULL;
-
-    /* count the braces -- we want to find the case when there is only one brace open */
-
-    p = (char *) rule;
-
-    while (*p) {
-        if (*p == '(') {
-            braces_present = true;
-            brace_count++;
-        }
-        else if (*p == ')') {
-            brace_count--;
-        }
-
-        if (brace_count == 1) {
-
-            /* the parser is recursive and just goes down the tree on the
-             * topmost level (where the brace count is 1). If there are no
-             * braces this is a literal */
-
-            /* find the operator AND or OR */
-
-            if (strncmp(p, "AND", 3) == 0) {
-
-                /* copy parts */
-                char *begin_left = (char *) rule+1;
-                char *begin_right = p+3;
-
-                int left_len = p - rule - 1; /* minus '(' */
-                int right_len = len - 3 - left_len - 2; /* minus AND and '(' and ')'*/
-
-                memcpy(left_buf, begin_left, left_len);
-                left_buf[left_len] = '\0';
-                memcpy(right_buf, begin_right, right_len);
-                right_buf[right_len] = '\0';
-
-                et->left = parse_rule_internal(left_buf, false);
-                et->right = parse_rule_internal(right_buf, false);
-                et->oper = operator_and;
-
-                if (!et->left || !et->right) {
-                    delete_expression_token(et);
-                    return NULL;
-                }
-
-                return et;
-            }
-            else if (strncmp(p, "OR", 2) == 0) {
-
-                char *begin_left = (char *) rule+1;
-                char *begin_right = p+2;
-
-                int left_len = p - rule - 1; /* minus '(' */
-                int right_len = len - 2 - left_len - 2; /* minus OR and '(' and ')'*/
-
-                if (!disjunction_allowed) {
-                    pa_log_error("logic expression not in dnf");
-                    delete_expression_token(et);
-                    return NULL;
-                }
-
-                memcpy(left_buf, begin_left, left_len);
-                left_buf[left_len] = '\0';
-                memcpy(right_buf, begin_right, right_len);
-                right_buf[right_len] = '\0';
-
-                et->left = parse_rule_internal(left_buf, true);
-                et->right = parse_rule_internal(right_buf, true);
-                et->oper = operator_or;
-
-                if (!et->left || !et->right) {
-                    delete_expression_token(et);
-                    return NULL;
-                }
-
-                return et;
-            }
-            /* else a literal which is inside braces */
-        }
-
-        p++;
-    }
-
-    if (brace_count != 0) {
-        /* the input is not valid */
-        pa_log_error("mismatched braces in logic expression");
-        delete_expression_token(et);
-        return NULL;
-    }
-    else {
-        /* this is a literal */
-        char *begin_lit;
-        char buf[len+1];
-        struct literal_token *lit = pa_xnew0(struct literal_token, 1);
-
-        if (!lit) {
-            delete_expression_token(et);
-            return NULL;
-        }
-
-        if (braces_present) {
-            /* remove all braces */
-            char *k;
-            char *l;
-
-            k = (char *) rule;
-            l = buf;
-
-            while (*k) {
-                if (*k == '(' || *k == ')') {
-                    k++;
-                    continue;
-                }
-
-                *l = *k;
-                l++;
-                k++;
-            }
-            *l = '\0';
-        }
-        else {
-            strncpy(buf, rule, len);
-            buf[len] = '\0';
-        }
-
-        if (strncmp(buf, "NEG", 3) == 0) {
-            begin_lit = (char *) buf + 3;
-            lit->negation = true;
-        }
-        else {
-            begin_lit = (char *) buf;
-            lit->negation = false;
-        }
-
-        lit->var = pa_xstrdup(begin_lit);
-
-        et->lit = lit;
-    }
-
-    return et;
-}
-
-static bool gather_literal(struct expression_token *et, struct literal *l) {
-#define PROPERTY_KEYWORD "property"
-#define DIRECTION_KEYWORD "direction"
-#define DIRECTION_VALUE_INPUT "input"
-#define DIRECTION_VALUE_OUTPUT "output"
-
-    char *p = et->lit->var;
-    int len = strlen(et->lit->var);
-
-    l->negation = et->lit->negation;
-
-    if (strncmp(p, PROPERTY_KEYWORD, strlen(PROPERTY_KEYWORD)) == 0) {
-        char name[len];
-        char value[len];
-        int i = 0;
-
-        p += strlen(PROPERTY_KEYWORD);
-
-        /* parse the property pair: name=value */
-
-        while (*p && *p != '=') {
-            name[i++] = *p;
-            p++;
-        }
-
-        /* check if we really found '=' */
-
-        if (*p != '=') {
-            pa_log_error("property syntax broken for '%s'", et->lit->var);
-            goto error;
-        }
-
-        name[i] = '\0';
-
-        p++;
-        i = 0;
-
-        while (*p) {
-            value[i++] = *p;
-            p++;
-        }
-
-        value[i] = '\0';
-
-        l->property_name = pa_xstrdup(name);
-        l->property_value = pa_xstrdup(value);
-    }
-    else if (strncmp(p, DIRECTION_KEYWORD, strlen(DIRECTION_KEYWORD)) == 0) {
-        p += strlen(DIRECTION_KEYWORD);
-
-        if (strncmp(p, DIRECTION_VALUE_INPUT, strlen(DIRECTION_VALUE_INPUT)) == 0) {
-            l->stream_direction = match_direction_input;
-        }
-        else if (strncmp(p, DIRECTION_VALUE_OUTPUT, strlen(DIRECTION_VALUE_OUTPUT)) == 0) {
-            l->stream_direction = match_direction_output;
-        }
-        else {
-            pa_log_error("unknown direction(%s): %s", et->lit->var, p);
-            goto error;
-        }
-    }
-    else {
-        pa_log_error("not able to parse the value: '%s'", et->lit->var);
-        goto error;
-    }
-
-    return true;
-
-error:
-    return false;
-
-#undef DIRECTION_VALUE_OUTPUT
-#undef DIRECTION_VALUE_INPUT
-#undef DIRECTION_KEYWORD
-#undef PROPERTY_KEYWORD
-}
-
-static bool gather_conjunction(struct expression_token *et, struct conjunction *c) {
-
-    if (et->oper == operator_and) {
-        if (!gather_conjunction(et->left, c) ||
-            !gather_conjunction(et->right, c)) {
-            return false;
-        }
-    }
-    else {
-        /* literal */
-        struct literal *l = pa_xnew0(struct literal, 1);
-
-        if (!l)
-            return false;
-
-        if (!gather_literal(et, l)) {
-            pa_log_error("audio groups config: literal parsing failed");
-            delete_literal(l);
-            return false;
-        }
-
-        PA_LLIST_INIT(struct literal, l);
-        PA_LLIST_PREPEND(struct literal, c->literals, l);
-    }
-
-    return true;
-}
-
-static bool gather_expression(struct expression *e, struct expression_token *et) {
-
-    if (et->oper == operator_or) {
-        if (!gather_expression(e, et->right) ||
-            !gather_expression(e, et->left))
-            return false;
-    }
-    else {
-        /* conjunction or literal */
-        struct conjunction *c = pa_xnew0(struct conjunction, 1);
-
-        if (!c)
-            return false;
-
-        PA_LLIST_HEAD_INIT(struct literal, c->literals);
-
-        if (!gather_conjunction(et, c)) {
-            delete_conjunction(c);
-            return false;
-        }
-
-        PA_LLIST_INIT(struct conjunction, c);
-        PA_LLIST_PREPEND(struct conjunction, e->conjunctions, c);
-    }
-
-    return true;
-}
-
-static int expression_from_string(const char *str, struct expression **_r) {
-    const char *k;
-    char *l;
-    struct expression *e = NULL;
-    char *buf = NULL;
-    struct expression_token *et = NULL;
-
-    pa_assert(str);
-    pa_assert(_r);
-
-    buf = pa_xmalloc0(strlen(str) + 1);
-
-    /* remove whitespace */
-
-    k = str;
-    l = buf;
-
-    while (*k) {
-        if (*k == ' ') {
-            k++;
-            continue;
-        }
-
-        *l = *k;
-        l++;
-        k++;
-    }
-
-    /* et is the root of an expression tree */
-    et = parse_rule_internal(buf, true);
-
-    if (!et)
-        goto error;
-
-    e = pa_xnew0(struct expression, 1);
-
-    PA_LLIST_HEAD_INIT(struct conjunction, e->conjunctions);
-
-    /* gather expressions to actual match format */
-    if (!gather_expression(e, et)) {
-        /* gathering the expression from tokens went wrong */
-        pa_log_error("failed to parse audio group stream classification data");
-        goto error;
-    }
-
-#if 0
-    print_expression(e);
-#endif
-
-    /* free memory */
-    delete_expression_token(et);
-    pa_xfree(buf);
-
-    *_r = e;
-    return 0;
-
-error:
-    delete_expression_token(et);
-    pa_xfree(buf);
-    expression_free(e);
-
-    return -PA_ERR_INVALID;
-}
-
-static int parse_streams(pa_config_parser_state *state) {
-    struct userdata *u;
-    char *name;
-    const char *split_state = NULL;
-
-    pa_assert(state);
-
-    u = state->userdata;
-
-    while ((name = pa_split_spaces(state->rvalue, &split_state))) {
-        const char *name2;
-        unsigned idx;
-        bool duplicate = false;
-
-        /* Avoid adding duplicates in u->stream_rule_names. */
-        PA_DYNARRAY_FOREACH(name2, u->stream_rule_names, idx) {
-            if (pa_streq(name, name2)) {
-                duplicate = true;
-                break;
-            }
-        }
-
-        if (duplicate) {
-            pa_xfree(name);
-            continue;
-        }
-
-        pa_dynarray_append(u->stream_rule_names, name);
-    }
-
-    return 0;
-}
-
-static int parse_group_control(pa_config_parser_state *state, struct group *group, enum control_type type) {
-    pa_assert(state);
-    pa_assert(group);
-
-    if (pa_streq(state->rvalue, NONE_KEYWORD))
-        group_disable_control(group, type);
-
-    else if (pa_startswith(state->rvalue, CREATE_PREFIX))
-        group_set_own_control_name(group, type, state->rvalue + strlen(CREATE_PREFIX));
-
-    else if (pa_startswith(state->rvalue, BIND_PREFIX)) {
-        if (pa_startswith(state->rvalue, BIND_AUDIO_GROUP_PREFIX)) {
-            int r;
-
-            r = group_set_master_name(group, type, state->rvalue + strlen(BIND_AUDIO_GROUP_PREFIX));
-            if (r < 0) {
-                pa_log("[%s:%u] Failed to set binding target \"%s\".", state->filename, state->lineno, state->rvalue + strlen(BIND_PREFIX));
-                return r;
-            }
-        } else {
-            pa_log("[%s:%u] Failed to parse binding target \"%s\".", state->filename, state->lineno, state->rvalue + strlen(BIND_PREFIX));
-            return -PA_ERR_INVALID;
-        }
-    } else {
-        pa_log("[%s:%u] Failed to parse value \"%s\".", state->filename, state->lineno, state->rvalue);
-        return -PA_ERR_INVALID;
-    }
-
-    return 0;
-}
-
-static int parse_common(pa_config_parser_state *state) {
-    char *section;
-    struct userdata *u = state->userdata;
-    const char *name;
-    int r;
-
-    pa_assert(state);
-
-    section = state->section;
-    if (!section) {
-        pa_log("[%s:%u] Lvalue \"%s\" not expected in the General section.", state->filename, state->lineno, state->lvalue);
-        return -PA_ERR_INVALID;
-    }
-
-    if (pa_startswith(section, AUDIOGROUP_START)) {
-        struct group *group;
-
-        name = section + strlen(AUDIOGROUP_START);
-
-        group = pa_hashmap_get(u->groups, name);
-        if (!group) {
-            r = group_new(u, name, &group);
-            if (r < 0) {
-                pa_log("[%s:%u] Failed to create an audio group with name \"%s\".", state->filename, state->lineno, name);
-                return r;
-            }
-
-            pa_hashmap_put(u->groups, (void *) group->audio_group->name, group);
-        }
-
-        if (pa_streq(state->lvalue, "description"))
-            pa_audio_group_set_description(group->audio_group, state->rvalue);
-
-        else if (pa_streq(state->lvalue, "volume-control"))
-            return parse_group_control(state, group, CONTROL_TYPE_VOLUME);
-
-        else if (pa_streq(state->lvalue, "mute-control"))
-            return parse_group_control(state, group, CONTROL_TYPE_MUTE);
-
-        else {
-            pa_log("[%s:%u] Lvalue \"%s\" not expected in the AudioGroup section.", state->filename, state->lineno, state->lvalue);
-            return -PA_ERR_INVALID;
-        }
-    }
-    else if (pa_startswith(section, STREAM_RULE_START)) {
-        struct stream_rule *rule;
-
-        name = section + strlen(STREAM_RULE_START);
-
-        rule = pa_hashmap_get(u->stream_rules, name);
-        if (!rule) {
-            rule = stream_rule_new(u, name);
-            pa_hashmap_put(u->stream_rules, rule->name, rule);
-        }
-
-        if (pa_streq(state->lvalue, "audio-group-for-volume"))
-            stream_rule_set_group_name(rule, CONTROL_TYPE_VOLUME, state->rvalue);
-
-        else if (pa_streq(state->lvalue, "audio-group-for-mute"))
-            stream_rule_set_group_name(rule, CONTROL_TYPE_MUTE, state->rvalue);
-
-        else if (pa_streq(state->lvalue, "match")) {
-            struct expression *expression;
-
-            r = expression_from_string(state->rvalue, &expression);
-            if (r < 0) {
-                pa_log("[%s:%u] Failed to parse value \"%s\".", state->filename, state->lineno, state->rvalue);
-                return r;
-            }
-
-            stream_rule_set_match_expression(rule, expression);
-        }
-    }
-
-    return 0;
-}
-
-int pa__init(pa_module *module) {
-    pa_modargs *ma = NULL;
-    struct userdata *u;
-    FILE *f;
-    char *fn = NULL;
-    struct group *group;
-    void *state;
-    const char *name;
-    unsigned idx;
-
-    pa_assert(module);
-
-    if (!(ma = pa_modargs_new(module->argument, valid_modargs))) {
-        pa_log("Failed to parse module arguments");
-        goto fail;
-    }
-
-    u = module->userdata = pa_xnew0(struct userdata, 1);
-    u->volume_api = pa_volume_api_get(module->core);
-    u->groups = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                    (pa_free_cb_t) group_free);
-    u->stream_rules = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                          (pa_free_cb_t) stream_rule_free);
-    u->stream_rules_list = pa_dynarray_new(NULL);
-    u->rules_by_stream = pa_hashmap_new(NULL, NULL);
-    u->stream_volume_controls = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) control_free);
-    u->stream_mute_controls = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) control_free);
-    u->stream_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PUT], PA_HOOK_NORMAL, stream_put_cb,
-                                         u);
-    u->stream_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_UNLINK], PA_HOOK_NORMAL,
-                                            stream_unlink_cb, u);
-    u->volume_control_implementation_initialized_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_IMPLEMENTATION_INITIALIZED],
-                            PA_HOOK_NORMAL, volume_control_implementation_initialized_cb, u);
-    u->mute_control_implementation_initialized_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_IMPLEMENTATION_INITIALIZED],
-                            PA_HOOK_NORMAL, mute_control_implementation_initialized_cb, u);
-    u->volume_control_set_initial_volume_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_SET_INITIAL_VOLUME], PA_HOOK_NORMAL,
-                            volume_control_set_initial_volume_cb, u);
-    u->mute_control_set_initial_mute_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_SET_INITIAL_MUTE], PA_HOOK_NORMAL,
-                            mute_control_set_initial_mute_cb, u);
-    u->volume_control_volume_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED], PA_HOOK_NORMAL,
-                            volume_control_volume_changed_cb, u);
-    u->mute_control_mute_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED], PA_HOOK_NORMAL,
-                            mute_control_mute_changed_cb, u);
-    u->volume_control_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK],
-                                                    PA_HOOK_NORMAL, volume_control_unlink_cb, u);
-    u->mute_control_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK],
-                                                  PA_HOOK_NORMAL, mute_control_unlink_cb, u);
-    u->stream_rule_names = pa_dynarray_new(pa_xfree);
-
-    f = pa_open_config_file(PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "audio-groups.conf", "audio-groups.conf", NULL, &fn);
-    if (f) {
-        pa_config_item config_items[] = {
-            { "stream-rules", parse_streams, NULL, "General" },
-            { NULL, parse_common, NULL, NULL },
-            { NULL, NULL, NULL, NULL },
-        };
-
-        pa_config_parse(fn, f, config_items, NULL, u);
-        pa_xfree(fn);
-        fn = NULL;
-        fclose(f);
-        f = NULL;
-    }
-
-    PA_HASHMAP_FOREACH(group, u->groups, state)
-        group_put(group);
-
-    PA_DYNARRAY_FOREACH(name, u->stream_rule_names, idx) {
-        struct stream_rule *rule;
-
-        rule = pa_hashmap_get(u->stream_rules, name);
-        if (rule)
-            pa_dynarray_append(u->stream_rules_list, rule);
-        else
-            pa_log("Non-existent stream rule \"%s\" referenced, ignoring.", name);
-    }
-
-    pa_dynarray_free(u->stream_rule_names);
-    u->stream_rule_names = NULL;
-
-    pa_modargs_free(ma);
-
-    return 0;
-
-fail:
-    pa__done(module);
-
-    if (ma)
-        pa_modargs_free(ma);
-
-    return -1;
-}
-
-void pa__done(pa_module *m) {
-    struct userdata *u;
-
-    pa_assert(m);
-
-    u = (struct userdata *) m->userdata;
-
-    if (!u)
-        return;
-
-    if (u->mute_control_unlink_slot)
-        pa_hook_slot_free(u->mute_control_unlink_slot);
-
-    if (u->volume_control_unlink_slot)
-        pa_hook_slot_free(u->volume_control_unlink_slot);
-
-    if (u->mute_control_mute_changed_slot)
-        pa_hook_slot_free(u->mute_control_mute_changed_slot);
-
-    if (u->volume_control_volume_changed_slot)
-        pa_hook_slot_free(u->volume_control_volume_changed_slot);
-
-    if (u->mute_control_set_initial_mute_slot)
-        pa_hook_slot_free(u->mute_control_set_initial_mute_slot);
-
-    if (u->volume_control_set_initial_volume_slot)
-        pa_hook_slot_free(u->volume_control_set_initial_volume_slot);
-
-    if (u->mute_control_implementation_initialized_slot)
-        pa_hook_slot_free(u->mute_control_implementation_initialized_slot);
-
-    if (u->volume_control_implementation_initialized_slot)
-        pa_hook_slot_free(u->volume_control_implementation_initialized_slot);
-
-    if (u->stream_unlink_slot)
-        pa_hook_slot_free(u->stream_unlink_slot);
-
-    if (u->stream_put_slot)
-        pa_hook_slot_free(u->stream_put_slot);
-
-    if (u->stream_mute_controls)
-        pa_hashmap_free(u->stream_mute_controls);
-
-    if (u->stream_volume_controls)
-        pa_hashmap_free(u->stream_volume_controls);
-
-    if (u->rules_by_stream)
-        pa_hashmap_free(u->rules_by_stream);
-
-    if (u->stream_rules_list)
-        pa_dynarray_free(u->stream_rules_list);
-
-    if (u->stream_rules)
-        pa_hashmap_free(u->stream_rules);
-
-    if (u->groups)
-        pa_hashmap_free(u->groups);
-
-    if (u->volume_api)
-        pa_volume_api_unref(u->volume_api);
-
-    pa_xfree(u);
-}
diff --git a/src/modules/main-volume-policy/main-volume-context.c b/src/modules/main-volume-policy/main-volume-context.c
deleted file mode 100644 (file)
index 9b9f9fd..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "main-volume-context.h"
-
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulsecore/core-util.h>
-
-int pa_main_volume_context_new(pa_main_volume_policy *policy, const char *name, void *userdata, pa_main_volume_context **_r) {
-    pa_main_volume_context *context;
-    int r;
-
-    pa_assert(policy);
-    pa_assert(name);
-    pa_assert(_r);
-
-    context = pa_xnew0(struct pa_main_volume_context, 1);
-    context->main_volume_policy = policy;
-    context->index = pa_main_volume_policy_allocate_main_volume_context_index(policy);
-
-    r = pa_main_volume_policy_register_name(policy, name, true, &context->name);
-    if (r < 0)
-        goto fail;
-
-    context->description = pa_xstrdup(context->name);
-    context->userdata = userdata;
-
-    *_r = context;
-    return 0;
-
-fail:
-    if (context)
-        pa_main_volume_context_free(context);
-
-    return r;
-}
-
-void pa_main_volume_context_put(pa_main_volume_context *context) {
-    pa_assert(context);
-
-    pa_main_volume_policy_add_main_volume_context(context->main_volume_policy, context);
-    context->linked = true;
-
-    pa_log_debug("Created main volume context #%u.", context->index);
-    pa_log_debug("    Name: %s", context->name);
-    pa_log_debug("    Description: %s", context->description);
-    pa_log_debug("    Main output volume control: %s",
-                 context->main_output_volume_control ? context->main_output_volume_control->name : "(unset)");
-    pa_log_debug("    Main input volume control: %s",
-                 context->main_input_volume_control ? context->main_input_volume_control->name : "(unset)");
-    pa_log_debug("    Main output mute control: %s",
-                 context->main_output_mute_control ? context->main_output_mute_control->name : "(unset)");
-    pa_log_debug("    Main input mute control: %s",
-                 context->main_input_mute_control ? context->main_input_mute_control->name : "(unset)");
-
-    pa_hook_fire(&context->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_PUT], context);
-}
-
-void pa_main_volume_context_unlink(pa_main_volume_context *context) {
-    pa_assert(context);
-
-    if (context->unlinked) {
-        pa_log_debug("Unlinking main volume context %s (already unlinked, this is a no-op).", context->name);
-        return;
-    }
-
-    context->unlinked = true;
-
-    pa_log_debug("Unlinking main volume context %s.", context->name);
-
-    if (context->linked)
-        pa_main_volume_policy_remove_main_volume_context(context->main_volume_policy, context);
-
-    pa_hook_fire(&context->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_UNLINK], context);
-
-    context->main_input_mute_control = NULL;
-    context->main_output_mute_control = NULL;
-    context->main_input_volume_control = NULL;
-    context->main_output_volume_control = NULL;
-}
-
-void pa_main_volume_context_free(pa_main_volume_context *context) {
-    pa_assert(context);
-
-    /* unlink() expects name to be set. */
-    if (!context->unlinked && context->name)
-        pa_main_volume_context_unlink(context);
-
-    pa_xfree(context->description);
-
-    if (context->name)
-        pa_main_volume_policy_unregister_name(context->main_volume_policy, context->name);
-
-    pa_xfree(context);
-}
-
-void pa_main_volume_context_set_description(pa_main_volume_context *context, const char *description) {
-    char *old_description;
-
-    pa_assert(context);
-    pa_assert(description);
-
-    old_description = context->description;
-
-    if (pa_streq(description, old_description))
-        return;
-
-    context->description = pa_xstrdup(description);
-
-    if (!context->linked || context->unlinked) {
-        pa_xfree(old_description);
-        return;
-    }
-
-    pa_log_debug("Main volume context %s description changed from \"%s\" to \"%s\".", context->name, old_description,
-                 description);
-    pa_xfree(old_description);
-
-    pa_hook_fire(&context->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_DESCRIPTION_CHANGED],
-                 context);
-}
-
-void pa_main_volume_context_set_main_output_volume_control(pa_main_volume_context *context, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(context);
-
-    old_control = context->main_output_volume_control;
-
-    if (control == old_control)
-        return;
-
-    context->main_output_volume_control = control;
-
-    if (!context->linked || context->unlinked)
-        return;
-
-    pa_log_debug("Main volume context %s main output volume control changed from %s to %s.", context->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&context->main_volume_policy->hooks
-                     [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED],
-                 context);
-}
-
-void pa_main_volume_context_set_main_input_volume_control(pa_main_volume_context *context, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(context);
-
-    old_control = context->main_input_volume_control;
-
-    if (control == old_control)
-        return;
-
-    context->main_input_volume_control = control;
-
-    if (!context->linked || context->unlinked)
-        return;
-
-    pa_log_debug("Main volume context %s main input volume control changed from %s to %s.", context->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&context->main_volume_policy->hooks
-                     [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_VOLUME_CONTROL_CHANGED],
-                 context);
-}
-
-void pa_main_volume_context_set_main_output_mute_control(pa_main_volume_context *context, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(context);
-
-    old_control = context->main_output_mute_control;
-
-    if (control == old_control)
-        return;
-
-    context->main_output_mute_control = control;
-
-    if (!context->linked || context->unlinked)
-        return;
-
-    pa_log_debug("Main volume context %s main output mute control changed from %s to %s.", context->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&context->main_volume_policy->hooks
-                     [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_MUTE_CONTROL_CHANGED],
-                 context);
-}
-
-void pa_main_volume_context_set_main_input_mute_control(pa_main_volume_context *context, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(context);
-
-    old_control = context->main_input_mute_control;
-
-    if (control == old_control)
-        return;
-
-    context->main_input_mute_control = control;
-
-    if (!context->linked || context->unlinked)
-        return;
-
-    pa_log_debug("Main volume context %s main input mute control changed from %s to %s.", context->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&context->main_volume_policy->hooks
-                     [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_MUTE_CONTROL_CHANGED],
-                 context);
-}
diff --git a/src/modules/main-volume-policy/main-volume-context.h b/src/modules/main-volume-policy/main-volume-context.h
deleted file mode 100644 (file)
index 3770168..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef foomainvolumecontexthfoo
-#define foomainvolumecontexthfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/main-volume-policy/main-volume-policy.h>
-
-typedef struct pa_main_volume_context pa_main_volume_context;
-
-struct pa_main_volume_context {
-    pa_main_volume_policy *main_volume_policy;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_volume_control *main_output_volume_control;
-    pa_volume_control *main_input_volume_control;
-    pa_mute_control *main_output_mute_control;
-    pa_mute_control *main_input_mute_control;
-
-    bool linked;
-    bool unlinked;
-
-    void *userdata;
-};
-
-int pa_main_volume_context_new(pa_main_volume_policy *policy, const char *name, void *userdata, pa_main_volume_context **_r);
-void pa_main_volume_context_put(pa_main_volume_context *context);
-void pa_main_volume_context_unlink(pa_main_volume_context *context);
-void pa_main_volume_context_free(pa_main_volume_context *context);
-
-void pa_main_volume_context_set_description(pa_main_volume_context *context, const char *description);
-void pa_main_volume_context_set_main_output_volume_control(pa_main_volume_context *context, pa_volume_control *control);
-void pa_main_volume_context_set_main_input_volume_control(pa_main_volume_context *context, pa_volume_control *control);
-void pa_main_volume_context_set_main_output_mute_control(pa_main_volume_context *context, pa_mute_control *control);
-void pa_main_volume_context_set_main_input_mute_control(pa_main_volume_context *context, pa_mute_control *control);
-
-#endif
diff --git a/src/modules/main-volume-policy/main-volume-policy.c b/src/modules/main-volume-policy/main-volume-policy.c
deleted file mode 100644 (file)
index 3c0fccf..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "main-volume-policy.h"
-
-#include <modules/main-volume-policy/main-volume-context.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/shared.h>
-
-static pa_main_volume_policy *main_volume_policy_new(pa_core *core);
-static void main_volume_policy_free(pa_main_volume_policy *policy);
-
-pa_main_volume_policy *pa_main_volume_policy_get(pa_core *core) {
-    pa_main_volume_policy *policy;
-
-    pa_assert(core);
-
-    policy = pa_shared_get(core, "main-volume-policy");
-
-    if (policy)
-        pa_main_volume_policy_ref(policy);
-    else {
-        policy = main_volume_policy_new(core);
-        pa_assert_se(pa_shared_set(core, "main-volume-policy", policy) >= 0);
-    }
-
-    return policy;
-}
-
-pa_main_volume_policy *pa_main_volume_policy_ref(pa_main_volume_policy *policy) {
-    pa_assert(policy);
-
-    policy->refcnt++;
-
-    return policy;
-}
-
-void pa_main_volume_policy_unref(pa_main_volume_policy *policy) {
-    pa_assert(policy);
-    pa_assert(policy->refcnt > 0);
-
-    policy->refcnt--;
-
-    if (policy->refcnt == 0) {
-        pa_assert_se(pa_shared_remove(policy->core, "main-volume-policy") >= 0);
-        main_volume_policy_free(policy);
-    }
-}
-
-static pa_hook_result_t volume_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_main_volume_policy *policy = userdata;
-    pa_volume_control *control = call_data;
-    pa_main_volume_context *context;
-    void *state;
-
-    pa_assert(policy);
-    pa_assert(control);
-
-    PA_HASHMAP_FOREACH(context, policy->main_volume_contexts, state) {
-        if (context->main_output_volume_control == control)
-            pa_main_volume_context_set_main_output_volume_control(context, NULL);
-
-        if (context->main_input_volume_control == control)
-            pa_main_volume_context_set_main_input_volume_control(context, NULL);
-    }
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_main_volume_policy *policy = userdata;
-    pa_mute_control *control = call_data;
-    pa_main_volume_context *context;
-    void *state;
-
-    pa_assert(policy);
-    pa_assert(control);
-
-    PA_HASHMAP_FOREACH(context, policy->main_volume_contexts, state) {
-        if (context->main_output_mute_control == control)
-            pa_main_volume_context_set_main_output_mute_control(context, NULL);
-
-        if (context->main_input_mute_control == control)
-            pa_main_volume_context_set_main_input_mute_control(context, NULL);
-    }
-
-    return PA_HOOK_OK;
-}
-
-static pa_main_volume_policy *main_volume_policy_new(pa_core *core) {
-    pa_main_volume_policy *policy;
-    unsigned i;
-
-    pa_assert(core);
-
-    policy = pa_xnew0(pa_main_volume_policy, 1);
-    policy->core = core;
-    policy->refcnt = 1;
-    policy->volume_api = pa_volume_api_get(core);
-    policy->names = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
-    policy->main_volume_contexts = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-
-    for (i = 0; i < PA_MAIN_VOLUME_POLICY_HOOK_MAX; i++)
-        pa_hook_init(&policy->hooks[i], policy);
-
-    policy->volume_control_unlink_slot = pa_hook_connect(&policy->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK],
-                                                         PA_HOOK_NORMAL, volume_control_unlink_cb, policy);
-    policy->mute_control_unlink_slot = pa_hook_connect(&policy->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK],
-                                                       PA_HOOK_NORMAL, mute_control_unlink_cb, policy);
-
-    pa_log_debug("Created a pa_main_volume_policy object.");
-
-    return policy;
-}
-
-static void main_volume_policy_free(pa_main_volume_policy *policy) {
-    unsigned i;
-
-    pa_assert(policy);
-    pa_assert(policy->refcnt == 0);
-
-    pa_log_debug("Freeing the pa_main_volume_policy object.");
-
-    if (policy->mute_control_unlink_slot)
-        pa_hook_slot_free(policy->mute_control_unlink_slot);
-
-    if (policy->volume_control_unlink_slot)
-        pa_hook_slot_free(policy->volume_control_unlink_slot);
-
-    for (i = 0; i < PA_MAIN_VOLUME_POLICY_HOOK_MAX; i++)
-        pa_hook_done(&policy->hooks[i]);
-
-    if (policy->main_volume_contexts) {
-        pa_assert(pa_hashmap_isempty(policy->main_volume_contexts));
-        pa_hashmap_free(policy->main_volume_contexts);
-    }
-
-    if (policy->names) {
-        pa_assert(pa_hashmap_isempty(policy->names));
-        pa_hashmap_free(policy->names);
-    }
-
-    if (policy->volume_api)
-        pa_volume_api_unref(policy->volume_api);
-
-    pa_xfree(policy);
-}
-
-int pa_main_volume_policy_register_name(pa_main_volume_policy *policy, const char *requested_name,
-                                        bool fail_if_already_registered, const char **registered_name) {
-    char *n;
-
-    pa_assert(policy);
-    pa_assert(requested_name);
-    pa_assert(registered_name);
-
-    if (!pa_namereg_is_valid_name(requested_name)) {
-        pa_log("Invalid name: \"%s\"", requested_name);
-        return -PA_ERR_INVALID;
-    }
-
-    n = pa_xstrdup(requested_name);
-
-    if (pa_hashmap_put(policy->names, n, n) < 0) {
-        unsigned i = 1;
-
-        if (fail_if_already_registered) {
-            pa_xfree(n);
-            pa_log("Name %s already registered.", requested_name);
-            return -PA_ERR_EXIST;
-        }
-
-        do {
-            pa_xfree(n);
-            i++;
-            n = pa_sprintf_malloc("%s.%u", requested_name, i);
-        } while (pa_hashmap_put(policy->names, n, n) < 0);
-    }
-
-    *registered_name = n;
-
-    return 0;
-}
-
-void pa_main_volume_policy_unregister_name(pa_main_volume_policy *policy, const char *name) {
-    pa_assert(policy);
-    pa_assert(name);
-
-    pa_assert_se(pa_hashmap_remove_and_free(policy->names, name) >= 0);
-}
-
-uint32_t pa_main_volume_policy_allocate_main_volume_context_index(pa_main_volume_policy *policy) {
-    uint32_t idx;
-
-    pa_assert(policy);
-
-    idx = policy->next_main_volume_context_index++;
-
-    return idx;
-}
-
-void pa_main_volume_policy_add_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
-    pa_assert(policy);
-    pa_assert(context);
-
-    pa_assert_se(pa_hashmap_put(policy->main_volume_contexts, (void *) context->name, context) >= 0);
-}
-
-int pa_main_volume_policy_remove_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
-    pa_assert(policy);
-    pa_assert(context);
-
-    if (!pa_hashmap_remove(policy->main_volume_contexts, context->name))
-        return -1;
-
-    if (context == policy->active_main_volume_context)
-        pa_main_volume_policy_set_active_main_volume_context(policy, NULL);
-
-    return 0;
-}
-
-void pa_main_volume_policy_set_active_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context) {
-    pa_main_volume_context *old_context;
-
-    pa_assert(policy);
-
-    old_context = policy->active_main_volume_context;
-
-    if (context == old_context)
-        return;
-
-    policy->active_main_volume_context = context;
-
-    pa_log_debug("The active main volume context changed from %s to %s.", old_context ? old_context->name : "(unset)",
-                 context ? context->name : "(unset)");
-
-    pa_hook_fire(&policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED], NULL);
-}
diff --git a/src/modules/main-volume-policy/main-volume-policy.conf.example b/src/modules/main-volume-policy/main-volume-policy.conf.example
deleted file mode 100644 (file)
index 3fcd267..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-[General]
-output-volume-model = by-active-main-volume-context
-input-volume-model = by-active-main-volume-context
-output-mute-model = none
-input-mute-model = none
-
-[MainVolumeContext x-example-call-main-volume-context]
-description = Call main volume context
-main-output-volume-control = bind:AudioGroup:x-example-call-downlink-audio-group
-main-input-volume-control = bind:AudioGroup:x-example-call-uplink-audio-group
-main-output-mute-control = none
-main-input-mute-control = none
-
-[MainVolumeContext x-example-default-main-volume-context]
-description = Default main volume context
-main-output-volume-control = bind:AudioGroup:x-example-default-output-audio-group
-main-input-volume-control = bind:AudioGroup:x-example-default-input-audio-group
-main-output-mute-control = none
-main-input-mute-control = none
diff --git a/src/modules/main-volume-policy/main-volume-policy.h b/src/modules/main-volume-policy/main-volume-policy.h
deleted file mode 100644 (file)
index d5f6e02..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef foomainvolumepolicyhfoo
-#define foomainvolumepolicyhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/volume-api.h>
-
-#include <pulsecore/core.h>
-
-typedef struct pa_main_volume_policy pa_main_volume_policy;
-
-/* Avoid circular dependencies... */
-typedef struct pa_main_volume_context pa_main_volume_context;
-
-enum {
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_PUT,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_UNLINK,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_DESCRIPTION_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_VOLUME_CONTROL_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_MUTE_CONTROL_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_MUTE_CONTROL_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED,
-    PA_MAIN_VOLUME_POLICY_HOOK_MAX,
-};
-
-struct pa_main_volume_policy {
-    pa_core *core;
-    unsigned refcnt;
-    pa_volume_api *volume_api;
-    pa_hashmap *names; /* object name -> object name (hashmap-as-a-set) */
-    pa_hashmap *main_volume_contexts; /* name -> pa_main_volume_context */
-    pa_main_volume_context *active_main_volume_context;
-
-    uint32_t next_main_volume_context_index;
-    pa_hook hooks[PA_MAIN_VOLUME_POLICY_HOOK_MAX];
-
-    pa_hook_slot *volume_control_unlink_slot;
-    pa_hook_slot *mute_control_unlink_slot;
-};
-
-pa_main_volume_policy *pa_main_volume_policy_get(pa_core *core);
-pa_main_volume_policy *pa_main_volume_policy_ref(pa_main_volume_policy *policy);
-void pa_main_volume_policy_unref(pa_main_volume_policy *policy);
-
-int pa_main_volume_policy_register_name(pa_main_volume_policy *policy, const char *requested_name,
-                                        bool fail_if_already_registered, const char **registered_name);
-void pa_main_volume_policy_unregister_name(pa_main_volume_policy *policy, const char *name);
-
-uint32_t pa_main_volume_policy_allocate_main_volume_context_index(pa_main_volume_policy *policy);
-void pa_main_volume_policy_add_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
-int pa_main_volume_policy_remove_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
-void pa_main_volume_policy_set_active_main_volume_context(pa_main_volume_policy *policy, pa_main_volume_context *context);
-
-#endif
diff --git a/src/modules/main-volume-policy/module-main-volume-policy.c b/src/modules/main-volume-policy/module-main-volume-policy.c
deleted file mode 100644 (file)
index 1b7693e..0000000
+++ /dev/null
@@ -1,754 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "module-main-volume-policy-symdef.h"
-
-#include <modules/main-volume-policy/main-volume-context.h>
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/volume-api.h>
-
-#include <pulse/direction.h>
-
-#include <pulsecore/conf-parser.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/i18n.h>
-
-#define BIND_PREFIX "bind:"
-#define BIND_AUDIO_GROUP_PREFIX BIND_PREFIX "AudioGroup:"
-
-PA_MODULE_AUTHOR("Tanu Kaskinen");
-PA_MODULE_DESCRIPTION(_("Main volume and mute policy"));
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(true);
-
-enum control_type {
-    CONTROL_TYPE_VOLUME,
-    CONTROL_TYPE_MUTE,
-};
-
-enum model {
-    MODEL_NONE,
-    MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT,
-};
-
-struct userdata {
-    pa_volume_api *volume_api;
-    pa_main_volume_policy *main_volume_policy;
-    enum model output_volume_model;
-    enum model input_volume_model;
-    enum model output_mute_model;
-    enum model input_mute_model;
-    pa_hashmap *contexts; /* name -> struct context */
-
-    pa_hook_slot *active_main_volume_context_changed_slot;
-    pa_hook_slot *main_volume_context_main_output_volume_control_changed_slot;
-    pa_hook_slot *main_volume_context_main_input_volume_control_changed_slot;
-    pa_hook_slot *main_volume_context_main_output_mute_control_changed_slot;
-    pa_hook_slot *main_volume_context_main_input_mute_control_changed_slot;
-    pa_hook_slot *audio_group_put_slot;
-    pa_hook_slot *audio_group_unlink_slot;
-    pa_hook_slot *audio_group_volume_control_changed_slot;
-    pa_hook_slot *audio_group_mute_control_changed_slot;
-};
-
-struct control_info {
-    /* As appropriate for this control, points to one of
-     *  - pa_main_volume_context.main_output_volume_control
-     *  - pa_main_volume_context.main_input_volume_control
-     *  - pa_main_volume_context.main_output_mute_control
-     *  - pa_main_volume_context.main_input_mute_control */
-    void **control;
-
-    /* As appropriate for this control, points to one of
-     *  - userdata.output_volume_model
-     *  - userdata.input_volume_model
-     *  - userdata.output_mute_model
-     *  - userdata.input_mute_model */
-    enum model *model;
-
-    /* Name of the audio group to which the context volume or mute control is
-     * bound. If the context control is not bound to anything, this is NULL. */
-    char *binding_target_name;
-
-    /* Points to the audio group to which the context volume or mute control is
-     * bound. If the context control is not bound to anything, or it's bound
-     * but the target doesn't currently exist, this is NULL. */
-    pa_audio_group *binding_target;
-
-    /* As appropriate for this control, points to one of
-     *  - pa_main_volume_context_set_main_output_volume_control()
-     *  - pa_main_volume_context_set_main_input_volume_control()
-     *  - pa_main_volume_context_set_main_output_mute_control()
-     *  - pa_main_volume_context_set_main_input_mute_control() */
-    void (*set_control)(pa_main_volume_context *context, void *control);
-
-    /* As appropriate for this control, points to one of
-     *  - pa_volume_api_set_main_output_volume_control()
-     *  - pa_volume_api_set_main_input_volume_control()
-     *  - pa_volume_api_set_main_output_mute_control()
-     *  - pa_volume_api_set_main_input_mute_control() */
-    void (*set_volume_api_control)(pa_volume_api *api, void *control);
-};
-
-struct context {
-    struct userdata *userdata;
-    pa_main_volume_context *main_volume_context;
-    struct control_info output_volume_info;
-    struct control_info input_volume_info;
-    struct control_info output_mute_info;
-    struct control_info input_mute_info;
-
-    bool unlinked;
-};
-
-static void context_free(struct context *context);
-
-static const char *model_to_string(enum model model) {
-    switch (model) {
-        case MODEL_NONE:
-            return "none";
-
-        case MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT:
-            return "by-active-main-volume-context";
-    }
-
-    pa_assert_not_reached();
-}
-
-static int model_from_string(const char *str, enum model *model) {
-    pa_assert(str);
-    pa_assert(model);
-
-    if (pa_streq(str, "none"))
-        *model = MODEL_NONE;
-    else if (pa_streq(str, "by-active-main-volume-context"))
-        *model = MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT;
-    else
-        return -PA_ERR_INVALID;
-
-    return 0;
-}
-
-static int context_new(struct userdata *u, const char *name, struct context **_r) {
-    struct context *context = NULL;
-    int r;
-
-    pa_assert(u);
-    pa_assert(name);
-    pa_assert(_r);
-
-    context = pa_xnew0(struct context, 1);
-    context->userdata = u;
-
-    r = pa_main_volume_context_new(u->main_volume_policy, name, u, &context->main_volume_context);
-    if (r < 0)
-        goto fail;
-
-    context->output_volume_info.control = (void **) &context->main_volume_context->main_output_volume_control;
-    context->input_volume_info.control = (void **) &context->main_volume_context->main_input_volume_control;
-    context->output_mute_info.control = (void **) &context->main_volume_context->main_output_mute_control;
-    context->input_mute_info.control = (void **) &context->main_volume_context->main_input_mute_control;
-
-    context->output_volume_info.model = &u->output_volume_model;
-    context->input_volume_info.model = &u->input_volume_model;
-    context->output_mute_info.model = &u->output_mute_model;
-    context->input_mute_info.model = &u->input_mute_model;
-
-    context->output_volume_info.set_control = (void *) pa_main_volume_context_set_main_output_volume_control;
-    context->input_volume_info.set_control = (void *) pa_main_volume_context_set_main_input_volume_control;
-    context->output_mute_info.set_control = (void *) pa_main_volume_context_set_main_output_mute_control;
-    context->input_mute_info.set_control = (void *) pa_main_volume_context_set_main_input_mute_control;
-
-    context->output_volume_info.set_volume_api_control = (void *) pa_volume_api_set_main_output_volume_control;
-    context->input_volume_info.set_volume_api_control = (void *) pa_volume_api_set_main_input_volume_control;
-    context->output_mute_info.set_volume_api_control = (void *) pa_volume_api_set_main_output_mute_control;
-    context->input_mute_info.set_volume_api_control = (void *) pa_volume_api_set_main_input_mute_control;
-
-    *_r = context;
-    return 0;
-
-fail:
-    if (context)
-        context_free(context);
-
-    return r;
-}
-
-static void context_put(struct context *context) {
-    pa_assert(context);
-
-    pa_main_volume_context_put(context->main_volume_context);
-}
-
-static void context_unlink(struct context *context) {
-    pa_assert(context);
-
-    if (context->unlinked)
-        return;
-
-    context->unlinked = true;
-
-    if (context->main_volume_context)
-        pa_main_volume_context_unlink(context->main_volume_context);
-}
-
-static void context_free(struct context *context) {
-    pa_assert(context);
-
-    if (!context->unlinked)
-        context_unlink(context);
-
-    if (context->main_volume_context)
-        pa_main_volume_context_free(context->main_volume_context);
-
-    pa_xfree(context);
-}
-
-static struct control_info *context_get_control_info(struct context *context, enum control_type type,
-                                                     pa_direction_t direction) {
-    pa_assert(context);
-
-    switch (type) {
-        case CONTROL_TYPE_VOLUME:
-            switch (direction) {
-                case PA_DIRECTION_OUTPUT:
-                    return &context->output_volume_info;
-
-                case PA_DIRECTION_INPUT:
-                    return &context->input_volume_info;
-            }
-            break;
-
-        case CONTROL_TYPE_MUTE:
-            switch (direction) {
-                case PA_DIRECTION_OUTPUT:
-                    return &context->output_mute_info;
-
-                case PA_DIRECTION_INPUT:
-                    return &context->input_mute_info;
-            }
-            break;
-    }
-
-    pa_assert_not_reached();
-}
-
-static void context_set_binding_target(struct context *context, enum control_type type, pa_direction_t direction,
-                                       pa_audio_group *group) {
-    struct control_info *info;
-    void *control = NULL;
-
-    pa_assert(context);
-
-    info = context_get_control_info(context, type, direction);
-    info->binding_target = group;
-
-    if (group) {
-        switch (type) {
-            case CONTROL_TYPE_VOLUME:
-                control = group->volume_control;
-                break;
-
-            case CONTROL_TYPE_MUTE:
-                control = group->mute_control;
-                break;
-        }
-    }
-
-    info->set_control(context->main_volume_context, control);
-}
-
-static void context_set_binding_target_name(struct context *context, enum control_type type, pa_direction_t direction,
-                                            const char *name) {
-    struct control_info *info;
-    pa_audio_group *group = NULL;
-
-    pa_assert(context);
-
-    info = context_get_control_info(context, type, direction);
-
-    if (pa_safe_streq(name, info->binding_target_name))
-        return;
-
-    pa_xfree(info->binding_target_name);
-    info->binding_target_name = pa_xstrdup(name);
-
-    if (name)
-        group = pa_hashmap_get(context->userdata->volume_api->audio_groups, name);
-
-    context_set_binding_target(context, type, direction, group);
-}
-
-static pa_hook_result_t active_main_volume_context_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_main_volume_context *context;
-
-    pa_assert(u);
-
-    context = u->main_volume_policy->active_main_volume_context;
-
-    if (u->output_volume_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
-        if (context)
-            pa_volume_api_set_main_output_volume_control(u->volume_api, context->main_output_volume_control);
-        else
-            pa_volume_api_set_main_output_volume_control(u->volume_api, NULL);
-    }
-
-    if (u->input_volume_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
-        if (context)
-            pa_volume_api_set_main_input_volume_control(u->volume_api, context->main_input_volume_control);
-        else
-            pa_volume_api_set_main_input_volume_control(u->volume_api, NULL);
-    }
-
-    if (u->output_mute_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
-        if (context)
-            pa_volume_api_set_main_output_mute_control(u->volume_api, context->main_output_mute_control);
-        else
-            pa_volume_api_set_main_output_mute_control(u->volume_api, NULL);
-    }
-
-    if (u->input_mute_model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT) {
-        if (context)
-            pa_volume_api_set_main_input_mute_control(u->volume_api, context->main_input_mute_control);
-        else
-            pa_volume_api_set_main_input_mute_control(u->volume_api, NULL);
-    }
-
-    return PA_HOOK_OK;
-}
-
-static void handle_context_control_change(struct context *context, enum control_type type, pa_direction_t direction) {
-    struct control_info *info;
-
-    pa_assert(context);
-
-    info = context_get_control_info(context, type, direction);
-
-    if (*info->model == MODEL_BY_ACTIVE_MAIN_VOLUME_CONTEXT
-            && context->userdata->main_volume_policy->active_main_volume_context == context->main_volume_context)
-        info->set_volume_api_control(context->userdata->volume_api, *info->control);
-}
-
-static pa_hook_result_t main_volume_context_main_output_volume_control_changed_cb(void *hook_data, void *call_data,
-                                                                                  void *userdata) {
-    pa_main_volume_context *context = call_data;
-
-    pa_assert(context);
-
-    handle_context_control_change(context->userdata, CONTROL_TYPE_VOLUME, PA_DIRECTION_OUTPUT);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t main_volume_context_main_input_volume_control_changed_cb(void *hook_data, void *call_data,
-                                                                                 void *userdata) {
-    pa_main_volume_context *context = call_data;
-
-    pa_assert(context);
-
-    handle_context_control_change(context->userdata, CONTROL_TYPE_VOLUME, PA_DIRECTION_INPUT);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t main_volume_context_main_output_mute_control_changed_cb(void *hook_data, void *call_data,
-                                                                                void *userdata) {
-    pa_main_volume_context *context = call_data;
-
-    pa_assert(context);
-
-    handle_context_control_change(context->userdata, CONTROL_TYPE_MUTE, PA_DIRECTION_OUTPUT);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t main_volume_context_main_input_mute_control_changed_cb(void *hook_data, void *call_data,
-                                                                               void *userdata) {
-    pa_main_volume_context *context = call_data;
-
-    pa_assert(context);
-
-    handle_context_control_change(context->userdata, CONTROL_TYPE_MUTE, PA_DIRECTION_INPUT);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-    struct context *context;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    PA_HASHMAP_FOREACH(context, u->contexts, state) {
-        if (context->output_volume_info.binding_target_name
-                && pa_streq(context->output_volume_info.binding_target_name, group->name))
-            context_set_binding_target(context, CONTROL_TYPE_VOLUME, PA_DIRECTION_OUTPUT, group);
-
-        if (context->input_volume_info.binding_target_name
-                && pa_streq(context->input_volume_info.binding_target_name, group->name))
-            context_set_binding_target(context, CONTROL_TYPE_VOLUME, PA_DIRECTION_INPUT, group);
-
-        if (context->output_mute_info.binding_target_name
-                && pa_streq(context->output_mute_info.binding_target_name, group->name))
-            context_set_binding_target(context, CONTROL_TYPE_MUTE, PA_DIRECTION_OUTPUT, group);
-
-        if (context->input_mute_info.binding_target_name
-                && pa_streq(context->input_mute_info.binding_target_name, group->name))
-            context_set_binding_target(context, CONTROL_TYPE_MUTE, PA_DIRECTION_INPUT, group);
-    }
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-    struct context *context;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    PA_HASHMAP_FOREACH(context, u->contexts, state) {
-        if (context->output_volume_info.binding_target == group)
-            context_set_binding_target(context, CONTROL_TYPE_VOLUME, PA_DIRECTION_OUTPUT, NULL);
-
-        if (context->input_volume_info.binding_target == group)
-            context_set_binding_target(context, CONTROL_TYPE_VOLUME, PA_DIRECTION_INPUT, NULL);
-
-        if (context->output_mute_info.binding_target == group)
-            context_set_binding_target(context, CONTROL_TYPE_MUTE, PA_DIRECTION_OUTPUT, NULL);
-
-        if (context->input_mute_info.binding_target == group)
-            context_set_binding_target(context, CONTROL_TYPE_MUTE, PA_DIRECTION_INPUT, NULL);
-    }
-
-    return PA_HOOK_OK;
-}
-
-static void handle_audio_group_control_change(struct userdata *u, pa_audio_group *group, enum control_type type) {
-    struct context *context;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    PA_HASHMAP_FOREACH(context, u->contexts, state) {
-        switch (type) {
-            case CONTROL_TYPE_VOLUME:
-                if (context->output_volume_info.binding_target == group)
-                    pa_main_volume_context_set_main_output_volume_control(context->main_volume_context, group->volume_control);
-
-                if (context->input_volume_info.binding_target == group)
-                    pa_main_volume_context_set_main_input_volume_control(context->main_volume_context, group->volume_control);
-                break;
-
-            case CONTROL_TYPE_MUTE:
-                if (context->output_mute_info.binding_target == group)
-                    pa_main_volume_context_set_main_output_mute_control(context->main_volume_context, group->mute_control);
-
-                if (context->input_mute_info.binding_target == group)
-                    pa_main_volume_context_set_main_input_mute_control(context->main_volume_context, group->mute_control);
-                break;
-        }
-    }
-}
-
-static pa_hook_result_t audio_group_volume_control_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    handle_audio_group_control_change(u, group, CONTROL_TYPE_VOLUME);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_mute_control_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    handle_audio_group_control_change(u, group, CONTROL_TYPE_MUTE);
-
-    return PA_HOOK_OK;
-}
-
-static int parse_model(pa_config_parser_state *state) {
-    int r;
-
-    pa_assert(state);
-
-    r = model_from_string(state->rvalue, state->data);
-    if (r < 0)
-        pa_log("[%s:%u] Failed to parse model: %s", state->filename, state->lineno, state->rvalue);
-
-    return r;
-}
-
-static int get_context(struct userdata *u, const char *section, struct context **_r) {
-    const char *name;
-    struct context *context;
-
-    pa_assert(u);
-
-    if (!section)
-        return -PA_ERR_INVALID;
-
-    if (!pa_startswith(section, "MainVolumeContext "))
-        return -PA_ERR_INVALID;
-
-    name = section + 18;
-
-    context = pa_hashmap_get(u->contexts, name);
-    if (!context) {
-        int r;
-
-        r = context_new(u, name, &context);
-        if (r < 0)
-            return r;
-
-        pa_hashmap_put(u->contexts, (void *) context->main_volume_context->name, context);
-    }
-
-    *_r = context;
-    return 0;
-}
-
-static int parse_description(pa_config_parser_state *state) {
-    struct userdata *u;
-    int r;
-    struct context *context;
-
-    pa_assert(state);
-
-    u = state->userdata;
-
-    r = get_context(u, state->section, &context);
-    if (r < 0) {
-        pa_log("[%s:%u] Couldn't get main volume context for section \"%s\".", state->filename, state->lineno,
-               pa_strnull(state->section));
-        return -PA_ERR_INVALID;
-    }
-
-    pa_main_volume_context_set_description(context->main_volume_context, state->rvalue);
-
-    return 0;
-}
-
-static int parse_control(pa_config_parser_state *state, enum control_type type, pa_direction_t direction) {
-    struct userdata *u;
-    int r;
-    struct context *context;
-
-    pa_assert(state);
-
-    u = state->userdata;
-
-    r = get_context(u, state->section, &context);
-    if (r < 0) {
-        pa_log("[%s:%u] Couldn't get main volume context for section \"%s\".", state->filename, state->lineno,
-               pa_strnull(state->section));
-        return -PA_ERR_INVALID;
-    }
-
-    if (pa_streq(state->rvalue, "none"))
-        context_set_binding_target_name(context, type, direction, NULL);
-    else if (pa_startswith(state->rvalue, BIND_PREFIX)) {
-        if (pa_startswith(state->rvalue, BIND_AUDIO_GROUP_PREFIX))
-            context_set_binding_target_name(context, type, direction, state->rvalue + strlen(BIND_AUDIO_GROUP_PREFIX));
-        else {
-            pa_log("[%s:%u] Failed to parse binding target \"%s\".", state->filename, state->lineno, state->rvalue + strlen(BIND_PREFIX));
-            return -PA_ERR_INVALID;
-        }
-    } else {
-        pa_log("[%s:%u] Failed to parse value \"%s\".", state->filename, state->lineno, state->rvalue);
-        return -PA_ERR_INVALID;
-    }
-
-    return 0;
-}
-
-static int parse_main_output_volume_control(pa_config_parser_state *state) {
-    pa_assert(state);
-
-    return parse_control(state, CONTROL_TYPE_VOLUME, PA_DIRECTION_OUTPUT);
-}
-
-static int parse_main_input_volume_control(pa_config_parser_state *state) {
-    pa_assert(state);
-
-    return parse_control(state, CONTROL_TYPE_VOLUME, PA_DIRECTION_INPUT);
-}
-
-static int parse_main_output_mute_control(pa_config_parser_state *state) {
-    pa_assert(state);
-
-    return parse_control(state, CONTROL_TYPE_MUTE, PA_DIRECTION_OUTPUT);
-}
-
-static int parse_main_input_mute_control(pa_config_parser_state *state) {
-    pa_assert(state);
-
-    return parse_control(state, CONTROL_TYPE_MUTE, PA_DIRECTION_INPUT);
-}
-
-int pa__init(pa_module *module) {
-    struct userdata *u;
-    FILE *f;
-    char *fn = NULL;
-    struct context *context;
-    void *state;
-
-    pa_assert(module);
-
-    u = module->userdata = pa_xnew0(struct userdata, 1);
-    u->volume_api = pa_volume_api_get(module->core);
-    u->main_volume_policy = pa_main_volume_policy_get(module->core);
-    u->output_volume_model = MODEL_NONE;
-    u->input_volume_model = MODEL_NONE;
-    u->output_mute_model = MODEL_NONE;
-    u->input_mute_model = MODEL_NONE;
-    u->contexts = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                      (pa_free_cb_t) context_free);
-    u->active_main_volume_context_changed_slot =
-            pa_hook_connect(&u->main_volume_policy->hooks[PA_MAIN_VOLUME_POLICY_HOOK_ACTIVE_MAIN_VOLUME_CONTEXT_CHANGED],
-                            PA_HOOK_NORMAL, active_main_volume_context_changed_cb, u);
-    u->main_volume_context_main_output_volume_control_changed_slot =
-            pa_hook_connect(&u->main_volume_policy->hooks
-                                [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, main_volume_context_main_output_volume_control_changed_cb, u);
-    u->main_volume_context_main_input_volume_control_changed_slot =
-            pa_hook_connect(&u->main_volume_policy->hooks
-                                [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, main_volume_context_main_input_volume_control_changed_cb, u);
-    u->main_volume_context_main_output_mute_control_changed_slot =
-            pa_hook_connect(&u->main_volume_policy->hooks
-                                [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_OUTPUT_MUTE_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, main_volume_context_main_output_mute_control_changed_cb, u);
-    u->main_volume_context_main_input_mute_control_changed_slot =
-            pa_hook_connect(&u->main_volume_policy->hooks
-                                [PA_MAIN_VOLUME_POLICY_HOOK_MAIN_VOLUME_CONTEXT_MAIN_INPUT_MUTE_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, main_volume_context_main_input_mute_control_changed_cb, u);
-    u->audio_group_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT], PA_HOOK_NORMAL,
-                                              audio_group_put_cb, u);
-    u->audio_group_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK], PA_HOOK_NORMAL,
-                                                 audio_group_unlink_cb, u);
-    u->audio_group_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED], PA_HOOK_NORMAL,
-                            audio_group_volume_control_changed_cb, u);
-    u->audio_group_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED], PA_HOOK_NORMAL,
-                            audio_group_mute_control_changed_cb, u);
-
-    f = pa_open_config_file(PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "main-volume-policy.conf", "main-volume-policy.conf", NULL, &fn);
-    if (f) {
-        pa_config_item config_items[] = {
-            { "output-volume-model", parse_model, &u->output_volume_model, "General" },
-            { "input-volume-model", parse_model, &u->input_volume_model, "General" },
-            { "output-mute-model", parse_model, &u->output_mute_model, "General" },
-            { "input-mute-model", parse_model, &u->input_mute_model, "General" },
-            { "description", parse_description, NULL, NULL },
-            { "main-output-volume-control", parse_main_output_volume_control, NULL, NULL },
-            { "main-input-volume-control", parse_main_input_volume_control, NULL, NULL },
-            { "main-output-mute-control", parse_main_output_mute_control, NULL, NULL },
-            { "main-input-mute-control", parse_main_input_mute_control, NULL, NULL },
-            { NULL },
-        };
-
-        pa_config_parse(fn, f, config_items, NULL, u);
-        pa_xfree(fn);
-        fn = NULL;
-        fclose(f);
-        f = NULL;
-    }
-
-    PA_HASHMAP_FOREACH(context, u->contexts, state)
-        context_put(context);
-
-    pa_log_debug("Output volume model: %s", model_to_string(u->output_volume_model));
-    pa_log_debug("Input volume model: %s", model_to_string(u->input_volume_model));
-    pa_log_debug("Output mute model: %s", model_to_string(u->output_mute_model));
-    pa_log_debug("Input mute model: %s", model_to_string(u->input_mute_model));
-
-    return 0;
-}
-
-void pa__done(pa_module *module) {
-    struct userdata *u;
-
-    pa_assert(module);
-
-    u = module->userdata;
-    if (!u)
-        return;
-
-    if (u->audio_group_mute_control_changed_slot)
-        pa_hook_slot_free(u->audio_group_mute_control_changed_slot);
-
-    if (u->audio_group_volume_control_changed_slot)
-        pa_hook_slot_free(u->audio_group_volume_control_changed_slot);
-
-    if (u->audio_group_unlink_slot)
-        pa_hook_slot_free(u->audio_group_unlink_slot);
-
-    if (u->audio_group_put_slot)
-        pa_hook_slot_free(u->audio_group_put_slot);
-
-    if (u->main_volume_context_main_input_mute_control_changed_slot)
-        pa_hook_slot_free(u->main_volume_context_main_input_mute_control_changed_slot);
-
-    if (u->main_volume_context_main_output_mute_control_changed_slot)
-        pa_hook_slot_free(u->main_volume_context_main_output_mute_control_changed_slot);
-
-    if (u->main_volume_context_main_input_volume_control_changed_slot)
-        pa_hook_slot_free(u->main_volume_context_main_input_volume_control_changed_slot);
-
-    if (u->main_volume_context_main_output_volume_control_changed_slot)
-        pa_hook_slot_free(u->main_volume_context_main_output_volume_control_changed_slot);
-
-    if (u->active_main_volume_context_changed_slot)
-        pa_hook_slot_free(u->active_main_volume_context_changed_slot);
-
-    if (u->contexts)
-        pa_hashmap_free(u->contexts);
-
-    if (u->main_volume_policy)
-        pa_main_volume_policy_unref(u->main_volume_policy);
-
-    if (u->volume_api)
-        pa_volume_api_unref(u->volume_api);
-
-    pa_xfree(u);
-}
diff --git a/src/modules/volume-api/PROTOCOL b/src/modules/volume-api/PROTOCOL
deleted file mode 100644 (file)
index 2e61361..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-==== v1 ====
-
-client->server
-CONNECT
-    uint32 version
-reply
-    uint32 version
-
-
-client->server, server->client
-DISCONNECT
-    (no arguments)
-(no reply)
-
-
-client->server
-SUBSCRIBE
-    uint32 mask
-reply
-    (no arguments)
-
-
-server->client
-SUBSCRIBE_EVENT
-    uint32 event_type
-    uint32 index
-(no reply)
-
-
-client->server
-GET_SERVER_INFO
-    (no arguments)
-reply
-    uint32 main_output_volume_control
-    uint32 main_input_volume_control
-    uint32 main_output_mute_control
-    uint32 main_input_mute_control
-
-
-client->server
-GET_VOLUME_CONTROL_INFO
-    uint32 index
-    string name
-reply
-    uint32 index
-    string name
-    string description
-    proplist proplist
-    volume volume
-    channel_map channel_map
-    uint64 balance (repeated channel_map.channels times)
-    boolean convertible_to_dB
-
-
-client->server
-GET_VOLUME_CONTROL_INFO_LIST
-    (no arguments)
-reply
-    (the same arguments as with GET_VOLUME_CONTROL_INFO, repeated for each
-    volume control in the system)
-
-
-client->server
-SET_VOLUME_CONTROL_VOLUME
-    uint32 index
-    string name
-    volume volume
-    channel_map channel_map
-    uint64 balance (repeated channel_map.channels times)
-reply
-    (no arguments)
-
-
-client->server
-GET_MUTE_CONTROL_INFO
-    uint32 index
-    string name
-reply
-    uint32 index
-    string name
-    string description
-    proplist proplist
-    boolean mute
-
-
-client->server
-GET_MUTE_CONTROL_INFO_LIST
-    (no arguments)
-reply
-    (the same arguments as with GET_MUTE_CONTROL_INFO, repeated for each mute
-    control in the system)
-
-
-client->server
-SET_MUTE_CONTROL_MUTE
-    uint32 index
-    string name
-    boolean mute
-reply
-    (no arguments)
-
-
-client->server
-GET_DEVICE_INFO
-    uint32 index
-    string name
-reply
-    uint32 index
-    string name
-    string description
-    uint8 direction
-    uint32 n_device_types
-    string device_type (repeated n_device_types times)
-    proplist proplist
-    uint32 volume_control
-    uint32 mute_control
-
-
-client->server
-GET_DEVICE_INFO_LIST
-    (no arguments)
-reply
-    (the same arguments as with GET_DEVICE_INFO, repeated for each device in
-    the system)
-
-
-client->server
-GET_STREAM_INFO
-    uint32 index
-    string name
-reply
-    uint32 index
-    string name
-    string description
-    uint8 direction
-    proplist proplist
-    uint32 volume_control
-    uint32 mute_control
-
-
-client->server
-GET_STREAM_INFO_LIST
-    (no arguments)
-reply
-    (the same arguments as with GET_STREAM_INFO, repeated for each stream in
-    the system)
-
-
-client->server
-GET_AUDIO_GROUP_INFO
-    uint32 index
-    string name
-reply
-    uint32 index
-    string name
-    string description
-    proplist proplist
-    uint32 volume_control
-    uint32 mute_control
-
-
-client->server
-GET_AUDIO_GROUP_INFO_LIST
-    (no arguments)
-reply
-    (the same arguments as with GET_AUDIO_GROUP_INFO, repeated for each audio
-    group in the system)
diff --git a/src/modules/volume-api/audio-group.c b/src/modules/volume-api/audio-group.c
deleted file mode 100644 (file)
index 66e0f8a..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "audio-group.h"
-
-#include <modules/volume-api/sstream.h>
-
-#include <pulsecore/core-util.h>
-
-int pa_audio_group_new(pa_volume_api *api, const char *name, pa_audio_group **_r) {
-    pa_audio_group *group = NULL;
-    int r;
-
-    pa_assert(api);
-    pa_assert(name);
-    pa_assert(_r);
-
-    group = pa_xnew0(pa_audio_group, 1);
-    group->volume_api = api;
-    group->index = pa_volume_api_allocate_audio_group_index(api);
-
-    r = pa_volume_api_register_name(api, name, true, &group->name);
-    if (r < 0)
-        goto fail;
-
-    group->description = pa_xstrdup(group->name);
-    group->proplist = pa_proplist_new();
-    group->volume_streams = pa_hashmap_new(NULL, NULL);
-    group->mute_streams = pa_hashmap_new(NULL, NULL);
-
-    *_r = group;
-    return 0;
-
-fail:
-    if (group)
-        pa_audio_group_free(group);
-
-    return r;
-}
-
-void pa_audio_group_put(pa_audio_group *group) {
-    const char *prop_key;
-    void *state = NULL;
-
-    pa_assert(group);
-
-    pa_volume_api_add_audio_group(group->volume_api, group);
-    group->linked = true;
-
-    pa_log_debug("Created audio group #%u.", group->index);
-    pa_log_debug("    Name: %s", group->name);
-    pa_log_debug("    Description: %s", group->description);
-    pa_log_debug("    Volume control: %s", group->volume_control ? group->volume_control->name : "(unset)");
-    pa_log_debug("    Mute control: %s", group->mute_control ? group->mute_control->name : "(unset)");
-    pa_log_debug("    Properties:");
-
-    while ((prop_key = pa_proplist_iterate(group->proplist, &state)))
-        pa_log_debug("        %s = %s", prop_key, pa_strnull(pa_proplist_gets(group->proplist, prop_key)));
-
-    pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT], group);
-}
-
-void pa_audio_group_unlink(pa_audio_group *group) {
-    pas_stream *stream;
-
-    pa_assert(group);
-
-    if (group->unlinked) {
-        pa_log_debug("Unlinking audio group %s (already unlinked, this is a no-op).", group->name);
-        return;
-    }
-
-    group->unlinked = true;
-
-    pa_log_debug("Unlinking audio group %s.", group->name);
-
-    if (group->linked)
-        pa_volume_api_remove_audio_group(group->volume_api, group);
-
-    pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK], group);
-
-    while ((stream = pa_hashmap_first(group->mute_streams)))
-        pas_stream_set_audio_group_for_mute(stream, NULL);
-
-    while ((stream = pa_hashmap_first(group->volume_streams)))
-        pas_stream_set_audio_group_for_volume(stream, NULL);
-
-    pa_audio_group_set_mute_control(group, NULL);
-    pa_audio_group_set_volume_control(group, NULL);
-}
-
-void pa_audio_group_free(pa_audio_group *group) {
-    pa_assert(group);
-
-    /* unlink() expects name to be set. */
-    if (!group->unlinked && group->name)
-        pa_audio_group_unlink(group);
-
-    if (group->mute_streams)
-        pa_hashmap_free(group->mute_streams);
-
-    if (group->volume_streams)
-        pa_hashmap_free(group->volume_streams);
-
-    if (group->proplist)
-        pa_proplist_free(group->proplist);
-
-    pa_xfree(group->description);
-
-    if (group->name)
-        pa_volume_api_unregister_name(group->volume_api, group->name);
-
-    pa_xfree(group);
-}
-
-void pa_audio_group_set_description(pa_audio_group *group, const char *description) {
-    char *old_description;
-
-    pa_assert(group);
-    pa_assert(description);
-
-    old_description = group->description;
-
-    if (pa_streq(description, old_description))
-        return;
-
-    group->description = pa_xstrdup(description);
-
-    if (!group->linked || group->unlinked) {
-        pa_xfree(old_description);
-        return;
-    }
-
-    pa_log_debug("The description of audio group %s changed from \"%s\" to \"%s\".", group->name, old_description,
-                 description);
-    pa_xfree(old_description);
-
-    pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_DESCRIPTION_CHANGED], group);
-
-}
-
-void pa_audio_group_set_volume_control(pa_audio_group *group, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(group);
-
-    old_control = group->volume_control;
-
-    if (control == old_control)
-        return;
-
-    group->volume_control = control;
-
-    if (!group->linked || group->unlinked)
-        return;
-
-    pa_log_debug("The volume control of audio group %s changed from %s to %s.", group->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED], group);
-}
-
-void pa_audio_group_set_mute_control(pa_audio_group *group, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(group);
-
-    old_control = group->mute_control;
-
-    if (control == old_control)
-        return;
-
-    group->mute_control = control;
-
-    if (!group->linked || group->unlinked)
-        return;
-
-    pa_log_debug("The mute control of audio group %s changed from %s to %s.", group->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&group->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED], group);
-}
-
-void pa_audio_group_add_volume_stream(pa_audio_group *group, pas_stream *stream) {
-    pa_assert(group);
-    pa_assert(stream);
-
-    pa_assert_se(pa_hashmap_put(group->volume_streams, stream, stream) >= 0);
-}
-
-void pa_audio_group_remove_volume_stream(pa_audio_group *group, pas_stream *stream) {
-    pa_assert(group);
-    pa_assert(stream);
-
-    pa_assert_se(pa_hashmap_remove(group->volume_streams, stream));
-}
-
-void pa_audio_group_add_mute_stream(pa_audio_group *group, pas_stream *stream) {
-    pa_assert(group);
-    pa_assert(stream);
-
-    pa_assert_se(pa_hashmap_put(group->mute_streams, stream, stream) >= 0);
-}
-
-void pa_audio_group_remove_mute_stream(pa_audio_group *group, pas_stream *stream) {
-    pa_assert(group);
-    pa_assert(stream);
-
-    pa_assert_se(pa_hashmap_remove(group->mute_streams, stream));
-}
diff --git a/src/modules/volume-api/audio-group.h b/src/modules/volume-api/audio-group.h
deleted file mode 100644 (file)
index 02db3eb..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef fooaudiogrouphfoo
-#define fooaudiogrouphfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulse/proplist.h>
-
-#include <inttypes.h>
-
-typedef struct pa_audio_group pa_audio_group;
-
-struct pa_audio_group {
-    pa_volume_api *volume_api;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_proplist *proplist;
-    pa_volume_control *volume_control;
-    pa_mute_control *mute_control;
-
-    pa_hashmap *volume_streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
-    pa_hashmap *mute_streams; /* pas_stream -> pas_stream (hashmap-as-a-set) */
-
-    bool linked;
-    bool unlinked;
-};
-
-int pa_audio_group_new(pa_volume_api *api, const char *name, pa_audio_group **_r);
-void pa_audio_group_put(pa_audio_group *group);
-void pa_audio_group_unlink(pa_audio_group *group);
-void pa_audio_group_free(pa_audio_group *group);
-
-/* Called by the audio group implementation. */
-void pa_audio_group_set_description(pa_audio_group *group, const char *description);
-void pa_audio_group_set_volume_control(pa_audio_group *group, pa_volume_control *control);
-void pa_audio_group_set_mute_control(pa_audio_group *group, pa_mute_control *control);
-
-/* Called by sstream.c only. If you want to assign a stream to an audio group, use
- * pas_stream_set_audio_group_for_volume() and
- * pas_stream_set_audio_group_for_mute(). */
-void pa_audio_group_add_volume_stream(pa_audio_group *group, pas_stream *stream);
-void pa_audio_group_remove_volume_stream(pa_audio_group *group, pas_stream *stream);
-void pa_audio_group_add_mute_stream(pa_audio_group *group, pas_stream *stream);
-void pa_audio_group_remove_mute_stream(pa_audio_group *group, pas_stream *stream);
-
-#endif
diff --git a/src/modules/volume-api/bvolume.h b/src/modules/volume-api/bvolume.h
deleted file mode 100644 (file)
index 75545dd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef foobvolumehfoo
-#define foobvolumehfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulse/ext-volume-api.h>
-
-typedef pa_ext_volume_api_bvolume pa_bvolume;
-
-#define pa_balance_valid pa_ext_volume_api_balance_valid
-#define pa_bvolume_valid pa_ext_volume_api_bvolume_valid
-#define pa_bvolume_init_invalid pa_ext_volume_api_bvolume_init_invalid
-#define pa_bvolume_init pa_ext_volume_api_bvolume_init
-#define pa_bvolume_init_mono pa_ext_volume_api_bvolume_init_mono
-#define pa_bvolume_parse_balance pa_ext_volume_api_bvolume_parse_balance
-#define pa_bvolume_equal pa_ext_volume_api_bvolume_equal
-#define pa_bvolume_from_cvolume pa_ext_volume_api_bvolume_from_cvolume
-#define pa_bvolume_to_cvolume pa_ext_volume_api_bvolume_to_cvolume
-#define pa_bvolume_copy_balance pa_ext_volume_api_bvolume_copy_balance
-#define pa_bvolume_reset_balance pa_ext_volume_api_bvolume_reset_balance
-#define pa_bvolume_remap pa_ext_volume_api_bvolume_remap
-#define pa_bvolume_balance_to_string pa_ext_volume_api_bvolume_balance_to_string
-
-#define PA_BVOLUME_SNPRINT_BALANCE_MAX PA_EXT_VOLUME_API_BVOLUME_SNPRINT_BALANCE_MAX
-#define pa_bvolume_snprint_balance pa_ext_volume_api_bvolume_snprint_balance
-
-#endif
diff --git a/src/modules/volume-api/device-creator.c b/src/modules/volume-api/device-creator.c
deleted file mode 100644 (file)
index fc486f8..0000000
+++ /dev/null
@@ -1,1083 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "device-creator.h"
-
-#include <modules/volume-api/device.h>
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/i18n.h>
-
-struct pa_device_creator {
-    pa_volume_api *volume_api;
-    pa_hashmap *devices; /* pa_device_port/pa_sink/pa_source -> struct device */
-    pa_hook_slot *card_put_slot;
-    pa_hook_slot *card_unlink_slot;
-    pa_hook_slot *sink_put_slot;
-    pa_hook_slot *sink_unlink_slot;
-    pa_hook_slot *source_put_slot;
-    pa_hook_slot *source_unlink_slot;
-};
-
-enum device_type {
-    DEVICE_TYPE_PORT,
-    DEVICE_TYPE_PORT_MONITOR,
-    DEVICE_TYPE_SINK,
-    DEVICE_TYPE_SOURCE,
-};
-
-struct device_volume_control {
-    struct device *device;
-    pa_volume_control *volume_control;
-
-    bool unlinked;
-
-    pa_hook_slot *volume_changed_slot;
-};
-
-static void device_volume_control_free(struct device_volume_control *control);
-
-struct device_mute_control {
-    struct device *device;
-    pa_mute_control *mute_control;
-
-    bool unlinked;
-
-    pa_hook_slot *mute_changed_slot;
-};
-
-static void device_mute_control_free(struct device_mute_control *control);
-
-struct device {
-    pa_device_creator *creator;
-    enum device_type type;
-    pa_device_port *port;
-    pa_sink *sink;
-    pa_source *source;
-    pa_device *device;
-    struct device_volume_control *volume_control;
-    struct device_mute_control *mute_control;
-
-    bool unlinked;
-
-    pa_hook_slot *proplist_changed_slot;
-    pa_hook_slot *port_active_changed_slot;
-    struct device *monitor;
-};
-
-static void device_free(struct device *device);
-
-static const char *device_type_from_icon_name(const char *icon_name) {
-    if (!icon_name)
-        return NULL;
-
-    if (pa_streq(icon_name, "audio-input-microphone"))
-        return "microphone";
-
-    if (pa_streq(icon_name, "audio-speakers"))
-        return "speakers";
-
-    if (pa_streq(icon_name, "audio-headphones"))
-        return "headphones";
-
-    return NULL;
-}
-
-static const char *device_type_from_port_name(pa_device_port *port) {
-    pa_assert(port);
-
-    if (strstr(port->name, "analog")) {
-        if (port->direction == PA_DIRECTION_INPUT)
-            return "analog-input";
-        else
-            return "analog-output";
-    }
-
-    if (strstr(port->name, "hdmi")) {
-        if (port->direction == PA_DIRECTION_INPUT)
-            return "hdmi-input";
-        else
-            return "hdmi-output";
-    }
-
-    if (strstr(port->name, "iec958")) {
-        if (port->direction == PA_DIRECTION_INPUT)
-            return "spdif-input";
-        else
-            return "spdif-output";
-    }
-
-    return NULL;
-}
-
-static const char *device_type_from_port(pa_device_port *port) {
-    const char *device_type;
-
-    pa_assert(port);
-
-    device_type = device_type_from_icon_name(pa_proplist_gets(port->proplist, PA_PROP_DEVICE_ICON_NAME));
-    if (device_type)
-        return device_type;
-
-    device_type = device_type_from_port_name(port);
-    if (device_type)
-        return device_type;
-
-    return NULL;
-}
-
-static const char *get_sink_description(pa_sink *sink) {
-    const char *description;
-
-    pa_assert(sink);
-
-    description = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
-    if (description)
-        return description;
-
-    return sink->name;
-}
-
-static const char *get_source_description(pa_source *source) {
-    const char *description;
-
-    pa_assert(source);
-
-    description = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION);
-    if (description)
-        return description;
-
-    return source->name;
-}
-
-static pa_hook_result_t sink_or_source_volume_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct device_volume_control *control = userdata;
-    struct device *device;
-    pa_sink *sink = NULL;
-    pa_source *source = NULL;
-    pa_bvolume bvolume;
-
-    pa_assert(control);
-    pa_assert(call_data);
-
-    device = control->device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                sink = call_data;
-            else
-                source = call_data;
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-        case DEVICE_TYPE_SOURCE:
-            source = call_data;
-            break;
-
-        case DEVICE_TYPE_SINK:
-            sink = call_data;
-            break;
-    }
-
-    if ((sink && sink != device->sink) || (source && source != device->source))
-        return PA_HOOK_OK;
-
-    if (sink)
-        pa_bvolume_from_cvolume(&bvolume, &sink->reference_volume, &sink->channel_map);
-    else if (source)
-        pa_bvolume_from_cvolume(&bvolume, &source->reference_volume, &source->channel_map);
-    else
-        pa_assert_not_reached();
-
-    pa_volume_control_set_volume(control->volume_control, &bvolume, true, true);
-
-    return PA_HOOK_OK;
-}
-
-static int volume_control_set_volume_cb(pa_volume_control *c, const pa_bvolume *original_volume,
-                                        const pa_bvolume *remapped_volume, bool set_volume, bool set_balance) {
-    struct device_volume_control *control;
-    struct device *device;
-    pa_bvolume bvolume;
-    pa_cvolume cvolume;
-
-    pa_assert(c);
-    pa_assert(original_volume);
-    pa_assert(remapped_volume);
-
-    control = c->userdata;
-    device = control->device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                pa_bvolume_from_cvolume(&bvolume, &device->sink->reference_volume, &device->sink->channel_map);
-            else
-                pa_bvolume_from_cvolume(&bvolume, &device->source->reference_volume, &device->source->channel_map);
-            break;
-
-        case DEVICE_TYPE_SINK:
-            pa_bvolume_from_cvolume(&bvolume, &device->sink->reference_volume, &device->sink->channel_map);
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-        case DEVICE_TYPE_SOURCE:
-            pa_bvolume_from_cvolume(&bvolume, &device->source->reference_volume, &device->source->channel_map);
-            break;
-    }
-
-    if (set_volume)
-        bvolume.volume = remapped_volume->volume;
-
-    if (set_balance)
-        pa_bvolume_copy_balance(&bvolume, remapped_volume);
-
-    pa_bvolume_to_cvolume(&bvolume, &cvolume);
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                pa_sink_set_volume(device->sink, &cvolume, true, true);
-            else
-                pa_source_set_volume(device->source, &cvolume, true, true);
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-        case DEVICE_TYPE_SOURCE:
-            pa_source_set_volume(device->source, &cvolume, true, true);
-            break;
-
-        case DEVICE_TYPE_SINK:
-            pa_sink_set_volume(device->sink, &cvolume, true, true);
-            break;
-    }
-
-    return 0;
-}
-
-static int device_volume_control_new(struct device *device, struct device_volume_control **_r) {
-    struct device_volume_control *control = NULL;
-    const char *name = NULL;
-    pa_bvolume volume;
-    bool convertible_to_dB = false;
-    int r;
-
-    pa_assert(device);
-    pa_assert(_r);
-
-    control = pa_xnew0(struct device_volume_control, 1);
-    control->device = device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            name = "port-volume-control";
-
-            if (device->port->direction == PA_DIRECTION_OUTPUT) {
-                control->volume_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED],
-                                                               PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
-                pa_bvolume_from_cvolume(&volume, &device->sink->reference_volume, &device->sink->channel_map);
-                convertible_to_dB = device->sink->flags & PA_SINK_DECIBEL_VOLUME;
-            } else {
-                control->volume_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
-                                                               PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
-                pa_bvolume_from_cvolume(&volume, &device->source->reference_volume, &device->source->channel_map);
-                convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
-            }
-
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            name = "port-monitor-volume-control";
-            control->volume_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
-                                                           PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
-            pa_bvolume_from_cvolume(&volume, &device->source->reference_volume, &device->source->channel_map);
-            convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
-            break;
-
-        case DEVICE_TYPE_SINK:
-            name = "sink-volume-control";
-            control->volume_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED],
-                                                           PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
-            pa_bvolume_from_cvolume(&volume, &device->sink->reference_volume, &device->sink->channel_map);
-            convertible_to_dB = device->sink->flags & PA_SINK_DECIBEL_VOLUME;
-            break;
-
-        case DEVICE_TYPE_SOURCE:
-            name = "source-volume-control";
-            control->volume_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
-                                                           PA_HOOK_NORMAL, sink_or_source_volume_changed_cb, control);
-            pa_bvolume_from_cvolume(&volume, &device->source->reference_volume, &device->source->channel_map);
-            convertible_to_dB = device->source->flags & PA_SOURCE_DECIBEL_VOLUME;
-            break;
-    }
-
-    r = pa_volume_control_new(device->creator->volume_api, name, false, &control->volume_control);
-    if (r < 0)
-        goto fail;
-
-    pa_volume_control_set_description(control->volume_control, device->device->description);
-    pa_volume_control_set_channel_map(control->volume_control, &volume.channel_map);
-    pa_volume_control_set_volume(control->volume_control, &volume, true, true);
-    pa_volume_control_set_convertible_to_dB(control->volume_control, convertible_to_dB);
-    control->volume_control->set_volume = volume_control_set_volume_cb;
-    control->volume_control->userdata = control;
-
-    *_r = control;
-    return 0;
-
-fail:
-    if (control)
-        device_volume_control_free(control);
-
-    return r;
-}
-
-static void device_volume_control_put(struct device_volume_control *control) {
-    pa_assert(control);
-
-    pa_volume_control_put(control->volume_control);
-}
-
-static void device_volume_control_unlink(struct device_volume_control *control) {
-    pa_assert(control);
-
-    if (control->unlinked)
-        return;
-
-    control->unlinked = true;
-
-    if (control->volume_control)
-        pa_volume_control_unlink(control->volume_control);
-}
-
-static void device_volume_control_free(struct device_volume_control *control) {
-    pa_assert(control);
-
-    if (!control->unlinked)
-        device_volume_control_unlink(control);
-
-    if (control->volume_control)
-        pa_volume_control_free(control->volume_control);
-
-    if (control->volume_changed_slot)
-        pa_hook_slot_free(control->volume_changed_slot);
-
-    pa_xfree(control);
-}
-
-static pa_hook_result_t sink_or_source_mute_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct device_mute_control *control = userdata;
-    struct device *device;
-    pa_sink *sink = NULL;
-    pa_source *source = NULL;
-    bool mute;
-
-    pa_assert(control);
-    pa_assert(call_data);
-
-    device = control->device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                sink = call_data;
-            else
-                source = call_data;
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-        case DEVICE_TYPE_SOURCE:
-            source = call_data;
-            break;
-
-        case DEVICE_TYPE_SINK:
-            sink = call_data;
-            break;
-    }
-
-    if ((sink && sink != device->sink) || (source && source != device->source))
-        return PA_HOOK_OK;
-
-    if (sink)
-        mute = sink->muted;
-    else if (source)
-        mute = source->muted;
-    else
-        pa_assert_not_reached();
-
-    pa_mute_control_set_mute(control->mute_control, mute);
-
-    return PA_HOOK_OK;
-}
-
-static int mute_control_set_mute_cb(pa_mute_control *c, bool mute) {
-    struct device_mute_control *control;
-    struct device *device;
-
-    pa_assert(c);
-
-    control = c->userdata;
-    device = control->device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                pa_sink_set_mute(device->sink, mute, true);
-            else
-                pa_source_set_mute(device->source, mute, true);
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-        case DEVICE_TYPE_SOURCE:
-            pa_source_set_mute(device->source, mute, true);
-            break;
-
-        case DEVICE_TYPE_SINK:
-            pa_sink_set_mute(device->sink, mute, true);
-            break;
-    }
-
-    return 0;
-}
-
-static int device_mute_control_new(struct device *device, struct device_mute_control **_r) {
-    struct device_mute_control *control = NULL;
-    const char *name = NULL;
-    bool mute = false;
-    int r;
-
-    pa_assert(device);
-    pa_assert(_r);
-
-    control = pa_xnew0(struct device_mute_control, 1);
-    control->device = device;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            name = "port-mute-control";
-
-            if (device->port->direction == PA_DIRECTION_OUTPUT) {
-                control->mute_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED],
-                                                             PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
-                mute = device->sink->muted;
-            } else {
-                control->mute_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SOURCE_MUTE_CHANGED],
-                                                             PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
-                mute = device->source->muted;
-            }
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            name = "port-monitor-mute-control";
-            control->mute_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_SOURCE_MUTE_CHANGED],
-                                                         PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
-            mute = device->source->muted;
-            break;
-
-        case DEVICE_TYPE_SINK:
-            name = "sink-mute-control";
-            control->mute_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED],
-                                                         PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
-            mute = device->sink->muted;
-            break;
-
-        case DEVICE_TYPE_SOURCE:
-            name = "source-mute-control";
-            control->mute_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_MUTE_CHANGED],
-                                                         PA_HOOK_NORMAL, sink_or_source_mute_changed_cb, control);
-            mute = device->source->muted;
-            break;
-    }
-
-    r = pa_mute_control_new(device->creator->volume_api, name, false, &control->mute_control);
-    if (r < 0)
-        goto fail;
-
-    pa_mute_control_set_description(control->mute_control, device->device->description);
-    pa_mute_control_set_mute(control->mute_control, mute);
-    control->mute_control->set_mute = mute_control_set_mute_cb;
-    control->mute_control->userdata = control;
-
-    *_r = control;
-    return 0;
-
-fail:
-    if (control)
-        device_mute_control_free(control);
-
-    return r;
-}
-
-static void device_mute_control_put(struct device_mute_control *control) {
-    pa_assert(control);
-
-    pa_mute_control_put(control->mute_control);
-}
-
-static void device_mute_control_unlink(struct device_mute_control *control) {
-    pa_assert(control);
-
-    if (control->unlinked)
-        return;
-
-    control->unlinked = true;
-
-    if (control->mute_control)
-        pa_mute_control_unlink(control->mute_control);
-}
-
-static void device_mute_control_free(struct device_mute_control *control) {
-    pa_assert(control);
-
-    if (!control->unlinked)
-        device_mute_control_unlink(control);
-
-    if (control->mute_control)
-        pa_mute_control_free(control->mute_control);
-
-    if (control->mute_changed_slot)
-        pa_hook_slot_free(control->mute_changed_slot);
-
-    pa_xfree(control);
-}
-
-static void device_set_sink_and_source_from_port(struct device *device) {
-    pa_sink *sink;
-    pa_source *source;
-    uint32_t idx;
-
-    pa_assert(device);
-
-    device->sink = NULL;
-    device->source = NULL;
-
-    if (!device->port->active)
-        return;
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT) {
-                PA_IDXSET_FOREACH(sink, device->port->card->sinks, idx) {
-                    if (sink->active_port == device->port) {
-                        device->sink = sink;
-                        break;
-                    }
-                }
-
-                pa_assert(device->sink);
-            } else {
-                PA_IDXSET_FOREACH(source, device->port->card->sources, idx) {
-                    if (source->active_port == device->port) {
-                        device->source = source;
-                        break;
-                    }
-                }
-
-                pa_assert(device->source);
-            }
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR: {
-            PA_IDXSET_FOREACH(sink, device->port->card->sinks, idx) {
-                if (sink->active_port == device->port) {
-                    device->sink = sink;
-                    device->source = sink->monitor_source;
-                    break;
-                }
-            }
-
-            pa_assert(device->sink);
-            break;
-        }
-
-        case DEVICE_TYPE_SINK:
-        case DEVICE_TYPE_SOURCE:
-            pa_assert_not_reached();
-    }
-}
-
-static pa_hook_result_t sink_or_source_proplist_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct device *device = userdata;
-    pa_sink *sink = NULL;
-    pa_source *source = NULL;
-    const char *description = NULL;
-
-    pa_assert(device);
-    pa_assert(call_data);
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-        case DEVICE_TYPE_PORT_MONITOR:
-            pa_assert_not_reached();
-
-        case DEVICE_TYPE_SINK:
-            sink = call_data;
-
-            if (sink != device->sink)
-                return PA_HOOK_OK;
-
-            description = get_sink_description(sink);
-            break;
-
-        case DEVICE_TYPE_SOURCE:
-            source = call_data;
-
-            if (source != device->source)
-                return PA_HOOK_OK;
-
-            description = get_source_description(source);
-            break;
-    }
-
-    pa_device_description_changed(device->device, description);
-    pa_volume_control_set_description(device->volume_control->volume_control, description);
-    pa_mute_control_set_description(device->mute_control->mute_control, description);
-
-    return PA_HOOK_OK;
-}
-
-static int device_new(pa_device_creator *creator, enum device_type type, void *core_device, struct device **_r) {
-    struct device *device = NULL;
-    const char *name = NULL;
-    char *description = NULL;
-    pa_direction_t direction = PA_DIRECTION_OUTPUT;
-    const char *device_type = NULL;
-    bool create_volume_and_mute_controls = true;
-    int r;
-
-    pa_assert(creator);
-    pa_assert(core_device);
-    pa_assert(_r);
-
-    device = pa_xnew0(struct device, 1);
-    device->creator = creator;
-    device->type = type;
-
-    switch (type) {
-        case DEVICE_TYPE_PORT:
-            device->port = core_device;
-            device_set_sink_and_source_from_port(device);
-            name = "port-device";
-            description = pa_xstrdup(device->port->description);
-            direction = device->port->direction;
-            device_type = device_type_from_port(device->port);
-
-            if (!device->sink && !device->source)
-                create_volume_and_mute_controls = false;
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            device->port = core_device;
-            device_set_sink_and_source_from_port(device);
-            name = "port-monitor-device";
-            description = pa_sprintf_malloc(_("Monitor of %s"), device->port->description);
-            direction = PA_DIRECTION_INPUT;
-
-            if (!device->source)
-                create_volume_and_mute_controls = false;
-            break;
-
-        case DEVICE_TYPE_SINK:
-            device->sink = core_device;
-            name = "sink-device";
-            description = pa_xstrdup(get_sink_description(device->sink));
-            direction = PA_DIRECTION_OUTPUT;
-            break;
-
-        case DEVICE_TYPE_SOURCE:
-            device->source = core_device;
-            name = "source-device";
-            description = pa_xstrdup(get_source_description(device->source));
-            direction = PA_DIRECTION_INPUT;
-            break;
-    }
-
-    r = pa_device_new(creator->volume_api, name, description, direction, &device_type, device_type ? 1 : 0, &device->device);
-    pa_xfree(description);
-    if (r < 0)
-        goto fail;
-
-    if (create_volume_and_mute_controls) {
-        device_volume_control_new(device, &device->volume_control);
-        device_mute_control_new(device, &device->mute_control);
-    }
-
-    switch (type) {
-        case DEVICE_TYPE_PORT:
-            if (device->port->direction == PA_DIRECTION_OUTPUT)
-                device_new(creator, DEVICE_TYPE_PORT_MONITOR, device->port, &device->monitor);
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            break;
-
-        case DEVICE_TYPE_SINK:
-            device->proplist_changed_slot = pa_hook_connect(&device->sink->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED],
-                                                            PA_HOOK_NORMAL, sink_or_source_proplist_changed_cb, device);
-            break;
-
-        case DEVICE_TYPE_SOURCE:
-            device->proplist_changed_slot = pa_hook_connect(&device->source->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED],
-                                                            PA_HOOK_NORMAL, sink_or_source_proplist_changed_cb, device);
-            break;
-    }
-
-    *_r = device;
-    return 0;
-
-fail:
-    if (device)
-        device_free(device);
-
-    return r;
-}
-
-static pa_hook_result_t port_active_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct device *device = userdata;
-    pa_device_port *port = call_data;
-    bool should_have_volume_and_mute_controls = false;
-
-    pa_assert(device);
-    pa_assert(port);
-
-    if (port != device->port)
-        return PA_HOOK_OK;
-
-    device_set_sink_and_source_from_port(device);
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-            should_have_volume_and_mute_controls = device->sink || device->source;
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            should_have_volume_and_mute_controls = !!device->source;
-            break;
-
-        case DEVICE_TYPE_SINK:
-        case DEVICE_TYPE_SOURCE:
-            pa_assert_not_reached();
-    }
-
-    if (should_have_volume_and_mute_controls) {
-        int r;
-
-        if (!device->volume_control) {
-            r = device_volume_control_new(device, &device->volume_control);
-            if (r >= 0) {
-                device_volume_control_put(device->volume_control);
-                pa_device_set_default_volume_control(device->device, device->volume_control->volume_control);
-            }
-        }
-
-        if (!device->mute_control) {
-            r = device_mute_control_new(device, &device->mute_control);
-            if (r >= 0) {
-                device_mute_control_put(device->mute_control);
-                pa_device_set_default_mute_control(device->device, device->mute_control->mute_control);
-            }
-        }
-    }
-
-    if (!should_have_volume_and_mute_controls) {
-        if (device->mute_control) {
-            device_mute_control_free(device->mute_control);
-            device->mute_control = NULL;
-        }
-
-        if (device->volume_control) {
-            device_volume_control_free(device->volume_control);
-            device->volume_control = NULL;
-        }
-    }
-
-    return PA_HOOK_OK;
-}
-
-static void device_put(struct device *device) {
-    pa_assert(device);
-
-    switch (device->type) {
-        case DEVICE_TYPE_PORT:
-        case DEVICE_TYPE_PORT_MONITOR:
-            device->port_active_changed_slot = pa_hook_connect(&device->port->core->hooks[PA_CORE_HOOK_PORT_ACTIVE_CHANGED],
-                                                               PA_HOOK_NORMAL, port_active_changed_cb, device);
-
-        case DEVICE_TYPE_SINK:
-        case DEVICE_TYPE_SOURCE:
-            break;
-    }
-
-    if (device->volume_control)
-        device_volume_control_put(device->volume_control);
-
-    if (device->mute_control)
-        device_mute_control_put(device->mute_control);
-
-    pa_device_put(device->device, device->volume_control ? device->volume_control->volume_control : NULL,
-                  device->mute_control ? device->mute_control->mute_control : NULL);
-
-    if (device->monitor)
-        device_put(device->monitor);
-}
-
-static void device_unlink(struct device *device) {
-    pa_assert(device);
-
-    if (device->unlinked)
-        return;
-
-    device->unlinked = true;
-
-    if (device->monitor)
-        device_unlink(device->monitor);
-
-    if (device->device)
-        pa_device_unlink(device->device);
-
-    if (device->mute_control)
-        device_mute_control_unlink(device->mute_control);
-
-    if (device->volume_control)
-        device_volume_control_unlink(device->volume_control);
-
-    if (device->port_active_changed_slot) {
-        pa_hook_slot_free(device->port_active_changed_slot);
-        device->port_active_changed_slot = NULL;
-    }
-}
-
-static void device_free(struct device *device) {
-    pa_assert(device);
-
-    if (!device->unlinked)
-        device_unlink(device);
-
-    if (device->monitor)
-        device_free(device->monitor);
-
-    if (device->proplist_changed_slot)
-        pa_hook_slot_free(device->proplist_changed_slot);
-
-    if (device->mute_control)
-        device_mute_control_free(device->mute_control);
-
-    if (device->volume_control)
-        device_volume_control_free(device->volume_control);
-
-    if (device->device)
-        pa_device_free(device->device);
-
-    pa_xfree(device);
-}
-
-static void create_device(pa_device_creator *creator, enum device_type type, void *core_device) {
-    struct device *device;
-    int r;
-
-    pa_assert(creator);
-    pa_assert(core_device);
-
-    switch (type) {
-        case DEVICE_TYPE_PORT:
-            break;
-
-        case DEVICE_TYPE_PORT_MONITOR:
-            pa_assert_not_reached();
-
-        case DEVICE_TYPE_SINK:
-            if (!pa_hashmap_isempty(((pa_sink *) core_device)->ports))
-                return;
-            break;
-
-        case DEVICE_TYPE_SOURCE: {
-            pa_source *source = core_device;
-
-            if (source->monitor_of && !pa_hashmap_isempty(source->monitor_of->ports))
-                return;
-
-            if (!pa_hashmap_isempty(((pa_source *) core_device)->ports))
-                return;
-            break;
-        }
-    }
-
-    r = device_new(creator, type, core_device, &device);
-    if (r >= 0) {
-        pa_hashmap_put(creator->devices, core_device, device);
-        device_put(device);
-    }
-}
-
-static pa_hook_result_t card_put_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_card *card = call_data;
-    pa_device_port *port;
-    void *state;
-
-    pa_assert(creator);
-    pa_assert(card);
-
-    PA_HASHMAP_FOREACH(port, card->ports, state)
-        create_device(creator, DEVICE_TYPE_PORT, port);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t card_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_card *card = call_data;
-    pa_device_port *port;
-    void *state;
-
-    pa_assert(creator);
-    pa_assert(card);
-
-    PA_HASHMAP_FOREACH(port, card->ports, state)
-        pa_hashmap_remove_and_free(creator->devices, port);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_sink *sink = call_data;
-
-    pa_assert(creator);
-    pa_assert(sink);
-
-    create_device(creator, DEVICE_TYPE_SINK, sink);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_sink *sink = call_data;
-
-    pa_assert(creator);
-    pa_assert(sink);
-
-    pa_hashmap_remove_and_free(creator->devices, sink);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_source *source = call_data;
-
-    pa_assert(creator);
-    pa_assert(source);
-
-    create_device(creator, DEVICE_TYPE_SOURCE, source);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_device_creator *creator = userdata;
-    pa_source *source = call_data;
-
-    pa_assert(creator);
-    pa_assert(source);
-
-    pa_hashmap_remove_and_free(creator->devices, source);
-
-    return PA_HOOK_OK;
-}
-
-pa_device_creator *pa_device_creator_new(pa_volume_api *api) {
-    pa_device_creator *creator;
-    pa_card *card;
-    uint32_t idx;
-    pa_sink *sink;
-    pa_source *source;
-
-    pa_assert(api);
-
-    creator = pa_xnew0(pa_device_creator, 1);
-    creator->volume_api = api;
-    creator->devices = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) device_free);
-    creator->card_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_CARD_PUT], PA_HOOK_NORMAL, card_put_cb, creator);
-    creator->card_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_CARD_UNLINK], PA_HOOK_NORMAL, card_unlink_cb,
-                                                creator);
-    creator->sink_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, creator);
-    creator->sink_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb,
-                                                creator);
-    creator->source_put_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb,
-                                               creator);
-    creator->source_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_NORMAL,
-                                                  source_unlink_cb, creator);
-
-    PA_IDXSET_FOREACH(card, api->core->cards, idx) {
-        pa_device_port *port;
-        void *state;
-
-        PA_HASHMAP_FOREACH(port, card->ports, state)
-            create_device(creator, DEVICE_TYPE_PORT, port);
-    }
-
-    PA_IDXSET_FOREACH(sink, api->core->sinks, idx)
-        create_device(creator, DEVICE_TYPE_SINK, sink);
-
-    PA_IDXSET_FOREACH(source, api->core->sources, idx)
-        create_device(creator, DEVICE_TYPE_SOURCE, source);
-
-    return creator;
-}
-
-void pa_device_creator_free(pa_device_creator *creator) {
-    pa_assert(creator);
-
-    if (creator->devices)
-        pa_hashmap_remove_all(creator->devices);
-
-    if (creator->source_unlink_slot)
-        pa_hook_slot_free(creator->source_unlink_slot);
-
-    if (creator->source_put_slot)
-        pa_hook_slot_free(creator->source_put_slot);
-
-    if (creator->sink_unlink_slot)
-        pa_hook_slot_free(creator->sink_unlink_slot);
-
-    if (creator->sink_put_slot)
-        pa_hook_slot_free(creator->sink_put_slot);
-
-    if (creator->card_unlink_slot)
-        pa_hook_slot_free(creator->card_unlink_slot);
-
-    if (creator->card_put_slot)
-        pa_hook_slot_free(creator->card_put_slot);
-
-    if (creator->devices)
-        pa_hashmap_free(creator->devices);
-
-    pa_xfree(creator);
-}
diff --git a/src/modules/volume-api/device-creator.h b/src/modules/volume-api/device-creator.h
deleted file mode 100644 (file)
index bcec8d9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef foodevicecreatorhfoo
-#define foodevicecreatorhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/volume-api.h>
-
-typedef struct pa_device_creator pa_device_creator;
-
-pa_device_creator *pa_device_creator_new(pa_volume_api *api);
-void pa_device_creator_free(pa_device_creator *creator);
-
-#endif
diff --git a/src/modules/volume-api/device.c b/src/modules/volume-api/device.c
deleted file mode 100644 (file)
index c1a580c..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "device.h"
-
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulse/direction.h>
-
-#include <pulsecore/core-util.h>
-
-int pa_device_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction,
-                  const char * const *device_types, unsigned n_device_types, pa_device **_r) {
-    pa_device *device = NULL;
-    int r;
-    unsigned i;
-
-    pa_assert(api);
-    pa_assert(name);
-    pa_assert(description);
-    pa_assert(device_types || n_device_types == 0);
-    pa_assert(_r);
-
-    device = pa_xnew0(pa_device, 1);
-    device->volume_api = api;
-    device->index = pa_volume_api_allocate_device_index(api);
-
-    r = pa_volume_api_register_name(api, name, false, &device->name);
-    if (r < 0)
-        goto fail;
-
-    device->description = pa_xstrdup(description);
-    device->direction = direction;
-    device->device_types = pa_dynarray_new(pa_xfree);
-
-    for (i = 0; i < n_device_types; i++)
-        pa_dynarray_append(device->device_types, pa_xstrdup(device_types[i]));
-
-    device->proplist = pa_proplist_new();
-    device->use_default_volume_control = true;
-    device->use_default_mute_control = true;
-
-    *_r = device;
-    return 0;
-
-fail:
-    if (device)
-        pa_device_free(device);
-
-    return r;
-}
-
-void pa_device_put(pa_device *device, pa_volume_control *default_volume_control, pa_mute_control *default_mute_control) {
-    char *device_types_str;
-    const char *prop_key;
-    void *state = NULL;
-
-    pa_assert(device);
-
-    if (default_volume_control) {
-        device->default_volume_control = default_volume_control;
-        pa_volume_control_add_default_for_device(default_volume_control, device);
-
-        device->volume_control = default_volume_control;
-        pa_volume_control_add_device(default_volume_control, device);
-    }
-
-    if (default_mute_control) {
-        device->default_mute_control = default_mute_control;
-        pa_mute_control_add_default_for_device(default_mute_control, device);
-
-        device->mute_control = default_mute_control;
-        pa_mute_control_add_device(default_mute_control, device);
-    }
-
-    pa_volume_api_add_device(device->volume_api, device);
-    device->linked = true;
-
-    device_types_str = pa_join((const char * const *) pa_dynarray_get_raw_array(device->device_types),
-                               pa_dynarray_size(device->device_types), ", ");
-
-    pa_log_debug("Created device #%u.", device->index);
-    pa_log_debug("    Name: %s", device->name);
-    pa_log_debug("    Description: %s", device->description);
-    pa_log_debug("    Direction: %s", pa_direction_to_string(device->direction));
-    pa_log_debug("    Device Types: %s", *device_types_str ? device_types_str : "(none)");
-    pa_log_debug("    Volume control: %s", device->volume_control ? device->volume_control->name : "(unset)");
-    pa_log_debug("    Mute control: %s", device->mute_control ? device->mute_control->name : "(unset)");
-    pa_log_debug("    Properties:");
-
-    while ((prop_key = pa_proplist_iterate(device->proplist, &state)))
-        pa_log_debug("        %s = %s", prop_key, pa_strnull(pa_proplist_gets(device->proplist, prop_key)));
-
-    pa_xfree(device_types_str);
-
-    pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_PUT], device);
-}
-
-void pa_device_unlink(pa_device *device) {
-    pa_assert(device);
-
-    if (device->unlinked) {
-        pa_log_debug("Unlinking device %s (already unlinked, this is a no-op).", device->name);
-        return;
-    }
-
-    device->unlinked = true;
-
-    pa_log_debug("Unlinking device %s.", device->name);
-
-    if (device->linked)
-        pa_volume_api_remove_device(device->volume_api, device);
-
-    pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_UNLINK], device);
-
-    pa_device_set_mute_control(device, NULL);
-    pa_device_set_default_mute_control(device, NULL);
-    pa_device_set_volume_control(device, NULL);
-    pa_device_set_default_volume_control(device, NULL);
-}
-
-void pa_device_free(pa_device *device) {
-    pa_assert(device);
-
-    /* unlink() expects name to be set. */
-    if (!device->unlinked && device->name)
-        pa_device_unlink(device);
-
-    if (device->proplist)
-        pa_proplist_free(device->proplist);
-
-    if (device->device_types)
-        pa_dynarray_free(device->device_types);
-
-    pa_xfree(device->description);
-
-    if (device->name)
-        pa_volume_api_unregister_name(device->volume_api, device->name);
-
-    pa_xfree(device);
-}
-
-static void set_volume_control_internal(pa_device *device, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(device);
-
-    old_control = device->volume_control;
-
-    if (control == old_control)
-        return;
-
-    if (old_control)
-        pa_volume_control_remove_device(old_control, device);
-
-    device->volume_control = control;
-
-    if (control)
-        pa_volume_control_add_device(control, device);
-
-    if (!device->linked || device->unlinked)
-        return;
-
-    pa_log_debug("The volume control of device %s changed from %s to %s.", device->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_VOLUME_CONTROL_CHANGED], device);
-}
-
-void pa_device_set_volume_control(pa_device *device, pa_volume_control *control) {
-    pa_assert(device);
-
-    device->use_default_volume_control = false;
-    set_volume_control_internal(device, control);
-}
-
-static void set_mute_control_internal(pa_device *device, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(device);
-
-    old_control = device->mute_control;
-
-    if (control == old_control)
-        return;
-
-    if (old_control)
-        pa_mute_control_remove_device(old_control, device);
-
-    device->mute_control = control;
-
-    if (control)
-        pa_mute_control_add_device(control, device);
-
-    pa_log_debug("The mute control of device %s changed from %s to %s.", device->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_MUTE_CONTROL_CHANGED], device);
-}
-
-void pa_device_set_mute_control(pa_device *device, pa_mute_control *control) {
-    pa_assert(device);
-
-    device->use_default_mute_control = false;
-    set_mute_control_internal(device, control);
-}
-
-void pa_device_description_changed(pa_device *device, const char *new_description) {
-    char *old_description;
-
-    pa_assert(device);
-    pa_assert(new_description);
-
-    old_description = device->description;
-
-    if (pa_streq(new_description, old_description))
-        return;
-
-    device->description = pa_xstrdup(new_description);
-    pa_log_debug("The description of device %s changed from \"%s\" to \"%s\".", device->name, old_description,
-                 new_description);
-    pa_xfree(old_description);
-    pa_hook_fire(&device->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_DESCRIPTION_CHANGED], device);
-}
-
-void pa_device_set_default_volume_control(pa_device *device, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(device);
-
-    old_control = device->default_volume_control;
-
-    if (control == old_control)
-        return;
-
-    if (old_control)
-        pa_volume_control_remove_default_for_device(old_control, device);
-
-    device->default_volume_control = control;
-
-    if (control)
-        pa_volume_control_add_default_for_device(control, device);
-
-    if (device->use_default_volume_control)
-        set_volume_control_internal(device, control);
-}
-
-void pa_device_set_default_mute_control(pa_device *device, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(device);
-
-    old_control = device->default_mute_control;
-
-    if (control == old_control)
-        return;
-
-    if (old_control)
-        pa_mute_control_remove_default_for_device(old_control, device);
-
-    device->default_mute_control = control;
-
-    if (control)
-        pa_mute_control_add_default_for_device(control, device);
-
-    if (device->use_default_mute_control)
-        set_mute_control_internal(device, control);
-}
diff --git a/src/modules/volume-api/device.h b/src/modules/volume-api/device.h
deleted file mode 100644 (file)
index 8bd5158..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef foodevicehfoo
-#define foodevicehfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/volume-api.h>
-
-#include <pulsecore/dynarray.h>
-
-typedef struct pa_device pa_device;
-
-struct pa_device {
-    pa_volume_api *volume_api;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_direction_t direction;
-    pa_dynarray *device_types;
-    pa_proplist *proplist;
-    pa_volume_control *volume_control;
-    pa_mute_control *mute_control;
-
-    /* The device implementation can provide default volume and mute controls,
-     * which are used in case there's no policy module that wants to override
-     * the defaults. */
-    pa_volume_control *default_volume_control;
-    bool use_default_volume_control;
-    pa_mute_control *default_mute_control;
-    bool use_default_mute_control;
-
-    bool linked;
-    bool unlinked;
-};
-
-int pa_device_new(pa_volume_api *api, const char *name, const char *description, pa_direction_t direction,
-                  const char * const *device_types, unsigned n_device_types, pa_device **_r);
-void pa_device_put(pa_device *device, pa_volume_control *default_volume_control, pa_mute_control *default_mute_control);
-void pa_device_unlink(pa_device *device);
-void pa_device_free(pa_device *device);
-
-/* Called by policy modules. */
-void pa_device_set_volume_control(pa_device *device, pa_volume_control *control);
-void pa_device_set_mute_control(pa_device *device, pa_mute_control *control);
-
-/* Called by policy modules. Note that pa_device_set_volume_control() and
- * pa_device_set_mute_control() automatically disable the corresponding
- * use_default flags, so these functions are mainly useful for re-enabling the
- * flags. */
-void pa_device_set_use_default_volume_control(pa_device *device, bool use);
-void pa_device_set_use_default_mute_control(pa_device *device, bool use);
-
-/* Called by the device implementation. */
-void pa_device_description_changed(pa_device *device, const char *new_description);
-void pa_device_set_default_volume_control(pa_device *device, pa_volume_control *control);
-void pa_device_set_default_mute_control(pa_device *device, pa_mute_control *control);
-
-#endif
diff --git a/src/modules/volume-api/inidb.c b/src/modules/volume-api/inidb.c
deleted file mode 100644 (file)
index 62a2825..0000000
+++ /dev/null
@@ -1,554 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "inidb.h"
-
-#include <pulse/mainloop-api.h>
-#include <pulse/rtclock.h>
-#include <pulse/timeval.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/conf-parser.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/core-rtclock.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/hashmap.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/namereg.h>
-
-#include <errno.h>
-
-#define SAVE_INTERVAL_USEC (10 * PA_USEC_PER_SEC)
-
-struct pa_inidb {
-    pa_core *core;
-    char *name;
-    char *file_path;
-    char *tmp_file_path;
-    pa_hashmap *tables; /* table name -> pa_inidb_table */
-    pa_time_event *time_event;
-    bool failed;
-    void *userdata;
-};
-
-struct pa_inidb_table {
-    pa_inidb *db;
-    char *name;
-    pa_hashmap *columns; /* column name -> column */
-    pa_hashmap *rows; /* row id -> pa_inidb_row */
-    pa_inidb_get_object_cb_t get_object;
-};
-
-struct column {
-    char *name;
-    pa_inidb_parse_cb_t parse;
-};
-
-struct pa_inidb_row {
-    char *id;
-    char *header;
-    pa_hashmap *cells; /* column name -> cell */
-};
-
-struct pa_inidb_cell {
-    pa_inidb *db;
-    struct column *column;
-    char *value;
-    char *assignment;
-};
-
-static void save(pa_inidb *db);
-
-static pa_inidb_table *table_new(pa_inidb *db, const char *name, pa_inidb_get_object_cb_t get_object_cb);
-static void table_free(pa_inidb_table *table);
-static pa_inidb_row *table_add_row_internal(pa_inidb_table *table, const char *row_id);
-
-static struct column *column_new(const char *name, pa_inidb_parse_cb_t parse_cb);
-static void column_free(struct column *column);
-
-static pa_inidb_row *row_new(pa_inidb_table *table, const char *id);
-static void row_free(pa_inidb_row *row);
-
-static pa_inidb_cell *cell_new(pa_inidb *db, struct column *column);
-static void cell_free(pa_inidb_cell *cell);
-static void cell_set_value_internal(pa_inidb_cell *cell, const char *value);
-
-static int parse_assignment(pa_config_parser_state *state) {
-    pa_inidb *db;
-    const char *end_of_table_name;
-    size_t table_name_len;
-    char *table_name;
-    pa_inidb_table *table;
-    const char *row_id;
-    pa_inidb_row *row;
-    int r;
-    void *object;
-    struct column *column;
-    pa_inidb_cell *cell;
-
-    pa_assert(state);
-
-    db = state->userdata;
-
-    /* FIXME: pa_config_parser should be improved so that it could parse the
-     * table name and row id for us in the section header. */
-    end_of_table_name = strchr(state->section, ' ');
-    if (!end_of_table_name) {
-        pa_log("[%s:%u] Failed to parse table name and row id in section \"%s\"", state->filename, state->lineno,
-               state->section);
-        return -PA_ERR_INVALID;
-    }
-
-    table_name_len = end_of_table_name - state->section;
-    table_name = pa_xstrndup(state->section, table_name_len);
-    table = pa_hashmap_get(db->tables, table_name);
-    if (!table)
-        pa_log("[%s:%u] Unknown table name: \"%s\"", state->filename, state->lineno, table_name);
-    pa_xfree(table_name);
-    if (!table)
-        return -PA_ERR_INVALID;
-
-    row_id = end_of_table_name + 1;
-    if (!pa_namereg_is_valid_name(row_id)) {
-        pa_log("[%s:%u] Invalid row id: \"%s\"", state->filename, state->lineno, row_id);
-        return -PA_ERR_INVALID;
-    }
-
-    /* This is not strictly necessary, but we do this to avoid saving the
-     * database when there is no actual change. Without this, the get_object()
-     * callback would cause redundant saving whenever creating new objects. */
-    if (!(row = pa_hashmap_get(table->rows, row_id)))
-        row = table_add_row_internal(table, row_id);
-
-    r = table->get_object(db, row_id, &object);
-    if (r < 0) {
-        pa_log("[%s:%u] Failed to create object %s.", state->filename, state->lineno, row_id);
-        return r;
-    }
-
-    column = pa_hashmap_get(table->columns, state->lvalue);
-    if (!column) {
-        pa_log("[%s:%u] Unknown column name: \"%s\"", state->filename, state->lineno, state->lvalue);
-        return -PA_ERR_INVALID;
-    }
-
-    /* This is not strictly necessary, but we do this to avoid saving the
-     * database when there is no actual change. Without this, the parse()
-     * callback would cause redundant saving whenever setting the cell value
-     * for the first time. */
-    cell = pa_hashmap_get(row->cells, column->name);
-    cell_set_value_internal(cell, state->rvalue);
-
-    r = column->parse(db, state->rvalue, object);
-    if (r < 0) {
-        pa_log("[%s:%u] Failed to parse %s value \"%s\".", state->filename, state->lineno, column->name, state->rvalue);
-        return r;
-    }
-
-    return 0;
-}
-
-pa_inidb *pa_inidb_new(pa_core *core, const char *name, void *userdata) {
-    pa_inidb *db;
-    int r;
-
-    pa_assert(core);
-    pa_assert(name);
-
-    db = pa_xnew0(pa_inidb, 1);
-    db->core = core;
-    db->name = pa_xstrdup(name);
-
-    r = pa_append_to_config_home_dir(name, true, &db->file_path);
-    if (r < 0) {
-        pa_log("Failed to find the file location for database \"%s\". The database will start empty, and updates will not be "
-               "saved on disk.", name);
-        db->failed = true;
-    }
-
-    if (db->file_path)
-        db->tmp_file_path = pa_sprintf_malloc("%s.tmp", db->file_path);
-
-    db->tables = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                     (pa_free_cb_t) table_free);
-    db->userdata = userdata;
-
-    return db;
-}
-
-void pa_inidb_free(pa_inidb *db) {
-    pa_assert(db);
-
-    if (db->time_event) {
-        db->core->mainloop->time_free(db->time_event);
-        save(db);
-    }
-
-    if (db->tables)
-        pa_hashmap_free(db->tables);
-
-    pa_xfree(db->tmp_file_path);
-    pa_xfree(db->file_path);
-    pa_xfree(db->name);
-    pa_xfree(db);
-}
-
-void *pa_inidb_get_userdata(pa_inidb *db) {
-    pa_assert(db);
-
-    return db->userdata;
-}
-
-pa_inidb_table *pa_inidb_add_table(pa_inidb *db, const char *name, pa_inidb_get_object_cb_t get_object_cb) {
-    pa_inidb_table *table;
-
-    pa_assert(db);
-    pa_assert(name);
-    pa_assert(get_object_cb);
-
-    table = table_new(db, name, get_object_cb);
-    pa_assert_se(pa_hashmap_put(db->tables, table->name, table) >= 0);
-
-    return table;
-}
-
-void pa_inidb_load(pa_inidb *db) {
-    unsigned n_config_items;
-    pa_inidb_table *table;
-    void *state;
-    pa_config_item *config_items;
-    unsigned i;
-
-    pa_assert(db);
-
-    if (db->failed)
-        return;
-
-    n_config_items = 0;
-    PA_HASHMAP_FOREACH(table, db->tables, state)
-        n_config_items += pa_hashmap_size(table->columns);
-
-    config_items = pa_xnew0(pa_config_item, n_config_items + 1);
-
-    i = 0;
-    PA_HASHMAP_FOREACH(table, db->tables, state) {
-        struct column *column;
-        void *state2;
-
-        PA_HASHMAP_FOREACH(column, table->columns, state2) {
-            config_items[i].lvalue = column->name;
-            config_items[i].parse = parse_assignment;
-            i++;
-        }
-    }
-
-    pa_config_parse(db->file_path, NULL, config_items, NULL, db);
-    pa_xfree(config_items);
-}
-
-static void save(pa_inidb *db) {
-    FILE *f;
-    pa_inidb_table *table;
-    void *state;
-    int r;
-
-    pa_assert(db);
-
-    if (db->failed)
-        return;
-
-    f = pa_fopen_cloexec(db->tmp_file_path, "w");
-    if (!f) {
-        pa_log("pa_fopen_cloexec() failed: %s", pa_cstrerror(errno));
-        goto fail;
-    }
-
-    PA_HASHMAP_FOREACH(table, db->tables, state) {
-        pa_inidb_row *row;
-        void *state2;
-
-        PA_HASHMAP_FOREACH(row, table->rows, state2) {
-            size_t len;
-            size_t items_written;
-            pa_inidb_cell *cell;
-            void *state3;
-
-            len = strlen(row->header);
-            items_written = fwrite(row->header, len, 1, f);
-
-            if (items_written != 1) {
-                pa_log("fwrite() failed: %s", pa_cstrerror(errno));
-                goto fail;
-            }
-
-            PA_HASHMAP_FOREACH(cell, row->cells, state3) {
-                if (!cell->assignment)
-                    continue;
-
-                len = strlen(cell->assignment);
-                items_written = fwrite(cell->assignment, len, 1, f);
-
-                if (items_written != 1) {
-                    pa_log("fwrite() failed: %s", pa_cstrerror(errno));
-                    goto fail;
-                }
-            }
-
-            items_written = fwrite("\n", 1, 1, f);
-
-            if (items_written != 1) {
-                pa_log("fwrite() failed: %s", pa_cstrerror(errno));
-                goto fail;
-            }
-        }
-    }
-
-    r = fclose(f);
-    f = NULL;
-    if (r < 0) {
-        pa_log("fclose() failed: %s", pa_cstrerror(errno));
-        goto fail;
-    }
-
-    r = rename(db->tmp_file_path, db->file_path);
-    if (r < 0) {
-        pa_log("rename() failed: %s", pa_cstrerror(errno));
-        goto fail;
-    }
-
-    pa_log_debug("Database \"%s\" saved.", db->name);
-
-    return;
-
-fail:
-    if (f)
-        fclose(f);
-
-    db->failed = true;
-    pa_log("Saving database \"%s\" failed, current and future database changes will not be written to the disk.", db->name);
-}
-
-static pa_inidb_table *table_new(pa_inidb *db, const char *name, pa_inidb_get_object_cb_t get_object_cb) {
-    pa_inidb_table *table;
-
-    pa_assert(db);
-    pa_assert(name);
-    pa_assert(get_object_cb);
-
-    table = pa_xnew0(pa_inidb_table, 1);
-    table->db = db;
-    table->name = pa_xstrdup(name);
-    table->columns = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                         (pa_free_cb_t) column_free);
-    table->rows = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                      (pa_free_cb_t) row_free);
-    table->get_object = get_object_cb;
-
-    return table;
-}
-
-static void table_free(pa_inidb_table *table) {
-    pa_assert(table);
-
-    if (table->rows)
-        pa_hashmap_free(table->rows);
-
-    if (table->columns)
-        pa_hashmap_free(table->columns);
-
-    pa_xfree(table->name);
-    pa_xfree(table);
-}
-
-void pa_inidb_table_add_column(pa_inidb_table *table, const char *name, pa_inidb_parse_cb_t parse_cb) {
-    struct column *column;
-
-    pa_assert(table);
-    pa_assert(name);
-    pa_assert(parse_cb);
-
-    column = column_new(name, parse_cb);
-    pa_assert_se(pa_hashmap_put(table->columns, column->name, column) >= 0);
-}
-
-static pa_inidb_row *table_add_row_internal(pa_inidb_table *table, const char *row_id) {
-    pa_inidb_row *row;
-
-    pa_assert(table);
-    pa_assert(row_id);
-
-    row = row_new(table, row_id);
-    pa_assert_se(pa_hashmap_put(table->rows, row->id, row) >= 0);
-
-    return row;
-}
-
-static void time_cb(pa_mainloop_api *api, pa_time_event *event, const struct timeval *tv, void *userdata) {
-    pa_inidb *db = userdata;
-
-    pa_assert(api);
-    pa_assert(db);
-
-    api->time_free(event);
-    db->time_event = NULL;
-
-    save(db);
-}
-
-static void trigger_save(pa_inidb *db) {
-    struct timeval tv;
-
-    pa_assert(db);
-
-    if (db->time_event)
-        return;
-
-    pa_timeval_rtstore(&tv, pa_rtclock_now() + SAVE_INTERVAL_USEC, true);
-    db->time_event = db->core->mainloop->time_new(db->core->mainloop, &tv, time_cb, db);
-}
-
-pa_inidb_row *pa_inidb_table_add_row(pa_inidb_table *table, const char *row_id) {
-    pa_inidb_row *row;
-
-    pa_assert(table);
-    pa_assert(row_id);
-
-    row = pa_hashmap_get(table->rows, row_id);
-    if (row)
-        return row;
-
-    row = table_add_row_internal(table, row_id);
-    trigger_save(table->db);
-
-    return row;
-}
-
-static struct column *column_new(const char *name, pa_inidb_parse_cb_t parse_cb) {
-    struct column *column;
-
-    pa_assert(name);
-    pa_assert(parse_cb);
-
-    column = pa_xnew(struct column, 1);
-    column->name = pa_xstrdup(name);
-    column->parse = parse_cb;
-
-    return column;
-}
-
-static void column_free(struct column *column) {
-    pa_assert(column);
-
-    pa_xfree(column->name);
-    pa_xfree(column);
-}
-
-static pa_inidb_row *row_new(pa_inidb_table *table, const char *id) {
-    pa_inidb_row *row;
-    struct column *column;
-    void *state;
-
-    pa_assert(table);
-    pa_assert(id);
-
-    row = pa_xnew0(pa_inidb_row, 1);
-    row->id = pa_xstrdup(id);
-    row->header = pa_sprintf_malloc("[%s %s]\n", table->name, id);
-    row->cells = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
-                                     (pa_free_cb_t) cell_free);
-
-    PA_HASHMAP_FOREACH(column, table->columns, state) {
-        pa_inidb_cell *cell;
-
-        cell = cell_new(table->db, column);
-        pa_hashmap_put(row->cells, cell->column->name, cell);
-    }
-
-    return row;
-}
-
-static void row_free(pa_inidb_row *row) {
-    pa_assert(row);
-
-    pa_xfree(row->header);
-    pa_xfree(row->id);
-    pa_xfree(row);
-}
-
-pa_inidb_cell *pa_inidb_row_get_cell(pa_inidb_row *row, const char *column_name) {
-    pa_inidb_cell *cell;
-
-    pa_assert(row);
-    pa_assert(column_name);
-
-    pa_assert_se(cell = pa_hashmap_get(row->cells, column_name));
-
-    return cell;
-}
-
-static pa_inidb_cell *cell_new(pa_inidb *db, struct column *column) {
-    pa_inidb_cell *cell;
-
-    pa_assert(db);
-    pa_assert(column);
-
-    cell = pa_xnew0(pa_inidb_cell, 1);
-    cell->db = db;
-    cell->column = column;
-
-    return cell;
-}
-
-static void cell_free(pa_inidb_cell *cell) {
-    pa_assert(cell);
-
-    pa_xfree(cell->assignment);
-    pa_xfree(cell->value);
-    pa_xfree(cell);
-}
-
-static void cell_set_value_internal(pa_inidb_cell *cell, const char *value) {
-    pa_assert(cell);
-    pa_assert(value);
-
-    pa_xfree(cell->value);
-    cell->value = pa_xstrdup(value);
-
-    pa_xfree(cell->assignment);
-    if (value)
-        cell->assignment = pa_sprintf_malloc("%s = %s\n", cell->column->name, value);
-    else
-        cell->assignment = NULL;
-}
-
-void pa_inidb_cell_set_value(pa_inidb_cell *cell, const char *value) {
-    pa_assert(cell);
-
-    if (pa_safe_streq(value, cell->value))
-        return;
-
-    cell_set_value_internal(cell, value);
-    trigger_save(cell->db);
-}
diff --git a/src/modules/volume-api/inidb.h b/src/modules/volume-api/inidb.h
deleted file mode 100644 (file)
index ded73ba..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef fooinidbhfoo
-#define fooinidbhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulsecore/core.h>
-
-typedef struct pa_inidb pa_inidb;
-typedef struct pa_inidb_cell pa_inidb_cell;
-typedef struct pa_inidb_row pa_inidb_row;
-typedef struct pa_inidb_table pa_inidb_table;
-
-/* If there's no object with the given name, the implementation is expected to
- * create a new object (or at least try to). */
-typedef int (*pa_inidb_get_object_cb_t)(pa_inidb *db, const char *name, void **_r);
-
-/* The implementation is expected to parse the value, and set the parsed value
- * on the object. */
-typedef int (*pa_inidb_parse_cb_t)(pa_inidb *db, const char *value, void *object);
-
-pa_inidb *pa_inidb_new(pa_core *core, const char *name, void *userdata);
-void pa_inidb_free(pa_inidb *db);
-
-void *pa_inidb_get_userdata(pa_inidb *db);
-pa_inidb_table *pa_inidb_add_table(pa_inidb *db, const char *name, pa_inidb_get_object_cb_t get_object_cb);
-void pa_inidb_load(pa_inidb *db);
-
-void pa_inidb_table_add_column(pa_inidb_table *table, const char *name, pa_inidb_parse_cb_t parse_cb);
-pa_inidb_row *pa_inidb_table_add_row(pa_inidb_table *table, const char *row_id);
-
-pa_inidb_cell *pa_inidb_row_get_cell(pa_inidb_row *row, const char *column_name);
-
-void pa_inidb_cell_set_value(pa_inidb_cell *cell, const char *value);
-
-#endif
diff --git a/src/modules/volume-api/module-volume-api.c b/src/modules/volume-api/module-volume-api.c
deleted file mode 100644 (file)
index e7ecdcb..0000000
+++ /dev/null
@@ -1,1456 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "module-volume-api-symdef.h"
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/bvolume.h>
-#include <modules/volume-api/device.h>
-#include <modules/volume-api/sstream.h>
-#include <modules/volume-api/volume-api.h>
-#include <modules/volume-api/volume-api-common.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/i18n.h>
-#include <pulsecore/protocol-native.h>
-#include <pulsecore/pstream-util.h>
-
-PA_MODULE_AUTHOR("Tanu Kaskinen");
-PA_MODULE_DESCRIPTION(_("Volume API"));
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(true);
-
-struct userdata {
-    pa_native_protocol *native_protocol;
-    bool extension_installed;
-    pa_volume_api *volume_api;
-    pa_hook_slot *volume_control_put_slot;
-    pa_hook_slot *volume_control_unlink_slot;
-    pa_hook_slot *volume_control_description_changed_slot;
-    pa_hook_slot *volume_control_volume_changed_slot;
-    pa_hook_slot *volume_control_convertible_to_db_changed_slot;
-    pa_hook_slot *mute_control_put_slot;
-    pa_hook_slot *mute_control_unlink_slot;
-    pa_hook_slot *mute_control_description_changed_slot;
-    pa_hook_slot *mute_control_mute_changed_slot;
-    pa_hook_slot *device_put_slot;
-    pa_hook_slot *device_unlink_slot;
-    pa_hook_slot *device_description_changed_slot;
-    pa_hook_slot *device_volume_control_changed_slot;
-    pa_hook_slot *device_mute_control_changed_slot;
-    pa_hook_slot *stream_put_slot;
-    pa_hook_slot *stream_unlink_slot;
-    pa_hook_slot *stream_description_changed_slot;
-    pa_hook_slot *stream_proplist_changed_slot;
-    pa_hook_slot *stream_volume_control_changed_slot;
-    pa_hook_slot *stream_relative_volume_control_changed_slot;
-    pa_hook_slot *stream_mute_control_changed_slot;
-    pa_hook_slot *audio_group_put_slot;
-    pa_hook_slot *audio_group_unlink_slot;
-    pa_hook_slot *audio_group_description_changed_slot;
-    pa_hook_slot *audio_group_volume_control_changed_slot;
-    pa_hook_slot *audio_group_mute_control_changed_slot;
-    pa_hook_slot *main_output_volume_control_changed_slot;
-    pa_hook_slot *main_input_volume_control_changed_slot;
-    pa_hook_slot *main_output_mute_control_changed_slot;
-    pa_hook_slot *main_input_mute_control_changed_slot;
-    pa_hashmap *connections; /* pa_native_connection -> volume_api_connection */
-    pa_hook_slot *native_connection_unlink_slot;
-};
-
-struct volume_api_connection {
-    pa_native_connection *native_connection;
-    bool dead;
-    pa_ext_volume_api_subscription_mask_t subscription_mask;
-};
-
-static struct volume_api_connection *volume_api_connection_new(pa_native_connection *native_connection) {
-    struct volume_api_connection *api_connection;
-
-    pa_assert(native_connection);
-
-    api_connection = pa_xnew0(struct volume_api_connection, 1);
-    api_connection->native_connection = native_connection;
-
-    return api_connection;
-}
-
-static void volume_api_connection_free(struct volume_api_connection *connection) {
-    pa_assert(connection);
-
-    pa_xfree(connection);
-}
-
-static void add_connection(struct userdata *u, struct volume_api_connection *connection) {
-    pa_assert(u);
-    pa_assert(connection);
-
-    pa_assert_se(pa_hashmap_put(u->connections, connection->native_connection, connection) >= 0);
-}
-
-static void remove_connection(struct userdata *u, struct volume_api_connection *connection) {
-    pa_assert(u);
-    pa_assert(connection);
-
-    if (!connection->dead) {
-        pa_tagstruct *tagstruct;
-
-        tagstruct = pa_tagstruct_new(NULL, 0);
-        pa_tagstruct_putu32(tagstruct, PA_COMMAND_EXTENSION);
-        pa_tagstruct_putu32(tagstruct, (uint32_t) -1);
-        pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-        pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-        pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_DISCONNECT);
-        pa_pstream_send_tagstruct(pa_native_connection_get_pstream(connection->native_connection), tagstruct);
-    }
-
-    pa_assert_se(pa_hashmap_remove_and_free(u->connections, connection->native_connection) >= 0);
-}
-
-static pa_tagstruct *reply_new(uint32_t tag) {
-    pa_tagstruct *reply;
-
-    reply = pa_tagstruct_new(NULL, 0);
-    pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
-    pa_tagstruct_putu32(reply, tag);
-
-    return reply;
-}
-
-static int command_connect(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                           pa_tagstruct *tagstruct) {
-    uint32_t version;
-    pa_tagstruct *reply;
-    struct volume_api_connection *api_connection;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (pa_tagstruct_getu32(tagstruct, &version) < 0
-            || version < 1
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a CONNECT command.");
-        return -1;
-    }
-
-    if (pa_hashmap_get(u->connections, native_connection)) {
-        pa_log_info("Tried to connect an already connected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-    pa_tagstruct_putu32(reply, PA_VOLUME_API_VERSION);
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    api_connection = volume_api_connection_new(native_connection);
-    add_connection(u, api_connection);
-
-    return 0;
-}
-
-static int command_disconnect(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                              pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a DISCONNECT command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("Tried to disconnect an unconnected client.");
-        return -1;
-    }
-
-    remove_connection(u, api_connection);
-
-    return 0;
-}
-
-static int command_subscribe(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                             pa_tagstruct *tagstruct) {
-    uint32_t mask;
-    struct volume_api_connection *api_connection;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (pa_tagstruct_getu32(tagstruct, &mask) < 0
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a SUBSCRIBE command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("SUBSCRIBE command received from an unconnected client.");
-        return -1;
-    }
-
-    api_connection->subscription_mask = mask;
-
-    return 0;
-}
-
-static void fill_volume_control_info(pa_tagstruct *tagstruct, pa_volume_control *control) {
-    unsigned i;
-
-    pa_assert(tagstruct);
-    pa_assert(control);
-
-    pa_tagstruct_putu32(tagstruct, control->index);
-    pa_tagstruct_puts(tagstruct, control->name);
-    pa_tagstruct_puts(tagstruct, control->description);
-    pa_tagstruct_put_proplist(tagstruct, control->proplist);
-    pa_tagstruct_put_volume(tagstruct, control->volume.volume);
-    pa_tagstruct_put_channel_map(tagstruct, &control->volume.channel_map);
-
-    for (i = 0; i < control->volume.channel_map.channels; i++) {
-        uint64_t u;
-
-        memcpy(&u, &control->volume.balance[i], sizeof(uint64_t));
-        pa_tagstruct_putu64(tagstruct, u);
-    }
-
-    pa_tagstruct_put_boolean(tagstruct, control->convertible_to_dB);
-}
-
-static int command_get_server_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                   pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_SERVER_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_SERVER_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-    pa_tagstruct_putu32(reply, u->volume_api->main_output_volume_control
-                               ? u->volume_api->main_output_volume_control->index
-                               : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(reply, u->volume_api->main_input_volume_control
-                               ? u->volume_api->main_input_volume_control->index
-                               : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(reply, u->volume_api->main_output_mute_control
-                               ? u->volume_api->main_output_mute_control->index
-                               : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(reply, u->volume_api->main_input_mute_control
-                               ? u->volume_api->main_input_mute_control->index
-                               : PA_INVALID_INDEX);
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static int command_get_volume_control_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                           pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    struct volume_api_connection *api_connection;
-    pa_volume_control *control = NULL;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name)
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_VOLUME_CONTROL_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_VOLUME_CONTROL_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        control = pa_hashmap_get(u->volume_api->volume_controls, name);
-
-        if (!control)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        control = pa_volume_api_get_volume_control_by_index(u->volume_api, idx);
-
-    if (!control) {
-        pa_log_info("Tried to get volume control info for a non-existing volume control.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    reply = reply_new(tag);
-    fill_volume_control_info(reply, control);
-    pa_pstream_send_tagstruct(pstream, reply);
-
-    return 0;
-}
-
-static int command_get_volume_control_info_list(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                                pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-    pa_volume_control *control;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_VOLUME_CONTROL_INFO_LIST command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_VOLUME_CONTROL_INFO_LIST command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-
-    PA_HASHMAP_FOREACH(control, u->volume_api->volume_controls, state)
-        fill_volume_control_info(reply, control);
-
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static int command_set_volume_control_volume(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                             pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    pa_bvolume bvolume;
-    bool set_volume;
-    bool set_balance;
-    struct volume_api_connection *api_connection;
-    pa_volume_control *control = NULL;
-    int r;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name) < 0
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || pa_tagstruct_get_volume(tagstruct, &bvolume.volume) < 0
-            || pa_tagstruct_get_channel_map(tagstruct, &bvolume.channel_map) < 0)
-        goto fail_parse;
-
-    set_volume = PA_VOLUME_IS_VALID(bvolume.volume);
-    set_balance = pa_channel_map_valid(&bvolume.channel_map);
-
-    if (set_balance) {
-        unsigned i;
-
-        for (i = 0; i < bvolume.channel_map.channels; i++) {
-            uint64_t balance;
-
-            if (pa_tagstruct_getu64(tagstruct, &balance) < 0)
-                goto fail_parse;
-
-            memcpy(&bvolume.balance[i], &balance, sizeof(double));
-
-            if (!pa_balance_valid(bvolume.balance[i]))
-                goto fail_parse;
-        }
-    }
-
-    if (!pa_tagstruct_eof(tagstruct))
-        goto fail_parse;
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("SET_VOLUME_CONTROL_VOLUME received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        control = pa_hashmap_get(u->volume_api->volume_controls, name);
-
-        if (!control)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        control = pa_volume_api_get_volume_control_by_index(u->volume_api, idx);
-
-    if (!control) {
-        pa_log_info("Tried to set volume of a non-existing volume control.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    r = pa_volume_control_set_volume(control, &bvolume, set_volume, set_balance);
-    if (r < 0) {
-        pa_pstream_send_error(pstream, tag, -r);
-        return 0;
-    }
-
-    pa_pstream_send_simple_ack(pstream, tag);
-
-    return 0;
-
-fail_parse:
-    pa_log_info("Failed to parse the parameters of a SET_VOLUME_CONTROL_VOLUME command.");
-
-    return -1;
-}
-
-static void fill_mute_control_info(pa_tagstruct *tagstruct, pa_mute_control *control) {
-    pa_assert(tagstruct);
-    pa_assert(control);
-
-    pa_tagstruct_putu32(tagstruct, control->index);
-    pa_tagstruct_puts(tagstruct, control->name);
-    pa_tagstruct_puts(tagstruct, control->description);
-    pa_tagstruct_put_proplist(tagstruct, control->proplist);
-    pa_tagstruct_put_boolean(tagstruct, control->mute);
-}
-
-static int command_get_mute_control_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                         pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    struct volume_api_connection *api_connection;
-    pa_mute_control *control = NULL;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name)
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_MUTE_CONTROL_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_MUTE_CONTROL_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        control = pa_hashmap_get(u->volume_api->mute_controls, name);
-
-        if (!control)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        control = pa_volume_api_get_mute_control_by_index(u->volume_api, idx);
-
-    if (!control) {
-        pa_log_info("Tried to get mute control info for a non-existing mute control.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    reply = reply_new(tag);
-    fill_mute_control_info(reply, control);
-    pa_pstream_send_tagstruct(pstream, reply);
-
-    return 0;
-}
-
-static int command_get_mute_control_info_list(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                              pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-    pa_mute_control *control;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_MUTE_CONTROL_INFO_LIST command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_MUTE_CONTROL_INFO_LIST command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-
-    PA_HASHMAP_FOREACH(control, u->volume_api->mute_controls, state)
-        fill_mute_control_info(reply, control);
-
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static int command_set_mute_control_mute(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                         pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    bool mute;
-    struct volume_api_connection *api_connection;
-    pa_mute_control *control = NULL;
-    int r;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name) < 0
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || pa_tagstruct_get_boolean(tagstruct, &mute) < 0
-            || !pa_tagstruct_eof(tagstruct))
-        goto fail_parse;
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("SET_MUTE_CONTROL_MUTE received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        control = pa_hashmap_get(u->volume_api->mute_controls, name);
-
-        if (!control)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        control = pa_volume_api_get_mute_control_by_index(u->volume_api, idx);
-
-    if (!control) {
-        pa_log_info("Tried to set mute of a non-existing mute control.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    r = pa_mute_control_set_mute(control, mute);
-    if (r < 0) {
-        pa_pstream_send_error(pstream, tag, -r);
-        return 0;
-    }
-
-    pa_pstream_send_simple_ack(pstream, tag);
-
-    return 0;
-
-fail_parse:
-    pa_log_info("Failed to parse the parameters of a SET_MUTE_CONTROL_MUTE command.");
-
-    return -1;
-}
-
-static void fill_device_info(pa_tagstruct *tagstruct, pa_device *device) {
-    unsigned i;
-
-    pa_assert(tagstruct);
-    pa_assert(device);
-
-    pa_tagstruct_putu32(tagstruct, device->index);
-    pa_tagstruct_puts(tagstruct, device->name);
-    pa_tagstruct_puts(tagstruct, device->description);
-    pa_tagstruct_putu8(tagstruct, device->direction);
-    pa_tagstruct_putu32(tagstruct, pa_dynarray_size(device->device_types));
-
-    for (i = 0; i < pa_dynarray_size(device->device_types); i++)
-        pa_tagstruct_puts(tagstruct, pa_dynarray_get(device->device_types, i));
-
-    pa_tagstruct_put_proplist(tagstruct, device->proplist);
-    pa_tagstruct_putu32(tagstruct, device->volume_control ? device->volume_control->index : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(tagstruct, device->mute_control ? device->mute_control->index : PA_INVALID_INDEX);
-}
-
-static int command_get_device_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                   pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    struct volume_api_connection *api_connection;
-    pa_device *device = NULL;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name)
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_DEVICE_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_DEVICE_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        device = pa_hashmap_get(u->volume_api->devices, name);
-
-        if (!device)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        device = pa_volume_api_get_device_by_index(u->volume_api, idx);
-
-    if (!device) {
-        pa_log_info("Tried to get device info for a non-existing device.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    reply = reply_new(tag);
-    fill_device_info(reply, device);
-    pa_pstream_send_tagstruct(pstream, reply);
-
-    return 0;
-}
-
-static int command_get_device_info_list(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                        pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-    pa_device *device;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_DEVICE_INFO_LIST command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_DEVICE_INFO_LIST command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-
-    PA_HASHMAP_FOREACH(device, u->volume_api->devices, state)
-        fill_device_info(reply, device);
-
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static void fill_stream_info(pa_tagstruct *tagstruct, pas_stream *stream) {
-    pa_assert(tagstruct);
-    pa_assert(stream);
-
-    pa_tagstruct_putu32(tagstruct, stream->index);
-    pa_tagstruct_puts(tagstruct, stream->name);
-    pa_tagstruct_puts(tagstruct, stream->description);
-    pa_tagstruct_putu8(tagstruct, stream->direction);
-    pa_tagstruct_put_proplist(tagstruct, stream->proplist);
-    pa_tagstruct_putu32(tagstruct, stream->volume_control ? stream->volume_control->index : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(tagstruct, stream->mute_control ? stream->mute_control->index : PA_INVALID_INDEX);
-}
-
-static int command_get_stream_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                   pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    struct volume_api_connection *api_connection;
-    pas_stream *stream = NULL;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name)
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_STREAM_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_STREAM_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        stream = pa_hashmap_get(u->volume_api->streams, name);
-
-        if (!stream)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        stream = pa_volume_api_get_stream_by_index(u->volume_api, idx);
-
-    if (!stream) {
-        pa_log_info("Tried to get stream info for a non-existing stream.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    reply = reply_new(tag);
-    fill_stream_info(reply, stream);
-    pa_pstream_send_tagstruct(pstream, reply);
-
-    return 0;
-}
-
-static int command_get_stream_info_list(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                        pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-    pas_stream *stream;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_STREAM_INFO_LIST command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_STREAM_INFO_LIST command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-
-    PA_HASHMAP_FOREACH(stream, u->volume_api->streams, state)
-        fill_stream_info(reply, stream);
-
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static void fill_audio_group_info(pa_tagstruct *tagstruct, pa_audio_group *group) {
-    pa_assert(tagstruct);
-    pa_assert(group);
-
-    pa_tagstruct_putu32(tagstruct, group->index);
-    pa_tagstruct_puts(tagstruct, group->name);
-    pa_tagstruct_puts(tagstruct, group->description);
-    pa_tagstruct_put_proplist(tagstruct, group->proplist);
-    pa_tagstruct_putu32(tagstruct, group->volume_control ? group->volume_control->index : PA_INVALID_INDEX);
-    pa_tagstruct_putu32(tagstruct, group->mute_control ? group->mute_control->index : PA_INVALID_INDEX);
-}
-
-static int command_get_audio_group_info(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                        pa_tagstruct *tagstruct) {
-    pa_pstream *pstream;
-    uint32_t idx;
-    const char *name;
-    struct volume_api_connection *api_connection;
-    pa_audio_group *group = NULL;
-    pa_tagstruct *reply;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    pstream = pa_native_connection_get_pstream(native_connection);
-
-    if (pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || pa_tagstruct_gets(tagstruct, &name)
-            || (idx == PA_INVALID_INDEX && !name)
-            || (idx != PA_INVALID_INDEX && name)
-            || (name && !*name)
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_AUDIO_GROUP_INFO command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_AUDIO_GROUP_INFO command received from an unconnected client.");
-        return -1;
-    }
-
-    if (name) {
-        group = pa_hashmap_get(u->volume_api->audio_groups, name);
-
-        if (!group)
-            pa_atou(name, &idx);
-    }
-
-    if (idx != PA_INVALID_INDEX)
-        group = pa_volume_api_get_audio_group_by_index(u->volume_api, idx);
-
-    if (!group) {
-        pa_log_info("Tried to get audio group info for a non-existing audio group.");
-        pa_pstream_send_error(pstream, tag, PA_ERR_NOENTITY);
-        return 0;
-    }
-
-    reply = reply_new(tag);
-    fill_audio_group_info(reply, group);
-    pa_pstream_send_tagstruct(pstream, reply);
-
-    return 0;
-}
-
-static int command_get_audio_group_info_list(struct userdata *u, pa_native_connection *native_connection, uint32_t tag,
-                                             pa_tagstruct *tagstruct) {
-    struct volume_api_connection *api_connection;
-    pa_tagstruct *reply;
-    pa_audio_group *group;
-    void *state;
-
-    pa_assert(u);
-    pa_assert(native_connection);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log_info("Failed to parse the parameters of a GET_AUDIO_GROUP_INFO_LIST command.");
-        return -1;
-    }
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection) {
-        pa_log_info("GET_AUDIO_GROUP_INFO_LIST command received from an unconnected client.");
-        return -1;
-    }
-
-    reply = reply_new(tag);
-
-    PA_HASHMAP_FOREACH(group, u->volume_api->audio_groups, state)
-        fill_audio_group_info(reply, group);
-
-    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(native_connection), reply);
-
-    return 0;
-}
-
-static int extension_cb(pa_native_protocol *protocol, pa_module *module, pa_native_connection *connection, uint32_t tag,
-                        pa_tagstruct *tagstruct) {
-    struct userdata *u;
-    uint32_t command;
-
-    pa_assert(protocol);
-    pa_assert(module);
-    pa_assert(connection);
-    pa_assert(tagstruct);
-
-    u = module->userdata;
-
-    if (pa_tagstruct_getu32(tagstruct, &command) < 0)
-        return -1;
-
-    switch (command) {
-        case PA_VOLUME_API_COMMAND_CONNECT:
-            return command_connect(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_DISCONNECT:
-            return command_disconnect(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_SUBSCRIBE:
-            return command_subscribe(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_SERVER_INFO:
-            return command_get_server_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO:
-            return command_get_volume_control_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO_LIST:
-            return command_get_volume_control_info_list(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_SET_VOLUME_CONTROL_VOLUME:
-            return command_set_volume_control_volume(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO:
-            return command_get_mute_control_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO_LIST:
-            return command_get_mute_control_info_list(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_SET_MUTE_CONTROL_MUTE:
-            return command_set_mute_control_mute(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_DEVICE_INFO:
-            return command_get_device_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_DEVICE_INFO_LIST:
-            return command_get_device_info_list(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_STREAM_INFO:
-            return command_get_stream_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_STREAM_INFO_LIST:
-            return command_get_stream_info_list(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO:
-            return command_get_audio_group_info(u, connection, tag, tagstruct);
-
-        case PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO_LIST:
-            return command_get_audio_group_info_list(u, connection, tag, tagstruct);
-
-        default:
-            pa_log_info("Received unrecognized command: %u", command);
-            return -1;
-    }
-}
-
-static void send_subscribe_event(struct userdata *u, pa_ext_volume_api_subscription_event_type_t event_type,
-                                 uint32_t idx) {
-    pa_ext_volume_api_subscription_event_type_t facility;
-    struct volume_api_connection *connection;
-    void *state;
-
-    pa_assert(u);
-
-    facility = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
-
-    PA_HASHMAP_FOREACH(connection, u->connections, state) {
-        pa_tagstruct *tagstruct;
-
-        if (!(connection->subscription_mask & (1 << facility)))
-            continue;
-
-        tagstruct = pa_tagstruct_new(NULL, 0);
-        pa_tagstruct_putu32(tagstruct, PA_COMMAND_EXTENSION);
-        pa_tagstruct_putu32(tagstruct, (uint32_t) -1);
-        pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-        pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-        pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SUBSCRIBE_EVENT);
-        pa_tagstruct_putu32(tagstruct, event_type);
-        pa_tagstruct_putu32(tagstruct, idx);
-        pa_pstream_send_tagstruct(pa_native_connection_get_pstream(connection->native_connection), tagstruct);
-    }
-}
-
-static pa_hook_result_t volume_control_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_VOLUME_CONTROL | PA_SUBSCRIPTION_EVENT_NEW,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t volume_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_VOLUME_CONTROL | PA_SUBSCRIPTION_EVENT_REMOVE,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t volume_control_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_volume_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_VOLUME_CONTROL | PA_SUBSCRIPTION_EVENT_CHANGE,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_MUTE_CONTROL | PA_SUBSCRIPTION_EVENT_NEW,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_MUTE_CONTROL | PA_SUBSCRIPTION_EVENT_REMOVE,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t mute_control_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_mute_control *control = call_data;
-
-    pa_assert(u);
-    pa_assert(control);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_MUTE_CONTROL | PA_SUBSCRIPTION_EVENT_CHANGE,
-                         control->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t device_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_device *device = call_data;
-
-    pa_assert(u);
-    pa_assert(device);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_DEVICE | PA_SUBSCRIPTION_EVENT_NEW, device->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t device_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_device *device = call_data;
-
-    pa_assert(u);
-    pa_assert(device);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_DEVICE | PA_SUBSCRIPTION_EVENT_REMOVE, device->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t device_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_device *device = call_data;
-
-    pa_assert(u);
-    pa_assert(device);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_DEVICE | PA_SUBSCRIPTION_EVENT_CHANGE, device->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t stream_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pas_stream *stream = call_data;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_STREAM | PA_SUBSCRIPTION_EVENT_NEW, stream->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t stream_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pas_stream *stream = call_data;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_STREAM | PA_SUBSCRIPTION_EVENT_REMOVE, stream->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t stream_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pas_stream *stream = call_data;
-
-    pa_assert(u);
-    pa_assert(stream);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_STREAM | PA_SUBSCRIPTION_EVENT_CHANGE, stream->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_put_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_AUDIO_GROUP | PA_SUBSCRIPTION_EVENT_NEW, group->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_AUDIO_GROUP | PA_SUBSCRIPTION_EVENT_REMOVE,
-                         group->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t audio_group_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-    pa_audio_group *group = call_data;
-
-    pa_assert(u);
-    pa_assert(group);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_AUDIO_GROUP | PA_SUBSCRIPTION_EVENT_CHANGE,
-                         group->index);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t server_event_cb(void *hook_data, void *call_data, void *userdata) {
-    struct userdata *u = userdata;
-
-    pa_assert(u);
-
-    send_subscribe_event(u, PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE,
-                         PA_INVALID_INDEX);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t native_connection_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_native_connection *native_connection = call_data;
-    struct userdata *u = userdata;
-    struct volume_api_connection *api_connection;
-
-    pa_assert(native_connection);
-    pa_assert(u);
-
-    api_connection = pa_hashmap_get(u->connections, native_connection);
-    if (!api_connection)
-        return PA_HOOK_OK;
-
-    api_connection->dead = true;
-    remove_connection(u, api_connection);
-
-    return PA_HOOK_OK;
-}
-
-int pa__init(pa_module *module) {
-    struct userdata *u;
-
-    pa_assert(module);
-
-    u = module->userdata = pa_xnew0(struct userdata, 1);
-    u->native_protocol = pa_native_protocol_get(module->core);
-    pa_native_protocol_install_ext(u->native_protocol, module, extension_cb);
-    u->extension_installed = true;
-    u->volume_api = pa_volume_api_get(module->core);
-    u->volume_control_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT],
-                                                 PA_HOOK_NORMAL, volume_control_put_cb, u);
-    u->volume_control_unlink_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK], PA_HOOK_NORMAL,
-                            volume_control_unlink_cb, u);
-    u->volume_control_description_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_DESCRIPTION_CHANGED],
-                            PA_HOOK_NORMAL, volume_control_event_cb, u);
-    u->volume_control_volume_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED],
-                            PA_HOOK_NORMAL, volume_control_event_cb, u);
-    u->volume_control_convertible_to_db_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_CONVERTIBLE_TO_DB_CHANGED], PA_HOOK_NORMAL,
-                            volume_control_event_cb, u);
-    u->mute_control_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT],
-                                               PA_HOOK_NORMAL, mute_control_put_cb, u);
-    u->mute_control_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK],
-                                                  PA_HOOK_NORMAL, mute_control_unlink_cb, u);
-    u->mute_control_description_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_DESCRIPTION_CHANGED],
-                            PA_HOOK_NORMAL, mute_control_event_cb, u);
-    u->mute_control_mute_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED], PA_HOOK_NORMAL,
-                            mute_control_event_cb, u);
-    u->device_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_PUT], PA_HOOK_NORMAL,
-                                         device_put_cb, u);
-    u->device_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_UNLINK],
-                                            PA_HOOK_NORMAL, device_unlink_cb, u);
-    u->device_description_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_DESCRIPTION_CHANGED], PA_HOOK_NORMAL,
-                            device_event_cb, u);
-    u->device_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, device_event_cb, u);
-    u->device_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_DEVICE_MUTE_CONTROL_CHANGED], PA_HOOK_NORMAL,
-                            device_event_cb, u);
-    u->stream_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PUT], PA_HOOK_NORMAL,
-                                         stream_put_cb, u);
-    u->stream_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_UNLINK],
-                                            PA_HOOK_NORMAL, stream_unlink_cb, u);
-    u->stream_description_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_DESCRIPTION_CHANGED], PA_HOOK_NORMAL,
-                            stream_event_cb, u);
-    u->stream_proplist_changed_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PROPLIST_CHANGED],
-                                                      PA_HOOK_NORMAL, stream_event_cb, u);
-    u->stream_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, stream_event_cb, u);
-    u->stream_relative_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_RELATIVE_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, stream_event_cb, u);
-    u->stream_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_MUTE_CONTROL_CHANGED], PA_HOOK_NORMAL,
-                            stream_event_cb, u);
-    u->audio_group_put_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT],
-                                              PA_HOOK_NORMAL, audio_group_put_cb, u);
-    u->audio_group_unlink_slot = pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK],
-                                                 PA_HOOK_NORMAL, audio_group_unlink_cb, u);
-    u->audio_group_description_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_DESCRIPTION_CHANGED], PA_HOOK_NORMAL,
-                            audio_group_event_cb, u);
-    u->audio_group_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, audio_group_event_cb, u);
-    u->audio_group_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, audio_group_event_cb, u);
-    u->main_output_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, server_event_cb, u);
-    u->main_input_volume_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_VOLUME_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, server_event_cb, u);
-    u->main_output_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_MUTE_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, server_event_cb, u);
-    u->main_input_mute_control_changed_slot =
-            pa_hook_connect(&u->volume_api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_MUTE_CONTROL_CHANGED],
-                            PA_HOOK_NORMAL, server_event_cb, u);
-    u->connections = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) volume_api_connection_free);
-    u->native_connection_unlink_slot =
-            pa_hook_connect(&pa_native_protocol_hooks(u->native_protocol)[PA_NATIVE_HOOK_CONNECTION_UNLINK], PA_HOOK_NORMAL,
-                            native_connection_unlink_cb, u);
-
-    return 0;
-}
-
-void pa__done(pa_module *module) {
-    struct userdata *u;
-
-    pa_assert(module);
-
-    u = module->userdata;
-    if (!u)
-        return;
-
-    if (u->native_connection_unlink_slot)
-        pa_hook_slot_free(u->native_connection_unlink_slot);
-
-    if (u->connections) {
-        struct volume_api_connection *connection;
-
-        while ((connection = pa_hashmap_first(u->connections)))
-            remove_connection(u, connection);
-
-        pa_hashmap_free(u->connections);
-    }
-
-    if (u->main_input_mute_control_changed_slot)
-        pa_hook_slot_free(u->main_input_mute_control_changed_slot);
-
-    if (u->main_output_mute_control_changed_slot)
-        pa_hook_slot_free(u->main_output_mute_control_changed_slot);
-
-    if (u->main_input_volume_control_changed_slot)
-        pa_hook_slot_free(u->main_input_volume_control_changed_slot);
-
-    if (u->main_output_volume_control_changed_slot)
-        pa_hook_slot_free(u->main_output_volume_control_changed_slot);
-
-    if (u->audio_group_mute_control_changed_slot)
-        pa_hook_slot_free(u->audio_group_mute_control_changed_slot);
-
-    if (u->audio_group_volume_control_changed_slot)
-        pa_hook_slot_free(u->audio_group_volume_control_changed_slot);
-
-    if (u->audio_group_description_changed_slot)
-        pa_hook_slot_free(u->audio_group_description_changed_slot);
-
-    if (u->audio_group_unlink_slot)
-        pa_hook_slot_free(u->audio_group_unlink_slot);
-
-    if (u->audio_group_put_slot)
-        pa_hook_slot_free(u->audio_group_put_slot);
-
-    if (u->stream_mute_control_changed_slot)
-        pa_hook_slot_free(u->stream_mute_control_changed_slot);
-
-    if (u->stream_relative_volume_control_changed_slot)
-        pa_hook_slot_free(u->stream_relative_volume_control_changed_slot);
-
-    if (u->stream_volume_control_changed_slot)
-        pa_hook_slot_free(u->stream_volume_control_changed_slot);
-
-    if (u->stream_proplist_changed_slot)
-        pa_hook_slot_free(u->stream_proplist_changed_slot);
-
-    if (u->stream_description_changed_slot)
-        pa_hook_slot_free(u->stream_description_changed_slot);
-
-    if (u->stream_unlink_slot)
-        pa_hook_slot_free(u->stream_unlink_slot);
-
-    if (u->stream_put_slot)
-        pa_hook_slot_free(u->stream_put_slot);
-
-    if (u->device_mute_control_changed_slot)
-        pa_hook_slot_free(u->device_mute_control_changed_slot);
-
-    if (u->device_volume_control_changed_slot)
-        pa_hook_slot_free(u->device_volume_control_changed_slot);
-
-    if (u->device_description_changed_slot)
-        pa_hook_slot_free(u->device_description_changed_slot);
-
-    if (u->device_unlink_slot)
-        pa_hook_slot_free(u->device_unlink_slot);
-
-    if (u->device_put_slot)
-        pa_hook_slot_free(u->device_put_slot);
-
-    if (u->mute_control_mute_changed_slot)
-        pa_hook_slot_free(u->mute_control_mute_changed_slot);
-
-    if (u->mute_control_description_changed_slot)
-        pa_hook_slot_free(u->mute_control_description_changed_slot);
-
-    if (u->mute_control_unlink_slot)
-        pa_hook_slot_free(u->mute_control_unlink_slot);
-
-    if (u->mute_control_put_slot)
-        pa_hook_slot_free(u->mute_control_put_slot);
-
-    if (u->volume_control_convertible_to_db_changed_slot)
-        pa_hook_slot_free(u->volume_control_convertible_to_db_changed_slot);
-
-    if (u->volume_control_volume_changed_slot)
-        pa_hook_slot_free(u->volume_control_volume_changed_slot);
-
-    if (u->volume_control_description_changed_slot)
-        pa_hook_slot_free(u->volume_control_description_changed_slot);
-
-    if (u->volume_control_unlink_slot)
-        pa_hook_slot_free(u->volume_control_unlink_slot);
-
-    if (u->volume_control_put_slot)
-        pa_hook_slot_free(u->volume_control_put_slot);
-
-    if (u->volume_api)
-        pa_volume_api_unref(u->volume_api);
-
-    if (u->extension_installed)
-        pa_native_protocol_remove_ext(u->native_protocol, module);
-
-    if (u->native_protocol)
-        pa_native_protocol_unref(u->native_protocol);
-
-    pa_xfree(u);
-}
diff --git a/src/modules/volume-api/mute-control.c b/src/modules/volume-api/mute-control.c
deleted file mode 100644 (file)
index 1b2f276..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "mute-control.h"
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/device.h>
-#include <modules/volume-api/sstream.h>
-
-#include <pulsecore/core-util.h>
-
-int pa_mute_control_new(pa_volume_api *api, const char *name, bool persistent, pa_mute_control **_r) {
-    pa_mute_control *control = NULL;
-    int r;
-
-    pa_assert(api);
-    pa_assert(name);
-    pa_assert(_r);
-
-    control = pa_xnew0(pa_mute_control, 1);
-    control->volume_api = api;
-    control->index = pa_volume_api_allocate_mute_control_index(api);
-
-    r = pa_volume_api_register_name(api, name, false, &control->name);
-    if (r < 0)
-        goto fail;
-
-    control->description = pa_xstrdup(control->name);
-    control->proplist = pa_proplist_new();
-    control->present = !persistent;
-    control->persistent = persistent;
-    control->purpose = PA_MUTE_CONTROL_PURPOSE_OTHER;
-    control->devices = pa_hashmap_new(NULL, NULL);
-    control->default_for_devices = pa_hashmap_new(NULL, NULL);
-
-    if (persistent) {
-        pa_inidb_row *row;
-
-        row = pa_inidb_table_add_row(api->control_db.mute_controls, control->name);
-        control->db_cells.description = pa_inidb_row_get_cell(row, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_DESCRIPTION);
-        control->db_cells.mute = pa_inidb_row_get_cell(row, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_MUTE);
-    }
-
-    *_r = control;
-    return 0;
-
-fail:
-    if (control)
-        pa_mute_control_free(control);
-
-    return r;
-}
-
-void pa_mute_control_put(pa_mute_control *control) {
-    const char *prop_key;
-    void *state = NULL;
-
-    pa_assert(control);
-    pa_assert(control->set_mute || !control->present);
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_IMPLEMENTATION_INITIALIZED], control);
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_SET_INITIAL_MUTE], control);
-
-    if (control->set_mute) {
-        control->set_mute_in_progress = true;
-        control->set_mute(control, control->mute);
-        control->set_mute_in_progress = false;
-    }
-
-    pa_volume_api_add_mute_control(control->volume_api, control);
-    control->linked = true;
-
-    pa_log_debug("Created mute control #%u.", control->index);
-    pa_log_debug("    Name: %s", control->name);
-    pa_log_debug("    Description: %s", control->description);
-    pa_log_debug("    Mute: %s", pa_yes_no(control->mute));
-    pa_log_debug("    Present: %s", pa_yes_no(control->present));
-    pa_log_debug("    Persistent: %s", pa_yes_no(control->persistent));
-    pa_log_debug("    Properties:");
-
-    while ((prop_key = pa_proplist_iterate(control->proplist, &state)))
-        pa_log_debug("        %s = %s", prop_key, pa_strnull(pa_proplist_gets(control->proplist, prop_key)));
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_PUT], control);
-}
-
-void pa_mute_control_unlink(pa_mute_control *control) {
-    pa_device *device;
-
-    pa_assert(control);
-
-    if (control->unlinked) {
-        pa_log_debug("Unlinking mute control %s (already unlinked, this is a no-op).", control->name);
-        return;
-    }
-
-    control->unlinked = true;
-
-    pa_log_debug("Unlinking mute control %s.", control->name);
-
-    if (control->linked)
-        pa_volume_api_remove_mute_control(control->volume_api, control);
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK], control);
-
-    while ((device = pa_hashmap_first(control->default_for_devices)))
-        pa_device_set_default_mute_control(device, NULL);
-
-    while ((device = pa_hashmap_first(control->devices))) {
-        /* Why do we have this assertion here? The concern is that if we call
-         * pa_device_set_mute_control() for some device that has the
-         * use_default_mute_control flag set, then that flag will be unset as
-         * a side effect, and we don't want that side effect. This assertion
-         * should be safe, because we just called
-         * pa_device_set_default_mute_control(NULL) for each device that this
-         * control was the default for, and that should ensure that we don't
-         * any more hold any references to devices that used to use this
-         * control as the default. */
-        pa_assert(!device->use_default_mute_control);
-        pa_device_set_mute_control(device, NULL);
-    }
-}
-
-void pa_mute_control_free(pa_mute_control *control) {
-    pa_assert(control);
-
-    /* unlink() expects name to be set. */
-    if (!control->unlinked && control->name)
-        pa_mute_control_unlink(control);
-
-    if (control->default_for_devices) {
-        pa_assert(pa_hashmap_isempty(control->default_for_devices));
-        pa_hashmap_free(control->default_for_devices);
-    }
-
-    if (control->devices) {
-        pa_assert(pa_hashmap_isempty(control->devices));
-        pa_hashmap_free(control->devices);
-    }
-
-    if (control->proplist)
-        pa_proplist_free(control->proplist);
-
-    pa_xfree(control->description);
-
-    if (control->name)
-        pa_volume_api_unregister_name(control->volume_api, control->name);
-
-    pa_xfree(control);
-}
-
-void pa_mute_control_set_purpose(pa_mute_control *control, pa_mute_control_purpose_t purpose, void *owner) {
-    pa_assert(control);
-    pa_assert(!control->linked);
-
-    control->purpose = purpose;
-    control->owner = owner;
-}
-
-int pa_mute_control_acquire_for_audio_group(pa_mute_control *control, pa_audio_group *group,
-                                            pa_mute_control_set_mute_cb_t set_mute_cb, void *userdata) {
-    pa_assert(control);
-    pa_assert(group);
-    pa_assert(set_mute_cb);
-
-    if (control->present) {
-        pa_log("Can't acquire mute control %s, it's already present.", control->name);
-        return -PA_ERR_BUSY;
-    }
-
-    control->owner_audio_group = group;
-    control->set_mute = set_mute_cb;
-    control->userdata = userdata;
-
-    control->set_mute_in_progress = true;
-    control->set_mute(control, control->mute);
-    control->set_mute_in_progress = false;
-
-    control->present = true;
-
-    if (!control->linked || control->unlinked)
-        return 0;
-
-    pa_log_debug("Mute control %s became present.", control->name);
-
-    return 0;
-}
-
-void pa_mute_control_release(pa_mute_control *control) {
-    pa_assert(control);
-
-    if (!control->present)
-        return;
-
-    control->present = false;
-
-    control->userdata = NULL;
-    control->set_mute = NULL;
-    control->owner_audio_group = NULL;
-
-    if (!control->linked || control->unlinked)
-        return;
-
-    pa_log_debug("Mute control %s became not present.", control->name);
-}
-
-void pa_mute_control_set_description(pa_mute_control *control, const char *description) {
-    char *old_description;
-
-    pa_assert(control);
-    pa_assert(description);
-
-    old_description = control->description;
-
-    if (pa_streq(description, old_description))
-        return;
-
-    control->description = pa_xstrdup(description);
-
-    if (control->persistent)
-        pa_inidb_cell_set_value(control->db_cells.description, description);
-
-    if (!control->linked || control->unlinked) {
-        pa_xfree(old_description);
-        return;
-    }
-
-    pa_log_debug("The description of mute control %s changed from \"%s\" to \"%s\".", control->name, old_description,
-                 description);
-    pa_xfree(old_description);
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_DESCRIPTION_CHANGED], control);
-}
-
-static void set_mute_internal(pa_mute_control *control, bool mute) {
-    bool old_mute;
-
-    pa_assert(control);
-
-    old_mute = control->mute;
-
-    if (mute == old_mute)
-        return;
-
-    control->mute = mute;
-
-    if (control->persistent)
-        pa_inidb_cell_set_value(control->db_cells.mute, pa_boolean_to_string(mute));
-
-    if (!control->linked || control->unlinked)
-        return;
-
-    pa_log_debug("The mute of mute control %s changed from %s to %s.", control->name, pa_boolean_to_string(old_mute),
-                 pa_boolean_to_string(control->mute));
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED], control);
-}
-
-int pa_mute_control_set_mute(pa_mute_control *control, bool mute) {
-    int r;
-
-    pa_assert(control);
-
-    if (control->set_mute_in_progress)
-        return 0;
-
-    if (mute == control->mute)
-        return 0;
-
-    if (control->linked && control->present) {
-        control->set_mute_in_progress = true;
-        r = control->set_mute(control, mute);
-        control->set_mute_in_progress = false;
-
-        if (r < 0) {
-            pa_log("Setting the mute of mute control %s failed.", control->name);
-            return r;
-        }
-    }
-
-    set_mute_internal(control, mute);
-
-    return 0;
-}
-
-void pa_mute_control_add_device(pa_mute_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_put(control->devices, device, device) >= 0);
-}
-
-void pa_mute_control_remove_device(pa_mute_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_remove(control->devices, device));
-}
-
-void pa_mute_control_add_default_for_device(pa_mute_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_put(control->default_for_devices, device, device) >= 0);
-}
-
-void pa_mute_control_remove_default_for_device(pa_mute_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_remove(control->default_for_devices, device));
-}
diff --git a/src/modules/volume-api/mute-control.h b/src/modules/volume-api/mute-control.h
deleted file mode 100644 (file)
index 40f8a9c..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef foomutecontrolhfoo
-#define foomutecontrolhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/inidb.h>
-#include <modules/volume-api/volume-api.h>
-
-typedef struct pa_mute_control pa_mute_control;
-
-typedef enum {
-    PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE,
-    PA_MUTE_CONTROL_PURPOSE_OTHER,
-} pa_mute_control_purpose_t;
-
-typedef int (*pa_mute_control_set_mute_cb_t)(pa_mute_control *control, bool mute);
-
-struct pa_mute_control {
-    pa_volume_api *volume_api;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_proplist *proplist;
-    bool mute;
-    bool present;
-    bool persistent;
-
-    pa_mute_control_purpose_t purpose;
-    union {
-        pas_stream *owner_stream;
-        void *owner;
-    };
-
-    /* If this mute control is the "own mute control" of an audio group, this
-     * is set to point to that group, otherwise this is NULL. */
-    pa_audio_group *owner_audio_group;
-
-    pa_hashmap *devices; /* pa_device -> pa_device (hashmap-as-a-set) */
-    pa_hashmap *default_for_devices; /* pa_device -> pa_device (hashmap-as-a-set) */
-
-    struct {
-        pa_inidb_cell *description;
-        pa_inidb_cell *mute;
-    } db_cells;
-
-    bool linked;
-    bool unlinked;
-    bool set_mute_in_progress;
-
-    /* Called from pa_mute_control_set_mute(). The implementation is expected
-     * to return a negative error code on failure. */
-    pa_mute_control_set_mute_cb_t set_mute;
-
-    void *userdata;
-};
-
-int pa_mute_control_new(pa_volume_api *api, const char *name, bool persistent, pa_mute_control **_r);
-void pa_mute_control_put(pa_mute_control *control);
-void pa_mute_control_unlink(pa_mute_control *control);
-void pa_mute_control_free(pa_mute_control *control);
-
-/* Called by the mute control implementation, before pa_mute_control_put(). */
-void pa_mute_control_set_purpose(pa_mute_control *control, pa_mute_control_purpose_t purpose, void *owner);
-
-/* Called by the mute control implementation. */
-int pa_mute_control_acquire_for_audio_group(pa_mute_control *control, pa_audio_group *group,
-                                            pa_mute_control_set_mute_cb_t set_mute_cb, void *userdata);
-
-/* Called by the mute control implementation. This must only be called for
- * persistent controls; use pa_mute_control_free() for non-persistent
- * controls. */
-void pa_mute_control_release(pa_mute_control *control);
-
-/* Called by anyone. */
-void pa_mute_control_set_description(pa_mute_control *control, const char *description);
-int pa_mute_control_set_mute(pa_mute_control *control, bool mute);
-
-/* Called from device.c only. */
-void pa_mute_control_add_device(pa_mute_control *control, pa_device *device);
-void pa_mute_control_remove_device(pa_mute_control *control, pa_device *device);
-void pa_mute_control_add_default_for_device(pa_mute_control *control, pa_device *device);
-void pa_mute_control_remove_default_for_device(pa_mute_control *control, pa_device *device);
-
-#endif
diff --git a/src/modules/volume-api/sstream.c b/src/modules/volume-api/sstream.c
deleted file mode 100644 (file)
index 1738d15..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "sstream.h"
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulse/direction.h>
-
-#include <pulsecore/core-util.h>
-
-int pas_stream_new(pa_volume_api *api, const char *name, pas_stream **_r) {
-    pas_stream *stream = NULL;
-    int r;
-
-    pa_assert(api);
-    pa_assert(name);
-    pa_assert(_r);
-
-    stream = pa_xnew0(pas_stream, 1);
-    stream->volume_api = api;
-    stream->index = pa_volume_api_allocate_stream_index(api);
-
-    r = pa_volume_api_register_name(api, name, false, &stream->name);
-    if (r < 0)
-        goto fail;
-
-    stream->description = pa_xstrdup(stream->name);
-    stream->direction = PA_DIRECTION_OUTPUT;
-    stream->proplist = pa_proplist_new();
-
-    *_r = stream;
-    return 0;
-
-fail:
-    if (stream)
-        pas_stream_free(stream);
-
-    return r;
-}
-
-void pas_stream_put(pas_stream *stream) {
-    const char *prop_key;
-    void *state = NULL;
-
-    pa_assert(stream);
-
-    pa_volume_api_add_stream(stream->volume_api, stream);
-    stream->linked = true;
-
-    pa_log_debug("Created stream #%u.", stream->index);
-    pa_log_debug("    Name: %s", stream->name);
-    pa_log_debug("    Description: %s", stream->description);
-    pa_log_debug("    Direction: %s", pa_direction_to_string(stream->direction));
-    pa_log_debug("    Volume control: %s", stream->volume_control ? stream->volume_control->name : "(unset)");
-    pa_log_debug("    Mute control: %s", stream->mute_control ? stream->mute_control->name : "(unset)");
-    pa_log_debug("    Audio group for volume: %s",
-                 stream->audio_group_for_volume ? stream->audio_group_for_volume->name : "(unset)");
-    pa_log_debug("    Audio group for mute: %s",
-                 stream->audio_group_for_mute ? stream->audio_group_for_mute->name : "(unset)");
-    pa_log_debug("    Properties:");
-
-    while ((prop_key = pa_proplist_iterate(stream->proplist, &state)))
-        pa_log_debug("        %s = %s", prop_key, pa_strnull(pa_proplist_gets(stream->proplist, prop_key)));
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PUT], stream);
-}
-
-void pas_stream_unlink(pas_stream *stream) {
-    pa_assert(stream);
-
-    if (stream->unlinked) {
-        pa_log_debug("Unlinking stream %s (already unlinked, this is a no-op).", stream->name);
-        return;
-    }
-
-    stream->unlinked = true;
-
-    pa_log_debug("Unlinking stream %s.", stream->name);
-
-    if (stream->linked)
-        pa_volume_api_remove_stream(stream->volume_api, stream);
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_UNLINK], stream);
-
-    pas_stream_set_audio_group_for_mute(stream, NULL);
-    pas_stream_set_audio_group_for_volume(stream, NULL);
-    pas_stream_set_mute_control(stream, NULL);
-    pas_stream_set_relative_volume_control(stream, NULL);
-    pas_stream_set_volume_control(stream, NULL);
-}
-
-void pas_stream_free(pas_stream *stream) {
-    pa_assert(stream);
-
-    /* unlink() expects name to be set. */
-    if (!stream->unlinked && stream->name)
-        pas_stream_unlink(stream);
-
-    if (stream->proplist)
-        pa_proplist_free(stream->proplist);
-
-    pa_xfree(stream->description);
-
-    if (stream->name)
-        pa_volume_api_unregister_name(stream->volume_api, stream->name);
-
-    pa_xfree(stream);
-}
-
-void pas_stream_set_direction(pas_stream *stream, pa_direction_t direction) {
-    pa_assert(stream);
-    pa_assert(!stream->linked);
-
-    stream->direction = direction;
-}
-
-void pas_stream_set_description(pas_stream *stream, const char *description) {
-    char *old_description;
-
-    pa_assert(stream);
-    pa_assert(description);
-
-    old_description = stream->description;
-
-    if (pa_streq(description, old_description))
-        return;
-
-    stream->description = pa_xstrdup(description);
-
-    if (!stream->linked || stream->unlinked) {
-        pa_xfree(old_description);
-        return;
-    }
-
-    pa_log_debug("Stream %s description changed from \"%s\" to \"%s\".", stream->name, old_description,
-                 description);
-    pa_xfree(old_description);
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_DESCRIPTION_CHANGED], stream);
-}
-
-void pas_stream_set_property(pas_stream *stream, const char *key, const char *value) {
-    const char *old_value;
-
-    pa_assert(stream);
-    pa_assert(key);
-
-    old_value = pa_proplist_gets(stream->proplist, key);
-
-    if (pa_safe_streq(value, old_value))
-        return;
-
-    if (value)
-        pa_proplist_sets(stream->proplist, key, value);
-    else
-        pa_proplist_unset(stream->proplist, key);
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("Stream %s property \"%s\" changed from \"%s\" to \"%s\".", stream->name, key,
-                 old_value ? old_value : "(unset)", value ? value : "(unset)");
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_PROPLIST_CHANGED], stream);
-}
-
-void pas_stream_set_volume_control(pas_stream *stream, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(stream);
-
-    old_control = stream->volume_control;
-
-    if (control == old_control)
-        return;
-
-    stream->volume_control = control;
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("The volume control of stream %s changed from %s to %s.", stream->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_VOLUME_CONTROL_CHANGED], stream);
-}
-
-void pas_stream_set_relative_volume_control(pas_stream *stream, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(stream);
-
-    old_control = stream->relative_volume_control;
-
-    if (control == old_control)
-        return;
-
-    stream->relative_volume_control = control;
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("The relative volume control of stream %s changed from %s to %s.", stream->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_RELATIVE_VOLUME_CONTROL_CHANGED], stream);
-}
-
-void pas_stream_set_mute_control(pas_stream *stream, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(stream);
-
-    old_control = stream->mute_control;
-
-    if (control == old_control)
-        return;
-
-    stream->mute_control = control;
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("The mute control of stream %s changed from %s to %s.", stream->name,
-                 old_control ? old_control->name : "(unset)", control ? control->name : "(unset)");
-
-    pa_hook_fire(&stream->volume_api->hooks[PA_VOLUME_API_HOOK_STREAM_MUTE_CONTROL_CHANGED], stream);
-}
-
-void pas_stream_set_audio_group_for_volume(pas_stream *stream, pa_audio_group *group) {
-    pa_audio_group *old_group;
-
-    pa_assert(stream);
-
-    old_group = stream->audio_group_for_volume;
-
-    if (group == old_group)
-        return;
-
-    if (old_group)
-        pa_audio_group_remove_volume_stream(old_group, stream);
-
-    stream->audio_group_for_volume = group;
-
-    if (group)
-        pa_audio_group_add_volume_stream(group, stream);
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("Stream %s audio group for volume changed from %s to %s.", stream->name,
-                 old_group ? old_group->name : "(unset)", group ? group->name : "(unset)");
-}
-
-void pas_stream_set_audio_group_for_mute(pas_stream *stream, pa_audio_group *group) {
-    pa_audio_group *old_group;
-
-    pa_assert(stream);
-
-    old_group = stream->audio_group_for_mute;
-
-    if (group == old_group)
-        return;
-
-    if (old_group)
-        pa_audio_group_remove_mute_stream(old_group, stream);
-
-    stream->audio_group_for_mute = group;
-
-    if (group)
-        pa_audio_group_add_mute_stream(group, stream);
-
-    if (!stream->linked || stream->unlinked)
-        return;
-
-    pa_log_debug("Stream %s audio group for mute changed from %s to %s.", stream->name,
-                 old_group ? old_group->name : "(unset)", group ? group->name : "(unset)");
-}
diff --git a/src/modules/volume-api/sstream.h b/src/modules/volume-api/sstream.h
deleted file mode 100644 (file)
index 715bf2c..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef foosstreamhfoo
-#define foosstreamhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/volume-api.h>
-
-/* We use the "pas_" prefix in pas_stream, because there's already pa_stream in
- * the client API, and there's no good alternative term for streams. The 's' in
- * "pas" means "server", i.e. the point is that this stuff is for servers,
- * while pa_stream is for clients. */
-
-typedef struct pas_stream pas_stream;
-
-struct pas_stream {
-    pa_volume_api *volume_api;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_direction_t direction;
-    pa_proplist *proplist;
-    pa_volume_control *volume_control;
-    pa_volume_control *relative_volume_control;
-    pa_mute_control *mute_control;
-    pa_audio_group *audio_group_for_volume;
-    pa_audio_group *audio_group_for_mute;
-
-    bool linked;
-    bool unlinked;
-
-    void *userdata;
-};
-
-int pas_stream_new(pa_volume_api *api, const char *name, pas_stream **_r);
-void pas_stream_put(pas_stream *stream);
-void pas_stream_unlink(pas_stream *stream);
-void pas_stream_free(pas_stream *stream);
-
-/* Called by the stream implementation, only during initialization. */
-void pas_stream_set_direction(pas_stream *stream, pa_direction_t direction);
-
-/* Called by the stream implementation. */
-void pas_stream_set_description(pas_stream *stream, const char *description);
-void pas_stream_set_property(pas_stream *stream, const char *key, const char *value);
-void pas_stream_set_volume_control(pas_stream *stream, pa_volume_control *control);
-void pas_stream_set_relative_volume_control(pas_stream *stream, pa_volume_control *control);
-void pas_stream_set_mute_control(pas_stream *stream, pa_mute_control *control);
-
-/* Called by anyone. */
-void pas_stream_set_audio_group_for_volume(pas_stream *stream, pa_audio_group *group);
-void pas_stream_set_audio_group_for_mute(pas_stream *stream, pa_audio_group *group);
-
-#endif
diff --git a/src/modules/volume-api/stream-creator.c b/src/modules/volume-api/stream-creator.c
deleted file mode 100644 (file)
index 0d9ea24..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "stream-creator.h"
-
-#include <modules/volume-api/sstream.h>
-#include <modules/volume-api/mute-control.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/i18n.h>
-
-struct pa_stream_creator {
-    pa_volume_api *volume_api;
-    pa_hashmap *streams; /* pa_sink_input/pa_source_output -> struct stream */
-    pa_hook_slot *sink_input_fixate_slot;
-    pa_hook_slot *sink_input_unlink_slot;
-    pa_hook_slot *source_output_fixate_slot;
-    pa_hook_slot *source_output_unlink_slot;
-};
-
-enum stream_type {
-    STREAM_TYPE_SINK_INPUT,
-    STREAM_TYPE_SOURCE_OUTPUT,
-};
-
-struct stream {
-    pa_core *core;
-    pa_stream_creator *creator;
-    enum stream_type type;
-    pa_sink_input_new_data *sink_input_new_data;
-    pa_sink_input *sink_input;
-    pa_source_output_new_data *source_output_new_data;
-    pa_source_output *source_output;
-    pa_client *client;
-    pa_volume_control *volume_control;
-    pa_volume_control *relative_volume_control;
-    pa_mute_control *mute_control;
-    pas_stream *stream;
-
-    pa_hook_slot *proplist_changed_slot;
-    pa_hook_slot *volume_changed_slot;
-    pa_hook_slot *reference_ratio_changed_slot;
-    pa_hook_slot *mute_changed_slot;
-};
-
-static void stream_free(struct stream *stream);
-
-static int volume_control_set_volume_cb(pa_volume_control *control, const pa_bvolume *original_volume,
-                                        const pa_bvolume *remapped_volume, bool set_volume, bool set_balance) {
-    struct stream *stream;
-    pa_bvolume bvolume;
-    pa_cvolume cvolume;
-
-    pa_assert(control);
-    pa_assert(original_volume);
-    pa_assert(remapped_volume);
-
-    stream = control->userdata;
-    bvolume = control->volume;
-
-    if (set_volume)
-        bvolume.volume = remapped_volume->volume;
-
-    if (set_balance)
-        pa_bvolume_copy_balance(&bvolume, remapped_volume);
-
-    pa_bvolume_to_cvolume(&bvolume, &cvolume);
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            if (stream->sink_input->state == PA_SINK_INPUT_INIT)
-                pa_sink_input_new_data_set_volume(stream->sink_input_new_data, &cvolume, false);
-            else
-                pa_sink_input_set_volume(stream->sink_input, &cvolume, true, true);
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            if (stream->source_output->state == PA_SOURCE_OUTPUT_INIT)
-                pa_source_output_new_data_set_volume(stream->source_output_new_data, &cvolume, false);
-            else
-                pa_source_output_set_volume(stream->source_output, &cvolume, true, true);
-            break;
-    }
-
-    return 0;
-}
-
-static pa_hook_result_t sink_input_or_source_output_volume_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct stream *stream = userdata;
-    pa_sink_input *input = NULL;
-    pa_source_output *output = NULL;
-    pa_bvolume bvolume;
-
-    pa_assert(stream);
-    pa_assert(call_data);
-
-    if (!stream->volume_control)
-        return PA_HOOK_OK;
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            input = call_data;
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            output = call_data;
-            break;
-    }
-
-    if ((input && input != stream->sink_input) || (output && output != stream->source_output))
-        return PA_HOOK_OK;
-
-    if (input)
-        pa_bvolume_from_cvolume(&bvolume, &input->volume, &input->channel_map);
-    else if (output)
-        pa_bvolume_from_cvolume(&bvolume, &output->volume, &output->channel_map);
-    else
-        pa_assert_not_reached();
-
-    pa_volume_control_set_volume(stream->volume_control, &bvolume, true, true);
-
-    return PA_HOOK_OK;
-}
-
-static int relative_volume_control_set_volume_cb(pa_volume_control *control, const pa_bvolume *original_volume,
-                                                 const pa_bvolume *remapped_volume, bool set_volume, bool set_balance) {
-    struct stream *stream;
-    pa_bvolume bvolume;
-    pa_cvolume cvolume;
-
-    pa_assert(control);
-    pa_assert(original_volume);
-    pa_assert(remapped_volume);
-
-    stream = control->userdata;
-    bvolume = control->volume;
-
-    if (set_volume)
-        bvolume.volume = remapped_volume->volume;
-
-    if (set_balance)
-        pa_bvolume_copy_balance(&bvolume, remapped_volume);
-
-    pa_bvolume_to_cvolume(&bvolume, &cvolume);
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            if (stream->sink_input->state == PA_SINK_INPUT_INIT) {
-                pa_sink_input_new_data_set_volume(stream->sink_input_new_data, &cvolume, true);
-
-                /* XXX: This is a bit ugly. This is needed, because when we
-                 * call pa_sink_input_new_data_set_volume(), there's no
-                 * automatic notification to the primary volume control object
-                 * about the changed volume. This problem should go away once
-                 * stream volume controls are moved into the core. */
-                if (stream->volume_control) {
-                    pa_bvolume absolute_volume;
-
-                    pa_bvolume_from_cvolume(&absolute_volume, &stream->sink_input_new_data->volume,
-                                            &stream->sink_input_new_data->channel_map);
-                    pa_volume_control_set_volume(stream->volume_control, &absolute_volume, true, true);
-                }
-            } else
-                pa_sink_input_set_volume(stream->sink_input, &cvolume, true, false);
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            if (stream->source_output->state == PA_SOURCE_OUTPUT_INIT) {
-                pa_source_output_new_data_set_volume(stream->source_output_new_data, &cvolume, true);
-
-                /* XXX: This is a bit ugly. This is needed, because when we
-                 * call pa_source_output_new_data_set_volume(), there's no
-                 * automatic notification to the primary volume control object
-                 * about the changed volume. This problem should go away once
-                 * stream volume controls are moved into the core. */
-                if (stream->volume_control) {
-                    pa_bvolume absolute_volume;
-
-                    pa_bvolume_from_cvolume(&absolute_volume, &stream->source_output_new_data->volume,
-                                            &stream->source_output_new_data->channel_map);
-                    pa_volume_control_set_volume(stream->volume_control, &absolute_volume, true, true);
-                }
-            } else
-                pa_source_output_set_volume(stream->source_output, &cvolume, true, false);
-            break;
-    }
-
-    return 0;
-}
-
-static pa_hook_result_t sink_input_or_source_output_reference_ratio_changed_cb(void *hook_data, void *call_data,
-                                                                               void *userdata) {
-    struct stream *stream = userdata;
-    pa_sink_input *input = NULL;
-    pa_source_output *output = NULL;
-    pa_bvolume bvolume;
-
-    pa_assert(stream);
-    pa_assert(call_data);
-
-    if (!stream->relative_volume_control)
-        return PA_HOOK_OK;
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            input = call_data;
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            output = call_data;
-            break;
-    }
-
-    if ((input && input != stream->sink_input) || (output && output != stream->source_output))
-        return PA_HOOK_OK;
-
-    if (input)
-        pa_bvolume_from_cvolume(&bvolume, &input->reference_ratio, &input->channel_map);
-    else if (output)
-        pa_bvolume_from_cvolume(&bvolume, &output->reference_ratio, &output->channel_map);
-    else
-        pa_assert_not_reached();
-
-    pa_volume_control_set_volume(stream->relative_volume_control, &bvolume, true, true);
-
-    return PA_HOOK_OK;
-}
-
-static int mute_control_set_mute_cb(pa_mute_control *control, bool mute) {
-    struct stream *stream;
-
-    pa_assert(control);
-
-    stream = control->userdata;
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            if (stream->sink_input->state == PA_SINK_INPUT_INIT)
-                pa_sink_input_new_data_set_muted(stream->sink_input_new_data, mute);
-            else
-                pa_sink_input_set_mute(stream->sink_input, mute, true);
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            if (stream->source_output->state == PA_SOURCE_OUTPUT_INIT)
-                pa_source_output_new_data_set_muted(stream->source_output_new_data, mute);
-            else
-                pa_source_output_set_mute(stream->source_output, mute, true);
-            break;
-    }
-
-    return 0;
-}
-
-static pa_hook_result_t sink_input_or_source_output_mute_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct stream *stream = userdata;
-    pa_sink_input *input = NULL;
-    pa_source_output *output = NULL;
-    bool mute;
-
-    pa_assert(stream);
-    pa_assert(call_data);
-
-    if (!stream->mute_control)
-        return PA_HOOK_OK;
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            input = call_data;
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            output = call_data;
-            break;
-    }
-
-    if ((input && input != stream->sink_input) || (output && output != stream->source_output))
-        return PA_HOOK_OK;
-
-    if (input)
-        mute = input->muted;
-    else if (output)
-        mute = output->muted;
-    else
-        pa_assert_not_reached();
-
-    pa_mute_control_set_mute(stream->mute_control, mute);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_input_or_source_output_proplist_changed_cb(void *hook_data, void *call_data, void *userdata) {
-    struct stream *stream = userdata;
-    pa_sink_input *input = NULL;
-    pa_source_output *output = NULL;
-    pa_proplist *proplist = NULL;
-    const char *description = NULL;
-
-    pa_assert(stream);
-    pa_assert(call_data);
-
-    switch (stream->type) {
-        case STREAM_TYPE_SINK_INPUT:
-            input = call_data;
-
-            if (input != stream->sink_input)
-                return PA_HOOK_OK;
-
-            proplist = stream->sink_input->proplist;
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            output = call_data;
-
-            if (output != stream->source_output)
-                return PA_HOOK_OK;
-
-            proplist = stream->source_output->proplist;
-            break;
-    }
-
-    description = pa_proplist_gets(proplist, PA_PROP_MEDIA_NAME);
-    if (!description)
-        description = stream->stream->name;
-
-    pas_stream_set_description(stream->stream, description);
-
-    return PA_HOOK_OK;
-}
-
-static int stream_new(pa_stream_creator *creator, enum stream_type type, void *new_data, void *core_stream,
-                      struct stream **_r) {
-    struct stream *stream = NULL;
-    pa_proplist *proplist = NULL;
-    pa_channel_map *channel_map = NULL;
-    bool volume_available = false;
-    pa_bvolume volume;
-    pa_bvolume relative_volume;
-    bool mute = false;
-    const char *stream_name = NULL;
-    const char *description = NULL;
-    const char *volume_control_name = NULL;
-    const char *relative_volume_control_name = NULL;
-    const char *mute_control_name = NULL;
-    pa_direction_t direction = PA_DIRECTION_OUTPUT;
-    int r;
-    const char *prop_key;
-    void *state = NULL;
-
-    pa_assert(creator);
-    pa_assert(core_stream);
-    pa_assert(_r);
-
-    pa_bvolume_init_invalid(&volume);
-    pa_bvolume_init_invalid(&relative_volume);
-
-    stream = pa_xnew0(struct stream, 1);
-    stream->core = creator->volume_api->core;
-    stream->creator = creator;
-    stream->type = type;
-
-    switch (type) {
-        case STREAM_TYPE_SINK_INPUT:
-            stream->sink_input_new_data = new_data;
-            stream->sink_input = core_stream;
-
-            if (new_data) {
-                stream->client = stream->sink_input_new_data->client;
-                proplist = stream->sink_input_new_data->proplist;
-                channel_map = &stream->sink_input_new_data->channel_map;
-                volume_available = stream->sink_input_new_data->volume_writable;
-
-                if (volume_available) {
-                    if (!stream->sink_input_new_data->volume_is_set) {
-                        pa_cvolume cvolume;
-
-                        pa_cvolume_reset(&cvolume, channel_map->channels);
-                        pa_sink_input_new_data_set_volume(stream->sink_input_new_data, &cvolume, true);
-                    }
-
-                    pa_bvolume_from_cvolume(&volume, &stream->sink_input_new_data->volume, channel_map);
-                    pa_bvolume_from_cvolume(&relative_volume, &stream->sink_input_new_data->reference_ratio, channel_map);
-                }
-
-                if (!stream->sink_input_new_data->muted_is_set)
-                    pa_sink_input_new_data_set_muted(stream->sink_input_new_data, false);
-
-                mute = stream->sink_input_new_data->muted;
-            } else {
-                stream->client = stream->sink_input->client;
-                proplist = stream->sink_input->proplist;
-                channel_map = &stream->sink_input->channel_map;
-                pa_bvolume_from_cvolume(&volume, &stream->sink_input->volume, channel_map);
-                pa_bvolume_from_cvolume(&relative_volume, &stream->sink_input->reference_ratio, channel_map);
-                mute = stream->sink_input->muted;
-            }
-
-            stream_name = "sink-input-stream";
-            volume_control_name = "sink-input-volume-control";
-            relative_volume_control_name = "sink-input-relative-volume-control";
-            mute_control_name = "sink-input-mute-control";
-
-            direction = PA_DIRECTION_OUTPUT;
-
-            stream->proplist_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_proplist_changed_cb, stream);
-            stream->volume_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SINK_INPUT_VOLUME_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_volume_changed_cb, stream);
-            stream->reference_ratio_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SINK_INPUT_REFERENCE_RATIO_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_reference_ratio_changed_cb, stream);
-            stream->mute_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SINK_INPUT_MUTE_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_mute_changed_cb, stream);
-            break;
-
-        case STREAM_TYPE_SOURCE_OUTPUT:
-            stream->source_output_new_data = new_data;
-            stream->source_output = core_stream;
-
-            if (new_data) {
-                stream->client = stream->source_output_new_data->client;
-                proplist = stream->source_output_new_data->proplist;
-                channel_map = &stream->source_output_new_data->channel_map;
-                volume_available = stream->source_output_new_data->volume_writable;
-
-                if (volume_available) {
-                    if (!stream->source_output_new_data->volume_is_set) {
-                        pa_cvolume cvolume;
-
-                        pa_cvolume_reset(&cvolume, channel_map->channels);
-                        pa_source_output_new_data_set_volume(stream->source_output_new_data, &cvolume, true);
-                    }
-
-                    pa_bvolume_from_cvolume(&volume, &stream->source_output_new_data->volume, channel_map);
-                    pa_bvolume_from_cvolume(&relative_volume, &stream->source_output_new_data->reference_ratio, channel_map);
-                }
-
-                if (!stream->source_output_new_data->muted_is_set)
-                    pa_source_output_new_data_set_muted(stream->source_output_new_data, false);
-
-                mute = stream->source_output_new_data->muted;
-            } else {
-                stream->client = stream->source_output->client;
-                proplist = stream->source_output->proplist;
-                channel_map = &stream->source_output->channel_map;
-                pa_bvolume_from_cvolume(&volume, &stream->source_output->volume, channel_map);
-                pa_bvolume_from_cvolume(&relative_volume, &stream->source_output->reference_ratio, channel_map);
-                mute = stream->source_output->muted;
-            }
-
-            stream_name = "source-output-stream";
-            volume_control_name = "source-output-volume-control";
-            relative_volume_control_name = "source-output-relative-volume-control";
-            mute_control_name = "source-output-mute-control";
-
-            direction = PA_DIRECTION_INPUT;
-
-            stream->proplist_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_proplist_changed_cb, stream);
-
-            if (volume_available) {
-                stream->volume_changed_slot =
-                        pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_VOLUME_CHANGED], PA_HOOK_NORMAL,
-                                        sink_input_or_source_output_volume_changed_cb, stream);
-                stream->reference_ratio_changed_slot =
-                        pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_REFERENCE_RATIO_CHANGED],
-                                        PA_HOOK_NORMAL, sink_input_or_source_output_reference_ratio_changed_cb, stream);
-            }
-
-            stream->mute_changed_slot =
-                    pa_hook_connect(&stream->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MUTE_CHANGED], PA_HOOK_NORMAL,
-                                    sink_input_or_source_output_mute_changed_cb, stream);
-            break;
-    }
-
-    r = pas_stream_new(creator->volume_api, stream_name, &stream->stream);
-    if (r < 0)
-        goto fail;
-
-    description = pa_proplist_gets(proplist, PA_PROP_MEDIA_NAME);
-    if (!description)
-        description = stream->stream->name;
-
-    pas_stream_set_description(stream->stream, description);
-
-    while ((prop_key = pa_proplist_iterate(proplist, &state)))
-        pas_stream_set_property(stream->stream, prop_key, pa_proplist_gets(proplist, prop_key));
-
-    pas_stream_set_direction(stream->stream, direction);
-    stream->stream->userdata = stream;
-
-    if (volume_available) {
-        r = pa_volume_control_new(stream->creator->volume_api, volume_control_name, false,
-                                  &stream->volume_control);
-        if (r >= 0) {
-            pa_volume_control_set_description(stream->volume_control, _("Volume"));
-            pa_volume_control_set_channel_map(stream->volume_control, channel_map);
-            pa_volume_control_set_volume(stream->volume_control, &volume, true, true);
-            pa_volume_control_set_convertible_to_dB(stream->volume_control, true);
-            stream->volume_control->set_volume = volume_control_set_volume_cb;
-            stream->volume_control->userdata = stream;
-
-            pas_stream_set_volume_control(stream->stream, stream->volume_control);
-        }
-
-        r = pa_volume_control_new(stream->creator->volume_api, relative_volume_control_name, false,
-                                  &stream->relative_volume_control);
-        if (r >= 0) {
-            pa_volume_control_set_description(stream->relative_volume_control, _("Relative volume"));
-            pa_volume_control_set_channel_map(stream->relative_volume_control, channel_map);
-            pa_volume_control_set_volume(stream->relative_volume_control, &relative_volume, true, true);
-            pa_volume_control_set_convertible_to_dB(stream->relative_volume_control, true);
-            pa_volume_control_set_purpose(stream->relative_volume_control, PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME,
-                                          stream->stream);
-            stream->relative_volume_control->set_volume = relative_volume_control_set_volume_cb;
-            stream->relative_volume_control->userdata = stream;
-
-            pas_stream_set_relative_volume_control(stream->stream, stream->relative_volume_control);
-        }
-    }
-
-    r = pa_mute_control_new(stream->creator->volume_api, mute_control_name, false, &stream->mute_control);
-    if (r >= 0) {
-        pa_mute_control_set_description(stream->mute_control, _("Mute"));
-        pa_mute_control_set_mute(stream->mute_control, mute);
-        pa_mute_control_set_purpose(stream->mute_control, PA_MUTE_CONTROL_PURPOSE_STREAM_MUTE, stream->stream);
-        stream->mute_control->set_mute = mute_control_set_mute_cb;
-        stream->mute_control->userdata = stream;
-
-        pas_stream_set_mute_control(stream->stream, stream->mute_control);
-    }
-
-    pas_stream_put(stream->stream);
-
-    if (stream->volume_control)
-        pa_volume_control_put(stream->volume_control);
-
-    if (stream->relative_volume_control)
-        pa_volume_control_put(stream->relative_volume_control);
-
-    if (stream->mute_control)
-        pa_mute_control_put(stream->mute_control);
-
-    *_r = stream;
-    return 0;
-
-fail:
-    if (stream)
-        stream_free(stream);
-
-    return r;
-}
-
-static void stream_free(struct stream *stream) {
-    pa_assert(stream);
-
-    if (stream->mute_changed_slot)
-        pa_hook_slot_free(stream->mute_changed_slot);
-
-    if (stream->reference_ratio_changed_slot)
-        pa_hook_slot_free(stream->reference_ratio_changed_slot);
-
-    if (stream->volume_changed_slot)
-        pa_hook_slot_free(stream->volume_changed_slot);
-
-    if (stream->proplist_changed_slot)
-        pa_hook_slot_free(stream->proplist_changed_slot);
-
-    if (stream->mute_control)
-        pa_mute_control_free(stream->mute_control);
-
-    if (stream->relative_volume_control)
-        pa_volume_control_free(stream->relative_volume_control);
-
-    if (stream->volume_control)
-        pa_volume_control_free(stream->volume_control);
-
-    if (stream->stream)
-        pas_stream_free(stream->stream);
-
-    pa_xfree(stream);
-}
-
-static pa_hook_result_t sink_input_fixate_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_stream_creator *creator = userdata;
-    pa_sink_input_new_data *data = call_data;
-    int r;
-    struct stream *stream;
-
-    pa_assert(creator);
-    pa_assert(data);
-
-    r = stream_new(creator, STREAM_TYPE_SINK_INPUT, data, data->sink_input, &stream);
-    if (r < 0)
-        return PA_HOOK_OK;
-
-    pa_hashmap_put(creator->streams, stream->sink_input, stream);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_input_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_stream_creator *creator = userdata;
-    pa_sink_input *input = call_data;
-
-    pa_assert(creator);
-    pa_assert(input);
-
-    pa_hashmap_remove_and_free(creator->streams, input);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_output_fixate_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_stream_creator *creator = userdata;
-    pa_source_output_new_data *data = call_data;
-    int r;
-    struct stream *stream;
-
-    pa_assert(creator);
-    pa_assert(data);
-
-    r = stream_new(creator, STREAM_TYPE_SOURCE_OUTPUT, data, data->source_output, &stream);
-    if (r < 0)
-        return PA_HOOK_OK;
-
-    pa_hashmap_put(creator->streams, stream->source_output, stream);
-
-    return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_output_unlink_cb(void *hook_data, void *call_data, void *userdata) {
-    pa_stream_creator *creator = userdata;
-    pa_source_output *output = call_data;
-
-    pa_assert(creator);
-    pa_assert(output);
-
-    pa_hashmap_remove_and_free(creator->streams, output);
-
-    return PA_HOOK_OK;
-}
-
-pa_stream_creator *pa_stream_creator_new(pa_volume_api *api) {
-    pa_stream_creator *creator;
-    uint32_t idx;
-    pa_sink_input *input;
-    pa_source_output *output;
-    int r;
-    struct stream *stream;
-
-    pa_assert(api);
-
-    creator = pa_xnew0(pa_stream_creator, 1);
-    creator->volume_api = api;
-    creator->streams = pa_hashmap_new_full(NULL, NULL, NULL, (pa_free_cb_t) stream_free);
-    creator->sink_input_fixate_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_NORMAL,
-                                                      sink_input_fixate_cb, creator);
-    creator->sink_input_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_NORMAL,
-                                                      sink_input_unlink_cb, creator);
-    creator->source_output_fixate_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_NORMAL,
-                                                         source_output_fixate_cb, creator);
-    creator->source_output_unlink_slot = pa_hook_connect(&api->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_NORMAL,
-                                                         source_output_unlink_cb, creator);
-
-    PA_IDXSET_FOREACH(input, api->core->sink_inputs, idx) {
-        r = stream_new(creator, STREAM_TYPE_SINK_INPUT, NULL, input, &stream);
-        if (r >= 0)
-            pa_hashmap_put(creator->streams, stream->sink_input, stream);
-    }
-
-    PA_IDXSET_FOREACH(output, api->core->source_outputs, idx) {
-        r = stream_new(creator, STREAM_TYPE_SOURCE_OUTPUT, NULL, output, &stream);
-        if (r >= 0)
-            pa_hashmap_put(creator->streams, stream->source_output, stream);
-    }
-
-    return creator;
-}
-
-void pa_stream_creator_free(pa_stream_creator *creator) {
-    pa_assert(creator);
-
-    if (creator->streams)
-        pa_hashmap_remove_all(creator->streams);
-
-    if (creator->source_output_unlink_slot)
-        pa_hook_slot_free(creator->source_output_unlink_slot);
-
-    if (creator->source_output_fixate_slot)
-        pa_hook_slot_free(creator->source_output_fixate_slot);
-
-    if (creator->sink_input_unlink_slot)
-        pa_hook_slot_free(creator->sink_input_unlink_slot);
-
-    if (creator->sink_input_fixate_slot)
-        pa_hook_slot_free(creator->sink_input_fixate_slot);
-
-    if (creator->streams)
-        pa_hashmap_free(creator->streams);
-
-    pa_xfree(creator);
-}
diff --git a/src/modules/volume-api/stream-creator.h b/src/modules/volume-api/stream-creator.h
deleted file mode 100644 (file)
index 97a03a4..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef foostreamcreatorhfoo
-#define foostreamcreatorhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/volume-api.h>
-
-typedef struct pa_stream_creator pa_stream_creator;
-
-pa_stream_creator *pa_stream_creator_new(pa_volume_api *api);
-void pa_stream_creator_free(pa_stream_creator *creator);
-
-#endif
diff --git a/src/modules/volume-api/volume-api-common.h b/src/modules/volume-api/volume-api-common.h
deleted file mode 100644 (file)
index d257ffc..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#define PA_VOLUME_API_VERSION 1
-#define PA_VOLUME_API_EXTENSION_NAME "module-volume-api"
-
-enum {
-    PA_VOLUME_API_COMMAND_CONNECT,
-    PA_VOLUME_API_COMMAND_DISCONNECT,
-    PA_VOLUME_API_COMMAND_SUBSCRIBE,
-    PA_VOLUME_API_COMMAND_SUBSCRIBE_EVENT,
-    PA_VOLUME_API_COMMAND_GET_SERVER_INFO,
-    PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO,
-    PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO_LIST,
-    PA_VOLUME_API_COMMAND_SET_VOLUME_CONTROL_VOLUME,
-    PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO,
-    PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO_LIST,
-    PA_VOLUME_API_COMMAND_SET_MUTE_CONTROL_MUTE,
-    PA_VOLUME_API_COMMAND_GET_DEVICE_INFO,
-    PA_VOLUME_API_COMMAND_GET_DEVICE_INFO_LIST,
-    PA_VOLUME_API_COMMAND_GET_STREAM_INFO,
-    PA_VOLUME_API_COMMAND_GET_STREAM_INFO_LIST,
-    PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO,
-    PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO_LIST
-};
diff --git a/src/modules/volume-api/volume-api.c b/src/modules/volume-api/volume-api.c
deleted file mode 100644 (file)
index 4a8a2e6..0000000
+++ /dev/null
@@ -1,733 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "volume-api.h"
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/device.h>
-#include <modules/volume-api/device-creator.h>
-#include <modules/volume-api/inidb.h>
-#include <modules/volume-api/sstream.h>
-#include <modules/volume-api/stream-creator.h>
-#include <modules/volume-api/volume-control.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/shared.h>
-
-#define CONTROL_DB_TABLE_NAME_VOLUME_CONTROL "VolumeControl"
-#define CONTROL_DB_TABLE_NAME_MUTE_CONTROL "MuteControl"
-
-static pa_volume_api *volume_api_new(pa_core *core);
-static void volume_api_free(pa_volume_api *api);
-
-pa_volume_api *pa_volume_api_get(pa_core *core) {
-    pa_volume_api *api;
-
-    pa_assert(core);
-
-    api = pa_shared_get(core, "volume-api");
-
-    if (api)
-        pa_volume_api_ref(api);
-    else {
-        api = volume_api_new(core);
-        pa_assert_se(pa_shared_set(core, "volume-api", api) >= 0);
-    }
-
-    return api;
-}
-
-pa_volume_api *pa_volume_api_ref(pa_volume_api *api) {
-    pa_assert(api);
-
-    api->refcnt++;
-
-    return api;
-}
-
-void pa_volume_api_unref(pa_volume_api *api) {
-    pa_assert(api);
-    pa_assert(api->refcnt > 0);
-
-    api->refcnt--;
-
-    if (api->refcnt == 0) {
-        pa_assert_se(pa_shared_remove(api->core, "volume-api") >= 0);
-        volume_api_free(api);
-    }
-}
-
-static int control_db_get_volume_control_cb(pa_inidb *db, const char *name, void **_r) {
-    pa_volume_api *api;
-    pa_volume_control *control;
-
-    pa_assert(db);
-    pa_assert(name);
-    pa_assert(_r);
-
-    api = pa_inidb_get_userdata(db);
-
-    control = pa_hashmap_get(api->volume_controls_from_db, name);
-    if (!control) {
-        int r;
-
-        r = pa_volume_control_new(api, name, true, &control);
-        if (r < 0)
-            return r;
-
-        pa_hashmap_put(api->volume_controls_from_db, (void *) control->name, control);
-    }
-
-    *_r = control;
-    return 0;
-}
-
-static int control_db_parse_volume_control_description_cb(pa_inidb *db, const char *value, void *object) {
-    pa_volume_control *control = object;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    pa_volume_control_set_description(control, value);
-
-    return 0;
-}
-
-static int control_db_parse_volume_control_volume_cb(pa_inidb *db, const char *value, void *object) {
-    pa_volume_control *control = object;
-    int r;
-    pa_bvolume bvolume;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    r = pa_atou(value, &bvolume.volume);
-    if (r < 0)
-        return -PA_ERR_INVALID;
-
-    if (!PA_VOLUME_IS_VALID(bvolume.volume))
-        return -PA_ERR_INVALID;
-
-    pa_volume_control_set_volume(control, &bvolume, true, false);
-
-    return 0;
-}
-
-static int control_db_parse_volume_control_balance_cb(pa_inidb *db, const char *value, void *object) {
-    pa_volume_control *control = object;
-    int r;
-    pa_bvolume bvolume;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    r = pa_bvolume_parse_balance(value, &bvolume);
-    if (r < 0)
-        return -PA_ERR_INVALID;
-
-    pa_volume_control_set_channel_map(control, &bvolume.channel_map);
-    pa_volume_control_set_volume(control, &bvolume, false, true);
-
-    return 0;
-}
-
-static int control_db_parse_volume_control_convertible_to_dB_cb(pa_inidb *db, const char *value, void *object) {
-    pa_volume_control *control = object;
-    int r;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    r = pa_parse_boolean(value);
-    if (r < 0)
-        return -PA_ERR_INVALID;
-
-    pa_volume_control_set_convertible_to_dB(control, r);
-
-    return 0;
-}
-
-static int control_db_get_mute_control_cb(pa_inidb *db, const char *name, void **_r) {
-    pa_volume_api *api;
-    pa_mute_control *control;
-
-    pa_assert(db);
-    pa_assert(name);
-    pa_assert(_r);
-
-    api = pa_inidb_get_userdata(db);
-
-    control = pa_hashmap_get(api->mute_controls_from_db, name);
-    if (!control) {
-        int r;
-
-        r = pa_mute_control_new(api, name, true, &control);
-        if (r < 0)
-            return r;
-
-        pa_hashmap_put(api->mute_controls_from_db, (void *) control->name, control);
-    }
-
-    *_r = control;
-    return 0;
-}
-
-static int control_db_parse_mute_control_description_cb(pa_inidb *db, const char *value, void *object) {
-    pa_mute_control *control = object;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    pa_mute_control_set_description(control, value);
-
-    return 0;
-}
-
-static int control_db_parse_mute_control_mute_cb(pa_inidb *db, const char *value, void *object) {
-    pa_mute_control *control = object;
-    int mute;
-
-    pa_assert(db);
-    pa_assert(value);
-    pa_assert(control);
-
-    mute = pa_parse_boolean(value);
-    if (mute < 0)
-        return -PA_ERR_INVALID;
-
-    pa_mute_control_set_mute(control, mute);
-
-    return 0;
-}
-
-static void create_control_db(pa_volume_api *api) {
-    pa_volume_control *volume_control;
-    pa_mute_control *mute_control;
-
-    pa_assert(api);
-    pa_assert(!api->control_db.db);
-
-    api->control_db.db = pa_inidb_new(api->core, "controls", api);
-
-    api->control_db.volume_controls = pa_inidb_add_table(api->control_db.db, CONTROL_DB_TABLE_NAME_VOLUME_CONTROL,
-                                                         control_db_get_volume_control_cb);
-    pa_inidb_table_add_column(api->control_db.volume_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_DESCRIPTION,
-                              control_db_parse_volume_control_description_cb);
-    pa_inidb_table_add_column(api->control_db.volume_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_VOLUME,
-                              control_db_parse_volume_control_volume_cb);
-    pa_inidb_table_add_column(api->control_db.volume_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_BALANCE,
-                              control_db_parse_volume_control_balance_cb);
-    pa_inidb_table_add_column(api->control_db.volume_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_CONVERTIBLE_TO_DB,
-                              control_db_parse_volume_control_convertible_to_dB_cb);
-
-    api->control_db.mute_controls = pa_inidb_add_table(api->control_db.db, CONTROL_DB_TABLE_NAME_MUTE_CONTROL,
-                                                       control_db_get_mute_control_cb);
-    pa_inidb_table_add_column(api->control_db.mute_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_DESCRIPTION,
-                              control_db_parse_mute_control_description_cb);
-    pa_inidb_table_add_column(api->control_db.mute_controls, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_MUTE,
-                              control_db_parse_mute_control_mute_cb);
-
-    api->volume_controls_from_db = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    api->mute_controls_from_db = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-
-    pa_inidb_load(api->control_db.db);
-
-    while ((volume_control = pa_hashmap_steal_first(api->volume_controls_from_db)))
-        pa_volume_control_put(volume_control);
-
-    pa_hashmap_free(api->volume_controls_from_db);
-    api->volume_controls_from_db = NULL;
-
-    while ((mute_control = pa_hashmap_steal_first(api->mute_controls_from_db)))
-        pa_mute_control_put(mute_control);
-
-    pa_hashmap_free(api->mute_controls_from_db);
-    api->mute_controls_from_db = NULL;
-}
-
-static void delete_control_db(pa_volume_api *api) {
-    pa_assert(api);
-
-    if (!api->control_db.db)
-        return;
-
-    pa_inidb_free(api->control_db.db);
-    api->control_db.mute_controls = NULL;
-    api->control_db.volume_controls = NULL;
-    api->control_db.db = NULL;
-}
-
-static void create_objects_defer_event_cb(pa_mainloop_api *mainloop_api, pa_defer_event *event, void *userdata) {
-    pa_volume_api *volume_api = userdata;
-
-    pa_assert(volume_api);
-    pa_assert(event == volume_api->create_objects_defer_event);
-
-    mainloop_api->defer_free(event);
-    volume_api->create_objects_defer_event = NULL;
-
-    volume_api->device_creator = pa_device_creator_new(volume_api);
-    volume_api->stream_creator = pa_stream_creator_new(volume_api);
-}
-
-static pa_volume_api *volume_api_new(pa_core *core) {
-    pa_volume_api *api;
-    unsigned i;
-
-    pa_assert(core);
-
-    api = pa_xnew0(pa_volume_api, 1);
-    api->core = core;
-    api->refcnt = 1;
-    api->names = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
-    api->volume_controls = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    api->mute_controls = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    api->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    api->streams = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    api->audio_groups = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-
-    for (i = 0; i < PA_VOLUME_API_HOOK_MAX; i++)
-        pa_hook_init(&api->hooks[i], api);
-
-    create_control_db(api);
-
-    /* We delay the object creation to ensure that policy modules have a chance
-     * to affect the initialization of the objects. If we created the objects
-     * immediately, policy modules wouldn't have a chance of connecting to the
-     * object creation hooks before the objects are created. */
-    api->create_objects_defer_event = core->mainloop->defer_new(core->mainloop, create_objects_defer_event_cb, api);
-
-    pa_log_debug("Created a pa_volume_api object.");
-
-    return api;
-}
-
-static void volume_api_free(pa_volume_api *api) {
-    unsigned i;
-
-    pa_assert(api);
-    pa_assert(api->refcnt == 0);
-
-    pa_log_debug("Freeing the pa_volume_api object.");
-
-    pa_assert(!api->mute_controls_from_db);
-    pa_assert(!api->volume_controls_from_db);
-
-    if (api->stream_creator)
-        pa_stream_creator_free(api->stream_creator);
-
-    if (api->device_creator)
-        pa_device_creator_free(api->device_creator);
-
-    if (api->create_objects_defer_event)
-        api->core->mainloop->defer_free(api->create_objects_defer_event);
-
-    delete_control_db(api);
-
-    for (i = 0; i < PA_VOLUME_API_HOOK_MAX; i++)
-        pa_hook_done(&api->hooks[i]);
-
-    if (api->audio_groups) {
-        pa_assert(pa_hashmap_isempty(api->audio_groups));
-        pa_hashmap_free(api->audio_groups);
-    }
-
-    if (api->streams) {
-        pa_assert(pa_hashmap_isempty(api->streams));
-        pa_hashmap_free(api->streams);
-    }
-
-    if (api->devices) {
-        pa_assert(pa_hashmap_isempty(api->devices));
-        pa_hashmap_free(api->devices);
-    }
-
-    if (api->mute_controls) {
-        pa_mute_control *control;
-
-        while ((control = pa_hashmap_first(api->mute_controls))) {
-            pa_assert(!control->present);
-            pa_mute_control_free(control);
-        }
-
-        pa_hashmap_free(api->mute_controls);
-    }
-
-    if (api->volume_controls) {
-        pa_volume_control *control;
-
-        while ((control = pa_hashmap_first(api->volume_controls))) {
-            pa_assert(!control->present);
-            pa_volume_control_free(control);
-        }
-
-        pa_hashmap_free(api->volume_controls);
-    }
-
-    if (api->names) {
-        pa_assert(pa_hashmap_isempty(api->names));
-        pa_hashmap_free(api->names);
-    }
-
-    pa_xfree(api);
-}
-
-int pa_volume_api_register_name(pa_volume_api *api, const char *requested_name, bool fail_if_already_registered,
-                                const char **registered_name) {
-    char *n;
-
-    pa_assert(api);
-    pa_assert(requested_name);
-    pa_assert(registered_name);
-
-    if (!pa_namereg_is_valid_name(requested_name)) {
-        pa_log("Invalid name: \"%s\"", requested_name);
-        return -PA_ERR_INVALID;
-    }
-
-    n = pa_xstrdup(requested_name);
-
-    if (pa_hashmap_put(api->names, n, n) < 0) {
-        unsigned i = 1;
-
-        if (fail_if_already_registered) {
-            pa_xfree(n);
-            pa_log("Name %s already registered.", requested_name);
-            return -PA_ERR_EXIST;
-        }
-
-        do {
-            pa_xfree(n);
-            i++;
-            n = pa_sprintf_malloc("%s.%u", requested_name, i);
-        } while (pa_hashmap_put(api->names, n, n) < 0);
-    }
-
-    *registered_name = n;
-
-    return 0;
-}
-
-void pa_volume_api_unregister_name(pa_volume_api *api, const char *name) {
-    pa_assert(api);
-    pa_assert(name);
-
-    pa_assert_se(pa_hashmap_remove_and_free(api->names, name) >= 0);
-}
-
-uint32_t pa_volume_api_allocate_volume_control_index(pa_volume_api *api) {
-    uint32_t idx;
-
-    pa_assert(api);
-
-    idx = api->next_volume_control_index++;
-
-    return idx;
-}
-
-void pa_volume_api_add_volume_control(pa_volume_api *api, pa_volume_control *control) {
-    pa_assert(api);
-    pa_assert(control);
-
-    pa_assert_se(pa_hashmap_put(api->volume_controls, (void *) control->name, control) >= 0);
-}
-
-int pa_volume_api_remove_volume_control(pa_volume_api *api, pa_volume_control *control) {
-    pa_assert(api);
-    pa_assert(control);
-
-    if (!pa_hashmap_remove(api->volume_controls, control->name))
-        return -1;
-
-    if (control == api->main_output_volume_control)
-        pa_volume_api_set_main_output_volume_control(api, NULL);
-
-    if (control == api->main_input_volume_control)
-        pa_volume_api_set_main_input_volume_control(api, NULL);
-
-    return 0;
-}
-
-pa_volume_control *pa_volume_api_get_volume_control_by_index(pa_volume_api *api, uint32_t idx) {
-    pa_volume_control *control;
-    void *state;
-
-    pa_assert(api);
-
-    PA_HASHMAP_FOREACH(control, api->volume_controls, state) {
-        if (control->index == idx)
-            return control;
-    }
-
-    return NULL;
-}
-
-uint32_t pa_volume_api_allocate_mute_control_index(pa_volume_api *api) {
-    uint32_t idx;
-
-    pa_assert(api);
-
-    idx = api->next_mute_control_index++;
-
-    return idx;
-}
-
-void pa_volume_api_add_mute_control(pa_volume_api *api, pa_mute_control *control) {
-    pa_assert(api);
-    pa_assert(control);
-
-    pa_assert_se(pa_hashmap_put(api->mute_controls, (void *) control->name, control) >= 0);
-}
-
-int pa_volume_api_remove_mute_control(pa_volume_api *api, pa_mute_control *control) {
-    pa_assert(api);
-    pa_assert(control);
-
-    if (!pa_hashmap_remove(api->mute_controls, control->name))
-        return -1;
-
-    if (control == api->main_output_mute_control)
-        pa_volume_api_set_main_output_mute_control(api, NULL);
-
-    if (control == api->main_input_mute_control)
-        pa_volume_api_set_main_input_mute_control(api, NULL);
-
-    return 0;
-}
-
-pa_mute_control *pa_volume_api_get_mute_control_by_index(pa_volume_api *api, uint32_t idx) {
-    pa_mute_control *control;
-    void *state;
-
-    pa_assert(api);
-
-    PA_HASHMAP_FOREACH(control, api->mute_controls, state) {
-        if (control->index == idx)
-            return control;
-    }
-
-    return NULL;
-}
-
-uint32_t pa_volume_api_allocate_device_index(pa_volume_api *api) {
-    uint32_t idx;
-
-    pa_assert(api);
-
-    idx = api->next_device_index++;
-
-    return idx;
-}
-
-void pa_volume_api_add_device(pa_volume_api *api, pa_device *device) {
-    pa_assert(api);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_put(api->devices, (void *) device->name, device) >= 0);
-}
-
-int pa_volume_api_remove_device(pa_volume_api *api, pa_device *device) {
-    pa_assert(api);
-    pa_assert(device);
-
-    if (!pa_hashmap_remove(api->devices, device->name))
-        return -1;
-
-    return 0;
-}
-
-pa_device *pa_volume_api_get_device_by_index(pa_volume_api *api, uint32_t idx) {
-    pa_device *device;
-    void *state;
-
-    pa_assert(api);
-
-    PA_HASHMAP_FOREACH(device, api->devices, state) {
-        if (device->index == idx)
-            return device;
-    }
-
-    return NULL;
-}
-
-uint32_t pa_volume_api_allocate_stream_index(pa_volume_api *api) {
-    uint32_t idx;
-
-    pa_assert(api);
-
-    idx = api->next_stream_index++;
-
-    return idx;
-}
-
-void pa_volume_api_add_stream(pa_volume_api *api, pas_stream *stream) {
-    pa_assert(api);
-    pa_assert(stream);
-
-    pa_assert_se(pa_hashmap_put(api->streams, (void *) stream->name, stream) >= 0);
-}
-
-int pa_volume_api_remove_stream(pa_volume_api *api, pas_stream *stream) {
-    pa_assert(api);
-    pa_assert(stream);
-
-    if (!pa_hashmap_remove(api->streams, stream->name))
-        return -1;
-
-    return 0;
-}
-
-pas_stream *pa_volume_api_get_stream_by_index(pa_volume_api *api, uint32_t idx) {
-    pas_stream *stream;
-    void *state;
-
-    pa_assert(api);
-
-    PA_HASHMAP_FOREACH(stream, api->streams, state) {
-        if (stream->index == idx)
-            return stream;
-    }
-
-    return NULL;
-}
-
-uint32_t pa_volume_api_allocate_audio_group_index(pa_volume_api *api) {
-    uint32_t idx;
-
-    pa_assert(api);
-
-    idx = api->next_audio_group_index++;
-
-    return idx;
-}
-
-void pa_volume_api_add_audio_group(pa_volume_api *api, pa_audio_group *group) {
-    pa_assert(api);
-    pa_assert(group);
-
-    pa_assert_se(pa_hashmap_put(api->audio_groups, (void *) group->name, group) >= 0);
-}
-
-int pa_volume_api_remove_audio_group(pa_volume_api *api, pa_audio_group *group) {
-    pa_assert(api);
-    pa_assert(group);
-
-    if (!pa_hashmap_remove(api->audio_groups, group->name))
-        return -1;
-
-    return 0;
-}
-
-pa_audio_group *pa_volume_api_get_audio_group_by_index(pa_volume_api *api, uint32_t idx) {
-    pa_audio_group *group;
-    void *state;
-
-    pa_assert(api);
-
-    PA_HASHMAP_FOREACH(group, api->audio_groups, state) {
-        if (group->index == idx)
-            return group;
-    }
-
-    return NULL;
-}
-
-void pa_volume_api_set_main_output_volume_control(pa_volume_api *api, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(api);
-
-    old_control = api->main_output_volume_control;
-
-    if (control == old_control)
-        return;
-
-    api->main_output_volume_control = control;
-
-    pa_log_debug("Main output volume control changed from %s to %s.", old_control ? old_control->name : "(unset)",
-                 control ? control->name : "(unset)");
-
-    pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED], api);
-}
-
-void pa_volume_api_set_main_input_volume_control(pa_volume_api *api, pa_volume_control *control) {
-    pa_volume_control *old_control;
-
-    pa_assert(api);
-
-    old_control = api->main_input_volume_control;
-
-    if (control == old_control)
-        return;
-
-    api->main_input_volume_control = control;
-
-    pa_log_debug("Main input volume control changed from %s to %s.", old_control ? old_control->name : "(unset)",
-                 control ? control->name : "(unset)");
-
-    pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_VOLUME_CONTROL_CHANGED], api);
-}
-
-void pa_volume_api_set_main_output_mute_control(pa_volume_api *api, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(api);
-
-    old_control = api->main_output_mute_control;
-
-    if (control == old_control)
-        return;
-
-    api->main_output_mute_control = control;
-
-    pa_log_debug("Main output mute control changed from %s to %s.", old_control ? old_control->name : "(unset)",
-                 control ? control->name : "(unset)");
-
-    pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_OUTPUT_MUTE_CONTROL_CHANGED], api);
-}
-
-void pa_volume_api_set_main_input_mute_control(pa_volume_api *api, pa_mute_control *control) {
-    pa_mute_control *old_control;
-
-    pa_assert(api);
-
-    old_control = api->main_input_mute_control;
-
-    if (control == old_control)
-        return;
-
-    api->main_input_mute_control = control;
-
-    pa_log_debug("Main input mute control changed from %s to %s.", old_control ? old_control->name : "(unset)",
-                 control ? control->name : "(unset)");
-
-    pa_hook_fire(&api->hooks[PA_VOLUME_API_HOOK_MAIN_INPUT_MUTE_CONTROL_CHANGED], api);
-}
diff --git a/src/modules/volume-api/volume-api.h b/src/modules/volume-api/volume-api.h
deleted file mode 100644 (file)
index f99182a..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#ifndef foovolumeapihfoo
-#define foovolumeapihfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulsecore/core.h>
-
-#define PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_DESCRIPTION "description"
-#define PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_VOLUME "volume"
-#define PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_BALANCE "balance"
-#define PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_CONVERTIBLE_TO_DB "convertible-to-dB"
-#define PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_MUTE "mute"
-
-typedef struct pa_volume_api pa_volume_api;
-
-/* Avoid circular dependencies... */
-typedef struct pa_audio_group pa_audio_group;
-typedef struct pa_device pa_device;
-typedef struct pa_device_creator pa_device_creator;
-typedef struct pa_inidb pa_inidb;
-typedef struct pa_inidb_table pa_inidb_table;
-typedef struct pa_mute_control pa_mute_control;
-typedef struct pas_stream pas_stream;
-typedef struct pa_stream_creator pa_stream_creator;
-typedef struct pa_volume_control pa_volume_control;
-
-enum {
-    /* This is fired after the volume control implementation has done its part
-     * of the volume control initialization, but before policy modules have
-     * done their part of the initialization. Hook users are expected to not
-     * modify the volume control state in this hook. */
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_IMPLEMENTATION_INITIALIZED,
-
-    /* Policy modules can use this hook to initialize the volume control
-     * volume. This is fired before PUT. If a policy module sets the volume, it
-     * should return PA_HOOK_STOP to prevent lower-priority policy modules from
-     * modifying the volume. */
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_SET_INITIAL_VOLUME,
-
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT,
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK,
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_DESCRIPTION_CHANGED,
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED,
-    PA_VOLUME_API_HOOK_VOLUME_CONTROL_CONVERTIBLE_TO_DB_CHANGED,
-
-    /* This is fired after the mute control implementation has done its part of
-     * the mute control initialization, but before policy modules have done
-     * their part of the initialization. Hook users are expected to not modify
-     * the mute control state in this hook. */
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_IMPLEMENTATION_INITIALIZED,
-
-    /* Policy modules can use this hook to initialize the mute control mute.
-     * This is fired before PUT. If a policy module sets the mute, it should
-     * return PA_HOOK_STOP to prevent lower-priority policy modules from
-     * modifying the mute. */
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_SET_INITIAL_MUTE,
-
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_PUT,
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_UNLINK,
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_DESCRIPTION_CHANGED,
-    PA_VOLUME_API_HOOK_MUTE_CONTROL_MUTE_CHANGED,
-    PA_VOLUME_API_HOOK_DEVICE_PUT,
-    PA_VOLUME_API_HOOK_DEVICE_UNLINK,
-    PA_VOLUME_API_HOOK_DEVICE_DESCRIPTION_CHANGED,
-    PA_VOLUME_API_HOOK_DEVICE_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_DEVICE_MUTE_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_STREAM_PUT,
-    PA_VOLUME_API_HOOK_STREAM_UNLINK,
-    PA_VOLUME_API_HOOK_STREAM_DESCRIPTION_CHANGED,
-    PA_VOLUME_API_HOOK_STREAM_PROPLIST_CHANGED,
-    PA_VOLUME_API_HOOK_STREAM_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_STREAM_RELATIVE_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_STREAM_MUTE_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_AUDIO_GROUP_PUT,
-    PA_VOLUME_API_HOOK_AUDIO_GROUP_UNLINK,
-    PA_VOLUME_API_HOOK_AUDIO_GROUP_DESCRIPTION_CHANGED,
-    PA_VOLUME_API_HOOK_AUDIO_GROUP_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_AUDIO_GROUP_MUTE_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_MAIN_OUTPUT_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_MAIN_INPUT_VOLUME_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_MAIN_OUTPUT_MUTE_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_MAIN_INPUT_MUTE_CONTROL_CHANGED,
-    PA_VOLUME_API_HOOK_MAX
-};
-
-struct pa_volume_api {
-    pa_core *core;
-    unsigned refcnt;
-    pa_hashmap *names; /* object name -> object name (hashmap-as-a-set) */
-    pa_hashmap *volume_controls; /* name -> pa_volume_control */
-    pa_hashmap *mute_controls; /* name -> pa_mute_control */
-    pa_hashmap *devices; /* name -> pa_device */
-    pa_hashmap *streams; /* name -> pas_stream */
-    pa_hashmap *audio_groups; /* name -> pa_audio_group */
-    pa_volume_control *main_output_volume_control;
-    pa_volume_control *main_input_volume_control;
-    pa_mute_control *main_output_mute_control;
-    pa_mute_control *main_input_mute_control;
-
-    uint32_t next_volume_control_index;
-    uint32_t next_mute_control_index;
-    uint32_t next_device_index;
-    uint32_t next_stream_index;
-    uint32_t next_audio_group_index;
-    pa_hook hooks[PA_VOLUME_API_HOOK_MAX];
-
-    struct {
-        pa_inidb *db;
-        pa_inidb_table *volume_controls;
-        pa_inidb_table *mute_controls;
-    } control_db;
-
-    pa_defer_event *create_objects_defer_event;
-    pa_device_creator *device_creator;
-    pa_stream_creator *stream_creator;
-
-    pa_hashmap *volume_controls_from_db; /* control name -> pa_volume_control, only used during initialization. */
-    pa_hashmap *mute_controls_from_db; /* control name -> pa_mute_control, only used during initialization. */
-};
-
-pa_volume_api *pa_volume_api_get(pa_core *core);
-pa_volume_api *pa_volume_api_ref(pa_volume_api *api);
-void pa_volume_api_unref(pa_volume_api *api);
-
-int pa_volume_api_register_name(pa_volume_api *api, const char *requested_name, bool fail_if_already_registered,
-                                const char **registered_name);
-void pa_volume_api_unregister_name(pa_volume_api *api, const char *name);
-
-uint32_t pa_volume_api_allocate_volume_control_index(pa_volume_api *api);
-void pa_volume_api_add_volume_control(pa_volume_api *api, pa_volume_control *control);
-int pa_volume_api_remove_volume_control(pa_volume_api *api, pa_volume_control *control);
-pa_volume_control *pa_volume_api_get_volume_control_by_index(pa_volume_api *api, uint32_t idx);
-
-uint32_t pa_volume_api_allocate_mute_control_index(pa_volume_api *api);
-void pa_volume_api_add_mute_control(pa_volume_api *api, pa_mute_control *control);
-int pa_volume_api_remove_mute_control(pa_volume_api *api, pa_mute_control *control);
-pa_mute_control *pa_volume_api_get_mute_control_by_index(pa_volume_api *api, uint32_t idx);
-
-uint32_t pa_volume_api_allocate_device_index(pa_volume_api *api);
-void pa_volume_api_add_device(pa_volume_api *api, pa_device *device);
-int pa_volume_api_remove_device(pa_volume_api *api, pa_device *device);
-pa_device *pa_volume_api_get_device_by_index(pa_volume_api *api, uint32_t idx);
-
-uint32_t pa_volume_api_allocate_stream_index(pa_volume_api *api);
-void pa_volume_api_add_stream(pa_volume_api *api, pas_stream *stream);
-int pa_volume_api_remove_stream(pa_volume_api *api, pas_stream *stream);
-pas_stream *pa_volume_api_get_stream_by_index(pa_volume_api *api, uint32_t idx);
-
-uint32_t pa_volume_api_allocate_audio_group_index(pa_volume_api *api);
-void pa_volume_api_add_audio_group(pa_volume_api *api, pa_audio_group *group);
-int pa_volume_api_remove_audio_group(pa_volume_api *api, pa_audio_group *group);
-pa_audio_group *pa_volume_api_get_audio_group_by_index(pa_volume_api *api, uint32_t idx);
-
-void pa_volume_api_set_main_output_volume_control(pa_volume_api *api, pa_volume_control *control);
-void pa_volume_api_set_main_input_volume_control(pa_volume_api *api, pa_volume_control *control);
-void pa_volume_api_set_main_output_mute_control(pa_volume_api *api, pa_mute_control *control);
-void pa_volume_api_set_main_input_mute_control(pa_volume_api *api, pa_mute_control *control);
-
-#endif
diff --git a/src/modules/volume-api/volume-control.c b/src/modules/volume-api/volume-control.c
deleted file mode 100644 (file)
index bf4db71..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "volume-control.h"
-
-#include <modules/volume-api/audio-group.h>
-#include <modules/volume-api/device.h>
-#include <modules/volume-api/inidb.h>
-#include <modules/volume-api/sstream.h>
-
-#include <pulsecore/core-util.h>
-
-int pa_volume_control_new(pa_volume_api *api, const char *name, bool persistent, pa_volume_control **_r) {
-    pa_volume_control *control = NULL;
-    int r;
-
-    pa_assert(api);
-    pa_assert(name);
-    pa_assert(_r);
-
-    control = pa_xnew0(pa_volume_control, 1);
-    control->volume_api = api;
-    control->index = pa_volume_api_allocate_volume_control_index(api);
-
-    r = pa_volume_api_register_name(api, name, persistent, &control->name);
-    if (r < 0)
-        goto fail;
-
-    control->description = pa_xstrdup(control->name);
-    control->proplist = pa_proplist_new();
-    pa_bvolume_init_mono(&control->volume, PA_VOLUME_NORM);
-    control->present = !persistent;
-    control->persistent = persistent;
-    control->purpose = PA_VOLUME_CONTROL_PURPOSE_OTHER;
-    control->devices = pa_hashmap_new(NULL, NULL);
-    control->default_for_devices = pa_hashmap_new(NULL, NULL);
-
-    if (persistent) {
-        pa_inidb_row *row;
-
-        row = pa_inidb_table_add_row(api->control_db.volume_controls, control->name);
-        control->db_cells.description = pa_inidb_row_get_cell(row, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_DESCRIPTION);
-        control->db_cells.volume = pa_inidb_row_get_cell(row, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_VOLUME);
-        control->db_cells.balance = pa_inidb_row_get_cell(row, PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_BALANCE);
-        control->db_cells.convertible_to_dB = pa_inidb_row_get_cell(row,
-                                                                    PA_VOLUME_API_CONTROL_DB_COLUMN_NAME_CONVERTIBLE_TO_DB);
-    }
-
-    *_r = control;
-    return 0;
-
-fail:
-    if (control)
-        pa_volume_control_free(control);
-
-    return r;
-}
-
-void pa_volume_control_put(pa_volume_control *control) {
-    const char *prop_key;
-    void *state = NULL;
-    char volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
-    char balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
-
-    pa_assert(control);
-    pa_assert(control->set_volume || !control->present);
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_IMPLEMENTATION_INITIALIZED], control);
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_SET_INITIAL_VOLUME], control);
-
-    if (control->set_volume) {
-        control->set_volume_in_progress = true;
-        control->set_volume(control, &control->volume, &control->volume, true, true);
-        control->set_volume_in_progress = false;
-    }
-
-    pa_volume_api_add_volume_control(control->volume_api, control);
-    control->linked = true;
-
-    pa_log_debug("Created volume control #%u.", control->index);
-    pa_log_debug("    Name: %s", control->name);
-    pa_log_debug("    Description: %s", control->description);
-    pa_log_debug("    Volume: %s", pa_volume_snprint_verbose(volume_str, sizeof(volume_str), control->volume.volume,
-                 control->convertible_to_dB));
-    pa_log_debug("    Balance: %s", pa_bvolume_snprint_balance(balance_str, sizeof(balance_str), &control->volume));
-    pa_log_debug("    Present: %s", pa_yes_no(control->present));
-    pa_log_debug("    Persistent: %s", pa_yes_no(control->persistent));
-    pa_log_debug("    Properties:");
-
-    while ((prop_key = pa_proplist_iterate(control->proplist, &state)))
-        pa_log_debug("        %s = %s", prop_key, pa_strnull(pa_proplist_gets(control->proplist, prop_key)));
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_PUT], control);
-}
-
-void pa_volume_control_unlink(pa_volume_control *control) {
-    pa_device *device;
-
-    pa_assert(control);
-
-    if (control->unlinked) {
-        pa_log_debug("Unlinking volume control %s (already unlinked, this is a no-op).", control->name);
-        return;
-    }
-
-    control->unlinked = true;
-
-    pa_log_debug("Unlinking volume control %s.", control->name);
-
-    if (control->linked)
-        pa_volume_api_remove_volume_control(control->volume_api, control);
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_UNLINK], control);
-
-    while ((device = pa_hashmap_first(control->default_for_devices)))
-        pa_device_set_default_volume_control(device, NULL);
-
-    while ((device = pa_hashmap_first(control->devices))) {
-        /* Why do we have this assertion here? The concern is that if we call
-         * pa_device_set_volume_control() for some device that has the
-         * use_default_volume_control flag set, then that flag will be unset as
-         * a side effect, and we don't want that side effect. This assertion
-         * should be safe, because we just called
-         * pa_device_set_default_volume_control(NULL) for each device that this
-         * control was the default for, and that should ensure that we don't
-         * any more hold any references to devices that used to use this
-         * control as the default. */
-        pa_assert(!device->use_default_volume_control);
-        pa_device_set_volume_control(device, NULL);
-    }
-}
-
-void pa_volume_control_free(pa_volume_control *control) {
-    pa_assert(control);
-
-    /* unlink() expects name to be set. */
-    if (!control->unlinked && control->name)
-        pa_volume_control_unlink(control);
-
-    if (control->default_for_devices) {
-        pa_assert(pa_hashmap_isempty(control->default_for_devices));
-        pa_hashmap_free(control->default_for_devices);
-    }
-
-    if (control->devices) {
-        pa_assert(pa_hashmap_isempty(control->devices));
-        pa_hashmap_free(control->devices);
-    }
-
-    if (control->proplist)
-        pa_proplist_free(control->proplist);
-
-    pa_xfree(control->description);
-
-    if (control->name)
-        pa_volume_api_unregister_name(control->volume_api, control->name);
-
-    pa_xfree(control);
-}
-
-void pa_volume_control_set_purpose(pa_volume_control *control, pa_volume_control_purpose_t purpose, void *owner) {
-    pa_assert(control);
-    pa_assert(!control->linked);
-
-    control->purpose = purpose;
-    control->owner = owner;
-}
-
-int pa_volume_control_acquire_for_audio_group(pa_volume_control *control, pa_audio_group *group,
-                                              pa_volume_control_set_volume_cb_t set_volume_cb, void *userdata) {
-    pa_assert(control);
-    pa_assert(group);
-    pa_assert(set_volume_cb);
-
-    if (control->present) {
-        pa_log("Can't acquire volume control %s, it's already present.", control->name);
-        return -PA_ERR_BUSY;
-    }
-
-    control->set_volume = set_volume_cb;
-    control->userdata = userdata;
-
-    control->set_volume_in_progress = true;
-    control->set_volume(control, &control->volume, &control->volume, true, true);
-    control->set_volume_in_progress = false;
-
-    control->present = true;
-
-    if (!control->linked || control->unlinked)
-        return 0;
-
-    pa_log_debug("Volume control %s became present.", control->name);
-
-    return 0;
-}
-
-void pa_volume_control_release(pa_volume_control *control) {
-    pa_assert(control);
-
-    if (!control->present)
-        return;
-
-    control->present = false;
-
-    control->userdata = NULL;
-    control->set_volume = NULL;
-
-    if (!control->linked || control->unlinked)
-        return;
-
-    pa_log_debug("Volume control %s became not present.", control->name);
-}
-
-void pa_volume_control_set_description(pa_volume_control *control, const char *description) {
-    char *old_description;
-
-    pa_assert(control);
-    pa_assert(description);
-
-    old_description = control->description;
-
-    if (pa_streq(description, old_description))
-        return;
-
-    control->description = pa_xstrdup(description);
-
-    if (control->persistent)
-        pa_inidb_cell_set_value(control->db_cells.description, description);
-
-    if (!control->linked || control->unlinked) {
-        pa_xfree(old_description);
-        return;
-    }
-
-    pa_log_debug("The description of volume control %s changed from \"%s\" to \"%s\".", control->name, old_description,
-                 description);
-    pa_xfree(old_description);
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_DESCRIPTION_CHANGED], control);
-}
-
-static void set_volume_internal(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance) {
-    pa_bvolume old_volume;
-    bool volume_changed;
-    bool balance_changed;
-    char *str;
-
-    pa_assert(control);
-    pa_assert(volume);
-
-    old_volume = control->volume;
-    volume_changed = !pa_bvolume_equal(volume, &old_volume, set_volume, false);
-    balance_changed = !pa_bvolume_equal(volume, &old_volume, false, set_balance);
-
-    if (!volume_changed && !balance_changed)
-        return;
-
-    if (volume_changed) {
-        control->volume.volume = volume->volume;
-
-        if (control->persistent) {
-            str = pa_sprintf_malloc("%u", control->volume.volume);
-            pa_inidb_cell_set_value(control->db_cells.volume, str);
-            pa_xfree(str);
-        }
-    }
-
-    if (balance_changed) {
-        pa_bvolume_copy_balance(&control->volume, volume);
-
-        if (control->persistent) {
-            pa_assert_se(pa_bvolume_balance_to_string(&control->volume, &str) >= 0);
-            pa_inidb_cell_set_value(control->db_cells.balance, str);
-            pa_xfree(str);
-        }
-    }
-
-    if (!control->linked || control->unlinked)
-        return;
-
-    if (volume_changed) {
-        char old_volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
-        char new_volume_str[PA_VOLUME_SNPRINT_VERBOSE_MAX];
-
-        pa_log_debug("The volume of volume control %s changed from %s to %s.", control->name,
-                     pa_volume_snprint_verbose(old_volume_str, sizeof(old_volume_str), old_volume.volume,
-                                               control->convertible_to_dB),
-                     pa_volume_snprint_verbose(new_volume_str, sizeof(new_volume_str), control->volume.volume,
-                                               control->convertible_to_dB));
-    }
-
-    if (balance_changed) {
-        char old_balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
-        char new_balance_str[PA_BVOLUME_SNPRINT_BALANCE_MAX];
-
-        pa_log_debug("The balance of volume control %s changed from %s to %s.", control->name,
-                     pa_bvolume_snprint_balance(old_balance_str, sizeof(old_balance_str), &control->volume),
-                     pa_bvolume_snprint_balance(new_balance_str, sizeof(new_balance_str), &control->volume));
-    }
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_VOLUME_CHANGED], control);
-}
-
-int pa_volume_control_set_volume(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance) {
-    pa_bvolume volume_local;
-    int r;
-
-    pa_assert(control);
-    pa_assert(volume);
-
-    if (control->set_volume_in_progress)
-        return 0;
-
-    volume_local = *volume;
-
-    if (set_balance && !pa_channel_map_equal(&volume_local.channel_map, &control->volume.channel_map))
-        pa_bvolume_remap(&volume_local, &control->volume.channel_map);
-
-    if (pa_bvolume_equal(&volume_local, &control->volume, set_volume, set_balance))
-        return 0;
-
-    if (control->linked && control->present) {
-        control->set_volume_in_progress = true;
-        r = control->set_volume(control, volume, &volume_local, set_volume, set_balance);
-        control->set_volume_in_progress = false;
-
-        if (r < 0) {
-            pa_log("Setting the volume of volume control %s failed.", control->name);
-            return r;
-        }
-    }
-
-    set_volume_internal(control, &volume_local, set_volume, set_balance);
-
-    return 0;
-}
-
-void pa_volume_control_set_channel_map(pa_volume_control *control, const pa_channel_map *map) {
-    pa_bvolume bvolume;
-
-    pa_assert(control);
-    pa_assert(map);
-
-    if (pa_channel_map_equal(map, &control->volume.channel_map))
-        return;
-
-    pa_bvolume_copy_balance(&bvolume, &control->volume);
-    pa_bvolume_remap(&bvolume, map);
-
-    set_volume_internal(control, &bvolume, false, true);
-}
-
-void pa_volume_control_set_convertible_to_dB(pa_volume_control *control, bool convertible) {
-    bool old_convertible;
-
-    pa_assert(control);
-
-    old_convertible = control->convertible_to_dB;
-
-    if (convertible == old_convertible)
-        return;
-
-    control->convertible_to_dB = convertible;
-
-    if (control->persistent)
-        pa_inidb_cell_set_value(control->db_cells.convertible_to_dB, pa_boolean_to_string(convertible));
-
-    if (!control->linked || control->unlinked)
-        return;
-
-    pa_log_debug("The volume of volume control %s became %sconvertible to dB.", control->name, convertible ? "" : "not ");
-
-    pa_hook_fire(&control->volume_api->hooks[PA_VOLUME_API_HOOK_VOLUME_CONTROL_CONVERTIBLE_TO_DB_CHANGED], control);
-}
-
-void pa_volume_control_add_device(pa_volume_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_put(control->devices, device, device) >= 0);
-}
-
-void pa_volume_control_remove_device(pa_volume_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_remove(control->devices, device));
-}
-
-void pa_volume_control_add_default_for_device(pa_volume_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_put(control->default_for_devices, device, device) >= 0);
-}
-
-void pa_volume_control_remove_default_for_device(pa_volume_control *control, pa_device *device) {
-    pa_assert(control);
-    pa_assert(device);
-
-    pa_assert_se(pa_hashmap_remove(control->default_for_devices, device));
-}
diff --git a/src/modules/volume-api/volume-control.h b/src/modules/volume-api/volume-control.h
deleted file mode 100644 (file)
index a47ab20..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef foovolumecontrolhfoo
-#define foovolumecontrolhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <modules/volume-api/bvolume.h>
-#include <modules/volume-api/inidb.h>
-#include <modules/volume-api/volume-api.h>
-
-typedef struct pa_volume_control pa_volume_control;
-
-typedef enum {
-    PA_VOLUME_CONTROL_PURPOSE_STREAM_RELATIVE_VOLUME,
-    PA_VOLUME_CONTROL_PURPOSE_OTHER,
-} pa_volume_control_purpose_t;
-
-/* Usually remapped_volume is the volume to use, because it has a matching
- * channel map with the control, but in case the volume needs to be propagated
- * to another control, original_volume can be used to avoid loss of precision
- * that can result from remapping. */
-typedef int (*pa_volume_control_set_volume_cb_t)(pa_volume_control *control, const pa_bvolume *original_volume,
-                                                 const pa_bvolume *remapped_volume, bool set_volume, bool set_balance);
-
-struct pa_volume_control {
-    pa_volume_api *volume_api;
-    uint32_t index;
-    const char *name;
-    char *description;
-    pa_proplist *proplist;
-    pa_bvolume volume;
-    bool convertible_to_dB;
-    bool present;
-    bool persistent;
-
-    pa_volume_control_purpose_t purpose;
-    union {
-        pas_stream *owner_stream;
-        void *owner;
-    };
-
-    pa_hashmap *devices; /* pa_device -> pa_device (hashmap-as-a-set) */
-    pa_hashmap *default_for_devices; /* pa_device -> pa_device (hashmap-as-a-set) */
-
-    struct {
-        pa_inidb_cell *description;
-        pa_inidb_cell *volume;
-        pa_inidb_cell *balance;
-        pa_inidb_cell *convertible_to_dB;
-    } db_cells;
-
-    bool linked;
-    bool unlinked;
-    bool set_volume_in_progress;
-
-    /* Called from pa_volume_control_set_volume(). The implementation is
-     * expected to return a negative error code on failure. */
-    pa_volume_control_set_volume_cb_t set_volume;
-
-    void *userdata;
-};
-
-int pa_volume_control_new(pa_volume_api *api, const char *name, bool persistent, pa_volume_control **_r);
-void pa_volume_control_put(pa_volume_control *control);
-void pa_volume_control_unlink(pa_volume_control *control);
-void pa_volume_control_free(pa_volume_control *control);
-
-/* Called by the volume control implementation, before
- * pa_volume_control_put(). */
-void pa_volume_control_set_purpose(pa_volume_control *control, pa_volume_control_purpose_t purpose, void *owner);
-
-/* Called by the volume control implementation. */
-int pa_volume_control_acquire_for_audio_group(pa_volume_control *control, pa_audio_group *group,
-                                              pa_volume_control_set_volume_cb_t set_volume_cb, void *userdata);
-
-/* Called by the volume control implementation. This must only be called for
- * persistent controls; use pa_volume_control_free() for non-persistent
- * controls. */
-void pa_volume_control_release(pa_volume_control *control);
-
-/* Called by anyone. */
-void pa_volume_control_set_description(pa_volume_control *control, const char *description);
-int pa_volume_control_set_volume(pa_volume_control *control, const pa_bvolume *volume, bool set_volume, bool set_balance);
-
-/* Called by the volume control implementation. */
-void pa_volume_control_set_channel_map(pa_volume_control *control, const pa_channel_map *map);
-void pa_volume_control_set_convertible_to_dB(pa_volume_control *control, bool convertible);
-
-/* Called from device.c only. */
-void pa_volume_control_add_device(pa_volume_control *control, pa_device *device);
-void pa_volume_control_remove_device(pa_volume_control *control, pa_device *device);
-void pa_volume_control_add_default_for_device(pa_volume_control *control, pa_device *device);
-void pa_volume_control_remove_default_for_device(pa_volume_control *control, pa_device *device);
-
-#endif
diff --git a/src/pulse/ext-volume-api.c b/src/pulse/ext-volume-api.c
deleted file mode 100644 (file)
index ad514b5..0000000
+++ /dev/null
@@ -1,1817 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ext-volume-api.h"
-
-#include <modules/volume-api/volume-api-common.h>
-
-#include <pulse/direction.h>
-#include <pulse/extension.h>
-#include <pulse/internal.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/i18n.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/pstream-util.h>
-#include <pulsecore/strbuf.h>
-
-#include <math.h>
-
-struct userdata {
-    pa_extension *extension;
-    pa_context *context;
-    pa_ext_volume_api_state_t state;
-    bool state_notification_needed;
-    pa_ext_volume_api_state_cb_t state_callback;
-    void *state_callback_userdata;
-    pa_ext_volume_api_subscription_mask_t subscription_mask;
-    pa_ext_volume_api_subscribe_cb_t subscribe_callback;
-    void *subscribe_callback_userdata;
-};
-
-static struct userdata *get_userdata(pa_context *context, bool create);
-static void userdata_free(struct userdata *u);
-static void set_state(struct userdata *u, pa_ext_volume_api_state_t state, bool notify);
-
-int pa_ext_volume_api_balance_valid(double balance) {
-    return balance >= 0.0 && balance <= 1.0;
-}
-
-int pa_ext_volume_api_bvolume_valid(const pa_ext_volume_api_bvolume *volume, int check_volume, int check_balance) {
-    unsigned channel;
-
-    pa_assert(volume);
-
-    if (check_volume && !PA_VOLUME_IS_VALID(volume->volume))
-        return 0;
-
-    if (!check_balance)
-        return 1;
-
-    if (!pa_channel_map_valid(&volume->channel_map))
-        return 0;
-
-    for (channel = 0; channel < volume->channel_map.channels; channel++) {
-        if (!pa_ext_volume_api_balance_valid(volume->balance[channel]))
-            return 0;
-    }
-
-    return 1;
-}
-
-void pa_ext_volume_api_bvolume_init_invalid(pa_ext_volume_api_bvolume *volume) {
-    unsigned i;
-
-    pa_assert(volume);
-
-    volume->volume = PA_VOLUME_INVALID;
-
-    for (i = 0; i < PA_CHANNELS_MAX; i++)
-        volume->balance[i] = -1.0;
-
-    pa_channel_map_init(&volume->channel_map);
-}
-
-void pa_ext_volume_api_bvolume_init(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume, pa_channel_map *map) {
-    unsigned i;
-
-    pa_assert(bvolume);
-    pa_assert(PA_VOLUME_IS_VALID(volume));
-    pa_assert(map);
-    pa_assert(pa_channel_map_valid(map));
-
-    bvolume->volume = volume;
-    bvolume->channel_map = *map;
-
-    for (i = 0; i < map->channels; i++)
-        bvolume->balance[i] = 1.0;
-}
-
-void pa_ext_volume_api_bvolume_init_mono(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume) {
-    pa_assert(bvolume);
-    pa_assert(PA_VOLUME_IS_VALID(volume));
-
-    bvolume->volume = volume;
-    bvolume->balance[0] = 1.0;
-    pa_channel_map_init_mono(&bvolume->channel_map);
-}
-
-int pa_ext_volume_api_bvolume_parse_balance(const char *str, pa_ext_volume_api_bvolume *_r) {
-    pa_ext_volume_api_bvolume bvolume;
-
-    pa_assert(str);
-    pa_assert(_r);
-
-    bvolume.channel_map.channels = 0;
-
-    for (;;) {
-        const char *colon;
-        size_t channel_name_len;
-        char *channel_name;
-        pa_channel_position_t position;
-        const char *space;
-        size_t balance_str_len;
-        char *balance_str;
-        int r;
-        double balance;
-
-        colon = strchr(str, ':');
-        if (!colon)
-            return -PA_ERR_INVALID;
-
-        channel_name_len = colon - str;
-        channel_name = pa_xstrndup(str, channel_name_len);
-
-        position = pa_channel_position_from_string(channel_name);
-        pa_xfree(channel_name);
-        if (position == PA_CHANNEL_POSITION_INVALID)
-            return -PA_ERR_INVALID;
-
-        bvolume.channel_map.map[bvolume.channel_map.channels] = position;
-        str = colon + 1;
-
-        space = strchr(str, ' ');
-        if (space)
-            balance_str_len = space - str;
-        else
-            balance_str_len = strlen(str);
-
-        balance_str = pa_xstrndup(str, balance_str_len);
-
-        r = pa_atod(balance_str, &balance);
-        if (r < 0)
-            return -PA_ERR_INVALID;
-
-        if (!pa_ext_volume_api_balance_valid(balance))
-            return -PA_ERR_INVALID;
-
-        bvolume.balance[bvolume.channel_map.channels++] = balance;
-
-        if (space)
-            str = space + 1;
-        else
-            break;
-    }
-
-    pa_ext_volume_api_bvolume_copy_balance(_r, &bvolume);
-    return 0;
-}
-
-int pa_ext_volume_api_bvolume_equal(const pa_ext_volume_api_bvolume *a, const pa_ext_volume_api_bvolume *b,
-                                    int check_volume, int check_balance) {
-    unsigned i;
-
-    pa_assert(a);
-    pa_assert(b);
-
-    if (check_volume && a->volume != b->volume)
-        return 0;
-
-    if (!check_balance)
-        return 1;
-
-    if (!pa_channel_map_equal(&a->channel_map, &b->channel_map))
-        return 0;
-
-    for (i = 0; i < a->channel_map.channels; i++) {
-        if (fabs(a->balance[i] - b->balance[i]) > 0.00001)
-            return 0;
-    }
-
-    return 1;
-}
-
-void pa_ext_volume_api_bvolume_from_cvolume(pa_ext_volume_api_bvolume *bvolume, const pa_cvolume *cvolume,
-                                            const pa_channel_map *map) {
-    unsigned i;
-
-    pa_assert(bvolume);
-    pa_assert(cvolume);
-    pa_assert(map);
-    pa_assert(cvolume->channels == map->channels);
-
-    bvolume->volume = pa_cvolume_max(cvolume);
-    bvolume->channel_map = *map;
-
-    for (i = 0; i < map->channels; i++) {
-        if (bvolume->volume != PA_VOLUME_MUTED)
-            bvolume->balance[i] = ((double) cvolume->values[i]) / ((double) bvolume->volume);
-        else
-            bvolume->balance[i] = 1.0;
-    }
-}
-
-void pa_ext_volume_api_bvolume_to_cvolume(const pa_ext_volume_api_bvolume *bvolume, pa_cvolume *cvolume) {
-    unsigned i;
-
-    pa_assert(bvolume);
-    pa_assert(cvolume);
-    pa_assert(pa_ext_volume_api_bvolume_valid(bvolume, true, true));
-
-    cvolume->channels = bvolume->channel_map.channels;
-
-    for (i = 0; i < bvolume->channel_map.channels; i++)
-        cvolume->values[i] = bvolume->volume * bvolume->balance[i];
-}
-
-void pa_ext_volume_api_bvolume_copy_balance(pa_ext_volume_api_bvolume *to,
-                                            const pa_ext_volume_api_bvolume *from) {
-    pa_assert(to);
-    pa_assert(from);
-
-    memcpy(to->balance, from->balance, sizeof(from->balance));
-    to->channel_map = from->channel_map;
-}
-
-void pa_ext_volume_api_bvolume_reset_balance(pa_ext_volume_api_bvolume *volume, const pa_channel_map *map) {
-    unsigned i;
-
-    pa_assert(volume);
-    pa_assert(map);
-    pa_assert(pa_channel_map_valid(map));
-
-    for (i = 0; i < map->channels; i++)
-        volume->balance[i] = 1.0;
-
-    volume->channel_map = *map;
-}
-
-void pa_ext_volume_api_bvolume_remap(pa_ext_volume_api_bvolume *volume, const pa_channel_map *to) {
-    unsigned i;
-    pa_cvolume cvolume;
-
-    pa_assert(volume);
-    pa_assert(to);
-    pa_assert(pa_ext_volume_api_bvolume_valid(volume, false, true));
-    pa_assert(pa_channel_map_valid(to));
-
-    cvolume.channels = volume->channel_map.channels;
-
-    for (i = 0; i < cvolume.channels; i++)
-        cvolume.values[i] = volume->balance[i] * (double) PA_VOLUME_NORM;
-
-    pa_cvolume_remap(&cvolume, &volume->channel_map, to);
-
-    for (i = 0; i < to->channels; i++)
-        volume->balance[i] = (double) cvolume.values[i] / (double) PA_VOLUME_NORM;
-
-    volume->channel_map = *to;
-}
-
-double pa_ext_volume_api_bvolume_get_left_right_balance(const pa_ext_volume_api_bvolume *volume) {
-    pa_ext_volume_api_bvolume bvolume;
-    pa_cvolume cvolume;
-    double ret;
-
-    pa_assert(volume);
-
-    bvolume.volume = PA_VOLUME_NORM;
-    pa_ext_volume_api_bvolume_copy_balance(&bvolume, volume);
-    pa_ext_volume_api_bvolume_to_cvolume(&bvolume, &cvolume);
-    ret = pa_cvolume_get_balance(&cvolume, &volume->channel_map);
-
-    return ret;
-}
-
-void pa_ext_volume_api_bvolume_set_left_right_balance(pa_ext_volume_api_bvolume *volume, double balance) {
-    pa_cvolume cvolume;
-    pa_volume_t old_volume;
-
-    pa_assert(volume);
-
-    if (!pa_channel_map_can_balance(&volume->channel_map))
-        return;
-
-    pa_cvolume_reset(&cvolume, volume->channel_map.channels);
-    pa_cvolume_set_balance(&cvolume, &volume->channel_map, balance);
-    old_volume = volume->volume;
-    pa_ext_volume_api_bvolume_from_cvolume(volume, &cvolume, &volume->channel_map);
-    volume->volume = old_volume;
-}
-
-double pa_ext_volume_api_bvolume_get_rear_front_balance(const pa_ext_volume_api_bvolume *volume) {
-    pa_ext_volume_api_bvolume bvolume;
-    pa_cvolume cvolume;
-    double ret;
-
-    pa_assert(volume);
-
-    bvolume.volume = PA_VOLUME_NORM;
-    pa_ext_volume_api_bvolume_copy_balance(&bvolume, volume);
-    pa_ext_volume_api_bvolume_to_cvolume(&bvolume, &cvolume);
-    ret = pa_cvolume_get_fade(&cvolume, &volume->channel_map);
-
-    return ret;
-}
-
-void pa_ext_volume_api_bvolume_set_rear_front_balance(pa_ext_volume_api_bvolume *volume, double balance) {
-    pa_cvolume cvolume;
-    pa_volume_t old_volume;
-
-    pa_assert(volume);
-
-    if (!pa_channel_map_can_fade(&volume->channel_map))
-        return;
-
-    pa_cvolume_reset(&cvolume, volume->channel_map.channels);
-    pa_cvolume_set_fade(&cvolume, &volume->channel_map, balance);
-    old_volume = volume->volume;
-    pa_ext_volume_api_bvolume_from_cvolume(volume, &cvolume, &volume->channel_map);
-    volume->volume = old_volume;
-}
-
-int pa_ext_volume_api_bvolume_balance_to_string(const pa_ext_volume_api_bvolume *volume, char **_r) {
-    pa_strbuf *buf;
-    unsigned i;
-
-    pa_assert(volume);
-    pa_assert(_r);
-
-    if (!pa_ext_volume_api_bvolume_valid(volume, false, true))
-        return -PA_ERR_INVALID;
-
-    buf = pa_strbuf_new();
-
-    for (i = 0; i < volume->channel_map.channels; i++) {
-        if (i != 0)
-            pa_strbuf_putc(buf, ' ');
-
-        pa_strbuf_printf(buf, "%s:%.2f", pa_channel_position_to_string(volume->channel_map.map[i]), volume->balance[i]);
-    }
-
-    *_r = pa_strbuf_tostring_free(buf);
-    return 0;
-}
-
-char *pa_ext_volume_api_bvolume_snprint_balance(char *buf, size_t buf_len,
-                                                const pa_ext_volume_api_bvolume *volume) {
-    char *e;
-    unsigned channel;
-    bool first = true;
-
-    pa_assert(buf);
-    pa_assert(buf_len > 0);
-    pa_assert(volume);
-
-    pa_init_i18n();
-
-    if (!pa_ext_volume_api_bvolume_valid(volume, true, true)) {
-        pa_snprintf(buf, buf_len, _("(invalid)"));
-        return buf;
-    }
-
-    *(e = buf) = 0;
-
-    for (channel = 0; channel < volume->channel_map.channels && buf_len > 1; channel++) {
-        buf_len -= pa_snprintf(e, buf_len, "%s%s: %u%%",
-                               first ? "" : ", ",
-                               pa_channel_position_to_string(volume->channel_map.map[channel]),
-                               (unsigned) (volume->balance[channel] * 100 + 0.5));
-
-        e = strchr(e, 0);
-        first = false;
-    }
-
-    return buf;
-}
-
-static void extension_context_state_changed_cb(pa_extension *extension, unsigned phase) {
-    struct userdata *u;
-    pa_context_state_t context_state;
-    pa_ext_volume_api_state_t api_state;
-
-    pa_assert(extension);
-    pa_assert(phase == 1 || phase == 2);
-
-    u = get_userdata(extension->context, false);
-    pa_assert(u);
-
-    api_state = u->state;
-
-    if (phase == 2) {
-        if (u->state_notification_needed && u->state_callback)
-            u->state_callback(u->context, u->state_callback_userdata);
-
-        u->state_notification_needed = false;
-        return;
-    }
-
-    context_state = pa_context_get_state(u->context);
-
-    switch (context_state) {
-        case PA_CONTEXT_UNCONNECTED:
-        case PA_CONTEXT_CONNECTING:
-        case PA_CONTEXT_AUTHORIZING:
-        case PA_CONTEXT_SETTING_NAME:
-        case PA_CONTEXT_READY:
-            /* The volume api connection can only be initiated after the
-             * context state becomes READY. */
-            pa_assert(u->state == PA_EXT_VOLUME_API_STATE_UNCONNECTED);
-            return;
-
-        case PA_CONTEXT_FAILED:
-            api_state = PA_EXT_VOLUME_API_STATE_FAILED;
-            break;
-
-        case PA_CONTEXT_TERMINATED:
-            api_state = PA_EXT_VOLUME_API_STATE_TERMINATED;
-            break;
-    }
-
-    if (api_state != u->state) {
-        set_state(u, api_state, false);
-        u->state_notification_needed = true;
-    }
-}
-
-static void extension_kill_cb(pa_extension *extension) {
-    pa_assert(extension);
-
-    userdata_free(extension->userdata);
-}
-
-static void command_disconnect(struct userdata *u, pa_tagstruct *tagstruct) {
-    pa_assert(u);
-    pa_assert(tagstruct);
-
-    if (!pa_tagstruct_eof(tagstruct)) {
-        pa_log("Failed to parse the parameters of a DISCONNECT command.");
-        pa_context_fail(u->context, PA_ERR_PROTOCOL);
-        return;
-    }
-
-    if (u->state == PA_EXT_VOLUME_API_STATE_UNCONNECTED
-            || u->state == PA_EXT_VOLUME_API_STATE_TERMINATED)
-        return;
-
-    /* We set the error to NOEXTENSION, because the assumption is that we only
-     * receive a DISCONNECT command when the extension module is unloaded. */
-    pa_context_set_error(u->context, PA_ERR_NOEXTENSION);
-    set_state(u, PA_EXT_VOLUME_API_STATE_FAILED, true);
-}
-
-static void command_subscribe_event(struct userdata *u, pa_tagstruct *tagstruct) {
-    pa_ext_volume_api_subscription_event_type_t event_type;
-    pa_ext_volume_api_subscription_event_type_t facility;
-    uint32_t idx;
-
-    pa_assert(u);
-    pa_assert(tagstruct);
-
-    if (pa_tagstruct_getu32(tagstruct, &event_type) < 0
-            || pa_tagstruct_getu32(tagstruct, &idx) < 0
-            || !pa_tagstruct_eof(tagstruct)) {
-        pa_log("Failed to parse the parameters of a SUBSCRIBE_EVENT command.");
-        pa_context_fail(u->context, PA_ERR_PROTOCOL);
-        return;
-    }
-
-    facility = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
-
-    if (u->subscription_mask & (1 << facility)) {
-        if (u->subscribe_callback)
-            u->subscribe_callback(u->context, event_type, idx, u->subscribe_callback_userdata);
-    }
-}
-
-static void extension_process_command_cb(pa_extension *extension, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct) {
-    struct userdata *u;
-
-    pa_assert(extension);
-    pa_assert(tagstruct);
-
-    u = extension->userdata;
-
-    if (u->state != PA_EXT_VOLUME_API_STATE_READY) {
-        pa_pstream_send_error(extension->context->pstream, tag, PA_ERR_BADSTATE);
-        return;
-    }
-
-    switch (command) {
-        case PA_VOLUME_API_COMMAND_DISCONNECT:
-            command_disconnect(u, tagstruct);
-            break;
-
-        case PA_VOLUME_API_COMMAND_SUBSCRIBE_EVENT:
-            command_subscribe_event(u, tagstruct);
-            break;
-
-        default:
-            pa_log("Received unrecognized command for the volume API extension: %u", command);
-            pa_context_fail(u->context, PA_ERR_PROTOCOL);
-            break;
-    }
-}
-
-static struct userdata *userdata_new(pa_context *context) {
-    struct userdata *u = NULL;
-
-    pa_assert(context);
-
-    u = pa_xnew0(struct userdata, 1);
-    u->extension = pa_extension_new(context, PA_VOLUME_API_EXTENSION_NAME);
-    u->extension->context_state_changed = extension_context_state_changed_cb;
-    u->extension->kill = extension_kill_cb;
-    u->extension->process_command = extension_process_command_cb;
-    u->extension->userdata = u;
-    u->context = context;
-    u->state = PA_EXT_VOLUME_API_STATE_UNCONNECTED;
-
-    pa_extension_put(u->extension);
-
-    return u;
-}
-
-static void userdata_free(struct userdata *u) {
-    pa_assert(u);
-
-    if (u->extension)
-        pa_extension_free(u->extension);
-
-    pa_xfree(u);
-}
-
-static struct userdata *get_userdata(pa_context *context, bool create) {
-    pa_extension *extension;
-
-    pa_assert(context);
-
-    extension = pa_context_get_extension(context, PA_VOLUME_API_EXTENSION_NAME);
-
-    if (extension) {
-        pa_assert(extension->userdata);
-        return extension->userdata;
-    }
-
-    if (!create)
-        return NULL;
-
-    return userdata_new(context);
-}
-
-static void set_state(struct userdata *u, pa_ext_volume_api_state_t state, bool notify) {
-    pa_assert(u);
-
-    if (state == u->state)
-        return;
-
-    u->state = state;
-
-    if (notify && u->state_callback)
-        u->state_callback(u->context, u->state_callback_userdata);
-}
-
-static void connect_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct, void *userdata) {
-    struct userdata *u = userdata;
-    uint32_t version;
-
-    pa_assert(u);
-
-    if (command != PA_COMMAND_REPLY) {
-        pa_context_handle_error(u->context, command, tagstruct, false);
-        set_state(u, PA_EXT_VOLUME_API_STATE_FAILED, true);
-        return;
-    }
-
-    pa_assert(tagstruct);
-    pa_assert(u->state == PA_EXT_VOLUME_API_STATE_CONNECTING);
-
-    if (pa_tagstruct_getu32(tagstruct, &version) < 0
-            || version < 1)
-        goto fail_parse;
-
-    set_state(u, PA_EXT_VOLUME_API_STATE_READY, true);
-
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a CONNECT command.");
-    pa_context_fail(u->context, PA_ERR_PROTOCOL);
-}
-
-int pa_ext_volume_api_connect(pa_context *context) {
-    struct userdata *u;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-
-    PA_CHECK_VALIDITY_RETURN_ANY(context, context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, -1);
-    PA_CHECK_VALIDITY_RETURN_ANY(context, context->version >= 14, PA_ERR_NOTSUPPORTED, -1);
-
-    u = get_userdata(context, true);
-
-    PA_CHECK_VALIDITY_RETURN_ANY(context, u->state == PA_EXT_VOLUME_API_STATE_UNCONNECTED
-                                          || u->state == PA_EXT_VOLUME_API_STATE_TERMINATED, PA_ERR_BADSTATE, -1);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_CONNECT);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_VERSION);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, connect_cb, u, NULL);
-
-    set_state(u, PA_EXT_VOLUME_API_STATE_CONNECTING, true);
-
-    return 0;
-}
-
-void pa_ext_volume_api_disconnect(pa_context *context) {
-    struct userdata *u;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-
-    u = get_userdata(context, false);
-    if (!u)
-        return;
-
-    if (u->state == PA_EXT_VOLUME_API_STATE_UNCONNECTED
-            || u->state == PA_EXT_VOLUME_API_STATE_FAILED
-            || u->state == PA_EXT_VOLUME_API_STATE_TERMINATED)
-        return;
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_DISCONNECT);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-
-    set_state(u, PA_EXT_VOLUME_API_STATE_TERMINATED, true);
-}
-
-void pa_ext_volume_api_set_state_callback(pa_context *context, pa_ext_volume_api_state_cb_t cb, void *userdata) {
-    struct userdata *u;
-
-    pa_assert(context);
-
-    u = get_userdata(context, true);
-    u->state_callback = cb;
-    u->state_callback_userdata = userdata;
-}
-
-pa_ext_volume_api_state_t pa_ext_volume_api_get_state(pa_context *context) {
-    struct userdata *u;
-
-    pa_assert(context);
-
-    u = get_userdata(context, false);
-    if (!u)
-        return PA_EXT_VOLUME_API_STATE_UNCONNECTED;
-
-    return u->state;
-}
-
-pa_operation *pa_ext_volume_api_subscribe(pa_context *context, pa_ext_volume_api_subscription_mask_t mask,
-                                          pa_context_success_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SUBSCRIBE);
-    pa_tagstruct_putu32(tagstruct, mask);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    u->subscription_mask = mask;
-
-    return operation;
-}
-
-void pa_ext_volume_api_set_subscribe_callback(pa_context *context, pa_ext_volume_api_subscribe_cb_t cb,
-                                              void *userdata) {
-    struct userdata *u;
-
-    pa_assert(context);
-
-    u = get_userdata(context, true);
-    u->subscribe_callback = cb;
-    u->subscribe_callback_userdata = userdata;
-}
-
-static void get_server_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                               void *userdata) {
-    pa_operation *operation = userdata;
-    pa_ext_volume_api_server_info info, *p = &info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        p = NULL;
-    } else {
-        pa_assert(tagstruct);
-
-        if (pa_tagstruct_getu32(tagstruct, &info.main_output_volume_control) < 0
-                || pa_tagstruct_getu32(tagstruct, &info.main_input_volume_control) < 0
-                || pa_tagstruct_getu32(tagstruct, &info.main_output_mute_control) < 0
-                || pa_tagstruct_getu32(tagstruct, &info.main_input_mute_control) < 0
-                || !pa_tagstruct_eof(tagstruct))
-            goto fail_parse;
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_server_info_cb_t cb = (pa_ext_volume_api_server_info_cb_t) operation->callback;
-        cb(operation->context, p, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_SERVER_INFO command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_server_info(pa_context *context, pa_ext_volume_api_server_info_cb_t cb,
-                                                void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_SERVER_INFO);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_server_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-static void volume_control_info_free(pa_ext_volume_api_volume_control_info *info) {
-    pa_assert(info);
-
-    if (info->proplist)
-        pa_proplist_free(info->proplist);
-
-    /* Description and name don't need to be freed, because they should point
-     * to memory owned by pa_tagstruct, so they'll be freed when the tagstruct
-     * is freed. */
-}
-
-static void get_volume_control_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                                       void *userdata) {
-    pa_operation *operation = userdata;
-    int eol = 1;
-    pa_ext_volume_api_volume_control_info info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        eol = -1;
-    } else {
-        pa_assert(tagstruct);
-
-        while (!pa_tagstruct_eof(tagstruct)) {
-            unsigned channel;
-            bool convertible_to_dB;
-
-            pa_zero(info);
-            info.proplist = pa_proplist_new();
-
-            if (pa_tagstruct_getu32(tagstruct, &info.index) < 0
-                    || info.index == PA_INVALID_INDEX
-                    || pa_tagstruct_gets(tagstruct, &info.name) < 0
-                    || !info.name || !*info.name
-                    || pa_tagstruct_gets(tagstruct, &info.description) < 0
-                    || !info.description
-                    || pa_tagstruct_get_proplist(tagstruct, info.proplist) < 0
-                    || pa_tagstruct_get_volume(tagstruct, &info.volume.volume) < 0
-                    || !PA_VOLUME_IS_VALID(info.volume.volume)
-                    || pa_tagstruct_get_channel_map(tagstruct, &info.volume.channel_map) < 0
-                    || !pa_channel_map_valid(&info.volume.channel_map))
-                goto fail_parse;
-
-            for (channel = 0; channel < info.volume.channel_map.channels; channel++) {
-                uint64_t balance;
-
-                if (pa_tagstruct_getu64(tagstruct, &balance) < 0)
-                    goto fail_parse;
-
-                memcpy(&info.volume.balance[channel], &balance, sizeof(double));
-
-                if (!pa_ext_volume_api_balance_valid(info.volume.balance[channel]))
-                    goto fail_parse;
-            }
-
-            if (pa_tagstruct_get_boolean(tagstruct, &convertible_to_dB) < 0)
-                goto fail_parse;
-
-            info.convertible_to_dB = convertible_to_dB;
-
-            if (operation->callback) {
-                pa_ext_volume_api_volume_control_info_cb_t cb =
-                        (pa_ext_volume_api_volume_control_info_cb_t) operation->callback;
-                cb(operation->context, &info, 0, operation->userdata);
-            }
-
-            volume_control_info_free(&info);
-        }
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_volume_control_info_cb_t cb =
-                (pa_ext_volume_api_volume_control_info_cb_t) operation->callback;
-        cb(operation->context, NULL, eol, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_VOLUME_CONTROL_INFO(_LIST) command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    volume_control_info_free(&info);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_volume_control_info_by_index(pa_context *context, uint32_t idx,
-                                                                 pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                                 void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_volume_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_volume_control_info_by_name(pa_context *context, const char *name,
-                                                                pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                                void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_volume_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_volume_control_info_list(pa_context *context,
-                                                             pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                             void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_VOLUME_CONTROL_INFO_LIST);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_volume_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_set_volume_control_volume_by_index(pa_context *context, uint32_t idx,
-                                                                   pa_ext_volume_api_bvolume *volume,
-                                                                   int set_volume, int set_balance,
-                                                                   pa_context_success_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_volume_t v;
-    pa_channel_map channel_map;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-    unsigned i;
-
-    pa_assert(context);
-    pa_assert(volume);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, set_volume || set_balance, PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, pa_ext_volume_api_bvolume_valid(volume, set_volume, set_balance),
-                                  PA_ERR_INVALID);
-
-    v = volume->volume;
-
-    if (!set_volume)
-        v = PA_VOLUME_INVALID;
-
-    channel_map = volume->channel_map;
-
-    if (!set_balance)
-        pa_channel_map_init(&channel_map);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SET_VOLUME_CONTROL_VOLUME);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_tagstruct_put_volume(tagstruct, v);
-    pa_tagstruct_put_channel_map(tagstruct, &channel_map);
-
-    for (i = 0; i < channel_map.channels; i++) {
-        uint64_t balance;
-
-        memcpy(&balance, &volume->balance[i], sizeof(uint64_t));
-        pa_tagstruct_putu64(tagstruct, balance);
-    }
-
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_set_volume_control_volume_by_name(pa_context *context, const char *name,
-                                                                  pa_ext_volume_api_bvolume *volume,
-                                                                  int set_volume, int set_balance,
-                                                                  pa_context_success_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_volume_t v;
-    pa_channel_map channel_map;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-    unsigned i;
-
-    pa_assert(context);
-    pa_assert(volume);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, set_volume || set_balance, PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, pa_ext_volume_api_bvolume_valid(volume, set_volume, set_balance),
-                                  PA_ERR_INVALID);
-
-    v = volume->volume;
-
-    if (!set_volume)
-        v = PA_VOLUME_INVALID;
-
-    channel_map = volume->channel_map;
-
-    if (!set_balance)
-        pa_channel_map_init(&channel_map);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SET_VOLUME_CONTROL_VOLUME);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_tagstruct_put_volume(tagstruct, v);
-    pa_tagstruct_put_channel_map(tagstruct, &channel_map);
-
-    for (i = 0; i < channel_map.channels; i++) {
-        uint64_t balance;
-
-        memcpy(&balance, &volume->balance[i], sizeof(uint64_t));
-        pa_tagstruct_putu64(tagstruct, balance);
-    }
-
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-static void mute_control_info_free(pa_ext_volume_api_mute_control_info *info) {
-    pa_assert(info);
-
-    if (info->proplist)
-        pa_proplist_free(info->proplist);
-
-    /* Description and name don't need to be freed, because they should point
-     * to memory owned by pa_tagstruct, so they'll be freed when the tagstruct
-     * is freed. */
-}
-
-static void get_mute_control_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                                     void *userdata) {
-    pa_operation *operation = userdata;
-    int eol = 1;
-    pa_ext_volume_api_mute_control_info info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        eol = -1;
-    } else {
-        pa_assert(tagstruct);
-
-        while (!pa_tagstruct_eof(tagstruct)) {
-            bool mute;
-
-            pa_zero(info);
-            info.proplist = pa_proplist_new();
-
-            if (pa_tagstruct_getu32(tagstruct, &info.index) < 0
-                    || info.index == PA_INVALID_INDEX
-                    || pa_tagstruct_gets(tagstruct, &info.name) < 0
-                    || !info.name || !*info.name
-                    || pa_tagstruct_gets(tagstruct, &info.description) < 0
-                    || !info.description
-                    || pa_tagstruct_get_proplist(tagstruct, info.proplist) < 0
-                    || pa_tagstruct_get_boolean(tagstruct, &mute) < 0)
-                goto fail_parse;
-
-            info.mute = mute;
-
-            if (operation->callback) {
-                pa_ext_volume_api_mute_control_info_cb_t cb =
-                        (pa_ext_volume_api_mute_control_info_cb_t) operation->callback;
-                cb(operation->context, &info, 0, operation->userdata);
-            }
-
-            mute_control_info_free(&info);
-        }
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_mute_control_info_cb_t cb =
-                (pa_ext_volume_api_mute_control_info_cb_t) operation->callback;
-        cb(operation->context, NULL, eol, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_MUTE_CONTROL_INFO(_LIST) command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    mute_control_info_free(&info);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_mute_control_info_by_index(pa_context *context, uint32_t idx,
-                                                               pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                               void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_mute_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_mute_control_info_by_name(pa_context *context, const char *name,
-                                                              pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                              void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_mute_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_mute_control_info_list(pa_context *context,
-                                                           pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                           void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_MUTE_CONTROL_INFO_LIST);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_mute_control_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_set_mute_control_mute_by_index(pa_context *context, uint32_t idx, int mute,
-                                                               pa_context_success_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SET_MUTE_CONTROL_MUTE);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_tagstruct_put_boolean(tagstruct, mute);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_set_mute_control_mute_by_name(pa_context *context, const char *name, int mute,
-                                                              pa_context_success_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_SET_MUTE_CONTROL_MUTE);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_tagstruct_put_boolean(tagstruct, mute);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-static void device_info_free(pa_ext_volume_api_device_info *info) {
-    pa_assert(info);
-
-    if (info->proplist)
-        pa_proplist_free(info->proplist);
-
-    /* The strings in device_types point to memory owned by pa_tagstruct, so we
-     * only need to free the device_types array. */
-    pa_xfree(info->device_types);
-
-    /* Description and name don't need to be freed, because they should point
-     * to memory owned by pa_tagstruct, so they'll be freed when the tagstruct
-     * is freed. */
-}
-
-static void get_device_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                               void *userdata) {
-    pa_operation *operation = userdata;
-    int eol = 1;
-    pa_ext_volume_api_device_info info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        eol = -1;
-    } else {
-        pa_assert(tagstruct);
-
-        while (!pa_tagstruct_eof(tagstruct)) {
-            uint8_t direction;
-            unsigned i;
-
-            pa_zero(info);
-            info.proplist = pa_proplist_new();
-
-            if (pa_tagstruct_getu32(tagstruct, &info.index) < 0
-                    || info.index == PA_INVALID_INDEX
-                    || pa_tagstruct_gets(tagstruct, &info.name) < 0
-                    || !info.name || !*info.name
-                    || pa_tagstruct_gets(tagstruct, &info.description) < 0
-                    || !info.description
-                    || pa_tagstruct_getu8(tagstruct, &direction) < 0
-                    || !pa_direction_valid(direction)
-                    || pa_tagstruct_getu32(tagstruct, &info.n_device_types) < 0
-                    || info.n_device_types > 1000)
-                goto fail_parse;
-
-            info.direction = direction;
-
-            if (info.n_device_types > 0)
-                info.device_types = pa_xnew0(const char *, info.n_device_types);
-
-            for (i = 0; i < info.n_device_types; i++) {
-                if (pa_tagstruct_gets(tagstruct, &info.device_types[i]) < 0
-                        || !info.device_types[i] || !*info.device_types[i])
-                    goto fail_parse;
-            }
-
-            if (pa_tagstruct_get_proplist(tagstruct, info.proplist) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.volume_control) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.mute_control) < 0)
-                goto fail_parse;
-
-            if (operation->callback) {
-                pa_ext_volume_api_device_info_cb_t cb = (pa_ext_volume_api_device_info_cb_t) operation->callback;
-                cb(operation->context, &info, 0, operation->userdata);
-            }
-
-            device_info_free(&info);
-        }
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_device_info_cb_t cb = (pa_ext_volume_api_device_info_cb_t) operation->callback;
-        cb(operation->context, NULL, eol, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_DEVICE_INFO(_LIST) command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    device_info_free(&info);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_device_info_by_index(pa_context *context, uint32_t idx,
-                                                         pa_ext_volume_api_device_info_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_DEVICE_INFO);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_device_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_device_info_by_name(pa_context *context, const char *name,
-                                                        pa_ext_volume_api_device_info_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_DEVICE_INFO);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_device_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_device_info_list(pa_context *context, pa_ext_volume_api_device_info_cb_t cb,
-                                                     void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_DEVICE_INFO_LIST);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_device_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-static void stream_info_free(pa_ext_volume_api_stream_info *info) {
-    pa_assert(info);
-
-    if (info->proplist)
-        pa_proplist_free(info->proplist);
-
-    /* Description and name don't need to be freed, because they should point
-     * to memory owned by pa_tagstruct, so they'll be freed when the tagstruct
-     * is freed. */
-}
-
-static void get_stream_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                               void *userdata) {
-    pa_operation *operation = userdata;
-    int eol = 1;
-    pa_ext_volume_api_stream_info info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        eol = -1;
-    } else {
-        pa_assert(tagstruct);
-
-        while (!pa_tagstruct_eof(tagstruct)) {
-            uint8_t direction;
-
-            pa_zero(info);
-            info.proplist = pa_proplist_new();
-
-            if (pa_tagstruct_getu32(tagstruct, &info.index) < 0
-                    || info.index == PA_INVALID_INDEX
-                    || pa_tagstruct_gets(tagstruct, &info.name) < 0
-                    || !info.name || !*info.name
-                    || pa_tagstruct_gets(tagstruct, &info.description) < 0
-                    || !info.description
-                    || pa_tagstruct_getu8(tagstruct, &direction) < 0
-                    || !pa_direction_valid(direction)
-                    || pa_tagstruct_get_proplist(tagstruct, info.proplist) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.volume_control) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.mute_control) < 0)
-                goto fail_parse;
-
-            info.direction = direction;
-
-            if (operation->callback) {
-                pa_ext_volume_api_stream_info_cb_t cb = (pa_ext_volume_api_stream_info_cb_t) operation->callback;
-                cb(operation->context, &info, 0, operation->userdata);
-            }
-
-            stream_info_free(&info);
-        }
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_stream_info_cb_t cb = (pa_ext_volume_api_stream_info_cb_t) operation->callback;
-        cb(operation->context, NULL, eol, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_STREAM_INFO(_LIST) command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    stream_info_free(&info);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_stream_info_by_index(pa_context *context, uint32_t idx,
-                                                         pa_ext_volume_api_stream_info_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_STREAM_INFO);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_stream_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_stream_info_by_name(pa_context *context, const char *name,
-                                                        pa_ext_volume_api_stream_info_cb_t cb, void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_STREAM_INFO);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_stream_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_stream_info_list(pa_context *context, pa_ext_volume_api_stream_info_cb_t cb,
-                                                     void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_STREAM_INFO_LIST);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_stream_info_cb, pa_operation_ref(operation),
-                                (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-static void audio_group_info_free(pa_ext_volume_api_audio_group_info *info) {
-    pa_assert(info);
-
-    if (info->proplist)
-        pa_proplist_free(info->proplist);
-
-    /* Description and name don't need to be freed, because they should point
-     * to memory owned by pa_tagstruct, so they'll be freed when the tagstruct
-     * is freed. */
-}
-
-static void get_audio_group_info_cb(pa_pdispatch *pdispatch, uint32_t command, uint32_t tag, pa_tagstruct *tagstruct,
-                                    void *userdata) {
-    pa_operation *operation = userdata;
-    int eol = 1;
-    pa_ext_volume_api_audio_group_info info;
-
-    pa_assert(pdispatch);
-    pa_assert(operation);
-
-    if (!operation->context)
-        goto finish;
-
-    if (command != PA_COMMAND_REPLY) {
-        if (pa_context_handle_error(operation->context, command, tagstruct, false) < 0)
-            goto finish;
-
-        eol = -1;
-    } else {
-        pa_assert(tagstruct);
-
-        while (!pa_tagstruct_eof(tagstruct)) {
-            pa_zero(info);
-            info.proplist = pa_proplist_new();
-
-            if (pa_tagstruct_getu32(tagstruct, &info.index) < 0
-                    || info.index == PA_INVALID_INDEX
-                    || pa_tagstruct_gets(tagstruct, &info.name) < 0
-                    || !info.name || !*info.name
-                    || pa_tagstruct_gets(tagstruct, &info.description) < 0
-                    || !info.description
-                    || pa_tagstruct_get_proplist(tagstruct, info.proplist) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.volume_control) < 0
-                    || pa_tagstruct_getu32(tagstruct, &info.mute_control) < 0)
-                goto fail_parse;
-
-            if (operation->callback) {
-                pa_ext_volume_api_audio_group_info_cb_t cb =
-                        (pa_ext_volume_api_audio_group_info_cb_t) operation->callback;
-                cb(operation->context, &info, 0, operation->userdata);
-            }
-
-            audio_group_info_free(&info);
-        }
-    }
-
-    if (operation->callback) {
-        pa_ext_volume_api_audio_group_info_cb_t cb = (pa_ext_volume_api_audio_group_info_cb_t) operation->callback;
-        cb(operation->context, NULL, eol, operation->userdata);
-    }
-
-finish:
-    pa_operation_done(operation);
-    pa_operation_unref(operation);
-    return;
-
-fail_parse:
-    pa_log("Failed to parse the reply parameters of a GET_AUDIO_GROUP_INFO(_LIST) command.");
-    pa_context_fail(operation->context, PA_ERR_PROTOCOL);
-    audio_group_info_free(&info);
-    goto finish;
-}
-
-pa_operation *pa_ext_volume_api_get_audio_group_info_by_index(pa_context *context, uint32_t idx,
-                                                              pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                              void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO);
-    pa_tagstruct_putu32(tagstruct, idx);
-    pa_tagstruct_puts(tagstruct, NULL);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_audio_group_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_audio_group_info_by_name(pa_context *context, const char *name,
-                                                             pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                             void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, name && *name, PA_ERR_INVALID);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, name);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_audio_group_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
-
-pa_operation *pa_ext_volume_api_get_audio_group_info_list(pa_context *context,
-                                                          pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                          void *userdata) {
-    struct userdata *u;
-    pa_operation *operation;
-    pa_tagstruct *tagstruct;
-    uint32_t tag;
-
-    pa_assert(context);
-    pa_assert(cb);
-
-    u = get_userdata(context, false);
-    PA_CHECK_VALIDITY_RETURN_NULL(context, u && u->state == PA_EXT_VOLUME_API_STATE_READY, PA_ERR_BADSTATE);
-
-    operation = pa_operation_new(context, NULL, (pa_operation_cb_t) cb, userdata);
-
-    tagstruct = pa_tagstruct_command(context, PA_COMMAND_EXTENSION, &tag);
-    pa_tagstruct_putu32(tagstruct, PA_INVALID_INDEX);
-    pa_tagstruct_puts(tagstruct, PA_VOLUME_API_EXTENSION_NAME);
-    pa_tagstruct_putu32(tagstruct, PA_VOLUME_API_COMMAND_GET_AUDIO_GROUP_INFO_LIST);
-    pa_pstream_send_tagstruct(context->pstream, tagstruct);
-    pa_pdispatch_register_reply(context->pdispatch, tag, DEFAULT_TIMEOUT, get_audio_group_info_cb,
-                                pa_operation_ref(operation), (pa_free_cb_t) pa_operation_unref);
-
-    return operation;
-}
diff --git a/src/pulse/ext-volume-api.h b/src/pulse/ext-volume-api.h
deleted file mode 100644 (file)
index 6402f4b..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-#ifndef fooextvolumeapihfoo
-#define fooextvolumeapihfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2014 Intel Corporation
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulse/cdecl.h>
-#include <pulse/context.h>
-#include <pulse/volume.h>
-
-/* This API is temporary, and has no stability guarantees whatsoever. Think
- * twice before making anything that relies on this API. This is undocumented
- * for a reason. */
-
-PA_C_DECL_BEGIN
-
-typedef struct pa_ext_volume_api_bvolume pa_ext_volume_api_bvolume;
-typedef struct pa_ext_volume_api_server_info pa_ext_volume_api_server_info;
-typedef struct pa_ext_volume_api_volume_control_info pa_ext_volume_api_volume_control_info;
-typedef struct pa_ext_volume_api_mute_control_info pa_ext_volume_api_mute_control_info;
-typedef struct pa_ext_volume_api_device_info pa_ext_volume_api_device_info;
-typedef struct pa_ext_volume_api_stream_info pa_ext_volume_api_stream_info;
-typedef struct pa_ext_volume_api_audio_group_info pa_ext_volume_api_audio_group_info;
-
-struct pa_ext_volume_api_bvolume {
-    pa_volume_t volume;
-    double balance[PA_CHANNELS_MAX];
-    pa_channel_map channel_map;
-};
-
-int pa_ext_volume_api_balance_valid(double balance) PA_GCC_CONST;
-int pa_ext_volume_api_bvolume_valid(const pa_ext_volume_api_bvolume *volume, int check_volume, int check_balance)
-        PA_GCC_PURE;
-void pa_ext_volume_api_bvolume_init_invalid(pa_ext_volume_api_bvolume *volume);
-void pa_ext_volume_api_bvolume_init(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume, pa_channel_map *map);
-void pa_ext_volume_api_bvolume_init_mono(pa_ext_volume_api_bvolume *bvolume, pa_volume_t volume);
-int pa_ext_volume_api_bvolume_parse_balance(const char *str, pa_ext_volume_api_bvolume *bvolume);
-int pa_ext_volume_api_bvolume_equal(const pa_ext_volume_api_bvolume *a, const pa_ext_volume_api_bvolume *b,
-                                    int check_volume, int check_balance) PA_GCC_PURE;
-void pa_ext_volume_api_bvolume_from_cvolume(pa_ext_volume_api_bvolume *bvolume, const pa_cvolume *cvolume,
-                                            const pa_channel_map *map);
-void pa_ext_volume_api_bvolume_to_cvolume(const pa_ext_volume_api_bvolume *bvolume, pa_cvolume *cvolume);
-void pa_ext_volume_api_bvolume_copy_balance(pa_ext_volume_api_bvolume *to,
-                                            const pa_ext_volume_api_bvolume *from);
-void pa_ext_volume_api_bvolume_reset_balance(pa_ext_volume_api_bvolume *volume, const pa_channel_map *map);
-void pa_ext_volume_api_bvolume_remap(pa_ext_volume_api_bvolume *volume, const pa_channel_map *to);
-double pa_ext_volume_api_bvolume_get_left_right_balance(const pa_ext_volume_api_bvolume *volume) PA_GCC_PURE;
-void pa_ext_volume_api_bvolume_set_left_right_balance(pa_ext_volume_api_bvolume *volume, double balance);
-double pa_ext_volume_api_bvolume_get_rear_front_balance(const pa_ext_volume_api_bvolume *volume) PA_GCC_PURE;
-void pa_ext_volume_api_bvolume_set_rear_front_balance(pa_ext_volume_api_bvolume *volume, double balance);
-int pa_ext_volume_api_bvolume_balance_to_string(const pa_ext_volume_api_bvolume *volume, char **_r);
-
-#define PA_EXT_VOLUME_API_BVOLUME_SNPRINT_BALANCE_MAX 500
-char *pa_ext_volume_api_bvolume_snprint_balance(char *buf, size_t buf_size,
-                                                const pa_ext_volume_api_bvolume *volume);
-
-typedef enum pa_ext_volume_api_state {
-    PA_EXT_VOLUME_API_STATE_UNCONNECTED,
-    PA_EXT_VOLUME_API_STATE_CONNECTING,
-    PA_EXT_VOLUME_API_STATE_READY,
-    PA_EXT_VOLUME_API_STATE_FAILED,
-    PA_EXT_VOLUME_API_STATE_TERMINATED
-} pa_ext_volume_api_state_t;
-
-int pa_ext_volume_api_connect(pa_context *context);
-void pa_ext_volume_api_disconnect(pa_context *context);
-
-typedef void (*pa_ext_volume_api_state_cb_t)(pa_context *context, void *userdata);
-void pa_ext_volume_api_set_state_callback(pa_context *context, pa_ext_volume_api_state_cb_t cb, void *userdata);
-pa_ext_volume_api_state_t pa_ext_volume_api_get_state(pa_context *context);
-
-typedef enum pa_ext_volume_api_subscription_mask {
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_NULL = 0x0U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_SERVER = 0x1U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_VOLUME_CONTROL = 0x2U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_MUTE_CONTROL = 0x4U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_DEVICE = 0x8U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_STREAM = 0x10U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_AUDIO_GROUP = 0x20U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_MASK_ALL = 0x3FU,
-} pa_ext_volume_api_subscription_mask_t;
-
-pa_operation *pa_ext_volume_api_subscribe(pa_context *context, pa_ext_volume_api_subscription_mask_t mask,
-                                          pa_context_success_cb_t cb, void *userdata);
-
-typedef enum pa_ext_volume_api_subscription_event_type {
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_SERVER = 0x0U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_VOLUME_CONTROL = 0x1U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_MUTE_CONTROL = 0x2U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_DEVICE = 0x3U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_STREAM = 0x4U,
-    PA_EXT_VOLUME_API_SUBSCRIPTION_EVENT_AUDIO_GROUP = 0x5U,
-} pa_ext_volume_api_subscription_event_type_t;
-
-typedef void (*pa_ext_volume_api_subscribe_cb_t)(pa_context *context,
-                                                 pa_ext_volume_api_subscription_event_type_t event_type,
-                                                 uint32_t idx, void *userdata);
-void pa_ext_volume_api_set_subscribe_callback(pa_context *context, pa_ext_volume_api_subscribe_cb_t cb,
-                                              void *userdata);
-
-struct pa_ext_volume_api_server_info {
-    uint32_t main_output_volume_control;
-    uint32_t main_input_volume_control;
-    uint32_t main_output_mute_control;
-    uint32_t main_input_mute_control;
-};
-
-typedef void (*pa_ext_volume_api_server_info_cb_t)(pa_context *context, const pa_ext_volume_api_server_info *info,
-                                                   void *userdata);
-pa_operation *pa_ext_volume_api_get_server_info(pa_context *context, pa_ext_volume_api_server_info_cb_t cb,
-                                                void *userdata);
-
-struct pa_ext_volume_api_volume_control_info {
-    uint32_t index;
-    const char *name;
-    const char *description;
-    pa_proplist *proplist;
-    pa_ext_volume_api_bvolume volume;
-    int convertible_to_dB;
-};
-
-typedef void (*pa_ext_volume_api_volume_control_info_cb_t)(pa_context *context,
-                                                           const pa_ext_volume_api_volume_control_info *info,
-                                                           int eol, void *userdata);
-pa_operation *pa_ext_volume_api_get_volume_control_info_by_index(pa_context *context, uint32_t idx,
-                                                                 pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                                 void *userdata);
-pa_operation *pa_ext_volume_api_get_volume_control_info_by_name(pa_context *context, const char *name,
-                                                                pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                                void *userdata);
-pa_operation *pa_ext_volume_api_get_volume_control_info_list(pa_context *context,
-                                                             pa_ext_volume_api_volume_control_info_cb_t cb,
-                                                             void *userdata);
-
-pa_operation *pa_ext_volume_api_set_volume_control_volume_by_index(pa_context *context, uint32_t idx,
-                                                                   pa_ext_volume_api_bvolume *volume,
-                                                                   int set_volume, int set_balance,
-                                                                   pa_context_success_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_set_volume_control_volume_by_name(pa_context *context, const char *name,
-                                                                  pa_ext_volume_api_bvolume *volume,
-                                                                  int set_volume, int set_balance,
-                                                                  pa_context_success_cb_t cb, void *userdata);
-
-struct pa_ext_volume_api_mute_control_info {
-    uint32_t index;
-    const char *name;
-    const char *description;
-    pa_proplist *proplist;
-    int mute;
-};
-
-typedef void (*pa_ext_volume_api_mute_control_info_cb_t)(pa_context *context,
-                                                         const pa_ext_volume_api_mute_control_info *info, int eol,
-                                                         void *userdata);
-pa_operation *pa_ext_volume_api_get_mute_control_info_by_index(pa_context *context, uint32_t idx,
-                                                               pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                               void *userdata);
-pa_operation *pa_ext_volume_api_get_mute_control_info_by_name(pa_context *context, const char *name,
-                                                              pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                              void *userdata);
-pa_operation *pa_ext_volume_api_get_mute_control_info_list(pa_context *context,
-                                                           pa_ext_volume_api_mute_control_info_cb_t cb,
-                                                           void *userdata);
-
-pa_operation *pa_ext_volume_api_set_mute_control_mute_by_index(pa_context *context, uint32_t idx, int mute,
-                                                               pa_context_success_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_set_mute_control_mute_by_name(pa_context *context, const char *name, int mute,
-                                                              pa_context_success_cb_t cb, void *userdata);
-
-struct pa_ext_volume_api_device_info {
-    uint32_t index;
-    const char *name;
-    const char *description;
-    pa_direction_t direction;
-    const char **device_types;
-    uint32_t n_device_types;
-    pa_proplist *proplist;
-    uint32_t volume_control;
-    uint32_t mute_control;
-};
-
-typedef void (*pa_ext_volume_api_device_info_cb_t)(pa_context *context, const pa_ext_volume_api_device_info *info,
-                                                   int eol, void *userdata);
-pa_operation *pa_ext_volume_api_get_device_info_by_index(pa_context *context, uint32_t idx,
-                                                         pa_ext_volume_api_device_info_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_get_device_info_by_name(pa_context *context, const char *name,
-                                                        pa_ext_volume_api_device_info_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_get_device_info_list(pa_context *context, pa_ext_volume_api_device_info_cb_t cb,
-                                                     void *userdata);
-
-struct pa_ext_volume_api_stream_info {
-    uint32_t index;
-    const char *name;
-    const char *description;
-    pa_direction_t direction;
-    pa_proplist *proplist;
-    uint32_t volume_control;
-    uint32_t mute_control;
-};
-
-typedef void (*pa_ext_volume_api_stream_info_cb_t)(pa_context *context, const pa_ext_volume_api_stream_info *info,
-                                                   int eol, void *userdata);
-pa_operation *pa_ext_volume_api_get_stream_info_by_index(pa_context *context, uint32_t idx,
-                                                         pa_ext_volume_api_stream_info_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_get_stream_info_by_name(pa_context *context, const char *name,
-                                                        pa_ext_volume_api_stream_info_cb_t cb, void *userdata);
-pa_operation *pa_ext_volume_api_get_stream_info_list(pa_context *context, pa_ext_volume_api_stream_info_cb_t cb,
-                                                     void *userdata);
-
-struct pa_ext_volume_api_audio_group_info {
-    uint32_t index;
-    const char *name;
-    const char *description;
-    pa_proplist *proplist;
-    uint32_t volume_control;
-    uint32_t mute_control;
-};
-
-typedef void (*pa_ext_volume_api_audio_group_info_cb_t)(pa_context *context,
-                                                        const pa_ext_volume_api_audio_group_info *info, int eol,
-                                                        void *userdata);
-pa_operation *pa_ext_volume_api_get_audio_group_info_by_index(pa_context *context, uint32_t idx,
-                                                              pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                              void *userdata);
-pa_operation *pa_ext_volume_api_get_audio_group_info_by_name(pa_context *context, const char *name,
-                                                             pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                             void *userdata);
-pa_operation *pa_ext_volume_api_get_audio_group_info_list(pa_context *context,
-                                                          pa_ext_volume_api_audio_group_info_cb_t cb,
-                                                          void *userdata);
-
-PA_C_DECL_END
-
-#endif