Chris Robinson : openal32: Wrap and track OpenAL contexts.
Alexandre Julliard
julliard at winehq.org
Wed Sep 9 09:58:49 CDT 2009
Module: wine
Branch: master
Commit: fbafa5d8f5137bec9e5468f3d7ac405ba3220c67
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fbafa5d8f5137bec9e5468f3d7ac405ba3220c67
Author: Chris Robinson <chris.kcat at gmail.com>
Date: Tue Aug 25 18:55:53 2009 -0700
openal32: Wrap and track OpenAL contexts.
---
dlls/openal32/openal.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/dlls/openal32/openal.c b/dlls/openal32/openal.c
index 840498d..6e48375 100644
--- a/dlls/openal32/openal.c
+++ b/dlls/openal32/openal.c
@@ -36,6 +36,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(openal32);
+typedef struct wine_ALCcontext {
+ ALCcontext *ctx;
+
+ struct wine_ALCcontext *next;
+} wine_ALCcontext;
struct FuncList {
const char *name;
@@ -45,6 +50,18 @@ struct FuncList {
static const struct FuncList ALCFuncs[];
static const struct FuncList ALFuncs[];
+static wine_ALCcontext *CtxList;
+static wine_ALCcontext *CurrentCtx;
+
+CRITICAL_SECTION openal_cs;
+static CRITICAL_SECTION_DEBUG openal_cs_debug =
+{
+ 0, 0, &openal_cs,
+ {&openal_cs_debug.ProcessLocksList,
+ &openal_cs_debug.ProcessLocksList},
+ 0, 0, {(DWORD_PTR)(__FILE__ ": openal_cs")}
+};
+CRITICAL_SECTION openal_cs = {&openal_cs_debug, -1, 0, 0, 0, 0};
/***********************************************************************
* OpenAL initialisation routine
@@ -56,12 +73,30 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinst);
break;
+ case DLL_PROCESS_DETACH:
+ while(CtxList)
+ {
+ wine_ALCcontext *next = CtxList->next;
+ HeapFree(GetProcessHeap(), 0, CtxList);
+ CtxList = next;
+ }
}
return TRUE;
}
+/* Validates the given context */
+static wine_ALCcontext *ValidateCtx(ALCcontext *ctx)
+{
+ wine_ALCcontext *cur = CtxList;
+
+ while(cur != NULL && cur->ctx != ctx)
+ cur = cur->next;
+ return cur;
+}
+
+
/***********************************************************************
* OpenAL thunk routines
*/
@@ -69,12 +104,55 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
/* OpenAL ALC 1.0 functions */
ALCcontext* CDECL wine_alcCreateContext(ALCdevice *device, const ALCint* attrlist)
{
- return alcCreateContext(device, attrlist);
+ wine_ALCcontext *ctx;
+
+ ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wine_ALCcontext));
+ if(!ctx)
+ {
+ ERR("Out of memory!\n");
+ return NULL;
+ }
+
+ ctx->ctx = alcCreateContext(device, attrlist);
+ if(!ctx->ctx)
+ {
+ HeapFree(GetProcessHeap(), 0, ctx);
+ WARN("Failed to create new context\n");
+ return NULL;
+ }
+ TRACE("Created new context %p\n", ctx->ctx);
+
+ EnterCriticalSection(&openal_cs);
+ ctx->next = CtxList;
+ CtxList = ctx;
+ LeaveCriticalSection(&openal_cs);
+
+ return ctx->ctx;
}
ALCboolean CDECL wine_alcMakeContextCurrent(ALCcontext *context)
{
- return alcMakeContextCurrent(context);
+ wine_ALCcontext *ctx = NULL;
+
+ EnterCriticalSection(&openal_cs);
+ if(context && !(ctx=ValidateCtx(context)))
+ {
+ FIXME("Could not find context %p in context list\n", context);
+ LeaveCriticalSection(&openal_cs);
+ return ALC_FALSE;
+ }
+
+ if(alcMakeContextCurrent(ctx ? ctx->ctx : NULL) == ALC_FALSE)
+ {
+ WARN("Failed to make context %p current\n", ctx->ctx);
+ LeaveCriticalSection(&openal_cs);
+ return ALC_FALSE;
+ }
+
+ CurrentCtx = ctx;
+ LeaveCriticalSection(&openal_cs);
+
+ return ALC_TRUE;
}
ALvoid CDECL wine_alcProcessContext(ALCcontext *context)
@@ -89,12 +167,43 @@ ALvoid CDECL wine_alcSuspendContext(ALCcontext *context)
ALvoid CDECL wine_alcDestroyContext(ALCcontext *context)
{
+ wine_ALCcontext **list, *ctx;
+
+ EnterCriticalSection(&openal_cs);
+
+ list = &CtxList;
+ while(*list && (*list)->ctx != context)
+ list = &(*list)->next;
+
+ if(!(*list))
+ {
+ FIXME("Could not find context %p in context list\n", context);
+ LeaveCriticalSection(&openal_cs);
+ return;
+ }
+
+ ctx = *list;
+ *list = (*list)->next;
+
+ if(ctx == CurrentCtx)
+ CurrentCtx = NULL;
+
+ LeaveCriticalSection(&openal_cs);
+
+ HeapFree(GetProcessHeap(), 0, ctx);
alcDestroyContext(context);
}
ALCcontext* CDECL wine_alcGetCurrentContext(ALCvoid)
{
- return alcGetCurrentContext();
+ ALCcontext *ret = NULL;
+
+ EnterCriticalSection(&openal_cs);
+ if(CurrentCtx)
+ ret = CurrentCtx->ctx;
+ LeaveCriticalSection(&openal_cs);
+
+ return ret;
}
ALCdevice* CDECL wine_alcGetContextsDevice(ALCcontext *context)
More information about the wine-cvs
mailing list