winepulse: Add initial stub for pulseaudio support.
Includes API compatibility patch by Juergen Tretthahn <orson@orson.at>. Synchronous static data initialization by Andrew Eikum <aeikum@codeweavers.com>. Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e4bc220802
commit
3fe0c08992
|
@ -654,6 +654,8 @@ OSS4_CFLAGS
|
|||
ALSA_LIBS
|
||||
GSTREAMER_LIBS
|
||||
GSTREAMER_CFLAGS
|
||||
PULSE_CFLAGS
|
||||
PULSE_LIBS
|
||||
GETTEXTPO_LIBS
|
||||
Z_LIBS
|
||||
FREETYPE_LIBS
|
||||
|
@ -830,6 +832,7 @@ with_oss
|
|||
with_pcap
|
||||
with_png
|
||||
with_pthread
|
||||
with_pulse
|
||||
with_sane
|
||||
with_tiff
|
||||
with_v4l
|
||||
|
@ -1341,6 +1344,7 @@ enable_winemapi
|
|||
enable_winemp3_acm
|
||||
enable_wineoss_drv
|
||||
enable_wineps_drv
|
||||
enable_winepulse_drv
|
||||
enable_wineqtdecoder
|
||||
enable_winex11_drv
|
||||
enable_wing32
|
||||
|
@ -1523,6 +1527,8 @@ LCMS2_CFLAGS
|
|||
LCMS2_LIBS
|
||||
FREETYPE_CFLAGS
|
||||
FREETYPE_LIBS
|
||||
PULSE_CFLAGS
|
||||
PULSE_LIBS
|
||||
GSTREAMER_CFLAGS
|
||||
GSTREAMER_LIBS
|
||||
CAPI20_CFLAGS
|
||||
|
@ -2205,6 +2211,7 @@ Optional Packages:
|
|||
--without-pcap do not use the Packet Capture library
|
||||
--without-png do not use PNG
|
||||
--without-pthread do not use the pthread library
|
||||
--without-pulse do not use PulseAudio sound support
|
||||
--without-sane do not use SANE (scanner support)
|
||||
--without-tiff do not use TIFF
|
||||
--without-v4l do not use v4l1 (v4l support)
|
||||
|
@ -2265,6 +2272,9 @@ Some influential environment variables:
|
|||
C compiler flags for freetype2, overriding pkg-config
|
||||
FREETYPE_LIBS
|
||||
Linker flags for freetype2, overriding pkg-config
|
||||
PULSE_CFLAGS
|
||||
C compiler flags for libpulse, overriding pkg-config
|
||||
PULSE_LIBS Linker flags for libpulse, overriding pkg-config
|
||||
GSTREAMER_CFLAGS
|
||||
C compiler flags for gstreamer-app-0.10, overriding pkg-config
|
||||
GSTREAMER_LIBS
|
||||
|
@ -3452,6 +3462,12 @@ if test "${with_pthread+set}" = set; then :
|
|||
fi
|
||||
|
||||
|
||||
# Check whether --with-pulse was given.
|
||||
if test "${with_pulse+set}" = set; then :
|
||||
withval=$with_pulse;
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-sane was given.
|
||||
if test "${with_sane+set}" = set; then :
|
||||
withval=$with_sane;
|
||||
|
@ -12576,6 +12592,94 @@ esac
|
|||
fi
|
||||
fi
|
||||
|
||||
PULSE_LIBS=""
|
||||
|
||||
PULSE_CFLAGS=""
|
||||
|
||||
if test "x$with_pulse" != "xno";
|
||||
then
|
||||
if ${PULSE_CFLAGS:+false} :; then :
|
||||
if ${PKG_CONFIG+:} false; then :
|
||||
PULSE_CFLAGS=`$PKG_CONFIG --cflags libpulse 2>/dev/null`
|
||||
fi
|
||||
fi
|
||||
|
||||
if ${PULSE_LIBS:+false} :; then :
|
||||
if ${PKG_CONFIG+:} false; then :
|
||||
PULSE_LIBS=`$PKG_CONFIG --libs libpulse 2>/dev/null`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: libpulse cflags: $PULSE_CFLAGS" >&5
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: libpulse libs: $PULSE_LIBS" >&5
|
||||
ac_save_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $PULSE_CFLAGS"
|
||||
for ac_header in pulse/pulseaudio.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "pulse/pulseaudio.h" "ac_cv_header_pulse_pulseaudio_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_pulse_pulseaudio_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_PULSE_PULSEAUDIO_H 1
|
||||
_ACEOF
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pa_stream_is_corked in -lpulse" >&5
|
||||
$as_echo_n "checking for pa_stream_is_corked in -lpulse... " >&6; }
|
||||
if ${ac_cv_lib_pulse_pa_stream_is_corked+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lpulse $PULSE_LIBS $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pa_stream_is_corked ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pa_stream_is_corked ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_pulse_pa_stream_is_corked=yes
|
||||
else
|
||||
ac_cv_lib_pulse_pa_stream_is_corked=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pulse_pa_stream_is_corked" >&5
|
||||
$as_echo "$ac_cv_lib_pulse_pa_stream_is_corked" >&6; }
|
||||
if test "x$ac_cv_lib_pulse_pa_stream_is_corked" = xyes; then :
|
||||
:
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
CPPFLAGS=$ac_save_CPPFLAGS
|
||||
test -z "$PULSE_CFLAGS" || PULSE_CFLAGS=`echo " $PULSE_CFLAGS" | sed 's/ -I\([^/]\)/ -I\$(top_builddir)\/\1/g'`
|
||||
test -z "$PULSE_LIBS" || PULSE_LIBS=`echo " $PULSE_LIBS" | sed 's/ -L\([^/]\)/ -L\$(top_builddir)\/\1/g'`
|
||||
|
||||
fi
|
||||
if test "$ac_cv_lib_pulse_pa_stream_is_corked" != "yes"; then :
|
||||
case "x$with_pulse" in
|
||||
x) as_fn_append wine_notices "|libpulse ${notice_platform}development files not found or too old, Pulse won't be supported." ;;
|
||||
xno) ;;
|
||||
*) as_fn_error $? "libpulse ${notice_platform}development files not found or too old, Pulse won't be supported.
|
||||
This is an error since --with-pulse was requested." "$LINENO" 5 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "x$with_gstreamer" != "xno"
|
||||
then
|
||||
if ${GSTREAMER_CFLAGS:+false} :; then :
|
||||
|
@ -13922,12 +14026,13 @@ fi
|
|||
|
||||
test -n "$ALSA_LIBS" || enable_winealsa_drv=${enable_winealsa_drv:-no}
|
||||
test -n "$COREAUDIO_LIBS" || enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no}
|
||||
test -n "$PULSE_LIBS" || enable_winepulse_drv=${enable_winepulse_drv:-no}
|
||||
test "x$ac_cv_member_oss_sysinfo_numaudioengines" = xyes || enable_wineoss_drv=${enable_wineoss_drv:-no}
|
||||
test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
|
||||
|
||||
if test "x$ALSA_LIBS$COREAUDIO_LIBS" = "x" -a \
|
||||
if test "x$ALSA_LIBS$COREAUDIO_LIBS$PULSE_LIBS" = "x" -a \
|
||||
"x$ac_cv_member_oss_sysinfo_numaudioengines" != xyes -a \
|
||||
"x$with_alsa$with_coreaudio$with_oss" != xnonono
|
||||
"x$with_alsa$with_coreaudio$with_oss$with_pulse" != xnononono
|
||||
then
|
||||
as_fn_append wine_warnings "|No sound system was found. Windows applications will be silent."
|
||||
fi
|
||||
|
@ -17177,6 +17282,8 @@ FREETYPE_CFLAGS = $FREETYPE_CFLAGS
|
|||
FREETYPE_LIBS = $FREETYPE_LIBS
|
||||
Z_LIBS = $Z_LIBS
|
||||
GETTEXTPO_LIBS = $GETTEXTPO_LIBS
|
||||
PULSE_LIBS = $PULSE_LIBS
|
||||
PULSE_CFLAGS = $PULSE_CFLAGS
|
||||
GSTREAMER_CFLAGS = $GSTREAMER_CFLAGS
|
||||
GSTREAMER_LIBS = $GSTREAMER_LIBS
|
||||
ALSA_LIBS = $ALSA_LIBS
|
||||
|
@ -17954,6 +18061,7 @@ wine_fn_config_dll winemp3.acm enable_winemp3_acm
|
|||
wine_fn_config_dll wineoss.drv enable_wineoss_drv
|
||||
wine_fn_config_dll wineps.drv enable_wineps_drv clean,po
|
||||
wine_fn_config_dll wineps16.drv16 enable_win16
|
||||
wine_fn_config_dll winepulse.drv enable_winepulse_drv
|
||||
wine_fn_config_dll wineqtdecoder enable_wineqtdecoder
|
||||
wine_fn_config_dll winex11.drv enable_winex11_drv
|
||||
wine_fn_config_dll wing.dll16 enable_win16
|
||||
|
|
19
configure.ac
19
configure.ac
|
@ -72,6 +72,7 @@ AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Ca
|
|||
AC_ARG_WITH(png, AS_HELP_STRING([--without-png],[do not use PNG]))
|
||||
AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]),
|
||||
[if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi])
|
||||
AC_ARG_WITH(pulse, AC_HELP_STRING([--without-pulse],[do not use PulseAudio sound support]))
|
||||
AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
|
||||
AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]))
|
||||
AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
|
||||
|
@ -1547,6 +1548,18 @@ then
|
|||
[GetText ${notice_platform}development files not found (or too old), po files can't be rebuilt.])
|
||||
fi
|
||||
|
||||
dnl **** Check for PulseAudio ****
|
||||
AC_SUBST(PULSE_LIBS,"")
|
||||
AC_SUBST(PULSE_CFLAGS,"")
|
||||
if test "x$with_pulse" != "xno";
|
||||
then
|
||||
WINE_PACKAGE_FLAGS(PULSE,[libpulse],,,,
|
||||
[AC_CHECK_HEADERS(pulse/pulseaudio.h,
|
||||
[AC_CHECK_LIB(pulse, pa_stream_is_corked,[:],,[$PULSE_LIBS])])])
|
||||
fi
|
||||
WINE_NOTICE_WITH(pulse, [test "$ac_cv_lib_pulse_pa_stream_is_corked" != "yes"],
|
||||
[libpulse ${notice_platform}development files not found or too old, Pulse won't be supported.])
|
||||
|
||||
dnl **** Check for gstreamer ****
|
||||
if test "x$with_gstreamer" != "xno"
|
||||
then
|
||||
|
@ -1779,13 +1792,14 @@ fi
|
|||
dnl **** Disable unsupported winmm drivers ****
|
||||
test -n "$ALSA_LIBS" || enable_winealsa_drv=${enable_winealsa_drv:-no}
|
||||
test -n "$COREAUDIO_LIBS" || enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no}
|
||||
test -n "$PULSE_LIBS" || enable_winepulse_drv=${enable_winepulse_drv:-no}
|
||||
test "x$ac_cv_member_oss_sysinfo_numaudioengines" = xyes || enable_wineoss_drv=${enable_wineoss_drv:-no}
|
||||
test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
|
||||
|
||||
dnl **** Check for any sound system ****
|
||||
if test "x$ALSA_LIBS$COREAUDIO_LIBS" = "x" -a \
|
||||
if test "x$ALSA_LIBS$COREAUDIO_LIBS$PULSE_LIBS" = "x" -a \
|
||||
"x$ac_cv_member_oss_sysinfo_numaudioengines" != xyes -a \
|
||||
"x$with_alsa$with_coreaudio$with_oss" != xnonono
|
||||
"x$with_alsa$with_coreaudio$with_oss$with_pulse" != xnononono
|
||||
then
|
||||
WINE_WARNING([No sound system was found. Windows applications will be silent.])
|
||||
fi
|
||||
|
@ -3402,6 +3416,7 @@ WINE_CONFIG_DLL(winemp3.acm)
|
|||
WINE_CONFIG_DLL(wineoss.drv)
|
||||
WINE_CONFIG_DLL(wineps.drv,,[clean,po])
|
||||
WINE_CONFIG_DLL(wineps16.drv16,enable_win16)
|
||||
WINE_CONFIG_DLL(winepulse.drv)
|
||||
WINE_CONFIG_DLL(wineqtdecoder)
|
||||
WINE_CONFIG_DLL(winex11.drv)
|
||||
WINE_CONFIG_DLL(wing.dll16,enable_win16)
|
||||
|
|
|
@ -113,7 +113,7 @@ static BOOL init_driver(void)
|
|||
{
|
||||
static const WCHAR drv_value[] = {'A','u','d','i','o',0};
|
||||
|
||||
static WCHAR default_list[] = {'a','l','s','a',',','o','s','s',',',
|
||||
static WCHAR default_list[] = {'p','u','l','s','e',',','a','l','s','a',',','o','s','s',',',
|
||||
'c','o','r','e','a','u','d','i','o',0};
|
||||
|
||||
DriverFuncs driver;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
MODULE = winepulse.drv
|
||||
IMPORTS = dxguid uuid winmm user32 advapi32 ole32
|
||||
EXTRALIBS = $(PULSE_LIBS) $(PTHREAD_LIBS)
|
||||
EXTRAINCL = $(PULSE_CFLAGS)
|
||||
|
||||
C_SRCS = \
|
||||
mmdevdrv.c
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright 2011-2012 Maarten Lankhorst
|
||||
* Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
|
||||
* Copyright 2011 Andrew Eikum for CodeWeavers
|
||||
*
|
||||
* This library 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.
|
||||
*
|
||||
* This library 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 this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define COBJMACROS
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#include "ole2.h"
|
||||
#include "dshow.h"
|
||||
#include "dsound.h"
|
||||
#include "propsys.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "ks.h"
|
||||
#include "ksmedia.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "audioclient.h"
|
||||
#include "endpointvolume.h"
|
||||
#include "audiopolicy.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(pulse);
|
||||
|
||||
#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
|
||||
|
||||
/* From <dlls/mmdevapi/mmdevapi.h> */
|
||||
enum DriverPriority {
|
||||
Priority_Unavailable = 0,
|
||||
Priority_Low,
|
||||
Priority_Neutral,
|
||||
Priority_Preferred
|
||||
};
|
||||
|
||||
static const REFERENCE_TIME MinimumPeriod = 30000;
|
||||
static const REFERENCE_TIME DefaultPeriod = 100000;
|
||||
|
||||
static pa_context *pulse_ctx;
|
||||
static pa_mainloop *pulse_ml;
|
||||
|
||||
static pthread_mutex_t pulse_lock;
|
||||
|
||||
static GUID pulse_render_guid =
|
||||
{ 0xfd47d9cc, 0x4218, 0x4135, { 0x9c, 0xe2, 0x0c, 0x19, 0x5c, 0x87, 0x40, 0x5b } };
|
||||
static GUID pulse_capture_guid =
|
||||
{ 0x25da76d0, 0x033c, 0x4235, { 0x90, 0x02, 0x19, 0xf4, 0x88, 0x94, 0xac, 0x6f } };
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
DisableThreadLibraryCalls(dll);
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
|
||||
|
||||
if (pthread_mutex_init(&pulse_lock, &attr) != 0)
|
||||
pthread_mutex_init(&pulse_lock, NULL);
|
||||
} else if (reason == DLL_PROCESS_DETACH) {
|
||||
if (pulse_ctx) {
|
||||
pa_context_disconnect(pulse_ctx);
|
||||
pa_context_unref(pulse_ctx);
|
||||
}
|
||||
if (pulse_ml)
|
||||
pa_mainloop_quit(pulse_ml, 0);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static const WCHAR defaultW[] = {'P','u','l','s','e','a','u','d','i','o',0};
|
||||
|
||||
/* Following pulseaudio design here, mainloop has the lock taken whenever
|
||||
* it is handling something for pulse, and the lock is required whenever
|
||||
* doing any pa_* call that can affect the state in any way
|
||||
*
|
||||
* pa_cond_wait is used when waiting on results, because the mainloop needs
|
||||
* the same lock taken to affect the state
|
||||
*
|
||||
* This is basically the same as the pa_threaded_mainloop implementation,
|
||||
* but that cannot be used because it uses pthread_create directly
|
||||
*
|
||||
* pa_threaded_mainloop_(un)lock -> pthread_mutex_(un)lock
|
||||
* pa_threaded_mainloop_signal -> pthread_cond_signal
|
||||
* pa_threaded_mainloop_wait -> pthread_cond_wait
|
||||
*/
|
||||
|
||||
static int pulse_poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void *userdata) {
|
||||
int r;
|
||||
pthread_mutex_unlock(&pulse_lock);
|
||||
r = poll(ufds, nfds, timeout);
|
||||
pthread_mutex_lock(&pulse_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void pulse_contextcallback(pa_context *c, void *userdata)
|
||||
{
|
||||
switch (pa_context_get_state(c)) {
|
||||
default:
|
||||
FIXME("Unhandled state: %i\n", pa_context_get_state(c));
|
||||
case PA_CONTEXT_CONNECTING:
|
||||
case PA_CONTEXT_UNCONNECTED:
|
||||
case PA_CONTEXT_AUTHORIZING:
|
||||
case PA_CONTEXT_SETTING_NAME:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
TRACE("State change to %i\n", pa_context_get_state(c));
|
||||
return;
|
||||
|
||||
case PA_CONTEXT_READY:
|
||||
TRACE("Ready\n");
|
||||
break;
|
||||
|
||||
case PA_CONTEXT_FAILED:
|
||||
ERR("Context failed: %s\n", pa_strerror(pa_context_errno(c)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* some poorly-behaved applications call audio functions during DllMain, so we
|
||||
* have to do as much as possible without creating a new thread. this function
|
||||
* sets up a synchronous connection to verify the server is running and query
|
||||
* static data. */
|
||||
static HRESULT pulse_test_connect(void)
|
||||
{
|
||||
int len, ret;
|
||||
WCHAR path[PATH_MAX], *name;
|
||||
char *str;
|
||||
|
||||
pulse_ml = pa_mainloop_new();
|
||||
|
||||
pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
|
||||
|
||||
GetModuleFileNameW(NULL, path, sizeof(path)/sizeof(*path));
|
||||
name = strrchrW(path, '\\');
|
||||
if (!name)
|
||||
name = path;
|
||||
else
|
||||
name++;
|
||||
len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL);
|
||||
str = pa_xmalloc(len);
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, name, -1, str, len, NULL, NULL);
|
||||
TRACE("Name: %s\n", str);
|
||||
pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), str);
|
||||
pa_xfree(str);
|
||||
if (!pulse_ctx) {
|
||||
ERR("Failed to create context\n");
|
||||
pa_mainloop_free(pulse_ml);
|
||||
pulse_ml = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pa_context_set_state_callback(pulse_ctx, pulse_contextcallback, NULL);
|
||||
|
||||
TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(pulse_ctx), PA_API_VERSION);
|
||||
if (pa_context_connect(pulse_ctx, NULL, 0, NULL) < 0)
|
||||
goto fail;
|
||||
|
||||
/* Wait for connection */
|
||||
while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0) {
|
||||
pa_context_state_t state = pa_context_get_state(pulse_ctx);
|
||||
|
||||
if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED)
|
||||
goto fail;
|
||||
|
||||
if (state == PA_CONTEXT_READY)
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("Test-connected to server %s with protocol version: %i.\n",
|
||||
pa_context_get_server(pulse_ctx),
|
||||
pa_context_get_server_protocol_version(pulse_ctx));
|
||||
|
||||
pa_context_unref(pulse_ctx);
|
||||
pulse_ctx = NULL;
|
||||
pa_mainloop_free(pulse_ml);
|
||||
pulse_ml = NULL;
|
||||
|
||||
return S_OK;
|
||||
|
||||
fail:
|
||||
pa_context_unref(pulse_ctx);
|
||||
pulse_ctx = NULL;
|
||||
pa_mainloop_free(pulse_ml);
|
||||
pulse_ml = NULL;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, const WCHAR ***ids, GUID **keys,
|
||||
UINT *num, UINT *def_index)
|
||||
{
|
||||
WCHAR *id;
|
||||
|
||||
TRACE("%d %p %p %p\n", flow, ids, num, def_index);
|
||||
|
||||
*num = 1;
|
||||
*def_index = 0;
|
||||
|
||||
*ids = HeapAlloc(GetProcessHeap(), 0, sizeof(**ids));
|
||||
*keys = NULL;
|
||||
if (!*ids)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
(*ids)[0] = id = HeapAlloc(GetProcessHeap(), 0, sizeof(defaultW));
|
||||
*keys = HeapAlloc(GetProcessHeap(), 0, sizeof(**keys));
|
||||
if (!*keys || !id) {
|
||||
HeapFree(GetProcessHeap(), 0, id);
|
||||
HeapFree(GetProcessHeap(), 0, *keys);
|
||||
HeapFree(GetProcessHeap(), 0, *ids);
|
||||
*ids = NULL;
|
||||
*keys = NULL;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(id, defaultW, sizeof(defaultW));
|
||||
|
||||
if (flow == eRender)
|
||||
(*keys)[0] = pulse_render_guid;
|
||||
else
|
||||
(*keys)[0] = pulse_capture_guid;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int WINAPI AUDDRV_GetPriority(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
pthread_mutex_lock(&pulse_lock);
|
||||
hr = pulse_test_connect();
|
||||
pthread_mutex_unlock(&pulse_lock);
|
||||
return SUCCEEDED(hr) ? Priority_Low : Priority_Unavailable;
|
||||
}
|
||||
|
||||
HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient **out)
|
||||
{
|
||||
TRACE("%s %p %p\n", debugstr_guid(guid), dev, out);
|
||||
*out = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI AUDDRV_GetAudioSessionManager(IMMDevice *device,
|
||||
IAudioSessionManager2 **out)
|
||||
{
|
||||
*out = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# MMDevAPI driver functions
|
||||
@ stdcall -private GetPriority() AUDDRV_GetPriority
|
||||
@ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
|
||||
@ stdcall -private GetAudioEndpoint(ptr ptr ptr) AUDDRV_GetAudioEndpoint
|
||||
@ stdcall -private GetAudioSessionManager(ptr ptr) AUDDRV_GetAudioSessionManager
|
|
@ -696,6 +696,9 @@
|
|||
/* Define to 1 if you have the <pthread_np.h> header file. */
|
||||
#undef HAVE_PTHREAD_NP_H
|
||||
|
||||
/* Define to 1 if you have the <pulse/pulseaudio.h> header file. */
|
||||
#undef HAVE_PULSE_PULSEAUDIO_H
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
|
|
Loading…
Reference in New Issue