diff options
65 files changed, 3590 insertions, 854 deletions
diff --git a/Makefile.am b/Makefile.am index 7935321d..2cf93c75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,11 +17,11 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA. -EXTRA_DIST = bootstrap.sh README LICENSE doxygen/Makefile.am doxygen/Makefile.in doxygen/doxygen.conf.in libtool.m4 ltdl.m4 -SUBDIRS=polyp doc libltdl +EXTRA_DIST = bootstrap.sh LICENSE doxygen/Makefile.am doxygen/Makefile.in doxygen/doxygen.conf.in libtool.m4 ltdl.m4 +SUBDIRS=libltdl polyp doc -MAINTAINERCLEANFILES=README -noinst_DATA = README +MAINTAINERCLEANFILES = +noinst_DATA = pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = polyplib.pc polyplib-simple.pc polyplib-error.pc polyplib-mainloop.pc polyplib-browse.pc @@ -36,10 +36,16 @@ pkgconfig_DATA += \ polyplib-glib12-mainloop.pc endif +if USE_LYNX +EXTRA_DIST += README +MAINTAINERCLEANFILES += README +noinst_DATA += README + README: rm -f README $(MAKE) -C doc README cd $(srcdir) && ln -s doc/README README +endif homepage: all dist doxygen test -d $$HOME/homepage/private @@ -49,8 +55,8 @@ homepage: all dist doxygen cp -a doxygen/html/* $$HOME/homepage/private/projects/polypaudio/doxygen cp $$HOME/homepage/private/projects/polypaudio/README.html $$HOME/homepage/private/projects/polypaudio/index.html -distcleancheck: - @: +#distcleancheck: +# @: doxygen: $(MAKE) -C doxygen doxygen diff --git a/acinclude.m4 b/acinclude.m4 index bedf51c3..02f271b4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -197,3 +197,44 @@ else fi AC_LANG_RESTORE ])dnl ACX_PTHREAD + +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1 defined], 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/configure.ac b/configure.ac index 12541345..e5e03d04 100644 --- a/configure.ac +++ b/configure.ac @@ -35,18 +35,60 @@ if type -p stow > /dev/null && test -d /usr/local/stow ; then ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}" fi -# Checks for programs. +#### Checks for programs. #### + +# CC + AC_PROG_CC +AC_PROG_GCC_TRADITIONAL + +# If using GCC specify some additional parameters +if test "x$GCC" = "xyes" ; then + CFLAGS="$CFLAGS -pipe -W -Wall -pedantic" + + AC_LANG_CONFTEST([int main() {}]) + $CC -c conftest.c -std=gnu9x -Wno-unused-parameter $CFLAGS > /dev/null 2> /dev/null && CFLAGS="$CFLAGS -std=gnu9x -Wno-unused-parameter" + rm -f conftest.o +fi + +# M4 + +AC_PATH_PROG([M4], [m4 gm4], [no]) +if test "x$M4" = xno ; then + AC_MSG_ERROR([m4 missing]) +fi + +# LYNX documentation generation +AC_ARG_ENABLE(lynx, + AC_HELP_STRING(--disable-lynx,Turn off lynx usage for documentation generation), +[case "${enableval}" in + yes) lynx=yes ;; + no) lynx=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-lynx) ;; +esac],[lynx=yes]) + +if test x$lynx = xyes ; then + AC_CHECK_PROG(have_lynx, lynx, yes, no) + + if test x$have_lynx = xno ; then + AC_MSG_WARN([*** lynx not found, plain text README will not be built ***]) + fi +fi -# libtool stuff +AM_CONDITIONAL([USE_LYNX], [test "x$have_lynx" = xyes]) + +#### libtool stuff #### + +AC_LTDL_ENABLE_INSTALL AC_LIBLTDL_INSTALLABLE AC_SUBST(LTDLINCL) AC_SUBST(LIBLTDL) AC_LIBTOOL_DLOPEN +AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_CONFIG_SUBDIRS(libltdl) -if test "x$ac_cv_lib_ltdl_lt_dlinit" = "xno" ; then +if test "x$enable_ltdl_install" = "xno" && test "x$ac_cv_lib_ltdl_lt_dlinit" = "xno" ; then AC_MSG_ERROR([[ *** Cannot find the libltdl development files. @@ -54,93 +96,211 @@ if test "x$ac_cv_lib_ltdl_lt_dlinit" = "xno" ; then ]]) fi -# Checks for header files. +#### Determine build environment #### + +os_is_win32=0 + +case "$host_os" in + mingw*) + AC_DEFINE([OS_IS_WIN32], 1, [Build target is Windows.]) + os_is_win32=1 + ;; + esac + +AM_CONDITIONAL(OS_IS_WIN32, test "x$os_is_win32" = "x1") + +################################### +# Basic environment checks # +################################### + +#### Checks for header files. #### + +# ISO AC_HEADER_STDC -AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h syslog.h]) -ACX_PTHREAD -AC_PATH_XTRA +# POSIX +AC_CHECK_HEADERS([arpa/inet.h glob.h grp.h netdb.h netinet/in.h \ + netinet/in_systm.h netinet/ip.h netinet/tcp.h pwd.h sched.h \ + sys/resource.h sys/select.h sys/socket.h sys/wait.h \ + syslog.h]) +AC_CHECK_HEADERS([regex.h], [HAVE_REGEX=1], [HAVE_REGEX=0]) +AC_CHECK_HEADERS([sys/un.h], [HAVE_AF_UNIX=1], [HAVE_AF_UNIX=0]) -HAVE_X11=0 -test "x$no_x" != "xyes" && HAVE_X11=1 -AC_SUBST(HAVE_X11) -AM_CONDITIONAL(HAVE_X11, test "x$no_x" != "xyes") -if test "x$no_x" != "xyes" ; then - AC_DEFINE([HAVE_X11], 1, [Have X11]) -fi +AM_CONDITIONAL(HAVE_REGEX, test "x$HAVE_REGEX" = "x1") +AM_CONDITIONAL(HAVE_AF_UNIX, test "x$HAVE_AF_UNIX" = "x1") + +# XPG4-UNIX +AC_CHECK_HEADERS([sys/poll.h]) + +# Linux +AC_CHECK_HEADERS([linux/input.h], [HAVE_EVDEV=1], [HAVE_EVDEV=0]) + +AM_CONDITIONAL([HAVE_EVDEV], [test "x$HAVE_EVDEV" = "x1"]) + +# Windows +AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) + +# Other +AC_CHECK_HEADERS([sys/ioctl.h]) + +#### Typdefs, structures, etc. #### -# Checks for typedefs, structures, and compiler characteristics. AC_C_CONST +AC_C_BIGENDIAN AC_TYPE_PID_T AC_TYPE_SIZE_T +AC_CHECK_TYPES(ssize_t, , [AC_DEFINE([ssize_t], [signed long], + [Define ssize_t if it is not done by the standard libs.])]) AC_TYPE_OFF_T -AC_HEADER_TIME - -# Checks for library functions. -AC_FUNC_FORK -AC_PROG_GCC_TRADITIONAL -AC_FUNC_LSTAT -AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK -AC_FUNC_MALLOC -AC_FUNC_MEMCMP -AC_FUNC_MMAP -AC_FUNC_REALLOC -AC_FUNC_SETPGRP -AC_FUNC_VPRINTF -AC_FUNC_CLOSEDIR_VOID -AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL AC_TYPE_UID_T -AC_CHECK_FUNCS([gethostname gettimeofday memchr memmove memset mkdir mkfifo munmap rmdir socket strcspn strerror strrchr strspn strstr strtol strtoul strcasecmp putenv strchr strpbrk strdup getgrgid_r getpwuid_r regcomp ftruncate select]) -AC_CHECK_LIB(m, pow) -AC_CHECK_FUNCS(pow) -AC_FUNC_STAT -AC_HEADER_SYS_WAIT -AC_HEADER_DIRENT -AC_C_BIGENDIAN +AC_CHECK_DEFINE([SIGXCPU], [signal.h], [HAVE_SIGXCPU=1], [HAVE_SIGXCPU=0]) +AM_CONDITIONAL(HAVE_SIGXCPU, test "x$HAVE_SIGXCPU" = "x1") + +# Solaris lacks this +AC_CHECK_DEFINE([INADDR_NONE], [netinet/in.h], [], + [AC_DEFINE([INADDR_NONE], [0xffffffff], [Define INADDR_NONE if not found in <netinet/in.h>])]) + +#### Check for libs #### + +# ISO +AC_CHECK_LIB([m], [pow]) + +# POSIX +AC_CHECK_LIB([rt], [sched_setscheduler]) + +# BSD +AC_CHECK_LIB([socket], [connect]) + +# Non-standard + +# This magic is needed so we do not needlessly add static libs to the win32 +# build, disabling its ability to make dlls. +AC_CHECK_FUNCS([getopt_long], [], [AC_CHECK_LIB([iberty], [getopt_long])]) + +#### Check for functions #### + +# POSIX +AC_FUNC_FORK AC_FUNC_GETGROUPS +AC_FUNC_SELECT_ARGTYPES +AC_CHECK_FUNCS([getaddrinfo getgrgid_r getpwuid_r gettimeofday getuid \ + inet_ntop nanosleep setpgid setsid sigaction sleep]) +AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0]) -AC_CHECK_LIB(cap, cap_init, [CAP_LIBS='-lcap'], [CAP_LIBS='']) -AC_SUBST(CAP_LIBS) +AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1") + +# X/OPEN +AC_CHECK_FUNCS([readlink]) + +# SUSv2 +AC_CHECK_FUNCS([ctime_r usleep]) -AC_CHECK_HEADERS(sys/capability.h) +# BSD +AC_CHECK_FUNCS([lstat]) + +# Non-standard AC_CHECK_FUNCS(setresuid) AC_CHECK_FUNCS(setreuid) +#### POSIX threads #### + +ACX_PTHREAD + +################################### +# External libraries # +################################### + +#### X11 (optional) #### + +HAVE_X11=0 + +# The macro tests the host, not the build target +if test "x$os_is_win32" != "x1" ; then + AC_PATH_XTRA + test "x$no_x" != "xyes" && HAVE_X11=1 +fi + +AC_SUBST(HAVE_X11) +AM_CONDITIONAL(HAVE_X11, test "x$HAVE_X11" = "x1") +if test "x$HAVE_X11" = "x1" ; then + AC_DEFINE([HAVE_X11], 1, [Have X11]) +fi + +#### Capabilities (optional) #### + +CAP_LIBS='' + +AC_ARG_WITH( + [caps], + AC_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.])) + +if test "x${with_caps}" != "xno"; then + AC_CHECK_LIB(cap, cap_init, [CAP_LIBS='-lcap'], [CAP_LIBS='']) + AC_CHECK_HEADERS([sys/capability.h]) +fi +AC_SUBST(CAP_LIBS) + +#### Sample rate conversion #### + PKG_CHECK_MODULES(LIBSAMPLERATE, [ samplerate >= 0.1.0 ]) AC_SUBST(LIBSAMPLERATE_CFLAGS) AC_SUBST(LIBSAMPLERATE_LIBS) +#### Sound file #### + PKG_CHECK_MODULES(LIBSNDFILE, [ sndfile >= 1.0.10 ]) AC_SUBST(LIBSNDFILE_CFLAGS) AC_SUBST(LIBSNDFILE_LIBS) +#### OSS support (optional) #### + +AC_CHECK_HEADERS([sys/soundcard.h], [HAVE_OSS=1], [HAVE_OSS=0]) +AC_SUBST(HAVE_OSS) +AM_CONDITIONAL([HAVE_OSS], [test "x$HAVE_OSS" = x1]) + +#### ALSA support (optional) #### + PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.0 ], [HAVE_ALSA=1], [HAVE_ALSA=0]) AC_SUBST(ASOUNDLIB_CFLAGS) AC_SUBST(ASOUNDLIB_LIBS) AC_SUBST(HAVE_ALSA) AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1]) +#### Solaris audio support (optional) #### + +AC_CHECK_HEADERS([sys/audio.h], [HAVE_SOLARIS=1], [HAVE_SOLARIS=0]) +AC_SUBST(HAVE_SOLARIS) +AM_CONDITIONAL([HAVE_SOLARIS], [test "x$HAVE_SOLARIS" = x1]) + +#### GLib 2 support (optional) #### + PKG_CHECK_MODULES(GLIB20, [ glib-2.0 >= 2.4.0 ], HAVE_GLIB20=1, HAVE_GLIB20=0) AC_SUBST(GLIB20_CFLAGS) AC_SUBST(GLIB20_LIBS) AC_SUBST(HAVE_GLIB20) AM_CONDITIONAL([HAVE_GLIB20], [test "x$HAVE_GLIB20" = x1]) +#### GLib 1 support (optional) #### + PKG_CHECK_MODULES(GLIB12, [ glib >= 1.2.0 ], HAVE_GLIB12=1, HAVE_GLIB12=0) AC_SUBST(GLIB12_CFLAGS) AC_SUBST(GLIB12_LIBS) AC_SUBST(HAVE_GLIB12) AM_CONDITIONAL([HAVE_GLIB12], [test "x$HAVE_GLIB12" = x1]) +#### Howl support (optional) #### + PKG_CHECK_MODULES(HOWL, [ howl >= 0.9.8 ], HAVE_HOWL=1, HAVE_HOWL=0) AC_SUBST(HOWL_CFLAGS) AC_SUBST(HOWL_LIBS) AC_SUBST(HAVE_HOWL) AM_CONDITIONAL([HAVE_HOWL], [test "x$HAVE_HOWL" = x1]) +#### Async DNS support (optional) #### + PKG_CHECK_MODULES(LIBASYNCNS, [ libasyncns >= 0.1 ], HAVE_LIBASYNCNS=1, HAVE_LIBASYNCNS=0) AC_SUBST(LIBASYNCNS_CFLAGS) AC_SUBST(LIBASYNCNS_LIBS) @@ -151,70 +311,60 @@ if test "x$HAVE_LIBASYNCNS" != "x0" ; then AC_DEFINE([HAVE_LIBASYNCNS], 1, [Have libasyncns?]) fi -AC_PATH_PROG([M4], [m4 gm4], [no]) -if test "x$M4" = xno ; then - AC_MSG_ERROR([m4 missing]) -fi +#### TCP wrappers (optional) #### -AC_MSG_CHECKING([for tcpwrap library and headers]) -LIBWRAP_LIBS= -saved_LIBS="$LIBS" -LIBS="$LIBS -lwrap" -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)]) +ACX_LIBWRAP AC_SUBST(LIBWRAP_LIBS) -LIBS="$saved_LIBS" -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) +#### LIRC support (optional) #### + +ACX_LIRC AC_SUBST(LIRC_CFLAGS) AC_SUBST(LIRC_LIBS) AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1]) -AC_CHECK_HEADER(linux/input.h,HAVE_EVDEV=1,HAVE_EVDEV=0) -AM_CONDITIONAL([HAVE_EVDEV], [test "x$HAVE_EVDEV" = x1]) - -# If using GCC specify some additional parameters -if test "x$GCC" = "xyes" ; then - CFLAGS="$CFLAGS -pipe -W -Wall -pedantic" - - AC_LANG_CONFTEST([int main() {}]) - $CC -c conftest.c -std=c99 -Wno-unused-parameter $CFLAGS > /dev/null 2> /dev/null && CFLAGS="$CFLAGS -std=c99 -Wno-unused-parameter" - rm -f conftest.o +################################### +# Output # +################################### + +AC_ARG_ENABLE( + [static-bins], + AC_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).]), + [PREOPEN_MODS=$withval], [PREOPEN_MODS="all"]) +AM_CONDITIONAL([PREOPEN_MODS], [test "x$PREOPEN_MODS" != "xall"]) +if test "x$PREOPEN_MODS" != "xall" ; then + tmpLIBS="" + for mod in $PREOPEN_MODS; do + tmpLIBS="$tmpLIBS module-$mod.la" + done + PREOPEN_MODS="$tmpLIBS" + AC_SUBST(PREOPEN_MODS) fi -# LYNX documentation generation -AC_ARG_ENABLE(lynx, - AC_HELP_STRING(--disable-lynx,Turn off lynx usage for documentation generation), -[case "${enableval}" in - yes) lynx=yes ;; - no) lynx=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --disable-lynx) ;; -esac],[lynx=yes]) - -if test x$lynx = xyes ; then - AC_CHECK_PROG(have_lynx, lynx, yes, no) - - if test x$have_lynx = xno ; then - AC_MSG_WARN([*** lynx not found, plain text README will not be built ***]) - fi -fi - -AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes]) - -AM_CONDITIONAL(BUILD_LIBPOLYPCORE, false) - -AC_CONFIG_FILES([Makefile polyp/Makefile polyplib.pc polyplib-simple.pc polyplib-mainloop.pc polyplib-browse.pc polyplib-error.pc polyplib-glib-mainloop.pc polyplib-glib12-mainloop.pc doc/Makefile doc/README.html doc/cli.html doc/daemon.html doc/modules.html doxygen/Makefile doxygen/doxygen.conf polyp/polyplib-version.h doc/FAQ.html]) +AC_CONFIG_FILES([ +Makefile +polyp/Makefile +polyplib.pc +polyplib-simple.pc +polyplib-mainloop.pc +polyplib-browse.pc +polyplib-error.pc +polyplib-glib-mainloop.pc +polyplib-glib12-mainloop.pc +doc/Makefile +doc/README.html +doc/cli.html +doc/daemon.html +doc/modules.html +doxygen/Makefile +doxygen/doxygen.conf +polyp/polyplib-version.h +doc/FAQ.html +]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am index fff06551..c68c00f5 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -16,7 +16,7 @@ # along with polypaudio; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -noinst_DATA = README.html cli.html modules.html daemon.html README +noinst_DATA = README.html cli.html modules.html daemon.html EXTRA_DIST = $(noinst_DATA) style.css README.html.in cli.html.in modules.html.in daemon.html.in todo FAQ.html.in MAINTAINERCLEANFILES = README.html cli.html modules.html daemon.html FAQ.html @@ -26,6 +26,7 @@ if USE_LYNX README: README.html lynx --dump $^ | sed 's,file://localhost/.*/doc/README.html,README,' > $@ +noinst_DATA += README CLEANFILES += README endif diff --git a/polyp/Makefile.am b/polyp/Makefile.am index 389cb0d3..22e8da3d 100644 --- a/polyp/Makefile.am +++ b/polyp/Makefile.am @@ -17,72 +17,483 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA. + +################################### +# Extra directories # +################################### + polypincludedir=$(includedir)/polyp polypconfdir=$(sysconfdir)/polypaudio modlibdir=$(libdir)/polypaudio-@PA_MAJORMINOR@ -AM_CFLAGS=-D_GNU_SOURCE -I$(top_srcdir) $(PTHREAD_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) -AM_CFLAGS+=-DDLSEARCHPATH=\"$(modlibdir)\" -AM_CFLAGS+=-DDEFAULT_CONFIG_DIR=\"$(polypconfdir)\" -AM_CFLAGS+=-DPOLYPAUDIO_BINARY=\"$(bindir)/polypaudio\" +################################### +# Defines # +################################### + +POLYPAUDIO_BINARY=$(bindir)/polypaudio$(EXEEXT) +if OS_IS_WIN32 +DEFAULT_CONFIG_DIR=%POLYP_ROOT% +else +DEFAULT_CONFIG_DIR=$(polypconfdir) +endif + +################################### +# Compiler/linker flags # +################################### + +AM_CFLAGS = -D_GNU_SOURCE -I$(top_srcdir) +AM_CFLAGS += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS +AM_CFLAGS += $(LTDLINCL) +AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) +AM_CFLAGS += -DDLSEARCHPATH=\"$(modlibdir)\" +AM_CFLAGS += -DDEFAULT_CONFIG_DIR=\"$(DEFAULT_CONFIG_DIR)\" +AM_CFLAGS += -DPOLYPAUDIO_BINARY=\"$(POLYPAUDIO_BINARY)\" # This cool debug trap works on i386/gcc only -AM_CFLAGS+='-DDEBUG_TRAP=__asm__("int $$3")' +AM_CFLAGS += '-DDEBUG_TRAP=__asm__("int $$3")' + +AM_LIBADD = $(PTHREAD_LIBS) +AM_LDADD = $(PTHREAD_LIBS) + +# Only required on some platforms but defined for all to avoid errors +AM_LDFLAGS = -no-undefined + +if STATIC_BINS +BINLDFLAGS = -static +endif + +if OS_IS_WIN32 +AM_LDFLAGS+=-Wl,--export-all-symbols +WINSOCK_LIBS=-lwsock32 -lws2_32 -lwininet +endif + +################################### +# Extra files # +################################### + +EXTRA_DIST = \ + client.conf.in \ + daemon.conf.in \ + default.pa.in \ + depmod.py \ + esdcompat.sh.in \ + module-defs.h.m4 + +polypconf_DATA = default.pa daemon.conf client.conf + +BUILT_SOURCES = polyplib-version.h + +################################### +# Main daemon # +################################### + +bin_PROGRAMS = polypaudio + +polypaudio_SOURCES = \ + caps.h caps.c \ + cmdline.c cmdline.h \ + cpulimit.c cpulimit.h \ + conf-parser.h conf-parser.c \ + daemon-conf.c daemon-conf.h \ + dumpmodules.c dumpmodules.h \ + gcc-printf.h \ + main.c \ + pid.c pid.h + +polypaudio_CFLAGS = $(AM_CFLAGS) +polypaudio_CPPFLAGS = $(AM_CPPFLAGS) +polypaudio_LDADD = $(AM_LDADD) libpolypcore.la $(LIBLTDL) \ + $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) +polypaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -dlopen force $(foreach f,$(PREOPEN_LIBS),-dlopen $(f)) + +if PREOPEN_MODS +PREOPEN_LIBS = $(PREOPEN_MODS) +else +PREOPEN_LIBS = $(modlib_LTLIBRARIES) +endif -AM_LIBADD=$(PTHREAD_LIBS) -lm -AM_LDADD=$(PTHREAD_LIBS) -lm +################################### +# Utility programs # +################################### -EXTRA_DIST = default.pa.in daemon.conf.in client.conf.in depmod.py esdcompat.sh.in module-defs.h.m4 -bin_PROGRAMS = \ - polypaudio \ +bin_PROGRAMS += \ pacat \ pactl \ - paplay \ - pacmd + paplay + +if HAVE_AF_UNIX +bin_PROGRAMS += pacmd +endif + +if HAVE_X11 +bin_PROGRAMS += pax11publish +endif + +if HAVE_HOWL +bin_PROGRAMS += pabrowse +endif bin_SCRIPTS = esdcompat.sh +pacat_SOURCES = pacat.c +pacat_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la +pacat_CFLAGS = $(AM_CFLAGS) +pacat_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +paplay_SOURCES = paplay.c +paplay_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS) +paplay_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) +paplay_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +pactl_SOURCES = pactl.c +pactl_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS) +pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) +pactl_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +pacmd_SOURCES = pacmd.c util.c util.h xmalloc.c xmalloc.h log.c log.h pid.c pid.h +pacmd_CFLAGS = $(AM_CFLAGS) +pacmd_LDADD = $(AM_LDADD) +pacmd_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +pax11publish_SOURCES = pax11publish.c util.c util.h xmalloc.c xmalloc.h log.c log.h authkey.c authkey.h client-conf.c client-conf.h conf-parser.c conf-parser.h x11prop.c x11prop.h random.c random.h +pax11publish_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) +pax11publish_LDADD = $(AM_LDADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) +pax11publish_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +pabrowse_SOURCES = pabrowse.c +pabrowse_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-browse-@PA_MAJORMINOR@.la +pabrowse_CFLAGS = $(AM_CFLAGS) +pabrowse_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +################################### +# Test programs # +################################### + noinst_PROGRAMS = \ mainloop-test \ + mcalign-test \ pacat-simple \ parec-simple \ - cpulimit-test \ - cpulimit-test2 \ - voltest \ strlist-test \ - mcalign-test + voltest + +if HAVE_SIGXCPU +noinst_PROGRAMS += \ + cpulimit-test \ + cpulimit-test2 +endif + +if HAVE_GLIB20 +noinst_PROGRAMS += \ + mainloop-test-glib +endif + +if HAVE_GLIB12 +noinst_PROGRAMS += \ + mainloop-test-glib12 +endif + +mainloop_test_SOURCES = mainloop-test.c +mainloop_test_CFLAGS = $(AM_CFLAGS) +mainloop_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-@PA_MAJORMINOR@.la +mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +mcalign_test_SOURCES = mcalign-test.c util.c util.h xmalloc.c xmalloc.h log.c log.h mcalign.c mcalign.h memchunk.c memchunk.h memblock.c memblock.h +mcalign_test_CFLAGS = $(AM_CFLAGS) +mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) +mcalign_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +pacat_simple_SOURCES = pacat-simple.c +pacat_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la +pacat_simple_CFLAGS = $(AM_CFLAGS) +pacat_simple_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +parec_simple_SOURCES = parec-simple.c +parec_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la +parec_simple_CFLAGS = $(AM_CFLAGS) +parec_simple_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +strlist_test_SOURCES = strlist-test.c strlist.c strlist.h strbuf.c strbuf.h util.c util.h xmalloc.c xmalloc.h log.c log.h +strlist_test_CFLAGS = $(AM_CFLAGS) +strlist_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) +strlist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +voltest_SOURCES = voltest.c sample.c +voltest_CFLAGS = $(AM_CFLAGS) +voltest_LDADD = $(AM_LDADD) +voltest_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +cpulimit_test_SOURCES = cpulimit-test.c cpulimit.c util.c log.c cpulimit.h util.h log.h +cpulimit_test_CFLAGS = $(AM_CFLAGS) +cpulimit_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la +cpulimit_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +cpulimit_test2_SOURCES = cpulimit-test.c cpulimit.c util.c log.c cpulimit.h util.h log.h +cpulimit_test2_CFLAGS = $(AM_CFLAGS) -DTEST2 +cpulimit_test2_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la +cpulimit_test2_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +mainloop_test_glib_SOURCES = $(mainloop_test_SOURCES) +mainloop_test_glib_CFLAGS = $(mainloop_test_CFLAGS) $(GLIB20_CFLAGS) -DGLIB_MAIN_LOOP +mainloop_test_glib_LDADD = $(mainloop_test_LDADD) $(GLIB20_LIBS) libpolyp-mainloop-glib-@PA_MAJORMINOR@.la +mainloop_test_glib_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -polypconf_DATA=default.pa daemon.conf client.conf +mainloop_test_glib12_SOURCES = $(mainloop_test_SOURCES) +mainloop_test_glib12_CFLAGS = $(mainloop_test_CFLAGS) $(GLIB12_CFLAGS) -DGLIB_MAIN_LOOP +mainloop_test_glib12_LDADD = $(mainloop_test_LDADD) $(GLIB12_LIBS) libpolyp-mainloop-glib12-@PA_MAJORMINOR@.la +mainloop_test_glib12_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -BUILT_SOURCES=polyplib-version.h +################################### +# Client library # +################################### -polypinclude_HEADERS= \ +polypinclude_HEADERS = \ + cdecl.h \ + glib-mainloop.h \ + mainloop.h \ + mainloop-api.h \ + mainloop-signal.h \ polyplib.h \ + polyplib-context.h \ polyplib-def.h \ - polyplib-simple.h \ polyplib-error.h \ - polyplib-stream.h \ - polyplib-context.h \ polyplib-introspect.h \ - polyplib-subscribe.h \ polyplib-operation.h \ polyplib-scache.h \ + polyplib-simple.h \ + polyplib-stream.h \ + polyplib-subscribe.h \ polyplib-version.h \ - cdecl.h \ - mainloop-api.h \ - mainloop.h \ - mainloop-signal.h \ sample.h \ - glib-mainloop.h \ typeid.h +if HAVE_HOWL +polypinclude_HEADERS += \ + polyplib-browser.h +endif + +lib_LTLIBRARIES = \ + libpolyp-@PA_MAJORMINOR@.la \ + libpolyp-error-@PA_MAJORMINOR@.la \ + libpolyp-mainloop-@PA_MAJORMINOR@.la \ + libpolyp-simple-@PA_MAJORMINOR@.la + +if HAVE_HOWL +lib_LTLIBRARIES += \ + libpolyp-browse-@PA_MAJORMINOR@.la +endif + +if HAVE_GLIB20 +lib_LTLIBRARIES += \ + libpolyp-mainloop-glib-@PA_MAJORMINOR@.la +endif + +if HAVE_GLIB12 +lib_LTLIBRARIES += \ + libpolyp-mainloop-glib12-@PA_MAJORMINOR@.la +endif + +libpolyp_@PA_MAJORMINOR@_la_SOURCES = \ + authkey.c authkey.h \ + cdecl.h \ + client-conf.c client-conf.h \ + conf-parser.c conf-parser.h \ + dllmain.c \ + dynarray.c dynarray.h \ + gcc-printf.h \ + idxset.c idxset.h \ + iochannel.c iochannel.h \ + llist.h \ + log.c log.h \ + mainloop-api.c mainloop-api.h \ + mcalign.c mcalign.h \ + memblock.c memblock.h \ + memchunk.c memchunk.h \ + native-common.h \ + packet.c packet.h \ + parseaddr.c parseaddr.h \ + pdispatch.c pdispatch.h \ + polyplib.h \ + polyplib-context.c polyplib-context.h \ + polyplib-def.h \ + polyplib-internal.h \ + polyplib-introspect.c polyplib-introspect.h \ + polyplib-operation.c polyplib-operation.h \ + polyplib-scache.c polyplib-scache.h \ + polyplib-stream.c polyplib-stream.h \ + polyplib-subscribe.c polyplib-subscribe.h \ + pstream.c pstream.h \ + pstream-util.c pstream-util.h \ + queue.c queue.h \ + random.c random.h \ + sample.c sample.h \ + socket-client.c socket-client.h \ + socket-util.c socket-util.h \ + strbuf.c strbuf.h \ + strlist.c strlist.h \ + tagstruct.c tagstruct.h \ + typeid.c typeid.h \ + util.c util.h \ + winsock.h \ + xmalloc.c xmalloc.h + +if HAVE_X11 +libpolyp_@PA_MAJORMINOR@_la_SOURCES += \ + client-conf-x11.c client-conf-x11.h \ + x11prop.c x11prop.h +endif + +libpolyp_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) +libpolyp_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 +libpolyp_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) + +if HAVE_X11 +libpolyp_@PA_MAJORMINOR@_la_CFLAGS += $(X_CFLAGS) +libpolyp_@PA_MAJORMINOR@_la_LDFLAGS += $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) +endif + +if HAVE_LIBASYNCNS +libpolyp_@PA_MAJORMINOR@_la_CFLAGS += $(LIBASYNCNS_CFLAGS) +libpolyp_@PA_MAJORMINOR@_la_LIBADD += $(LIBASYNCNS_LIBS) +endif + +libpolyp_error_@PA_MAJORMINOR@_la_SOURCES = polyplib-error.c polyplib-error.h +libpolyp_error_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) +libpolyp_error_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la +libpolyp_error_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +libpolyp_mainloop_@PA_MAJORMINOR@_la_SOURCES = \ + mainloop.c mainloop.h \ + mainloop-api.h mainloop-api.c \ + mainloop-signal.c mainloop-signal.h \ + poll.c poll.h +libpolyp_mainloop_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) +libpolyp_mainloop_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la $(WINSOCK_LIBS) +libpolyp_mainloop_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +libpolyp_simple_@PA_MAJORMINOR@_la_SOURCES = polyplib-simple.c polyplib-simple.h +libpolyp_simple_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) +libpolyp_simple_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la +libpolyp_simple_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +libpolyp_browse_@PA_MAJORMINOR@_la_SOURCES = polyplib-browser.c polyplib-browser.h +libpolyp_browse_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) +libpolyp_browse_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la $(HOWL_LIBS) +libpolyp_browse_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_SOURCES = glib-mainloop.h glib-mainloop.c +libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS) +libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-mainloop-@PA_MAJORMINOR@.la $(GLIB20_LIBS) +libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_SOURCES = glib-mainloop.h glib12-mainloop.c +libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(GLIB12_CFLAGS) +libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-mainloop-@PA_MAJORMINOR@.la $(GLIB12_LIBS) +libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 + +################################### +# Daemon core library # +################################### + +polypinclude_HEADERS += \ + cli-command.h \ + client.h \ + core.h \ + dynarray.h \ + endianmacros.h \ + hashmap.h \ + idxset.h \ + iochannel.h \ + memblock.h \ + memblockq.h \ + memchunk.h \ + modargs.h \ + module.h \ + namereg.h \ + queue.h \ + resampler.h \ + sample-util.h \ + sink.h \ + sink-input.h \ + sioman.h \ + socket-server.h \ + socket-client.h \ + socket-util.h \ + source.h \ + source-output.h \ + strbuf.h \ + tokenizer.h \ + tagstruct.h \ + util.h + +lib_LTLIBRARIES += libpolypcore.la + +libpolypcore_la_SOURCES = \ + autoload.c autoload.h \ + cli-command.c cli-command.h \ + cli-text.c cli-text.h \ + client.c client.h \ + core.c core.h \ + dllmain.c \ + dynarray.c dynarray.h \ + endianmacros.h \ + g711.c g711.h \ + hashmap.c hashmap.h \ + idxset.c idxset.h \ + log.c log.h \ + mainloop.c mainloop.h \ + mainloop-api.c mainloop-api.h \ + mainloop-signal.c mainloop-signal.h \ + mcalign.c mcalign.h \ + memblock.c memblock.h \ + memblockq.c memblockq.h \ + memchunk.c memchunk.h \ + modargs.c modargs.h \ + modinfo.c modinfo.h \ + module.c module.h \ + namereg.c namereg.h \ + play-memchunk.c play-memchunk.h \ + poll.c poll.h \ + props.c props.h \ + queue.c queue.h \ + random.c random.h \ + resampler.c resampler.h \ + sample.c sample.h \ + sample-util.c sample-util.h \ + scache.c scache.h \ + sconv.c sconv.h \ + sconv-s16be.c sconv-s16be.h \ + sconv-s16le.c sconv-s16le.h \ + sink.c sink.h \ + sink-input.c sink-input.h \ + sioman.c sioman.h \ + sound-file.c sound-file.h \ + sound-file-stream.c sound-file-stream.h \ + source.c source.h \ + source-output.c source-output.h \ + strbuf.c strbuf.h \ + subscribe.c subscripe.h \ + tokenizer.c tokenizer.h \ + typeid.c typeid.h \ + util.c util.h \ + winsock.h \ + xmalloc.c xmalloc.h + +libpolypcore_la_CPPFLAGS = $(AM_CPPFLAGS) +libpolypcore_la_LDFLAGS = -avoid-version +libpolypcore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) + +################################### +# Plug-in support libraries # +################################### + ### Warning! Due to an obscure bug in libtool/automake it is required ### that the libraries in modlib_LTLIBRARIES are specified in-order, ### i.e. libraries near the end of the list depend on libraries near ### the head, and not the other way! -modlib_LTLIBRARIES= \ +modlib_LTLIBRARIES = \ libsocket-util.la \ libiochannel.la \ libsocket-server.la \ @@ -90,7 +501,6 @@ modlib_LTLIBRARIES= \ libparseaddr.la \ libpacket.la \ libpstream.la \ - liboss-util.la \ libioline.la \ libcli.la \ libprotocol-cli.la \ @@ -103,163 +513,51 @@ modlib_LTLIBRARIES= \ libprotocol-simple.la \ libprotocol-esound.la \ libprotocol-native.la \ - libprotocol-http.la \ - module-cli.la \ - module-cli-protocol-tcp.la \ - module-cli-protocol-tcp6.la \ - module-cli-protocol-unix.la \ - module-pipe-sink.la \ - module-pipe-source.la \ - module-oss.la \ - module-oss-mmap.la \ - module-simple-protocol-tcp.la \ - module-simple-protocol-tcp6.la \ - module-simple-protocol-unix.la \ - module-esound-protocol-tcp.la \ - module-esound-protocol-tcp6.la \ - module-esound-protocol-unix.la \ - module-native-protocol-tcp.la \ - module-native-protocol-tcp6.la \ - module-native-protocol-unix.la \ - module-native-protocol-fd.la \ - module-sine.la \ - module-combine.la \ - module-esound-compat-spawnfd.la \ - module-esound-compat-spawnpid.la \ - module-match.la \ - module-tunnel-sink.la \ - module-tunnel-source.la \ - module-null-sink.la \ - module-esound-sink.la \ - module-http-protocol-tcp.la \ - module-http-protocol-tcp6.la \ - module-http-protocol-unix.la - -SYMDEF_FILES= \ - module-cli-symdef.h \ - module-cli-protocol-tcp-symdef.h \ - module-cli-protocol-tcp6-symdef.h \ - module-cli-protocol-unix-symdef.h \ - module-pipe-sink-symdef.h \ - module-pipe-source-symdef.h \ - module-oss-symdef.h \ - module-oss-mmap-symdef.h \ - module-simple-protocol-tcp-symdef.h \ - module-simple-protocol-tcp6-symdef.h \ - module-simple-protocol-unix-symdef.h \ - module-esound-protocol-tcp-symdef.h \ - module-esound-protocol-tcp6-symdef.h \ - module-esound-protocol-unix-symdef.h \ - module-native-protocol-tcp-symdef.h \ - module-native-protocol-tcp6-symdef.h \ - module-native-protocol-unix-symdef.h \ - module-native-protocol-fd-symdef.h \ - module-sine-symdef.h \ - module-combine-symdef.h \ - module-esound-compat-spawnfd-symdef.h \ - module-esound-compat-spawnpid-symdef.h \ - module-match-symdef.h \ - module-tunnel-sink-symdef.h \ - module-tunnel-source-symdef.h \ - module-null-sink-symdef.h \ - module-esound-sink-symdef.h \ - module-zeroconf-publish-symdef.h \ - module-lirc-symdef.h \ - module-mmkbd-evdev-symdef.h \ - module-http-protocol-tcp-symdef.h \ - module-http-protocol-tcp6-symdef.h \ - module-http-protocol-unix-symdef.h + libprotocol-http.la -EXTRA_DIST+=$(SYMDEF_FILES) -BUILT_SOURCES+=$(SYMDEF_FILES) +if HAVE_X11 +modlib_LTLIBRARIES += \ + libx11wrap.la \ + libx11prop.la +endif -lib_LTLIBRARIES= \ - libpolyp-@PA_MAJORMINOR@.la \ - libpolyp-error-@PA_MAJORMINOR@.la \ - libpolyp-mainloop-@PA_MAJORMINOR@.la \ - libpolyp-simple-@PA_MAJORMINOR@.la +if HAVE_OSS +modlib_LTLIBRARIES += \ + liboss-util.la +endif -polypaudio_SOURCES = idxset.c idxset.h \ - queue.c queue.h \ - strbuf.c strbuf.h \ - main.c \ - mainloop.c mainloop.h \ - memblock.c memblock.h \ - sample.c sample.h \ - sample-util.c sample-util.h \ - memblockq.c memblockq.h \ - client.c client.h \ - core.c core.h \ - source-output.c source-output.h \ - sink-input.c sink-input.h \ - source.c source.h \ - sink.c sink.h \ - module.c module.h \ - mainloop-signal.c mainloop-signal.h \ - mainloop-api.c mainloop-api.h \ - util.c util.h \ - hashmap.c hashmap.h \ - namereg.c namereg.h \ - sconv.c sconv.h \ - resampler.c resampler.h \ - endianmacros.h \ - memchunk.c memchunk.h \ - sconv-s16le.c sconv-s16le.h \ - sconv-s16be.c sconv-s16be.h \ - sioman.c sioman.h \ - modargs.c modargs.h \ - cmdline.c cmdline.h \ - cli-command.c cli-command.h \ - cli-text.c cli-text.h \ - tokenizer.c tokenizer.h \ - dynarray.c dynarray.h \ - scache.c scache.h \ - sound-file.c sound-file.h \ - play-memchunk.c play-memchunk.h \ - autoload.c autoload.h \ - xmalloc.c xmalloc.h \ - subscribe.h subscribe.c \ - sound-file-stream.c sound-file-stream.h \ - cpulimit.c cpulimit.h \ - log.c log.h \ - gcc-printf.h \ - modinfo.c modinfo.h \ - daemon-conf.c daemon-conf.h \ - dumpmodules.c dumpmodules.h \ - conf-parser.h conf-parser.c \ - caps.h caps.c \ - props.h props.c \ - mcalign.c mcalign.h \ - g711.c g711.h \ - pid.c pid.h \ - random.c random.h \ - typeid.c typeid.h +if HAVE_ALSA +modlib_LTLIBRARIES += \ + libalsa-util.la +endif -polypaudio_CFLAGS = $(AM_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) -polypaudio_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -polypaudio_LDADD = $(AM_LDADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) -polypaudio_LDFLAGS= $(AM_LDFLAGS) -export-dynamic -dlopen force -#q-static $(foreach f,$(modlib_LTLIBRARIES),-dlpreopen $(f)) +if HAVE_HOWL +modlib_LTLIBRARIES += \ + libhowl-wrap.la +endif libprotocol_simple_la_SOURCES = protocol-simple.c protocol-simple.h libprotocol_simple_la_LDFLAGS = -avoid-version -libprotocol_simple_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la +libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpolypcore.la libsocket-server.la libiochannel.la -libsocket_server_la_SOURCES = socket-server.c socket-server.h +libsocket_server_la_SOURCES = \ + inet_ntop.c inet_ntop.h \ + socket-server.c socket-server.h libsocket_server_la_LDFLAGS = -avoid-version -libsocket_server_la_LIBADD = $(AM_LIBADD) libiochannel.la libsocket-util.la $(LIBWRAP_LIBS) +libsocket_server_la_LIBADD = $(AM_LIBADD) libpolypcore.la libiochannel.la libsocket-util.la $(LIBWRAP_LIBS) $(WINSOCK_LIBS) libsocket_client_la_SOURCES = socket-client.c socket-client.h libsocket_client_la_LDFLAGS = -avoid-version -libsocket_client_la_LIBADD = $(AM_LIBADD) libiochannel.la libsocket-util.la libparseaddr.la $(LIBASYNCNS_LIBS) +libsocket_client_la_LIBADD = $(AM_LIBADD) libpolypcore.la libiochannel.la libsocket-util.la libparseaddr.la $(LIBASYNCNS_LIBS) $(WINSOCK_LIBS) libsocket_client_la_CFLAGS = $(AM_CFLAGS) $(LIBASYNCNS_CFLAGS) libparseaddr_la_SOURCES = parseaddr.c parseaddr.h libparseaddr_la_LDFLAGS = -avoid-version +libparseaddr_la_LIBADD = $(AM_LIBADD) libpolypcore.la libpstream_la_SOURCES = pstream.c pstream.h libpstream_la_LDFLAGS = -avoid-version -libpstream_la_LIBADD = $(AM_LIBADD) libpacket.la libiochannel.la +libpstream_la_LIBADD = $(AM_LIBADD) libpolypcore.la libpacket.la libiochannel.la $(WINSOCK_LIBS) libpstream_util_la_SOURCES = pstream-util.c pstream-util.h libpstream_util_la_LDFLAGS = -avoid-version @@ -267,326 +565,380 @@ libpstream_util_la_LIBADD = $(AM_LIBADD) libpacket.la libpstream.la libtagstruct libpdispatch_la_SOURCES = pdispatch.c pdispatch.h libpdispatch_la_LDFLAGS = -avoid-version -libpdispatch_la_LIBADD = $(AM_LIBADD) libtagstruct.la +libpdispatch_la_LIBADD = $(AM_LIBADD) libtagstruct.la libpolypcore.la libiochannel_la_SOURCES = iochannel.c iochannel.h libiochannel_la_LDFLAGS = -avoid-version -libiochannel_la_LIBADD = $(AM_LIBADD) libsocket-util.la +libiochannel_la_LIBADD = $(AM_LIBADD) libsocket-util.la libpolypcore.la $(WINSOCK_LIBS) libpacket_la_SOURCES = packet.c packet.h libpacket_la_LDFLAGS = -avoid-version - -liboss_util_la_SOURCES = oss-util.c oss-util.h -liboss_util_la_LDFLAGS = -avoid-version +libpacket_la_LIBADD = $(AM_LIBADD) libpolypcore.la libioline_la_SOURCES = ioline.c ioline.h libioline_la_LDFLAGS = -avoid-version -libioline_la_LIBADD = $(AM_LIBADD) libiochannel.la +libioline_la_LIBADD = $(AM_LIBADD) libiochannel.la libpolypcore.la libcli_la_SOURCES = cli.c cli.h +libcli_la_CPPFLAGS = $(AM_CPPFLAGS) libcli_la_LDFLAGS = -avoid-version -libcli_la_LIBADD = $(AM_LIBADD) libiochannel.la libioline.la +libcli_la_LIBADD = $(AM_LIBADD) libiochannel.la libioline.la libpolypcore.la libstrlist_la_SOURCES = strlist.c strlist.h libstrlist_la_LDFLAGS = -avoid-version -libstrlist_la_LIBADD = $(AM_LIBADD) +libstrlist_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol_cli_la_SOURCES = protocol-cli.c protocol-cli.h libprotocol_cli_la_LDFLAGS = -avoid-version -libprotocol_cli_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libcli.la +libprotocol_cli_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libcli.la libpolypcore.la libprotocol_http_la_SOURCES = protocol-http.c protocol-http.h libprotocol_http_la_LDFLAGS = -avoid-version -libprotocol_http_la_LIBADD = $(AM_LIBADD) libsocket-server.la libioline.la +libprotocol_http_la_LIBADD = $(AM_LIBADD) libsocket-server.la libioline.la libpolypcore.la libiochannel.la libprotocol_native_la_SOURCES = protocol-native.c protocol-native.h native-common.h libprotocol_native_la_LDFLAGS = -avoid-version -libprotocol_native_la_LIBADD = $(AM_LIBADD) libsocket-server.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libstrlist.la +libprotocol_native_la_LIBADD = $(AM_LIBADD) libsocket-server.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libstrlist.la libpolypcore.la libiochannel.la libtagstruct_la_SOURCES = tagstruct.c tagstruct.h libtagstruct_la_LDFLAGS = -avoid-version +libtagstruct_la_LIBADD = $(AM_LIBADD) libpolypcore.la $(WINSOCK_LIBS) libprotocol_esound_la_SOURCES = protocol-esound.c protocol-esound.h esound.h libprotocol_esound_la_LDFLAGS = -avoid-version -libprotocol_esound_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libauthkey.la +libprotocol_esound_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libauthkey.la libpolypcore.la libauthkey_la_SOURCES = authkey.c authkey.h libauthkey_la_LDFLAGS = -avoid-version +libauthkey_la_LIBADD = $(AM_LIBADD) libpolypcore.la libauthkey_prop_la_SOURCES = authkey-prop.c authkey-prop.h libauthkey_prop_la_LDFLAGS = -avoid-version +libauthkey_prop_la_LIBADD = $(AM_LIBADD) libpolypcore.la libsocket_util_la_SOURCES = socket-util.c socket-util.h libsocket_util_la_LDFLAGS = -avoid-version +libsocket_util_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) + +# X11 + +libx11wrap_la_SOURCES = x11wrap.c x11wrap.h +libx11wrap_la_LDFLAGS = -avoid-version +libx11wrap_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) +libx11wrap_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) + +libx11prop_la_SOURCES = x11prop.c x11prop.h +libx11prop_la_LDFLAGS = -avoid-version +libx11prop_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) +libx11prop_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) + +# OSS + +liboss_util_la_SOURCES = oss-util.c oss-util.h +liboss_util_la_LDFLAGS = -avoid-version + +# ALSA + +libalsa_util_la_SOURCES = alsa-util.c alsa-util.h +libalsa_util_la_LDFLAGS = -avoid-version +libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) +libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) + +# HOWL + +libhowl_wrap_la_SOURCES = howl-wrap.c howl-wrap.h +libhowl_wrap_la_LDFLAGS = -avoid-version +libhowl_wrap_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) +libhowl_wrap_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) + +################################### +# Plug-in libraries # +################################### + +modlib_LTLIBRARIES += \ + module-cli.la \ + module-cli-protocol-tcp.la \ + module-cli-protocol-tcp6.la \ + module-simple-protocol-tcp.la \ + module-simple-protocol-tcp6.la \ + module-esound-protocol-tcp.la \ + module-esound-protocol-tcp6.la \ + module-native-protocol-tcp.la \ + module-native-protocol-tcp6.la \ + module-native-protocol-fd.la \ + module-sine.la \ + module-combine.la \ + module-tunnel-sink.la \ + module-tunnel-source.la \ + module-null-sink.la \ + module-esound-sink.la \ + module-http-protocol-tcp.la \ + module-http-protocol-tcp6.la + +if HAVE_AF_UNIX +modlib_LTLIBRARIES += \ + module-cli-protocol-unix.la \ + module-simple-protocol-unix.la \ + module-esound-protocol-unix.la \ + module-native-protocol-unix.la \ + module-http-protocol-unix.la +endif + +if HAVE_MKFIFO +modlib_LTLIBRARIES += \ + module-pipe-sink.la \ + module-pipe-source.la +endif + +if !OS_IS_WIN32 +modlib_LTLIBRARIES += \ + module-esound-compat-spawnfd.la \ + module-esound-compat-spawnpid.la +endif + +if HAVE_REGEX +modlib_LTLIBRARIES += \ + module-match.la +endif + +if HAVE_X11 +modlib_LTLIBRARIES += \ + module-x11-bell.la \ + module-x11-publish.la +endif + +if HAVE_OSS +modlib_LTLIBRARIES += \ + module-oss.la \ + module-oss-mmap.la +endif + +if HAVE_ALSA +modlib_LTLIBRARIES += \ + module-alsa-sink.la \ + module-alsa-source.la +endif + +if HAVE_SOLARIS +modlib_LTLIBRARIES += \ + module-solaris.la +endif + +if HAVE_HOWL +modlib_LTLIBRARIES += \ + module-zeroconf-publish.la +endif + +if HAVE_LIRC +modlib_LTLIBRARIES += \ + module-lirc.la +endif + +if HAVE_EVDEV +modlib_LTLIBRARIES += \ + module-mmkbd-evdev.la +endif + +if OS_IS_WIN32 +modlib_LTLIBRARIES += \ + module-waveout.la +endif + +# These are generated by a M4 script + +SYMDEF_FILES = \ + module-cli-symdef.h \ + module-cli-protocol-tcp-symdef.h \ + module-cli-protocol-tcp6-symdef.h \ + module-cli-protocol-unix-symdef.h \ + module-pipe-sink-symdef.h \ + module-pipe-source-symdef.h \ + module-simple-protocol-tcp-symdef.h \ + module-simple-protocol-tcp6-symdef.h \ + module-simple-protocol-unix-symdef.h \ + module-esound-protocol-tcp-symdef.h \ + module-esound-protocol-tcp6-symdef.h \ + module-esound-protocol-unix-symdef.h \ + module-native-protocol-tcp-symdef.h \ + module-native-protocol-tcp6-symdef.h \ + module-native-protocol-unix-symdef.h \ + module-native-protocol-fd-symdef.h \ + module-sine-symdef.h \ + module-combine-symdef.h \ + module-esound-compat-spawnfd-symdef.h \ + module-esound-compat-spawnpid-symdef.h \ + module-match-symdef.h \ + module-tunnel-sink-symdef.h \ + module-tunnel-source-symdef.h \ + module-null-sink-symdef.h \ + module-esound-sink-symdef.h \ + module-zeroconf-publish-symdef.h \ + module-lirc-symdef.h \ + module-mmkbd-evdev-symdef.h \ + module-http-protocol-tcp-symdef.h \ + module-http-protocol-tcp6-symdef.h \ + module-http-protocol-unix-symdef.h \ + module-x11-bell-symdef.h \ + module-x11-publish-symdef.h \ + module-oss-symdef.h \ + module-oss-mmap-symdef.h \ + module-alsa-sink-symdef.h \ + module-alsa-source-symdef.h \ + module-solaris-symdef.h \ + module-waveout-symdef.h + +EXTRA_DIST += $(SYMDEF_FILES) +BUILT_SOURCES += $(SYMDEF_FILES) + +$(SYMDEF_FILES): module-defs.h.m4 + $(M4) -Dfname="$@" $< > $@ + +# Simple protocol module_simple_protocol_tcp_la_SOURCES = module-protocol-stub.c module_simple_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS) module_simple_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libprotocol-simple.la libsocket-server.la +module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-simple.la libsocket-server.la module_simple_protocol_tcp6_la_SOURCES = module-protocol-stub.c module_simple_protocol_tcp6_la_CFLAGS = -DUSE_TCP6_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS) module_simple_protocol_tcp6_la_LDFLAGS = -module -avoid-version -module_simple_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libprotocol-simple.la libsocket-server.la +module_simple_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-simple.la libsocket-server.la module_simple_protocol_unix_la_SOURCES = module-protocol-stub.c module_simple_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS) module_simple_protocol_unix_la_LDFLAGS = -module -avoid-version -module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libprotocol-simple.la libsocket-server.la libsocket-util.la +module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-simple.la libsocket-server.la libsocket-util.la + +# CLI protocol + +module_cli_la_SOURCES = module-cli.c +module_cli_la_LDFLAGS = -module -avoid-version +module_cli_la_LIBADD = $(AM_LIBADD) libcli.la libiochannel.la libpolypcore.la module_cli_protocol_tcp_la_SOURCES = module-protocol-stub.c module_cli_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS) module_cli_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_cli_protocol_tcp_la_LIBADD = $(AM_LIBADD) libprotocol-cli.la libsocket-server.la +module_cli_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-cli.la libsocket-server.la module_cli_protocol_tcp6_la_SOURCES = module-protocol-stub.c module_cli_protocol_tcp6_la_CFLAGS = -DUSE_TCP6_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS) module_cli_protocol_tcp6_la_LDFLAGS = -module -avoid-version -module_cli_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libprotocol-cli.la libsocket-server.la +module_cli_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-cli.la libsocket-server.la module_cli_protocol_unix_la_SOURCES = module-protocol-stub.c module_cli_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS) module_cli_protocol_unix_la_LDFLAGS = -module -avoid-version -module_cli_protocol_unix_la_LIBADD = $(AM_LIBADD) libprotocol-cli.la libsocket-server.la libsocket-util.la +module_cli_protocol_unix_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-cli.la libsocket-server.la libsocket-util.la + +# HTTP protocol module_http_protocol_tcp_la_SOURCES = module-protocol-stub.c module_http_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS) module_http_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_http_protocol_tcp_la_LIBADD = $(AM_LIBADD) libprotocol-http.la libsocket-server.la +module_http_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-http.la libsocket-server.la module_http_protocol_tcp6_la_SOURCES = module-protocol-stub.c module_http_protocol_tcp6_la_CFLAGS = -DUSE_TCP6_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS) module_http_protocol_tcp6_la_LDFLAGS = -module -avoid-version -module_http_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libprotocol-http.la libsocket-server.la +module_http_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-http.la libsocket-server.la module_http_protocol_unix_la_SOURCES = module-protocol-stub.c module_http_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS) module_http_protocol_unix_la_LDFLAGS = -module -avoid-version -module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libprotocol-http.la libsocket-server.la libsocket-util.la +module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-http.la libsocket-server.la libsocket-util.la + +# Native protocol module_native_protocol_tcp_la_SOURCES = module-protocol-stub.c module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libsocket-server.la +module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-native.la libsocket-server.la module_native_protocol_tcp6_la_SOURCES = module-protocol-stub.c module_native_protocol_tcp6_la_CFLAGS = -DUSE_TCP6_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) module_native_protocol_tcp6_la_LDFLAGS = -module -avoid-version -module_native_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libsocket-server.la +module_native_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-native.la libsocket-server.la module_native_protocol_unix_la_SOURCES = module-protocol-stub.c module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) module_native_protocol_unix_la_LDFLAGS = -module -avoid-version -module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libsocket-server.la libsocket-util.la +module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-native.la libsocket-server.la libsocket-util.la module_native_protocol_fd_la_SOURCES = module-native-protocol-fd.c module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS) module_native_protocol_fd_la_LDFLAGS = -module -avoid-version -module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libsocket-server.la libsocket-util.la +module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la + +# EsounD protocol module_esound_protocol_tcp_la_SOURCES = module-protocol-stub.c module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libprotocol-esound.la libsocket-server.la +module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-esound.la libsocket-server.la module_esound_protocol_tcp6_la_SOURCES = module-protocol-stub.c module_esound_protocol_tcp6_la_CFLAGS = -DUSE_TCP6_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) module_esound_protocol_tcp6_la_LDFLAGS = -module -avoid-version -module_esound_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libprotocol-esound.la libsocket-server.la +module_esound_protocol_tcp6_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-esound.la libsocket-server.la module_esound_protocol_unix_la_SOURCES = module-protocol-stub.c module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version -module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libprotocol-esound.la libsocket-server.la libsocket-util.la +module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpolypcore.la libprotocol-esound.la libsocket-server.la libsocket-util.la + +module_esound_compat_spawnfd_la_SOURCES = module-esound-compat-spawnfd.c +module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version +module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpolypcore.la + +module_esound_compat_spawnpid_la_SOURCES = module-esound-compat-spawnpid.c +module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version +module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpolypcore.la + +module_esound_sink_la_SOURCES = module-esound-sink.c +module_esound_sink_la_LDFLAGS = -module -avoid-version +module_esound_sink_la_LIBADD = $(AM_LIBADD) libpolypcore.la libiochannel.la libsocket-client.la libauthkey.la + +# Pipes module_pipe_sink_la_SOURCES = module-pipe-sink.c module_pipe_sink_la_LDFLAGS = -module -avoid-version -module_pipe_sink_la_LIBADD = $(AM_LIBADD) libiochannel.la +module_pipe_sink_la_LIBADD = $(AM_LIBADD) libpolypcore.la libiochannel.la module_pipe_source_la_SOURCES = module-pipe-source.c module_pipe_source_la_LDFLAGS = -module -avoid-version -module_pipe_source_la_LIBADD = $(AM_LIBADD) libiochannel.la - -module_oss_la_SOURCES = module-oss.c -module_oss_la_LDFLAGS = -module -avoid-version -module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la +module_pipe_source_la_LIBADD = $(AM_LIBADD) libpolypcore.la libiochannel.la -module_oss_mmap_la_SOURCES = module-oss-mmap.c -module_oss_mmap_la_LDFLAGS = -module -avoid-version -module_oss_mmap_la_LIBADD = $(AM_LIBADD) liboss-util.la - -module_cli_la_SOURCES = module-cli.c -module_cli_la_LDFLAGS = -module -avoid-version -module_cli_la_LIBADD = $(AM_LIBADD) libcli.la libiochannel.la +# Fake sources/sinks module_sine_la_SOURCES = module-sine.c module_sine_la_LDFLAGS = -module -avoid-version -module_sine_la_LIBADD = $(AM_LIBADD) - -module_combine_la_SOURCES = module-combine.c -module_combine_la_LDFLAGS = -module -avoid-version -module_combine_la_LIBADD = $(AM_LIBADD) +module_sine_la_LIBADD = $(AM_LIBADD) libpolypcore.la module_null_sink_la_SOURCES = module-null-sink.c module_null_sink_la_LDFLAGS = -module -avoid-version -module_null_sink_la_LIBADD = $(AM_LIBADD) +module_null_sink_la_LIBADD = $(AM_LIBADD) libpolypcore.la + +# Couplings + +module_combine_la_SOURCES = module-combine.c +module_combine_la_LDFLAGS = -module -avoid-version +module_combine_la_LIBADD = $(AM_LIBADD) libpolypcore.la module_match_la_SOURCES = module-match.c module_match_la_LDFLAGS = -module -avoid-version -module_match_la_LIBADD = $(AM_LIBADD) +module_match_la_LIBADD = $(AM_LIBADD) libpolypcore.la module_tunnel_sink_la_SOURCES = module-tunnel.c module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS) module_tunnel_sink_la_LDFLAGS = -module -avoid-version -module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la +module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpolypcore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la module_tunnel_source_la_SOURCES = module-tunnel.c module_tunnel_source_la_LDFLAGS = -module -avoid-version -module_tunnel_source_la_LIBADD = $(AM_LIBADD) libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la - -module_esound_compat_spawnfd_la_SOURCES = module-esound-compat-spawnfd.c -module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version -module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) - -module_esound_compat_spawnpid_la_SOURCES = module-esound-compat-spawnpid.c -module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version -module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) - -module_esound_sink_la_SOURCES = module-esound-sink.c -module_esound_sink_la_LDFLAGS = -module -avoid-version -module_esound_sink_la_LIBADD = $(AM_LIBADD) libsocket-client.la libauthkey.la - -libpolyp_@PA_MAJORMINOR@_la_SOURCES = polyplib.h \ - polyplib-def.h \ - tagstruct.c tagstruct.h \ - iochannel.c iochannel.h \ - pstream.c pstream.h \ - pstream-util.c pstream-util.h \ - pdispatch.c pdispatch.h \ - mainloop-api.c mainloop-api.h \ - idxset.c idxset.h \ - util.c util.h \ - memblock.c memblock.h \ - socket-client.c socket-client.h \ - parseaddr.c parseaddr.h \ - packet.c packet.h \ - queue.c queue.h \ - dynarray.c dynarray.h \ - memchunk.c memchunk.h \ - authkey.c authkey.h \ - socket-util.c socket-util.h \ - native-common.h \ - sample.c sample.h \ - xmalloc.c xmalloc.h \ - polyplib-operation.c polyplib-operation.h \ - polyplib-context.c polyplib-context.h \ - polyplib-stream.c polyplib-stream.h \ - polyplib-introspect.c polyplib-introspect.h \ - polyplib-scache.c polyplib-scache.h \ - polyplib-subscribe.c polyplib-subscribe.h \ - polyplib-internal.h \ - cdecl.h \ - llist.h \ - log.c log.h \ - gcc-printf.h \ - client-conf.c client-conf.h \ - conf-parser.c conf-parser.h \ - strlist.c strlist.h \ - strbuf.c strbuf.h \ - mcalign.c mcalign.h \ - typeid.c typeid.h \ - random.c random.h - -libpolyp_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) -libpolyp_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 -libpolyp_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) - -libpolyp_mainloop_@PA_MAJORMINOR@_la_SOURCES = mainloop-api.h mainloop-api.c \ - mainloop.c mainloop.h \ - mainloop-signal.c mainloop-signal.h -libpolyp_mainloop_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) -libpolyp_mainloop_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la -libpolyp_mainloop_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -libpolyp_error_@PA_MAJORMINOR@_la_SOURCES = polyplib-error.c polyplib-error.h -libpolyp_error_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) -libpolyp_error_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la -libpolyp_error_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -libpolyp_simple_@PA_MAJORMINOR@_la_SOURCES = polyplib-simple.c polyplib-simple.h -libpolyp_simple_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) -libpolyp_simple_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la -libpolyp_simple_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -pacat_SOURCES = pacat.c -pacat_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la -pacat_CFLAGS = $(AM_CFLAGS) - -paplay_SOURCES = paplay.c -paplay_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS) -paplay_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) - -pactl_SOURCES = pactl.c -pactl_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS) -pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) - -pacat_simple_SOURCES = pacat-simple.c -pacat_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la -pacat_simple_CFLAGS = $(AM_CFLAGS) - -parec_simple_SOURCES = parec-simple.c -parec_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la -parec_simple_CFLAGS = $(AM_CFLAGS) - -mainloop_test_SOURCES = mainloop-test.c -mainloop_test_CFLAGS = $(AM_CFLAGS) -mainloop_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-@PA_MAJORMINOR@.la - -voltest_SOURCES = voltest.c sample.c -voltest_CFLAGS = $(AM_CFLAGS) -voltest_LDADD = $(AM_LDADD) - -strlist_test_SOURCES = strlist-test.c strlist.c strlist.h strbuf.c strbuf.h util.c util.h xmalloc.c xmalloc.h log.c log.h -strlist_test_CFLAGS = $(AM_CFLAGS) -strlist_test_LDADD = $(AM_LDADD) - -mcalign_test_SOURCES = mcalign-test.c util.c util.h xmalloc.c xmalloc.h log.c log.h mcalign.c mcalign.h memchunk.c memchunk.h memblock.c memblock.h -mcalign_test_CFLAGS = $(AM_CFLAGS) -mcalign_test_LDADD = $(AM_LDADD) +module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpolypcore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la -pacmd_SOURCES = pacmd.c util.c util.h xmalloc.c xmalloc.h log.c log.h pid.c pid.h -pacmd_CFLAGS = $(AM_CFLAGS) -pacmd_LDADD = $(AM_LDADD) - -cpulimit_test_SOURCES = cpulimit-test.c cpulimit.c util.c log.c cpulimit.h util.h log.h -cpulimit_test_CFLAGS = $(AM_CFLAGS) -cpulimit_test_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la - -cpulimit_test2_SOURCES = cpulimit-test.c cpulimit.c util.c log.c cpulimit.h util.h log.h -cpulimit_test2_CFLAGS = $(AM_CFLAGS) -DTEST2 -cpulimit_test2_LDADD = $(AM_LDADD) libpolyp-mainloop-@PA_MAJORMINOR@.la - -### X11 stuff - -if HAVE_X11 -modlib_LTLIBRARIES+= \ - libx11wrap.la \ - libx11prop.la \ - module-x11-bell.la \ - module-x11-publish.la -SYMDEF_FILES += \ - module-x11-bell-symdef.h \ - module-x11-publish-symdef.h - -libx11wrap_la_SOURCES = x11wrap.c x11wrap.h -libx11wrap_la_LDFLAGS = -avoid-version -libx11wrap_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) -libx11wrap_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) - -libx11prop_la_SOURCES = x11prop.c x11prop.h -libx11prop_la_LDFLAGS = -avoid-version -libx11prop_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) -libx11prop_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) +# X11 module_x11_bell_la_SOURCES = module-x11-bell.c module_x11_bell_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) @@ -598,41 +950,17 @@ module_x11_publish_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) module_x11_publish_la_LDFLAGS = -module -avoid-version module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libauthkey.la libauthkey-prop.la libx11prop.la libstrlist.la -bin_PROGRAMS+= \ - pax11publish +# OSS -pax11publish_SOURCES = pax11publish.c util.c util.h xmalloc.c xmalloc.h log.c log.h authkey.c authkey.h client-conf.c client-conf.h conf-parser.c conf-parser.h x11prop.c x11prop.h random.c random.h -pax11publish_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) -pax11publish_LDADD = $(AM_LDADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) - -libpolyp_@PA_MAJORMINOR@_la_CFLAGS += $(X_CFLAGS) -libpolyp_@PA_MAJORMINOR@_la_LDFLAGS += $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) -libpolyp_@PA_MAJORMINOR@_la_SOURCES += x11prop.c x11prop.h client-conf-x11.c client-conf-x11.h - -endif - -### libasyncns stuff - -if HAVE_LIBASYNCNS -libpolyp_@PA_MAJORMINOR@_la_CFLAGS += $(LIBASYNCNS_CFLAGS) -libpolyp_@PA_MAJORMINOR@_la_LIBADD += $(LIBASYNCNS_LIBS) -endif - -### ALSA modules +module_oss_la_SOURCES = module-oss.c +module_oss_la_LDFLAGS = -module -avoid-version +module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la -if HAVE_ALSA -modlib_LTLIBRARIES+= \ - libalsa-util.la \ - module-alsa-sink.la \ - module-alsa-source.la -SYMDEF_FILES += \ - module-alsa-sink-symdef.h \ - module-alsa-source-symdef.h +module_oss_mmap_la_SOURCES = module-oss-mmap.c +module_oss_mmap_la_LDFLAGS = -module -avoid-version +module_oss_mmap_la_LIBADD = $(AM_LIBADD) liboss-util.la -libalsa_util_la_SOURCES = alsa-util.c alsa-util.h -libalsa_util_la_LDFLAGS = -avoid-version -libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) -libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +# ALSA module_alsa_sink_la_SOURCES = module-alsa-sink.c module_alsa_sink_la_LDFLAGS = -module -avoid-version @@ -643,184 +971,44 @@ module_alsa_source_la_SOURCES = module-alsa-source.c module_alsa_source_la_LDFLAGS = -module -avoid-version module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -endif -### HOWL modules -if HAVE_HOWL -modlib_LTLIBRARIES+= \ - libhowl-wrap.la \ - module-zeroconf-publish.la +# Solaris -libhowl_wrap_la_SOURCES = howl-wrap.c howl-wrap.h -libhowl_wrap_la_LDFLAGS = -avoid-version -libhowl_wrap_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) -libhowl_wrap_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) +module_solaris_la_SOURCES = module-solaris.c +module_solaris_la_LDFLAGS = -module -avoid-version +module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la + +# HOWL module_zeroconf_publish_la_SOURCES = module-zeroconf-publish.c module_zeroconf_publish_la_LDFLAGS = -module -avoid-version module_zeroconf_publish_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) libhowl-wrap.la module_zeroconf_publish_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) -lib_LTLIBRARIES+= \ - libpolyp-browse-@PA_MAJORMINOR@.la - -libpolyp_browse_@PA_MAJORMINOR@_la_SOURCES = polyplib-browser.c polyplib-browser.h -libpolyp_browse_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS) -libpolyp_browse_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-@PA_MAJORMINOR@.la $(HOWL_LIBS) -libpolyp_browse_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -bin_PROGRAMS += \ - pabrowse - -pabrowse_SOURCES = pabrowse.c -pabrowse_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la libpolyp-browse-@PA_MAJORMINOR@.la -pabrowse_CFLAGS = $(AM_CFLAGS) - -polypinclude_HEADERS+=polyplib-browser.h - -endif - -### GLIB 2.0 support - -if HAVE_GLIB20 -lib_LTLIBRARIES+= \ - libpolyp-mainloop-glib-@PA_MAJORMINOR@.la - -noinst_PROGRAMS+= \ - mainloop-test-glib - -libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_SOURCES = glib-mainloop.h glib-mainloop.c -libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS) -libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-mainloop-@PA_MAJORMINOR@.la $(GLIB20_LIBS) -libpolyp_mainloop_glib_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -mainloop_test_glib_SOURCES = $(mainloop_test_SOURCES) -mainloop_test_glib_CFLAGS = $(mainloop_test_CFLAGS) $(GLIB20_CFLAGS) -DGLIB_MAIN_LOOP -mainloop_test_glib_LDADD = $(mainloop_test_LDADD) $(GLIB20_LIBS) libpolyp-mainloop-glib-@PA_MAJORMINOR@.la -endif - -### GLIB 1.2 support - -if HAVE_GLIB12 - -lib_LTLIBRARIES+= \ - libpolyp-mainloop-glib12-@PA_MAJORMINOR@.la - -noinst_PROGRAMS+= \ - mainloop-test-glib12 - -libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_SOURCES = glib-mainloop.h glib12-mainloop.c -libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(GLIB12_CFLAGS) -libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) libpolyp-mainloop-@PA_MAJORMINOR@.la $(GLIB12_LIBS) -libpolyp_mainloop_glib12_@PA_MAJORMINOR@_la_LDFLAGS = -version-info 0:0:0 - -mainloop_test_glib12_SOURCES = $(mainloop_test_SOURCES) -mainloop_test_glib12_CFLAGS = $(mainloop_test_CFLAGS) $(GLIB12_CFLAGS) -DGLIB_MAIN_LOOP -mainloop_test_glib12_LDADD = $(mainloop_test_LDADD) $(GLIB12_LIBS) libpolyp-mainloop-glib12-@PA_MAJORMINOR@.la - -endif - -### LIRC support - -if HAVE_LIRC - -modlib_LTLIBRARIES+= \ - module-lirc.la +# LIRC module_lirc_la_SOURCES = module-lirc.c module_lirc_la_LDFLAGS = -module -avoid-version module_lirc_la_LIBADD = $(AM_LIBADD) $(LIRC_LIBS) module_lirc_la_CFLAGS = $(AM_CFLAGS) $(LIRC_CFLAGS) -endif - - -### Linux evdev - -if HAVE_EVDEV - -modlib_LTLIBRARIES+= \ - module-mmkbd-evdev.la +# Linux evdev module_mmkbd_evdev_la_SOURCES = module-mmkbd-evdev.c module_mmkbd_evdev_la_LDFLAGS = -module -avoid-version module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD) module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS) -endif +# Windows waveout -### libpolypcore (needs to be updated) +module_waveout_la_SOURCES = module-waveout.c +module_waveout_la_LDFLAGS = -module -avoid-version +module_waveout_la_LIBADD = $(AM_LIBADD) libpolypcore.la -lwinmm +module_waveout_la_CFLAGS = $(AM_CFLAGS) -if BUILD_LIBPOLYPCORE - -polypinclude_HEADERS+=cli-command.h\ - client.h \ - core.h \ - dynarray.h \ - endianmacros.h \ - hashmap.h \ - idxset.h \ - iochannel.h \ - memblock.h \ - memblockq.h \ - memchunk.h \ - modargs.h \ - module.h \ - namereg.h \ - queue.h \ - resampler.h \ - sample-util.h \ - sink.h \ - sink-input.h \ - sioman.h \ - socket-server.h \ - socket-client.h \ - socket-util.h \ - source.h \ - source-output.h \ - strbuf.h \ - tokenizer.h \ - tagstruct.h \ - util.h - -lib_LTLIBRARIES+= libpolypcore.la - -libpolypcore_la_SOURCES = idxset.c idxset.h \ - queue.c queue.h \ - strbuf.c strbuf.h \ - mainloop.c mainloop.h \ - memblock.c memblock.h \ - sample.c sample.h \ - sample-util.c sample-util.h \ - memblockq.c memblockq.h \ - client.c client.h \ - core.c core.h \ - source-output.c source-output.h \ - sink-input.c sink-input.h \ - source.c source.h \ - sink.c sink.h \ - module.c module.h \ - mainloop-signal.c mainloop-signal.h \ - mainloop-api.c mainloop-api.h \ - util.c util.h \ - hashmap.c hashmap.h \ - namereg.c namereg.h \ - sconv.c sconv.h \ - resampler.c resampler.h \ - endianmacros.h \ - memchunk.c memchunk.h \ - sconv-s16le.c sconv-s16le.h \ - sconv-s16be.c sconv-s16be.h \ - sioman.c sioman.h \ - modargs.c modargs.h \ - cli-command.c cli-command.h \ - cli-text.c cli-text.h \ - tokenizer.c tokenizer.h \ - dynarray.c dynarray.h - -endif - -### Some minor stuff +################################### +# Some minor stuff # +################################### suid: polypaudio chown root $< @@ -829,22 +1017,24 @@ suid: polypaudio esdcompat.sh: esdcompat.sh.in Makefile sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \ - -e 's,@POLYPAUDIO_BINARY\@,$(bindir)/polypaudio,g' < $< > $@ + -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@ client.conf: client.conf.in Makefile - sed -e 's,@POLYPAUDIO_BINARY\@,$(bindir)/polypaudio,g' < $< > $@ + sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@ +if OS_IS_WIN32 +default.pa: default.pa.win32 + cp $< $@ +else default.pa: default.pa.in Makefile - sed -e 's,@POLYPAUDIO_BINARY\@,$(bindir)/polypaudio,g' < $< > $@ + sed -e 's,@POLYPAUDIO_BINARY\@,$(POLYPAUDIO_BINARY),g' < $< > $@ +endif daemon.conf: daemon.conf.in Makefile sed -e 's,@DLSEARCHPATH\@,$(modlibdir),g' \ - -e 's,@DEFAULT_CONFIG_FILE\@,$(polypconfdir)/daemon.conf,g' < $< > $@ + -e 's,@DEFAULT_CONFIG_FILE\@,$(DEFAULT_CONFIG_DIR),g' < $< > $@ install-exec-hook: chown root $(DESTDIR)$(bindir)/polypaudio ; true chmod u+s $(DESTDIR)$(bindir)/polypaudio ln -sf pacat $(DESTDIR)$(bindir)/parec - -$(SYMDEF_FILES): module-defs.h.m4 - $(M4) -Dfname="$@" $< > $@ diff --git a/polyp/authkey.c b/polyp/authkey.c index e16883d3..969f09d9 100644 --- a/polyp/authkey.c +++ b/polyp/authkey.c @@ -63,7 +63,7 @@ static int generate(int fd, void *ret_data, size_t length) { static int load(const char *fn, void *data, size_t length) { int fd = -1; int writable = 1; - int unlock = 0, ret; + int unlock = 0, ret = -1; ssize_t r; assert(fn && data && length); @@ -128,12 +128,20 @@ int pa_authkey_load(const char *path, void *data, size_t length) { static const char *normalize_path(const char *fn, char *s, size_t l) { assert(fn && s && l > 0); +#ifndef OS_IS_WIN32 if (fn[0] != '/') { +#else + if (strlen(fn) < 3 || !isalpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') { +#endif char homedir[PATH_MAX]; if (!pa_get_home_dir(homedir, sizeof(homedir))) return NULL; +#ifndef OS_IS_WIN32 snprintf(s, l, "%s/%s", homedir, fn); +#else + snprintf(s, l, "%s\\%s", homedir, fn); +#endif return s; } diff --git a/polyp/caps.c b/polyp/caps.c index 739e7071..4ecb5848 100644 --- a/polyp/caps.c +++ b/polyp/caps.c @@ -35,6 +35,8 @@ #include "log.h" #include "caps.h" +#ifdef HAVE_GETUID + /* Drop root rights when called SUID root */ void pa_drop_root(void) { uid_t uid = getuid(); @@ -54,6 +56,13 @@ void pa_drop_root(void) { #endif } +#else + +void pa_drop_root(void) { +} + +#endif + #ifdef HAVE_SYS_CAPABILITY_H /* Limit capabilities set to CAPSYS_NICE */ diff --git a/polyp/cli-command.c b/polyp/cli-command.c index 0e8e09a5..12447879 100644 --- a/polyp/cli-command.c +++ b/polyp/cli-command.c @@ -641,7 +641,11 @@ static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct time(&now); +#ifdef HAVE_CTIME_R pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt)); +#else + pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now)); +#endif for (m = pa_idxset_first(c->modules, &index); m; m = pa_idxset_next(c->modules, &index)) { diff --git a/polyp/client-conf.c b/polyp/client-conf.c index 4906383d..04c3d2ef 100644 --- a/polyp/client-conf.c +++ b/polyp/client-conf.c @@ -19,6 +19,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <stdlib.h> #include <assert.h> #include <unistd.h> @@ -33,11 +37,21 @@ #include "authkey.h" #ifndef DEFAULT_CONFIG_DIR -#define DEFAULT_CONFIG_DIR "/etc/polypaudio" +# ifndef OS_IS_WIN32 +# define DEFAULT_CONFIG_DIR "/etc/polypaudio" +# else +# define DEFAULT_CONFIG_DIR "%POLYP_ROOT%" +# endif +#endif + +#ifndef OS_IS_WIN32 +# define PATH_SEP "/" +#else +# define PATH_SEP "\\" #endif -#define DEFAULT_CLIENT_CONFIG_FILE DEFAULT_CONFIG_DIR"/client.conf" -#define DEFAULT_CLIENT_CONFIG_FILE_USER ".polypaudio/client.conf" +#define DEFAULT_CLIENT_CONFIG_FILE DEFAULT_CONFIG_DIR PATH_SEP "client.conf" +#define DEFAULT_CLIENT_CONFIG_FILE_USER ".polypaudio" PATH_SEP "client.conf" #define ENV_CLIENT_CONFIG_FILE "POLYP_CLIENTCONFIG" #define ENV_DEFAULT_SINK "POLYP_SINK" diff --git a/polyp/conf-parser.c b/polyp/conf-parser.c index b25508e2..8d2f2f68 100644 --- a/polyp/conf-parser.c +++ b/polyp/conf-parser.c @@ -19,6 +19,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <assert.h> #include <string.h> #include <stdio.h> diff --git a/polyp/core.c b/polyp/core.c index e2bebec2..60439243 100644 --- a/polyp/core.c +++ b/polyp/core.c @@ -89,7 +89,9 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) { pa_random(&c->cookie, sizeof(c->cookie)); +#ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); +#endif return c; } @@ -144,7 +146,7 @@ void pa_core_check_quit(struct pa_core *c) { if (!c->quit_event && c->exit_idle_time >= 0 && pa_idxset_ncontents(c->clients) == 0) { struct timeval tv; - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec+= c->exit_idle_time; c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c); } else if (c->quit_event && pa_idxset_ncontents(c->clients) > 0) { diff --git a/polyp/cpulimit.c b/polyp/cpulimit.c index 0fab98a0..53920f50 100644 --- a/polyp/cpulimit.c +++ b/polyp/cpulimit.c @@ -23,15 +23,20 @@ #include <config.h> #endif +#ifdef HAVE_SIGXCPU + #include <errno.h> #include <stdio.h> #include <string.h> #include <assert.h> #include <sys/time.h> -#include <sys/resource.h> #include <unistd.h> #include <signal.h> +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + #include "cpulimit.h" #include "util.h" #include "log.h" @@ -219,3 +224,16 @@ void pa_cpu_limit_done(void) { installed = 0; } } + +#else /* HAVE_SIGXCPU */ + +struct pa_mainloop_api; + +int pa_cpu_limit_init(struct pa_mainloop_api *m) { + return 0; +} + +void pa_cpu_limit_done(void) { +} + +#endif diff --git a/polyp/daemon-conf.c b/polyp/daemon-conf.c index a6afd05a..780581b2 100644 --- a/polyp/daemon-conf.c +++ b/polyp/daemon-conf.c @@ -37,13 +37,23 @@ #include "resampler.h" #ifndef DEFAULT_CONFIG_DIR -#define DEFAULT_CONFIG_DIR "/etc/polypaudio" +# ifndef OS_IS_WIN32 +# define DEFAULT_CONFIG_DIR "/etc/polypaudio" +# else +# define DEFAULT_CONFIG_DIR "%POLYP_ROOT%" +# endif #endif -#define DEFAULT_SCRIPT_FILE DEFAULT_CONFIG_DIR"/default.pa" -#define DEFAULT_SCRIPT_FILE_USER ".polypaudio/default.pa" -#define DEFAULT_CONFIG_FILE DEFAULT_CONFIG_DIR"/daemon.conf" -#define DEFAULT_CONFIG_FILE_USER ".polypaudio/daemon.conf" +#ifndef OS_IS_WIN32 +# define PATH_SEP "/" +#else +# define PATH_SEP "\\" +#endif + +#define DEFAULT_SCRIPT_FILE DEFAULT_CONFIG_DIR PATH_SEP "default.pa" +#define DEFAULT_SCRIPT_FILE_USER ".polypaudio" PATH_SEP "default.pa" +#define DEFAULT_CONFIG_FILE DEFAULT_CONFIG_DIR PATH_SEP "daemon.conf" +#define DEFAULT_CONFIG_FILE_USER ".polypaudio" PATH_SEP "daemon.conf" #define ENV_SCRIPT_FILE "POLYP_SCRIPT" #define ENV_CONFIG_FILE "POLYP_CONFIG" diff --git a/polyp/default.pa.win32 b/polyp/default.pa.win32 new file mode 100644 index 00000000..3478adab --- /dev/null +++ b/polyp/default.pa.win32 @@ -0,0 +1,43 @@ +#
+# This file is part of polypaudio.
+#
+# polypaudio 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.
+#
+# polypaudio 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 polypaudio; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+
+# Load audio drivers statically
+
+load-module module-waveout sink_name=output source_name=input
+load-module module-null-sink
+
+# Load audio drivers automatically on access
+
+#add-autoload-sink output module-waveout sink_name=output source_name=input
+#add-autoload-source input module-waveout sink_name=output source_name=input
+
+# Load several protocols
+#load-module module-esound-protocol-tcp
+#load-module module-native-protocol-tcp
+#load-module module-simple-protocol-tcp
+#load-module module-cli-protocol-tcp
+
+# Make some devices default
+set-default-sink output
+set-default-source input
+
+.nofail
+
+# Load something to the sample cache
+load-sample x11-bell %WINDIR%\Media\ding.wav
+load-sample-dir-lazy %WINDIR%\Media\*.wav
diff --git a/polyp/dllmain.c b/polyp/dllmain.c new file mode 100644 index 00000000..34d0eed1 --- /dev/null +++ b/polyp/dllmain.c @@ -0,0 +1,46 @@ +/* $Id: dllmain.c 317 2004-12-11 00:10:41Z lennart $ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 + +#ifdef OS_IS_WIN32 + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <windows.h> + +extern pa_set_root(HANDLE handle); + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + if (fdwReason != DLL_PROCESS_ATTACH) + return TRUE; + + if (!pa_set_root(hinstDLL)) + return FALSE; + + return TRUE; +} + +#endif /* OS_IS_WIN32 */ diff --git a/polyp/dumpmodules.c b/polyp/dumpmodules.c index 1dc14edc..5aaa108d 100644 --- a/polyp/dumpmodules.c +++ b/polyp/dumpmodules.c @@ -31,6 +31,7 @@ #include "dumpmodules.h" #include "modinfo.h" +#include "util.h" #define PREFIX "module-" @@ -80,10 +81,7 @@ static int callback(const char *path, lt_ptr data) { const char *e; struct pa_daemon_conf *c = (data); - if ((e = (const char*) strrchr(path, '/'))) - e++; - else - e = path; + e = pa_path_get_filename(path); if (strlen(e) > sizeof(PREFIX)-1 && !strncmp(e, PREFIX, sizeof(PREFIX)-1)) show_info(e, path, c->log_level >= PA_LOG_INFO ? long_info : short_info); diff --git a/polyp/glib-mainloop.c b/polyp/glib-mainloop.c index 809c0b0f..0f96a594 100644 --- a/polyp/glib-mainloop.c +++ b/polyp/glib-mainloop.c @@ -241,7 +241,7 @@ static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv) struct timeval now; assert(e && e->mainloop && !e->dead); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); if (e->source) { g_source_destroy(e->source); g_source_unref(e->source); diff --git a/polyp/glib12-mainloop.c b/polyp/glib12-mainloop.c index 5f037347..c328471c 100644 --- a/polyp/glib12-mainloop.c +++ b/polyp/glib12-mainloop.c @@ -233,7 +233,7 @@ static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv) struct timeval now; assert(e && e->mainloop && !e->dead); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); if (e->source != (guint) -1) g_source_remove(e->source); diff --git a/polyp/inet_ntop.c b/polyp/inet_ntop.c new file mode 100644 index 00000000..ac2b5295 --- /dev/null +++ b/polyp/inet_ntop.c @@ -0,0 +1,80 @@ +/* $Id: inet_ntop.c 428 2006-01-09 16:50:39Z ossman $ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 <stdio.h> +#include <errno.h> +#include <assert.h> + +#ifndef HAVE_INET_NTOP + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#include "winsock.h" + +#include "inet_ntop.h" + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + struct in_addr *in = (struct in_addr*)src; + struct in6_addr *in6 = (struct in6_addr*)src; + + assert(src && dst); + + switch (af) { + case AF_INET: + snprintf(dst, cnt, "%d.%d.%d.%d", +#ifdef WORDS_BIGENDIAN + (int)(in->s_addr >> 24) & 0xff, + (int)(in->s_addr >> 16) & 0xff, + (int)(in->s_addr >> 8) & 0xff, + (int)(in->s_addr >> 0) & 0xff); +#else + (int)(in->s_addr >> 0) & 0xff, + (int)(in->s_addr >> 8) & 0xff, + (int)(in->s_addr >> 16) & 0xff, + (int)(in->s_addr >> 24) & 0xff); +#endif + break; + case AF_INET6: + snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x", + in6->s6_addr[ 0] << 8 | in6->s6_addr[ 1], + in6->s6_addr[ 2] << 8 | in6->s6_addr[ 3], + in6->s6_addr[ 4] << 8 | in6->s6_addr[ 5], + in6->s6_addr[ 6] << 8 | in6->s6_addr[ 7], + in6->s6_addr[ 8] << 8 | in6->s6_addr[ 9], + in6->s6_addr[10] << 8 | in6->s6_addr[11], + in6->s6_addr[12] << 8 | in6->s6_addr[13], + in6->s6_addr[14] << 8 | in6->s6_addr[15]); + break; + default: + errno = EAFNOSUPPORT; + return NULL; + } + + return dst; +} + +#endif /* INET_NTOP */ diff --git a/polyp/inet_ntop.h b/polyp/inet_ntop.h new file mode 100644 index 00000000..7fb67b44 --- /dev/null +++ b/polyp/inet_ntop.h @@ -0,0 +1,12 @@ +#ifndef fooinet_ntophfoo +#define fooinet_ntophfoo + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#include "winsock.h" + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); + +#endif diff --git a/polyp/iochannel.c b/polyp/iochannel.c index 0e7e8db8..1a0dbf91 100644 --- a/polyp/iochannel.c +++ b/polyp/iochannel.c @@ -28,6 +28,8 @@ #include <fcntl.h> #include <unistd.h> +#include "winsock.h" + #include "iochannel.h" #include "util.h" #include "socket-util.h" @@ -189,7 +191,19 @@ ssize_t pa_iochannel_write(struct pa_iochannel*io, const void*data, size_t l) { ssize_t r; assert(io && data && l && io->ofd >= 0); - if ((r = write(io->ofd, data, l)) >= 0) { +#ifdef OS_IS_WIN32 + r = send(io->ofd, data, l, 0); + if (r < 0) { + if (WSAGetLastError() != WSAENOTSOCK) { + errno = WSAGetLastError(); + return r; + } + } + + if (r < 0) +#endif + r = write(io->ofd, data, l); + if (r >= 0) { io->writable = 0; enable_mainloop_sources(io); } @@ -201,7 +215,19 @@ ssize_t pa_iochannel_read(struct pa_iochannel*io, void*data, size_t l) { ssize_t r; assert(io && data && io->ifd >= 0); - if ((r = read(io->ifd, data, l)) >= 0) { +#ifdef OS_IS_WIN32 + r = recv(io->ifd, data, l, 0); + if (r < 0) { + if (WSAGetLastError() != WSAENOTSOCK) { + errno = WSAGetLastError(); + return r; + } + } + + if (r < 0) +#endif + r = read(io->ifd, data, l); + if (r >= 0) { io->readable = 0; enable_mainloop_sources(io); } diff --git a/polyp/log.c b/polyp/log.c index 78736a47..2bbf2e86 100644 --- a/polyp/log.c +++ b/polyp/log.c @@ -25,9 +25,12 @@ #include <assert.h> #include <stdarg.h> -#include <syslog.h> #include <stdio.h> +#ifdef HAVE_SYSLOG_H +#include <syslog.h> +#endif + #include "log.h" #include "xmalloc.h" #include "util.h" @@ -39,6 +42,7 @@ static enum pa_log_target log_target = PA_LOG_STDERR; static void (*user_log_func)(enum pa_log_level l, const char *s) = NULL; static enum pa_log_level maximal_level = PA_LOG_NOTICE; +#ifdef HAVE_SYSLOG_H static const int level_to_syslog[] = { [PA_LOG_ERROR] = LOG_ERR, [PA_LOG_WARN] = LOG_WARNING, @@ -46,6 +50,7 @@ static const int level_to_syslog[] = { [PA_LOG_INFO] = LOG_INFO, [PA_LOG_DEBUG] = LOG_DEBUG }; +#endif void pa_log_set_ident(const char *p) { if (log_ident) @@ -79,13 +84,15 @@ void pa_log_levelv(enum pa_log_level level, const char *format, va_list ap) { case PA_LOG_STDERR: vfprintf(stderr, format, ap); break; - + +#ifdef HAVE_SYSLOG_H case PA_LOG_SYSLOG: openlog(log_ident ? log_ident : "???", LOG_PID, LOG_USER); vsyslog(level_to_syslog[level], format, ap); closelog(); - break; - + break; +#endif + case PA_LOG_USER: { char *t = pa_vsprintf_malloc(format, ap); assert(user_log_func); @@ -94,6 +101,7 @@ void pa_log_levelv(enum pa_log_level level, const char *format, va_list ap) { } case PA_LOG_NULL: + default: break; } diff --git a/polyp/main.c b/polyp/main.c index 26fa4a87..e481fce1 100644 --- a/polyp/main.c +++ b/polyp/main.c @@ -35,13 +35,20 @@ #include <memblock.h> #include <limits.h> #include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> + +#ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> +#endif #ifdef HAVE_LIBWRAP #include <syslog.h> #include <tcpd.h> #endif +#include "winsock.h" + #include "core.h" #include "mainloop.h" #include "module.h" @@ -66,24 +73,47 @@ int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; #endif +#ifdef OS_IS_WIN32 + +static void message_cb(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) { + MSG msg; + + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) + raise(SIGTERM); + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +} + +#endif + static void signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) { pa_log_info(__FILE__": Got signal %s.\n", pa_strsignal(sig)); switch (sig) { +#ifdef SIGUSR1 case SIGUSR1: pa_module_load(userdata, "module-cli", NULL); break; +#endif +#ifdef SIGUSR2 case SIGUSR2: pa_module_load(userdata, "module-cli-protocol-unix", NULL); break; +#endif +#ifdef SIGHUP case SIGHUP: { char *c = pa_full_status_string(userdata); pa_log_notice(c); pa_xfree(c); return; } +#endif case SIGINT: case SIGTERM: @@ -111,24 +141,42 @@ int main(int argc, char *argv[]) { char *s; int r, retval = 1, d = 0; int daemon_pipe[2] = { -1, -1 }; - gid_t gid = (gid_t) -1; int suid_root; int valid_pid_file = 0; +#ifdef HAVE_GETUID + gid_t gid = (gid_t) -1; +#endif + +#ifdef OS_IS_WIN32 + struct pa_defer_event *defer; +#endif + pa_limit_caps(); +#ifdef HAVE_GETUID suid_root = getuid() != 0 && geteuid() == 0; if (suid_root && (pa_uid_in_group("realtime", &gid) <= 0 || gid >= 1000)) { pa_log_warn(__FILE__": WARNING: called SUID root, but not in group 'realtime'.\n"); pa_drop_root(); } +#else + suid_root = 0; +#endif LTDL_SET_PRELOADED_SYMBOLS(); r = lt_dlinit(); assert(r == 0); +#ifdef OS_IS_WIN32 + { + WSADATA data; + WSAStartup(MAKEWORD(2, 0), &data); + } +#endif + pa_log_set_ident("polypaudio"); conf = pa_daemon_conf_new(); @@ -217,6 +265,7 @@ int main(int argc, char *argv[]) { goto finish; } +#ifdef HAVE_FORK if (pipe(daemon_pipe) < 0) { pa_log(__FILE__": failed to create pipe.\n"); goto finish; @@ -248,13 +297,19 @@ int main(int argc, char *argv[]) { close(daemon_pipe[0]); daemon_pipe[0] = -1; +#endif if (conf->auto_log_target) pa_log_set_target(PA_LOG_SYSLOG, NULL); +#ifdef HAVE_SETSID setsid(); +#endif +#ifdef HAVE_SETPGID setpgid(0,0); - +#endif + +#ifndef OS_IS_WIN32 close(0); close(1); close(2); @@ -262,23 +317,37 @@ int main(int argc, char *argv[]) { open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); open("/dev/null", O_WRONLY); - +#else + FreeConsole(); +#endif + +#ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); +#endif +#ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); +#endif +#ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); +#endif +#ifdef TIOCNOTTY if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(tty_fd, TIOCNOTTY, (char*) 0); close(tty_fd); } +#endif } chdir("/"); if (conf->use_pid_file) { if (pa_pid_file_create() < 0) { + pa_log(__FILE__": pa_pid_file_create() failed.\n"); +#ifdef HAVE_FORK if (conf->daemonize) pa_loop_write(daemon_pipe[1], &retval, sizeof(retval)); +#endif goto finish; } @@ -288,20 +357,34 @@ int main(int argc, char *argv[]) { mainloop = pa_mainloop_new(); assert(mainloop); + c = pa_core_new(pa_mainloop_get_api(mainloop)); + assert(c); + r = pa_signal_init(pa_mainloop_get_api(mainloop)); assert(r == 0); pa_signal_new(SIGINT, signal_callback, c); pa_signal_new(SIGTERM, signal_callback, c); +#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); +#endif + +#ifdef OS_IS_WIN32 + defer = pa_mainloop_get_api(mainloop)->defer_new(pa_mainloop_get_api(mainloop), message_cb, NULL); + assert(defer); +#endif - c = pa_core_new(pa_mainloop_get_api(mainloop)); - assert(c); if (conf->daemonize) c->running_as_daemon = 1; - + +#ifdef SIGUSR1 pa_signal_new(SIGUSR1, signal_callback, c); +#endif +#ifdef SIGUSR2 pa_signal_new(SIGUSR2, signal_callback, c); +#endif +#ifdef SIGHUP pa_signal_new(SIGHUP, signal_callback, c); +#endif r = pa_cpu_limit_init(pa_mainloop_get_api(mainloop)); assert(r == 0); @@ -318,17 +401,23 @@ int main(int argc, char *argv[]) { if (r < 0 && conf->fail) { pa_log(__FILE__": failed to initialize daemon.\n"); +#ifdef HAVE_FORK if (conf->daemonize) pa_loop_write(daemon_pipe[1], &retval, sizeof(retval)); +#endif } else if (!c->modules || pa_idxset_ncontents(c->modules) == 0) { pa_log(__FILE__": daemon startup without any loaded modules, refusing to work.\n"); +#ifdef HAVE_FORK if (conf->daemonize) pa_loop_write(daemon_pipe[1], &retval, sizeof(retval)); +#endif } else { retval = 0; +#ifdef HAVE_FORK if (conf->daemonize) pa_loop_write(daemon_pipe[1], &retval, sizeof(retval)); +#endif c->disallow_module_loading = conf->disallow_module_loading; c->exit_idle_time = conf->exit_idle_time; @@ -346,7 +435,11 @@ int main(int argc, char *argv[]) { pa_log_info(__FILE__": Daemon shutdown initiated.\n"); } } - + +#ifdef OS_IS_WIN32 + pa_mainloop_get_api(mainloop)->defer_free(defer); +#endif + pa_core_free(c); pa_cpu_limit_done(); @@ -365,6 +458,10 @@ finish: close_pipe(daemon_pipe); +#ifdef OS_IS_WIN32 + WSACleanup(); +#endif + lt_dlexit(); return retval; diff --git a/polyp/mainloop-signal.c b/polyp/mainloop-signal.c index 89f195ed..432498a8 100644 --- a/polyp/mainloop-signal.c +++ b/polyp/mainloop-signal.c @@ -30,6 +30,11 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <fcntl.h> + +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif #include "mainloop-signal.h" #include "util.h" @@ -38,7 +43,11 @@ struct pa_signal_event { int sig; +#ifdef HAVE_SIGACTION struct sigaction saved_sigaction; +#else + void (*saved_handler)(int sig); +#endif void (*callback) (struct pa_mainloop_api*a, struct pa_signal_event *e, int signal, void *userdata); void *userdata; void (*destroy_callback) (struct pa_mainloop_api*a, struct pa_signal_event*e, void *userdata); @@ -48,16 +57,70 @@ struct pa_signal_event { static struct pa_mainloop_api *api = NULL; static int signal_pipe[2] = { -1, -1 }; static struct pa_io_event* io_event = NULL; +static struct pa_defer_event *defer_event = NULL; static struct pa_signal_event *signals = NULL; +#ifdef OS_IS_WIN32 +static unsigned int waiting_signals = 0; +static CRITICAL_SECTION crit; +#endif + static void signal_handler(int sig) { +#ifndef HAVE_SIGACTION + signal(sig, signal_handler); +#endif write(signal_pipe[1], &sig, sizeof(sig)); + +#ifdef OS_IS_WIN32 + EnterCriticalSection(&crit); + waiting_signals++; + LeaveCriticalSection(&crit); +#endif +} + +static void dispatch(struct pa_mainloop_api*a, int sig) { + struct pa_signal_event*s; + + for (s = signals; s; s = s->next) + if (s->sig == sig) { + assert(s->callback); + s->callback(a, s, sig, s->userdata); + break; + } +} + +static void defer(struct pa_mainloop_api*a, struct pa_defer_event*e, void *userdata) { + ssize_t r; + int sig; + unsigned int sigs; + +#ifdef OS_IS_WIN32 + EnterCriticalSection(&crit); + sigs = waiting_signals; + waiting_signals = 0; + LeaveCriticalSection(&crit); +#endif + + while (sigs) { + if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) { + pa_log(__FILE__": read(): %s\n", strerror(errno)); + return; + } + + if (r != sizeof(sig)) { + pa_log(__FILE__": short read()\n"); + return; + } + + dispatch(a, sig); + + sigs--; + } } static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata) { ssize_t r; int sig; - struct pa_signal_event*s; assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]); @@ -73,19 +136,18 @@ static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enu pa_log(__FILE__": short read()\n"); return; } - - for (s = signals; s; s = s->next) - if (s->sig == sig) { - assert(s->callback); - s->callback(a, s, sig, s->userdata); - break; - } + + dispatch(a, sig); } int pa_signal_init(struct pa_mainloop_api *a) { - assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event); - + assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event && !defer_event); + +#ifdef OS_IS_WIN32 + if (_pipe(signal_pipe, 200, _O_BINARY) < 0) { +#else if (pipe(signal_pipe) < 0) { +#endif pa_log(__FILE__": pipe() failed: %s\n", strerror(errno)); return -1; } @@ -96,20 +158,36 @@ int pa_signal_init(struct pa_mainloop_api *a) { pa_fd_set_cloexec(signal_pipe[1], 1); api = a; + +#ifndef OS_IS_WIN32 io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL); assert(io_event); +#else + defer_event = api->defer_new(api, defer, NULL); + assert(defer_event); + + InitializeCriticalSection(&crit); +#endif + return 0; } void pa_signal_done(void) { - assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event); + assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && (io_event || defer_event)); while (signals) pa_signal_free(signals); - api->io_free(io_event); +#ifndef OS_IS_WIN32 + api->io_free(io_event); io_event = NULL; +#else + api->defer_free(defer_event); + defer_event = NULL; + + DeleteCriticalSection(&crit); +#endif close(signal_pipe[0]); close(signal_pipe[1]); @@ -120,7 +198,11 @@ void pa_signal_done(void) { struct pa_signal_event* pa_signal_new(int sig, void (*callback) (struct pa_mainloop_api *api, struct pa_signal_event*e, int sig, void *userdata), void *userdata) { struct pa_signal_event *e = NULL; + +#ifdef HAVE_SIGACTION struct sigaction sa; +#endif + assert(sig > 0 && callback); for (e = signals; e; e = e->next) @@ -133,12 +215,16 @@ struct pa_signal_event* pa_signal_new(int sig, void (*callback) (struct pa_mainl e->userdata = userdata; e->destroy_callback = NULL; +#ifdef HAVE_SIGACTION memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(sig, &sa, &e->saved_sigaction) < 0) +#else + if ((e->saved_handler = signal(sig, signal_handler)) == SIG_ERR) +#endif goto fail; e->previous = NULL; @@ -162,7 +248,11 @@ void pa_signal_free(struct pa_signal_event *e) { else signals = e->next; +#ifdef HAVE_SIGACTION sigaction(e->sig, &e->saved_sigaction, NULL); +#else + signal(e->sig, e->saved_handler); +#endif if (e->destroy_callback) e->destroy_callback(api, e, e->userdata); diff --git a/polyp/mainloop-test.c b/polyp/mainloop-test.c index 0d40e76e..dd8f8137 100644 --- a/polyp/mainloop-test.c +++ b/polyp/mainloop-test.c @@ -111,7 +111,7 @@ int main(int argc, char *argv[]) { de = a->defer_new(a, dcb, NULL); assert(de); - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec += 10; te = a->time_new(a, &tv, tcb, NULL); diff --git a/polyp/mainloop.c b/polyp/mainloop.c index f6bb4145..ada74afc 100644 --- a/polyp/mainloop.c +++ b/polyp/mainloop.c @@ -26,13 +26,20 @@ #include <stdio.h> #include <signal.h> #include <unistd.h> -#include <sys/poll.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <fcntl.h> #include <errno.h> +#ifdef HAVE_SYS_POLL_H +#include <sys/poll.h> +#else +#include "poll.h" +#endif + +#include "winsock.h" + #include "mainloop.h" #include "util.h" #include "idxset.h" @@ -103,6 +110,26 @@ static struct pa_io_event* mainloop_io_new(struct pa_mainloop_api*a, int fd, enu e->destroy_callback = NULL; e->pollfd = NULL; +#ifdef OS_IS_WIN32 + { + fd_set xset; + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO (&xset); + FD_SET (fd, &xset); + + if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset, + SELECT_TYPE_ARG5 &tv) == -1) && + (WSAGetLastError() == WSAENOTSOCK)) { + pa_log_warn(__FILE__": WARNING: cannot monitor non-socket file descriptors.\n"); + e->dead = 1; + } + } +#endif + pa_idxset_put(m->io_events, e, NULL); m->rebuild_pollfds = 1; return e; @@ -457,7 +484,7 @@ static int calc_next_timeout(struct pa_mainloop *m) { /* Let's save a system call */ if (!got_time) { - gettimeofday(&now, NULL); + pa_gettimeofday(&now); got_time = 1; } @@ -498,7 +525,7 @@ static int dispatch_timeout(struct pa_mainloop *m) { /* Let's save a system call */ if (!got_time) { - gettimeofday(&now, NULL); + pa_gettimeofday(&now); got_time = 1; } diff --git a/polyp/mcalign-test.c b/polyp/mcalign-test.c index e4a6a239..2ace6e59 100644 --- a/polyp/mcalign-test.c +++ b/polyp/mcalign-test.c @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) { c.length = r; pa_mcalign_push(a, &c); - fprintf(stderr, "Read %u bytes\n", r); + fprintf(stderr, "Read %d bytes\n", r); c.index += r; diff --git a/polyp/module-alsa-sink.c b/polyp/module-alsa-sink.c index 69db2875..dde5d8b6 100644 --- a/polyp/module-alsa-sink.c +++ b/polyp/module-alsa-sink.c @@ -25,7 +25,12 @@ #include <assert.h> #include <stdio.h> + +#ifdef HAVE_SYS_POLL_H #include <sys/poll.h> +#else +#include "poll.h" +#endif #include <asoundlib.h> diff --git a/polyp/module-alsa-source.c b/polyp/module-alsa-source.c index 55abe8e0..5b4076f8 100644 --- a/polyp/module-alsa-source.c +++ b/polyp/module-alsa-source.c @@ -25,7 +25,12 @@ #include <assert.h> #include <stdio.h> + +#ifdef HAVE_SYS_POLL_H #include <sys/poll.h> +#else +#include "poll.h" +#endif #include <asoundlib.h> diff --git a/polyp/module-combine.c b/polyp/module-combine.c index ca79d7df..7283c554 100644 --- a/polyp/module-combine.c +++ b/polyp/module-combine.c @@ -157,7 +157,7 @@ static void time_callback(struct pa_mainloop_api*a, struct pa_time_event* e, con adjust_rates(u); - gettimeofday(&n, NULL); + pa_gettimeofday(&n); n.tv_sec += u->adjust_time; u->sink->core->mainloop->time_restart(e, &n); } @@ -363,7 +363,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { pa_log_warn(__FILE__": WARNING: no slave sinks specified.\n"); if (u->adjust_time > 0) { - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec += u->adjust_time; u->time_event = c->mainloop->time_new(c->mainloop, &tv, time_callback, u); } diff --git a/polyp/module-esound-sink.c b/polyp/module-esound-sink.c index 82c38cc2..19106506 100644 --- a/polyp/module-esound-sink.c +++ b/polyp/module-esound-sink.c @@ -144,7 +144,7 @@ static int do_write(struct userdata *u) { pa_module_set_used(u->module, pa_idxset_ncontents(u->sink->inputs) + pa_idxset_ncontents(u->sink->monitor_source->outputs)); if (!u->memchunk.length) - if (pa_sink_render(u->sink, PIPE_BUF, &u->memchunk) < 0) + if (pa_sink_render(u->sink, 8192, &u->memchunk) < 0) return 0; assert(u->memchunk.memblock && u->memchunk.length); diff --git a/polyp/module-mmkbd-evdev.c b/polyp/module-mmkbd-evdev.c index 758aaae5..5368af50 100644 --- a/polyp/module-mmkbd-evdev.c +++ b/polyp/module-mmkbd-evdev.c @@ -49,6 +49,17 @@ PA_MODULE_USAGE("device=<evdev device> sink=<sink name>") #define DEFAULT_DEVICE "/dev/input/event0" +/* + * This isn't defined in older kernel headers and there is no way of + * detecting it. + */ +struct _input_id { + __u16 bustype; + __u16 vendor; + __u16 product; + __u16 version; +}; + static const char* const valid_modargs[] = { "device", "sink", @@ -136,7 +147,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_modargs *ma = NULL; struct userdata *u; int version; - struct input_id input_id; + struct _input_id input_id; char name[256]; uint8_t evtype_bitmask[EV_MAX/8 + 1]; assert(c && m); diff --git a/polyp/module-null-sink.c b/polyp/module-null-sink.c index fcac1ea4..6c7a44f2 100644 --- a/polyp/module-null-sink.c +++ b/polyp/module-null-sink.c @@ -117,7 +117,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { pa_sink_set_owner(u->sink, m); u->sink->description = pa_sprintf_malloc("NULL sink"); - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); u->time_event = c->mainloop->time_new(c->mainloop, &tv, time_callback, u); u->block_size = pa_bytes_per_second(&ss) / 10; diff --git a/polyp/module-protocol-stub.c b/polyp/module-protocol-stub.c index 15697582..141eadd3 100644 --- a/polyp/module-protocol-stub.c +++ b/polyp/module-protocol-stub.c @@ -27,9 +27,20 @@ #include <errno.h> #include <stdio.h> #include <assert.h> -#include <arpa/inet.h> #include <unistd.h> +#include <limits.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETINET_IN_H #include <netinet/in.h> +#endif + +#include "winsock.h" #include "module.h" #include "socket-server.h" diff --git a/polyp/module-solaris.c b/polyp/module-solaris.c new file mode 100644 index 00000000..3eb66462 --- /dev/null +++ b/polyp/module-solaris.c @@ -0,0 +1,436 @@ +/* $Id: module-oss.c 333 2005-01-08 21:36:53Z lennart $ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <limits.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <stropts.h> +#include <sys/conf.h> +#include <sys/audio.h> + +#include "iochannel.h" +#include "sink.h" +#include "source.h" +#include "module.h" +#include "sample-util.h" +#include "util.h" +#include "modargs.h" +#include "xmalloc.h" +#include "log.h" +#include "module-solaris-symdef.h" + +PA_MODULE_AUTHOR("Pierre Ossman") +PA_MODULE_DESCRIPTION("Solaris Sink/Source") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE("sink_name=<name for the sink> source_name=<name for the source> device=<OSS device> record=<enable source?> playback=<enable sink?> format=<sample format> channels=<number of channels> rate=<sample rate> buffer_size=<record buffer size>") + +#define PA_TYPEID_SOLARIS PA_TYPEID_MAKE('S', 'L', 'R', 'S') + +struct userdata { + struct pa_sink *sink; + struct pa_source *source; + struct pa_iochannel *io; + struct pa_core *core; + + struct pa_memchunk memchunk, silence; + + uint32_t sample_size; + unsigned int written_bytes, read_bytes; + + int fd; + struct pa_module *module; +}; + +static const char* const valid_modargs[] = { + "sink_name", + "source_name", + "device", + "record", + "playback", + "buffer_size", + "format", + "rate", + "channels", + NULL +}; + +#define DEFAULT_SINK_NAME "solaris_output" +#define DEFAULT_SOURCE_NAME "solaris_input" +#define DEFAULT_DEVICE "/dev/audio" + +#define CHUNK_SIZE 2048 + +static void update_usage(struct userdata *u) { + pa_module_set_used(u->module, + (u->sink ? pa_idxset_ncontents(u->sink->inputs) : 0) + + (u->sink ? pa_idxset_ncontents(u->sink->monitor_source->outputs) : 0) + + (u->source ? pa_idxset_ncontents(u->source->outputs) : 0)); +} + +static void do_write(struct userdata *u) { + struct pa_memchunk *memchunk; + ssize_t r; + + assert(u); + + if (!u->sink || !pa_iochannel_is_writable(u->io)) + return; + + update_usage(u); + + memchunk = &u->memchunk; + + if (!memchunk->length) + if (pa_sink_render(u->sink, CHUNK_SIZE, memchunk) < 0) + memchunk = &u->silence; + + assert(memchunk->memblock); + assert(memchunk->memblock->data); + assert(memchunk->length); + + if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length)) < 0) { + pa_log(__FILE__": write() failed: %s\n", strerror(errno)); + return; + } + + if (memchunk == &u->silence) + assert(r % u->sample_size == 0); + else { + u->memchunk.index += r; + u->memchunk.length -= r; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + u->memchunk.memblock = NULL; + } + } + + u->written_bytes += r; +} + +static void do_read(struct userdata *u) { + struct pa_memchunk memchunk; + int err, l; + ssize_t r; + assert(u); + + if (!u->source || !pa_iochannel_is_readable(u->io)) + return; + + update_usage(u); + + err = ioctl(u->fd, I_NREAD, &l); + assert(err >= 0); + + memchunk.memblock = pa_memblock_new(l, u->core->memblock_stat); + assert(memchunk.memblock); + if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) { + pa_memblock_unref(memchunk.memblock); + if (errno != EAGAIN) + pa_log(__FILE__": read() failed: %s\n", strerror(errno)); + return; + } + + assert(r <= (ssize_t) memchunk.memblock->length); + memchunk.length = memchunk.memblock->length = r; + memchunk.index = 0; + + pa_source_post(u->source, &memchunk); + pa_memblock_unref(memchunk.memblock); + + u->read_bytes += r; +} + +static void io_callback(struct pa_iochannel *io, void*userdata) { + struct userdata *u = userdata; + assert(u); + do_write(u); + do_read(u); +} + +static pa_usec_t sink_get_latency_cb(struct pa_sink *s) { + pa_usec_t r = 0; + audio_info_t info; + int err; + struct userdata *u = s->userdata; + assert(s && u && u->sink); + + err = ioctl(u->fd, AUDIO_GETINFO, &info); + assert(err >= 0); + + r += pa_bytes_to_usec(u->written_bytes, &s->sample_spec); + r -= pa_bytes_to_usec(info.play.samples * u->sample_size, &s->sample_spec); + + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, &s->sample_spec); + + return r; +} + +static pa_usec_t source_get_latency_cb(struct pa_source *s) { + pa_usec_t r = 0; + struct userdata *u = s->userdata; + audio_info_t info; + int err; + assert(s && u && u->source); + + err = ioctl(u->fd, AUDIO_GETINFO, &info); + assert(err >= 0); + + r += pa_bytes_to_usec(info.record.samples * u->sample_size, &s->sample_spec); + r -= pa_bytes_to_usec(u->read_bytes, &s->sample_spec); + + return r; +} + +static int pa_solaris_auto_format(int fd, int mode, struct pa_sample_spec *ss) { + audio_info_t info; + + AUDIO_INITINFO(&info); + + if (mode != O_RDONLY) { + info.play.sample_rate = ss->rate; + info.play.channels = ss->channels; + switch (ss->format) { + case PA_SAMPLE_U8: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_LINEAR; + break; + case PA_SAMPLE_ALAW: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_ALAW; + break; + case PA_SAMPLE_ULAW: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_ULAW; + break; + case PA_SAMPLE_S16NE: + info.play.precision = 16; + info.play.encoding = AUDIO_ENCODING_LINEAR; + break; + default: + return -1; + } + } + + if (mode != O_WRONLY) { + info.record.sample_rate = ss->rate; + info.record.channels = ss->channels; + switch (ss->format) { + case PA_SAMPLE_U8: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_LINEAR; + break; + case PA_SAMPLE_ALAW: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_ALAW; + break; + case PA_SAMPLE_ULAW: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_ULAW; + break; + case PA_SAMPLE_S16NE: + info.record.precision = 16; + info.record.encoding = AUDIO_ENCODING_LINEAR; + break; + default: + return -1; + } + } + + if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log(__FILE__": AUDIO_SETINFO: Unsupported sample format.\n"); + else + pa_log(__FILE__": AUDIO_SETINFO: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +static int pa_solaris_set_buffer(int fd, int buffer_size) { + audio_info_t info; + + AUDIO_INITINFO(&info); + + info.record.buffer_size = buffer_size; + + if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log(__FILE__": AUDIO_SETINFO: Unsupported buffer size.\n"); + else + pa_log(__FILE__": AUDIO_SETINFO: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int pa__init(struct pa_core *c, struct pa_module*m) { + struct userdata *u = NULL; + const char *p; + int fd = -1; + int buffer_size; + int mode; + int record = 1, playback = 1; + struct pa_sample_spec ss; + struct pa_modargs *ma = NULL; + assert(c && m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log(__FILE__": failed to parse module arguments.\n"); + goto fail; + } + + if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { + pa_log(__FILE__": record= and playback= expect numeric argument.\n"); + goto fail; + } + + if (!playback && !record) { + pa_log(__FILE__": neither playback nor record enabled for device.\n"); + goto fail; + } + + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + + buffer_size = -1; + if (pa_modargs_get_value_s32(ma, "buffer_size", &buffer_size) < 0) { + pa_log(__FILE__": failed to parse buffer size argument\n"); + goto fail; + } + + ss = c->default_sample_spec; + if (pa_modargs_get_sample_spec(ma, &ss) < 0) { + pa_log(__FILE__": failed to parse sample specification\n"); + goto fail; + } + + if ((fd = open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), mode)) < 0) + goto fail; + + pa_log_info(__FILE__": device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); + + if (pa_solaris_auto_format(fd, mode, &ss) < 0) + goto fail; + + if ((mode != O_WRONLY) && (buffer_size >= 1)) + if (pa_solaris_set_buffer(fd, buffer_size) < 0) + goto fail; + + u = pa_xmalloc(sizeof(struct userdata)); + u->core = c; + + if (mode != O_WRONLY) { + u->source = pa_source_new(c, PA_TYPEID_SOLARIS, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss); + assert(u->source); + u->source->userdata = u; + u->source->get_latency = source_get_latency_cb; + pa_source_set_owner(u->source, m); + u->source->description = pa_sprintf_malloc("Solaris PCM on '%s'", p); + } else + u->source = NULL; + + if (mode != O_RDONLY) { + u->sink = pa_sink_new(c, PA_TYPEID_SOLARIS, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss); + assert(u->sink); + u->sink->get_latency = sink_get_latency_cb; + u->sink->userdata = u; + pa_sink_set_owner(u->sink, m); + u->sink->description = pa_sprintf_malloc("Solaris PCM on '%s'", p); + } else + u->sink = NULL; + + assert(u->source || u->sink); + + u->io = pa_iochannel_new(c->mainloop, u->source ? fd : -1, u->sink ? fd : 0); + assert(u->io); + pa_iochannel_set_callback(u->io, io_callback, u); + u->fd = fd; + + u->memchunk.memblock = NULL; + u->memchunk.length = 0; + u->sample_size = pa_frame_size(&ss); + + u->silence.memblock = pa_memblock_new(u->silence.length = CHUNK_SIZE, u->core->memblock_stat); + assert(u->silence.memblock); + pa_silence_memblock(u->silence.memblock, &ss); + u->silence.index = 0; + + u->written_bytes = 0; + u->read_bytes = 0; + + u->module = m; + m->userdata = u; + + pa_modargs_free(ma); + + return 0; + +fail: + if (fd >= 0) + close(fd); + + if (ma) + pa_modargs_free(ma); + + return -1; +} + +void pa__done(struct pa_core *c, struct pa_module*m) { + struct userdata *u; + assert(c && m); + + if (!(u = m->userdata)) + return; + + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + if (u->silence.memblock) + pa_memblock_unref(u->silence.memblock); + + if (u->sink) { + pa_sink_disconnect(u->sink); + pa_sink_unref(u->sink); + } + + if (u->source) { + pa_source_disconnect(u->source); + pa_source_unref(u->source); + } + + pa_iochannel_free(u->io); + pa_xfree(u); +} diff --git a/polyp/module-tunnel.c b/polyp/module-tunnel.c index 9da87b3d..c6a35ca6 100644 --- a/polyp/module-tunnel.c +++ b/polyp/module-tunnel.c @@ -28,7 +28,6 @@ #include <string.h> #include <errno.h> #include <sys/types.h> -#include <regex.h> #include <stdio.h> #include <stdlib.h> @@ -284,7 +283,7 @@ static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t comman return; } - gettimeofday(&now, NULL); + pa_gettimeofday(&now); if (pa_timeval_cmp(&local, &remote) < 0 && pa_timeval_cmp(&remote, &now)) { /* local and remote seem to have synchronized clocks */ @@ -324,7 +323,7 @@ static void request_latency(struct userdata *u) { pa_tagstruct_putu32(t, tag = u->ctag++); pa_tagstruct_putu32(t, u->channel); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); pa_tagstruct_put_timeval(t, &now); pa_tagstruct_putu64(t, 0); @@ -536,7 +535,7 @@ static void timeout_callback(struct pa_mainloop_api *m, struct pa_time_event*e, request_latency(u); - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += LATENCY_INTERVAL; m->time_restart(e, &ntv); } @@ -650,7 +649,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { pa_source_set_owner(u->source, m); #endif - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += LATENCY_INTERVAL; u->time_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, u); diff --git a/polyp/module-waveout.c b/polyp/module-waveout.c new file mode 100644 index 00000000..4e01bc75 --- /dev/null +++ b/polyp/module-waveout.c @@ -0,0 +1,583 @@ +/* $Id: module-waveout.c 333 2005-01-08 21:36:53Z lennart $ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 <windows.h> +#include <mmsystem.h> +#include <assert.h> + +#include "sink.h" +#include "source.h" +#include "module.h" +#include "mainloop-api.h" +#include "modargs.h" +#include "sample-util.h" +#include "util.h" +#include "log.h" +#include "xmalloc.h" +#include "module-waveout-symdef.h" + +PA_MODULE_AUTHOR("Pierre Ossman") +PA_MODULE_DESCRIPTION("Windows waveOut Sink/Source") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE("sink_name=<name for the sink> source_name=<name for the source> record=<enable source?> playback=<enable sink?> format=<sample format> channels=<number of channels> rate=<sample rate> fragments=<number of fragments> fragment_size=<fragment size>") + +#define PA_TYPEID_WAVEOUT PA_TYPEID_MAKE('W', 'A', 'V', 'E') + +#define DEFAULT_SINK_NAME "wave_output" +#define DEFAULT_SOURCE_NAME "wave_input" + +struct userdata { + struct pa_sink *sink; + struct pa_source *source; + struct pa_core *core; + struct pa_time_event *event; + struct pa_defer_event *defer; + pa_usec_t poll_timeout; + + uint32_t fragments, fragment_size; + + uint32_t free_ofrags, free_ifrags; + + DWORD written_bytes; + + int cur_ohdr, cur_ihdr; + unsigned int oremain; + WAVEHDR *ohdrs, *ihdrs; + struct pa_memchunk silence; + + HWAVEOUT hwo; + HWAVEIN hwi; + struct pa_module *module; + + CRITICAL_SECTION crit; +}; + +static const char* const valid_modargs[] = { + "sink_name", + "source_name", + "record", + "playback", + "fragments", + "fragment_size", + "format", + "rate", + "channels", + NULL +}; + +static void update_usage(struct userdata *u) { + pa_module_set_used(u->module, + (u->sink ? pa_idxset_ncontents(u->sink->inputs) : 0) + + (u->sink ? pa_idxset_ncontents(u->sink->monitor_source->outputs) : 0) + + (u->source ? pa_idxset_ncontents(u->source->outputs) : 0)); +} + +static void do_write(struct userdata *u) +{ + uint32_t free_frags, remain; + struct pa_memchunk memchunk, *cur_chunk; + WAVEHDR *hdr; + MMRESULT res; + + if (!u->sink) + return; + + EnterCriticalSection(&u->crit); + + free_frags = u->free_ofrags; + u->free_ofrags = 0; + + LeaveCriticalSection(&u->crit); + + while (free_frags) { + hdr = &u->ohdrs[u->cur_ohdr]; + if (hdr->dwFlags & WHDR_PREPARED) + waveOutUnprepareHeader(u->hwo, hdr, sizeof(WAVEHDR)); + + remain = u->oremain; + while (remain) { + cur_chunk = &memchunk; + + if (pa_sink_render(u->sink, remain, cur_chunk) < 0) { + /* + * Don't fill with silence unless we're getting close to + * underflowing. + */ + if (free_frags > u->fragments/2) + cur_chunk = &u->silence; + else { + EnterCriticalSection(&u->crit); + + u->free_ofrags += free_frags; + + LeaveCriticalSection(&u->crit); + + u->oremain = remain; + return; + } + } + + assert(cur_chunk->memblock); + assert(cur_chunk->memblock->data); + assert(cur_chunk->length); + + memcpy(hdr->lpData + u->fragment_size - remain, + (char*)cur_chunk->memblock->data + cur_chunk->index, + (cur_chunk->length < remain)?cur_chunk->length:remain); + + remain -= (cur_chunk->length < remain)?cur_chunk->length:remain; + + if (cur_chunk != &u->silence) { + pa_memblock_unref(cur_chunk->memblock); + cur_chunk->memblock = NULL; + } + } + + res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR)); + if (res != MMSYSERR_NOERROR) { + pa_log_error(__FILE__ ": ERROR: Unable to prepare waveOut block: %d\n", + res); + } + res = waveOutWrite(u->hwo, hdr, sizeof(WAVEHDR)); + if (res != MMSYSERR_NOERROR) { + pa_log_error(__FILE__ ": ERROR: Unable to write waveOut block: %d\n", + res); + } + + u->written_bytes += u->fragment_size; + + free_frags--; + u->cur_ohdr++; + u->cur_ohdr %= u->fragments; + u->oremain = u->fragment_size; + } +} + +static void do_read(struct userdata *u) +{ + uint32_t free_frags; + struct pa_memchunk memchunk; + WAVEHDR *hdr; + MMRESULT res; + + if (!u->source) + return; + + EnterCriticalSection(&u->crit); + + free_frags = u->free_ifrags; + u->free_ifrags = 0; + + LeaveCriticalSection(&u->crit); + + while (free_frags) { + hdr = &u->ihdrs[u->cur_ihdr]; + if (hdr->dwFlags & WHDR_PREPARED) + waveInUnprepareHeader(u->hwi, hdr, sizeof(WAVEHDR)); + + if (hdr->dwBytesRecorded) { + memchunk.memblock = pa_memblock_new(hdr->dwBytesRecorded, u->core->memblock_stat); + assert(memchunk.memblock); + + memcpy((char*)memchunk.memblock->data, hdr->lpData, hdr->dwBytesRecorded); + + memchunk.length = memchunk.memblock->length = hdr->dwBytesRecorded; + memchunk.index = 0; + + pa_source_post(u->source, &memchunk); + pa_memblock_unref(memchunk.memblock); + } + + res = waveInPrepareHeader(u->hwi, hdr, sizeof(WAVEHDR)); + if (res != MMSYSERR_NOERROR) { + pa_log_error(__FILE__ ": ERROR: Unable to prepare waveIn block: %d\n", + res); + } + res = waveInAddBuffer(u->hwi, hdr, sizeof(WAVEHDR)); + if (res != MMSYSERR_NOERROR) { + pa_log_error(__FILE__ ": ERROR: Unable to add waveIn block: %d\n", + res); + } + + free_frags--; + u->cur_ihdr++; + u->cur_ihdr %= u->fragments; + } +} + +static void poll_cb(struct pa_mainloop_api*a, struct pa_time_event *e, const struct timeval *tv, void *userdata) { + struct userdata *u = userdata; + struct timeval ntv; + + assert(u); + + update_usage(u); + + do_write(u); + do_read(u); + + pa_gettimeofday(&ntv); + pa_timeval_add(&ntv, u->poll_timeout); + + a->time_restart(e, &ntv); +} + +static void defer_cb(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) { + struct userdata *u = userdata; + + assert(u); + + a->defer_enable(e, 0); + + do_write(u); + do_read(u); +} + +static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) { + struct userdata *u = (struct userdata *)inst; + + if (msg != WOM_DONE) + return; + + EnterCriticalSection(&u->crit); + + u->free_ofrags++; + assert(u->free_ofrags <= u->fragments); + + LeaveCriticalSection(&u->crit); +} + +static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) { + struct userdata *u = (struct userdata *)inst; + + if (msg != WIM_DATA) + return; + + EnterCriticalSection(&u->crit); + + u->free_ifrags++; + assert(u->free_ifrags <= u->fragments); + + LeaveCriticalSection(&u->crit); +} + +static pa_usec_t sink_get_latency_cb(struct pa_sink *s) { + struct userdata *u = s->userdata; + uint32_t free_frags; + MMTIME mmt; + assert(s && u && u->sink); + + memset(&mmt, 0, sizeof(mmt)); + mmt.wType = TIME_BYTES; + if (waveOutGetPosition(u->hwo, &mmt, sizeof(mmt)) == MMSYSERR_NOERROR) + return pa_bytes_to_usec(u->written_bytes - mmt.u.cb, &s->sample_spec); + else { + EnterCriticalSection(&u->crit); + + free_frags = u->free_ofrags; + + LeaveCriticalSection(&u->crit); + + return pa_bytes_to_usec((u->fragments - free_frags) * u->fragment_size, + &s->sample_spec); + } +} + +static pa_usec_t source_get_latency_cb(struct pa_source *s) { + pa_usec_t r = 0; + struct userdata *u = s->userdata; + uint32_t free_frags; + assert(s && u && u->sink); + + EnterCriticalSection(&u->crit); + + free_frags = u->free_ifrags; + + LeaveCriticalSection(&u->crit); + + r += pa_bytes_to_usec((free_frags + 1) * u->fragment_size, &s->sample_spec); + + fprintf(stderr, "Latency: %d us\n", (int)r); + + return r; +} + +static void notify_sink_cb(struct pa_sink *s) { + struct userdata *u = s->userdata; + assert(u); + + u->core->mainloop->defer_enable(u->defer, 1); +} + +static void notify_source_cb(struct pa_source *s) { + struct userdata *u = s->userdata; + assert(u); + + u->core->mainloop->defer_enable(u->defer, 1); +} + +static int ss_to_waveformat(struct pa_sample_spec *ss, LPWAVEFORMATEX wf) { + wf->wFormatTag = WAVE_FORMAT_PCM; + + if (ss->channels > 2) { + pa_log_error(__FILE__": ERROR: More than two channels not supported.\n"); + return -1; + } + + wf->nChannels = ss->channels; + + switch (ss->rate) { + case 8000: + case 11025: + case 22005: + case 44100: + break; + default: + pa_log_error(__FILE__": ERROR: Unsupported sample rate.\n"); + return -1; + } + + wf->nSamplesPerSec = ss->rate; + + if (ss->format == PA_SAMPLE_U8) + wf->wBitsPerSample = 8; + else if (ss->format == PA_SAMPLE_S16NE) + wf->wBitsPerSample = 16; + else { + pa_log_error(__FILE__": ERROR: Unsupported sample format.\n"); + return -1; + } + + wf->nBlockAlign = wf->nChannels * wf->wBitsPerSample/8; + wf->nAvgBytesPerSec = wf->nSamplesPerSec * wf->nBlockAlign; + + wf->cbSize = 0; + + return 0; +} + +int pa__init(struct pa_core *c, struct pa_module*m) { + struct userdata *u = NULL; + HWAVEOUT hwo = INVALID_HANDLE_VALUE; + HWAVEIN hwi = INVALID_HANDLE_VALUE; + WAVEFORMATEX wf; + int nfrags, frag_size; + int record = 1, playback = 1; + struct pa_sample_spec ss; + struct pa_modargs *ma = NULL; + unsigned int i; + struct timeval tv; + + assert(c && m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log(__FILE__": failed to parse module arguments.\n"); + goto fail; + } + + if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { + pa_log(__FILE__": record= and playback= expect boolean argument.\n"); + goto fail; + } + + if (!playback && !record) { + pa_log(__FILE__": neither playback nor record enabled for device.\n"); + goto fail; + } + + nfrags = 20; + frag_size = 1024; + if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { + pa_log(__FILE__": failed to parse fragments arguments\n"); + goto fail; + } + + ss = c->default_sample_spec; + if (pa_modargs_get_sample_spec(ma, &ss) < 0) { + pa_log(__FILE__": failed to parse sample specification\n"); + goto fail; + } + + if (ss_to_waveformat(&ss, &wf) < 0) + goto fail; + + u = pa_xmalloc(sizeof(struct userdata)); + + if (record) { + if (waveInOpen(&hwi, WAVE_MAPPER, &wf, (DWORD_PTR)chunk_ready_cb, (DWORD_PTR)u, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) + goto fail; + if (waveInStart(hwi) != MMSYSERR_NOERROR) + goto fail; + pa_log_debug(__FILE__": Opened waveIn subsystem.\n"); + } + + if (playback) { + if (waveOutOpen(&hwo, WAVE_MAPPER, &wf, (DWORD_PTR)chunk_done_cb, (DWORD_PTR)u, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) + goto fail; + pa_log_debug(__FILE__": Opened waveOut subsystem.\n"); + } + + InitializeCriticalSection(&u->crit); + + if (hwi != INVALID_HANDLE_VALUE) { + u->source = pa_source_new(c, PA_TYPEID_WAVEOUT, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss); + assert(u->source); + u->source->userdata = u; + u->source->notify = notify_source_cb; + u->source->get_latency = source_get_latency_cb; + pa_source_set_owner(u->source, m); + u->source->description = pa_sprintf_malloc("Windows waveIn PCM"); + } else + u->source = NULL; + + if (hwo != INVALID_HANDLE_VALUE) { + u->sink = pa_sink_new(c, PA_TYPEID_WAVEOUT, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss); + assert(u->sink); + u->sink->notify = notify_sink_cb; + u->sink->get_latency = sink_get_latency_cb; + u->sink->userdata = u; + pa_sink_set_owner(u->sink, m); + u->sink->description = pa_sprintf_malloc("Windows waveOut PCM"); + } else + u->sink = NULL; + + assert(u->source || u->sink); + + u->core = c; + u->hwi = hwi; + u->hwo = hwo; + + u->fragments = nfrags; + u->free_ifrags = u->fragments; + u->free_ofrags = u->fragments; + u->fragment_size = frag_size - (frag_size % pa_frame_size(&ss)); + + u->written_bytes = 0; + + u->oremain = u->fragment_size; + + u->poll_timeout = pa_bytes_to_usec(u->fragments * u->fragment_size / 3, &ss); + + pa_gettimeofday(&tv); + pa_timeval_add(&tv, u->poll_timeout); + + u->event = c->mainloop->time_new(c->mainloop, &tv, poll_cb, u); + assert(u->event); + + u->defer = c->mainloop->defer_new(c->mainloop, defer_cb, u); + assert(u->defer); + c->mainloop->defer_enable(u->defer, 0); + + u->cur_ihdr = 0; + u->cur_ohdr = 0; + u->ihdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments); + assert(u->ihdrs); + u->ohdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments); + assert(u->ohdrs); + for (i = 0;i < u->fragments;i++) { + u->ihdrs[i].dwBufferLength = u->fragment_size; + u->ohdrs[i].dwBufferLength = u->fragment_size; + u->ihdrs[i].lpData = pa_xmalloc(u->fragment_size); + assert(u->ihdrs); + u->ohdrs[i].lpData = pa_xmalloc(u->fragment_size); + assert(u->ohdrs); + } + + u->silence.length = u->fragment_size; + u->silence.memblock = pa_memblock_new(u->silence.length, u->core->memblock_stat); + assert(u->silence.memblock); + pa_silence_memblock(u->silence.memblock, &ss); + u->silence.index = 0; + + u->module = m; + m->userdata = u; + + pa_modargs_free(ma); + + return 0; + +fail: + if (hwi != INVALID_HANDLE_VALUE) + waveInClose(hwi); + + if (hwo != INVALID_HANDLE_VALUE) + waveOutClose(hwo); + + if (u) + pa_xfree(u); + + if (ma) + pa_modargs_free(ma); + + return -1; +} + +void pa__done(struct pa_core *c, struct pa_module*m) { + struct userdata *u; + unsigned int i; + + assert(c && m); + + if (!(u = m->userdata)) + return; + + if (u->event) + c->mainloop->time_free(u->event); + + if (u->defer) + c->mainloop->defer_free(u->defer); + + if (u->sink) { + pa_sink_disconnect(u->sink); + pa_sink_unref(u->sink); + } + + if (u->source) { + pa_source_disconnect(u->source); + pa_source_unref(u->source); + } + + if (u->hwi != INVALID_HANDLE_VALUE) { + waveInReset(u->hwi); + waveInClose(u->hwi); + } + + if (u->hwo != INVALID_HANDLE_VALUE) { + waveOutReset(u->hwo); + waveOutClose(u->hwo); + } + + for (i = 0;i < u->fragments;i++) { + pa_xfree(u->ihdrs[i].lpData); + pa_xfree(u->ohdrs[i].lpData); + } + + pa_xfree(u->ihdrs); + pa_xfree(u->ohdrs); + + DeleteCriticalSection(&u->crit); + + pa_xfree(u); +} diff --git a/polyp/module.c b/polyp/module.c index aedaae02..0a3d569b 100644 --- a/polyp/module.c +++ b/polyp/module.c @@ -47,7 +47,7 @@ static void timeout_callback(struct pa_mainloop_api *m, struct pa_time_event*e, pa_module_unload_unused(c); - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += UNLOAD_POLL_TIME; m->time_restart(e, &ntv); } @@ -98,7 +98,7 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char if (!c->module_auto_unload_event) { struct timeval ntv; - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += UNLOAD_POLL_TIME; c->module_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); } diff --git a/polyp/oss-util.c b/polyp/oss-util.c index 8c83cbbf..799bc40a 100644 --- a/polyp/oss-util.c +++ b/polyp/oss-util.c @@ -92,7 +92,7 @@ fail: int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) { int format, channels, speed, reqformat; - static const int format_trans[] = { + static const int format_trans[PA_SAMPLE_MAX] = { [PA_SAMPLE_U8] = AFMT_U8, [PA_SAMPLE_ALAW] = AFMT_A_LAW, [PA_SAMPLE_ULAW] = AFMT_MU_LAW, diff --git a/polyp/pacat.c b/polyp/pacat.c index 5910d13f..1bba2ee4 100644 --- a/polyp/pacat.c +++ b/polyp/pacat.c @@ -480,8 +480,12 @@ int main(int argc, char *argv[]) { assert(r == 0); pa_signal_new(SIGINT, exit_signal_callback, NULL); pa_signal_new(SIGTERM, exit_signal_callback, NULL); +#ifdef SIGUSR1 pa_signal_new(SIGUSR1, sigusr1_signal_callback, NULL); +#endif +#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); +#endif if (!(stdio_event = mainloop_api->io_new(mainloop_api, mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO, diff --git a/polyp/pactl.c b/polyp/pactl.c index 423cce95..725b5460 100644 --- a/polyp/pactl.c +++ b/polyp/pactl.c @@ -739,7 +739,9 @@ int main(int argc, char *argv[]) { r = pa_signal_init(mainloop_api); assert(r == 0); pa_signal_new(SIGINT, exit_signal_callback, NULL); +#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); +#endif if (!(context = pa_context_new(mainloop_api, client_name))) { fprintf(stderr, "pa_context_new() failed.\n"); diff --git a/polyp/paplay.c b/polyp/paplay.c index 2eaf07c1..4ace1973 100644 --- a/polyp/paplay.c +++ b/polyp/paplay.c @@ -338,7 +338,9 @@ int main(int argc, char *argv[]) { r = pa_signal_init(mainloop_api); assert(r == 0); pa_signal_new(SIGINT, exit_signal_callback, NULL); +#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); +#endif /* Create a new connection context */ if (!(context = pa_context_new(mainloop_api, client_name))) { diff --git a/polyp/pdispatch.c b/polyp/pdispatch.c index 7a9e9c68..60dd911c 100644 --- a/polyp/pdispatch.c +++ b/polyp/pdispatch.c @@ -32,6 +32,7 @@ #include "xmalloc.h" #include "llist.h" #include "log.h" +#include "util.h" /*#define DEBUG_OPCODES */ @@ -245,7 +246,7 @@ void pa_pdispatch_register_reply(struct pa_pdispatch *pd, uint32_t tag, int time r->userdata = userdata; r->tag = tag; - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec += timeout; r->time_event = pd->mainloop->time_new(pd->mainloop, &tv, timeout_callback, r); diff --git a/polyp/pid.c b/polyp/pid.c index 2fac687e..ae3dc7f5 100644 --- a/polyp/pid.c +++ b/polyp/pid.c @@ -35,6 +35,10 @@ #include <limits.h> #include <signal.h> +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif + #include "pid.h" #include "util.h" #include "log.h" @@ -130,6 +134,10 @@ int pa_pid_file_create(void) { pid_t pid; size_t l; +#ifdef OS_IS_WIN32 + HANDLE process; +#endif + pa_runtime_path("pid", fn, sizeof(fn)); if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0) @@ -138,7 +146,12 @@ int pa_pid_file_create(void) { if ((pid = read_pid(fn, fd)) == (pid_t) -1) pa_log(__FILE__": corrupt PID file, overwriting.\n"); else if (pid > 0) { +#ifdef OS_IS_WIN32 + if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) { + CloseHandle(process); +#else if (kill(pid, 0) >= 0 || errno != ESRCH) { +#endif pa_log(__FILE__": daemon already running.\n"); goto fail; } @@ -198,6 +211,12 @@ int pa_pid_file_remove(void) { goto fail; } +#ifdef OS_IS_WIN32 + pa_lock_fd(fd, 0); + close(fd); + fd = -1; +#endif + if (unlink(fn) < 0) { pa_log(__FILE__": failed to remove PID file '%s': %s\n", fn, strerror(errno)); goto fail; @@ -223,6 +242,8 @@ int pa_pid_file_check_running(pid_t *pid) { return pa_pid_file_kill(0, pid); } +#ifndef OS_IS_WIN32 + /* Kill a current running daemon. Return non-zero on success, -1 * otherwise. If successful *pid contains the PID of the daemon * process. */ @@ -242,7 +263,7 @@ int pa_pid_file_kill(int sig, pid_t *pid) { if ((*pid = read_pid(fn, fd)) == (pid_t) -1) goto fail; - + ret = kill(*pid, sig); fail: @@ -255,3 +276,11 @@ fail: return ret; } + +#else /* OS_IS_WIN32 */ + +int pa_pid_file_kill(int sig, pid_t *pid) { + return -1; +} + +#endif diff --git a/polyp/poll.c b/polyp/poll.c new file mode 100644 index 00000000..6a260daf --- /dev/null +++ b/polyp/poll.c @@ -0,0 +1,190 @@ +/* $Id: mainloop.c 302 2004-11-21 17:02:25Z lennart $ */ + +/*** + Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 2005, Cendio AB. + This file is part of polypaudio. + Based on work for the GNU C Library. + + polypaudio is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + polypaudio 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with polypaudio; If not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. +***/ + +/* Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> + +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +#include "winsock.h" + +#ifndef HAVE_SYS_POLL_H + +#include "util.h" +#include "poll.h" + +int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { + struct timeval tv; + fd_set rset, wset, xset; + struct pollfd *f; + int ready; + int maxfd = 0; + char data[64]; + + FD_ZERO (&rset); + FD_ZERO (&wset); + FD_ZERO (&xset); + + if (nfds == 0) { + if (timeout >= 0) { + pa_msleep(timeout); + return 0; + } + +#ifdef OS_IS_WIN32 + /* + * Windows does not support signals properly so waiting for them would + * mean a deadlock. + */ + pa_msleep(100); + return 0; +#else + return select(0, NULL, NULL, NULL, NULL); +#endif + } + + for (f = fds; f < &fds[nfds]; ++f) { + if (f->fd != -1) { + if (f->events & POLLIN) + FD_SET (f->fd, &rset); + if (f->events & POLLOUT) + FD_SET (f->fd, &wset); + if (f->events & POLLPRI) + FD_SET (f->fd, &xset); + if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) + maxfd = f->fd; + } + } + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset, + SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, + SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv)); + if ((ready == -1) && (errno == EBADF)) { + ready = 0; + + FD_ZERO (&rset); + FD_ZERO (&wset); + FD_ZERO (&xset); + + maxfd = -1; + + for (f = fds; f < &fds[nfds]; ++f) { + if (f->fd != -1) { + fd_set sngl_rset, sngl_wset, sngl_xset; + + FD_ZERO (&sngl_rset); + FD_ZERO (&sngl_wset); + FD_ZERO (&sngl_xset); + + if (f->events & POLLIN) + FD_SET (f->fd, &sngl_rset); + if (f->events & POLLOUT) + FD_SET (f->fd, &sngl_wset); + if (f->events & POLLPRI) + FD_SET (f->fd, &sngl_xset); + if (f->events & (POLLIN|POLLOUT|POLLPRI)) { + struct timeval singl_tv; + + singl_tv.tv_sec = 0; + singl_tv.tv_usec = 0; + + if (select((SELECT_TYPE_ARG1) f->fd, SELECT_TYPE_ARG234 &rset, + SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, + SELECT_TYPE_ARG5 &singl_tv) != -1) { + if (f->events & POLLIN) + FD_SET (f->fd, &rset); + if (f->events & POLLOUT) + FD_SET (f->fd, &wset); + if (f->events & POLLPRI) + FD_SET (f->fd, &xset); + if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) + maxfd = f->fd; + ++ready; + } else if (errno == EBADF) + f->revents |= POLLNVAL; + } + } + } + + if (ready) { + /* Linux alters the tv struct... but it shouldn't matter here ... + * as we're going to be a little bit out anyway as we've just eaten + * more than a couple of cpu cycles above */ + ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset, + SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, + SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv)); + } + } + +#ifdef OS_IS_WIN32 + errno = WSAGetLastError(); +#endif + + if (ready > 0) { + ready = 0; + for (f = fds; f < &fds[nfds]; ++f) { + f->revents = 0; + if (f->fd != -1) { + if (FD_ISSET (f->fd, &rset)) { + /* support for POLLHUP. An hung up descriptor does not + increase the return value! */ + if (recv (f->fd, data, 64, MSG_PEEK) == -1) { + if (errno == ESHUTDOWN || errno == ECONNRESET || + errno == ECONNABORTED || errno == ENETRESET) { + fprintf(stderr, "Hangup\n"); + f->revents |= POLLHUP; + } + } + + if (f->revents == 0) + f->revents |= POLLIN; + } + if (FD_ISSET (f->fd, &wset)) + f->revents |= POLLOUT; + if (FD_ISSET (f->fd, &xset)) + f->revents |= POLLPRI; + } + if (f->revents) + ready++; + } + } + + return ready; +} + +#endif /* HAVE_SYS_POLL_H */ diff --git a/polyp/poll.h b/polyp/poll.h new file mode 100644 index 00000000..573f90ea --- /dev/null +++ b/polyp/poll.h @@ -0,0 +1,57 @@ +/* $Id: mainloop.c 302 2004-11-21 17:02:25Z lennart $ */ + +/*** + Compatibility definitions for System V `poll' interface. + Copyright (C) 1994,96,97,98,99,2000,2001,2004 Free Software Foundation, Inc. + Copyright (C) 2005, Cendio AB. + This file is part of polypaudio. + Based on work for the GNU C Library. + + polypaudio is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + polypaudio 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with polypaudio; If not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. +***/ + +/* Event types that can be polled for. These bits may be set in `events' + to indicate the interesting event types; they will appear in `revents' + to indicate the status of the file descriptor. */ +#define POLLIN 0x001 /* There is data to read. */ +#define POLLPRI 0x002 /* There is urgent data to read. */ +#define POLLOUT 0x004 /* Writing now will not block. */ + +/* Event types always implicitly polled for. These bits need not be set in + `events', but they will appear in `revents' to indicate the status of + the file descriptor. */ +#define POLLERR 0x008 /* Error condition. */ +#define POLLHUP 0x010 /* Hung up. */ +#define POLLNVAL 0x020 /* Invalid polling request. */ + + +/* Type used for the number of file descriptors. */ +typedef unsigned long int nfds_t; + +/* Data structure describing a polling request. */ +struct pollfd + { + int fd; /* File descriptor to poll. */ + short int events; /* Types of events poller cares about. */ + short int revents; /* Types of events that actually occurred. */ + }; + +/* Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors. */ +extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); diff --git a/polyp/polyplib-context.c b/polyp/polyplib-context.c index bca7d7ea..f97d9b82 100644 --- a/polyp/polyplib-context.c +++ b/polyp/polyplib-context.c @@ -28,13 +28,24 @@ #include <stdlib.h> #include <string.h> #include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> #include <unistd.h> #include <sys/stat.h> #include <errno.h> -#include <sys/wait.h> #include <signal.h> +#include <limits.h> + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +#include "winsock.h" #include "polyplib-internal.h" #include "polyplib-context.h" @@ -110,8 +121,10 @@ struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char * c->autospawn_lock_fd = -1; memset(&c->spawn_api, 0, sizeof(c->spawn_api)); c->do_autospawn = 0; - + +#ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); +#endif c->conf = pa_client_conf_new(); pa_client_conf_load(c->conf, NULL); @@ -372,6 +385,8 @@ finish: static void on_connection(struct pa_socket_client *client, struct pa_iochannel*io, void *userdata); +#ifndef OS_IS_WIN32 + static int context_connect_spawn(struct pa_context *c) { pid_t pid; int status, r; @@ -485,6 +500,8 @@ fail: return -1; } +#endif /* OS_IS_WIN32 */ + static int try_next_connection(struct pa_context *c) { char *u = NULL; int r = -1; @@ -499,10 +516,12 @@ static int try_next_connection(struct pa_context *c) { if (!u) { +#ifndef OS_IS_WIN32 if (c->do_autospawn) { r = context_connect_spawn(c); goto finish; } +#endif pa_context_fail(c, PA_ERROR_CONNECTIONREFUSED); goto finish; diff --git a/polyp/polyplib-internal.h b/polyp/polyplib-internal.h index d1b3a27f..8677c813 100644 --- a/polyp/polyplib-internal.h +++ b/polyp/polyplib-internal.h @@ -93,6 +93,7 @@ struct pa_stream { uint32_t requested_bytes; uint64_t counter; pa_usec_t previous_time; + pa_usec_t previous_ipol_time; enum pa_stream_state state; struct pa_mcalign *mcalign; diff --git a/polyp/polyplib-stream.c b/polyp/polyplib-stream.c index 6a73c608..b6a091b3 100644 --- a/polyp/polyplib-stream.c +++ b/polyp/polyplib-stream.c @@ -66,6 +66,7 @@ struct pa_stream *pa_stream_new(struct pa_context *c, const char *name, const st s->counter = 0; s->previous_time = 0; + s->previous_ipol_time = 0; s->corked = 0; s->interpolate = 0; @@ -217,7 +218,7 @@ static void ipol_callback(struct pa_mainloop_api *m, struct pa_time_event *e, co s->ipol_requested = 1; } - gettimeofday(&tv2, NULL); + pa_gettimeofday(&tv2); pa_timeval_add(&tv2, LATENCY_IPOL_INTERVAL_USEC); m->time_restart(e, &tv2); @@ -256,7 +257,7 @@ void pa_create_stream_callback(struct pa_pdispatch *pd, uint32_t command, uint32 struct timeval tv; pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ assert(!s->ipol_event); @@ -412,7 +413,7 @@ static void stream_get_latency_info_callback(struct pa_pdispatch *pd, uint32_t c pa_context_fail(o->context, PA_ERROR_PROTOCOL); goto finish; } else { - gettimeofday(&now, NULL); + pa_gettimeofday(&now); if (pa_timeval_cmp(&local, &remote) <= 0 && pa_timeval_cmp(&remote, &now) <= 0) { /* local and remote seem to have synchronized clocks */ @@ -470,7 +471,7 @@ struct pa_operation* pa_stream_get_latency_info(struct pa_stream *s, void (*cb)( pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, s->channel); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); pa_tagstruct_put_timeval(t, &now); pa_tagstruct_putu64(t, s->counter); @@ -581,7 +582,7 @@ struct pa_operation* pa_stream_cork(struct pa_stream *s, int b, void (*cb) (stru s->ipol_usec = pa_stream_get_interpolated_time(s); else if (s->corked && !b) /* Unpausing */ - gettimeofday(&s->ipol_timestamp, NULL); + pa_gettimeofday(&s->ipol_timestamp); } s->corked = b; @@ -702,7 +703,7 @@ pa_usec_t pa_stream_get_time(struct pa_stream *s, const struct pa_latency_info * usec = s->previous_time; s->previous_time = usec; - + return usec; } @@ -762,10 +763,11 @@ pa_usec_t pa_stream_get_interpolated_time(struct pa_stream *s) { usec = s->ipol_usec + pa_timeval_age(&s->ipol_timestamp); } - if (usec < s->previous_time) - usec = s->previous_time; + if (usec < s->previous_ipol_time) + usec = s->previous_ipol_time; + + s->previous_ipol_time = usec; - s->previous_time = usec; return usec; } diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c index d99b721c..18ecb0ac 100644 --- a/polyp/protocol-esound.c +++ b/polyp/protocol-esound.c @@ -239,11 +239,14 @@ static void* connection_write(struct connection *c, size_t length) { return (uint8_t*) c->write_data+i; } -static void format_esd2native(int format, struct pa_sample_spec *ss) { +static void format_esd2native(int format, int swap_bytes, struct pa_sample_spec *ss) { assert(ss); ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; - ss->format = ((format & ESD_MASK_BITS) == ESD_BITS16) ? PA_SAMPLE_S16NE : PA_SAMPLE_U8; + if ((format & ESD_MASK_BITS) == ESD_BITS16) + ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE; + else + ss->format = PA_SAMPLE_U8; } static int format_native2esd(struct pa_sample_spec *ss) { @@ -303,7 +306,7 @@ static int esd_proto_stream_play(struct connection *c, esd_proto_t request, cons rate = maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1)); ss.rate = rate; - format_esd2native(format, &ss); + format_esd2native(format, c->swap_byte_order, &ss); if (!pa_sample_spec_valid(&ss)) { pa_log(__FILE__": invalid sample specification\n"); @@ -359,7 +362,7 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co rate = maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1)); ss.rate = rate; - format_esd2native(format, &ss); + format_esd2native(format, c->swap_byte_order, &ss); if (!pa_sample_spec_valid(&ss)) { pa_log(__FILE__": invalid sample specification.\n"); @@ -426,7 +429,6 @@ static int esd_proto_get_latency(struct connection *c, esd_proto_t request, cons latency = 0; else { double usec = pa_sink_get_latency(sink); - usec += PLAYBACK_BUFFER_SECONDS*1000000; /* A better estimation would be a good idea! */ latency = (int) ((usec*44100)/1000000); } @@ -603,7 +605,7 @@ static int esd_proto_sample_cache(struct connection *c, esd_proto_t request, con rate = maybe_swap_endian_32(c->swap_byte_order, *((int*)data + 1)); ss.rate = rate; - format_esd2native(format, &ss); + format_esd2native(format, c->swap_byte_order, &ss); sc_length = (size_t) maybe_swap_endian_32(c->swap_byte_order, (*((int*)data + 2))); @@ -1099,7 +1101,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo if (!c->authorized) { struct timeval tv; - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec += AUTH_TIMEOUT; c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c); } else diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 7e1a8894..90dbdaf5 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -928,7 +928,7 @@ static void command_get_playback_latency(struct pa_pdispatch *pd, uint32_t comma pa_tagstruct_put_boolean(reply, pa_memblockq_is_readable(s->memblockq)); pa_tagstruct_putu32(reply, pa_memblockq_get_length(s->memblockq)); pa_tagstruct_put_timeval(reply, &tv); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); pa_tagstruct_put_timeval(reply, &now); pa_tagstruct_putu64(reply, counter); pa_pstream_send_tagstruct(c->pstream, reply); @@ -971,7 +971,7 @@ static void command_get_record_latency(struct pa_pdispatch *pd, uint32_t command pa_tagstruct_put_boolean(reply, 0); pa_tagstruct_putu32(reply, pa_memblockq_get_length(s->memblockq)); pa_tagstruct_put_timeval(reply, &tv); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); pa_tagstruct_put_timeval(reply, &now); pa_tagstruct_putu64(reply, counter); pa_pstream_send_tagstruct(c->pstream, reply); @@ -2024,7 +2024,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo if (!c->authorized) { struct timeval tv; - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); tv.tv_sec += AUTH_TIMEOUT; c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c); } else diff --git a/polyp/pstream.c b/polyp/pstream.c index c081c242..6f983289 100644 --- a/polyp/pstream.c +++ b/polyp/pstream.c @@ -27,7 +27,12 @@ #include <stdlib.h> #include <assert.h> #include <unistd.h> + +#ifdef HAVE_NETINET_IN_H #include <netinet/in.h> +#endif + +#include "winsock.h" #include "pstream.h" #include "queue.h" diff --git a/polyp/random.c b/polyp/random.c index 456954a2..12f27bfd 100644 --- a/polyp/random.c +++ b/polyp/random.c @@ -19,6 +19,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <fcntl.h> #include <unistd.h> #include <errno.h> @@ -31,13 +35,16 @@ #include "util.h" #include "log.h" +#ifndef OS_IS_WIN32 #define RANDOM_DEVICE "/dev/urandom" +#endif void pa_random(void *ret_data, size_t length) { int fd; ssize_t r = 0; assert(ret_data && length); - + +#ifdef RANDOM_DEVICE if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) { if ((r = pa_loop_read(fd, ret_data, length)) < 0 || (size_t) r != length) @@ -45,17 +52,20 @@ void pa_random(void *ret_data, size_t length) { close(fd); } +#endif if ((size_t) r != length) { uint8_t *p; size_t l; - + +#ifdef RANDOM_DEVICE pa_log_warn(__FILE__": WARNING: Failed to open entropy device '"RANDOM_DEVICE"': %s" ", falling back to unsecure pseudo RNG.\n", strerror(errno)); +#endif - srandom(time(NULL)); + srand(time(NULL)); for (p = ret_data, l = length; l > 0; p++, l--) - *p = (uint8_t) random(); + *p = (uint8_t) rand(); } } diff --git a/polyp/sample-util.c b/polyp/sample-util.c index d521afe4..bf8be34e 100644 --- a/polyp/sample-util.c +++ b/polyp/sample-util.c @@ -161,7 +161,7 @@ size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, siz size_t d; for (d = 0;; d += sizeof(float)) { - float_t sum = 0; + pa_volume_t sum = 0; unsigned c; if (d >= length) diff --git a/polyp/sample.h b/polyp/sample.h index 0494c7de..82c14615 100644 --- a/polyp/sample.h +++ b/polyp/sample.h @@ -51,11 +51,19 @@ enum pa_sample_format { #define PA_SAMPLE_S16NE PA_SAMPLE_S16BE /** 32 Bit IEEE floating point, native endian */ #define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32BE +/** Signed 16 Bit PCM reverse endian */ +#define PA_SAMPLE_S16RE PA_SAMPLE_S16LE +/** 32 Bit IEEE floating point, reverse endian */ +#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32LE #else /** Signed 16 Bit PCM, native endian */ #define PA_SAMPLE_S16NE PA_SAMPLE_S16LE /** 32 Bit IEEE floating point, native endian */ #define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE +/** Signed 16 Bit PCM reverse endian */ +#define PA_SAMPLE_S16RE PA_SAMPLE_S16BE +/** 32 Bit IEEE floating point, reverse endian */ +#define PA_SAMPLE_FLOAT32RE PA_SAMPLE_FLOAT32BE #endif /** A Shortcut for PA_SAMPLE_FLOAT32NE */ diff --git a/polyp/scache.c b/polyp/scache.c index ccdc7185..2953145d 100644 --- a/polyp/scache.c +++ b/polyp/scache.c @@ -32,7 +32,14 @@ #include <sys/stat.h> #include <errno.h> #include <limits.h> + +#ifdef HAVE_GLOB_H #include <glob.h> +#endif + +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif #include "scache.h" #include "sink-input.h" @@ -55,7 +62,7 @@ static void timeout_callback(struct pa_mainloop_api *m, struct pa_time_event*e, pa_scache_unload_unused(c); - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += UNLOAD_POLL_TIME; m->time_restart(e, &ntv); } @@ -144,6 +151,13 @@ int pa_scache_add_file(struct pa_core *c, const char *name, const char *filename struct pa_memchunk chunk; int r; +#ifdef OS_IS_WIN32 + char buf[MAX_PATH]; + + if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) + filename = buf; +#endif + if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0) return -1; @@ -155,6 +169,14 @@ int pa_scache_add_file(struct pa_core *c, const char *name, const char *filename int pa_scache_add_file_lazy(struct pa_core *c, const char *name, const char *filename, uint32_t *index) { struct pa_scache_entry *e; + +#ifdef OS_IS_WIN32 + char buf[MAX_PATH]; + + if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) + filename = buf; +#endif + assert(c && name); if (!(e = scache_add_item(c, name))) @@ -165,7 +187,7 @@ int pa_scache_add_file_lazy(struct pa_core *c, const char *name, const char *fil if (!c->scache_auto_unload_event) { struct timeval ntv; - gettimeofday(&ntv, NULL); + pa_gettimeofday(&ntv); ntv.tv_sec += UNLOAD_POLL_TIME; c->scache_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); } @@ -303,17 +325,16 @@ static void add_file(struct pa_core *c, const char *pathname) { struct stat st; const char *e; - if (!(e = strrchr(pathname, '/'))) - e = pathname; - else - e++; + e = pa_path_get_filename(pathname); if (stat(pathname, &st) < 0) { pa_log(__FILE__": stat('%s') failed: %s\n", pathname, strerror(errno)); return; } +#if defined(S_ISREG) && defined(S_ISLNK) if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) +#endif pa_scache_add_file_lazy(c, e, pathname, NULL); } @@ -323,6 +344,7 @@ int pa_scache_add_directory_lazy(struct pa_core *c, const char *pathname) { /* First try to open this as directory */ if (!(dir = opendir(pathname))) { +#ifdef HAVE_GLOB_H glob_t p; unsigned int i; /* If that fails, try to open it as shell glob */ @@ -336,6 +358,9 @@ int pa_scache_add_directory_lazy(struct pa_core *c, const char *pathname) { add_file(c, p.gl_pathv[i]); globfree(&p); +#else + return -1; +#endif } else { struct dirent *e; diff --git a/polyp/socket-client.c b/polyp/socket-client.c index 21563d35..51134b84 100644 --- a/polyp/socket-client.c +++ b/polyp/socket-client.c @@ -31,14 +31,29 @@ #include <string.h> #include <assert.h> #include <stdlib.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_UN_H #include <sys/un.h> -#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_NETDB_H #include <netdb.h> +#endif + #ifdef HAVE_LIBASYNCNS #include <asyncns.h> #endif +#include "winsock.h" + #include "socket-client.h" #include "socket-util.h" #include "util.h" @@ -120,7 +135,7 @@ static void do_call(struct pa_socket_client *c) { goto finish; lerror = sizeof(error); - if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &error, &lerror) < 0) { + if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &lerror) < 0) { pa_log(__FILE__": getsockopt(): %s\n", strerror(errno)); goto finish; } @@ -198,18 +213,28 @@ struct pa_socket_client* pa_socket_client_new_ipv4(struct pa_mainloop_api *m, ui return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); } +#ifdef HAVE_SYS_UN_H + struct pa_socket_client* pa_socket_client_new_unix(struct pa_mainloop_api *m, const char *filename) { struct sockaddr_un sa; assert(m && filename); memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_LOCAL; + sa.sun_family = AF_UNIX; strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1); sa.sun_path[sizeof(sa.sun_path) - 1] = 0; return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); } +#else /* HAVE_SYS_UN_H */ + +struct pa_socket_client* pa_socket_client_new_unix(struct pa_mainloop_api *m, const char *filename) { + return NULL; +} + +#endif /* HAVE_SYS_UN_H */ + static int sockaddr_prepare(struct pa_socket_client *c, const struct sockaddr *sa, size_t salen) { assert(c); assert(sa); @@ -377,7 +402,7 @@ static void start_timeout(struct pa_socket_client *c) { assert(c); assert(!c->timeout_event); - gettimeofday(&tv, NULL); + pa_gettimeofday(&tv); pa_timeval_add(&tv, CONNECT_TIMEOUT * 1000000); c->timeout_event = c->mainloop->time_new(c->mainloop, &tv, timeout_cb, c); } @@ -426,8 +451,9 @@ struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m, assert(c->asyncns_query); start_timeout(c); } -#else +#else /* HAVE_LIBASYNCNS */ { +#ifdef HAVE_GETADDRINFO int ret; struct addrinfo *res = NULL; @@ -438,12 +464,37 @@ struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m, if (res->ai_addr) { if ((c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen))) - start_timeout(c); + start_timeout(c); } freeaddrinfo(res); +#else /* HAVE_GETADDRINFO */ + struct hostent *host = NULL; + struct sockaddr_in s; + + /* FIXME: PF_INET6 support */ + if (hints.ai_family != PF_INET) + goto finish; + + host = gethostbyname(a.path_or_host); + if (!host) { + unsigned int addr = inet_addr(a.path_or_host); + if (addr != INADDR_NONE) + host = gethostbyaddr((char*)&addr, 4, AF_INET); + } + + if (!host) + goto finish; + + s.sin_family = AF_INET; + memcpy(&s.sin_addr, host->h_addr, sizeof(struct in_addr)); + s.sin_port = port; + + if ((c = pa_socket_client_new_sockaddr(m, &s, sizeof(s)))) + start_timeout(c); +#endif /* HAVE_GETADDRINFO */ } -#endif +#endif /* HAVE_LIBASYNCNS */ } } diff --git a/polyp/socket-client.h b/polyp/socket-client.h index 9c3e0b37..b8c73ed8 100644 --- a/polyp/socket-client.h +++ b/polyp/socket-client.h @@ -23,11 +23,12 @@ ***/ #include <inttypes.h> -#include <sys/socket.h> #include "mainloop-api.h" #include "iochannel.h" +struct sockaddr; + struct pa_socket_client; struct pa_socket_client* pa_socket_client_new_ipv4(struct pa_mainloop_api *m, uint32_t address, uint16_t port); diff --git a/polyp/socket-server.c b/polyp/socket-server.c index e67a9daa..a78f04cd 100644 --- a/polyp/socket-server.c +++ b/polyp/socket-server.c @@ -28,17 +28,36 @@ #include <errno.h> #include <string.h> #include <sys/types.h> -#include <sys/socket.h> #include <stdio.h> #include <unistd.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_UN_H #include <sys/un.h> -#include <netinet/in.h> +#ifndef SUN_LEN +#define SUN_LEN(ptr) \ + ((size_t)(((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path)) +#endif +#endif +#ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif #ifdef HAVE_LIBWRAP #include <tcpd.h> #endif +#ifndef HAVE_INET_NTOP +#include "inet_ntop.h" +#endif + +#include "winsock.h" + #include "socket-server.h" #include "socket-util.h" #include "xmalloc.h" @@ -137,6 +156,8 @@ struct pa_socket_server* pa_socket_server_ref(struct pa_socket_server *s) { return s; } +#ifdef HAVE_SYS_UN_H + struct pa_socket_server* pa_socket_server_new_unix(struct pa_mainloop_api *m, const char *filename) { int fd = -1; struct sockaddr_un sa; @@ -144,14 +165,14 @@ struct pa_socket_server* pa_socket_server_new_unix(struct pa_mainloop_api *m, co assert(m && filename); - if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log(__FILE__": socket(): %s\n", strerror(errno)); goto fail; } pa_fd_set_cloexec(fd, 1); - sa.sun_family = AF_LOCAL; + sa.sun_family = AF_UNIX; strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1); sa.sun_path[sizeof(sa.sun_path) - 1] = 0; @@ -182,6 +203,14 @@ fail: return NULL; } +#else /* HAVE_SYS_UN_H */ + +struct pa_socket_server* pa_socket_server_new_unix(struct pa_mainloop_api *m, const char *filename) { + return NULL; +} + +#endif /* HAVE_SYS_UN_H */ + struct pa_socket_server* pa_socket_server_new_ipv4(struct pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service) { struct pa_socket_server *ss; int fd = -1; @@ -197,7 +226,7 @@ struct pa_socket_server* pa_socket_server_new_ipv4(struct pa_mainloop_api *m, ui pa_fd_set_cloexec(fd, 1); - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) pa_log(__FILE__": setsockopt(): %s\n", strerror(errno)); pa_socket_tcp_low_delay(fd); @@ -246,7 +275,7 @@ struct pa_socket_server* pa_socket_server_new_ipv6(struct pa_mainloop_api *m, ui pa_fd_set_cloexec(fd, 1); - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) pa_log(__FILE__": setsockopt(): %s\n", strerror(errno)); pa_socket_tcp_low_delay(fd); @@ -314,9 +343,9 @@ char *pa_socket_server_get_address(struct pa_socket_server *s, char *c, size_t l switch (s->type) { case SOCKET_SERVER_IPV6: { struct sockaddr_in6 sa; - socklen_t l = sizeof(sa); + socklen_t sa_len = sizeof(sa); - if (getsockname(s->fd, (struct sockaddr*) &sa, &l) < 0) { + if (getsockname(s->fd, (struct sockaddr*) &sa, &sa_len) < 0) { pa_log(__FILE__": getsockname() failed: %s\n", strerror(errno)); return NULL; } @@ -350,9 +379,9 @@ char *pa_socket_server_get_address(struct pa_socket_server *s, char *c, size_t l case SOCKET_SERVER_IPV4: { struct sockaddr_in sa; - socklen_t l = sizeof(sa); + socklen_t sa_len = sizeof(sa); - if (getsockname(s->fd, &sa, &l) < 0) { + if (getsockname(s->fd, (struct sockaddr*) &sa, &sa_len) < 0) { pa_log(__FILE__": getsockname() failed: %s\n", strerror(errno)); return NULL; } diff --git a/polyp/socket-util.c b/polyp/socket-util.c index 495ee1b0..381502b5 100644 --- a/polyp/socket-util.c +++ b/polyp/socket-util.c @@ -31,16 +31,33 @@ #include <string.h> #include <stdio.h> #include <sys/types.h> -#include <sys/un.h> -#include <netinet/in.h> #include <fcntl.h> #include <unistd.h> +#include <sys/stat.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H #include <netinet/in_systm.h> -#include <netinet/tcp.h> +#endif +#ifdef HAVE_NETINET_IP_H #include <netinet/ip.h> -#include <sys/socket.h> -#include <sys/stat.h> +#endif +#ifdef HAVE_NETINET_TCP_H +#include <netinet/tcp.h> +#endif +#ifdef HAVE_NETDB_H #include <netdb.h> +#endif + +#include "winsock.h" #include "socket-util.h" #include "util.h" @@ -57,6 +74,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { return; } +#ifndef OS_IS_WIN32 if (S_ISSOCK(st.st_mode)) { union { struct sockaddr sa; @@ -77,7 +95,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { ip & 0xFF, ntohs(sa.in.sin_port)); return; - } else if (sa.sa.sa_family == AF_LOCAL) { + } else if (sa.sa.sa_family == AF_UNIX) { snprintf(c, l, "UNIX socket client"); return; } @@ -89,17 +107,18 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { snprintf(c, l, "STDIN/STDOUT client"); return; } +#endif /* OS_IS_WIN32 */ snprintf(c, l, "Unknown client"); } int pa_socket_low_delay(int fd) { +#ifdef SO_PRIORITY int priority; assert(fd >= 0); -#ifdef SO_PRIORITY priority = 7; - if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) return -1; #endif @@ -114,12 +133,13 @@ int pa_socket_tcp_low_delay(int fd) { ret = pa_socket_low_delay(fd); on = 1; + tos = 0; #if defined(SOL_TCP) || defined(IPPROTO_TCP) #if defined(SOL_TCP) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) #else - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) #endif ret = -1; #endif @@ -128,9 +148,9 @@ int pa_socket_tcp_low_delay(int fd) { defined(IPPROTO_IP)) tos = IPTOS_LOWDELAY; #ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0) + if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #endif ret = -1; #endif @@ -142,7 +162,7 @@ int pa_socket_tcp_low_delay(int fd) { int pa_socket_set_rcvbuf(int fd, size_t l) { assert(fd >= 0); -/* if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &l, sizeof(l)) < 0) { */ +/* if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&l, sizeof(l)) < 0) { */ /* pa_log(__FILE__": SO_RCVBUF: %s\n", strerror(errno)); */ /* return -1; */ /* } */ @@ -153,7 +173,7 @@ int pa_socket_set_rcvbuf(int fd, size_t l) { int pa_socket_set_sndbuf(int fd, size_t l) { assert(fd >= 0); -/* if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &l, sizeof(l)) < 0) { */ +/* if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&l, sizeof(l)) < 0) { */ /* pa_log(__FILE__": SO_SNDBUF: %s\n", strerror(errno)); */ /* return -1; */ /* } */ @@ -161,16 +181,18 @@ int pa_socket_set_sndbuf(int fd, size_t l) { return 0; } +#ifdef HAVE_SYS_UN_H + int pa_unix_socket_is_stale(const char *fn) { struct sockaddr_un sa; int fd = -1, ret = -1; - if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log(__FILE__": socket(): %s\n", strerror(errno)); goto finish; } - sa.sun_family = AF_LOCAL; + sa.sun_family = AF_UNIX; strncpy(sa.sun_path, fn, sizeof(sa.sun_path)-1); sa.sun_path[sizeof(sa.sun_path) - 1] = 0; @@ -202,3 +224,15 @@ int pa_unix_socket_remove_stale(const char *fn) { return 0; } + +#else /* HAVE_SYS_UN_H */ + +int pa_unix_socket_is_stale(const char *fn) { + return -1; +} + +int pa_unix_socket_remove_stale(const char *fn) { + return -1; +} + +#endif /* HAVE_SYS_UN_H */ diff --git a/polyp/tagstruct.c b/polyp/tagstruct.c index a6dad868..1ff09cd1 100644 --- a/polyp/tagstruct.c +++ b/polyp/tagstruct.c @@ -27,9 +27,14 @@ #include <string.h> #include <unistd.h> #include <sys/time.h> -#include <netinet/in.h> #include <assert.h> +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#include "winsock.h" + #include "tagstruct.h" #include "xmalloc.h" @@ -118,7 +123,8 @@ void pa_tagstruct_putu32(struct pa_tagstruct*t, uint32_t i) { assert(t); extend(t, 5); t->data[t->length] = TAG_U32; - *((uint32_t*) (t->data+t->length+1)) = htonl(i); + i = htonl(i); + memcpy(t->data+t->length+1, &i, 4); t->length += 5; } @@ -131,21 +137,25 @@ void pa_tagstruct_putu8(struct pa_tagstruct*t, uint8_t c) { } void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample_spec *ss) { + uint32_t rate; assert(t && ss); extend(t, 7); t->data[t->length] = TAG_SAMPLE_SPEC; t->data[t->length+1] = (uint8_t) ss->format; t->data[t->length+2] = ss->channels; - *(uint32_t*) (t->data+t->length+3) = htonl(ss->rate); + rate = htonl(ss->rate); + memcpy(t->data+t->length+3, &rate, 4); t->length += 7; } void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t length) { + uint32_t tmp; assert(t && p); extend(t, 5+length); t->data[t->length] = TAG_ARBITRARY; - *((uint32_t*) (t->data+t->length+1)) = htonl(length); + tmp = htonl(length); + memcpy(t->data+t->length+1, &tmp, 4); if (length) memcpy(t->data+t->length+5, p, length); t->length += 5+length; @@ -159,29 +169,38 @@ void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b) { } void pa_tagstruct_put_timeval(struct pa_tagstruct*t, const struct timeval *tv) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_TIMEVAL; - *((uint32_t*) (t->data+t->length+1)) = htonl(tv->tv_sec); - *((uint32_t*) (t->data+t->length+5)) = htonl(tv->tv_usec); + tmp = htonl(tv->tv_sec); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl(tv->tv_usec); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } void pa_tagstruct_put_usec(struct pa_tagstruct*t, pa_usec_t u) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_USEC; - *((uint32_t*) (t->data+t->length+1)) = htonl((uint32_t) (u >> 32)); - *((uint32_t*) (t->data+t->length+5)) = htonl((uint32_t) u); + tmp = htonl((uint32_t) (u >> 32)); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl((uint32_t) u); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } void pa_tagstruct_putu64(struct pa_tagstruct*t, uint64_t u) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_U64; - *((uint32_t*) (t->data+t->length+1)) = htonl((uint32_t) (u >> 32)); - *((uint32_t*) (t->data+t->length+5)) = htonl((uint32_t) u); + tmp = htonl((uint32_t) (u >> 32)); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl((uint32_t) u); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } @@ -230,8 +249,9 @@ int pa_tagstruct_getu32(struct pa_tagstruct*t, uint32_t *i) { if (t->data[t->rindex] != TAG_U32) return -1; - - *i = ntohl(*((uint32_t*) (t->data+t->rindex+1))); + + memcpy(i, t->data+t->rindex+1, 4); + *i = ntohl(*i); t->rindex += 5; return 0; } @@ -261,13 +281,15 @@ int pa_tagstruct_get_sample_spec(struct pa_tagstruct *t, struct pa_sample_spec * ss->format = t->data[t->rindex+1]; ss->channels = t->data[t->rindex+2]; - ss->rate = ntohl(*(uint32_t*) (t->data+t->rindex+3)); + memcpy(&ss->rate, t->data+t->rindex+3, 4); + ss->rate = ntohl(ss->rate); t->rindex += 7; return 0; } int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t length) { + uint32_t len; assert(t && p); if (t->rindex+5+length > t->length) @@ -276,7 +298,8 @@ int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t le if (t->data[t->rindex] != TAG_ARBITRARY) return -1; - if (ntohl(*((uint32_t*) (t->data+t->rindex+1))) != length) + memcpy(&len, t->data+t->rindex+1, 4); + if (ntohl(len) != length) return -1; *p = t->data+t->rindex+5; @@ -319,15 +342,18 @@ int pa_tagstruct_get_timeval(struct pa_tagstruct*t, struct timeval *tv) { if (t->data[t->rindex] != TAG_TIMEVAL) return -1; - - tv->tv_sec = ntohl(*((uint32_t*) (t->data+t->rindex+1))); - tv->tv_usec = ntohl(*((uint32_t*) (t->data+t->rindex+5))); + + memcpy(&tv->tv_sec, t->data+t->rindex+1, 4); + tv->tv_sec = ntohl(tv->tv_sec); + memcpy(&tv->tv_usec, t->data+t->rindex+5, 4); + tv->tv_usec = ntohl(tv->tv_usec); t->rindex += 9; return 0; } int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u) { + uint32_t tmp; assert(t && u); if (t->rindex+9 > t->length) @@ -336,13 +362,16 @@ int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u) { if (t->data[t->rindex] != TAG_USEC) return -1; - *u = (pa_usec_t) ntohl(*((uint32_t*) (t->data+t->rindex+1))) << 32; - *u |= (pa_usec_t) ntohl(*((uint32_t*) (t->data+t->rindex+5))); + memcpy(&tmp, t->data+t->rindex+1, 4); + *u = (pa_usec_t) ntohl(tmp) << 32; + memcpy(&tmp, t->data+t->rindex+5, 4); + *u |= (pa_usec_t) ntohl(tmp); t->rindex +=9; return 0; } int pa_tagstruct_getu64(struct pa_tagstruct*t, uint64_t *u) { + uint32_t tmp; assert(t && u); if (t->rindex+9 > t->length) @@ -351,8 +380,10 @@ int pa_tagstruct_getu64(struct pa_tagstruct*t, uint64_t *u) { if (t->data[t->rindex] != TAG_U64) return -1; - *u = (uint64_t) ntohl(*((uint32_t*) (t->data+t->rindex+1))) << 32; - *u |= (uint64_t) ntohl(*((uint32_t*) (t->data+t->rindex+5))); + memcpy(&tmp, t->data+t->rindex+1, 4); + *u = (pa_usec_t) ntohl(tmp) << 32; + memcpy(&tmp, t->data+t->rindex+5, 4); + *u |= (pa_usec_t) ntohl(tmp); t->rindex +=9; return 0; } diff --git a/polyp/util.c b/polyp/util.c index ee3fa87d..26d71203 100644 --- a/polyp/util.c +++ b/polyp/util.c @@ -32,35 +32,98 @@ #include <stdio.h> #include <fcntl.h> #include <unistd.h> +#include <limits.h> +#include <time.h> +#include <ctype.h> #include <sys/types.h> #include <sys/stat.h> -#include <pwd.h> -#include <signal.h> -#include <pthread.h> #include <sys/time.h> + +#ifdef HAVE_SCHED_H #include <sched.h> +#endif + +#ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> -#include <limits.h> -#include <unistd.h> -#include <grp.h> +#endif + +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif + +#ifdef HAVE_NETDB_H #include <netdb.h> +#endif + +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif #include <samplerate.h> +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif +#ifdef HAVE_GRP_H +#include <grp.h> +#endif + +#include "winsock.h" + #include "util.h" #include "xmalloc.h" #include "log.h" +#ifndef OS_IS_WIN32 #define PA_RUNTIME_PATH_PREFIX "/tmp/polypaudio-" +#define PATH_SEP '/' +#else +#define PA_RUNTIME_PATH_PREFIX "%TEMP%\\polypaudio-" +#define PATH_SEP '\\' +#endif + +#ifdef OS_IS_WIN32 + +#define POLYP_ROOTENV "POLYP_ROOT" + +int pa_set_root(HANDLE handle) { + char library_path[MAX_PATH + sizeof(POLYP_ROOTENV) + 1], *sep; + + strcpy(library_path, POLYP_ROOTENV "="); + + if (!GetModuleFileName(handle, library_path + sizeof(POLYP_ROOTENV), MAX_PATH)) + return 0; + + sep = strrchr(library_path, '\\'); + if (sep) + *sep = '\0'; + + if (_putenv(library_path) < 0) + return 0; + + return 1; +} + +#endif /** Make a file descriptor nonblock. Doesn't do any error checking */ void pa_make_nonblock_fd(int fd) { +#ifdef O_NONBLOCK int v; assert(fd >= 0); if ((v = fcntl(fd, F_GETFL)) >= 0) if (!(v & O_NONBLOCK)) fcntl(fd, F_SETFL, v|O_NONBLOCK); +#elif defined(OS_IS_WIN32) + u_long arg = 1; + if (ioctlsocket(fd, FIONBIO, &arg) < 0) { + if (WSAGetLastError() == WSAENOTSOCK) + pa_log_warn(__FILE__": WARNING: Only sockets can be made non-blocking!\n"); + } +#else + pa_log_warn(__FILE__": WARNING: Non-blocking I/O not supported.!\n"); +#endif } /** Creates a directory securely */ @@ -68,15 +131,27 @@ int pa_make_secure_dir(const char* dir) { struct stat st; assert(dir); - if (mkdir(dir, 0700) < 0) +#ifdef OS_IS_WIN32 + if (mkdir(dir) < 0) +#else + if (mkdir(dir, 0700) < 0) +#endif if (errno != EEXIST) return -1; - - if (lstat(dir, &st) < 0) + +#ifdef HAVE_LSTAT + if (lstat(dir, &st) < 0) +#else + if (stat(dir, &st) < 0) +#endif goto fail; - + +#ifndef OS_IS_WIN32 if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700)) goto fail; +#else + fprintf(stderr, "FIXME: pa_make_secure_dir()\n"); +#endif return 0; @@ -89,10 +164,11 @@ fail: int pa_make_secure_parent_dir(const char *fn) { int ret = -1; char *slash, *dir = pa_xstrdup(fn); - - if (!(slash = strrchr(dir, '/'))) + + slash = pa_path_get_filename(dir); + if (slash == fn) goto finish; - *slash = 0; + *(slash-1) = 0; if (pa_make_secure_dir(dir) < 0) goto finish; @@ -153,6 +229,7 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size) { /* Print a warning messages in case that the given signal is not * blocked or trapped */ void pa_check_signal_is_blocked(int sig) { +#ifdef HAVE_SIGACTION struct sigaction sa; sigset_t set; @@ -185,6 +262,9 @@ void pa_check_signal_is_blocked(int sig) { return; pa_log(__FILE__": WARNING: %s is not trapped. This might cause malfunction!\n", pa_strsignal(sig)); +#else /* HAVE_SIGACTION */ + pa_log(__FILE__": WARNING: %s might not be trapped. This might cause malfunction!\n", pa_strsignal(sig)); +#endif } /* The following function is based on an example from the GNU libc @@ -240,30 +320,47 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) { /* Return the current username in the specified string buffer. */ char *pa_get_user_name(char *s, size_t l) { - struct passwd pw, *r; - char buf[1024]; char *p; + char buf[1024]; + +#ifdef HAVE_PWD_H + struct passwd pw, *r; +#endif + assert(s && l > 0); if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) { +#ifdef HAVE_PWD_H #ifdef HAVE_GETPWUID_R if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { #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) { + /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) + * that do not support getpwuid_r. */ + if ((r = getpwuid(getuid())) == NULL) { #endif - snprintf(s, l, "%lu", (unsigned long) getuid()); - return s; - } - - p = r->pw_name; + snprintf(s, l, "%lu", (unsigned long) getuid()); + return s; } + + p = r->pw_name; - return pa_strlcpy(s, p, l); +#elif defined(OS_IS_WIN32) /* HAVE_PWD_H */ + DWORD size = sizeof(buf); + + if (!GetUserName(buf, &size)) + return NULL; + + p = buf; + +#else /* HAVE_PWD_H */ + return NULL; +#endif /* HAVE_PWD_H */ } + return pa_strlcpy(s, p, l); +} + /* Return the current hostname in the specified buffer. */ char *pa_get_host_name(char *s, size_t l) { assert(s && l > 0); @@ -278,19 +375,37 @@ char *pa_get_host_name(char *s, size_t l) { /* Return the home directory of the current user */ char *pa_get_home_dir(char *s, size_t l) { char *e; + +#ifdef HAVE_PWD_H char buf[1024]; struct passwd pw, *r; +#endif + assert(s && l); if ((e = getenv("HOME"))) return pa_strlcpy(s, e, l); + if ((e = getenv("USERPROFILE"))) + return pa_strlcpy(s, e, l); + +#ifdef HAVE_PWD_H +#ifdef HAVE_GETPWUID_R if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { pa_log(__FILE__": getpwuid_r() failed\n"); +#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(__FILE__": getpwuid_r() failed\n"); +#endif return NULL; } return pa_strlcpy(s, r->pw_dir, l); +#else /* HAVE_PWD_H */ + return NULL; +#endif } /* Similar to OpenBSD's strlcpy() function */ @@ -302,6 +417,42 @@ char *pa_strlcpy(char *b, const char *s, size_t l) { return b; } +int pa_gettimeofday(struct timeval *tv) { +#ifdef HAVE_GETTIMEOFDAY + return gettimeofday(tv, NULL); +#elif defined(OS_IS_WIN32) + /* + * Copied from implementation by Steven Edwards (LGPL). + * Found on wine mailing list. + */ + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define EPOCHFILETIME (116444736000000000i64) +#else +#define EPOCHFILETIME (116444736000000000LL) +#endif + + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + + if (tv) { + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + tv->tv_sec = (long)(t / 1000000); + tv->tv_usec = (long)(t % 1000000); + } + + return 0; +#else +#error "Platform lacks gettimeofday() or equivalent function." +#endif +} + /* Calculate the difference between the two specfified timeval * timestamsps. */ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { @@ -351,7 +502,7 @@ int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) { pa_usec_t pa_timeval_age(const struct timeval *tv) { struct timeval now; assert(tv); - gettimeofday(&now, NULL); + pa_gettimeofday(&now); return pa_timeval_diff(&now, tv); } @@ -380,10 +531,12 @@ sensible: set the nice level to -15 and enable realtime scheduling if supported.*/ void pa_raise_priority(void) { +#ifdef HAVE_SYS_RESOURCE_H if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) pa_log_warn(__FILE__": setpriority() failed: %s\n", strerror(errno)); else pa_log_info(__FILE__": Successfully gained nice level %i.\n", NICE_LEVEL); +#endif #ifdef _POSIX_PRIORITY_SCHEDULING { @@ -403,10 +556,21 @@ void pa_raise_priority(void) { pa_log_info(__FILE__": Successfully enabled SCHED_FIFO scheduling.\n"); } #endif + +#ifdef OS_IS_WIN32 + if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) + pa_log_warn(__FILE__": SetPriorityClass() failed: 0x%08X\n", GetLastError()); + else + pa_log_info(__FILE__": Successfully gained high priority class.\n"); +#endif } /* Reset the priority to normal, inverting the changes made by pa_raise_priority() */ void pa_reset_priority(void) { +#ifdef OS_IS_WIN32 + SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); +#endif + #ifdef _POSIX_PRIORITY_SCHEDULING { struct sched_param sp; @@ -416,11 +580,15 @@ void pa_reset_priority(void) { } #endif +#ifdef HAVE_SYS_RESOURCE_H setpriority(PRIO_PROCESS, 0, 0); +#endif } /* Set the FD_CLOEXEC flag for a fd */ int pa_fd_set_cloexec(int fd, int b) { + +#ifdef FD_CLOEXEC int v; assert(fd >= 0); @@ -431,7 +599,8 @@ int pa_fd_set_cloexec(int fd, int b) { if (fcntl(fd, F_SETFD, v) < 0) return -1; - +#endif + return 0; } @@ -439,6 +608,8 @@ int pa_fd_set_cloexec(int fd, int b) { * only. This shoul be used for eyecandy only, don't rely on return * non-NULL! */ char *pa_get_binary_name(char *s, size_t l) { + +#ifdef HAVE_READLINK char path[PATH_MAX]; int i; assert(s && l); @@ -451,6 +622,15 @@ char *pa_get_binary_name(char *s, size_t l) { s[i] = 0; return s; +#elif defined(OS_IS_WIN32) + char path[PATH_MAX]; + if (!GetModuleFileName(NULL, path, PATH_MAX)) + return NULL; + pa_strlcpy(s, pa_path_get_filename(path), l); + return s; +#else + return NULL; +#endif } /* Return a pointer to the filename inside a path (which is the last @@ -458,7 +638,7 @@ char *pa_get_binary_name(char *s, size_t l) { char *pa_path_get_filename(const char *p) { char *fn; - if ((fn = strrchr(p, '/'))) + if ((fn = strrchr(p, PATH_SEP))) return fn+1; return (char*) p; @@ -519,16 +699,29 @@ const char *pa_strsignal(int sig) { switch(sig) { case SIGINT: return "SIGINT"; case SIGTERM: return "SIGTERM"; +#ifdef SIGUSR1 case SIGUSR1: return "SIGUSR1"; +#endif +#ifdef SIGUSR2 case SIGUSR2: return "SIGUSR2"; +#endif +#ifdef SIGXCPU case SIGXCPU: return "SIGXCPU"; +#endif +#ifdef SIGPIPE case SIGPIPE: return "SIGPIPE"; +#endif +#ifdef SIGCHLD case SIGCHLD: return "SIGCHLD"; +#endif +#ifdef SIGHUP case SIGHUP: return "SIGHUP"; +#endif default: return "UNKNOWN SIGNAL"; } } +#ifdef HAVE_GRP_H /* Check whether the specified GID and the group name match */ static int is_group(gid_t gid, const char *name) { @@ -575,7 +768,7 @@ finish: /* Check the current user is member of the specified group */ int pa_uid_in_group(const char *name, gid_t *gid) { gid_t *gids, tgid; - long n = sysconf(_SC_NGROUPS_MAX); + GETGROUPS_T n = sysconf(_SC_NGROUPS_MAX); int r = -1, i; assert(n > 0); @@ -609,8 +802,18 @@ finish: return r; } -/* Lock or unlock a file entirely. (advisory) */ +#else /* HAVE_GRP_H */ + +int pa_uid_in_group(const char *name, gid_t *gid) { + return -1; +} + +#endif + +/* Lock or unlock a file entirely. + (advisory on UNIX, mandatory on Windows) */ int pa_lock_fd(int fd, int b) { +#ifdef F_SETLKW struct flock flock; /* Try a R/W lock first */ @@ -631,6 +834,19 @@ int pa_lock_fd(int fd, int b) { } pa_log(__FILE__": %slock failed: %s\n", !b ? "un" : "", strerror(errno)); +#endif + +#ifdef OS_IS_WIN32 + HANDLE h = (HANDLE)_get_osfhandle(fd); + + if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF)) + return 0; + if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF)) + return 0; + + pa_log(__FILE__": %slock failed: 0x%08X\n", !b ? "un" : "", GetLastError()); +#endif + return -1; } @@ -722,31 +938,51 @@ int pa_unlock_lockfile(const char *fn, int fd) { * allocated buffer containing the used configuration file is * stored there.*/ FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) { - const char *e; + const char *fn; char h[PATH_MAX]; - if (env && (e = getenv(env))) { +#ifdef OS_IS_WIN32 + char buf[PATH_MAX]; + + if (!getenv(POLYP_ROOTENV)) + pa_set_root(NULL); +#endif + + if (env && (fn = getenv(env))) { +#ifdef OS_IS_WIN32 + if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX)) + return NULL; + fn = buf; +#endif + if (result) - *result = pa_xstrdup(e); - return fopen(e, "r"); + *result = pa_xstrdup(fn); + + return fopen(fn, "r"); } if (local && pa_get_home_dir(h, sizeof(h))) { FILE *f; - char *l; + char *lfn; - l = pa_sprintf_malloc("%s/%s", h, local); - f = fopen(l, "r"); + lfn = pa_sprintf_malloc("%s/%s", h, local); + +#ifdef OS_IS_WIN32 + if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) + return NULL; + lfn = buf; +#endif + + f = fopen(lfn, "r"); if (f || errno != ENOENT) { if (result) - *result = l; - else - pa_xfree(l); + *result = pa_xstrdup(lfn); + pa_xfree(lfn); return f; } - pa_xfree(l); + pa_xfree(lfn); } if (!global) { @@ -756,6 +992,12 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env return NULL; } +#ifdef OS_IS_WIN32 + if (!ExpandEnvironmentStrings(global, buf, PATH_MAX)) + return NULL; + global = buf; +#endif + if (result) *result = pa_xstrdup(global); @@ -823,11 +1065,14 @@ size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { /* Return the fully qualified domain name in *s */ char *pa_get_fqdn(char *s, size_t l) { char hn[256]; +#ifdef HAVE_GETADDRINFO struct addrinfo *a, hints; +#endif if (!pa_get_host_name(hn, sizeof(hn))) return NULL; +#ifdef HAVE_GETADDRINFO memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_CANONNAME; @@ -838,6 +1083,9 @@ char *pa_get_fqdn(char *s, size_t l) { pa_strlcpy(s, a->ai_canonname, l); freeaddrinfo(a); return s; +#else + return pa_strlcpy(s, hn, l); +#endif } /* Returns nonzero when *s starts with *pfx */ @@ -855,21 +1103,44 @@ int pa_startswith(const char *s, const char *pfx) { char *pa_runtime_path(const char *fn, char *s, size_t l) { char u[256]; +#ifndef OS_IS_WIN32 if (fn && *fn == '/') +#else + if (fn && strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\') +#endif return pa_strlcpy(s, fn, l); - - snprintf(s, l, PA_RUNTIME_PATH_PREFIX"%s%s%s", pa_get_user_name(u, sizeof(u)), fn ? "/" : "", fn ? fn : ""); + + if (fn) + snprintf(s, l, "%s%s%c%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn); + else + snprintf(s, l, "%s%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u))); + +#ifdef OS_IS_WIN32 + { + char buf[l]; + strcpy(buf, s); + ExpandEnvironmentStrings(buf, s, l); + } +#endif + return s; } /* Wait t milliseconds */ int pa_msleep(unsigned long t) { +#ifdef OS_IS_WIN32 + Sleep(t); + return 0; +#elif defined(HAVE_NANOSLEEP) struct timespec ts; ts.tv_sec = t/1000; ts.tv_nsec = (t % 1000) * 1000000; return nanosleep(&ts, NULL); +#else +#error "Platform lacks a sleep function." +#endif } /* Convert the string s to a signed integer in *ret_i */ diff --git a/polyp/util.h b/polyp/util.h index 2cfc5f6e..d9e18ddb 100644 --- a/polyp/util.h +++ b/polyp/util.h @@ -30,6 +30,8 @@ #include "gcc-printf.h" #include "sample.h" +struct timeval; + void pa_make_nonblock_fd(int fd); int pa_make_secure_dir(const char* dir); @@ -53,6 +55,7 @@ char *pa_get_home_dir(char *s, size_t l); char *pa_path_get_filename(const char *p); +int pa_gettimeofday(struct timeval *tv); pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b); int pa_timeval_cmp(const struct timeval *a, const struct timeval *b); pa_usec_t pa_timeval_age(const struct timeval *tv); diff --git a/polyp/winsock.h b/polyp/winsock.h new file mode 100644 index 00000000..b1e0f7d4 --- /dev/null +++ b/polyp/winsock.h @@ -0,0 +1,23 @@ +#ifndef foowinsockhfoo +#define foowinsockhfoo + +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> + +#define ESHUTDOWN WSAESHUTDOWN +#define ECONNRESET WSAECONNRESET +#define ECONNABORTED WSAECONNABORTED +#define ENETRESET WSAENETRESET +#define EINPROGRESS WSAEINPROGRESS +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define ETIMEDOUT WSAETIMEDOUT +#define ECONNREFUSED WSAECONNREFUSED +#define EHOSTUNREACH WSAEHOSTUNREACH + +#endif + +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif + +#endif diff --git a/polyp/xmalloc.c b/polyp/xmalloc.c index 7ddefa94..f2751e52 100644 --- a/polyp/xmalloc.c +++ b/polyp/xmalloc.c @@ -45,7 +45,9 @@ static void oom(void) { static const char e[] = "Not enough memory\n"; pa_loop_write(STDERR_FILENO, e, sizeof(e)-1); +#ifdef SIGQUIT raise(SIGQUIT); +#endif _exit(1); } |