Fix some bugs, works on Windows and ReactOS with Mesa and NVIDIA driver.

x86 asm version of gl dispatch functions work now too (in gl.c)

svn path=/trunk/; revision=10141
This commit is contained in:
Gregor Anich
2004-07-16 16:16:16 +00:00
parent 28e3667b69
commit 243d59c9e6
5 changed files with 474 additions and 291 deletions
+18 -6
View File
@@ -20,7 +20,7 @@
* On other machines we use C to forward the calls (slow...)
*/
#define WIN32_LEAN_AND_MEAN
#define WIN32_LEANER_AND_MEANER
#include <windows.h>
#include "teb.h"
@@ -58,13 +58,25 @@ int STDCALL glEmptyFunc56( long l1, long l2, long l3, long l4, long l5,
long l11, long l12, long l13, long l14 )
{ return 0; }
#if 1//!defined(_M_IX86)
#if defined(_M_IX86)
# define FOO(x) #x
# define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
__asm__(".globl _"#func"@"#stack "\n\t" \
"_"#func"@"#stack":" "\n\t" \
" movl %fs:0x18, %eax" "\n\t" \
" movl 0xbe8(%eax), %eax" "\n\t" \
" jmp *"FOO((icdidx*4))"(%eax)" "\n\t");
GLFUNCS_MACRO
# undef FOO
# undef X
#else /* defined(_M_IX86) */
# define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
ret STDCALL func typeargs \
{ \
PROC *table; \
PROC *table; \
PROC fn; \
if (tebidx >= 0) \
if (tebidx >= 10000) \
{ \
table = (PROC *)NtCurrentTeb()->glDispatchTable; \
fn = table[tebidx]; \
@@ -79,7 +91,7 @@ ret STDCALL func typeargs \
GLFUNCS_MACRO
#undef X
#endif//non-x86 architectures
# undef X
#endif /* !defined(_M_IX86) */
/* EOF */
+2 -2
View File
@@ -14,8 +14,8 @@ enum icdoffsets_e
typedef struct tagICDTable
{
DWORD num_funcs; /* Normally 336 (0x150) */
PROC dispatch_table[812];
DWORD num_funcs; /*!< Normally 336 (0x150) -- the number of functions in OpenGL 1.1 */
PROC dispatch_table[812]; /*!< Table containing \a num_funcs pointers to OpenGL functions */
} ICDTable, *PICDTable;
#endif /* OPENGL32_PRIVATE_ICDTABLE_H */
+163 -127
View File
@@ -1,4 +1,4 @@
/* $Id: opengl32.c,v 1.16 2004/03/01 19:36:20 navaraf Exp $
/* $Id: opengl32.c,v 1.17 2004/07/16 16:16:16 blight Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -17,21 +17,65 @@
#include <string.h>
#include "opengl32.h"
/* function prototypes */
/*static BOOL OPENGL32_LoadDrivers();*/
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
void
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()
{
/* FIXME - do we need to release some HDC or something? */
@@ -56,8 +100,47 @@ OPENGL32_ThreadDetach()
}
static
void
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;
@@ -106,17 +189,9 @@ OPENGL32_ProcessDetach()
}
BOOL
WINAPI
BOOL WINAPI
DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
{
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL;
TEB *teb = NULL;
SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
NULL, /* lpSecurityDescriptor */
TRUE /* bInheritHandle */ };
DBGPRINT( "Info: Called!" );
switch ( Reason )
{
@@ -125,71 +200,15 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
*/
case DLL_PROCESS_ATTACH:
DBGTRACE( "Process attach" );
OPENGL32_tls = TlsAlloc();
if ( 0xFFFFFFFF == OPENGL32_tls )
if (!OPENGL32_ProcessAttach())
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;
}
/* No break: Initialize the index for first thread. */
/* The attached process creates a new thread. */
case DLL_THREAD_ATTACH:
DBGTRACE( "Thread attach" );
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" );
if (!OPENGL32_ThreadAttach())
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 );
break;
/* The thread of the attached process terminates. */
@@ -206,16 +225,18 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
OPENGL32_ProcessDetach();
break;
}
return TRUE;
}
/* FUNCTION: Append ICD to linked list.
* ARGUMENTS: [IN] icd: GLDRIVERDATA to append to list
* NOTES: Only call this when you hold the driver_mutex
/*! \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
static void
OPENGL32_AppendICD( GLDRIVERDATA *icd )
{
if (OPENGL32_processdata.driver_list == NULL)
@@ -230,12 +251,13 @@ OPENGL32_AppendICD( GLDRIVERDATA *icd )
}
/* FUNCTION: Remove ICD from linked list.
* ARGUMENTS: [IN] icd: GLDRIVERDATA to remove from list
* NOTES: Only call this when you hold the driver_mutex
/*! \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
static void
OPENGL32_RemoveICD( GLDRIVERDATA *icd )
{
if (icd == OPENGL32_processdata.driver_list)
@@ -257,14 +279,16 @@ OPENGL32_RemoveICD( GLDRIVERDATA *icd )
}
/* FUNCTION: Load an ICD.
* ARGUMENTS: [IN] driver: Name of display driver.
* RETURNS: error code; ERROR_SUCCESS on success
/*! \brief Load an ICD.
*
* TODO: call SetLastError() where appropriate
* \param driver Name of installable client driver.
*
* \return Pointer to an allocated GLDRIVERDATA struct.
* \retval NULL Failure.
*
* \todo Call SetLastError() where appropriate.
*/
static
GLDRIVERDATA*
static GLDRIVERDATA *
OPENGL32_LoadDriver( LPCWSTR driver )
{
LONG ret;
@@ -316,10 +340,12 @@ OPENGL32_LoadDriver( LPCWSTR driver )
}
/* FUNCTION: Initialize a driver (Load DLL, DrvXXX and glXXX procs)
* ARGUMENTS: [IN] icd: ICD to initialize with the dll, version, driverVersion
* and flags already filled.
* RETURNS: error code; ERROR_SUCCESS on success
/*! \brief Initialize a driver (Load DLL and DrvXxx procs)
*
* \param icd ICD to initialize with the dll, version, driverVersion
* and flags already filled.
* \return Error code.
* \retval ERROR_SUCCESS Success
*/
#define LOAD_DRV_PROC( icd, proc, required ) \
*(char**)&icd->proc = (char*)GetProcAddress( icd->handle, #proc ); \
@@ -329,8 +355,7 @@ OPENGL32_LoadDriver( LPCWSTR driver )
return GetLastError(); \
}
static
DWORD
static DWORD
OPENGL32_InitializeDriver( GLDRIVERDATA *icd )
{
/* check version */
@@ -394,11 +419,12 @@ OPENGL32_InitializeDriver( GLDRIVERDATA *icd )
}
/* FUNCTION: Unload loaded ICD.
* RETURNS: TRUE on success, FALSE otherwise.
/*! \brief Unload ICD.
*
* \retval TRUE Success.
* \retval FALSE Failure.
*/
static
BOOL
static BOOL
OPENGL32_UnloadDriver( GLDRIVERDATA *icd )
{
BOOL allOk = TRUE;
@@ -428,11 +454,13 @@ OPENGL32_UnloadDriver( GLDRIVERDATA *icd )
}
/* FUNCTION: Load ICD (shared ICD data)
* RETURNS: GLDRIVERDATA pointer on success, NULL otherwise.
/*! \brief Load ICD (shared ICD data)
*
* \return Pointer to an allocated GLDRIVERDATA on success.
* \retval NULL Failure.
*/
GLDRIVERDATA*
OPENGL32_LoadICD ( LPCWSTR driver )
GLDRIVERDATA *
OPENGL32_LoadICD( LPCWSTR driver )
{
GLDRIVERDATA *icd;
@@ -472,8 +500,10 @@ OPENGL32_LoadICD ( LPCWSTR driver )
}
/* FUNCTION: Unload ICD (shared ICD data)
* RETURNS: TRUE on success, FALSE otherwise.
/*! \brief Unload ICD (shared ICD data)
*
* \retval TRUE Success.
* \retval FALSE Failure.
*/
BOOL
OPENGL32_UnloadICD( GLDRIVERDATA *icd )
@@ -489,8 +519,8 @@ OPENGL32_UnloadICD( GLDRIVERDATA *icd )
}
icd->refcount--;
//if (icd->refcount == 0)
if (0)
if (icd->refcount == 0)
// if (0)
ret = OPENGL32_UnloadDriver( icd );
/* FIXME: InitializeICD crashes when called a second time */
@@ -502,21 +532,24 @@ OPENGL32_UnloadICD( GLDRIVERDATA *icd )
}
/* FUNCTION: Enumerate OpenGLDrivers (from registry)
* ARGUMENTS: [IN] idx Index of the driver to get information about
* [OUT] name Pointer to an array of WCHARs (can be NULL)
* [I,O] cName Pointer to a DWORD. Input is len of name array;
* Output is length of the drivername.
* Can be NULL if name is NULL.
* RETURNS: Error code (ERROR_NO_MORE_ITEMS at end of list); On failure all
* OUT vars are left untouched.
/*! \brief Enumerate OpenGLDrivers (from registry)
*
* \param idx Index of the driver to get information about.
* \param name Pointer to an array of WCHARs (can be NULL)
* \param cName Pointer to a DWORD. Input is len of name array.
* Output is length of the drivername.
* Can be NULL if name is NULL.
*
* \return Error code
* \retval ERROR_NO_MORE_ITEMS End of driver list.
* \retval ERROR_SUCCESS Success.
*/
#if 0 /* unused */
DWORD
OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName )
{
HKEY hKey;
LPCWSTR subKey =
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers\\";
LPCWSTR subKey = OPENGL_DRIVERS_SUBKEY;
LONG ret;
DWORD size;
WCHAR driver[256];
@@ -550,22 +583,25 @@ OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName )
RegCloseKey( hKey );
return ERROR_SUCCESS;
}
#endif /* 0 -- unused */
/* FUNCTION: Get registry values for a driver given a name
* ARGUMENTS: [IN] idx Index of the driver to get information about
* [OUT] icd Pointer to GLDRIVERDATA. On success the following
* fields are filled: driver_name, dll, version,
* driver_version and flags.
* RETURNS: Error code; On failure all OUT vars are left untouched.
/*! \brief Get registry values for a driver given a name.
*
* \param driver Name of the driver to get information about.
* \param icd Pointer to GLDRIVERDATA.
*
* \return Error code.
* \retval ERROR_SUCCESS Success.
*
* \note On success the following fields of \a icd are filled: \a driver_name,
* \a dll, \a version, \a driver_version and \a flags.
*/
/*static*/
DWORD
static DWORD
OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd )
{
HKEY hKey;
WCHAR subKey[1024] =
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers\\";
WCHAR subKey[1024] = OPENGL_DRIVERS_SUBKEY;
LONG ret;
DWORD type, size;
+54 -38
View File
@@ -1,4 +1,4 @@
/* $Id: opengl32.h,v 1.15 2004/03/01 19:36:21 navaraf Exp $
/* $Id: opengl32.h,v 1.16 2004/07/16 16:16:16 blight Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -14,7 +14,15 @@
#ifdef __cplusplus
extern "C" {
#endif//__cplusplus
#endif /* __cplusplus */
#define NDEBUG
#ifndef PFD_GENERIC_ACCELERATED
# define PFD_GENERIC_ACCELERATED 0x00001000
#endif
#define OPENGL_DRIVERS_SUBKEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers\\"
/* gl function list */
#include "glfuncs.h"
@@ -25,7 +33,7 @@ extern "C" {
/* debug flags */
#if !defined(NDEBUG)
# define DEBUG_OPENGL32
# define DEBUG_OPENGL32_BRKPTS /* enable breakpoints */
/*# define DEBUG_OPENGL32_BRKPTS*/ /* enable breakpoints */
# define DEBUG_OPENGL32_ICD_EXPORTS /* dumps the list of (un)supported glXXX
functions when an ICD is loaded. */
# define DEBUG_OPENGL32_TRACE /* prints much information about whats going on */
@@ -40,11 +48,13 @@ ULONG DbgPrint(PCH Format,...);
# include <debug.h>
# define DBGPRINT( fmt, args... ) \
DPRINT( "OpenGL32.DLL: %s: "fmt"\n", __FUNCTION__, ##args )
# else
# define DBGPRINT( ... ) do {} while (0)
# endif
#endif
#ifndef DBGPRINT
# define DBGPRINT( ... ) do {} while (0)
#endif
#ifdef DEBUG_OPENGL32_BRKPTS
# if defined(__GNUC__)
# define DBGBREAK() __asm__( "int $3" );
@@ -53,10 +63,14 @@ ULONG DbgPrint(PCH Format,...);
# else
# error Unsupported compiler!
# endif
#else
# define DBGBREAK() do {} while (0)
#endif
#ifdef DEBUG_OPENGL32_TRACE
# define DBGTRACE( args... ) DBGPRINT( args )
#else
# define DBGTRACE( ... ) do {} while (0)
#endif
/* function/data attributes */
@@ -66,7 +80,7 @@ ULONG DbgPrint(PCH Format,...);
# define SHARED
# ifndef STDCALL
# define STDCALL __stdcall
# endif/*STDCALL*/
# endif /* STDCALL */
#else /* GCC */
# define NAKED __attribute__((naked))
# define SHARED __attribute__((section("shared"), shared))
@@ -74,7 +88,7 @@ ULONG DbgPrint(PCH Format,...);
#ifdef APIENTRY
#undef APIENTRY
#endif//APIENTRY
#endif /* APIENTRY */
#define APIENTRY EXPORT __stdcall
/* gl function list */
@@ -104,14 +118,14 @@ typedef DWORD APIENTRY (*SetContextCallBack)( const ICDTable * );
/* OpenGL ICD data */
typedef struct tagGLDRIVERDATA
{
HMODULE handle; /* DLL handle */
UINT refcount; /* number of references to this ICD */
WCHAR driver_name[256]; /* name of display driver */
HMODULE handle; /*!< DLL handle */
UINT refcount; /*!< Number of references to this ICD */
WCHAR driver_name[256]; /*!< Name of ICD driver */
WCHAR dll[256]; /* Dll value from registry */
DWORD version; /* Version value from registry */
DWORD driver_version; /* DriverVersion value from registry */
DWORD flags; /* Flags value from registry */
WCHAR dll[256]; /*!< Dll filename from registry */
DWORD version; /*!< Version value from registry */
DWORD driver_version; /*!< DriverVersion value from registry */
DWORD flags; /*!< Flags value from registry */
BOOL APIENTRY (*DrvCopyContext)( HGLRC, HGLRC, UINT );
HGLRC APIENTRY (*DrvCreateContext)( HDC );
@@ -121,11 +135,11 @@ typedef struct tagGLDRIVERDATA
int APIENTRY (*DrvDescribePixelFormat)( IN HDC, IN int, IN UINT, OUT LPPIXELFORMATDESCRIPTOR );
int APIENTRY (*DrvGetLayerPaletteEntries)( HDC, int, int, int, COLORREF * );
PROC APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName );
void APIENTRY (*DrvReleaseContext)();
void APIENTRY (*DrvReleaseContext)( HGLRC hglrc ); /* maybe returns BOOL? */
BOOL APIENTRY (*DrvRealizeLayerPalette)( HDC, int, BOOL );
PICDTable APIENTRY (*DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback );
int APIENTRY (*DrvSetLayerPaletteEntries)( HDC, int, int, int, CONST COLORREF * );
BOOL APIENTRY (*DrvSetPixelFormat)( IN HDC, IN int, IN CONST PIXELFORMATDESCRIPTOR * );
BOOL APIENTRY (*DrvSetPixelFormat)( IN HDC, IN int ); /*, IN CONST PIXELFORMATDESCRIPTOR * );*/
BOOL APIENTRY (*DrvShareLists)( HGLRC, HGLRC );
BOOL APIENTRY (*DrvSwapBuffers)( HDC );
BOOL APIENTRY (*DrvSwapLayerBuffers)( HDC, UINT );
@@ -137,12 +151,12 @@ typedef struct tagGLDRIVERDATA
/* Our private OpenGL context (stored in TLS) */
typedef struct tagGLRC
{
GLDRIVERDATA *icd; /* driver used for this context */
HDC hdc; /* DC handle */
BOOL is_current; /* wether this context is current for some DC */
DWORD thread_id; /* thread holding this context */
GLDRIVERDATA *icd; /*!< driver used for this context */
HDC hdc; /*!< DC handle */
BOOL is_current; /*!< Wether this context is current for some DC */
DWORD thread_id; /*!< Thread holding this context */
HGLRC hglrc; /* GLRC from DrvCreateContext */
HGLRC hglrc; /*!< GLRC from DrvCreateContext (ICD internal) */
struct tagGLRC *next; /* linked list */
} GLRC;
@@ -150,9 +164,9 @@ typedef struct tagGLRC
/* OpenGL private device context data */
typedef struct tagGLDCDATA
{
HDC hdc; /* device context handle for which this data is */
GLDRIVERDATA *icd; /* driver used for this DC */
int pixel_format; /* selected pixel format */
HDC hdc; /*!< Device context handle for which this data is */
GLDRIVERDATA *icd; /*!< Driver used for this DC */
int pixel_format; /*!< Selected pixel format */
struct tagGLDCDATA *next; /* linked list */
} GLDCDATA;
@@ -161,18 +175,18 @@ typedef struct tagGLDCDATA
/* Process data */
typedef struct tagGLPROCESSDATA
{
GLDRIVERDATA *driver_list; /* list of loaded drivers */
HANDLE driver_mutex; /* mutex to protect driver list */
GLRC *glrc_list; /* list of GL rendering contexts */
HANDLE glrc_mutex; /* mutex to protect glrc list */
GLDCDATA *dcdata_list; /* list of GL private DC data */
HANDLE dcdata_mutex; /* mutex to protect glrc list */
GLDRIVERDATA *driver_list; /*!< List of loaded drivers */
HANDLE driver_mutex; /*!< Mutex to protect driver list */
GLRC *glrc_list; /*!< List of GL rendering contexts */
HANDLE glrc_mutex; /*!< Mutex to protect glrc list */
GLDCDATA *dcdata_list; /*!< List of GL private DC data */
HANDLE dcdata_mutex; /*!< Mutex to protect glrc list */
} GLPROCESSDATA;
/* TLS data */
typedef struct tagGLTHREADDATA
{
GLRC *glrc; /* current GL rendering context */
GLRC *glrc; /*!< current GL rendering context */
} GLTHREADDATA;
extern DWORD OPENGL32_tls;
@@ -180,11 +194,9 @@ extern GLPROCESSDATA OPENGL32_processdata;
#define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls ))
/* function prototypes */
/*GLDRIVERDATA *OPENGL32_LoadICDForHDC( HDC hdc );*/
GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver );
BOOL OPENGL32_UnloadICD( GLDRIVERDATA *icd );
DWORD OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName );
DWORD OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd );
/* empty gl functions from gl.c */
int STDCALL glEmptyFunc0();
@@ -209,14 +221,18 @@ int STDCALL glEmptyFunc52( long, long, long, long, long, long, long, long,
int STDCALL glEmptyFunc56( long, long, long, long, long, long, long, long,
long, long, long, long, long, long );
#ifdef OPENGL32_GL_FUNC_PROTOTYPES
#define X(func,ret,typeargs,args,icdidx,tebidx,stack) EXPORT ret STDCALL func typeargs;
GLFUNCS_MACRO
#undef X
#ifdef __cplusplus
}; // extern "C"
#endif//__cplusplus
#endif /* OPENGL32_GL_FUNC_PROTOTYPES */
#endif//OPENGL32_PRIVATE_H
#ifdef __cplusplus
}; /* extern "C" */
#endif /* __cplusplus */
#endif /* OPENGL32_PRIVATE_H */
/* EOF */
+237 -118
View File
@@ -10,29 +10,33 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include "teb.h"
#define OPENGL32_GL_FUNC_PROTOTYPES
#include "opengl32.h"
#ifdef __cplusplus
extern "C" {
#endif//__cplusplus
#endif /* __cplusplus */
#ifdef _MSC_VER
#define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
#endif//_MSC_VER
#if !defined(UNIMPLEMENTED)
# define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
#endif
#define EXT_GET_DRIVERINFO 0x1101 /* ExtEscape code to get driver info */
#define EXT_GET_DRIVERINFO 0x1101 /*!< ExtEscape code to get driver info */
typedef struct tagEXTDRIVERINFO
{
DWORD version; /* driver interface version */
DWORD driver_version; /* driver version */
WCHAR driver_name[256]; /* driver name */
DWORD version; /*!< Driver interface version */
DWORD driver_version; /*!< Driver version */
WCHAR driver_name[256]; /*!< Driver name */
} EXTDRIVERINFO;
/* FUNCTION: Append OpenGL Rendering Context (GLRC) to list
* ARGUMENTS: [IN] glrc: GLRC to append to list
/*! \brief Append OpenGL Rendering Context (GLRC) to list
*
* \param glrc [IN] Pointer to GLRC to append to list
*/
static
void
@@ -62,8 +66,9 @@ ROSGL_AppendContext( GLRC *glrc )
}
/* FUNCTION: Remove OpenGL Rendering Context (GLRC) from list
* ARGUMENTS: [IN] glrc: GLRC to remove from list
/*! \brief Remove OpenGL Rendering Context (GLRC) from list
*
* \param glrc [IN] Pointer to GLRC to remove from list
*/
static
void
@@ -100,8 +105,10 @@ ROSGL_RemoveContext( GLRC *glrc )
}
/* FUNCTION: Create a new GL Context (GLRC) and append it to the list
* RETURNS: Pointer to new GLRC on success; NULL on failure
/*! \brief Create a new GL Context (GLRC) and append it to the list
*
* \return Pointer to new GLRC on success
* \retval NULL Returned on failure (i.e. Out of memory)
*/
static
GLRC *
@@ -120,9 +127,12 @@ ROSGL_NewContext()
}
/* FUNCTION: Delete a GL Context (GLRC) and remove it from the list
* ARGUMENTS: [IN] glrc GLRC to delete
* RETURNS: TRUE if there were no error; FALSE otherwise
/*! \brief Delete a GL Context (GLRC) and remove it from the list
*
* \param glrc [IN] Pointer to GLRC to delete
*
* \retval TRUE Success
* \retval FALSE Failure
*/
static
BOOL
@@ -142,8 +152,12 @@ ROSGL_DeleteContext( GLRC *glrc )
}
/* FUNCTION: Check wether a GLRC is in the list
* ARGUMENTS: [IN] glrc: GLRC to remove from list
/*! \brief Check wether a GLRC is in the list
*
* \param glrc [IN] Pointer to GLRC to look for in the list
*
* \retval TRUE GLRC was found
* \retval FALSE GLRC was not found
*/
static
BOOL
@@ -175,10 +189,15 @@ ROSGL_ContainsContext( GLRC *glrc )
}
/* FUNCTION: Get GL private DC data. Adds an empty GLDCDATA to the list if
* there is no data for the given DC and returns it.
* ARGUMENTS: [IN] hdc Device Context for which to get the data
* RETURNS: Pointer to GLDCDATA on success; NULL on failure
/*! \brief Get GL private DC data.
*
* This function adds an empty GLDCDATA to the list if there is no data for the
* given DC yet.
*
* \param hdc [IN] Handle to a Device Context for which to get the data
*
* \return Pointer to GLDCDATA on success
* \retval NULL on failure
*/
static
GLDCDATA *
@@ -238,9 +257,15 @@ ROSGL_GetPrivateDCData( HDC hdc )
}
/* FUNCTION: Get ICD from HDC
* RETURNS: GLDRIVERDATA pointer on success, NULL otherwise.
* NOTES: Make sure the handle you pass in is one for a DC!
/*! \brief Get ICD from HDC.
*
* This function asks the display driver which OpenGL ICD to load for the given
* HDC, loads it and returns a pointer to a GLDRIVERDATA struct on success.
*
* \param hdc [IN] Handle for DC for which to load/get the ICD
*
* \return Pointer to GLDRIVERDATA
* \retval NULL Failure.
*/
static
GLDRIVERDATA *
@@ -253,43 +278,78 @@ ROSGL_ICDForHDC( HDC hdc )
return NULL;
if (dcdata->icd == NULL)
#if 1
{
DWORD dwInput = 0;
LONG ret;
LPCWSTR driverName;
EXTDRIVERINFO info;
/* get driver name */
ret = ExtEscape( hdc, EXT_GET_DRIVERINFO, sizeof (dwInput), (LPCSTR)&dwInput,
sizeof (EXTDRIVERINFO), (LPSTR)&info );
if (ret < 0)
driverName = _wgetenv( L"OPENGL32_DRIVER" );
if (driverName == NULL)
{
DBGPRINT( "Warning: ExtEscape to get the drivername failed!!! (%d)", GetLastError() );
return 0;
}
DWORD dwInput = 0;
LONG ret;
/* get driver name */
ret = ExtEscape( hdc, EXT_GET_DRIVERINFO, sizeof (dwInput), (LPCSTR)&dwInput,
sizeof (EXTDRIVERINFO), (LPSTR)&info );
if (ret < 0)
{
HKEY hKey;
DWORD type, size;
DBGPRINT( "Warning: ExtEscape to get the drivername failed!!! (%d)", GetLastError() );
if (MessageBox( WindowFromDC( hdc ), L"Couldn't get installable client driver name!\nUsing default driver.",
L"OPENGL32.dll: Warning", MB_OKCANCEL | MB_ICONWARNING ) == IDCANCEL)
{
SetLastError( ret );
return NULL;
}
/* open registry key */
ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, OPENGL_DRIVERS_SUBKEY, 0, KEY_READ, &hKey );
if (ret != ERROR_SUCCESS)
{
DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY );
SetLastError( ret );
return NULL;
}
/* query value */
size = sizeof (info.driver_name);
ret = RegQueryValueExW( hKey, L"DefaultDriver", 0, &type, (LPBYTE)info.driver_name, &size );
RegCloseKey( hKey );
if (ret != ERROR_SUCCESS || type != REG_SZ)
{
DBGPRINT( "Error: Couldn't query DefaultDriver value or not a string" );
SetLastError( ret );
return NULL;
}
}
}
else
{
wcsncpy( info.driver_name, driverName, sizeof (info.driver_name) / sizeof (info.driver_name[0]) );
}
/* load driver (or get a reference) */
dcdata->icd = OPENGL32_LoadICD( info.driver_name );
}
#else
dcdata->icd = OPENGL32_LoadICD( L"OGLICD" );
#endif
return dcdata->icd;
}
/* FUNCTION: SetContextCallBack passed to DrvSetContext. Gets called whenever
* the current GL context (dispatch table) is to be changed.
* ARGUMENTS: [IN] table Function pointer table (first DWORD is number of
* functions)
* RETURNS: unkown (maybe void?)
/*! \brief SetContextCallBack passed to DrvSetContext.
*
* This function gets called by the OpenGL driver whenever the current GL
* context (dispatch table) is to be changed.
*
* \param table [IN] Function pointer table (first DWORD is number of functions)
*
* \return unkown (maybe void? ERROR_SUCCESS at the moment)
*/
DWORD
CALLBACK
ROSGL_SetContextCallBack( const ICDTable *table )
{
/* UINT i;*/
TEB *teb;
PROC *tebTable, *tebDispatchTable;
INT size;
@@ -298,6 +358,8 @@ ROSGL_SetContextCallBack( const ICDTable *table )
tebTable = (PROC *)teb->glTable;
tebDispatchTable = (PROC *)teb->glDispatchTable;
DBGTRACE( "Called!" );
if (table != NULL)
{
DBGPRINT( "Function count: %d\n", table->num_funcs );
@@ -314,18 +376,6 @@ ROSGL_SetContextCallBack( const ICDTable *table )
memset( tebTable, 0, sizeof (table->dispatch_table) );
}
/* FIXME: pull in software fallbacks -- need mesa */
#if 0 /* unused atm */
for (i = 0; i < (sizeof (table->dispatch_table) / sizeof (PROC)); i++)
{
if (tebTable[i] == NULL)
{
/* FIXME: fallback */
DBGPRINT( "Warning: GL proc #%d is NULL!", i );
}
}
#endif
/* put in empty functions as long as we dont have a fallback */
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
if (tebTable[icdidx] == NULL) \
@@ -344,13 +394,27 @@ ROSGL_SetContextCallBack( const ICDTable *table )
GLFUNCS_MACRO
#undef X
DBGPRINT( "Done." );
/* DBGBREAK();*/
return ERROR_SUCCESS;
}
/* FUNCTION: Attempts to find the best matching pixel format for HDC
* ARGUMENTS: [IN] pdf PFD describing what kind of format you want
* RETURNS: one-based positive format index on success, 0 on failure
/*! \brief Attempts to find the best matching pixel format for HDC
*
* This function is comparing each available format with the preferred one
* and returns the one which is closest to it.
* If PFD_DOUBLEBUFFER, PFD_STEREO or one of PFD_DRAW_TO_WINDOW,
* PFD_DRAW_TO_BITMAP, PFD_SUPPORT_GDI and PDF_SUPPORT_OPENGL is given then
* only formats which also support those will be enumerated (unless
* PFD_DOUBLEBUFFER_DONTCARE or PFD_STEREO_DONTCARE is also set)
*
* \param hdc [IN] Handle to DC for which to get a pixel format index
* \param pfd [IN] PFD describing what kind of format you want
*
* \return Pixel format index
* \retval 0 Failed to find a suitable format
*/
#define BUFFERDEPTH_SCORE(want, have) \
((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
@@ -382,7 +446,6 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
}
/* get number of formats */
// __asm__( "int $3" );
icdNumFormats = icd->DrvDescribePixelFormat( hdc, 1,
sizeof (PIXELFORMATDESCRIPTOR), &icdPfd );
if (icdNumFormats == 0)
@@ -403,6 +466,11 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
break;
}
if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) != 0) /* we do not support such kind of drivers */
{
continue;
}
/* compare flags */
if ((pfd->dwFlags & compareFlags) != (icdPfd.dwFlags & compareFlags))
continue;
@@ -444,11 +512,14 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
}
/* FUNCTION: Copy data specified by mask from one GLRC to another.
* ARGUMENTS: [IN] src Source GLRC
* [OUT] dst Destination GLRC
* [IN] mask Bitfield like given to glPushAttrib()
* RETURN: TRUE on success, FALSE on failure
/*! \brief Copy data specified by mask from one GLRC to another.
*
* \param src [IN] Source GLRC
* \param src [OUT] Destination GLRC
* \param mask [IN] Bitfield like given to glPushAttrib()
*
* \retval TRUE Success
* \retval FALSE Failure
*/
BOOL
APIENTRY
@@ -481,11 +552,15 @@ rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
}
/* FUNCTION: Create a new GL Rendering Context for the given plane on
* the given DC.
* ARGUMENTS: [IN] hdc Handle for DC for which to create context
* [IN] layer Layer number to bind (draw?) to
* RETURNS: NULL on failure, new GLRC on success
/*! \brief Create a new GL Rendering Context.
*
* This function can create over- or underlay surfaces.
*
* \param hdc [IN] Handle for DC for which to create context
* \param layer [IN] Layer number to bind (draw?) to
*
* \return Handle for the created GLRC
* \retval NULL Failure
*/
HGLRC
APIENTRY
@@ -495,6 +570,8 @@ rosglCreateLayerContext( HDC hdc, int layer )
GLRC *glrc;
HGLRC drvHglrc = NULL;
DBGTRACE( "Called!" );
/* if (GetObjectType( hdc ) != OBJ_DC)
{
DBGPRINT( "Error: hdc is not a DC handle!" );
@@ -542,9 +619,12 @@ rosglCreateLayerContext( HDC hdc, int layer )
}
/* FUNCTION: Create a new GL Rendering Context for the given DC.
* ARGUMENTS: [IN] hdc Handle for DC for which to create context
* RETURNS: NULL on failure, new GLRC on success
/*! \brief Create a new GL Rendering Context.
*
* \param hdc [IN] Handle for DC for which to create context
*
* \return Handle for the created GLRC
* \retval NULL Failure
*/
HGLRC
APIENTRY
@@ -554,9 +634,12 @@ rosglCreateContext( HDC hdc )
}
/* FUNCTION: Delete an OpenGL context
* ARGUMENTS: [IN] hglrc Handle to GLRC to delete; must not be a threads RC!
* RETURNS: TRUE on success, FALSE otherwise
/*! \brief Delete an OpenGL context
*
* \param hglrc [IN] Handle to GLRC to delete; must not be a threads current RC!
*
* \retval TRUE Success
* \retval FALSE Failure (i.e. GLRC is current for a thread)
*/
BOOL
APIENTRY
@@ -603,13 +686,15 @@ rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
}
/* FUNCTION: Gets information about the pixelformat specified by iFormat and
* puts it into pfd.
* ARGUMENTS: [IN] hdc Handle to DC
* [IN] iFormat Pixelformat index
* [IN] nBytes sizeof (pfd) - at most nBytes are copied into pfd
* [OUT] pfd Pointer to a PIXELFORMATDESCRIPTOR
* RETURNS: Maximum pixelformat index/number of formats on success; 0 on failure
/*! \brief Gets information about a pixelformat.
*
* \param hdc [IN] Handle to DC
* \param iFormat [IN] Pixelformat index
* \param nBytes [IN] sizeof (pfd) - at most nBytes are copied into pfd
* \param pfd [OUT] Pointer to a PIXELFORMATDESCRIPTOR
*
* \return Maximum pixelformat index/number of formats
* \retval 0 Failure
*/
int
APIENTRY
@@ -626,13 +711,14 @@ rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
}
/* FIXME: implement own functionality? */
return ret;
}
/* FUNCTION: Return the current GLRC
* RETURNS: Current GLRC (NULL if none was set current)
/*! \brief Return the thread's current GLRC
*
* \return Handle for thread's current GLRC
* \retval NULL No current GLRC set
*/
HGLRC
APIENTRY
@@ -642,8 +728,10 @@ rosglGetCurrentContext()
}
/* FUNCTION: Return the current DC
* RETURNS: NULL on failure, current DC otherwise
/*! \brief Return the thread's current DC
*
* \return Handle for thread's current DC
* \retval NULL No current DC/GLRC set
*/
HDC
APIENTRY
@@ -667,9 +755,12 @@ rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
}
/* FUNCTION: Returns the current pixelformat for the given hdc.
* ARGUMENTS: [IN] hdc Handle to DC of which to get the pixelformat
* RETURNS: Pixelformat index on success; 0 on failure
/*! \brief Returns the current pixelformat.
*
* \param hdc [IN] Handle to DC to get the pixelformat from
*
* \return Pixelformat index
* \retval 0 Failure
*/
int
WINAPI
@@ -690,9 +781,15 @@ rosglGetPixelFormat( HDC hdc )
}
/* FUNCTION: Get the address for an OpenGL extension function from the current ICD.
* ARGUMENTS: [IN] proc: Name of the function to look for
* RETURNS: The address of the proc or NULL on failure.
/*! \brief Get the address for an OpenGL extension function.
*
* The addresses this function returns are only valid within the same thread
* which it was called from.
*
* \param proc [IN] Name of the function to look for
*
* \return The address of the proc
* \retval NULL Failure
*/
PROC
APIENTRY
@@ -704,7 +801,7 @@ rosglGetProcAddress( LPCSTR proc )
return NULL;
}
if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */
if (proc[0] == 'g' && proc[1] == 'l' && proc[2] != 'u') /* glXXX */
{
PROC glXXX = NULL;
GLDRIVERDATA *icd = OPENGL32_threaddata->glrc->icd;
@@ -733,10 +830,13 @@ rosglGetProcAddress( LPCSTR proc )
}
/* FUNCTION: make the given GLRC the threads current GLRC for hdc
* ARGUMENTS: [IN] hdc Handle for a DC to be drawn on
* [IN] hglrc Handle for a GLRC to make current
* RETURNS: TRUE on success, FALSE otherwise
/*! \brief Make the given GLRC the threads current GLRC for hdc
*
* \param hdc [IN] Handle for a DC to be drawn on
* \param hglrc [IN] Handle for a GLRC to make current
*
* \retval TRUE Success
* \retval FALSE Failure
*/
BOOL
APIENTRY
@@ -745,6 +845,8 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
GLRC *glrc = (GLRC *)hglrc;
ICDTable *icdTable = NULL;
DBGTRACE( "Called!" );
/* flush current context */
if (OPENGL32_threaddata->glrc != NULL)
{
@@ -756,7 +858,9 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
{
if (OPENGL32_threaddata->glrc != NULL)
{
OPENGL32_threaddata->glrc->is_current = FALSE;
glrc = OPENGL32_threaddata->glrc;
glrc->icd->DrvReleaseContext( glrc->hglrc );
glrc->is_current = FALSE;
OPENGL32_threaddata->glrc = NULL;
}
}
@@ -786,8 +890,10 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
/* call the ICD */
if (glrc->hglrc != NULL)
{
DBGPRINT( "Info: Calling DrvSetContext!" );
DBGBREAK();
icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
ROSGL_SetContextCallBack );
ROSGL_SetContextCallBack );
if (icdTable == NULL)
{
DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
@@ -805,7 +911,7 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
OPENGL32_threaddata->glrc = glrc;
}
if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS && icdTable == NULL)
{
DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
}
@@ -833,11 +939,14 @@ rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
}
/* FUNCTION: Set pixelformat of given DC
* ARGUMENTS: [IN] hdc Handle to DC for which to set the format
* [IN] iFormat Index of the pixelformat to set
* [IN] pfd Not sure what this is for
* RETURNS: TRUE on success, FALSE on failure
/*! \brief Set a DCs pixelformat
*
* \param hdc [IN] Handle to DC for which to set the format
* \param iFormat [IN] Index of the pixelformat to set
* \param pfd [IN] Not sure what this is for
*
* \retval TRUE Success
* \retval FALSE Failure
*/
BOOL
WINAPI
@@ -857,7 +966,7 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
}
/* call ICD */
if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
if (!icd->DrvSetPixelFormat( hdc, iFormat/*, pfd*/ ))
{
DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
iFormat, GetLastError() );
@@ -877,10 +986,15 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
}
/* FUNCTION: Enable display-list sharing between multiple GLRCs
* ARGUMENTS: [IN] hglrc1 GLRC number 1
* [IN] hglrc2 GLRC number 2
* RETURNS: TRUE on success, FALSE on failure
/*! \brief Enable display-list sharing between multiple GLRCs
*
* This will only work if both GLRCs are from the same driver.
*
* \param hglrc1 [IN] GLRC number 1
* \param hglrc2 [IN] GLRC number 2
*
* \retval TRUE Success
* \retval FALSE Failure
*/
BOOL
APIENTRY
@@ -913,17 +1027,22 @@ rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
}
/* FUNCTION: Flushes GL and swaps front/back buffer if appropriate
* ARGUMENTS: [IN] hdc Handle to device context to swap buffers for
* RETURNS: TRUE on success, FALSE on failure
/*! \brief Flushes GL and swaps front/back buffer if appropriate
*
* \param hdc [IN] Handle to device context to swap buffers for
*
* \retval TRUE Success
* \retval FALSE Failure
*/
BOOL
APIENTRY
rosglSwapBuffers( HDC hdc )
{
GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
DBGTRACE( "Called!" );
if (icd != NULL)
{
DBGPRINT( "Swapping buffers!" );
if (!icd->DrvSwapBuffers( hdc ))
{
DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
@@ -986,7 +1105,7 @@ rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
}
#ifdef __cplusplus
}; // extern "C"
#endif//__cplusplus
}; /* extern "C" */
#endif /* __cplusplus */
/* EOF */