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