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