Initial revision
[mesa.git] / src / mesa / drivers / glide / fxwgl.c
1 /* fxwgl.c - Microsoft wgl functions emulation for
2 * 3Dfx VooDoo/Mesa interface
3 */
4
5 /*
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * See the file fxapi.c for more informations about authors
21 *
22 */
23
24 #ifdef __WIN32__
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #include <windows.h>
31 #include <GL/gl.h>
32 #include <GL/glu.h>
33
34 #ifdef __cplusplus
35 }
36 #endif
37
38 #include <stdio.h>
39 #include <GL/fxmesa.h>
40 #include "fxdrv.h"
41
42 #define MAX_MESA_ATTRS 20
43
44 struct __extensions__
45 {
46 PROC proc;
47 char *name;
48 };
49
50 struct __pixelformat__
51 {
52 PIXELFORMATDESCRIPTOR pfd;
53 GLint mesaAttr[MAX_MESA_ATTRS];
54 };
55
56 WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
57
58 static struct __extensions__ ext[] = {
59
60 #ifdef GL_EXT_polygon_offset
61 { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
62 #endif
63 { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
64 { (PROC)glBlendColorEXT, "glBlendColorExt" },
65 { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
66 { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
67 { (PROC)glColorPointerEXT, "glColorPointerEXT" },
68 { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
69 { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
70 { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
71 { (PROC)glGetPointervEXT, "glGetPointervEXT" },
72 { (PROC)glArrayElementEXT, "glArrayElementEXT" },
73 { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
74 { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
75 { (PROC)glBindTextureEXT, "glBindTextureEXT" },
76 { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
77 { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
78 { (PROC)glIsTextureEXT, "glIsTextureEXT" },
79 { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
80 { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
81 { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
82 { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
83 { (PROC)gl3DfxSetPaletteEXT, "3DFX_set_global_palette" },
84 { (PROC)glColorTableEXT, "glColorTableEXT" },
85 { (PROC)glColorSubTableEXT, "glColorSubTableEXT" },
86 { (PROC)glGetColorTableEXT, "glGetColorTableEXT" },
87 { (PROC)glGetColorTableParameterfvEXT, "glGetColorTableParameterfvEXT" },
88 { (PROC)glGetColorTableParameterivEXT, "glGetColorTableParameterivEXT" },
89 { (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
90 { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
91 { (PROC)glBlendFuncSeparateINGR, "glBlendFuncSeparateINGR" },
92 { (PROC)glLockArraysEXT, "glLockArraysEXT" },
93 { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }
94 };
95
96 static int qt_ext = sizeof(ext) / sizeof(ext[0]);
97
98 struct __pixelformat__ pix[] =
99 {
100 /* None */
101 {
102 {
103 sizeof(PIXELFORMATDESCRIPTOR), 1,
104 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
105 PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
106 PFD_TYPE_RGBA,
107 32,
108 8,0,8,8,8,16,0,24,
109 0,0,0,0,0,
110 0,
111 0,
112 0,
113 PFD_MAIN_PLANE,
114 0,0,0,0
115 },
116 {
117 FXMESA_DOUBLEBUFFER,
118 FXMESA_ALPHA_SIZE, 0,
119 FXMESA_DEPTH_SIZE, 0,
120 FXMESA_STENCIL_SIZE, 0,
121 FXMESA_ACCUM_SIZE, 0,
122 FXMESA_NONE
123 }
124 },
125
126 /* Alpha */
127 {
128 {
129 sizeof(PIXELFORMATDESCRIPTOR), 1,
130 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
131 PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
132 PFD_TYPE_RGBA,
133 32,
134 8,0,8,8,8,16,8,24,
135 0,0,0,0,0,
136 0,
137 0,
138 0,
139 PFD_MAIN_PLANE,
140 0,0,0,0
141 },
142 {
143 FXMESA_DOUBLEBUFFER,
144 FXMESA_ALPHA_SIZE, 8,
145 FXMESA_DEPTH_SIZE, 0,
146 FXMESA_STENCIL_SIZE, 0,
147 FXMESA_ACCUM_SIZE, 0,
148 FXMESA_NONE
149 }
150 },
151
152 /* Depth */
153 {
154 {
155 sizeof(PIXELFORMATDESCRIPTOR), 1,
156 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
157 PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
158 PFD_TYPE_RGBA,
159 32,
160 8,0,8,8,8,16,0,24,
161 0,0,0,0,0,
162 16,
163 0,
164 0,
165 PFD_MAIN_PLANE,
166 0,0,0,0
167 },
168 {
169 FXMESA_DOUBLEBUFFER,
170 FXMESA_ALPHA_SIZE, 0,
171 FXMESA_DEPTH_SIZE, 16,
172 FXMESA_STENCIL_SIZE, 0,
173 FXMESA_ACCUM_SIZE, 0,
174 FXMESA_NONE
175 }
176 }
177 };
178 static int qt_pix = sizeof(pix) / sizeof(pix[0]);
179
180 static fxMesaContext ctx = NULL;
181 static WNDPROC hWNDOldProc;
182 static int curPFD = 0;
183 static HDC hDC;
184 static HWND hWND;
185
186 static GLboolean haveDualHead;
187
188 /* For the in-window-rendering hack */
189
190 static GLboolean gdiWindowHack;
191 static GLboolean gdiWindowHackEna;
192 static void *dibSurfacePtr;
193 static BITMAPINFO *dibBMI;
194 static HBITMAP dibHBM;
195 static HWND dibWnd;
196
197 LONG GLAPIENTRY __wglMonitor(HWND hwnd,UINT message,UINT wParam,LONG lParam)
198
199 {
200 long ret; /* Now gives the resized window at the end to hWNDOldProc */
201
202 if(ctx && hwnd == hWND) {
203 switch(message) {
204 case WM_PAINT:
205 case WM_MOVE:
206 break;
207 case WM_DISPLAYCHANGE:
208 case WM_SIZE:
209 if (wParam != SIZE_MINIMIZED) {
210 static int moving = 0;
211 if (!moving) {
212 if(fxQueryHardware()!=GR_SSTTYPE_VOODOO) {
213 if(!grSstControl(GR_CONTROL_RESIZE)) {
214 moving = 1;
215 SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER);
216 moving = 0;
217 if(!grSstControl(GR_CONTROL_RESIZE)) {
218 /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
219 PostMessage(hWND,WM_CLOSE,0,0);
220 }
221 }
222 }
223
224 /* Do the clipping in the glide library */
225 grClipWindow(0,0,grSstScreenWidth(),grSstScreenHeight());
226 /* And let the new size set in the context */
227 fxMesaUpdateScreenSize(ctx);
228 }
229 }
230 break;
231 case WM_ACTIVATE:
232 if((fxQueryHardware()==GR_SSTTYPE_VOODOO) &&
233 (!gdiWindowHack) &&
234 (!haveDualHead)) {
235 WORD fActive = LOWORD(wParam);
236 BOOL fMinimized = (BOOL) HIWORD(wParam);
237
238 if((fActive == WA_INACTIVE) || fMinimized)
239 grSstControl(GR_CONTROL_DEACTIVATE);
240 else
241 grSstControl(GR_CONTROL_ACTIVATE);
242 }
243 break;
244 case WM_SHOWWINDOW:
245 break;
246 case WM_SYSCHAR:
247 if(gdiWindowHackEna && (VK_RETURN == wParam)) {
248 if(gdiWindowHack) {
249 gdiWindowHack = GL_FALSE;
250 grSstControl(GR_CONTROL_ACTIVATE);
251 } else {
252 gdiWindowHack = GL_TRUE;
253 grSstControl(GR_CONTROL_DEACTIVATE);
254 }
255 }
256 break;
257 }
258 }
259
260 /* Finaly call the hWNDOldProc, which handles the resize witch the
261 now changed window sizes */
262 ret = CallWindowProc( hWNDOldProc, hwnd, message, wParam, lParam );
263
264 return(ret);
265 }
266
267 BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
268 {
269 return(FALSE);
270 }
271
272 HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
273 {
274 HWND hWnd;
275 WNDPROC oldProc;
276 int error;
277
278 if(ctx) {
279 SetLastError(0);
280 return(NULL);
281 }
282
283 if(!(hWnd = WindowFromDC(hdc))) {
284 SetLastError(0);
285 return(NULL);
286 }
287
288 if(curPFD == 0) {
289 SetLastError(0);
290 return(NULL);
291 }
292
293 if((oldProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC)) != __wglMonitor) {
294 hWNDOldProc = oldProc;
295 SetWindowLong(hWnd,GWL_WNDPROC,(LONG)__wglMonitor);
296 }
297
298 #ifndef FX_SILENT
299 freopen("MESA.LOG","w",stderr);
300 #endif
301
302 ShowWindow(hWnd, SW_SHOWNORMAL);
303 SetForegroundWindow(hWnd);
304 Sleep(100); /* an hack for win95 */
305
306 if(fxQueryHardware() == GR_SSTTYPE_VOODOO) {
307 RECT cliRect;
308
309 GetClientRect(hWnd,&cliRect);
310 error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
311 pix[curPFD - 1].mesaAttr));
312
313 if(!error) {
314 /* create the DIB section for windowed rendering */
315 DWORD *p;
316
317 dibWnd = hWnd;
318
319 hDC = GetDC(dibWnd);
320
321 dibBMI = (BITMAPINFO*) malloc( sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
322
323 memset(dibBMI,0,sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
324
325 dibBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
326 dibBMI->bmiHeader.biWidth = ctx->width;
327 dibBMI->bmiHeader.biHeight = -ctx->height;
328 dibBMI->bmiHeader.biPlanes = (short)1;
329 dibBMI->bmiHeader.biBitCount = (short)16;
330 dibBMI->bmiHeader.biCompression = BI_BITFIELDS;
331 dibBMI->bmiHeader.biSizeImage = 0;
332 dibBMI->bmiHeader.biXPelsPerMeter = 0;
333 dibBMI->bmiHeader.biYPelsPerMeter = 0;
334 dibBMI->bmiHeader.biClrUsed = 3;
335 dibBMI->bmiHeader.biClrImportant = 3;
336
337 p = (DWORD*)dibBMI->bmiColors;
338 p[0] = 0xF800;
339 p[1] = 0x07E0;
340 p[2] = 0x001F;
341
342 dibHBM = CreateDIBSection(hDC, dibBMI, DIB_RGB_COLORS, &dibSurfacePtr, NULL, 0);
343
344 ReleaseDC(dibWnd, hDC);
345
346 gdiWindowHackEna = (dibHBM != NULL ? GL_TRUE : GL_FALSE);
347
348 if (!getenv("MESA_WGL_FX") || !strcmp(getenv("MESA_WGL_FX"),"fullscreen"))
349 gdiWindowHack = GL_FALSE;
350 else {
351 gdiWindowHack = GL_TRUE;
352 grSstControl(GR_CONTROL_DEACTIVATE);
353 }
354 }
355 } else {
356 /* For the Voodoo Rush */
357
358 if(getenv("MESA_WGL_FX") && !strcmp(getenv("MESA_WGL_FX"),"fullscreen")) {
359 RECT cliRect;
360
361 GetClientRect(hWnd,&cliRect);
362 error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
363 pix[curPFD - 1].mesaAttr));
364 } else
365 error = !(ctx = fxMesaCreateContext((GLuint)hWnd,GR_RESOLUTION_NONE,GR_REFRESH_75Hz,
366 pix[curPFD - 1].mesaAttr));
367 }
368
369 if(getenv("SST_DUALHEAD"))
370 haveDualHead=((atoi(getenv("SST_DUALHEAD"))==1) ? GL_TRUE:GL_FALSE);
371 else
372 haveDualHead=GL_FALSE;
373
374 if(error) {
375 SetLastError(0);
376 return(NULL);
377 }
378
379 hDC = hdc;
380 hWND = hWnd;
381
382 /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
383 wglMakeCurrent(hdc,(HGLRC)1);
384
385 return((HGLRC)1);
386 }
387
388 HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
389 {
390 SetLastError(0);
391 return(NULL);
392 }
393
394 BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
395 {
396 if(ctx && hglrc == (HGLRC)1) {
397 if (gdiWindowHackEna) {
398 DeleteObject(dibHBM);
399 free(dibBMI);
400
401 dibSurfacePtr = NULL;
402 dibBMI = NULL;
403 dibHBM = NULL;
404 dibWnd = NULL;
405 }
406
407 fxMesaDestroyContext(ctx);
408
409 SetWindowLong(WindowFromDC(hDC),GWL_WNDPROC,(LONG)hWNDOldProc);
410
411 ctx = NULL;
412 hDC = 0;
413 return(TRUE);
414 }
415
416 SetLastError(0);
417
418 return(FALSE);
419 }
420
421 HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
422 {
423 if(ctx)
424 return((HGLRC)1);
425
426 SetLastError(0);
427 return(NULL);
428 }
429
430 HDC GLAPIENTRY wglGetCurrentDC(VOID)
431 {
432 if(ctx)
433 return(hDC);
434
435 SetLastError(0);
436 return(NULL);
437 }
438
439 PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
440 {
441 int i;
442
443 /*fprintf(stderr,"fxMesa: looking for extension %s\n",lpszProc);
444 fflush(stderr);*/
445
446 for(i = 0;i < qt_ext;i++)
447 if(!strcmp(lpszProc,ext[i].name)) {
448 /*fprintf(stderr,"fxMesa: found extension %s\n",lpszProc);
449 fflush(stderr);*/
450
451 return(ext[i].proc);
452 }
453 SetLastError(0);
454 return(NULL);
455 }
456
457 BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
458 {
459 if((hdc==NULL) && (hglrc==NULL))
460 return(TRUE);
461
462 if(!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) {
463 SetLastError(0);
464 return(FALSE);
465 }
466
467 hDC = hdc;
468
469 fxMesaMakeCurrent(ctx);
470
471 return(TRUE);
472 }
473
474 BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
475 {
476 if(!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
477 SetLastError(0);
478 return(FALSE);
479 }
480
481 return(TRUE);
482 }
483
484 BOOL GLAPIENTRY wglUseFontBitmaps(HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase)
485 {
486 #define VERIFY(a) a
487
488 TEXTMETRIC metric;
489 BITMAPINFO *dibInfo;
490 HDC bitDevice;
491 COLORREF tempColor;
492 int i;
493
494 VERIFY(GetTextMetrics(fontDevice, &metric));
495
496 dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
497 dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
498 dibInfo->bmiHeader.biPlanes = 1;
499 dibInfo->bmiHeader.biBitCount = 1;
500 dibInfo->bmiHeader.biCompression = BI_RGB;
501
502 bitDevice = CreateCompatibleDC(fontDevice);
503 // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
504 // VERIFY(bitDevice);
505
506 // Swap fore and back colors so the bitmap has the right polarity
507 tempColor = GetBkColor(bitDevice);
508 SetBkColor(bitDevice, GetTextColor(bitDevice));
509 SetTextColor(bitDevice, tempColor);
510
511 // Place chars based on base line
512 VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0);
513
514 for(i = 0; i < numChars; i++) {
515 SIZE size;
516 char curChar;
517 int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
518 HBITMAP bitObject;
519 HGDIOBJ origBmap;
520 unsigned char *bmap;
521
522 curChar = i + firstChar;
523
524 // Find how high/wide this character is
525 VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
526
527 // Create the output bitmap
528 charWidth = size.cx;
529 charHeight = size.cy;
530 bmapWidth = ((charWidth + 31) / 32) * 32; // Round up to the next multiple of 32 bits
531 bmapHeight = charHeight;
532 bitObject = CreateCompatibleBitmap(bitDevice,
533 bmapWidth,
534 bmapHeight);
535 //VERIFY(bitObject);
536
537 // Assign the output bitmap to the device
538 origBmap = SelectObject(bitDevice, bitObject);
539 VERIFY(origBmap);
540
541 VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
542
543 // Use our source font on the device
544 VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
545
546 // Draw the character
547 VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
548
549 // Unselect our bmap object
550 VERIFY(SelectObject(bitDevice, origBmap));
551
552 // Convert the display dependant representation to a 1 bit deep DIB
553 numBytes = (bmapWidth * bmapHeight) / 8;
554 bmap = malloc(numBytes);
555 dibInfo->bmiHeader.biWidth = bmapWidth;
556 dibInfo->bmiHeader.biHeight = bmapHeight;
557 res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
558 dibInfo,
559 DIB_RGB_COLORS);
560 //VERIFY(res);
561
562 // Create the GL object
563 glNewList(i + listBase, GL_COMPILE);
564 glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
565 charWidth, 0.0,
566 bmap);
567 glEndList();
568 // CheckGL();
569
570 // Destroy the bmap object
571 DeleteObject(bitObject);
572
573 // Deallocate the bitmap data
574 free(bmap);
575 }
576
577 // Destroy the DC
578 VERIFY(DeleteDC(bitDevice));
579
580 free(dibInfo);
581
582 return TRUE;
583 #undef VERIFY
584 }
585
586 BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
587 {
588 return(FALSE);
589 }
590
591 BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
592 DWORD listBase,FLOAT deviation,
593 FLOAT extrusion,int format,
594 LPGLYPHMETRICSFLOAT lpgmf)
595 {
596 SetLastError(0);
597 return(FALSE);
598 }
599
600 BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
601 DWORD listBase,FLOAT deviation,
602 FLOAT extrusion,int format,
603 LPGLYPHMETRICSFLOAT lpgmf)
604 {
605 SetLastError(0);
606 return(FALSE);
607 }
608
609
610 BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
611 {
612 if(ctx && WindowFromDC(hdc) == hWND) {
613 fxMesaSwapBuffers();
614
615 return(TRUE);
616 }
617
618 SetLastError(0);
619 return(FALSE);
620 }
621
622 int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
623 CONST PIXELFORMATDESCRIPTOR *ppfd)
624 {
625 int i,best=-1,qt_valid_pix;
626
627 qt_valid_pix = qt_pix;
628
629 if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) {
630 SetLastError(0);
631 return(0);
632 }
633
634 for(i = 0;i < qt_valid_pix;i++) {
635 if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
636 continue;
637 if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
638 continue;
639 if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
640 continue;
641 if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
642 continue;
643 if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
644 ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
645 continue;
646 if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
647 ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
648 continue;
649
650 if (ppfd->cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
651 continue; /* need depth buffer */
652
653 if (ppfd->cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
654 continue; /* need alpha buffer */
655
656 if(ppfd->iPixelType == pix[i].pfd.iPixelType) {
657 best = i + 1;
658 break;
659 }
660 }
661
662 if(best == -1) {
663 SetLastError(0);
664 return(0);
665 }
666
667 return(best);
668 }
669
670 int GLAPIENTRY ChoosePixelFormat(HDC hdc,
671 CONST PIXELFORMATDESCRIPTOR *ppfd)
672 {
673 return wglChoosePixelFormat(hdc,ppfd);
674 }
675
676 int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
677 LPPIXELFORMATDESCRIPTOR ppfd)
678 {
679 int qt_valid_pix;
680
681 qt_valid_pix = qt_pix;
682
683 if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
684 ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
685 SetLastError(0);
686 return(0);
687 }
688
689 if(nBytes != 0)
690 *ppfd = pix[iPixelFormat - 1].pfd;
691
692 return(qt_valid_pix);
693 }
694
695 int GLAPIENTRY DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
696 LPPIXELFORMATDESCRIPTOR ppfd)
697 {
698 return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
699 }
700
701 int GLAPIENTRY wglGetPixelFormat(HDC hdc)
702 {
703 if(curPFD == 0) {
704 SetLastError(0);
705 return(0);
706 }
707
708 return(curPFD);
709 }
710
711 int GLAPIENTRY GetPixelFormat(HDC hdc)
712 {
713 return wglGetPixelFormat(hdc);
714 }
715
716 BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
717 CONST PIXELFORMATDESCRIPTOR *ppfd)
718 {
719 int qt_valid_pix;
720
721 qt_valid_pix = qt_pix;
722
723 if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
724 SetLastError(0);
725 return(FALSE);
726 }
727 curPFD = iPixelFormat;
728
729 return(TRUE);
730 }
731
732 BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
733 {
734 if(!ctx) {
735 SetLastError(0);
736 return(FALSE);
737 }
738
739 fxMesaSwapBuffers();
740
741 if(gdiWindowHack) {
742 GLuint width=ctx->width;
743 GLuint height=ctx->height;
744
745 HDC hdcScreen = GetDC(dibWnd);
746 HDC hdcDIBSection = CreateCompatibleDC(hdcScreen);
747 HBITMAP holdBitmap = (HBITMAP) SelectObject(hdcDIBSection, dibHBM);
748
749 grLfbReadRegion(GR_BUFFER_FRONTBUFFER, 0, 0,
750 width, height,
751 width * 2,
752 dibSurfacePtr);
753
754 /* Since the hardware is configured for GR_COLORFORMAT_ABGR the pixel data is
755 * going to come out as BGR 565, which is reverse of what we need for blitting
756 * to screen, so we need to convert it here pixel-by-pixel (ick). This loop would NOT
757 * be required if the color format was changed to GR_COLORFORMAT_ARGB, but I do
758 * not know the ramifications of that, so this will work until that is resolved.
759 *
760 * This routine CRIES out for MMX implementation, however since that's not
761 * guaranteed to be running on MMX enabled hardware so I'm not going to do
762 * that. I'm just going to try to make a reasonably efficient C
763 * version. -TAJ
764 *
765 * This routine drops frame rate by <1 fps on a 200Mhz MMX processor with a 640x480
766 * display. Obviously, it's performance hit will be higher on larger displays and
767 * less on smaller displays. To support the window-hack display this is probably fine.
768 */
769 {
770 unsigned long *pixel = dibSurfacePtr;
771 unsigned long count = (width * height) / 2;
772
773 while (count--)
774 {
775 *pixel++ = (*pixel & 0x07e007e0) /* greens */
776 | ((*pixel & 0xf800f800) >> 11) /* swap blues */
777 | ((*pixel & 0x001f001f) << 11) /* swap reds */
778 ;
779 }
780 }
781
782 BitBlt(hdcScreen, 0, 0,
783 width, height,
784 hdcDIBSection,
785 0, 0, SRCCOPY);
786
787 ReleaseDC(dibWnd, hdcScreen);
788 SelectObject(hdcDIBSection, holdBitmap);
789 DeleteDC(hdcDIBSection);
790 }
791
792 return(TRUE);
793 }
794
795 BOOL GLAPIENTRY SetPixelFormat(HDC hdc, int iPixelFormat,
796 CONST PIXELFORMATDESCRIPTOR *ppfd)
797 {
798 return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
799 }
800
801 BOOL GLAPIENTRY SwapBuffers(HDC hdc)
802 {
803 return wglSwapBuffers(hdc);
804 }
805
806 #endif /* FX */