📄 opengl32.c
字号:
/* $Id: opengl32.c 22407 2006-06-19 12:09:56Z gedmurphy $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/opengl32/opengl32.c
* PURPOSE: OpenGL32 lib
* PROGRAMMER: Anich Gregor (blight), Royce Mitchell III
* UPDATE HISTORY:
* Feb 1, 2004: Created
*/
#define WIN32_LEAN_AND_MEAN
#define WIN32_NO_STATUS
#include <windows.h>
#include <winreg.h>
#include "teb.h"
#include <string.h>
#include "opengl32.h"
/* function prototypes */
static void OPENGL32_AppendICD( GLDRIVERDATA *icd );
static void OPENGL32_RemoveICD( GLDRIVERDATA *icd );
static GLDRIVERDATA *OPENGL32_LoadDriver( LPCWSTR regKey );
static DWORD OPENGL32_InitializeDriver( GLDRIVERDATA *icd );
static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd );
static DWORD OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd );
/* global vars */
DWORD OPENGL32_tls;
GLPROCESSDATA OPENGL32_processdata;
static BOOL
OPENGL32_ThreadAttach()
{
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL;
TEB *teb = NULL;
dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (((ICDTable *)(0))->dispatch_table) );
if (dispatchTable == NULL)
{
DBGPRINT( "Error: Couldn't allocate GL dispatch table" );
return FALSE;
}
lpData = (GLTHREADDATA*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (GLTHREADDATA) );
if (lpData == NULL)
{
DBGPRINT( "Error: Couldn't allocate GLTHREADDATA" );
HeapFree( GetProcessHeap(), 0, dispatchTable );
return FALSE;
}
teb = NtCurrentTeb();
/* initialize dispatch table with empty functions */
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
dispatchTable[icdidx] = (PROC)glEmptyFunc##stack; \
if (tebidx >= 0) \
teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack;
GLFUNCS_MACRO
#undef X
teb->glTable = dispatchTable;
TlsSetValue( OPENGL32_tls, lpData );
return TRUE;
}
static void
OPENGL32_ThreadDetach()
{
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL;
rosglMakeCurrent( NULL, NULL );
lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
if (lpData != NULL)
{
if (!HeapFree( GetProcessHeap(), 0, lpData ))
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() );
}
}
static BOOL
OPENGL32_ProcessAttach()
{
SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
NULL, /* lpSecurityDescriptor */
TRUE /* bInheritHandle */ };
OPENGL32_tls = TlsAlloc();
if (0xFFFFFFFF == OPENGL32_tls)
return FALSE;
memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) );
/* create driver, glrc & dcdata list mutex */
OPENGL32_processdata.driver_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.driver_mutex == NULL)
{
DBGPRINT( "Error: Couldn't create driver_list mutex (%d)",
GetLastError() );
return FALSE;
}
OPENGL32_processdata.glrc_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.glrc_mutex == NULL)
{
DBGPRINT( "Error: Couldn't create glrc_list mutex (%d)",
GetLastError() );
return FALSE;
}
OPENGL32_processdata.dcdata_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.dcdata_mutex == NULL)
{
DBGPRINT( "Error: Couldn't create dcdata_list mutex (%d)",
GetLastError() );
return FALSE;
}
return TRUE;
}
static void
OPENGL32_ProcessDetach()
{
GLDRIVERDATA *icd, *icd2;
GLDCDATA *dcdata, *dcdata2;
GLRC *glrc, *glrc2;
/* free lists */
for (dcdata = OPENGL32_processdata.dcdata_list; dcdata != NULL;)
{
dcdata2 = dcdata;
dcdata = dcdata->next;
if (!HeapFree( GetProcessHeap(), 0, dcdata ))
DBGPRINT( "Warning: HeapFree() on DCDATA 0x%08x failed (%d)",
dcdata, GetLastError() );
}
for (glrc = OPENGL32_processdata.glrc_list; glrc != NULL;)
{
glrc2 = glrc;
glrc = glrc->next;
if (!HeapFree( GetProcessHeap(), 0, glrc ))
DBGPRINT( "Warning: HeapFree() on GLRC 0x%08x failed (%d)",
glrc, GetLastError() );
}
for (icd = OPENGL32_processdata.driver_list; icd != NULL;)
{
icd2 = icd;
icd = icd->next;
if (!HeapFree( GetProcessHeap(), 0, icd ))
DBGPRINT( "Warning: HeapFree() on DRIVERDATA 0x%08x failed (%d)",
icd, GetLastError() );
}
/* free mutexes */
if (OPENGL32_processdata.driver_mutex != NULL)
CloseHandle( OPENGL32_processdata.driver_mutex );
if (OPENGL32_processdata.glrc_mutex != NULL)
CloseHandle( OPENGL32_processdata.glrc_mutex );
if (OPENGL32_processdata.dcdata_mutex != NULL)
CloseHandle( OPENGL32_processdata.dcdata_mutex );
/* free TLS */
if (OPENGL32_tls != 0xffffffff)
TlsFree(OPENGL32_tls);
}
BOOL WINAPI
DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
{
DBGPRINT( "Info: Called!" );
switch ( Reason )
{
/* The DLL is loading due to process
* initialization or a call to LoadLibrary.
*/
case DLL_PROCESS_ATTACH:
DBGTRACE( "Process attach" );
if (!OPENGL32_ProcessAttach())
return FALSE;
/* No break: Initialize the index for first thread. */
/* The attached process creates a new thread. */
case DLL_THREAD_ATTACH:
DBGTRACE( "Thread attach" );
if (!OPENGL32_ThreadAttach())
return FALSE;
break;
/* The thread of the attached process terminates. */
case DLL_THREAD_DETACH:
DBGTRACE( "Thread detach" );
/* Release the allocated memory for this thread.*/
OPENGL32_ThreadDetach();
break;
/* DLL unload due to process termination or FreeLibrary. */
case DLL_PROCESS_DETACH:
DBGTRACE( "Process detach" );
OPENGL32_ThreadDetach();
OPENGL32_ProcessDetach();
break;
}
return TRUE;
}
/*! \brief Append ICD to linked list.
*
* \param icd GLDRIVERDATA to append to list
*
* \note Only call this when you hold the driver_mutex.
*/
static void
OPENGL32_AppendICD( GLDRIVERDATA *icd )
{
if (OPENGL32_processdata.driver_list == NULL)
OPENGL32_processdata.driver_list = icd;
else
{
GLDRIVERDATA *p = OPENGL32_processdata.driver_list;
while (p->next != NULL)
p = p->next;
p->next = icd;
}
}
/*! \brief Remove ICD from linked list.
*
* \param icd GLDRIVERDATA to remove from list
*
* \note Only call this when you hold the driver_mutex.
*/
static void
OPENGL32_RemoveICD( GLDRIVERDATA *icd )
{
if (icd == OPENGL32_processdata.driver_list)
OPENGL32_processdata.driver_list = icd->next;
else
{
GLDRIVERDATA *p = OPENGL32_processdata.driver_list;
while (p != NULL)
{
if (p->next == icd)
{
p->next = icd->next;
return;
}
p = p->next;
}
DBGPRINT( "Error: ICD 0x%08x not found in list!", icd );
}
}
/*! \brief Load an ICD.
*
* \param driver Name of installable client driver.
*
* \return Pointer to an allocated GLDRIVERDATA struct.
* \retval NULL Failure.
*
* \todo Call SetLastError() where appropriate.
*/
static GLDRIVERDATA *
OPENGL32_LoadDriver( LPCWSTR driver )
{
LONG ret;
GLDRIVERDATA *icd;
DBGPRINT( "Info: Loading driver %ws...", driver );
/* allocate driver data */
icd = (GLDRIVERDATA*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (GLDRIVERDATA) );
if (icd == NULL)
{
DBGPRINT( "Error: Couldn't allocate GLDRIVERDATA! (%d)", GetLastError() );
return NULL;
}
ret = OPENGL32_RegGetDriverInfo( driver, icd );
if (ret != ERROR_SUCCESS)
{
DBGPRINT( "Error: Couldn't query driver information (%d)", ret );
if (!HeapFree( GetProcessHeap(), 0, icd ))
DBGPRINT( "Error: HeapFree() returned false, error code = %d",
GetLastError() );
return NULL;
}
DBGPRINT( "Info: Dll = %ws", icd->dll );
DBGPRINT( "Info: Version = 0x%08x", icd->version );
DBGPRINT( "Info: DriverVersion = 0x%08x", icd->driver_version );
DBGPRINT( "Info: Flags = 0x%08x", icd->flags );
/* load/initialize ICD */
ret = OPENGL32_InitializeDriver( icd );
if (ret != ERROR_SUCCESS)
{
DBGPRINT( "Error: Couldnt initialize ICD!" );
if (!HeapFree( GetProcessHeap(), 0, icd ))
DBGPRINT( "Error: HeapFree() returned false, error code = %d",
GetLastError() );
return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -