-/* $Id: opengl32.c,v 1.14 2004/02/09 08:00:15 vizzini Exp $
+/* $Id: opengl32.c,v 1.15 2004/02/12 23:56:15 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd );
/* global vars */
-/*const char* OPENGL32_funcnames[GLIDX_COUNT] SHARED =
-{
-#define X(func, ret, typeargs, args) #func,
- GLFUNCS_MACRO
-#undef X
-};*/
-
DWORD OPENGL32_tls;
GLPROCESSDATA OPENGL32_processdata;
{
/* FIXME - do we need to release some HDC or something? */
GLTHREADDATA* lpData = NULL;
+ PROC *dispatchTable = NULL;
+
lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
if (lpData != NULL)
{
DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)",
GetLastError() );
}
+
+
+ dispatchTable = NtCurrentTeb()->glTable;
+
+ if (dispatchTable != NULL)
+ {
+ if (!HeapFree( GetProcessHeap(), 0, dispatchTable ))
+ DBGPRINT( "Warning: HeapFree() on dispatch table failed (%d)",
+ GetLastError() );
+ }
}
DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
{
GLTHREADDATA* lpData = NULL;
- ICDTable *dispatchTable = NULL;
+ PROC *dispatchTable = NULL;
TEB *teb = NULL;
SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
NULL, /* lpSecurityDescriptor */
/* The attached process creates a new thread. */
case DLL_THREAD_ATTACH:
- dispatchTable = (ICDTable*)HeapAlloc( GetProcessHeap(),
+ dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
- sizeof (ICDTable) );
+ sizeof (((ICDTable *)(0))->dispatch_table) );
if (dispatchTable == NULL)
{
DBGPRINT( "Error: Couldn't allocate GL dispatch table" );
/* initialize dispatch table with empty functions */
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
- dispatchTable->dispatch_table[icdidx] = (PROC)glEmptyFunc##stack; \
+ dispatchTable[icdidx] = (PROC)glEmptyFunc##stack; \
if (tebidx >= 0) \
teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack;
GLFUNCS_MACRO
#undef X
- teb->glTable = dispatchTable->dispatch_table;
+ teb->glTable = dispatchTable;
TlsSetValue( OPENGL32_tls, lpData );
break;
LOAD_DRV_PROC(icd, DrvSwapLayerBuffers, TRUE);
/* we require at least one of DrvCreateContext and DrvCreateLayerContext */
- if (icd->DrvCreateContext == NULL || icd->DrvCreateLayerContext == NULL)
+ if (icd->DrvCreateContext == NULL && icd->DrvCreateLayerContext == NULL)
{
DBGPRINT( "Error: One of DrvCreateContext/DrvCreateLayerContext is required!" );
FreeLibrary( icd->handle );
}
icd->refcount--;
- if (icd->refcount == 0)
+ //if (icd->refcount == 0)
+ if (0)
ret = OPENGL32_UnloadDriver( icd );
+ /* FIXME: InitializeICD crashes when called a second time */
/* release mutex */
if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
* be multiple times for one DrvSetContext call.
* ARGUMENTS: [IN] table Function pointer table (first DWORD is number of
* functions)
- * RETURNS: unkown
+ * RETURNS: unkown (maybe void?)
*/
DWORD
CALLBACK
/* UINT i;*/
TEB *teb;
PROC *tebTable, *tebDispatchTable;
+ INT size;
teb = NtCurrentTeb();
tebTable = (PROC *)teb->glTable;
tebDispatchTable = (PROC *)teb->glDispatchTable;
- DBGPRINT( "Function count: %d\n", table->num_funcs );
+ if (table != NULL)
+ {
+ DBGPRINT( "Function count: %d\n", table->num_funcs );
- /* save table */
- memcpy( tebTable, table->dispatch_table,
- sizeof (PROC) * table->num_funcs );
- memset( tebTable + sizeof (PROC) * table->num_funcs, 0,
- sizeof (table->dispatch_table) - (sizeof (PROC) * table->num_funcs) );
+ /* save table */
+ size = sizeof (PROC) * table->num_funcs;
+ memcpy( tebTable, table->dispatch_table, size );
+ memset( tebTable + table->num_funcs, 0,
+ sizeof (table->dispatch_table) - size );
+ }
+ else
+ {
+ DBGPRINT( "Unsetting current context" );
+ memset( tebTable, 0, sizeof (table->dispatch_table) );
+ }
/* FIXME: pull in software fallbacks -- need mesa */
#if 0 /* unused atm */
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
if (tebTable[icdidx] == NULL) \
{ \
- DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
+ if (table != NULL) \
+ DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
}
GLFUNCS_MACRO
/* check input */
if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
{
+ OPENGL32_UnloadICD( icd );
SetLastError( 0 ); /* FIXME: use appropriate errorcode */
return 0;
}
if (icdNumFormats == 0)
{
DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
+ OPENGL32_UnloadICD( icd );
return 0;
}
DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
if (best == 0)
SetLastError( 0 ); /* FIXME: set appropriate error */
+ OPENGL32_UnloadICD( icd );
DBGPRINT( "Info: Suggesting pixelformat %d", best );
return best;
ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
if (ret == 0)
DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
+ OPENGL32_UnloadICD( icd );
}
/* FIXME: implement own functionality? */
if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */
{
- PROC glXXX = OPENGL32_threaddata->glrc->icd->DrvGetProcAddress( proc );
+ PROC glXXX = NULL;
+ GLDRIVERDATA *icd = OPENGL32_threaddata->glrc->icd;
+ glXXX = icd->DrvGetProcAddress( proc );
if (glXXX)
{
DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
glFlush();
}
- /* check hdc */
- if (GetObjectType( hdc ) != OBJ_DC)
+ /* check if current context is unset */
+ if (glrc == NULL)
{
- DBGPRINT( "Error: hdc is not a DC handle!" );
- return FALSE;
+ if (OPENGL32_threaddata->glrc != NULL)
+ {
+ OPENGL32_threaddata->glrc->is_current = FALSE;
+ OPENGL32_threaddata->glrc = NULL;
+ }
}
-
- /* check if we know about this glrc */
- if (!WGL_ContainsContext( glrc ))
+ else
{
- DBGPRINT( "Error: hglrc not found!" );
- return FALSE; /* FIXME: SetLastError() */
- }
+ /* check hdc */
+ if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
+ {
+ DBGPRINT( "Error: hdc is not a DC handle!" );
+ return FALSE;
+ }
- /* check if it is available */
- if (glrc->is_current) /* used by another thread */
- {
- DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
- return FALSE; /* FIXME: SetLastError() */
- }
+ /* check if we know about this glrc */
+ if (!WGL_ContainsContext( glrc ))
+ {
+ DBGPRINT( "Error: hglrc not found!" );
+ return FALSE; /* FIXME: SetLastError() */
+ }
- /* call the ICD */
- if (glrc->hglrc != NULL)
- {
- icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
- WGL_SetContextCallBack );
- if (icdTable == NULL)
+ /* check if it is available */
+ if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
{
- DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
- return FALSE;
+ DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
+ return FALSE; /* FIXME: SetLastError() */
}
- DBGPRINT( "Info: DrvSetContext succeeded!" );
+
+ /* call the ICD */
+ if (glrc->hglrc != NULL)
+ {
+ icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
+ WGL_SetContextCallBack );
+ if (icdTable == NULL)
+ {
+ DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
+ return FALSE;
+ }
+ DBGPRINT( "Info: DrvSetContext succeeded!" );
+ }
+
+ /* make it current */
+ if (OPENGL32_threaddata->glrc != NULL)
+ OPENGL32_threaddata->glrc->is_current = FALSE;
+ glrc->is_current = TRUE;
+ glrc->thread_id = GetCurrentThreadId();
+ glrc->hdc = hdc;
+ OPENGL32_threaddata->glrc = glrc;
}
- /* make it current */
- if (OPENGL32_threaddata->glrc != NULL)
- OPENGL32_threaddata->glrc->is_current = FALSE;
- glrc->is_current = TRUE;
- glrc->thread_id = GetCurrentThreadId();
- glrc->hdc = hdc;
- OPENGL32_threaddata->glrc = glrc;
+ WGL_SetContextCallBack( icdTable );
if (icdTable != NULL)
if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
{
DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
iFormat, GetLastError() );
+ OPENGL32_UnloadICD( icd );
return FALSE;
}
OPENGL32_processdata.cachedHdc = hdc;
OPENGL32_processdata.cachedFormat = iFormat;
+ OPENGL32_UnloadICD( icd );
return TRUE;
}
if (!icd->DrvSwapBuffers( hdc ))
{
DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
+ OPENGL32_UnloadICD( icd );
return FALSE;
}
+ OPENGL32_UnloadICD( icd );
return TRUE;
}