⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opengl32.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $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 + -