diff options
Diffstat (limited to 'mesalib/src/mesa/drivers/windows/fx/fxwgl.c')
-rw-r--r-- | mesalib/src/mesa/drivers/windows/fx/fxwgl.c | 1307 |
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 */ |