patch by blight:
[reactos.git] / reactos / lib / opengl32 / wgl.c
index 94556e0..76bc728 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
  * FILE:                 lib/opengl32/wgl.c
- * PURPOSE:              OpenGL32 lib, wglXXX functions
+ * PURPOSE:              OpenGL32 lib, rosglXXX functions
  * PROGRAMMER:           Anich Gregor (blight)
  * UPDATE HISTORY:
  *                       Feb 2, 2004: Created
 
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
-
+#include "teb.h"
 #include "opengl32.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif//__cplusplus
+
+#ifdef _MSC_VER
+#define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
+#endif//_MSC_VER
 
 /* FUNCTION: Append OpenGL Rendering Context (GLRC) to list
  * ARGUMENTS: [IN] glrc: GLRC to append to list
  */
-static void WGL_AppendContext( GLRC *glrc )
+static
+void
+WGL_AppendContext( GLRC *glrc )
 {
        /* synchronize */
        if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
@@ -46,7 +55,9 @@ static void WGL_AppendContext( GLRC *glrc )
 /* FUNCTION: Remove OpenGL Rendering Context (GLRC) from list
  * ARGUMENTS: [IN] glrc: GLRC to remove from list
  */
-static void WGL_RemoveContext( GLRC *glrc )
+static
+void
+WGL_RemoveContext( GLRC *glrc )
 {
        /* synchronize */
        if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
@@ -81,10 +92,21 @@ static void WGL_RemoveContext( GLRC *glrc )
 /* FUNCTION: Check wether a GLRC is in the list
  * ARGUMENTS: [IN] glrc: GLRC to remove from list
  */
-static BOOL WGL_ContainsContext( GLRC *glrc )
+static
+BOOL
+WGL_ContainsContext( GLRC *glrc )
 {
-       GLRC *p = OPENGL32_processdata.glrc_list;
+       GLRC *p;
+
+       /* synchronize */
+       if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
+           WAIT_FAILED)
+       {
+               DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
+               return FALSE; /* FIXME: do we have to expect such an error and handle it? */
+       }
 
+       p = OPENGL32_processdata.glrc_list;
        while (p != NULL)
        {
                if (p == glrc)
@@ -92,6 +114,10 @@ static BOOL WGL_ContainsContext( GLRC *glrc )
                p = p->next;
        }
 
+       /* release mutex */
+       if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
+               DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
+
        return FALSE;
 }
 
@@ -101,23 +127,176 @@ static BOOL WGL_ContainsContext( GLRC *glrc )
  *           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 WGL_SetContextCallBack( void *table )
+DWORD
+CALLBACK
+WGL_SetContextCallBack( const ICDTable *table )
 {
-       DBGPRINT( "Function count: %d\n", *(DWORD *)table );
-       DBGBREAK();
+/*     UINT i;*/
+       TEB *teb;
+       PROC *tebTable, *tebDispatchTable;
+       INT size;
+
+       teb = NtCurrentTeb();
+       tebTable = (PROC *)teb->glTable;
+       tebDispatchTable = (PROC *)teb->glDispatchTable;
+
+       if (table != NULL)
+       {
+               DBGPRINT( "Function count: %d\n", 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 */
+       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)                                      \
+               {                                                                  \
+                       if (table != NULL)                                             \
+                               DBGPRINT( "Warning: GL proc '%s' is NULL", #func );        \
+                       tebTable[icdidx] = (PROC)glEmptyFunc##stack;                   \
+               }
+       GLFUNCS_MACRO
+       #undef X
+
+       /* fill teb->glDispatchTable for fast calls */
+       #define X(func, ret, typeargs, args, icdidx, tebidx, stack)            \
+               if (tebidx >= 0)                                                   \
+                       tebDispatchTable[tebidx] = tebTable[icdidx];
+       GLFUNCS_MACRO
+       #undef X
+
        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
+ */
+#define BUFFERDEPTH_SCORE(want, have) \
+       ((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
+int
+APIENTRY
+rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
+{
+       GLDRIVERDATA *icd;
+       PIXELFORMATDESCRIPTOR icdPfd;
+       int i;
+       int best = 0;
+       int score, bestScore = 0x7fff; /* used to choose a pfd if no exact match */
+       int icdNumFormats;
+       const DWORD compareFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
+                                  PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL;
+
+       /* load ICD */
+       icd = OPENGL32_LoadICDForHDC( hdc );
+       if (icd == NULL)
+               return 0;
+
+       /* check input */
+       if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
+       {
+               OPENGL32_UnloadICD( icd );
+               SetLastError( 0 ); /* FIXME: use appropriate errorcode */
+               return 0;
+       }
+
+       /* get number of formats -- FIXME: use 1 or 0 as index? */
+       icdNumFormats = icd->DrvDescribePixelFormat( hdc, 0,
+                                         sizeof (PIXELFORMATDESCRIPTOR), NULL );
+       if (icdNumFormats == 0)
+       {
+               DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
+               OPENGL32_UnloadICD( icd );
+               return 0;
+       }
+       DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
+
+       /* try to find best format */
+       for (i = 0; i < icdNumFormats; i++)
+       {
+               if (icd->DrvDescribePixelFormat( hdc, i + 1,
+                                        sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ) == 0)
+               {
+                       DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)",
+                                 GetLastError() );
+                       break;
+               }
+
+               /* compare flags */
+               if ((pfd->dwFlags & compareFlags) != (icdPfd.dwFlags & compareFlags))
+                       continue;
+               if (!(pfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+                   ((pfd->dwFlags & PFD_DOUBLEBUFFER) != (icdPfd.dwFlags & PFD_DOUBLEBUFFER)))
+                       continue;
+               if (!(pfd->dwFlags & PFD_STEREO_DONTCARE) &&
+                   ((pfd->dwFlags & PFD_STEREO) != (icdPfd.dwFlags & PFD_STEREO)))
+                       continue;
+
+               /* check other attribs */
+               score = 0; /* higher is worse */
+               if (pfd->iPixelType != icdPfd.iPixelType)
+                       score += 5; /* this is really bad i think */
+               if (pfd->iLayerType != icdPfd.iLayerType)
+                       score += 15; /* this is very very bad ;) */
+
+               score += BUFFERDEPTH_SCORE(pfd->cAlphaBits, icdPfd.cAlphaBits);
+               score += BUFFERDEPTH_SCORE(pfd->cAccumBits, icdPfd.cAccumBits);
+               score += BUFFERDEPTH_SCORE(pfd->cDepthBits, icdPfd.cDepthBits);
+               score += BUFFERDEPTH_SCORE(pfd->cStencilBits, icdPfd.cStencilBits);
+               score += BUFFERDEPTH_SCORE(pfd->cAuxBuffers, icdPfd.cAuxBuffers);
+
+               /* check score */
+               if (score < bestScore)
+               {
+                       bestScore = score;
+                       best = i + 1;
+                       if (bestScore == 0)
+                               break;
+               }
+       }
+
+       if (best == 0)
+               SetLastError( 0 ); /* FIXME: set appropriate error */
+       OPENGL32_UnloadICD( icd );
+
+       DBGPRINT( "Info: Suggesting pixelformat %d", best );
+       return best;
+}
+
+
 /* 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
  */
-BOOL WINAPI wglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
+BOOL
+APIENTRY
+rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
 {
        GLRC *src = (GLRC *)hsrc;
        GLRC *dst = (GLRC *)hdst;
@@ -146,44 +325,37 @@ BOOL WINAPI wglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
 }
 
 
-/* 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
- */
-HGLRC WINAPI wglCreateContext( HDC hdc )
-{
-       return wglCreateLayerContext( hdc, 0 );
-}
-
-
 /* 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
  */
-HGLRC WINAPI wglCreateLayerContext( HDC hdc, int layer )
+HGLRC
+APIENTRY
+rosglCreateLayerContext( HDC hdc, int layer )
 {
-       LONG ret;
+/*     LONG ret;
        WCHAR driver[256];
-       DWORD dw, size;
+       DWORD dw, size;*/
 
-       GLDRIVERDATA *icd;
+       GLDRIVERDATA *icd = NULL;
        GLRC *glrc;
        HGLRC drvHglrc = NULL;
 
-       if (GetObjectType( hdc ) != OBJ_DC)
+/*     if (GetObjectType( hdc ) != OBJ_DC)
        {
                DBGPRINT( "Error: hdc is not a DC handle!" );
                return NULL;
        }
-
+*/
        /* allocate our GLRC */
        glrc = (GLRC*)HeapAlloc( GetProcessHeap(),
                       HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
        if (glrc == NULL)
                return NULL;
 
+#if 0 /* old code */
        /* try to find an ICD */
        for (dw = 0; drvHglrc == NULL; dw++) /* enumerate values */
        {
@@ -198,7 +370,7 @@ HGLRC WINAPI wglCreateLayerContext( HDC hdc, int layer )
 
                if (icd->DrvCreateLayerContext)
                        drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
-               else
+               if (drvHglrc == NULL)
                {
                        if (layer == 0)
                                drvHglrc = icd->DrvCreateContext( hdc );
@@ -217,21 +389,47 @@ HGLRC WINAPI wglCreateLayerContext( HDC hdc, int layer )
                break;
        }
 
-       if (drvHglrc == NULL) /* no ICD was found */
+       if (drvHglrc == NULL || icd == NULL) /* no ICD was found */
        {
                /* FIXME: fallback to mesa */
                DBGPRINT( "Error: No working ICD found!" );
                HeapFree( GetProcessHeap(), 0, glrc );
                return NULL;
        }
+#endif /* unused */
+
+       /* load ICD */
+       icd = OPENGL32_LoadICDForHDC( hdc );
+       if (icd == NULL)
+       {
+               DBGPRINT( "Couldn't get ICD by HDC :-(" );
+               /* FIXME: fallback? */
+               return NULL;
+       }
+
+       /* create context */
+       if (icd->DrvCreateLayerContext != NULL)
+               drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
+       if (drvHglrc == NULL)
+       {
+               if (layer == 0 && icd->DrvCreateContext != NULL)
+                       drvHglrc = icd->DrvCreateContext( hdc );
+               else
+                       DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
+       }
+
+       if (drvHglrc == NULL)
+       {
+               /* FIXME: fallback to mesa? */
+               DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
+               OPENGL32_UnloadICD( icd );
+               HeapFree( GetProcessHeap(), 0, glrc );
+               return NULL;
+       }
 
        /* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
        glrc->hglrc = drvHglrc;
-       glrc->iFormat = -1; /* what is this used for? */
        glrc->icd = icd;
-       memcpy( glrc->func_list, icd->func_list, sizeof (PVOID) * GLIDX_COUNT );
-
-       /* FIXME: fill NULL-pointers in glrc->func_list with mesa functions */
 
        /* append glrc to context list */
        WGL_AppendContext( glrc );
@@ -240,11 +438,25 @@ HGLRC WINAPI wglCreateLayerContext( 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
+ */
+HGLRC
+APIENTRY
+rosglCreateContext( HDC hdc )
+{
+       return rosglCreateLayerContext( hdc, 0 );
+}
+
+
 /* 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
  */
-BOOL WINAPI wglDeleteContext( HGLRC hglrc )
+BOOL
+APIENTRY
+rosglDeleteContext( HGLRC hglrc )
 {
        GLRC *glrc = (GLRC *)hglrc;
 
@@ -273,6 +485,7 @@ BOOL WINAPI wglDeleteContext( HGLRC hglrc )
        }
 
        /* free resources */
+       OPENGL32_UnloadICD( glrc->icd );
        WGL_RemoveContext( glrc );
        HeapFree( GetProcessHeap(), 0, glrc );
 
@@ -280,19 +493,43 @@ BOOL WINAPI wglDeleteContext( HGLRC hglrc )
 }
 
 
-BOOL WINAPI wglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
+BOOL
+APIENTRY
+rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
                                    UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
 {
+       UNIMPLEMENTED;
+       return FALSE;
+}
+
+
+int
+APIENTRY
+rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
+                                   LPPIXELFORMATDESCRIPTOR pfd )
+{
+       int ret = 0;
+       GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc );
 
+       if (icd != NULL)
+       {
+               ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
+               if (ret == 0)
+                       DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
+               OPENGL32_UnloadICD( icd );
+       }
 
-       return FALSE;
+       /* FIXME: implement own functionality? */
+       return ret;
 }
 
 
 /* FUNCTION: Return the current GLRC
  * RETURNS: Current GLRC (NULL if none was set current)
  */
-HGLRC WINAPI wglGetCurrentContext()
+HGLRC
+APIENTRY
+rosglGetCurrentContext()
 {
        return (HGLRC)(OPENGL32_threaddata->glrc);
 }
@@ -301,7 +538,9 @@ HGLRC WINAPI wglGetCurrentContext()
 /* FUNCTION: Return the current DC
  * RETURNS: NULL on failure, current DC otherwise
  */
-HDC WINAPI wglGetCurrentDC()
+HDC
+APIENTRY
+rosglGetCurrentDC()
 {
        /* FIXME: is it correct to return NULL when there is no current GLRC or
           is there another way to find out the wanted HDC? */
@@ -311,9 +550,26 @@ HDC WINAPI wglGetCurrentDC()
 }
 
 
-int WINAPI wglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
+int
+APIENTRY
+rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
                                int cEntries, COLORREF *pcr )
 {
+       UNIMPLEMENTED;
+       return 0;
+}
+
+
+int
+WINAPI
+rosglGetPixelFormat( HDC hdc )
+{
+       if (OPENGL32_processdata.cachedHdc == hdc)
+               return OPENGL32_processdata.cachedFormat;
+
+       /* FIXME: create real implementation of this function */
+       DBGPRINT( "Warning: Pixel format not cached, returning 0" );
+
        return 0;
 }
 
@@ -322,7 +578,9 @@ int WINAPI wglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
  * ARGUMENTS: [IN] proc:  Name of the function to look for
  * RETURNS: The address of the proc or NULL on failure.
  */
-PROC WINAPI wglGetProcAddress( LPCSTR proc )
+PROC
+APIENTRY
+rosglGetProcAddress( LPCSTR proc )
 {
        if (OPENGL32_threaddata->glrc == NULL)
        {
@@ -332,7 +590,9 @@ PROC WINAPI wglGetProcAddress( LPCSTR proc )
 
        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 );
@@ -340,17 +600,17 @@ PROC WINAPI wglGetProcAddress( LPCSTR proc )
                }
 
                /* FIXME: go through own functions? */
-               DBGPRINT( "Unsupported GL extension: %s", proc );
+               DBGPRINT( "Warning: Unsupported GL extension: %s", proc );
        }
        if (proc[0] == 'w' && proc[1] == 'g' && proc[2] == 'l') /* wglXXX */
        {
                /* FIXME: support wgl extensions? (there are such IIRC) */
-               DBGPRINT( "Unsupported WGL extension: %s", proc );
+               DBGPRINT( "Warning: Unsupported WGL extension: %s", proc );
        }
        if (proc[0] == 'g' && proc[1] == 'l' && proc[2] == 'u') /* gluXXX */
        {
                /* FIXME: do we support these as well? */
-               DBGPRINT( "GLU extension %s requested, returning NULL", proc );
+               DBGPRINT( "Warning: GLU extension %s requested, returning NULL", proc );
        }
 
        return NULL;
@@ -362,74 +622,138 @@ PROC WINAPI wglGetProcAddress( LPCSTR proc )
  *            [IN] hglrc Handle for a GLRC to make current
  * RETURNS: TRUE on success, FALSE otherwise
  */
-BOOL WINAPI wglMakeCurrent( HDC hdc, HGLRC hglrc )
+BOOL
+APIENTRY
+rosglMakeCurrent( HDC hdc, HGLRC hglrc )
 {
        GLRC *glrc = (GLRC *)hglrc;
+       ICDTable *icdTable = NULL;
 
-       /* FIXME: glFlush() current context */
-
-       /* check hdc */
-       if (GetObjectType( hdc ) != OBJ_DC)
-       {
-               DBGPRINT( "Error: hdc is not a DC handle!" );
-               return FALSE;
-       }
-
-       /* check if we know about this glrc */
-       if (!WGL_ContainsContext( glrc ))
+       /* flush current context */
+       if (OPENGL32_threaddata->glrc != NULL)
        {
-               DBGPRINT( "Error: hglrc not found!" );
-               return FALSE; /* FIXME: SetLastError() */
+               glFlush();
        }
 
-       /* check if it is available */
-       if (glrc->is_current) /* used by another thread */
+       /* check if current context is unset */
+       if (glrc == NULL)
        {
-               DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
-               return FALSE; /* FIXME: SetLastError() */
+               if (OPENGL32_threaddata->glrc != NULL)
+               {
+                       OPENGL32_threaddata->glrc->is_current = FALSE;
+                       OPENGL32_threaddata->glrc = NULL;
+               }
        }
-
-       /* call the ICD */
-       if (glrc->hglrc != NULL)
+       else
        {
-               /* FIXME: which function to call? DrvSetContext?
-                         does it crash with NULL as SetContextCallBack? */
-               if (!glrc->icd->DrvSetContext( hdc, glrc->hglrc, NULL ))
+               /* check hdc */
+               if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
                {
-                       DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
+                       DBGPRINT( "Error: hdc is not a DC handle!" );
                        return FALSE;
                }
+
+               /* check if we know about this glrc */
+               if (!WGL_ContainsContext( glrc ))
+               {
+                       DBGPRINT( "Error: hglrc not found!" );
+                       return FALSE; /* FIXME: SetLastError() */
+               }
+
+               /* check if it is available */
+               if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
+               {
+                       DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
+                       return FALSE; /* FIXME: SetLastError() */
+               }
+
+               /* 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();
-       OPENGL32_threaddata->glrc = glrc;
+       WGL_SetContextCallBack( icdTable );
+
+       if (icdTable != NULL)
+               if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
+               {
+                       DBGPRINT( "Warning: WGL_SetContextCallBack failed!" );
+               }
 
        return TRUE;
 }
 
 
-BOOL WINAPI wglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
+BOOL
+APIENTRY
+rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
 
-int WINAPI wglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
+int
+APIENTRY
+rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
                                int cEntries, CONST COLORREF *pcr )
 {
+       UNIMPLEMENTED;
        return 0;
 }
 
+
+BOOL
+WINAPI
+rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
+{
+       GLDRIVERDATA *icd;
+
+       icd = OPENGL32_LoadICDForHDC( hdc );
+       if (icd == NULL)
+               return FALSE;
+
+       if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
+       {
+               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;
+}
+
+
 /* FUNCTION: Enable display-list sharing between multiple GLRCs
  * ARGUMENTS: [IN] hglrc1 GLRC number 1
  *            [IN] hglrc2 GLRC number 2
  * RETURNS: TRUR on success, FALSE on failure
  */
-BOOL WINAPI wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
+BOOL
+APIENTRY
+rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
 {
        GLRC *glrc1 = (GLRC *)hglrc1;
        GLRC *glrc2 = (GLRC *)hglrc2;
@@ -457,68 +781,83 @@ BOOL WINAPI wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
        return glrc1->icd->DrvShareLists( glrc1->hglrc, glrc2->hglrc );
 }
 
+
 /* 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
  */
-BOOL WINAPI wglSwapBuffers( HDC hdc )
+BOOL
+APIENTRY
+rosglSwapBuffers( HDC hdc )
 {
-       /* check if there is a current GLRC */
-       if (OPENGL32_threaddata->glrc == NULL)
-       {
-               DBGPRINT( "Error: No current GL context!" );
-               return FALSE;
-       }
-
-       /* ask ICD to swap buffers */
-       /* FIXME: also ask ICD when we didnt use it to create the context/it couldnt? */
-       if (OPENGL32_threaddata->glrc->hglrc != NULL)
+       GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc );
+       if (icd != NULL)
        {
-               if (!OPENGL32_threaddata->glrc->icd->DrvSwapBuffers( hdc ))
+               if (!icd->DrvSwapBuffers( hdc ))
                {
                        DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
+                       OPENGL32_UnloadICD( icd );
                        return FALSE;
                }
+               OPENGL32_UnloadICD( icd );
                return TRUE;
        }
 
-       /* FIXME: implement own functionality */
-
+       /* FIXME: implement own functionality? */
        return FALSE;
 }
 
 
-BOOL WINAPI wglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
+BOOL
+APIENTRY
+rosglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
 
-BOOL WINAPI wglUseFontBitmapsA( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
+BOOL
+APIENTRY
+rosglUseFontBitmapsA( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
 
-BOOL WINAPI wglUseFontBitmapsW( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
+BOOL
+APIENTRY
+rosglUseFontBitmapsW( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
 
-BOOL WINAPI wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
+BOOL
+APIENTRY
+rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
                           FLOAT deviation, FLOAT extrusion, int  format,
                           LPGLYPHMETRICSFLOAT  lpgmf )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
 
-BOOL WINAPI wglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
+BOOL
+APIENTRY
+rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
                           FLOAT deviation, FLOAT extrusion, int  format,
                           LPGLYPHMETRICSFLOAT  lpgmf )
 {
+       UNIMPLEMENTED;
        return FALSE;
 }
 
+#ifdef __cplusplus
+}; // extern "C"
+#endif//__cplusplus
+
 /* EOF */