/**************************************************************************
*
- * 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(
wglCreateContext(
HDC hdc )
{
+ overrideOpenGL32EntryPoints();
return (HGLRC) DrvCreateContext(hdc);
}
HDC hdc,
int iLayerPlane )
{
+ overrideOpenGL32EntryPoints();
return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
}
return stw_get_current_dc();
}
+WINGDIAPI HDC APIENTRY
+wglGetCurrentReadDCARB( VOID )
+{
+ return stw_get_current_read_dc();
+}
+
+
WINGDIAPI BOOL APIENTRY
wglMakeCurrent(
HDC hdc,
}
+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,
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 );
}
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
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
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;
+}