wgl: use gldrv.h instead of stw_icd.h
[mesa.git] / src / gallium / state_trackers / wgl / stw_wgl.c
index d4b2f51f4c8071f2ff1f9723510ebc7c731370ef..443158271128669106a509e86efcd6afd25dfb8c 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  **************************************************************************/
 
+/**
+ * @file
+ *
+ * Fake WGL API implementation.
+ *
+ * These functions implement the WGL API, on top of the ICD DDI, so that the
+ * resulting DLL can be used as a drop-in replacement for the system's
+ * opengl32.dll.
+ *
+ * These functions never get called for ICD drivers, which use exclusively the
+ * ICD DDI, i.e., the Drv* entrypoints.
+ */
+
 #include <windows.h>
+#include <GL/gl.h>
 
 #include "util/u_debug.h"
-#include "stw_public.h"
+#include "gldrv.h"
+#include "stw_context.h"
+#include "stw_pixelformat.h"
 #include "stw_wgl.h"
+#include "stw_ext_context.h"
 
 
+static void
+overrideOpenGL32EntryPoints(void);
+
 WINGDIAPI BOOL APIENTRY
 wglCopyContext(
    HGLRC hglrcSrc,
    HGLRC hglrcDst,
    UINT mask )
 {
-   return stw_copy_context( (UINT_PTR)hglrcSrc, 
-                            (UINT_PTR)hglrcDst, 
-                            mask );
+   return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc,
+                          (DHGLRC)(UINT_PTR)hglrcDst,
+                          mask );
 }
 
 WINGDIAPI HGLRC APIENTRY
 wglCreateContext(
    HDC hdc )
 {
-   return wglCreateLayerContext(hdc, 0);
+   overrideOpenGL32EntryPoints();
+   return (HGLRC) DrvCreateContext(hdc);
 }
 
 WINGDIAPI HGLRC APIENTRY
@@ -55,21 +76,22 @@ wglCreateLayerContext(
    HDC hdc,
    int iLayerPlane )
 {
-   return (HGLRC) stw_create_layer_context( hdc, iLayerPlane );
+   overrideOpenGL32EntryPoints();
+   return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
 }
 
 WINGDIAPI BOOL APIENTRY
 wglDeleteContext(
    HGLRC hglrc )
 {
-   return stw_delete_context( (UINT_PTR)hglrc );
+   return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
 }
 
 
 WINGDIAPI HGLRC APIENTRY
 wglGetCurrentContext( VOID )
 {
-   return (HGLRC)stw_get_current_context();
+   return (HGLRC)(UINT_PTR)stw_get_current_context();
 }
 
 WINGDIAPI HDC APIENTRY
@@ -78,12 +100,19 @@ wglGetCurrentDC( VOID )
    return stw_get_current_dc();
 }
 
+WINGDIAPI HDC APIENTRY
+wglGetCurrentReadDCARB( VOID )
+{
+   return stw_get_current_read_dc();
+}
+
+
 WINGDIAPI BOOL APIENTRY
 wglMakeCurrent(
    HDC hdc,
    HGLRC hglrc )
 {
-   return stw_make_current( hdc, (UINT_PTR)hglrc );
+   return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
 }
 
 
@@ -91,7 +120,20 @@ WINGDIAPI BOOL APIENTRY
 wglSwapBuffers(
    HDC hdc )
 {
-   return stw_swap_buffers( hdc );
+   return DrvSwapBuffers( hdc );
+}
+
+
+WINGDIAPI DWORD WINAPI
+wglSwapMultipleBuffers(UINT n,
+                       CONST WGLSWAP *ps)
+{
+   UINT i;
+
+   for (i =0; i < n; ++i)
+      wglSwapBuffers(ps->hdc);
+
+   return 0;
 }
 
 
@@ -100,14 +142,14 @@ wglSwapLayerBuffers(
    HDC hdc,
    UINT fuPlanes )
 {
-   return stw_swap_layer_buffers( hdc, fuPlanes );
+   return DrvSwapLayerBuffers( hdc, fuPlanes );
 }
 
 WINGDIAPI PROC APIENTRY
 wglGetProcAddress(
     LPCSTR lpszProc )
 {
-   return stw_get_proc_address( lpszProc );
+   return DrvGetProcAddress( lpszProc );
 }
 
 
@@ -141,7 +183,7 @@ wglDescribePixelFormat(
    UINT nBytes,
    LPPIXELFORMATDESCRIPTOR ppfd )
 {
-   return stw_pixelformat_describe( hdc, iPixelFormat, nBytes, ppfd );
+   return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
 }
 
 WINGDIAPI int APIENTRY
@@ -157,10 +199,12 @@ wglSetPixelFormat(
    int iPixelFormat,
    const PIXELFORMATDESCRIPTOR *ppfd )
 {
-   if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ))
-      return FALSE;
+    /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
+     * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
+     */
+   (void) ppfd;
 
-   return stw_pixelformat_set( hdc, iPixelFormat );
+   return DrvSetPixelFormat( hdc, iPixelFormat );
 }
 
 
@@ -171,14 +215,7 @@ wglUseFontBitmapsA(
    DWORD count,
    DWORD listBase )
 {
-   (void) hdc;
-   (void) first;
-   (void) count;
-   (void) listBase;
-
-   assert( 0 );
-
-   return FALSE;
+   return wglUseFontBitmapsW(hdc, first, count, listBase);
 }
 
 WINGDIAPI BOOL APIENTRY
@@ -186,7 +223,8 @@ wglShareLists(
    HGLRC hglrc1,
    HGLRC hglrc2 )
 {
-   return stw_share_lists( (UINT_PTR)hglrc1, (UINT_PTR)hglrc2);;
+   return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1,
+                        (DHGLRC)(UINT_PTR)hglrc2);
 }
 
 WINGDIAPI BOOL APIENTRY
@@ -196,14 +234,56 @@ wglUseFontBitmapsW(
    DWORD count,
    DWORD listBase )
 {
-   (void) hdc;
-   (void) first;
-   (void) count;
-   (void) listBase;
-
-   assert( 0 );
-
-   return FALSE;
+   GLYPHMETRICS gm;
+   MAT2 tra;
+   FIXED one, minus_one, zero;
+   void *buffer = NULL;
+   BOOL result = TRUE;
+
+   one.value = 1;
+   one.fract = 0;
+   minus_one.value = -1;
+   minus_one.fract = 0;
+   zero.value = 0;
+   zero.fract = 0;
+
+   tra.eM11 = one;
+   tra.eM22 = minus_one;
+   tra.eM12 = tra.eM21 = zero;
+
+   for (int i = 0; i < count; i++) {
+      DWORD size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0,
+                                   NULL, &tra);
+
+      glNewList(listBase + i, GL_COMPILE);
+
+      if (size != GDI_ERROR) {
+         if (size == 0) {
+            glBitmap(0, 0, (GLfloat)-gm.gmptGlyphOrigin.x,
+                     (GLfloat)gm.gmptGlyphOrigin.y,
+                     (GLfloat)gm.gmCellIncX,
+                     (GLfloat)gm.gmCellIncY, NULL);
+         }
+         else {
+            buffer = realloc(buffer, size);
+            size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm,
+                                   size, buffer, &tra);
+
+            glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
+                     -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y,
+                     gm.gmCellIncX, gm.gmCellIncY, buffer);
+         }
+      }
+      else {
+         result = FALSE;
+      }
+
+      glEndList();
+   }
+
+   free(buffer);
+
+   return result;
 }
 
 WINGDIAPI BOOL APIENTRY
@@ -264,15 +344,7 @@ wglDescribeLayerPlane(
    UINT nBytes,
    LPLAYERPLANEDESCRIPTOR plpd )
 {
-   (void) hdc;
-   (void) iPixelFormat;
-   (void) iLayerPlane;
-   (void) nBytes;
-   (void) plpd;
-
-   assert( 0 );
-
-   return FALSE;
+   return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
 }
 
 WINGDIAPI int APIENTRY
@@ -283,15 +355,7 @@ wglSetLayerPaletteEntries(
    int cEntries,
    CONST COLORREF *pcr )
 {
-   (void) hdc;
-   (void) iLayerPlane;
-   (void) iStart;
-   (void) cEntries;
-   (void) pcr;
-
-   assert( 0 );
-
-   return 0;
+   return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
 }
 
 WINGDIAPI int APIENTRY
@@ -302,15 +366,7 @@ wglGetLayerPaletteEntries(
    int cEntries,
    COLORREF *pcr )
 {
-   (void) hdc;
-   (void) iLayerPlane;
-   (void) iStart;
-   (void) cEntries;
-   (void) pcr;
-
-   assert( 0 );
-
-   return 0;
+   return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
 }
 
 WINGDIAPI BOOL APIENTRY
@@ -327,3 +383,18 @@ wglRealizeLayerPalette(
 
    return FALSE;
 }
+
+
+/* When this library is used as a opengl32.dll drop-in replacement, ensure we
+ * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll,
+ * which could happen if this library's name is not opengl32.dll exactly.
+ *
+ * For example, Qt 5.4 bundles this as opengl32sw.dll:
+ * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
+ */
+static void
+overrideOpenGL32EntryPoints(void)
+{
+   wglCreateContext_func = &wglCreateContext;
+   wglDeleteContext_func = &wglDeleteContext;
+}