wgl: use gldrv.h instead of stw_icd.h
[mesa.git] / src / gallium / state_trackers / wgl / stw_wgl.c
index bb199fdd2526c738f9a6618ac8197cd3d4c152b6..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_icd.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(
@@ -49,6 +67,7 @@ WINGDIAPI HGLRC APIENTRY
 wglCreateContext(
    HDC hdc )
 {
+   overrideOpenGL32EntryPoints();
    return (HGLRC) DrvCreateContext(hdc);
 }
 
@@ -57,6 +76,7 @@ wglCreateLayerContext(
    HDC hdc,
    int iLayerPlane )
 {
+   overrideOpenGL32EntryPoints();
    return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
 }
 
@@ -80,6 +100,13 @@ wglGetCurrentDC( VOID )
    return stw_get_current_dc();
 }
 
+WINGDIAPI HDC APIENTRY
+wglGetCurrentReadDCARB( VOID )
+{
+   return stw_get_current_read_dc();
+}
+
+
 WINGDIAPI BOOL APIENTRY
 wglMakeCurrent(
    HDC hdc,
@@ -97,6 +124,19 @@ wglSwapBuffers(
 }
 
 
+WINGDIAPI DWORD WINAPI
+wglSwapMultipleBuffers(UINT n,
+                       CONST WGLSWAP *ps)
+{
+   UINT i;
+
+   for (i =0; i < n; ++i)
+      wglSwapBuffers(ps->hdc);
+
+   return 0;
+}
+
+
 WINGDIAPI BOOL APIENTRY
 wglSwapLayerBuffers(
    HDC hdc,
@@ -159,8 +199,10 @@ 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 DrvSetPixelFormat( hdc, iPixelFormat );
 }
@@ -173,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
@@ -199,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
@@ -306,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;
+}