diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3f9640 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/pulseaudio-10.0.tar.xz diff --git a/.pulseaudio.metadata b/.pulseaudio.metadata new file mode 100644 index 0000000..4e3a23e --- /dev/null +++ b/.pulseaudio.metadata @@ -0,0 +1 @@ +ab7cc41a2dc2b9da0794e3a51a4eb7e82e7da511 SOURCES/pulseaudio-10.0.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch b/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch new file mode 100644 index 0000000..d5bffcd --- /dev/null +++ b/SOURCES/0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch @@ -0,0 +1,96 @@ +From 1e057be093d948faa26b94b6efcae79bee7e6aee Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Fri, 26 May 2017 15:42:40 +0800 +Subject: [PATCH 1/4] alsa-mixer: Add support for usb audio in the Dell dock + TB16 + +There are one headset jack on the front panel of TB16, through this +jack, we have one stereo headphone output (hw:%f,0,0) and one mono +headset-mic input (hw:%f,0,0); and there is one speaker output jack +(hw:%f,1,0) on the rear panel of TB16. + +The detail information of the Dell dock TB16: +http://www.dell.com/support/article/sg/en/sgbsdt1/SLN301105 + +Signed-off-by: Hui Wang +--- + .../alsa/mixer/profile-sets/90-pulseaudio.rules | 1 + + .../profile-sets/dell-dock-tb16-usb-audio.conf | 55 ++++++++++++++++++++++ + 3 files changed, 57 insertions(+) + create mode 100644 src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf + +diff --git a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules +index 70e34e6fa..805a05b2a 100644 +--- a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules ++++ b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules +@@ -98,5 +98,6 @@ ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="nativ + ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf" + ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf" + ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf" ++ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf" + + LABEL="pulseaudio_end" +diff --git a/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf +new file mode 100644 +index 000000000..118655246 +--- /dev/null ++++ b/src/modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf +@@ -0,0 +1,55 @@ ++# This file is part of PulseAudio. ++# ++# 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, see . ++ ++; Dell Dock TB16 USB audio ++; ++; This card has two stereo pairs of output, One Mono input. ++; ++; See default.conf for an explanation on the directives used here. ++ ++[General] ++auto-profiles = no ++ ++[Mapping analog-stereo-headphone] ++description = Headphone ++device-strings = hw:%f,0,0 ++channel-map = left,right ++direction = output ++ ++[Mapping analog-stereo-speaker] ++description = Speaker ++device-strings = hw:%f,1,0 ++channel-map = left,right ++direction = output ++ ++[Mapping analog-stereo-mic] ++description = Headset-Mic ++device-strings = hw:%f,0,0 ++channel-map = left,right ++direction = input ++ ++ ++[Profile output:analog-stereo-speaker] ++description = Speaker ++output-mappings = analog-stereo-speaker ++priority = 60 ++skip-probe = yes ++ ++[Profile output:analog-stereo-headphone+input:analog-stereo-mic] ++description = Headset ++output-mappings = analog-stereo-headphone ++input-mappings = analog-stereo-mic ++priority = 80 ++skip-probe = yes +-- +2.14.3 + diff --git a/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch b/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch new file mode 100644 index 0000000..2a2a5ec --- /dev/null +++ b/SOURCES/0002-sink-source-update-the-default-sink-source-on-port-s.patch @@ -0,0 +1,60 @@ +From 1e13b722545a23699479bb177648f30f7be396ca Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Sun, 7 May 2017 12:12:39 +0300 +Subject: [PATCH 2/4] sink, source: update the default sink/source on port + switches + +When sinks are compared during the default sink selection, the active +port's availability is inspected. Therefore, the default sink should be +updated when the active port changes, because the new port may have +different availability status than the old port. + +For example, let's say that a laptop has an analog sink with a speaker +and a headphone port, and headphones are initially plugged in, so both +ports can be used[1]. The headphone port is initially the active port. +There's also a null sink in the system. When the headphones are +unplugged, the headphone port becomes unavailable, and the null sink +becomes the new default sink. Then module-switch-on-connect changes the +analog sink port to speakers. Now the default sink should change back to +the analog sink, but that doesn't happen without this patch. + +[1] Actually we currently mark speakers as unavailable when headphones +are plugged in, but that's not strictly necessary. My example relies on +both ports being available initially, so the bug can't be reproduced +with the current mixer configuration. +--- + src/pulsecore/sink.c | 3 +++ + src/pulsecore/source.c | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c +index aa2182220..ebb13c2c9 100644 +--- a/src/pulsecore/sink.c ++++ b/src/pulsecore/sink.c +@@ -3355,6 +3355,9 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) { + + pa_sink_set_port_latency_offset(s, s->active_port->latency_offset); + ++ /* The active port affects the default sink selection. */ ++ pa_core_update_default_sink(s->core); ++ + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s); + + return 0; +diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c +index 8ce781804..3f0f53b52 100644 +--- a/src/pulsecore/source.c ++++ b/src/pulsecore/source.c +@@ -2630,6 +2630,9 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) { + s->active_port = port; + s->save_port = save; + ++ /* The active port affects the default source selection. */ ++ pa_core_update_default_source(s->core); ++ + pa_source_set_port_latency_offset(s, s->active_port->latency_offset); + + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s); +-- +2.14.3 + diff --git a/SOURCES/0003-improve-default-sink-source-handling.patch b/SOURCES/0003-improve-default-sink-source-handling.patch new file mode 100644 index 0000000..c39ff6a --- /dev/null +++ b/SOURCES/0003-improve-default-sink-source-handling.patch @@ -0,0 +1,1262 @@ +From 84dbc69202771252b0c7a0d8b6b32f728931bb7f Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Thu, 16 Feb 2017 12:09:38 +0200 +Subject: [PATCH 3/4] improve default sink/source handling + +Currently the default sink policy is simple: either the user has +configured it explicitly, in which case we always use that as the +default, or we pick the sink with the highest priority. The sink +priorities are currently static, so there's no need to worry about +updating the default sink when sink priorities change. + +I intend to make things a bit more complex: if the active port of a sink +is unavailable, the sink should not be the default sink, and I also want +to make sink priorities dependent on the active port, so changing the +port should cause re-evaluation of which sink to choose as the default. +Currently the default sink choice is done only when someone calls +pa_namereg_get_default_sink(), and change notifications are only sent +when a sink is created or destroyed. That makes it hard to add new rules +to the default sink selection policy. + +This patch moves the default sink selection to +pa_core_update_default_sink(), which is called whenever something +happens that can affect the default sink choice. That function needs to +know the previous choice in order to send change notifications as +appropriate, but previously pa_core.default_sink was only set when the +user had configured it explicitly. Now pa_core.default_sink is always +set (unless there are no sinks at all), so pa_core_update_default_sink() +can use that to get the previous choice. The user configuration is saved +in a new variable, pa_core.configured_default_sink. + +pa_namereg_get_default_sink() is now unnecessary, because +pa_core.default_sink can be used directly to get the +currently-considered-best sink. pa_namereg_set_default_sink() is +replaced by pa_core_set_configured_default_sink(). + +I haven't confirmed it, but I expect that this patch will fix problems +in the D-Bus protocol related to default sink handling. The D-Bus +protocol used to get confused when the current default sink gets +removed. It would incorrectly think that if there's no explicitly +configured default sink, then there's no default sink at all. Even +worse, when the D-Bus thinks that there's no default sink, it concludes +that there are no sinks at all, which made it impossible to configure +the default sink via the D-Bus interface. Now that pa_core.default_sink +is always set, except when there really aren't any sinks, the D-Bus +protocol should behave correctly. + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99425 +--- + src/modules/dbus/iface-core.c | 114 +++++++++++++------ + src/modules/dbus/iface-sample.c | 10 +- + src/modules/module-default-device-restore.c | 14 +-- + src/modules/module-intended-roles.c | 37 +++--- + src/modules/module-rescue-streams.c | 20 ++-- + src/modules/module-switch-on-connect.c | 30 ++--- + src/pulsecore/cli-command.c | 20 ++-- + src/pulsecore/cli-text.c | 12 +- + src/pulsecore/core.c | 170 ++++++++++++++++++++++++++++ + src/pulsecore/core.h | 28 ++++- + src/pulsecore/namereg.c | 115 +------------------ + src/pulsecore/namereg.h | 6 - + src/pulsecore/protocol-native.c | 19 ++-- + src/pulsecore/sink.c | 7 ++ + src/pulsecore/source.c | 7 ++ + 15 files changed, 370 insertions(+), 239 deletions(-) + +diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c +index 508913de1..3f368ab46 100644 +--- a/src/modules/dbus/iface-core.c ++++ b/src/modules/dbus/iface-core.c +@@ -721,7 +721,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu + return; + } + +- pa_namereg_set_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)); ++ pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)); + + pa_dbus_send_empty_reply(conn, msg); + } +@@ -809,7 +809,7 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, D + return; + } + +- pa_namereg_set_default_source(c->core, pa_dbusiface_device_get_source(fallback_source)); ++ pa_core_set_configured_default_source(c->core, pa_dbusiface_device_get_source(fallback_source)); + + pa_dbus_send_empty_reply(conn, msg); + } +@@ -1692,6 +1692,28 @@ static pa_hook_result_t sample_cache_removed_cb(void *hook_data, void *call_data + return PA_HOOK_OK; + } + ++static pa_dbusiface_device *create_dbus_object_for_sink(pa_dbusiface_core *c, pa_sink *s) { ++ pa_dbusiface_device *d; ++ const char *object_path; ++ DBusMessage *signal_msg; ++ ++ d = pa_dbusiface_device_new_sink(c, s); ++ object_path = pa_dbusiface_device_get_path(d); ++ ++ pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); ++ pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0); ++ ++ pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, ++ PA_DBUS_CORE_INTERFACE, ++ signals[SIGNAL_NEW_SINK].name))); ++ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); ++ ++ pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); ++ dbus_message_unref(signal_msg); ++ ++ return d; ++} ++ + static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + pa_sink *new_fallback_sink = call_data; +@@ -1707,7 +1729,15 @@ static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data + c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL; + + if (c->fallback_sink) { +- pa_assert_se((device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)))); ++ device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)); ++ ++ /* It's possible that we haven't created a dbus object for the ++ * source yet, because if a new source immediately becomes the ++ * default source, the default source change hook is fired before ++ * the put hook. */ ++ if (!device_iface) ++ device_iface = create_dbus_object_for_sink(c, c->fallback_sink); ++ + object_path = pa_dbusiface_device_get_path(device_iface); + + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, +@@ -1730,6 +1760,28 @@ static pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data + return PA_HOOK_OK; + } + ++static pa_dbusiface_device *create_dbus_object_for_source(pa_dbusiface_core *c, pa_source *s) { ++ pa_dbusiface_device *d; ++ const char *object_path; ++ DBusMessage *signal_msg; ++ ++ d = pa_dbusiface_device_new_source(c, s); ++ object_path = pa_dbusiface_device_get_path(d); ++ ++ pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); ++ pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0); ++ ++ pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, ++ PA_DBUS_CORE_INTERFACE, ++ signals[SIGNAL_NEW_SOURCE].name))); ++ pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); ++ ++ pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); ++ dbus_message_unref(signal_msg); ++ ++ return d; ++} ++ + static pa_hook_result_t default_source_changed_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + pa_source *new_fallback_source = call_data; +@@ -1745,7 +1797,15 @@ static pa_hook_result_t default_source_changed_cb(void *hook_data, void *call_da + c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL; + + if (c->fallback_source) { +- pa_assert_se((device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)))); ++ device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)); ++ ++ /* It's possible that we haven't created a dbus object for the ++ * source yet, because if a new source immediately becomes the ++ * default source, the default source change hook is fired before ++ * the put hook. */ ++ if (!device_iface) ++ device_iface = create_dbus_object_for_source(c, c->fallback_source); ++ + object_path = pa_dbusiface_device_get_path(device_iface); + + pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, +@@ -1983,26 +2043,17 @@ static pa_hook_result_t client_unlink_cb(void *hook_data, void *call_data, void + static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + pa_sink *s = call_data; +- pa_dbusiface_device *d = NULL; +- const char *object_path = NULL; +- DBusMessage *signal_msg = NULL; + + pa_assert(c); + pa_assert(s); + +- d = pa_dbusiface_device_new_sink(c, s); +- object_path = pa_dbusiface_device_get_path(d); +- +- pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); +- pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0); +- +- pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, +- PA_DBUS_CORE_INTERFACE, +- signals[SIGNAL_NEW_SINK].name)); +- pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); ++ /* We may have alredy encountered this sink, because if the new sink was ++ * chosen as the default sink, the default sink change hook was fired ++ * first, and we saw the sink in default_sink_changed_cb(). */ ++ if (pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(s->index))) ++ return PA_HOOK_OK; + +- pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); +- dbus_message_unref(signal_msg); ++ create_dbus_object_for_sink(c, s); + + return PA_HOOK_OK; + } +@@ -2037,26 +2088,17 @@ static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *s + static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + pa_source *s = call_data; +- pa_dbusiface_device *d = NULL; +- const char *object_path = NULL; +- DBusMessage *signal_msg = NULL; + + pa_assert(c); + pa_assert(s); + +- d = pa_dbusiface_device_new_source(c, s); +- object_path = pa_dbusiface_device_get_path(d); +- +- pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); +- pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0); +- +- pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, +- PA_DBUS_CORE_INTERFACE, +- signals[SIGNAL_NEW_SOURCE].name))); +- pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); ++ /* We may have alredy encountered this source, because if the new source ++ * was chosen as the default source, the default source change hook was ++ * fired first, and we saw the source in default_source_changed_cb(). */ ++ if (pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(s->index))) ++ return PA_HOOK_OK; + +- pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); +- dbus_message_unref(signal_msg); ++ create_dbus_object_for_source(c, s); + + return PA_HOOK_OK; + } +@@ -2158,8 +2200,8 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { + c->samples = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_sample_free); + c->modules = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_module_free); + c->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_client_free); +- c->fallback_sink = pa_namereg_get_default_sink(core); +- c->fallback_source = pa_namereg_get_default_source(core); ++ c->fallback_sink = core->default_sink; ++ c->fallback_source = core->default_source; + c->default_sink_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], + PA_HOOK_NORMAL, default_sink_changed_cb, c); + c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], +diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c +index 61f2ba091..51189196d 100644 +--- a/src/modules/dbus/iface-sample.c ++++ b/src/modules/dbus/iface-sample.c +@@ -352,7 +352,6 @@ static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata) + DBusMessageIter msg_iter; + dbus_uint32_t volume = 0; + pa_proplist *property_list = NULL; +- pa_sink *sink = NULL; + + pa_assert(conn); + pa_assert(msg); +@@ -370,13 +369,18 @@ static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata) + goto finish; + } + +- if (!(sink = pa_namereg_get_default_sink(s->sample->core))) { ++ if (!s->sample->core->default_sink) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, + "Can't play sample %s, because there are no sinks available.", s->sample->name); + goto finish; + } + +- if (pa_scache_play_item(s->sample->core, s->sample->name, sink, volume, property_list, NULL) < 0) { ++ if (pa_scache_play_item(s->sample->core, ++ s->sample->name, ++ s->sample->core->default_sink, ++ volume, ++ property_list, ++ NULL) < 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Playing sample %s failed.", s->sample->name); + goto finish; + } +diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c +index d76e28e68..56fee67f8 100644 +--- a/src/modules/module-default-device-restore.c ++++ b/src/modules/module-default-device-restore.c +@@ -56,7 +56,7 @@ static void load(struct userdata *u) { + + /* We never overwrite manually configured settings */ + +- if (u->core->default_sink) ++ if (u->core->configured_default_sink) + pa_log_info("Manually configured default sink, not overwriting."); + else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) { + char ln[256] = ""; +@@ -69,7 +69,7 @@ static void load(struct userdata *u) { + if (!ln[0]) + pa_log_info("No previous default sink setting, ignoring."); + else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SINK))) { +- pa_namereg_set_default_sink(u->core, s); ++ pa_core_set_configured_default_sink(u->core, s); + pa_log_info("Restored default sink '%s'.", ln); + } else + pa_log_info("Saved default sink '%s' not existent, not restoring default sink setting.", ln); +@@ -77,7 +77,7 @@ static void load(struct userdata *u) { + } else if (errno != ENOENT) + pa_log("Failed to load default sink: %s", pa_cstrerror(errno)); + +- if (u->core->default_source) ++ if (u->core->configured_default_source) + pa_log_info("Manually configured default source, not overwriting."); + else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) { + char ln[256] = ""; +@@ -90,7 +90,7 @@ static void load(struct userdata *u) { + if (!ln[0]) + pa_log_info("No previous default source setting, ignoring."); + else if ((s = pa_namereg_get(u->core, ln, PA_NAMEREG_SOURCE))) { +- pa_namereg_set_default_source(u->core, s); ++ pa_core_set_configured_default_source(u->core, s); + pa_log_info("Restored default source '%s'.", ln); + } else + pa_log_info("Saved default source '%s' not existent, not restoring default source setting.", ln); +@@ -107,8 +107,7 @@ static void save(struct userdata *u) { + + if (u->sink_filename) { + if ((f = pa_fopen_cloexec(u->sink_filename, "w"))) { +- pa_sink *s = pa_namereg_get_default_sink(u->core); +- fprintf(f, "%s\n", s ? s->name : ""); ++ fprintf(f, "%s\n", u->core->default_sink ? u->core->default_sink->name : ""); + fclose(f); + } else + pa_log("Failed to save default sink: %s", pa_cstrerror(errno)); +@@ -116,8 +115,7 @@ static void save(struct userdata *u) { + + if (u->source_filename) { + if ((f = pa_fopen_cloexec(u->source_filename, "w"))) { +- pa_source *s = pa_namereg_get_default_source(u->core); +- fprintf(f, "%s\n", s ? s->name : ""); ++ fprintf(f, "%s\n", u->core->default_source ? u->core->default_source->name : ""); + fclose(f); + } else + pa_log("Failed to save default source: %s", pa_cstrerror(errno)); +diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c +index 60ec7e982..f906b8800 100644 +--- a/src/modules/module-intended-roles.c ++++ b/src/modules/module-intended-roles.c +@@ -69,7 +69,7 @@ static bool role_match(pa_proplist *proplist, const char *role) { + + static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) { + const char *role; +- pa_sink *s, *def; ++ pa_sink *s; + uint32_t idx; + + pa_assert(c); +@@ -92,13 +92,13 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n + } + + /* Prefer the default sink over any other sink, just in case... */ +- if ((def = pa_namereg_get_default_sink(c))) +- if (role_match(def->proplist, role) && pa_sink_input_new_data_set_sink(new_data, def, false)) ++ if (c->default_sink) ++ if (role_match(c->default_sink->proplist, role) && pa_sink_input_new_data_set_sink(new_data, c->default_sink, false)) + return PA_HOOK_OK; + + /* @todo: favour the highest priority device, not the first one we find? */ + PA_IDXSET_FOREACH(s, c->sinks, idx) { +- if (s == def) ++ if (s == c->default_sink) + continue; + + if (!PA_SINK_IS_LINKED(pa_sink_get_state(s))) +@@ -113,7 +113,7 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n + + static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) { + const char *role; +- pa_source *s, *def; ++ pa_source *s; + uint32_t idx; + + pa_assert(c); +@@ -136,9 +136,9 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou + } + + /* Prefer the default source over any other source, just in case... */ +- if ((def = pa_namereg_get_default_source(c))) +- if (role_match(def->proplist, role)) { +- pa_source_output_new_data_set_source(new_data, def, false); ++ if (c->default_source) ++ if (role_match(c->default_source->proplist, role)) { ++ pa_source_output_new_data_set_source(new_data, c->default_source, false); + return PA_HOOK_OK; + } + +@@ -146,7 +146,7 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou + if (s->monitor_of) + continue; + +- if (s == def) ++ if (s == c->default_source) + continue; + + if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s))) +@@ -259,7 +259,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, + static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) { + pa_sink_input *si; + uint32_t idx; +- pa_sink *def; + + pa_assert(c); + pa_assert(sink); +@@ -271,7 +270,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str + return PA_HOOK_OK; + + /* If there not default sink, then there is no sink at all */ +- if (!(def = pa_namereg_get_default_sink(c))) ++ if (!c->default_sink) + return PA_HOOK_OK; + + PA_IDXSET_FOREACH(si, sink->inputs, idx) { +@@ -286,14 +285,14 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str + continue; + + /* Would the default sink fit? If so, let's use it */ +- if (def != sink && role_match(def->proplist, role)) +- if (pa_sink_input_move_to(si, def, false) >= 0) ++ if (c->default_sink != sink && role_match(c->default_sink->proplist, role)) ++ if (pa_sink_input_move_to(si, c->default_sink, false) >= 0) + continue; + + /* Try to find some other fitting sink */ + /* @todo: favour the highest priority device, not the first one we find? */ + PA_IDXSET_FOREACH(d, c->sinks, jdx) { +- if (d == def || d == sink) ++ if (d == c->default_sink || d == sink) + continue; + + if (!PA_SINK_IS_LINKED(pa_sink_get_state(d))) +@@ -311,7 +310,6 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str + static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) { + pa_source_output *so; + uint32_t idx; +- pa_source *def; + + pa_assert(c); + pa_assert(source); +@@ -323,7 +321,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc + return PA_HOOK_OK; + + /* If there not default source, then there is no source at all */ +- if (!(def = pa_namereg_get_default_source(c))) ++ if (!c->default_source) + return PA_HOOK_OK; + + PA_IDXSET_FOREACH(so, source->outputs, idx) { +@@ -341,15 +339,16 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc + continue; + + /* Would the default source fit? If so, let's use it */ +- if (def != source && role_match(def->proplist, role) && !source->monitor_of == !def->monitor_of) { +- pa_source_output_move_to(so, def, false); ++ if (c->default_source != source && role_match(c->default_source->proplist, role) ++ && !source->monitor_of == !c->default_source->monitor_of) { ++ pa_source_output_move_to(so, c->default_source, false); + continue; + } + + /* Try to find some other fitting source */ + /* @todo: favour the highest priority device, not the first one we find? */ + PA_IDXSET_FOREACH(d, c->sources, jdx) { +- if (d == def || d == source) ++ if (d == c->default_source || d == source) + continue; + + if (!PA_SOURCE_IS_LINKED(pa_source_get_state(d))) +diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c +index 60ac1c4cf..d3c9953ec 100644 +--- a/src/modules/module-rescue-streams.c ++++ b/src/modules/module-rescue-streams.c +@@ -96,7 +96,7 @@ static void build_group_ports(pa_hashmap *g_ports, pa_hashmap *s_ports) { + } + + static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip) { +- pa_sink *target, *def, *fb_sink = NULL; ++ pa_sink *target, *fb_sink = NULL; + uint32_t idx; + pa_hashmap *all_ports; + pa_device_port *best_port; +@@ -104,15 +104,13 @@ static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip + pa_assert(c); + pa_assert(i); + +- def = pa_namereg_get_default_sink(c); +- +- if (def && def != skip && pa_sink_input_may_move_to(i, def)) +- return def; ++ if (c->default_sink && c->default_sink != skip && pa_sink_input_may_move_to(i, c->default_sink)) ++ return c->default_sink; + + all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + PA_IDXSET_FOREACH(target, c->sinks, idx) { +- if (target == def) ++ if (target == c->default_sink) + continue; + + if (target == skip) +@@ -204,7 +202,7 @@ static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i + } + + static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_source *skip) { +- pa_source *target, *def, *fb_source = NULL; ++ pa_source *target, *fb_source = NULL; + uint32_t idx; + pa_hashmap *all_ports; + pa_device_port *best_port; +@@ -212,15 +210,13 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou + pa_assert(c); + pa_assert(o); + +- def = pa_namereg_get_default_source(c); +- +- if (def && def != skip && pa_source_output_may_move_to(o, def)) +- return def; ++ if (c->default_source && c->default_source != skip && pa_source_output_may_move_to(o, c->default_source)) ++ return c->default_source; + + all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + PA_IDXSET_FOREACH(target, c->sources, idx) { +- if (target == def) ++ if (target == c->default_source) + continue; + + if (target == skip) +diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c +index c844add6e..776c923ee 100644 +--- a/src/modules/module-switch-on-connect.c ++++ b/src/modules/module-switch-on-connect.c +@@ -55,7 +55,7 @@ struct userdata { + static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { + pa_sink_input *i; + uint32_t idx; +- pa_sink *def; ++ pa_sink *old_default_sink; + const char *s; + struct userdata *u = userdata; + +@@ -75,24 +75,25 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* + return PA_HOOK_OK; + } + +- def = pa_namereg_get_default_sink(c); +- if (def == sink) ++ if (c->default_sink == sink) + return PA_HOOK_OK; + + if (u->only_from_unavailable) +- if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO) ++ if (!c->default_sink->active_port || c->default_sink->active_port->available != PA_AVAILABLE_NO) + return PA_HOOK_OK; + ++ old_default_sink = c->default_sink; ++ + /* Actually do the switch to the new sink */ +- pa_namereg_set_default_sink(c, sink); ++ pa_core_set_configured_default_sink(c, sink); + + /* Now move all old inputs over */ +- if (pa_idxset_size(def->inputs) <= 0) { ++ if (pa_idxset_size(old_default_sink->inputs) <= 0) { + pa_log_debug("No sink inputs to move away."); + return PA_HOOK_OK; + } + +- PA_IDXSET_FOREACH(i, def->inputs, idx) { ++ PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) { + if (i->save_sink || !PA_SINK_INPUT_IS_LINKED(i->state)) + continue; + +@@ -110,7 +111,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* + static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void* userdata) { + pa_source_output *o; + uint32_t idx; +- pa_source *def; ++ pa_source *old_default_source; + const char *s; + struct userdata *u = userdata; + +@@ -134,24 +135,25 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, + return PA_HOOK_OK; + } + +- def = pa_namereg_get_default_source(c); +- if (def == source) ++ if (c->default_source == source) + return PA_HOOK_OK; + + if (u->only_from_unavailable) +- if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO) ++ if (!c->default_source->active_port || c->default_source->active_port->available != PA_AVAILABLE_NO) + return PA_HOOK_OK; + ++ old_default_source = c->default_source; ++ + /* Actually do the switch to the new source */ +- pa_namereg_set_default_source(c, source); ++ pa_core_set_configured_default_source(c, source); + + /* Now move all old outputs over */ +- if (pa_idxset_size(def->outputs) <= 0) { ++ if (pa_idxset_size(old_default_source->outputs) <= 0) { + pa_log_debug("No source outputs to move away."); + return PA_HOOK_OK; + } + +- PA_IDXSET_FOREACH(o, def->outputs, idx) { ++ PA_IDXSET_FOREACH(o, old_default_source->outputs, idx) { + if (o->save_source || !PA_SOURCE_OUTPUT_IS_LINKED(o->state)) + continue; + +diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c +index 9a7360582..5a632be45 100644 +--- a/src/pulsecore/cli-command.c ++++ b/src/pulsecore/cli-command.c +@@ -344,8 +344,6 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool + char bytes[PA_BYTES_SNPRINT_MAX]; + const pa_mempool_stat *mstat; + unsigned k; +- pa_sink *def_sink; +- pa_source *def_source; + + static const char* const type_table[PA_MEMBLOCK_TYPE_MAX] = { + [PA_MEMBLOCK_POOL] = "POOL", +@@ -388,12 +386,10 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool + pa_strbuf_printf(buf, "Default channel map: %s\n", + pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map)); + +- def_sink = pa_namereg_get_default_sink(c); +- def_source = pa_namereg_get_default_source(c); + pa_strbuf_printf(buf, "Default sink name: %s\n" + "Default source name: %s\n", +- def_sink ? def_sink->name : "none", +- def_source ? def_source->name : "none"); ++ c->default_sink ? c->default_sink->name : "none", ++ c->default_source ? c->default_source->name : "none"); + + for (k = 0; k < PA_MEMBLOCK_TYPE_MAX; k++) + pa_strbuf_printf(buf, +@@ -1034,7 +1030,7 @@ static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *b + } + + if ((s = pa_namereg_get(c, n, PA_NAMEREG_SINK))) +- pa_namereg_set_default_sink(c, s); ++ pa_core_set_configured_default_sink(c, s); + else + pa_strbuf_printf(buf, "Sink %s does not exist.\n", n); + +@@ -1056,7 +1052,7 @@ static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf + } + + if ((s = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) +- pa_namereg_set_default_source(c, s); ++ pa_core_set_configured_default_source(c, s); + else + pa_strbuf_printf(buf, "Source %s does not exist.\n", n); + return 0; +@@ -1850,20 +1846,20 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool + } + + nl = false; +- if ((sink = pa_namereg_get_default_sink(c))) { ++ if (c->default_sink) { + if (!nl) { + pa_strbuf_puts(buf, "\n"); + nl = true; + } + +- pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name); ++ pa_strbuf_printf(buf, "set-default-sink %s\n", c->default_sink->name); + } + +- if ((source = pa_namereg_get_default_source(c))) { ++ if (c->default_source) { + if (!nl) + pa_strbuf_puts(buf, "\n"); + +- pa_strbuf_printf(buf, "set-default-source %s\n", source->name); ++ pa_strbuf_printf(buf, "set-default-source %s\n", c->default_source->name); + } + + pa_strbuf_puts(buf, "\n### EOF\n"); +diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c +index af79a1ebe..ded82f6e4 100644 +--- a/src/pulsecore/cli-text.c ++++ b/src/pulsecore/cli-text.c +@@ -232,7 +232,7 @@ static const char *source_state_to_string(pa_source_state_t state) { + + char *pa_sink_list_to_string(pa_core *c) { + pa_strbuf *s; +- pa_sink *sink, *default_sink; ++ pa_sink *sink; + uint32_t idx = PA_IDXSET_INVALID; + pa_assert(c); + +@@ -240,8 +240,6 @@ char *pa_sink_list_to_string(pa_core *c) { + + pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks)); + +- default_sink = pa_namereg_get_default_sink(c); +- + PA_IDXSET_FOREACH(sink, c->sinks, idx) { + char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], + cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], +@@ -273,7 +271,7 @@ char *pa_sink_list_to_string(pa_core *c) { + "\tchannel map: %s%s%s\n" + "\tused by: %u\n" + "\tlinked by: %u\n", +- sink == default_sink ? '*' : ' ', ++ sink == c->default_sink ? '*' : ' ', + sink->index, + sink->name, + sink->driver, +@@ -350,7 +348,7 @@ char *pa_sink_list_to_string(pa_core *c) { + + char *pa_source_list_to_string(pa_core *c) { + pa_strbuf *s; +- pa_source *source, *default_source; ++ pa_source *source; + uint32_t idx = PA_IDXSET_INVALID; + pa_assert(c); + +@@ -358,8 +356,6 @@ char *pa_source_list_to_string(pa_core *c) { + + pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); + +- default_source = pa_namereg_get_default_source(c); +- + PA_IDXSET_FOREACH(source, c->sources, idx) { + char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], + cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], +@@ -389,7 +385,7 @@ char *pa_source_list_to_string(pa_core *c) { + "\tchannel map: %s%s%s\n" + "\tused by: %u\n" + "\tlinked by: %u\n", +- source == default_source ? '*' : ' ', ++ source == c->default_source ? '*' : ' ', + source->index, + source->name, + source->driver, +diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c +index 2a96dfa5e..da1abb3ba 100644 +--- a/src/pulsecore/core.c ++++ b/src/pulsecore/core.c +@@ -223,6 +223,176 @@ static void core_free(pa_object *o) { + pa_xfree(c); + } + ++void pa_core_set_configured_default_sink(pa_core *core, pa_sink *sink) { ++ pa_sink *old_sink; ++ ++ pa_assert(core); ++ ++ old_sink = core->configured_default_sink; ++ ++ if (sink == old_sink) ++ return; ++ ++ core->configured_default_sink = sink; ++ pa_log_info("configured_default_sink: %s -> %s", ++ old_sink ? old_sink->name : "(unset)", sink ? sink->name : "(unset)"); ++ ++ pa_core_update_default_sink(core); ++} ++ ++void pa_core_set_configured_default_source(pa_core *core, pa_source *source) { ++ pa_source *old_source; ++ ++ pa_assert(core); ++ ++ old_source = core->configured_default_source; ++ ++ if (source == old_source) ++ return; ++ ++ core->configured_default_source = source; ++ pa_log_info("configured_default_source: %s -> %s", ++ old_source ? old_source->name : "(unset)", source ? source->name : "(unset)"); ++ ++ pa_core_update_default_source(core); ++} ++ ++/* a < b -> return -1 ++ * a == b -> return 0 ++ * a > b -> return 1 */ ++static int compare_sinks(pa_sink *a, pa_sink *b) { ++ pa_core *core; ++ ++ core = a->core; ++ ++ /* The configured default sink is preferred over any other sink. */ ++ if (b == core->configured_default_sink) ++ return -1; ++ if (a == core->configured_default_sink) ++ return 1; ++ ++ if (a->priority < b->priority) ++ return -1; ++ if (a->priority > b->priority) ++ return 1; ++ ++ /* It's hard to find any difference between these sinks, but maybe one of ++ * them is already the default sink? If so, it's best to keep it as the ++ * default to avoid changing the routing for no good reason. */ ++ if (b == core->default_sink) ++ return -1; ++ if (a == core->default_sink) ++ return 1; ++ ++ return 0; ++} ++ ++void pa_core_update_default_sink(pa_core *core) { ++ pa_sink *best = NULL; ++ pa_sink *sink; ++ uint32_t idx; ++ pa_sink *old_default_sink; ++ ++ pa_assert(core); ++ ++ PA_IDXSET_FOREACH(sink, core->sinks, idx) { ++ if (!best) { ++ best = sink; ++ continue; ++ } ++ ++ if (compare_sinks(sink, best) > 0) ++ best = sink; ++ } ++ ++ old_default_sink = core->default_sink; ++ ++ if (best == old_default_sink) ++ return; ++ ++ core->default_sink = best; ++ pa_log_info("default_sink: %s -> %s", ++ old_default_sink ? old_default_sink->name : "(unset)", best ? best->name : "(unset)"); ++ ++ /* If the default sink changed, it may be that the default source has to be ++ * changed too, because monitor sources are prioritized partly based on the ++ * priorities of the monitored sinks. */ ++ pa_core_update_default_source(core); ++ ++ pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); ++ pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], core->default_sink); ++} ++ ++/* a < b -> return -1 ++ * a == b -> return 0 ++ * a > b -> return 1 */ ++static int compare_sources(pa_source *a, pa_source *b) { ++ pa_core *core; ++ ++ core = a->core; ++ ++ /* The configured default source is preferred over any other source. */ ++ if (b == core->configured_default_source) ++ return -1; ++ if (a == core->configured_default_source) ++ return 1; ++ ++ /* Monitor sources lose to non-monitor sources. */ ++ if (a->monitor_of && !b->monitor_of) ++ return -1; ++ if (!a->monitor_of && b->monitor_of) ++ return 1; ++ ++ if (a->priority < b->priority) ++ return -1; ++ if (a->priority > b->priority) ++ return 1; ++ ++ /* If the sources are monitors, we can compare the monitored sinks. */ ++ if (a->monitor_of) ++ return compare_sinks(a->monitor_of, b->monitor_of); ++ ++ /* It's hard to find any difference between these sources, but maybe one of ++ * them is already the default source? If so, it's best to keep it as the ++ * default to avoid changing the routing for no good reason. */ ++ if (b == core->default_source) ++ return -1; ++ if (a == core->default_source) ++ return 1; ++ ++ return 0; ++} ++ ++void pa_core_update_default_source(pa_core *core) { ++ pa_source *best = NULL; ++ pa_source *source; ++ uint32_t idx; ++ pa_source *old_default_source; ++ ++ pa_assert(core); ++ ++ PA_IDXSET_FOREACH(source, core->sources, idx) { ++ if (!best) { ++ best = source; ++ continue; ++ } ++ ++ if (compare_sources(source, best) > 0) ++ best = source; ++ } ++ ++ old_default_source = core->default_source; ++ ++ if (best == old_default_source) ++ return; ++ ++ core->default_source = best; ++ pa_log_info("default_source: %s -> %s", ++ old_default_source ? old_default_source->name : "(unset)", best ? best->name : "(unset)"); ++ pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); ++ pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], core->default_source); ++} ++ + static void exit_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) { + pa_core *c = userdata; + pa_assert(c->exit_event == e); +diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h +index 802111ba1..6e613edeb 100644 +--- a/src/pulsecore/core.h ++++ b/src/pulsecore/core.h +@@ -160,9 +160,18 @@ struct pa_core { + /* Some hashmaps for all sorts of entities */ + pa_hashmap *namereg, *shared; + +- /* The default sink/source */ +- pa_source *default_source; ++ /* The default sink/source as configured by the user. If the user hasn't ++ * explicitly configured anything, these are set to NULL. */ ++ pa_sink *configured_default_sink; ++ pa_source *configured_default_source; ++ ++ /* The effective default sink/source. If no sink or source is explicitly ++ * configured as the default, we pick the device that ranks highest ++ * according to the compare_sinks() and compare_sources() functions in ++ * core.c. pa_core_update_default_sink/source() has to be called whenever ++ * anything changes that might change the comparison results. */ + pa_sink *default_sink; ++ pa_source *default_source; + + pa_channel_map default_channel_map; + pa_sample_spec default_sample_spec; +@@ -223,6 +232,21 @@ enum { + + pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size); + ++void pa_core_set_configured_default_sink(pa_core *core, pa_sink *sink); ++void pa_core_set_configured_default_source(pa_core *core, pa_source *source); ++ ++/* These should be called whenever something changes that may affect the ++ * default sink or source choice. ++ * ++ * If the default source choice happens between two monitor sources, the ++ * monitored sinks are compared, so if the default sink changes, the default ++ * source may change too. However, pa_core_update_default_sink() calls ++ * pa_core_update_default_source() internally, so it's sufficient to only call ++ * pa_core_update_default_sink() when something happens that affects the sink ++ * ordering. */ ++void pa_core_update_default_sink(pa_core *core); ++void pa_core_update_default_source(pa_core *core); ++ + /* Check whether no one is connected to this core */ + void pa_core_check_idle(pa_core *c); + +diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c +index 47bfc087f..0b7388592 100644 +--- a/src/pulsecore/namereg.c ++++ b/src/pulsecore/namereg.c +@@ -168,17 +168,6 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t + + pa_assert_se(pa_hashmap_put(c->namereg, e->name, e) >= 0); + +- /* If a sink or source is registered and there was none registered +- * before we inform the clients which then can ask for the default +- * sink/source which is then assigned. We don't adjust the default +- * sink/source here right away to give the module the chance to +- * register more sinks/sources before we choose a new default +- * sink/source. */ +- +- if ((!c->default_sink && type == PA_NAMEREG_SINK) || +- (!c->default_source && type == PA_NAMEREG_SOURCE)) +- pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); +- + return e->name; + } + +@@ -189,12 +178,6 @@ void pa_namereg_unregister(pa_core *c, const char *name) { + pa_assert(name); + + pa_assert_se(e = pa_hashmap_remove(c->namereg, name)); +- +- if (c->default_sink == e->data) +- pa_namereg_set_default_sink(c, NULL); +- else if (c->default_source == e->data) +- pa_namereg_set_default_source(c, NULL); +- + pa_xfree(e->name); + pa_xfree(e); + } +@@ -205,22 +188,16 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) { + pa_assert(c); + + if (type == PA_NAMEREG_SOURCE && (!name || pa_streq(name, "@DEFAULT_SOURCE@"))) { +- pa_source *s; +- +- if ((s = pa_namereg_get_default_source(c))) +- return s; ++ return c->default_source; + + } else if (type == PA_NAMEREG_SINK && (!name || pa_streq(name, "@DEFAULT_SINK@"))) { +- pa_sink *s; +- +- if ((s = pa_namereg_get_default_sink(c))) +- return s; ++ return c->default_sink; + + } else if (type == PA_NAMEREG_SOURCE && name && pa_streq(name, "@DEFAULT_MONITOR@")) { +- pa_sink *s; +- +- if ((s = pa_namereg_get(c, NULL, PA_NAMEREG_SINK))) +- return s->monitor_source; ++ if (c->default_sink) ++ return c->default_sink->monitor_source; ++ else ++ return NULL; + } + + if (!name) +@@ -248,83 +225,3 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) { + + return NULL; + } +- +-pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) { +- pa_assert(c); +- +- if (s && !PA_SINK_IS_LINKED(pa_sink_get_state(s))) +- return NULL; +- +- if (c->default_sink != s) { +- c->default_sink = s; +- pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], c->default_sink); +- pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); +- } +- +- return s; +-} +- +-pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) { +- pa_assert(c); +- +- if (s && !PA_SOURCE_IS_LINKED(pa_source_get_state(s))) +- return NULL; +- +- if (c->default_source != s) { +- c->default_source = s; +- pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], c->default_source); +- pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); +- } +- +- return s; +-} +- +-pa_sink *pa_namereg_get_default_sink(pa_core *c) { +- pa_sink *s, *best = NULL; +- uint32_t idx; +- +- pa_assert(c); +- +- if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink))) +- return c->default_sink; +- +- PA_IDXSET_FOREACH(s, c->sinks, idx) +- if (PA_SINK_IS_LINKED(pa_sink_get_state(s))) +- if (!best || s->priority > best->priority) +- best = s; +- +- return best; +-} +- +-pa_source *pa_namereg_get_default_source(pa_core *c) { +- pa_source *s, *best = NULL; +- uint32_t idx; +- +- pa_assert(c); +- +- if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source))) +- return c->default_source; +- +- /* First, try to find one that isn't a monitor */ +- PA_IDXSET_FOREACH(s, c->sources, idx) +- if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) +- if (!best || +- s->priority > best->priority) +- best = s; +- +- if (best) +- return best; +- +- /* Then, fallback to a monitor */ +- PA_IDXSET_FOREACH(s, c->sources, idx) +- if (PA_SOURCE_IS_LINKED(pa_source_get_state(s))) +- if (!best || +- s->priority > best->priority || +- (s->priority == best->priority && +- s->monitor_of && +- best->monitor_of && +- s->monitor_of->priority > best->monitor_of->priority)) +- best = s; +- +- return best; +-} +diff --git a/src/pulsecore/namereg.h b/src/pulsecore/namereg.h +index 467db5d43..eb3475ad3 100644 +--- a/src/pulsecore/namereg.h ++++ b/src/pulsecore/namereg.h +@@ -36,12 +36,6 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t + void pa_namereg_unregister(pa_core *c, const char *name); + void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type); + +-pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s); +-pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s); +- +-pa_sink *pa_namereg_get_default_sink(pa_core *c); +-pa_source *pa_namereg_get_default_source(pa_core *c); +- + bool pa_namereg_is_valid_name(const char *name); + bool pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type); + char* pa_namereg_make_valid_name(const char *name); +diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c +index 13f4f6238..8869ae4fa 100644 +--- a/src/pulsecore/protocol-native.c ++++ b/src/pulsecore/protocol-native.c +@@ -3637,10 +3637,9 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t + static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); + pa_tagstruct *reply; +- pa_sink *def_sink; +- pa_source *def_source; + pa_sample_spec fixed_ss; + char *h, *u; ++ pa_core *core; + + pa_native_connection_assert_ref(c); + pa_assert(t); +@@ -3664,18 +3663,18 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t + pa_tagstruct_puts(reply, h); + pa_xfree(h); + +- fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec); ++ core = c->protocol->core; ++ ++ fixup_sample_spec(c, &fixed_ss, &core->default_sample_spec); + pa_tagstruct_put_sample_spec(reply, &fixed_ss); + +- def_sink = pa_namereg_get_default_sink(c->protocol->core); +- pa_tagstruct_puts(reply, def_sink ? def_sink->name : NULL); +- def_source = pa_namereg_get_default_source(c->protocol->core); +- pa_tagstruct_puts(reply, def_source ? def_source->name : NULL); ++ pa_tagstruct_puts(reply, core->default_sink ? core->default_sink->name : NULL); ++ pa_tagstruct_puts(reply, core->default_source ? core->default_source->name : NULL); + + pa_tagstruct_putu32(reply, c->protocol->core->cookie); + + if (c->version >= 15) +- pa_tagstruct_put_channel_map(reply, &c->protocol->core->default_channel_map); ++ pa_tagstruct_put_channel_map(reply, &core->default_channel_map); + + pa_pstream_send_tagstruct(c->pstream, reply); + } +@@ -4347,7 +4346,7 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman + source = pa_namereg_get(c->protocol->core, s, PA_NAMEREG_SOURCE); + CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); + +- pa_namereg_set_default_source(c->protocol->core, source); ++ pa_core_set_configured_default_source(c->protocol->core, source); + } else { + pa_sink *sink; + pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK); +@@ -4355,7 +4354,7 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman + sink = pa_namereg_get(c->protocol->core, s, PA_NAMEREG_SINK); + CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); + +- pa_namereg_set_default_sink(c->protocol->core, sink); ++ pa_core_set_configured_default_sink(c->protocol->core, sink); + } + + pa_pstream_send_simple_ack(c->pstream, tag); +diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c +index ebb13c2c9..b4b373a58 100644 +--- a/src/pulsecore/sink.c ++++ b/src/pulsecore/sink.c +@@ -660,6 +660,8 @@ void pa_sink_put(pa_sink* s) { + + pa_source_put(s->monitor_source); + ++ pa_core_update_default_sink(s->core); ++ + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s); + } +@@ -690,6 +692,11 @@ void pa_sink_unlink(pa_sink* s) { + pa_namereg_unregister(s->core, s->name); + pa_idxset_remove_by_data(s->core->sinks, s, NULL); + ++ if (s == s->core->configured_default_sink) ++ pa_core_set_configured_default_sink(s->core, NULL); ++ else ++ pa_core_update_default_sink(s->core); ++ + if (s->card) + pa_idxset_remove_by_data(s->card->sinks, s, NULL); + +diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c +index 3f0f53b52..ccf8efc91 100644 +--- a/src/pulsecore/source.c ++++ b/src/pulsecore/source.c +@@ -603,6 +603,8 @@ void pa_source_put(pa_source *s) { + else + pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0); + ++ pa_core_update_default_source(s->core); ++ + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s); + } +@@ -632,6 +634,11 @@ void pa_source_unlink(pa_source *s) { + pa_namereg_unregister(s->core, s->name); + pa_idxset_remove_by_data(s->core->sources, s, NULL); + ++ if (s == s->core->configured_default_source) ++ pa_core_set_configured_default_source(s->core, NULL); ++ else ++ pa_core_update_default_source(s->core); ++ + if (s->card) + pa_idxset_remove_by_data(s->card->sources, s, NULL); + +-- +2.14.3 + diff --git a/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch b/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch new file mode 100644 index 0000000..9569aff --- /dev/null +++ b/SOURCES/0004-core-device-port-check-availability-when-choosing-th.patch @@ -0,0 +1,70 @@ +From fa883e254c28a36657b0f28443bd69ee5a1821e0 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Thu, 16 Feb 2017 12:09:39 +0200 +Subject: [PATCH 4/4] core, device-port: check availability when choosing the + default device + +It doesn't make sense to use a sink or source whose active port is +unavailable, so let's take this into account when choosing the default +sink and source. +--- + src/pulsecore/core.c | 16 ++++++++++++++++ + src/pulsecore/device-port.c | 8 ++++++++ + 2 files changed, 24 insertions(+) + +diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c +index da1abb3ba..340b41ff3 100644 +--- a/src/pulsecore/core.c ++++ b/src/pulsecore/core.c +@@ -265,6 +265,14 @@ static int compare_sinks(pa_sink *a, pa_sink *b) { + + core = a->core; + ++ /* Available sinks always beat unavailable sinks. */ ++ if (a->active_port && a->active_port->available == PA_AVAILABLE_NO ++ && (!b->active_port || b->active_port->available != PA_AVAILABLE_NO)) ++ return -1; ++ if (b->active_port && b->active_port->available == PA_AVAILABLE_NO ++ && (!a->active_port || a->active_port->available != PA_AVAILABLE_NO)) ++ return 1; ++ + /* The configured default sink is preferred over any other sink. */ + if (b == core->configured_default_sink) + return -1; +@@ -331,6 +339,14 @@ static int compare_sources(pa_source *a, pa_source *b) { + + core = a->core; + ++ /* Available sources always beat unavailable sources. */ ++ if (a->active_port && a->active_port->available == PA_AVAILABLE_NO ++ && (!b->active_port || b->active_port->available != PA_AVAILABLE_NO)) ++ return -1; ++ if (b->active_port && b->active_port->available == PA_AVAILABLE_NO ++ && (!a->active_port || a->active_port->available != PA_AVAILABLE_NO)) ++ return 1; ++ + /* The configured default source is preferred over any other source. */ + if (b == core->configured_default_source) + return -1; +diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c +index 7c9ddf325..76a7e80a1 100644 +--- a/src/pulsecore/device-port.c ++++ b/src/pulsecore/device-port.c +@@ -93,6 +93,14 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) { + * be created before port objects, and then p->card could be non-NULL for + * the whole lifecycle of pa_device_port. */ + if (p->card) { ++ /* A sink or source whose active port is unavailable can't be the ++ * default sink/source, so port availability changes may affect the ++ * default sink/source choice. */ ++ if (p->direction == PA_DIRECTION_OUTPUT) ++ pa_core_update_default_sink(p->core); ++ else ++ pa_core_update_default_source(p->core); ++ + pa_subscription_post(p->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index); + pa_hook_fire(&p->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p); + } +-- +2.14.3 + diff --git a/SOURCES/add-dell-dock-conf.path b/SOURCES/add-dell-dock-conf.path new file mode 100644 index 0000000..663fe18 --- /dev/null +++ b/SOURCES/add-dell-dock-conf.path @@ -0,0 +1,18 @@ +--- pulseaudio-10.0/src/Makefile.in 2017-01-18 04:54:18.000000000 +0100 ++++ pulseaudio-10.0-new/src/Makefile.in 2018-01-16 11:45:09.881076974 +0100 +@@ -3009,6 +3009,7 @@ + modules/alsa/mixer/paths/hdmi-output-7.conf + am__dist_alsaprofilesets_DATA_DIST = \ + modules/alsa/mixer/profile-sets/default.conf \ ++ modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \ + modules/alsa/mixer/profile-sets/force-speaker.conf \ + modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf \ + modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \ +@@ -4244,6 +4245,7 @@ + libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la + @HAVE_ALSA_TRUE@dist_alsaprofilesets_DATA = \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/default.conf \ ++@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/force-speaker.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \ diff --git a/SOURCES/default.pa-for-gdm b/SOURCES/default.pa-for-gdm new file mode 100644 index 0000000..d633aee --- /dev/null +++ b/SOURCES/default.pa-for-gdm @@ -0,0 +1,10 @@ +load-module module-device-restore +load-module module-card-restore +load-module module-udev-detect +load-module module-native-protocol-unix +load-module module-default-device-restore +load-module module-rescue-streams +load-module module-always-sink +load-module module-intended-roles +load-module module-suspend-on-idle +load-module module-position-event-sounds diff --git a/SOURCES/pulseaudio-10.0.tar.xz.md5 b/SOURCES/pulseaudio-10.0.tar.xz.md5 new file mode 100644 index 0000000..2f9b45d --- /dev/null +++ b/SOURCES/pulseaudio-10.0.tar.xz.md5 @@ -0,0 +1 @@ +4950d2799bf55ab91f6b7f990b7f0971 pulseaudio-10.0.tar.xz diff --git a/SOURCES/pulseaudio-10.0.tar.xz.sha1 b/SOURCES/pulseaudio-10.0.tar.xz.sha1 new file mode 100644 index 0000000..56e164f --- /dev/null +++ b/SOURCES/pulseaudio-10.0.tar.xz.sha1 @@ -0,0 +1 @@ +ab7cc41a2dc2b9da0794e3a51a4eb7e82e7da511 pulseaudio-10.0.tar.xz diff --git a/SOURCES/pulseaudio-8.99.2-getaffinity.patch b/SOURCES/pulseaudio-8.99.2-getaffinity.patch new file mode 100644 index 0000000..adc0f14 --- /dev/null +++ b/SOURCES/pulseaudio-8.99.2-getaffinity.patch @@ -0,0 +1,12 @@ +diff -up pulseaudio-8.99.2/src/tests/once-test.c.than pulseaudio-8.99.2/src/tests/once-test.c +--- pulseaudio-8.99.2/src/tests/once-test.c.than 2016-06-22 10:20:57.127583628 -0400 ++++ pulseaudio-8.99.2/src/tests/once-test.c 2016-06-22 10:59:38.905573634 -0400 +@@ -70,7 +70,7 @@ static void thread_func(void *data) { + #endif + + CPU_ZERO(&mask); +- CPU_SET((size_t) (pa_atomic_inc(&i_cpu) % n_cpu), &mask); ++ CPU_SET(pthread_getaffinity_np(pthread_self(), sizeof(mask), &mask), &mask); + fail_unless(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0); + #endif + diff --git a/SOURCES/pulseaudio-9.0-disable_flat_volumes.patch b/SOURCES/pulseaudio-9.0-disable_flat_volumes.patch new file mode 100644 index 0000000..3e489d6 --- /dev/null +++ b/SOURCES/pulseaudio-9.0-disable_flat_volumes.patch @@ -0,0 +1,48 @@ +diff -up pulseaudio-8.99.2/man/pulse-daemon.conf.5.xml.in.disable_flat_volumes pulseaudio-8.99.2/man/pulse-daemon.conf.5.xml.in +--- pulseaudio-8.99.2/man/pulse-daemon.conf.5.xml.in.disable_flat_volumes 2016-05-26 23:21:17.000000000 -0500 ++++ pulseaudio-8.99.2/man/pulse-daemon.conf.5.xml.in 2016-05-31 10:01:55.679976730 -0500 +@@ -220,7 +220,7 @@ License along with PulseAudio; if not, s +

flat-volumes= Enable 'flat' volumes, i.e. where + possible let the sink volume equal the maximum of the volumes of + the inputs connected to it. Takes a boolean argument, defaults +- to yes.

++ to no.

+ + + +diff -up pulseaudio-8.99.2/src/daemon/daemon-conf.c.disable_flat_volumes pulseaudio-8.99.2/src/daemon/daemon-conf.c +--- pulseaudio-8.99.2/src/daemon/daemon-conf.c.disable_flat_volumes 2016-05-26 23:21:17.000000000 -0500 ++++ pulseaudio-8.99.2/src/daemon/daemon-conf.c 2016-05-31 10:01:55.680976735 -0500 +@@ -68,7 +68,7 @@ static const pa_daemon_conf default_conf + .realtime_priority = 5, /* Half of JACK's default rtprio */ + .disallow_module_loading = false, + .disallow_exit = false, +- .flat_volumes = true, ++ .flat_volumes = false, + .exit_idle_time = 20, + .scache_idle_time = 20, + .script_commands = NULL, +diff -up pulseaudio-8.99.2/src/daemon/daemon.conf.in.disable_flat_volumes pulseaudio-8.99.2/src/daemon/daemon.conf.in +--- pulseaudio-8.99.2/src/daemon/daemon.conf.in.disable_flat_volumes 2016-05-31 10:01:55.680976735 -0500 ++++ pulseaudio-8.99.2/src/daemon/daemon.conf.in 2016-05-31 10:02:28.048133267 -0500 +@@ -57,7 +57,7 @@ ifelse(@HAVE_DBUS@, 1, [dnl + ; enable-lfe-remixing = no + ; lfe-crossover-freq = 0 + +-; flat-volumes = yes ++; flat-volumes = no + + ifelse(@HAVE_SYS_RESOURCE_H@, 1, [dnl + ; rlimit-fsize = -1 +diff -up pulseaudio-8.99.2/src/pulsecore/core.c.disable_flat_volumes pulseaudio-8.99.2/src/pulsecore/core.c +--- pulseaudio-8.99.2/src/pulsecore/core.c.disable_flat_volumes 2016-05-26 23:21:17.000000000 -0500 ++++ pulseaudio-8.99.2/src/pulsecore/core.c 2016-05-31 10:01:55.681976740 -0500 +@@ -135,7 +135,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, + c->exit_idle_time = -1; + c->scache_idle_time = 20; + +- c->flat_volumes = true; ++ c->flat_volumes = false; + c->disallow_module_loading = false; + c->disallow_exit = false; + c->running_as_daemon = false; diff --git a/SOURCES/pulseaudio-autostart.patch b/SOURCES/pulseaudio-autostart.patch new file mode 100644 index 0000000..eb44bdb --- /dev/null +++ b/SOURCES/pulseaudio-autostart.patch @@ -0,0 +1,13 @@ +diff -up pulseaudio-6.0/src/daemon/start-pulseaudio-x11.in.autostart pulseaudio-6.0/src/daemon/start-pulseaudio-x11.in +--- pulseaudio-6.0/src/daemon/start-pulseaudio-x11.in.autostart 2015-02-12 08:10:35.000000000 -0600 ++++ pulseaudio-6.0/src/daemon/start-pulseaudio-x11.in 2015-06-22 11:24:13.561614127 -0500 +@@ -17,6 +17,9 @@ + + set -e + ++# probe to test if autospawn works, else resort to starting manually ++@PACTL_BINARY@ info > /dev/null 2>&1 || @PA_BINARY@ --start "$@" ++ + if [ x"$DISPLAY" != x ] ; then + + @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null diff --git a/SPECS/pulseaudio.spec b/SPECS/pulseaudio.spec new file mode 100644 index 0000000..e7484ba --- /dev/null +++ b/SPECS/pulseaudio.spec @@ -0,0 +1,1140 @@ +%global pa_major 10.0 +#global pa_minor 0 + +#global snap 20141103 +#global gitrel 327 +#global gitcommit aec811798cd883a454b9b5cd82c77831906bbd2d +#global shortcommit (c=%{gitcommit}; echo ${c:0:5}) + +%ifarch x86_64 %{arm} +%global with_webrtc 1 +%endif + +# https://bugzilla.redhat.com/983606 +%global _hardened_build 1 + +## enable systemd activation +%global systemd 1 + +## comment to disable tests +#global tests 1 + +# where/how to apply multilib hacks +%global multilib_archs x86_64 %{ix86} ppc64 ppc s390x s390 sparc64 sparcv9 ppc64le + +Name: pulseaudio +Summary: Improved Linux Sound Server +Version: %{pa_major}%{?pa_minor:.%{pa_minor}} +Release: 5%{?snap:.%{snap}git%{shortcommit}}%{?dist} +License: LGPLv2+ +URL: http://www.freedesktop.org/wiki/Software/PulseAudio +%if 0%{?gitrel} +# git clone git://anongit.freedesktop.org/pulseaudio/pulseaudio +# cd pulseaudio; git reset --hard %{gitcommit}; ./autogen.sh; make; make distcheck +Source0: pulseaudio-%{version}-%{gitrel}-g%{shortcommit}.tar.xz +%else +Source0: http://freedesktop.org/software/pulseaudio/releases/pulseaudio-%{version}.tar.xz +Source1: http://freedesktop.org/software/pulseaudio/releases/pulseaudio-%{version}.tar.xz.md5 +Source2: http://freedesktop.org/software/pulseaudio/releases/pulseaudio-%{version}.tar.xz.sha1 +%endif + +Source5: default.pa-for-gdm + +# revert upstream commit to rely solely on autospawn for autostart, instead +# include a fallback to manual launch when autospawn fails, like when +# user disables autospawn, or logging in as root +Patch1: pulseaudio-autostart.patch + +# disable flat-volumes by default +# https://bugzilla.redhat.com/show_bug.cgi?id=1265267 +Patch2: pulseaudio-9.0-disable_flat_volumes.patch + +# bz#1067470, only start threads on activ CPUs +# see also https://bugs.freedesktop.org/show_bug.cgi?id=96638 +Patch3: pulseaudio-8.99.2-getaffinity.patch + +## upstream patches +Patch101: 0001-alsa-mixer-Add-support-for-usb-audio-in-the-Dell-doc.patch +Patch102: 0002-sink-source-update-the-default-sink-source-on-port-s.patch +Patch103: 0003-improve-default-sink-source-handling.patch +Patch104: 0004-core-device-port-check-availability-when-choosing-th.patch +Patch105: add-dell-dock-conf.path + +## upstreamable patches + +BuildRequires: automake libtool +BuildRequires: pkgconfig(bash-completion) +%global bash_completionsdir %(pkg-config --variable=completionsdir bash-completion 2>/dev/null || echo '/etc/bash_completion.d') +BuildRequires: m4 +BuildRequires: libtool-ltdl-devel +BuildRequires: intltool +BuildRequires: pkgconfig +BuildRequires: doxygen +BuildRequires: xmltoman +BuildRequires: tcp_wrappers-devel +BuildRequires: libsndfile-devel +BuildRequires: alsa-lib-devel +BuildRequires: glib2-devel +BuildRequires: gtk2-devel +BuildRequires: GConf2-devel +BuildRequires: avahi-devel +%if 0%{?fedora} +%global enable_lirc 1 +%global enable_jack 1 +%endif +BuildRequires: libatomic_ops-static, libatomic_ops-devel +%ifnarch s390 s390x +%global bluez5 1 +BuildRequires: pkgconfig(bluez) >= 5.0 +BuildRequires: sbc-devel +%endif +BuildRequires: libXt-devel +BuildRequires: xorg-x11-proto-devel +BuildRequires: libXtst-devel +BuildRequires: libXi-devel +BuildRequires: libSM-devel +BuildRequires: libX11-devel +BuildRequires: libICE-devel +BuildRequires: xcb-util-devel +BuildRequires: openssl-devel +BuildRequires: orc-devel +BuildRequires: libtdb-devel +%if 0%{?fedora} +BuildRequires: pkgconfig(soxr) +%endif +BuildRequires: pkgconfig(speexdsp) >= 1.2 +BuildRequires: libasyncns-devel +BuildRequires: systemd-devel >= 184 +BuildRequires: dbus-devel +BuildRequires: libcap-devel +BuildRequires: pkgconfig(fftw3f) +%if 0%{?with_webrtc} +BuildRequires: pkgconfig(webrtc-audio-processing) >= 0.2 +%endif +%if 0%{?tests} +BuildRequires: pkgconfig(check) +%endif + +# retired along with -libs-zeroconf, add Obsoletes here for lack of anything better +Obsoletes: padevchooser < 1.0 +Requires(pre): shadow-utils +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: systemd >= 184 +Requires: rtkit + +%description +PulseAudio is a sound server for Linux and other Unix like operating +systems. It is intended to be an improved drop-in replacement for the +Enlightened Sound Daemon (ESOUND). + +%package qpaeq +Summary: Pulseaudio equalizer interface +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: PyQt4 +Requires: dbus-python +%description qpaeq +qpaeq is a equalizer interface for pulseaudio's equalizer sinks. + +%package esound-compat +Summary: PulseAudio EsounD daemon compatibility script +Requires: %{name}%{?_isa} = %{version}-%{release} +%description esound-compat +A compatibility script that allows applications to call /usr/bin/esd +and start PulseAudio with EsounD protocol modules. + +%if 0%{?enable_lirc} +%package module-lirc +Summary: LIRC support for the PulseAudio sound server +BuildRequires: lirc-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description module-lirc +LIRC volume control module for the PulseAudio sound server. +%endif + +%package module-x11 +Summary: X11 support for the PulseAudio sound server +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-utils + +%description module-x11 +X11 bell and security modules for the PulseAudio sound server. + +%package module-zeroconf +Summary: Zeroconf support for the PulseAudio sound server +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-utils + +%description module-zeroconf +Zeroconf publishing module for the PulseAudio sound server. + +%if 0%{?bluez4} || 0%{?bluez5} +%package module-bluetooth +Summary: Bluetooth support for the PulseAudio sound server +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: bluez%{?bluez5: >= 5.0} + +%description module-bluetooth +Contains Bluetooth audio (A2DP/HSP/HFP) support for the PulseAudio sound server. +%endif + +%if 0%{?enable_jack} +%package module-jack +Summary: JACK support for the PulseAudio sound server +BuildRequires: jack-audio-connection-kit-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description module-jack +JACK sink and source modules for the PulseAudio sound server. +%endif + +%package module-gconf +Summary: GConf support for the PulseAudio sound server +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description module-gconf +GConf configuration backend for the PulseAudio sound server. + +%package libs +Summary: Libraries for PulseAudio clients +License: LGPLv2+ +Obsoletes: pulseaudio-libs-zeroconf < 1.1 + +%description libs +This package contains the runtime libraries for any application that wishes +to interface with a PulseAudio sound server. + +%package libs-glib2 +Summary: GLIB 2.x bindings for PulseAudio clients +License: LGPLv2+ +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description libs-glib2 +This package contains bindings to integrate the PulseAudio client library with +a GLIB 2.x based application. + +%package libs-devel +Summary: Headers and libraries for PulseAudio client development +License: LGPLv2+ +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs-glib2%{?_isa} = %{version}-%{release} +%description libs-devel +Headers and libraries for developing applications that can communicate with +a PulseAudio sound server. + +%package utils +Summary: PulseAudio sound server utilities +License: LGPLv2+ +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +# when made non-multilib'd, https://bugzilla.redhat.com/891425 +Obsoletes: pulseaudio-utils < 3.0-3 + +%description utils +This package contains command line utilities for the PulseAudio sound server. + +%package gdm-hooks +Summary: PulseAudio GDM integration +License: LGPLv2+ +Requires: gdm >= 1:2.22.0 +# for the gdm user +Requires(pre): gdm + +%description gdm-hooks +This package contains GDM integration hooks for the PulseAudio sound server. + + +%prep +%setup -q -T -b0 -n %{name}-%{version}%{?gitrel:-%{gitrel}-g%{shortcommit}} + +%patch1 -p1 -b .autostart +%patch2 -p1 -b .disable_flat_volumes +%patch3 -p1 -b .affinity +%patch101 -p1 -b .101 +%patch102 -p1 -b .102 +%patch103 -p1 -b .103 +%patch104 -p1 -b .104 +%patch105 -p1 -b .105 + +sed -i.no_consolekit -e \ + 's/^load-module module-console-kit/#load-module module-console-kit/' \ + src/daemon/default.pa.in + +%if 0%{?gitrel:1} +# fixup PACKAGE_VERSION that leaks into pkgconfig files and friends +sed -i.PACKAGE_VERSION -e "s|^PACKAGE_VERSION=.*|PACKAGE_VERSION=\'%{version}\'|" configure +%else +## kill rpaths +%if "%{_libdir}" != "/usr/lib" +sed -i -e 's|"/lib /usr/lib|"/%{_lib} %{_libdir}|' configure +%endif +%endif + + +%build +%configure \ + --disable-silent-rules \ + --disable-static \ + --disable-rpath \ + --with-system-user=pulse \ + --with-system-group=pulse \ + --with-access-group=pulse-access \ + --disable-oss-output \ + %{?enable_jack:--enable-jack}%{!?enable_jack:--disable-jack} \ + %{?enable_lirc:--enable-lirc}%{!?enable_lirc:--disable-lirc} \ + %{?bluez4:--enable-bluez4}%{!?bluez4:--disable-bluez4} \ + %{?bluez5:--enable-bluez5}%{!?bluez5:--disable-bluez5} \ +%ifarch %{arm} + --disable-neon-opt \ +%endif +%if 0%{?with_webrtc} + --enable-webrtc-aec \ +%endif + %{!?systemd:--disable-systemd-daemon} \ + %{?tests:--enable-tests} + +# we really should preopen here --preopen-mods=module-udev-detect.la, --force-preopen +make %{?_smp_mflags} V=1 +make doxygen + + +%install +make install DESTDIR=$RPM_BUILD_ROOT + +## padsp multilib hack alert +%ifarch %{multilib_archs} +pushd %{buildroot}%{_bindir} +# make 32 bit version available as padsp-32 +# %%{_libdir} == /usr/lib may be a naive check for 32bit-ness +# but should be the only case we care about here -- rex +%if "%{_libdir}" == "/usr/lib" +ln -s padsp padsp-32 +%else +cp -a padsp padsp-32 +sed -i -e "s|%{_libdir}/pulseaudio/libpulsedsp.so|/usr/lib/pulseaudio/libpulsedsp.so|g" padsp-32 +%endif +popd +%endif + +# upstream should use udev.pc +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/udev/rules.d +mv -fv $RPM_BUILD_ROOT/lib/udev/rules.d/90-pulseaudio.rules $RPM_BUILD_ROOT%{_prefix}/lib/udev/rules.d + +# /var/lib/pulse seems unused, can consider dropping it? -- rex +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/pulse +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/pulse +install -p -m644 -D %{SOURCE5} $RPM_BUILD_ROOT%{_localstatedir}/lib/gdm/.pulse/default.pa + +## unpackaged files +# extraneous libtool crud +rm -fv $RPM_BUILD_ROOT%{_libdir}/lib*.la +rm -fv $RPM_BUILD_ROOT%{_libdir}/pulseaudio/lib*.la +rm -fv $RPM_BUILD_ROOT%{_libdir}/pulse-%{pa_major}/modules/*.la +# PA_MODULE_DEPRECATED("Please use module-udev-detect instead of module-detect!"); +rm -fv $RPM_BUILD_ROOT%{_libdir}/pulse-%{pa_major}/modules/module-detect.so + +%find_lang %{name} + + +%check +%if 0%{?tests} +make %{?_smp_mflags} check +%endif + + +%pre +getent group pulse-access >/dev/null || groupadd -r pulse-access +getent group pulse-rt >/dev/null || groupadd -r pulse-rt +getent group pulse >/dev/null || groupadd -f -g 171 -r pulse +if ! getent passwd pulse >/dev/null ; then + if ! getent passwd 171 >/dev/null ; then + useradd -r -u 171 -g pulse -d %{_localstatedir}/run/pulse -s /sbin/nologin -c "PulseAudio System Daemon" pulse + else + useradd -r -g pulse -d %{_localstatedir}/run/pulse -s /sbin/nologin -c "PulseAudio System Daemon" pulse + fi +fi +exit 0 + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%posttrans +# handle renamed module-cork-music-on-phone => module-role-cork +(grep '^load-module module-cork-music-on-phone$' %{_sysconfdir}/pulse/default.pa > /dev/null && \ + sed -i.rpmsave -e 's|^load-module module-cork-music-on-phone$|load-module module-role-cork|' \ + %{_sysconfdir}/pulse/default.pa +) ||: + +%files +%doc README LICENSE GPL LGPL +%config(noreplace) %{_sysconfdir}/pulse/daemon.conf +%config(noreplace) %{_sysconfdir}/pulse/default.pa +%config(noreplace) %{_sysconfdir}/pulse/system.pa +%{_sysconfdir}/dbus-1/system.d/pulseaudio-system.conf +%{bash_completionsdir}/* +%if 0%{?systemd} +%{_userunitdir}/pulseaudio.* +%endif +%{_bindir}/pulseaudio +%{_libdir}/pulseaudio/libpulsecore-%{pa_major}.so +%dir %{_libdir}/pulse-%{pa_major}/ +%dir %{_libdir}/pulse-%{pa_major}/modules/ +%{_libdir}/pulse-%{pa_major}/modules/libalsa-util.so +%{_libdir}/pulse-%{pa_major}/modules/libcli.so +%{_libdir}/pulse-%{pa_major}/modules/libprotocol-cli.so +%{_libdir}/pulse-%{pa_major}/modules/libprotocol-esound.so +%{_libdir}/pulse-%{pa_major}/modules/libprotocol-http.so +%{_libdir}/pulse-%{pa_major}/modules/libprotocol-native.so +%{_libdir}/pulse-%{pa_major}/modules/libprotocol-simple.so +%{_libdir}/pulse-%{pa_major}/modules/librtp.so +%if 0%{?with_webrtc} +%{_libdir}/pulse-%{pa_major}/modules/libwebrtc-util.so +%endif +%{_libdir}/pulse-%{pa_major}/modules/module-allow-passthrough.so +%{_libdir}/pulse-%{pa_major}/modules/module-alsa-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-alsa-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-alsa-card.so +%{_libdir}/pulse-%{pa_major}/modules/module-cli-protocol-tcp.so +%{_libdir}/pulse-%{pa_major}/modules/module-cli-protocol-unix.so +%{_libdir}/pulse-%{pa_major}/modules/module-cli.so +%{_libdir}/pulse-%{pa_major}/modules/module-combine.so +%{_libdir}/pulse-%{pa_major}/modules/module-combine-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-dbus-protocol.so +%{_libdir}/pulse-%{pa_major}/modules/module-filter-apply.so +%{_libdir}/pulse-%{pa_major}/modules/module-filter-heuristics.so +%{_libdir}/pulse-%{pa_major}/modules/module-device-manager.so +%{_libdir}/pulse-%{pa_major}/modules/module-loopback.so +%{_libdir}/pulse-%{pa_major}/modules/module-esound-compat-spawnfd.so +%{_libdir}/pulse-%{pa_major}/modules/module-esound-compat-spawnpid.so +%{_libdir}/pulse-%{pa_major}/modules/module-esound-protocol-tcp.so +%{_libdir}/pulse-%{pa_major}/modules/module-esound-protocol-unix.so +%{_libdir}/pulse-%{pa_major}/modules/module-esound-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-udev-detect.so +%{_libdir}/pulse-%{pa_major}/modules/module-hal-detect.so +%{_libdir}/pulse-%{pa_major}/modules/module-http-protocol-tcp.so +%{_libdir}/pulse-%{pa_major}/modules/module-http-protocol-unix.so +%{_libdir}/pulse-%{pa_major}/modules/module-match.so +%{_libdir}/pulse-%{pa_major}/modules/module-mmkbd-evdev.so +%{_libdir}/pulse-%{pa_major}/modules/module-native-protocol-fd.so +%{_libdir}/pulse-%{pa_major}/modules/module-native-protocol-tcp.so +%{_libdir}/pulse-%{pa_major}/modules/module-native-protocol-unix.so +%{_libdir}/pulse-%{pa_major}/modules/module-null-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-null-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-pipe-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-pipe-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-remap-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-rescue-streams.so +%{_libdir}/pulse-%{pa_major}/modules/module-role-ducking.so +%{_libdir}/pulse-%{pa_major}/modules/module-rtp-recv.so +%{_libdir}/pulse-%{pa_major}/modules/module-rtp-send.so +%{_libdir}/pulse-%{pa_major}/modules/module-simple-protocol-tcp.so +%{_libdir}/pulse-%{pa_major}/modules/module-simple-protocol-unix.so +%{_libdir}/pulse-%{pa_major}/modules/module-sine.so +%{_libdir}/pulse-%{pa_major}/modules/module-switch-on-port-available.so +%{_libdir}/pulse-%{pa_major}/modules/module-systemd-login.so +%{_libdir}/pulse-%{pa_major}/modules/module-tunnel-sink-new.so +%{_libdir}/pulse-%{pa_major}/modules/module-tunnel-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-tunnel-source-new.so +%{_libdir}/pulse-%{pa_major}/modules/module-tunnel-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-volume-restore.so +%{_libdir}/pulse-%{pa_major}/modules/module-suspend-on-idle.so +%{_libdir}/pulse-%{pa_major}/modules/module-default-device-restore.so +%{_libdir}/pulse-%{pa_major}/modules/module-device-restore.so +%{_libdir}/pulse-%{pa_major}/modules/module-stream-restore.so +%{_libdir}/pulse-%{pa_major}/modules/module-card-restore.so +%{_libdir}/pulse-%{pa_major}/modules/module-ladspa-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-remap-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-always-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-console-kit.so +%{_libdir}/pulse-%{pa_major}/modules/module-position-event-sounds.so +%{_libdir}/pulse-%{pa_major}/modules/module-augment-properties.so +%{_libdir}/pulse-%{pa_major}/modules/module-role-cork.so +%{_libdir}/pulse-%{pa_major}/modules/module-sine-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-intended-roles.so +%{_libdir}/pulse-%{pa_major}/modules/module-rygel-media-server.so +%{_libdir}/pulse-%{pa_major}/modules/module-echo-cancel.so +%{_libdir}/pulse-%{pa_major}/modules/module-switch-on-connect.so +%{_libdir}/pulse-%{pa_major}/modules/module-virtual-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-virtual-source.so +%{_libdir}/pulse-%{pa_major}/modules/module-virtual-surround-sink.so +%dir %{_datadir}/pulseaudio/ +%dir %{_datadir}/pulseaudio/alsa-mixer/ +%{_datadir}/pulseaudio/alsa-mixer/paths/ +%{_datadir}/pulseaudio/alsa-mixer/profile-sets/ +%{_mandir}/man1/pulseaudio.1* +%{_mandir}/man5/default.pa.5* +%{_mandir}/man5/pulse-cli-syntax.5* +%{_mandir}/man5/pulse-client.conf.5* +%{_mandir}/man5/pulse-daemon.conf.5* +%{_prefix}/lib/udev/rules.d/90-pulseaudio.rules +%dir %{_libexecdir}/pulse +%attr(0700, pulse, pulse) %dir %{_localstatedir}/lib/pulse +%attr(0700, pulse, pulse) %dir %{_localstatedir}/run/pulse +%dir %{_datadir}/zsh/ +%dir %{_datadir}/zsh/site-functions/ +%{_datadir}/zsh/site-functions/_pulseaudio + +%files qpaeq +%{_bindir}/qpaeq +%{_libdir}/pulse-%{pa_major}/modules/module-equalizer-sink.so + +%files esound-compat +%{_bindir}/esdcompat +%{_mandir}/man1/esdcompat.1.gz + +%if 0%{?enable_lirc} +%files module-lirc +%{_libdir}/pulse-%{pa_major}/modules/module-lirc.so +%endif + +%files module-x11 +%{_sysconfdir}/xdg/autostart/pulseaudio.desktop +#{_bindir}/start-pulseaudio-kde +%{_bindir}/start-pulseaudio-x11 +%{_libdir}/pulse-%{pa_major}/modules/module-x11-bell.so +%{_libdir}/pulse-%{pa_major}/modules/module-x11-publish.so +%{_libdir}/pulse-%{pa_major}/modules/module-x11-xsmp.so +%{_libdir}/pulse-%{pa_major}/modules/module-x11-cork-request.so +%{_mandir}/man1/start-pulseaudio-x11.1.gz + +%files module-zeroconf +%{_libdir}/pulse-%{pa_major}/modules/libavahi-wrap.so +%{_libdir}/pulse-%{pa_major}/modules/module-zeroconf-publish.so +%{_libdir}/pulse-%{pa_major}/modules/module-zeroconf-discover.so +%{_libdir}/pulse-%{pa_major}/modules/libraop.so +%{_libdir}/pulse-%{pa_major}/modules/module-raop-discover.so +%{_libdir}/pulse-%{pa_major}/modules/module-raop-sink.so + +%if 0%{?enable_jack} +%files module-jack +%{_libdir}/pulse-%{pa_major}/modules/module-jackdbus-detect.so +%{_libdir}/pulse-%{pa_major}/modules/module-jack-sink.so +%{_libdir}/pulse-%{pa_major}/modules/module-jack-source.so +%endif + +%if 0%{?bluez4} || 0%{?bluez5} +%files module-bluetooth +%{_libdir}/pulse-%{pa_major}/modules/libbluez*-util.so +%{_libdir}/pulse-%{pa_major}/modules/module-bluez*-device.so +%{_libdir}/pulse-%{pa_major}/modules/module-bluez*-discover.so +%{_libdir}/pulse-%{pa_major}/modules/module-bluetooth-discover.so +%{_libdir}/pulse-%{pa_major}/modules/module-bluetooth-policy.so +%endif + +%files module-gconf +%{_libdir}/pulse-%{pa_major}/modules/module-gconf.so +%{_libexecdir}/pulse/gconf-helper + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig + +%files libs -f %{name}.lang +%doc README LICENSE GPL LGPL +%dir %{_sysconfdir}/pulse/ +%config(noreplace) %{_sysconfdir}/pulse/client.conf +%{_libdir}/libpulse.so.0* +%{_libdir}/libpulse-simple.so.0* +%dir %{_libdir}/pulseaudio/ +%{_libdir}/pulseaudio/libpulsecommon-%{pa_major}.so +%{_libdir}/pulseaudio/libpulsedsp.so + +%post libs-glib2 -p /sbin/ldconfig +%postun libs-glib2 -p /sbin/ldconfig + +%files libs-glib2 +%{_libdir}/libpulse-mainloop-glib.so.0* + +%files libs-devel +%doc doxygen/html +%{_includedir}/pulse/ +%{_libdir}/libpulse.so +%{_libdir}/libpulse-mainloop-glib.so +%{_libdir}/libpulse-simple.so +%{_libdir}/pkgconfig/libpulse*.pc +%dir %{_datadir}/vala +%dir %{_datadir}/vala/vapi +%{_datadir}/vala/vapi/libpulse.vapi +%{_datadir}/vala/vapi/libpulse.deps +%{_datadir}/vala/vapi/libpulse-mainloop-glib.vapi +%{_datadir}/vala/vapi/libpulse-mainloop-glib.deps +%{_datadir}/vala/vapi/libpulse-simple.deps +%{_datadir}/vala/vapi/libpulse-simple.vapi + +%dir %{_libdir}/cmake +%{_libdir}/cmake/PulseAudio/ + +%files utils +%{_bindir}/pacat +%{_bindir}/pacmd +%{_bindir}/pactl +%{_bindir}/paplay +%{_bindir}/parec +%{_bindir}/pamon +%{_bindir}/parecord +%{_bindir}/pax11publish +%{_bindir}/padsp +%ifarch %{multilib_archs} +%{_bindir}/padsp-32 +%endif +%{_bindir}/pasuspender +%{_mandir}/man1/pacat.1* +%{_mandir}/man1/pacmd.1* +%{_mandir}/man1/pactl.1* +%{_mandir}/man1/padsp.1* +%{_mandir}/man1/pamon.1* +%{_mandir}/man1/paplay.1* +%{_mandir}/man1/parec.1* +%{_mandir}/man1/parecord.1* +%{_mandir}/man1/pasuspender.1* +%{_mandir}/man1/pax11publish.1* + +## pulseaudio should be using .config/pulse/ these days anyway +## TODO: move this to gdm packaging under /var/lib/gdm/.config/pulse -- rex +%files gdm-hooks +%attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.pulse +%attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.pulse/default.pa + +%changelog +* Tue Jan 16 2018 Wim Taymans - 10.0-5 +- Dist the new config file for Dell dock TB16 +- Resolves: #1457385 + +* Wed Aug 09 2017 Wim Taymans - 10.0-4 +- Add support for usb audio in the Dell dock TB16 +- Add patches to improve default sinks +- Resolves: #1457385 + +* Thu Mar 09 2017 Wim Taymans - 10.0-3 +- Add more Requires to avoid testing multiple versions +- Resolves: #1387036 + +* Thu Feb 09 2017 Wim Taymans - 10.0-2 +- enable webrtc +- Resolves: #1387036 + +* Thu Jan 19 2017 Kalev Lember - 10.0-1 +- Update to 10.0 +- Resolves: #1387036 + +* Mon Jun 27 2016 Wim Taymans - 6.0-8 +- update translations +- Resolves: #1272897 + +* Mon Jun 22 2015 Rex Dieter - 6.0-7 +- better autostart.patch, handle case were autospawn is disabled + (or otherwise doesn't work, like for root user) +- Resolves: #1269104 + +* Fri May 8 2015 Wim Taymans - 6.0-6 +- build against bluez5 +- disable ofono backend +- Resolves: #1174548 + +* Fri May 8 2015 Wim Taymans - 6.0-5 +- Add more Requires to avoid testing multiple versions for qpaeq +- Resolves: #1174548 + +* Wed May 6 2015 Wim Taymans - 6.0-4 +- Add more Requires to avoid testing multiple versions +- enable hardened build +- Fix missing %endif +- Resolves: #1174548 + +* Thu Mar 26 2015 Wim Taymans 6.0-3 +- Avoid multilib conflict in /usr/bin/padsp +- Add korean translation +- Resolves: #1174548 + +* Thu Mar 19 2015 Richard Hughes 6.0-2 +- pulseaudio-6.0 (#1192384) +- Resolves: #1174548 + +* Fri May 03 2013 Rex Dieter 3.0-8 +- RFE: Restore the pipe-sink and pipe-source modules (#958949) + +* Thu Apr 11 2013 Rex Dieter 3.0-7 +- pull a few more patches from upstream stable-3.x branch + +* Fri Feb 08 2013 Rex Dieter 3.0-6 +- default.pa: fix for renamed modules (#908117) + +* Sat Jan 19 2013 Ville Skyttä - 3.0-5 +- Own the %%{_libdir}/pulseaudio dir. +- Fix bogus %%changelog dates. + +* Fri Jan 04 2013 Rex Dieter 3.0-4 +- alsa-mixer: Fix the analog-output-speaker-always path + +* Fri Jan 04 2013 Rex Dieter 3.0-3 +- move libpulsedsp plugin to -libs, avoids -utils multilib (#891425) + +* Wed Dec 19 2012 Dan Horák 3.0-2 +- SBC is needed only when BlueZ is used + +* Tue Dec 18 2012 Rex Dieter 3.0-1 +- pulseaudio-3.0 + +* Tue Dec 11 2012 Peter Robinson 2.99.3-1 +- PulseAudio 2.99.3 (3.0 rc3) + +* Wed Oct 10 2012 Dan Horák 2.1-4 +- fix the with_webrtc condition + +* Tue Oct 09 2012 Dan Horák 2.1-3 +- webrtc-aec is x86 and ARM only for now + +* Mon Oct 08 2012 Debarshi Ray 2.1-2 +- Enable webrtc-aec + +* Tue Sep 25 2012 Rex Dieter 2.1-1 +- pulseaudio-2.1 + +* Sat Jul 21 2012 Fedora Release Engineering - 2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Jun 23 2012 Kalev Lember - 2.0-3 +- Move module-jackdbus-detect.so to -module-jack subpackage with the + rest of the jack modules + +* Mon Jun 04 2012 Kay Sievers - 2.0-2 +- rebuild for libudev1 + +* Sat May 12 2012 Rex Dieter 2.0-1 +- pulseaudio-2.0 + +* Sat Apr 21 2012 Matthias Clasen - 1.1-9 +- Don't load the ck module in gdm, either + +* Tue Feb 28 2012 Bruno Wolff III - 1.1-8 +- Bring in Lennart's patch from f17 +- Temporary fix for CK/systemd move (#794690) + +* Tue Feb 28 2012 Bruno Wolff III - 1.1-7 +- Fix for building with gcc 4.7 + +* Mon Jan 23 2012 Dan Horák - 1.1-6 +- rebuilt for json-c-0.9-4.fc17 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Dec 13 2011 Adam Jackson 1.1-4 +- Fix RHEL build + +* Tue Nov 22 2011 Rex Dieter 1.1-3 +- Obsoletes: padevchooser < 1.0 + +* Thu Nov 10 2011 Rex Dieter 1.1-2 +- -libs: Obsoletes: pulseaudio-libs-zeroconf +- use versioned Obsoletes/Provides +- tighten subpkg deps via %%_isa +- remove autoconf/libtool hackery + +* Thu Nov 3 2011 Lennart Poettering - 1.1-1 +- New upstream release + +* Mon Aug 15 2011 Matthias Clasen - 0.9.23-1 +- Update to 0.9.23 + +* Thu Apr 7 2011 Peter Robinson - 0.9.22-5 +- Add upstream patch to fix compilation on ARM + +* Mon Mar 28 2011 Matthias Clasen - 0.9.22-4 +- Activate pulseaudio earlier during login + +* Wed Feb 09 2011 Fedora Release Engineering - 0.9.22-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sun Jan 30 2011 Ville Skyttä - 0.9.22-2 +- Own /usr/share/pulseaudio dirs. + +* Fri Nov 26 2010 Lennart Poettering - 0.9.22-1 +- New upstream release + +* Sun Nov 21 2010 Matěj Cepl - 0.9.21-7 +- Fix racy condition with patch by jkratoch (RHBZ# 643296). + +* Tue Feb 23 2010 Lennart Poettering - 0.9.21-6 +- backport another 30 fixes from upstream git + +* Sun Jan 17 2010 Lennart Poettering - 0.9.21-5 +- fix buffer flushing + +* Fri Jan 15 2010 Lennart Poettering - 0.9.21-4 +- backport 31 fixes from upstream git +- sync spec file with rhel + +* Tue Dec 8 2009 Michael Schwendt - 0.9.21-3 +- Explicitly BR libatomic_ops-static in accordance with the Packaging + Guidelines (libatomic_ops-devel is still static-only). + +* Wed Dec 02 2009 Rex Dieter - 0.9.21-2 +- module-device-manager, kde autostart bits missing (#541419) + +* Mon Nov 23 2009 Lennart Poettering - 0.9.21-1 +- New release + +* Wed Nov 11 2009 Lennart Poettering - 0.9.20-1 +- New release + +* Wed Nov 04 2009 Warren Togami - 0.9.19-2 +- Bug #532583 gdm should not require pulseaudio + +* Wed Sep 30 2009 Lennart Poettering - 0.9.19-1 +- New release + +* Sat Sep 19 2009 Lennart Poettering - 0.9.18-1 +- New release + +* Fri Sep 11 2009 Lennart Poettering 0.9.17-1 +- Final release + +* Thu Sep 10 2009 Lennart Poettering 0.9.16-14 +- Final release + +* Thu Sep 3 2009 Lennart Poettering 0.9.16-13.test7 +- Fix build for ppc + +* Thu Sep 3 2009 Lennart Poettering 0.9.16-12.test7 +- New test release + +* Thu Aug 27 2009 Tomas Mraz - 0.9.16-11.test6 +- rebuilt with new openssl + +* Mon Aug 24 2009 Lennart Poettering 0.9.16-10.test6 +- Fix build for ppc + +* Mon Aug 24 2009 Lennart Poettering 0.9.16-9.test6 +- New test release + +* Thu Aug 20 2009 Matthias Clasen - 0.9.16-7.test5 +- Fix install ordering between gdm and pulseaudio-gdm-hooks + +* Wed Aug 19 2009 Lennart Poettering 0.9.16-6.test5 +- New test release + +* Wed Aug 5 2009 Lennart Poettering 0.9.16-5.test4 +- New test release + +* Tue Jul 28 2009 Lennart Poettering 0.9.16-4.test3 +- New test release + +* Sun Jul 26 2009 Fedora Release Engineering - 0.9.16-3.test2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 2 2009 Lennart Poettering 0.9.16-2.test2 +- New test release + +* Tue Jun 23 2009 Lennart Poettering 0.9.16-1.test1 +- Fix endianess build + +* Tue Jun 23 2009 Lennart Poettering 0.9.16-0.test1 +- First 0.9.16 test release + +* Wed Apr 22 2009 Warren Togami 0.9.15-11 +- Bug #497214 + Do not start pulseaudio daemon if PULSE_SERVER directs pulse elsewhere. + +* Mon Apr 13 2009 Lennart Poettering 0.9.15-10 +- Final 0.9.15 release + +* Thu Apr 9 2009 Lennart Poettering 0.9.15-9.test8 +- New test release + +* Wed Apr 1 2009 Lennart Poettering 0.9.15-8.test7 +- Only load bt modules when installed + +* Wed Apr 1 2009 Lennart Poettering 0.9.15-7.test7 +- New test release + +* Wed Apr 1 2009 Lennart Poettering 0.9.15-6.test6 +- Fix mistag + +* Wed Apr 1 2009 Lennart Poettering 0.9.15-5.test6 +- Fix tarball name + +* Wed Apr 1 2009 Lennart Poettering 0.9.15-4.test6 +- New test release + +* Thu Mar 5 2009 Lennart Poettering 0.9.15-3.test5 +- New test release + +* Thu Mar 5 2009 Lennart Poettering 0.9.15-3.test4 +- New test release + +* Fri Feb 27 2009 Lennart Poettering 0.9.15-3.test3 +- Steal patch from git master to fix .so dependencies + +* Wed Feb 25 2009 Lennart Poettering 0.9.15-2.test3 +- Add more missing X11 dependencies + +* Wed Feb 25 2009 Lennart Poettering 0.9.15-1.test3 +- Add missing dependency on XTEST + +* Tue Feb 24 2009 Lennart Poettering 0.9.15-0.test3 +- New test release + +* Thu Feb 12 2009 Lennart Poettering 0.9.15-0.test2 +- New test release + +* Tue Jan 13 2009 Adel Gadllah 0.9.14-2 +- Prefer mixer controls with volumes over switches + +* Tue Jan 13 2009 Lennart Poettering 0.9.14-1 +- New release + +* Thu Nov 13 2008 Matthias Clasen 0.9.13-7 +- Rebuild + +* Sat Nov 1 2008 Lennart Poettering 0.9.13-6 +- Backport another two fixes from current git master + +* Tue Oct 28 2008 Matthias Clasen 0.9.13-5 +- Require new enough speex-devel + +* Fri Oct 24 2008 Lennart Poettering 0.9.13-4 +- Backport another fix from current git master + +* Thu Oct 23 2008 Lennart Poettering 0.9.13-3 +- Backport a couple of fixes from current git master + +* Thu Oct 9 2008 Matthhias Clasen 0.9.13-2 +- Handle locales properly + +* Mon Oct 6 2008 Lennart Poettering 0.9.13-1 +- New release + +* Mon Sep 15 2008 Matthias Clasen 0.9.12-6 +- Survive a missing ~/.pulse (#462407) + +* Thu Sep 11 2008 - Bastien Nocera 0.9.12-5 +- Rebuild + +* Tue Sep 9 2008 Lennart Poettering 0.9.12-4 +- Ship /var/lib/pulse in the RPM + +* Tue Sep 9 2008 Lennart Poettering 0.9.12-3 +- Don't remove pulse users/groups on package removal + +* Tue Sep 9 2008 Lennart Poettering 0.9.12-2 +- Add intltool to deps + +* Tue Sep 9 2008 Lennart Poettering 0.9.12-1 +- Release 0.9.12 + +* Thu Jul 24 2008 Lennart Poettering 0.9.11-1 +- Final release 0.9.11 + +* Tue Jul 22 2008 Jon McCann 0.9.11-0.7.git20080626 +- Fix for CK API changes + +* Thu Jun 26 2008 Lennart Poettering 0.9.11-0.6.git20080626 +- New GIT snapshot + +* Sun Jun 22 2008 Lennart Poettering 0.9.11-0.5.svn20080622 +- New GIT snapshot + +* Wed Jun 18 2008 Lennart Poettering 0.9.11-0.4.svn20080618 +- New SVN snapshot + +* Fri May 30 2008 Lennart Poettering 0.9.11-0.3.svn20080529 +- Fix snapshot versioning + +* Thu May 29 2008 Lennart Poettering 0.9.11-0.0.svn20080529 +- New SVN snapshot + +* Tue May 20 2008 Matthias Clasen 0.9.11-0.2.svn20080516 +- Actually apply the patch + +* Sat May 17 2008 Matthias Clasen 0.9.11-0.1.svn20080516 +- Fix a wrong assertion in module-default-device-restore + +* Fri May 16 2008 Matthias Clasen 0.9.11-0.0.svn20080516 +- Update to an svn snapshot of the 'glitch-free' rewrite of pulseaudio + +* Sun Mar 30 2008 Lennart Poettering 0.9.10-1 +- Update to PulseAudio 0.9.10 +- drop all patches, since they have been integrated upstream + +* Thu Mar 27 2008 Lubomir Kundrak 0.9.8-13 +- Abort on CPU time comsumption, so we can get core + +* Thu Mar 13 2008 Lubomir Kundrak 0.9.8-12 +- Own /usr/libexec/pulse (#437228) + +* Wed Mar 12 2008 Adam Jackson 0.9.8-11 +- pulseaudio-0.9.8-disable-realtime.patch: Don't ask PolicyKit for increased + scheduling mojo for now. It's not clear that it's a win; and if it is, + the policy should just be fixed to always allow it. + +* Wed Mar 12 2008 Lubomir Kundrak 0.9.8-10 +- Build the manual pages with xmltoman + +* Fri Feb 29 2008 Lubomir Kundrak 0.9.8-9 +- Fix the fix. + +* Fri Feb 29 2008 Lubomir Kundrak 0.9.8-8 +- Fix multilib issue (#228383) +- Prevent dumping core if exiting sooner that ltdl initializaion (#427962) + +* Thu Feb 21 2008 Adam Tkac 0.9.8-7 +- really rebuild against new libcap + +* Sun Feb 17 2008 Adam Tkac 0.9.8-6 +- rebuild against new libcap + +* Wed Jan 23 2008 Lubomir Kundrak 0.9.8-5 +- Fix CVE-2008-0008 security issue (#425481) + +* Sun Jan 13 2008 Lubomir Kundrak 0.9.8-4.1 +- Actually add content to pulseaudio-0.9.8-create-dot-pulse.patch +- Make the Source0 tag point to URL instead of a local file +- Drop the nochown patch; it's not applied at all and no longer needed + +* Thu Nov 29 2007 Lennart Poettering 0.9.8-4 +- add missing dependency on pulseaudio-utils for pulseaudio-module-x11 + +* Thu Nov 29 2007 Lennart Poettering 0.9.8-3 +- Create ~/.pulse/ if not existant + +* Thu Nov 29 2007 Lennart Poettering 0.9.8-2 +- Add missing dependency on jack-audio-connection-kit-devel + +* Wed Nov 28 2007 Lennart Poettering 0.9.8-1 +- Upgrade to current upstream + +* Wed Oct 17 2007 Lennart Poettering 0.9.7-0.16.svn20071017 +- Another SVN snapshot, fixing another round of bugs (#330541) +- Split libpulscore into a seperate package to work around multilib limitation (#335011) + +* Mon Oct 1 2007 Lennart Poettering 0.9.7-0.15.svn20071001 +- Another SVN snapshot, fixing another round of bugs + +* Sat Sep 29 2007 Lennart Poettering 0.9.7-0.14.svn20070929 +- Another SVN snapshot, fixing a couple of subtle bugs + +* Tue Sep 25 2007 Lennart Poettering 0.9.7-0.13.svn20070925 +- Remove libpulsecore.so symlink from pulseaudio-libs-devel to avoid multilib issues + +* Tue Sep 25 2007 Lennart Poettering 0.9.7-0.12.svn20070925 +- New SVN snapshot +- Split off libflashsupport again +- Rename "-lib" packages to "-libs", like all other packages do it. +- Provide esound + +* Fri Sep 7 2007 Lennart Poettering 0.9.7-0.11.svn20070907 +- Update SVN snapshot, don't link libpulsecore.so statically anymore + +* Wed Sep 5 2007 Lennart Poettering 0.9.7-0.10.svn20070905 +- Update SVN snapshot + +* Tue Sep 4 2007 Lennart Poettering 0.9.7-0.9.svn20070904 +- Update SVN snapshot +- ship libflashsupport in our package +- drop pulseaudio-devel since libpulsecore is not linked statically + +* Thu Aug 23 2007 Lennart Poettering 0.9.7-0.8.svn20070823 +- Update SVN snapshot + +* Thu Aug 16 2007 Lennart Poettering 0.9.7-0.7.svn20070816 +- Update SVN snapshot + +* Thu Aug 16 2007 Lennart Poettering 0.9.7-0.6.svn20070816 +- Update SVN snapshot + +* Tue Aug 14 2007 Lennart Poettering 0.9.7-0.5.svn20070814 +- Forgot to upload tarball + +* Tue Aug 14 2007 Lennart Poettering 0.9.7-0.4.svn20070814 +- Update snapshot. Install file into /etc/xdg/autostart/ to load module-x11-smp + only after login + +* Sun Aug 12 2007 Lennart Poettering 0.9.7-0.3.svn20070812 +- Depend on tcp_wrappers-devel instead of tcp_wrappers, to make sure we + actually get the headers installed. + +* Sun Aug 12 2007 Lennart Poettering 0.9.7-0.2.svn20070812 +- Update snapshot, contains 64 bit build fixes, and disables module-x11-xsmp by + default to avoid deadlock when PA is started from gnome-session + +* Sun Aug 12 2007 Lennart Poettering 0.9.7-0.1.svn20070812 +- Take snapshot from SVN + +* Tue May 29 2007 Pierre Ossman 0.9.6-2 +- Add libatomic_ops-devel as a build requirement. + +* Tue May 29 2007 Pierre Ossman 0.9.6-1 +- Upgrade to 0.9.6. + +* Fri Mar 2 2007 Pierre Ossman 0.9.5-5 +- Fix merge problems with patch. + +* Fri Mar 2 2007 Pierre Ossman 0.9.5-4 +- Add patch to handle ALSA changing the frame size (bug 230211). +- Add patch for suspended ALSA devices (bug 228205). + +* Mon Feb 5 2007 Pierre Ossman 0.9.5-3 +- Add esound-compat subpackage that allows PulseAudio to be a drop-in + replacement for esd (based on patch by Matthias Clasen). +- Backport patch allows startup to continue even when the users' + config cannot be read. + +* Mon Oct 23 2006 Pierre Ossman 0.9.5-2 +- Create user and groups for daemon. + +* Mon Aug 28 2006 Pierre Ossman 0.9.5-1 +- Upgrade to 0.9.5. + +* Wed Aug 23 2006 Pierre Ossman 0.9.4-3 +- Make sure JACK modules are built and packaged. + +* Tue Aug 22 2006 Pierre Ossman 0.9.4-2 +- Merge the ALSA modules into the main package as ALSA is the + standard API. + +* Sun Aug 20 2006 Pierre Ossman 0.9.4-1 +- Update to 0.9.4. +- Remove fix for rpath as it is merged upstream. + +* Fri Jul 21 2006 Toshio Kuratomi 0.9.3-2 +- Remove static libraries. +- Fix for rpath issues. + +* Fri Jul 21 2006 Pierre Ossman 0.9.3-1 +- Update to 0.9.3 +- GLib 1.2 bindings dropped. +- Howl compat dropped as Avahi is supported natively. +- Added fix for pc files on x86_64. + +* Sat Jul 8 2006 Pierre Ossman 0.9.2-1 +- Update to 0.9.2. +- Added Avahi HOWL compat dependencies. + +* Thu Jun 8 2006 Pierre Ossman 0.9.1-1 +- Update to 0.9.1. + +* Mon May 29 2006 Pierre Ossman 0.9.0-2 +- Build and package doxygen docs +- Call ldconfig for relevant subpackages. + +* Mon May 29 2006 Pierre Ossman 0.9.0-1 +- Update to 0.9.0 + +* Tue May 9 2006 Pierre Ossman 0.8.1-1 +- Update to 0.8.1 +- Split into more packages +- Remove the modules' static libs as those shouldn't be used (they shouldn't + even be installed) + +* Fri Feb 24 2006 Tom "spot" Callaway 0.7-2 +- dance around with perms so we don't strip the binary +- add missing BR + +* Mon Nov 28 2005 Tom "spot" Callaway 0.7-1 +- Initial package for Fedora Extras