aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/drivers/windows/fx/fxwgl.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/drivers/windows/fx/fxwgl.c')
-rw-r--r--mesalib/src/mesa/drivers/windows/fx/fxwgl.c1307
1 files changed, 1307 insertions, 0 deletions
diff --git a/mesalib/src/mesa/drivers/windows/fx/fxwgl.c b/mesalib/src/mesa/drivers/windows/fx/fxwgl.c
new file mode 100644
index 000000000..ce76ecd15
--- /dev/null
+++ b/mesalib/src/mesa/drivers/windows/fx/fxwgl.c
@@ -0,0 +1,1307 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+/* Authors:
+ * David Bucciarelli
+ * Brian Paul
+ * Keith Whitwell
+ * Hiroshi Morii
+ * Daniel Borca
+ */
+
+/* fxwgl.c - Microsoft wgl functions emulation for
+ * 3Dfx VooDoo/Mesa interface
+ */
+
+
+#ifdef _WIN32
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+#define GL_GLEXT_PROTOTYPES
+#include "GL/gl.h"
+#include "GL/glext.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "GL/fxmesa.h"
+#include "glheader.h"
+#include "glapi.h"
+#include "imports.h"
+#include "../../glide/fxdrv.h"
+
+#define MAX_MESA_ATTRS 20
+
+#if (_MSC_VER >= 1200)
+#pragma warning( push )
+#pragma warning( disable : 4273 )
+#endif
+
+struct __extensions__ {
+ PROC proc;
+ char *name;
+};
+
+struct __pixelformat__ {
+ PIXELFORMATDESCRIPTOR pfd;
+ GLint mesaAttr[MAX_MESA_ATTRS];
+};
+
+WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
+static GLushort gammaTable[3 * 256];
+
+struct __pixelformat__ pix[] = {
+ /* 16bit RGB565 single buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ 16,
+ 5, 0, 6, 5, 5, 11, 0, 0,
+ 0, 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 16,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+ ,
+ /* 16bit RGB565 double buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 16,
+ 5, 0, 6, 5, 5, 11, 0, 0,
+ 0, 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 16,
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+ ,
+ /* 16bit ARGB1555 single buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ 16,
+ 5, 0, 5, 5, 5, 10, 1, 15,
+ 0, 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 15,
+ FXMESA_ALPHA_SIZE, 1,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+ ,
+ /* 16bit ARGB1555 double buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 16,
+ 5, 0, 5, 5, 5, 10, 1, 15,
+ 0, 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 15,
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 1,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+ ,
+ /* 32bit ARGB8888 single buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ 32,
+ 8, 0, 8, 8, 8, 16, 8, 24,
+ 0, 0, 0, 0, 0,
+ 24,
+ 8,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 32,
+ FXMESA_ALPHA_SIZE, 8,
+ FXMESA_DEPTH_SIZE, 24,
+ FXMESA_STENCIL_SIZE, 8,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+ ,
+ /* 32bit ARGB8888 double buffer with depth */
+ {
+ {sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 32,
+ 8, 0, 8, 8, 8, 16, 8, 24,
+ 0, 0, 0, 0, 0,
+ 24,
+ 8,
+ 0,
+ PFD_MAIN_PLANE,
+ 0, 0, 0, 0}
+ ,
+ {FXMESA_COLORDEPTH, 32,
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 8,
+ FXMESA_DEPTH_SIZE, 24,
+ FXMESA_STENCIL_SIZE, 8,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE}
+ }
+};
+
+static fxMesaContext ctx = NULL;
+static WNDPROC hWNDOldProc;
+static int curPFD = 0;
+static HDC hDC;
+static HWND hWND;
+
+static GLboolean haveDualHead;
+
+/* For the in-window-rendering hack */
+
+#ifndef GR_CONTROL_RESIZE
+/* Apparently GR_CONTROL_RESIZE can be ignored. OK? */
+#define GR_CONTROL_RESIZE -1
+#endif
+
+static GLboolean gdiWindowHack;
+static void *dibSurfacePtr;
+static BITMAPINFO *dibBMI;
+static HBITMAP dibHBM;
+static HWND dibWnd;
+
+static int
+env_check (const char *var, int val)
+{
+ const char *env = getenv(var);
+ return (env && (env[0] == val));
+}
+
+static LRESULT APIENTRY
+__wglMonitor (HWND hwnd, UINT message, UINT wParam, LONG lParam)
+{
+ long ret; /* Now gives the resized window at the end to hWNDOldProc */
+
+ if (ctx && hwnd == hWND) {
+ switch (message) {
+ case WM_PAINT:
+ case WM_MOVE:
+ break;
+ case WM_DISPLAYCHANGE:
+ case WM_SIZE:
+#if 0
+ if (wParam != SIZE_MINIMIZED) {
+ static int moving = 0;
+ if (!moving) {
+ if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
+ moving = 1;
+ SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE | SWP_NOZORDER);
+ moving = 0;
+ if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
+ /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
+ PostMessage(hWND, WM_CLOSE, 0, 0);
+ }
+ }
+ /* Do the clipping in the glide library */
+ grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight());
+ /* And let the new size set in the context */
+ fxMesaUpdateScreenSize(ctx);
+ }
+ }
+#endif
+ break;
+ case WM_ACTIVATE:
+ break;
+ case WM_SHOWWINDOW:
+ break;
+ case WM_SYSKEYDOWN:
+ case WM_SYSCHAR:
+ break;
+ }
+ }
+
+ /* Finally call the hWNDOldProc, which handles the resize with the
+ * now changed window sizes */
+ ret = CallWindowProc(hWNDOldProc, hwnd, message, wParam, lParam);
+
+ return ret;
+}
+
+static void
+wgl_error (long error)
+{
+#define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT
+ SetLastError(0xC0000000 /* error severity */
+ |0x00070000 /* error facility (who we are) */
+ |error);
+}
+
+GLAPI BOOL GLAPIENTRY
+wglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
+{
+ return FALSE;
+}
+
+GLAPI HGLRC GLAPIENTRY
+wglCreateContext (HDC hdc)
+{
+ HWND hWnd;
+ WNDPROC oldProc;
+ int error;
+
+ if (ctx) {
+ SetLastError(0);
+ return NULL;
+ }
+
+ if (!(hWnd = WindowFromDC(hdc))) {
+ SetLastError(0);
+ return NULL;
+ }
+
+ if (curPFD == 0) {
+ wgl_error(WGL_INVALID_PIXELFORMAT);
+ return NULL;
+ }
+
+ if ((oldProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC)) != __wglMonitor) {
+ hWNDOldProc = oldProc;
+ SetWindowLong(hWnd, GWL_WNDPROC, (LONG)__wglMonitor);
+ }
+
+ /* always log when debugging, or if user demands */
+ if (TDFX_DEBUG || env_check("MESA_FX_INFO", 'r')) {
+ freopen("MESA.LOG", "w", stderr);
+ }
+
+ {
+ RECT cliRect;
+ ShowWindow(hWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hWnd);
+ Sleep(100); /* a hack for win95 */
+ if (env_check("MESA_GLX_FX", 'w') && !(GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP)) {
+ /* XXX todo - windowed modes */
+ error = !(ctx = fxMesaCreateContext((GLuint) hWnd, GR_RESOLUTION_NONE, GR_REFRESH_NONE, pix[curPFD - 1].mesaAttr));
+ } else {
+ GetClientRect(hWnd, &cliRect);
+ error = !(ctx = fxMesaCreateBestContext((GLuint) hWnd, cliRect.right, cliRect.bottom, pix[curPFD - 1].mesaAttr));
+ }
+ }
+
+ /*if (getenv("SST_DUALHEAD"))
+ haveDualHead =
+ ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE : GL_FALSE);
+ else
+ haveDualHead = GL_FALSE;*/
+
+ if (error) {
+ SetLastError(0);
+ return NULL;
+ }
+
+ hDC = hdc;
+ hWND = hWnd;
+
+ /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
+ wglMakeCurrent(hdc, (HGLRC)1);
+
+ return (HGLRC)1;
+}
+
+GLAPI HGLRC GLAPIENTRY
+wglCreateLayerContext (HDC hdc, int iLayerPlane)
+{
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglDeleteContext (HGLRC hglrc)
+{
+ if (ctx && hglrc == (HGLRC)1) {
+
+ fxMesaDestroyContext(ctx);
+
+ SetWindowLong(WindowFromDC(hDC), GWL_WNDPROC, (LONG) hWNDOldProc);
+
+ ctx = NULL;
+ hDC = 0;
+ return TRUE;
+ }
+
+ SetLastError(0);
+
+ return FALSE;
+}
+
+GLAPI HGLRC GLAPIENTRY
+wglGetCurrentContext (VOID)
+{
+ if (ctx)
+ return (HGLRC)1;
+
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI HDC GLAPIENTRY
+wglGetCurrentDC (VOID)
+{
+ if (ctx)
+ return hDC;
+
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglSwapIntervalEXT (int interval)
+{
+ if (ctx == NULL) {
+ return FALSE;
+ }
+ if (interval < 0) {
+ interval = 0;
+ } else if (interval > 3) {
+ interval = 3;
+ }
+ ctx->swapInterval = interval;
+ return TRUE;
+}
+
+GLAPI int GLAPIENTRY
+wglGetSwapIntervalEXT (void)
+{
+ return (ctx == NULL) ? -1 : ctx->swapInterval;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglGetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
+{
+ /* gammaTable should be per-context */
+ memcpy(arrays, gammaTable, 3 * 256 * sizeof(GLushort));
+ return TRUE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglSetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
+{
+ GLint i, tableSize, inc, index;
+ GLushort *red, *green, *blue;
+ FxU32 gammaTableR[256], gammaTableG[256], gammaTableB[256];
+
+ /* gammaTable should be per-context */
+ memcpy(gammaTable, arrays, 3 * 256 * sizeof(GLushort));
+
+ tableSize = FX_grGetInteger(GR_GAMMA_TABLE_ENTRIES);
+ inc = 256 / tableSize;
+ red = (GLushort *)arrays;
+ green = (GLushort *)arrays + 256;
+ blue = (GLushort *)arrays + 512;
+ for (i = 0, index = 0; i < tableSize; i++, index += inc) {
+ gammaTableR[i] = red[index] >> 8;
+ gammaTableG[i] = green[index] >> 8;
+ gammaTableB[i] = blue[index] >> 8;
+ }
+
+ grLoadGammaTable(tableSize, gammaTableR, gammaTableG, gammaTableB);
+
+ return TRUE;
+}
+
+typedef void *HPBUFFERARB;
+
+/* WGL_ARB_pixel_format */
+GLAPI BOOL GLAPIENTRY
+wglGetPixelFormatAttribivARB (HDC hdc,
+ int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ int *piValues)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglGetPixelFormatAttribfvARB (HDC hdc,
+ int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ FLOAT *pfValues)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglChoosePixelFormatARB (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+/* WGL_ARB_render_texture */
+GLAPI BOOL GLAPIENTRY
+wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglSetPbufferAttribARB (HPBUFFERARB hPbuffer,
+ const int *piAttribList)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+/* WGL_ARB_pbuffer */
+GLAPI HPBUFFERARB GLAPIENTRY
+wglCreatePbufferARB (HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int *piAttribList)
+{
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI HDC GLAPIENTRY
+wglGetPbufferDCARB (HPBUFFERARB hPbuffer)
+{
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI int GLAPIENTRY
+wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC)
+{
+ SetLastError(0);
+ return -1;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglDestroyPbufferARB (HPBUFFERARB hPbuffer)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglQueryPbufferARB (HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int *piValue)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI const char * GLAPIENTRY
+wglGetExtensionsStringEXT (void)
+{
+ return "WGL_3DFX_gamma_control "
+ "WGL_EXT_swap_control "
+ "WGL_EXT_extensions_string WGL_ARB_extensions_string"
+ /*WGL_ARB_pixel_format WGL_ARB_render_texture WGL_ARB_pbuffer*/;
+}
+
+GLAPI const char * GLAPIENTRY
+wglGetExtensionsStringARB (HDC hdc)
+{
+ return wglGetExtensionsStringEXT();
+}
+
+static struct {
+ const char *name;
+ PROC func;
+} wgl_ext[] = {
+ {"wglGetExtensionsStringARB", (PROC)wglGetExtensionsStringARB},
+ {"wglGetExtensionsStringEXT", (PROC)wglGetExtensionsStringEXT},
+ {"wglSwapIntervalEXT", (PROC)wglSwapIntervalEXT},
+ {"wglGetSwapIntervalEXT", (PROC)wglGetSwapIntervalEXT},
+ {"wglGetDeviceGammaRamp3DFX", (PROC)wglGetDeviceGammaRamp3DFX},
+ {"wglSetDeviceGammaRamp3DFX", (PROC)wglSetDeviceGammaRamp3DFX},
+ /* WGL_ARB_pixel_format */
+ {"wglGetPixelFormatAttribivARB", (PROC)wglGetPixelFormatAttribivARB},
+ {"wglGetPixelFormatAttribfvARB", (PROC)wglGetPixelFormatAttribfvARB},
+ {"wglChoosePixelFormatARB", (PROC)wglChoosePixelFormatARB},
+ /* WGL_ARB_render_texture */
+ {"wglBindTexImageARB", (PROC)wglBindTexImageARB},
+ {"wglReleaseTexImageARB", (PROC)wglReleaseTexImageARB},
+ {"wglSetPbufferAttribARB", (PROC)wglSetPbufferAttribARB},
+ /* WGL_ARB_pbuffer */
+ {"wglCreatePbufferARB", (PROC)wglCreatePbufferARB},
+ {"wglGetPbufferDCARB", (PROC)wglGetPbufferDCARB},
+ {"wglReleasePbufferDCARB", (PROC)wglReleasePbufferDCARB},
+ {"wglDestroyPbufferARB", (PROC)wglDestroyPbufferARB},
+ {"wglQueryPbufferARB", (PROC)wglQueryPbufferARB},
+ {NULL, NULL}
+};
+
+GLAPI PROC GLAPIENTRY
+wglGetProcAddress (LPCSTR lpszProc)
+{
+ int i;
+ PROC p = (PROC)_glapi_get_proc_address((const char *)lpszProc);
+
+ /* we can't BlendColor. work around buggy applications */
+ if (p && strcmp(lpszProc, "glBlendColor")
+ && strcmp(lpszProc, "glBlendColorEXT"))
+ return p;
+
+ for (i = 0; wgl_ext[i].name; i++) {
+ if (!strcmp(lpszProc, wgl_ext[i].name)) {
+ return wgl_ext[i].func;
+ }
+ }
+
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI PROC GLAPIENTRY
+wglGetDefaultProcAddress (LPCSTR lpszProc)
+{
+ SetLastError(0);
+ return NULL;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglMakeCurrent (HDC hdc, HGLRC hglrc)
+{
+ if ((hdc == NULL) && (hglrc == NULL))
+ return TRUE;
+
+ if (!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) {
+ SetLastError(0);
+ return FALSE;
+ }
+
+ hDC = hdc;
+
+ fxMesaMakeCurrent(ctx);
+
+ return TRUE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglShareLists (HGLRC hglrc1, HGLRC hglrc2)
+{
+ if (!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
+ SetLastError(0);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL
+wglUseFontBitmaps_FX (HDC fontDevice, DWORD firstChar, DWORD numChars,
+ DWORD listBase)
+{
+ TEXTMETRIC metric;
+ BITMAPINFO *dibInfo;
+ HDC bitDevice;
+ COLORREF tempColor;
+ int i;
+
+ GetTextMetrics(fontDevice, &metric);
+
+ dibInfo = (BITMAPINFO *)calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
+ dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibInfo->bmiHeader.biPlanes = 1;
+ dibInfo->bmiHeader.biBitCount = 1;
+ dibInfo->bmiHeader.biCompression = BI_RGB;
+
+ bitDevice = CreateCompatibleDC(fontDevice);
+
+ /* Swap fore and back colors so the bitmap has the right polarity */
+ tempColor = GetBkColor(bitDevice);
+ SetBkColor(bitDevice, GetTextColor(bitDevice));
+ SetTextColor(bitDevice, tempColor);
+
+ /* Place chars based on base line */
+ SetTextAlign(bitDevice, TA_BASELINE);
+
+ for (i = 0; i < (int)numChars; i++) {
+ SIZE size;
+ char curChar;
+ int charWidth, charHeight, bmapWidth, bmapHeight, numBytes, res;
+ HBITMAP bitObject;
+ HGDIOBJ origBmap;
+ unsigned char *bmap;
+
+ curChar = (char)(i + firstChar); /* [koolsmoky] explicit cast */
+
+ /* Find how high/wide this character is */
+ GetTextExtentPoint32(bitDevice, &curChar, 1, &size);
+
+ /* Create the output bitmap */
+ charWidth = size.cx;
+ charHeight = size.cy;
+ bmapWidth = ((charWidth + 31) / 32) * 32; /* Round up to the next multiple of 32 bits */
+ bmapHeight = charHeight;
+ bitObject = CreateCompatibleBitmap(bitDevice, bmapWidth, bmapHeight);
+ /*VERIFY(bitObject);*/
+
+ /* Assign the output bitmap to the device */
+ origBmap = SelectObject(bitDevice, bitObject);
+
+ PatBlt(bitDevice, 0, 0, bmapWidth, bmapHeight, BLACKNESS);
+
+ /* Use our source font on the device */
+ SelectObject(bitDevice, GetCurrentObject(fontDevice, OBJ_FONT));
+
+ /* Draw the character */
+ TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1);
+
+ /* Unselect our bmap object */
+ SelectObject(bitDevice, origBmap);
+
+ /* Convert the display dependant representation to a 1 bit deep DIB */
+ numBytes = (bmapWidth * bmapHeight) / 8;
+ bmap = MALLOC(numBytes);
+ dibInfo->bmiHeader.biWidth = bmapWidth;
+ dibInfo->bmiHeader.biHeight = bmapHeight;
+ res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
+ dibInfo, DIB_RGB_COLORS);
+
+ /* Create the GL object */
+ glNewList(i + listBase, GL_COMPILE);
+ glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
+ charWidth, 0.0, bmap);
+ glEndList();
+ /* CheckGL(); */
+
+ /* Destroy the bmap object */
+ DeleteObject(bitObject);
+
+ /* Deallocate the bitmap data */
+ FREE(bmap);
+ }
+
+ /* Destroy the DC */
+ DeleteDC(bitDevice);
+
+ FREE(dibInfo);
+
+ return TRUE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglUseFontBitmapsW (HDC hdc, DWORD first, DWORD count, DWORD listBase)
+{
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglUseFontOutlinesA (HDC hdc, DWORD first, DWORD count,
+ DWORD listBase, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglUseFontOutlinesW (HDC hdc, DWORD first, DWORD count,
+ DWORD listBase, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+
+GLAPI BOOL GLAPIENTRY
+wglSwapLayerBuffers (HDC hdc, UINT fuPlanes)
+{
+ if (ctx && WindowFromDC(hdc) == hWND) {
+ fxMesaSwapBuffers();
+
+ return TRUE;
+ }
+
+ SetLastError(0);
+ return FALSE;
+}
+
+static int
+pfd_tablen (void)
+{
+ /* we should take an envvar for `fxMesaSelectCurrentBoard' */
+ return (fxMesaSelectCurrentBoard(0) < GR_SSTTYPE_Voodoo4)
+ ? 2 /* only 16bit entries */
+ : sizeof(pix) / sizeof(pix[0]); /* full table */
+}
+
+GLAPI int GLAPIENTRY
+wglChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int i, best = -1, qt_valid_pix;
+ PIXELFORMATDESCRIPTOR pfd = *ppfd;
+
+ qt_valid_pix = pfd_tablen();
+
+#if 1 || QUAKE2 || GORE
+ /* QUAKE2: 24+32 */
+ /* GORE : 24+16 */
+ if ((pfd.cColorBits == 24) || (pfd.cColorBits == 32)) {
+ /* the first 2 entries are 16bit */
+ pfd.cColorBits = (qt_valid_pix > 2) ? 32 : 16;
+ }
+ if (pfd.cColorBits == 32) {
+ pfd.cDepthBits = 24;
+ } else if (pfd.cColorBits == 16) {
+ pfd.cDepthBits = 16;
+ }
+#endif
+
+ if (pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR) || pfd.nVersion != 1) {
+ SetLastError(0);
+ return 0;
+ }
+
+ for (i = 0; i < qt_valid_pix; i++) {
+ if (pfd.cColorBits > 0 && pix[i].pfd.cColorBits != pfd.cColorBits)
+ continue;
+
+ if ((pfd.dwFlags & PFD_DRAW_TO_WINDOW)
+ && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue;
+ if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP)
+ && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) continue;
+ if ((pfd.dwFlags & PFD_SUPPORT_GDI)
+ && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI)) continue;
+ if ((pfd.dwFlags & PFD_SUPPORT_OPENGL)
+ && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue;
+ if (!(pfd.dwFlags & PFD_DOUBLEBUFFER_DONTCARE)
+ && ((pfd.dwFlags & PFD_DOUBLEBUFFER) !=
+ (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+#if 1 /* Doom3 fails here! */
+ if (!(pfd.dwFlags & PFD_STEREO_DONTCARE)
+ && ((pfd.dwFlags & PFD_STEREO) !=
+ (pix[i].pfd.dwFlags & PFD_STEREO))) continue;
+#endif
+
+ if (pfd.cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
+ continue; /* need depth buffer */
+
+ if (pfd.cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
+ continue; /* need alpha buffer */
+
+#if 0 /* regression bug? */
+ if (pfd.cStencilBits > 0 && pix[i].pfd.cStencilBits == 0)
+ continue; /* need stencil buffer */
+#endif
+
+ if (pfd.iPixelType == pix[i].pfd.iPixelType) {
+ best = i + 1;
+ break;
+ }
+ }
+
+ if (best == -1) {
+ FILE *err = fopen("MESA.LOG", "w");
+ if (err != NULL) {
+ fprintf(err, "wglChoosePixelFormat failed\n");
+ fprintf(err, "\tnSize = %d\n", ppfd->nSize);
+ fprintf(err, "\tnVersion = %d\n", ppfd->nVersion);
+ fprintf(err, "\tdwFlags = %lu\n", ppfd->dwFlags);
+ fprintf(err, "\tiPixelType = %d\n", ppfd->iPixelType);
+ fprintf(err, "\tcColorBits = %d\n", ppfd->cColorBits);
+ fprintf(err, "\tcRedBits = %d\n", ppfd->cRedBits);
+ fprintf(err, "\tcRedShift = %d\n", ppfd->cRedShift);
+ fprintf(err, "\tcGreenBits = %d\n", ppfd->cGreenBits);
+ fprintf(err, "\tcGreenShift = %d\n", ppfd->cGreenShift);
+ fprintf(err, "\tcBlueBits = %d\n", ppfd->cBlueBits);
+ fprintf(err, "\tcBlueShift = %d\n", ppfd->cBlueShift);
+ fprintf(err, "\tcAlphaBits = %d\n", ppfd->cAlphaBits);
+ fprintf(err, "\tcAlphaShift = %d\n", ppfd->cAlphaShift);
+ fprintf(err, "\tcAccumBits = %d\n", ppfd->cAccumBits);
+ fprintf(err, "\tcAccumRedBits = %d\n", ppfd->cAccumRedBits);
+ fprintf(err, "\tcAccumGreenBits = %d\n", ppfd->cAccumGreenBits);
+ fprintf(err, "\tcAccumBlueBits = %d\n", ppfd->cAccumBlueBits);
+ fprintf(err, "\tcAccumAlphaBits = %d\n", ppfd->cAccumAlphaBits);
+ fprintf(err, "\tcDepthBits = %d\n", ppfd->cDepthBits);
+ fprintf(err, "\tcStencilBits = %d\n", ppfd->cStencilBits);
+ fprintf(err, "\tcAuxBuffers = %d\n", ppfd->cAuxBuffers);
+ fprintf(err, "\tiLayerType = %d\n", ppfd->iLayerType);
+ fprintf(err, "\tbReserved = %d\n", ppfd->bReserved);
+ fprintf(err, "\tdwLayerMask = %lu\n", ppfd->dwLayerMask);
+ fprintf(err, "\tdwVisibleMask = %lu\n", ppfd->dwVisibleMask);
+ fprintf(err, "\tdwDamageMask = %lu\n", ppfd->dwDamageMask);
+ fclose(err);
+ }
+
+ SetLastError(0);
+ return 0;
+ }
+
+ return best;
+}
+
+GLAPI int GLAPIENTRY
+ChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+
+ return wglChoosePixelFormat(hdc, ppfd);
+}
+
+GLAPI int GLAPIENTRY
+wglDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = pfd_tablen();
+
+ if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
+ ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
+ SetLastError(0);
+ return qt_valid_pix;
+ }
+
+ if (nBytes != 0)
+ *ppfd = pix[iPixelFormat - 1].pfd;
+
+ return qt_valid_pix;
+}
+
+GLAPI int GLAPIENTRY
+DescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
+}
+
+GLAPI int GLAPIENTRY
+wglGetPixelFormat (HDC hdc)
+{
+ if (curPFD == 0) {
+ SetLastError(0);
+ return 0;
+ }
+
+ return curPFD;
+}
+
+GLAPI int GLAPIENTRY
+GetPixelFormat (HDC hdc)
+{
+ return wglGetPixelFormat(hdc);
+}
+
+GLAPI BOOL GLAPIENTRY
+wglSetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = pfd_tablen();
+
+ if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix) {
+ if (ppfd == NULL) {
+ PIXELFORMATDESCRIPTOR my_pfd;
+ if (!wglDescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &my_pfd)) {
+ SetLastError(0);
+ return FALSE;
+ }
+ } else if (ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
+ SetLastError(0);
+ return FALSE;
+ }
+ }
+ curPFD = iPixelFormat;
+
+ return TRUE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglSwapBuffers (HDC hdc)
+{
+ if (!ctx) {
+ SetLastError(0);
+ return FALSE;
+ }
+
+ fxMesaSwapBuffers();
+
+ return TRUE;
+}
+
+GLAPI BOOL GLAPIENTRY
+SetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ return wglSetPixelFormat(hdc, iPixelFormat, ppfd);
+}
+
+GLAPI BOOL GLAPIENTRY
+SwapBuffers(HDC hdc)
+{
+ return wglSwapBuffers(hdc);
+}
+
+static FIXED
+FixedFromDouble (double d)
+{
+ struct {
+ FIXED f;
+ long l;
+ } pun;
+ pun.l = (long)(d * 65536L);
+ return pun.f;
+}
+
+/*
+** This was yanked from windows/gdi/wgl.c
+*/
+GLAPI BOOL GLAPIENTRY
+wglUseFontBitmapsA (HDC hdc, DWORD first, DWORD count, DWORD listBase)
+{
+ int i;
+ GLuint font_list;
+ DWORD size;
+ GLYPHMETRICS gm;
+ HANDLE hBits;
+ LPSTR lpBits;
+ MAT2 mat;
+ int success = TRUE;
+
+ font_list = listBase;
+
+ mat.eM11 = FixedFromDouble(1);
+ mat.eM12 = FixedFromDouble(0);
+ mat.eM21 = FixedFromDouble(0);
+ mat.eM22 = FixedFromDouble(-1);
+
+ memset(&gm, 0, sizeof(gm));
+
+ /*
+ ** If we can't get the glyph outline, it may be because this is a fixed
+ ** font. Try processing it that way.
+ */
+ if (GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) == GDI_ERROR) {
+ return wglUseFontBitmaps_FX(hdc, first, count, listBase);
+ }
+
+ /*
+ ** Otherwise process all desired characters.
+ */
+ for (i = 0; i < count; i++) {
+ DWORD err;
+
+ glNewList(font_list + i, GL_COMPILE);
+
+ /* allocate space for the bitmap/outline */
+ size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
+ if (size == GDI_ERROR) {
+ glEndList();
+ err = GetLastError();
+ success = FALSE;
+ continue;
+ }
+
+ hBits = GlobalAlloc(GHND, size + 1);
+ lpBits = GlobalLock(hBits);
+
+ err = GetGlyphOutline(hdc, /* handle to device context */
+ first + i, /* character to query */
+ GGO_BITMAP, /* format of data to return */
+ &gm, /* pointer to structure for metrics */
+ size, /* size of buffer for data */
+ lpBits, /* pointer to buffer for data */
+ &mat /* pointer to transformation */
+ /* matrix structure */
+ );
+
+ if (err == GDI_ERROR) {
+ GlobalUnlock(hBits);
+ GlobalFree(hBits);
+
+ glEndList();
+ err = GetLastError();
+ success = FALSE;
+ continue;
+ }
+
+ glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
+ -gm.gmptGlyphOrigin.x,
+ gm.gmptGlyphOrigin.y,
+ gm.gmCellIncX, gm.gmCellIncY,
+ (const GLubyte *)lpBits);
+
+ GlobalUnlock(hBits);
+ GlobalFree(hBits);
+
+ glEndList();
+ }
+
+ return success;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglDescribeLayerPlane (HDC hdc, int iPixelFormat, int iLayerPlane,
+ UINT nBytes, LPLAYERPLANEDESCRIPTOR ppfd)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI int GLAPIENTRY
+wglGetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart,
+ int cEntries, COLORREF *pcr)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI BOOL GLAPIENTRY
+wglRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+GLAPI int GLAPIENTRY
+wglSetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart,
+ int cEntries, CONST COLORREF *pcr)
+{
+ SetLastError(0);
+ return FALSE;
+}
+
+
+/***************************************************************************
+ * [dBorca] simplistic ICD implementation, based on ICD code by Gregor Anich
+ */
+
+typedef struct _icdTable {
+ DWORD size;
+ PROC table[336];
+} ICDTABLE, *PICDTABLE;
+
+#ifdef USE_MGL_NAMESPACE
+#define GL_FUNC(func) mgl##func
+#else
+#define GL_FUNC(func) gl##func
+#endif
+
+static ICDTABLE icdTable = { 336, {
+#define ICD_ENTRY(func) (PROC)GL_FUNC(func),
+#include "../icd/icdlist.h"
+#undef ICD_ENTRY
+} };
+
+
+GLAPI BOOL GLAPIENTRY
+DrvCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
+{
+ return wglCopyContext(hglrcSrc, hglrcDst, mask);
+}
+
+
+GLAPI HGLRC GLAPIENTRY
+DrvCreateContext (HDC hdc)
+{
+ return wglCreateContext(hdc);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvDeleteContext (HGLRC hglrc)
+{
+ return wglDeleteContext(hglrc);
+}
+
+
+GLAPI HGLRC GLAPIENTRY
+DrvCreateLayerContext (HDC hdc, int iLayerPlane)
+{
+ return wglCreateContext(hdc);
+}
+
+
+GLAPI PICDTABLE GLAPIENTRY
+DrvSetContext (HDC hdc, HGLRC hglrc, void *callback)
+{
+ return wglMakeCurrent(hdc, hglrc) ? &icdTable : NULL;
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvReleaseContext (HGLRC hglrc)
+{
+ return TRUE;
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvShareLists (HGLRC hglrc1, HGLRC hglrc2)
+{
+ return wglShareLists(hglrc1, hglrc2);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvDescribeLayerPlane (HDC hdc, int iPixelFormat,
+ int iLayerPlane, UINT nBytes,
+ LPLAYERPLANEDESCRIPTOR plpd)
+{
+ return wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
+}
+
+
+GLAPI int GLAPIENTRY
+DrvSetLayerPaletteEntries (HDC hdc, int iLayerPlane,
+ int iStart, int cEntries, CONST COLORREF *pcr)
+{
+ return wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
+}
+
+
+GLAPI int GLAPIENTRY
+DrvGetLayerPaletteEntries (HDC hdc, int iLayerPlane,
+ int iStart, int cEntries, COLORREF *pcr)
+{
+ return wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize)
+{
+ return wglRealizeLayerPalette(hdc, iLayerPlane, bRealize);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvSwapLayerBuffers (HDC hdc, UINT fuPlanes)
+{
+ return wglSwapLayerBuffers(hdc, fuPlanes);
+}
+
+GLAPI int GLAPIENTRY
+DrvDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
+}
+
+
+GLAPI PROC GLAPIENTRY
+DrvGetProcAddress (LPCSTR lpszProc)
+{
+ return wglGetProcAddress(lpszProc);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvSetPixelFormat (HDC hdc, int iPixelFormat)
+{
+ return wglSetPixelFormat(hdc, iPixelFormat, NULL);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvSwapBuffers (HDC hdc)
+{
+ return wglSwapBuffers(hdc);
+}
+
+
+GLAPI BOOL GLAPIENTRY
+DrvValidateVersion (DWORD version)
+{
+ (void)version;
+ return TRUE;
+}
+
+
+#if (_MSC_VER >= 1200)
+#pragma warning( pop )
+#endif
+
+#endif /* FX */