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