diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index 89f04b14766..8236b243ccb 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mmdevapi.dll IMPORTS = uuid ole32 oleaut32 user32 advapi32 kernel32 ntdll +EXTRALIBS = @FRAMEWORK_OPENAL@ C_SRCS = \ devenum.c \ diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 6b15dab6a6e..d9536aa6a65 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -17,6 +17,7 @@ */ #include "config.h" +#include "wine/port.h" #include @@ -25,7 +26,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" -#include "wine/debug.h" +#include "wine/library.h" #include "ole2.h" #include "olectl.h" @@ -39,9 +40,267 @@ #include "devpkey.h" #include "mmdevapi.h" +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); +#ifdef HAVE_OPENAL + +int local_contexts; + +static CRITICAL_SECTION_DEBUG openal_crst_debug = +{ + 0, 0, &openal_crst, + { &openal_crst_debug.ProcessLocksList, + &openal_crst_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": openal_crst_debug") } +}; +CRITICAL_SECTION openal_crst = { &openal_crst_debug, -1, 0, 0, 0, 0 }; + +static void *openal_handle = RTLD_DEFAULT; +int openal_loaded; +#ifdef SONAME_LIBOPENAL +LPALCCREATECONTEXT palcCreateContext = NULL; +LPALCMAKECONTEXTCURRENT palcMakeContextCurrent = NULL; +LPALCPROCESSCONTEXT palcProcessContext = NULL; +LPALCSUSPENDCONTEXT palcSuspendContext = NULL; +LPALCDESTROYCONTEXT palcDestroyContext = NULL; +LPALCGETCURRENTCONTEXT palcGetCurrentContext = NULL; +LPALCGETCONTEXTSDEVICE palcGetContextsDevice = NULL; +LPALCOPENDEVICE palcOpenDevice = NULL; +LPALCCLOSEDEVICE palcCloseDevice = NULL; +LPALCGETERROR palcGetError = NULL; +LPALCISEXTENSIONPRESENT palcIsExtensionPresent = NULL; +LPALCGETPROCADDRESS palcGetProcAddress = NULL; +LPALCGETENUMVALUE palcGetEnumValue = NULL; +LPALCGETSTRING palcGetString = NULL; +LPALCGETINTEGERV palcGetIntegerv = NULL; +LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice = NULL; +LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice = NULL; +LPALCCAPTURESTART palcCaptureStart = NULL; +LPALCCAPTURESTOP palcCaptureStop = NULL; +LPALCCAPTURESAMPLES palcCaptureSamples = NULL; +LPALENABLE palEnable = NULL; +LPALDISABLE palDisable = NULL; +LPALISENABLED palIsEnabled = NULL; +LPALGETSTRING palGetString = NULL; +LPALGETBOOLEANV palGetBooleanv = NULL; +LPALGETINTEGERV palGetIntegerv = NULL; +LPALGETFLOATV palGetFloatv = NULL; +LPALGETDOUBLEV palGetDoublev = NULL; +LPALGETBOOLEAN palGetBoolean = NULL; +LPALGETINTEGER palGetInteger = NULL; +LPALGETFLOAT palGetFloat = NULL; +LPALGETDOUBLE palGetDouble = NULL; +LPALGETERROR palGetError = NULL; +LPALISEXTENSIONPRESENT palIsExtensionPresent = NULL; +LPALGETPROCADDRESS palGetProcAddress = NULL; +LPALGETENUMVALUE palGetEnumValue = NULL; +LPALLISTENERF palListenerf = NULL; +LPALLISTENER3F palListener3f = NULL; +LPALLISTENERFV palListenerfv = NULL; +LPALLISTENERI palListeneri = NULL; +LPALLISTENER3I palListener3i = NULL; +LPALLISTENERIV palListeneriv = NULL; +LPALGETLISTENERF palGetListenerf = NULL; +LPALGETLISTENER3F palGetListener3f = NULL; +LPALGETLISTENERFV palGetListenerfv = NULL; +LPALGETLISTENERI palGetListeneri = NULL; +LPALGETLISTENER3I palGetListener3i = NULL; +LPALGETLISTENERIV palGetListeneriv = NULL; +LPALGENSOURCES palGenSources = NULL; +LPALDELETESOURCES palDeleteSources = NULL; +LPALISSOURCE palIsSource = NULL; +LPALSOURCEF palSourcef = NULL; +LPALSOURCE3F palSource3f = NULL; +LPALSOURCEFV palSourcefv = NULL; +LPALSOURCEI palSourcei = NULL; +LPALSOURCE3I palSource3i = NULL; +LPALSOURCEIV palSourceiv = NULL; +LPALGETSOURCEF palGetSourcef = NULL; +LPALGETSOURCE3F palGetSource3f = NULL; +LPALGETSOURCEFV palGetSourcefv = NULL; +LPALGETSOURCEI palGetSourcei = NULL; +LPALGETSOURCE3I palGetSource3i = NULL; +LPALGETSOURCEIV palGetSourceiv = NULL; +LPALSOURCEPLAYV palSourcePlayv = NULL; +LPALSOURCESTOPV palSourceStopv = NULL; +LPALSOURCEREWINDV palSourceRewindv = NULL; +LPALSOURCEPAUSEV palSourcePausev = NULL; +LPALSOURCEPLAY palSourcePlay = NULL; +LPALSOURCESTOP palSourceStop = NULL; +LPALSOURCEREWIND palSourceRewind = NULL; +LPALSOURCEPAUSE palSourcePause = NULL; +LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers = NULL; +LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers = NULL; +LPALGENBUFFERS palGenBuffers = NULL; +LPALDELETEBUFFERS palDeleteBuffers = NULL; +LPALISBUFFER palIsBuffer = NULL; +LPALBUFFERF palBufferf = NULL; +LPALBUFFER3F palBuffer3f = NULL; +LPALBUFFERFV palBufferfv = NULL; +LPALBUFFERI palBufferi = NULL; +LPALBUFFER3I palBuffer3i = NULL; +LPALBUFFERIV palBufferiv = NULL; +LPALGETBUFFERF palGetBufferf = NULL; +LPALGETBUFFER3F palGetBuffer3f = NULL; +LPALGETBUFFERFV palGetBufferfv = NULL; +LPALGETBUFFERI palGetBufferi = NULL; +LPALGETBUFFER3I palGetBuffer3i = NULL; +LPALGETBUFFERIV palGetBufferiv = NULL; +LPALBUFFERDATA palBufferData = NULL; +LPALDOPPLERFACTOR palDopplerFactor = NULL; +LPALDOPPLERVELOCITY palDopplerVelocity = NULL; +LPALDISTANCEMODEL palDistanceModel = NULL; +LPALSPEEDOFSOUND palSpeedOfSound = NULL; +#endif + +typeof(alcGetCurrentContext) *get_context; +typeof(alcMakeContextCurrent) *set_context; + +static void load_libopenal(void) +{ + DWORD failed = 0; + +#ifdef SONAME_LIBOPENAL + char error[128]; + openal_handle = wine_dlopen(SONAME_LIBOPENAL, RTLD_NOW, error, sizeof(error)); + if (!openal_handle) + ERR("Couldn't load " SONAME_LIBOPENAL ": %s\n", error); +#define LOAD_FUNCPTR(f) \ + if((p##f = wine_dlsym(openal_handle, #f, NULL, 0)) == NULL) { \ + ERR("Couldn't lookup %s in libopenal\n", #f); \ + failed = 1; \ + } + + LOAD_FUNCPTR(alcCreateContext); + LOAD_FUNCPTR(alcMakeContextCurrent); + LOAD_FUNCPTR(alcProcessContext); + LOAD_FUNCPTR(alcSuspendContext); + LOAD_FUNCPTR(alcDestroyContext); + LOAD_FUNCPTR(alcGetCurrentContext); + LOAD_FUNCPTR(alcGetContextsDevice); + LOAD_FUNCPTR(alcOpenDevice); + LOAD_FUNCPTR(alcCloseDevice); + LOAD_FUNCPTR(alcGetError); + LOAD_FUNCPTR(alcIsExtensionPresent); + LOAD_FUNCPTR(alcGetProcAddress); + LOAD_FUNCPTR(alcGetEnumValue); + LOAD_FUNCPTR(alcGetString); + LOAD_FUNCPTR(alcGetIntegerv); + LOAD_FUNCPTR(alcCaptureOpenDevice); + LOAD_FUNCPTR(alcCaptureCloseDevice); + LOAD_FUNCPTR(alcCaptureStart); + LOAD_FUNCPTR(alcCaptureStop); + LOAD_FUNCPTR(alcCaptureSamples); + LOAD_FUNCPTR(alEnable); + LOAD_FUNCPTR(alDisable); + LOAD_FUNCPTR(alIsEnabled); + LOAD_FUNCPTR(alGetString); + LOAD_FUNCPTR(alGetBooleanv); + LOAD_FUNCPTR(alGetIntegerv); + LOAD_FUNCPTR(alGetFloatv); + LOAD_FUNCPTR(alGetDoublev); + LOAD_FUNCPTR(alGetBoolean); + LOAD_FUNCPTR(alGetInteger); + LOAD_FUNCPTR(alGetFloat); + LOAD_FUNCPTR(alGetDouble); + LOAD_FUNCPTR(alGetError); + LOAD_FUNCPTR(alIsExtensionPresent); + LOAD_FUNCPTR(alGetProcAddress); + LOAD_FUNCPTR(alGetEnumValue); + LOAD_FUNCPTR(alListenerf); + LOAD_FUNCPTR(alListener3f); + LOAD_FUNCPTR(alListenerfv); + LOAD_FUNCPTR(alListeneri); + LOAD_FUNCPTR(alListener3i); + LOAD_FUNCPTR(alListeneriv); + LOAD_FUNCPTR(alGetListenerf); + LOAD_FUNCPTR(alGetListener3f); + LOAD_FUNCPTR(alGetListenerfv); + LOAD_FUNCPTR(alGetListeneri); + LOAD_FUNCPTR(alGetListener3i); + LOAD_FUNCPTR(alGetListeneriv); + LOAD_FUNCPTR(alGenSources); + LOAD_FUNCPTR(alDeleteSources); + LOAD_FUNCPTR(alIsSource); + LOAD_FUNCPTR(alSourcef); + LOAD_FUNCPTR(alSource3f); + LOAD_FUNCPTR(alSourcefv); + LOAD_FUNCPTR(alSourcei); + LOAD_FUNCPTR(alSource3i); + LOAD_FUNCPTR(alSourceiv); + LOAD_FUNCPTR(alGetSourcef); + LOAD_FUNCPTR(alGetSource3f); + LOAD_FUNCPTR(alGetSourcefv); + LOAD_FUNCPTR(alGetSourcei); + LOAD_FUNCPTR(alGetSource3i); + LOAD_FUNCPTR(alGetSourceiv); + LOAD_FUNCPTR(alSourcePlayv); + LOAD_FUNCPTR(alSourceStopv); + LOAD_FUNCPTR(alSourceRewindv); + LOAD_FUNCPTR(alSourcePausev); + LOAD_FUNCPTR(alSourcePlay); + LOAD_FUNCPTR(alSourceStop); + LOAD_FUNCPTR(alSourceRewind); + LOAD_FUNCPTR(alSourcePause); + LOAD_FUNCPTR(alSourceQueueBuffers); + LOAD_FUNCPTR(alSourceUnqueueBuffers); + LOAD_FUNCPTR(alGenBuffers); + LOAD_FUNCPTR(alDeleteBuffers); + LOAD_FUNCPTR(alIsBuffer); + LOAD_FUNCPTR(alBufferf); + LOAD_FUNCPTR(alBuffer3f); + LOAD_FUNCPTR(alBufferfv); + LOAD_FUNCPTR(alBufferi); + LOAD_FUNCPTR(alBuffer3i); + LOAD_FUNCPTR(alBufferiv); + LOAD_FUNCPTR(alGetBufferf); + LOAD_FUNCPTR(alGetBuffer3f); + LOAD_FUNCPTR(alGetBufferfv); + LOAD_FUNCPTR(alGetBufferi); + LOAD_FUNCPTR(alGetBuffer3i); + LOAD_FUNCPTR(alGetBufferiv); + LOAD_FUNCPTR(alBufferData); + LOAD_FUNCPTR(alDopplerFactor); + LOAD_FUNCPTR(alDopplerVelocity); + LOAD_FUNCPTR(alDistanceModel); + LOAD_FUNCPTR(alSpeedOfSound); +#undef LOAD_FUNCPTR +#endif + + if (failed) + { + WARN("Unloading openal\n"); + if (openal_handle != RTLD_DEFAULT) + wine_dlclose(openal_handle, NULL, 0); + openal_handle = NULL; + openal_loaded = 0; + } + else + { + openal_loaded = 1; + local_contexts = palcIsExtensionPresent(NULL, "ALC_EXT_thread_local_context"); + if (local_contexts) + { + set_context = palcGetProcAddress(NULL, "alcSetThreadContext"); + get_context = palcGetProcAddress(NULL, "alcGetThreadContext"); + if (!set_context || !get_context) + { + ERR("TLS advertised but functions not found, disabling thread local context\n"); + local_contexts = 0; + } + } + if (!local_contexts) + { + set_context = palcMakeContextCurrent; + get_context = palcGetCurrentContext; + } + } +} + +#endif /*HAVE_OPENAL*/ + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); @@ -50,6 +309,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); +#ifdef HAVE_OPENAL + load_libopenal(); +#endif /*HAVE_OPENAL*/ break; case DLL_PROCESS_DETACH: MMDevEnum_Free(); diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index cc4b3f26388..310c9f1b121 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -34,3 +34,255 @@ typedef struct MMDevice { GUID devguid; WCHAR *alname; } MMDevice; + +#ifdef HAVE_OPENAL + +#ifdef HAVE_AL_AL_H +#include +#include +#elif defined(HAVE_OPENAL_AL_H) +#include +#include +#else +#error No OpenAL headers found? +#endif +#include "alext.h" + +/* All openal functions */ +extern int openal_loaded; +#ifdef SONAME_LIBOPENAL +extern LPALCCREATECONTEXT palcCreateContext; +extern LPALCMAKECONTEXTCURRENT palcMakeContextCurrent; +extern LPALCPROCESSCONTEXT palcProcessContext; +extern LPALCSUSPENDCONTEXT palcSuspendContext; +extern LPALCDESTROYCONTEXT palcDestroyContext; +extern LPALCGETCURRENTCONTEXT palcGetCurrentContext; +extern LPALCGETCONTEXTSDEVICE palcGetContextsDevice; +extern LPALCOPENDEVICE palcOpenDevice; +extern LPALCCLOSEDEVICE palcCloseDevice; +extern LPALCGETERROR palcGetError; +extern LPALCISEXTENSIONPRESENT palcIsExtensionPresent; +extern LPALCGETPROCADDRESS palcGetProcAddress; +extern LPALCGETENUMVALUE palcGetEnumValue; +extern LPALCGETSTRING palcGetString; +extern LPALCGETINTEGERV palcGetIntegerv; +extern LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice; +extern LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice; +extern LPALCCAPTURESTART palcCaptureStart; +extern LPALCCAPTURESTOP palcCaptureStop; +extern LPALCCAPTURESAMPLES palcCaptureSamples; +extern LPALENABLE palEnable; +extern LPALDISABLE palDisable; +extern LPALISENABLED palIsEnabled; +extern LPALGETSTRING palGetString; +extern LPALGETBOOLEANV palGetBooleanv; +extern LPALGETINTEGERV palGetIntegerv; +extern LPALGETFLOATV palGetFloatv; +extern LPALGETDOUBLEV palGetDoublev; +extern LPALGETBOOLEAN palGetBoolean; +extern LPALGETINTEGER palGetInteger; +extern LPALGETFLOAT palGetFloat; +extern LPALGETDOUBLE palGetDouble; +extern LPALGETERROR palGetError; +extern LPALISEXTENSIONPRESENT palIsExtensionPresent; +extern LPALGETPROCADDRESS palGetProcAddress; +extern LPALGETENUMVALUE palGetEnumValue; +extern LPALLISTENERF palListenerf; +extern LPALLISTENER3F palListener3f; +extern LPALLISTENERFV palListenerfv; +extern LPALLISTENERI palListeneri; +extern LPALLISTENER3I palListener3i; +extern LPALLISTENERIV palListeneriv; +extern LPALGETLISTENERF palGetListenerf; +extern LPALGETLISTENER3F palGetListener3f; +extern LPALGETLISTENERFV palGetListenerfv; +extern LPALGETLISTENERI palGetListeneri; +extern LPALGETLISTENER3I palGetListener3i; +extern LPALGETLISTENERIV palGetListeneriv; +extern LPALGENSOURCES palGenSources; +extern LPALDELETESOURCES palDeleteSources; +extern LPALISSOURCE palIsSource; +extern LPALSOURCEF palSourcef; +extern LPALSOURCE3F palSource3f; +extern LPALSOURCEFV palSourcefv; +extern LPALSOURCEI palSourcei; +extern LPALSOURCE3I palSource3i; +extern LPALSOURCEIV palSourceiv; +extern LPALGETSOURCEF palGetSourcef; +extern LPALGETSOURCE3F palGetSource3f; +extern LPALGETSOURCEFV palGetSourcefv; +extern LPALGETSOURCEI palGetSourcei; +extern LPALGETSOURCE3I palGetSource3i; +extern LPALGETSOURCEIV palGetSourceiv; +extern LPALSOURCEPLAYV palSourcePlayv; +extern LPALSOURCESTOPV palSourceStopv; +extern LPALSOURCEREWINDV palSourceRewindv; +extern LPALSOURCEPAUSEV palSourcePausev; +extern LPALSOURCEPLAY palSourcePlay; +extern LPALSOURCESTOP palSourceStop; +extern LPALSOURCEREWIND palSourceRewind; +extern LPALSOURCEPAUSE palSourcePause; +extern LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers; +extern LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers; +extern LPALGENBUFFERS palGenBuffers; +extern LPALDELETEBUFFERS palDeleteBuffers; +extern LPALISBUFFER palIsBuffer; +extern LPALBUFFERF palBufferf; +extern LPALBUFFER3F palBuffer3f; +extern LPALBUFFERFV palBufferfv; +extern LPALBUFFERI palBufferi; +extern LPALBUFFER3I palBuffer3i; +extern LPALBUFFERIV palBufferiv; +extern LPALGETBUFFERF palGetBufferf; +extern LPALGETBUFFER3F palGetBuffer3f; +extern LPALGETBUFFERFV palGetBufferfv; +extern LPALGETBUFFERI palGetBufferi; +extern LPALGETBUFFER3I palGetBuffer3i; +extern LPALGETBUFFERIV palGetBufferiv; +extern LPALBUFFERDATA palBufferData; +extern LPALDOPPLERFACTOR palDopplerFactor; +extern LPALDOPPLERVELOCITY palDopplerVelocity; +extern LPALDISTANCEMODEL palDistanceModel; +extern LPALSPEEDOFSOUND palSpeedOfSound; +#else +#define palcCreateContext alcCreateContext +#define palcMakeContextCurrent alcMakeContextCurrent +#define palcProcessContext alcProcessContext +#define palcSuspendContext alcSuspendContext +#define palcDestroyContext alcDestroyContext +#define palcGetCurrentContext alcGetCurrentContext +#define palcGetContextsDevice alcGetContextsDevice +#define palcOpenDevice alcOpenDevice +#define palcCloseDevice alcCloseDevice +#define palcGetError alcGetError +#define palcIsExtensionPresent alcIsExtensionPresent +#define palcGetProcAddress alcGetProcAddress +#define palcGetEnumValue alcGetEnumValue +#define palcGetString alcGetString +#define palcGetIntegerv alcGetIntegerv +#define palcCaptureOpenDevice alcCaptureOpenDevice +#define palcCaptureCloseDevice alcCaptureCloseDevice +#define palcCaptureStart alcCaptureStart +#define palcCaptureStop alcCaptureStop +#define palcCaptureSamples alcCaptureSamples +#define palEnable alEnable +#define palDisable alDisable +#define palIsEnabled alIsEnabled +#define palGetString alGetString +#define palGetBooleanv alGetBooleanv +#define palGetIntegerv alGetIntegerv +#define palGetFloatv alGetFloatv +#define palGetDoublev alGetDoublev +#define palGetBoolean alGetBoolean +#define palGetInteger alGetInteger +#define palGetFloat alGetFloat +#define palGetDouble alGetDouble +#define palGetError alGetError +#define palIsExtensionPresent alIsExtensionPresent +#define palGetProcAddress alGetProcAddress +#define palGetEnumValue alGetEnumValue +#define palListenerf alListenerf +#define palListener3f alListener3f +#define palListenerfv alListenerfv +#define palListeneri alListeneri +#define palListener3i alListener3i +#define palListeneriv alListeneriv +#define palGetListenerf alGetListenerf +#define palGetListener3f alGetListener3f +#define palGetListenerfv alGetListenerfv +#define palGetListeneri alGetListeneri +#define palGetListener3i alGetListener3i +#define palGetListeneriv alGetListeneriv +#define palGenSources alGenSources +#define palDeleteSources alDeleteSources +#define palIsSource alIsSource +#define palSourcef alSourcef +#define palSource3f alSource3f +#define palSourcefv alSourcefv +#define palSourcei alSourcei +#define palSource3i alSource3i +#define palSourceiv alSourceiv +#define palGetSourcef alGetSourcef +#define palGetSource3f alGetSource3f +#define palGetSourcefv alGetSourcefv +#define palGetSourcei alGetSourcei +#define palGetSource3i alGetSource3i +#define palGetSourceiv alGetSourceiv +#define palSourcePlayv alSourcePlayv +#define palSourceStopv alSourceStopv +#define palSourceRewindv alSourceRewindv +#define palSourcePausev alSourcePausev +#define palSourcePlay alSourcePlay +#define palSourceStop alSourceStop +#define palSourceRewind alSourceRewind +#define palSourcePause alSourcePause +#define palSourceQueueBuffers alSourceQueueBuffers +#define palSourceUnqueueBuffers alSourceUnqueueBuffers +#define palGenBuffers alGenBuffers +#define palDeleteBuffers alDeleteBuffers +#define palIsBuffer alIsBuffer +#define palBufferf alBufferf +#define palBuffer3f alBuffer3f +#define palBufferfv alBufferfv +#define palBufferi alBufferi +#define palBuffer3i alBuffer3i +#define palBufferiv alBufferiv +#define palGetBufferf alGetBufferf +#define palGetBuffer3f alGetBuffer3f +#define palGetBufferfv alGetBufferfv +#define palGetBufferi alGetBufferi +#define palGetBuffer3i alGetBuffer3i +#define palGetBufferiv alGetBufferiv +#define palBufferData alBufferData +#define palDopplerFactor alDopplerFactor +#define palDopplerVelocity alDopplerVelocity +#define palDistanceModel alDistanceModel +#define palSpeedOfSound alSpeedOfSound +#endif + +/* OpenAL only allows for 1 single access to the device at the same time */ +extern CRITICAL_SECTION openal_crst; +extern int local_contexts; +extern typeof(alcGetCurrentContext) *get_context; +extern typeof(alcMakeContextCurrent) *set_context; + +#define getALError() \ +do { \ + ALenum err = palGetError(); \ + if(err != AL_NO_ERROR) \ + { \ + ERR(">>>>>>>>>>>> Received AL error %#x on context %p, %s:%u\n", err, get_context(), __FUNCTION__, __LINE__); \ + } \ +} while (0) + +#define getALCError(dev) \ +do { \ + ALenum err = palcGetError(dev); \ + if(err != ALC_NO_ERROR) \ + { \ + ERR(">>>>>>>>>>>> Received ALC error %#x on device %p, %s:%u\n", err, dev, __FUNCTION__, __LINE__); \ + } \ +} while(0) + +#define setALContext(actx) \ + do { \ + ALCcontext *__old_ctx, *cur_ctx = actx ; \ + if (!local_contexts) EnterCriticalSection(&openal_crst); \ + __old_ctx = get_context(); \ + if (__old_ctx != cur_ctx && set_context(cur_ctx) == ALC_FALSE) {\ + ERR("Couldn't set current context!!\n"); \ + getALCError(palcGetContextsDevice(cur_ctx)); \ + } + +/* Only restore a NULL context if using global contexts, for TLS contexts always restore */ +#define popALContext() \ + if (__old_ctx != cur_ctx \ + && (local_contexts || __old_ctx) \ + && set_context(__old_ctx) == ALC_FALSE) { \ + ERR("Couldn't restore old context!!\n"); \ + getALCError(palcGetContextsDevice(__old_ctx)); \ + } \ + if (!local_contexts) LeaveCriticalSection(&openal_crst); \ + } while (0) + +#endif