summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/glide/fxwgl.c
diff options
context:
space:
mode:
authorjtg <jtg>1999-08-19 00:55:39 +0000
committerjtg <jtg>1999-08-19 00:55:39 +0000
commitafb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1c (patch)
tree59d65b4da12fb5379224cf5f6b808fde91523c7f /src/mesa/drivers/glide/fxwgl.c
parentf2544d4920ce168bec9cd94d774b7ea5103a3d74 (diff)
Initial revision
Diffstat (limited to 'src/mesa/drivers/glide/fxwgl.c')
-rw-r--r--src/mesa/drivers/glide/fxwgl.c806
1 files changed, 806 insertions, 0 deletions
diff --git a/src/mesa/drivers/glide/fxwgl.c b/src/mesa/drivers/glide/fxwgl.c
new file mode 100644
index 0000000000..cbea79aecd
--- /dev/null
+++ b/src/mesa/drivers/glide/fxwgl.c
@@ -0,0 +1,806 @@
+/* fxwgl.c - Microsoft wgl functions emulation for
+ * 3Dfx VooDoo/Mesa interface
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef __WIN32__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#ifdef __cplusplus
+ }
+#endif
+
+#include <stdio.h>
+#include <GL/fxmesa.h>
+#include "fxdrv.h"
+
+#define MAX_MESA_ATTRS 20
+
+struct __extensions__
+{
+ PROC proc;
+ char *name;
+};
+
+struct __pixelformat__
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ GLint mesaAttr[MAX_MESA_ATTRS];
+};
+
+WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
+
+static struct __extensions__ ext[] = {
+
+#ifdef GL_EXT_polygon_offset
+ { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
+#endif
+ { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
+ { (PROC)glBlendColorEXT, "glBlendColorExt" },
+ { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
+ { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
+ { (PROC)glColorPointerEXT, "glColorPointerEXT" },
+ { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
+ { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
+ { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
+ { (PROC)glGetPointervEXT, "glGetPointervEXT" },
+ { (PROC)glArrayElementEXT, "glArrayElementEXT" },
+ { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
+ { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
+ { (PROC)glBindTextureEXT, "glBindTextureEXT" },
+ { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
+ { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
+ { (PROC)glIsTextureEXT, "glIsTextureEXT" },
+ { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
+ { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
+ { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
+ { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
+ { (PROC)gl3DfxSetPaletteEXT, "3DFX_set_global_palette" },
+ { (PROC)glColorTableEXT, "glColorTableEXT" },
+ { (PROC)glColorSubTableEXT, "glColorSubTableEXT" },
+ { (PROC)glGetColorTableEXT, "glGetColorTableEXT" },
+ { (PROC)glGetColorTableParameterfvEXT, "glGetColorTableParameterfvEXT" },
+ { (PROC)glGetColorTableParameterivEXT, "glGetColorTableParameterivEXT" },
+ { (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
+ { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
+ { (PROC)glBlendFuncSeparateINGR, "glBlendFuncSeparateINGR" },
+ { (PROC)glLockArraysEXT, "glLockArraysEXT" },
+ { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }
+};
+
+static int qt_ext = sizeof(ext) / sizeof(ext[0]);
+
+struct __pixelformat__ pix[] =
+{
+ /* None */
+ {
+ {
+ 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,0,24,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 0,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ },
+
+ /* Alpha */
+ {
+ {
+ 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,
+ 0,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 8,
+ FXMESA_DEPTH_SIZE, 0,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ },
+
+ /* 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,0,24,
+ 0,0,0,0,0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,0,0,0
+ },
+ {
+ FXMESA_DOUBLEBUFFER,
+ FXMESA_ALPHA_SIZE, 0,
+ FXMESA_DEPTH_SIZE, 16,
+ FXMESA_STENCIL_SIZE, 0,
+ FXMESA_ACCUM_SIZE, 0,
+ FXMESA_NONE
+ }
+ }
+};
+static int qt_pix = sizeof(pix) / sizeof(pix[0]);
+
+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 */
+
+static GLboolean gdiWindowHack;
+static GLboolean gdiWindowHackEna;
+static void *dibSurfacePtr;
+static BITMAPINFO *dibBMI;
+static HBITMAP dibHBM;
+static HWND dibWnd;
+
+LONG GLAPIENTRY __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 (wParam != SIZE_MINIMIZED) {
+ static int moving = 0;
+ if (!moving) {
+ if(fxQueryHardware()!=GR_SSTTYPE_VOODOO) {
+ if(!grSstControl(GR_CONTROL_RESIZE)) {
+ moving = 1;
+ SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER);
+ moving = 0;
+ if(!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,grSstScreenWidth(),grSstScreenHeight());
+ /* And let the new size set in the context */
+ fxMesaUpdateScreenSize(ctx);
+ }
+ }
+ break;
+ case WM_ACTIVATE:
+ if((fxQueryHardware()==GR_SSTTYPE_VOODOO) &&
+ (!gdiWindowHack) &&
+ (!haveDualHead)) {
+ WORD fActive = LOWORD(wParam);
+ BOOL fMinimized = (BOOL) HIWORD(wParam);
+
+ if((fActive == WA_INACTIVE) || fMinimized)
+ grSstControl(GR_CONTROL_DEACTIVATE);
+ else
+ grSstControl(GR_CONTROL_ACTIVATE);
+ }
+ break;
+ case WM_SHOWWINDOW:
+ break;
+ case WM_SYSCHAR:
+ if(gdiWindowHackEna && (VK_RETURN == wParam)) {
+ if(gdiWindowHack) {
+ gdiWindowHack = GL_FALSE;
+ grSstControl(GR_CONTROL_ACTIVATE);
+ } else {
+ gdiWindowHack = GL_TRUE;
+ grSstControl(GR_CONTROL_DEACTIVATE);
+ }
+ }
+ break;
+ }
+ }
+
+ /* Finaly call the hWNDOldProc, which handles the resize witch the
+ now changed window sizes */
+ ret = CallWindowProc( hWNDOldProc, hwnd, message, wParam, lParam );
+
+ return(ret);
+}
+
+BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
+{
+ return(FALSE);
+}
+
+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) {
+ SetLastError(0);
+ return(NULL);
+ }
+
+ if((oldProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC)) != __wglMonitor) {
+ hWNDOldProc = oldProc;
+ SetWindowLong(hWnd,GWL_WNDPROC,(LONG)__wglMonitor);
+ }
+
+#ifndef FX_SILENT
+ freopen("MESA.LOG","w",stderr);
+#endif
+
+ ShowWindow(hWnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hWnd);
+ Sleep(100); /* an hack for win95 */
+
+ if(fxQueryHardware() == GR_SSTTYPE_VOODOO) {
+ RECT cliRect;
+
+ GetClientRect(hWnd,&cliRect);
+ error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+ pix[curPFD - 1].mesaAttr));
+
+ if(!error) {
+ /* create the DIB section for windowed rendering */
+ DWORD *p;
+
+ dibWnd = hWnd;
+
+ hDC = GetDC(dibWnd);
+
+ dibBMI = (BITMAPINFO*) malloc( sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+ memset(dibBMI,0,sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+ dibBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibBMI->bmiHeader.biWidth = ctx->width;
+ dibBMI->bmiHeader.biHeight = -ctx->height;
+ dibBMI->bmiHeader.biPlanes = (short)1;
+ dibBMI->bmiHeader.biBitCount = (short)16;
+ dibBMI->bmiHeader.biCompression = BI_BITFIELDS;
+ dibBMI->bmiHeader.biSizeImage = 0;
+ dibBMI->bmiHeader.biXPelsPerMeter = 0;
+ dibBMI->bmiHeader.biYPelsPerMeter = 0;
+ dibBMI->bmiHeader.biClrUsed = 3;
+ dibBMI->bmiHeader.biClrImportant = 3;
+
+ p = (DWORD*)dibBMI->bmiColors;
+ p[0] = 0xF800;
+ p[1] = 0x07E0;
+ p[2] = 0x001F;
+
+ dibHBM = CreateDIBSection(hDC, dibBMI, DIB_RGB_COLORS, &dibSurfacePtr, NULL, 0);
+
+ ReleaseDC(dibWnd, hDC);
+
+ gdiWindowHackEna = (dibHBM != NULL ? GL_TRUE : GL_FALSE);
+
+ if (!getenv("MESA_WGL_FX") || !strcmp(getenv("MESA_WGL_FX"),"fullscreen"))
+ gdiWindowHack = GL_FALSE;
+ else {
+ gdiWindowHack = GL_TRUE;
+ grSstControl(GR_CONTROL_DEACTIVATE);
+ }
+ }
+ } else {
+ /* For the Voodoo Rush */
+
+ if(getenv("MESA_WGL_FX") && !strcmp(getenv("MESA_WGL_FX"),"fullscreen")) {
+ RECT cliRect;
+
+ GetClientRect(hWnd,&cliRect);
+ error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+ pix[curPFD - 1].mesaAttr));
+ } else
+ error = !(ctx = fxMesaCreateContext((GLuint)hWnd,GR_RESOLUTION_NONE,GR_REFRESH_75Hz,
+ 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);
+}
+
+HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
+{
+ SetLastError(0);
+ return(NULL);
+}
+
+BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
+{
+ if(ctx && hglrc == (HGLRC)1) {
+ if (gdiWindowHackEna) {
+ DeleteObject(dibHBM);
+ free(dibBMI);
+
+ dibSurfacePtr = NULL;
+ dibBMI = NULL;
+ dibHBM = NULL;
+ dibWnd = NULL;
+ }
+
+ fxMesaDestroyContext(ctx);
+
+ SetWindowLong(WindowFromDC(hDC),GWL_WNDPROC,(LONG)hWNDOldProc);
+
+ ctx = NULL;
+ hDC = 0;
+ return(TRUE);
+ }
+
+ SetLastError(0);
+
+ return(FALSE);
+}
+
+HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
+{
+ if(ctx)
+ return((HGLRC)1);
+
+ SetLastError(0);
+ return(NULL);
+}
+
+HDC GLAPIENTRY wglGetCurrentDC(VOID)
+{
+ if(ctx)
+ return(hDC);
+
+ SetLastError(0);
+ return(NULL);
+}
+
+PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
+{
+ int i;
+
+ /*fprintf(stderr,"fxMesa: looking for extension %s\n",lpszProc);
+ fflush(stderr);*/
+
+ for(i = 0;i < qt_ext;i++)
+ if(!strcmp(lpszProc,ext[i].name)) {
+ /*fprintf(stderr,"fxMesa: found extension %s\n",lpszProc);
+ fflush(stderr);*/
+
+ return(ext[i].proc);
+ }
+ SetLastError(0);
+ return(NULL);
+}
+
+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);
+}
+
+BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
+{
+ if(!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
+ SetLastError(0);
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY wglUseFontBitmaps(HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase)
+{
+#define VERIFY(a) a
+
+ TEXTMETRIC metric;
+ BITMAPINFO *dibInfo;
+ HDC bitDevice;
+ COLORREF tempColor;
+ int i;
+
+ VERIFY(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);
+ // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
+ // VERIFY(bitDevice);
+
+ // 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
+ VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0);
+
+ for(i = 0; i < numChars; i++) {
+ SIZE size;
+ char curChar;
+ int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
+ HBITMAP bitObject;
+ HGDIOBJ origBmap;
+ unsigned char *bmap;
+
+ curChar = i + firstChar;
+
+ // Find how high/wide this character is
+ VERIFY(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);
+ VERIFY(origBmap);
+
+ VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
+
+ // Use our source font on the device
+ VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
+
+ // Draw the character
+ VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
+
+ // Unselect our bmap object
+ VERIFY(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);
+ //VERIFY(res);
+
+ // 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
+ VERIFY(DeleteDC(bitDevice));
+
+ free(dibInfo);
+
+ return TRUE;
+#undef VERIFY
+}
+
+BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
+{
+ return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
+ DWORD listBase,FLOAT deviation,
+ FLOAT extrusion,int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
+ DWORD listBase,FLOAT deviation,
+ FLOAT extrusion,int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ SetLastError(0);
+ return(FALSE);
+}
+
+
+BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
+{
+ if(ctx && WindowFromDC(hdc) == hWND) {
+ fxMesaSwapBuffers();
+
+ return(TRUE);
+ }
+
+ SetLastError(0);
+ return(FALSE);
+}
+
+int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int i,best=-1,qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) {
+ SetLastError(0);
+ return(0);
+ }
+
+ for(i = 0;i < qt_valid_pix;i++) {
+ if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
+ continue;
+ if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
+ continue;
+ if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
+ continue;
+ if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ continue;
+ if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
+ continue;
+ if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
+ continue;
+
+ if (ppfd->cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
+ continue; /* need depth buffer */
+
+ if (ppfd->cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
+ continue; /* need alpha buffer */
+
+ if(ppfd->iPixelType == pix[i].pfd.iPixelType) {
+ best = i + 1;
+ break;
+ }
+ }
+
+ if(best == -1) {
+ SetLastError(0);
+ return(0);
+ }
+
+ return(best);
+}
+
+int GLAPIENTRY ChoosePixelFormat(HDC hdc,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ return wglChoosePixelFormat(hdc,ppfd);
+}
+
+int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
+ ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
+ SetLastError(0);
+ return(0);
+ }
+
+ if(nBytes != 0)
+ *ppfd = pix[iPixelFormat - 1].pfd;
+
+ return(qt_valid_pix);
+}
+
+int GLAPIENTRY DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
+}
+
+int GLAPIENTRY wglGetPixelFormat(HDC hdc)
+{
+ if(curPFD == 0) {
+ SetLastError(0);
+ return(0);
+ }
+
+ return(curPFD);
+}
+
+int GLAPIENTRY GetPixelFormat(HDC hdc)
+{
+ return wglGetPixelFormat(hdc);
+}
+
+BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int qt_valid_pix;
+
+ qt_valid_pix = qt_pix;
+
+ if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
+ SetLastError(0);
+ return(FALSE);
+ }
+ curPFD = iPixelFormat;
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
+{
+ if(!ctx) {
+ SetLastError(0);
+ return(FALSE);
+ }
+
+ fxMesaSwapBuffers();
+
+ if(gdiWindowHack) {
+ GLuint width=ctx->width;
+ GLuint height=ctx->height;
+
+ HDC hdcScreen = GetDC(dibWnd);
+ HDC hdcDIBSection = CreateCompatibleDC(hdcScreen);
+ HBITMAP holdBitmap = (HBITMAP) SelectObject(hdcDIBSection, dibHBM);
+
+ grLfbReadRegion(GR_BUFFER_FRONTBUFFER, 0, 0,
+ width, height,
+ width * 2,
+ dibSurfacePtr);
+
+ /* Since the hardware is configured for GR_COLORFORMAT_ABGR the pixel data is
+ * going to come out as BGR 565, which is reverse of what we need for blitting
+ * to screen, so we need to convert it here pixel-by-pixel (ick). This loop would NOT
+ * be required if the color format was changed to GR_COLORFORMAT_ARGB, but I do
+ * not know the ramifications of that, so this will work until that is resolved.
+ *
+ * This routine CRIES out for MMX implementation, however since that's not
+ * guaranteed to be running on MMX enabled hardware so I'm not going to do
+ * that. I'm just going to try to make a reasonably efficient C
+ * version. -TAJ
+ *
+ * This routine drops frame rate by <1 fps on a 200Mhz MMX processor with a 640x480
+ * display. Obviously, it's performance hit will be higher on larger displays and
+ * less on smaller displays. To support the window-hack display this is probably fine.
+ */
+ {
+ unsigned long *pixel = dibSurfacePtr;
+ unsigned long count = (width * height) / 2;
+
+ while (count--)
+ {
+ *pixel++ = (*pixel & 0x07e007e0) /* greens */
+ | ((*pixel & 0xf800f800) >> 11) /* swap blues */
+ | ((*pixel & 0x001f001f) << 11) /* swap reds */
+ ;
+ }
+ }
+
+ BitBlt(hdcScreen, 0, 0,
+ width, height,
+ hdcDIBSection,
+ 0, 0, SRCCOPY);
+
+ ReleaseDC(dibWnd, hdcScreen);
+ SelectObject(hdcDIBSection, holdBitmap);
+ DeleteDC(hdcDIBSection);
+ }
+
+ return(TRUE);
+}
+
+BOOL GLAPIENTRY SetPixelFormat(HDC hdc, int iPixelFormat,
+ CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+ return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
+}
+
+BOOL GLAPIENTRY SwapBuffers(HDC hdc)
+{
+ return wglSwapBuffers(hdc);
+}
+
+#endif /* FX */