summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac12
-rw-r--r--doxygen/.gitignore1
-rw-r--r--src/.gitignore2
-rw-r--r--src/Makefile.am26
-rw-r--r--src/daemon/daemon-conf.c2
-rw-r--r--src/daemon/daemon.conf.in2
-rwxr-xr-xsrc/daemon/default.pa.in30
-rw-r--r--src/daemon/main.c9
-rw-r--r--src/daemon/pulseaudio-module-xsmp.desktop10
-rw-r--r--src/daemon/pulseaudio.desktop10
-rwxr-xr-xsrc/daemon/start-pulseaudio-x11.in31
-rwxr-xr-xsrc/daemon/system.pa.in54
-rw-r--r--src/modules/module-bt-proximity.c1
-rw-r--r--src/modules/module-console-kit.c51
-rw-r--r--src/modules/module-hal-detect.c20
-rw-r--r--src/modules/module-x11-xsmp.c2
-rw-r--r--src/pulse/channelmap.h6
-rw-r--r--src/pulse/client-conf.c2
-rw-r--r--src/pulse/client.conf.in2
-rw-r--r--src/pulse/context.h5
-rw-r--r--src/pulse/def.h72
-rw-r--r--src/pulse/introspect.h10
-rw-r--r--src/pulse/proplist.h34
-rw-r--r--src/pulse/pulseaudio.h10
-rw-r--r--src/pulse/sample.h2
-rw-r--r--src/pulse/stream.h113
-rw-r--r--src/pulsecore/core-util.c25
-rw-r--r--src/pulsecore/sink.c17
-rw-r--r--src/pulsecore/source.c17
29 files changed, 423 insertions, 155 deletions
diff --git a/configure.ac b/configure.ac
index 511e17eb..2ea4d893 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,12 +29,12 @@ m4_define(PA_MICRO, [11])
AC_INIT([pulseaudio], PA_MAJOR.PA_MINOR.PA_MICRO,[mzchyfrnhqvb (at) 0pointer (dot) net])
AC_CONFIG_SRCDIR([src/daemon/main.c])
AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([foreign -Wall])
+AM_INIT_AUTOMAKE([foreign 1.10 -Wall])
AC_SUBST(PA_MAJORMINOR, "PA_MAJOR.PA_MINOR")
AC_SUBST(PACKAGE_URL, [http://pulseaudio.org/])
-AC_SUBST(PA_API_VERSION, 11)
+AC_SUBST(PA_API_VERSION, 12)
AC_SUBST(PA_PROTOCOL_VERSION, 13)
# The stable ABI for client applications, for the version info x:y:z
@@ -376,7 +376,7 @@ AC_SEARCH_LIBS([connect], [socket])
AC_CHECK_FUNCS([getopt_long], [], [AC_CHECK_LIB([iberty], [getopt_long])])
AC_CHECK_LIB(gdbm, gdbm_open)
-AC_CHECK_HEADERS(gdbm.h)
+AC_CHECK_HEADERS(gdbm.h, [], [AC_MSG_ERROR([gdbm.h not found])])
#### Check for functions ####
@@ -599,7 +599,7 @@ AC_ARG_ENABLE([alsa],
[alsa=auto])
if test "x${alsa}" != xno ; then
- PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.16 ],
+ PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.17 ],
[
HAVE_ALSA=1
AC_DEFINE([HAVE_ALSA], 1, [Have ALSA?])
@@ -607,7 +607,7 @@ if test "x${alsa}" != xno ; then
[
HAVE_ALSA=0
if test "x$alsa" = xyes ; then
- AC_MSG_ERROR([*** ALSA support not found])
+ AC_MSG_ERROR([*** Needed alsa >= 1.0.17 support not found])
fi
])
else
@@ -693,7 +693,7 @@ AC_ARG_ENABLE([gconf],
*) AC_MSG_ERROR(bad value ${enableval} for --disable-gconf) ;;
esac
],
- [glib=auto])
+ [gconf=auto])
if test "x${gconf}" != xno ; then
PKG_CHECK_MODULES(GCONF, [ gconf-2.0 >= 2.4.0 ],
diff --git a/doxygen/.gitignore b/doxygen/.gitignore
index ca9b4441..a709d164 100644
--- a/doxygen/.gitignore
+++ b/doxygen/.gitignore
@@ -1 +1,2 @@
doxygen.conf
+html
diff --git a/src/.gitignore b/src/.gitignore
index f3ed2e2e..6902eb9f 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -15,6 +15,7 @@ cpulimit-test
cpulimit-test2
daemon.conf
default.pa
+system.pa
envelope-test
esdcompat
flist-test
@@ -54,3 +55,4 @@ thread-mainloop-test
thread-test
utf8-test
voltest
+start-pulseaudio-x11
diff --git a/src/Makefile.am b/src/Makefile.am
index 788857cd..51fd9976 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -96,23 +96,26 @@ EXTRA_DIST = \
pulse/version.h.in \
daemon/daemon.conf.in \
daemon/default.pa.in \
+ daemon/system.pa.in \
daemon/default.pa.win32 \
depmod.py \
daemon/esdcompat.in \
+ daemon/start-pulseaudio-x11.in \
utils/padsp \
modules/module-defs.h.m4 \
- daemon/pulseaudio-module-xsmp.desktop \
+ daemon/pulseaudio.desktop \
map-file \
daemon/org.pulseaudio.policy
pulseconf_DATA = \
default.pa \
+ system.pa \
daemon.conf \
client.conf
if HAVE_X11
xdgautostart_DATA = \
- daemon/pulseaudio-module-xsmp.desktop
+ daemon/pulseaudio.desktop
endif
BUILT_SOURCES = \
@@ -184,7 +187,7 @@ if HAVE_AVAHI
bin_PROGRAMS += pabrowse
endif
-bin_SCRIPTS = esdcompat
+bin_SCRIPTS = esdcompat start-pulseaudio-x11
pacat_SOURCES = utils/pacat.c
pacat_LDADD = $(AM_LDADD) libpulse.la
@@ -585,7 +588,7 @@ endif
libpulse_la_CFLAGS = $(AM_CFLAGS)
libpulse_la_LDFLAGS = -version-info $(LIBPULSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
-libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LIBICONV)
+libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV)
if HAVE_X11
libpulse_la_CFLAGS += $(X_CFLAGS)
@@ -801,7 +804,7 @@ endif
libpulsecore_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBOIL_CFLAGS)
libpulsecore_la_LDFLAGS = -version-info $(LIBPULSECORE_VERSION_INFO)
-libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) libffmpeg-resampler.la
+libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LTLIBICONV) libffmpeg-resampler.la
###################################
# Plug-in support libraries #
@@ -1542,7 +1545,7 @@ suid: pulseaudio .libs/lt-pulseaudio
chown root $^
chmod u+s $^
-CLEANFILES = esdcompat client.conf default.pa daemon.conf
+CLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11
esdcompat: daemon/esdcompat.in Makefile
sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
@@ -1550,17 +1553,28 @@ esdcompat: daemon/esdcompat.in Makefile
-e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@
chmod +x esdcompat
+start-pulseaudio-x11: daemon/start-pulseaudio-x11.in Makefile
+ sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
+ -e 's,@PACTL_BINARY\@,$(bindir)/pactl,g' < $< > $@
+ chmod +x start-pulseaudio-x11
+
client.conf: pulse/client.conf.in Makefile
sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@
if OS_IS_WIN32
default.pa: daemon/default.pa.win32
cp $< $@
+system.pa: daemon/default.pa.win32
+ cp $< $@
else
default.pa: daemon/default.pa.in Makefile
sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
-e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \
-e 's,@PA_SOEXT\@,.so,g' < $< > $@
+system.pa: daemon/system.pa.in Makefile
+ sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
+ -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \
+ -e 's,@PA_SOEXT\@,.so,g' < $< > $@
endif
daemon.conf: daemon/daemon.conf.in Makefile
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 9ac40901..50b812dc 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -62,7 +62,7 @@ static const pa_daemon_conf default_conf = {
.realtime_scheduling = FALSE,
.realtime_priority = 5, /* Half of JACK's default rtprio */
.disallow_module_loading = FALSE,
- .exit_idle_time = -1,
+ .exit_idle_time = 20,
.module_idle_time = 20,
.scache_idle_time = 20,
.auto_log_target = 1,
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index dfabcfb2..41c26e2a 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -32,7 +32,7 @@
; realtime-scheduling = no
; realtime-priority = 5
-; exit-idle-time = -1
+; exit-idle-time = 20
; module-idle-time = 20
; scache-idle-time = 20
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index aad9f5d6..917fc309 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -16,6 +16,9 @@
# along with PulseAudio; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+# This startup script is used only if PulseAudio is started per-user
+# (i.e. not in system mode)
+
.nofail
### Load something into the sample cache
@@ -80,14 +83,6 @@ load-module module-always-sink
### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle
-### Load X11 bell module
-#load-module module-x11-bell sample=bell-windowing-system
-
-### Register ourselves in the X11 session manager
-# Deactivated by default, to avoid deadlock when PA is started as esd from gnome-session
-# Instead we load this via /etc/xdg/autostart/ and "pactl load-module" now
-#load-module module-x11-xsmp
-
### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
load-module module-console-kit
@@ -104,12 +99,21 @@ load-module module-gconf
.fail
.endif
+# X11 modules should not be started from default.pa so that one daemon
+# can be shared by multiple sessions.
+
+### Load X11 bell module
+#load-module module-x11-bell sample=bell-windowing-system
+
+### Register ourselves in the X11 session manager
+#load-module module-x11-xsmp
+
### Publish connection data in the X11 root window
-.ifexists module-x11-publish@PA_SOEXT@
-.nofail
-load-module module-x11-publish
-.fail
-.endif
+#.ifexists module-x11-publish@PA_SOEXT@
+#.nofail
+#load-module module-x11-publish
+#.fail
+#.endif
### Make some devices default
#set-default-sink output
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 14594416..5fc9f01c 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -496,7 +496,7 @@ int main(int argc, char *argv[]) {
if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
pa_raise_priority(conf->nice_level);
- if (pa_have_caps()) {
+ if (!real_root && pa_have_caps()) {
pa_bool_t drop;
drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
@@ -627,6 +627,11 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ if (conf->cmd == PA_CMD_START && conf->system_instance) {
+ pa_log("--start not supported for system instances.");
+ goto finish;
+ }
+
if (conf->cmd == PA_CMD_START) {
/* If we shall start PA only when it is not running yet, we
* first take the autospawn lock to make things
@@ -762,8 +767,6 @@ int main(int argc, char *argv[]) {
/* If we are already running and with are run in
* --start mode, then let's return this as success. */
- pa_log_info("z=%i rock!", z);
-
retval = 0;
goto finish;
}
diff --git a/src/daemon/pulseaudio-module-xsmp.desktop b/src/daemon/pulseaudio-module-xsmp.desktop
deleted file mode 100644
index fa719a73..00000000
--- a/src/daemon/pulseaudio-module-xsmp.desktop
+++ /dev/null
@@ -1,10 +0,0 @@
-[Desktop Entry]
-Version=1.0
-Encoding=UTF-8
-Name=PulseAudio Session Management
-Comment=Load module-x11-xsmp into PulseAudio
-Exec=pactl load-module module-x11-xsmp
-Terminal=false
-Type=Application
-Categories=
-GenericName=
diff --git a/src/daemon/pulseaudio.desktop b/src/daemon/pulseaudio.desktop
new file mode 100644
index 00000000..57a7a6e4
--- /dev/null
+++ b/src/daemon/pulseaudio.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=PulseAudio Sound System
+Comment=Start the PulseAudio Sound System
+Exec=start-pulseaudio-x11
+Terminal=false
+Type=Application
+Categories=
+GenericName=
diff --git a/src/daemon/start-pulseaudio-x11.in b/src/daemon/start-pulseaudio-x11.in
new file mode 100755
index 00000000..3cccc4dc
--- /dev/null
+++ b/src/daemon/start-pulseaudio-x11.in
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# 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 of the License, or
+# (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+
+set -e
+
+@PA_BINARY@ --start "$@"
+
+if [ x"$DISPLAY" != x ] ; then
+
+ @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null
+
+ if [ x"$SESSION_MANAGER" != x ] ; then
+ @PACTL_BINARY@ load-module module-x11-xsmp "display=$DISPLAY session_manager=$SESSION_MANAGER" > /dev/null
+ fi
+fi
diff --git a/src/daemon/system.pa.in b/src/daemon/system.pa.in
new file mode 100755
index 00000000..f6052c4b
--- /dev/null
+++ b/src/daemon/system.pa.in
@@ -0,0 +1,54 @@
+#!@PA_BINARY@ -nF
+#
+# 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 of the License, or
+# (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+# This startup script is used only if PulseAudio is started in system
+# mode.
+
+### Automatically load driver modules depending on the hardware available
+.ifexists module-hal-detect@PA_SOEXT@
+load-module module-hal-detect
+.else
+### Alternatively use the static hardware detection module (for systems that
+### lack HAL support)
+load-module module-detect
+.endif
+
+### Load several protocols
+.ifexists module-esound-protocol-unix@PA_SOEXT@
+load-module module-esound-protocol-unix
+.endif
+load-module module-native-protocol-unix
+
+### Automatically restore the volume of playback streams
+load-module module-volume-restore
+
+### Automatically restore the default sink/source when changed by the user during runtime
+load-module module-default-device-restore
+
+### Automatically move streams to the default sink if the sink they are
+### connected to dies, similar for sources
+load-module module-rescue-streams
+
+### Make sure we always have a sink around, even if it is a null sink.
+load-module module-always-sink
+
+### Automatically suspend sinks/sources that become idle for too long
+load-module module-suspend-on-idle
+
+### Enable positioned event sounds
+load-module module-position-event-sounds
diff --git a/src/modules/module-bt-proximity.c b/src/modules/module-bt-proximity.c
index 77b95868..f924c3cb 100644
--- a/src/modules/module-bt-proximity.c
+++ b/src/modules/module-bt-proximity.c
@@ -358,7 +358,6 @@ static int add_matches(struct userdata *u, pa_bool_t add) {
} else
dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter2, &e);
-
if (add)
pa_assert_se(dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u, NULL));
else
diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c
index 3adee99e..e1933c28 100644
--- a/src/modules/module-console-kit.c
+++ b/src/modules/module-console-kit.c
@@ -71,7 +71,7 @@ struct userdata {
static void add_session(struct userdata *u, const char *id) {
DBusError error;
DBusMessage *m = NULL, *reply = NULL;
- int32_t uid;
+ uint32_t uid;
struct session *session;
char *t;
@@ -92,10 +92,14 @@ static void add_session(struct userdata *u, const char *id) {
goto fail;
}
- /* FIXME: Why is this in int32? and not an uint32? */
- if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) {
- pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message);
- goto fail;
+ /* CK 0.3 this changed from int32 to uint32 */
+ if (!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) {
+ dbus_error_free(&error);
+
+ if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) {
+ pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message);
+ goto fail;
+ }
}
/* We only care about our own sessions */
@@ -163,27 +167,39 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo
if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
- pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message);
- goto finish;
+ /* CK API changed to match spec in 0.3 */
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+ dbus_error_free(&error);
+
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
+ pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message);
+ goto finish;
+ }
}
add_session(u, path);
+ return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) {
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
- pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message);
- goto finish;
+ /* CK API changed to match spec in 0.3 */
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+ dbus_error_free(&error);
+
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
+ pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message);
+ goto finish;
+ }
}
remove_session(u, path);
+ return DBUS_HANDLER_RESULT_HANDLED;
}
finish:
dbus_error_free(&error);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static int get_session_list(struct userdata *u) {
@@ -327,8 +343,17 @@ void pa__done(pa_module *m) {
pa_hashmap_free(u->sessions, NULL, NULL);
}
- if (u->connection)
+ if (u->connection) {
+ DBusError error;
+ dbus_error_init(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.ConsoleKit', interface='org.freedesktop.ConsoleKit.Seat'", &error);
+ dbus_error_free(&error);
+
+ dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
+
pa_dbus_connection_unref(u->connection);
+ }
pa_xfree(u);
}
diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c
index 19430a3d..ab5b206f 100644
--- a/src/modules/module-hal-detect.c
+++ b/src/modules/module-hal-detect.c
@@ -615,6 +615,8 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo
device_added_cb(u->context, udi);
}
+ return DBUS_HANDLER_RESULT_HANDLED;
+
} else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) {
/* We use this message to avoid a dirty race condition when we
get an ACLAdded message before the previously owning PA
@@ -661,12 +663,14 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo
} else
/* Yes, we don't check the UDI for validity, but hopefully HAL will */
device_added_cb(u->context, udi);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
}
finish:
dbus_error_free(&error);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void hal_context_free(LibHalContext* hal_context) {
@@ -842,8 +846,20 @@ void pa__done(pa_module *m) {
if (u->devices)
pa_hashmap_free(u->devices, hal_device_free_cb, NULL);
- if (u->connection)
+ if (u->connection) {
+ DBusError error;
+ dbus_error_init(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.Hal', interface='org.freedesktop.Hal.Device.AccessControl'", &error);
+ dbus_error_free(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',interface='org.pulseaudio.Server'", &error);
+ dbus_error_free(&error);
+
+ dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
+
pa_dbus_connection_unref(u->connection);
+ }
pa_xfree(u);
}
diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c
index 696826d8..0b2e375a 100644
--- a/src/modules/module-x11-xsmp.c
+++ b/src/modules/module-x11-xsmp.c
@@ -47,7 +47,7 @@
PA_MODULE_AUTHOR("Lennart Poettering");
PA_MODULE_DESCRIPTION("X11 session management");
PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_LOAD_ONCE(FALSE);
PA_MODULE_USAGE("session_manager=<session manager string> display=<X11 display>");
static pa_bool_t ice_in_use = FALSE;
diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index 2551eae9..7c32b868 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -47,8 +47,10 @@
*
* \li pa_channel_map_init_mono() - Create a channel map with only mono audio.
* \li pa_channel_map_init_stereo() - Create a standard stereo mapping.
- * \li pa_channel_map_init_auto() - Create a standard channel map for up to
- * six channels.
+ * \li pa_channel_map_init_auto() - Create a standard channel map for a specific number of channels
+ * \li pa_channel_map_init_extend() - Similar to
+ * pa_channel_map_init_auto() but synthesize a channel map if noone
+ * predefined one is known for the specified number of channels.
*
* \section conv_sec Convenience Functions
*
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 2ead871f..915d0ccb 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -66,7 +66,7 @@ pa_client_conf *pa_client_conf_new(void) {
pa_client_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf));
c->daemon_binary = pa_xstrdup(PA_BINARY);
- c->extra_arguments = pa_xstrdup("--log-target=syslog --exit-idle-time=5");
+ c->extra_arguments = pa_xstrdup("--log-target=syslog");
c->cookie_file = pa_xstrdup(PA_NATIVE_COOKIE_FILE);
return c;
diff --git a/src/pulse/client.conf.in b/src/pulse/client.conf.in
index 749e9688..8339d651 100644
--- a/src/pulse/client.conf.in
+++ b/src/pulse/client.conf.in
@@ -25,7 +25,7 @@
; autospawn = yes
; daemon-binary = @PA_BINARY@
-; extra-arguments = --log-target=syslog --exit-idle-time=5
+; extra-arguments = --log-target=syslog
; cookie-file =
diff --git a/src/pulse/context.h b/src/pulse/context.h
index 8dff7642..3b513976 100644
--- a/src/pulse/context.h
+++ b/src/pulse/context.h
@@ -35,7 +35,7 @@
* \section overv_sec Overview
*
* The asynchronous API is the native interface to the PulseAudio library.
- * It allows full access to all available functions. This also means that
+ * It allows full access to all available functionality. This however means that
* it is rather complex and can take some time to fully master.
*
* \section mainloop_sec Main Loop Abstraction
@@ -64,8 +64,7 @@
* implementation where all of PulseAudio's
* internal handling runs in a separate
* thread.
- * \li \subpage glib-mainloop - A wrapper around GLIB's main loop. Available
- * for both GLIB 1.2 and GLIB 2.x.
+ * \li \subpage glib-mainloop - A wrapper around GLib's main loop.
*
* UNIX signals may be hooked to a main loop using the functions from
* \ref mainloop-signal.h. These rely only on the main loop abstraction
diff --git a/src/pulse/def.h b/src/pulse/def.h
index 8407ddeb..95071978 100644
--- a/src/pulse/def.h
+++ b/src/pulse/def.h
@@ -233,12 +233,11 @@ typedef enum pa_stream_flags {
PA_STREAM_START_MUTED = 4096, /**< Create in muted state. \since 0.9.11 */
-
PA_STREAM_ADJUST_LATENCY = 8192, /**< Try to adjust the latency of
* the sink/source based on the
* requested buffer metrics and
* adjust buffer metrics
- * accordingly. \since 0.9.11 */
+ * accordingly. See pa_buffer_attr \since 0.9.11 */
} pa_stream_flags_t;
@@ -248,53 +247,86 @@ typedef enum pa_stream_flags {
/** Playback and record buffer metrics */
typedef struct pa_buffer_attr {
uint32_t maxlength; /**< Maximum length of the
- * buffer. Setting this to 0 will
+ * buffer. Setting this to (uint32_t) -1 will
* initialize this to the maximum value
* supported by server, which is
* recommended. */
uint32_t tlength; /**< Playback only: target length of the
* buffer. The server tries to assure
* that at least tlength bytes are always
- * available in the buffer. It is
- * recommended to set this to 0, which
- * will initialize this to a value that
- * is deemed sensible by the
+ * available in the per-stream
+ * server-side playback buffer. It is
+ * recommended to set this to (uint32_t)
+ * -1, which will initialize this to a
+ * value that is deemed sensible by the
* server. However, this value will
* default to something like 2s, i.e. for
* applications that have specific
* latency requirements this value should
* be set to the maximum latency that the
- * application can deal with. */
+ * application can deal with. When
+ * PA_STREAM_ADJUST_LATENCY is not set
+ * this value will influence only the
+ * per-stream playback buffer size. When
+ * PA_STREAM_ADJUST_LATENCY is set the
+ * overall latency of the sink plus the
+ * playback buffer size is configured to
+ * this value. Set
+ * PA_STREAM_ADJUST_LATENCY if you are
+ * interested in adjusting the overall
+ * latency. Don't set it if you are
+ * interested in configuring the
+ * server-sider per-stream playback
+ * buffer size. */
uint32_t prebuf; /**< Playback only: pre-buffering. The
* server does not start with playback
* before at least prebug bytes are
* available in the buffer. It is
- * recommended to set this to 0, which
- * will initialize this to the same value
- * as tlength, whatever that may be. */
+ * recommended to set this to (uint32_t)
+ * -1, which will initialize this to the
+ * same value as tlength, whatever that
+ * may be. Initialize to 0 to enable
+ * manual start/stop control of the
+ * stream. This means that playback will
+ * not stop on underrun and playback will
+ * not start automatically. Instead
+ * pa_stream_corked() needs to be called
+ * explicitly. If you set this value to 0
+ * you should also set
+ * PA_STREAM_START_CORKED. */
uint32_t minreq; /**< Playback only: minimum request. The
* server does not request less than
* minreq bytes from the client, instead
* waits until the buffer is free enough
* to request more bytes at once. It is
- * recommended to set this to 0, which
- * will initialize this to a value that
- * is deemed sensible by the server. */
+ * recommended to set this to (uint32_t)
+ * -1, which will initialize this to a
+ * value that is deemed sensible by the
+ * server. This should be set to a value
+ * that gives PulseAudio enough time to
+ * move the data from the per-stream
+ * playback buffer into the hardware
+ * playback buffer. */
uint32_t fragsize; /**< Recording only: fragment size. The
* server sends data in blocks of
* fragsize bytes size. Large values
* deminish interactivity with other
* operations on the connection context
* but decrease control overhead. It is
- * recommended to set this to 0, which
- * will initialize this to a value that
- * is deemed sensible by the
+ * recommended to set this to (uint32_t)
+ * -1, which will initialize this to a
+ * value that is deemed sensible by the
* server. However, this value will
* default to something like 2s, i.e. for
* applications that have specific
* latency requirements this value should
* be set to the maximum latency that the
- * application can deal with. */
+ * application can deal with. If
+ * PA_STREAM_ADJUST_LATENCY is set the
+ * overall source latency will be
+ * adjusted according to this value. If
+ * it is not set the source latency is
+ * left unmodified. */
} pa_buffer_attr;
/** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */
@@ -431,9 +463,9 @@ typedef struct pa_timing_info {
* PA_SEEK_RELATIVE_ON_READ
* instead. */
- pa_usec_t configured_sink_usec; /**< The static configured latency for
+ pa_usec_t configured_sink_usec; /**< The configured latency for
* the sink. \since 0.9.11 */
- pa_usec_t configured_source_usec; /**< The static configured latency for
+ pa_usec_t configured_source_usec; /**< The configured latency for
* the source. \since 0.9.11 */
int64_t since_underrun; /**< Bytes that were handed to the sink
diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h
index c8c13a75..6a6755e7 100644
--- a/src/pulse/introspect.h
+++ b/src/pulse/introspect.h
@@ -130,8 +130,10 @@
*
* \subsection autoload_subsec Autoload Entries
*
- * Modules can be autoloaded as a result of a client requesting a certain
- * sink or source. This mapping between sink/source names and modules can be
+ * Modules can be autoloaded as a result of a client requesting a
+ * certain sink or source. Please note that autoloading is deprecated
+ * in 0.9.11. and is likely to be removed from the API in a later
+ * version. This mapping between sink/source names and modules can be
* queried from the server:
*
* \li By index - pa_context_get_autoload_info_by_index()
@@ -191,7 +193,9 @@
*
* New module autoloading rules can be added, and existing can be removed
* using pa_context_add_autoload() and pa_context_remove_autoload_by_index()
- * / pa_context_remove_autoload_by_name().
+ * / pa_context_remove_autoload_by_name(). Please note that autoloading is deprecated
+ * in 0.9.11. and is likely to be removed from the API in a later
+ * version.
*
* \subsection client_subsec Clients
*
diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h
index f75cca54..39d53303 100644
--- a/src/pulse/proplist.h
+++ b/src/pulse/proplist.h
@@ -36,19 +36,20 @@ PA_C_DECL_BEGIN
* media.artist "Guns'N'Roses"
* media.language "de_DE"
* media.filename
- * media.icon
- * media.icon_name
+ * media.icon Binary blob containing PNG icon data
+ * media.icon_name Name from XDG icon naming spec
* media.role video, music, game, event, phone, production, filter, abstract, stream
- * event.id button-click, session-login
+ * event.id Name from XDG sound naming spec
+ * event.description "Button blabla clicked" for a11y
* event.mouse.x
* event.mouse.y
- * event.mouse.hpos
- * event.mouse.vpos
- * event.mouse.button
+ * event.mouse.hpos Float formatted as string in range 0..1
+ * event.mouse.vpos Float formatted as string in range 0..1
+ * event.mouse.button Button number following X11 ordering
* window.name
- * window.id
- * window.icon
- * window.icon_name
+ * window.id "org.gnome.rhytmbox.MainWindow"
+ * window.icon Binary blob containing PNG icon data
+ * window.icon_name Name from XDG icon naming spec
* window.x11.display
* window.x11.screen
* window.x11.monitor
@@ -56,23 +57,23 @@ PA_C_DECL_BEGIN
* application.name "Rhythmbox Media Player"
* application.id "org.gnome.rhythmbox"
* application.version
- * application.icon
- * application.icon_name
+ * application.icon Binary blob containing PNG icon data
+ * application.icon_name Name from XDG icon naming spec
* application.language
* application.process.id
* application.process.binary
* application.process.user
* application.process.host
* device.string
- * device.api oss, alsa, sunaudio
+ * device.api oss, alsa, sunaudio
* device.description
* device.bus_path
* device.serial
* device.vendor_product_id
- * device.class sound, modem, monitor, filter, abstract
- * device.form_factor laptop-speakers, external-speakers, telephone, tv-capture, webcam-capture, microphone-capture, headset
- * device.connector isa, pci, usb, firewire, bluetooth
- * device.access_mode mmap, mmap_rewrite, serial
+ * device.class sound, modem, monitor, filter, abstract
+ * device.form_factor laptop-speakers, external-speakers, telephone, tv-capture, webcam-capture, microphone-capture, headset
+ * device.connector isa, pci, usb, firewire, bluetooth
+ * device.access_mode mmap, mmap_rewrite, serial
* device.master_device
* device.bufferin.buffer_size
* device.bufferin.fragment_size
@@ -86,6 +87,7 @@ PA_C_DECL_BEGIN
#define PA_PROP_MEDIA_ICON_NAME "media.icon_name"
#define PA_PROP_MEDIA_ROLE "media.role"
#define PA_PROP_EVENT_ID "event.id"
+#define PA_PROP_EVENT_DESCRIPTION "event.description"
#define PA_PROP_EVENT_MOUSE_X "event.mouse.x"
#define PA_PROP_EVENT_MOUSE_Y "event.mouse.y"
#define PA_PROP_EVENT_MOUSE_HPOS "event.mouse.hpos"
diff --git a/src/pulse/pulseaudio.h b/src/pulse/pulseaudio.h
index 4a4531e6..e09cacaf 100644
--- a/src/pulse/pulseaudio.h
+++ b/src/pulse/pulseaudio.h
@@ -89,17 +89,17 @@
*
* \section thread_sec Threads
*
- * The PulseAudio client libraries are not designed to be used in a
- * heavily threaded environment. They are however designed to be reentrant
- * safe.
+ * The PulseAudio client libraries are not designed to be directly
+ * thread-safe. They are however designed to be reentrant and
+ * threads-aware.
*
- * To use a the libraries in a threaded environment, you must assure that
+ * To use the libraries in a threaded environment, you must assure that
* all objects are only used in one thread at a time. Normally, this means
* that all objects belonging to a single context must be accessed from the
* same thread.
*
* The included main loop implementation is also not thread safe. Take care
- * to make sure event lists are not manipulated when any other code is
+ * to make sure event objects are not manipulated when any other code is
* using the main loop.
*
* \section pkgconfig pkg-config
diff --git a/src/pulse/sample.h b/src/pulse/sample.h
index 1ba3f871..2680cf7e 100644
--- a/src/pulse/sample.h
+++ b/src/pulse/sample.h
@@ -52,7 +52,7 @@
* \li PA_SAMPLE_S32LE - Signed 32 bit integer PCM, little endian.
* \li PA_SAMPLE_S32BE - Signed 32 bit integer PCM, big endian.
*
- * The floating point sample formats have the range from -1 to 1.
+ * The floating point sample formats have the range from -1.0 to 1.0.
*
* The sample formats that are sensitive to endianness have convenience
* macros for native endian (NE), and reverse endian (RE).
diff --git a/src/pulse/stream.h b/src/pulse/stream.h
index fbf0ae44..2a8f7a8b 100644
--- a/src/pulse/stream.h
+++ b/src/pulse/stream.h
@@ -70,35 +70,85 @@
*
* \subsection bufattr_subsec Buffer Attributes
*
- * Playback and record streams always have a server side buffer as
- * part of the data flow. The size of this buffer strikes a
- * compromise between low latency and sensitivity for buffer
+ * Playback and record streams always have a server-side buffer as
+ * part of the data flow. The size of this buffer needs to be chosen
+ * in a compromise between low latency and sensitivity for buffer
* overflows/underruns.
*
* The buffer metrics may be controlled by the application. They are
* described with a pa_buffer_attr structure which contains a number
* of fields:
*
- * \li maxlength - The absolute maximum number of bytes that can be stored in
- * the buffer. If this value is exceeded then data will be
- * lost.
- * \li tlength - The target length of a playback buffer. The server will only
- * send requests for more data as long as the buffer has less
- * than this number of bytes of data.
+ * \li maxlength - The absolute maximum number of bytes that can be
+ * stored in the buffer. If this value is exceeded
+ * then data will be lost. It is recommended to pass
+ * (uint32_t) -1 here which will cause the server to
+ * fill in the maximum possible value.
+ *
+ * \li tlength - The target fill level of the playback buffer. The
+ * server will only send requests for more data as long
+ * as the buffer has less than this number of bytes of
+ * data. If you pass (uint32_t) -1 (which is
+ * recommended) here the server will choose the longest
+ * target buffer fill level possible to minimize the
+ * number of necessary wakeups and maximize drop-out
+ * safety. This can exceed 2s of buffering. For
+ * low-latency applications or applications where
+ * latency matters you should pass a proper value here.
+ *
* \li prebuf - Number of bytes that need to be in the buffer before
- * playback will commence. Start of playback can be forced using
- * pa_stream_trigger() even though the prebuffer size hasn't been
- * reached. If a buffer underrun occurs, this prebuffering will be
- * again enabled. If the playback shall never stop in case of a buffer
- * underrun, this value should be set to 0. In that case the read
- * index of the output buffer overtakes the write index, and hence the
- * fill level of the buffer is negative.
- * \li minreq - Minimum free number of the bytes in the playback buffer before
- * the server will request more data.
- * \li fragsize - Maximum number of bytes that the server will push in one
- * chunk for record streams.
- *
- * The server side playback buffers are indexed by a write and a read
+ * playback will commence. Start of playback can be
+ * forced using pa_stream_trigger() even though the
+ * prebuffer size hasn't been reached. If a buffer
+ * underrun occurs, this prebuffering will be again
+ * enabled. If the playback shall never stop in case of a
+ * buffer underrun, this value should be set to 0. In
+ * that case the read index of the output buffer
+ * overtakes the write index, and hence the fill level of
+ * the buffer is negative. If you pass (uint32_t) -1 here
+ * (which is recommended) the server will choose the same
+ * value as tlength here.
+ *
+ * \li minreq - Minimum free number of the bytes in the playback
+ * buffer before the server will request more data. It is
+ * recommended to fill in (uint32_t) -1 here. This value
+ * influences how much time the sound server has to move
+ * data from the per-stream server-side playback buffer
+ * to the hardware playback buffer.
+ *
+ * \li fragsize - Maximum number of bytes that the server will push in
+ * one chunk for record streams. If you pass (uint32_t)
+ * -1 (which is recommended) here, the server will
+ * choose the longest fragment setting possible to
+ * minimize the number of necessary wakeups and
+ * maximize drop-out safety. This can exceed 2s of
+ * buffering. For low-latency applications or
+ * applications where latency matters you should pass a
+ * proper value here.
+ *
+ * If PA_STREAM_ADJUST_LATENCY is set, then the tlength/fragsize
+ * parameters will be interpreted slightly differently than described
+ * above when passed to pa_stream_connect_record() and
+ * pa_stream_connect_playback(): the overall latency that is comprised
+ * of both the server side playback buffer length, the hardware
+ * playback buffer length and additional latencies will be adjusted in
+ * a way that it matches tlength resp. fragsize. Set
+ * PA_STREAM_ADJUST_LATENCY if you want to control the overall
+ * playback latency for your stream. Unset it if you want to control
+ * only the latency induced by the server-side, rewritable playback
+ * buffer. The server will try to fulfill the clients latency requests
+ * as good as possible. However if the underlying hardware cannot
+ * change the hardware buffer length or only in a limited range, the
+ * actually resulting latency might be different from what the client
+ * requested. Thus, for synchronization clients always need to check
+ * the actual measured latency via pa_stream_get_latency() or a
+ * similar call, and not make any assumptions. about the latency
+ * available. The function pa_stream_get_buffer_attr() will always
+ * return the actual size of the server-side per-stream buffer in
+ * tlength/fragsize, regardless whether PA_STREAM_ADJUST_LATENCY is
+ * set or not.
+ *
+ * The server-side per-stream playback buffers are indexed by a write and a read
* index. The application writes to the write index and the sound
* device reads from the read index. The read index is increased
* monotonically, while the write index may be freely controlled by
@@ -196,10 +246,10 @@
* accordingly.
*
* The raw timing data in the pa_timing_info structure is usually hard
- * to deal with. Therefore a more simplistic interface is available:
+ * to deal with. Therefore a simpler interface is available:
* you can call pa_stream_get_time() or pa_stream_get_latency(). The
* former will return the current playback time of the hardware since
- * the stream has been started. The latter returns the time a sample
+ * the stream has been started. The latter returns the overall time a sample
* that you write now takes to be played by the hardware. These two
* functions base their calculations on the same data that is returned
* by pa_stream_get_timing_info(). Hence the same rules for keeping
@@ -512,9 +562,14 @@ const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s);
/** Return a pointer to the stream's channel map. */
const pa_channel_map* pa_stream_get_channel_map(pa_stream *s);
-/** Return the buffer metrics of the stream. Only valid after the
- * stream has been connected successfuly and if the server is at least
- * PulseAudio 0.9. \since 0.9.0 */
+/** Return the per-stream server-side buffer metrics of the
+ * stream. Only valid after the stream has been connected successfuly
+ * and if the server is at least PulseAudio 0.9. This will return the
+ * actual configured buffering metrics, which may differ from what was
+ * requested during pa_stream_connect_record() or
+ * pa_stream_connect_playback(). This call will always return the
+ * actually per-stream server-side buffer metrics, regardless whether
+ * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.0 */
const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);
/** Change the buffer metrics of the stream during playback. The
@@ -522,7 +577,9 @@ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);
* requested. The selected metrics may be queried with
* pa_stream_get_buffer_attr() as soon as the callback is called. Only
* valid after the stream has been connected successfully and if the
- * server is at least PulseAudio 0.9.8. \since 0.9.8 */
+ * server is at least PulseAudio 0.9.8. Please be aware of the
+ * slightly different semantics of the call depending whether
+ * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.8 */
pa_operation *pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata);
/** Change the stream sampling rate during playback. You need to pass
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index d259fb16..c4818e39 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -177,7 +177,7 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
#else
{
mode_t u;
- u = umask(~m);
+ u = umask((~m) & 0777);
r = mkdir(dir, m);
umask(u);
}
@@ -1887,17 +1887,21 @@ int pa_close_allv(const int except_fds[]) {
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
return -1;
- for (fd = 0; fd < (int) rl.rlim_max; fd++) {
+ for (fd = 3; fd < (int) rl.rlim_max; fd++) {
int i;
+ pa_bool_t found;
- if (fd <= 3)
- continue;
-
+ found = FALSE;
for (i = 0; except_fds[i] >= 0; i++)
- if (except_fds[i] == fd)
- continue;
+ if (except_fds[i] == fd) {
+ found = TRUE;
+ break;
+ }
- if (close(fd) < 0 && errno != EBADF)
+ if (found)
+ continue;
+
+ if (pa_close(fd) < 0 && errno != EBADF)
return -1;
}
@@ -1972,10 +1976,11 @@ int pa_reset_sigs(int except, ...) {
i = 0;
if (except >= 1) {
+ int sig;
p[i++] = except;
- while ((p[i++] = va_arg(ap, int)) >= 0)
- ;
+ while ((sig = va_arg(ap, int)) >= 0)
+ sig = p[i++];
}
p[i] = -1;
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 74971035..4102f31d 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -261,22 +261,31 @@ pa_sink* pa_sink_new(
static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
int ret;
pa_bool_t suspend_change;
+ pa_sink_state_t original_state;
pa_assert(s);
if (s->state == state)
return 0;
+ original_state = s->state;
+
suspend_change =
- (s->state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
- (PA_SINK_IS_OPENED(s->state) && state == PA_SINK_SUSPENDED);
+ (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) ||
+ (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);
if (s->set_state)
if ((ret = s->set_state(s, state)) < 0)
- return -1;
+ return ret;
if (s->asyncmsgq)
- pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
+ if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
+
+ if (s->set_state)
+ s->set_state(s, original_state);
+
+ return ret;
+ }
s->state = state;
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index e62c6c24..95007af4 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -224,22 +224,31 @@ pa_source* pa_source_new(
static int source_set_state(pa_source *s, pa_source_state_t state) {
int ret;
pa_bool_t suspend_change;
+ pa_source_state_t original_state;
pa_assert(s);
if (s->state == state)
return 0;
+ original_state = s->state;
+
suspend_change =
- (s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) ||
- (PA_SOURCE_IS_OPENED(s->state) && state == PA_SOURCE_SUSPENDED);
+ (original_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) ||
+ (PA_SOURCE_IS_OPENED(original_state) && state == PA_SOURCE_SUSPENDED);
if (s->set_state)
if ((ret = s->set_state(s, state)) < 0)
- return -1;
+ return ret;
if (s->asyncmsgq)
- pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
+ if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) {
+
+ if (s->set_state)
+ s->set_state(s, original_state);
+
+ return ret;
+ }
s->state = state;