Rename the various function types in t_context.h to include a tnl_ prefix.
[mesa.git] / src / mesa / drivers / glide / fxwgl.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 *
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Authors:
26 * David Bucciarelli
27 * Brian Paul
28 * Keith Whitwell
29 * Hiroshi Morii
30 * Daniel Borca
31 */
32
33 /* fxwgl.c - Microsoft wgl functions emulation for
34 * 3Dfx VooDoo/Mesa interface
35 */
36
37
38 #ifdef _WIN32
39
40 #ifdef __cplusplus
41 extern "C"
42 {
43 #endif
44
45 #include <windows.h>
46 #define GL_GLEXT_PROTOTYPES
47 #include "GL/gl.h"
48 #include "GL/glext.h"
49
50 #ifdef __cplusplus
51 }
52 #endif
53
54 #include "GL/fxmesa.h"
55 #include "glheader.h"
56 #include "glapi.h"
57 #include "imports.h"
58 #include "fxdrv.h"
59
60 #define MAX_MESA_ATTRS 20
61
62 #if (_MSC_VER >= 1200)
63 #pragma warning( push )
64 #pragma warning( disable : 4273 )
65 #endif
66
67 struct __extensions__
68 {
69 PROC proc;
70 char *name;
71 };
72
73 struct __pixelformat__
74 {
75 PIXELFORMATDESCRIPTOR pfd;
76 GLint mesaAttr[MAX_MESA_ATTRS];
77 };
78
79 WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
80 static GLushort gammaTable[3*256];
81
82 struct __pixelformat__ pix[] = {
83 /* 16bit RGB565 single buffer with depth */
84 {
85 {sizeof(PIXELFORMATDESCRIPTOR), 1,
86 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
87 PFD_TYPE_RGBA,
88 16,
89 5, 0, 6, 5, 5, 11, 0, 0,
90 0, 0, 0, 0, 0,
91 16,
92 0,
93 0,
94 PFD_MAIN_PLANE,
95 0, 0, 0, 0}
96 ,
97 {FXMESA_COLORDEPTH, 16,
98 FXMESA_ALPHA_SIZE, 0,
99 FXMESA_DEPTH_SIZE, 16,
100 FXMESA_STENCIL_SIZE, 0,
101 FXMESA_ACCUM_SIZE, 0,
102 FXMESA_NONE}
103 }
104 ,
105 /* 16bit RGB565 double buffer with depth */
106 {
107 {sizeof(PIXELFORMATDESCRIPTOR), 1,
108 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
109 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
110 PFD_TYPE_RGBA,
111 16,
112 5, 0, 6, 5, 5, 11, 0, 0,
113 0, 0, 0, 0, 0,
114 16,
115 0,
116 0,
117 PFD_MAIN_PLANE,
118 0, 0, 0, 0}
119 ,
120 {FXMESA_COLORDEPTH, 16,
121 FXMESA_DOUBLEBUFFER,
122 FXMESA_ALPHA_SIZE, 0,
123 FXMESA_DEPTH_SIZE, 16,
124 FXMESA_STENCIL_SIZE, 0,
125 FXMESA_ACCUM_SIZE, 0,
126 FXMESA_NONE}
127 }
128 ,
129 /* 16bit ARGB1555 single buffer with depth */
130 {
131 {sizeof(PIXELFORMATDESCRIPTOR), 1,
132 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
133 PFD_TYPE_RGBA,
134 16,
135 5, 0, 5, 5, 5, 10, 1, 15,
136 0, 0, 0, 0, 0,
137 16,
138 0,
139 0,
140 PFD_MAIN_PLANE,
141 0, 0, 0, 0}
142 ,
143 {FXMESA_COLORDEPTH, 15,
144 FXMESA_ALPHA_SIZE, 1,
145 FXMESA_DEPTH_SIZE, 16,
146 FXMESA_STENCIL_SIZE, 0,
147 FXMESA_ACCUM_SIZE, 0,
148 FXMESA_NONE}
149 }
150 ,
151 /* 16bit ARGB1555 double buffer with depth */
152 {
153 {sizeof(PIXELFORMATDESCRIPTOR), 1,
154 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
155 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
156 PFD_TYPE_RGBA,
157 16,
158 5, 0, 5, 5, 5, 10, 1, 15,
159 0, 0, 0, 0, 0,
160 16,
161 0,
162 0,
163 PFD_MAIN_PLANE,
164 0, 0, 0, 0}
165 ,
166 {FXMESA_COLORDEPTH, 15,
167 FXMESA_DOUBLEBUFFER,
168 FXMESA_ALPHA_SIZE, 1,
169 FXMESA_DEPTH_SIZE, 16,
170 FXMESA_STENCIL_SIZE, 0,
171 FXMESA_ACCUM_SIZE, 0,
172 FXMESA_NONE}
173 }
174 ,
175 /* 32bit ARGB8888 single buffer with depth */
176 {
177 {sizeof(PIXELFORMATDESCRIPTOR), 1,
178 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
179 PFD_TYPE_RGBA,
180 32,
181 8, 0, 8, 8, 8, 16, 8, 24,
182 0, 0, 0, 0, 0,
183 24,
184 8,
185 0,
186 PFD_MAIN_PLANE,
187 0, 0, 0, 0}
188 ,
189 {FXMESA_COLORDEPTH, 32,
190 FXMESA_ALPHA_SIZE, 8,
191 FXMESA_DEPTH_SIZE, 24,
192 FXMESA_STENCIL_SIZE, 8,
193 FXMESA_ACCUM_SIZE, 0,
194 FXMESA_NONE}
195 }
196 ,
197 /* 32bit ARGB8888 double buffer with depth */
198 {
199 {sizeof(PIXELFORMATDESCRIPTOR), 1,
200 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
201 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
202 PFD_TYPE_RGBA,
203 32,
204 8, 0, 8, 8, 8, 16, 8, 24,
205 0, 0, 0, 0, 0,
206 24,
207 8,
208 0,
209 PFD_MAIN_PLANE,
210 0, 0, 0, 0}
211 ,
212 {FXMESA_COLORDEPTH, 32,
213 FXMESA_DOUBLEBUFFER,
214 FXMESA_ALPHA_SIZE, 8,
215 FXMESA_DEPTH_SIZE, 24,
216 FXMESA_STENCIL_SIZE, 8,
217 FXMESA_ACCUM_SIZE, 0,
218 FXMESA_NONE}
219 }
220 };
221
222 static fxMesaContext ctx = NULL;
223 static WNDPROC hWNDOldProc;
224 static int curPFD = 0;
225 static HDC hDC;
226 static HWND hWND;
227
228 static GLboolean haveDualHead;
229
230 /* For the in-window-rendering hack */
231
232 #ifndef GR_CONTROL_RESIZE
233 /* Apparently GR_CONTROL_RESIZE can be ignored. OK? */
234 #define GR_CONTROL_RESIZE -1
235 #endif
236
237 static GLboolean gdiWindowHack;
238 static void *dibSurfacePtr;
239 static BITMAPINFO *dibBMI;
240 static HBITMAP dibHBM;
241 static HWND dibWnd;
242
243 static int env_check (const char *var, int val)
244 {
245 const char *env = getenv(var);
246 return (env && (env[0] == val));
247 }
248
249 static LRESULT APIENTRY
250 __wglMonitor(HWND hwnd, UINT message, UINT wParam, LONG lParam)
251 {
252 long ret; /* Now gives the resized window at the end to hWNDOldProc */
253
254 if (ctx && hwnd == hWND) {
255 switch (message) {
256 case WM_PAINT:
257 case WM_MOVE:
258 break;
259 case WM_DISPLAYCHANGE:
260 case WM_SIZE:
261 #if 0
262 if (wParam != SIZE_MINIMIZED) {
263 static int moving = 0;
264 if (!moving) {
265 if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
266 moving = 1;
267 SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE | SWP_NOZORDER);
268 moving = 0;
269 if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
270 /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK); */
271 PostMessage(hWND, WM_CLOSE, 0, 0);
272 }
273 }
274 /* Do the clipping in the glide library */
275 grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight());
276 /* And let the new size set in the context */
277 fxMesaUpdateScreenSize(ctx);
278 }
279 }
280 #endif
281 break;
282 case WM_ACTIVATE:
283 break;
284 case WM_SHOWWINDOW:
285 break;
286 case WM_SYSKEYDOWN:
287 case WM_SYSCHAR:
288 break;
289 }
290 }
291
292 /* Finaly call the hWNDOldProc, which handles the resize witch the
293 now changed window sizes */
294 ret = CallWindowProc(hWNDOldProc, hwnd, message, wParam, lParam);
295
296 return (ret);
297 }
298
299 static void wgl_error (long error)
300 {
301 #define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT
302 SetLastError(0xC0000000 /* error severity */
303 |0x00070000 /* error facility (who we are) */
304 |error);
305 }
306
307 GLAPI BOOL GLAPIENTRY
308 wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
309 {
310 return (FALSE);
311 }
312
313 GLAPI HGLRC GLAPIENTRY
314 wglCreateContext(HDC hdc)
315 {
316 HWND hWnd;
317 WNDPROC oldProc;
318 int error;
319
320 if (ctx) {
321 SetLastError(0);
322 return (NULL);
323 }
324
325 if (!(hWnd = WindowFromDC(hdc))) {
326 SetLastError(0);
327 return (NULL);
328 }
329
330 if (curPFD == 0) {
331 wgl_error(WGL_INVALID_PIXELFORMAT);
332 return (NULL);
333 }
334
335 if ((oldProc = (WNDPROC) GetWindowLong(hWnd, GWL_WNDPROC)) != __wglMonitor) {
336 hWNDOldProc = oldProc;
337 SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __wglMonitor);
338 }
339
340 /* always log when debugging, or if user demands */
341 if (TDFX_DEBUG || env_check("MESA_FX_INFO", 'r')) {
342 freopen("MESA.LOG", "w", stderr);
343 }
344
345 {
346 RECT cliRect;
347 ShowWindow(hWnd, SW_SHOWNORMAL);
348 SetForegroundWindow(hWnd);
349 Sleep(100); /* a hack for win95 */
350 if (env_check("MESA_GLX_FX", 'w') && !(GetWindowLong (hWnd, GWL_STYLE) & WS_POPUP)) {
351 /* [dBorca] Hack alert: unfinished business! */
352 error = !(ctx = fxMesaCreateContext((GLuint) hWnd, GR_RESOLUTION_NONE, GR_REFRESH_NONE, pix[curPFD - 1].mesaAttr));
353 } else {
354 GetClientRect(hWnd, &cliRect);
355 error = !(ctx = fxMesaCreateBestContext((GLuint) hWnd, cliRect.right, cliRect.bottom, pix[curPFD - 1].mesaAttr));
356 }
357 }
358
359 /*if (getenv("SST_DUALHEAD"))
360 haveDualHead =
361 ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE : GL_FALSE);
362 else
363 haveDualHead = GL_FALSE;*/
364
365 if (error) {
366 SetLastError(0);
367 return (NULL);
368 }
369
370 hDC = hdc;
371 hWND = hWnd;
372
373 /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
374 wglMakeCurrent(hdc, (HGLRC) 1);
375
376 return ((HGLRC) 1);
377 }
378
379 GLAPI HGLRC GLAPIENTRY
380 wglCreateLayerContext(HDC hdc, int iLayerPlane)
381 {
382 SetLastError(0);
383 return (NULL);
384 }
385
386 GLAPI BOOL GLAPIENTRY
387 wglDeleteContext(HGLRC hglrc)
388 {
389 if (ctx && hglrc == (HGLRC) 1) {
390
391 fxMesaDestroyContext(ctx);
392
393 SetWindowLong(WindowFromDC(hDC), GWL_WNDPROC, (LONG) hWNDOldProc);
394
395 ctx = NULL;
396 hDC = 0;
397 return (TRUE);
398 }
399
400 SetLastError(0);
401
402 return (FALSE);
403 }
404
405 GLAPI HGLRC GLAPIENTRY
406 wglGetCurrentContext(VOID)
407 {
408 if (ctx)
409 return ((HGLRC) 1);
410
411 SetLastError(0);
412 return (NULL);
413 }
414
415 GLAPI HDC GLAPIENTRY
416 wglGetCurrentDC(VOID)
417 {
418 if (ctx)
419 return (hDC);
420
421 SetLastError(0);
422 return (NULL);
423 }
424
425 GLAPI BOOL GLAPIENTRY
426 wglSwapIntervalEXT (int interval)
427 {
428 if (ctx == NULL) {
429 return FALSE;
430 }
431 if (interval < 0) {
432 interval = 0;
433 } else if (interval > 3) {
434 interval = 3;
435 }
436 ctx->swapInterval = interval;
437 return TRUE;
438 }
439
440 GLAPI int GLAPIENTRY
441 wglGetSwapIntervalEXT (void)
442 {
443 return (ctx == NULL) ? -1 : ctx->swapInterval;
444 }
445
446 GLAPI BOOL GLAPIENTRY
447 wglGetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
448 {
449 /* gammaTable should be per-context */
450 memcpy(arrays, gammaTable, 3*256*sizeof(GLushort));
451 return TRUE;
452 }
453
454 GLAPI BOOL GLAPIENTRY
455 wglSetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
456 {
457 GLint i, tableSize, inc, index;
458 GLushort *red, *green, *blue;
459 FxU32 gammaTableR[256], gammaTableG[256], gammaTableB[256];
460
461 /* gammaTable should be per-context */
462 memcpy(gammaTable, arrays, 3*256*sizeof(GLushort));
463
464 tableSize = FX_grGetInteger(GR_GAMMA_TABLE_ENTRIES);
465 inc = 256 / tableSize;
466 red = (GLushort *)arrays;
467 green = (GLushort *)arrays + 256;
468 blue = (GLushort *)arrays + 512;
469 for (i = 0, index = 0; i < tableSize; i++, index += inc) {
470 gammaTableR[i] = red[index] >> 8;
471 gammaTableG[i] = green[index] >> 8;
472 gammaTableB[i] = blue[index] >> 8;
473 }
474
475 grLoadGammaTable(tableSize, gammaTableR, gammaTableG, gammaTableB);
476
477 return TRUE;
478 }
479
480 typedef void *HPBUFFERARB;
481
482 /* WGL_ARB_pixel_format */
483 GLAPI BOOL GLAPIENTRY
484 wglGetPixelFormatAttribivARB (HDC hdc,
485 int iPixelFormat,
486 int iLayerPlane,
487 UINT nAttributes,
488 const int *piAttributes,
489 int *piValues)
490 {
491 SetLastError(0);
492 return(FALSE);
493 }
494
495 GLAPI BOOL GLAPIENTRY
496 wglGetPixelFormatAttribfvARB (HDC hdc,
497 int iPixelFormat,
498 int iLayerPlane,
499 UINT nAttributes,
500 const int *piAttributes,
501 FLOAT *pfValues)
502 {
503 SetLastError(0);
504 return(FALSE);
505 }
506
507 GLAPI BOOL GLAPIENTRY
508 wglChoosePixelFormatARB (HDC hdc,
509 const int *piAttribIList,
510 const FLOAT *pfAttribFList,
511 UINT nMaxFormats,
512 int *piFormats,
513 UINT *nNumFormats)
514 {
515 SetLastError(0);
516 return(FALSE);
517 }
518
519 /* WGL_ARB_render_texture */
520 GLAPI BOOL GLAPIENTRY
521 wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
522 {
523 SetLastError(0);
524 return(FALSE);
525 }
526
527 GLAPI BOOL GLAPIENTRY
528 wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
529 {
530 SetLastError(0);
531 return(FALSE);
532 }
533
534 GLAPI BOOL GLAPIENTRY
535 wglSetPbufferAttribARB (HPBUFFERARB hPbuffer,
536 const int *piAttribList)
537 {
538 SetLastError(0);
539 return(FALSE);
540 }
541
542 /* WGL_ARB_pbuffer */
543 GLAPI HPBUFFERARB GLAPIENTRY
544 wglCreatePbufferARB (HDC hDC,
545 int iPixelFormat,
546 int iWidth,
547 int iHeight,
548 const int *piAttribList)
549 {
550 SetLastError(0);
551 return NULL;
552 }
553
554 GLAPI HDC GLAPIENTRY
555 wglGetPbufferDCARB (HPBUFFERARB hPbuffer)
556 {
557 SetLastError(0);
558 return NULL;
559 }
560
561 GLAPI int GLAPIENTRY
562 wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC)
563 {
564 SetLastError(0);
565 return -1;
566 }
567
568 GLAPI BOOL GLAPIENTRY
569 wglDestroyPbufferARB (HPBUFFERARB hPbuffer)
570 {
571 SetLastError(0);
572 return(FALSE);
573 }
574
575 GLAPI BOOL GLAPIENTRY
576 wglQueryPbufferARB (HPBUFFERARB hPbuffer,
577 int iAttribute,
578 int *piValue)
579 {
580 SetLastError(0);
581 return(FALSE);
582 }
583
584 GLAPI const char * GLAPIENTRY
585 wglGetExtensionsStringEXT (void)
586 {
587 return "WGL_3DFX_gamma_control "
588 "WGL_EXT_swap_control "
589 "WGL_EXT_extensions_string WGL_ARB_extensions_string"
590 /*WGL_ARB_pixel_format WGL_ARB_render_texture WGL_ARB_pbuffer*/;
591 }
592
593 GLAPI const char * GLAPIENTRY
594 wglGetExtensionsStringARB (HDC hdc)
595 {
596 return wglGetExtensionsStringEXT();
597 }
598
599 static struct {
600 const char *name;
601 PROC func;
602 } wgl_ext[] = {
603 {"wglGetExtensionsStringARB", wglGetExtensionsStringARB},
604 {"wglGetExtensionsStringEXT", wglGetExtensionsStringEXT},
605 {"wglSwapIntervalEXT", wglSwapIntervalEXT},
606 {"wglGetSwapIntervalEXT", wglGetSwapIntervalEXT},
607 {"wglGetDeviceGammaRamp3DFX", wglGetDeviceGammaRamp3DFX},
608 {"wglSetDeviceGammaRamp3DFX", wglSetDeviceGammaRamp3DFX},
609 /* WGL_ARB_pixel_format */
610 {"wglGetPixelFormatAttribivARB", wglGetPixelFormatAttribivARB},
611 {"wglGetPixelFormatAttribfvARB", wglGetPixelFormatAttribfvARB},
612 {"wglChoosePixelFormatARB", wglChoosePixelFormatARB},
613 /* WGL_ARB_render_texture */
614 {"wglBindTexImageARB", wglBindTexImageARB},
615 {"wglReleaseTexImageARB", wglReleaseTexImageARB},
616 {"wglSetPbufferAttribARB", wglSetPbufferAttribARB},
617 /* WGL_ARB_pbuffer */
618 {"wglCreatePbufferARB", wglCreatePbufferARB},
619 {"wglGetPbufferDCARB", wglGetPbufferDCARB},
620 {"wglReleasePbufferDCARB", wglReleasePbufferDCARB},
621 {"wglDestroyPbufferARB", wglDestroyPbufferARB},
622 {"wglQueryPbufferARB", wglQueryPbufferARB},
623 {NULL, NULL}
624 };
625
626 GLAPI PROC GLAPIENTRY
627 wglGetProcAddress(LPCSTR lpszProc)
628 {
629 int i;
630 PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
631
632 /* [dBorca] we can't do BlendColor */
633 if (p && strcmp(lpszProc, "glBlendColor") && strcmp(lpszProc, "glBlendColorEXT"))
634 return p;
635
636 for (i = 0; wgl_ext[i].name; i++) {
637 if (!strcmp(lpszProc, wgl_ext[i].name)) {
638 return wgl_ext[i].func;
639 }
640 }
641
642 SetLastError(0);
643 return (NULL);
644 }
645
646 GLAPI PROC GLAPIENTRY
647 wglGetDefaultProcAddress(LPCSTR lpszProc)
648 {
649 SetLastError(0);
650 return (NULL);
651 }
652
653 GLAPI BOOL GLAPIENTRY
654 wglMakeCurrent(HDC hdc, HGLRC hglrc)
655 {
656 if ((hdc == NULL) && (hglrc == NULL))
657 return (TRUE);
658
659 if (!ctx || hglrc != (HGLRC) 1 || WindowFromDC(hdc) != hWND) {
660 SetLastError(0);
661 return (FALSE);
662 }
663
664 hDC = hdc;
665
666 fxMesaMakeCurrent(ctx);
667
668 return (TRUE);
669 }
670
671 GLAPI BOOL GLAPIENTRY
672 wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
673 {
674 if (!ctx || hglrc1 != (HGLRC) 1 || hglrc1 != hglrc2) {
675 SetLastError(0);
676 return (FALSE);
677 }
678
679 return (TRUE);
680 }
681
682 static BOOL
683 wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, DWORD numChars,
684 DWORD listBase)
685 {
686 TEXTMETRIC metric;
687 BITMAPINFO *dibInfo;
688 HDC bitDevice;
689 COLORREF tempColor;
690 int i;
691
692 GetTextMetrics(fontDevice, &metric);
693
694 dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
695 dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
696 dibInfo->bmiHeader.biPlanes = 1;
697 dibInfo->bmiHeader.biBitCount = 1;
698 dibInfo->bmiHeader.biCompression = BI_RGB;
699
700 bitDevice = CreateCompatibleDC(fontDevice);
701
702 /* Swap fore and back colors so the bitmap has the right polarity */
703 tempColor = GetBkColor(bitDevice);
704 SetBkColor(bitDevice, GetTextColor(bitDevice));
705 SetTextColor(bitDevice, tempColor);
706
707 /* Place chars based on base line */
708 SetTextAlign(bitDevice, TA_BASELINE);
709
710 for (i = 0; i < (int)numChars; i++) {
711 SIZE size;
712 char curChar;
713 int charWidth, charHeight, bmapWidth, bmapHeight, numBytes, res;
714 HBITMAP bitObject;
715 HGDIOBJ origBmap;
716 unsigned char *bmap;
717
718 curChar = (char)(i + firstChar); /* [koolsmoky] explicit cast */
719
720 /* Find how high/wide this character is */
721 GetTextExtentPoint32(bitDevice, &curChar, 1, &size);
722
723 /* Create the output bitmap */
724 charWidth = size.cx;
725 charHeight = size.cy;
726 bmapWidth = ((charWidth + 31) / 32) * 32; /* Round up to the next multiple of 32 bits */
727 bmapHeight = charHeight;
728 bitObject = CreateCompatibleBitmap(bitDevice, bmapWidth, bmapHeight);
729 /*VERIFY(bitObject);*/
730
731 /* Assign the output bitmap to the device */
732 origBmap = SelectObject(bitDevice, bitObject);
733
734 PatBlt(bitDevice, 0, 0, bmapWidth, bmapHeight, BLACKNESS);
735
736 /* Use our source font on the device */
737 SelectObject(bitDevice, GetCurrentObject(fontDevice, OBJ_FONT));
738
739 /* Draw the character */
740 TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1);
741
742 /* Unselect our bmap object */
743 SelectObject(bitDevice, origBmap);
744
745 /* Convert the display dependant representation to a 1 bit deep DIB */
746 numBytes = (bmapWidth * bmapHeight) / 8;
747 bmap = MALLOC(numBytes);
748 dibInfo->bmiHeader.biWidth = bmapWidth;
749 dibInfo->bmiHeader.biHeight = bmapHeight;
750 res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
751 dibInfo, DIB_RGB_COLORS);
752
753 /* Create the GL object */
754 glNewList(i + listBase, GL_COMPILE);
755 glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
756 charWidth, 0.0, bmap);
757 glEndList();
758 /* CheckGL(); */
759
760 /* Destroy the bmap object */
761 DeleteObject(bitObject);
762
763 /* Deallocate the bitmap data */
764 FREE(bmap);
765 }
766
767 /* Destroy the DC */
768 DeleteDC(bitDevice);
769
770 FREE(dibInfo);
771
772 return TRUE;
773 }
774
775 GLAPI BOOL GLAPIENTRY
776 wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase)
777 {
778 return (FALSE);
779 }
780
781 GLAPI BOOL GLAPIENTRY
782 wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count,
783 DWORD listBase, FLOAT deviation,
784 FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
785 {
786 SetLastError(0);
787 return (FALSE);
788 }
789
790 GLAPI BOOL GLAPIENTRY
791 wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count,
792 DWORD listBase, FLOAT deviation,
793 FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
794 {
795 SetLastError(0);
796 return (FALSE);
797 }
798
799
800 GLAPI BOOL GLAPIENTRY
801 wglSwapLayerBuffers(HDC hdc, UINT fuPlanes)
802 {
803 if (ctx && WindowFromDC(hdc) == hWND) {
804 fxMesaSwapBuffers();
805
806 return (TRUE);
807 }
808
809 SetLastError(0);
810 return (FALSE);
811 }
812
813 static int pfd_tablen (void)
814 {
815 /* we should take an envvar for `fxMesaSelectCurrentBoard' */
816 return (fxMesaSelectCurrentBoard(0) < GR_SSTTYPE_Voodoo4)
817 ? 2 /* only 16bit entries */
818 : sizeof(pix) / sizeof(pix[0]); /* full table */
819 }
820
821 GLAPI int GLAPIENTRY
822 wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR * ppfd)
823 {
824 int i, best = -1, qt_valid_pix;
825 PIXELFORMATDESCRIPTOR pfd = *ppfd;
826
827 qt_valid_pix = pfd_tablen();
828
829 #if 1 || QUAKE2 || GORE
830 /* QUAKE2: 24+32 */
831 /* GORE : 24+16 */
832 if ((pfd.cColorBits == 24) || (pfd.cColorBits == 32)) {
833 /* the first 2 entries are 16bit */
834 pfd.cColorBits = (qt_valid_pix > 2) ? 32 : 16;
835 }
836 if (pfd.cColorBits == 32) {
837 pfd.cDepthBits = 24;
838 } else if (pfd.cColorBits == 16) {
839 pfd.cDepthBits = 16;
840 }
841 #endif
842
843 if (pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR) || pfd.nVersion != 1) {
844 SetLastError(0);
845 return (0);
846 }
847
848 for (i = 0; i < qt_valid_pix; i++) {
849 if (pfd.cColorBits > 0 && pix[i].pfd.cColorBits != pfd.cColorBits)
850 continue;
851
852 if ((pfd.dwFlags & PFD_DRAW_TO_WINDOW)
853 && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue;
854 if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP)
855 && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) continue;
856 if ((pfd.dwFlags & PFD_SUPPORT_GDI)
857 && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI)) continue;
858 if ((pfd.dwFlags & PFD_SUPPORT_OPENGL)
859 && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue;
860 if (!(pfd.dwFlags & PFD_DOUBLEBUFFER_DONTCARE)
861 && ((pfd.dwFlags & PFD_DOUBLEBUFFER) !=
862 (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
863 if (!(pfd.dwFlags & PFD_STEREO_DONTCARE)
864 && ((pfd.dwFlags & PFD_STEREO) !=
865 (pix[i].pfd.dwFlags & PFD_STEREO))) continue;
866
867 if (pfd.cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
868 continue; /* need depth buffer */
869
870 if (pfd.cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
871 continue; /* need alpha buffer */
872
873 #if 0 /* [dBorca] regression bug? */
874 if (pfd.cStencilBits > 0 && pix[i].pfd.cStencilBits == 0)
875 continue; /* need stencil buffer */
876 #endif
877
878 if (pfd.iPixelType == pix[i].pfd.iPixelType) {
879 best = i + 1;
880 break;
881 }
882 }
883
884 if (best == -1) {
885 FILE *err = fopen("MESA.LOG", "w");
886 if (err != NULL) {
887 fprintf(err, "wglChoosePixelFormat failed\n");
888 fprintf(err, "\tnSize = %d\n", ppfd->nSize);
889 fprintf(err, "\tnVersion = %d\n", ppfd->nVersion);
890 fprintf(err, "\tdwFlags = %d\n", ppfd->dwFlags);
891 fprintf(err, "\tiPixelType = %d\n", ppfd->iPixelType);
892 fprintf(err, "\tcColorBits = %d\n", ppfd->cColorBits);
893 fprintf(err, "\tcRedBits = %d\n", ppfd->cRedBits);
894 fprintf(err, "\tcRedShift = %d\n", ppfd->cRedShift);
895 fprintf(err, "\tcGreenBits = %d\n", ppfd->cGreenBits);
896 fprintf(err, "\tcGreenShift = %d\n", ppfd->cGreenShift);
897 fprintf(err, "\tcBlueBits = %d\n", ppfd->cBlueBits);
898 fprintf(err, "\tcBlueShift = %d\n", ppfd->cBlueShift);
899 fprintf(err, "\tcAlphaBits = %d\n", ppfd->cAlphaBits);
900 fprintf(err, "\tcAlphaShift = %d\n", ppfd->cAlphaShift);
901 fprintf(err, "\tcAccumBits = %d\n", ppfd->cAccumBits);
902 fprintf(err, "\tcAccumRedBits = %d\n", ppfd->cAccumRedBits);
903 fprintf(err, "\tcAccumGreenBits = %d\n", ppfd->cAccumGreenBits);
904 fprintf(err, "\tcAccumBlueBits = %d\n", ppfd->cAccumBlueBits);
905 fprintf(err, "\tcAccumAlphaBits = %d\n", ppfd->cAccumAlphaBits);
906 fprintf(err, "\tcDepthBits = %d\n", ppfd->cDepthBits);
907 fprintf(err, "\tcStencilBits = %d\n", ppfd->cStencilBits);
908 fprintf(err, "\tcAuxBuffers = %d\n", ppfd->cAuxBuffers);
909 fprintf(err, "\tiLayerType = %d\n", ppfd->iLayerType);
910 fprintf(err, "\tbReserved = %d\n", ppfd->bReserved);
911 fprintf(err, "\tdwLayerMask = %d\n", ppfd->dwLayerMask);
912 fprintf(err, "\tdwVisibleMask = %d\n", ppfd->dwVisibleMask);
913 fprintf(err, "\tdwDamageMask = %d\n", ppfd->dwDamageMask);
914 fclose(err);
915 }
916
917 SetLastError(0);
918 return (0);
919 }
920
921 return (best);
922 }
923
924 GLAPI int GLAPIENTRY
925 ChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR * ppfd)
926 {
927
928 return wglChoosePixelFormat(hdc, ppfd);
929 }
930
931 GLAPI int GLAPIENTRY
932 wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes,
933 LPPIXELFORMATDESCRIPTOR ppfd)
934 {
935 int qt_valid_pix;
936
937 qt_valid_pix = pfd_tablen();
938
939 if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
940 ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
941 SetLastError(0);
942 return (qt_valid_pix);
943 }
944
945 if (nBytes != 0)
946 *ppfd = pix[iPixelFormat - 1].pfd;
947
948 return (qt_valid_pix);
949 }
950
951 GLAPI int GLAPIENTRY
952 DescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes,
953 LPPIXELFORMATDESCRIPTOR ppfd)
954 {
955 return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
956 }
957
958 GLAPI int GLAPIENTRY
959 wglGetPixelFormat(HDC hdc)
960 {
961 if (curPFD == 0) {
962 SetLastError(0);
963 return (0);
964 }
965
966 return (curPFD);
967 }
968
969 GLAPI int GLAPIENTRY
970 GetPixelFormat(HDC hdc)
971 {
972 return wglGetPixelFormat(hdc);
973 }
974
975 GLAPI BOOL GLAPIENTRY
976 wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR * ppfd)
977 {
978 int qt_valid_pix;
979
980 qt_valid_pix = pfd_tablen();
981
982 if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix) {
983 if (ppfd == NULL) {
984 PIXELFORMATDESCRIPTOR my_pfd;
985 if (!wglDescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &my_pfd)) {
986 SetLastError(0);
987 return (FALSE);
988 }
989 } else if (ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
990 SetLastError(0);
991 return (FALSE);
992 }
993 }
994 curPFD = iPixelFormat;
995
996 return (TRUE);
997 }
998
999 GLAPI BOOL GLAPIENTRY
1000 wglSwapBuffers(HDC hdc)
1001 {
1002 if (!ctx) {
1003 SetLastError(0);
1004 return (FALSE);
1005 }
1006
1007 fxMesaSwapBuffers();
1008
1009 return (TRUE);
1010 }
1011
1012 GLAPI BOOL GLAPIENTRY
1013 SetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR * ppfd)
1014 {
1015 return wglSetPixelFormat(hdc, iPixelFormat, ppfd);
1016 }
1017
1018 GLAPI BOOL GLAPIENTRY
1019 SwapBuffers(HDC hdc)
1020 {
1021 return wglSwapBuffers(hdc);
1022 }
1023
1024 static FIXED FixedFromDouble(double d)
1025 {
1026 long l = (long) (d * 65536L);
1027 return *(FIXED *)&l;
1028 }
1029
1030 /*
1031 ** This was yanked from windows/gdi/wgl.c
1032 */
1033 GLAPI BOOL GLAPIENTRY
1034 wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase)
1035 {
1036 int i;
1037 GLuint font_list;
1038 DWORD size;
1039 GLYPHMETRICS gm;
1040 HANDLE hBits;
1041 LPSTR lpBits;
1042 MAT2 mat;
1043 int success = TRUE;
1044
1045 if (first<0)
1046 return FALSE;
1047 if (count<0)
1048 return FALSE;
1049 if (listBase<0)
1050 return FALSE;
1051
1052 font_list = listBase;
1053
1054 mat.eM11 = FixedFromDouble(1);
1055 mat.eM12 = FixedFromDouble(0);
1056 mat.eM21 = FixedFromDouble(0);
1057 mat.eM22 = FixedFromDouble(-1);
1058
1059 memset(&gm,0,sizeof(gm));
1060
1061 /*
1062 ** If we can't get the glyph outline, it may be because this is a fixed
1063 ** font. Try processing it that way.
1064 */
1065 if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat)
1066 == GDI_ERROR )
1067 {
1068 return wglUseFontBitmaps_FX( hdc, first, count, listBase );
1069 }
1070
1071 /*
1072 ** Otherwise process all desired characters.
1073 */
1074 for (i = 0; i < count; i++)
1075 {
1076 DWORD err;
1077
1078 glNewList( font_list+i, GL_COMPILE );
1079
1080 /* allocate space for the bitmap/outline */
1081 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
1082 if (size == GDI_ERROR)
1083 {
1084 glEndList( );
1085 err = GetLastError();
1086 success = FALSE;
1087 continue;
1088 }
1089
1090 hBits = GlobalAlloc(GHND, size+1);
1091 lpBits = GlobalLock(hBits);
1092
1093 err = GetGlyphOutline(hdc, /* handle to device context */
1094 first + i, /* character to query */
1095 GGO_BITMAP, /* format of data to return */
1096 &gm, /* pointer to structure for metrics*/
1097 size, /* size of buffer for data */
1098 lpBits, /* pointer to buffer for data */
1099 &mat /* pointer to transformation */
1100 /* matrix structure */
1101 );
1102
1103 if (err == GDI_ERROR)
1104 {
1105 GlobalUnlock(hBits);
1106 GlobalFree(hBits);
1107
1108 glEndList( );
1109 err = GetLastError();
1110 success = FALSE;
1111 continue;
1112 }
1113
1114 glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
1115 -gm.gmptGlyphOrigin.x,
1116 gm.gmptGlyphOrigin.y,
1117 gm.gmCellIncX,gm.gmCellIncY,
1118 (const GLubyte * )lpBits);
1119
1120 GlobalUnlock(hBits);
1121 GlobalFree(hBits);
1122
1123 glEndList( );
1124 }
1125
1126 return success;
1127 }
1128
1129 GLAPI BOOL GLAPIENTRY
1130 wglDescribeLayerPlane(HDC hdc, int iPixelFormat, int iLayerPlane,
1131 UINT nBytes, LPLAYERPLANEDESCRIPTOR ppfd)
1132 {
1133 SetLastError(0);
1134 return (FALSE);
1135 }
1136
1137 GLAPI int GLAPIENTRY
1138 wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart,
1139 int cEntries, COLORREF *pcr)
1140 {
1141 SetLastError(0);
1142 return (FALSE);
1143 }
1144
1145 GLAPI BOOL GLAPIENTRY
1146 wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)
1147 {
1148 SetLastError(0);
1149 return(FALSE);
1150 }
1151
1152 GLAPI int GLAPIENTRY
1153 wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane, int iStart,
1154 int cEntries, CONST COLORREF *pcr)
1155 {
1156 SetLastError(0);
1157 return(FALSE);
1158 }
1159
1160 #if (_MSC_VER >= 1200)
1161 #pragma warning( pop )
1162 #endif
1163
1164 #endif /* FX */