diff options
196 files changed, 7690 insertions, 3286 deletions
@@ -1,3 +1,7 @@ +ABOUT-NLS +intltool-extract.in +intltool-merge.in +intltool-update.in *~ *.tar.gz *.pc diff --git a/Makefile.am b/Makefile.am index b32b46e9..facce0df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,8 +15,10 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA. +ACLOCAL_AMFLAGS = -I m4 + EXTRA_DIST = bootstrap.sh LICENSE GPL LGPL doxygen/Makefile.am doxygen/Makefile.in doxygen/doxygen.conf.in README todo -SUBDIRS=src doxygen man +SUBDIRS=src doxygen man po MAINTAINERCLEANFILES = noinst_DATA = @@ -60,3 +62,6 @@ dist-hook: fi .PHONY: homepage distcleancheck doxygen + +DISTCLEANFILES = \ + po/.intltool-merge-cache @@ -140,3 +140,7 @@ new message: new message: PA_COMMAND_EXTENSION + +PA_COMMAND_CREATE_RECORD_STREAM, PA_COMMAND_CREATE_PLAYBACK_STREAM: + + bool volume_set at the end diff --git a/bootstrap.sh b/bootstrap.sh index ceea55b7..5dfcdf20 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -23,12 +23,12 @@ run_versioned() { local V V=$(echo "$2" | sed -e 's,\.,,g') - + if [ -e "`which $1$V 2> /dev/null`" ] ; then - P="$1$V" + P="$1$V" else if [ -e "`which $1-$2 2> /dev/null`" ] ; then - P="$1-$2" + P="$1-$2" else P="$1" fi @@ -43,21 +43,28 @@ set -ex if [ "x$1" = "xam" ] ; then run_versioned automake "$VERSION" -a -c --foreign ./config.status -else +else rm -rf autom4te.cache rm -f config.cache + rm -f Makefile.am~ configure.ac~ + # Evil, evil, evil, evil hack + sed 's/read dummy/\#/' `which gettextize` | sh -s -- --copy --force + test -f Makefile.am~ && mv Makefile.am~ Makefile.am + test -f configure.ac~ && mv configure.ac~ configure.ac + touch config.rpath test "x$LIBTOOLIZE" = "x" && LIBTOOLIZE=libtoolize + intltoolize --copy --force --automake "$LIBTOOLIZE" -c --force --ltdl - run_versioned aclocal "$VERSION" - run_versioned autoconf 2.59 -Wall - run_versioned autoheader 2.59 + run_versioned aclocal "$VERSION" -I m4 + run_versioned autoconf 2.62 -Wall + run_versioned autoheader 2.62 run_versioned automake "$VERSION" --copy --foreign --add-missing if test "x$NOCONFIGURE" = "x"; then - CFLAGS="-g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --enable-force-preopen "$@" + CFLAGS="-g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --enable-force-preopen "$@" make clean fi fi diff --git a/configure.ac b/configure.ac index 80a06f0b..568f43a2 100644 --- a/configure.ac +++ b/configure.ac @@ -20,14 +20,15 @@ # along with PulseAudio; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -AC_PREREQ(2.60) +AC_PREREQ(2.62) m4_define(PA_MAJOR, [0]) m4_define(PA_MINOR, [9]) -m4_define(PA_MICRO, [11]) +m4_define(PA_MICRO, [12]) -AC_INIT([pulseaudio], PA_MAJOR.PA_MINOR.PA_MICRO,[mzchyfrnhqvb (at) 0pointer (dot) net]) +AC_INIT([pulseaudio],[PA_MAJOR.PA_MINOR.PA_MICRO],[mzchyfrnhqvb (at) 0pointer (dot) net]) AC_CONFIG_SRCDIR([src/daemon/main.c]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign 1.10 -Wall]) @@ -85,9 +86,10 @@ AC_PROG_MKDIR_P # CC AC_PROG_CC +AC_PROG_CC_C99 AM_PROG_CC_C_O AC_PROG_GCC_TRADITIONAL -AC_GNU_SOURCE +AC_USE_SYSTEM_EXTENSIONS # M4 @@ -96,37 +98,16 @@ if test "x$M4" = xno ; then AC_MSG_ERROR([m4 missing]) fi -# GCC flags - -test_gcc_flag() { - AC_LANG_CONFTEST([int main(int argc, char*argv[]) {}]) - $CC -c conftest.c $CFLAGS -o conftest.o > /dev/null 2> /dev/null - ret=$? - rm -f conftest.o - return $ret -} - -# If using GCC specify some additional parameters -if test "x$GCC" = "xyes" ; then - - # We use gnu99 instead of c99 because many have interpreted the standard - # in a way that int64_t isn't defined on non-64 bit platforms. - DESIRED_FLAGS="-std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -ffast-math" - - for flag in $DESIRED_FLAGS ; do - AC_MSG_CHECKING([whether $CC accepts $flag]) - if test_gcc_flag $flag ; then - CFLAGS="$CFLAGS $flag" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - done -fi +dnl Compiler flags +DESIRED_FLAGS="-Wall -W -Wextra -pedantic -pipe -Wno-long-long -Wvla -Wno-overlength-strings -Wconversion -Wundef -Wformat -Wlogical-op -Wpacked -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -ffast-math" + +for flag in $DESIRED_FLAGS ; do + CC_CHECK_CFLAGS([$flag], [CFLAGS="$CFLAGS $flag"]) +done # Native atomic operation support AC_ARG_ENABLE([atomic-arm-linux-helpers], - AC_HELP_STRING([--disable-atomic-arm-linux-helpers], [use inline asm or libatomic_ops instead]), + AS_HELP_STRING([--disable-atomic-arm-linux-helpers],[use inline asm or libatomic_ops instead]), [ case "${enableval}" in yes) atomic_arm_linux_helpers=yes ;; @@ -137,7 +118,7 @@ AC_ARG_ENABLE([atomic-arm-linux-helpers], [atomic_arm_linux_helpers=auto]) AC_ARG_ENABLE([atomic-arm-memory-barrier], - AC_HELP_STRING([--enable-atomic-arm-memory-barrier], [only really needed in SMP arm systems]), + AS_HELP_STRING([--enable-atomic-arm-memory-barrier],[only really needed in SMP arm systems]), [ case "${enableval}" in yes) AC_DEFINE_UNQUOTED(ATOMIC_ARM_MEMORY_BARRIER_ENABLED, 1, [Enable memory barriers]) ;; @@ -161,17 +142,18 @@ esac # If everything else fails use libatomic_ops need_libatomic_ops=yes -AC_MSG_CHECKING([whether $CC knows __sync_bool_compare_and_swap()]) -AC_LANG_CONFTEST([int main() { int a = 4; __sync_bool_compare_and_swap(&a, 4, 5); }]) -$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null -ret=$? -rm -f conftest.o conftest -if test $ret -eq 0 ; then +AC_CACHE_CHECK([whether $CC knows __sync_bool_compare_and_swap()], + pulseaudio_cv_sync_bool_compare_and_swap, + [AC_LINK_IFELSE( + AC_LANG_PROGRAM([], [[int a = 4; __sync_bool_compare_and_swap(&a, 4, 5);]]), + [pulseaudio_cv_sync_bool_compare_and_swap=yes], + [pulseaudio_cv_sync_bool_compare_and_swap=no]) + ]) + +if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then AC_DEFINE([HAVE_ATOMIC_BUILTINS], 1, [Have __sync_bool_compare_and_swap() and friends.]) - AC_MSG_RESULT([yes]) need_libatomic_ops=no else - AC_MSG_RESULT([no]) # HW specific atomic ops stuff AC_MSG_CHECKING([architecture for native atomic operations]) case $host_cpu in @@ -187,29 +169,27 @@ else need_libatomic_ops=no else AC_MSG_RESULT([no]) - AC_MSG_CHECKING([compiler support for arm inline asm atomic operations]) - AC_LANG_CONFTEST([[int main() - { - volatile int a=0; - int o=0, n=1, r; - asm volatile ("ldrex %0, [%1]\n" - "subs %0, %0, %2\n" - "strexeq %0, %3, [%1]\n" - : "=&r" (r) - : "r" (&a), "Ir" (o), "r" (n) - : "cc"); - return (a==1 ? 0 : -1); - }]]) - $CC conftest.c $CFLAGS -o conftest > /dev/null 2>&1 - ret=$? - rm -f conftest.o conftest - if test $ret -eq 0 ; then + AC_CACHE_CHECK([compiler support for arm inline asm atomic operations], + pulseaudio_cv_support_arm_atomic_ops, + [AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([], + [[volatile int a=0; + int o=0, n=1, r; + asm volatile ("ldrex %0, [%1]\n" + "subs %0, %0, %2\n" + "strexeq %0, %3, [%1]\n" + : "=&r" (r) + : "r" (&a), "Ir" (o), "r" (n) + : "cc"); + return (a==1 ? 0 : -1); + ]]), + [pulseaudio_cv_support_arm_atomic_ops=yes], + [pulseaudio_cv_support_arm_atomic_ops=no]) + ]) + AS_IF([test "$pulseaudio_cv_support_arm_atomic_ops" = "yes"], [ AC_DEFINE([ATOMIC_ARM_INLINE_ASM], 1, [Have ARMv6 instructions.]) - AC_MSG_RESULT([yes]) need_libatomic_ops=no - else - AC_MSG_RESULT([no]) - fi + ]) fi ;; *) @@ -218,29 +198,19 @@ else esac fi -AC_MSG_CHECKING([whether $CC knows __thread]) -AC_LANG_CONFTEST([static __thread int a = 6; int main() { a = 5; }]) -$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null -ret=$? -rm -f conftest.o conftest -if test $ret -eq 0 ; then - AC_DEFINE([HAVE_TLS_BUILTIN], 1, [Have __thread().]) - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi +CC_CHECK_TLS -AC_MSG_CHECKING([whether $CC knows _Bool]) -AC_LANG_CONFTEST([int main() { _Bool b; }]) -$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null -ret=$? -rm -f conftest.o conftest -if test $ret -eq 0 ; then +AC_CACHE_CHECK([whether $CC knows _Bool], + pulseaudio_cv__Bool, + [AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([], [[_Bool b;]]), + [pulseaudio_cv__Bool=yes], + [pulseaudio_cv__Bool=no]) + ]) + +AS_IF([test "$pulseaudio_cv__Bool" = "yes"], [ AC_DEFINE([HAVE_STD_BOOL], 1, [Have _Bool.]) - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi + ]) #### libtool stuff #### @@ -326,6 +296,7 @@ AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([byteswap.h]) AC_CHECK_HEADERS([sys/syscall.h]) +AC_CHECK_HEADERS([sys/eventfd.h]) #### Typdefs, structures, etc. #### @@ -414,20 +385,27 @@ AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strs AC_FUNC_ALLOCA -AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT]) -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -#include <pthread.h> -int main() { int i = PTHREAD_PRIO_INHERIT; }]])]) -$PTHREAD_CC conftest.c $PTHREAD_CFLAGS $CFLAGS $PTHREAD_LIBS -o conftest > /dev/null 2> /dev/null -ret=$? -rm -f conftest.o conftest - -if test $ret -eq 0 ; then +AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + pulseaudio_cv_PTHREAD_PRIO_INHERIT, + [save_CC=$CC; CC=$PTHREAD_CC + save_CFLAGS=$CFLAGS; CFLAGS=$PTHREAD_CFLAGS + save_LIBS=$LIBS; LIBS=$PTHREAD_LIBS + AC_LINK_IFELSE( + AC_LANG_PROGRAM( + [[ + #include <pthread.h> + ]], + [[int i = PTHREAD_PRIO_INHERIT;]]), + [pulseaudio_cv_PTHREAD_PRIO_INHERIT=yes], + [pulseaudio_cv_PTHREAD_PRIO_INHERIT=no]) + CC=$save_CC + CFLAGS=$save_CFLAGS + LIBS=$save_LIBS + ]) + +AS_IF([test "$pulseaudio_cv_PTHREAD_PRIO_INHERIT" = "yes"], [ AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]) - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi + ]) #### Large File-Support (LFS) #### @@ -440,6 +418,15 @@ AC_CHECK_FUNCS([open64]) AM_ICONV +IT_PROG_INTLTOOL([0.35.0]) +GETTEXT_PACKAGE=pulseaudio +AC_SUBST([GETTEXT_PACKAGE]) +AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package]) +AM_GLIB_GNU_GETTEXT + +pulselocaledir='${prefix}/${DATADIRNAME}/locale' +AC_SUBST(pulselocaledir) + ################################### # External libraries # ################################### @@ -466,7 +453,7 @@ CAP_LIBS='' AC_ARG_WITH( [caps], - AC_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.])) + AS_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.])) if test "x${with_caps}" != "xno"; then AC_SEARCH_LIBS([cap_init], [cap], [], [ @@ -479,6 +466,10 @@ if test "x${with_caps}" != "xno"; then fi]) fi +#### Valgrind (optional) #### + +AC_CHECK_HEADERS([valgrind/memcheck.h]) + #### pkg-config #### # Check for pkg-config manually first, as if its not installed the @@ -521,7 +512,7 @@ fi #### Libsamplerate support (optional) #### AC_ARG_ENABLE([samplerate], - AC_HELP_STRING([--disable-samplerate], [Disable optional libsamplerate support]), + AS_HELP_STRING([--disable-samplerate],[Disable optional libsamplerate support]), [ case "${enableval}" in yes) samplerate=yes ;; @@ -556,7 +547,7 @@ AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1]) #### OSS support (optional) #### AC_ARG_ENABLE([oss], - AC_HELP_STRING([--disable-oss], [Disable optional OSS support]), + AS_HELP_STRING([--disable-oss],[Disable optional OSS support]), [ case "${enableval}" in yes) oss=yes ;; @@ -589,7 +580,7 @@ AM_CONDITIONAL([HAVE_OSS], [test "x$HAVE_OSS" = x1]) #### ALSA support (optional) #### AC_ARG_ENABLE([alsa], - AC_HELP_STRING([--disable-alsa], [Disable optional ALSA support]), + AS_HELP_STRING([--disable-alsa],[Disable optional ALSA support]), [ case "${enableval}" in yes) alsa=yes ;; @@ -623,7 +614,7 @@ AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1]) #### Solaris audio support (optional) #### AC_ARG_ENABLE([solaris], - AC_HELP_STRING([--disable-solaris], [Disable optional Solaris audio support]), + AS_HELP_STRING([--disable-solaris],[Disable optional Solaris audio support]), [ case "${enableval}" in yes) solaris=yes ;; @@ -655,7 +646,7 @@ AM_CONDITIONAL([HAVE_SOLARIS], [test "x$HAVE_SOLARIS" = x1]) #### GLib 2 support (optional) #### AC_ARG_ENABLE([glib2], - AC_HELP_STRING([--disable-glib2], [Disable optional GLib 2 support]), + AS_HELP_STRING([--disable-glib2],[Disable optional GLib 2 support]), [ case "${enableval}" in yes) glib2=yes ;; @@ -686,7 +677,7 @@ AM_CONDITIONAL([HAVE_GLIB20], [test "x$HAVE_GLIB20" = x1]) #### GConf support (optional) #### AC_ARG_ENABLE([gconf], - AC_HELP_STRING([--disable-gconf], [Disable optional GConf support]), + AS_HELP_STRING([--disable-gconf],[Disable optional GConf support]), [ case "${enableval}" in yes) gconf=yes ;; @@ -717,7 +708,7 @@ AM_CONDITIONAL([HAVE_GCONF], [test "x$HAVE_GCONF" = x1]) #### Avahi support (optional) #### AC_ARG_ENABLE([avahi], - AC_HELP_STRING([--disable-avahi], [Disable optional Avahi support]), + AS_HELP_STRING([--disable-avahi],[Disable optional Avahi support]), [ case "${enableval}" in yes) avahi=yes ;; @@ -754,7 +745,7 @@ AC_SUBST(LIBOIL_LIBS) ### JACK (optional) #### AC_ARG_ENABLE([jack], - AC_HELP_STRING([--disable-jack], [Disable optional JACK support]), + AS_HELP_STRING([--disable-jack],[Disable optional JACK support]), [ case "${enableval}" in yes) jack=yes ;; @@ -785,7 +776,7 @@ AM_CONDITIONAL([HAVE_JACK], [test "x$HAVE_JACK" = x1]) #### Async DNS support (optional) #### AC_ARG_ENABLE([asyncns], - AC_HELP_STRING([--disable-asyncns], [Disable optional Async DNS support]), + AS_HELP_STRING([--disable-asyncns],[Disable optional Async DNS support]), [ case "${enableval}" in yes) asyncns=yes ;; @@ -820,7 +811,7 @@ fi #### TCP wrappers (optional) #### AC_ARG_ENABLE([tcpwrap], - AC_HELP_STRING([--disable-tcpwrap], [Disable optional TCP wrappers support]), + AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]), [ case "${enableval}" in yes) tcpwrap=yes ;; @@ -844,7 +835,7 @@ AC_SUBST(LIBWRAP_LIBS) #### LIRC support (optional) #### AC_ARG_ENABLE([lirc], - AC_HELP_STRING([--disable-lirc], [Disable optional LIRC support]), + AS_HELP_STRING([--disable-lirc],[Disable optional LIRC support]), [ case "${enableval}" in yes) lirc=yes ;; @@ -870,7 +861,7 @@ AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1]) #### HAL support (optional) #### AC_ARG_ENABLE([hal], - AC_HELP_STRING([--disable-hal], [Disable optional HAL support]), + AS_HELP_STRING([--disable-hal],[Disable optional HAL support]), [ case "${enableval}" in yes) hal=yes ;; @@ -900,7 +891,7 @@ AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1]) #### BlueZ support (optional) #### AC_ARG_ENABLE([bluez], - AC_HELP_STRING([--disable-bluez], [Disable optional BlueZ support]), + AS_HELP_STRING([--disable-bluez],[Disable optional BlueZ support]), [ case "${enableval}" in yes) bluez=yes ;; @@ -930,7 +921,7 @@ AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1]) #### D-Bus support (optional) #### AC_ARG_ENABLE([dbus], - AC_HELP_STRING([--disable-dbus], [Disable optional D-Bus support]), + AS_HELP_STRING([--disable-dbus],[Disable optional D-Bus support]), [ case "${enableval}" in yes) dbus=yes ;; @@ -973,7 +964,7 @@ AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1]) #### PolicyKit support (optional) #### AC_ARG_ENABLE([polkit], - AC_HELP_STRING([--disable-polkit], [Disable optional PolicyKit support]), + AS_HELP_STRING([--disable-polkit],[Disable optional PolicyKit support]), [ case "${enableval}" in yes) polkit=yes ;; @@ -1086,13 +1077,13 @@ AC_SUBST(PA_SYSTEM_STATE_PATH) AC_ARG_ENABLE( [static-bins], - AC_HELP_STRING([--enable-static-bins],[Statically link executables.]), + AS_HELP_STRING([--enable-static-bins],[Statically link executables.]), [STATIC_BINS=1], [STATIC_BINS=0]) AM_CONDITIONAL([STATIC_BINS], [test "x$STATIC_BINS" = "x1"]) AC_ARG_WITH( [preopen-mods], - AC_HELP_STRING([--with-preopen-mods],[Modules to preopen in daemon (default: all).]), + AS_HELP_STRING([--with-preopen-mods],[Modules to preopen in daemon (default: all).]), [PREOPEN_MODS=$withval], [PREOPEN_MODS="all"]) AM_CONDITIONAL([PREOPEN_MODS], [test "x$PREOPEN_MODS" != "xall"]) if test "x$PREOPEN_MODS" != "xall" ; then @@ -1106,14 +1097,14 @@ fi AC_ARG_WITH( [module-dir], - AC_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINOR}/modules/]), + AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINOR}/modules/]), [modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINOR}/modules/"]) AC_SUBST(modlibexecdir) AC_ARG_ENABLE( [force-preopen], - AC_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]), + AS_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]), [FORCE_PREOPEN=1], [FORCE_PREOPEN=0]) AM_CONDITIONAL([FORCE_PREOPEN], [test "x$FORCE_PREOPEN" = "x1"]) @@ -1128,6 +1119,7 @@ libpulse-mainloop-glib.pc doxygen/Makefile doxygen/doxygen.conf src/pulse/version.h +po/Makefile.in ]) AC_OUTPUT diff --git a/doxygen/doxygen.conf.in b/doxygen/doxygen.conf.in index 7ad5d2f3..6c2021ce 100644 --- a/doxygen/doxygen.conf.in +++ b/doxygen/doxygen.conf.in @@ -14,191 +14,191 @@ # Project related configuration options #--------------------------------------------------------------------------- -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = PulseAudio -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = +OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of source -# files, where putting all generated files in the same directory would otherwise +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise # cause performance problems for the file system. CREATE_SUBDIRS = NO -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is used -# as the annotated text. Otherwise, the brief description is used as-is. If left -# blank, the following values are used ("$name" is automatically replaced with the -# name of the entity): "The $name class" "The $name widget" "The $name file" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" # "is" "provides" "specifies" "contains" "represents" "a" "an" "the" -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of # the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = +STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member +# If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES @@ -207,162 +207,162 @@ SUBGROUPING = YES # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = NO -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = NO -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = NO -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= NO -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES @@ -371,133 +371,133 @@ SHOW_USED_FILES = YES # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../src/pulse/context.h ../src/pulse/stream.h ../src/pulse/pulseaudio.h ../src/pulse/sample.h ../src/pulse/def.h ../src/pulse/subscribe.h ../src/pulse/introspect.h ../src/pulse/scache.h ../src/pulse/mainloop-api.h ../src/pulse/glib-mainloop.h ../src/pulse/mainloop.h ../src/pulse/mainloop-signal.h ../src/pulse/error.h ../src/pulse/operation.h ../src/pulse/simple.h ../src/pulse/version.h ../src/pulse/volume.h ../src/pulse/channelmap.h ../src/pulse/thread-mainloop.h ../src/pulse/xmalloc.h ../src/pulse/utf8.h ../src/pulse/util.h ../src/pulse/timeval.h ../src/pulse/proplist.h ../src/pulse/gccmacro.h +INPUT = ../src/pulse/context.h ../src/pulse/stream.h ../src/pulse/pulseaudio.h ../src/pulse/sample.h ../src/pulse/def.h ../src/pulse/subscribe.h ../src/pulse/introspect.h ../src/pulse/scache.h ../src/pulse/mainloop-api.h ../src/pulse/glib-mainloop.h ../src/pulse/mainloop.h ../src/pulse/mainloop-signal.h ../src/pulse/error.h ../src/pulse/operation.h ../src/pulse/simple.h ../src/pulse/version.h ../src/pulse/volume.h ../src/pulse/channelmap.h ../src/pulse/thread-mainloop.h ../src/pulse/xmalloc.h ../src/pulse/utf8.h ../src/pulse/util.h ../src/pulse/timeval.h ../src/pulse/proplist.h ../src/pulse/gccmacro.h ../src/pulse/ext-stream-restore.h -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm -FILE_PATTERNS = +FILE_PATTERNS = -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # that are symbolic links (a Unix filesystem feature) are excluded from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = ../src/utils ../src/tests -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO @@ -506,38 +506,38 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES @@ -546,21 +546,21 @@ VERBATIM_HEADERS = YES # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = pa_ PA_ @@ -569,110 +569,110 @@ IGNORE_PREFIX = pa_ PA_ # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 1 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = YES -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 @@ -681,74 +681,74 @@ TREEVIEW_WIDTH = 250 # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO @@ -757,68 +757,68 @@ LATEX_HIDE_INDICES = NO # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -827,33 +827,33 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -862,10 +862,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -874,283 +874,282 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = YES -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. PREDEFINED = PA_C_DECL_BEGIN= PA_C_DECL_END= -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. #EXPAND_AS_DEFINED = PA_C_DECL_BEGIN, PA_C_DECL_END -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse the +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the # parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen +# If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is # recommended to install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. -DOT_PATH = +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes that -# lay further from the root node will be omitted. Note that setting this option to -# 1 or 2 may greatly reduce the computation time needed for large code bases. Also -# note that a graph may be further truncated if the graph's image dimensions are -# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). # If 0 is used for the depth value (the default), the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- -# Configuration::additions related to the search engine +# Configuration::additions related to the search engine #--------------------------------------------------------------------------- -# The SEARCHENGINE tag specifies whether or not a search engine should be +# The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO SHOW_DIRECTORIES=NO - diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..8b81e54b --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,17 @@ +ChangeLog +gettext.m4 +iconv.m4 +lib-ld.m4 +lib-link.m4 +lib-prefix.m4 +nls.m4 +po.m4 +progtest.m4 +argz.m4 +intltool.m4 +libtool.m4 +ltdl.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4 new file mode 100644 index 00000000..e1602144 --- /dev/null +++ b/m4/acx_libwrap.m4 @@ -0,0 +1,19 @@ +AC_DEFUN([ACX_LIBWRAP], [ +LIBWRAP_LIBS= +saved_LIBS="$LIBS" +LIBS="$LIBS -lwrap" +AC_MSG_CHECKING([for tcpwrap library and headers]) +AC_LINK_IFELSE( +AC_LANG_PROGRAM( +[#include <tcpd.h> +#include <syslog.h> +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING;], +[struct request_info *req; +return hosts_access (req);]), +[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?]) +LIBWRAP_LIBS="-lwrap" +AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) +LIBS="$saved_LIBS" +]) diff --git a/m4/acx_lirc.m4 b/m4/acx_lirc.m4 new file mode 100644 index 00000000..d3f8ea73 --- /dev/null +++ b/m4/acx_lirc.m4 @@ -0,0 +1,6 @@ +AC_DEFUN([ACX_LIRC], [ +LIRC_CFLAGS= +LIRC_LIBS= +AC_CHECK_HEADER(lirc/lirc_client.h,[AC_CHECK_LIB(lirc_client,lirc_init,[HAVE_LIRC=1 +LIRC_LIBS=-llirc_client],HAVE_LIRC=0)],HAVE_LIRC=0) +]) diff --git a/acinclude.m4 b/m4/acx_pthread.m4 index 02c05186..cbd6bfa0 100644 --- a/acinclude.m4 +++ b/m4/acx_pthread.m4 @@ -346,43 +346,3 @@ else fi AC_LANG_RESTORE ])dnl ACX_PTHREAD -AC_DEFUN([AC_CHECK_DEFINE],[ -AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1_$2])dnl -AC_CACHE_CHECK([for $1 in $2], ac_var, -AC_TRY_COMPILE([#include <$2>],[ - #ifdef $1 - int ok; - #else - choke me - #endif -],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no))) -AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl -AS_VAR_POPDEF([ac_var])dnl -]) - -AC_DEFUN([ACX_LIBWRAP], [ -LIBWRAP_LIBS= -saved_LIBS="$LIBS" -LIBS="$LIBS -lwrap" -AC_MSG_CHECKING([for tcpwrap library and headers]) -AC_LINK_IFELSE( -AC_LANG_PROGRAM( -[#include <tcpd.h> -#include <syslog.h> -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING;], -[struct request_info *req; -return hosts_access (req);]), -[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?]) -LIBWRAP_LIBS="-lwrap" -AC_MSG_RESULT(yes)], -[AC_MSG_RESULT(no)]) -LIBS="$saved_LIBS" -]) - -AC_DEFUN([ACX_LIRC], [ -LIRC_CFLAGS= -LIRC_LIBS= -AC_CHECK_HEADER(lirc/lirc_client.h,[AC_CHECK_LIB(lirc_client,lirc_init,[HAVE_LIRC=1 -LIRC_LIBS=-llirc_client],HAVE_LIRC=0)],HAVE_LIRC=0) -]) diff --git a/m4/attributes.m4 b/m4/attributes.m4 new file mode 100644 index 00000000..9c4a0c89 --- /dev/null +++ b/m4/attributes.m4 @@ -0,0 +1,258 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2007 Diego Pettenò <flameeyes@gmail.com> +dnl Copyright (c) 2006-2007 xine project +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ + AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_COMPILE_IFELSE([int a;], + [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +AC_DEFUN([CC_CHECK_CFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([int main() { return 1; }], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([$3], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/m4/check_define.m4 b/m4/check_define.m4 new file mode 100644 index 00000000..43edc78e --- /dev/null +++ b/m4/check_define.m4 @@ -0,0 +1,13 @@ +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1_$2])dnl +AC_CACHE_CHECK([for $1 in $2], ac_var, +AC_TRY_COMPILE([#include <$2>],[ + #ifdef $1 + int ok; + #else + choke me + #endif +],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no))) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +]) diff --git a/m4/tls.m4 b/m4/tls.m4 new file mode 100644 index 00000000..3808f06e --- /dev/null +++ b/m4/tls.m4 @@ -0,0 +1,17 @@ +AC_DEFUN([CC_CHECK_TLS], [ + AC_CACHE_CHECK([whether $CC knows __thread for Thread-Local Storage], + cc_cv_tls___thread, + [AC_COMPILE_IFELSE( + AC_LANG_PROGRAM( + [[static __thread int a = 6;]], + [[a = 5;]]), + [cc_cv_tls___thread=yes], + [cc_cv_tls___thread=no]) + ]) + + AS_IF([test "x$cc_cv_tls___thread" = "xyes"], + [AC_DEFINE([SUPPORT_TLS___THREAD], 1, + [Define this if the compiler supports __thread for Thread-Local Storage]) + $1], + [$2]) +]) diff --git a/man/Makefile.am b/man/Makefile.am index b0536d84..9b229f52 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -17,9 +17,10 @@ pulseconfdir=$(sysconfdir)/pulse -if BUILD_MANPAGES +CLEANFILES = \ + $(noinst_DATA) -man_MANS = \ +dist_man_MANS = \ pulseaudio.1 \ esdcompat.1 \ pax11publish.1 \ @@ -49,115 +50,18 @@ noinst_DATA = \ pulse-client.conf.5.xml \ default.pa.5.xml -CLEANFILES = \ - $(noinst_DATA) - -pulseaudio.1.xml: pulseaudio.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -esdcompat.1.xml: esdcompat.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pax11publish.1.xml: pax11publish.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -paplay.1.xml: paplay.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pacat.1.xml: pacat.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pacmd.1.xml: pacmd.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pactl.1.xml: pactl.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pasuspender.1.xml: pasuspender.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -padsp.1.xml: padsp.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pabrowse.1.xml: pabrowse.1.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ - -pulse-daemon.conf.5.xml: pulse-daemon.conf.5.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ +if BUILD_MANPAGES -pulse-client.conf.5.xml: pulse-client.conf.5.xml.in Makefile - sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ - -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ - -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ +CLEANFILES += \ + $(dist_man_MANS) -default.pa.5.xml: default.pa.5.xml.in Makefile +%.xml: %.xml.in Makefile sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \ -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \ -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@ -CLEANFILES += \ - $(man_MANS) - -pulseaudio.1: pulseaudio.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -esdcompat.1: esdcompat.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pax11publish.1: pax11publish.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -paplay.1: paplay.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pacat.1: pacat.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pacmd.1: pacmd.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pactl.1: pactl.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pasuspender.1: pasuspender.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -padsp.1: padsp.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pabrowse.1: pabrowse.1.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pulse-daemon.conf.5: pulse-daemon.conf.5.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -pulse-client.conf.5: pulse-client.conf.5.xml Makefile - perl xmltoman $< > $@ || rm -f $@ - -default.pa.5: default.pa.5.xml Makefile - perl xmltoman $< > $@ || rm -f $@ +%: %.xml Makefile + perl $(srcdir)/xmltoman $< > $@ || rm -f $@ xmllint: $(noinst_DATA) for f in $(noinst_DATA) ; do \ @@ -167,7 +71,6 @@ xmllint: $(noinst_DATA) endif EXTRA_DIST = \ - $(man_MANS) \ pulseaudio.1.xml.in \ esdcompat.1.xml.in \ pax11publish.1.xml.in \ diff --git a/po/.gitignore b/po/.gitignore new file mode 100644 index 00000000..26919828 --- /dev/null +++ b/po/.gitignore @@ -0,0 +1,14 @@ +Makefile.in.in +Makevars.template +POTFILES +Rules-quot +boldquot.sed +en@boldquot.header +en@quot.header +insert-header.sin +pulseaudio.pot +quot.sed +remove-potcdate.sin +ChangeLog +*.mo +*.gmo diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 00000000..7673daa9 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1 @@ +de diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 00000000..fa28b6a7 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,192 @@ +src/modules/module-rescue-streams.c +src/modules/module-tunnel.c +src/modules/module-native-protocol-fd.c +src/modules/module-zeroconf-discover.c +src/modules/module-alsa-source.c +src/modules/module-device-restore.c +src/modules/module-match.c +src/modules/dbus-util.c +src/modules/module-console-kit.c +src/modules/module-oss.c +src/modules/oss-util.c +src/modules/module-mmkbd-evdev.c +src/modules/module-position-event-sounds.c +src/modules/alsa-util.c +src/modules/module-pipe-source.c +src/modules/module-solaris.c +src/modules/module-default-device-restore.c +src/modules/module-x11-xsmp.c +src/modules/module-remap-sink.c +src/modules/module-bt-proximity.c +src/modules/module-detect.c +src/modules/module-always-sink.c +src/modules/module-lirc.c +src/modules/module-hal-detect.c +src/modules/module-sine.c +src/modules/module-zeroconf-publish.c +src/modules/module-jack-source.c +src/modules/module-cli.c +src/modules/gconf/module-gconf.c +src/modules/gconf/gconf-helper.c +src/modules/module-esound-sink.c +src/modules/module-alsa-sink.c +src/modules/module-volume-restore.c +src/modules/module-x11-bell.c +src/modules/module-protocol-stub.c +src/modules/module-stream-restore.c +src/modules/module-jack-sink.c +src/modules/module-esound-compat-spawnfd.c +src/modules/module-esound-compat-spawnpid.c +#src/modules/module-waveout.c +src/modules/module-combine.c +src/modules/bt-proximity-helper.c +src/modules/module-x11-publish.c +src/modules/rtp/module-rtp-recv.c +src/modules/rtp/sdp.c +src/modules/rtp/rtp.c +src/modules/rtp/sap.c +src/modules/rtp/module-rtp-send.c +src/modules/module-ladspa-sink.c +src/modules/module-suspend-on-idle.c +src/modules/module-pipe-sink.c +src/modules/module-null-sink.c +src/pulsecore/memblock.c +src/pulsecore/queue.c +src/pulsecore/core.c +#src/pulsecore/shmasyncq.c +src/pulsecore/x11wrap.c +src/pulsecore/rtclock.c +src/pulsecore/ioline.c +src/pulsecore/autoload.c +src/pulsecore/asyncq.c +src/pulsecore/mutex-posix.c +src/pulsecore/protocol-esound.c +src/pulsecore/proplist-util.c +src/pulsecore/pstream.c +src/pulsecore/cli-command.c +src/pulsecore/ltdl-helper.c +src/pulsecore/ipacl.c +src/pulsecore/sample-util.c +src/pulsecore/log.c +src/pulsecore/auth-cookie.c +src/pulsecore/protocol-cli.c +src/pulsecore/resampler.c +src/pulsecore/pdispatch.c +src/pulsecore/hook-list.c +src/pulsecore/conf-parser.c +src/pulsecore/mcalign.c +src/pulsecore/core-subscribe.c +src/pulsecore/protocol-native.c +src/pulsecore/source-output.c +src/pulsecore/modargs.c +src/pulsecore/core-scache.c +src/pulsecore/iochannel.c +src/pulsecore/shared.c +src/pulsecore/socket-client.c +src/pulsecore/idxset.c +src/pulsecore/pipe.c +src/pulsecore/asyncmsgq.c +src/pulsecore/inet_pton.c +src/pulsecore/socket-util.c +src/pulsecore/object.c +src/pulsecore/sioman.c +src/pulsecore/sink-input.c +src/pulsecore/x11prop.c +src/pulsecore/sconv-s16be.c +src/pulsecore/thread-posix.c +src/pulsecore/client.c +src/pulsecore/inet_ntop.c +src/pulsecore/strlist.c +src/pulsecore/msgobject.c +src/pulsecore/mutex-win32.c +src/pulsecore/dynarray.c +src/pulsecore/rtsig.c +src/pulsecore/once.c +src/pulsecore/source.c +src/pulsecore/memchunk.c +src/pulsecore/protocol-simple.c +src/pulsecore/sink.c +src/pulsecore/sconv-s16le.c +src/pulsecore/sconv.c +src/pulsecore/core-error.c +src/pulsecore/strbuf.c +src/pulsecore/play-memblockq.c +src/pulsecore/dllmain.c +src/pulsecore/envelope.c +src/pulsecore/pid.c +src/pulsecore/thread-mq.c +src/pulsecore/shm.c +src/pulsecore/play-memchunk.c +src/pulsecore/hashmap.c +src/pulsecore/avahi-wrap.c +src/pulsecore/authkey.c +src/pulsecore/namereg.c +src/pulsecore/poll.c +src/pulsecore/tokenizer.c +src/pulsecore/semaphore-posix.c +src/pulsecore/cli-text.c +src/pulsecore/g711.c +src/pulsecore/core-util.c +src/pulsecore/thread-win32.c +src/pulsecore/tagstruct.c +src/pulsecore/socket-server.c +src/pulsecore/flist.c +src/pulsecore/fdsem.c +src/pulsecore/random.c +src/pulsecore/modinfo.c +src/pulsecore/start-child.c +src/pulsecore/packet.c +src/pulsecore/pstream-util.c +src/pulsecore/rtpoll.c +src/pulsecore/sound-file.c +src/pulsecore/module.c +src/pulsecore/ffmpeg/resample2.c +src/pulsecore/cli.c +src/pulsecore/time-smoother.c +src/pulsecore/parseaddr.c +src/pulsecore/sound-file-stream.c +src/pulsecore/memblockq.c +src/pulsecore/protocol-http.c +src/pulsecore/semaphore-win32.c +src/daemon/cpulimit.c +src/daemon/ltdl-bind-now.c +src/daemon/polkit.c +src/daemon/main.c +src/daemon/cmdline.c +src/daemon/dumpmodules.c +src/daemon/daemon-conf.c +src/daemon/caps.c +src/pulse/channelmap.c +src/pulse/error.c +src/pulse/proplist.c +src/pulse/xmalloc.c +src/pulse/ext-stream-restore.c +src/pulse/stream.c +src/pulse/i18n.c +src/pulse/util.c +src/pulse/utf8.c +src/pulse/mainloop-api.c +src/pulse/sample.c +src/pulse/client-conf-x11.c +src/pulse/client-conf.c +src/pulse/browser.c +src/pulse/volume.c +src/pulse/simple.c +src/pulse/subscribe.c +src/pulse/introspect.c +src/pulse/mainloop.c +src/pulse/mainloop-signal.c +src/pulse/operation.c +src/pulse/context.c +src/pulse/thread-mainloop.c +src/pulse/scache.c +src/pulse/glib-mainloop.c +src/pulse/timeval.c +src/utils/pacat.c +src/utils/pasuspender.c +src/utils/pabrowse.c +src/utils/pactl.c +src/utils/padsp.c +src/utils/pax11publish.c +src/utils/pacmd.c +src/utils/paplay.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip new file mode 100644 index 00000000..4622d2fe --- /dev/null +++ b/po/POTFILES.skip @@ -0,0 +1 @@ +src/pulsecore/atomic.h diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..2a7c5deb --- /dev/null +++ b/po/de.po @@ -0,0 +1,1753 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-08-06 20:24+0200\n" +"PO-Revision-Date: 2008-08-06 20:34+0100\n" +"Last-Translator: Lennart Poettering <lennart@poettering.net>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../src/daemon/ltdl-bind-now.c:171 +#: ../src/daemon/ltdl-bind-now.c:191 +msgid "Failed to add bind-now-loader." +msgstr "" + +#: ../src/daemon/ltdl-bind-now.c:178 +msgid "Failed to find original dlopen loader." +msgstr "" + +#: ../src/daemon/polkit.c:55 +#, c-format +msgid "Cannot connect to system bus: %s" +msgstr "" + +#: ../src/daemon/polkit.c:65 +#, c-format +msgid "Cannot get caller from PID: %s" +msgstr "" + +#: ../src/daemon/polkit.c:77 +msgid "Cannot set UID on caller object." +msgstr "" + +#: ../src/daemon/polkit.c:82 +msgid "Failed to get CK session." +msgstr "" + +#: ../src/daemon/polkit.c:90 +msgid "Cannot set UID on session object." +msgstr "" + +#: ../src/daemon/polkit.c:95 +msgid "Cannot allocate PolKitAction." +msgstr "" + +#: ../src/daemon/polkit.c:100 +msgid "Cannot set action_id" +msgstr "" + +#: ../src/daemon/polkit.c:105 +msgid "Cannot allocate PolKitContext." +msgstr "" + +#: ../src/daemon/polkit.c:110 +#, c-format +msgid "Cannot initialize PolKitContext: %s" +msgstr "" + +#: ../src/daemon/polkit.c:119 +#, c-format +msgid "Could not determine whether caller is authorized: %s" +msgstr "" + +#: ../src/daemon/polkit.c:139 +#, c-format +msgid "Cannot obtain auth: %s" +msgstr "" + +#: ../src/daemon/polkit.c:148 +#, c-format +msgid "PolicyKit responded with '%s'" +msgstr "" + +#: ../src/daemon/main.c:135 +#, c-format +msgid "Got signal %s." +msgstr "Signal %s empfangen." + +#: ../src/daemon/main.c:162 +msgid "Exiting." +msgstr "Beende." + +#: ../src/daemon/main.c:180 +#, c-format +msgid "Failed to find user '%s'." +msgstr "" + +#: ../src/daemon/main.c:185 +#, c-format +msgid "Failed to find group '%s'." +msgstr "" + +#: ../src/daemon/main.c:189 +#, c-format +msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)." +msgstr "" + +#: ../src/daemon/main.c:194 +#, c-format +msgid "GID of user '%s' and of group '%s' don't match." +msgstr "" + +#: ../src/daemon/main.c:199 +#, c-format +msgid "Home directory of user '%s' is not '%s', ignoring." +msgstr "" + +#: ../src/daemon/main.c:202 +#: ../src/daemon/main.c:207 +#, c-format +msgid "Failed to create '%s': %s" +msgstr "" + +#: ../src/daemon/main.c:214 +#, c-format +msgid "Failed to change group list: %s" +msgstr "" + +#: ../src/daemon/main.c:230 +#, c-format +msgid "Failed to change GID: %s" +msgstr "" + +#: ../src/daemon/main.c:246 +#, c-format +msgid "Failed to change UID: %s" +msgstr "" + +#: ../src/daemon/main.c:260 +msgid "Successfully dropped root privileges." +msgstr "" + +#: ../src/daemon/main.c:268 +msgid "System wide mode unsupported on this platform." +msgstr "" + +#: ../src/daemon/main.c:286 +#, c-format +msgid "setrlimit(%s, (%u, %u)) failed: %s" +msgstr "" + +#: ../src/daemon/main.c:425 +msgid "Failed to parse command line." +msgstr "" + +#: ../src/daemon/main.c:441 +#, c-format +msgid "We're in the group '%s', allowing high-priority scheduling." +msgstr "" + +#: ../src/daemon/main.c:448 +#, c-format +msgid "We're in the group '%s', allowing real-time scheduling." +msgstr "" + +#: ../src/daemon/main.c:456 +msgid "PolicyKit grants us acquire-high-priority privilege." +msgstr "" + +#: ../src/daemon/main.c:459 +msgid "PolicyKit refuses acquire-high-priority privilege." +msgstr "" + +#: ../src/daemon/main.c:464 +msgid "PolicyKit grants us acquire-real-time privilege." +msgstr "" + +#: ../src/daemon/main.c:467 +msgid "PolicyKit refuses acquire-real-time privilege." +msgstr "" + +#: ../src/daemon/main.c:479 +msgid "" +"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n" +"We are not in group '" +msgstr "" + +#: ../src/daemon/main.c:497 +msgid "High-priority scheduling enabled in configuration but not allowed by policy." +msgstr "" + +#: ../src/daemon/main.c:522 +msgid "Successfully increased RLIMIT_RTPRIO" +msgstr "" + +#: ../src/daemon/main.c:525 +#, c-format +msgid "RLIMIT_RTPRIO failed: %s" +msgstr "" + +#: ../src/daemon/main.c:532 +msgid "Giving up CAP_NICE" +msgstr "" + +#: ../src/daemon/main.c:539 +msgid "Real-time scheduling enabled in configuration but not allowed by policy." +msgstr "" + +#: ../src/daemon/main.c:597 +msgid "Daemon not running" +msgstr "" + +#: ../src/daemon/main.c:599 +#, c-format +msgid "Daemon running as PID %u" +msgstr "" + +#: ../src/daemon/main.c:609 +msgid "Failed to kill daemon." +msgstr "" + +#: ../src/daemon/main.c:627 +msgid "This program is not intended to be run as root (unless --system is specified)." +msgstr "" + +#: ../src/daemon/main.c:629 +msgid "Root priviliges required." +msgstr "" + +#: ../src/daemon/main.c:634 +msgid "--start not supported for system instances." +msgstr "" + +#: ../src/daemon/main.c:639 +msgid "Running in system mode, but --disallow-exit not set!" +msgstr "" + +#: ../src/daemon/main.c:642 +msgid "Running in system mode, but --disallow-module-loading not set!" +msgstr "" + +#: ../src/daemon/main.c:645 +msgid "Running in system mode, forcibly disabling SHM mode!" +msgstr "" + +#: ../src/daemon/main.c:650 +msgid "Running in system mode, forcibly disabling exit idle time!" +msgstr "" + +#: ../src/daemon/main.c:668 +msgid "Failed to acquire stdio." +msgstr "" + +#: ../src/daemon/main.c:674 +#, c-format +msgid "pipe failed: %s" +msgstr "" + +#: ../src/daemon/main.c:679 +#, c-format +msgid "fork() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:693 +#, c-format +msgid "read() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:699 +msgid "Daemon startup failed." +msgstr "Start des Dämons fehlgeschlagen." + +#: ../src/daemon/main.c:701 +msgid "Daemon startup successful." +msgstr "Start des Dämons erfolgreich." + +#: ../src/daemon/main.c:768 +#, c-format +msgid "This is PulseAudio %s" +msgstr "Dies ist PulseAudio %s" + +#: ../src/daemon/main.c:769 +#, c-format +msgid "Page size is %lu bytes" +msgstr "Seitengröße ist %lu Bytes." + +#: ../src/daemon/main.c:772 +#, c-format +msgid "Using runtime directory %s." +msgstr "" + +#: ../src/daemon/main.c:775 +#, c-format +msgid "Using state directory %s." +msgstr "" + +#: ../src/daemon/main.c:778 +#, c-format +msgid "Running in system mode: %s" +msgstr "" + +#: ../src/daemon/main.c:793 +msgid "pa_pid_file_create() failed." +msgstr "" + +#: ../src/daemon/main.c:805 +msgid "Fresh high-resolution timers available! Bon appetit!" +msgstr "" + +#: ../src/daemon/main.c:807 +msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!" +msgstr "" + +#: ../src/daemon/main.c:817 +msgid "pa_core_new() failed." +msgstr "" + +#: ../src/daemon/main.c:877 +msgid "Failed to initialize daemon." +msgstr "" + +#: ../src/daemon/main.c:882 +msgid "Daemon startup without any loaded modules, refusing to work." +msgstr "" + +#: ../src/daemon/main.c:887 +#, c-format +msgid "Default sink name (%s) does not exist in name register." +msgstr "" + +#: ../src/daemon/main.c:900 +msgid "Daemon startup complete." +msgstr "Start des Dämons abgeschlossen." + +#: ../src/daemon/main.c:906 +msgid "Daemon shutdown initiated." +msgstr "" + +#: ../src/daemon/main.c:923 +msgid "Daemon terminated." +msgstr "Dämon beendet." + +#: ../src/daemon/cmdline.c:117 +#, c-format +msgid "" +"%s [options]\n" +"\n" +"COMMANDS:\n" +" -h, --help Show this help\n" +" --version Show version\n" +" --dump-conf Dump default configuration\n" +" --dump-modules Dump list of available modules\n" +" --dump-resample-methods Dump available resample methods\n" +" --cleanup-shm Cleanup stale shared memory segments\n" +" --start Start the daemon if it is not running\n" +" -k --kill Kill a running daemon\n" +" --check Check for a running daemon\n" +"\n" +"OPTIONS:\n" +" --system[=BOOL] Run as system-wide instance\n" +" -D, --daemonize[=BOOL] Daemonize after startup\n" +" --fail[=BOOL] Quit when startup fails\n" +" --high-priority[=BOOL] Try to set high nice level\n" +" (only available as root, when SUID or\n" +" with elevated RLIMIT_NICE)\n" +" --realtime[=BOOL] Try to enable realtime scheduling\n" +" (only available as root, when SUID or\n" +" with elevated RLIMIT_RTPRIO)\n" +" --disallow-module-loading[=BOOL] Disallow module user requested module\n" +" loading/unloading after startup\n" +" --disallow-exit[=BOOL] Disallow user requested exit\n" +" --exit-idle-time=SECS Terminate the daemon when idle and this\n" +" time passed\n" +" --module-idle-time=SECS Unload autoloaded modules when idle and\n" +" this time passed\n" +" --scache-idle-time=SECS Unload autoloaded samples when idle and\n" +" this time passed\n" +" --log-level[=LEVEL] Increase or set verbosity level\n" +" -v Increase the verbosity level\n" +" --log-target={auto,syslog,stderr} Specify the log target\n" +" -p, --dl-search-path=PATH Set the search path for dynamic shared\n" +" objects (plugins)\n" +" --resample-method=METHOD Use the specified resampling method\n" +" (See --dump-resample-methods for\n" +" possible values)\n" +" --use-pid-file[=BOOL] Create a PID file\n" +" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n" +" platforms that support it.\n" +" --disable-shm[=BOOL] Disable shared memory support.\n" +"\n" +"STARTUP SCRIPT:\n" +" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module with\n" +" the specified argument\n" +" -F, --file=FILENAME Run the specified script\n" +" -C Open a command line on the running TTY\n" +" after startup\n" +"\n" +" -n Don't load default script file\n" +msgstr "" + +#: ../src/daemon/cmdline.c:245 +msgid "--daemonize expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:252 +msgid "--fail expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:262 +msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)." +msgstr "" + +#: ../src/daemon/cmdline.c:274 +msgid "--high-priority expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:281 +msgid "--realtime expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:288 +msgid "--disallow-module-loading expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:295 +msgid "--disallow-exit boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:302 +msgid "--use-pid-file expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:319 +msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'." +msgstr "" + +#: ../src/daemon/cmdline.c:338 +#, c-format +msgid "Invalid resample method '%s'." +msgstr "" + +#: ../src/daemon/cmdline.c:345 +msgid "--system expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:352 +msgid "--no-cpu-limit expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:359 +msgid "--disable-shm expects boolean argument" +msgstr "" + +#: ../src/daemon/dumpmodules.c:60 +#, c-format +msgid "Name: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:63 +#, c-format +msgid "No module information available\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:66 +#, c-format +msgid "Version: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:68 +#, c-format +msgid "Description: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:70 +#, c-format +msgid "Author: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:72 +#, c-format +msgid "Usage: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:73 +#, c-format +msgid "Load Once: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:77 +#, c-format +msgid "Path: %s\n" +msgstr "" + +#: ../src/daemon/daemon-conf.c:203 +#, c-format +msgid "[%s:%u] Invalid log target '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:219 +#, c-format +msgid "[%s:%u] Invalid log level '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:235 +#, c-format +msgid "[%s:%u] Invalid resample method '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:258 +#, c-format +msgid "[%s:%u] Invalid rlimit '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:265 +#, c-format +msgid "[%s:%u] rlimit not supported on this platform." +msgstr "" + +#: ../src/daemon/daemon-conf.c:281 +#, c-format +msgid "[%s:%u] Invalid sample format '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:299 +#, c-format +msgid "[%s:%u] Invalid sample rate '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:317 +#, c-format +msgid "[%s:%u] Invalid sample channels '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:335 +#, c-format +msgid "[%s:%u] Invalid number of fragments '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:353 +#, c-format +msgid "[%s:%u] Invalid fragment size '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:371 +#, c-format +msgid "[%s:%u] Invalid nice level '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:564 +#, c-format +msgid "Failed to open configuration file: %s" +msgstr "" + +#: ../src/daemon/daemon-conf.c:638 +#, c-format +msgid "### Read from configuration file: %s ###\n" +msgstr "" + +#: ../src/daemon/caps.c:62 +msgid "Dropping root priviliges." +msgstr "" + +#: ../src/daemon/caps.c:102 +msgid "Limited capabilities successfully to CAP_SYS_NICE." +msgstr "" + +#: ../src/pulse/channelmap.c:102 +msgid "Mono" +msgstr "Mono" + +#: ../src/pulse/channelmap.c:104 +msgid "Front Center" +msgstr "Vorne Mitte" + +#: ../src/pulse/channelmap.c:105 +msgid "Front Left" +msgstr "Vorne Links" + +#: ../src/pulse/channelmap.c:106 +msgid "Front Right" +msgstr "Vorne Rechts" + +#: ../src/pulse/channelmap.c:108 +msgid "Rear Center" +msgstr "Hinten Mitte" + +#: ../src/pulse/channelmap.c:109 +msgid "Rear Left" +msgstr "Hinten Links" + +#: ../src/pulse/channelmap.c:110 +msgid "Rear Right" +msgstr "Hinten Rechts" + +#: ../src/pulse/channelmap.c:112 +msgid "Low Frequency Emmiter" +msgstr "Niedrigfrequenzemitter" + +#: ../src/pulse/channelmap.c:114 +msgid "Front Left-of-center" +msgstr "Vorne Links der Mitte" + +#: ../src/pulse/channelmap.c:115 +msgid "Front Right-of-center" +msgstr "Vorne Rechts der Mitte" + +#: ../src/pulse/channelmap.c:117 +msgid "Side Left" +msgstr "Seite Links" + +#: ../src/pulse/channelmap.c:118 +msgid "Side Right" +msgstr "Seite Rechts" + +#: ../src/pulse/channelmap.c:120 +msgid "Auxiliary 0" +msgstr "" + +#: ../src/pulse/channelmap.c:121 +msgid "Auxiliary 1" +msgstr "" + +#: ../src/pulse/channelmap.c:122 +msgid "Auxiliary 2" +msgstr "" + +#: ../src/pulse/channelmap.c:123 +msgid "Auxiliary 3" +msgstr "" + +#: ../src/pulse/channelmap.c:124 +msgid "Auxiliary 4" +msgstr "" + +#: ../src/pulse/channelmap.c:125 +msgid "Auxiliary 5" +msgstr "" + +#: ../src/pulse/channelmap.c:126 +msgid "Auxiliary 6" +msgstr "" + +#: ../src/pulse/channelmap.c:127 +msgid "Auxiliary 7" +msgstr "" + +#: ../src/pulse/channelmap.c:128 +msgid "Auxiliary 8" +msgstr "" + +#: ../src/pulse/channelmap.c:129 +msgid "Auxiliary 9" +msgstr "" + +#: ../src/pulse/channelmap.c:130 +msgid "Auxiliary 10" +msgstr "" + +#: ../src/pulse/channelmap.c:131 +msgid "Auxiliary 11" +msgstr "" + +#: ../src/pulse/channelmap.c:132 +msgid "Auxiliary 12" +msgstr "" + +#: ../src/pulse/channelmap.c:133 +msgid "Auxiliary 13" +msgstr "" + +#: ../src/pulse/channelmap.c:134 +msgid "Auxiliary 14" +msgstr "" + +#: ../src/pulse/channelmap.c:135 +msgid "Auxiliary 15" +msgstr "" + +#: ../src/pulse/channelmap.c:136 +msgid "Auxiliary 16" +msgstr "" + +#: ../src/pulse/channelmap.c:137 +msgid "Auxiliary 17" +msgstr "" + +#: ../src/pulse/channelmap.c:138 +msgid "Auxiliary 18" +msgstr "" + +#: ../src/pulse/channelmap.c:139 +msgid "Auxiliary 19" +msgstr "" + +#: ../src/pulse/channelmap.c:140 +msgid "Auxiliary 20" +msgstr "" + +#: ../src/pulse/channelmap.c:141 +msgid "Auxiliary 21" +msgstr "" + +#: ../src/pulse/channelmap.c:142 +msgid "Auxiliary 22" +msgstr "" + +#: ../src/pulse/channelmap.c:143 +msgid "Auxiliary 23" +msgstr "" + +#: ../src/pulse/channelmap.c:144 +msgid "Auxiliary 24" +msgstr "" + +#: ../src/pulse/channelmap.c:145 +msgid "Auxiliary 25" +msgstr "" + +#: ../src/pulse/channelmap.c:146 +msgid "Auxiliary 26" +msgstr "" + +#: ../src/pulse/channelmap.c:147 +msgid "Auxiliary 27" +msgstr "" + +#: ../src/pulse/channelmap.c:148 +msgid "Auxiliary 28" +msgstr "" + +#: ../src/pulse/channelmap.c:149 +msgid "Auxiliary 29" +msgstr "" + +#: ../src/pulse/channelmap.c:150 +msgid "Auxiliary 30" +msgstr "" + +#: ../src/pulse/channelmap.c:151 +msgid "Auxiliary 31" +msgstr "" + +#: ../src/pulse/channelmap.c:153 +msgid "Top Center" +msgstr "Oben Mitte" + +#: ../src/pulse/channelmap.c:155 +msgid "Top Front Center" +msgstr "Oben Vorne Mitter" + +#: ../src/pulse/channelmap.c:156 +msgid "Top Front Left" +msgstr "Oben Vorne Links" + +#: ../src/pulse/channelmap.c:157 +msgid "Top Front Right" +msgstr "Oben Vorne Rechts" + +#: ../src/pulse/channelmap.c:159 +msgid "Top Rear Center" +msgstr "Oben Hinten Mitte" + +#: ../src/pulse/channelmap.c:160 +msgid "Top Rear Left" +msgstr "Oben Hinten Links" + +#: ../src/pulse/channelmap.c:161 +msgid "Top Rear Right" +msgstr "Oben Hinten Rechts" + +#: ../src/pulse/error.c:43 +msgid "OK" +msgstr "" + +#: ../src/pulse/error.c:44 +msgid "Access denied" +msgstr "Zugriff abgelehnt" + +#: ../src/pulse/error.c:45 +msgid "Unknown command" +msgstr "Unbekannter Befehl" + +#: ../src/pulse/error.c:46 +msgid "Invalid argument" +msgstr "Ungültiges Argument" + +#: ../src/pulse/error.c:47 +msgid "Entity exists" +msgstr "Entität existiert bereits" + +#: ../src/pulse/error.c:48 +msgid "No such entity" +msgstr "Keine Entität vorhanden" + +#: ../src/pulse/error.c:49 +msgid "Connection refused" +msgstr "Verbindung zurückgewiesen" + +#: ../src/pulse/error.c:50 +msgid "Protocol error" +msgstr "Protokollfehler" + +#: ../src/pulse/error.c:51 +msgid "Timeout" +msgstr "Zeitüberschreitung" + +#: ../src/pulse/error.c:52 +msgid "No authorization key" +msgstr "Kein Authorisierungsschlüssel vorhanden" + +#: ../src/pulse/error.c:53 +msgid "Internal error" +msgstr "Interner Fehler" + +#: ../src/pulse/error.c:54 +msgid "Connection terminated" +msgstr "Verbindung beendet" + +#: ../src/pulse/error.c:55 +msgid "Entity killed" +msgstr "Entität terminiert." + +#: ../src/pulse/error.c:56 +msgid "Invalid server" +msgstr "Ungültiger Server" + +#: ../src/pulse/error.c:57 +msgid "Module initalization failed" +msgstr "Modulinitialisierung fehlgeschlagen" + +#: ../src/pulse/error.c:58 +msgid "Bad state" +msgstr "Ungültiger Zustand" + +#: ../src/pulse/error.c:59 +msgid "No data" +msgstr "Keine Daten vorhanden" + +#: ../src/pulse/error.c:60 +msgid "Incompatible protocol version" +msgstr "Inkompatible Protokollversion" + +#: ../src/pulse/error.c:61 +msgid "Too large" +msgstr "Zu groß" + +#: ../src/pulse/error.c:62 +msgid "Not supported" +msgstr "Nicht unterstützt" + +#: ../src/pulse/error.c:63 +msgid "Unknown error code" +msgstr "Unbekannter Fehlercode" + +#: ../src/pulse/error.c:64 +msgid "No such extension" +msgstr "Erweiterung nicht vorhanden" + +#: ../src/pulse/sample.c:134 +msgid "Invalid" +msgstr "Ungültig" + +#: ../src/pulse/client-conf-x11.c:55 +#: ../src/utils/pax11publish.c:100 +msgid "XOpenDisplay() failed" +msgstr "" + +#: ../src/pulse/client-conf-x11.c:78 +msgid "Failed to parse cookie data" +msgstr "" + +#: ../src/pulse/client-conf.c:117 +#, c-format +msgid "Failed to open configuration file '%s': %s" +msgstr "" + +#: ../src/pulse/context.c:110 +msgid "Cannot unlock autospawn because runtime path is no more." +msgstr "" + +#: ../src/pulse/context.c:536 +msgid "No cookie loaded. Attempting to connect without." +msgstr "" + +#: ../src/pulse/context.c:590 +#, c-format +msgid "socketpair(): %s" +msgstr "" + +#: ../src/pulse/context.c:604 +#, c-format +msgid "fork(): %s" +msgstr "" + +#: ../src/pulse/context.c:667 +#, c-format +msgid "waitpid(): %s" +msgstr "" + +#: ../src/pulse/context.c:1265 +#, c-format +msgid "Received message for unknown extension '%s'" +msgstr "" + +#: ../src/utils/pacat.c:93 +#, c-format +msgid "pa_stream_write() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:132 +#, c-format +msgid "pa_stream_peek() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:141 +#, c-format +msgid "Buffer overrun, dropping incoming data\n" +msgstr "" + +#: ../src/utils/pacat.c:143 +#, c-format +msgid "pa_stream_drop() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:169 +#, c-format +msgid "Stream successfully created.\n" +msgstr "" + +#: ../src/utils/pacat.c:172 +#, c-format +msgid "pa_stream_get_buffer_attr() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:176 +#, c-format +msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n" +msgstr "" + +#: ../src/utils/pacat.c:179 +#, c-format +msgid "Buffer metrics: maxlength=%u, fragsize=%u\n" +msgstr "" + +#: ../src/utils/pacat.c:183 +#, c-format +msgid "Using sample spec '%s', channel map '%s'.\n" +msgstr "" + +#: ../src/utils/pacat.c:187 +#, c-format +msgid "Connected to device %s (%u, %ssuspended).\n" +msgstr "" + +#: ../src/utils/pacat.c:197 +#, c-format +msgid "Stream error: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:207 +#, c-format +msgid "Stream device suspended.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:209 +#, c-format +msgid "Stream device resumed.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:217 +#, c-format +msgid "Stream underrun.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:224 +#, c-format +msgid "Stream overrun.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:231 +#, c-format +msgid "Stream started.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:238 +#, c-format +msgid "Stream moved to device %s (%u, %ssuspended).%s \n" +msgstr "" + +#: ../src/utils/pacat.c:238 +msgid "not " +msgstr "" + +#: ../src/utils/pacat.c:259 +#, c-format +msgid "Connection established.%s \n" +msgstr "" + +#: ../src/utils/pacat.c:262 +#, c-format +msgid "pa_stream_new() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:287 +#, c-format +msgid "pa_stream_connect_playback() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:293 +#, c-format +msgid "pa_stream_connect_record() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:307 +#: ../src/utils/pasuspender.c:159 +#: ../src/utils/pactl.c:666 +#: ../src/utils/paplay.c:183 +#, c-format +msgid "Connection failure: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:328 +#: ../src/utils/paplay.c:75 +#, c-format +msgid "Failed to drain stream: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:333 +#: ../src/utils/paplay.c:80 +#, c-format +msgid "Playback stream drained.\n" +msgstr "" + +#: ../src/utils/pacat.c:343 +#: ../src/utils/paplay.c:92 +#, c-format +msgid "Draining connection to server.\n" +msgstr "" + +#: ../src/utils/pacat.c:369 +#, c-format +msgid "Got EOF.\n" +msgstr "" + +#: ../src/utils/pacat.c:375 +#, c-format +msgid "pa_stream_drain(): %s\n" +msgstr "" + +#: ../src/utils/pacat.c:385 +#, c-format +msgid "read() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:417 +#, c-format +msgid "write() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:438 +#, c-format +msgid "Got signal, exiting.\n" +msgstr "" + +#: ../src/utils/pacat.c:452 +#, c-format +msgid "Failed to get latency: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:457 +#, c-format +msgid "Time: %0.3f sec; Latency: %0.0f usec. \r" +msgstr "" + +#: ../src/utils/pacat.c:477 +#, c-format +msgid "pa_stream_update_timing_info() failed: %s\n" +msgstr "" + +#: ../src/utils/pacat.c:490 +#, c-format +msgid "" +"%s [options]\n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"\n" +" -r, --record Create a connection for recording\n" +" -p, --playback Create a connection for playback\n" +"\n" +" -v, --verbose Enable verbose operations\n" +"\n" +" -s, --server=SERVER The name of the server to connect to\n" +" -d, --device=DEVICE The name of the sink/source to connect to\n" +" -n, --client-name=NAME How to call this client on the server\n" +" --stream-name=NAME How to call this stream on the server\n" +" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n" +" --rate=SAMPLERATE The sample rate in Hz (defaults to 44100)\n" +" --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le,\n" +" float32be, ulaw, alaw (defaults to s16ne)\n" +" --channels=CHANNELS The number of channels, 1 for mono, 2 for stereo\n" +" (defaults to 2)\n" +" --channel-map=CHANNELMAP Channel map to use instead of the default\n" +" --fix-format Take the sample format from the sink the stream is\n" +" being connected to.\n" +" --fix-rate Take the sampling rate from the sink the stream is\n" +" being connected to.\n" +" --fix-channels Take the number of channels and the channel map\n" +" from the sink the stream is being connected to.\n" +" --no-remix Don't upmix or downmix channels.\n" +" --no-remap Map channels by index instead of name.\n" +" --latency=BYTES Request the specified latency in bytes.\n" +" --process-time=BYTES Request the specified process time per request in bytes.\n" +msgstr "" + +#: ../src/utils/pacat.c:591 +#, c-format +msgid "" +"pacat %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pacat.c:647 +#, c-format +msgid "Invalid channel map '%s'\n" +msgstr "" + +#: ../src/utils/pacat.c:676 +#, c-format +msgid "Invalid latency specification '%s'\n" +msgstr "" + +#: ../src/utils/pacat.c:683 +#, c-format +msgid "Invalid process time specification '%s'\n" +msgstr "" + +#: ../src/utils/pacat.c:694 +#, c-format +msgid "Invalid sample specification\n" +msgstr "" + +#: ../src/utils/pacat.c:699 +#, c-format +msgid "Channel map doesn't match sample specification\n" +msgstr "" + +#: ../src/utils/pacat.c:706 +#, c-format +msgid "Opening a %s stream with sample specification '%s'.\n" +msgstr "" + +#: ../src/utils/pacat.c:706 +msgid "recording" +msgstr "" + +#: ../src/utils/pacat.c:706 +msgid "playback" +msgstr "" + +#: ../src/utils/pacat.c:714 +#, c-format +msgid "open(): %s\n" +msgstr "" + +#: ../src/utils/pacat.c:719 +#, c-format +msgid "dup2(): %s\n" +msgstr "" + +#: ../src/utils/pacat.c:729 +#, c-format +msgid "Too many arguments.\n" +msgstr "" + +#: ../src/utils/pacat.c:742 +#: ../src/utils/pasuspender.c:280 +#: ../src/utils/pactl.c:909 +#: ../src/utils/paplay.c:381 +#, c-format +msgid "pa_mainloop_new() failed.\n" +msgstr "" + +#: ../src/utils/pacat.c:763 +#, c-format +msgid "io_new() failed.\n" +msgstr "" + +#: ../src/utils/pacat.c:769 +#: ../src/utils/pasuspender.c:293 +#: ../src/utils/pactl.c:923 +#: ../src/utils/paplay.c:396 +#, c-format +msgid "pa_context_new() failed.\n" +msgstr "" + +#: ../src/utils/pacat.c:785 +#, c-format +msgid "time_new() failed.\n" +msgstr "" + +#: ../src/utils/pacat.c:792 +#: ../src/utils/pasuspender.c:301 +#: ../src/utils/pactl.c:931 +#: ../src/utils/paplay.c:407 +#, c-format +msgid "pa_mainloop_run() failed.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:81 +#, c-format +msgid "fork(): %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:92 +#, c-format +msgid "execvp(): %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:109 +#, c-format +msgid "Failure to suspend: %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:124 +#, c-format +msgid "Failure to resume: %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:147 +#, c-format +msgid "WARNING: Sound server is not local, not suspending.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:176 +#: ../src/utils/pactl.c:672 +#: ../src/utils/paplay.c:191 +#, c-format +msgid "Got SIGINT, exiting.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:194 +#, c-format +msgid "WARNING: Child process terminated by signal %u\n" +msgstr "" + +#: ../src/utils/pasuspender.c:212 +#, c-format +msgid "" +"%s [options] ... \n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +" -s, --server=SERVER The name of the server to connect to\n" +"\n" +msgstr "" + +#: ../src/utils/pasuspender.c:251 +#, c-format +msgid "" +"pasuspender %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pactl.c:107 +#, c-format +msgid "Failed to get statistics: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:113 +#, c-format +msgid "Currently in use: %u blocks containing %s bytes total.\n" +msgstr "" + +#: ../src/utils/pactl.c:116 +#, c-format +msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n" +msgstr "" + +#: ../src/utils/pactl.c:119 +#, c-format +msgid "Sample cache size: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:128 +#, c-format +msgid "Failed to get server information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:135 +#, c-format +msgid "" +"User name: %s\n" +"Host Name: %s\n" +"Server Name: %s\n" +"Server Version: %s\n" +"Default Sample Specification: %s\n" +"Default Sink: %s\n" +"Default Source: %s\n" +"Cookie: %08x\n" +msgstr "" + +#: ../src/utils/pactl.c:160 +#, c-format +msgid "Failed to get sink information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:176 +#, c-format +msgid "" +"*** Sink #%u ***\n" +"Name: %s\n" +"Driver: %s\n" +"Sample Specification: %s\n" +"Channel Map: %s\n" +"Owner Module: %u\n" +"Volume: %s\n" +"Monitor Source: %s\n" +"Latency: %0.0f usec, configured %0.0f usec\n" +"Flags: %s%s%s%s%s%s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:193 +#: ../src/utils/pactl.c:371 +msgid "muted" +msgstr "" + +#: ../src/utils/pactl.c:212 +#, c-format +msgid "Failed to get source information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:228 +#, c-format +msgid "" +"*** Source #%u ***\n" +"Name: %s\n" +"Driver: %s\n" +"Sample Specification: %s\n" +"Channel Map: %s\n" +"Owner Module: %u\n" +"Volume: %s\n" +"Monitor of Sink: %s\n" +"Latency: %0.0f usec, configured %0.0f usec\n" +"Flags: %s%s%s%s%s%s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:246 +#: ../src/utils/pactl.c:289 +#: ../src/utils/pactl.c:322 +#: ../src/utils/pactl.c:366 +#: ../src/utils/pactl.c:367 +#: ../src/utils/pactl.c:374 +#: ../src/utils/pactl.c:418 +#: ../src/utils/pactl.c:419 +#: ../src/utils/pactl.c:425 +#: ../src/utils/pactl.c:468 +#: ../src/utils/pactl.c:469 +#: ../src/utils/pactl.c:473 +msgid "n/a" +msgstr "" + +#: ../src/utils/pactl.c:263 +#, c-format +msgid "Failed to get module information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:281 +#, c-format +msgid "" +"*** Module #%u ***\n" +"Name: %s\n" +"Argument: %s\n" +"Usage counter: %s\n" +"Auto unload: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:298 +#, c-format +msgid "Failed to get client information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:316 +#, c-format +msgid "" +"*** Client #%u ***\n" +"Driver: %s\n" +"Owner Module: %s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:333 +#, c-format +msgid "Failed to get sink input information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:352 +#, c-format +msgid "" +"*** Sink Input #%u ***\n" +"Driver: %s\n" +"Owner Module: %s\n" +"Client: %s\n" +"Sink: %u\n" +"Sample Specification: %s\n" +"Channel Map: %s\n" +"Volume: %s\n" +"Buffer Latency: %0.0f usec\n" +"Sink Latency: %0.0f usec\n" +"Resample method: %s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:385 +#, c-format +msgid "Failed to get source output information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:405 +#, c-format +msgid "" +"*** Source Output #%u ***\n" +"Driver: %s\n" +"Owner Module: %s\n" +"Client: %s\n" +"Source: %u\n" +"Sample Specification: %s\n" +"Channel Map: %s\n" +"Buffer Latency: %0.0f usec\n" +"Source Latency: %0.0f usec\n" +"Resample method: %s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:436 +#, c-format +msgid "Failed to get sample information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:455 +#, c-format +msgid "" +"*** Sample #%u ***\n" +"Name: %s\n" +"Volume: %s\n" +"Sample Specification: %s\n" +"Channel Map: %s\n" +"Duration: %0.1fs\n" +"Size: %s\n" +"Lazy: %s\n" +"Filename: %s\n" +"Properties:\n" +"%s" +msgstr "" + +#: ../src/utils/pactl.c:481 +#, c-format +msgid "Failed to get autoload information: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:497 +#, c-format +msgid "" +"*** Autoload Entry #%u ***\n" +"Name: %s\n" +"Type: %s\n" +"Module: %s\n" +"Argument: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:504 +msgid "sink" +msgstr "" + +#: ../src/utils/pactl.c:504 +msgid "source" +msgstr "" + +#: ../src/utils/pactl.c:511 +#: ../src/utils/pactl.c:521 +#, c-format +msgid "Failure: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:545 +#, c-format +msgid "Failed to upload sample: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:562 +#, c-format +msgid "Premature end of file\n" +msgstr "" + +#: ../src/utils/pactl.c:678 +#, c-format +msgid "" +"%s [options] stat\n" +"%s [options] list\n" +"%s [options] exit\n" +"%s [options] upload-sample FILENAME [NAME]\n" +"%s [options] play-sample NAME [SINK]\n" +"%s [options] remove-sample NAME\n" +"%s [options] move-sink-input ID SINK\n" +"%s [options] move-source-output ID SOURCE\n" +"%s [options] load-module NAME [ARGS ...]\n" +"%s [options] unload-module ID\n" +"%s [options] suspend-sink [SINK] 1|0\n" +"%s [options] suspend-source [SOURCE] 1|0\n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"\n" +" -s, --server=SERVER The name of the server to connect to\n" +" -n, --client-name=NAME How to call this client on the server\n" +msgstr "" + +#: ../src/utils/pactl.c:729 +#, c-format +msgid "" +"pactl %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pactl.c:768 +#, c-format +msgid "Please specify a sample file to load\n" +msgstr "" + +#: ../src/utils/pactl.c:790 +#, c-format +msgid "Failed to open sound file.\n" +msgstr "" + +#: ../src/utils/pactl.c:802 +#, c-format +msgid "You have to specify a sample name to play\n" +msgstr "" + +#: ../src/utils/pactl.c:814 +#, c-format +msgid "You have to specify a sample name to remove\n" +msgstr "" + +#: ../src/utils/pactl.c:822 +#, c-format +msgid "You have to specify a sink input index and a sink\n" +msgstr "" + +#: ../src/utils/pactl.c:831 +#, c-format +msgid "You have to specify a source output index and a source\n" +msgstr "" + +#: ../src/utils/pactl.c:845 +#, c-format +msgid "You have to specify a module name and arguments.\n" +msgstr "" + +#: ../src/utils/pactl.c:865 +#, c-format +msgid "You have to specify a module index\n" +msgstr "" + +#: ../src/utils/pactl.c:875 +#, c-format +msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n" +msgstr "" + +#: ../src/utils/pactl.c:888 +#, c-format +msgid "You may not specify more than one source. You have to specify at least one boolean value.\n" +msgstr "" + +#: ../src/utils/pactl.c:904 +#, c-format +msgid "No valid command specified.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:61 +#, c-format +msgid "" +"%s [-D display] [-S server] [-O sink] [-I source] [-c file] [-d|-e|-i|-r]\n" +"\n" +" -d Show current PulseAudio data attached to X11 display (default)\n" +" -e Export local PulseAudio data to X11 display\n" +" -i Import PulseAudio data from X11 display to local environment variables and cookie file.\n" +" -r Remove PulseAudio data from X11 display\n" +msgstr "" + +#: ../src/utils/pax11publish.c:94 +#, c-format +msgid "Failed to parse command line.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:108 +#, c-format +msgid "Server: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:110 +#, c-format +msgid "Source: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:112 +#, c-format +msgid "Sink: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:114 +#, c-format +msgid "Cookie: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:132 +#, c-format +msgid "Failed to parse cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:137 +#, c-format +msgid "Failed to save cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:152 +#, c-format +msgid "Failed to load client configuration file.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:157 +#, c-format +msgid "Failed to read environment configuration data.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:174 +#, c-format +msgid "Failed to get FQDN.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:194 +#, c-format +msgid "Failed to load cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:211 +#, c-format +msgid "Not yet implemented.\n" +msgstr "" + +#: ../src/utils/pacmd.c:64 +#, c-format +msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s" +msgstr "" + +#: ../src/utils/pacmd.c:81 +#, c-format +msgid "connect(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:89 +msgid "Failed to kill PulseAudio daemon." +msgstr "" + +#: ../src/utils/pacmd.c:97 +msgid "Daemon not responding." +msgstr "" + +#: ../src/utils/pacmd.c:112 +#, c-format +msgid "select(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:124 +#: ../src/utils/pacmd.c:140 +#, c-format +msgid "read(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:153 +#: ../src/utils/pacmd.c:167 +#, c-format +msgid "write(): %s" +msgstr "" + +#: ../src/utils/paplay.c:139 +#, c-format +msgid "Stream successfully created\n" +msgstr "" + +#: ../src/utils/paplay.c:144 +#, c-format +msgid "Stream errror: %s\n" +msgstr "" + +#: ../src/utils/paplay.c:165 +#, c-format +msgid "Connection established.\n" +msgstr "" + +#: ../src/utils/paplay.c:198 +#, c-format +msgid "" +"%s [options] [FILE]\n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"\n" +" -v, --verbose Enable verbose operation\n" +"\n" +" -s, --server=SERVER The name of the server to connect to\n" +" -d, --device=DEVICE The name of the sink to connect to\n" +" -n, --client-name=NAME How to call this client on the server\n" +" --stream-name=NAME How to call this stream on the server\n" +" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n" +" --channel-map=CHANNELMAP Set the channel map to the use\n" +msgstr "" + +#: ../src/utils/paplay.c:255 +#, c-format +msgid "" +"paplay %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/paplay.c:292 +#, c-format +msgid "Invalid channel map\n" +msgstr "" + +#: ../src/utils/paplay.c:314 +#, c-format +msgid "Failed to open file '%s'\n" +msgstr "" + +#: ../src/utils/paplay.c:350 +#, c-format +msgid "Channel map doesn't match file.\n" +msgstr "" + +#: ../src/utils/paplay.c:376 +#, c-format +msgid "Using sample spec '%s'\n" +msgstr "" + diff --git a/src/.gitignore b/src/.gitignore index 6902eb9f..543f4e8e 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +lock-autospawn-test *.lo *.o *.la diff --git a/src/Makefile.am b/src/Makefile.am index 298eb658..21584ad9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,8 @@ AM_CFLAGS += -DPA_SYSTEM_RUNTIME_PATH=\"$(PA_SYSTEM_RUNTIME_PATH)\" AM_CFLAGS += -DPA_SYSTEM_CONFIG_PATH=\"$(PA_SYSTEM_CONFIG_PATH)\" AM_CFLAGS += -DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\" AM_CFLAGS += -DAO_REQUIRE_CAS +AM_CFLAGS += -DPULSE_LOCALEDIR=\"$(pulselocaledir)\" +AM_CFLAGS += -DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\" # This cool debug trap works on i386/gcc only AM_CFLAGS += '-DDEBUG_TRAP=__asm__("int $$3")' @@ -260,7 +262,8 @@ noinst_PROGRAMS = \ envelope-test \ proplist-test \ rtstutter \ - stripnul + stripnul \ + lock-autospawn-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -450,6 +453,11 @@ stripnul_LDADD = $(AM_LDADD) libpulsecore.la stripnul_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) stripnul_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) +lock_autospawn_test_SOURCES = tests/lock-autospawn-test.c +lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore.la +lock_autospawn_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) +lock_autospawn_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) + ################################### # Client library # ################################### @@ -479,7 +487,8 @@ pulseinclude_HEADERS = \ pulse/volume.h \ pulse/xmalloc.h \ pulse/proplist.h \ - pulse/gccmacro.h + pulse/gccmacro.h \ + pulse/ext-stream-restore.h if HAVE_AVAHI pulseinclude_HEADERS += \ @@ -530,7 +539,10 @@ libpulse_la_SOURCES = \ pulse/util.c pulse/util.h \ pulse/volume.c pulse/volume.h \ pulse/xmalloc.c pulse/xmalloc.h \ - pulse/proplist.c pulse/proplist.h + pulse/proplist.c pulse/proplist.h \ + pulse/ext-stream-restore.c pulse/ext-stream-restore.h \ + pulse/i18n.c pulse/i18n.h \ + pulse/lock-autospawn.c pulse/lock-autospawn.h # Internal stuff that is shared with libpulsecore libpulse_la_SOURCES += \ @@ -725,7 +737,9 @@ libpulsecore_la_SOURCES = \ pulse/util.c pulse/util.h \ pulse/volume.c pulse/volume.h \ pulse/xmalloc.c pulse/xmalloc.h \ - pulse/proplist.c pulse/proplist.h + pulse/proplist.c pulse/proplist.h \ + pulse/i18n.c pulse/i18n.h \ + pulse/lock-autospawn.c pulse/lock-autospawn.h # Pure core stuff (some are shared in libpulse though). libpulsecore_la_SOURCES += \ @@ -1609,7 +1623,7 @@ update-ffmpeg: update-map-file: ( echo "PULSE_0 {" ; \ echo "global:" ; \ - ctags -I PA_GCC_PURE,PA_GCC_CONST -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \ + ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \ echo "local:" ; \ echo "*;" ; \ echo "};" ) > $(srcdir)/map-file diff --git a/src/daemon/caps.c b/src/daemon/caps.c index 8a49e373..f7b6658b 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -28,7 +28,12 @@ #include <errno.h> #include <string.h> #include <sys/types.h> + +#include <pulse/i18n.h> + #include <pulsecore/macro.h> +#include <pulsecore/core-error.h> +#include <pulsecore/log.h> #ifdef HAVE_SYS_CAPABILITY_H #include <sys/capability.h> @@ -37,10 +42,6 @@ #include <sys/prctl.h> #endif -#include <pulsecore/core-error.h> - -#include <pulsecore/log.h> - #include "caps.h" /* Glibc <= 2.2 has broken unistd.h */ @@ -58,7 +59,7 @@ void pa_drop_root(void) { if (uid == 0 || geteuid() != 0) return; - pa_log_info("Dropping root priviliges."); + pa_log_info(_("Dropping root priviliges.")); #if defined(HAVE_SETRESUID) pa_assert_se(setresuid(uid, uid, uid) >= 0); @@ -98,7 +99,7 @@ void pa_limit_caps(void) { * that */ pa_drop_caps(); else - pa_log_info("Limited capabilities successfully to CAP_SYS_NICE."); + pa_log_info(_("Limited capabilities successfully to CAP_SYS_NICE.")); pa_assert_se(cap_free(caps) == 0); diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 4b2466ce..fbd6dc32 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -30,6 +30,7 @@ #include <sys/stat.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/strbuf.h> @@ -49,6 +50,7 @@ enum { ARG_HIGH_PRIORITY, ARG_REALTIME, ARG_DISALLOW_MODULE_LOADING, + ARG_DISALLOW_EXIT, ARG_EXIT_IDLE_TIME, ARG_MODULE_IDLE_TIME, ARG_SCACHE_IDLE_TIME, @@ -81,6 +83,7 @@ static const struct option long_options[] = { {"high-priority", 2, 0, ARG_HIGH_PRIORITY}, {"realtime", 2, 0, ARG_REALTIME}, {"disallow-module-loading", 2, 0, ARG_DISALLOW_MODULE_LOADING}, + {"disallow-exit", 2, 0, ARG_DISALLOW_EXIT}, {"exit-idle-time", 2, 0, ARG_EXIT_IDLE_TIME}, {"module-idle-time", 2, 0, ARG_MODULE_IDLE_TIME}, {"scache-idle-time", 2, 0, ARG_SCACHE_IDLE_TIME}, @@ -111,7 +114,7 @@ void pa_cmdline_help(const char *argv0) { else e = argv0; - printf("%s [options]\n\n" + printf(_("%s [options]\n\n" "COMMANDS:\n" " -h, --help Show this help\n" " --version Show version\n" @@ -133,7 +136,9 @@ void pa_cmdline_help(const char *argv0) { " --realtime[=BOOL] Try to enable realtime scheduling\n" " (only available as root, when SUID or\n" " with elevated RLIMIT_RTPRIO)\n" - " --disallow-module-loading[=BOOL] Disallow module loading after startup\n" + " --disallow-module-loading[=BOOL] Disallow module user requested module\n" + " loading/unloading after startup\n" + " --disallow-exit[=BOOL] Disallow user requested exit\n" " --exit-idle-time=SECS Terminate the daemon when idle and this\n" " time passed\n" " --module-idle-time=SECS Unload autoloaded modules when idle and\n" @@ -160,7 +165,7 @@ void pa_cmdline_help(const char *argv0) { " -C Open a command line on the running TTY\n" " after startup\n\n" - " -n Don't load default script file\n", e); + " -n Don't load default script file\n"), e); } int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) { @@ -237,14 +242,14 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d case ARG_DAEMONIZE: case 'D': if ((conf->daemonize = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--daemonize expects boolean argument"); + pa_log(_("--daemonize expects boolean argument")); goto fail; } break; case ARG_FAIL: if ((conf->fail = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--fail expects boolean argument"); + pa_log(_("--fail expects boolean argument")); goto fail; } break; @@ -254,7 +259,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d if (optarg) { if (pa_daemon_conf_set_log_level(conf, optarg) < 0) { - pa_log("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."); + pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error).")); goto fail; } } else { @@ -266,28 +271,35 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d case ARG_HIGH_PRIORITY: if ((conf->high_priority = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--high-priority expects boolean argument"); + pa_log(_("--high-priority expects boolean argument")); goto fail; } break; case ARG_REALTIME: if ((conf->realtime_scheduling = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--realtime expects boolean argument"); + pa_log(_("--realtime expects boolean argument")); goto fail; } break; case ARG_DISALLOW_MODULE_LOADING: if ((conf->disallow_module_loading = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--disallow-module-loading expects boolean argument"); + pa_log(_("--disallow-module-loading expects boolean argument")); + goto fail; + } + break; + + case ARG_DISALLOW_EXIT: + if ((conf->disallow_exit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { + pa_log(_("--disallow-exit boolean argument")); goto fail; } break; case ARG_USE_PID_FILE: if ((conf->use_pid_file = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--use-pid-file expects boolean argument"); + pa_log(_("--use-pid-file expects boolean argument")); goto fail; } break; @@ -304,7 +316,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d case ARG_LOG_TARGET: if (pa_daemon_conf_set_log_target(conf, optarg) < 0) { - pa_log("Invalid log target: use either 'syslog', 'stderr' or 'auto'."); + pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto'.")); goto fail; } break; @@ -323,28 +335,28 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d case ARG_RESAMPLE_METHOD: if (pa_daemon_conf_set_resample_method(conf, optarg) < 0) { - pa_log("Invalid resample method '%s'.", optarg); + pa_log(_("Invalid resample method '%s'."), optarg); goto fail; } break; case ARG_SYSTEM: if ((conf->system_instance = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--system expects boolean argument"); + pa_log(_("--system expects boolean argument")); goto fail; } break; case ARG_NO_CPU_LIMIT: if ((conf->no_cpu_limit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--no-cpu-limit expects boolean argument"); + pa_log(_("--no-cpu-limit expects boolean argument")); goto fail; } break; case ARG_DISABLE_SHM: if ((conf->disable_shm = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) { - pa_log("--disable-shm expects boolean argument"); + pa_log(_("--disable-shm expects boolean argument")); goto fail; } break; diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 42a71f7e..59552828 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -24,11 +24,13 @@ #endif #include <pulse/error.h> +#include <pulse/timeval.h> #include <pulsecore/core-util.h> #include <pulsecore/core-error.h> #include <pulsecore/log.h> #include <pulsecore/macro.h> +#include <pulsecore/rtclock.h> #include "cpulimit.h" @@ -67,7 +69,7 @@ #define CPUTIME_INTERVAL_HARD (5) /* Time of the last CPU load check */ -static time_t last_time = 0; +static pa_usec_t last_time = 0; /* Pipe for communicating with the main loop */ static int the_pipe[2] = {-1, -1}; @@ -100,7 +102,7 @@ static void reset_cpu_time(int t) { n = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec + t; pa_assert_se(getrlimit(RLIMIT_CPU, &rl) >= 0); - rl.rlim_cur = n; + rl.rlim_cur = (rlim_t) n; pa_assert_se(setrlimit(RLIMIT_CPU, &rl) >= 0); } @@ -117,20 +119,21 @@ static void signal_handler(int sig) { pa_assert(sig == SIGXCPU); if (phase == PHASE_IDLE) { - time_t now; + pa_usec_t now, elapsed; #ifdef PRINT_CPU_LOAD char t[256]; #endif - time(&now); + now = pa_rtclock_usec(); + elapsed = now - last_time; #ifdef PRINT_CPU_LOAD - pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100); + pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", ((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) / (double) elapsed * 100.0); write_err(t); #endif - if (CPUTIME_INTERVAL_SOFT >= ((now-last_time)*(double)CPUTIME_PERCENT/100)) { + if (((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) >= ((double) elapsed * (double) CPUTIME_PERCENT / 100.0)) { static const char c = 'X'; write_err("Soft CPU time limit exhausted, terminating.\n"); @@ -179,7 +182,7 @@ int pa_cpu_limit_init(pa_mainloop_api *m) { pa_assert(the_pipe[1] == -1); pa_assert(!installed); - time(&last_time); + last_time = pa_rtclock_usec(); /* Prepare the main loop pipe */ if (pipe(the_pipe) < 0) { @@ -235,7 +238,7 @@ void pa_cpu_limit_done(void) { #else /* HAVE_SIGXCPU */ -int pa_cpu_limit_init(PA_GCC_UNUSED pa_mainloop_api *m) { +int pa_cpu_limit_init(pa_mainloop_api *m) { return 0; } diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 50b812dc..40e0a170 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -32,6 +32,7 @@ #include <pulse/xmalloc.h> #include <pulse/timeval.h> +#include <pulse/i18n.h> #include <pulsecore/core-error.h> #include <pulsecore/core-util.h> @@ -62,6 +63,7 @@ static const pa_daemon_conf default_conf = { .realtime_scheduling = FALSE, .realtime_priority = 5, /* Half of JACK's default rtprio */ .disallow_module_loading = FALSE, + .disallow_exit = FALSE, .exit_idle_time = 20, .module_idle_time = 20, .scache_idle_time = 20, @@ -189,7 +191,7 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) { return 0; } -static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -198,14 +200,14 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva pa_assert(data); if (pa_daemon_conf_set_log_target(c, rvalue) < 0) { - pa_log("[%s:%u] Invalid log target '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid log target '%s'."), filename, line, rvalue); return -1; } return 0; } -static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -214,14 +216,14 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval pa_assert(data); if (pa_daemon_conf_set_log_level(c, rvalue) < 0) { - pa_log("[%s:%u] Invalid log level '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid log level '%s'."), filename, line, rvalue); return -1; } return 0; } -static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -230,14 +232,14 @@ static int parse_resample_method(const char *filename, unsigned line, const char pa_assert(data); if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) { - pa_log("[%s:%u] Invalid resample method '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid resample method '%s'."), filename, line, rvalue); return -1; } return 0; } -static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { #ifdef HAVE_SYS_RESOURCE_H struct pa_rlimit *r = data; @@ -253,20 +255,20 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, } else { int32_t k; if (pa_atoi(rvalue, &k) < 0) { - pa_log("[%s:%u] Invalid rlimit '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid rlimit '%s'."), filename, line, rvalue); return -1; } r->is_set = k >= 0; r->value = k >= 0 ? (rlim_t) k : 0; } #else - pa_log_warn("[%s:%u] rlimit not supported on this platform.", filename, line); + pa_log_warn(_("[%s:%u] rlimit not supported on this platform."), filename, line); #endif return 0; } -static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_sample_format_t f; @@ -276,7 +278,7 @@ static int parse_sample_format(const char *filename, unsigned line, const char * pa_assert(data); if ((f = pa_parse_sample_format(rvalue)) < 0) { - pa_log("[%s:%u] Invalid sample format '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid sample format '%s'."), filename, line, rvalue); return -1; } @@ -284,17 +286,17 @@ static int parse_sample_format(const char *filename, unsigned line, const char * return 0; } -static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; - int32_t r; + uint32_t r; pa_assert(filename); pa_assert(lvalue); pa_assert(rvalue); pa_assert(data); - if (pa_atoi(rvalue, &r) < 0 || r > (int32_t) PA_RATE_MAX || r <= 0) { - pa_log("[%s:%u] Invalid sample rate '%s'.", filename, line, rvalue); + if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) { + pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue); return -1; } @@ -302,7 +304,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv return 0; } -static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -312,7 +314,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char pa_assert(data); if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) { - pa_log("[%s:%u] Invalid sample channels '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid sample channels '%s'."), filename, line, rvalue); return -1; } @@ -320,7 +322,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char return 0; } -static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -330,7 +332,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval pa_assert(data); if (pa_atoi(rvalue, &n) < 0 || n < 2) { - pa_log("[%s:%u] Invalid number of fragments '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid number of fragments '%s'."), filename, line, rvalue); return -1; } @@ -338,7 +340,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval return 0; } -static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -348,7 +350,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c pa_assert(data); if (pa_atoi(rvalue, &n) < 0 || n < 1) { - pa_log("[%s:%u] Invalid fragment size '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid fragment size '%s'."), filename, line, rvalue); return -1; } @@ -356,7 +358,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c return 0; } -static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t level; @@ -366,7 +368,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva pa_assert(data); if (pa_atoi(rvalue, &level) < 0 || level < -20 || level > 19) { - pa_log("[%s:%u] Invalid nice level '%s'.", filename, line, rvalue); + pa_log(_("[%s:%u] Invalid nice level '%s'."), filename, line, rvalue); return -1; } @@ -374,7 +376,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva return 0; } -static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t rtprio; @@ -402,6 +404,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { { "high-priority", pa_config_parse_bool, NULL }, { "realtime-scheduling", pa_config_parse_bool, NULL }, { "disallow-module-loading", pa_config_parse_bool, NULL }, + { "disallow-exit", pa_config_parse_bool, NULL }, { "use-pid-file", pa_config_parse_bool, NULL }, { "system-instance", pa_config_parse_bool, NULL }, { "no-cpu-limit", pa_config_parse_bool, NULL }, @@ -465,17 +468,17 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { table[2].data = &c->high_priority; table[3].data = &c->realtime_scheduling; table[4].data = &c->disallow_module_loading; - table[5].data = &c->use_pid_file; - table[6].data = &c->system_instance; - table[7].data = &c->no_cpu_limit; - table[8].data = &c->disable_shm; - table[9].data = &c->exit_idle_time; - table[10].data = &c->module_idle_time; - table[11].data = &c->scache_idle_time; - table[12].data = c; - table[13].data = &c->dl_search_path; - table[14].data = &c->default_script_file; - table[15].data = c; + table[5].data = &c->disallow_exit; + table[6].data = &c->use_pid_file; + table[7].data = &c->system_instance; + table[8].data = &c->no_cpu_limit; + table[9].data = &c->disable_shm; + table[10].data = &c->exit_idle_time; + table[11].data = &c->module_idle_time; + table[12].data = &c->scache_idle_time; + table[13].data = c; + table[14].data = &c->dl_search_path; + table[15].data = &c->default_script_file; table[16].data = c; table[17].data = c; table[18].data = c; @@ -485,67 +488,68 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { table[22].data = c; table[23].data = c; table[24].data = c; - table[25].data = &c->disable_remixing; - table[26].data = &c->load_default_script_file; + table[25].data = c; + table[26].data = &c->disable_remixing; + table[27].data = &c->load_default_script_file; #ifdef HAVE_SYS_RESOURCE_H - table[27].data = &c->rlimit_fsize; - table[28].data = &c->rlimit_data; - table[29].data = &c->rlimit_stack; - table[30].data = &c->rlimit_as; - table[31].data = &c->rlimit_core; - table[32].data = &c->rlimit_nofile; - table[33].data = &c->rlimit_as; + table[28].data = &c->rlimit_fsize; + table[29].data = &c->rlimit_data; + table[30].data = &c->rlimit_stack; + table[31].data = &c->rlimit_as; + table[32].data = &c->rlimit_core; + table[33].data = &c->rlimit_nofile; + table[34].data = &c->rlimit_as; #ifdef RLIMIT_NPROC - table[34].data = &c->rlimit_nproc; + table[35].data = &c->rlimit_nproc; #endif #ifdef RLIMIT_MEMLOCK #ifndef RLIMIT_NPROC #error "Houston, we have a numbering problem!" #endif - table[35].data = &c->rlimit_memlock; + table[36].data = &c->rlimit_memlock; #endif #ifdef RLIMIT_LOCKS #ifndef RLIMIT_MEMLOCK #error "Houston, we have a numbering problem!" #endif - table[36].data = &c->rlimit_locks; + table[37].data = &c->rlimit_locks; #endif #ifdef RLIMIT_SIGPENDING #ifndef RLIMIT_LOCKS #error "Houston, we have a numbering problem!" #endif - table[37].data = &c->rlimit_sigpending; + table[38].data = &c->rlimit_sigpending; #endif #ifdef RLIMIT_MSGQUEUE #ifndef RLIMIT_SIGPENDING #error "Houston, we have a numbering problem!" #endif - table[38].data = &c->rlimit_msgqueue; + table[39].data = &c->rlimit_msgqueue; #endif #ifdef RLIMIT_NICE #ifndef RLIMIT_MSGQUEUE #error "Houston, we have a numbering problem!" #endif - table[39].data = &c->rlimit_nice; + table[40].data = &c->rlimit_nice; #endif #ifdef RLIMIT_RTPRIO #ifndef RLIMIT_NICE #error "Houston, we have a numbering problem!" #endif - table[40].data = &c->rlimit_rtprio; + table[41].data = &c->rlimit_rtprio; #endif #ifdef RLIMIT_RTTIME #ifndef RLIMIT_RTTIME #error "Houston, we have a numbering problem!" #endif - table[41].data = &c->rlimit_rttime; + table[42].data = &c->rlimit_rttime; #endif #endif @@ -557,7 +561,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file); if (!f && errno != ENOENT) { - pa_log_warn("Failed to open configuration file: %s", pa_cstrerror(errno)); + pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno)); goto finish; } @@ -631,7 +635,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) { s = pa_strbuf_new(); if (c->config_file) - pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file); + pa_strbuf_printf(s, _("### Read from configuration file: %s ###\n"), c->config_file); pa_assert(c->log_level <= PA_LOG_LEVEL_MAX); @@ -642,6 +646,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) { pa_strbuf_printf(s, "realtime-scheduling = %s\n", pa_yes_no(c->realtime_scheduling)); pa_strbuf_printf(s, "realtime-priority = %i\n", c->realtime_priority); pa_strbuf_printf(s, "disallow-module-loading = %s\n", pa_yes_no(c->disallow_module_loading)); + pa_strbuf_printf(s, "disallow-exit = %s\n", pa_yes_no(c->disallow_exit)); pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file)); pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance)); pa_strbuf_printf(s, "no-cpu-limit = %s\n", pa_yes_no(c->no_cpu_limit)); diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index be2fe1ab..c42984f9 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -66,7 +66,8 @@ typedef struct pa_daemon_conf { no_cpu_limit, disable_shm, disable_remixing, - load_default_script_file; + load_default_script_file, + disallow_exit; int exit_idle_time, module_idle_time, scache_idle_time, diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index 41c26e2a..33b1d61d 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -22,6 +22,7 @@ ; daemonize = no ; fail = yes ; disallow-module-loading = no +; disallow-exit = no ; use-pid-file = yes ; system-instance = no ; disable-shm = no diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index cdaa8bbd..5f35e3ec 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -23,7 +23,7 @@ ### Load something into the sample cache #load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav -load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav +#load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav #load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav #load-sample-lazy pulse-access /usr/share/sounds/generic.wav diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c index cd6866aa..9c9f1c81 100644 --- a/src/daemon/dumpmodules.c +++ b/src/daemon/dumpmodules.c @@ -30,6 +30,7 @@ #include <ltdl.h> #include <pulse/util.h> +#include <pulse/i18n.h> #include <pulsecore/modinfo.h> #include <pulsecore/core-util.h> @@ -39,7 +40,7 @@ #define PREFIX "module-" -static void short_info(const char *name, PA_GCC_UNUSED const char *path, pa_modinfo *i) { +static void short_info(const char *name, const char *path, pa_modinfo *i) { pa_assert(name); pa_assert(i); @@ -56,24 +57,24 @@ static void long_info(const char *name, const char *path, pa_modinfo *i) { nl = 1; - printf("Name: %s\n", name); + printf(_("Name: %s\n"), name); if (!i->description && !i->version && !i->author && !i->usage) - printf("No module information available\n"); + printf(_("No module information available\n")); else { if (i->version) - printf("Version: %s\n", i->version); + printf(_("Version: %s\n"), i->version); if (i->description) - printf("Description: %s\n", i->description); + printf(_("Description: %s\n"), i->description); if (i->author) - printf("Author: %s\n", i->author); + printf(_("Author: %s\n"), i->author); if (i->usage) - printf("Usage: %s\n", i->usage); - printf("Load Once: %s\n", pa_yes_no(i->load_once)); + printf(_("Usage: %s\n"), i->usage); + printf(_("Load Once: %s\n"), pa_yes_no(i->load_once)); } if (path) - printf("Path: %s\n", path); + printf(_("Path: %s\n"), path); } static void show_info(const char *name, const char *path, void (*info)(const char *name, const char *path, pa_modinfo*i)) { diff --git a/src/daemon/ltdl-bind-now.c b/src/daemon/ltdl-bind-now.c index b1770674..92e5d40d 100644 --- a/src/daemon/ltdl-bind-now.c +++ b/src/daemon/ltdl-bind-now.c @@ -24,21 +24,20 @@ #include <config.h> #endif -#if HAVE_DLFCN_H +#ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif -#if HAVE_SYS_DL_H +#ifdef HAVE_SYS_DL_H #include <sys/dl.h> #endif -#ifndef HAVE_STRUCT_LT_USER_DLLOADER -/* Only used with ltdl 2.2 */ #include <string.h> -#endif #include <ltdl.h> +#include <pulse/i18n.h> + #include <pulsecore/macro.h> #include <pulsecore/mutex.h> #include <pulsecore/thread.h> @@ -54,9 +53,9 @@ #undef PA_BIND_NOW #endif -static pa_mutex *libtool_mutex = NULL; +#ifdef HAVE_LT_DLMUTEX_REGISTER -PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); +static pa_mutex *libtool_mutex = NULL; static void libtool_lock(void) { pa_mutex_lock(libtool_mutex); @@ -66,6 +65,10 @@ static void libtool_unlock(void) { pa_mutex_unlock(libtool_mutex); } +#endif + +PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); + static void libtool_set_error(const char *error) { PA_STATIC_TLS_SET(libtool_tls, (char*) error); } @@ -89,16 +92,19 @@ static const char *libtool_get_error(void) { */ #ifndef HAVE_LT_DLADVISE -static lt_module bind_now_open(lt_user_data d, const char *fname) { +static lt_module bind_now_open(lt_user_data d, const char *fname) #else - static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise) { +static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise) #endif +{ lt_module m; pa_assert(fname); if (!(m = dlopen(fname, PA_BIND_NOW))) { +#ifdef HAVE_LT_DLMUTEX_REGISTER libtool_set_error(dlerror()); +#endif return NULL; } @@ -110,7 +116,9 @@ static int bind_now_close(lt_user_data d, lt_module m) { pa_assert(m); if (dlclose(m) != 0){ +#ifdef HAVE_LT_DLMUTEX_REGISTER libtool_set_error(dlerror()); +#endif return 1; } @@ -124,7 +132,9 @@ static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol) pa_assert(symbol); if (!(ptr = dlsym(m, symbol))) { +#ifdef HAVE_LT_DLMUTEX_REGISTER libtool_set_error(dlerror()); +#endif return NULL; } @@ -150,8 +160,9 @@ void pa_ltdl_init(void) { #endif pa_assert_se(lt_dlinit() == 0); - pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); + #ifdef HAVE_LT_DLMUTEX_REGISTER + pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); #endif @@ -163,14 +174,15 @@ void pa_ltdl_init(void) { /* Add our BIND_NOW loader as the default module loader. */ if (lt_dlloader_add(place, &loader, "bind-now-loader") != 0) - pa_log_warn("Failed to add bind-now-loader."); + pa_log_warn(_("Failed to add bind-now-loader.")); # else /* Already initialised */ - if ( dlopen_loader != NULL ) return; + if (dlopen_loader) + return; if (!(dlopen_loader = lt_dlloader_find("dlopen"))) { - pa_log_warn("Failed to find original dlopen loader."); - return; + pa_log_warn(_("Failed to find original dlopen loader.")); + return; } memcpy(&bindnow_loader, dlopen_loader, sizeof(bindnow_loader)); @@ -182,14 +194,16 @@ void pa_ltdl_init(void) { /* Add our BIND_NOW loader as the default module loader. */ if (lt_dlloader_add(&bindnow_loader) != 0) - pa_log_warn("Failed to add bind-now-loader."); + pa_log_warn(_("Failed to add bind-now-loader.")); # endif #endif } void pa_ltdl_done(void) { pa_assert_se(lt_dlexit() == 0); + +#ifdef HAVE_LT_DLMUTEX_REGISTER pa_mutex_free(libtool_mutex); libtool_mutex = NULL; +#endif } - diff --git a/src/daemon/main.c b/src/daemon/main.c index 5fc9f01c..b57a74a2 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -64,6 +64,8 @@ #include <pulse/mainloop-signal.h> #include <pulse/timeval.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> +#include <pulse/lock-autospawn.h> #include <pulsecore/winsock.h> #include <pulsecore/core-error.h> @@ -94,8 +96,6 @@ #include "ltdl-bind-now.h" #include "polkit.h" -#define AUTOSPAWN_LOCK "autospawn.lock" - #ifdef HAVE_LIBWRAP /* Only one instance of these variables */ int allow_severity = LOG_INFO; @@ -111,7 +111,7 @@ int __padsp_disabled__ = 7; #ifdef OS_IS_WIN32 -static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) { MSG msg; struct timeval tvnext; @@ -130,8 +130,8 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const s #endif -static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, int sig, void *userdata) { - pa_log_info("Got signal %s.", pa_sig2str(sig)); +static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) { + pa_log_info(_("Got signal %s."), pa_sig2str(sig)); switch (sig) { #ifdef SIGUSR1 @@ -158,7 +158,7 @@ static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, case SIGINT: case SIGTERM: default: - pa_log_info("Exiting."); + pa_log_info(_("Exiting.")); m->quit(m, 1); break; } @@ -176,41 +176,41 @@ static int change_user(void) { * afterwards. */ if (!(pw = getpwnam(PA_SYSTEM_USER))) { - pa_log("Failed to find user '%s'.", PA_SYSTEM_USER); + pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER); return -1; } if (!(gr = getgrnam(PA_SYSTEM_GROUP))) { - pa_log("Failed to find group '%s'.", PA_SYSTEM_GROUP); + pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP); return -1; } - pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).", + pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."), PA_SYSTEM_USER, (unsigned long) pw->pw_uid, PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid); if (pw->pw_gid != gr->gr_gid) { - pa_log("GID of user '%s' and of group '%s' don't match.", PA_SYSTEM_USER, PA_SYSTEM_GROUP); + pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP); return -1; } if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0) - pa_log_warn("Warning: home directory of user '%s' is not '%s', ignoring.", PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH); + pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH); if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) { - pa_log("Failed to create '%s': %s", PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno)); + pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno)); return -1; } if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) { - pa_log("Failed to create '%s': %s", PA_SYSTEM_STATE_PATH, pa_cstrerror(errno)); + pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno)); return -1; } /* We don't create the config dir here, because we don't need to write to it */ if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) { - pa_log("Failed to change group list: %s", pa_cstrerror(errno)); + pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno)); return -1; } @@ -226,7 +226,7 @@ static int change_user(void) { #endif if (r < 0) { - pa_log("Failed to change GID: %s", pa_cstrerror(errno)); + pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno)); return -1; } @@ -242,7 +242,7 @@ static int change_user(void) { #endif if (r < 0) { - pa_log("Failed to change UID: %s", pa_cstrerror(errno)); + pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno)); return -1; } @@ -256,7 +256,7 @@ static int change_user(void) { pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH); pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); - pa_log_info("Successfully dropped root privileges."); + pa_log_info(_("Successfully dropped root privileges.")); return 0; } @@ -264,7 +264,7 @@ static int change_user(void) { #else /* HAVE_PWD_H && HAVE_GRP_H */ static int change_user(void) { - pa_log("System wide mode unsupported on this platform."); + pa_log(_("System wide mode unsupported on this platform.")); return -1; } @@ -282,7 +282,7 @@ static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) { rl.rlim_cur = rl.rlim_max = r->value; if (setrlimit(resource, &rl) < 0) { - pa_log_info("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno)); + pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno)); return -1; } @@ -345,7 +345,8 @@ int main(int argc, char *argv[]) { struct timeval win32_tv; #endif char *lf = NULL; - int autospawn_lock_fd = -1; + int autospawn_fd = -1; + pa_bool_t autospawn_locked = FALSE; #if defined(__linux__) && defined(__OPTIMIZE__) /* @@ -407,6 +408,8 @@ int main(int argc, char *argv[]) { * still are normal root. */ setlocale(LC_ALL, ""); + pa_init_i18n(); + pa_log_set_maximal_level(PA_LOG_INFO); pa_log_set_ident("pulseaudio"); @@ -419,7 +422,7 @@ int main(int argc, char *argv[]) { goto finish; if (pa_cmdline_parse(conf, argc, argv, &d) < 0) { - pa_log("Failed to parse command line."); + pa_log(_("Failed to parse command line.")); goto finish; } @@ -435,14 +438,14 @@ int main(int argc, char *argv[]) { if (conf->high_priority && !allow_high_priority) { if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) { - pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing high-priority scheduling."); + pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP); allow_high_priority = TRUE; } } if (conf->realtime_scheduling && !allow_realtime) { if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) { - pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time scheduling."); + pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP); allow_realtime = TRUE; } } @@ -450,18 +453,18 @@ int main(int argc, char *argv[]) { #ifdef HAVE_POLKIT if (conf->high_priority && !allow_high_priority) { if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) { - pa_log_info("PolicyKit grants us acquire-high-priority privilege."); + pa_log_info(_("PolicyKit grants us acquire-high-priority privilege.")); allow_high_priority = TRUE; } else - pa_log_info("PolicyKit refuses acquire-high-priority privilege."); + pa_log_info(_("PolicyKit refuses acquire-high-priority privilege.")); } if (conf->realtime_scheduling && !allow_realtime) { if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) { - pa_log_info("PolicyKit grants us acquire-real-time privilege."); + pa_log_info(_("PolicyKit grants us acquire-real-time privilege.")); allow_realtime = TRUE; } else - pa_log_info("PolicyKit refuses acquire-real-time privilege."); + pa_log_info(_("PolicyKit refuses acquire-real-time privilege.")); } #endif @@ -473,9 +476,9 @@ int main(int argc, char *argv[]) { pa_drop_caps(); if (conf->high_priority || conf->realtime_scheduling) - pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n" - "We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" - "For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."); + pa_log_notice(_("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n" + "We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" + "For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user.")); } } @@ -491,7 +494,7 @@ int main(int argc, char *argv[]) { #endif if (conf->high_priority && !pa_can_high_priority()) - pa_log_warn("High-priority scheduling enabled in configuration but not allowed by policy."); + pa_log_warn(_("High-priority scheduling enabled in configuration but not allowed by policy.")); if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START)) pa_raise_priority(conf->nice_level); @@ -516,24 +519,24 @@ int main(int argc, char *argv[]) { rl.rlim_max = rl.rlim_cur = 9; if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) { - pa_log_info("Successfully increased RLIMIT_RTPRIO"); + pa_log_info(_("Successfully increased RLIMIT_RTPRIO")); drop = TRUE; } else - pa_log_warn("RLIMIT_RTPRIO failed: %s", pa_cstrerror(errno)); + pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno)); } } } #endif if (drop) { - pa_log_info("Giving up CAP_NICE"); + pa_log_info(_("Giving up CAP_NICE")); pa_drop_caps(); suid_root = FALSE; } } if (conf->realtime_scheduling && !pa_can_realtime()) - pa_log_warn("Real-time scheduling enabled in configuration but not allowed by policy."); + pa_log_warn(_("Real-time scheduling enabled in configuration but not allowed by policy.")); pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority())); @@ -591,9 +594,9 @@ int main(int argc, char *argv[]) { pid_t pid; if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) - pa_log_info("Daemon not running"); + pa_log_info(_("Daemon not running")); else { - pa_log_info("Daemon running as PID %u", pid); + pa_log_info(_("Daemon running as PID %u"), pid); retval = 0; } @@ -603,7 +606,7 @@ int main(int argc, char *argv[]) { case PA_CMD_KILL: if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0) - pa_log("Failed to kill daemon."); + pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno)); else retval = 0; @@ -621,24 +624,49 @@ int main(int argc, char *argv[]) { } if (real_root && !conf->system_instance) - pa_log_warn("This program is not intended to be run as root (unless --system is specified)."); + pa_log_warn(_("This program is not intended to be run as root (unless --system is specified).")); else if (!real_root && conf->system_instance) { - pa_log("Root priviliges required."); + pa_log(_("Root priviliges required.")); goto finish; } if (conf->cmd == PA_CMD_START && conf->system_instance) { - pa_log("--start not supported for system instances."); + pa_log(_("--start not supported for system instances.")); goto finish; } + if (conf->system_instance && !conf->disallow_exit) + pa_log_warn(_("Running in system mode, but --disallow-exit not set!")); + + if (conf->system_instance && !conf->disallow_module_loading) + pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!")); + + if (conf->system_instance && !conf->disable_shm) { + pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!")); + conf->disable_shm = TRUE; + } + + if (conf->system_instance && conf->exit_idle_time > 0) { + pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!")); + conf->exit_idle_time = 0; + } + 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 * synchronous. */ - lf = pa_runtime_path(AUTOSPAWN_LOCK); - autospawn_lock_fd = pa_lock_lockfile(lf); + if ((autospawn_fd = pa_autospawn_lock_init()) < 0) { + pa_log("Failed to initialize autospawn lock"); + goto finish; + } + + if ((pa_autospawn_lock_acquire(TRUE) < 0)) { + pa_log("Failed to acquire autospawn lock"); + goto finish; + } + + autospawn_locked = TRUE; } if (conf->daemonize) { @@ -646,18 +674,18 @@ int main(int argc, char *argv[]) { int tty_fd; if (pa_stdio_acquire() < 0) { - pa_log("Failed to acquire stdio."); + pa_log(_("Failed to acquire stdio.")); goto finish; } #ifdef HAVE_FORK if (pipe(daemon_pipe) < 0) { - pa_log("pipe failed: %s", pa_cstrerror(errno)); + pa_log(_("pipe failed: %s"), pa_cstrerror(errno)); goto finish; } if ((child = fork()) < 0) { - pa_log("fork() failed: %s", pa_cstrerror(errno)); + pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); goto finish; } @@ -671,25 +699,28 @@ int main(int argc, char *argv[]) { if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) { if (n < 0) - pa_log("read() failed: %s", pa_cstrerror(errno)); + pa_log(_("read() failed: %s"), pa_cstrerror(errno)); retval = 1; } if (retval) - pa_log("Daemon startup failed."); + pa_log(_("Daemon startup failed.")); else - pa_log_info("Daemon startup successful."); + pa_log_info(_("Daemon startup successful.")); goto finish; } - if (autospawn_lock_fd >= 0) { + if (autospawn_fd >= 0) { /* The lock file is unlocked from the parent, so we need * to close it in the child */ - pa_close(autospawn_lock_fd); - autospawn_lock_fd = -1; + pa_autospawn_lock_release(); + pa_autospawn_lock_done(TRUE); + + autospawn_locked = FALSE; + autospawn_fd = -1; } pa_assert_se(pa_close(daemon_pipe[0]) == 0); @@ -746,17 +777,27 @@ int main(int argc, char *argv[]) { pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0"); - pa_log_info("This is PulseAudio " PACKAGE_VERSION); - pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE); + pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION); + pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE); + + if (!(s = pa_machine_id())) { + pa_log(_("Failed to get machine ID")); + goto finish; + } + pa_log_info(_("Machine ID is %s."), s); + pa_xfree(s); + if (!(s = pa_get_runtime_dir())) goto finish; - pa_log_info("Using runtime directory %s.", s); + pa_log_info(_("Using runtime directory %s."), s); pa_xfree(s); + if (!(s = pa_get_state_dir())) - pa_log_info("Using state directory %s.", s); + goto finish; + pa_log_info(_("Using state directory %s."), s); pa_xfree(s); - pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode())); + pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode())); if (conf->use_pid_file) { int z; @@ -771,7 +812,7 @@ int main(int argc, char *argv[]) { goto finish; } - pa_log("pa_pid_file_create() failed."); + pa_log(_("pa_pid_file_create() failed.")); goto finish; } @@ -783,9 +824,9 @@ int main(int argc, char *argv[]) { #endif if (pa_rtclock_hrtimer()) - pa_log_info("Fresh high-resolution timers available! Bon appetit!"); + pa_log_info(_("Fresh high-resolution timers available! Bon appetit!")); else - pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); + pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!")); #ifdef SIGRTMIN /* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */ @@ -795,7 +836,7 @@ int main(int argc, char *argv[]) { pa_assert_se(mainloop = pa_mainloop_new()); if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) { - pa_log("pa_core_new() failed."); + pa_log(_("pa_core_new() failed.")); goto finish; } @@ -810,6 +851,7 @@ int main(int argc, char *argv[]) { c->realtime_scheduling = !!conf->realtime_scheduling; c->disable_remixing = !!conf->disable_remixing; c->running_as_daemon = !!conf->daemonize; + c->disallow_exit = conf->disallow_exit; pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0); pa_signal_new(SIGINT, signal_callback, c); @@ -854,17 +896,17 @@ int main(int argc, char *argv[]) { c->disallow_module_loading = !!conf->disallow_module_loading; if (r < 0 && conf->fail) { - pa_log("Failed to initialize daemon."); + pa_log(_("Failed to initialize daemon.")); goto finish; } if (!c->modules || pa_idxset_size(c->modules) == 0) { - pa_log("Daemon startup without any loaded modules, refusing to work."); + pa_log(_("Daemon startup without any loaded modules, refusing to work.")); goto finish; } if (c->default_sink_name && !pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, TRUE) && conf->fail) { - pa_log_error("Default sink name (%s) does not exist in name register.", c->default_sink_name); + pa_log_error(_("Default sink name (%s) does not exist in name register."), c->default_sink_name); goto finish; } @@ -877,18 +919,22 @@ int main(int argc, char *argv[]) { } #endif - pa_log_info("Daemon startup complete."); + pa_log_info(_("Daemon startup complete.")); retval = 0; if (pa_mainloop_run(mainloop, &retval) < 0) goto finish; - pa_log_info("Daemon shutdown initiated."); + pa_log_info(_("Daemon shutdown initiated.")); finish: - if (autospawn_lock_fd >= 0) - pa_unlock_lockfile(lf, autospawn_lock_fd); + if (autospawn_fd >= 0) { + if (autospawn_locked) + pa_autospawn_lock_release(); + + pa_autospawn_lock_done(FALSE); + } if (lf) pa_xfree(lf); @@ -900,7 +946,7 @@ finish: if (c) { pa_core_unref(c); - pa_log_info("Daemon terminated."); + pa_log_info(_("Daemon terminated.")); } if (!conf->no_cpu_limit) diff --git a/src/daemon/polkit.c b/src/daemon/polkit.c index 08155cf2..921e5d1d 100644 --- a/src/daemon/polkit.c +++ b/src/daemon/polkit.c @@ -31,6 +31,8 @@ #include <dbus/dbus.h> #include <polkit-dbus/polkit-dbus.h> +#include <pulse/i18n.h> + #include <pulsecore/log.h> #include <pulsecore/macro.h> @@ -50,7 +52,7 @@ int pa_polkit_check(const char *action_id) { dbus_error_init(&dbus_error); if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error))) { - pa_log_error("Cannot connect to system bus: %s", dbus_error.message); + pa_log_error(_("Cannot connect to system bus: %s"), dbus_error.message); goto finish; } @@ -60,7 +62,7 @@ int pa_polkit_check(const char *action_id) { dbus_connection_set_exit_on_disconnect(bus, FALSE); if (!(caller = polkit_caller_new_from_pid(bus, getpid(), &dbus_error))) { - pa_log_error("Cannot get caller from PID: %s", dbus_error.message); + pa_log_error(_("Cannot get caller from PID: %s"), dbus_error.message); goto finish; } @@ -72,12 +74,12 @@ int pa_polkit_check(const char *action_id) { * -- an not the EUID or any other user id. */ if (!(polkit_caller_set_uid(caller, getuid()))) { - pa_log_error("Cannot set UID on caller object."); + pa_log_error(_("Cannot set UID on caller object.")); goto finish; } if (!(polkit_caller_get_ck_session(caller, &session))) { - pa_log_error("Failed to get CK session."); + pa_log_error(_("Failed to get CK session.")); goto finish; } @@ -85,27 +87,27 @@ int pa_polkit_check(const char *action_id) { * object */ if (!(polkit_session_set_uid(session, getuid()))) { - pa_log_error("Cannot set UID on session object."); + pa_log_error(_("Cannot set UID on session object.")); goto finish; } if (!(action = polkit_action_new())) { - pa_log_error("Cannot allocate PolKitAction."); + pa_log_error(_("Cannot allocate PolKitAction.")); goto finish; } if (!polkit_action_set_action_id(action, action_id)) { - pa_log_error("Cannot set action_id"); + pa_log_error(_("Cannot set action_id")); goto finish; } if (!(context = polkit_context_new())) { - pa_log_error("Cannot allocate PolKitContext."); + pa_log_error(_("Cannot allocate PolKitContext.")); goto finish; } if (!polkit_context_init(context, &polkit_error)) { - pa_log_error("Cannot initialize PolKitContext: %s", polkit_error_get_error_message(polkit_error)); + pa_log_error(_("Cannot initialize PolKitContext: %s"), polkit_error_get_error_message(polkit_error)); goto finish; } @@ -114,7 +116,7 @@ int pa_polkit_check(const char *action_id) { polkit_result = polkit_context_is_caller_authorized(context, action, caller, TRUE, &polkit_error); if (polkit_error_is_set(polkit_error)) { - pa_log_error("Could not determine whether caller is authorized: %s", polkit_error_get_error_message(polkit_error)); + pa_log_error(_("Could not determine whether caller is authorized: %s"), polkit_error_get_error_message(polkit_error)); goto finish; } @@ -134,7 +136,7 @@ int pa_polkit_check(const char *action_id) { } if (dbus_error_is_set(&dbus_error)) { - pa_log_error("Cannot obtain auth: %s", dbus_error.message); + pa_log_error(_("Cannot obtain auth: %s"), dbus_error.message); goto finish; } } @@ -143,7 +145,7 @@ int pa_polkit_check(const char *action_id) { } if (polkit_result != POLKIT_RESULT_YES && polkit_result != POLKIT_RESULT_NO) - pa_log_warn("PolicyKit responded with '%s'", polkit_result_to_string_representation(polkit_result)); + pa_log_warn(_("PolicyKit responded with '%s'"), polkit_result_to_string_representation(polkit_result)); ret = polkit_result == POLKIT_RESULT_YES; diff --git a/src/map-file b/src/map-file index 8d1c582e..b6d3b63d 100644 --- a/src/map-file +++ b/src/map-file @@ -98,9 +98,16 @@ pa_context_unref; pa_cvolume_avg; pa_cvolume_channels_equal_to; pa_cvolume_equal; +pa_cvolume_remap; pa_cvolume_set; pa_cvolume_snprint; pa_cvolume_valid; +pa_ext_stream_restore_delete; +pa_ext_stream_restore_read; +pa_ext_stream_restore_set_subscribe_cb; +pa_ext_stream_restore_subscribe; +pa_ext_stream_restore_test; +pa_ext_stream_restore_write; pa_frame_size; pa_get_binary_name; pa_get_fqdn; @@ -133,21 +140,21 @@ pa_operation_ref; pa_operation_unref; pa_parse_sample_format; pa_path_get_filename; -pa_proplist_free; -pa_proplist_contains; pa_proplist_clear; +pa_proplist_contains; pa_proplist_copy; +pa_proplist_free; pa_proplist_get; pa_proplist_gets; pa_proplist_iterate; -pa_proplist_update; pa_proplist_new; pa_proplist_set; -pa_proplist_sets; pa_proplist_setf; +pa_proplist_sets; +pa_proplist_to_string; pa_proplist_unset; pa_proplist_unset_many; -pa_proplist_to_string; +pa_proplist_update; pa_sample_format_to_string; pa_sample_size; pa_sample_spec_equal; @@ -198,8 +205,8 @@ pa_stream_readable_size; pa_stream_ref; pa_stream_set_buffer_attr; pa_stream_set_latency_update_callback; -pa_stream_set_moved_callback; pa_stream_set_monitor_stream; +pa_stream_set_moved_callback; pa_stream_set_name; pa_stream_set_overflow_callback; pa_stream_set_read_callback; diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 8abf834d..e8c7e146 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -39,7 +39,7 @@ #include "alsa-util.h" struct pa_alsa_fdlist { - int num_fds; + unsigned num_fds; struct pollfd *fds; /* This is a temporary buffer used to avoid lots of mallocs */ struct pollfd *work_fds; @@ -50,16 +50,17 @@ struct pa_alsa_fdlist { pa_defer_event *defer; pa_io_event **ios; - int polled; + pa_bool_t polled; void (*cb)(void *userdata); void *userdata; }; -static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) { +static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { struct pa_alsa_fdlist *fdl = userdata; - int err, i; + int err; + unsigned i; unsigned short revents; pa_assert(a); @@ -71,11 +72,11 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io if (fdl->polled) return; - fdl->polled = 1; + fdl->polled = TRUE; memcpy(fdl->work_fds, fdl->fds, sizeof(struct pollfd) * fdl->num_fds); - for (i = 0;i < fdl->num_fds; i++) { + for (i = 0; i < fdl->num_fds; i++) { if (e == fdl->ios[i]) { if (events & PA_IO_EVENT_INPUT) fdl->work_fds[i].revents |= POLLIN; @@ -102,9 +103,10 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io snd_mixer_handle_events(fdl->mixer); } -static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *userdata) { +static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) { struct pa_alsa_fdlist *fdl = userdata; - int num_fds, i, err; + unsigned num_fds, i; + int err; struct pollfd *temp; pa_assert(a); @@ -113,8 +115,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u a->defer_enable(fdl->defer, 0); - num_fds = snd_mixer_poll_descriptors_count(fdl->mixer); - pa_assert(num_fds > 0); + num_fds = (unsigned) snd_mixer_poll_descriptors_count(fdl->mixer); if (num_fds != fdl->num_fds) { if (fdl->fds) @@ -132,7 +133,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u return; } - fdl->polled = 0; + fdl->polled = FALSE; if (memcmp(fdl->fds, fdl->work_fds, sizeof(struct pollfd) * num_fds) == 0) return; @@ -176,7 +177,7 @@ struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) { fdl->m = NULL; fdl->defer = NULL; fdl->ios = NULL; - fdl->polled = 0; + fdl->polled = FALSE; return fdl; } @@ -190,9 +191,9 @@ void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) { } if (fdl->ios) { - int i; + unsigned i; pa_assert(fdl->m); - for (i = 0;i < fdl->num_fds;i++) + for (i = 0; i < fdl->num_fds; i++) fdl->m->io_free(fdl->ios[i]); pa_xfree(fdl->ios); } @@ -403,7 +404,7 @@ int pa_alsa_set_hw_params( /* If the sample rate deviates too much, we need to resample */ if (r < ss->rate*.95 || r > ss->rate*1.05) ss->rate = r; - ss->channels = c; + ss->channels = (uint8_t) c; ss->format = f; pa_assert(_periods > 0); @@ -808,7 +809,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel if (channel_map->channels > 1 && ((playback && snd_mixer_selem_has_playback_volume_joined(elem)) || (!playback && snd_mixer_selem_has_capture_volume_joined(elem)))) { - pa_log_info("ALSA device lacks independant volume controls for each channel, falling back to software volume control."); + pa_log_info("ALSA device lacks independant volume controls for each channel."); return -1; } @@ -820,7 +821,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel id = alsa_channel_ids[channel_map->map[i]]; if (!is_mono && id == SND_MIXER_SCHN_UNKNOWN) { - pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer. Falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i])); + pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer.", pa_channel_position_to_string(channel_map->map[i])); return -1; } @@ -832,7 +833,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel if ((playback && (!snd_mixer_selem_has_playback_channel(elem, id) || (is_mono && !snd_mixer_selem_is_playback_mono(elem)))) || (!playback && (!snd_mixer_selem_has_capture_channel(elem, id) || (is_mono && !snd_mixer_selem_is_capture_mono(elem))))) { - pa_log_info("ALSA device lacks separate volumes control for channel '%s', falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i])); + pa_log_info("ALSA device lacks separate volumes control for channel '%s'", pa_channel_position_to_string(channel_map->map[i])); return -1; } @@ -850,56 +851,6 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel return 0; } -void pa_alsa_0dB_playback(snd_mixer_elem_t *elem) { - long min, max, v; - - pa_assert(elem); - - /* Try to enable 0 dB if possible. If ALSA cannot do dB, then use - * raw volume levels and fix them to 75% */ - - if (snd_mixer_selem_set_playback_dB_all(elem, 0, -1) >= 0) - return; - - if (snd_mixer_selem_set_playback_dB_all(elem, 0, 1) >= 0) - return; - - if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) < 0) - return; - - v = min + ((max - min) * 3) / 4; /* 75% */ - - if (v <= min) - v = max; - - snd_mixer_selem_set_playback_volume_all(elem, v); -} - -void pa_alsa_0dB_capture(snd_mixer_elem_t *elem) { - long min, max, v; - - pa_assert(elem); - - /* Try to enable 0 dB if possible. If ALSA cannot do dB, then use - * raw volume levels and fix them to 75% */ - - if (snd_mixer_selem_set_capture_dB_all(elem, 0, -1) >= 0) - return; - - if (snd_mixer_selem_set_capture_dB_all(elem, 0, 1) >= 0) - return; - - if (snd_mixer_selem_get_capture_volume_range(elem, &min, &max) < 0) - return; - - v = min + ((max - min) * 3) / 4; /* 75% */ - - if (v <= min) - v = max; - - snd_mixer_selem_set_capture_volume_all(elem, v); -} - void pa_alsa_dump(snd_pcm_t *pcm) { int err; snd_output_t *out; @@ -1106,10 +1057,10 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) { return NULL; } - item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, n); + item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, (unsigned) n); pollfd = pa_rtpoll_item_get_pollfd(item, NULL); - if ((err = snd_pcm_poll_descriptors(pcm, pollfd, n)) < 0) { + if ((err = snd_pcm_poll_descriptors(pcm, pollfd, (unsigned) n)) < 0) { pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); pa_rtpoll_item_free(item); return NULL; @@ -1117,3 +1068,27 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) { return item; } + +pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t) { + unsigned i; + + pa_assert(r); + pa_assert(t); + pa_assert(r->channels == t->channels); + + for (i = 0; i < r->channels; i++) { + double a, b, c; + + a = pa_sw_volume_to_linear(r->values[i]); /* the hw volume */ + b = pa_sw_volume_to_linear(t->values[i]); /* the intended volume */ + + if (a <= 0) + c = 0; + else + c = b / a; + + r->values[i] = pa_sw_volume_from_linear(c); + } + + return r; +} diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index 4de8bcd2..7991a107 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -26,6 +26,7 @@ #include <asoundlib.h> #include <pulse/sample.h> +#include <pulse/volume.h> #include <pulse/mainloop-api.h> #include <pulse/channelmap.h> #include <pulse/proplist.h> @@ -79,9 +80,6 @@ snd_pcm_t *pa_alsa_open_by_device_string( int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel_map, snd_mixer_selem_channel_id_t mixer_map[], pa_bool_t playback); -void pa_alsa_0dB_playback(snd_mixer_elem_t *elem); -void pa_alsa_0dB_capture(snd_mixer_elem_t *elem); - void pa_alsa_dump(snd_pcm_t *pcm); void pa_alsa_dump_status(snd_pcm_t *pcm); @@ -94,4 +92,6 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents); pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll); +pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t); + #endif diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 8e0066bc..d2abf087 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -90,7 +90,7 @@ static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) { } /* pa_io_event_cb_t IO event handler */ -static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) { +static void handle_io_event(pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) { unsigned int flags = 0; DBusWatch *watch = userdata; @@ -126,7 +126,7 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc dbus_timeout_handle(timeout); /* restart it for the next scheduled time */ - pa_timeval_add(&next, dbus_timeout_get_interval(timeout) * 1000); + pa_timeval_add(&next, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000); ea->time_restart(e, &next); } } @@ -192,7 +192,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { return FALSE; pa_gettimeofday(&tv); - pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000); + pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000); ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, timeout); @@ -227,7 +227,7 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) { struct timeval tv; pa_gettimeofday(&tv); - pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000); + pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000); c->mainloop->time_restart(ev, &tv); } else diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c index a2a43278..6e8ab6ea 100644 --- a/src/modules/gconf/module-gconf.c +++ b/src/modules/gconf/module-gconf.c @@ -96,7 +96,7 @@ static int fill_buf(struct userdata *u) { if ((r = pa_read(u->fd, u->buf + u->buf_fill, BUF_MAX - u->buf_fill, &u->fd_type)) <= 0) return -1; - u->buf_fill += r; + u->buf_fill += (size_t) r; return 0; } @@ -123,7 +123,7 @@ static char *read_string(struct userdata *u) { if ((e = memchr(u->buf, 0, u->buf_fill))) { char *ret = pa_xstrdup(u->buf); - u->buf_fill -= e - u->buf +1; + u->buf_fill -= (size_t) (e - u->buf +1); memmove(u->buf, e+1, u->buf_fill); return ret; } @@ -142,7 +142,7 @@ static void unload_one_module(struct userdata *u, struct module_info*m, unsigned return; pa_log_debug("Unloading module #%i", m->items[i].index); - pa_module_unload_by_index(u->core, m->items[i].index); + pa_module_unload_by_index(u->core, m->items[i].index, TRUE); m->items[i].index = PA_INVALID_INDEX; pa_xfree(m->items[i].name); pa_xfree(m->items[i].args); @@ -164,10 +164,10 @@ static void unload_all_modules(struct userdata *u, struct module_info*m) { static void load_module( struct userdata *u, struct module_info *m, - int i, + unsigned i, const char *name, const char *args, - int is_new) { + pa_bool_t is_new) { pa_module *mod; @@ -324,7 +324,7 @@ static void io_event_cb( u->io_event = NULL; } - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index aad6801e..e3f9a5ff 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -28,6 +28,10 @@ #include <asoundlib.h> +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include <valgrind/memcheck.h> +#endif + #include <pulse/xmalloc.h> #include <pulse/util.h> #include <pulse/timeval.h> @@ -68,8 +72,7 @@ PA_MODULE_USAGE( "mmap=<enable memory mapping?> " "tsched=<enable system timer based scheduling mode?> " "tsched_buffer_size=<buffer size when using timer based scheduling> " - "tsched_buffer_watermark=<lower fill watermark> " - "mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>"); + "tsched_buffer_watermark=<lower fill watermark>"); static const char* const valid_modargs[] = { "sink_name", @@ -85,7 +88,6 @@ static const char* const valid_modargs[] = { "tsched", "tsched_buffer_size", "tsched_buffer_watermark", - "mixer_reset", NULL }; @@ -112,6 +114,8 @@ struct userdata { long hw_volume_max, hw_volume_min; long hw_dB_max, hw_dB_min; pa_bool_t hw_dB_supported; + pa_bool_t mixer_seperate_channels; + pa_cvolume hardware_volume; size_t frame_size, fragment_size, hwbuf_size, tsched_watermark; unsigned nfragments; @@ -139,7 +143,7 @@ static void fix_tsched_watermark(struct userdata *u) { size_t min_sleep, min_wakeup; pa_assert(u); - max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size; + max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size; min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->sink->sample_spec); min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->sink->sample_spec); @@ -212,8 +216,8 @@ static int try_recover(struct userdata *u, const char *call, int err) { static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) { size_t left_to_play; - if (n*u->frame_size < u->hwbuf_size) - left_to_play = u->hwbuf_size - (n*u->frame_size); + if ((size_t) n*u->frame_size < u->hwbuf_size) + left_to_play = u->hwbuf_size - ((size_t) n*u->frame_size); else left_to_play = 0; @@ -239,7 +243,7 @@ static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) { static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { int work_done = 0; - pa_usec_t max_sleep_usec, process_usec; + pa_usec_t max_sleep_usec = 0, process_usec = 0; size_t left_to_play; pa_assert(u); @@ -259,7 +263,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) { - if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0) + if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0) continue; return r; @@ -291,6 +295,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { int err; const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n; + snd_pcm_sframes_t sframes; /* pa_log_debug("%lu frames to write", (unsigned long) frames); */ @@ -326,9 +331,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { * a little bit longer around? */ pa_memblock_unref_fixed(chunk.memblock); - if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) { + if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) { - if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0) + if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0) continue; return r; @@ -336,7 +341,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { work_done = 1; - u->frame_index += frames; + u->frame_index += (int64_t) frames; u->since_start += frames * u->frame_size; /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */ @@ -344,7 +349,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { if (frames >= (snd_pcm_uframes_t) n) break; - n -= frames; + n -= (snd_pcm_sframes_t) frames; } } @@ -354,7 +359,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) { static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) { int work_done = 0; - pa_usec_t max_sleep_usec, process_usec; + pa_usec_t max_sleep_usec = 0, process_usec = 0; size_t left_to_play; pa_assert(u); @@ -371,7 +376,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) { if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) { - if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0) + if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0) continue; return r; @@ -402,31 +407,31 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) { /* pa_log_debug("%lu frames to write", (unsigned long) frames); */ if (u->memchunk.length <= 0) - pa_sink_render(u->sink, n * u->frame_size, &u->memchunk); + pa_sink_render(u->sink, (size_t) n * u->frame_size, &u->memchunk); pa_assert(u->memchunk.length > 0); - frames = u->memchunk.length / u->frame_size; + frames = (snd_pcm_sframes_t) (u->memchunk.length / u->frame_size); if (frames > n) frames = n; p = pa_memblock_acquire(u->memchunk.memblock); - frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, frames); + frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, (snd_pcm_uframes_t) frames); pa_memblock_release(u->memchunk.memblock); pa_assert(frames != 0); if (PA_UNLIKELY(frames < 0)) { - if ((r = try_recover(u, "snd_pcm_writei", n)) == 0) + if ((r = try_recover(u, "snd_pcm_writei", (int) frames)) == 0) continue; return r; } - u->memchunk.index += frames * u->frame_size; - u->memchunk.length -= frames * u->frame_size; + u->memchunk.index += (size_t) frames * u->frame_size; + u->memchunk.length -= (size_t) frames * u->frame_size; if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); @@ -436,7 +441,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) { work_done = 1; u->frame_index += frames; - u->since_start += frames * u->frame_size; + u->since_start += (size_t) frames * u->frame_size; /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */ @@ -490,7 +495,7 @@ static void update_smoother(struct userdata *u) { /* now1 = pa_timeval_load(×tamp); */ now1 = pa_rtclock_usec(); - now2 = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec); + now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->sink->sample_spec); pa_smoother_put(u->smoother, now1, now2); } @@ -504,7 +509,7 @@ static pa_usec_t sink_get_latency(struct userdata *u) { now1 = pa_rtclock_usec(); now2 = pa_smoother_get(u->smoother, now1); - delay = (int64_t) pa_bytes_to_usec(u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2; + delay = (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2; if (delay > 0) r = (pa_usec_t) delay; @@ -573,9 +578,9 @@ static int update_sw_params(struct userdata *u) { if (PA_UNLIKELY(b < u->frame_size)) b = u->frame_size; - u->hwbuf_unused_frames = - PA_LIKELY(b < u->hwbuf_size) ? - ((u->hwbuf_size - b) / u->frame_size) : 0; + u->hwbuf_unused_frames = (snd_pcm_sframes_t) + (PA_LIKELY(b < u->hwbuf_size) ? + ((u->hwbuf_size - b) / u->frame_size) : 0); fix_tsched_watermark(u); } @@ -584,7 +589,7 @@ static int update_sw_params(struct userdata *u) { pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames); /* We need at last one frame in the used part of the buffer */ - avail_min = u->hwbuf_unused_frames + 1; + avail_min = (snd_pcm_uframes_t) u->hwbuf_unused_frames + 1; if (u->use_tsched) { pa_usec_t sleep_usec, process_usec; @@ -600,7 +605,7 @@ static int update_sw_params(struct userdata *u) { return err; } - pa_sink_set_max_request(u->sink, u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size); + pa_sink_set_max_request(u->sink, u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size); return 0; } @@ -737,8 +742,8 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { return 0; if (mask & SND_CTL_EVENT_MASK_VALUE) { - pa_sink_get_volume(u->sink); - pa_sink_get_mute(u->sink); + pa_sink_get_volume(u->sink, TRUE); + pa_sink_get_mute(u->sink, TRUE); } return 0; @@ -747,30 +752,68 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { static int sink_get_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int err; - int i; + unsigned i; + pa_cvolume r; + char t[PA_CVOLUME_SNPRINT_MAX]; pa_assert(u); pa_assert(u->mixer_elem); - for (i = 0; i < s->sample_spec.channels; i++) { - long alsa_vol; + if (u->mixer_seperate_channels) { - pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i])); + r.channels = s->sample_spec.channels; - if (u->hw_dB_supported) { + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; - if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) { - s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0); - continue; - } + if (u->hw_dB_supported) { + + if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; - u->hw_dB_supported = FALSE; +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); +#endif + + r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0); + } else { + + if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; + + r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min)); + } } - if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + } else { + long alsa_vol; + + pa_assert(u->hw_dB_supported); + + if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0) goto fail; - s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); +#endif + + pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0)); + } + + pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); + + if (!pa_cvolume_equal(&u->hardware_volume, &r)) { + + u->hardware_volume = s->volume = r; + + if (u->hw_dB_supported) { + pa_cvolume reset; + + /* Hmm, so the hardware volume changed, let's reset our software volume */ + + pa_cvolume_reset(&reset, s->sample_spec.channels); + pa_sink_set_soft_volume(s, &reset); + } } return 0; @@ -784,45 +827,90 @@ fail: static int sink_set_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; int err; - int i; + unsigned i; + pa_cvolume r; pa_assert(u); pa_assert(u->mixer_elem); - for (i = 0; i < s->sample_spec.channels; i++) { - long alsa_vol; - pa_volume_t vol; + if (u->mixer_seperate_channels) { - pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i])); + r.channels = s->sample_spec.channels; - vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM); + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; + pa_volume_t vol; - if (u->hw_dB_supported) { - alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); - alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); + vol = s->volume.values[i]; - if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) { + if (u->hw_dB_supported) { - if (snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0) - s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0); + alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); - continue; - } + if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0) + goto fail; + + if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; + + r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0); + } else { + + alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); + + if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0) + goto fail; - u->hw_dB_supported = FALSE; + if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; + r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min)); + } } - alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; - alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); + } else { + pa_volume_t vol; + long alsa_vol; + + pa_assert(u->hw_dB_supported); + + vol = pa_cvolume_max(&s->volume); + + alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); + + if ((err = snd_mixer_selem_set_playback_dB_all(u->mixer_elem, alsa_vol, 1)) < 0) + goto fail; - if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0) + if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0) goto fail; - if (snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0) - s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); + pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0)); } + u->hardware_volume = r; + + if (u->hw_dB_supported) { + char t[PA_CVOLUME_SNPRINT_MAX]; + + /* Match exactly what the user requested by software */ + + pa_alsa_volume_divide(&r, &s->volume); + pa_sink_set_soft_volume(s, &r); + + pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume)); + pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume)); + pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); + + } else + + /* We can't match exactly what the user requested, hence let's + * at least tell the user about it */ + + s->volume = r; + return 0; fail: @@ -903,7 +991,7 @@ static int process_rewind(struct userdata *u) { snd_pcm_hwsync(u->pcm_handle); if ((unused = snd_pcm_avail_update(u->pcm_handle)) < 0) { - pa_log("snd_pcm_avail_update() failed: %s", snd_strerror(unused)); + pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused)); return -1; } @@ -922,15 +1010,15 @@ static int process_rewind(struct userdata *u) { pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes); - in_frames = (snd_pcm_sframes_t) rewind_nbytes / u->frame_size; + in_frames = (snd_pcm_sframes_t) (rewind_nbytes / u->frame_size); pa_log_debug("before: %lu", (unsigned long) in_frames); - if ((out_frames = snd_pcm_rewind(u->pcm_handle, in_frames)) < 0) { - pa_log("snd_pcm_rewind() failed: %s", snd_strerror(out_frames)); + if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) { + pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames)); return -1; } pa_log_debug("after: %lu", (unsigned long) out_frames); - rewind_nbytes = out_frames * u->frame_size; + rewind_nbytes = (size_t) out_frames * u->frame_size; if (rewind_nbytes <= 0) pa_log_info("Tried rewind, but was apparently not possible."); @@ -974,7 +1062,7 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) { int work_done; - pa_usec_t sleep_usec; + pa_usec_t sleep_usec = 0; if (u->sink->thread_info.rewind_requested) if (process_rewind(u) < 0) @@ -1100,7 +1188,7 @@ int pa__init(pa_module*m) { const char *name; char *name_buf = NULL; pa_bool_t namereg_fail; - pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE; + pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d; pa_usec_t usec; pa_sink_new_data data; @@ -1124,11 +1212,11 @@ int pa__init(pa_module*m) { frame_size = pa_frame_size(&ss); nfrags = m->core->default_n_fragments; - frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss); + frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss); if (frag_size <= 0) - frag_size = frame_size; - tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss); - tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss); + frag_size = (uint32_t) frame_size; + tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss); + tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss); if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || @@ -1157,11 +1245,6 @@ int pa__init(pa_module*m) { use_tsched = FALSE; } - if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) { - pa_log("Failed to parse mixer_reset argument."); - goto fail; - } - u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -1313,7 +1396,7 @@ int pa__init(pa_module*m) { pa_sink_set_rtpoll(u->sink, u->rtpoll); u->frame_size = frame_size; - u->fragment_size = frag_size = period_frames * frame_size; + u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size); u->nfragments = nfrags; u->hwbuf_size = u->fragment_size * nfrags; u->hwbuf_unused_frames = 0; @@ -1322,6 +1405,8 @@ int pa__init(pa_module*m) { u->hw_dB_supported = FALSE; u->hw_dB_min = u->hw_dB_max = 0; u->hw_volume_min = u->hw_volume_max = 0; + u->mixer_seperate_channels = FALSE; + pa_cvolume_mute(&u->hardware_volume, u->sink->sample_spec.channels); if (use_tsched) fix_tsched_watermark(u); @@ -1349,76 +1434,56 @@ int pa__init(pa_module*m) { if (u->mixer_handle) { pa_assert(u->mixer_elem); - if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) - - if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0 && - snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) { - - pa_bool_t suitable = TRUE; + if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { + pa_bool_t suitable = TRUE; + if (snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) { + pa_log_info("Failed to get volume range. Falling back to software volume control."); + suitable = FALSE; + } else { pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max); + pa_assert(u->hw_volume_min < u->hw_volume_max); + } - if (u->hw_volume_min > u->hw_volume_max) { - - pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max); - suitable = FALSE; - - } else if (u->hw_volume_max - u->hw_volume_min < 3) { - - pa_log_info("Device has less than 4 volume levels. Falling back to software volume control."); - suitable = FALSE; - - } else if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) { - - /* u->hw_dB_max = 0; u->hw_dB_min = -3000; Use this to make valgrind shut up */ - - pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0); - - /* Let's see if this thing actually is useful for muting */ - if (u->hw_dB_min > -6000) { - pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100); - - suitable = FALSE; - } else if (u->hw_dB_max < 0) { - - pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100); - suitable = FALSE; + if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0) + pa_log_info("Mixer doesn't support dB information."); + else { +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min)); + VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max)); +#endif - } else if (u->hw_dB_min >= u->hw_dB_max) { + pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0); + pa_assert(u->hw_dB_min < u->hw_dB_max); + u->hw_dB_supported = TRUE; + } - pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100); - suitable = FALSE; + if (suitable && + !u->hw_dB_supported && + u->hw_volume_max - u->hw_volume_min < 3) { - } else { + pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control."); + suitable = FALSE; + } - if (u->hw_dB_max > 0) { - /* dB > 0 means overamplification, and clipping, we don't want that here */ - pa_log_info("Device can do overamplification for %0.2f dB. Limiting to 0 db", ((double) u->hw_dB_max) / 100); - u->hw_dB_max = 0; - } + if (suitable) { + u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0; - u->hw_dB_supported = TRUE; - } - } + u->sink->get_volume = sink_get_volume_cb; + u->sink->set_volume = sink_set_volume_cb; + u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0); + pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); - if (suitable) { - u->sink->get_volume = sink_get_volume_cb; - u->sink->set_volume = sink_set_volume_cb; - u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0); - pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); - - } else if (mixer_reset) { - pa_log_info("Using software volume control. Trying to reset sound card to 0 dB."); - pa_alsa_0dB_playback(u->mixer_elem); - } else - pa_log_info("Using software volume control. Leaving hw mixer controls untouched."); - } + } else + pa_log_info("Using software volume control."); + } if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { u->sink->get_mute = sink_get_mute_cb; u->sink->set_mute = sink_set_mute_cb; u->sink->flags |= PA_SINK_HW_MUTE_CTRL; - } + } else + pa_log_info("Using software mute control."); u->mixer_fdl = pa_alsa_fdlist_new(); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 1cc467d9..54ffde57 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -28,6 +28,10 @@ #include <asoundlib.h> +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include <valgrind/memcheck.h> +#endif + #include <pulse/xmalloc.h> #include <pulse/util.h> #include <pulse/timeval.h> @@ -69,8 +73,7 @@ PA_MODULE_USAGE( "mmap=<enable memory mapping?> " "tsched=<enable system timer based scheduling mode?> " "tsched_buffer_size=<buffer size when using timer based scheduling> " - "tsched_buffer_watermark=<upper fill watermark> " - "mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>"); + "tsched_buffer_watermark=<upper fill watermark>"); static const char* const valid_modargs[] = { "source_name", @@ -86,7 +89,6 @@ static const char* const valid_modargs[] = { "tsched", "tsched_buffer_size", "tsched_buffer_watermark", - "mixer_reset", NULL }; @@ -113,6 +115,9 @@ struct userdata { long hw_volume_max, hw_volume_min; long hw_dB_max, hw_dB_min; pa_bool_t hw_dB_supported; + pa_bool_t mixer_seperate_channels; + + pa_cvolume hardware_volume; size_t frame_size, fragment_size, hwbuf_size, tsched_watermark; unsigned nfragments; @@ -136,7 +141,7 @@ static void fix_tsched_watermark(struct userdata *u) { size_t min_sleep, min_wakeup; pa_assert(u); - max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size; + max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size; min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->source->sample_spec); min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->source->sample_spec); @@ -207,8 +212,8 @@ static int try_recover(struct userdata *u, const char *call, int err) { static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) { size_t left_to_record; - if (n*u->frame_size < u->hwbuf_size) - left_to_record = u->hwbuf_size - (n*u->frame_size); + if ((size_t) n*u->frame_size < u->hwbuf_size) + left_to_record = u->hwbuf_size - ((size_t) n*u->frame_size); else left_to_record = 0; @@ -234,7 +239,7 @@ static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) { static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { int work_done = 0; - pa_usec_t max_sleep_usec, process_usec; + pa_usec_t max_sleep_usec = 0, process_usec = 0; size_t left_to_record; pa_assert(u); @@ -251,7 +256,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) { - if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0) + if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0) continue; return r; @@ -272,6 +277,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n; pa_memchunk chunk; void *p; + snd_pcm_sframes_t sframes; /* pa_log_debug("%lu frames to read", (unsigned long) frames); */ @@ -304,9 +310,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { pa_source_post(u->source, &chunk); pa_memblock_unref_fixed(chunk.memblock); - if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) { + if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) { - if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0) + if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0) continue; return r; @@ -314,14 +320,14 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { work_done = 1; - u->frame_index += frames; + u->frame_index += (int64_t) frames; /* pa_log_debug("read %lu frames", (unsigned long) frames); */ if (frames >= (snd_pcm_uframes_t) n) break; - n -= frames; + n -= (snd_pcm_sframes_t) frames; } } @@ -331,7 +337,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) { static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) { int work_done = 0; - pa_usec_t max_sleep_usec, process_usec; + pa_usec_t max_sleep_usec = 0, process_usec = 0; size_t left_to_record; pa_assert(u); @@ -348,7 +354,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) { if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) { - if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0) + if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0) continue; return r; @@ -370,7 +376,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) { chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); - frames = pa_memblock_get_length(chunk.memblock) / u->frame_size; + frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size); if (frames > n) frames = n; @@ -378,7 +384,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) { /* pa_log_debug("%lu frames to read", (unsigned long) n); */ p = pa_memblock_acquire(chunk.memblock); - frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, frames); + frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames); pa_memblock_release(chunk.memblock); pa_assert(frames != 0); @@ -386,14 +392,14 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) { if (PA_UNLIKELY(frames < 0)) { pa_memblock_unref(chunk.memblock); - if ((r = try_recover(u, "snd_pcm_readi", n)) == 0) + if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0) continue; return r; } chunk.index = 0; - chunk.length = frames * u->frame_size; + chunk.length = (size_t) frames * u->frame_size; pa_source_post(u->source, &chunk); pa_memblock_unref(chunk.memblock); @@ -437,7 +443,7 @@ static void update_smoother(struct userdata *u) { frames = u->frame_index + delay; now1 = pa_rtclock_usec(); - now2 = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec); + now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->source->sample_spec); pa_smoother_put(u->smoother, now1, now2); } @@ -452,7 +458,7 @@ static pa_usec_t source_get_latency(struct userdata *u) { now1 = pa_rtclock_usec(); now2 = pa_smoother_get(u->smoother, now1); - delay = (int64_t) now2 - pa_bytes_to_usec(u->frame_index * u->frame_size, &u->source->sample_spec); + delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->source->sample_spec); if (delay > 0) r = (pa_usec_t) delay; @@ -517,9 +523,9 @@ static int update_sw_params(struct userdata *u) { if (PA_UNLIKELY(b < u->frame_size)) b = u->frame_size; - u->hwbuf_unused_frames = - PA_LIKELY(b < u->hwbuf_size) ? - ((u->hwbuf_size - b) / u->frame_size) : 0; + u->hwbuf_unused_frames = (snd_pcm_sframes_t) + (PA_LIKELY(b < u->hwbuf_size) ? + ((u->hwbuf_size - b) / u->frame_size) : 0); fix_tsched_watermark(u); } @@ -680,8 +686,8 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { return 0; if (mask & SND_CTL_EVENT_MASK_VALUE) { - pa_source_get_volume(u->source); - pa_source_get_mute(u->source); + pa_source_get_volume(u->source, TRUE); + pa_source_get_mute(u->source, TRUE); } return 0; @@ -690,30 +696,68 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { static int source_get_volume_cb(pa_source *s) { struct userdata *u = s->userdata; int err; - int i; + unsigned i; + pa_cvolume r; + char t[PA_CVOLUME_SNPRINT_MAX]; pa_assert(u); pa_assert(u->mixer_elem); - for (i = 0; i < s->sample_spec.channels; i++) { - long alsa_vol; + if (u->mixer_seperate_channels) { - pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i])); + r.channels = s->sample_spec.channels; - if (u->hw_dB_supported) { + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; - if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) { - s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0); - continue; - } + if (u->hw_dB_supported) { + + if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; - u->hw_dB_supported = FALSE; +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); +#endif + + r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0); + } else { + + if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; + + r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min)); + } } - if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + } else { + long alsa_vol; + + pa_assert(u->hw_dB_supported); + + if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0) goto fail; - s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol)); +#endif + + pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0)); + } + + pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); + + if (!pa_cvolume_equal(&u->hardware_volume, &r)) { + + u->hardware_volume = s->volume = r; + + if (u->hw_dB_supported) { + pa_cvolume reset; + + /* Hmm, so the hardware volume changed, let's reset our software volume */ + + pa_cvolume_reset(&reset, s->sample_spec.channels); + pa_source_set_soft_volume(s, &reset); + } } return 0; @@ -727,45 +771,90 @@ fail: static int source_set_volume_cb(pa_source *s) { struct userdata *u = s->userdata; int err; - int i; + unsigned i; + pa_cvolume r; pa_assert(u); pa_assert(u->mixer_elem); - for (i = 0; i < s->sample_spec.channels; i++) { - long alsa_vol; - pa_volume_t vol; + if (u->mixer_seperate_channels) { - pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i])); + r.channels = s->sample_spec.channels; - vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM); + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; + pa_volume_t vol; - if (u->hw_dB_supported) { - alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); - alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); + vol = s->volume.values[i]; + if (u->hw_dB_supported) { - if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) { + alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); - if (snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0) - s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0); + if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0) + goto fail; - continue; - } + if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; + + r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0); + } else { + + alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); + + if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0) + goto fail; + + if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0) + goto fail; - u->hw_dB_supported = FALSE; + r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min)); + } } - alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; - alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max); + } else { + pa_volume_t vol; + long alsa_vol; + + pa_assert(u->hw_dB_supported); + + vol = pa_cvolume_max(&s->volume); - if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0) + alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100); + alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max); + + if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0) goto fail; - if (snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0) - s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); + if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0) + goto fail; + + pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0)); } + u->hardware_volume = r; + + if (u->hw_dB_supported) { + char t[PA_CVOLUME_SNPRINT_MAX]; + + /* Match exactly what the user requested by software */ + + pa_alsa_volume_divide(&r, &s->volume); + pa_source_set_soft_volume(s, &r); + + pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume)); + pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume)); + pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r)); + + } else + + /* We can't match exactly what the user requested, hence let's + * at least tell the user about it */ + + s->volume = r; + return 0; fail: @@ -837,7 +926,7 @@ static void thread_func(void *userdata) { /* Read some data and pass it to the sources */ if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) { int work_done = 0; - pa_usec_t sleep_usec; + pa_usec_t sleep_usec = 0; if (u->use_mmap) work_done = mmap_read(u, &sleep_usec); @@ -932,7 +1021,7 @@ int pa__init(pa_module*m) { const char *name; char *name_buf = NULL; pa_bool_t namereg_fail; - pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE; + pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d; pa_source_new_data data; snd_pcm_info_alloca(&pcm_info); @@ -955,11 +1044,11 @@ int pa__init(pa_module*m) { frame_size = pa_frame_size(&ss); nfrags = m->core->default_n_fragments; - frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss); + frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss); if (frag_size <= 0) - frag_size = frame_size; - tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss); - tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss); + frag_size = (uint32_t) frame_size; + tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss); + tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss); if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || @@ -988,11 +1077,6 @@ int pa__init(pa_module*m) { use_tsched = FALSE; } - if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) { - pa_log("Failed to parse mixer_reset argument."); - goto fail; - } - u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -1137,7 +1221,7 @@ int pa__init(pa_module*m) { pa_source_set_rtpoll(u->source, u->rtpoll); u->frame_size = frame_size; - u->fragment_size = frag_size = period_frames * frame_size; + u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size); u->nfragments = nfrags; u->hwbuf_size = u->fragment_size * nfrags; u->hwbuf_unused_frames = 0; @@ -1146,6 +1230,8 @@ int pa__init(pa_module*m) { u->hw_dB_supported = FALSE; u->hw_dB_min = u->hw_dB_max = 0; u->hw_volume_min = u->hw_volume_max = 0; + u->mixer_seperate_channels = FALSE; + pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels); if (use_tsched) fix_tsched_watermark(u); @@ -1168,67 +1254,56 @@ int pa__init(pa_module*m) { if (u->mixer_handle) { pa_assert(u->mixer_elem); - if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) - if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0 && - snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) { - - pa_bool_t suitable = TRUE; + if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) { + pa_bool_t suitable = TRUE; + if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) { + pa_log_info("Failed to get volume range. Falling back to software volume control."); + suitable = FALSE; + } else { pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max); + pa_assert(u->hw_volume_min < u->hw_volume_max); + } - if (u->hw_volume_min > u->hw_volume_max) { - - pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max); - suitable = FALSE; - - } else if (u->hw_volume_max - u->hw_volume_min < 3) { - - pa_log_info("Device has less than 4 volume levels. Falling back to software volume control."); - suitable = FALSE; - - } else if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) { - - pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0); - - /* Let's see if this thing actually is useful for muting */ - if (u->hw_dB_min > -6000) { - pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100); - - suitable = FALSE; - } else if (u->hw_dB_max < 0) { - - pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100); - suitable = FALSE; - - } else if (u->hw_dB_min >= u->hw_dB_max) { + if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0) + pa_log_info("Mixer doesn't support dB information."); + else { +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min)); + VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max)); +#endif - pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100); - suitable = FALSE; + pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0); + pa_assert(u->hw_dB_min < u->hw_dB_max); + u->hw_dB_supported = TRUE; + } - } else - u->hw_dB_supported = TRUE; - } + if (suitable && + !u->hw_dB_supported && + u->hw_volume_max - u->hw_volume_min < 3) { - if (suitable) { - u->source->get_volume = source_get_volume_cb; - u->source->set_volume = source_set_volume_cb; - u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0); - pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); + pa_log_info("Device has less than 4 volume levels. Falling back to software volume control."); + suitable = FALSE; + } - } else if (mixer_reset) { - pa_log_info("Using software volume control. Trying to reset sound card to 0 dB."); - pa_alsa_0dB_capture(u->mixer_elem); - } else - pa_log_info("Using software volume control. Leaving hw mixer controls untouched."); - } + if (suitable) { + u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0; + u->source->get_volume = source_get_volume_cb; + u->source->set_volume = source_set_volume_cb; + u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0); + pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported"); + } else + pa_log_info("Using software volume control."); + } if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) { u->source->get_mute = source_get_mute_cb; u->source->set_mute = source_set_mute_cb; u->source->flags |= PA_SOURCE_HW_MUTE_CTRL; - } + } else + pa_log_info("Using software mute control."); u->mixer_fdl = pa_alsa_fdlist_new(); diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c index 8b67a36d..9d60c29e 100644 --- a/src/modules/module-always-sink.c +++ b/src/modules/module-always-sink.c @@ -108,7 +108,7 @@ static pa_hook_result_t put_hook_callback(pa_core *c, pa_sink *sink, void* userd pa_log_info("A new sink has been discovered. Unloading null-sink."); - pa_module_unload_request(u->null_module); + pa_module_unload_request(u->null_module, TRUE); u->null_module = NULL; return PA_HOOK_OK; @@ -171,7 +171,7 @@ void pa__done(pa_module*m) { if (u->unlink_slot) pa_hook_slot_free(u->unlink_slot); if (u->null_module) - pa_module_unload_request(u->null_module); + pa_module_unload_request(u->null_module, TRUE); pa_xfree(u->sink_name); pa_xfree(u); diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index df7783fa..439aa8b0 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -53,7 +53,7 @@ static void eof_and_unload_cb(pa_cli*c, void *userdata) { pa_assert(c); pa_assert(m); - pa_module_unload_request(m); + pa_module_unload_request(m, TRUE); } static void eof_and_exit_cb(pa_cli*c, void *userdata) { @@ -62,7 +62,7 @@ static void eof_and_exit_cb(pa_cli*c, void *userdata) { pa_assert(c); pa_assert(m); - m->core->mainloop->quit(m->core->mainloop, 0); + pa_core_exit(m->core, FALSE, 0); } int pa__init(pa_module*m) { diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 0a0b8d20..d61d127a 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -206,9 +206,9 @@ static void adjust_rates(struct userdata *u) { continue; if (o->total_latency < target_latency) - r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/PA_USEC_PER_SEC); + r -= (uint32_t) ((((double) (target_latency - o->total_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC); else if (o->total_latency > target_latency) - r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/PA_USEC_PER_SEC); + r += (uint32_t) ((((double) (o->total_latency - target_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC); if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) { pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", pa_proplist_gets(o->sink_input->proplist, PA_PROP_MEDIA_NAME), base_rate, r); @@ -233,7 +233,7 @@ static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct time adjust_rates(u); pa_gettimeofday(&n); - n.tv_sec += u->adjust_time; + n.tv_sec += (time_t) u->adjust_time; u->sink->core->mainloop->time_restart(e, &n); } @@ -389,7 +389,7 @@ static void request_memblock(struct output *o, size_t length) { /* OK, we need to prepare new data, but only if the sink is actually running */ if (pa_atomic_load(&o->userdata->thread_info.running)) - pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, length, NULL); + pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, (int64_t) length, NULL); } /* Called from I/O thread context */ @@ -489,7 +489,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert(o = i->userdata); - pa_module_unload_request(o->userdata->module); + pa_module_unload_request(o->userdata->module, TRUE); output_free(o); } @@ -1159,7 +1159,7 @@ int pa__init(pa_module*m) { if (u->adjust_time > 0) { struct timeval tv; pa_gettimeofday(&tv); - tv.tv_sec += u->adjust_time; + tv.tv_sec += (time_t) u->adjust_time; u->time_event = m->core->mainloop->time_new(m->core->mainloop, &tv, time_callback, u); } diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c index 7f21efa0..d2cc24f3 100644 --- a/src/modules/module-default-device-restore.c +++ b/src/modules/module-default-device-restore.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <pulse/timeval.h> +#include <pulse/util.h> #include <pulsecore/core-util.h> #include <pulsecore/module.h> @@ -41,8 +42,6 @@ PA_MODULE_DESCRIPTION("Automatically restore the default sink and source"); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(TRUE); -#define DEFAULT_SINK_FILE "default-sink" -#define DEFAULT_SOURCE_FILE "default-source" #define DEFAULT_SAVE_INTERVAL 5 struct userdata { @@ -161,10 +160,10 @@ int pa__init(pa_module *m) { m->userdata = u = pa_xnew0(struct userdata, 1); u->core = m->core; - if (!(u->sink_filename = pa_state_path(DEFAULT_SINK_FILE))) + if (!(u->sink_filename = pa_state_path("default-sink", TRUE))) goto fail; - if (!(u->source_filename = pa_state_path(DEFAULT_SOURCE_FILE))) + if (!(u->source_filename = pa_state_path("default-source", TRUE))) goto fail; load(u); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 13bcfcd1..1616d47c 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -236,16 +236,16 @@ int pa__init(pa_module*m) { goto fail; } -#if HAVE_ALSA +#ifdef HAVE_ALSA if ((n = detect_alsa(m->core, just_one)) <= 0) #endif #if HAVE_OSS if ((n = detect_oss(m->core, just_one)) <= 0) #endif -#if HAVE_SOLARIS +#ifdef HAVE_SOLARIS if ((n = detect_solaris(m->core, just_one)) <= 0) #endif -#if OS_IS_WIN32 +#ifdef OS_IS_WIN32 if ((n = detect_waveout(m->core, just_one)) <= 0) #endif { @@ -256,7 +256,7 @@ int pa__init(pa_module*m) { pa_log_info("loaded %i modules.", n); /* We were successful and can unload ourselves now. */ - pa_module_unload_request(m); + pa_module_unload_request(m, TRUE); pa_modargs_free(ma); diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c index c0d2ddb7..920b4517 100644 --- a/src/modules/module-device-restore.c +++ b/src/modules/module-device-restore.c @@ -1,7 +1,7 @@ /*** This file is part of PulseAudio. - Copyright 2006 Lennart Poettering + Copyright 2006-2008 Lennart Poettering PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -64,6 +64,7 @@ static const char* const valid_modargs[] = { struct userdata { pa_core *core; + pa_module *module; pa_subscription *subscription; pa_hook_slot *sink_fixate_hook_slot, @@ -76,6 +77,7 @@ struct userdata { }; struct entry { + pa_channel_map channel_map; pa_cvolume volume; pa_bool_t muted:1; }; @@ -104,7 +106,7 @@ static struct entry* read_entry(struct userdata *u, char *name) { pa_assert(name); key.dptr = name; - key.dsize = strlen(name); + key.dsize = (int) strlen(name); data = gdbm_fetch(u->gdbm_file, key); @@ -123,6 +125,16 @@ static struct entry* read_entry(struct userdata *u, char *name) { goto fail; } + if (!(pa_channel_map_valid(&e->channel_map))) { + pa_log_warn("Invalid channel map stored in database for device %s", name); + goto fail; + } + + if (e->volume.channels != e->channel_map.channels) { + pa_log_warn("Volume and channel map don't match in database entry for device %s", name); + goto fail; + } + return e; fail: @@ -131,6 +143,17 @@ fail: return NULL; } +static void trigger_save(struct userdata *u) { + struct timeval tv; + + if (u->save_time_event) + return; + + pa_gettimeofday(&tv); + tv.tv_sec += SAVE_INTERVAL; + u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u); +} + static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; struct entry entry, *old; @@ -146,6 +169,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE)) return; + memset(&entry, 0, sizeof(entry)); + if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) { pa_sink *sink; @@ -153,8 +178,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 return; name = pa_sprintf_malloc("sink:%s", sink->name); - entry.volume = *pa_sink_get_volume(sink); - entry.muted = pa_sink_get_mute(sink); + entry.channel_map = sink->channel_map; + entry.volume = *pa_sink_get_volume(sink, FALSE); + entry.muted = pa_sink_get_mute(sink, FALSE); } else { pa_source *source; @@ -165,13 +191,14 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 return; name = pa_sprintf_malloc("source:%s", source->name); - entry.volume = *pa_source_get_volume(source); - entry.muted = pa_source_get_mute(source); + entry.channel_map = source->channel_map; + entry.volume = *pa_source_get_volume(source, FALSE); + entry.muted = pa_source_get_mute(source, FALSE); } if ((old = read_entry(u, name))) { - if (pa_cvolume_equal(&old->volume, &entry.volume) && + if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) && !old->muted == !entry.muted) { pa_xfree(old); @@ -183,7 +210,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 } key.dptr = name; - key.dsize = strlen(name); + key.dsize = (int) strlen(name); data.dptr = (void*) &entry; data.dsize = sizeof(entry); @@ -192,14 +219,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 gdbm_store(u->gdbm_file, key, data, GDBM_REPLACE); - if (!u->save_time_event) { - struct timeval tv; - pa_gettimeofday(&tv); - tv.tv_sec += SAVE_INTERVAL; - u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u); - } - pa_xfree(name); + + trigger_save(u); } static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) { @@ -212,11 +234,9 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data * if ((e = read_entry(u, name))) { - if (u->restore_volume && - e->volume.channels == new_data->sample_spec.channels) { - + if (u->restore_volume) { pa_log_info("Restoring volume for sink %s.", new_data->name); - pa_sink_new_data_set_volume(new_data, &e->volume); + pa_sink_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map)); } if (u->restore_muted) { @@ -242,11 +262,9 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da if ((e = read_entry(u, name))) { - if (u->restore_volume && - e->volume.channels == new_data->sample_spec.channels) { - + if (u->restore_volume) { pa_log_info("Restoring volume for source %s.", new_data->name); - pa_source_new_data_set_volume(new_data, &e->volume); + pa_source_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map)); } if (u->restore_muted) { @@ -266,7 +284,6 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; char *fname, *fn; - char hn[256]; pa_sink *sink; pa_source *source; uint32_t idx; @@ -290,9 +307,11 @@ int pa__init(pa_module*m) { m->userdata = u = pa_xnew(struct userdata, 1); u->core = m->core; + u->module = m; u->save_time_event = NULL; u->restore_volume = restore_volume; u->restore_muted = restore_muted; + u->gdbm_file = NULL; u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u); @@ -301,11 +320,12 @@ int pa__init(pa_module*m) { u->source_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_fixate_hook_callback, u); } - if (!pa_get_host_name(hn, sizeof(hn))) - goto fail; + /* We include the host identifier in the file name because gdbm + * files are CPU dependant, and we don't want things to go wrong + * if we are on a multiarch system. */ - fn = pa_sprintf_malloc("device-volumes.%s."CANONICAL_HOST".gdbm", hn); - fname = pa_state_path(fn); + fn = pa_sprintf_malloc("device-volumes."CANONICAL_HOST".gdbm"); + fname = pa_state_path(fn, TRUE); pa_xfree(fn); if (!fname) diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 8eb4985b..578ad3b5 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -66,7 +66,7 @@ int pa__init(pa_module*m) { pa_assert_se(pa_close(fd) == 0); - pa_module_unload_request(m); + pa_module_unload_request(m, TRUE); ret = 0; diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c index 67f0a231..882dba8c 100644 --- a/src/modules/module-esound-compat-spawnpid.c +++ b/src/modules/module-esound-compat-spawnpid.c @@ -62,10 +62,10 @@ int pa__init(pa_module*m) { goto finish; } - if (kill(pid, SIGUSR1) < 0) + if (kill((pid_t) pid, SIGUSR1) < 0) pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno)); - pa_module_unload_request(m); + pa_module_unload_request(m, TRUE); ret = 0; diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index 6ca64978..14f1810a 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -165,7 +165,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse pa_usec_t w, r; r = pa_smoother_get(u->smoother, pa_rtclock_usec()); - w = pa_bytes_to_usec(u->offset + u->memchunk.length, &u->sink->sample_spec); + w = pa_bytes_to_usec((uint64_t) u->offset + u->memchunk.length, &u->sink->sample_spec); *((pa_usec_t*) data) = w > r ? w - r : 0; break; @@ -250,8 +250,8 @@ static void thread_func(void *userdata) { } else { u->offset += l; - u->memchunk.index += l; - u->memchunk.length -= l; + u->memchunk.index += (size_t) l; + u->memchunk.length -= (size_t) l; if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); @@ -285,7 +285,7 @@ static void thread_func(void *userdata) { } #endif - usec = pa_bytes_to_usec(n, &u->sink->sample_spec); + usec = pa_bytes_to_usec((uint64_t) n, &u->sink->sample_spec); if (usec > u->latency) usec -= u->latency; @@ -296,7 +296,7 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - pollfd->events = PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0; + pollfd->events = (short) (PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0); } if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) @@ -342,7 +342,7 @@ static int do_write(struct userdata *u) { return -1; } - u->write_index += r; + u->write_index += (size_t) r; pa_assert(u->write_index <= u->write_length); if (u->write_index == u->write_length) { @@ -458,7 +458,7 @@ static int do_read(struct userdata *u) { return -1; } - u->read_index += r; + u->read_index += (size_t) r; pa_assert(u->read_index <= u->read_length); if (u->read_index == u->read_length) @@ -468,7 +468,7 @@ static int do_read(struct userdata *u) { return 0; } -static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { +static void io_callback(pa_iochannel *io, void*userdata) { struct userdata *u = userdata; pa_assert(u); @@ -479,11 +479,11 @@ static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { u->io = NULL; } - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } -static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, void *userdata) { +static void on_connection(pa_socket_client *c, pa_iochannel*io, void *userdata) { struct userdata *u = userdata; pa_socket_client_unref(u->client); @@ -491,7 +491,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, vo if (!io) { pa_log("Connection failed: %s", pa_cstrerror(errno)); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } @@ -545,7 +545,7 @@ int pa__init(pa_module*m) { u->format = (ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) | (ss.channels == 2 ? ESD_STEREO : ESD_MONO); - u->rate = ss.rate; + u->rate = (int32_t) ss.rate; u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss); u->read_data = u->write_data = NULL; diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index bfabd91a..c76a366c 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -108,7 +108,7 @@ static void hal_device_free(struct device* d) { pa_xfree(d); } -static void hal_device_free_cb(void *d, PA_GCC_UNUSED void *data) { +static void hal_device_free_cb(void *d, void *data) { hal_device_free(d); } @@ -405,7 +405,7 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s dbus_error_init(&error); if (!pa_hashmap_get(td->u->devices, td->udi)) { - int b; + dbus_bool_t b; struct device *d; b = libhal_device_exists(td->u->context, td->udi, &error); @@ -433,7 +433,7 @@ static void device_added_cb(LibHalContext *context, const char *udi) { struct timeval tv; struct timerdata *t; struct userdata *u; - int good = 0; + pa_bool_t good = FALSE; pa_assert_se(u = libhal_ctx_get_user_data(context)); @@ -511,7 +511,7 @@ static void device_removed_cb(LibHalContext* context, const char *udi) { pa_log_debug("Device removed: %s", udi); if ((d = pa_hashmap_remove(u->devices, udi))) { - pa_module_unload_by_index(u->core, d->index); + pa_module_unload_by_index(u->core, d->index, TRUE); hal_device_free(d); } } @@ -749,17 +749,17 @@ int pa__init(pa_module*m) { } if ((api = pa_modargs_get_value(ma, "api", NULL))) { - int good = 0; + pa_bool_t good = FALSE; #ifdef HAVE_ALSA if (strcmp(api, CAPABILITY_ALSA) == 0) { - good = 1; + good = TRUE; api = CAPABILITY_ALSA; } #endif #ifdef HAVE_OSS if (strcmp(api, CAPABILITY_OSS) == 0) { - good = 1; + good = TRUE; api = CAPABILITY_OSS; } #endif diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index edc543a8..555cb825 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -130,12 +130,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse void *p; pa_assert(offset > 0); - nbytes = offset * pa_frame_size(&u->sink->sample_spec); + nbytes = (size_t) offset * pa_frame_size(&u->sink->sample_spec); pa_sink_render_full(u->sink, nbytes, &chunk); p = (uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index; - pa_deinterleave(p, u->buffer, u->channels, sizeof(float), offset); + pa_deinterleave(p, u->buffer, u->channels, sizeof(float), (unsigned) offset); pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); @@ -149,10 +149,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse ss.channels = 1; for (c = 0; c < u->channels; c++) - pa_silence_memory(u->buffer[c], offset * pa_sample_size(&ss), &ss); + pa_silence_memory(u->buffer[c], (size_t) offset * pa_sample_size(&ss), &ss); } - u->frames_in_buffer = offset; + u->frames_in_buffer = (jack_nframes_t) offset; u->saved_frame_time = * (jack_nframes_t*) data; u->saved_frame_time_valid = TRUE; @@ -342,7 +342,7 @@ int pa__init(pa_module*m) { pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client)); - ss.channels = u->channels = channels; + u->channels = ss.channels = (uint8_t) channels; ss.rate = jack_get_sample_rate(u->client); ss.format = PA_SAMPLE_FLOAT32NE; diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index 03f9d15c..9eccbbfa 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -116,7 +116,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off if (u->source->thread_info.state == PA_SOURCE_RUNNING) pa_source_post(u->source, chunk); - u->saved_frame_time = offset; + u->saved_frame_time = (jack_nframes_t) offset; u->saved_frame_time_valid = TRUE; return 0; @@ -309,7 +309,7 @@ int pa__init(pa_module*m) { pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client)); - ss.channels = u->channels = channels; + u->channels = ss.channels = (uint8_t) channels; ss.rate = jack_get_sample_rate(u->client); ss.format = PA_SAMPLE_FLOAT32NE; diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index eae80086..9127af01 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -187,7 +187,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk pa_assert(tchunk.length > 0); fs = pa_frame_size(&i->sample_spec); - n = PA_MIN(tchunk.length, u->block_size) / fs; + n = (unsigned) (PA_MIN(tchunk.length, u->block_size) / fs); pa_assert(n > 0); @@ -340,7 +340,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_input_unref(u->sink_input); u->sink_input = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from IO thread context */ @@ -502,9 +502,9 @@ int pa__init(pa_module*m) { u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss); - u->input = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size); + u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) - u->output = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size); + u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size); else u->output = u->input; @@ -530,8 +530,8 @@ int pa__init(pa_module*m) { char *k; unsigned long h; - u->control = pa_xnew(LADSPA_Data, n_control); - use_default = pa_xnew(pa_bool_t, n_control); + u->control = pa_xnew(LADSPA_Data, (unsigned) n_control); + use_default = pa_xnew(pa_bool_t, (unsigned) n_control); p = 0; while ((k = pa_split(cdata, ",", &state)) && p < n_control) { @@ -552,7 +552,7 @@ int pa__init(pa_module*m) { pa_xfree(k); use_default[p] = FALSE; - u->control[p++] = f; + u->control[p++] = (LADSPA_Data) f; } /* The previous loop doesn't take the last control value into account @@ -601,8 +601,8 @@ int pa__init(pa_module*m) { upper = d->PortRangeHints[p].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) { - lower *= ss.rate; - upper *= ss.rate; + lower *= (LADSPA_Data) ss.rate; + upper *= (LADSPA_Data) ss.rate; } switch (hint & LADSPA_HINT_DEFAULT_MASK) { @@ -617,23 +617,23 @@ int pa__init(pa_module*m) { case LADSPA_HINT_DEFAULT_LOW: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - u->control[h] = exp(log(lower) * 0.75 + log(upper) * 0.25); + u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25); else - u->control[h] = lower * 0.75 + upper * 0.25; + u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25); break; case LADSPA_HINT_DEFAULT_MIDDLE: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - u->control[h] = exp(log(lower) * 0.5 + log(upper) * 0.5); + u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5); else - u->control[h] = lower * 0.5 + upper * 0.5; + u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5); break; case LADSPA_HINT_DEFAULT_HIGH: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - u->control[h] = exp(log(lower) * 0.25 + log(upper) * 0.75); + u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75); else - u->control[h] = lower * 0.25 + upper * 0.75; + u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75); break; case LADSPA_HINT_DEFAULT_0: diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index 0570a6a1..97e97dc7 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -65,7 +65,7 @@ struct userdata { static int lirc_in_use = 0; -static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) { +static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; char *name = NULL, *code = NULL; @@ -122,7 +122,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_log("Failed to get sink '%s'", u->sink_name); else { int i; - pa_cvolume cv = *pa_sink_get_volume(s); + pa_cvolume cv = *pa_sink_get_volume(s, FALSE); #define DELTA (PA_VOLUME_NORM/20) @@ -159,7 +159,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC case MUTE_TOGGLE: - pa_sink_set_mute(s, !pa_sink_get_mute(s)); + pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE)); break; case INVALID: @@ -178,7 +178,7 @@ fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); pa_xfree(code); } diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 4388e49c..21f176a4 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -76,7 +76,7 @@ struct userdata { pa_module *module; }; -static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) { +static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; pa_assert(io); @@ -113,7 +113,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_log("Failed to get sink '%s'", u->sink_name); else { int i; - pa_cvolume cv = *pa_sink_get_volume(s); + pa_cvolume cv = *pa_sink_get_volume(s, FALSE); #define DELTA (PA_VOLUME_NORM/20) @@ -142,7 +142,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC case MUTE_TOGGLE: - pa_sink_set_mute(s, !pa_sink_get_mute(s)); + pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE)); break; case INVALID: @@ -159,7 +159,7 @@ fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } #define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c index fa9c0e4f..f17f435a 100644 --- a/src/modules/module-native-protocol-fd.c +++ b/src/modules/module-native-protocol-fd.c @@ -48,7 +48,8 @@ static const char* const valid_modargs[] = { int pa__init(pa_module*m) { pa_iochannel *io; pa_modargs *ma; - int fd, r = -1; + int32_t fd; + int r = -1; pa_native_options *options = NULL; pa_assert(m); @@ -63,18 +64,16 @@ int pa__init(pa_module*m) { goto finish; } - options = pa_native_options_new(); - options->module = m; - options->auth_anonymous = TRUE; + m->userdata = pa_native_protocol_get(m->core); io = pa_iochannel_new(m->core->mainloop, fd, fd); - m->userdata = pa_native_protocol_get(m->core); + options = pa_native_options_new(); + options->module = m; + options->auth_anonymous = TRUE; pa_native_protocol_connect(m->userdata, io, options); - pa_native_options_unref(options); - r = 0; finish: diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 15b1e956..23a32549 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -258,7 +258,7 @@ static int mmap_write(struct userdata *u) { u->out_mmap_saved_nfrags = 0; if (info.blocks > 0) - mmap_fill_memblocks(u, info.blocks); + mmap_fill_memblocks(u, (unsigned) info.blocks); return info.blocks; } @@ -336,7 +336,7 @@ static int mmap_read(struct userdata *u) { u->in_mmap_saved_nfrags = 0; if (info.blocks > 0) { - mmap_post_memblocks(u, info.blocks); + mmap_post_memblocks(u, (unsigned) info.blocks); mmap_clear_memblocks(u, u->in_nfrags/2); } @@ -356,12 +356,12 @@ static pa_usec_t mmap_sink_get_latency(struct userdata *u) { u->out_mmap_saved_nfrags += info.blocks; - bpos = ((u->out_mmap_current + u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size; + bpos = ((u->out_mmap_current + (unsigned) u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size; if (bpos <= (size_t) info.ptr) - n = u->out_hwbuf_size - (info.ptr - bpos); + n = u->out_hwbuf_size - ((size_t) info.ptr - bpos); else - n = bpos - info.ptr; + n = bpos - (size_t) info.ptr; /* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->out_fragment_size, u->out_fragments); */ @@ -380,12 +380,12 @@ static pa_usec_t mmap_source_get_latency(struct userdata *u) { } u->in_mmap_saved_nfrags += info.blocks; - bpos = ((u->in_mmap_current + u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size; + bpos = ((u->in_mmap_current + (unsigned) u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size; if (bpos <= (size_t) info.ptr) - n = info.ptr - bpos; + n = (size_t) info.ptr - bpos; else - n = u->in_hwbuf_size - bpos + info.ptr; + n = u->in_hwbuf_size - bpos + (size_t) info.ptr; /* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->in_fragment_size, u->in_fragments); */ @@ -404,7 +404,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) { pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); u->use_getodelay = 0; } else - r = pa_bytes_to_usec(arg, &u->sink->sample_spec); + r = pa_bytes_to_usec((size_t) arg, &u->sink->sample_spec); } @@ -415,7 +415,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) { pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); u->use_getospace = 0; } else - r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); + r = pa_bytes_to_usec((size_t) info.bytes, &u->sink->sample_spec); } if (u->memchunk.memblock) @@ -437,7 +437,7 @@ static pa_usec_t io_source_get_latency(struct userdata *u) { pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); u->use_getispace = 0; } else - r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec); + r = pa_bytes_to_usec((size_t) info.bytes, &u->source->sample_spec); } return r; @@ -528,8 +528,9 @@ static int unsuspend(struct userdata *u) { if ((u->fd = pa_oss_open(u->device_name, &m, NULL)) < 0) { pa_log_warn("Resume failed, device busy (%s)", pa_cstrerror(errno)); return -1; + } - if (m != u->mode) + if (m != u->mode) { pa_log_warn("Resume failed, couldn't open device with original access mode."); goto fail; } @@ -859,7 +860,7 @@ static int source_set_volume(pa_source *s) { static void thread_func(void *userdata) { struct userdata *u = userdata; int write_type = 0, read_type = 0; - unsigned short revents = 0; + short revents = 0; pa_assert(u); @@ -898,7 +899,7 @@ static void thread_func(void *userdata) { ssize_t l; pa_bool_t loop = FALSE, work_done = FALSE; - l = u->out_fragment_size; + l = (ssize_t) u->out_fragment_size; if (u->use_getospace) { audio_buf_info info; @@ -919,14 +920,14 @@ static void thread_func(void *userdata) { /* Round down to multiples of the fragment size, * because OSS needs that (at least some versions * do) */ - l = (l/u->out_fragment_size) * u->out_fragment_size; + l = (l/(ssize_t) u->out_fragment_size) * (ssize_t) u->out_fragment_size; /* Hmm, so poll() signalled us that we can read * something, but GETOSPACE told us there was nothing? * Hmm, make the best of it, try to read some data, to * avoid spinning forever. */ if (l <= 0 && (revents & POLLOUT)) { - l = u->out_fragment_size; + l = (ssize_t) u->out_fragment_size; loop = FALSE; } @@ -935,7 +936,7 @@ static void thread_func(void *userdata) { ssize_t t; if (u->memchunk.length <= 0) - pa_sink_render(u->sink, l, &u->memchunk); + pa_sink_render(u->sink, (size_t) l, &u->memchunk); pa_assert(u->memchunk.length > 0); @@ -965,8 +966,8 @@ static void thread_func(void *userdata) { } else { - u->memchunk.index += t; - u->memchunk.length -= t; + u->memchunk.index += (size_t) t; + u->memchunk.length -= (size_t) t; if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); @@ -1009,7 +1010,7 @@ static void thread_func(void *userdata) { pa_memchunk memchunk; pa_bool_t loop = FALSE, work_done = FALSE; - l = u->in_fragment_size; + l = (ssize_t) u->in_fragment_size; if (u->use_getispace) { audio_buf_info info; @@ -1023,15 +1024,16 @@ static void thread_func(void *userdata) { } } - l = (l/u->in_fragment_size) * u->in_fragment_size; + l = (l/(ssize_t) u->in_fragment_size) * (ssize_t) u->in_fragment_size; if (l <= 0 && (revents & POLLIN)) { - l = u->in_fragment_size; + l = (ssize_t) u->in_fragment_size; loop = FALSE; } while (l > 0) { - ssize_t t, k; + ssize_t t; + size_t k; pa_assert(l > 0); @@ -1039,8 +1041,8 @@ static void thread_func(void *userdata) { k = pa_memblock_get_length(memchunk.memblock); - if (k > l) - k = l; + if (k > (size_t) l) + k = (size_t) l; k = (k/u->frame_size)*u->frame_size; @@ -1071,7 +1073,7 @@ static void thread_func(void *userdata) { } else { memchunk.index = 0; - memchunk.length = t; + memchunk.length = (size_t) t; pa_source_post(u->source, &memchunk); pa_memblock_unref(memchunk.memblock); @@ -1099,9 +1101,9 @@ static void thread_func(void *userdata) { pa_assert(u->fd >= 0); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - pollfd->events = - ((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | - ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); + pollfd->events = (short) + (((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | + ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0)); } /* Hmm, nothing to do. Let's sleep */ @@ -1179,10 +1181,10 @@ int pa__init(pa_module*m) { goto fail; } - nfrags = m->core->default_n_fragments; - frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); + nfrags = (int) m->core->default_n_fragments; + frag_size = (int) pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); if (frag_size <= 0) - frag_size = pa_frame_size(&ss); + frag_size = (int) pa_frame_size(&ss); if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { pa_log("Failed to parse fragments arguments"); @@ -1238,8 +1240,8 @@ int pa__init(pa_module*m) { u->mode = mode; u->frame_size = pa_frame_size(&ss); u->device_name = pa_xstrdup(dev); - u->in_nfrags = u->out_nfrags = u->nfrags = nfrags; - u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; + u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags); + u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size); u->use_mmap = use_mmap; u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); @@ -1248,15 +1250,15 @@ int pa__init(pa_module*m) { if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); - u->in_fragment_size = info.fragsize; - u->in_nfrags = info.fragstotal; + u->in_fragment_size = (uint32_t) info.fragsize; + u->in_nfrags = (uint32_t) info.fragstotal; u->use_getispace = TRUE; } if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize); - u->out_fragment_size = info.fragsize; - u->out_nfrags = info.fragstotal; + u->out_fragment_size = (uint32_t) info.fragsize; + u->out_nfrags = (uint32_t) info.fragstotal; u->use_getospace = TRUE; } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index f389cd06..ae230b2c 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -145,8 +145,8 @@ static int process_render(struct userdata *u) { } else { - u->memchunk.index += l; - u->memchunk.length -= l; + u->memchunk.index += (size_t) l; + u->memchunk.length -= (size_t) l; if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); @@ -189,7 +189,7 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; + pollfd->events = (short) (u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0); if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) goto fail; diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index b0de34ca..25151d95 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -135,9 +135,9 @@ static void thread_func(void *userdata) { } else { - u->memchunk.length = l; + u->memchunk.length = (size_t) l; pa_source_post(u->source, &u->memchunk); - u->memchunk.index += l; + u->memchunk.index += (size_t) l; if (u->memchunk.index >= pa_memblock_get_length(u->memchunk.memblock)) { pa_memblock_unref(u->memchunk.memblock); @@ -149,7 +149,7 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; + pollfd->events = (short) (u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0); if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) goto fail; diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 8136c6fc..0e98b1c3 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -260,7 +260,7 @@ int pa__init(pa_module*m) { goto fail; } - u = pa_xnew0(struct userdata, 1); + m->userdata = u = pa_xnew0(struct userdata, 1); u->module = m; #if defined(USE_PROTOCOL_SIMPLE) @@ -299,11 +299,11 @@ int pa__init(pa_module*m) { listen_on = pa_modargs_get_value(ma, "listen", NULL); if (listen_on) { - u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); - u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); + u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE); + u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE); } else { - u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE); - u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE); + u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE); + u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE); } if (!u->socket_server_ipv4 && !u->socket_server_ipv6) @@ -327,7 +327,7 @@ int pa__init(pa_module*m) { /* This socket doesn't reside in our own runtime dir but in * /tmp/.esd/, hence we have to create the dir first */ - if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) { + if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1) < 0) { pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno)); goto fail; } @@ -368,8 +368,6 @@ int pa__init(pa_module*m) { # endif #endif - m->userdata = u; - if (ma) pa_modargs_free(ma); @@ -390,7 +388,8 @@ void pa__done(pa_module*m) { pa_assert(m); - u = m->userdata; + if (!(u = m->userdata)) + return; #if defined(USE_PROTOCOL_SIMPLE) if (u->simple_protocol) { diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index bd86f4d6..5b2be118 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -255,7 +255,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_input_unref(u->sink_input); u->sink_input = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from IO thread context */ diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 38780f24..21565cc4 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -99,7 +99,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_input_unref(u->sink_input); u->sink_input = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from IO thread context */ @@ -116,13 +116,13 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s pa_sink_input_request_rewind(i, 0, FALSE, TRUE); } -static void calc_sine(float *f, size_t l, float freq) { +static void calc_sine(float *f, size_t l, double freq) { size_t i; l /= sizeof(float); for (i = 0; i < l; i++) - f[i] = (float) sin((double) i/l*M_PI*2*freq)/2; + f[i] = (float) sin((double) i/(double)l*M_PI*2*freq)/2; } int pa__init(pa_module*m) { @@ -163,7 +163,7 @@ int pa__init(pa_module*m) { u->memblock = pa_memblock_new(m->core->mempool, pa_bytes_per_second(&ss)); p = pa_memblock_acquire(u->memblock); - calc_sine(p, pa_memblock_get_length(u->memblock), frequency); + calc_sine(p, pa_memblock_get_length(u->memblock), (double) frequency); pa_memblock_release(u->memblock); pa_sink_input_new_data_init(&data); diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 22e2ff62..37e8b067 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -46,6 +46,9 @@ #include <pulsecore/sink-input.h> #include <pulsecore/source-output.h> #include <pulsecore/namereg.h> +#include <pulsecore/protocol-native.h> +#include <pulsecore/pstream.h> +#include <pulsecore/pstream-util.h> #include "module-stream-restore-symdef.h" @@ -65,25 +68,41 @@ static const char* const valid_modargs[] = { struct userdata { pa_core *core; + pa_module *module; pa_subscription *subscription; pa_hook_slot *sink_input_new_hook_slot, *sink_input_fixate_hook_slot, - *source_output_new_hook_slot; + *source_output_new_hook_slot, + *connection_unlink_hook_slot; pa_time_event *save_time_event; GDBM_FILE gdbm_file; pa_bool_t restore_device:1; pa_bool_t restore_volume:1; pa_bool_t restore_muted:1; + + pa_native_protocol *protocol; + pa_idxset *subscribed; }; struct entry { - pa_cvolume volume; char device[PA_NAME_MAX]; + pa_channel_map channel_map; + pa_cvolume volume; pa_bool_t muted:1; }; + +enum { + SUBCOMMAND_TEST, + SUBCOMMAND_READ, + SUBCOMMAND_WRITE, + SUBCOMMAND_DELETE, + SUBCOMMAND_SUBSCRIBE, + SUBCOMMAND_EVENT +}; + static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { struct userdata *u = userdata; @@ -126,7 +145,7 @@ static struct entry* read_entry(struct userdata *u, char *name) { pa_assert(name); key.dptr = name; - key.dsize = strlen(name); + key.dsize = (int) strlen(name); data = gdbm_fetch(u->gdbm_file, key); @@ -146,7 +165,17 @@ static struct entry* read_entry(struct userdata *u, char *name) { } if (!(pa_cvolume_valid(&e->volume))) { - pa_log_warn("Invalid volume stored in database for device %s", name); + pa_log_warn("Invalid volume stored in database for stream %s", name); + goto fail; + } + + if (!(pa_channel_map_valid(&e->channel_map))) { + pa_log_warn("Invalid channel map stored in database for stream %s", name); + goto fail; + } + + if (e->volume.channels != e->channel_map.channels) { + pa_log_warn("Volume and channel map don't match in database entry for stream %s", name); goto fail; } @@ -158,6 +187,32 @@ fail: return NULL; } +static void trigger_save(struct userdata *u) { + struct timeval tv; + pa_native_connection *c; + uint32_t idx; + + for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) { + pa_tagstruct *t; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION); + pa_tagstruct_putu32(t, 0); + pa_tagstruct_putu32(t, u->module->index); + pa_tagstruct_puts(t, u->module->name); + pa_tagstruct_putu32(t, SUBCOMMAND_EVENT); + + pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t); + } + + if (u->save_time_event) + return; + + pa_gettimeofday(&tv); + tv.tv_sec += SAVE_INTERVAL; + u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u); +} + static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; struct entry entry, *old; @@ -173,6 +228,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE)) return; + memset(&entry, 0, sizeof(entry)); + if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) { pa_sink_input *sink_input; @@ -182,6 +239,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 if (!(name = get_name(sink_input->proplist, "sink-input"))) return; + entry.channel_map = sink_input->channel_map; entry.volume = *pa_sink_input_get_volume(sink_input); entry.muted = pa_sink_input_get_mute(sink_input); pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device)); @@ -197,15 +255,16 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 if (!(name = get_name(source_output->proplist, "source-output"))) return; - memset(&entry.volume, 0, sizeof(entry.volume)); - entry.muted = FALSE; - + /* The following fields are filled in to make the entry valid + * according to read_entry(). They are otherwise useless */ + entry.channel_map = source_output->channel_map; + pa_cvolume_reset(&entry.volume, entry.channel_map.channels); pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device)); } if ((old = read_entry(u, name))) { - if (pa_cvolume_equal(&old->volume, &entry.volume) && + if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) && !old->muted == !entry.muted && strcmp(old->device, entry.device) == 0) { @@ -218,7 +277,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 } key.dptr = name; - key.dsize = strlen(name); + key.dsize = (int) strlen(name); data.dptr = (void*) &entry; data.dsize = sizeof(entry); @@ -227,14 +286,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 gdbm_store(u->gdbm_file, key, data, GDBM_REPLACE); - if (!u->save_time_event) { - struct timeval tv; - pa_gettimeofday(&tv); - tv.tv_sec += SAVE_INTERVAL; - u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u); - } - pa_xfree(name); + + trigger_save(u); } static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) { @@ -250,11 +304,13 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n pa_sink *s; if (u->restore_device && - e->device[0] && (s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK, TRUE))) { - pa_log_info("Restoring device for stream %s.", name); - new_data->sink = s; + if (!new_data->sink) { + pa_log_info("Restoring device for stream %s.", name); + new_data->sink = s; + } else + pa_log_info("Not restore device for stream %s, because already set.", name); } pa_xfree(e); @@ -276,16 +332,21 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu if ((e = read_entry(u, name))) { - if (u->restore_volume && - e->volume.channels == new_data->sample_spec.channels) { + if (u->restore_volume) { - pa_log_info("Restoring volume for sink input %s.", name); - pa_sink_input_new_data_set_volume(new_data, &e->volume); + if (!new_data->volume_is_set) { + pa_log_info("Restoring volume for sink input %s.", name); + pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map)); + } else + pa_log_debug("Not restoring volume for sink input %s, because already set.", name); } if (u->restore_muted) { - pa_log_info("Restoring mute state for sink input %s.", name); - pa_sink_input_new_data_set_muted(new_data, e->muted); + if (!new_data->muted_is_set) { + pa_log_info("Restoring mute state for sink input %s.", name); + pa_sink_input_new_data_set_muted(new_data, e->muted); + } else + pa_log_debug("Not restoring mute state for sink input %s, because already set.", name); } pa_xfree(e); @@ -309,11 +370,14 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou pa_source *s; if (u->restore_device && - e->device[0] && + !new_data->direct_on_input && (s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE, TRUE))) { - pa_log_info("Restoring device for stream %s.", name); - new_data->source = s; + if (!new_data->source) { + pa_log_info("Restoring device for stream %s.", name); + new_data->source = s; + } else + pa_log_info("Not restroing device for stream %s, because already set", name); } pa_xfree(e); @@ -324,11 +388,300 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou return PA_HOOK_OK; } +#define EXT_VERSION 1 + +static void clear_db(struct userdata *u) { + datum key; + + pa_assert(u); + + key = gdbm_firstkey(u->gdbm_file); + while (key.dptr) { + datum next_key; + next_key = gdbm_nextkey(u->gdbm_file, key); + + gdbm_delete(u->gdbm_file, key); + pa_xfree(key.dptr); + + key = next_key; + } + + gdbm_reorganize(u->gdbm_file); +} + +static void apply_entry(struct userdata *u, const char *name, struct entry *e) { + pa_sink_input *si; + pa_source_output *so; + uint32_t idx; + + pa_assert(u); + pa_assert(name); + pa_assert(e); + + for (si = pa_idxset_first(u->core->sink_inputs, &idx); si; si = pa_idxset_next(u->core->sink_inputs, &idx)) { + char *n; + pa_sink *s; + + if (!(n = get_name(si->proplist, "sink-input"))) + continue; + + if (strcmp(name, n)) { + pa_xfree(n); + continue; + } + + if (u->restore_volume) { + pa_cvolume v = e->volume; + pa_log_info("Restoring volume for sink input %s.", name); + pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map)); + } + + if (u->restore_muted) { + pa_log_info("Restoring mute state for sink input %s.", name); + pa_sink_input_set_mute(si, e->muted); + } + + if (u->restore_device && + (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) { + + pa_log_info("Restoring device for stream %s.", name); + pa_sink_input_move_to(si, s); + } + } + + for (so = pa_idxset_first(u->core->source_outputs, &idx); so; so = pa_idxset_next(u->core->source_outputs, &idx)) { + char *n; + pa_source *s; + + if (!(n = get_name(so->proplist, "source-output"))) + continue; + + if (strcmp(name, n)) { + pa_xfree(n); + continue; + } + + if (u->restore_device && + (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) { + + pa_log_info("Restoring device for stream %s.", name); + pa_source_output_move_to(so, s); + } + } +} + +#if 0 +static void dump_database(struct userdata *u) { + datum key; + + key = gdbm_firstkey(u->gdbm_file); + while (key.dptr) { + datum next_key; + struct entry *e; + char *name; + + next_key = gdbm_nextkey(u->gdbm_file, key); + + name = pa_xstrndup(key.dptr, key.dsize); + pa_xfree(key.dptr); + + if ((e = read_entry(u, name))) { + char t[256]; + pa_log("name=%s", name); + pa_log("device=%s", e->device); + pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map)); + pa_log("volume=%s", pa_cvolume_snprint(t, sizeof(t), &e->volume)); + pa_log("mute=%s", pa_yes_no(e->muted)); + pa_xfree(e); + } + + pa_xfree(name); + + key = next_key; + } +} +#endif + +static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) { + struct userdata *u; + uint32_t command; + pa_tagstruct *reply = NULL; + + pa_assert(p); + pa_assert(m); + pa_assert(c); + pa_assert(t); + + u = m->userdata; + + if (pa_tagstruct_getu32(t, &command) < 0) + goto fail; + + reply = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); + pa_tagstruct_putu32(reply, tag); + + switch (command) { + case SUBCOMMAND_TEST: { + if (!pa_tagstruct_eof(t)) + goto fail; + + pa_tagstruct_putu32(reply, EXT_VERSION); + break; + } + + case SUBCOMMAND_READ: { + datum key; + + if (!pa_tagstruct_eof(t)) + goto fail; + + key = gdbm_firstkey(u->gdbm_file); + while (key.dptr) { + datum next_key; + struct entry *e; + char *name; + + next_key = gdbm_nextkey(u->gdbm_file, key); + + name = pa_xstrndup(key.dptr, (size_t) key.dsize); + pa_xfree(key.dptr); + + if ((e = read_entry(u, name))) { + pa_tagstruct_puts(reply, name); + pa_tagstruct_put_channel_map(reply, &e->channel_map); + pa_tagstruct_put_cvolume(reply, &e->volume); + pa_tagstruct_puts(reply, e->device); + pa_tagstruct_put_boolean(reply, e->muted); + + pa_xfree(e); + } + + pa_xfree(name); + + key = next_key; + } + + break; + } + + case SUBCOMMAND_WRITE: { + uint32_t mode; + pa_bool_t apply_immediately = FALSE; + + if (pa_tagstruct_getu32(t, &mode) < 0 || + pa_tagstruct_get_boolean(t, &apply_immediately) < 0) + goto fail; + + if (mode != PA_UPDATE_MERGE && + mode != PA_UPDATE_REPLACE && + mode != PA_UPDATE_SET) + goto fail; + + if (mode == PA_UPDATE_SET) + clear_db(u); + + while (!pa_tagstruct_eof(t)) { + const char *name, *device; + pa_bool_t muted; + struct entry entry; + datum key, data; + int k; + + memset(&entry, 0, sizeof(entry)); + + if (pa_tagstruct_gets(t, &name) < 0 || + pa_tagstruct_get_channel_map(t, &entry.channel_map) || + pa_tagstruct_get_cvolume(t, &entry.volume) < 0 || + pa_tagstruct_gets(t, &device) < 0 || + pa_tagstruct_get_boolean(t, &muted) < 0) + goto fail; + + if (entry.channel_map.channels != entry.volume.channels) + goto fail; + + entry.muted = muted; + pa_strlcpy(entry.device, device, sizeof(entry.device)); + + key.dptr = (void*) name; + key.dsize = (int) strlen(name); + + data.dptr = (void*) &entry; + data.dsize = sizeof(entry); + + if ((k = gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT)) == 0) + if (apply_immediately) + apply_entry(u, name, &entry); + } + + trigger_save(u); + + break; + } + + case SUBCOMMAND_DELETE: + + while (!pa_tagstruct_eof(t)) { + const char *name; + datum key; + + if (pa_tagstruct_gets(t, &name) < 0) + goto fail; + + key.dptr = (void*) name; + key.dsize = (int) strlen(name); + + gdbm_delete(u->gdbm_file, key); + } + + trigger_save(u); + + break; + + case SUBCOMMAND_SUBSCRIBE: { + + pa_bool_t enabled; + + if (pa_tagstruct_get_boolean(t, &enabled) < 0 || + !pa_tagstruct_eof(t)) + goto fail; + + if (enabled) + pa_idxset_put(u->subscribed, c, NULL); + else + pa_idxset_remove_by_data(u->subscribed, c, NULL); + + break; + } + + default: + goto fail; + } + + pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply); + return 0; + +fail: + + if (reply) + pa_tagstruct_free(reply); + + return -1; +} + +static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) { + pa_assert(p); + pa_assert(c); + pa_assert(u); + + pa_idxset_remove_by_data(u->subscribed, c, NULL); + return PA_HOOK_OK; +} + int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; char *fname, *fn; - char hn[256]; pa_sink_input *si; pa_source_output *so; uint32_t idx; @@ -353,10 +706,18 @@ int pa__init(pa_module*m) { m->userdata = u = pa_xnew(struct userdata, 1); u->core = m->core; + u->module = m; u->save_time_event = NULL; u->restore_device = restore_device; u->restore_volume = restore_volume; u->restore_muted = restore_muted; + u->gdbm_file = NULL; + u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + u->protocol = pa_native_protocol_get(m->core); + pa_native_protocol_install_ext(u->protocol, m, extension_cb); + + u->connection_unlink_hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_CONNECTION_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) connection_unlink_hook_cb, u); u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u); @@ -368,11 +729,12 @@ int pa__init(pa_module*m) { if (restore_volume || restore_muted) u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u); - if (!pa_get_host_name(hn, sizeof(hn))) - goto fail; + /* We include the host identifier in the file name because gdbm + * files are CPU dependant, and we don't want things to go wrong + * if we are on a multiarch system. */ - fn = pa_sprintf_malloc("stream-volumes.%s."CANONICAL_HOST".gdbm", hn); - fname = pa_state_path(fn); + fn = pa_sprintf_malloc("stream-volumes."CANONICAL_HOST".gdbm"); + fname = pa_state_path(fn, TRUE); pa_xfree(fn); if (!fname) @@ -423,11 +785,22 @@ void pa__done(pa_module*m) { if (u->source_output_new_hook_slot) pa_hook_slot_free(u->source_output_new_hook_slot); + if (u->connection_unlink_hook_slot) + pa_hook_slot_free(u->connection_unlink_hook_slot); + if (u->save_time_event) u->core->mainloop->time_free(u->save_time_event); if (u->gdbm_file) gdbm_close(u->gdbm_file); + if (u->protocol) { + pa_native_protocol_remove_ext(u->protocol, m); + pa_native_protocol_unref(u->protocol); + } + + if (u->subscribed) + pa_idxset_free(u->subscribed, NULL, NULL); + pa_xfree(u); } diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index af27ce74..de3c7274 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -178,7 +178,7 @@ struct userdata { #ifdef TUNNEL_SINK char *sink_name; pa_sink *sink; - int32_t requested_bytes; + size_t requested_bytes; #else char *source_name; pa_source *source; @@ -231,7 +231,7 @@ static void command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t pa_assert(u->pdispatch == pd); pa_log_warn("Stream killed"); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from main context */ @@ -262,7 +262,7 @@ static void command_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag pa_tagstruct_get_boolean(t, &suspended) < 0 || !pa_tagstruct_eof(t)) { pa_log("Invalid packet"); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } @@ -389,7 +389,7 @@ static void send_data(struct userdata *u) { u->requested_bytes -= memchunk.length; - u->counter += memchunk.length; + u->counter += (int64_t) memchunk.length; } } @@ -417,7 +417,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_MESSAGE_GET_LATENCY: { pa_usec_t yl, yr, *usec = data; - yl = pa_bytes_to_usec(u->counter, &u->sink->sample_spec); + yl = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec); yr = pa_smoother_get(u->smoother, pa_rtclock_usec()); *usec = yl > yr ? yl - yr : 0; @@ -444,10 +444,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case SINK_MESSAGE_UPDATE_LATENCY: { pa_usec_t y; - y = pa_bytes_to_usec(u->counter, &u->sink->sample_spec); + y = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec); if (y > (pa_usec_t) offset || offset < 0) - y -= offset; + y -= (pa_usec_t) offset; else y = 0; @@ -465,7 +465,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse pa_pstream_send_memblock(u->pstream, u->channel, 0, PA_SEEK_RELATIVE, chunk); - u->counter_delta += chunk->length; + u->counter_delta += (int64_t) chunk->length; return 0; } @@ -520,7 +520,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off case PA_SOURCE_MESSAGE_GET_LATENCY: { pa_usec_t yr, yl, *usec = data; - yl = pa_bytes_to_usec(u->counter, &PA_SINK(o)->sample_spec); + yl = pa_bytes_to_usec((uint64_t) u->counter, &PA_SINK(o)->sample_spec); yr = pa_smoother_get(u->smoother, pa_rtclock_usec()); *usec = yr > yl ? yr - yl : 0; @@ -532,7 +532,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) pa_source_post(u->source, chunk); - u->counter += chunk->length; + u->counter += (int64_t) chunk->length; return 0; @@ -544,10 +544,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off case SOURCE_MESSAGE_UPDATE_LATENCY: { pa_usec_t y; - y = pa_bytes_to_usec(u->counter, &u->source->sample_spec); + y = pa_bytes_to_usec((uint64_t) u->counter, &u->source->sample_spec); if (offset >= 0 || y > (pa_usec_t) -offset) - y += offset; + y += (pa_usec_t) offset; else y = 0; @@ -652,7 +652,7 @@ static void command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, p return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } #endif @@ -736,9 +736,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint /* Add the length of our server-side buffer */ if (write_index >= read_index) - delay += (int64_t) pa_bytes_to_usec(write_index-read_index, ss); + delay += (int64_t) pa_bytes_to_usec((uint64_t) (write_index-read_index), ss); else - delay -= (int64_t) pa_bytes_to_usec(read_index-write_index, ss); + delay -= (int64_t) pa_bytes_to_usec((uint64_t) (read_index-write_index), ss); /* Our measurements are already out of date, hence correct by the * * transport latency */ @@ -750,9 +750,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint /* Now correct by what we have have read/written since we requested the update */ #ifdef TUNNEL_SINK - delay += (int64_t) pa_bytes_to_usec(u->counter_delta, ss); + delay += (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss); #else - delay -= (int64_t) pa_bytes_to_usec(u->counter_delta, ss); + delay -= (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss); #endif #ifdef TUNNEL_SINK @@ -765,7 +765,7 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from main context */ @@ -902,7 +902,7 @@ static void server_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } #ifdef TUNNEL_SINK @@ -979,7 +979,7 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); pa_proplist_free(pl); } @@ -1066,7 +1066,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); pa_proplist_free(pl); } @@ -1142,7 +1142,7 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); pa_proplist_free(pl); } @@ -1204,7 +1204,7 @@ static void command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32 if (pa_tagstruct_getu32(t, &e) < 0 || pa_tagstruct_getu32(t, &idx) < 0) { pa_log("Invalid protocol reply"); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } @@ -1344,7 +1344,7 @@ parse_error: pa_log("Invalid reply. (Create stream)"); fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } @@ -1425,11 +1425,11 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t u->maxlength = 4*1024*1024; #ifdef TUNNEL_SINK - u->tlength = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec); - u->minreq = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec); + u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec); + u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec); u->prebuf = u->tlength; #else - u->fragsize = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec); + u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec); #endif #ifdef TUNNEL_SINK @@ -1502,7 +1502,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t return; fail: - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from main context */ @@ -1513,7 +1513,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) { pa_assert(u); pa_log_warn("Stream died."); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } /* Called from main context */ @@ -1526,7 +1526,7 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_c if (pa_pdispatch_run(u->pdispatch, packet, creds, u) < 0) { pa_log("Invalid packet"); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } } @@ -1542,13 +1542,13 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o if (channel != u->channel) { pa_log("Recieved memory block on bad channel."); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_POST, PA_UINT_TO_PTR(seek), offset, chunk); - u->counter_delta += chunk->length; + u->counter_delta += (int64_t) chunk->length; } #endif @@ -1568,7 +1568,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata if (!io) { pa_log("Connection failed: %s", pa_cstrerror(errno)); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); return; } diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index d862c203..aac0d046 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -103,7 +103,7 @@ static pa_cvolume* parse_volume(const char *s, pa_cvolume *v) { if (k <= 0 || k > (long) PA_CHANNELS_MAX) return NULL; - v->channels = (unsigned) k; + v->channels = (uint8_t) k; for (i = 0; i < v->channels; i++) { p += strspn(p, WHITESPACE); @@ -493,7 +493,7 @@ int pa__init(pa_module*m) { m->userdata = u; - if (!(u->table_file = pa_state_path(pa_modargs_get_value(ma, "table", DEFAULT_VOLUME_TABLE_FILE)))) + if (!(u->table_file = pa_state_path(pa_modargs_get_value(ma, "table", DEFAULT_VOLUME_TABLE_FILE), TRUE))) goto fail; if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 || diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index f7be48f7..e93721c1 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -82,7 +82,7 @@ static int x11_event_cb(pa_x11_wrapper *w, XEvent *e, void *userdata) { bne = (XkbBellNotifyEvent*) e; - if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, (bne->percent*PA_VOLUME_NORM)/100, NULL, NULL) < 0) { + if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, ((pa_volume_t) bne->percent*PA_VOLUME_NORM)/100U, NULL, NULL) < 0) { pa_log_info("Ringing bell failed, reverting to X11 device bell."); XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent); } @@ -106,7 +106,7 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) { u->x11_client = NULL; u->x11_wrapper = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } int pa__init(pa_module*m) { diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index c29535e6..c6c5bacd 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -126,7 +126,7 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) { u->x11_client = NULL; u->x11_wrapper = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } int pa__init(pa_module*m) { @@ -152,7 +152,7 @@ int pa__init(pa_module*m) { u->x11_client = NULL; u->x11_wrapper = NULL; - u->hook_slot = pa_hook_connect(pa_native_protocol_servers_changed(u->protocol), PA_HOOK_NORMAL, servers_changed_cb, u); + u->hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_SERVERS_CHANGED], PA_HOOK_NORMAL, servers_changed_cb, u); if (!(u->auth_cookie = pa_auth_cookie_get(m->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH))) goto fail; diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c index 0b2e375a..57d182fd 100644 --- a/src/modules/module-x11-xsmp.c +++ b/src/modules/module-x11-xsmp.c @@ -77,7 +77,7 @@ static void die_cb(SmcConn connection, SmPointer client_data){ pa_x11_wrapper_unref(u->x11); u->x11 = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } static void save_complete_cb(SmcConn connection, SmPointer client_data) { @@ -181,7 +181,7 @@ int pa__init(pa_module*m) { prop_program.name = (char*) SmProgram; prop_program.type = (char*) SmARRAY8; val_program.value = (char*) PACKAGE_NAME; - val_program.length = strlen(val_program.value); + val_program.length = (int) strlen(val_program.value); prop_program.num_vals = 1; prop_program.vals = &val_program; prop_list[0] = &prop_program; @@ -190,7 +190,7 @@ int pa__init(pa_module*m) { prop_user.type = (char*) SmARRAY8; pa_get_user_name(t, sizeof(t)); val_user.value = t; - val_user.length = strlen(val_user.value); + val_user.length = (int) strlen(val_user.value); prop_user.num_vals = 1; prop_user.vals = &val_user; prop_list[1] = &prop_user; diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c index 2fc81370..c8087abb 100644 --- a/src/modules/module-zeroconf-discover.c +++ b/src/modules/module-zeroconf-discover.c @@ -173,9 +173,9 @@ static void resolver_cb( device = value; value = NULL; } else if (strcmp(key, "rate") == 0) - ss.rate = atoi(value); + ss.rate = (uint32_t) atoi(value); else if (strcmp(key, "channels") == 0) - ss.channels = atoi(value); + ss.channels = (uint8_t) atoi(value); else if (strcmp(key, "format") == 0) ss.format = pa_parse_sample_format(value); else if (strcmp(key, "channel_map") == 0) { @@ -286,7 +286,7 @@ static void browser_cb( struct tunnel *t2; if ((t2 = pa_hashmap_get(u->tunnels, t))) { - pa_module_unload_by_index(u->core, t2->module_index); + pa_module_unload_by_index(u->core, t2->module_index, TRUE); pa_hashmap_remove(u->tunnels, t2); tunnel_free(t2); } @@ -319,7 +319,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda browser_cb, u))) { pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c))); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } @@ -334,7 +334,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda browser_cb, u))) { pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c))); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } @@ -348,7 +348,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) { pa_log("avahi_client_new() failed: %s", avahi_strerror(error)); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } @@ -427,7 +427,7 @@ void pa__done(pa_module*m) { struct tunnel *t; while ((t = pa_hashmap_steal_first(u->tunnels))) { - pa_module_unload_by_index(u->core, t->module_index); + pa_module_unload_by_index(u->core, t->module_index, TRUE); tunnel_free(t); } diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 78929179..985564f4 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -539,7 +539,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) { pa_log("avahi_client_new() failed: %s", avahi_strerror(error)); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); } } diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 2791e165..f766030d 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -204,10 +204,10 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { if (ss->channels != channels) { pa_log_warn("device doesn't support %i channels, using %i channels.", ss->channels, channels); - ss->channels = channels; + ss->channels = (uint8_t) channels; } - speed = ss->rate; + speed = (int) ss->rate; if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { pa_log("SNDCTL_DSP_SPEED: %s", pa_cstrerror(errno)); return -1; @@ -219,7 +219,7 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { /* If the sample rate deviates too much, we need to resample */ if (speed < ss->rate*.95 || speed > ss->rate*1.05) - ss->rate = speed; + ss->rate = (uint32_t) speed; } return 0; diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index e04e4611..01637892 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -238,15 +238,15 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { else delta = j; - pa_memblockq_seek(s->memblockq, delta * s->rtp_context.frame_size, PA_SEEK_RELATIVE); + pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE); pa_rtclock_get(&now); - pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec(pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec)); + pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec((uint64_t) pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec)); if (pa_memblockq_push(s->memblockq, &chunk) < 0) { pa_log_warn("Queue overrun"); - pa_memblockq_seek(s->memblockq, chunk.length, PA_SEEK_RELATIVE); + pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE); } pa_log("blocks in q: %u", pa_memblockq_get_nblocks(s->memblockq)); @@ -254,9 +254,9 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { pa_memblock_unref(chunk.memblock); /* The next timestamp we expect */ - s->offset = s->rtp_context.timestamp + (chunk.length / s->rtp_context.frame_size); + s->offset = s->rtp_context.timestamp + (uint32_t) (chunk.length / s->rtp_context.frame_size); - pa_atomic_store(&s->timestamp, now.tv_sec); + pa_atomic_store(&s->timestamp, (int) now.tv_sec); if (s->last_rate_update + RATE_UPDATE_INTERVAL < pa_timeval_load(&now)) { pa_usec_t wi, ri, render_delay, sink_delay = 0, latency, fix; @@ -265,7 +265,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { pa_log("Updating sample rate"); wi = pa_smoother_get(s->smoother, pa_timeval_load(&now)); - ri = pa_bytes_to_usec(pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec); + ri = pa_bytes_to_usec((uint64_t) pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec); if (PA_MSGOBJECT(s->sink_input->sink)->process_msg(PA_MSGOBJECT(s->sink_input->sink), PA_SINK_MESSAGE_GET_LATENCY, &sink_delay, 0, NULL) < 0) sink_delay = 0; @@ -291,7 +291,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { fix = latency - s->intended_latency; /* How many samples is this per second? */ - fix_samples = fix * s->sink_input->thread_info.sample_spec.rate / RATE_UPDATE_INTERVAL; + fix_samples = (unsigned) (fix * (pa_usec_t) s->sink_input->thread_info.sample_spec.rate / (pa_usec_t) RATE_UPDATE_INTERVAL); /* Check if deviation is in bounds */ if (fix_samples > s->sink_input->sample_spec.rate*.20) @@ -431,7 +431,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in s->smoother = pa_smoother_new(PA_USEC_PER_SEC*5, PA_USEC_PER_SEC*2, TRUE, 10); pa_smoother_set_time_offset(s->smoother, pa_timeval_load(&now)); s->last_rate_update = pa_timeval_load(&now); - pa_atomic_store(&s->timestamp, now.tv_sec); + pa_atomic_store(&s->timestamp, (int) now.tv_sec); if ((fd = mcast_socket((const struct sockaddr*) &sdp_info->sa, sdp_info->salen)) < 0) goto fail; @@ -566,7 +566,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event } else { struct timeval now; pa_rtclock_get(&now); - pa_atomic_store(&s->timestamp, now.tv_sec); + pa_atomic_store(&s->timestamp, (int) now.tv_sec); pa_sdp_info_destroy(&info); } diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index d0d06c4d..280067a5 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -67,10 +67,12 @@ PA_MODULE_USAGE( "destination=<destination IP address> " "port=<port number> " "mtu=<maximum transfer unit> " - "loop=<loopback to local host?>" + "loop=<loopback to local host?> " + "ttl=<ttl value>" ); #define DEFAULT_PORT 46000 +#define DEFAULT_TTL 1 #define SAP_PORT 9875 #define DEFAULT_DESTINATION "224.0.0.56" #define MEMBLOCKQ_MAXLENGTH (1024*170) @@ -86,6 +88,7 @@ static const char* const valid_modargs[] = { "port", "mtu" , "loop", + "ttl", NULL }; @@ -139,7 +142,7 @@ static void source_output_kill(pa_source_output* o) { pa_source_output_assert_ref(o); pa_assert_se(u = o->userdata); - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); pa_source_output_unlink(u->source_output); pa_source_output_unref(u->source_output); @@ -167,7 +170,9 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; const char *dest; uint32_t port = DEFAULT_PORT, mtu; - int af, fd = -1, sap_fd = -1; + uint32_t ttl = DEFAULT_TTL; + sa_family_t af; + int fd = -1, sap_fd = -1; pa_source *s; pa_sample_spec ss; pa_channel_map cm; @@ -219,14 +224,14 @@ int pa__init(pa_module*m) { payload = pa_rtp_payload_from_sample_spec(&ss); - mtu = pa_frame_align(DEFAULT_MTU, &ss); + mtu = (uint32_t) pa_frame_align(DEFAULT_MTU, &ss); if (pa_modargs_get_value_u32(ma, "mtu", &mtu) < 0 || mtu < 1 || mtu % pa_frame_size(&ss) != 0) { pa_log("Invalid MTU."); goto fail; } - port = DEFAULT_PORT + ((rand() % 512) << 1); + port = DEFAULT_PORT + ((uint32_t) (rand() % 512) << 1); if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) { pa_log("port= expects a numerical argument between 1 and 65535."); goto fail; @@ -235,16 +240,21 @@ int pa__init(pa_module*m) { if (port & 1) pa_log_warn("Port number not even as suggested in RFC3550!"); + if (pa_modargs_get_value_u32(ma, "ttl", &ttl) < 0 || ttl < 1 || ttl > 0xFF) { + pa_log("ttl= expects a numerical argument between 1 and 255."); + goto fail; + } + dest = pa_modargs_get_value(ma, "destination", DEFAULT_DESTINATION); if (inet_pton(AF_INET6, dest, &sa6.sin6_addr) > 0) { sa6.sin6_family = af = AF_INET6; - sa6.sin6_port = htons(port); + sa6.sin6_port = htons((uint16_t) port); sap_sa6 = sa6; sap_sa6.sin6_port = htons(SAP_PORT); } else if (inet_pton(AF_INET, dest, &sa4.sin_addr) > 0) { sa4.sin_family = af = AF_INET; - sa4.sin_port = htons(port); + sa4.sin_port = htons((uint16_t) port); sap_sa4 = sa4; sap_sa4.sin_port = htons(SAP_PORT); } else { @@ -257,7 +267,7 @@ int pa__init(pa_module*m) { goto fail; } - if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, af == AF_INET ? sizeof(sa4) : sizeof(sa6)) < 0) { + if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, (socklen_t) (af == AF_INET ? sizeof(sa4) : sizeof(sa6))) < 0) { pa_log("connect() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -267,7 +277,7 @@ int pa__init(pa_module*m) { goto fail; } - if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6)) < 0) { + if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, (socklen_t) (af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6))) < 0) { pa_log("connect() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -279,6 +289,15 @@ int pa__init(pa_module*m) { goto fail; } + if (ttl != DEFAULT_TTL) { + int _ttl = (int) ttl; + + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &_ttl, sizeof(_ttl)) < 0) { + pa_log("IP_MULTICAST_TTL failed: %s", pa_cstrerror(errno)); + goto fail; + } + } + /* If the socket queue is full, let's drop packets */ pa_make_fd_nonblock(fd); pa_make_udp_socket_low_delay(fd); @@ -290,6 +309,7 @@ int pa__init(pa_module*m) { pa_proplist_sets(data.proplist, "rtp.destination", dest); pa_proplist_setf(data.proplist, "rtp.mtu", "%lu", (unsigned long) mtu); pa_proplist_setf(data.proplist, "rtp.port", "%lu", (unsigned long) port); + pa_proplist_setf(data.proplist, "rtp.ttl", "%lu", (unsigned long) ttl); data.driver = __FILE__; data.module = m; data.source = s; @@ -335,14 +355,14 @@ int pa__init(pa_module*m) { p = pa_sdp_build(af, af == AF_INET ? (void*) &((struct sockaddr_in*) &sa_dst)->sin_addr : (void*) &((struct sockaddr_in6*) &sa_dst)->sin6_addr, af == AF_INET ? (void*) &sa4.sin_addr : (void*) &sa6.sin6_addr, - n, port, payload, &ss); + n, (uint16_t) port, payload, &ss); pa_xfree(n); pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss)); pa_sap_context_init_send(&u->sap_context, sap_fd, p); - pa_log_info("RTP stream initialized with mtu %u on %s:%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, u->rtp_context.ssrc, payload, u->rtp_context.sequence); + pa_log_info("RTP stream initialized with mtu %u on %s:%u ttl=%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, ttl, u->rtp_context.ssrc, payload, u->rtp_context.sequence); pa_log_info("SDP-Data:\n%s\nEOF", p); pa_sap_send(&u->sap_context, 0); diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index 5a33ebc2..88351010 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -50,7 +50,7 @@ pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssr c->sequence = (uint16_t) (rand()*rand()); c->timestamp = 0; c->ssrc = ssrc ? ssrc : (uint32_t) (rand()*rand()); - c->payload = payload & 127; + c->payload = (uint8_t) (payload & 127U); c->frame_size = frame_size; pa_memchunk_reset(&c->memchunk); @@ -99,7 +99,8 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) { uint32_t header[3]; struct msghdr m; - int k, i; + ssize_t k; + int i; if (n > 0) { header[0] = htonl(((uint32_t) 2 << 30) | ((uint32_t) c->payload << 16) | ((uint32_t) c->sequence)); @@ -112,7 +113,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { m.msg_name = NULL; m.msg_namelen = 0; m.msg_iov = iov; - m.msg_iovlen = iov_idx; + m.msg_iovlen = (size_t) iov_idx; m.msg_control = NULL; m.msg_controllen = 0; m.msg_flags = 0; @@ -128,7 +129,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { } else k = 0; - c->timestamp += n/c->frame_size; + c->timestamp += (unsigned) (n/c->frame_size); if (k < 0) { if (errno != EAGAIN && errno != EINTR) /* If the queue is full, just ignore it */ @@ -162,7 +163,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { struct msghdr m; struct iovec iov; uint32_t header; - int cc; + unsigned cc; ssize_t r; pa_assert(c); @@ -197,7 +198,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { chunk->index = c->memchunk.index; iov.iov_base = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index; - iov.iov_len = size; + iov.iov_len = (size_t) size; m.msg_name = NULL; m.msg_namelen = 0; @@ -246,16 +247,16 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { } cc = (header >> 24) & 0xF; - c->payload = (header >> 16) & 127; - c->sequence = header & 0xFFFF; + c->payload = (uint8_t) ((header >> 16) & 127U); + c->sequence = (uint16_t) (header & 0xFFFFU); - if (12 + cc*4 > size) { + if (12 + cc*4 > (unsigned) size) { pa_log_warn("RTP packet too short. (CSRC)"); goto fail; } chunk->index += 12 + cc*4; - chunk->length = size - 12 + cc*4; + chunk->length = (size_t) size - 12 + cc*4; if (chunk->length % c->frame_size != 0) { pa_log_warn("Bad RTP packet size."); diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c index 5d9b58fa..b0c95aa5 100644 --- a/src/modules/rtp/sap.c +++ b/src/modules/rtp/sap.c @@ -76,7 +76,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) { socklen_t salen = sizeof(sa_buf); struct iovec iov[4]; struct msghdr m; - int k; + ssize_t k; if (getsockname(c->fd, sa, &salen) < 0) { pa_log("getsockname() failed: %s\n", pa_cstrerror(errno)); @@ -94,7 +94,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) { iov[0].iov_len = sizeof(header); iov[1].iov_base = sa->sa_family == AF_INET ? (void*) &((struct sockaddr_in*) sa)->sin_addr : (void*) &((struct sockaddr_in6*) sa)->sin6_addr; - iov[1].iov_len = sa->sa_family == AF_INET ? 4 : 16; + iov[1].iov_len = sa->sa_family == AF_INET ? 4U : 16U; iov[2].iov_base = (char*) MIME_TYPE; iov[2].iov_len = sizeof(MIME_TYPE); @@ -113,7 +113,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) { if ((k = sendmsg(c->fd, &m, MSG_DONTWAIT)) < 0) pa_log_warn("sendmsg() failed: %s\n", pa_cstrerror(errno)); - return k; + return (int) k; } pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) { @@ -128,10 +128,10 @@ pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) { int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) { struct msghdr m; struct iovec iov; - int size, k; + int size; char *buf = NULL, *e; uint32_t header; - int six, ac; + unsigned six, ac, k; ssize_t r; pa_assert(c); @@ -142,11 +142,11 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) { goto fail; } - buf = pa_xnew(char, size+1); + buf = pa_xnew(char, (unsigned) size+1); buf[size] = 0; iov.iov_base = buf; - iov.iov_len = size; + iov.iov_len = (size_t) size; m.msg_name = NULL; m.msg_namelen = 0; @@ -184,21 +184,21 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) { goto fail; } - six = (header >> 28) & 1; - ac = (header >> 16) & 0xFF; + six = (header >> 28) & 1U; + ac = (header >> 16) & 0xFFU; - k = 4 + (six ? 16 : 4) + ac*4; - if (size < k) { + k = 4 + (six ? 16U : 4U) + ac*4U; + if ((unsigned) size < k) { pa_log_warn("SAP packet too short (AD)."); goto fail; } e = buf + k; - size -= k; + size -= (int) k; if ((unsigned) size >= sizeof(MIME_TYPE) && !strcmp(e, MIME_TYPE)) { e += sizeof(MIME_TYPE); - size -= sizeof(MIME_TYPE); + size -= (int) sizeof(MIME_TYPE); } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) { pa_log_warn("Invalid SDP header."); goto fail; @@ -207,7 +207,7 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) { if (c->sdp_data) pa_xfree(c->sdp_data); - c->sdp_data = pa_xstrndup(e, size); + c->sdp_data = pa_xstrndup(e, (unsigned) size); pa_xfree(buf); *goodbye = !!((header >> 26) & 1); diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index cef90433..59989e1a 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -55,7 +55,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u if (!(u = pa_get_user_name(un, sizeof(un)))) u = "-"; - ntp = time(NULL) + 2208988800U; + ntp = (uint32_t) time(NULL) + 2208988800U; pa_assert_se(a = inet_ntop(af, src, buf_src, sizeof(buf_src))); pa_assert_se(a = inet_ntop(af, dst, buf_dst, sizeof(buf_dst))); @@ -99,10 +99,10 @@ static pa_sample_spec *parse_sdp_sample_spec(pa_sample_spec *ss, char *c) { return NULL; if (sscanf(c, "%u/%u", &rate, &channels) == 2) { - ss->rate = rate; - ss->channels = channels; + ss->rate = (uint32_t) rate; + ss->channels = (uint8_t) channels; } else if (sscanf(c, "%u", &rate) == 2) { - ss->rate = rate; + ss->rate = (uint32_t) rate; ss->channels = 1; } else return NULL; diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index 7348b32e..1766e729 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -29,6 +29,7 @@ #include <string.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/macro.h> @@ -98,66 +99,66 @@ const char *const table[PA_CHANNEL_POSITION_MAX] = { }; const char *const pretty_table[PA_CHANNEL_POSITION_MAX] = { - [PA_CHANNEL_POSITION_MONO] = "Mono", - - [PA_CHANNEL_POSITION_FRONT_CENTER] = "Front Center", - [PA_CHANNEL_POSITION_FRONT_LEFT] = "Front Left", - [PA_CHANNEL_POSITION_FRONT_RIGHT] = "Front Right", - - [PA_CHANNEL_POSITION_REAR_CENTER] = "Rear Center", - [PA_CHANNEL_POSITION_REAR_LEFT] = "Rear Left", - [PA_CHANNEL_POSITION_REAR_RIGHT] = "Rear Right", - - [PA_CHANNEL_POSITION_LFE] = "Low Frequency Emmiter", - - [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "Front Left-of-center", - [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "Front Right-of-center", - - [PA_CHANNEL_POSITION_SIDE_LEFT] = "Side Left", - [PA_CHANNEL_POSITION_SIDE_RIGHT] = "Side Right", - - [PA_CHANNEL_POSITION_AUX0] = "Auxiliary 0", - [PA_CHANNEL_POSITION_AUX1] = "Auxiliary 1", - [PA_CHANNEL_POSITION_AUX2] = "Auxiliary 2", - [PA_CHANNEL_POSITION_AUX3] = "Auxiliary 3", - [PA_CHANNEL_POSITION_AUX4] = "Auxiliary 4", - [PA_CHANNEL_POSITION_AUX5] = "Auxiliary 5", - [PA_CHANNEL_POSITION_AUX6] = "Auxiliary 6", - [PA_CHANNEL_POSITION_AUX7] = "Auxiliary 7", - [PA_CHANNEL_POSITION_AUX8] = "Auxiliary 8", - [PA_CHANNEL_POSITION_AUX9] = "Auxiliary 9", - [PA_CHANNEL_POSITION_AUX10] = "Auxiliary 10", - [PA_CHANNEL_POSITION_AUX11] = "Auxiliary 11", - [PA_CHANNEL_POSITION_AUX12] = "Auxiliary 12", - [PA_CHANNEL_POSITION_AUX13] = "Auxiliary 13", - [PA_CHANNEL_POSITION_AUX14] = "Auxiliary 14", - [PA_CHANNEL_POSITION_AUX15] = "Auxiliary 15", - [PA_CHANNEL_POSITION_AUX16] = "Auxiliary 16", - [PA_CHANNEL_POSITION_AUX17] = "Auxiliary 17", - [PA_CHANNEL_POSITION_AUX18] = "Auxiliary 18", - [PA_CHANNEL_POSITION_AUX19] = "Auxiliary 19", - [PA_CHANNEL_POSITION_AUX20] = "Auxiliary 20", - [PA_CHANNEL_POSITION_AUX21] = "Auxiliary 21", - [PA_CHANNEL_POSITION_AUX22] = "Auxiliary 22", - [PA_CHANNEL_POSITION_AUX23] = "Auxiliary 23", - [PA_CHANNEL_POSITION_AUX24] = "Auxiliary 24", - [PA_CHANNEL_POSITION_AUX25] = "Auxiliary 25", - [PA_CHANNEL_POSITION_AUX26] = "Auxiliary 26", - [PA_CHANNEL_POSITION_AUX27] = "Auxiliary 27", - [PA_CHANNEL_POSITION_AUX28] = "Auxiliary 28", - [PA_CHANNEL_POSITION_AUX29] = "Auxiliary 29", - [PA_CHANNEL_POSITION_AUX30] = "Auxiliary 30", - [PA_CHANNEL_POSITION_AUX31] = "Auxiliary 31", - - [PA_CHANNEL_POSITION_TOP_CENTER] = "Top Center", - - [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "Top Front Center", - [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "Top Front Left", - [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "Top Front Right", - - [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "Top Rear Center", - [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "Top Rear left", - [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "Top Rear Right" + [PA_CHANNEL_POSITION_MONO] = N_("Mono"), + + [PA_CHANNEL_POSITION_FRONT_CENTER] = N_("Front Center"), + [PA_CHANNEL_POSITION_FRONT_LEFT] = N_("Front Left"), + [PA_CHANNEL_POSITION_FRONT_RIGHT] = N_("Front Right"), + + [PA_CHANNEL_POSITION_REAR_CENTER] = N_("Rear Center"), + [PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"), + [PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"), + + [PA_CHANNEL_POSITION_LFE] = N_("Low Frequency Emmiter"), + + [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = N_("Front Left-of-center"), + [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = N_("Front Right-of-center"), + + [PA_CHANNEL_POSITION_SIDE_LEFT] = N_("Side Left"), + [PA_CHANNEL_POSITION_SIDE_RIGHT] = N_("Side Right"), + + [PA_CHANNEL_POSITION_AUX0] = N_("Auxiliary 0"), + [PA_CHANNEL_POSITION_AUX1] = N_("Auxiliary 1"), + [PA_CHANNEL_POSITION_AUX2] = N_("Auxiliary 2"), + [PA_CHANNEL_POSITION_AUX3] = N_("Auxiliary 3"), + [PA_CHANNEL_POSITION_AUX4] = N_("Auxiliary 4"), + [PA_CHANNEL_POSITION_AUX5] = N_("Auxiliary 5"), + [PA_CHANNEL_POSITION_AUX6] = N_("Auxiliary 6"), + [PA_CHANNEL_POSITION_AUX7] = N_("Auxiliary 7"), + [PA_CHANNEL_POSITION_AUX8] = N_("Auxiliary 8"), + [PA_CHANNEL_POSITION_AUX9] = N_("Auxiliary 9"), + [PA_CHANNEL_POSITION_AUX10] = N_("Auxiliary 10"), + [PA_CHANNEL_POSITION_AUX11] = N_("Auxiliary 11"), + [PA_CHANNEL_POSITION_AUX12] = N_("Auxiliary 12"), + [PA_CHANNEL_POSITION_AUX13] = N_("Auxiliary 13"), + [PA_CHANNEL_POSITION_AUX14] = N_("Auxiliary 14"), + [PA_CHANNEL_POSITION_AUX15] = N_("Auxiliary 15"), + [PA_CHANNEL_POSITION_AUX16] = N_("Auxiliary 16"), + [PA_CHANNEL_POSITION_AUX17] = N_("Auxiliary 17"), + [PA_CHANNEL_POSITION_AUX18] = N_("Auxiliary 18"), + [PA_CHANNEL_POSITION_AUX19] = N_("Auxiliary 19"), + [PA_CHANNEL_POSITION_AUX20] = N_("Auxiliary 20"), + [PA_CHANNEL_POSITION_AUX21] = N_("Auxiliary 21"), + [PA_CHANNEL_POSITION_AUX22] = N_("Auxiliary 22"), + [PA_CHANNEL_POSITION_AUX23] = N_("Auxiliary 23"), + [PA_CHANNEL_POSITION_AUX24] = N_("Auxiliary 24"), + [PA_CHANNEL_POSITION_AUX25] = N_("Auxiliary 25"), + [PA_CHANNEL_POSITION_AUX26] = N_("Auxiliary 26"), + [PA_CHANNEL_POSITION_AUX27] = N_("Auxiliary 27"), + [PA_CHANNEL_POSITION_AUX28] = N_("Auxiliary 28"), + [PA_CHANNEL_POSITION_AUX29] = N_("Auxiliary 29"), + [PA_CHANNEL_POSITION_AUX30] = N_("Auxiliary 30"), + [PA_CHANNEL_POSITION_AUX31] = N_("Auxiliary 31"), + + [PA_CHANNEL_POSITION_TOP_CENTER] = N_("Top Center"), + + [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = N_("Top Front Center"), + [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = N_("Top Front Left"), + [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = N_("Top Front Right"), + + [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = N_("Top Rear Center"), + [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = N_("Top Rear Left"), + [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = N_("Top Rear Right") }; pa_channel_map* pa_channel_map_init(pa_channel_map *m) { @@ -200,7 +201,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p pa_channel_map_init(m); - m->channels = channels; + m->channels = (uint8_t) channels; switch (def) { case PA_CHANNEL_MAP_AIFF: @@ -414,7 +415,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels, i++; } - m->channels = channels; + m->channels = (uint8_t) channels; return m; } @@ -432,10 +433,13 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) { } const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) { + + pa_init_i18n(); + if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX) return NULL; - return pretty_table[pos]; + return _(pretty_table[pos]); } int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { @@ -456,7 +460,7 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { unsigned channel; - int first = 1; + pa_bool_t first = TRUE; char *e; pa_assert(s); @@ -471,7 +475,7 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { pa_channel_position_to_string(map->map[channel])); e = strchr(e, 0); - first = 0; + first = FALSE; } return s; @@ -552,7 +556,6 @@ int pa_channel_map_valid(const pa_channel_map *map) { if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX) return 0; - } return 1; diff --git a/src/pulse/client-conf-x11.c b/src/pulse/client-conf-x11.c index 393a7cd3..a8a90fb8 100644 --- a/src/pulse/client-conf-x11.c +++ b/src/pulse/client-conf-x11.c @@ -29,6 +29,7 @@ #include <X11/Xatom.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/x11prop.h> #include <pulsecore/log.h> @@ -51,7 +52,7 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) { goto finish; if (!(d = XOpenDisplay(dname))) { - pa_log("XOpenDisplay() failed"); + pa_log(_("XOpenDisplay() failed")); goto finish; } @@ -74,7 +75,7 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) { uint8_t cookie[PA_NATIVE_COOKIE_LENGTH]; if (pa_parsehex(t, cookie, sizeof(cookie)) != sizeof(cookie)) { - pa_log("failed to parse cookie data"); + pa_log(_("Failed to parse cookie data")); goto finish; } diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 915d0ccb..739ef161 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -30,6 +30,7 @@ #include <string.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/macro.h> #include <pulsecore/core-error.h> @@ -113,7 +114,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { if (filename) { if (!(f = fopen(filename, "r"))) { - pa_log("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno)); + pa_log(_("Failed to open configuration file '%s': %s"), fn, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulse/context.c b/src/pulse/context.c index f56cb241..99a47a18 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -53,6 +53,8 @@ #include <pulse/xmalloc.h> #include <pulse/utf8.h> #include <pulse/util.h> +#include <pulse/i18n.h> +#include <pulse/lock-autospawn.h> #include <pulsecore/winsock.h> #include <pulsecore/core-error.h> @@ -80,7 +82,7 @@ #include "context.h" -#define AUTOSPAWN_LOCK "autospawn.lock" +void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_REQUEST] = pa_command_request, @@ -93,23 +95,27 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended, [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended, [PA_COMMAND_STARTED] = pa_command_stream_started, - [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event + [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event, + [PA_COMMAND_EXTENSION] = pa_command_extension }; -static void unlock_autospawn_lock_file(pa_context *c) { +static void unlock_autospawn(pa_context *c) { pa_assert(c); - if (c->autospawn_lock_fd >= 0) { - char *lf; + if (c->autospawn_fd >= 0) { - if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) - pa_log_warn("Cannot unlock autospawn because runtime path is no more."); + if (c->autospawn_locked) + pa_autospawn_lock_release(); - pa_unlock_lockfile(lf, c->autospawn_lock_fd); - pa_xfree(lf); + if (c->autospawn_event) + c->mainloop->io_free(c->autospawn_event); - c->autospawn_lock_fd = -1; + pa_autospawn_lock_done(FALSE); } + + c->autospawn_locked = FALSE; + c->autospawn_fd = -1; + c->autospawn_event = NULL; } static void context_free(pa_context *c); @@ -126,6 +132,9 @@ static void reset_callbacks(pa_context *c) { c->subscribe_callback = NULL; c->subscribe_userdata = NULL; + + c->ext_stream_restore.callback = NULL; + c->ext_stream_restore.userdata = NULL; } pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) { @@ -133,6 +142,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * pa_assert(mainloop); + pa_init_i18n(); + if (!name && !pa_proplist_contains(p, PA_PROP_APPLICATION_NAME)) return NULL; @@ -165,11 +176,15 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * c->is_local = FALSE; c->server_list = NULL; c->server = NULL; - c->autospawn_lock_fd = -1; - memset(&c->spawn_api, 0, sizeof(c->spawn_api)); - c->do_autospawn = FALSE; + c->do_shm = FALSE; + c->do_autospawn = FALSE; + c->autospawn_fd = -1; + c->autospawn_locked = FALSE; + c->autospawn_event = NULL; + memset(&c->spawn_api, 0, sizeof(c->spawn_api)); + #ifndef MSG_NOSIGNAL #ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); @@ -237,7 +252,7 @@ static void context_free(pa_context *c) { context_unlink(c); - unlock_autospawn_lock_file(c); + unlock_autospawn(c); if (c->record_streams) pa_dynarray_free(c->record_streams, NULL, NULL); @@ -398,11 +413,11 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa err = PA_ERR_UNKNOWN; if (fail) { - pa_context_fail(c, err); + pa_context_fail(c, (int) err); return -1; } - pa_context_set_error(c, err); + pa_context_set_error(c, (int) err); return 0; } @@ -424,7 +439,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t switch(c->state) { case PA_CONTEXT_AUTHORIZING: { pa_tagstruct *reply; - pa_bool_t shm_on_remote; + pa_bool_t shm_on_remote = FALSE; if (pa_tagstruct_getu32(t, &c->version) < 0 || !pa_tagstruct_eof(t)) { @@ -524,7 +539,7 @@ static void setup_context(pa_context *c, pa_iochannel *io) { c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX); if (!c->conf->cookie_valid) - pa_log_info("No cookie loaded. Attempting to connect without."); + pa_log_info(_("No cookie loaded. Attempting to connect without.")); t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag); @@ -578,7 +593,7 @@ static int context_connect_spawn(pa_context *c) { pa_context_ref(c); if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { - pa_log_error("socketpair(): %s", pa_cstrerror(errno)); + pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } @@ -592,7 +607,7 @@ static int context_connect_spawn(pa_context *c) { c->spawn_api.prefork(); if ((pid = fork()) < 0) { - pa_log_error("fork(): %s", pa_cstrerror(errno)); + pa_log_error(_("fork(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); if (c->spawn_api.postfork) @@ -655,7 +670,7 @@ static int context_connect_spawn(pa_context *c) { c->spawn_api.postfork(); if (r < 0) { - pa_log("waitpid(): %s", pa_cstrerror(errno)); + pa_log(_("waitpid(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { @@ -665,7 +680,7 @@ static int context_connect_spawn(pa_context *c) { c->is_local = TRUE; - unlock_autospawn_lock_file(c); + unlock_autospawn(c); io = pa_iochannel_new(c->mainloop, fds[0], fds[0]); setup_context(c, io); @@ -677,7 +692,7 @@ static int context_connect_spawn(pa_context *c) { fail: pa_close_pipe(fds); - unlock_autospawn_lock_file(c); + unlock_autospawn(c); pa_context_unref(c); @@ -759,15 +774,48 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd goto finish; } - unlock_autospawn_lock_file(c); + unlock_autospawn(c); setup_context(c, io); finish: pa_context_unref(c); } +static void autospawn_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) { + pa_context *c = userdata; + int k; + + pa_assert(a); + pa_assert(e); + pa_assert(fd >= 0); + pa_assert(events == PA_IO_EVENT_INPUT); + pa_assert(c); + pa_assert(e == c->autospawn_event); + pa_assert(fd == c->autospawn_fd); + + pa_context_ref(c); + + /* Check whether we can get the lock right now*/ + if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) { + pa_context_fail(c, PA_ERR_ACCESS); + goto finish; + } + + if (k > 0) { + /* So we got it, rock on! */ + c->autospawn_locked = TRUE; + try_next_connection(c); + + c->mainloop->io_free(c->autospawn_event); + c->autospawn_event = NULL; + } -static char *get_legacy_runtime_dir(void) { +finish: + + pa_context_unref(c); +} + +static char *get_old_legacy_runtime_dir(void) { char *p, u[128]; struct stat st; @@ -789,6 +837,28 @@ static char *get_legacy_runtime_dir(void) { return p; } +static char *get_very_old_legacy_runtime_dir(void) { + char *p, h[128]; + struct stat st; + + if (!pa_get_home_dir(h, sizeof(h))) + return NULL; + + p = pa_sprintf_malloc("%s/.pulse", h); + + if (stat(p, &st) < 0) { + pa_xfree(p); + return NULL; + } + + if (st.st_uid != getuid()) { + pa_xfree(p); + return NULL; + } + + return p; +} + int pa_context_connect( pa_context *c, const char *server, @@ -816,6 +886,7 @@ int pa_context_connect( pa_context_fail(c, PA_ERR_INVALIDSERVER); goto finish; } + } else { char *d, *ufn; static char *legacy_dir; @@ -840,8 +911,16 @@ int pa_context_connect( /* The system wide instance */ c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET); - /* The old per-user instance path. This is supported only to ease upgrades */ - if ((legacy_dir = get_legacy_runtime_dir())) { + /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */ + if ((legacy_dir = get_very_old_legacy_runtime_dir())) { + char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir); + c->server_list = pa_strlist_prepend(c->server_list, p); + pa_xfree(p); + pa_xfree(legacy_dir); + } + + /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */ + if ((legacy_dir = get_old_legacy_runtime_dir())) { char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir); c->server_list = pa_strlist_prepend(c->server_list, p); pa_xfree(p); @@ -856,21 +935,40 @@ int pa_context_connect( /* Wrap the connection attempts in a single transaction for sane autospawn locking */ if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) { - char *lf; + int k; + + pa_assert(c->autospawn_fd < 0); + pa_assert(!c->autospawn_locked); - if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) { + /* Start the locking procedure */ + if ((c->autospawn_fd = pa_autospawn_lock_init()) < 0) { pa_context_fail(c, PA_ERR_ACCESS); goto finish; } - pa_assert(c->autospawn_lock_fd <= 0); - c->autospawn_lock_fd = pa_lock_lockfile(lf); - pa_xfree(lf); - if (api) c->spawn_api = *api; c->do_autospawn = TRUE; + + /* Check whether we can get the lock right now*/ + if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) { + pa_context_fail(c, PA_ERR_ACCESS); + goto finish; + } + + if (k > 0) + /* So we got it, rock on! */ + c->autospawn_locked = TRUE; + else { + /* Hmm, we didn't get it, so let's wait for it */ + c->autospawn_event = c->mainloop->io_new(c->mainloop, c->autospawn_fd, PA_IO_EVENT_INPUT, autospawn_cb, c); + + pa_context_set_state(c, PA_CONTEXT_CONNECTING); + r = 0; + goto finish; + } + } } @@ -929,11 +1027,11 @@ int pa_context_is_pending(pa_context *c) { static void set_dispatch_callbacks(pa_operation *o); -static void pdispatch_drain_callback(PA_GCC_UNUSED pa_pdispatch*pd, void *userdata) { +static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) { set_dispatch_callbacks(userdata); } -static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) { +static void pstream_drain_callback(pa_pstream *s, void *userdata) { set_dispatch_callbacks(userdata); } @@ -985,7 +1083,7 @@ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *u return o; } -void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; @@ -1137,7 +1235,7 @@ const char* pa_context_get_server(pa_context *c) { return c->server; } -uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) { +uint32_t pa_context_get_protocol_version(pa_context *c) { return PA_PROTOCOL_VERSION; } @@ -1230,3 +1328,31 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[] return o; } + +void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_context *c = userdata; + uint32_t idx; + const char *name; + + pa_assert(pd); + pa_assert(command == PA_COMMAND_EXTENSION); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + pa_context_ref(c); + + if (pa_tagstruct_getu32(t, &idx) < 0 || + pa_tagstruct_gets(t, &name) < 0) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + + if (!strcmp(name, "module-stream-restore")) + pa_ext_stream_restore_command(c, tag, t); + else + pa_log(_("Received message for unknown extension '%s'"), name); + +finish: + pa_context_unref(c); +} diff --git a/src/pulse/error.c b/src/pulse/error.c index 50bbf703..d9d0a8c6 100644 --- a/src/pulse/error.c +++ b/src/pulse/error.c @@ -30,6 +30,7 @@ #include <string.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/native-common.h> @@ -39,32 +40,34 @@ const char*pa_strerror(int error) { static const char* const errortab[PA_ERR_MAX] = { - [PA_OK] = "OK", - [PA_ERR_ACCESS] = "Access denied", - [PA_ERR_COMMAND] = "Unknown command", - [PA_ERR_INVALID] = "Invalid argument", - [PA_ERR_EXIST] = "Entity exists", - [PA_ERR_NOENTITY] = "No such entity", - [PA_ERR_CONNECTIONREFUSED] = "Connection refused", - [PA_ERR_PROTOCOL] = "Protocol error", - [PA_ERR_TIMEOUT] = "Timeout", - [PA_ERR_AUTHKEY] = "No authorization key", - [PA_ERR_INTERNAL] = "Internal error", - [PA_ERR_CONNECTIONTERMINATED] = "Connection terminated", - [PA_ERR_KILLED] = "Entity killed", - [PA_ERR_INVALIDSERVER] = "Invalid server", - [PA_ERR_MODINITFAILED] = "Module initalization failed", - [PA_ERR_BADSTATE] = "Bad state", - [PA_ERR_NODATA] = "No data", - [PA_ERR_VERSION] = "Incompatible protocol version", - [PA_ERR_TOOLARGE] = "Too large", - [PA_ERR_NOTSUPPORTED] = "Not supported", - [PA_ERR_UNKNOWN] = "Unknown error code", - [PA_ERR_NOEXTENSION] = "No such extension" + [PA_OK] = N_("OK"), + [PA_ERR_ACCESS] = N_("Access denied"), + [PA_ERR_COMMAND] = N_("Unknown command"), + [PA_ERR_INVALID] = N_("Invalid argument"), + [PA_ERR_EXIST] = N_("Entity exists"), + [PA_ERR_NOENTITY] = N_("No such entity"), + [PA_ERR_CONNECTIONREFUSED] = N_("Connection refused"), + [PA_ERR_PROTOCOL] = N_("Protocol error"), + [PA_ERR_TIMEOUT] = N_("Timeout"), + [PA_ERR_AUTHKEY] = N_("No authorization key"), + [PA_ERR_INTERNAL] = N_("Internal error"), + [PA_ERR_CONNECTIONTERMINATED] = N_("Connection terminated"), + [PA_ERR_KILLED] = N_("Entity killed"), + [PA_ERR_INVALIDSERVER] = N_("Invalid server"), + [PA_ERR_MODINITFAILED] = N_("Module initalization failed"), + [PA_ERR_BADSTATE] = N_("Bad state"), + [PA_ERR_NODATA] = N_("No data"), + [PA_ERR_VERSION] = N_("Incompatible protocol version"), + [PA_ERR_TOOLARGE] = N_("Too large"), + [PA_ERR_NOTSUPPORTED] = N_("Not supported"), + [PA_ERR_UNKNOWN] = N_("Unknown error code"), + [PA_ERR_NOEXTENSION] = N_("No such extension") }; + pa_init_i18n(); + if (error < 0 || error >= PA_ERR_MAX) return NULL; - return errortab[error]; + return _(errortab[error]); } diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c new file mode 100644 index 00000000..703179c5 --- /dev/null +++ b/src/pulse/ext-stream-restore.c @@ -0,0 +1,326 @@ +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulse/context.h> +#include <pulse/gccmacro.h> + +#include <pulsecore/macro.h> +#include <pulsecore/pstream-util.h> + +#include "internal.h" + +#include "ext-stream-restore.h" + +enum { + SUBCOMMAND_TEST, + SUBCOMMAND_READ, + SUBCOMMAND_WRITE, + SUBCOMMAND_DELETE, + SUBCOMMAND_SUBSCRIBE, + SUBCOMMAND_EVENT +}; + +static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_operation *o = userdata; + uint32_t version = PA_INVALID_INDEX; + + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); + + if (!o->context) + goto finish; + + if (command != PA_COMMAND_REPLY) { + if (pa_context_handle_error(o->context, command, t, FALSE) < 0) + goto finish; + + } else if (pa_tagstruct_getu32(t, &version) < 0 || + !pa_tagstruct_eof(t)) { + + pa_context_fail(o->context, PA_ERR_PROTOCOL); + goto finish; + } + + if (o->callback) { + pa_ext_stream_restore_test_cb_t cb = (pa_ext_stream_restore_test_cb_t) o->callback; + cb(o->context, version, o->userdata); + } + +finish: + pa_operation_done(o); + pa_operation_unref(o); +} + +pa_operation *pa_ext_stream_restore_test( + pa_context *c, + pa_ext_stream_restore_test_cb_t cb, + void *userdata) { + + uint32_t tag; + pa_operation *o; + pa_tagstruct *t; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, "module-stream-restore"); + pa_tagstruct_putu32(t, SUBCOMMAND_TEST); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_operation *o = userdata; + int eol = 1; + + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); + + if (!o->context) + goto finish; + + if (command != PA_COMMAND_REPLY) { + if (pa_context_handle_error(o->context, command, t, FALSE) < 0) + goto finish; + + eol = -1; + } else { + + while (!pa_tagstruct_eof(t)) { + pa_ext_stream_restore_info i; + pa_bool_t mute = FALSE; + + memset(&i, 0, sizeof(i)); + + if (pa_tagstruct_gets(t, &i.name) < 0 || + pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 || + pa_tagstruct_get_cvolume(t, &i.volume) < 0 || + pa_tagstruct_gets(t, &i.device) < 0 || + pa_tagstruct_get_boolean(t, &mute) < 0) { + + pa_context_fail(o->context, PA_ERR_PROTOCOL); + goto finish; + } + + i.mute = (int) mute; + + if (o->callback) { + pa_ext_stream_restore_read_cb_t cb = (pa_ext_stream_restore_read_cb_t) o->callback; + cb(o->context, &i, 0, o->userdata); + } + } + } + + if (o->callback) { + pa_ext_stream_restore_read_cb_t cb = (pa_ext_stream_restore_read_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); + } + +finish: + pa_operation_done(o); + pa_operation_unref(o); +} + +pa_operation *pa_ext_stream_restore_read( + pa_context *c, + pa_ext_stream_restore_read_cb_t cb, + void *userdata) { + + uint32_t tag; + pa_operation *o; + pa_tagstruct *t; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, "module-stream-restore"); + pa_tagstruct_putu32(t, SUBCOMMAND_READ); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_read_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation *pa_ext_stream_restore_write( + pa_context *c, + pa_update_mode_t mode, + const pa_ext_stream_restore_info data[], + unsigned n, + int apply_immediately, + pa_context_success_cb_t cb, + void *userdata) { + + uint32_t tag; + pa_operation *o; + pa_tagstruct *t; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE || mode == PA_UPDATE_SET); + pa_assert(data); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, "module-stream-restore"); + pa_tagstruct_putu32(t, SUBCOMMAND_WRITE); + + pa_tagstruct_putu32(t, mode); + pa_tagstruct_put_boolean(t, apply_immediately); + + for (; n > 0; n--, data++) { + pa_tagstruct_puts(t, data->name); + pa_tagstruct_put_channel_map(t, &data->channel_map); + pa_tagstruct_put_cvolume(t, &data->volume); + pa_tagstruct_puts(t, data->device); + pa_tagstruct_put_boolean(t, data->mute); + } + + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation *pa_ext_stream_restore_delete( + pa_context *c, + const char *const s[], + pa_context_success_cb_t cb, + void *userdata) { + + uint32_t tag; + pa_operation *o; + pa_tagstruct *t; + const char *const *k; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(s); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, "module-stream-restore"); + pa_tagstruct_putu32(t, SUBCOMMAND_DELETE); + + for (k = s; *k; k++) + pa_tagstruct_puts(t, *k); + + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation *pa_ext_stream_restore_subscribe( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata) { + + uint32_t tag; + pa_operation *o; + pa_tagstruct *t; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, "module-stream-restore"); + pa_tagstruct_putu32(t, SUBCOMMAND_SUBSCRIBE); + pa_tagstruct_put_boolean(t, enable); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +void pa_ext_stream_restore_set_subscribe_cb( + pa_context *c, + pa_ext_stream_restore_subscribe_cb_t cb, + void *userdata) { + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + c->ext_stream_restore.callback = cb; + c->ext_stream_restore.userdata = userdata; +} + +void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t) { + uint32_t subcommand; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(t); + + if (pa_tagstruct_getu32(t, &subcommand) < 0 || + !pa_tagstruct_eof(t)) { + + pa_context_fail(c, PA_ERR_PROTOCOL); + return; + } + + if (subcommand != SUBCOMMAND_EVENT) { + pa_context_fail(c, PA_ERR_PROTOCOL); + return; + } + + if (c->ext_stream_restore.callback) + c->ext_stream_restore.callback(c, c->ext_stream_restore.userdata); + +} diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h new file mode 100644 index 00000000..2038eb4a --- /dev/null +++ b/src/pulse/ext-stream-restore.h @@ -0,0 +1,107 @@ +#ifndef foopulseextstreamrestorehfoo +#define foopulseextstreamrestorehfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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. +***/ + +#include <pulse/context.h> + +/** \file + * + * Routines for controlling module-stream-restore + */ + +PA_C_DECL_BEGIN + +/** Stores information about one entry in the stream database that is + * maintained by module-stream-restore. \since 0.9.12 */ +typedef struct pa_ext_stream_restore_info { + const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */ + pa_channel_map channel_map; /**< The channel map for the volume field */ + pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable */ + const char *device; /**< The sink/source of the stream when it was last seen */ + int mute; /**< The boolean mute state of the stream when it was last seen, if applicable */ +} pa_ext_stream_restore_info; + +/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_test_cb_t)( + pa_context *c, + uint32_t version, + void *userdata); + +/** Test if this extension module is available in the server. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_test( + pa_context *c, + pa_ext_stream_restore_test_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_stream_restore_read(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_read_cb_t)( + pa_context *c, + const pa_ext_stream_restore_info *info, + int eol, + void *userdata); + +/** Read all entries from the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_read( + pa_context *c, + pa_ext_stream_restore_read_cb_t cb, + void *userdata); + +/** Store entries in the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_write( + pa_context *c, + pa_update_mode_t mode, + const pa_ext_stream_restore_info data[], + unsigned n, + int apply_immediately, + pa_context_success_cb_t cb, + void *userdata); + +/** Delete entries from the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_delete( + pa_context *c, + const char *const s[], + pa_context_success_cb_t cb, + void *userdata); + +/** Subscribe to changes in the stream database. \since 0.9.12 */ +pa_operation *pa_ext_stream_restore_subscribe( + pa_context *c, + int enable, + pa_context_success_cb_t cb, + void *userdata); + +/** Callback prototype for pa_ext_stream_restore_set_subscribe_cb(). \since 0.9.12 */ +typedef void (*pa_ext_stream_restore_subscribe_cb_t)( + pa_context *c, + void *userdata); + +/** Set the subscription callback that is called when + * pa_ext_stream_restore_subscribe() was called. \since 0.9.12 */ +void pa_ext_stream_restore_set_subscribe_cb( + pa_context *c, + pa_ext_stream_restore_subscribe_cb_t cb, + void *userdata); + +PA_C_DECL_END + +#endif diff --git a/src/pulse/glib-mainloop.c b/src/pulse/glib-mainloop.c index 6ddb0faa..5f5dc494 100644 --- a/src/pulse/glib-mainloop.c +++ b/src/pulse/glib-mainloop.c @@ -195,11 +195,11 @@ static void cleanup_defer_events(pa_glib_mainloop *g, int force) { } static gushort map_flags_to_glib(pa_io_event_flags_t flags) { - return - (flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) | - (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) | - (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) | - (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0); + return (gushort) + ((flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) | + (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) | + (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) | + (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0)); } static pa_io_event_flags_t map_flags_from_glib(gushort flags) { @@ -425,7 +425,7 @@ static void glib_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_ /* quit() */ -static void glib_quit(pa_mainloop_api*a, PA_GCC_UNUSED int retval) { +static void glib_quit(pa_mainloop_api*a, int retval) { g_warning("quit() ignored"); @@ -536,7 +536,7 @@ static gboolean check_func(GSource *source) { return FALSE; } -static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callback, PA_GCC_UNUSED gpointer userdata) { +static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) { pa_glib_mainloop *g = (pa_glib_mainloop*) source; pa_io_event *e; diff --git a/src/pulse/i18n.c b/src/pulse/i18n.c new file mode 100644 index 00000000..7f25b20d --- /dev/null +++ b/src/pulse/i18n.c @@ -0,0 +1,38 @@ +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulsecore/once.h> + +#include "i18n.h" + +void pa_init_i18n(void) { + + PA_ONCE_BEGIN { + + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + } PA_ONCE_END; +} diff --git a/src/pulse/i18n.h b/src/pulse/i18n.h new file mode 100644 index 00000000..4c0ef9d3 --- /dev/null +++ b/src/pulse/i18n.h @@ -0,0 +1,62 @@ +#ifndef foopulsei18nhfoo +#define foopulsei18nhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include <pulse/cdecl.h> +#include <pulse/gccmacro.h> + +PA_C_DECL_BEGIN + +#if !defined(GETTEXT_PACKAGE) +#error "Something is very wrong here, config.h needs to be included first" +#endif + +#ifdef ENABLE_NLS + +#include <libintl.h> + +#define _(String) dgettext(GETTEXT_PACKAGE, String) +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif + +#else /* NLS is disabled */ + +#define _(String) (String) +#define N_(String) (String) +#define textdomain(String) (String) +#define gettext(String) (String) +#define dgettext(Domain,String) (String) +#define dcgettext(Domain,String,Type) (String) +#define bindtextdomain(Domain,Directory) (Domain) +#define bind_textdomain_codeset(Domain,Codeset) (Codeset) + +#endif /* ENABLE_NLS */ + +void pa_init_i18n(void); + +PA_C_DECL_END + +#endif diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 9ed541d1..9167bf1b 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -28,6 +28,7 @@ #include <pulse/stream.h> #include <pulse/operation.h> #include <pulse/subscribe.h> +#include <pulse/ext-stream-restore.h> #include <pulsecore/socket-client.h> #include <pulsecore/pstream.h> @@ -63,7 +64,7 @@ struct pa_context { uint32_t version; uint32_t ctag; uint32_t csyncid; - uint32_t error; + int error; pa_context_state_t state; pa_context_notify_cb_t state_callback; @@ -74,9 +75,12 @@ struct pa_context { pa_mempool *mempool; pa_bool_t is_local:1; - pa_bool_t do_autospawn:1; pa_bool_t do_shm:1; - int autospawn_lock_fd; + + pa_bool_t do_autospawn:1; + pa_bool_t autospawn_locked:1; + int autospawn_fd; + pa_io_event *autospawn_event; pa_spawn_api spawn_api; pa_strlist *server_list; @@ -86,6 +90,12 @@ struct pa_context { pa_client_conf *conf; uint32_t client_index; + + /* Extension specific data */ + struct { + pa_ext_stream_restore_subscribe_cb_t callback; + void *userdata; + } ext_stream_restore; }; #define PA_MAX_WRITE_INDEX_CORRECTIONS 32 @@ -233,4 +243,6 @@ pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *ta #define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error) PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL) +void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t); + #endif diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 4be2c62a..4e362fd8 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -36,7 +36,7 @@ /*** Statistics ***/ -static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; pa_stat_info i, *p = &i; @@ -79,7 +79,7 @@ pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdat /*** Server Info ***/ -static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; pa_server_info i, *p = &i; @@ -127,7 +127,7 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, /*** Sink Info ***/ -static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -248,7 +248,7 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, /*** Source info ***/ -static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -369,7 +369,7 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name /*** Client info ***/ -static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -451,7 +451,7 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t /*** Module info ***/ -static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -530,7 +530,7 @@ pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t /*** Sink input info ***/ -static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -624,7 +624,7 @@ pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_c /*** Source output info ***/ -static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -954,7 +954,7 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name /** Sample Cache **/ -static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; @@ -1098,7 +1098,7 @@ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_cont return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata); } -static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; uint32_t idx; @@ -1159,7 +1159,7 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s /*** Autoload stuff ***/ -static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int eol = 1; diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index 6a6755e7..ca79f5b7 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -52,14 +52,14 @@ * Some objects can have multiple entries at the server. When requesting all * of these at once, the callback will be called multiple times, once for * each object. When the list has been exhausted, the callback will be called - * without an information structure and the eol parameter set to a non-zero + * without an information structure and the eol parameter set to a positive * value. * * Note that even if a single object is requested, and not the entire list, * the terminating call will still be made. * * If an error occurs, the callback will be called without and information - * structure and eol set to zero. + * structure and eol set to a negative value.. * * Data members in the information structures are only valid during the * duration of the callback. If they are required after the callback is @@ -210,11 +210,6 @@ PA_C_DECL_BEGIN -#define PA_PORT_DIGITAL "spdif" -#define PA_PORT_ANALOG_STEREO "analog-stereo" -#define PA_PORT_ANALOG_5_1 "analog-5-1" -#define PA_PORT_ANALOG_4_0 "analog-4-0" - /** @{ \name Sinks */ /** Stores information about sinks. Please note that this structure diff --git a/src/pulse/lock-autospawn.c b/src/pulse/lock-autospawn.c new file mode 100644 index 00000000..d36b669e --- /dev/null +++ b/src/pulse/lock-autospawn.c @@ -0,0 +1,330 @@ +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/poll.h> +#include <signal.h> +#include <pthread.h> + +#include <pulse/i18n.h> +#include <pulse/xmalloc.h> + +#include <pulsecore/mutex.h> +#include <pulsecore/thread.h> +#include <pulsecore/core-util.h> + +#include "lock-autospawn.h" + +/* So, why do we have this complex code here with threads and pipes + * and stuff? For two reasons: POSIX file locks are per-process, not + * per-file descriptor. That means that two contexts within the same + * process that try to create the autospawn lock might end up assuming + * they both managed to lock the file. And then, POSIX locking + * operations are synchronous. If two contexts run from the same event + * loop it must be made sure that they do not block each other, but + * that the locking operation can happen asynchronously. */ + +#define AUTOSPAWN_LOCK "autospawn.lock" + +static pa_mutex *mutex; + +static unsigned n_ref = 0; +static int lock_fd = -1; +static pa_mutex *lock_fd_mutex = NULL; +static pa_bool_t taken = FALSE; +static pa_thread *thread; +static int pipe_fd[2] = { -1, -1 }; + +static void destroy_mutex(void) PA_GCC_DESTRUCTOR; + +static int ref(void) { + + if (n_ref > 0) { + + pa_assert(pipe_fd[0] >= 0); + pa_assert(pipe_fd[1] >= 0); + + n_ref++; + + return 0; + } + + pa_assert(lock_fd < 0); + pa_assert(!lock_fd_mutex); + pa_assert(!taken); + pa_assert(!thread); + pa_assert(pipe_fd[0] < 0); + pa_assert(pipe_fd[1] < 0); + + if (pipe(pipe_fd) < 0) + return -1; + + lock_fd_mutex = pa_mutex_new(FALSE, FALSE); + + pa_make_fd_cloexec(pipe_fd[0]); + pa_make_fd_cloexec(pipe_fd[1]); + + pa_make_fd_nonblock(pipe_fd[1]); + pa_make_fd_nonblock(pipe_fd[0]); + + n_ref = 1; + return 0; +} + +static void unref(pa_bool_t after_fork) { + + pa_assert(n_ref > 0); + pa_assert(pipe_fd[0] >= 0); + pa_assert(pipe_fd[1] >= 0); + pa_assert(lock_fd_mutex); + + n_ref--; + + if (n_ref > 0) + return; + + pa_assert(!taken); + + if (thread) { + pa_thread_free(thread); + thread = NULL; + } + + pa_mutex_lock(lock_fd_mutex); + if (lock_fd >= 0) { + + if (after_fork) + pa_close(lock_fd); + else { + char *lf; + + if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) + pa_log_warn(_("Cannot access autospawn lock.")); + + pa_unlock_lockfile(lf, lock_fd); + pa_xfree(lf); + + lock_fd = -1; + } + } + pa_mutex_unlock(lock_fd_mutex); + + pa_mutex_free(lock_fd_mutex); + lock_fd_mutex = NULL; + + pa_close(pipe_fd[0]); + pa_close(pipe_fd[1]); + pipe_fd[0] = pipe_fd[1] = -1; +} + +static void ping(void) { + ssize_t s; + + pa_assert(pipe_fd[1] >= 0); + + for (;;) { + char x = 'x'; + + if ((s = write(pipe_fd[1], &x, 1)) == 1) + break; + + pa_assert(s < 0); + + if (errno == EAGAIN) + break; + + pa_assert(errno == EINTR); + } +} + +static void wait_for_ping(void) { + ssize_t s; + char x; + struct pollfd pfd; + int k; + + pa_assert(pipe_fd[0] >= 0); + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = pipe_fd[0]; + pfd.events = POLLIN; + + if ((k = poll(&pfd, 1, -1)) != 1) { + pa_assert(k < 0); + pa_assert(errno == EINTR); + } else if ((s = read(pipe_fd[0], &x, 1)) != 1) { + pa_assert(s < 0); + pa_assert(errno == EAGAIN); + } +} + +static void empty_pipe(void) { + char x[16]; + ssize_t s; + + pa_assert(pipe_fd[0] >= 0); + + if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) { + pa_assert(s < 0); + pa_assert(errno == EAGAIN); + } +} + +static void thread_func(void *u) { + int fd; + char *lf; + sigset_t fullset; + + /* No signals in this thread please */ + sigfillset(&fullset); + pthread_sigmask(SIG_BLOCK, &fullset, NULL); + + if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) { + pa_log_warn(_("Cannot access autospawn lock.")); + goto finish; + } + + if ((fd = pa_lock_lockfile(lf)) < 0) + goto finish; + + pa_mutex_lock(lock_fd_mutex); + pa_assert(lock_fd < 0); + lock_fd = fd; + pa_mutex_unlock(lock_fd_mutex); + +finish: + pa_xfree(lf); + + ping(); +} + +static int start_thread(void) { + + if (!thread) + if (!(thread = pa_thread_new(thread_func, NULL))) + return -1; + + return 0; +} + +static void create_mutex(void) { + PA_ONCE_BEGIN { + mutex = pa_mutex_new(FALSE, FALSE); + } PA_ONCE_END; +} + +static void destroy_mutex(void) { + + if (mutex) + pa_mutex_free(mutex); +} + + +int pa_autospawn_lock_init(void) { + int ret = -1; + + create_mutex(); + pa_mutex_lock(mutex); + + if (ref() < 0) + ret = -1; + else + ret = pipe_fd[0]; + + pa_mutex_unlock(mutex); + + return ret; +} + +int pa_autospawn_lock_acquire(pa_bool_t block) { + int ret = -1; + + create_mutex(); + pa_mutex_lock(mutex); + pa_assert(n_ref >= 1); + + pa_mutex_lock(lock_fd_mutex); + + for (;;) { + + empty_pipe(); + + if (lock_fd >= 0 && !taken) { + taken = TRUE; + ret = 1; + break; + } + + if (lock_fd < 0) + if (start_thread() < 0) + break; + + if (!block) { + ret = 0; + break; + } + + pa_mutex_unlock(lock_fd_mutex); + pa_mutex_unlock(mutex); + + wait_for_ping(); + + pa_mutex_lock(mutex); + pa_mutex_lock(lock_fd_mutex); + } + + pa_mutex_unlock(lock_fd_mutex); + + pa_mutex_unlock(mutex); + + return ret; +} + +void pa_autospawn_lock_release(void) { + + create_mutex(); + pa_mutex_lock(mutex); + pa_assert(n_ref >= 1); + + pa_assert(taken); + taken = FALSE; + + ping(); + + pa_mutex_unlock(mutex); +} + +void pa_autospawn_lock_done(pa_bool_t after_fork) { + + create_mutex(); + pa_mutex_lock(mutex); + pa_assert(n_ref >= 1); + + unref(after_fork); + + pa_mutex_unlock(mutex); +} diff --git a/src/pulse/lock-autospawn.h b/src/pulse/lock-autospawn.h new file mode 100644 index 00000000..c04c4bd1 --- /dev/null +++ b/src/pulse/lock-autospawn.h @@ -0,0 +1,32 @@ +#ifndef foopulselockautospawnhfoo +#define foopulselockautospawnhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include <pulsecore/macro.h> + +int pa_autospawn_lock_init(void); +int pa_autospawn_lock_acquire(pa_bool_t block); +void pa_autospawn_lock_release(void); +void pa_autospawn_lock_done(pa_bool_t after_fork); + +#endif diff --git a/src/pulse/mainloop-api.c b/src/pulse/mainloop-api.c index 90aff164..4b862f9a 100644 --- a/src/pulse/mainloop-api.c +++ b/src/pulse/mainloop-api.c @@ -27,6 +27,7 @@ #include <pulse/xmalloc.h> #include <pulse/gccmacro.h> +#include <pulse/i18n.h> #include <pulsecore/macro.h> @@ -50,7 +51,7 @@ static void once_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) m->defer_free(e); } -static void free_callback(pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event *e, void *userdata) { +static void free_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { struct once_info *i = userdata; pa_assert(m); @@ -65,6 +66,8 @@ void pa_mainloop_api_once(pa_mainloop_api* m, void (*callback)(pa_mainloop_api * pa_assert(m); pa_assert(callback); + pa_init_i18n(); + i = pa_xnew(struct once_info, 1); i->callback = callback; i->userdata = userdata; diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index 9161dec4..d09f4b0a 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -38,6 +38,7 @@ #include <pulse/xmalloc.h> #include <pulse/gccmacro.h> +#include <pulse/i18n.h> #include <pulsecore/core-error.h> #include <pulsecore/core-util.h> @@ -89,7 +90,7 @@ static void dispatch(pa_mainloop_api*a, int sig) { } } -static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) { +static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) { ssize_t r; int sig; @@ -165,6 +166,8 @@ pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t _callback, void *userdata pa_assert(sig > 0); pa_assert(_callback); + pa_init_i18n(); + for (e = signals; e; e = e->next) if (e->sig == sig) goto fail; diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index aaed3caf..60e5d1ff 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -44,6 +44,7 @@ #include <pulse/timeval.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/llist.h> @@ -56,7 +57,7 @@ struct pa_io_event { pa_mainloop *mainloop; - int dead; + pa_bool_t dead:1; int fd; pa_io_event_flags_t events; @@ -71,9 +72,9 @@ struct pa_io_event { struct pa_time_event { pa_mainloop *mainloop; - int dead; + pa_bool_t dead:1; - int enabled; + pa_bool_t enabled:1; struct timeval timeval; pa_time_event_cb_t callback; @@ -85,9 +86,9 @@ struct pa_time_event { struct pa_defer_event { pa_mainloop *mainloop; - int dead; + pa_bool_t dead:1; - int enabled; + pa_bool_t enabled:1; pa_defer_event_cb_t callback; void *userdata; @@ -101,22 +102,24 @@ struct pa_mainloop { PA_LLIST_HEAD(pa_time_event, time_events); PA_LLIST_HEAD(pa_defer_event, defer_events); - int n_enabled_defer_events, n_enabled_time_events, n_io_events; - int io_events_please_scan, time_events_please_scan, defer_events_please_scan; + unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events; + unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan; + pa_bool_t rebuild_pollfds:1; struct pollfd *pollfds; unsigned max_pollfds, n_pollfds; - int rebuild_pollfds; int prepared_timeout; pa_time_event *cached_next_time_event; - int quit, retval; pa_mainloop_api api; + int retval; + pa_bool_t quit:1; + + pa_bool_t wakeup_requested:1; int wakeup_pipe[2]; int wakeup_pipe_type; - int wakeup_requested; enum { STATE_PASSIVE, @@ -132,11 +135,11 @@ struct pa_mainloop { }; static short map_flags_to_libc(pa_io_event_flags_t flags) { - return - (flags & PA_IO_EVENT_INPUT ? POLLIN : 0) | - (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) | - (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) | - (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0); + return (short) + ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) | + (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) | + (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) | + (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0)); } static pa_io_event_flags_t map_flags_from_libc(short flags) { @@ -168,7 +171,7 @@ static pa_io_event* mainloop_io_new( e = pa_xnew(pa_io_event, 1); e->mainloop = m; - e->dead = 0; + e->dead = FALSE; e->fd = fd; e->events = events; @@ -193,13 +196,13 @@ static pa_io_event* mainloop_io_new( SELECT_TYPE_ARG5 &tv) == -1) && (WSAGetLastError() == WSAENOTSOCK)) { pa_log_warn("Cannot monitor non-socket file descriptors."); - e->dead = 1; + e->dead = TRUE; } } #endif PA_LLIST_PREPEND(pa_io_event, m->io_events, e); - m->rebuild_pollfds = 1; + m->rebuild_pollfds = TRUE; m->n_io_events ++; pa_mainloop_wakeup(m); @@ -219,7 +222,7 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) { if (e->pollfd) e->pollfd->events = map_flags_to_libc(events); else - e->mainloop->rebuild_pollfds = 1; + e->mainloop->rebuild_pollfds = TRUE; pa_mainloop_wakeup(e->mainloop); } @@ -228,11 +231,11 @@ static void mainloop_io_free(pa_io_event *e) { pa_assert(e); pa_assert(!e->dead); - e->dead = 1; + e->dead = TRUE; e->mainloop->io_events_please_scan ++; e->mainloop->n_io_events --; - e->mainloop->rebuild_pollfds = 1; + e->mainloop->rebuild_pollfds = TRUE; pa_mainloop_wakeup(e->mainloop); } @@ -261,9 +264,9 @@ static pa_defer_event* mainloop_defer_new( e = pa_xnew(pa_defer_event, 1); e->mainloop = m; - e->dead = 0; + e->dead = FALSE; - e->enabled = 1; + e->enabled = TRUE; m->n_enabled_defer_events++; e->callback = callback; @@ -296,13 +299,13 @@ static void mainloop_defer_free(pa_defer_event *e) { pa_assert(e); pa_assert(!e->dead); - e->dead = 1; + e->dead = TRUE; e->mainloop->defer_events_please_scan ++; if (e->enabled) { pa_assert(e->mainloop->n_enabled_defer_events > 0); e->mainloop->n_enabled_defer_events--; - e->enabled = 0; + e->enabled = FALSE; } } @@ -332,7 +335,7 @@ static pa_time_event* mainloop_time_new( e = pa_xnew(pa_time_event, 1); e->mainloop = m; - e->dead = 0; + e->dead = FALSE; if ((e->enabled = !!tv)) { e->timeval = *tv; @@ -387,13 +390,13 @@ static void mainloop_time_free(pa_time_event *e) { pa_assert(e); pa_assert(!e->dead); - e->dead = 1; + e->dead = TRUE; e->mainloop->time_events_please_scan ++; if (e->enabled) { pa_assert(e->mainloop->n_enabled_time_events > 0); e->mainloop->n_enabled_time_events--; - e->enabled = 0; + e->enabled = FALSE; } if (e->mainloop->cached_next_time_event == e) @@ -446,6 +449,8 @@ static const pa_mainloop_api vtable = { pa_mainloop *pa_mainloop_new(void) { pa_mainloop *m; + pa_init_i18n(); + m = pa_xnew(pa_mainloop, 1); m->wakeup_pipe_type = 0; @@ -459,7 +464,7 @@ pa_mainloop *pa_mainloop_new(void) { pa_make_fd_nonblock(m->wakeup_pipe[1]); pa_make_fd_cloexec(m->wakeup_pipe[0]); pa_make_fd_cloexec(m->wakeup_pipe[1]); - m->wakeup_requested = 0; + m->wakeup_requested = FALSE; PA_LLIST_HEAD_INIT(pa_io_event, m->io_events); PA_LLIST_HEAD_INIT(pa_time_event, m->time_events); @@ -473,9 +478,10 @@ pa_mainloop *pa_mainloop_new(void) { m->pollfds = NULL; m->max_pollfds = m->n_pollfds = 0; - m->rebuild_pollfds = 1; + m->rebuild_pollfds = TRUE; - m->quit = m->retval = 0; + m->quit = FALSE; + m->retval = 0; m->api = vtable; m->api.userdata = m; @@ -489,7 +495,7 @@ pa_mainloop *pa_mainloop_new(void) { return m; } -static void cleanup_io_events(pa_mainloop *m, int force) { +static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) { pa_io_event *e; e = m->io_events; @@ -512,7 +518,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) { pa_xfree(e); - m->rebuild_pollfds = 1; + m->rebuild_pollfds = TRUE; } e = n; @@ -521,7 +527,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) { pa_assert(m->io_events_please_scan == 0); } -static void cleanup_time_events(pa_mainloop *m, int force) { +static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) { pa_time_event *e; e = m->time_events; @@ -542,7 +548,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) { if (!e->dead && e->enabled) { pa_assert(m->n_enabled_time_events > 0); m->n_enabled_time_events--; - e->enabled = 0; + e->enabled = FALSE; } if (e->destroy_callback) @@ -557,7 +563,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) { pa_assert(m->time_events_please_scan == 0); } -static void cleanup_defer_events(pa_mainloop *m, int force) { +static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) { pa_defer_event *e; e = m->defer_events; @@ -578,7 +584,7 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { if (!e->dead && e->enabled) { pa_assert(m->n_enabled_defer_events > 0); m->n_enabled_defer_events--; - e->enabled = 0; + e->enabled = FALSE; } if (e->destroy_callback) @@ -597,9 +603,9 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { void pa_mainloop_free(pa_mainloop* m) { pa_assert(m); - cleanup_io_events(m, 1); - cleanup_defer_events(m, 1); - cleanup_time_events(m, 1); + cleanup_io_events(m, TRUE); + cleanup_defer_events(m, TRUE); + cleanup_time_events(m, TRUE); pa_xfree(m->pollfds); @@ -612,13 +618,13 @@ static void scan_dead(pa_mainloop *m) { pa_assert(m); if (m->io_events_please_scan) - cleanup_io_events(m, 0); + cleanup_io_events(m, FALSE); if (m->time_events_please_scan) - cleanup_time_events(m, 0); + cleanup_time_events(m, FALSE); if (m->defer_events_please_scan) - cleanup_defer_events(m, 0); + cleanup_defer_events(m, FALSE); } static void rebuild_pollfds(pa_mainloop *m) { @@ -659,7 +665,7 @@ static void rebuild_pollfds(pa_mainloop *m) { m->n_pollfds++; } - m->rebuild_pollfds = 0; + m->rebuild_pollfds = FALSE; } static int dispatch_pollfds(pa_mainloop *m) { @@ -945,7 +951,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) { void pa_mainloop_quit(pa_mainloop *m, int retval) { pa_assert(m); - m->quit = 1; + m->quit = TRUE; m->retval = retval; pa_mainloop_wakeup(m); } diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c index 74aea20a..93bc0034 100644 --- a/src/pulse/proplist.c +++ b/src/pulse/proplist.c @@ -27,6 +27,7 @@ #include <pulse/xmalloc.h> #include <pulse/utf8.h> +#include <pulse/i18n.h> #include <pulsecore/hashmap.h> #include <pulsecore/strbuf.h> @@ -63,6 +64,8 @@ static void property_free(struct property *prop) { } pa_proplist* pa_proplist_new(void) { + pa_init_i18n(); + return MAKE_PROPLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func)); } @@ -277,7 +280,7 @@ char *pa_proplist_to_string(pa_proplist *p) { char *c; pa_assert_se(pa_proplist_get(p, key, &value, &nbytes) == 0); - c = pa_xnew(char, nbytes*2+1); + c = pa_xmalloc(nbytes*2+1); pa_hexstr((const uint8_t*) value, nbytes, c, nbytes*2+1); pa_strbuf_printf(buf, "%s = hex:%s\n", key, c); diff --git a/src/pulse/sample.c b/src/pulse/sample.c index 4aef5bb0..93da2465 100644 --- a/src/pulse/sample.c +++ b/src/pulse/sample.c @@ -28,9 +28,11 @@ #include <math.h> #include <string.h> +#include <pulse/timeval.h> +#include <pulse/i18n.h> + #include <pulsecore/core-util.h> #include <pulsecore/macro.h> -#include <pulse/timeval.h> #include "sample.h" @@ -126,8 +128,10 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { pa_assert(l); pa_assert(spec); + pa_init_i18n(); + if (!pa_sample_spec_valid(spec)) - pa_snprintf(s, l, "Invalid"); + pa_snprintf(s, l, _("Invalid")); else pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate); diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 5e31e7af..fd3b9876 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -47,6 +47,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) { PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID); + PA_CHECK_VALIDITY(s->context, length == (size_t) (uint32_t) length, PA_ERR_INVALID); if (!(name = pa_proplist_gets(s->proplist, PA_PROP_EVENT_ID))) name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME); @@ -63,7 +64,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) { pa_tagstruct_puts(t, name); pa_tagstruct_put_sample_spec(t, &s->sample_spec); pa_tagstruct_put_channel_map(t, &s->channel_map); - pa_tagstruct_putu32(t, length); + pa_tagstruct_putu32(t, (uint32_t) length); if (s->context->version >= 13) { pa_init_proplist(s->proplist); diff --git a/src/pulse/simple.c b/src/pulse/simple.c index 70396835..51160ad7 100644 --- a/src/pulse/simple.c +++ b/src/pulse/simple.c @@ -453,4 +453,3 @@ unlock_and_fail: pa_threaded_mainloop_unlock(p->mainloop); return (pa_usec_t) -1; } - diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 585518f0..536a82ce 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -124,7 +124,7 @@ pa_stream *pa_stream_new_with_proplist( * what older PA versions provided. */ s->buffer_attr.maxlength = (uint32_t) -1; - s->buffer_attr.tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */ + s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */ s->buffer_attr.minreq = (uint32_t) -1; s->buffer_attr.prebuf = (uint32_t) -1; s->buffer_attr.fragsize = (uint32_t) -1; @@ -315,7 +315,7 @@ static void request_auto_timing_update(pa_stream *s, pa_bool_t force) { } } -void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; pa_stream *s; uint32_t channel; @@ -382,7 +382,7 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t * if prebuf is non-zero! */ } -void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; pa_stream *s; uint32_t channel; @@ -479,7 +479,7 @@ finish: pa_context_unref(c); } -void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; pa_stream *s; uint32_t channel; @@ -563,7 +563,7 @@ finish: pa_context_unref(c); } -void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s; pa_context *c = userdata; uint32_t bytes, channel; @@ -598,7 +598,7 @@ finish: pa_context_unref(c); } -void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s; pa_context *c = userdata; uint32_t channel; @@ -670,7 +670,7 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) { request_auto_timing_update(s, TRUE); } -static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void auto_timing_update_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) { pa_stream *s = userdata; pa_assert(s); @@ -694,7 +694,7 @@ static void create_stream_complete(pa_stream *s) { if (s->flags & PA_STREAM_AUTO_TIMING_UPDATE) { struct timeval tv; pa_gettimeofday(&tv); - tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ + tv.tv_usec += (suseconds_t) LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ pa_assert(!s->auto_timing_update_event); s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s); @@ -722,7 +722,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */ if (attr->tlength == (uint32_t) -1) - attr->tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */ + attr->tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */ if (attr->minreq == (uint32_t) -1) attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */ @@ -734,7 +734,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s attr->fragsize = attr->tlength; /* Pass data to the app only when the buffer is filled up once */ } -void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; pa_assert(pd); @@ -865,6 +865,7 @@ static int create_stream( pa_tagstruct *t; uint32_t tag; + pa_bool_t volume_set = FALSE; pa_assert(s); pa_assert(PA_REFCNT_VALUE(s) >= 1); @@ -930,7 +931,7 @@ static int create_stream( t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM, + (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM), &tag); if (s->context->version < 13) @@ -957,6 +958,8 @@ static int create_stream( PA_TAG_U32, s->syncid, PA_TAG_INVALID); + volume_set = !!volume; + if (!volume) volume = pa_cvolume_reset(&cv, s->sample_spec.channels); @@ -994,6 +997,15 @@ static int create_stream( pa_tagstruct_putu32(t, s->direct_on_input); } + if (s->context->version >= 14 && + s->direction == PA_STREAM_PLAYBACK) { + + pa_tagstruct_put( + t, + PA_TAG_BOOLEAN, volume_set, + PA_TAG_INVALID); + } + pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL); @@ -1093,7 +1105,7 @@ int pa_stream_write( free_cb((void*) data); if (length < s->requested_bytes) - s->requested_bytes -= length; + s->requested_bytes -= (uint32_t) length; else s->requested_bytes = 0; @@ -1107,10 +1119,10 @@ int pa_stream_write( if (seek == PA_SEEK_ABSOLUTE) { s->write_index_corrections[s->current_write_index_correction].corrupt = FALSE; s->write_index_corrections[s->current_write_index_correction].absolute = TRUE; - s->write_index_corrections[s->current_write_index_correction].value = offset + length; + s->write_index_corrections[s->current_write_index_correction].value = offset + (int64_t) length; } else if (seek == PA_SEEK_RELATIVE) { if (!s->write_index_corrections[s->current_write_index_correction].corrupt) - s->write_index_corrections[s->current_write_index_correction].value += offset + length; + s->write_index_corrections[s->current_write_index_correction].value += offset + (int64_t) length; } else s->write_index_corrections[s->current_write_index_correction].corrupt = TRUE; } @@ -1120,10 +1132,10 @@ int pa_stream_write( if (seek == PA_SEEK_ABSOLUTE) { s->timing_info.write_index_corrupt = FALSE; - s->timing_info.write_index = offset + length; + s->timing_info.write_index = offset + (int64_t) length; } else if (seek == PA_SEEK_RELATIVE) { if (!s->timing_info.write_index_corrupt) - s->timing_info.write_index += offset + length; + s->timing_info.write_index += offset + (int64_t) length; } else s->timing_info.write_index_corrupt = TRUE; } @@ -1173,7 +1185,7 @@ int pa_stream_drop(pa_stream *s) { /* Fix the simulated local read index */ if (s->timing_info_valid && !s->timing_info.read_index_corrupt) - s->timing_info.read_index += s->peek_memchunk.length; + s->timing_info.read_index += (int64_t) s->peek_memchunk.length; pa_assert(s->peek_data); pa_memblock_release(s->peek_memchunk.memblock); @@ -1257,7 +1269,9 @@ static pa_usec_t calc_time(pa_stream *s, pa_bool_t ignore_transport) { usec -= s->timing_info.sink_usec; } - } else if (s->direction == PA_STREAM_RECORD) { + } else { + pa_assert(s->direction == PA_STREAM_RECORD); + /* The last byte written into the server side queue had * this time value associated */ usec = pa_bytes_to_usec(s->timing_info.write_index < 0 ? 0 : (uint64_t) s->timing_info.write_index, &s->sample_spec); @@ -1340,7 +1354,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, i->read_index_corrupt = FALSE; i->playing = (int) playing; - i->since_underrun = playing ? playing_for : underrun_for; + i->since_underrun = (int64_t) (playing ? playing_for : underrun_for); pa_gettimeofday(&now); @@ -1418,7 +1432,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, /* Read index correction */ if (!i->read_index_corrupt) - i->read_index -= pa_memblockq_get_length(o->stream->record_memblockq); + i->read_index -= (int64_t) pa_memblockq_get_length(o->stream->record_memblockq); } /* Update smoother */ @@ -1435,7 +1449,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, * speakers. Since we follow that timing here, we need * to try to fix this up */ - su = pa_bytes_to_usec(i->since_underrun, &o->stream->sample_spec); + su = pa_bytes_to_usec((uint64_t) i->since_underrun, &o->stream->sample_spec); if (su < i->sink_usec) x += i->sink_usec - su; @@ -1494,7 +1508,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY, + (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY), &tag); pa_tagstruct_putu32(t, s->channel); pa_tagstruct_put_timeval(t, pa_gettimeofday(&now)); @@ -1517,7 +1531,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t return o; } -void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; pa_assert(pd); @@ -1557,8 +1571,8 @@ int pa_stream_disconnect(pa_stream *s) { t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM : - (s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM), + (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM : + (s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM)), &tag); pa_tagstruct_putu32(t, s->channel); pa_pstream_send_tagstruct(s->context->pstream, t); @@ -1667,7 +1681,7 @@ void pa_stream_set_started_callback(pa_stream *s, pa_stream_notify_cb_t cb, void s->started_userdata = userdata; } -void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; @@ -1715,7 +1729,7 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM, + (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM), &tag); pa_tagstruct_putu32(t, s->channel); pa_tagstruct_put_boolean(t, !!b); @@ -1760,7 +1774,7 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); - if (!(o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata))) + if (!(o = stream_send_simple_command(s, (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM), cb, userdata))) return NULL; if (s->direction == PA_STREAM_PLAYBACK) { @@ -1846,7 +1860,7 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME, + (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME), &tag); pa_tagstruct_putu32(t, s->channel); pa_tagstruct_puts(t, name); @@ -1932,7 +1946,7 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { if (cindex < 0) cindex = 0; - c = pa_bytes_to_usec(cindex, &s->sample_spec); + c = pa_bytes_to_usec((uint64_t) cindex, &s->sample_spec); if (s->direction == PA_STREAM_PLAYBACK) *r_usec = time_counter_diff(s, c, t, negative); @@ -1978,7 +1992,7 @@ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) { return &s->buffer_attr; } -static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; @@ -2046,7 +2060,7 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR, + (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR), &tag); pa_tagstruct_putu32(t, s->channel); @@ -2120,7 +2134,7 @@ int pa_stream_is_corked(pa_stream *s) { return s->corked; } -static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; @@ -2177,7 +2191,7 @@ pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_strea t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE, + (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE), &tag); pa_tagstruct_putu32(t, s->channel); pa_tagstruct_putu32(t, rate); @@ -2205,7 +2219,7 @@ pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_ t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST, + (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST), &tag); pa_tagstruct_putu32(t, s->channel); pa_tagstruct_putu32(t, (uint32_t) mode); @@ -2238,7 +2252,7 @@ pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[], t = pa_tagstruct_command( s->context, - s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST, + (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST), &tag); pa_tagstruct_putu32(t, s->channel); diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c index d9c06b7e..e12d1446 100644 --- a/src/pulse/subscribe.c +++ b/src/pulse/subscribe.c @@ -34,7 +34,7 @@ #include "subscribe.h" -void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; pa_subscription_event_type_t e; uint32_t idx; @@ -61,7 +61,6 @@ finish: pa_context_unref(c); } - pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 6b66696c..fb73ff1b 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -35,6 +35,7 @@ #include <pulse/xmalloc.h> #include <pulse/mainloop.h> +#include <pulse/i18n.h> #include <pulsecore/log.h> #include <pulsecore/hashmap.h> @@ -94,6 +95,8 @@ static void thread(void *userdata) { pa_threaded_mainloop *pa_threaded_mainloop_new(void) { pa_threaded_mainloop *m; + pa_init_i18n(); + m = pa_xnew(pa_threaded_mainloop, 1); if (!(m->real_mainloop = pa_mainloop_new())) { diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 9708a735..376cf13c 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -90,13 +90,13 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { } /* Calculate the second difference*/ - r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC; + r = ((pa_usec_t) a->tv_sec - (pa_usec_t) b->tv_sec) * PA_USEC_PER_SEC; /* Calculate the microsecond difference */ if (a->tv_usec > b->tv_usec) - r += ((pa_usec_t) a->tv_usec - b->tv_usec); + r += ((pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec); else if (a->tv_usec < b->tv_usec) - r -= ((pa_usec_t) b->tv_usec - a->tv_usec); + r -= ((pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec); return r; } @@ -132,7 +132,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { pa_assert(tv); secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec += secs; + tv->tv_sec += (time_t) secs; v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; tv->tv_usec += (suseconds_t) v; @@ -140,7 +140,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { /* Normalize */ while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) { tv->tv_sec++; - tv->tv_usec -= PA_USEC_PER_SEC; + tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC; } return tv; @@ -151,14 +151,14 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) { pa_assert(tv); secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec -= secs; + tv->tv_sec -= (time_t) secs; v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; if (tv->tv_usec >= (suseconds_t) v) tv->tv_usec -= (suseconds_t) v; else { tv->tv_sec --; - tv->tv_usec = tv->tv_usec + PA_USEC_PER_SEC - v; + tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v); } return tv; @@ -167,8 +167,8 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) { struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { pa_assert(tv); - tv->tv_sec = v / PA_USEC_PER_SEC; - tv->tv_usec = v % PA_USEC_PER_SEC; + tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC); return tv; } diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 119be542..91aa9c81 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -109,17 +109,17 @@ static char* utf8_validate(const char *str, char *output) { if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */ size = 2; min = 128; - val = *p & 0x1e; + val = (uint32_t) (*p & 0x1e); goto ONE_REMAINING; } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/ size = 3; min = (1 << 11); - val = *p & 0x0f; + val = (uint32_t) (*p & 0x0f); goto TWO_REMAINING; } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */ size = 4; min = (1 << 16); - val = *p & 0x07; + val = (uint32_t) (*p & 0x07); } else { size = 1; goto error; @@ -149,7 +149,7 @@ ONE_REMAINING: goto error; if (o) { - memcpy(o, last, size); + memcpy(o, last, (size_t) size); o += size - 1; } @@ -189,7 +189,7 @@ char* pa_utf8_filter (const char *str) { char *new_str; pa_assert(str); - new_str = pa_xnew(char, strlen(str) + 1); + new_str = pa_xmalloc(strlen(str) + 1); return utf8_validate(str, new_str); } @@ -212,7 +212,7 @@ static char* iconv_simple(const char *str, const char *to, const char *from) { return NULL; inlen = len = strlen(str) + 1; - new_str = pa_xnew(char, len); + new_str = pa_xmalloc(len); for (;;) { inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */ diff --git a/src/pulse/util.c b/src/pulse/util.c index c0911b51..b20ea46a 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -95,12 +95,15 @@ char *pa_get_user_name(char *s, size_t l) { #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */ DWORD size = sizeof(buf); - if (!GetUserName(buf, &size)) + if (!GetUserName(buf, &size)) { + errno = ENOENT; return NULL; + } p = buf; #else /* HAVE_PWD_H */ + return NULL; #endif /* HAVE_PWD_H */ } @@ -113,10 +116,8 @@ char *pa_get_host_name(char *s, size_t l) { pa_assert(s); pa_assert(l > 0); - if (gethostname(s, l) < 0) { - pa_log("gethostname(): %s", pa_cstrerror(errno)); + if (gethostname(s, l) < 0) return NULL; - } s[l-1] = 0; return s; @@ -140,20 +141,25 @@ char *pa_get_home_dir(char *s, size_t l) { return pa_strlcpy(s, e, l); #ifdef HAVE_PWD_H + + errno = 0; #ifdef HAVE_GETPWUID_R if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { - pa_log("getpwuid_r() failed"); #else /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) * that do not support getpwuid_r. */ if ((r = getpwuid(getuid())) == NULL) { - pa_log("getpwuid_r() failed"); #endif + if (!errno) + errno = ENOENT; + return NULL; } return pa_strlcpy(s, r->pw_dir, l); #else /* HAVE_PWD_H */ + + errno = ENOENT; return NULL; #endif } @@ -204,6 +210,7 @@ char *pa_get_binary_name(char *s, size_t l) { } #endif + errno = ENOENT; return NULL; } @@ -253,8 +260,8 @@ int pa_msleep(unsigned long t) { #elif defined(HAVE_NANOSLEEP) struct timespec ts; - ts.tv_sec = t/1000; - ts.tv_nsec = (t % 1000) * 1000000; + ts.tv_sec = (time_t) (t/1000UL); + ts.tv_nsec = (long) ((t % 1000UL) * 1000000UL); return nanosleep(&ts, NULL); #else diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 70d6f86a..768bf49c 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -53,7 +53,7 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) { pa_assert(channels > 0); pa_assert(channels <= PA_CHANNELS_MAX); - a->channels = channels; + a->channels = (uint8_t) channels; for (i = 0; i < a->channels; i++) a->values[i] = v; @@ -74,6 +74,18 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) { return (pa_volume_t) sum; } +pa_volume_t pa_cvolume_max(const pa_cvolume *a) { + pa_volume_t m = 0; + int i; + pa_assert(a); + + for (i = 0; i < a->channels; i++) + if (a->values[i] > m) + m = a->values[i]; + + return m; +} + pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) { return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a)* pa_sw_volume_to_linear(b)); } @@ -163,7 +175,7 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const i < b->channels ? b->values[i] : PA_VOLUME_NORM); } - dest->channels = i; + dest->channels = (uint8_t) i; return dest; } @@ -176,3 +188,88 @@ int pa_cvolume_valid(const pa_cvolume *v) { return 1; } + +static pa_bool_t on_left(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_LEFT || + p == PA_CHANNEL_POSITION_REAR_LEFT || + p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER || + p == PA_CHANNEL_POSITION_SIDE_LEFT || + p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT || + p == PA_CHANNEL_POSITION_TOP_REAR_LEFT; +} + +static pa_bool_t on_right(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_RIGHT || + p == PA_CHANNEL_POSITION_REAR_RIGHT || + p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER || + p == PA_CHANNEL_POSITION_SIDE_RIGHT || + p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT || + p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT; +} + +static pa_bool_t on_center(pa_channel_position_t p) { + + return + p == PA_CHANNEL_POSITION_FRONT_CENTER || + p == PA_CHANNEL_POSITION_REAR_CENTER || + p == PA_CHANNEL_POSITION_TOP_CENTER || + p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER || + p == PA_CHANNEL_POSITION_TOP_REAR_CENTER; +} + +static pa_bool_t on_lfe(pa_channel_position_t p) { + return + p == PA_CHANNEL_POSITION_LFE; +} + +pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to) { + int a, b; + pa_cvolume result; + + pa_assert(v); + pa_assert(from); + pa_assert(to); + pa_assert(v->channels == from->channels); + + if (pa_channel_map_equal(from, to)) + return v; + + result.channels = to->channels; + + for (b = 0; b < to->channels; b++) { + pa_volume_t k = 0; + int n = 0; + + for (a = 0; a < from->channels; a++) + if (from->map[a] == to->map[b]) { + k += v->values[a]; + n ++; + } + + if (n <= 0) { + for (a = 0; a < from->channels; a++) + if ((on_left(from->map[a]) && on_left(to->map[b])) || + (on_right(from->map[a]) && on_right(to->map[b])) || + (on_center(from->map[a]) && on_center(to->map[b])) || + (on_lfe(from->map[a]) && on_lfe(to->map[b]))) { + + k += v->values[a]; + n ++; + } + } + + if (n <= 0) + k = pa_cvolume_avg(v); + else + k /= n; + + result.values[b] = k; + } + + *v = result; + return v; +} diff --git a/src/pulse/volume.h b/src/pulse/volume.h index 5cce083e..d612c7f9 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -28,6 +28,7 @@ #include <pulse/cdecl.h> #include <pulse/gccmacro.h> #include <pulse/sample.h> +#include <pulse/channelmap.h> /** \page volume Volume Control * @@ -133,6 +134,9 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c); /** Return the average volume of all channels */ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE; +/** Return the maximum volume of all channels. \since 0.9.12 */ +pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE; + /** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */ int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE; @@ -170,6 +174,9 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST; #define PA_DECIBEL_MININFTY ((double) -200.0) #endif +/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */ +pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to); + PA_C_DECL_END #endif diff --git a/src/pulse/xmalloc.c b/src/pulse/xmalloc.c index 90237013..d1138d65 100644 --- a/src/pulse/xmalloc.c +++ b/src/pulse/xmalloc.c @@ -113,7 +113,7 @@ char *pa_xstrndup(const char *s, size_t l) { return NULL; if ((e = memchr(s, 0, l))) - return pa_xmemdup(s, e-s+1); + return pa_xmemdup(s, (size_t) (e-s+1)); r = pa_xmalloc(l+1); memcpy(r, s, l); diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index 03e9f0df..f64931a5 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -71,7 +71,7 @@ PA_STATIC_FLIST_DECLARE(localq, 0, pa_xfree); #define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq)))) -static int reduce(pa_asyncq *l, int value) { +static unsigned reduce(pa_asyncq *l, unsigned value) { return value & (unsigned) (l->size - 1); } @@ -132,7 +132,7 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { } static int push(pa_asyncq*l, void *p, pa_bool_t wait) { - int idx; + unsigned idx; pa_atomic_ptr_t *cells; pa_assert(l); @@ -220,7 +220,7 @@ void pa_asyncq_post(pa_asyncq*l, void *p) { } void* pa_asyncq_pop(pa_asyncq*l, pa_bool_t wait) { - int idx; + unsigned idx; void *ret; pa_atomic_ptr_t *cells; @@ -263,7 +263,7 @@ int pa_asyncq_read_fd(pa_asyncq *q) { } int pa_asyncq_read_before_poll(pa_asyncq *l) { - int idx; + unsigned idx; pa_atomic_ptr_t *cells; pa_assert(l); @@ -280,8 +280,6 @@ int pa_asyncq_read_before_poll(pa_asyncq *l) { if (pa_fdsem_before_poll(l->write_fdsem) >= 0) return 0; } - - return 0; } void pa_asyncq_read_after_poll(pa_asyncq *l) { diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index a91c4d56..072943ab 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -420,7 +420,7 @@ typedef struct pa_atomic { volatile AO_t value; } pa_atomic_t; -#define PA_ATOMIC_INIT(v) { .value = (v) } +#define PA_ATOMIC_INIT(v) { .value = (AO_t) (v) } static inline int pa_atomic_load(const pa_atomic_t *a) { return (int) AO_load_full((AO_t*) &a->value); @@ -431,23 +431,23 @@ static inline void pa_atomic_store(pa_atomic_t *a, int i) { } static inline int pa_atomic_add(pa_atomic_t *a, int i) { - return AO_fetch_and_add_full(&a->value, (AO_t) i); + return (int) AO_fetch_and_add_full(&a->value, (AO_t) i); } static inline int pa_atomic_sub(pa_atomic_t *a, int i) { - return AO_fetch_and_add_full(&a->value, (AO_t) -i); + return (int) AO_fetch_and_add_full(&a->value, (AO_t) -i); } static inline int pa_atomic_inc(pa_atomic_t *a) { - return AO_fetch_and_add1_full(&a->value); + return (int) AO_fetch_and_add1_full(&a->value); } static inline int pa_atomic_dec(pa_atomic_t *a) { - return AO_fetch_and_sub1_full(&a->value); + return (int) AO_fetch_and_sub1_full(&a->value); } static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { - return AO_compare_and_swap_full(&a->value, old_i, new_i); + return AO_compare_and_swap_full(&a->value, (unsigned long) old_i, (unsigned long) new_i); } typedef struct pa_atomic_ptr { diff --git a/src/pulsecore/authkey-prop.c b/src/pulsecore/authkey-prop.c deleted file mode 100644 index d52bdcf4..00000000 --- a/src/pulsecore/authkey-prop.c +++ /dev/null @@ -1,104 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2004-2006 Lennart Poettering - - 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. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <pulse/xmalloc.h> - -#include <pulsecore/shared.h> -#include <pulsecore/macro.h> -#include <pulsecore/log.h> -#include <pulsecore/refcnt.h> - -#include "authkey-prop.h" - -struct authkey_data { - PA_REFCNT_DECLARE; - size_t length; -}; - -int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len) { - struct authkey_data *a; - - pa_assert(c); - pa_assert(name); - pa_assert(data); - pa_assert(len > 0); - - if (!(a = pa_shared_get(c, name))) - return -1; - - pa_assert(a->length == len); - memcpy(data, (uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), len); - - return 0; -} - -int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len) { - struct authkey_data *a; - - pa_assert(c); - pa_assert(name); - - if (pa_shared_get(c, name)) - return -1; - - a = pa_xmalloc(PA_ALIGN(sizeof(struct authkey_data)) + len); - PA_REFCNT_INIT(a); - a->length = len; - memcpy((uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), data, len); - - pa_shared_set(c, name, a); - - return 0; -} - -void pa_authkey_prop_ref(pa_core *c, const char *name) { - struct authkey_data *a; - - pa_assert(c); - pa_assert(name); - - a = pa_shared_get(c, name); - pa_assert(a); - pa_assert(PA_REFCNT_VALUE(a) >= 1); - PA_REFCNT_INC(a); -} - -void pa_authkey_prop_unref(pa_core *c, const char *name) { - struct authkey_data *a; - - pa_assert(c); - pa_assert(name); - - a = pa_shared_get(c, name); - pa_assert(a); - pa_assert(PA_REFCNT_VALUE(a) >= 1); - - if (PA_REFCNT_DEC(a) <= 0) { - pa_shared_remove(c, name); - pa_xfree(a); - } -} diff --git a/src/pulsecore/authkey-prop.h b/src/pulsecore/authkey-prop.h deleted file mode 100644 index de02d2aa..00000000 --- a/src/pulsecore/authkey-prop.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef fooauthkeyprophfoo -#define fooauthkeyprophfoo - -/*** - This file is part of PulseAudio. - - Copyright 2004-2006 Lennart Poettering - - 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. -***/ - -#include <pulsecore/core.h> - -/* The authkey-prop uses a central property to store a previously - * loaded cookie in memory. Useful for sharing the same cookie between - * several modules. */ - -/* Return the data of the specified authorization key property. Doesn't alter the refernce count of the key */ -int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len); - -/* Store data in the specified authorization key property. The initial reference count is set to 1 */ -int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len); - -/* Increase the reference count of the specified authorization key */ -void pa_authkey_prop_ref(pa_core *c, const char *name); - -/* Decrease the reference count of the specified authorization key */ -void pa_authkey_prop_unref(pa_core *c, const char *name); - -#endif diff --git a/src/pulsecore/autoload.c b/src/pulsecore/autoload.c index 26c294b2..8c84cee5 100644 --- a/src/pulsecore/autoload.c +++ b/src/pulsecore/autoload.c @@ -158,7 +158,7 @@ void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) { e->in_action = 0; } -static void free_func(void *p, PA_GCC_UNUSED void *userdata) { +static void free_func(void *p, void *userdata) { pa_autoload_entry *e = p; pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); entry_free(e); diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 0bd4070c..1624165d 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -188,7 +188,9 @@ static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b pa_assert(buf); pa_assert(fail); - c->mainloop->quit(c->mainloop, 0); + if (pa_core_exit(c, FALSE, 0) < 0) + pa_strbuf_puts(buf, "Not allowed to terminate daemon.\n"); + return 0; } @@ -316,22 +318,22 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n", (unsigned) pa_atomic_load(&stat->n_allocated), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->allocated_size))); + pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->allocated_size))); pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n", (unsigned) pa_atomic_load(&stat->n_accumulated), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->accumulated_size))); + pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->accumulated_size))); pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n", (unsigned) pa_atomic_load(&stat->n_imported), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->imported_size))); + pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->imported_size))); pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n", (unsigned) pa_atomic_load(&stat->n_exported), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->exported_size))); + pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->exported_size))); pa_strbuf_printf(buf, "Total sample cache size: %s.\n", - pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c))); + pa_bytes_snprint(s, sizeof(s), (unsigned) pa_scache_total_size(c))); pa_strbuf_printf(buf, "Default sample spec: %s\n", pa_sample_spec_snprint(s, sizeof(s), &c->default_sample_spec)); @@ -415,7 +417,7 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa return -1; } - pa_module_unload_request(m); + pa_module_unload_request(m, FALSE); return 0; } @@ -1249,8 +1251,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b nl = 1; } - pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink))); - pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink))); + pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, FALSE))); + pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE))); pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED)); } @@ -1263,8 +1265,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b nl = 1; } - pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source))); - pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source))); + pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, FALSE))); + pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE))); pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED)); } diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index c92fca20..7bbc2660 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -149,10 +149,12 @@ char *pa_sink_list_to_string(pa_core *c) { sink->flags & PA_SINK_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "", sink->flags & PA_SINK_LATENCY ? "LATENCY " : "", state_table[pa_sink_get_state(sink)], - pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)), - pa_yes_no(pa_sink_get_mute(sink)), - (double) pa_sink_get_latency(sink) / PA_USEC_PER_MSEC, - (double) pa_sink_get_requested_latency(sink) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC, + pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE)), + pa_yes_no(pa_sink_get_mute(sink, FALSE)), + (double) pa_sink_get_latency(sink) / (double) PA_USEC_PER_MSEC, + (double) pa_sink_get_requested_latency(sink) / (double) PA_USEC_PER_MSEC, + (double) min_latency / PA_USEC_PER_MSEC, + (double) max_latency / PA_USEC_PER_MSEC, (unsigned long) pa_sink_get_max_request(sink) / 1024, (unsigned long) pa_sink_get_max_rewind(sink) / 1024, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, @@ -222,10 +224,12 @@ char *pa_source_list_to_string(pa_core *c) { source->flags & PA_SOURCE_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "", source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", state_table[pa_source_get_state(source)], - pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)), - pa_yes_no(pa_source_get_mute(source)), + pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)), + pa_yes_no(pa_source_get_mute(source, FALSE)), (double) pa_source_get_latency(source) / PA_USEC_PER_MSEC, - (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC, + (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, + (double) min_latency / PA_USEC_PER_MSEC, + (double) max_latency / PA_USEC_PER_MSEC, (unsigned long) pa_source_get_max_rewind(source) / 1024, pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map), @@ -411,7 +415,7 @@ char *pa_scache_list_to_string(pa_core *c) { if (e->memchunk.memblock) { pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec); pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map); - l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec); + l = (double) e->memchunk.length / (double) pa_bytes_per_second(&e->sample_spec); } pa_strbuf_printf( diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c index 0ffd2330..ab6e5df4 100644 --- a/src/pulsecore/client.c +++ b/src/pulsecore/client.c @@ -58,7 +58,7 @@ pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { pa_log_info("Created %u \"%s\"", c->index, pa_strnull(name)); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); - pa_core_check_quit(core); + pa_core_check_idle(core); return c; } @@ -78,7 +78,7 @@ void pa_client_free(pa_client *c) { pa_xfree(c->driver); pa_xfree(c); - pa_core_check_quit(core); + pa_core_check_idle(core); } void pa_client_kill(pa_client *c) { diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index 4aec45d7..6b0e1d56 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -148,7 +148,7 @@ finish: return r; } -int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { int *i = data; int32_t k; @@ -166,7 +166,7 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, return 0; } -int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { int k; pa_bool_t *b = data; @@ -185,7 +185,7 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue return 0; } -int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { +int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { char **s = data; pa_assert(filename); diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index 75fa2ff1..814dff59 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -63,7 +63,7 @@ #define UNLOAD_POLL_TIME 60 -static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) { pa_core *c = userdata; struct timeval ntv; @@ -282,7 +282,7 @@ int pa_scache_remove_item(pa_core *c, const char *name) { return 0; } -static void free_cb(void *p, PA_GCC_UNUSED void *userdata) { +static void free_cb(void *p, void *userdata) { pa_scache_entry *e = p; pa_assert(e); diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c index 6107002b..c70d8adc 100644 --- a/src/pulsecore/core-subscribe.c +++ b/src/pulsecore/core-subscribe.c @@ -42,7 +42,7 @@ struct pa_subscription { pa_core *core; - int dead; + pa_bool_t dead; pa_subscription_cb_t callback; void *userdata; @@ -72,7 +72,7 @@ pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_su s = pa_xnew(pa_subscription, 1); s->core = c; - s->dead = 0; + s->dead = FALSE; s->callback = callback; s->userdata = userdata; s->mask = m; @@ -86,7 +86,7 @@ void pa_subscription_free(pa_subscription*s) { pa_assert(s); pa_assert(!s->dead); - s->dead = 1; + s->dead = TRUE; sched_event(s->core); } @@ -145,7 +145,7 @@ static void dump_event(const char * prefix, pa_subscription_event*e) { [PA_SUBSCRIPTION_EVENT_REMOVE] = "REMOVE" }; - pa_log("%s event (%s|%s|%u)", + pa_log_debug("%s event (%s|%s|%u)", prefix, fac_table[e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK], type_table[e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK], @@ -234,7 +234,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i * entry in the queue. */ free_event(i); - pa_log_debug("dropped redundant event."); + pa_log_debug("Dropped redundant event due to remove event."); continue; } @@ -242,7 +242,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i /* This object has changed. If a "new" or "change" event for * this object is still in the queue we can exit. */ - pa_log_debug("dropped redundant event."); + pa_log_debug("Dropped redundant event due to change event."); return; } } diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index c4818e39..89416d8b 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -40,6 +40,8 @@ #include <sys/stat.h> #include <sys/time.h> #include <dirent.h> +#include <regex.h> +#include <langinfo.h> #ifdef HAVE_STRTOF_L #include <locale.h> @@ -111,6 +113,8 @@ int pa_set_root(HANDLE handle) { strcpy(library_path, PULSE_ROOTENV "="); + /* FIXME: Needs to set errno */ + if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH)) return 0; @@ -168,7 +172,7 @@ void pa_make_fd_cloexec(int fd) { /** Creates a directory securely */ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) { struct stat st; - int r; + int r, saved_errno; pa_assert(dir); @@ -220,7 +224,10 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) { return 0; fail: + saved_errno = errno; rmdir(dir); + errno = saved_errno; + return -1; } @@ -230,6 +237,7 @@ char *pa_parent_dir(const char *fn) { if ((slash = (char*) pa_path_get_filename(dir)) == dir) { pa_xfree(dir); + errno = ENOENT; return NULL; } @@ -337,7 +345,7 @@ ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) { ret += r; data = (uint8_t*) data + r; - size -= r; + size -= (size_t) r; } return ret; @@ -368,7 +376,7 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) { ret += r; data = (const uint8_t*) data + r; - size -= r; + size -= (size_t) r; } return ret; @@ -437,7 +445,7 @@ void pa_check_signal_is_blocked(int sig) { /* The following function is based on an example from the GNU libc * documentation. This function is similar to GNU's asprintf(). */ char *pa_sprintf_malloc(const char *format, ...) { - int size = 100; + size_t size = 100; char *c = NULL; pa_assert(format); @@ -454,11 +462,11 @@ char *pa_sprintf_malloc(const char *format, ...) { c[size-1] = 0; - if (r > -1 && r < size) + if (r > -1 && (size_t) r < size) return c; if (r > -1) /* glibc 2.1 */ - size = r+1; + size = (size_t) r+1; else /* glibc 2.0 */ size *= 2; } @@ -467,7 +475,7 @@ char *pa_sprintf_malloc(const char *format, ...) { /* Same as the previous function, but use a va_list instead of an * ellipsis */ char *pa_vsprintf_malloc(const char *format, va_list ap) { - int size = 100; + size_t size = 100; char *c = NULL; pa_assert(format); @@ -484,11 +492,11 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) { c[size-1] = 0; - if (r > -1 && r < size) + if (r > -1 && (size_t) r < size) return c; if (r > -1) /* glibc 2.1 */ - size = r+1; + size = (size_t) r+1; else /* glibc 2.0 */ size *= 2; } @@ -546,6 +554,8 @@ int pa_make_realtime(int rtprio) { pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority); return 0; #else + + errno = ENOTSUP; return -1; #endif } @@ -653,6 +663,7 @@ int pa_raise_priority(int nice_level) { if (nice_level < 0) { if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) { pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError()); + errno = EPERM; return .-1; } else pa_log_info("Successfully gained high priority class."); @@ -679,15 +690,55 @@ void pa_reset_priority(void) { #endif } +static int match(const char *expr, const char *v) { + int k; + regex_t re; + int r; + + if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) { + errno = EINVAL; + return -1; + } + + if ((k = regexec(&re, v, 0, NULL, 0)) == 0) + r = 1; + else if (k == REG_NOMATCH) + r = 0; + else + r = -1; + + regfree(&re); + + if (r < 0) + errno = EINVAL; + + return r; +} + /* Try to parse a boolean string value.*/ int pa_parse_boolean(const char *v) { + const char *expr; + int r; pa_assert(v); + /* First we check language independant */ if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on")) return 1; else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off")) return 0; + /* And then we check language dependant */ + if ((expr = nl_langinfo(YESEXPR))) + if (expr[0]) + if ((r = match(expr, v)) > 0) + return 1; + + if ((expr = nl_langinfo(NOEXPR))) + if (expr[0]) + if ((r = match(expr, v)) > 0) + return 0; + + errno = EINVAL; return -1; } @@ -875,11 +926,18 @@ static int is_group(gid_t gid, const char *name) { #else n = -1; #endif - if (n < 0) n = 512; - data = pa_xmalloc(n); + if (n < 0) + n = 512; + + data = pa_xmalloc((size_t) n); + + errno = 0; + if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) { + pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno)); + + if (!errno) + errno = ENOENT; - if (getgrgid_r(gid, &group, data, n, &result) < 0 || !result) { - pa_log("getgrgid_r(%u): %s", (unsigned)gid, pa_cstrerror(errno)); goto finish; } @@ -890,8 +948,14 @@ finish: #else /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not * support getgrgid_r. */ + + errno = 0; if ((result = getgrgid(gid)) == NULL) { pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno)); + + if (!errno) + errno = ENOENT; + goto finish; } @@ -906,27 +970,32 @@ finish: /* Check the current user is member of the specified group */ int pa_own_uid_in_group(const char *name, gid_t *gid) { GETGROUPS_T *gids, tgid; - int n = sysconf(_SC_NGROUPS_MAX); - int r = -1, i; + long n = sysconf(_SC_NGROUPS_MAX); + int r = -1, i, k; pa_assert(n > 0); - gids = pa_xmalloc(sizeof(GETGROUPS_T)*n); + gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n); - if ((n = getgroups(n, gids)) < 0) { + if ((n = getgroups((int) n, gids)) < 0) { pa_log("getgroups(): %s", pa_cstrerror(errno)); goto finish; } for (i = 0; i < n; i++) { - if (is_group(gids[i], name) > 0) { + + if ((k = is_group(gids[i], name)) < 0) + goto finish; + else if (k > 0) { *gid = gids[i]; r = 1; goto finish; } } - if (is_group(tgid = getgid(), name) > 0) { + if ((k = is_group(tgid = getgid(), name)) < 0) + goto finish; + else if (k > 0) { *gid = tgid; r = 1; goto finish; @@ -949,18 +1018,25 @@ int pa_uid_in_group(uid_t uid, const char *name) { int r = -1; g_n = sysconf(_SC_GETGR_R_SIZE_MAX); - g_buf = pa_xmalloc(g_n); + g_buf = pa_xmalloc((size_t) g_n); p_n = sysconf(_SC_GETPW_R_SIZE_MAX); - p_buf = pa_xmalloc(p_n); + p_buf = pa_xmalloc((size_t) p_n); + + errno = 0; + if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) { + + if (!errno) + errno = ENOENT; - if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) goto finish; + } r = 0; for (i = gr->gr_mem; *i; i++) { struct passwd pwbuf, *pw; + errno = 0; if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw) continue; @@ -985,10 +1061,16 @@ gid_t pa_get_gid_of_group(const char *name) { struct group grbuf, *gr; g_n = sysconf(_SC_GETGR_R_SIZE_MAX); - g_buf = pa_xmalloc(g_n); + g_buf = pa_xmalloc((size_t) g_n); + + errno = 0; + if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) { + + if (!errno) + errno = ENOENT; - if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) goto finish; + } ret = gr->gr_gid; @@ -1014,19 +1096,23 @@ int pa_check_in_group(gid_t g) { #else /* HAVE_GRP_H */ int pa_own_uid_in_group(const char *name, gid_t *gid) { + errno = ENOSUP; return -1; } int pa_uid_in_group(uid_t uid, const char *name) { + errno = ENOSUP; return -1; } gid_t pa_get_gid_of_group(const char *name) { + errno = ENOSUP; return (gid_t) -1; } int pa_check_in_group(gid_t g) { + errno = ENOSUP; return -1; } @@ -1040,7 +1126,7 @@ int pa_lock_fd(int fd, int b) { /* Try a R/W lock first */ - flock.l_type = b ? F_WRLCK : F_UNLCK; + flock.l_type = (short) (b ? F_WRLCK : F_UNLCK); flock.l_whence = SEEK_SET; flock.l_start = 0; flock.l_len = 0; @@ -1067,6 +1153,8 @@ int pa_lock_fd(int fd, int b) { return 0; pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError()); + + /* FIXME: Needs to set errno! */ #endif return -1; @@ -1133,8 +1221,11 @@ int pa_lock_lockfile(const char *fn) { fail: - if (fd >= 0) + if (fd >= 0) { + int saved_errno = errno; pa_close(fd); + errno = saved_errno; + } return -1; } @@ -1164,48 +1255,245 @@ int pa_unlock_lockfile(const char *fn, int fd) { return r; } -static char *get_dir(mode_t m, const char *env_name) { - const char *e; - char *d; +static char *get_pulse_home(void) { + char h[PATH_MAX]; + struct stat st; - if ((e = getenv(env_name))) - d = pa_xstrdup(e); - else { - char h[PATH_MAX]; - struct stat st; + if (!pa_get_home_dir(h, sizeof(h))) { + pa_log_error("Failed to get home directory."); + return NULL; + } - if (!pa_get_home_dir(h, sizeof(h))) { - pa_log_error("Failed to get home directory."); - return NULL; - } + if (stat(h, &st) < 0) { + pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno)); + return NULL; + } - if (stat(h, &st) < 0) { - pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno)); - return NULL; - } + if (st.st_uid != getuid()) { + pa_log_error("Home directory %s not ours.", h); + errno = EACCES; + return NULL; + } - if (st.st_uid != getuid()) { - pa_log_error("Home directory %s not ours.", d); + return pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h); +} + +char *pa_get_state_dir(void) { + char *d; + + /* The state directory shall contain dynamic data that should be + * kept across reboots, and is private to this user */ + + if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH")))) + if (!(d = get_pulse_home())) return NULL; - } - d = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h); - } + /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same + * dir then this will break. */ - if (pa_make_secure_dir(d, m, (pid_t) -1, (pid_t) -1) < 0) { + if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) { pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno)); + pa_xfree(d); return NULL; } return d; } -char *pa_get_runtime_dir(void) { - return get_dir(pa_in_system_mode() ? 0755 : 0700, "PULSE_RUNTIME_PATH"); +static char* make_random_dir(mode_t m) { + static const char table[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + + char fn[24] = "/tmp/pulse-"; + + fn[sizeof(fn)-1] = 0; + + for (;;) { + unsigned i; + int r; + mode_t u; + int saved_errno; + + for (i = 11; i < sizeof(fn)-1; i++) + fn[i] = table[rand() % (sizeof(table)-1)]; + + u = umask((~m) & 0777); + r = mkdir(fn, m); + saved_errno = errno; + umask(u); + + if (r >= 0) + return pa_xstrdup(fn); + + errno = saved_errno; + + if (errno != EEXIST) { + pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno)); + return NULL; + } + } } -char *pa_get_state_dir(void) { - return get_dir(0700, "PULSE_STATE_PATH"); +static int make_random_dir_and_link(mode_t m, const char *k) { + char *p; + + if (!(p = make_random_dir(m))) + return -1; + + if (symlink(p, k) < 0) { + int saved_errno = errno; + + if (errno != EEXIST) + pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno)); + + rmdir(p); + pa_xfree(p); + + errno = saved_errno; + return -1; + } + + return 0; +} + +char *pa_get_runtime_dir(void) { + char *d, *k = NULL, *p = NULL, *t = NULL, *mid; + struct stat st; + + /* The runtime directory shall contain dynamic data that needs NOT + * to be kept accross reboots and is usuallly private to the user, + * except in system mode, where it might be accessible by other + * users, too. Since we need POSIX locking and UNIX sockets in + * this directory, we link it to a random subdir in /tmp, if it + * was not explicitly configured. */ + + if ((d = getenv("PULSE_RUNTIME_PATH"))) { + mode_t m; + + m = pa_in_system_mode() ? 0755U : 0700U; + + if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) { + pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno)); + goto fail; + } + + return pa_xstrdup(d); + } + + if (!(d = get_pulse_home())) + goto fail; + + if (!(mid = pa_machine_id())) { + pa_xfree(d); + goto fail; + } + + k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:runtime", d, mid); + pa_xfree(d); + pa_xfree(mid); + + for (;;) { + /* OK, first let's check if the "runtime" symlink is already + * existant */ + + if (!(p = pa_readlink(k))) { + + if (errno != ENOENT) { + pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno)); + goto fail; + } + + /* Hmm, so the runtime directory didn't exist yet, so let's + * create one in /tmp and symlink that to it */ + + if (make_random_dir_and_link(0700, k) < 0) { + + /* Mhmm, maybe another process was quicker than us, + * let's check if that was valid */ + if (errno == EEXIST) + continue; + + goto fail; + } + + return k; + } + + /* Make sure that this actually makes sense */ + if (!pa_is_path_absolute(p)) { + pa_log_error("Path %s in link %s is not absolute.", p, k); + errno = ENOENT; + goto fail; + } + + /* Hmm, so this symlink is still around, make sure nobody fools + * us */ + + if (lstat(p, &st) < 0) { + + if (errno != ENOENT) { + pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno)); + goto fail; + } + + } else { + + if (S_ISDIR(st.st_mode) && + (st.st_uid == getuid()) && + ((st.st_mode & 0777) == 0700)) { + + pa_xfree(p); + return k; + } + + pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory."); + } + + pa_xfree(p); + p = NULL; + + /* Hmm, so the link points to some nonexisting or invalid + * dir. Let's replace it by a new link. We first create a + * temporary link and then rename that to allow concurrent + * execution of this function. */ + + t = pa_sprintf_malloc("%s.tmp", k); + + if (make_random_dir_and_link(0700, t) < 0) { + + if (errno != EEXIST) { + pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno)); + goto fail; + } + + pa_xfree(t); + t = NULL; + + /* Hmm, someone lese was quicker then us. Let's give + * him some time to finish, and retry. */ + pa_msleep(10); + continue; + } + + /* OK, we succeeded in creating the temporary symlink, so + * let's rename it */ + if (rename(t, k) < 0) { + pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno)); + goto fail; + } + + pa_xfree(t); + return k; + } + +fail: + pa_xfree(p); + pa_xfree(k); + pa_xfree(t); + + return NULL; } /* Try to open a configuration file. If "env" is specified, open the @@ -1228,6 +1516,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX)) + /* FIXME: Needs to set errno! */ return NULL; fn = buf; #endif @@ -1253,9 +1542,12 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local); else if (pa_get_home_dir(h, sizeof(h))) fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local); + else + return NULL; #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) { + /* FIXME: Needs to set errno! */ pa_xfree(lfn); return NULL; } @@ -1284,6 +1576,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX)) + /* FIXME: Needs to set errno! */ return NULL; global = buf; #endif @@ -1295,9 +1588,9 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env return f; } - } else - errno = ENOENT; + } + errno = ENOENT; return NULL; } @@ -1311,8 +1604,10 @@ char *pa_find_config_file(const char *global, const char *local, const char *env #endif if (env && (fn = getenv(env))) { + #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX)) + /* FIXME: Needs to set errno! */ return NULL; fn = buf; #endif @@ -1333,9 +1628,12 @@ char *pa_find_config_file(const char *global, const char *local, const char *env fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local); else if (pa_get_home_dir(h, sizeof(h))) fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local); + else + return NULL; #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) { + /* FIXME: Needs to set errno! */ pa_xfree(lfn); return NULL; } @@ -1360,14 +1658,16 @@ char *pa_find_config_file(const char *global, const char *local, const char *env if (global) { #ifdef OS_IS_WIN32 if (!ExpandEnvironmentStrings(global, buf, PATH_MAX)) + /* FIXME: Needs to set errno! */ return NULL; global = buf; #endif - if (access(fn, R_OK) == 0) + if (access(global, R_OK) == 0) return pa_xstrdup(global); - } else - errno = ENOENT; + } + + errno = ENOENT; return NULL; } @@ -1404,6 +1704,7 @@ static int hexc(char c) { if (c >= 'a' && c <= 'f') return c - 'a' + 10; + errno = EINVAL; return -1; } @@ -1490,7 +1791,7 @@ char *pa_make_path_absolute(const char *p) { /* if fn is null return the PulseAudio run time path in s (~/.pulse) * if fn is non-null and starts with / return fn * otherwise append fn to the run time path and return it */ -static char *get_path(const char *fn, pa_bool_t rt) { +static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) { char *rtp; if (pa_is_path_absolute(fn)) @@ -1503,7 +1804,20 @@ static char *get_path(const char *fn, pa_bool_t rt) { if (fn) { char *r; - r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn); + + if (prependmid) { + char *mid; + + if (!(mid = pa_machine_id())) { + pa_xfree(rtp); + return NULL; + } + + r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:%s", rtp, mid, fn); + pa_xfree(mid); + } else + r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn); + pa_xfree(rtp); return r; } else @@ -1511,11 +1825,11 @@ static char *get_path(const char *fn, pa_bool_t rt) { } char *pa_runtime_path(const char *fn) { - return get_path(fn, 1); + return get_path(fn, FALSE, TRUE); } -char *pa_state_path(const char *fn) { - return get_path(fn, 0); +char *pa_state_path(const char *fn, pa_bool_t appendmid) { + return get_path(fn, appendmid, FALSE); } /* Convert the string s to a signed integer in *ret_i */ @@ -1529,11 +1843,16 @@ int pa_atoi(const char *s, int32_t *ret_i) { errno = 0; l = strtol(s, &x, 0); - if (!x || *x || errno != 0) + if (!x || *x || errno) { + if (!errno) + errno = EINVAL; return -1; + } - if ((int32_t) l != l) + if ((int32_t) l != l) { + errno = ERANGE; return -1; + } *ret_i = (int32_t) l; @@ -1551,11 +1870,16 @@ int pa_atou(const char *s, uint32_t *ret_u) { errno = 0; l = strtoul(s, &x, 0); - if (!x || *x || errno != 0) + if (!x || *x || errno) { + if (!errno) + errno = EINVAL; return -1; + } - if ((uint32_t) l != l) + if ((uint32_t) l != l) { + errno = ERANGE; return -1; + } *ret_u = (uint32_t) l; @@ -1573,7 +1897,6 @@ static void c_locale_destroy(void) { int pa_atod(const char *s, double *ret_d) { char *x = NULL; double f; - int r = 0; pa_assert(s); pa_assert(ret_d); @@ -1599,17 +1922,20 @@ int pa_atod(const char *s, double *ret_d) { f = strtod(s, &x); } - if (!x || *x || errno != 0) - r = -1; - else - *ret_d = f; + if (!x || *x || errno) { + if (!errno) + errno = EINVAL; + return -1; + } - return r; + *ret_d = f; + + return 0; } /* Same as snprintf, but guarantees NUL-termination on every platform */ -int pa_snprintf(char *str, size_t size, const char *format, ...) { - int ret; +size_t pa_snprintf(char *str, size_t size, const char *format, ...) { + size_t ret; va_list ap; pa_assert(str); @@ -1624,7 +1950,7 @@ int pa_snprintf(char *str, size_t size, const char *format, ...) { } /* Same as vsnprintf, but guarantees NUL-termination on every platform */ -int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) { +size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) { int ret; pa_assert(str); @@ -1636,9 +1962,12 @@ int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) { str[size-1] = 0; if (ret < 0) - ret = strlen(str); + return strlen(str); - return PA_MIN((int) size-1, ret); + if ((size_t) ret > size-1) + return size-1; + + return (size_t) ret; } /* Truncate the specified string, but guarantee that the string @@ -1662,7 +1991,7 @@ char *pa_getcwd(void) { size_t l = 128; for (;;) { - char *p = pa_xnew(char, l); + char *p = pa_xmalloc(l); if (getcwd(p, l)) return p; @@ -1687,7 +2016,7 @@ void *pa_will_need(const void *p, size_t l) { pa_assert(l > 0); a = PA_PAGE_ALIGN_PTR(p); - size = (const uint8_t*) p + l - (const uint8_t*) a; + size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a); #ifdef HAVE_POSIX_MADVISE if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) { @@ -1708,10 +2037,11 @@ void *pa_will_need(const void *p, size_t l) { if (rlim.rlim_cur < PA_PAGE_SIZE) { pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r)); + errno = EPERM; return (void*) p; } - bs = PA_PAGE_ALIGN(rlim.rlim_cur); + bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur); #else bs = PA_PAGE_SIZE*4; #endif @@ -1763,7 +2093,7 @@ char *pa_readlink(const char *p) { char *c; ssize_t n; - c = pa_xnew(char, l); + c = pa_xmalloc(l); if ((n = readlink(p, c, l-1)) < 0) { pa_xfree(c); @@ -1782,8 +2112,8 @@ char *pa_readlink(const char *p) { int pa_close_all(int except_fd, ...) { va_list ap; - int n = 0, i, r; - int *p; + unsigned n = 0, i; + int r, *p; va_start(ap, except_fd); @@ -1910,8 +2240,8 @@ int pa_close_allv(const int except_fds[]) { int pa_unblock_sigs(int except, ...) { va_list ap; - int n = 0, i, r; - int *p; + unsigned n = 0, i; + int r, *p; va_start(ap, except); @@ -1959,8 +2289,8 @@ int pa_unblock_sigsv(const int except[]) { int pa_reset_sigs(int except, ...) { va_list ap; - int n = 0, i, r; - int *p; + unsigned n = 0, i; + int *p, r; va_start(ap, except); @@ -2048,3 +2378,47 @@ pa_bool_t pa_in_system_mode(void) { return !!atoi(e); } + +char *pa_machine_id(void) { + FILE *f; + size_t l; + + if ((f = fopen(PA_MACHINE_ID, "r"))) { + char ln[34] = "", *r; + + r = fgets(ln, sizeof(ln)-1, f); + fclose(f); + + if (r) + return pa_xstrdup(pa_strip_nl(ln)); + } + + l = 100; + + for (;;) { + char *c; + + c = pa_xmalloc(l); + + if (!pa_get_host_name(c, l)) { + + if (errno == EINVAL || errno == ENAMETOOLONG) { + pa_xfree(c); + l *= 2; + continue; + } + + return NULL; + } + + if (strlen(c) < l-1) + return c; + + /* Hmm, the hostname is as long the space we offered the + * function, we cannot know if it fully fit in, so let's play + * safe and retry. */ + + pa_xfree(c); + l *= 2; + } +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 2ed81fc5..7167972b 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -121,14 +121,14 @@ char* pa_find_config_file(const char *global, const char *local, const char *env char *pa_get_runtime_dir(void); char *pa_get_state_dir(void); char *pa_runtime_path(const char *fn); -char *pa_state_path(const char *fn); +char *pa_state_path(const char *fn, pa_bool_t prepend_machine_id); int pa_atoi(const char *s, int32_t *ret_i); int pa_atou(const char *s, uint32_t *ret_u); int pa_atod(const char *s, double *ret_d); -int pa_snprintf(char *str, size_t size, const char *format, ...); -int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap); +size_t pa_snprintf(char *str, size_t size, const char *format, ...); +size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap); char *pa_truncate_utf8(char *c, size_t l); @@ -184,4 +184,6 @@ pa_bool_t pa_in_system_mode(void); #define pa_streq(a,b) (!strcmp((a),(b))) +char *pa_machine_id(void); + #endif diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index aa8de8df..b9f04b68 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -56,7 +56,7 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o switch (code) { case PA_CORE_MESSAGE_UNLOAD_MODULE: - pa_module_unload(c, userdata); + pa_module_unload(c, userdata, TRUE); return 0; default: @@ -125,7 +125,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->mempool = pool; pa_silence_cache_init(&c->silence_cache); - c->quit_event = NULL; + c->exit_event = NULL; c->exit_idle_time = -1; c->module_idle_time = 20; @@ -134,6 +134,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3; c->disallow_module_loading = FALSE; + c->disallow_exit = FALSE; c->realtime_scheduling = FALSE; c->realtime_priority = 5; c->disable_remixing = FALSE; @@ -149,7 +150,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_check_signal_is_blocked(SIGPIPE); #endif - pa_core_check_quit(c); + pa_core_check_idle(c); return c; } @@ -182,8 +183,8 @@ static void core_free(pa_object *o) { pa_autoload_free(c); pa_subscription_free_all(c); - if (c->quit_event) - c->mainloop->time_free(c->quit_event); + if (c->exit_event) + c->mainloop->time_free(c->exit_event); pa_xfree(c->default_source_name); pa_xfree(c->default_sink_name); @@ -199,17 +200,17 @@ static void core_free(pa_object *o) { pa_xfree(c); } -static void quit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { pa_core *c = userdata; - pa_assert(c->quit_event == e); + pa_assert(c->exit_event == e); - m->quit(m, 0); + pa_core_exit(c, TRUE, 0); } -void pa_core_check_quit(pa_core *c) { +void pa_core_check_idle(pa_core *c) { pa_assert(c); - if (!c->quit_event && + if (!c->exit_event && c->exit_idle_time >= 0 && pa_idxset_size(c->clients) == 0) { @@ -217,10 +218,20 @@ void pa_core_check_quit(pa_core *c) { pa_gettimeofday(&tv); tv.tv_sec+= c->exit_idle_time; - c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c); + c->exit_event = c->mainloop->time_new(c->mainloop, &tv, exit_callback, c); - } else if (c->quit_event && pa_idxset_size(c->clients) > 0) { - c->mainloop->time_free(c->quit_event); - c->quit_event = NULL; + } else if (c->exit_event && pa_idxset_size(c->clients) > 0) { + c->mainloop->time_free(c->exit_event); + c->exit_event = NULL; } } + +int pa_core_exit(pa_core *c, pa_bool_t force, int retval) { + pa_assert(c); + + if (c->disallow_exit && !force) + return -1; + + c->mainloop->quit(c->mainloop, retval); + return 0; +} diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index e11655ef..eb768418 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -115,11 +115,12 @@ struct pa_core { int exit_idle_time, module_idle_time, scache_idle_time; - pa_time_event *quit_event; + pa_time_event *exit_event; pa_time_event *scache_auto_unload_event; pa_bool_t disallow_module_loading:1; + pa_bool_t disallow_exit:1; pa_bool_t running_as_daemon:1; pa_bool_t realtime_scheduling:1; pa_bool_t disable_remixing:1; @@ -142,6 +143,8 @@ enum { pa_core* pa_core_new(pa_mainloop_api *m, int shared); /* Check whether noone is connected to this core */ -void pa_core_check_quit(pa_core *c); +void pa_core_check_idle(pa_core *c); + +int pa_core_exit(pa_core *c, pa_bool_t force, int retval); #endif diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index 26336918..1b94de17 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -46,9 +46,14 @@ #endif static inline float PA_FLOAT32_SWAP(float x) { - uint32_t i = *(uint32_t*) &x; - i = PA_UINT32_SWAP(i); - return *(float*) &i; + union { + float f; + uint32_t u; + } t; + + t.f = x; + t.u = PA_UINT32_SWAP(t.u); + return t.f; } #define PA_MAYBE_INT16_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : x) diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c index e2691611..7f2252e9 100644 --- a/src/pulsecore/envelope.c +++ b/src/pulsecore/envelope.c @@ -153,11 +153,11 @@ void pa_envelope_free(pa_envelope *e) { } static int32_t linear_interpolate_int(pa_usec_t x1, int32_t _y1, pa_usec_t x2, int32_t y2, pa_usec_t x3) { - return (int32_t) (_y1 + (x3 - x1) * (float) (y2 - _y1) / (float) (x2 - x1)); + return (int32_t) ((double) _y1 + (double) (x3 - x1) * (double) (y2 - _y1) / (double) (x2 - x1)); } static float linear_interpolate_float(pa_usec_t x1, float _y1, pa_usec_t x2, float y2, pa_usec_t x3) { - return _y1 + (x3 - x1) * (y2 - _y1) / (x2 - x1); + return _y1 + ((float) x3 - (float) x1) * (y2 - _y1) / ((float) x2 - (float) x1); } static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) { @@ -573,11 +573,11 @@ static float linear_get_float(pa_envelope *e, int v) { if (!e->points[v].cached_valid) { e->points[v].cached_dy_dx = (e->points[v].y.f[e->points[v].n_current+1] - e->points[v].y.f[e->points[v].n_current]) / - (e->points[v].x[e->points[v].n_current+1] - e->points[v].x[e->points[v].n_current]); + ((float) e->points[v].x[e->points[v].n_current+1] - (float) e->points[v].x[e->points[v].n_current]); e->points[v].cached_valid = TRUE; } - return e->points[v].y.f[e->points[v].n_current] + (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx; + return e->points[v].y.f[e->points[v].n_current] + (float) (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx; } void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { @@ -605,7 +605,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { uint8_t *t; for (t = p; n > 0; n -= fs) { - int16_t factor = linear_get_int(e, v); + int32_t factor = linear_get_int(e, v); unsigned c; e->x += fs; @@ -620,13 +620,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { uint8_t *t; for (t = p; n > 0; n -= fs) { - int16_t factor = linear_get_int(e, v); + int32_t factor = linear_get_int(e, v); unsigned c; e->x += fs; for (c = 0; c < e->sample_spec.channels; c++, t++) { int16_t k = st_ulaw2linear16(*t); - *t = (uint8_t) st_14linear2ulaw(((factor * k) / 0x10000) >> 2); + *t = (uint8_t) st_14linear2ulaw((int16_t) (((factor * k) / 0x10000) >> 2)); } } @@ -637,13 +637,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { uint8_t *t; for (t = p; n > 0; n -= fs) { - int16_t factor = linear_get_int(e, v); + int32_t factor = linear_get_int(e, v); unsigned c; e->x += fs; for (c = 0; c < e->sample_spec.channels; c++, t++) { int16_t k = st_alaw2linear16(*t); - *t = (uint8_t) st_13linear2alaw(((factor * k) / 0x10000) >> 3); + *t = (uint8_t) st_13linear2alaw((int16_t) (((factor * k) / 0x10000) >> 3)); } } @@ -659,7 +659,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { e->x += fs; for (c = 0; c < e->sample_spec.channels; c++, t++) - *t = (factor * *t) / 0x10000; + *t = (int16_t) ((factor * *t) / 0x10000); } break; @@ -674,7 +674,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { e->x += fs; for (c = 0; c < e->sample_spec.channels; c++, t++) { - int16_t r = (factor * PA_INT16_SWAP(*t)) / 0x10000; + int16_t r = (int16_t) ((factor * PA_INT16_SWAP(*t)) / 0x10000); *t = PA_INT16_SWAP(r); } } diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 1531e3db..380f34f5 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -41,39 +41,15 @@ #include <pulsecore/pipe.h> #endif -#ifdef __linux__ - -#if !defined(__NR_eventfd) && defined(__i386__) -#define __NR_eventfd 323 -#endif - -#if !defined(__NR_eventfd) && defined(__x86_64__) -#define __NR_eventfd 284 -#endif - -#if !defined(__NR_eventfd) && defined(__arm__) -#define __NR_eventfd (__NR_SYSCALL_BASE+351) -#endif - -#if !defined(SYS_eventfd) && defined(__NR_eventfd) -#define SYS_eventfd __NR_eventfd -#endif - -#ifdef SYS_eventfd -#define HAVE_EVENTFD - -static inline long eventfd(unsigned count) { - return syscall(SYS_eventfd, count); -} - -#endif +#ifdef HAVE_SYS_EVENTFD_H +#include <sys/eventfd.h> #endif #include "fdsem.h" struct pa_fdsem { int fds[2]; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H int efd; #endif @@ -85,8 +61,8 @@ pa_fdsem *pa_fdsem_new(void) { f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data))); -#ifdef HAVE_EVENTFD - if ((f->efd = eventfd(0)) >= 0) { +#ifdef HAVE_SYS_EVENTFD_H + if ((f->efd = eventfd(0, 0)) >= 0) { pa_make_fd_cloexec(f->efd); f->fds[0] = f->fds[1] = -1; } else @@ -116,7 +92,7 @@ pa_fdsem *pa_fdsem_open_shm(pa_fdsem_data *data, int event_fd) { pa_assert(data); pa_assert(event_fd >= 0); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H f = pa_xnew(pa_fdsem, 1); f->efd = event_fd; @@ -134,11 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) { pa_assert(data); pa_assert(event_fd); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H f = pa_xnew(pa_fdsem, 1); - if ((f->efd = eventfd(0)) < 0) { + if ((f->efd = eventfd(0, 0)) < 0) { pa_xfree(f); return NULL; } @@ -159,7 +135,7 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) { void pa_fdsem_free(pa_fdsem *f) { pa_assert(f); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) pa_close(f->efd); #endif @@ -178,7 +154,7 @@ static void flush(pa_fdsem *f) { do { char x[10]; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) { uint64_t u; @@ -195,7 +171,7 @@ static void flush(pa_fdsem *f) { continue; } - } while (pa_atomic_sub(&f->data->in_pipe, r) > r); + } while (pa_atomic_sub(&f->data->in_pipe, (int) r) > (int) r); } void pa_fdsem_post(pa_fdsem *f) { @@ -211,7 +187,7 @@ void pa_fdsem_post(pa_fdsem *f) { for (;;) { -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) { uint64_t u = 1; @@ -247,7 +223,7 @@ void pa_fdsem_wait(pa_fdsem *f) { char x[10]; ssize_t r; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) { uint64_t u; @@ -265,7 +241,7 @@ void pa_fdsem_wait(pa_fdsem *f) { continue; } - pa_atomic_sub(&f->data->in_pipe, r); + pa_atomic_sub(&f->data->in_pipe, (int) r); } pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1); @@ -285,7 +261,7 @@ int pa_fdsem_try(pa_fdsem *f) { int pa_fdsem_get(pa_fdsem *f) { pa_assert(f); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H if (f->efd >= 0) return f->efd; #endif diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c index fb4497b8..b6423efd 100644 --- a/src/pulsecore/idxset.c +++ b/src/pulsecore/idxset.c @@ -66,7 +66,7 @@ unsigned pa_idxset_string_hash_func(const void *p) { const char *c; for (c = p; *c; c++) - hash = 31 * hash + *c; + hash = 31 * hash + (unsigned) *c; return hash; } diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 90afaafd..88174c05 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -164,7 +164,7 @@ void pa_ioline_puts(pa_ioline *l, const char *c) { /* In case the allocated buffer is too small, enlarge it. */ if (l->wbuf_valid_length + len > l->wbuf_length) { size_t n = l->wbuf_valid_length+len; - char *new = pa_xnew(char, n); + char *new = pa_xnew(char, (unsigned) n); if (l->wbuf) { memcpy(new, l->wbuf+l->wbuf_index, l->wbuf_valid_length); @@ -285,7 +285,7 @@ static int do_read(pa_ioline *l) { memmove(l->rbuf, l->rbuf+l->rbuf_index, l->rbuf_valid_length); } else { /* Enlarge the buffer */ - char *new = pa_xnew(char, n); + char *new = pa_xnew(char, (unsigned) n); if (l->rbuf_valid_length) memcpy(new, l->rbuf+l->rbuf_index, l->rbuf_valid_length); pa_xfree(l->rbuf); @@ -315,10 +315,10 @@ static int do_read(pa_ioline *l) { return -1; } - l->rbuf_valid_length += r; + l->rbuf_valid_length += (size_t) r; /* Look if a line has been terminated in the newly read data */ - scan_for_lines(l, l->rbuf_valid_length - r); + scan_for_lines(l, l->rbuf_valid_length - (size_t) r); } return 0; @@ -346,8 +346,8 @@ static int do_write(pa_ioline *l) { return -1; } - l->wbuf_index += r; - l->wbuf_valid_length -= r; + l->wbuf_index += (size_t) r; + l->wbuf_valid_length -= (size_t) r; /* A shortcut for the next time */ if (l->wbuf_valid_length == 0) diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c index 7b5f865b..6d5080fb 100644 --- a/src/pulsecore/ipacl.c +++ b/src/pulsecore/ipacl.c @@ -122,7 +122,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { if (e.bits < 128) { int t = 0, i; - for (i = 0, bits = e.bits; i < 16; i++) { + for (i = 0, bits = (uint32_t) e.bits; i < 16; i++) { if (bits >= 8) bits -= 8; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index b43113d6..6d12acdc 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -31,6 +31,10 @@ #include <signal.h> #include <errno.h> +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include <valgrind/memcheck.h> +#endif + #include <pulse/xmalloc.h> #include <pulse/def.h> @@ -158,14 +162,14 @@ static void stat_add(pa_memblock*b) { pa_assert(b->pool); pa_atomic_inc(&b->pool->stat.n_allocated); - pa_atomic_add(&b->pool->stat.allocated_size, b->length); + pa_atomic_add(&b->pool->stat.allocated_size, (int) b->length); pa_atomic_inc(&b->pool->stat.n_accumulated); - pa_atomic_add(&b->pool->stat.accumulated_size, b->length); + pa_atomic_add(&b->pool->stat.accumulated_size, (int) b->length); if (b->type == PA_MEMBLOCK_IMPORTED) { pa_atomic_inc(&b->pool->stat.n_imported); - pa_atomic_add(&b->pool->stat.imported_size, b->length); + pa_atomic_add(&b->pool->stat.imported_size, (int) b->length); } pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]); @@ -181,14 +185,14 @@ static void stat_remove(pa_memblock *b) { pa_assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_allocated); - pa_atomic_sub(&b->pool->stat.allocated_size, b->length); + pa_atomic_sub(&b->pool->stat.allocated_size, (int) b->length); if (b->type == PA_MEMBLOCK_IMPORTED) { pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_imported); - pa_atomic_sub(&b->pool->stat.imported_size, b->length); + pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length); } pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); @@ -248,7 +252,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks) pa_atomic_dec(&p->n_init); else - slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * idx)); + slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * (size_t) idx)); if (!slot) { pa_log_info("Pool full"); @@ -257,6 +261,10 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { } } +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); +#endif + return slot; } @@ -272,7 +280,7 @@ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) { pa_assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr); pa_assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); - return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size; + return (unsigned) ((size_t) ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size); } /* No lock necessary */ @@ -519,7 +527,7 @@ static void memblock_free(pa_memblock *b) { case PA_MEMBLOCK_POOL_EXTERNAL: case PA_MEMBLOCK_POOL: { struct mempool_slot *slot; - int call_free; + pa_bool_t call_free; slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data)); pa_assert(slot); @@ -532,6 +540,10 @@ static void memblock_free(pa_memblock *b) { while (pa_flist_push(b->pool->free_slots, slot) < 0) ; +#ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size); +#endif + if (call_free) if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0) pa_xfree(b); @@ -647,7 +659,7 @@ static void memblock_replace_import(pa_memblock *b) { pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_imported); - pa_atomic_sub(&b->pool->stat.imported_size, b->length); + pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length); seg = b->per_type.imported.segment; pa_assert(seg); @@ -754,7 +766,7 @@ void pa_mempool_vacuum(pa_mempool *p) { ; while ((slot = pa_flist_pop(list))) { - pa_shm_punch(&p->memory, (uint8_t*) slot - (uint8_t*) p->memory.ptr, p->block_size); + pa_shm_punch(&p->memory, (size_t) ((uint8_t*) slot - (uint8_t*) p->memory.ptr), p->block_size); while (pa_flist_push(p->free_slots, slot)) ; @@ -967,7 +979,7 @@ void pa_memexport_free(pa_memexport *e) { pa_mutex_lock(e->mutex); while (e->used_slots) - pa_memexport_process_release(e, e->used_slots - e->slots); + pa_memexport_process_release(e, (uint32_t) (e->used_slots - e->slots)); pa_mutex_unlock(e->mutex); pa_mutex_lock(e->pool->mutex); @@ -1006,7 +1018,7 @@ int pa_memexport_process_release(pa_memexport *e, uint32_t id) { pa_assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length); pa_atomic_dec(&e->pool->stat.n_exported); - pa_atomic_sub(&e->pool->stat.exported_size, b->length); + pa_atomic_sub(&e->pool->stat.exported_size, (int) b->length); pa_memblock_unref(b); @@ -1034,7 +1046,7 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { slot->block->per_type.imported.segment->import != i) continue; - idx = slot - e->slots; + idx = (uint32_t) (slot - e->slots); e->revoke_cb(e, idx, e->userdata); pa_memexport_process_release(e, idx); } @@ -1095,7 +1107,7 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 PA_LLIST_PREPEND(struct memexport_slot, e->used_slots, slot); slot->block = b; - *block_id = slot - e->slots; + *block_id = (uint32_t) (slot - e->slots); pa_mutex_unlock(e->mutex); /* pa_log("Got block id %u", *block_id); */ @@ -1115,13 +1127,13 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->ptr + memory->size); *shm_id = memory->id; - *offset = (uint8_t*) data - (uint8_t*) memory->ptr; + *offset = (size_t) ((uint8_t*) data - (uint8_t*) memory->ptr); *size = b->length; pa_memblock_release(b); pa_atomic_inc(&e->pool->stat.n_exported); - pa_atomic_add(&e->pool->stat.exported_size, b->length); + pa_atomic_add(&e->pool->stat.exported_size, (int) b->length); return 0; } diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index 841b9075..265da37f 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -84,7 +84,8 @@ pa_memblockq* pa_memblockq_new( pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu", (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind); - bq->missing = bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0; + bq->missing = 0; + bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0; bq->in_prebuf = TRUE; pa_memblockq_set_maxlength(bq, maxlength); @@ -215,7 +216,7 @@ static void drop_backlog(pa_memblockq *bq) { int64_t boundary; pa_assert(bq); - boundary = bq->read_index - bq->maxrewind; + boundary = bq->read_index - (int64_t) bq->maxrewind; while (bq->blocks && (bq->blocks->index + (int64_t) bq->blocks->chunk.length <= boundary)) drop_block(bq, bq->blocks); @@ -227,10 +228,10 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) { pa_assert(bq); if (bq->read_index > bq->write_index) { - size_t d = bq->read_index - bq->write_index; + int64_t d = bq->read_index - bq->write_index; - if (l > d) - l -= d; + if ((int64_t) l > d) + l -= (size_t) d; else return TRUE; } @@ -239,7 +240,7 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) { /* Make sure that the list doesn't get too long */ if (bq->write_index + (int64_t) l > end) - if (bq->write_index + l - bq->read_index > bq->maxlength) + if (bq->write_index + (int64_t) l - bq->read_index > (int64_t) bq->maxlength) return FALSE; return TRUE; @@ -294,7 +295,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* This entry isn't touched at all, let's skip it */ q = q->prev; } else if (bq->write_index <= q->index && - bq->write_index + chunk.length >= q->index + q->chunk.length) { + bq->write_index + (int64_t) chunk.length >= q->index + (int64_t) q->chunk.length) { /* This entry is fully replaced by the new entry, so let's drop it */ @@ -306,7 +307,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* The write index points into this memblock, so let's * truncate or split it */ - if (bq->write_index + chunk.length < q->index + q->chunk.length) { + if (bq->write_index + (int64_t) chunk.length < q->index + (int64_t) q->chunk.length) { /* We need to save the end of this memchunk */ struct list_item *p; @@ -320,11 +321,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { pa_memblock_ref(p->chunk.memblock); /* Calculate offset */ - d = bq->write_index + chunk.length - q->index; + d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index); pa_assert(d > 0); /* Drop it from the new entry */ - p->index = q->index + d; + p->index = q->index + (int64_t) d; p->chunk.length -= d; /* Add it to the list */ @@ -339,7 +340,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { } /* Truncate the chunk */ - if (!(q->chunk.length = bq->write_index - q->index)) { + if (!(q->chunk.length = (size_t) (bq->write_index - q->index))) { struct list_item *p; p = q; q = q->prev; @@ -357,8 +358,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* The job overwrites the current entry at the end, so let's drop the beginning of this entry */ - d = bq->write_index + chunk.length - q->index; - q->index += d; + d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index); + q->index += (int64_t) d; q->chunk.index += d; q->chunk.length -= d; @@ -373,11 +374,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* Try to merge memory blocks */ if (q->chunk.memblock == chunk.memblock && - q->chunk.index + (int64_t)q->chunk.length == chunk.index && - bq->write_index == q->index + (int64_t)q->chunk.length) { + q->chunk.index + q->chunk.length == chunk.index && + bq->write_index == q->index + (int64_t) q->chunk.length) { q->chunk.length += chunk.length; - bq->write_index += chunk.length; + bq->write_index += (int64_t) chunk.length; goto finish; } } else @@ -389,7 +390,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { n->chunk = chunk; pa_memblock_ref(n->chunk.memblock); n->index = bq->write_index; - bq->write_index += n->chunk.length; + bq->write_index += (int64_t) n->chunk.length; n->next = q ? q->next : bq->blocks; n->prev = q; @@ -411,10 +412,10 @@ finish: delta = bq->write_index - old; if (delta >= (int64_t) bq->requested) { - delta -= bq->requested; + delta -= (int64_t) bq->requested; bq->requested = 0; } else { - bq->requested -= delta; + bq->requested -= (size_t) delta; delta = 0; } @@ -471,7 +472,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { /* How much silence shall we return? */ if (bq->current_read) - length = bq->current_read->index - bq->read_index; + length = (size_t) (bq->current_read->index - bq->read_index); else if (bq->write_index > bq->read_index) length = (size_t) (bq->write_index - bq->read_index); else @@ -506,8 +507,8 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { pa_assert(bq->read_index >= bq->current_read->index); d = bq->read_index - bq->current_read->index; - chunk->index += d; - chunk->length -= d; + chunk->index += (size_t) d; + chunk->length -= (size_t) d; return 0; } @@ -533,20 +534,20 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) { /* We go through this piece by piece to make sure we don't * drop more than allowed by prebuf */ - p = bq->current_read->index + bq->current_read->chunk.length; + p = bq->current_read->index + (int64_t) bq->current_read->chunk.length; pa_assert(p >= bq->read_index); d = p - bq->read_index; if (d > (int64_t) length) - d = length; + d = (int64_t) length; bq->read_index += d; - length -= d; + length -= (size_t) d; } else { /* The list is empty, there's nothing we could drop */ - bq->read_index += length; + bq->read_index += (int64_t) length; break; } } @@ -563,8 +564,8 @@ void pa_memblockq_rewind(pa_memblockq *bq, size_t length) { /* This is kind of the inverse of pa_memblockq_drop() */ - bq->read_index -= length; - bq->missing -= length; + bq->read_index -= (int64_t) length; + bq->missing -= (int64_t) length; } pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) { @@ -628,10 +629,10 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { delta = bq->write_index - old; if (delta >= (int64_t) bq->requested) { - delta -= bq->requested; + delta -= (int64_t) bq->requested; bq->requested = 0; } else if (delta >= 0) { - bq->requested -= delta; + bq->requested -= (size_t) delta; delta = 0; } @@ -652,10 +653,10 @@ void pa_memblockq_flush_write(pa_memblockq *bq) { delta = bq->write_index - old; if (delta >= (int64_t) bq->requested) { - delta -= bq->requested; + delta -= (int64_t) bq->requested; bq->requested = 0; } else if (delta >= 0) { - bq->requested -= delta; + bq->requested -= (size_t) delta; delta = 0; } @@ -874,7 +875,7 @@ int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) { pa_memblock_unref(chunk.memblock); } else - pa_memblockq_seek(bq, chunk.length, PA_SEEK_RELATIVE); + pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE); pa_memblockq_drop(bq, chunk.length); } diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index d257b4ce..9e60125e 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -183,7 +183,7 @@ fail: return NULL; } -static void free_func(void *p, PA_GCC_UNUSED void*userdata) { +static void free_func(void *p, void*userdata) { struct entry *e = p; pa_assert(e); diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index edd0b0a7..29003af8 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -48,7 +48,7 @@ #define UNLOAD_POLL_TIME 2 -static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) { pa_core *c = PA_CORE(userdata); struct timeval ntv; @@ -156,9 +156,6 @@ static void pa_module_free(pa_module *m) { pa_assert(m); pa_assert(m->core); - if (m->core->disallow_module_loading) - return; - pa_log_info("Unloading \"%s\" (index: #%u).", m->name, m->index); if (m->done) @@ -175,22 +172,27 @@ static void pa_module_free(pa_module *m) { pa_xfree(m); } -void pa_module_unload(pa_core *c, pa_module *m) { +void pa_module_unload(pa_core *c, pa_module *m, pa_bool_t force) { pa_assert(c); pa_assert(m); - pa_assert(c->modules); + if (m->core->disallow_module_loading && !force) + return; + if (!(m = pa_idxset_remove_by_data(c->modules, m, NULL))) return; pa_module_free(m); } -void pa_module_unload_by_index(pa_core *c, uint32_t idx) { +void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) { pa_module *m; pa_assert(c); pa_assert(idx != PA_IDXSET_INVALID); + if (c->disallow_module_loading && !force) + return; + if (!(m = pa_idxset_remove_by_index(c->modules, idx))) return; @@ -198,7 +200,6 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx) { } void pa_module_unload_all(pa_core *c) { - pa_assert(c); if (c->modules) { @@ -245,7 +246,7 @@ void pa_module_unload_unused(pa_core *c) { if (m->last_used_time + m->core->module_idle_time > now) continue; - pa_module_unload(c, m); + pa_module_unload(c, m, FALSE); } } @@ -262,12 +263,15 @@ static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) { while ((m = pa_idxset_iterate(c->modules, &state, NULL))) if (m->unload_requested) - pa_module_unload(c, m); + pa_module_unload(c, m, TRUE); } -void pa_module_unload_request(pa_module *m) { +void pa_module_unload_request(pa_module *m, pa_bool_t force) { pa_assert(m); + if (m->core->disallow_module_loading && !force) + return; + m->unload_requested = TRUE; if (!m->core->module_defer_unload_event) diff --git a/src/pulsecore/module.h b/src/pulsecore/module.h index bb3a3f57..365ab67e 100644 --- a/src/pulsecore/module.h +++ b/src/pulsecore/module.h @@ -52,13 +52,13 @@ struct pa_module { }; pa_module* pa_module_load(pa_core *c, const char *name, const char*argument); -void pa_module_unload(pa_core *c, pa_module *m); -void pa_module_unload_by_index(pa_core *c, uint32_t idx); +void pa_module_unload(pa_core *c, pa_module *m, pa_bool_t force); +void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force); void pa_module_unload_all(pa_core *c); void pa_module_unload_unused(pa_core *c); -void pa_module_unload_request(pa_module *m); +void pa_module_unload_request(pa_module *m, pa_bool_t force); void pa_module_set_used(pa_module*m, int used); diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c index 30420546..ad697ed5 100644 --- a/src/pulsecore/namereg.c +++ b/src/pulsecore/namereg.c @@ -45,7 +45,7 @@ struct namereg_entry { void *data; }; -static int is_valid_char(char c) { +static pa_bool_t is_valid_char(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || @@ -77,10 +77,10 @@ char* pa_namereg_make_valid_name(const char *name) { if (*name == 0) return NULL; - n = pa_xnew(char, strlen(name)+1); + n = pa_xmalloc(strlen(name)+1); for (a = name, b = n; *a && (a-name < PA_NAME_MAX); a++, b++) - *b = is_valid_char(*a) ? *a : '_'; + *b = (char) (is_valid_char(*a) ? *a : '_'); *b = 0; @@ -136,7 +136,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t return NULL; } - k = pa_xnew(char, l+4); + k = pa_xmalloc(l+4); for (i = 2; i <= 99; i++) { pa_snprintf(k, l+4, "%s.%u", name, i); diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c index f2b6b2cf..c5cd7fe7 100644 --- a/src/pulsecore/parseaddr.c +++ b/src/pulsecore/parseaddr.c @@ -51,20 +51,29 @@ static char *parse_host(const char *s, uint16_t *ret_port) { if (!(e = strchr(s+1, ']'))) return NULL; - if (e[1] == ':') - *ret_port = atoi(e+2); - else if (e[1] != 0) + if (e[1] == ':') { + uint32_t p; + + if (pa_atou(e+2, &p) < 0) + return NULL; + + *ret_port = (uint16_t) p; + } else if (e[1] != 0) return NULL; - return pa_xstrndup(s+1, e-s-1); + return pa_xstrndup(s+1, (size_t) (e-s-1)); } else { char *e; + uint32_t p; if (!(e = strrchr(s, ':'))) return pa_xstrdup(s); - *ret_port = atoi(e+1); - return pa_xstrndup(s, e-s); + if (pa_atou(e+1, &p) < 0) + return NULL; + + *ret_port = (uint16_t) p; + return pa_xstrndup(s, (size_t) (e-s)); } } diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c index e6a6ae4d..00df0f79 100644 --- a/src/pulsecore/pdispatch.c +++ b/src/pulsecore/pdispatch.c @@ -255,7 +255,7 @@ finish: return ret; } -static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, const struct timeval *tv, void *userdata) { struct reply_info*r = userdata; pa_assert(r); diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index addb17cc..1c0851ba 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -73,6 +73,7 @@ static pid_t read_pid(const char *fn, int fd) { if (pa_atou(t, &pid) < 0) { pa_log_warn("Failed to parse PID file '%s'", fn); + errno = EINVAL; return (pid_t) -1; } @@ -110,7 +111,7 @@ static int open_pid_file(const char *fn, int mode) { goto fail; } - /* Does the file still exist in the file system? When ye, w're done, otherwise restart */ + /* Does the file still exist in the file system? When yes, we're done, otherwise restart */ if (st.st_nlink >= 1) break; @@ -131,8 +132,10 @@ static int open_pid_file(const char *fn, int mode) { fail: if (fd >= 0) { + int saved_errno = errno; pa_lock_fd(fd, 0); pa_close(fd); + errno = saved_errno; } return -1; @@ -154,8 +157,11 @@ static int proc_name_ours(pid_t pid, const char *procname) { char stored[64]; if (!(fgets(stored, sizeof(stored), f))) { + int saved_errno = feof(f) ? EINVAL : errno; pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno)); fclose(f); + + errno = saved_errno; return -1; } @@ -176,9 +182,11 @@ static int proc_name_ours(pid_t pid, const char *procname) { return !!good; } -#endif +#else return 1; +#endif + } /* Create a new PID file for the current process. */ @@ -342,8 +350,13 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) { if (!(fn = pa_runtime_path("pid"))) goto fail; - if ((fd = open_pid_file(fn, O_RDONLY)) < 0) + if ((fd = open_pid_file(fn, O_RDONLY)) < 0) { + + if (errno == ENOENT) + errno = ESRCH; + goto fail; + } if ((*pid = read_pid(fn, fd)) == (pid_t) -1) goto fail; @@ -354,8 +367,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) { if ((ours = proc_name_ours(*pid, procname)) < 0) goto fail; - if (!ours) + if (!ours) { + errno = ESRCH; goto fail; + } } ret = kill(*pid, sig); @@ -363,8 +378,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) { fail: if (fd >= 0) { + int saved_errno = errno; pa_lock_fd(fd, 0); pa_close(fd); + errno = saved_errno; } #ifdef __linux__ diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 8b3e79b9..86edfe98 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -146,7 +146,6 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) { memblockq_stream *u; pa_sink_input_assert_ref(i); - pa_assert(nbytes > 0); u = MEMBLOCKQ_STREAM(i->userdata); memblockq_stream_assert_ref(u); diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 4f121a3a..460119a9 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -184,7 +184,7 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = { { sizeof(int), esd_proto_sample_free_or_play, "sample play" }, /* 8 */ { sizeof(int), NULL, "sample loop" }, { sizeof(int), NULL, "sample stop" }, - { -1, NULL, "TODO: sample kill" }, + { (size_t) -1, NULL, "TODO: sample kill" }, { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "standby" }, /* NOOP! */ { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "resume" }, /* NOOP! */ /* 13 */ @@ -194,8 +194,8 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = { { sizeof(int), esd_proto_server_info, "server info" }, { sizeof(int), esd_proto_all_info, "all info" }, - { -1, NULL, "TODO: subscribe" }, - { -1, NULL, "TODO: unsubscribe" }, + { (size_t) -1, NULL, "TODO: subscribe" }, + { (size_t) -1, NULL, "TODO: unsubscribe" }, { 3 * sizeof(int), esd_proto_stream_pan, "stream pan"}, { 3 * sizeof(int), NULL, "sample pan" }, @@ -309,7 +309,7 @@ static void connection_write(connection *c, const void *data, size_t length) { static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) { pa_assert(ss); - ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; + ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1); if ((format & ESD_MASK_BITS) == ESD_BITS16) ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE; else @@ -334,7 +334,7 @@ static int format_native2esd(pa_sample_spec *ss) { /*** esound commands ***/ -static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length) { uint32_t ekey; int ok; @@ -377,7 +377,7 @@ static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, c return 0; } -static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length) { char name[ESD_NAME_MAX], *utf8_name; int32_t format, rate; pa_sample_spec ss; @@ -397,7 +397,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*) data + sizeof(int32_t); - ss.rate = rate; + ss.rate = (uint32_t) rate; format_esd2native(format, c->swap_byte_order, &ss); CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification"); @@ -430,7 +430,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques CHECK_VALIDITY(c->sink_input, "Failed to create sink input."); - l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS); + l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS); c->input_memblockq = pa_memblockq_new( 0, l, @@ -455,7 +455,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques c->protocol->n_player++; - pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq)); pa_sink_input_put(c->sink_input); @@ -482,7 +482,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*) data + sizeof(int32_t); - ss.rate = rate; + ss.rate = (uint32_t) rate; format_esd2native(format, c->swap_byte_order, &ss); CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); @@ -561,7 +561,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi return 0; } -static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) { pa_sink *sink; int32_t latency; @@ -572,7 +572,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques if (!(sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1))) latency = 0; else { - double usec = pa_sink_get_latency(sink); + double usec = (double) pa_sink_get_latency(sink); latency = (int) ((usec*44100)/1000000); } @@ -581,7 +581,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques return 0; } -static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) { int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16; int32_t response; pa_sink *sink; @@ -591,7 +591,7 @@ static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t reques pa_assert(length == sizeof(int32_t)); if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1))) { - rate = sink->sample_spec.rate; + rate = (int32_t) sink->sample_spec.rate; format = format_native2esd(&sink->sample_spec); } @@ -641,9 +641,9 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da if (conn->sink_input) { pa_cvolume volume = *pa_sink_input_get_volume(conn->sink_input); - rate = conn->sink_input->sample_spec.rate; - lvolume = (volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; - rvolume = (volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; + rate = (int32_t) conn->sink_input->sample_spec.rate; + lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); + rvolume = (int32_t) ((volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); format = format_native2esd(&conn->sink_input->sample_spec); } @@ -706,15 +706,15 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da connection_write(c, name, ESD_NAME_MAX); /* rate */ - rate = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ce->sample_spec.rate); connection_write(c, &rate, sizeof(int32_t)); /* left */ - lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); + lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM)); connection_write(c, &lvolume, sizeof(int32_t)); /*right*/ - rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); + rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM)); connection_write(c, &rvolume, sizeof(int32_t)); /*format*/ @@ -736,7 +736,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da return 0; } -static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) { int32_t ok; uint32_t idx, lvolume, rvolume; connection *conn; @@ -772,7 +772,7 @@ static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request return 0; } -static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) { pa_sample_spec ss; int32_t format, rate, sc_length; uint32_t idx; @@ -790,7 +790,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*)data + sizeof(int32_t); - ss.rate = rate; + ss.rate = (uint32_t) rate; format_esd2native(format, c->swap_byte_order, &ss); CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); @@ -807,9 +807,9 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name."); pa_assert(!c->scache.memchunk.memblock); - c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, sc_length); + c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length); c->scache.memchunk.index = 0; - c->scache.memchunk.length = sc_length; + c->scache.memchunk.length = (size_t) sc_length; c->scache.sample_spec = ss; pa_assert(!c->scache.name); c->scache.name = pa_xstrdup(name); @@ -824,7 +824,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque return 0; } -static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) { int32_t ok; uint32_t idx; char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; @@ -840,7 +840,7 @@ static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t requ ok = -1; if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID) - ok = idx + 1; + ok = (int32_t) idx + 1; connection_write(c, &ok, sizeof(int32_t)); @@ -867,12 +867,12 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1))) if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM, c->client->proplist, NULL) >= 0) - ok = idx + 1; + ok = (int32_t) idx + 1; } else { pa_assert(request == ESD_PROTO_SAMPLE_FREE); if (pa_scache_remove_item(c->protocol->core, name) >= 0) - ok = idx + 1; + ok = (int32_t) idx + 1; } } @@ -881,7 +881,7 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con return 0; } -static int esd_proto_standby_or_resume(connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) { +static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) { int32_t ok; connection_assert_ref(c); @@ -919,7 +919,9 @@ static int do_read(connection *c) { return -1; } - if ((c->read_data_length+= r) >= sizeof(c->request)) { + c->read_data_length += (size_t) r; + + if (c->read_data_length >= sizeof(c->request)) { struct proto_handler *handler; c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request); @@ -970,7 +972,8 @@ static int do_read(connection *c) { return -1; } - if ((c->read_data_length += r) >= handler->data_length) { + c->read_data_length += (size_t) r; + if (c->read_data_length >= handler->data_length) { size_t l = c->read_data_length; pa_assert(handler->proc); @@ -1000,7 +1003,7 @@ static int do_read(connection *c) { return -1; } - c->scache.memchunk.index += r; + c->scache.memchunk.index += (size_t) r; pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length); if (c->scache.memchunk.index == c->scache.memchunk.length) { @@ -1033,7 +1036,7 @@ static int do_read(connection *c) { /* pa_log("STREAMING_DATA"); */ - if (!(l = pa_atomic_load(&c->playback.missing))) + if (!(l = (size_t) pa_atomic_load(&c->playback.missing))) return 0; if (c->playback.current_memblock) { @@ -1071,12 +1074,12 @@ static int do_read(connection *c) { chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; - chunk.length = r; + chunk.length = (size_t) r; - c->playback.memblock_index += r; + c->playback.memblock_index += (size_t) r; pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); - pa_atomic_sub(&c->playback.missing, r); + pa_atomic_sub(&c->playback.missing, (int) r); } return 0; @@ -1100,7 +1103,8 @@ static int do_write(connection *c) { return -1; } - if ((c->write_data_index +=r) >= c->write_data_length) + c->write_data_index += (size_t) r; + if (c->write_data_index >= c->write_data_length) c->write_data_length = c->write_data_index = 0; } else if (c->state == ESD_STREAMING_DATA && c->source_output) { @@ -1129,7 +1133,7 @@ static int do_write(connection *c) { return -1; } - pa_memblockq_drop(c->output_memblockq, r); + pa_memblockq_drop(c->output_memblockq, (size_t) r); } return 0; @@ -1288,7 +1292,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk m = pa_memblockq_pop_missing(c->input_memblockq); if (m > 0) - if (pa_atomic_add(&c->playback.missing, m) <= 0) + if (pa_atomic_add(&c->playback.missing, (int) m) <= 0) pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); return 0; @@ -1574,7 +1578,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) { if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) { pa_ip_acl *ipa; - if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) { + if (!(ipa = pa_ip_acl_new(acl))) { pa_log("Failed to parse IP ACL '%s'", acl); return -1; } diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index ef56a6f4..1ee7a971 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -50,7 +50,6 @@ #include <pulsecore/core-subscribe.h> #include <pulsecore/log.h> #include <pulsecore/autoload.h> -#include <pulsecore/authkey-prop.h> #include <pulsecore/strlist.h> #include <pulsecore/shared.h> #include <pulsecore/sample-util.h> @@ -73,13 +72,12 @@ #define DEFAULT_PROCESS_MSEC 20 /* 20ms */ #define DEFAULT_FRAGSIZE_MSEC DEFAULT_TLENGTH_MSEC -typedef struct connection connection; struct pa_native_protocol; typedef struct record_stream { pa_msgobject parent; - connection *connection; + pa_native_connection *connection; uint32_t index; pa_source_output *source_output; @@ -103,7 +101,7 @@ static PA_DEFINE_CHECK_TYPE(output_stream, pa_msgobject); typedef struct playback_stream { output_stream parent; - connection *connection; + pa_native_connection *connection; uint32_t index; pa_sink_input *sink_input; @@ -129,7 +127,7 @@ static PA_DEFINE_CHECK_TYPE(playback_stream, output_stream); typedef struct upload_stream { output_stream parent; - connection *connection; + pa_native_connection *connection; uint32_t index; pa_memchunk memchunk; @@ -144,7 +142,7 @@ PA_DECLARE_CLASS(upload_stream); #define UPLOAD_STREAM(o) (upload_stream_cast(o)) static PA_DEFINE_CHECK_TYPE(upload_stream, output_stream); -struct connection { +struct pa_native_connection { pa_msgobject parent; pa_native_protocol *protocol; pa_native_options *options; @@ -160,9 +158,9 @@ struct connection { pa_time_event *auth_timeout_event; }; -PA_DECLARE_CLASS(connection); -#define CONNECTION(o) (connection_cast(o)) -static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); +PA_DECLARE_CLASS(pa_native_connection); +#define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o)) +static PA_DEFINE_CHECK_TYPE(pa_native_connection, pa_msgobject); struct pa_native_protocol { PA_REFCNT_DECLARE; @@ -171,10 +169,9 @@ struct pa_native_protocol { pa_idxset *connections; pa_strlist *servers; - pa_hook servers_changed; + pa_hook hooks[PA_NATIVE_HOOK_MAX]; pa_hashmap *extensions; - }; enum { @@ -212,8 +209,8 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes); static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes); static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes); -static void send_memblock(connection *c); -static void request_bytes(struct playback_stream*s); +static void native_connection_send_memblock(pa_native_connection *c); +static void playback_stream_request_bytes(struct playback_stream*s); static void source_output_kill_cb(pa_source_output *o); static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); @@ -389,7 +386,7 @@ static void upload_stream_free(pa_object *o) { } static upload_stream* upload_stream_new( - connection *c, + pa_native_connection *c, const pa_sample_spec *ss, const pa_channel_map *map, const char *name, @@ -464,7 +461,7 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i } if (!pa_pstream_is_pending(s->connection->pstream)) - send_memblock(s->connection); + native_connection_send_memblock(s->connection); break; } @@ -480,12 +477,12 @@ static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latenc if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH) *maxlength = MAX_MEMBLOCKQ_LENGTH; if (*maxlength <= 0) - *maxlength = pa_frame_size(&s->source_output->sample_spec); + *maxlength = (uint32_t) pa_frame_size(&s->source_output->sample_spec); if (*fragsize == (uint32_t) -1) - *fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec); + *fragsize = (uint32_t) pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec); if (*fragsize <= 0) - *fragsize = pa_frame_size(&s->source_output->sample_spec); + *fragsize = (uint32_t) pa_frame_size(&s->source_output->sample_spec); if (adjust_latency) { pa_usec_t fragsize_usec; @@ -504,7 +501,7 @@ static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latenc else fragsize_usec = s->source_latency; - *fragsize = pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec); + *fragsize = (uint32_t) pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec); } else s->source_latency = 0; } @@ -516,7 +513,7 @@ static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, u pa_assert(maxlength); pa_assert(fragsize); - *maxlength = pa_memblockq_get_maxlength(s->memblockq); + *maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq); base = pa_frame_size(&s->source_output->sample_spec); @@ -527,11 +524,11 @@ static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, u if (s->fragment_size > *maxlength) s->fragment_size = *maxlength; - *fragsize = s->fragment_size; + *fragsize = (uint32_t) s->fragment_size; } static record_stream* record_stream_new( - connection *c, + pa_native_connection *c, pa_source *source, pa_sample_spec *ss, pa_channel_map *map, @@ -615,6 +612,17 @@ static record_stream* record_stream_new( return s; } +static void record_stream_send_killed(record_stream *r) { + pa_tagstruct *t; + record_stream_assert_ref(r); + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, r->index); + pa_pstream_send_tagstruct(r->connection->pstream, t); +} + static void playback_stream_unlink(playback_stream *s) { pa_assert(s); @@ -658,10 +666,10 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, uint32_t l = 0; for (;;) { - if ((l = pa_atomic_load(&s->missing)) <= 0) + if ((l = (uint32_t) pa_atomic_load(&s->missing)) <= 0) break; - if (pa_atomic_cmpxchg(&s->missing, l, 0)) + if (pa_atomic_cmpxchg(&s->missing, (int) l, 0)) break; } @@ -741,20 +749,20 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH) *maxlength = MAX_MEMBLOCKQ_LENGTH; if (*maxlength <= 0) - *maxlength = frame_size; + *maxlength = (uint32_t) frame_size; if (*tlength == (uint32_t) -1) - *tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); + *tlength = (uint32_t) pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); if (*tlength <= 0) - *tlength = frame_size; + *tlength = (uint32_t) frame_size; if (*minreq == (uint32_t) -1) - *minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); + *minreq = (uint32_t) pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); if (*minreq <= 0) - *minreq = frame_size; + *minreq = (uint32_t) frame_size; if (*tlength < *minreq+frame_size) - *tlength = *minreq+frame_size; + *tlength = *minreq+(uint32_t) frame_size; tlength_usec = pa_bytes_to_usec(*tlength, &s->sink_input->sample_spec); minreq_usec = pa_bytes_to_usec(*minreq, &s->sink_input->sample_spec); @@ -815,16 +823,16 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la if (tlength_usec < s->sink_latency + 2*minreq_usec) tlength_usec = s->sink_latency + 2*minreq_usec; - *tlength = pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec); - *minreq = pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec); + *tlength = (uint32_t) pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec); + *minreq = (uint32_t) pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec); if (*minreq <= 0) { - *minreq += frame_size; - *tlength += frame_size*2; + *minreq += (uint32_t) frame_size; + *tlength += (uint32_t) frame_size*2; } if (*tlength <= *minreq) - *tlength = *minreq*2 + frame_size; + *tlength = *minreq*2 + (uint32_t) frame_size; if (*prebuf == (uint32_t) -1 || *prebuf > *tlength) *prebuf = *tlength; @@ -846,7 +854,7 @@ static void fix_playback_buffer_attr_post(playback_stream *s, uint32_t *maxlengt } static playback_stream* playback_stream_new( - connection *c, + pa_native_connection *c, pa_sink *sink, pa_sample_spec *ss, pa_channel_map *map, @@ -875,7 +883,6 @@ static playback_stream* playback_stream_new( pa_assert(tlength); pa_assert(prebuf); pa_assert(minreq); - pa_assert(volume); pa_assert(missing); pa_assert(p); @@ -908,7 +915,8 @@ static playback_stream* playback_stream_new( data.sink = sink; pa_sink_input_new_data_set_sample_spec(&data, ss); pa_sink_input_new_data_set_channel_map(&data, map); - pa_sink_input_new_data_set_volume(&data, volume); + if (volume) + pa_sink_input_new_data_set_volume(&data, volume); pa_sink_input_new_data_set_muted(&data, muted); data.sync_base = ssync ? ssync->sink_input : NULL; @@ -974,9 +982,42 @@ static playback_stream* playback_stream_new( return s; } -static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { - connection *c = CONNECTION(o); - connection_assert_ref(c); + +/* Called from thread context */ +static void playback_stream_request_bytes(playback_stream *s) { + size_t m, previous_missing; + + playback_stream_assert_ref(s); + + m = pa_memblockq_pop_missing(s->memblockq); + + if (m <= 0) + return; + +/* pa_log("request_bytes(%lu)", (unsigned long) m); */ + + previous_missing = (size_t) pa_atomic_add(&s->missing, (int) m); + + if (pa_memblockq_prebuf_active(s->memblockq) || + (previous_missing < s->minreq && previous_missing+m >= s->minreq)) + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); +} + + +static void playback_stream_send_killed(playback_stream *p) { + pa_tagstruct *t; + playback_stream_assert_ref(p); + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, p->index); + pa_pstream_send_tagstruct(p->connection->pstream, t); +} + +static int native_connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + pa_native_connection *c = PA_NATIVE_CONNECTION(o); + pa_native_connection_assert_ref(c); if (!c->protocol) return -1; @@ -995,7 +1036,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 return 0; } -static void connection_unlink(connection *c) { +static void native_connection_unlink(pa_native_connection *c) { record_stream *r; output_stream *o; @@ -1004,6 +1045,8 @@ static void connection_unlink(connection *c) { if (!c->protocol) return; + pa_hook_fire(&c->protocol->hooks[PA_NATIVE_HOOK_CONNECTION_UNLINK], c); + if (c->options) pa_native_options_unref(c->options); @@ -1029,15 +1072,15 @@ static void connection_unlink(connection *c) { pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); c->protocol = NULL; - connection_unref(c); + pa_native_connection_unref(c); } -static void connection_free(pa_object *o) { - connection *c = CONNECTION(o); +static void native_connection_free(pa_object *o) { + pa_native_connection *c = PA_NATIVE_CONNECTION(o); pa_assert(c); - connection_unlink(c); + native_connection_unlink(c); pa_idxset_free(c->record_streams, NULL, NULL); pa_idxset_free(c->output_streams, NULL, NULL); @@ -1049,27 +1092,7 @@ static void connection_free(pa_object *o) { pa_xfree(c); } -/* Called from thread context */ -static void request_bytes(playback_stream *s) { - size_t m, previous_missing; - - playback_stream_assert_ref(s); - - m = pa_memblockq_pop_missing(s->memblockq); - - if (m <= 0) - return; - -/* pa_log("request_bytes(%lu)", (unsigned long) m); */ - - previous_missing = pa_atomic_add(&s->missing, m); - - if (pa_memblockq_prebuf_active(s->memblockq) || - (previous_missing < s->minreq && previous_missing+m >= s->minreq)) - pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); -} - -static void send_memblock(connection *c) { +static void native_connection_send_memblock(pa_native_connection *c) { uint32_t start; record_stream *r; @@ -1101,28 +1124,6 @@ static void send_memblock(connection *c) { } } -static void send_playback_stream_killed(playback_stream *p) { - pa_tagstruct *t; - playback_stream_assert_ref(p); - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, p->index); - pa_pstream_send_tagstruct(p->connection->pstream, t); -} - -static void send_record_stream_killed(record_stream *r) { - pa_tagstruct *t; - record_stream_assert_ref(r); - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, r->index); - pa_pstream_send_tagstruct(r->connection->pstream, t); -} - /*** sink input callbacks ***/ static void handle_seek(playback_stream *s, int64_t indexw) { @@ -1141,7 +1142,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) { pa_log_debug("Requesting rewind due to end of underrun."); pa_sink_input_request_rewind(s->sink_input, - s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for, + (size_t) (s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for), FALSE, TRUE); } @@ -1155,11 +1156,11 @@ static void handle_seek(playback_stream *s, int64_t indexw) { * let's have it usk us again */ pa_log_debug("Requesting rewind due to rewrite."); - pa_sink_input_request_rewind(s->sink_input, indexr - indexw, TRUE, FALSE); + pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE); } } - request_bytes(s); + playback_stream_request_bytes(s); } /* Called from thread context */ @@ -1195,7 +1196,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { pa_log_warn("Failed to push data into queue"); pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL); - pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE); + pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE); } handle_seek(s, windex); @@ -1321,7 +1322,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk s->is_underrun = TRUE; - request_bytes(s); + playback_stream_request_bytes(s); } /* This call will not fail with prebuf=0, hence we check for @@ -1335,7 +1336,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_STARTED, NULL, 0, NULL, NULL); pa_memblockq_drop(s->memblockq, chunk->length); - request_bytes(s); + playback_stream_request_bytes(s); return 0; } @@ -1386,7 +1387,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { s = PLAYBACK_STREAM(i->userdata); playback_stream_assert_ref(s); - send_playback_stream_killed(s); + playback_stream_send_killed(s); playback_stream_unlink(s); } @@ -1475,7 +1476,7 @@ static void source_output_kill_cb(pa_source_output *o) { s = RECORD_STREAM(o->userdata); record_stream_assert_ref(s); - send_record_stream_killed(s); + record_stream_send_killed(s); record_stream_unlink(s); } @@ -1550,9 +1551,9 @@ static void source_output_moved_cb(pa_source_output *o) { /*** pdispatch callbacks ***/ -static void protocol_error(connection *c) { +static void protocol_error(pa_native_connection *c) { pa_log("protocol error, kicking client"); - connection_unlink(c); + native_connection_unlink(c); } #define CHECK_VALIDITY(pstream, expression, tag, error) do { \ @@ -1571,8 +1572,8 @@ static pa_tagstruct *reply_new(uint32_t tag) { return reply; } -static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); playback_stream *s; uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid, missing; const char *name = NULL, *sink_name; @@ -1595,8 +1596,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_sink_input_flags_t flags = 0; pa_proplist *p; + pa_bool_t volume_set = TRUE; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if ((c->version < 13 && (pa_tagstruct_gets(t, &name) < 0 || !name)) || @@ -1620,7 +1622,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(sink_name)), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); @@ -1659,6 +1663,15 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC } } + if (c->version >= 14) { + + if (pa_tagstruct_get_boolean(t, &volume_set) < 0) { + protocol_error(c); + pa_proplist_free(p); + return; + } + } + if (!pa_tagstruct_eof(t)) { protocol_error(c); pa_proplist_free(p); @@ -1692,7 +1705,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC (no_move ? PA_SINK_INPUT_DONT_MOVE : 0) | (variable_rate ? PA_SINK_INPUT_VARIABLE_RATE : 0); - s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, &volume, muted, syncid, &missing, flags, p, adjust_latency); + s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, volume_set ? &volume : NULL, muted, syncid, &missing, flags, p, adjust_latency); pa_proplist_free(p); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); @@ -1734,11 +1747,11 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t channel; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &channel) < 0 || @@ -1792,8 +1805,8 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); record_stream *s; uint32_t maxlength, fragment_size; uint32_t source_index; @@ -1818,7 +1831,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ uint32_t direct_on_input_idx = PA_INVALID_INDEX; pa_sink_input *direct_on_input = NULL; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if ((c->version < 13 && (pa_tagstruct_gets(t, &name) < 0 || !name)) || @@ -1834,9 +1847,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); + CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name(source_name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, source_index != PA_INVALID_INDEX || !source_name || (*source_name && pa_utf8_valid(source_name)), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID); p = pa_proplist_new(); @@ -1952,10 +1967,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); + int ret; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (!pa_tagstruct_eof(t)) { @@ -1964,18 +1980,19 @@ static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); + ret = pa_core_exit(c->protocol->core, FALSE, 0); + CHECK_VALIDITY(c->pstream, ret >= 0, tag, PA_ERR_ACCESS); - c->protocol->core->mainloop->quit(c->protocol->core->mainloop, 0); pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */ } -static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const void*cookie; pa_tagstruct *reply; pa_bool_t shm_on_remote, do_shm; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &c->version) < 0 || @@ -1992,7 +2009,7 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t } /* Starting with protocol version 13 the MSB of the version tag - reflects if shm is available for this connection or + reflects if shm is available for this pa_native_connection or not. */ if (c->version >= 13) { shm_on_remote = !!(c->version & 0x80000000U); @@ -2100,13 +2117,13 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t #endif } -static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *name = NULL; pa_proplist *p; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); p = pa_proplist_new(); @@ -2140,12 +2157,12 @@ static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *name; uint32_t idx = PA_IDXSET_INVALID; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || @@ -2155,7 +2172,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); if (command == PA_COMMAND_LOOKUP_SINK) { pa_sink *sink; @@ -2178,12 +2195,12 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin } } -static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; playback_stream *s; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2200,12 +2217,12 @@ static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC pa_asyncmsgq_post(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_DRAIN, PA_UINT_TO_PTR(tag), 0, NULL, NULL); } -static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_stat(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; const pa_mempool_stat *stat; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (!pa_tagstruct_eof(t)) { @@ -2222,19 +2239,19 @@ static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->allocated_size)); pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->n_accumulated)); pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->accumulated_size)); - pa_tagstruct_putu32(reply, pa_scache_total_size(c->protocol->core)); + pa_tagstruct_putu32(reply, (uint32_t) pa_scache_total_size(c->protocol->core)); pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_playback_latency(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; playback_stream *s; struct timeval tv, now; uint32_t idx; pa_usec_t latency; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2272,14 +2289,14 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_record_latency(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; record_stream *s; struct timeval tv, now; uint32_t idx; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2304,8 +2321,8 @@ static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); upload_stream *s; uint32_t length; const char *name = NULL; @@ -2314,7 +2331,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_tagstruct *reply; pa_proplist *p; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || @@ -2346,7 +2363,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ if (!(name = pa_proplist_gets(p, PA_PROP_EVENT_ID))) name = pa_proplist_gets(p, PA_PROP_MEDIA_NAME); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); s = upload_stream_new(c, &ss, &map, name, length, p); pa_proplist_free(p); @@ -2359,13 +2376,13 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t channel; upload_stream *s; uint32_t idx; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &channel) < 0 || @@ -2388,8 +2405,8 @@ static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ upload_stream_unlink(s); } -static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t sink_index; pa_volume_t volume; pa_sink *sink; @@ -2398,7 +2415,7 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui pa_proplist *p; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -2411,8 +2428,10 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui return; } - CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); if (sink_index != PA_INVALID_INDEX) sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index); @@ -2430,6 +2449,8 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui return; } + pa_proplist_update(p, PA_UPDATE_MERGE, c->client->proplist); + if (pa_scache_play_item(c->protocol->core, name, sink, volume, p, &idx) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); pa_proplist_free(p); @@ -2446,11 +2467,11 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *name; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || @@ -2460,7 +2481,7 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); if (pa_scache_remove_item(c->protocol->core, name) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); @@ -2470,7 +2491,7 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED pa_pstream_send_simple_ack(c->pstream, tag); } -static void fixup_sample_spec(connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) { +static void fixup_sample_spec(pa_native_connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) { pa_assert(c); pa_assert(fixed); pa_assert(original); @@ -2488,7 +2509,7 @@ static void fixup_sample_spec(connection *c, pa_sample_spec *fixed, const pa_sam } } -static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) { +static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink *sink) { pa_sample_spec fixed_ss; pa_assert(t); @@ -2504,8 +2525,8 @@ static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) { PA_TAG_SAMPLE_SPEC, &fixed_ss, PA_TAG_CHANNEL_MAP, &sink->channel_map, PA_TAG_U32, sink->module ? sink->module->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_sink_get_volume(sink), - PA_TAG_BOOLEAN, pa_sink_get_mute(sink), + PA_TAG_CVOLUME, pa_sink_get_volume(sink, FALSE), + PA_TAG_BOOLEAN, pa_sink_get_mute(sink, FALSE), PA_TAG_U32, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL, PA_TAG_USEC, pa_sink_get_latency(sink), @@ -2519,7 +2540,7 @@ static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) { } } -static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *source) { +static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source *source) { pa_sample_spec fixed_ss; pa_assert(t); @@ -2535,8 +2556,8 @@ static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *sou PA_TAG_SAMPLE_SPEC, &fixed_ss, PA_TAG_CHANNEL_MAP, &source->channel_map, PA_TAG_U32, source->module ? source->module->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_source_get_volume(source), - PA_TAG_BOOLEAN, pa_source_get_mute(source), + PA_TAG_CVOLUME, pa_source_get_volume(source, FALSE), + PA_TAG_BOOLEAN, pa_source_get_mute(source, FALSE), PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX, PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL, PA_TAG_USEC, pa_source_get_latency(source), @@ -2551,7 +2572,7 @@ static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *sou } -static void client_fill_tagstruct(connection *c, pa_tagstruct *t, pa_client *client) { +static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_client *client) { pa_assert(t); pa_assert(client); @@ -2572,11 +2593,11 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { pa_tagstruct_putu32(t, module->index); pa_tagstruct_puts(t, module->name); pa_tagstruct_puts(t, module->argument); - pa_tagstruct_putu32(t, module->n_used); + pa_tagstruct_putu32(t, (uint32_t) module->n_used); pa_tagstruct_put_boolean(t, module->auto_unload); } -static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_input *s) { +static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink_input *s) { pa_sample_spec fixed_ss; pa_usec_t sink_latency; @@ -2603,7 +2624,7 @@ static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_in pa_tagstruct_put_proplist(t, s->proplist); } -static void source_output_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source_output *s) { +static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source_output *s) { pa_sample_spec fixed_ss; pa_usec_t source_latency; @@ -2628,7 +2649,7 @@ static void source_output_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sour pa_tagstruct_put_proplist(t, s->proplist); } -static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entry *e) { +static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_scache_entry *e) { pa_sample_spec fixed_ss; pa_assert(t); @@ -2645,7 +2666,7 @@ static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entr pa_tagstruct_put_usec(t, e->memchunk.memblock ? pa_bytes_to_usec(e->memchunk.length, &e->sample_spec) : 0); pa_tagstruct_put_sample_spec(t, &fixed_ss); pa_tagstruct_put_channel_map(t, &e->channel_map); - pa_tagstruct_putu32(t, e->memchunk.length); + pa_tagstruct_putu32(t, (uint32_t) e->memchunk.length); pa_tagstruct_put_boolean(t, e->lazy); pa_tagstruct_puts(t, e->filename); @@ -2653,8 +2674,8 @@ static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entr pa_tagstruct_put_proplist(t, e->proplist); } -static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; pa_sink *sink = NULL; pa_source *source = NULL; @@ -2666,7 +2687,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u const char *name; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2681,7 +2702,10 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID); if (command == PA_COMMAND_GET_SINK_INFO) { if (idx != PA_INVALID_INDEX) @@ -2732,14 +2756,14 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_idxset *i; uint32_t idx; void *p; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (!pa_tagstruct_eof(t)) { @@ -2792,14 +2816,14 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +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; char txt[256]; const char *n; pa_sample_spec fixed_ss; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (!pa_tagstruct_eof(t)) { @@ -2830,9 +2854,9 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) { pa_tagstruct *t; - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT); @@ -2842,11 +2866,11 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3 pa_pstream_send_tagstruct(c->pstream, t); } -static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_subscription_mask_t m; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &m) < 0 || @@ -2871,13 +2895,13 @@ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint } static void command_set_volume( - PA_GCC_UNUSED pa_pdispatch *pd, + pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; pa_cvolume volume; pa_sink *sink = NULL; @@ -2885,7 +2909,7 @@ static void command_set_volume( pa_sink_input *si = NULL; const char *name = NULL; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2898,7 +2922,10 @@ static void command_set_volume( } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); switch (command) { @@ -2938,13 +2965,13 @@ static void command_set_volume( } static void command_set_mute( - PA_GCC_UNUSED pa_pdispatch *pd, + pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; pa_bool_t mute; pa_sink *sink = NULL; @@ -2952,7 +2979,7 @@ static void command_set_mute( pa_sink_input *si = NULL; const char *name = NULL; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2965,7 +2992,10 @@ static void command_set_mute( } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID); switch (command) { @@ -3006,13 +3036,13 @@ static void command_set_mute( pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; pa_bool_t b; playback_stream *s; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3032,12 +3062,12 @@ static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; playback_stream *s; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3072,13 +3102,13 @@ static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_ pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; record_stream *s; pa_bool_t b; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3097,12 +3127,12 @@ static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; record_stream *s; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3120,12 +3150,12 @@ static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_U } static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; uint32_t maxlength, tlength, prebuf, minreq, fragsize; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0) { @@ -3207,11 +3237,11 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u } static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; uint32_t rate; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3247,12 +3277,12 @@ static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command } static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; uint32_t mode; pa_proplist *p; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -3312,13 +3342,13 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t } static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; unsigned changed = 0; pa_proplist *p; pa_strlist *l = NULL; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -3382,7 +3412,7 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t if (!z) break; - changed += pa_proplist_unset(p, z) >= 0; + changed += (unsigned) (pa_proplist_unset(p, z) >= 0); pa_xfree(z); } @@ -3408,11 +3438,11 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t } } -static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *s; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &s) < 0 || @@ -3422,18 +3452,18 @@ static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, u } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, !s || (*s && pa_utf8_valid(s)), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !s || pa_namereg_is_valid_name(s), tag, PA_ERR_INVALID); pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK); pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; const char *name; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3468,11 +3498,11 @@ static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t com pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3489,7 +3519,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 client = pa_idxset_get_by_index(c->protocol->core->clients, idx); CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY); - connection_ref(c); + pa_native_connection_ref(c); pa_client_kill(client); } else if (command == PA_COMMAND_KILL_SINK_INPUT) { @@ -3498,7 +3528,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - connection_ref(c); + pa_native_connection_ref(c); pa_sink_input_kill(s); } else { pa_source_output *s; @@ -3508,21 +3538,21 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - connection_ref(c); + pa_native_connection_ref(c); pa_source_output_kill(s); } pa_pstream_send_simple_ack(c->pstream, tag); - connection_unref(c); + pa_native_connection_unref(c); } -static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_module *m; const char *name, *argument; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || @@ -3546,12 +3576,12 @@ static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx; pa_module *m; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3564,18 +3594,18 @@ static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED m = pa_idxset_get_by_index(c->protocol->core->modules, idx); CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY); - pa_module_unload_request(m); + pa_module_unload_request(m, FALSE); pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_add_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *name, *module, *argument; uint32_t type; uint32_t idx; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || @@ -3603,13 +3633,13 @@ static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED u pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_remove_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const char *name = NULL; uint32_t type, idx = PA_IDXSET_INVALID; int r; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if ((pa_tagstruct_getu32(t, &idx) < 0 && @@ -3639,19 +3669,19 @@ static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e) pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); - pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1); + pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0U : 1U); pa_tagstruct_puts(t, e->module); pa_tagstruct_puts(t, e->argument); } -static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_autoload_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const pa_autoload_entry *a = NULL; uint32_t type, idx; const char *name; pa_tagstruct *reply; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if ((pa_tagstruct_getu32(t, &idx) < 0 && @@ -3678,11 +3708,11 @@ static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNU pa_pstream_send_tagstruct(c->pstream, reply); } -static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); +static void command_get_autoload_info_list(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; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (!pa_tagstruct_eof(t)) { @@ -3706,16 +3736,16 @@ static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC } static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx = PA_INVALID_INDEX, idx_device = PA_INVALID_INDEX; - const char *name = NULL; + const char *name_device = NULL; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_getu32(t, &idx_device) < 0 || - pa_tagstruct_gets(t, &name) < 0 || + pa_tagstruct_gets(t, &name_device) < 0 || !pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -3723,7 +3753,11 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); + + CHECK_VALIDITY(c->pstream, !name_device || pa_namereg_is_valid_name(name_device), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || name_device, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx_device == PA_INVALID_INDEX || !name_device, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name_device || idx_device == PA_INVALID_INDEX, tag, PA_ERR_INVALID); if (command == PA_COMMAND_MOVE_SINK_INPUT) { pa_sink_input *si = NULL; @@ -3734,7 +3768,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag if (idx_device != PA_INVALID_INDEX) sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device); else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); + sink = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SINK, 1); CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY); @@ -3753,7 +3787,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag if (idx_device != PA_INVALID_INDEX) source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device); else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); + source = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SOURCE, 1); CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY); @@ -3767,12 +3801,12 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag } static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx = PA_INVALID_INDEX; const char *name = NULL; pa_bool_t b; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3784,7 +3818,10 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID); if (command == PA_COMMAND_SUSPEND_SINK) { @@ -3841,13 +3878,13 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa } static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); uint32_t idx = PA_INVALID_INDEX; const char *name = NULL; pa_module *m; pa_native_protocol_ext_cb_t cb; - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3857,7 +3894,10 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, } CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || pa_utf8_valid(name), tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); + CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID); if (idx != PA_INVALID_INDEX) m = pa_idxset_get_by_index(c->protocol->core->modules, idx); @@ -3873,32 +3913,33 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, cb = (pa_native_protocol_ext_cb_t) pa_hashmap_get(c->protocol->extensions, m); CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOEXTENSION); - cb(c->protocol, m, c->pstream, tag, t); + if (cb(c->protocol, m, c, tag, t) < 0) + protocol_error(c); } /*** pstream callbacks ***/ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_assert(p); pa_assert(packet); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) { pa_log("invalid packet."); - connection_unlink(c); + native_connection_unlink(c); } } static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); output_stream *stream; pa_assert(p); pa_assert(chunk); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); if (!(stream = OUTPUT_STREAM(pa_idxset_get_by_index(c->output_streams, channel)))) { pa_log("client sent block for invalid stream."); @@ -3954,22 +3995,22 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } static void pstream_die_callback(pa_pstream *p, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_assert(p); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); - connection_unlink(c); - pa_log_info("connection died."); + native_connection_unlink(c); + pa_log_info("Connection died."); } static void pstream_drain_callback(pa_pstream *p, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_assert(p); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); - send_memblock(c); + native_connection_send_memblock(c); } static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *userdata) { @@ -3995,25 +4036,28 @@ static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *use static void client_kill_cb(pa_client *c) { pa_assert(c); - connection_unlink(CONNECTION(c->userdata)); + native_connection_unlink(PA_NATIVE_CONNECTION(c->userdata)); + pa_log_info("Connection killed."); } /*** module entry points ***/ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { - connection *c = CONNECTION(userdata); + pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); pa_assert(m); pa_assert(tv); - connection_assert_ref(c); + pa_native_connection_assert_ref(c); pa_assert(c->auth_timeout_event == e); - if (!c->authorized) - connection_unlink(c); + if (!c->authorized) { + native_connection_unlink(c); + pa_log_info("Connection terminated due to authentication timeout."); + } } void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *o) { - connection *c; + pa_native_connection *c; char cname[256], pname[128]; pa_assert(p); @@ -4026,9 +4070,9 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati return; } - c = pa_msgobject_new(connection); - c->parent.parent.free = connection_free; - c->parent.process_msg = connection_process_msg; + c = pa_msgobject_new(pa_native_connection); + c->parent.parent.free = native_connection_free; + c->parent.process_msg = native_connection_process_msg; c->protocol = p; c->options = pa_native_options_ref(o); c->authorized = FALSE; @@ -4087,10 +4131,12 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati if (pa_iochannel_creds_supported(io)) pa_iochannel_creds_enable(io); #endif + + pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_CONNECTION_PUT], c); } void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m) { - connection *c; + pa_native_connection *c; void *state = NULL; pa_assert(p); @@ -4098,11 +4144,12 @@ void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m) { while ((c = pa_idxset_iterate(p->connections, &state, NULL))) if (c->options->module == m) - connection_unlink(c); + native_connection_unlink(c); } static pa_native_protocol* native_protocol_new(pa_core *c) { pa_native_protocol *p; + pa_native_hook_t h; pa_assert(c); @@ -4112,7 +4159,11 @@ static pa_native_protocol* native_protocol_new(pa_core *c) { p->connections = pa_idxset_new(NULL, NULL); p->servers = NULL; - pa_hook_init(&p->servers_changed, p); + + p->extensions = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + for (h = 0; h < PA_NATIVE_HOOK_MAX; h++) + pa_hook_init(&p->hooks[h], p); pa_assert_se(pa_shared_set(c, "native-protocol", p) >= 0); @@ -4138,7 +4189,9 @@ pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p) { } void pa_native_protocol_unref(pa_native_protocol *p) { - connection *c; + pa_native_connection *c; + pa_native_hook_t h; + pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) >= 1); @@ -4146,12 +4199,16 @@ void pa_native_protocol_unref(pa_native_protocol *p) { return; while ((c = pa_idxset_first(p->connections, NULL))) - connection_unlink(c); + native_connection_unlink(c); pa_idxset_free(p->connections, NULL, NULL); pa_strlist_free(p->servers); - pa_hook_done(&p->servers_changed); + + for (h = 0; h < PA_NATIVE_HOOK_MAX; h++) + pa_hook_done(&p->hooks[h]); + + pa_hashmap_free(p->extensions, NULL, NULL); pa_assert_se(pa_shared_remove(p->core, "native-protocol") >= 0); @@ -4165,7 +4222,7 @@ void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *nam p->servers = pa_strlist_prepend(p->servers, name); - pa_hook_fire(&p->servers_changed, p->servers); + pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_SERVERS_CHANGED], p->servers); } void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name) { @@ -4175,14 +4232,14 @@ void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char * p->servers = pa_strlist_remove(p->servers, name); - pa_hook_fire(&p->servers_changed, p->servers); + pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_SERVERS_CHANGED], p->servers); } -pa_hook *pa_native_protocol_servers_changed(pa_native_protocol *p) { +pa_hook *pa_native_protocol_hooks(pa_native_protocol *p) { pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) >= 1); - return &p->servers_changed; + return p->hooks; } pa_strlist *pa_native_protocol_servers(pa_native_protocol *p) { @@ -4277,7 +4334,7 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) { if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) { pa_ip_acl *ipa; - if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) { + if (!(ipa = pa_ip_acl_new(acl))) { pa_log("Failed to parse IP ACL '%s'", acl); return -1; } @@ -4314,3 +4371,9 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) { return 0; } + +pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c) { + pa_native_connection_assert_ref(c); + + return c->pstream; +} diff --git a/src/pulsecore/protocol-native.h b/src/pulsecore/protocol-native.h index b3db305c..06731c0c 100644 --- a/src/pulsecore/protocol-native.h +++ b/src/pulsecore/protocol-native.h @@ -36,6 +36,8 @@ typedef struct pa_native_protocol pa_native_protocol; +typedef struct pa_native_connection pa_native_connection; + typedef struct pa_native_options { PA_REFCNT_DECLARE; @@ -48,22 +50,37 @@ typedef struct pa_native_options { } pa_native_options; +typedef enum pa_native_hook { + PA_NATIVE_HOOK_SERVERS_CHANGED, + PA_NATIVE_HOOK_CONNECTION_PUT, + PA_NATIVE_HOOK_CONNECTION_UNLINK, + PA_NATIVE_HOOK_MAX +} pa_native_hook_t; + pa_native_protocol* pa_native_protocol_get(pa_core *core); pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p); void pa_native_protocol_unref(pa_native_protocol *p); void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *a); void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m); +pa_hook *pa_native_protocol_hooks(pa_native_protocol *p); + void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *name); void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name); - -pa_hook *pa_native_protocol_servers_changed(pa_native_protocol *p); pa_strlist *pa_native_protocol_servers(pa_native_protocol *p); -typedef void (*pa_native_protocol_ext_cb_t)(pa_native_protocol *p, pa_module *m, pa_pstream *ps, uint32_t tag, pa_tagstruct *t); +typedef int (*pa_native_protocol_ext_cb_t)( + pa_native_protocol *p, + pa_module *m, + pa_native_connection *c, + uint32_t tag, + pa_tagstruct *t); + int pa_native_protocol_install_ext(pa_native_protocol *p, pa_module *m, pa_native_protocol_ext_cb_t cb); void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m); +pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c); + pa_native_options* pa_native_options_new(void); pa_native_options* pa_native_options_ref(pa_native_options *o); void pa_native_options_unref(pa_native_options *o); diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 78874bb9..65e67737 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -159,7 +159,7 @@ static int do_read(connection *c) { connection_assert_ref(c); - if (!c->sink_input || (l = pa_atomic_load(&c->playback.missing)) <= 0) + if (!c->sink_input || (l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0) return 0; if (c->playback.current_memblock) { @@ -197,12 +197,12 @@ static int do_read(connection *c) { chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; - chunk.length = r; + chunk.length = (size_t) r; - c->playback.memblock_index += r; + c->playback.memblock_index += (size_t) r; pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); - pa_atomic_sub(&c->playback.missing, r); + pa_atomic_sub(&c->playback.missing, (int) r); return 0; } @@ -240,7 +240,7 @@ static int do_write(connection *c) { return -1; } - pa_memblockq_drop(c->output_memblockq, r); + pa_memblockq_drop(c->output_memblockq, (size_t) r); return 0; } @@ -377,7 +377,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk m = pa_memblockq_pop_missing(c->input_memblockq); if (m > 0) - if (pa_atomic_add(&c->playback.missing, m) <= 0) + if (pa_atomic_add(&c->playback.missing, (int) m) <= 0) pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); return 0; @@ -546,7 +546,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY); - l = (size_t) (pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS); + l = (size_t) ((double) pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS); c->input_memblockq = pa_memblockq_new( 0, l, @@ -558,7 +558,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp NULL); pa_iochannel_socket_set_rcvbuf(io, l); - pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq)); pa_sink_input_put(c->sink_input); } diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 6b1af67b..7ff8edc9 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -283,7 +283,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo return p; } -static void item_free(void *item, PA_GCC_UNUSED void *q) { +static void item_free(void *item, void *q) { struct item_info *i = item; pa_assert(i); @@ -488,7 +488,7 @@ static void prepare_next_write_item(pa_pstream *p) { pa_assert(p->write.current->packet); p->write.data = p->write.current->packet->data; - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->packet->length); + p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->packet->length); } else if (p->write.current->type == PA_PSTREAM_ITEM_SHMRELEASE) { @@ -511,7 +511,7 @@ static void prepare_next_write_item(pa_pstream *p) { p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32)); p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = htonl((uint32_t) ((uint64_t) p->write.current->offset)); - flags = p->write.current->seek_mode & PA_FLAG_SEEKMASK; + flags = (uint32_t) (p->write.current->seek_mode & PA_FLAG_SEEKMASK); if (p->use_shm) { uint32_t block_id, shm_id; @@ -542,7 +542,7 @@ static void prepare_next_write_item(pa_pstream *p) { } if (send_payload) { - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length); + p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->chunk.length); p->write.memchunk = p->write.current->chunk; pa_memblock_ref(p->write.memchunk.memblock); p->write.data = NULL; @@ -607,7 +607,7 @@ static int do_write(pa_pstream *p) { if (release_memblock) pa_memblock_release(release_memblock); - p->write.index += r; + p->write.index += (size_t) r; if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) { pa_assert(p->write.current); @@ -675,7 +675,7 @@ static int do_read(pa_pstream *p) { if (release_memblock) pa_memblock_release(release_memblock); - p->read.index += r; + p->read.index += (size_t) r; if (p->read.index == PA_PSTREAM_DESCRIPTOR_SIZE) { uint32_t flags, length, channel; @@ -769,7 +769,7 @@ static int do_read(pa_pstream *p) { if (p->read.memblock && p->recieve_memblock_callback) { /* Is this memblock data? Than pass it to the user */ - l = (p->read.index - r) < PA_PSTREAM_DESCRIPTOR_SIZE ? p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE : (size_t) r; + l = (p->read.index - (size_t) r) < PA_PSTREAM_DESCRIPTOR_SIZE ? (size_t) (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE) : (size_t) r; if (l > 0) { pa_memchunk chunk; diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c82f4c1e..b20fc61f 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -373,7 +373,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) { /* We deduce the "largest" sample spec we're using during the * conversion */ - ss.channels = PA_MAX(r->i_ss.channels, r->o_ss.channels); + ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels)); /* We silently assume that the format enum is ordered by size */ ss.format = PA_MAX(r->i_ss.format, r->o_ss.format); @@ -642,7 +642,7 @@ static void calc_map_table(pa_resampler *r) { if (n > 0) for (ic = 0; ic < r->i_ss.channels; ic++) if (on_left(r->i_cm.map[ic])) { - r->map_table[oc][ic] = 1.0 / n; + r->map_table[oc][ic] = 1.0f / (float) n; ic_connected[ic] = TRUE; } @@ -663,7 +663,7 @@ static void calc_map_table(pa_resampler *r) { if (n > 0) for (ic = 0; ic < r->i_ss.channels; ic++) if (on_right(r->i_cm.map[ic])) { - r->map_table[oc][ic] = 1.0 / n; + r->map_table[oc][ic] = 1.0f / (float) n; ic_connected[ic] = TRUE; } @@ -684,7 +684,7 @@ static void calc_map_table(pa_resampler *r) { if (n > 0) { for (ic = 0; ic < r->i_ss.channels; ic++) if (on_center(r->i_cm.map[ic])) { - r->map_table[oc][ic] = 1.0 / n; + r->map_table[oc][ic] = 1.0f / (float) n; ic_connected[ic] = TRUE; } } else { @@ -701,7 +701,7 @@ static void calc_map_table(pa_resampler *r) { if (n > 0) for (ic = 0; ic < r->i_ss.channels; ic++) if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) { - r->map_table[oc][ic] = 1.0 / n; + r->map_table[oc][ic] = 1.0f / (float) n; ic_connected[ic] = TRUE; } @@ -716,7 +716,7 @@ static void calc_map_table(pa_resampler *r) { * channels for LFE. */ for (ic = 0; ic < r->i_ss.channels; ic++) { - r->map_table[oc][ic] = 1.0 / r->i_ss.channels; + r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels; /* Please note that a channel connected to LFE * doesn't really count as connected. */ @@ -763,12 +763,12 @@ static void calc_map_table(pa_resampler *r) { for (ic = 0; ic < r->i_ss.channels; ic++) { if (ic_connected[ic]) { - r->map_table[oc][ic] *= .9; + r->map_table[oc][ic] *= .9f; continue; } if (on_left(r->i_cm.map[ic])) - r->map_table[oc][ic] = .1 / ic_unconnected_left; + r->map_table[oc][ic] = .1f / (float) ic_unconnected_left; } } } @@ -788,12 +788,12 @@ static void calc_map_table(pa_resampler *r) { for (ic = 0; ic < r->i_ss.channels; ic++) { if (ic_connected[ic]) { - r->map_table[oc][ic] *= .9; + r->map_table[oc][ic] *= .9f; continue; } if (on_right(r->i_cm.map[ic])) - r->map_table[oc][ic] = .1 / ic_unconnected_right; + r->map_table[oc][ic] = .1f / (float) ic_unconnected_right; } } } @@ -814,12 +814,12 @@ static void calc_map_table(pa_resampler *r) { for (ic = 0; ic < r->i_ss.channels; ic++) { if (ic_connected[ic]) { - r->map_table[oc][ic] *= .9; + r->map_table[oc][ic] *= .9f; continue; } if (on_center(r->i_cm.map[ic])) { - r->map_table[oc][ic] = .1 / ic_unconnected_center; + r->map_table[oc][ic] = .1f / (float) ic_unconnected_center; mixed_in = TRUE; } } @@ -840,12 +840,12 @@ static void calc_map_table(pa_resampler *r) { for (ic = 0; ic < r->i_ss.channels; ic++) { if (ic_connected[ic]) { - r->map_table[oc][ic] *= .75; + r->map_table[oc][ic] *= .75f; continue; } if (on_center(r->i_cm.map[ic])) - r->map_table[oc][ic] = .375 / ic_unconnected_center; + r->map_table[oc][ic] = .375f / (float) ic_unconnected_center; } } } @@ -862,7 +862,7 @@ static void calc_map_table(pa_resampler *r) { continue; for (oc = 0; oc < r->o_ss.channels; oc++) - r->map_table[oc][ic] = 0.375 / ic_unconnected_lfe; + r->map_table[oc][ic] = 0.375f / (float) ic_unconnected_lfe; } } } @@ -905,7 +905,7 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) if (!r->to_work_format_func || !input->length) return input; - n_samples = (input->length / r->i_fz) * r->i_ss.channels; + n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels); r->buf1.index = 0; r->buf1.length = r->w_sz * n_samples; @@ -974,7 +974,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { if (!r->map_required || !input->length) return input; - in_n_samples = input->length / r->w_sz; + in_n_samples = (unsigned) (input->length / r->w_sz); n_frames = in_n_samples / r->i_ss.channels; out_n_samples = n_frames * r->o_ss.channels; @@ -994,8 +994,8 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { memset(dst, 0, r->buf2.length); - o_skip = r->w_sz * r->o_ss.channels; - i_skip = r->w_sz * r->i_ss.channels; + o_skip = (int) (r->w_sz * r->o_ss.channels); + i_skip = (int) (r->w_sz * r->i_ss.channels); switch (r->work_format) { case PA_SAMPLE_FLOAT32NE: @@ -1013,7 +1013,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { (float*) dst + oc, o_skip, (float*) dst + oc, o_skip, (float*) src + ic, i_skip, - n_frames, + (int) n_frames, &one, &r->map_table[oc][ic]); } } @@ -1037,7 +1037,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { (int16_t*) dst + oc, o_skip, (int16_t*) dst + oc, o_skip, (int16_t*) src + ic, i_skip, - n_frames, + (int) n_frames, &one, &one); } else @@ -1046,7 +1046,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { (int16_t*) dst + oc, o_skip, (int16_t*) dst + oc, o_skip, (int16_t*) src + ic, i_skip, - n_frames, + (int) n_frames, 1.0, r->map_table[oc][ic]); } } @@ -1077,8 +1077,8 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { if (!r->impl_resample || !input->length) return input; - in_n_samples = input->length / r->w_sz; - in_n_frames = in_n_samples / r->o_ss.channels; + in_n_samples = (unsigned) (input->length / r->w_sz); + in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels); out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES; out_n_samples = out_n_frames * r->o_ss.channels; @@ -1112,8 +1112,8 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input if (!r->from_work_format_func || !input->length) return input; - n_samples = input->length / r->w_sz; - n_frames = n_samples / r->o_ss.channels; + n_samples = (unsigned) (input->length / r->w_sz); + n_frames = n_samples / r->o_ss.channels; r->buf4.index = 0; r->buf4.length = r->o_fz * n_frames; @@ -1178,10 +1178,10 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un memset(&data, 0, sizeof(data)); data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - data.input_frames = in_n_frames; + data.input_frames = (long int) in_n_frames; data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); - data.output_frames = *out_n_frames; + data.output_frames = (long int) *out_n_frames; data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; data.end_of_input = 0; @@ -1192,7 +1192,7 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un pa_memblock_release(input->memblock); pa_memblock_release(output->memblock); - *out_n_frames = data.output_frames_gen; + *out_n_frames = (unsigned) data.output_frames_gen; } static void libsamplerate_update_rates(pa_resampler *r) { @@ -1354,7 +1354,7 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned pa_assert(o_index * fz < pa_memblock_get_length(output->memblock)); oil_memcpy((uint8_t*) dst + fz * o_index, - (uint8_t*) src + fz * j, fz); + (uint8_t*) src + fz * j, (int) fz); } pa_memblock_release(input->memblock); @@ -1430,7 +1430,7 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i for (c = 0; c < r->o_ss.channels; c++, s++) { int16_t n; - n = *s < 0 ? -*s : *s; + n = (int16_t) (*s < 0 ? -*s : *s); if (n > r->peaks.max_i[c]) r->peaks.max_i[c] = n; @@ -1523,7 +1523,7 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned p = pa_memblock_acquire(b); /* Copy the remaining data into it */ - l = r->ffmpeg.buf[c].length; + l = (unsigned) r->ffmpeg.buf[c].length; if (r->ffmpeg.buf[c].memblock) { t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index); memcpy(p, t, l); @@ -1543,18 +1543,18 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned pa_memblock_release(input->memblock); /* Calculate the resulting number of frames */ - in = in_n_frames + l / sizeof(int16_t); + in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t); /* Allocate buffer for the result */ w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t)); q = pa_memblock_acquire(w); /* Now, resample */ - used_frames = av_resample(r->ffmpeg.state, - q, p, - &consumed_frames, - in, *out_n_frames, - c >= (unsigned) r->o_ss.channels-1); + used_frames = (unsigned) av_resample(r->ffmpeg.state, + q, p, + &consumed_frames, + (int) in, (int) *out_n_frames, + c >= (unsigned) (r->o_ss.channels-1)); pa_memblock_release(b); @@ -1562,8 +1562,8 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned pa_assert(consumed_frames <= (int) in); if (consumed_frames < (int) in) { r->ffmpeg.buf[c].memblock = b; - r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t); - r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t); + r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t); + r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t); } else pa_memblock_unref(b); @@ -1605,7 +1605,7 @@ static int ffmpeg_init(pa_resampler *r) { * internally only uses these hardcoded values, so let's use them * here for now as well until ffmpeg makes this configurable. */ - if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8))) + if (!(r->ffmpeg.state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8))) return -1; r->impl_free = ffmpeg_free; diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index 705de48f..aa2cdace 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -23,6 +23,7 @@ ***/ #include <pulsecore/macro.h> +#include <pulse/sample.h> struct timeval; diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index a67a5516..543262bc 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -394,7 +394,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { #endif #endif - r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1); + r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1); if (r < 0) { if (errno == EAGAIN || errno == EINTR) diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index 4df217c3..4cd6aa8f 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -40,7 +40,7 @@ static void _free_rtsig(void *p) { pa_rtsig_put(PA_PTR_TO_INT(p)); } -PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two(SIGRTMAX-SIGRTMIN+1), NULL); +PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two((unsigned) (SIGRTMAX-SIGRTMIN+1)), NULL); PA_STATIC_TLS_DECLARE(rtsig_tls, _free_rtsig); static pa_atomic_t rtsig_current = PA_ATOMIC_INIT(-1); diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index b42b79d1..4b2efe5e 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -85,7 +85,6 @@ static uint8_t silence_byte(pa_sample_format_t format) { default: pa_assert_not_reached(); } - return 0; } void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { @@ -134,7 +133,7 @@ static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nst for (channel = 0; channel < spec->channels; channel++) { pa_mix_info *m = streams + k; - m->linear[channel].f = pa_sw_volume_to_linear(m->volume.values[channel]); + m->linear[channel].f = (float) pa_sw_volume_to_linear(m->volume.values[channel]); } } } @@ -146,7 +145,7 @@ static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) { pa_assert(volume); for (channel = 0; channel < volume->channels; channel++) - linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); + linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]); } size_t pa_mix( @@ -160,7 +159,8 @@ size_t pa_mix( pa_cvolume full_volume; unsigned k; - size_t d = 0; + unsigned z; + void *end; pa_assert(streams); pa_assert(data); @@ -170,9 +170,20 @@ size_t pa_mix( if (!volume) volume = pa_cvolume_reset(&full_volume, spec->channels); + if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) { + pa_silence_memory(data, length, spec); + return length; + } + for (k = 0; k < nstreams; k++) streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index; + for (z = 0; z < nstreams; z++) + if (length > streams[z].chunk.length) + length = streams[z].chunk.length; + + end = (uint8_t*) data + length; + switch (spec->format) { case PA_SAMPLE_S16NE:{ @@ -182,21 +193,15 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d += sizeof(int16_t)) { + while (data < end) { int32_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t v, cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = *((int16_t*) m->ptr); @@ -207,8 +212,8 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); } - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); sum = (sum * linear[channel]) / 0x10000; + sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); *((int16_t*) data) = (int16_t) sum; data = (uint8_t*) data + sizeof(int16_t); @@ -227,21 +232,15 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d += sizeof(int16_t)) { + while (data < end) { int32_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t v, cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = PA_INT16_SWAP(*((int16_t*) m->ptr)); @@ -252,8 +251,8 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); } - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); sum = (sum * linear[channel]) / 0x10000; + sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum); data = (uint8_t*) data + sizeof(int16_t); @@ -272,22 +271,16 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d += sizeof(int32_t)) { + while (data < end) { int64_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int64_t v; int32_t cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = *((int32_t*) m->ptr); @@ -298,8 +291,8 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + sizeof(int32_t); } - sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL); sum = (sum * linear[channel]) / 0x10000; + sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL); *((int32_t*) data) = (int32_t) sum; data = (uint8_t*) data + sizeof(int32_t); @@ -318,22 +311,16 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d += sizeof(int32_t)) { + while (data < end) { int64_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int64_t v; int32_t cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = PA_INT32_SWAP(*((int32_t*) m->ptr)); @@ -344,8 +331,8 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + sizeof(int32_t); } - sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL); sum = (sum * linear[channel]) / 0x10000; + sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL); *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum); data = (uint8_t*) data + sizeof(int32_t); @@ -364,21 +351,15 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d ++) { + while (data < end) { int32_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t v, cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = (int32_t) *((uint8_t*) m->ptr) - 0x80; @@ -409,21 +390,15 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d ++) { + while (data < end) { int32_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t v, cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr)); @@ -434,9 +409,9 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + 1; } - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); sum = (sum * linear[channel]) / 0x10000; - *((uint8_t*) data) = (uint8_t) st_14linear2ulaw(sum >> 2); + sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); + *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2); data = (uint8_t*) data + 1; @@ -454,21 +429,15 @@ size_t pa_mix( calc_linear_integer_stream_volumes(streams, nstreams, spec); calc_linear_integer_volume(linear, volume); - for (d = 0;; d ++) { + while (data < end) { int32_t sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; int32_t v, cv = m->linear[channel].i; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr)); @@ -479,9 +448,9 @@ size_t pa_mix( m->ptr = (uint8_t*) m->ptr + 1; } - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); sum = (sum * linear[channel]) / 0x10000; - *((uint8_t*) data) = (uint8_t) st_13linear2alaw(sum >> 3); + sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); + *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3); data = (uint8_t*) data + 1; @@ -499,21 +468,15 @@ size_t pa_mix( calc_linear_float_stream_volumes(streams, nstreams, spec); calc_linear_float_volume(linear, volume); - for (d = 0;; d += sizeof(float)) { + while (data < end) { float sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; float v, cv = m->linear[channel].f; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; else { v = *((float*) m->ptr); @@ -543,35 +506,25 @@ size_t pa_mix( calc_linear_float_stream_volumes(streams, nstreams, spec); calc_linear_float_volume(linear, volume); - for (d = 0;; d += sizeof(float)) { + while (data < end) { float sum = 0; unsigned i; - if (PA_UNLIKELY(d >= length)) - goto finish; - for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; float v, cv = m->linear[channel].f; - if (PA_UNLIKELY(d >= m->chunk.length)) - goto finish; - - if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) + if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0)) v = 0; - else { - uint32_t z = *(uint32_t*) m->ptr; - z = PA_UINT32_SWAP(z); - v = *((float*) &z); - v *= cv; - } + else + v = PA_FLOAT32_SWAP(*(float*) m->ptr) *cv; sum += v; m->ptr = (uint8_t*) m->ptr + sizeof(float); } sum *= linear[channel]; - *((uint32_t*) data) = PA_UINT32_SWAP(*(uint32_t*) &sum); + *((float*) data) = PA_FLOAT32_SWAP(sum); data = (uint8_t*) data + sizeof(float); @@ -583,16 +536,14 @@ size_t pa_mix( } default: - pa_log_error("ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); + pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); pa_assert_not_reached(); } -finish: - for (k = 0; k < nstreams; k++) pa_memblock_release(streams[k].chunk.memblock); - return d; + return length; } @@ -624,14 +575,15 @@ void pa_volume_memchunk( switch (spec->format) { case PA_SAMPLE_S16NE: { - int16_t *d; - size_t n; + int16_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) { + e = (int16_t*) ptr + c->length/sizeof(int16_t); + + for (channel = 0, d = ptr; d < e; d++) { int32_t t; t = (int32_t)(*d); @@ -646,17 +598,18 @@ void pa_volume_memchunk( } case PA_SAMPLE_S16RE: { - int16_t *d; - size_t n; + int16_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) { + e = (int16_t*) ptr + c->length/sizeof(int16_t); + + for (channel = 0, d = ptr; d < e; d++) { int32_t t; - t = (int32_t)(PA_INT16_SWAP(*d)); + t = (int32_t) PA_INT16_SWAP(*d); t = (t * linear[channel]) / 0x10000; t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); *d = PA_INT16_SWAP((int16_t) t); @@ -669,14 +622,15 @@ void pa_volume_memchunk( } case PA_SAMPLE_S32NE: { - int32_t *d; - size_t n; + int32_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) { + e = (int32_t*) ptr + c->length/sizeof(int32_t); + + for (channel = 0, d = ptr; d < e; d++) { int64_t t; t = (int64_t)(*d); @@ -691,17 +645,18 @@ void pa_volume_memchunk( } case PA_SAMPLE_S32RE: { - int32_t *d; - size_t n; + int32_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) { + e = (int32_t*) ptr + c->length/sizeof(int32_t); + + for (channel = 0, d = ptr; d < e; d++) { int64_t t; - t = (int64_t)(PA_INT32_SWAP(*d)); + t = (int64_t) PA_INT32_SWAP(*d); t = (t * linear[channel]) / 0x10000; t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL); *d = PA_INT32_SWAP((int32_t) t); @@ -714,14 +669,15 @@ void pa_volume_memchunk( } case PA_SAMPLE_U8: { - uint8_t *d; - size_t n; + uint8_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { + e = (uint8_t*) ptr + c->length; + + for (channel = 0, d = ptr; d < e; d++) { int32_t t; t = (int32_t) *d - 0x80; @@ -736,20 +692,21 @@ void pa_volume_memchunk( } case PA_SAMPLE_ULAW: { - uint8_t *d; - size_t n; + uint8_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { + e = (uint8_t*) ptr + c->length; + + for (channel = 0, d = ptr; d < e; d++) { int32_t t; t = (int32_t) st_ulaw2linear16(*d); t = (t * linear[channel]) / 0x10000; t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); - *d = (uint8_t) st_14linear2ulaw(t >> 2); + *d = (uint8_t) st_14linear2ulaw((int16_t) t >> 2); if (PA_UNLIKELY(++channel >= spec->channels)) channel = 0; @@ -758,20 +715,21 @@ void pa_volume_memchunk( } case PA_SAMPLE_ALAW: { - uint8_t *d; - size_t n; + uint8_t *d, *e; unsigned channel; int32_t linear[PA_CHANNELS_MAX]; calc_linear_integer_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { + e = (uint8_t*) ptr + c->length; + + for (channel = 0, d = ptr; d < e; d++) { int32_t t; t = (int32_t) st_alaw2linear16(*d); t = (t * linear[channel]) / 0x10000; t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); - *d = (uint8_t) st_13linear2alaw(t >> 3); + *d = (uint8_t) st_13linear2alaw((int16_t) t >> 3); if (PA_UNLIKELY(++channel >= spec->channels)) channel = 0; @@ -786,8 +744,8 @@ void pa_volume_memchunk( unsigned channel; d = ptr; - skip = spec->channels * sizeof(float); - n = c->length/sizeof(float)/spec->channels; + skip = (int) (spec->channels * sizeof(float)); + n = (unsigned) (c->length/sizeof(float)/spec->channels); for (channel = 0; channel < spec->channels; channel ++) { float v, *t; @@ -797,28 +755,26 @@ void pa_volume_memchunk( v = (float) pa_sw_volume_to_linear(volume->values[channel]); t = d + channel; - oil_scalarmult_f32(t, skip, t, skip, &v, n); + oil_scalarmult_f32(t, skip, t, skip, &v, (int) n); } break; } case PA_SAMPLE_FLOAT32RE: { - uint32_t *d; - size_t n; + float *d, *e; unsigned channel; float linear[PA_CHANNELS_MAX]; calc_linear_float_volume(linear, volume); - for (channel = 0, d = ptr, n = c->length/sizeof(float); n > 0; d++, n--) { + e = (float*) ptr + c->length/sizeof(float); + + for (channel = 0, d = ptr; d < e; d++) { float t; - uint32_t z; - z = PA_UINT32_SWAP(*d); - t = *(float*) &z; + t = PA_FLOAT32_SWAP(*d); t *= linear[channel]; - z = *(uint32_t*) &t; - *d = PA_UINT32_SWAP(z); + *d = PA_FLOAT32_SWAP(t); if (PA_UNLIKELY(++channel >= spec->channels)) channel = 0; @@ -877,7 +833,7 @@ void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, u d = (uint8_t*) dst + c * ss; for (j = 0; j < n; j ++) { - oil_memcpy(d, s, ss); + oil_memcpy(d, s, (int) ss); s = (uint8_t*) s + ss; d = (uint8_t*) d + fs; } @@ -905,7 +861,7 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, d = dst[c]; for (j = 0; j < n; j ++) { - oil_memcpy(d, s, ss); + oil_memcpy(d, s, (int) ss); s = (uint8_t*) s + fs; d = (uint8_t*) d + ss; } @@ -1008,7 +964,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo if (format == PA_SAMPLE_FLOAT32NE) { float minus_one = -1.0, plus_one = 1.0; - oil_clip_f32(d, dstr, s, sstr, n, &minus_one, &plus_one); + oil_clip_f32(d, (int) dstr, s, (int) sstr, (int) n, &minus_one, &plus_one); } else { pa_assert(format == PA_SAMPLE_FLOAT32RE); @@ -1017,7 +973,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo float f; f = PA_FLOAT32_SWAP(*s); - f = PA_CLAMP_UNLIKELY(f, -1.0, 1.0); + f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f); *d = PA_FLOAT32_SWAP(f); s = (const float*) ((const uint8_t*) s + sstr); diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index 41670f27..693d529b 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -70,13 +70,13 @@ void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) { for (; n > 0; n--) { int16_t s = *(a++); - *(b++) = ((float) INT16_FROM(s))/0x7FFF; + *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF; } #else { static const double add = 0, factor = 1.0/0x7FFF; - oil_scaleconv_f32_s16(b, a, n, &add, &factor); + oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor); } #endif } @@ -95,7 +95,7 @@ void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) { #else { static const double add = 0, factor = 1.0/0x7FFFFFFF; - oil_scaleconv_f32_s32(b, a, n, &add, &factor); + oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor); } #endif } @@ -110,7 +110,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) { int16_t s; float v = *(a++); - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f); s = (int16_t) (v * 0x7FFF); *(b++) = INT16_TO(s); } @@ -118,7 +118,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) { #else { static const double add = 0, factor = 0x7FFF; - oil_scaleconv_s16_f32(b, a, n, &add, &factor); + oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor); } #endif } @@ -133,7 +133,7 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) { int32_t s; float v = *(a++); - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f); s = (int32_t) ((double) v * (double) 0x7FFFFFFF); *(b++) = INT32_TO(s); } @@ -141,7 +141,7 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) { #else { static const double add = 0, factor = 0x7FFFFFFF; - oil_scaleconv_s32_f32(b, a, n, &add, &factor); + oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor); } #endif } @@ -181,7 +181,7 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { float v = *(a++); uint32_t *j = (uint32_t*) &v; *j = PA_UINT32_SWAP(*j); - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f); s = (int16_t) (v * 0x7FFF); *(b++) = INT16_TO(s); } @@ -196,7 +196,7 @@ void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) { float v = *(a++); uint32_t *j = (uint32_t*) &v; *j = PA_UINT32_SWAP(*j); - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f); s = (int32_t) ((double) v * 0x7FFFFFFF); *(b++) = INT32_TO(s); } @@ -219,7 +219,7 @@ void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) { for (; n > 0; n--) { int16_t s = (int16_t) (INT32_FROM(*a) >> 16); - *b = PA_UINT32_SWAP(s); + *b = PA_INT16_SWAP(s); a++; b++; } @@ -241,7 +241,7 @@ void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) { pa_assert(b); for (; n > 0; n--) { - int32_t s = ((int32_t) PA_UINT16_SWAP(*a)) << 16; + int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16; *b = INT32_TO(s); a++; b++; diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c index 581e4681..733a46ae 100644 --- a/src/pulsecore/sconv.c +++ b/src/pulsecore/sconv.c @@ -46,7 +46,7 @@ static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) { pa_assert(a); pa_assert(b); - oil_scaleconv_f32_u8(b, a, n, &add, &factor); + oil_scaleconv_f32_u8(b, a, (int) n, &add, &factor); } static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { @@ -55,7 +55,7 @@ static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { pa_assert(a); pa_assert(b); - oil_scaleconv_u8_f32(b, a, n, &add, &factor); + oil_scaleconv_u8_f32(b, a, (int) n, &add, &factor); } static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { @@ -64,9 +64,9 @@ static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { pa_assert(a); pa_assert(b); - oil_conv_s16_u8(b, 2, a, 1, n); - oil_scalaradd_s16(b, 2, b, 2, &add, n); - oil_scalarmult_s16(b, 2, b, 2, &factor, n); + oil_conv_s16_u8(b, 2, a, 1, (int) n); + oil_scalaradd_s16(b, 2, b, 2, &add, (int) n); + oil_scalarmult_s16(b, 2, b, 2, &factor, (int) n); } static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { @@ -84,7 +84,7 @@ static void float32ne_to_float32ne(unsigned n, const float *a, float *b) { pa_assert(a); pa_assert(b); - oil_memcpy(b, a, sizeof(float) * n); + oil_memcpy(b, a, (int) (sizeof(float) * n)); } static void float32re_to_float32ne(unsigned n, const float *a, float *b) { @@ -101,7 +101,7 @@ static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { pa_assert(a); pa_assert(b); - oil_memcpy(b, a, sizeof(int16_t) * n); + oil_memcpy(b, a, (int) (sizeof(int16_t) * n)); } static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { @@ -109,7 +109,7 @@ static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { pa_assert(b); for (; n > 0; n--, a++, b++) - *b = PA_UINT16_SWAP(*a); + *b = PA_INT16_SWAP(*a); } /* ulaw */ @@ -128,7 +128,7 @@ static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { for (; n > 0; n--) { float v = *(a++); - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f); v *= 0x1FFF; *(b++) = st_14linear2ulaw((int16_t) v); } @@ -166,7 +166,7 @@ static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { for (; n > 0; n--, a++, b++) { float v = *a; - v = PA_CLAMP_UNLIKELY(v, -1, 1); + v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f); v *= 0xFFF; *b = st_13linear2alaw((int16_t) v); } @@ -177,7 +177,7 @@ static void alaw_to_s16ne(unsigned n, const int8_t *a, int16_t *b) { pa_assert(b); for (; n > 0; n--, a++, b++) - *b = st_alaw2linear16(*a); + *b = st_alaw2linear16((uint8_t) *a); } static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 298bf716..b0870202 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -138,7 +138,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) { m->size = size + PA_ALIGN(sizeof(struct shm_marker)); - if (ftruncate(fd, m->size) < 0) { + if (ftruncate(fd, (off_t) m->size) < 0) { pa_log("ftruncate() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -235,7 +235,7 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { /* Align this to multiples of the page size */ ptr = (uint8_t*) m->ptr + offset; - o = (uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr); + o = (size_t) ((uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr)); if (o > 0) { ps = PA_PAGE_SIZE; @@ -289,7 +289,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { goto fail; } - m->size = st.st_size; + m->size = (size_t) st.st_size; if ((m->ptr = mmap(NULL, m->size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { pa_log("mmap() failed: %s", pa_cstrerror(errno)); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 64a6cdf9..f4e803d0 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -535,7 +535,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa * data, so let's just hand out silence */ pa_atomic_store(&i->thread_info.drained, 1); - pa_memblockq_seek(i->thread_info.render_memblockq, slength, PA_SEEK_RELATIVE); + pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE); i->thread_info.playing_for = 0; if (i->thread_info.underrun_for != (uint64_t) -1) i->thread_info.underrun_for += ilength; diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index c07a7404..7663f22c 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -212,19 +212,19 @@ typedef struct pa_sink_input_new_data { pa_sink *sink; + pa_resample_method_t resample_method; + + pa_sink_input *sync_base; + pa_sample_spec sample_spec; - pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - pa_bool_t channel_map_is_set; - pa_cvolume volume; - pa_bool_t volume_is_set; - pa_bool_t muted; - pa_bool_t muted_is_set; - - pa_resample_method_t resample_method; + pa_bool_t muted:1; - pa_sink_input *sync_base; + pa_bool_t sample_spec_is_set:1; + pa_bool_t channel_map_is_set:1; + pa_bool_t volume_is_set:1; + pa_bool_t muted_is_set:1; } pa_sink_input_new_data; pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 4102f31d..24fb8913 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -856,18 +856,29 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) { s->set_volume = NULL; if (!s->set_volume) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL); + pa_sink_set_soft_volume(s, volume); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } /* Called from main thread */ -const pa_cvolume *pa_sink_get_volume(pa_sink *s) { +void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) { + pa_sink_assert_ref(s); + pa_assert(volume); + + if (PA_SINK_IS_LINKED(s->state)) + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL); + else + s->thread_info.soft_volume = *volume; +} + +/* Called from main thread */ +const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) { pa_sink_assert_ref(s); pa_assert(PA_SINK_IS_LINKED(s->state)); - if (s->refresh_volume) { + if (s->refresh_volume || force_refresh) { struct pa_cvolume old_volume = s->volume; if (s->get_volume && s->get_volume(s) < 0) @@ -904,12 +915,12 @@ void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) { } /* Called from main thread */ -pa_bool_t pa_sink_get_mute(pa_sink *s) { +pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) { pa_sink_assert_ref(s); pa_assert(PA_SINK_IS_LINKED(s->state)); - if (s->refresh_muted) { + if (s->refresh_muted || force_refresh) { pa_bool_t old_muted = s->muted; if (s->get_mute && s->get_mute(s) < 0) diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 604be269..672bdd39 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -180,21 +180,22 @@ typedef enum pa_sink_message { typedef struct pa_sink_new_data { char *name; - pa_bool_t namereg_fail; pa_proplist *proplist; const char *driver; pa_module *module; pa_sample_spec sample_spec; - pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - pa_bool_t channel_map_is_set; - pa_cvolume volume; - pa_bool_t volume_is_set; - pa_bool_t muted; - pa_bool_t muted_is_set; + pa_bool_t muted :1; + + pa_bool_t sample_spec_is_set:1; + pa_bool_t channel_map_is_set:1; + pa_bool_t volume_is_set:1; + pa_bool_t muted_is_set:1; + + pa_bool_t namereg_fail:1; } pa_sink_new_data; pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data); @@ -239,9 +240,10 @@ int pa_sink_suspend(pa_sink *s, pa_bool_t suspend); int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend); void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume); -const pa_cvolume *pa_sink_get_volume(pa_sink *sink); +void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume); +const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_bool_t force_refresh); void pa_sink_set_mute(pa_sink *sink, pa_bool_t mute); -pa_bool_t pa_sink_get_mute(pa_sink *sink); +pa_bool_t pa_sink_get_mute(pa_sink *sink, pa_bool_t force_refres); unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */ unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */ diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index e69a63da..3bde40d0 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -187,7 +187,7 @@ static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userda do_call(c); } -static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_socket_client *c = userdata; pa_assert(m); @@ -283,7 +283,7 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size else pa_make_socket_low_delay(c->fd); - if (do_connect(c, sa, salen) < 0) + if (do_connect(c, sa, (socklen_t) salen) < 0) return -1; return 0; @@ -370,7 +370,7 @@ pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[ #ifdef HAVE_LIBASYNCNS -static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_socket_client *c = userdata; struct addrinfo *res = NULL; int ret; diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index 9885a02b..a600e0a6 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -199,7 +199,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file pa_make_socket_low_delay(fd); - if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) { + if (bind(fd, (struct sockaddr*) &sa, (socklen_t) SUN_LEN(&sa)) < 0) { pa_log("bind(): %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 8eedf830..c30c16eb 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -170,10 +170,10 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk if (u->readf_function) { fs = pa_frame_size(&i->sample_spec); - n = u->readf_function(u->sndfile, p, length/fs); + n = u->readf_function(u->sndfile, p, (sf_count_t) (length/fs)); } else { fs = 1; - n = sf_read_raw(u->sndfile, p, length); + n = sf_read_raw(u->sndfile, p, (sf_count_t) length); } pa_memblock_release(tchunk.memblock); @@ -186,7 +186,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk break; } - tchunk.length = n * fs; + tchunk.length = (size_t) n * fs; pa_memblockq_push(u->memblockq, &tchunk); pa_memblock_unref(tchunk.memblock); @@ -206,12 +206,9 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) { file_stream *u; pa_sink_input_assert_ref(i); - pa_assert(nbytes > 0); u = FILE_STREAM(i->userdata); file_stream_assert_ref(u); - pa_log("backwards %lu", (unsigned long) nbytes); - if (!u->memblockq) return; @@ -313,8 +310,8 @@ int pa_play_file( break; } - ss.rate = sfinfo.samplerate; - ss.channels = sfinfo.channels; + ss.rate = (uint32_t) sfinfo.samplerate; + ss.channels = (uint8_t) sfinfo.channels; if (!pa_sample_spec_valid(&ss)) { pa_log("Unsupported sample format in file %s", fname); diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 3183ede6..74338f9a 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -108,8 +108,8 @@ int pa_sound_file_load( break; } - ss->rate = sfinfo.samplerate; - ss->channels = sfinfo.channels; + ss->rate = (uint32_t) sfinfo.samplerate; + ss->channels = (uint8_t) sfinfo.channels; if (!pa_sample_spec_valid(ss)) { pa_log("Unsupported sample format in file %s", fname); @@ -119,7 +119,7 @@ int pa_sound_file_load( if (map) pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT); - if ((l = pa_frame_size(ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { + if ((l = pa_frame_size(ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { pa_log("File too large"); goto finish; } @@ -131,7 +131,7 @@ int pa_sound_file_load( ptr = pa_memblock_acquire(chunk->memblock); if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) || - (!readf_function && sf_read_raw(sf, ptr, l) != (sf_count_t) l)) { + (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) { pa_log("Premature file end"); goto finish; } @@ -189,15 +189,15 @@ int pa_sound_file_too_big_to_cache(const char *fname) { break; } - ss.rate = sfinfo.samplerate; - ss.channels = sfinfo.channels; + ss.rate = (uint32_t) sfinfo.samplerate; + ss.channels = (uint8_t) sfinfo.channels; if (!pa_sample_spec_valid(&ss)) { pa_log("Unsupported sample format in file %s", fname); return -1; } - if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { + if ((pa_frame_size(&ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { pa_log("File too large: %s", fname); return 1; } diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 3d1abe30..4257154e 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -397,7 +397,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) { pa_log_debug("Delay queue overflow!"); - pa_memblockq_seek(o->thread_info.delay_memblockq, chunk->length, PA_SEEK_RELATIVE); + pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE); } limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind; @@ -441,7 +441,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { } /* Called from thread context */ -void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in sink sample spec */) { +void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in source sample spec */) { pa_source_output_assert_ref(o); pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->thread_info.state)); @@ -512,7 +512,7 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0); else { - /* If this sink input is not realized yet, we have to touch + /* If this source output is not realized yet, we have to touch * the thread info data directly */ usec = fixup_latency(o->source, usec); @@ -532,7 +532,7 @@ pa_usec_t pa_source_output_get_requested_latency(pa_source_output *o) { if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0); else - /* If this sink input is not realized yet, we have to touch + /* If this source output is not realized yet, we have to touch * the thread info data directly */ usec = o->thread_info.requested_source_latency; @@ -752,7 +752,7 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int return 0; } - case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: { + case PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY: { pa_usec_t *r = userdata; *r = o->thread_info.requested_source_latency; diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 61825b22..a7aac814 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -174,12 +174,13 @@ typedef struct pa_source_output_new_data { pa_source *source; + pa_resample_method_t resample_method; + pa_sample_spec sample_spec; - pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - pa_bool_t channel_map_is_set; - pa_resample_method_t resample_method; + pa_bool_t sample_spec_is_set:1; + pa_bool_t channel_map_is_set:1; } pa_source_output_new_data; pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 95007af4..7ed32e92 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -260,7 +260,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) if (o->suspend) - o->suspend(o, state == PA_SINK_SUSPENDED); + o->suspend(o, state == PA_SOURCE_SUSPENDED); } if (state != PA_SOURCE_UNLINKED) /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */ @@ -273,7 +273,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { void pa_source_put(pa_source *s) { pa_source_assert_ref(s); - pa_assert(s->state == PA_SINK_INIT); + pa_assert(s->state == PA_SOURCE_INIT); /* The following fields must be initialized properly when calling _put() */ pa_assert(s->asyncmsgq); @@ -520,18 +520,29 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { s->set_volume = NULL; if (!s->set_volume) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL); + pa_source_set_soft_volume(s, volume); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } /* Called from main thread */ -const pa_cvolume *pa_source_get_volume(pa_source *s) { +void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) { + pa_source_assert_ref(s); + pa_assert(volume); + + if (PA_SOURCE_IS_LINKED(s->state)) + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL); + else + s->thread_info.soft_volume = *volume; +} + +/* Called from main thread */ +const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_IS_LINKED(s->state)); - if (s->refresh_volume) { + if (s->refresh_volume || force_refresh) { pa_cvolume old_volume = s->volume; if (s->get_volume && s->get_volume(s) < 0) @@ -568,12 +579,12 @@ void pa_source_set_mute(pa_source *s, pa_bool_t mute) { } /* Called from main thread */ -pa_bool_t pa_source_get_mute(pa_source *s) { +pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_IS_LINKED(s->state)); - if (s->refresh_muted) { + if (s->refresh_muted || force_refresh) { pa_bool_t old_muted = s->muted; if (s->get_mute && s->get_mute(s) < 0) @@ -932,7 +943,7 @@ void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t pa_assert(!min_latency || !max_latency || min_latency <= max_latency); - if (PA_SINK_IS_LINKED(s->state)) { + if (PA_SOURCE_IS_LINKED(s->state)) { pa_usec_t r[2]; r[0] = min_latency; diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index f4a17e8d..cae78693 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -168,21 +168,22 @@ typedef enum pa_source_message { typedef struct pa_source_new_data { char *name; - pa_bool_t namereg_fail; pa_proplist *proplist; const char *driver; pa_module *module; pa_sample_spec sample_spec; - pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - pa_bool_t channel_map_is_set; - pa_cvolume volume; - pa_bool_t volume_is_set; - pa_bool_t muted; - pa_bool_t muted_is_set; + pa_bool_t muted:1; + + pa_bool_t volume_is_set:1; + pa_bool_t muted_is_set:1; + pa_bool_t sample_spec_is_set:1; + pa_bool_t channel_map_is_set:1; + + pa_bool_t namereg_fail:1; } pa_source_new_data; pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data); @@ -226,9 +227,10 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend); int pa_source_suspend_all(pa_core *c, pa_bool_t suspend); void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); -const pa_cvolume *pa_source_get_volume(pa_source *source); +void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume); +const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh); void pa_source_set_mute(pa_source *source, pa_bool_t mute); -pa_bool_t pa_source_get_mute(pa_source *source); +pa_bool_t pa_source_get_mute(pa_source *source, pa_bool_t force_refresh); unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */ unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */ diff --git a/src/pulsecore/start-child.c b/src/pulsecore/start-child.c index 1661383d..7774bde6 100644 --- a/src/pulsecore/start-child.c +++ b/src/pulsecore/start-child.c @@ -66,11 +66,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) { return pipe_fds[0]; } else { -#ifdef __linux__ - DIR* d; -#endif - int max_fd, i; - /* child */ pa_reset_priority(); @@ -87,48 +82,9 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) { pa_close(2); pa_assert_se(open("/dev/null", O_WRONLY) == 2); -#ifdef __linux__ - - if ((d = opendir("/proc/self/fd/"))) { - - struct dirent *de; - - while ((de = readdir(d))) { - char *e = NULL; - int fd; - - if (de->d_name[0] == '.') - continue; - - errno = 0; - fd = strtol(de->d_name, &e, 10); - pa_assert(errno == 0 && e && *e == 0); - - if (fd >= 3 && dirfd(d) != fd) - pa_close(fd); - } - - closedir(d); - } else { - -#endif - - max_fd = 1024; - -#ifdef HAVE_SYS_RESOURCE_H - { - struct rlimit r; - if (getrlimit(RLIMIT_NOFILE, &r) == 0) - max_fd = r.rlim_max; - } -#endif - - for (i = 3; i < max_fd; i++) - pa_close(i); - -#ifdef __linux__ - } -#endif + pa_close_all(-1); + pa_reset_sigs(-1); + pa_unblock_sigs(-1); #ifdef PR_SET_PDEATHSIG /* On Linux we can use PR_SET_PDEATHSIG to have the helper @@ -139,16 +95,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) { prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); #endif -#ifdef SIGPIPE - /* Make sure that SIGPIPE kills the child process */ - signal(SIGPIPE, SIG_DFL); -#endif - -#ifdef SIGTERM - /* Make sure that SIGTERM kills the child process */ - signal(SIGTERM, SIG_DFL); -#endif - execl(name, name, argv1, NULL); _exit(1); } diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index b59b6f49..540faef9 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -77,7 +77,7 @@ char *pa_strbuf_tostring(pa_strbuf *sb) { pa_assert(sb); - e = t = pa_xnew(char, sb->length+1); + e = t = pa_xmalloc(sb->length+1); for (c = sb->head; c; c = c->next) { pa_assert((size_t) (e-t) <= sb->length); @@ -150,8 +150,8 @@ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) { /* Append a printf() style formatted string to the string buffer. */ /* The following is based on an example from the GNU libc documentation */ -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { - int size = 100; +size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { + size_t size = 100; struct chunk *c = NULL; pa_assert(sb); @@ -168,14 +168,14 @@ int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { CHUNK_TO_TEXT(c)[size-1] = 0; va_end(ap); - if (r > -1 && r < size) { - c->length = r; + if (r > -1 && (size_t) r < size) { + c->length = (size_t) r; append(sb, c); - return r; + return (size_t) r; } if (r > -1) /* glibc 2.1 */ - size = r+1; + size = (size_t) r+1; else /* glibc 2.0 */ size *= 2; } diff --git a/src/pulsecore/strbuf.h b/src/pulsecore/strbuf.h index 24c876d5..ac68d7be 100644 --- a/src/pulsecore/strbuf.h +++ b/src/pulsecore/strbuf.h @@ -31,7 +31,7 @@ void pa_strbuf_free(pa_strbuf *sb); char *pa_strbuf_tostring(pa_strbuf *sb); char *pa_strbuf_tostring_free(pa_strbuf *sb); -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); +size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); void pa_strbuf_puts(pa_strbuf *sb, const char *t); void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t m); diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c index b0ed59ef..62a30144 100644 --- a/src/pulsecore/tagstruct.c +++ b/src/pulsecore/tagstruct.c @@ -154,7 +154,7 @@ void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) { extend(t, 5+length); t->data[t->length] = PA_TAG_ARBITRARY; - tmp = htonl(length); + tmp = htonl((uint32_t) length); memcpy(t->data+t->length+1, &tmp, 4); if (length) memcpy(t->data+t->length+5, p, length); @@ -165,7 +165,7 @@ void pa_tagstruct_put_boolean(pa_tagstruct*t, pa_bool_t b) { pa_assert(t); extend(t, 1); - t->data[t->length] = b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE; + t->data[t->length] = (uint8_t) (b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE); t->length += 1; } @@ -175,9 +175,9 @@ void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) { extend(t, 9); t->data[t->length] = PA_TAG_TIMEVAL; - tmp = htonl(tv->tv_sec); + tmp = htonl((uint32_t) tv->tv_sec); memcpy(t->data+t->length+1, &tmp, 4); - tmp = htonl(tv->tv_usec); + tmp = htonl((uint32_t) tv->tv_usec); memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } @@ -228,7 +228,7 @@ void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) { unsigned i; pa_assert(t); - extend(t, 2 + map->channels); + extend(t, 2 + (size_t) map->channels); t->data[t->length++] = PA_TAG_CHANNEL_MAP; t->data[t->length++] = map->channels; @@ -435,9 +435,9 @@ int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) { return -1; memcpy(&tv->tv_sec, t->data+t->rindex+1, 4); - tv->tv_sec = ntohl(tv->tv_sec); + tv->tv_sec = (time_t) ntohl((uint32_t) tv->tv_sec); memcpy(&tv->tv_usec, t->data+t->rindex+5, 4); - tv->tv_usec = ntohl(tv->tv_usec); + tv->tv_usec = (suseconds_t) ntohl((uint32_t) tv->tv_usec); t->rindex += 9; return 0; } @@ -523,7 +523,7 @@ int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) { for (i = 0; i < map->channels; i ++) map->map[i] = (int8_t) t->data[t->rindex + 2 + i]; - t->rindex += 2 + map->channels; + t->rindex += 2 + (size_t) map->channels; return 0; } diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 20ed16d9..ade398f9 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -41,6 +41,7 @@ struct pa_thread { pa_thread_func_t thread_func; void *userdata; pa_atomic_t running; + pa_bool_t joined; }; struct pa_tls { @@ -82,6 +83,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; t->userdata = userdata; + t->joined = FALSE; pa_atomic_store(&t->running, 0); if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { @@ -115,7 +117,12 @@ void pa_thread_free(pa_thread *t) { int pa_thread_join(pa_thread *t) { pa_assert(t); + pa_assert(t->thread_func); + + if (t->joined) + return -1; + t->joined = TRUE; return pthread_join(t->id, NULL); } @@ -132,6 +139,7 @@ pa_thread* pa_thread_self(void) { t->id = pthread_self(); t->thread_func = NULL; t->userdata = NULL; + t->joined = TRUE; pa_atomic_store(&t->running, 2); PA_STATIC_TLS_SET(current_thread, t); @@ -192,4 +200,3 @@ void *pa_tls_set(pa_tls *t, void *userdata) { pa_assert_se(pthread_setspecific(t->key, userdata) == 0); return r; } - diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index f3aca13e..87e850d6 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -86,7 +86,7 @@ void *pa_tls_set(pa_tls *t, void *userdata); } \ struct __stupid_useless_struct_to_allow_trailing_semicolon -#ifdef HAVE_TLS_BUILTIN +#ifdef SUPPORT_TLS___THREAD /* An optimized version of the above that requires no dynamic * allocation if the compiler supports __thread */ #define PA_STATIC_TLS_DECLARE_NO_FREE(name) \ diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c index d0231486..b165f4a8 100644 --- a/src/pulsecore/time-smoother.c +++ b/src/pulsecore/time-smoother.c @@ -209,8 +209,8 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) { i = s->history_idx; for (j = s->n_history; j > 0; j--) { - ax += s->history_x[i]; - ay += s->history_y[i]; + ax += (int64_t) s->history_x[i]; + ay += (int64_t) s->history_y[i]; c++; REDUCE_INC(i); @@ -236,7 +236,7 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) { REDUCE_INC(i); } - r = (double) k / t; + r = (double) k / (double) t; return (s->monotonic && r < 0) ? 0 : r; } @@ -268,8 +268,8 @@ static void calc_abc(pa_smoother *s) { /* Calculate a, b, c for y=ax^3+bx^2+cx */ s->c = de; - s->b = (((double) (3*ky)/kx - dp - 2*de)) / kx; - s->a = (dp/kx - 2*s->b - de/kx) / (3*kx); + s->b = (((double) (3*ky)/ (double) kx - dp - (double) (2*de))) / (double) kx; + s->a = (dp/(double) kx - 2*s->b - de/(double) kx) / (double) (3*kx); s->abc_valid = TRUE; } @@ -284,7 +284,7 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) { /* The requested point is right of the point where we wanted * to be on track again, thus just linearly estimate */ - t = (int64_t) s->py + (int64_t) (s->dp * (x - s->px)); + t = (int64_t) s->py + (int64_t) (s->dp * (double) (x - s->px)); if (t < 0) t = 0; @@ -360,7 +360,7 @@ void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) { /* And calculate when we want to be on track again */ s->px = s->ex + s->adjust_time; - s->py = s->ry + s->dp *s->adjust_time; + s->py = s->ry + (pa_usec_t) (s->dp * (double) s->adjust_time); s->abc_valid = FALSE; diff --git a/src/pulsecore/tokenizer.c b/src/pulsecore/tokenizer.c index d1e0836b..07a9f3ac 100644 --- a/src/pulsecore/tokenizer.c +++ b/src/pulsecore/tokenizer.c @@ -34,7 +34,7 @@ #include "tokenizer.h" -static void token_free(void *p, PA_GCC_UNUSED void *userdata) { +static void token_free(void *p, void *userdata) { pa_xfree(p); } diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c index 9e75f63a..7f91ba3c 100644 --- a/src/pulsecore/x11prop.c +++ b/src/pulsecore/x11prop.c @@ -32,7 +32,7 @@ void pa_x11_set_prop(Display *d, const char *name, const char *data) { Atom a = XInternAtom(d, name, False); - XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, strlen(data)+1); + XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1)); } void pa_x11_del_prop(Display *d, const char *name) { @@ -49,7 +49,7 @@ char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) { char *ret = NULL; Atom a = XInternAtom(d, name, False); - if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (l+2)/4, False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success) + if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success) goto finish; if (actual_type != XA_STRING) diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c index 17f8e6a4..332ebb2e 100644 --- a/src/pulsecore/x11wrap.c +++ b/src/pulsecore/x11wrap.c @@ -91,7 +91,7 @@ static void work(pa_x11_wrapper *w) { } /* IO notification event for the X11 display connection */ -static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_x11_wrapper *w = userdata; pa_assert(m); @@ -118,7 +118,7 @@ static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { } /* IO notification event for X11 internal connections */ -static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_x11_wrapper *w = userdata; pa_assert(m); diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c index 9c234602..12b39f10 100644 --- a/src/tests/channelmap-test.c +++ b/src/tests/channelmap-test.c @@ -4,7 +4,7 @@ #include <pulse/channelmap.h> #include <pulse/gccmacro.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { char cm[PA_CHANNEL_MAP_SNPRINT_MAX]; pa_channel_map map, map2; diff --git a/src/tests/cpulimit-test.c b/src/tests/cpulimit-test.c index b7145e8a..fdc0162e 100644 --- a/src/tests/cpulimit-test.c +++ b/src/tests/cpulimit-test.c @@ -42,7 +42,7 @@ static time_t start; #ifdef TEST2 -static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UNUSED int sig, PA_GCC_UNUSED void *userdata) { +static void func(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { time_t now; time(&now); @@ -55,7 +55,7 @@ static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UN #endif -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { pa_mainloop *m; m = pa_mainloop_new(); diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c index 9f914553..d71eff1c 100644 --- a/src/tests/envelope-test.c +++ b/src/tests/envelope-test.c @@ -40,7 +40,7 @@ const pa_envelope_def ramp_down = { .n_points = 2, .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC }, .points_y = { - .f = { 1.0, 0.2 }, + .f = { 1.0f, 0.2f }, .i = { 0x10000, 0x10000/5 } } }; @@ -49,7 +49,7 @@ const pa_envelope_def ramp_up = { .n_points = 2, .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC }, .points_y = { - .f = { 0.2, 1.0 }, + .f = { 0.2f, 1.0f }, .i = { 0x10000/5, 0x10000 } } }; @@ -58,7 +58,7 @@ const pa_envelope_def ramp_down2 = { .n_points = 2, .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC }, .points_y = { - .f = { 0.8, 0.7 }, + .f = { 0.8f, 0.7f }, .i = { 0x10000*4/5, 0x10000*7/10 } } }; @@ -67,7 +67,7 @@ const pa_envelope_def ramp_up2 = { .n_points = 2, .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC }, .points_y = { - .f = { 0.7, 0.9 }, + .f = { 0.7f, 0.9f }, .i = { 0x10000*7/10, 0x10000*9/10 } } }; @@ -140,7 +140,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss) unsigned n_samples; block = pa_memblock_new(pool, pa_bytes_per_second(ss)); - n_samples = pa_memblock_get_length(block) / pa_sample_size(ss); + n_samples = (unsigned) (pa_memblock_get_length(block) / pa_sample_size(ss)); d = pa_memblock_acquire(block); @@ -171,7 +171,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss) float *f; for (f = d; n_samples > 0; n_samples--, f++) - *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0); + *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0f); break; } diff --git a/src/tests/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c new file mode 100644 index 00000000..cb3dc87c --- /dev/null +++ b/src/tests/lock-autospawn-test.c @@ -0,0 +1,109 @@ +/*** + This file is part of PulseAudio. + + Copyright 2008 Lennart Poettering + + 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. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/poll.h> +#include <string.h> + +#include <pulsecore/macro.h> +#include <pulsecore/thread.h> +#include <pulse/lock-autospawn.h> +#include <pulse/util.h> + +static void thread_func(void*k) { + pa_assert_se(pa_autospawn_lock_init() >= 0); + + pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k)); + + pa_assert_se(pa_autospawn_lock_acquire(TRUE) > 0); + + pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k)); + + pa_msleep(5000); + + pa_log("%i, Releasing", PA_PTR_TO_INT(k)); + + pa_autospawn_lock_release(); + + pa_autospawn_lock_done(FALSE); +} + +static void thread_func2(void *k) { + int fd; + + pa_assert_se((fd = pa_autospawn_lock_init()) >= 0); + + pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k)); + + for (;;) { + struct pollfd pollfd; + int j; + + if ((j = pa_autospawn_lock_acquire(FALSE)) > 0) + break; + + pa_assert(j == 0); + + memset(&pollfd, 0, sizeof(pollfd)); + pollfd.fd = fd; + pollfd.events = POLLIN; + + pa_assert_se(poll(&pollfd, 1, -1) == 1); + + pa_log("%i, woke up", PA_PTR_TO_INT(k)); + } + + pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k)); + + pa_msleep(5000); + + pa_log("%i, Releasing", PA_PTR_TO_INT(k)); + + pa_autospawn_lock_release(); + + pa_autospawn_lock_done(FALSE); +} + +int main(int argc, char**argv) { + pa_thread *a, *b, *c, *d; + + pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1)))); + pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2)))); + pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3)))); + pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4)))); + + pa_thread_join(a); + pa_thread_join(b); + pa_thread_join(c); + pa_thread_join(d); + + pa_thread_free(a); + pa_thread_free(b); + pa_thread_free(c); + pa_thread_free(d); + + pa_log("End"); + + return 0; +} diff --git a/src/tests/mainloop-test.c b/src/tests/mainloop-test.c index 9fa2e466..2580fa72 100644 --- a/src/tests/mainloop-test.c +++ b/src/tests/mainloop-test.c @@ -66,7 +66,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v #endif } -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { pa_mainloop_api *a; pa_io_event *ioe; pa_time_event *te; diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c index 9e358359..c0665822 100644 --- a/src/tests/mcalign-test.c +++ b/src/tests/mcalign-test.c @@ -36,7 +36,7 @@ /* A simple program for testing pa_mcalign */ -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { pa_mempool *p; pa_mcalign *a; pa_memchunk c; @@ -47,7 +47,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { pa_memchunk_reset(&c); - srand(time(NULL)); + srand((unsigned) time(NULL)); for (;;) { ssize_t r; @@ -62,7 +62,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { l = pa_memblock_get_length(c.memblock) - c.index; - l = l <= 1 ? l : rand() % (l-1) +1 ; + l = l <= 1 ? l : (size_t) rand() % (l-1) +1; p = pa_memblock_acquire(c.memblock); @@ -74,11 +74,11 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { pa_memblock_release(c.memblock); - c.length = r; + c.length = (size_t) r; pa_mcalign_push(a, &c); fprintf(stderr, "Read %ld bytes\n", (long)r); - c.index += r; + c.index += (size_t) r; if (c.index >= pa_memblock_get_length(c.memblock)) { pa_memblock_unref(c.memblock); diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c index f3f6f829..544121fd 100644 --- a/src/tests/mix-test.c +++ b/src/tests/mix-test.c @@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { case PA_SAMPLE_FLOAT32RE: { float *u = d; - u[0] = 0.0; - u[1] = -1.0; - u[2] = 1.0; - u[3] = 4711; - u[4] = 0.222; - u[5] = 0.33; - u[6] = -.3; - u[7] = 99; - u[8] = -0.555; - u[9] = -.123; + u[0] = 0.0f; + u[1] = -1.0f; + u[2] = 1.0f; + u[3] = 4711.0f; + u[4] = 0.222f; + u[5] = 0.33f; + u[6] = -.3f; + u[7] = 99.0f; + u[8] = -0.555f; + u[9] = -.123f; if (ss->format == PA_SAMPLE_FLOAT32RE) for (i = 0; i < 10; i++) diff --git a/src/tests/pacat-simple.c b/src/tests/pacat-simple.c index b26e4b68..ffe3176a 100644 --- a/src/tests/pacat-simple.c +++ b/src/tests/pacat-simple.c @@ -33,7 +33,7 @@ #define BUFSIZE 1024 -int main(PA_GCC_UNUSED int argc, char*argv[]) { +int main(int argc, char*argv[]) { /* The Sample format to use */ static const pa_sample_spec ss = { @@ -94,7 +94,7 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) { } /* ... and play it */ - if (pa_simple_write(s, buf, r, &error) < 0) { + if (pa_simple_write(s, buf, (size_t) r, &error) < 0) { fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error)); goto finish; } diff --git a/src/tests/parec-simple.c b/src/tests/parec-simple.c index 6c0d529b..0312005d 100644 --- a/src/tests/parec-simple.c +++ b/src/tests/parec-simple.c @@ -47,13 +47,13 @@ static ssize_t loop_write(int fd, const void*data, size_t size) { ret += r; data = (const uint8_t*) data + r; - size -= r; + size -= (size_t) r; } return ret; } -int main(PA_GCC_UNUSED int argc, char*argv[]) { +int main(int argc, char*argv[]) { /* The sample type to use */ static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, @@ -80,6 +80,9 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) { goto finish; } + if (r == 0) + break; + /* And write it to STDOUT */ if ((r = loop_write(STDOUT_FILENO, buf, sizeof(buf))) <= 0) { fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index 1a20be2c..6959127b 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { case PA_SAMPLE_FLOAT32RE: { float *u = d; - u[0] = 0.0; - u[1] = -1.0; - u[2] = 1.0; - u[3] = 4711; - u[4] = 0.222; - u[5] = 0.33; - u[6] = -.3; - u[7] = 99; - u[8] = -0.555; - u[9] = -.123; + u[0] = 0.0f; + u[1] = -1.0f; + u[2] = 1.0f; + u[3] = 4711.0f; + u[4] = 0.222f; + u[5] = 0.33f; + u[6] = -.3f; + u[7] = 99.0f; + u[8] = -0.555f; + u[9] = -.123f; if (ss->format == PA_SAMPLE_FLOAT32RE) for (i = 0; i < 10; i++) diff --git a/src/tests/rtstutter.c b/src/tests/rtstutter.c index 91e85c36..6b0cb8f7 100644 --- a/src/tests/rtstutter.c +++ b/src/tests/rtstutter.c @@ -52,7 +52,7 @@ static void* work(void *p) { pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) == 0); CPU_ZERO(&mask); - CPU_SET(PA_PTR_TO_INT(p), &mask); + CPU_SET((size_t) PA_PTR_TO_INT(p), &mask); pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0); for (;;) { @@ -65,17 +65,17 @@ static void* work(void *p) { pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0); nsec = - (uint64_t) ((((double) rand())*(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) + - (uint64_t) (msec_lower*PA_NSEC_PER_MSEC); + (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) + + (uint64_t) ((uint64_t) msec_lower*PA_NSEC_PER_MSEC); pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_INT(p), (int) (nsec/PA_NSEC_PER_MSEC)); - end.tv_sec += nsec / PA_NSEC_PER_SEC; - end.tv_nsec += nsec % PA_NSEC_PER_SEC; + end.tv_sec += (time_t) (nsec / PA_NSEC_PER_SEC); + end.tv_nsec += (long int) (nsec % PA_NSEC_PER_SEC); while ((pa_usec_t) end.tv_nsec > PA_NSEC_PER_SEC) { end.tv_sec++; - end.tv_nsec -= PA_NSEC_PER_SEC; + end.tv_nsec -= (long int) PA_NSEC_PER_SEC; } do { @@ -88,7 +88,7 @@ static void* work(void *p) { int main(int argc, char*argv[]) { int n; - srand(time(NULL)); + srand((unsigned) time(NULL)); if (argc >= 3) { msec_lower = atoi(argv[1]); diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c index b78f3c91..15700ec2 100644 --- a/src/tests/smoother-test.c +++ b/src/tests/smoother-test.c @@ -64,7 +64,7 @@ int main(int argc, char*argv[]) { for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) { while (u < PA_ELEMENTSOF(msec) && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) { - pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC); + pa_smoother_put(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, (pa_usec_t) msec[u+1] * PA_USEC_PER_MSEC); printf("%i\t\t%i\n", msec[u], msec[u+1]); u += 2; } diff --git a/src/tests/stripnul.c b/src/tests/stripnul.c index 0ab06776..2b8aa083 100644 --- a/src/tests/stripnul.c +++ b/src/tests/stripnul.c @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) { uint8_t *zero; pa_assert_se(argc >= 2); - pa_assert_se((granularity = atoi(argv[1])) >= 1); + pa_assert_se((granularity = (size_t) atoi(argv[1])) >= 1); pa_assert_se((i = (argc >= 3) ? fopen(argv[2], "r") : stdin)); pa_assert_se((o = (argc >= 4) ? fopen(argv[3], "w") : stdout)); @@ -53,11 +53,11 @@ int main(int argc, char *argv[]) { if (found) pa_assert_se(fwrite(buffer, granularity, k, o) == k); else { - for (p = buffer; (p-buffer)/granularity < k; p += granularity) + for (p = buffer; ((size_t) (p-buffer)/granularity) < k; p += granularity) if (memcmp(p, zero, granularity)) { size_t left; found = TRUE; - left = k - (p-buffer)/granularity; + left = (size_t) (k - (size_t) (p-buffer)/granularity); pa_assert_se(fwrite(p, granularity, left, o) == left); break; } diff --git a/src/tests/strlist-test.c b/src/tests/strlist-test.c index 2bd1645c..10f370c2 100644 --- a/src/tests/strlist-test.c +++ b/src/tests/strlist-test.c @@ -5,7 +5,7 @@ #include <pulsecore/strlist.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char* argv[]) { +int main(int argc, char* argv[]) { char *t, *u; pa_strlist *l = NULL; diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c index 7e364685..42c479a1 100644 --- a/src/tests/sync-playback.c +++ b/src/tests/sync-playback.c @@ -89,7 +89,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) { fprintf(stderr, "Writing data to stream %i.\n", i); - r = pa_stream_write(s, data, sizeof(data), nop_free_cb, sizeof(data) * i, PA_SEEK_ABSOLUTE); + r = pa_stream_write(s, data, sizeof(data), nop_free_cb, (int64_t) sizeof(data) * (int64_t) i, PA_SEEK_ABSOLUTE); assert(r == 0); /* Be notified when this stream is drained */ diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c index 7a62f85a..263cd57d 100644 --- a/src/tests/thread-mainloop-test.c +++ b/src/tests/thread-mainloop-test.c @@ -39,7 +39,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v fprintf(stderr, "TIME EVENT END\n"); } -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { pa_mainloop_api *a; pa_threaded_mainloop *m; struct timeval tv; diff --git a/src/tests/voltest.c b/src/tests/voltest.c index d2c0ff69..5b26c0f1 100644 --- a/src/tests/voltest.c +++ b/src/tests/voltest.c @@ -3,7 +3,7 @@ #include <pulse/volume.h> #include <pulse/gccmacro.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) { pa_volume_t v; for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) { diff --git a/src/utils/pacat.c b/src/utils/pacat.c index 78b9cef8..c1826d7b 100644 --- a/src/utils/pacat.c +++ b/src/utils/pacat.c @@ -33,15 +33,13 @@ #include <stdlib.h> #include <getopt.h> #include <fcntl.h> +#include <locale.h> +#include <pulse/i18n.h> #include <pulse/pulseaudio.h> #define TIME_EVENT_USEC 50000 -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif - #define CLEAR_LINE "\x1B[K" static enum { RECORD, PLAYBACK } mode = PLAYBACK; @@ -92,7 +90,7 @@ static void do_stream_write(size_t length) { l = buffer_length; if (pa_stream_write(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, PA_SEEK_RELATIVE) < 0) { - fprintf(stderr, "pa_stream_write() failed: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("pa_stream_write() failed: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); return; } @@ -131,7 +129,7 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) { mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT); if (pa_stream_peek(s, &data, &length) < 0) { - fprintf(stderr, "pa_stream_peek() failed: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("pa_stream_peek() failed: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); return; } @@ -140,9 +138,9 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) { assert(length > 0); if (buffer) { - fprintf(stderr, "Buffer overrun, dropping incoming data\n"); + fprintf(stderr, _("Buffer overrun, dropping incoming data\n")); if (pa_stream_drop(s) < 0) { - fprintf(stderr, "pa_stream_drop() failed: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("pa_stream_drop() failed: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); } return; @@ -168,25 +166,25 @@ static void stream_state_callback(pa_stream *s, void *userdata) { const pa_buffer_attr *a; char cmt[PA_CHANNEL_MAP_SNPRINT_MAX], sst[PA_SAMPLE_SPEC_SNPRINT_MAX]; - fprintf(stderr, "Stream successfully created.\n"); + fprintf(stderr, _("Stream successfully created.\n")); if (!(a = pa_stream_get_buffer_attr(s))) - fprintf(stderr, "pa_stream_get_buffer_attr() failed: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); + fprintf(stderr, _("pa_stream_get_buffer_attr() failed: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s)))); else { if (mode == PLAYBACK) - fprintf(stderr, "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n", a->maxlength, a->tlength, a->prebuf, a->minreq); + fprintf(stderr, _("Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"), a->maxlength, a->tlength, a->prebuf, a->minreq); else { assert(mode == RECORD); - fprintf(stderr, "Buffer metrics: maxlength=%u, fragsize=%u\n", a->maxlength, a->fragsize); + fprintf(stderr, _("Buffer metrics: maxlength=%u, fragsize=%u\n"), a->maxlength, a->fragsize); } } - fprintf(stderr, "Using sample spec '%s', channel map '%s'.\n", + fprintf(stderr, _("Using sample spec '%s', channel map '%s'.\n"), pa_sample_spec_snprint(sst, sizeof(sst), pa_stream_get_sample_spec(s)), pa_channel_map_snprint(cmt, sizeof(cmt), pa_stream_get_channel_map(s))); - fprintf(stderr, "Connected to device %s (%u, %ssuspended).\n", + fprintf(stderr, _("Connected to device %s (%u, %ssuspended).\n"), pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : "not "); @@ -196,7 +194,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) { case PA_STREAM_FAILED: default: - fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); + fprintf(stderr, _("Stream error: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s)))); quit(1); } } @@ -206,9 +204,9 @@ static void stream_suspended_callback(pa_stream *s, void *userdata) { if (verbose) { if (pa_stream_is_suspended(s)) - fprintf(stderr, "Stream device suspended." CLEAR_LINE " \n"); + fprintf(stderr, _("Stream device suspended.%s \n"), CLEAR_LINE); else - fprintf(stderr, "Stream device resumed." CLEAR_LINE " \n"); + fprintf(stderr, _("Stream device resumed.%s \n"), CLEAR_LINE); } } @@ -216,28 +214,28 @@ static void stream_underflow_callback(pa_stream *s, void *userdata) { assert(s); if (verbose) - fprintf(stderr, "Stream underrun." CLEAR_LINE " \n"); + fprintf(stderr, _("Stream underrun.%s \n"), CLEAR_LINE); } static void stream_overflow_callback(pa_stream *s, void *userdata) { assert(s); if (verbose) - fprintf(stderr, "Stream overrun." CLEAR_LINE " \n"); + fprintf(stderr, _("Stream overrun.%s \n"), CLEAR_LINE); } static void stream_started_callback(pa_stream *s, void *userdata) { assert(s); if (verbose) - fprintf(stderr, "Stream started." CLEAR_LINE " \n"); + fprintf(stderr, _("Stream started.%s \n"), CLEAR_LINE); } static void stream_moved_callback(pa_stream *s, void *userdata) { assert(s); if (verbose) - fprintf(stderr, "Stream moved to device %s (%u, %ssuspended)." CLEAR_LINE " \n", pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : "not "); + fprintf(stderr, _("Stream moved to device %s (%u, %ssuspended).%s \n"), pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : _("not "), CLEAR_LINE); } /* This is called whenever the context status changes */ @@ -258,10 +256,10 @@ static void context_state_callback(pa_context *c, void *userdata) { assert(!stream); if (verbose) - fprintf(stderr, "Connection established." CLEAR_LINE " \n"); + fprintf(stderr, _("Connection established.%s \n"), CLEAR_LINE); if (!(stream = pa_stream_new(c, stream_name, &sample_spec, channel_map_set ? &channel_map : NULL))) { - fprintf(stderr, "pa_stream_new() failed: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("pa_stream_new() failed: %s\n"), pa_strerror(pa_context_errno(c))); goto fail; } @@ -276,8 +274,8 @@ static void context_state_callback(pa_context *c, void *userdata) { if (latency > 0) { memset(&buffer_attr, 0, sizeof(buffer_attr)); - buffer_attr.tlength = latency; - buffer_attr.minreq = process_time; + buffer_attr.tlength = (uint32_t) latency; + buffer_attr.minreq = (uint32_t) process_time; buffer_attr.maxlength = (uint32_t) -1; buffer_attr.prebuf = (uint32_t) -1; flags |= PA_STREAM_ADJUST_LATENCY; @@ -286,13 +284,13 @@ static void context_state_callback(pa_context *c, void *userdata) { if (mode == PLAYBACK) { pa_cvolume cv; if ((r = pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags, pa_cvolume_set(&cv, sample_spec.channels, volume), NULL)) < 0) { - fprintf(stderr, "pa_stream_connect_playback() failed: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("pa_stream_connect_playback() failed: %s\n"), pa_strerror(pa_context_errno(c))); goto fail; } } else { if ((r = pa_stream_connect_record(stream, device, latency > 0 ? &buffer_attr : NULL, flags)) < 0) { - fprintf(stderr, "pa_stream_connect_record() failed: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("pa_stream_connect_record() failed: %s\n"), pa_strerror(pa_context_errno(c))); goto fail; } } @@ -306,7 +304,7 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_FAILED: default: - fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c))); goto fail; } @@ -327,12 +325,12 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) { pa_operation *o; if (!success) { - fprintf(stderr, "Failed to drain stream: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("Failed to drain stream: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); } if (verbose) - fprintf(stderr, "Playback stream drained.\n"); + fprintf(stderr, _("Playback stream drained.\n")); pa_stream_disconnect(stream); pa_stream_unref(stream); @@ -342,7 +340,7 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) { pa_context_disconnect(context); else { if (verbose) - fprintf(stderr, "Draining connection to server.\n"); + fprintf(stderr, _("Draining connection to server.\n")); } } @@ -368,13 +366,13 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even if ((r = read(fd, buffer, l)) <= 0) { if (r == 0) { if (verbose) - fprintf(stderr, "Got EOF.\n"); + fprintf(stderr, _("Got EOF.\n")); if (stream) { pa_operation *o; if (!(o = pa_stream_drain(stream, stream_drain_complete, NULL))) { - fprintf(stderr, "pa_stream_drain(): %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("pa_stream_drain(): %s\n"), pa_strerror(pa_context_errno(context))); quit(1); return; } @@ -384,7 +382,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even quit(0); } else { - fprintf(stderr, "read() failed: %s\n", strerror(errno)); + fprintf(stderr, _("read() failed: %s\n"), strerror(errno)); quit(1); } @@ -393,7 +391,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even return; } - buffer_length = r; + buffer_length = (uint32_t) r; buffer_index = 0; if (w) @@ -416,7 +414,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve assert(buffer_length); if ((r = write(fd, (uint8_t*) buffer+buffer_index, buffer_length)) <= 0) { - fprintf(stderr, "write() failed: %s\n", strerror(errno)); + fprintf(stderr, _("write() failed: %s\n"), strerror(errno)); quit(1); mainloop_api->io_free(stdio_event); @@ -424,8 +422,8 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve return; } - buffer_length -= r; - buffer_index += r; + buffer_length -= (uint32_t) r; + buffer_index += (uint32_t) r; if (!buffer_length) { pa_xfree(buffer); @@ -437,7 +435,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve /* UNIX signal to quit recieved */ static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) { if (verbose) - fprintf(stderr, "Got signal, exiting.\n"); + fprintf(stderr, _("Got signal, exiting.\n")); quit(0); } @@ -451,14 +449,14 @@ static void stream_update_timing_callback(pa_stream *s, int success, void *userd if (!success || pa_stream_get_time(s, &usec) < 0 || pa_stream_get_latency(s, &l, &negative) < 0) { - fprintf(stderr, "Failed to get latency: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("Failed to get latency: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); return; } - fprintf(stderr, "Time: %0.3f sec; Latency: %0.0f usec. \r", + fprintf(stderr, _("Time: %0.3f sec; Latency: %0.0f usec. \r"), (float) usec / 1000000, - (float) l * (negative?-1:1)); + (float) l * (negative?-1.0f:1.0f)); } /* Someone requested that the latency is shown */ @@ -476,7 +474,7 @@ static void time_event_callback(pa_mainloop_api*m, pa_time_event *e, const struc if (stream && pa_stream_get_state(stream) == PA_STREAM_READY) { pa_operation *o; if (!(o = pa_stream_update_timing_info(stream, stream_update_timing_callback, NULL))) - fprintf(stderr, "pa_stream_update_timing_info() failed: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("pa_stream_update_timing_info() failed: %s\n"), pa_strerror(pa_context_errno(context))); else pa_operation_unref(o); } @@ -489,7 +487,7 @@ static void time_event_callback(pa_mainloop_api*m, pa_time_event *e, const struc static void help(const char *argv0) { - printf("%s [options]\n\n" + printf(_("%s [options]\n\n" " -h, --help Show this help\n" " --version Show version\n\n" " -r, --record Create a connection for recording\n" @@ -515,7 +513,7 @@ static void help(const char *argv0) { " --no-remix Don't upmix or downmix channels.\n" " --no-remap Map channels by index instead of name.\n" " --latency=BYTES Request the specified latency in bytes.\n" - " --process-time=BYTES Request the specified process time per request in bytes.\n" + " --process-time=BYTES Request the specified process time per request in bytes.\n") , argv0); } @@ -568,6 +566,9 @@ int main(int argc, char *argv[]) { {NULL, 0, NULL, 0} }; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + if (!(bn = strrchr(argv[0], '/'))) bn = argv[0]; else @@ -587,7 +588,7 @@ int main(int argc, char *argv[]) { goto quit; case ARG_VERSION: - printf("pacat "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); + printf(_("pacat %s\nCompiled with libpulse %s\nLinked with libpulse %s\n"), PACKAGE_VERSION, pa_get_headers_version(), pa_get_library_version()); ret = 0; goto quit; @@ -625,12 +626,12 @@ int main(int argc, char *argv[]) { case ARG_VOLUME: { int v = atoi(optarg); - volume = v < 0 ? 0 : v; + volume = v < 0 ? 0U : (pa_volume_t) v; break; } case ARG_CHANNELS: - sample_spec.channels = atoi(optarg); + sample_spec.channels = (uint8_t) atoi(optarg); break; case ARG_SAMPLEFORMAT: @@ -638,12 +639,12 @@ int main(int argc, char *argv[]) { break; case ARG_SAMPLERATE: - sample_spec.rate = atoi(optarg); + sample_spec.rate = (uint32_t) atoi(optarg); break; case ARG_CHANNELMAP: if (!pa_channel_map_parse(&channel_map, optarg)) { - fprintf(stderr, "Invalid channel map '%s'\n", optarg); + fprintf(stderr, _("Invalid channel map '%s'\n"), optarg); goto quit; } @@ -671,15 +672,15 @@ int main(int argc, char *argv[]) { break; case ARG_LATENCY: - if (((latency = atoi(optarg))) <= 0) { - fprintf(stderr, "Invalid latency specification '%s'\n", optarg); + if (((latency = (size_t) atoi(optarg))) <= 0) { + fprintf(stderr, _("Invalid latency specification '%s'\n"), optarg); goto quit; } break; case ARG_PROCESS_TIME: - if (((process_time = atoi(optarg))) <= 0) { - fprintf(stderr, "Invalid process time specification '%s'\n", optarg); + if (((process_time = (size_t) atoi(optarg))) <= 0) { + fprintf(stderr, _("Invalid process time specification '%s'\n"), optarg); goto quit; } break; @@ -690,19 +691,19 @@ int main(int argc, char *argv[]) { } if (!pa_sample_spec_valid(&sample_spec)) { - fprintf(stderr, "Invalid sample specification\n"); + fprintf(stderr, _("Invalid sample specification\n")); goto quit; } if (channel_map_set && channel_map.channels != sample_spec.channels) { - fprintf(stderr, "Channel map doesn't match sample specification\n"); + fprintf(stderr, _("Channel map doesn't match sample specification\n")); goto quit; } if (verbose) { char t[PA_SAMPLE_SPEC_SNPRINT_MAX]; pa_sample_spec_snprint(t, sizeof(t), &sample_spec); - fprintf(stderr, "Opening a %s stream with sample specification '%s'.\n", mode == RECORD ? "recording" : "playback", t); + fprintf(stderr, _("Opening a %s stream with sample specification '%s'.\n"), mode == RECORD ? _("recording") : _("playback"), t); } if (!(optind >= argc)) { @@ -710,12 +711,12 @@ int main(int argc, char *argv[]) { int fd; if ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) { - fprintf(stderr, "open(): %s\n", strerror(errno)); + fprintf(stderr, _("open(): %s\n"), strerror(errno)); goto quit; } if (dup2(fd, mode == PLAYBACK ? 0 : 1) < 0) { - fprintf(stderr, "dup2(): %s\n", strerror(errno)); + fprintf(stderr, _("dup2(): %s\n"), strerror(errno)); goto quit; } @@ -725,7 +726,7 @@ int main(int argc, char *argv[]) { stream_name = pa_xstrdup(argv[optind]); } else { - fprintf(stderr, "Too many arguments.\n"); + fprintf(stderr, _("Too many arguments.\n")); goto quit; } } @@ -738,7 +739,7 @@ int main(int argc, char *argv[]) { /* Set up a new main loop */ if (!(m = pa_mainloop_new())) { - fprintf(stderr, "pa_mainloop_new() failed.\n"); + fprintf(stderr, _("pa_mainloop_new() failed.\n")); goto quit; } @@ -759,13 +760,13 @@ int main(int argc, char *argv[]) { mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO, mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT, mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) { - fprintf(stderr, "io_new() failed.\n"); + fprintf(stderr, _("io_new() failed.\n")); goto quit; } /* Create a new connection context */ if (!(context = pa_context_new(mainloop_api, client_name))) { - fprintf(stderr, "pa_context_new() failed.\n"); + fprintf(stderr, _("pa_context_new() failed.\n")); goto quit; } @@ -781,14 +782,14 @@ int main(int argc, char *argv[]) { pa_timeval_add(&tv, TIME_EVENT_USEC); if (!(time_event = mainloop_api->time_new(mainloop_api, &tv, time_event_callback, NULL))) { - fprintf(stderr, "time_new() failed.\n"); + fprintf(stderr, _("time_new() failed.\n")); goto quit; } } /* Run the main loop */ if (pa_mainloop_run(m, &ret) < 0) { - fprintf(stderr, "pa_mainloop_run() failed.\n"); + fprintf(stderr, _("pa_mainloop_run() failed.\n")); goto quit; } diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c index 67d95252..2c89c8d9 100644 --- a/src/utils/pacmd.c +++ b/src/utils/pacmd.c @@ -31,16 +31,18 @@ #include <errno.h> #include <string.h> #include <sys/un.h> +#include <locale.h> #include <pulse/error.h> #include <pulse/util.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/log.h> #include <pulsecore/pid.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { +int main(int argc, char*argv[]) { pid_t pid ; int fd = -1; int ret = 1, i; @@ -50,13 +52,16 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { fd_set ifds, ofds; char *cli; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) { - pa_log("no PulseAudio daemon running"); + pa_log("No PulseAudio daemon running"); goto fail; } if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - pa_log("socket(PF_UNIX, SOCK_STREAM, 0): %s", strerror(errno)); + pa_log(_("socket(PF_UNIX, SOCK_STREAM, 0): %s"), strerror(errno)); goto fail; } @@ -73,7 +78,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { int r; if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) { - pa_log("connect(): %s", strerror(errno)); + pa_log(_("connect(): %s"), strerror(errno)); goto fail; } @@ -81,7 +86,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { break; if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0) { - pa_log("failed to kill PulseAudio daemon."); + pa_log(_("Failed to kill PulseAudio daemon.")); goto fail; } @@ -89,7 +94,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { } if (i >= 5) { - pa_log("daemon not responding."); + pa_log(_("Daemon not responding.")); goto fail; } @@ -104,7 +109,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { for (;;) { if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) { - pa_log("select(): %s", strerror(errno)); + pa_log(_("select(): %s"), strerror(errno)); goto fail; } @@ -116,7 +121,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { if (r == 0) break; - pa_log("read(): %s", strerror(errno)); + pa_log(_("read(): %s"), strerror(errno)); goto fail; } @@ -132,7 +137,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { if (r == 0) break; - pa_log("read(): %s", strerror(errno)); + pa_log(_("read(): %s"), strerror(errno)); goto fail; } @@ -145,7 +150,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { assert(obuf_length); if ((r = write(1, obuf + obuf_index, obuf_length)) < 0) { - pa_log("write(): %s", strerror(errno)); + pa_log(_("write(): %s"), strerror(errno)); goto fail; } @@ -159,7 +164,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { assert(ibuf_length); if ((r = write(fd, ibuf + ibuf_index, ibuf_length)) < 0) { - pa_log("write(): %s", strerror(errno)); + pa_log(_("write(): %s"), strerror(errno)); goto fail; } @@ -182,7 +187,6 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { FD_SET(fd, &ofds); } - ret = 0; fail: diff --git a/src/utils/pactl.c b/src/utils/pactl.c index 4cca2f86..2f430ca7 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -32,16 +32,14 @@ #include <stdlib.h> #include <limits.h> #include <getopt.h> +#include <locale.h> #include <sndfile.h> +#include <pulse/i18n.h> #include <pulse/pulseaudio.h> #include <pulsecore/core-util.h> -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif - #define BUFSIZE 1024 static pa_context *context = NULL; @@ -106,19 +104,19 @@ static void complete_action(void) { static void stat_callback(pa_context *c, const pa_stat_info *i, void *userdata) { char s[128]; if (!i) { - fprintf(stderr, "Failed to get statistics: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get statistics: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } pa_bytes_snprint(s, sizeof(s), i->memblock_total_size); - printf("Currently in use: %u blocks containing %s bytes total.\n", i->memblock_total, s); + printf(_("Currently in use: %u blocks containing %s bytes total.\n"), i->memblock_total, s); pa_bytes_snprint(s, sizeof(s), i->memblock_allocated_size); - printf("Allocated during whole lifetime: %u blocks containing %s bytes total.\n", i->memblock_allocated, s); + printf(_("Allocated during whole lifetime: %u blocks containing %s bytes total.\n"), i->memblock_allocated, s); pa_bytes_snprint(s, sizeof(s), i->scache_size); - printf("Sample cache size: %s\n", s); + printf(_("Sample cache size: %s\n"), s); complete_action(); } @@ -127,21 +125,21 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi char s[PA_SAMPLE_SPEC_SNPRINT_MAX]; if (!i) { - fprintf(stderr, "Failed to get server information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get server information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec); - printf("User name: %s\n" + printf(_("User name: %s\n" "Host Name: %s\n" "Server Name: %s\n" "Server Version: %s\n" "Default Sample Specification: %s\n" "Default Sink: %s\n" "Default Source: %s\n" - "Cookie: %08x\n", + "Cookie: %08x\n"), i->user_name, i->host_name, i->server_name, @@ -159,7 +157,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_ char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get sink information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -175,7 +173,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_ printf("\n"); nl = 1; - printf("*** Sink #%u ***\n" + printf(_("*** Sink #%u ***\n" "Name: %s\n" "Driver: %s\n" "Sample Specification: %s\n" @@ -185,14 +183,14 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_ "Monitor Source: %s\n" "Latency: %0.0f usec, configured %0.0f usec\n" "Flags: %s%s%s%s%s%s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, i->name, pa_strnull(i->driver), pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), i->owner_module, - i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), + i->mute ? _("muted") : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), pa_strnull(i->monitor_source_name), (double) i->latency, (double) i->configured_latency, i->flags & PA_SINK_HARDWARE ? "HARDWARE " : "", @@ -211,7 +209,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get source information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get source information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -227,7 +225,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int printf("\n"); nl = 1; - printf("*** Source #%u ***\n" + printf(_("*** Source #%u ***\n" "Name: %s\n" "Driver: %s\n" "Sample Specification: %s\n" @@ -237,7 +235,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int "Monitor of Sink: %s\n" "Latency: %0.0f usec, configured %0.0f usec\n" "Flags: %s%s%s%s%s%s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, i->name, pa_strnull(i->driver), @@ -245,7 +243,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), i->owner_module, i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), - i->monitor_of_sink_name ? i->monitor_of_sink_name : "n/a", + i->monitor_of_sink_name ? i->monitor_of_sink_name : _("n/a"), (double) i->latency, (double) i->configured_latency, i->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "", i->flags & PA_SOURCE_NETWORK ? "NETWORK " : "", @@ -262,7 +260,7 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int char t[32]; if (is_last < 0) { - fprintf(stderr, "Failed to get module information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get module information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -280,15 +278,15 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int snprintf(t, sizeof(t), "%u", i->n_used); - printf("*** Module #%u ***\n" + printf(_("*** Module #%u ***\n" "Name: %s\n" "Argument: %s\n" "Usage counter: %s\n" - "Auto unload: %s\n", + "Auto unload: %s\n"), i->index, i->name, i->argument ? i->argument : "", - i->n_used != PA_INVALID_INDEX ? t : "n/a", + i->n_used != PA_INVALID_INDEX ? t : _("n/a"), pa_yes_no(i->auto_unload)); } @@ -297,7 +295,7 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get client information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get client information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -315,13 +313,13 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int snprintf(t, sizeof(t), "%u", i->owner_module); - printf("*** Client #%u ***\n" + printf(_("*** Client #%u ***\n" "Driver: %s\n" "Owner Module: %s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, pa_strnull(i->driver), - i->owner_module != PA_INVALID_INDEX ? t : "n/a", + i->owner_module != PA_INVALID_INDEX ? t : _("n/a"), pl = pa_proplist_to_string(i->proplist)); pa_xfree(pl); @@ -332,7 +330,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get sink input information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get sink input information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -351,7 +349,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info snprintf(t, sizeof(t), "%u", i->owner_module); snprintf(k, sizeof(k), "%u", i->client); - printf("*** Sink Input #%u ***\n" + printf(_("*** Sink Input #%u ***\n" "Driver: %s\n" "Owner Module: %s\n" "Client: %s\n" @@ -362,18 +360,18 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info "Buffer Latency: %0.0f usec\n" "Sink Latency: %0.0f usec\n" "Resample method: %s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, pa_strnull(i->driver), - i->owner_module != PA_INVALID_INDEX ? t : "n/a", - i->client != PA_INVALID_INDEX ? k : "n/a", + i->owner_module != PA_INVALID_INDEX ? t : _("n/a"), + i->client != PA_INVALID_INDEX ? k : _("n/a"), i->sink, pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), - i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), + i->mute ? _("muted") : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), (double) i->buffer_usec, (double) i->sink_usec, - i->resample_method ? i->resample_method : "n/a", + i->resample_method ? i->resample_method : _("n/a"), pl = pa_proplist_to_string(i->proplist)); pa_xfree(pl); @@ -384,7 +382,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get source output information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get source output information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -404,7 +402,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu snprintf(t, sizeof(t), "%u", i->owner_module); snprintf(k, sizeof(k), "%u", i->client); - printf("*** Source Output #%u ***\n" + printf(_("*** Source Output #%u ***\n" "Driver: %s\n" "Owner Module: %s\n" "Client: %s\n" @@ -414,17 +412,17 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu "Buffer Latency: %0.0f usec\n" "Source Latency: %0.0f usec\n" "Resample method: %s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, pa_strnull(i->driver), - i->owner_module != PA_INVALID_INDEX ? t : "n/a", - i->client != PA_INVALID_INDEX ? k : "n/a", + i->owner_module != PA_INVALID_INDEX ? t : _("n/a"), + i->client != PA_INVALID_INDEX ? k : _("n/a"), i->source, pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), (double) i->buffer_usec, (double) i->source_usec, - i->resample_method ? i->resample_method : "n/a", + i->resample_method ? i->resample_method : _("n/a"), pl = pa_proplist_to_string(i->proplist)); pa_xfree(pl); @@ -435,7 +433,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int char *pl; if (is_last < 0) { - fprintf(stderr, "Failed to get sample information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get sample information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -454,7 +452,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int pa_bytes_snprint(t, sizeof(t), i->bytes); - printf("*** Sample #%u ***\n" + printf(_("*** Sample #%u ***\n" "Name: %s\n" "Volume: %s\n" "Sample Specification: %s\n" @@ -463,16 +461,16 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int "Size: %s\n" "Lazy: %s\n" "Filename: %s\n" - "Properties:\n%s", + "Properties:\n%s"), i->index, i->name, pa_cvolume_snprint(cv, sizeof(cv), &i->volume), - pa_sample_spec_valid(&i->sample_spec) ? pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec) : "n/a", - pa_sample_spec_valid(&i->sample_spec) ? pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map) : "n/a", + pa_sample_spec_valid(&i->sample_spec) ? pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec) : _("n/a"), + pa_sample_spec_valid(&i->sample_spec) ? pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map) : _("n/a"), (double) i->duration/1000000, t, pa_yes_no(i->lazy), - i->filename ? i->filename : "n/a", + i->filename ? i->filename : _("n/a"), pl = pa_proplist_to_string(i->proplist)); pa_xfree(pl); @@ -480,7 +478,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int static void get_autoload_info_callback(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata) { if (is_last < 0) { - fprintf(stderr, "Failed to get autoload information: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failed to get autoload information: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -496,21 +494,21 @@ static void get_autoload_info_callback(pa_context *c, const pa_autoload_info *i, printf("\n"); nl = 1; - printf("*** Autoload Entry #%u ***\n" + printf(_("*** Autoload Entry #%u ***\n" "Name: %s\n" "Type: %s\n" "Module: %s\n" - "Argument: %s\n", + "Argument: %s\n"), i->index, i->name, - i->type == PA_AUTOLOAD_SINK ? "sink" : "source", + i->type == PA_AUTOLOAD_SINK ? _("sink") : _("source"), i->module, i->argument ? i->argument : ""); } static void simple_callback(pa_context *c, int success, void *userdata) { if (!success) { - fprintf(stderr, "Failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failure: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -520,7 +518,7 @@ static void simple_callback(pa_context *c, int success, void *userdata) { static void index_callback(pa_context *c, uint32_t idx, void *userdata) { if (idx == PA_INVALID_INDEX) { - fprintf(stderr, "Failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failure: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -544,7 +542,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) { case PA_STREAM_FAILED: default: - fprintf(stderr, "Failed to upload sample: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); + fprintf(stderr, _("Failed to upload sample: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s)))); quit(1); } } @@ -557,11 +555,11 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { d = pa_xmalloc(length); assert(sample_length >= length); - l = length/pa_frame_size(&sample_spec); + l = (sf_count_t) (length/pa_frame_size(&sample_spec)); if ((sf_readf_float(sndfile, d, l)) != l) { pa_xfree(d); - fprintf(stderr, "Premature end of file\n"); + fprintf(stderr, _("Premature end of file\n")); quit(1); } @@ -609,8 +607,8 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case EXIT: - pa_operation_unref(pa_context_exit_daemon(c, NULL, NULL)); - drain(); + pa_operation_unref(pa_context_exit_daemon(c, simple_callback, NULL)); + break; case LIST: actions = 8; @@ -665,19 +663,19 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_FAILED: default: - fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); } } static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { - fprintf(stderr, "Got SIGINT, exiting.\n"); + fprintf(stderr, _("Got SIGINT, exiting.\n")); quit(0); } static void help(const char *argv0) { - printf("%s [options] stat\n" + printf(_("%s [options] stat\n" "%s [options] list\n" "%s [options] exit\n" "%s [options] upload-sample FILENAME [NAME]\n" @@ -692,7 +690,7 @@ static void help(const char *argv0) { " -h, --help Show this help\n" " --version Show version\n\n" " -s, --server=SERVER The name of the server to connect to\n" - " -n, --client-name=NAME How to call this client on the server\n", + " -n, --client-name=NAME How to call this client on the server\n"), argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); } @@ -712,6 +710,9 @@ int main(int argc, char *argv[]) { {NULL, 0, NULL, 0} }; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + if (!(bn = strrchr(argv[0], '/'))) bn = argv[0]; else @@ -725,7 +726,12 @@ int main(int argc, char *argv[]) { goto quit; case ARG_VERSION: - printf("pactl "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); + printf(_("pactl %s\n" + "Compiled with libpulse %s\n" + "Linked with libpulse %s\n"), + PACKAGE_VERSION, + pa_get_headers_version(), + pa_get_library_version()); ret = 0; goto quit; @@ -759,7 +765,7 @@ int main(int argc, char *argv[]) { action = UPLOAD_SAMPLE; if (optind+1 >= argc) { - fprintf(stderr, "Please specify a sample file to load\n"); + fprintf(stderr, _("Please specify a sample file to load\n")); goto quit; } @@ -781,19 +787,19 @@ int main(int argc, char *argv[]) { memset(&sfinfo, 0, sizeof(sfinfo)); if (!(sndfile = sf_open(argv[optind+1], SFM_READ, &sfinfo))) { - fprintf(stderr, "Failed to open sound file.\n"); + fprintf(stderr, _("Failed to open sound file.\n")); goto quit; } - sample_spec.format = PA_SAMPLE_FLOAT32; - sample_spec.rate = sfinfo.samplerate; - sample_spec.channels = sfinfo.channels; + sample_spec.format = PA_SAMPLE_FLOAT32; + sample_spec.rate = (uint32_t) sfinfo.samplerate; + sample_spec.channels = (uint8_t) sfinfo.channels; - sample_length = sfinfo.frames*pa_frame_size(&sample_spec); + sample_length = (size_t)sfinfo.frames*pa_frame_size(&sample_spec); } else if (!strcmp(argv[optind], "play-sample")) { action = PLAY_SAMPLE; if (argc != optind+2 && argc != optind+3) { - fprintf(stderr, "You have to specify a sample name to play\n"); + fprintf(stderr, _("You have to specify a sample name to play\n")); goto quit; } @@ -805,7 +811,7 @@ int main(int argc, char *argv[]) { } else if (!strcmp(argv[optind], "remove-sample")) { action = REMOVE_SAMPLE; if (argc != optind+2) { - fprintf(stderr, "You have to specify a sample name to remove\n"); + fprintf(stderr, _("You have to specify a sample name to remove\n")); goto quit; } @@ -813,20 +819,20 @@ int main(int argc, char *argv[]) { } else if (!strcmp(argv[optind], "move-sink-input")) { action = MOVE_SINK_INPUT; if (argc != optind+3) { - fprintf(stderr, "You have to specify a sink input index and a sink\n"); + fprintf(stderr, _("You have to specify a sink input index and a sink\n")); goto quit; } - sink_input_idx = atoi(argv[optind+1]); + sink_input_idx = (uint32_t) atoi(argv[optind+1]); sink_name = pa_xstrdup(argv[optind+2]); } else if (!strcmp(argv[optind], "move-source-output")) { action = MOVE_SOURCE_OUTPUT; if (argc != optind+3) { - fprintf(stderr, "You have to specify a source output index and a source\n"); + fprintf(stderr, _("You have to specify a source output index and a source\n")); goto quit; } - source_output_idx = atoi(argv[optind+1]); + source_output_idx = (uint32_t) atoi(argv[optind+1]); source_name = pa_xstrdup(argv[optind+2]); } else if (!strcmp(argv[optind], "load-module")) { int i; @@ -836,7 +842,7 @@ int main(int argc, char *argv[]) { action = LOAD_MODULE; if (argc <= optind+1) { - fprintf(stderr, "You have to specify a module name and arguments.\n"); + fprintf(stderr, _("You have to specify a module name and arguments.\n")); goto quit; } @@ -846,7 +852,7 @@ int main(int argc, char *argv[]) { n += strlen(argv[i])+1; if (n > 0) { - p = module_args = pa_xnew0(char, n); + p = module_args = pa_xmalloc(n); for (i = optind+2; i < argc; i++) p += sprintf(p, "%s%s", p == module_args ? "" : " ", argv[i]); @@ -856,17 +862,17 @@ int main(int argc, char *argv[]) { action = UNLOAD_MODULE; if (argc != optind+2) { - fprintf(stderr, "You have to specify a module index\n"); + fprintf(stderr, _("You have to specify a module index\n")); goto quit; } - module_index = atoi(argv[optind+1]); + module_index = (uint32_t) atoi(argv[optind+1]); } else if (!strcmp(argv[optind], "suspend-sink")) { action = SUSPEND_SINK; if (argc > optind+3 || optind+1 >= argc) { - fprintf(stderr, "You may not specify more than one sink. You have to specify at least one boolean value.\n"); + fprintf(stderr, _("You may not specify more than one sink. You have to specify at least one boolean value.\n")); goto quit; } @@ -879,7 +885,7 @@ int main(int argc, char *argv[]) { action = SUSPEND_SOURCE; if (argc > optind+3 || optind+1 >= argc) { - fprintf(stderr, "You may not specify more than one source. You have to specify at least one boolean value.\n"); + fprintf(stderr, _("You may not specify more than one source. You have to specify at least one boolean value.\n")); goto quit; } @@ -895,12 +901,12 @@ int main(int argc, char *argv[]) { } if (action == NONE) { - fprintf(stderr, "No valid command specified.\n"); + fprintf(stderr, _("No valid command specified.\n")); goto quit; } if (!(m = pa_mainloop_new())) { - fprintf(stderr, "pa_mainloop_new() failed.\n"); + fprintf(stderr, _("pa_mainloop_new() failed.\n")); goto quit; } @@ -914,7 +920,7 @@ int main(int argc, char *argv[]) { #endif if (!(context = pa_context_new(mainloop_api, client_name))) { - fprintf(stderr, "pa_context_new() failed.\n"); + fprintf(stderr, _("pa_context_new() failed.\n")); goto quit; } @@ -922,7 +928,7 @@ int main(int argc, char *argv[]) { pa_context_connect(context, server, 0, NULL); if (pa_mainloop_run(m, &ret) < 0) { - fprintf(stderr, "pa_mainloop_run() failed.\n"); + fprintf(stderr, _("pa_mainloop_run() failed.\n")); goto quit; } diff --git a/src/utils/padsp.c b/src/utils/padsp.c index d650707e..134a7e58 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -748,7 +748,7 @@ static void fix_metrics(fd_info *i) { /* Number of fragments set? */ if (i->n_fragments < 2) { if (i->fragment_size > 0) { - i->n_fragments = pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size; + i->n_fragments = (unsigned) (pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size); if (i->n_fragments < 2) i->n_fragments = 2; } else @@ -864,7 +864,7 @@ static int fd_info_copy_data(fd_info *i, int force) { return -1; } - if (pa_stream_write(i->play_stream, i->buf, r, free, 0, PA_SEEK_RELATIVE) < 0) { + if (pa_stream_write(i->play_stream, i->buf, (size_t) r, free, 0, PA_SEEK_RELATIVE) < 0) { debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_write(): %s\n", pa_strerror(pa_context_errno(i->context))); return -1; } @@ -872,7 +872,7 @@ static int fd_info_copy_data(fd_info *i, int force) { i->buf = NULL; assert(n >= (size_t) r); - n -= r; + n -= (size_t) r; } if (n >= i->fragment_size) @@ -916,7 +916,7 @@ static int fd_info_copy_data(fd_info *i, int force) { } assert((size_t)r <= len - i->rec_offset); - i->rec_offset += r; + i->rec_offset += (size_t) r; if (i->rec_offset == len) { if (pa_stream_drop(i->rec_stream) < 0) { @@ -927,7 +927,7 @@ static int fd_info_copy_data(fd_info *i, int force) { } assert(n >= (size_t) r); - n -= r; + n -= (size_t) r; } if (n >= i->fragment_size) @@ -998,10 +998,10 @@ static int create_playback_stream(fd_info *i) { pa_stream_set_latency_update_callback(i->play_stream, stream_latency_update_cb, i); memset(&attr, 0, sizeof(attr)); - attr.maxlength = i->fragment_size * (i->n_fragments+1); - attr.tlength = i->fragment_size * i->n_fragments; - attr.prebuf = i->fragment_size; - attr.minreq = i->fragment_size; + attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1)); + attr.tlength = (uint32_t) (i->fragment_size * i->n_fragments); + attr.prebuf = (uint32_t) i->fragment_size; + attr.minreq = (uint32_t) i->fragment_size; flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE; if (i->play_precork) { @@ -1013,9 +1013,9 @@ static int create_playback_stream(fd_info *i) { goto fail; } - n = i->fragment_size; + n = (int) i->fragment_size; setsockopt(i->app_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)); - n = i->fragment_size; + n = (int) i->fragment_size; setsockopt(i->thread_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); return 0; @@ -1042,8 +1042,8 @@ static int create_record_stream(fd_info *i) { pa_stream_set_latency_update_callback(i->rec_stream, stream_latency_update_cb, i); memset(&attr, 0, sizeof(attr)); - attr.maxlength = i->fragment_size * (i->n_fragments+1); - attr.fragsize = i->fragment_size; + attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1)); + attr.fragsize = (uint32_t) i->fragment_size; flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE; if (i->rec_precork) { @@ -1055,9 +1055,9 @@ static int create_record_stream(fd_info *i) { goto fail; } - n = i->fragment_size; + n = (int) i->fragment_size; setsockopt(i->app_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); - n = i->fragment_size; + n = (int) i->fragment_size; setsockopt(i->thread_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)); return 0; @@ -1474,7 +1474,7 @@ int open(const char *filename, int flags, ...) { if (flags & O_CREAT) { va_start(args, flags); if (sizeof(mode_t) < sizeof(int)) - mode = va_arg(args, int); + mode = (mode_t) va_arg(args, int); else mode = va_arg(args, mode_t); va_end(args); @@ -2250,7 +2250,7 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) for (;;) { pa_usec_t usec; - PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, exit_loop); + PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, exit_loop2); if (pa_stream_get_time(i->play_stream, &usec) >= 0) { size_t k = pa_usec_to_bytes(usec, &i->sample_spec); @@ -2272,6 +2272,8 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) pa_threaded_mainloop_wait(i->mainloop); } + exit_loop2: + pa_threaded_mainloop_unlock(i->mainloop); debug(DEBUG_LEVEL_NORMAL, __FILE__": GETOPTR bytes=%i, blocks=%i, ptr=%i\n", info->bytes, info->blocks, info->ptr); diff --git a/src/utils/paplay.c b/src/utils/paplay.c index 1b6228b1..df2edf62 100644 --- a/src/utils/paplay.c +++ b/src/utils/paplay.c @@ -37,10 +37,7 @@ #include <sndfile.h> #include <pulse/pulseaudio.h> - -#if PA_API_VERSION < 9 -#error Invalid PulseAudio API version -#endif +#include <pulse/i18n.h> static pa_context *context = NULL; static pa_stream *stream = NULL; @@ -75,12 +72,12 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) { pa_operation *o; if (!success) { - fprintf(stderr, "Failed to drain stream: %s\n", pa_strerror(pa_context_errno(context))); + fprintf(stderr, _("Failed to drain stream: %s\n"), pa_strerror(pa_context_errno(context))); quit(1); } if (verbose) - fprintf(stderr, "Playback stream drained.\n"); + fprintf(stderr, _("Playback stream drained.\n")); pa_stream_disconnect(stream); pa_stream_unref(stream); @@ -92,7 +89,7 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) { pa_operation_unref(o); if (verbose) - fprintf(stderr, "Draining connection to server.\n"); + fprintf(stderr, _("Draining connection to server.\n")); } } @@ -110,14 +107,14 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { if (readf_function) { size_t k = pa_frame_size(&sample_spec); - if ((bytes = readf_function(sndfile, data, length/k)) > 0) - bytes *= k; + if ((bytes = readf_function(sndfile, data, (sf_count_t) (length/k))) > 0) + bytes *= (sf_count_t) k; } else - bytes = sf_read_raw(sndfile, data, length); + bytes = sf_read_raw(sndfile, data, (sf_count_t) length); if (bytes > 0) - pa_stream_write(s, data, bytes, pa_xfree, 0, PA_SEEK_RELATIVE); + pa_stream_write(s, data, (size_t) bytes, pa_xfree, 0, PA_SEEK_RELATIVE); else pa_xfree(data); @@ -139,12 +136,12 @@ static void stream_state_callback(pa_stream *s, void *userdata) { case PA_STREAM_READY: if (verbose) - fprintf(stderr, "Stream successfully created\n"); + fprintf(stderr, _("Stream successfully created\n")); break; case PA_STREAM_FAILED: default: - fprintf(stderr, "Stream errror: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); + fprintf(stderr, _("Stream errror: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s)))); quit(1); } } @@ -165,7 +162,7 @@ static void context_state_callback(pa_context *c, void *userdata) { assert(c && !stream); if (verbose) - fprintf(stderr, "Connection established.\n"); + fprintf(stderr, _("Connection established.\n")); stream = pa_stream_new(c, stream_name, &sample_spec, channel_map_set ? &channel_map : NULL); assert(stream); @@ -183,7 +180,7 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_FAILED: default: - fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); } } @@ -191,14 +188,14 @@ static void context_state_callback(pa_context *c, void *userdata) { /* UNIX signal to quit recieved */ static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) { if (verbose) - fprintf(stderr, "Got SIGINT, exiting.\n"); + fprintf(stderr, _("Got SIGINT, exiting.\n")); quit(0); } static void help(const char *argv0) { - printf("%s [options] [FILE]\n\n" + printf(_("%s [options] [FILE]\n\n" " -h, --help Show this help\n" " --version Show version\n\n" " -v, --verbose Enable verbose operation\n\n" @@ -207,7 +204,7 @@ static void help(const char *argv0) { " -n, --client-name=NAME How to call this client on the server\n" " --stream-name=NAME How to call this stream on the server\n" " --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n" - " --channel-map=CHANNELMAP Set the channel map to the use\n", + " --channel-map=CHANNELMAP Set the channel map to the use\n"), argv0); } @@ -239,6 +236,7 @@ int main(int argc, char *argv[]) { }; setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); if (!(bn = strrchr(argv[0], '/'))) bn = argv[0]; @@ -254,7 +252,8 @@ int main(int argc, char *argv[]) { goto quit; case ARG_VERSION: - printf("paplay "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); + printf(_("paplay %s\nCompiled with libpulse %s\n" + "Linked with libpulse %s\n"), PACKAGE_VERSION, pa_get_headers_version(), pa_get_library_version()); ret = 0; goto quit; @@ -284,13 +283,13 @@ int main(int argc, char *argv[]) { case ARG_VOLUME: { int v = atoi(optarg); - volume = v < 0 ? 0 : v; + volume = v < 0 ? 0U : (pa_volume_t) v; break; } case ARG_CHANNELMAP: if (!pa_channel_map_parse(&channel_map, optarg)) { - fprintf(stderr, "Invalid channel map\n"); + fprintf(stderr, _("Invalid channel map\n")); goto quit; } @@ -312,12 +311,12 @@ int main(int argc, char *argv[]) { sndfile = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0); if (!sndfile) { - fprintf(stderr, "Failed to open file '%s'\n", filename); + fprintf(stderr, _("Failed to open file '%s'\n"), filename); goto quit; } - sample_spec.rate = sfinfo.samplerate; - sample_spec.channels = sfinfo.channels; + sample_spec.rate = (uint32_t) sfinfo.samplerate; + sample_spec.channels = (uint8_t) sfinfo.channels; readf_function = NULL; @@ -348,7 +347,7 @@ int main(int argc, char *argv[]) { assert(pa_sample_spec_valid(&sample_spec)); if (channel_map_set && channel_map.channels != sample_spec.channels) { - fprintf(stderr, "Channel map doesn't match file.\n"); + fprintf(stderr, _("Channel map doesn't match file.\n")); goto quit; } @@ -374,12 +373,12 @@ int main(int argc, char *argv[]) { if (verbose) { char t[PA_SAMPLE_SPEC_SNPRINT_MAX]; pa_sample_spec_snprint(t, sizeof(t), &sample_spec); - fprintf(stderr, "Using sample spec '%s'\n", t); + fprintf(stderr, _("Using sample spec '%s'\n"), t); } /* Set up a new main loop */ if (!(m = pa_mainloop_new())) { - fprintf(stderr, "pa_mainloop_new() failed.\n"); + fprintf(stderr, _("pa_mainloop_new() failed.\n")); goto quit; } @@ -394,7 +393,7 @@ int main(int argc, char *argv[]) { /* Create a new connection context */ if (!(context = pa_context_new(mainloop_api, client_name))) { - fprintf(stderr, "pa_context_new() failed.\n"); + fprintf(stderr, _("pa_context_new() failed.\n")); goto quit; } @@ -405,7 +404,7 @@ int main(int argc, char *argv[]) { /* Run the main loop */ if (pa_mainloop_run(m, &ret) < 0) { - fprintf(stderr, "pa_mainloop_run() failed.\n"); + fprintf(stderr, _("pa_mainloop_run() failed.\n")); goto quit; } diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index 5b4885db..8a59d5e4 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -35,20 +35,16 @@ #include <stdlib.h> #include <limits.h> #include <getopt.h> - -#include <sndfile.h> +#include <locale.h> #ifdef __linux__ #include <sys/prctl.h> #endif +#include <pulse/i18n.h> #include <pulse/pulseaudio.h> #include <pulsecore/macro.h> -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif - #define BUFSIZE 1024 static pa_context *context = NULL; @@ -82,7 +78,7 @@ static void start_child(void) { if ((child_pid = fork()) < 0) { - fprintf(stderr, "fork(): %s\n", strerror(errno)); + fprintf(stderr, _("fork(): %s\n"), strerror(errno)); quit(1); } else if (child_pid == 0) { @@ -93,7 +89,7 @@ static void start_child(void) { #endif if (execvp(child_argv[0], child_argv) < 0) - fprintf(stderr, "execvp(): %s\n", strerror(errno)); + fprintf(stderr, _("execvp(): %s\n"), strerror(errno)); _exit(1); @@ -110,7 +106,7 @@ static void suspend_complete(pa_context *c, int success, void *userdata) { n++; if (!success) { - fprintf(stderr, "Failure to suspend: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failure to suspend: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -125,7 +121,7 @@ static void resume_complete(pa_context *c, int success, void *userdata) { n++; if (!success) { - fprintf(stderr, "Failure to resume: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Failure to resume: %s\n"), pa_strerror(pa_context_errno(c))); quit(1); return; } @@ -148,7 +144,7 @@ static void context_state_callback(pa_context *c, void *userdata) { pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); } else { - fprintf(stderr, "WARNING: Sound server is not local, not suspending.\n"); + fprintf(stderr, _("WARNING: Sound server is not local, not suspending.\n")); start_child(); } @@ -160,7 +156,7 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_FAILED: default: - fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); + fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c))); pa_context_unref(context); context = NULL; @@ -177,7 +173,7 @@ static void context_state_callback(pa_context *c, void *userdata) { } static void sigint_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { - fprintf(stderr, "Got SIGINT, exiting.\n"); + fprintf(stderr, _("Got SIGINT, exiting.\n")); quit(0); } @@ -195,7 +191,7 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo if (WIFEXITED(status)) child_ret = WEXITSTATUS(status); else if (WIFSIGNALED(status)) { - fprintf(stderr, "WARNING: Child process terminated by signal %u\n", WTERMSIG(status)); + fprintf(stderr, _("WARNING: Child process terminated by signal %u\n"), WTERMSIG(status)); child_ret = 1; } @@ -213,10 +209,10 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo static void help(const char *argv0) { - printf("%s [options] ... \n\n" + printf(_("%s [options] ... \n\n" " -h, --help Show this help\n" " --version Show version\n" - " -s, --server=SERVER The name of the server to connect to\n\n", + " -s, --server=SERVER The name of the server to connect to\n\n"), argv0); } @@ -236,6 +232,9 @@ int main(int argc, char *argv[]) { {NULL, 0, NULL, 0} }; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + if (!(bn = strrchr(argv[0], '/'))) bn = argv[0]; else @@ -249,7 +248,12 @@ int main(int argc, char *argv[]) { goto quit; case ARG_VERSION: - printf("pasuspender "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); + printf(_("pasuspender %s\n" + "Compiled with libpulse %s\n" + "Linked with libpulse %s\n"), + PACKAGE_VERSION, + pa_get_headers_version(), + pa_get_library_version()); ret = 0; goto quit; @@ -273,7 +277,7 @@ int main(int argc, char *argv[]) { } if (!(m = pa_mainloop_new())) { - fprintf(stderr, "pa_mainloop_new() failed.\n"); + fprintf(stderr, _("pa_mainloop_new() failed.\n")); goto quit; } @@ -286,7 +290,7 @@ int main(int argc, char *argv[]) { #endif if (!(context = pa_context_new(mainloop_api, bn))) { - fprintf(stderr, "pa_context_new() failed.\n"); + fprintf(stderr, _("pa_context_new() failed.\n")); goto quit; } @@ -294,7 +298,7 @@ int main(int argc, char *argv[]) { pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL); if (pa_mainloop_run(m, &ret) < 0) { - fprintf(stderr, "pa_mainloop_run() failed.\n"); + fprintf(stderr, _("pa_mainloop_run() failed.\n")); goto quit; } diff --git a/src/utils/pax11publish.c b/src/utils/pax11publish.c index eee7b6a8..50d621d4 100644 --- a/src/utils/pax11publish.c +++ b/src/utils/pax11publish.c @@ -27,11 +27,13 @@ #include <getopt.h> #include <string.h> #include <assert.h> +#include <locale.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <pulse/util.h> +#include <pulse/i18n.h> #include <pulsecore/core-util.h> #include <pulsecore/log.h> @@ -47,17 +49,20 @@ int main(int argc, char *argv[]) { Display *d = NULL; enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); + while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) { switch (c) { case 'D' : dname = optarg; break; case 'h': - printf("%s [-D display] [-S server] [-O sink] [-I source] [-c file] [-d|-e|-i|-r]\n\n" + printf(_("%s [-D display] [-S server] [-O sink] [-I source] [-c file] [-d|-e|-i|-r]\n\n" " -d Show current PulseAudio data attached to X11 display (default)\n" " -e Export local PulseAudio data to X11 display\n" " -i Import PulseAudio data from X11 display to local environment variables and cookie file.\n" - " -r Remove PulseAudio data from X11 display\n", + " -r Remove PulseAudio data from X11 display\n"), pa_path_get_filename(argv[0])); ret = 0; goto finish; @@ -86,13 +91,13 @@ int main(int argc, char *argv[]) { server = optarg; break; default: - fprintf(stderr, "Failed to parse command line.\n"); + fprintf(stderr, _("Failed to parse command line.\n")); goto finish; } } if (!(d = XOpenDisplay(dname))) { - pa_log("XOpenDisplay() failed"); + pa_log(_("XOpenDisplay() failed")); goto finish; } @@ -100,13 +105,13 @@ int main(int argc, char *argv[]) { case DUMP: { char t[1024]; if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t))) - printf("Server: %s\n", t); + printf(_("Server: %s\n"), t); if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t))) - printf("Source: %s\n", t); + printf(_("Source: %s\n"), t); if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t))) - printf("Sink: %s\n", t); + printf(_("Sink: %s\n"), t); if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t))) - printf("Cookie: %s\n", t); + printf(_("Cookie: %s\n"), t); break; } @@ -124,12 +129,12 @@ int main(int argc, char *argv[]) { uint8_t cookie[PA_NATIVE_COOKIE_LENGTH]; size_t l; if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) { - fprintf(stderr, "Failed to parse cookie data\n"); + fprintf(stderr, _("Failed to parse cookie data\n")); goto finish; } if (pa_authkey_save(cookie_file, cookie, l) < 0) { - fprintf(stderr, "Failed to save cookie data\n"); + fprintf(stderr, _("Failed to save cookie data\n")); goto finish; } } @@ -144,12 +149,12 @@ int main(int argc, char *argv[]) { assert(conf); if (pa_client_conf_load(conf, NULL) < 0) { - fprintf(stderr, "Failed to load client configuration file.\n"); + fprintf(stderr, _("Failed to load client configuration file.\n")); goto finish; } if (pa_client_conf_env(conf) < 0) { - fprintf(stderr, "Failed to read environment configuration data.\n"); + fprintf(stderr, _("Failed to read environment configuration data.\n")); goto finish; } @@ -166,7 +171,7 @@ int main(int argc, char *argv[]) { else { char hn[256]; if (!pa_get_fqdn(hn, sizeof(hn))) { - fprintf(stderr, "Failed to get FQDN.\n"); + fprintf(stderr, _("Failed to get FQDN.\n")); goto finish; } @@ -186,7 +191,7 @@ int main(int argc, char *argv[]) { pa_client_conf_free(conf); if (pa_authkey_load_auto(cookie_file, cookie, sizeof(cookie)) < 0) { - fprintf(stderr, "Failed to load cookie data\n"); + fprintf(stderr, _("Failed to load cookie data\n")); goto finish; } @@ -203,7 +208,7 @@ int main(int argc, char *argv[]) { break; default: - fprintf(stderr, "No yet implemented.\n"); + fprintf(stderr, _("Not yet implemented.\n")); goto finish; } |