intel: fix i8xx vbo enable bit
[mesa.git] / src / mesa / drivers / windows / fx / 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 #endif
43
44 #include <windows.h>
45 #define GL_GLEXT_PROTOTYPES
46 #include "GL/gl.h"
47 #include "GL/glext.h"
48
49 #ifdef __cplusplus
50 }
51 #endif
52
53 #include "GL/fxmesa.h"
54 #include "glheader.h"
55 #include "glapi.h"
56 #include "imports.h"
57 #include "../../glide/fxdrv.h"
58
59 #define MAX_MESA_ATTRS 20
60
61 #if (_MSC_VER >= 1200)
62 #pragma warning( push )
63 #pragma warning( disable : 4273 )
64 #endif
65
66 struct __extensions__ {
67 PROC proc;
68 char *name;
69 };
70
71 struct __pixelformat__ {
72 PIXELFORMATDESCRIPTOR pfd;
73 GLint mesaAttr[MAX_MESA_ATTRS];
74 };
75
76 WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
77 static GLushort gammaTable[3 * 256];
78
79 struct __pixelformat__ pix[] = {
80 /* 16bit RGB565 single buffer with depth */
81 {
82 {sizeof(PIXELFORMATDESCRIPTOR), 1,
83 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
84 PFD_TYPE_RGBA,
85 16,
86 5, 0, 6, 5, 5, 11, 0, 0,
87 0, 0, 0, 0, 0,
88 16,
89 0,
90 0,
91 PFD_MAIN_PLANE,
92 0, 0, 0, 0}
93 ,
94 {FXMESA_COLORDEPTH, 16,
95 FXMESA_ALPHA_SIZE, 0,
96 FXMESA_DEPTH_SIZE, 16,
97 FXMESA_STENCIL_SIZE, 0,
98 FXMESA_ACCUM_SIZE, 0,
99 FXMESA_NONE}
100 }
101 ,
102 /* 16bit RGB565 double buffer with depth */
103 {
104 {sizeof(PIXELFORMATDESCRIPTOR), 1,
105 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
106 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
107 PFD_TYPE_RGBA,
108 16,
109 5, 0, 6, 5, 5, 11, 0, 0,
110 0, 0, 0, 0, 0,
111 16,
112 0,
113 0,
114 PFD_MAIN_PLANE,
115 0, 0, 0, 0}
116 ,
117 {FXMESA_COLORDEPTH, 16,
118 FXMESA_DOUBLEBUFFER,
119 FXMESA_ALPHA_SIZE, 0,
120 FXMESA_DEPTH_SIZE, 16,
121 FXMESA_STENCIL_SIZE, 0,
122 FXMESA_ACCUM_SIZE, 0,
123 FXMESA_NONE}
124 }
125 ,
126 /* 16bit ARGB1555 single buffer with depth */
127 {
128 {sizeof(PIXELFORMATDESCRIPTOR), 1,
129 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
130 PFD_TYPE_RGBA,
131 16,
132 5, 0, 5, 5, 5, 10, 1, 15,
133 0, 0, 0, 0, 0,
134 16,
135 0,
136 0,
137 PFD_MAIN_PLANE,
138 0, 0, 0, 0}
139 ,
140 {FXMESA_COLORDEPTH, 15,
141 FXMESA_ALPHA_SIZE, 1,
142 FXMESA_DEPTH_SIZE, 16,
143 FXMESA_STENCIL_SIZE, 0,
144 FXMESA_ACCUM_SIZE, 0,
145 FXMESA_NONE}
146 }
147 ,
148 /* 16bit ARGB1555 double buffer with depth */
149 {
150 {sizeof(PIXELFORMATDESCRIPTOR), 1,
151 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
152 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
153 PFD_TYPE_RGBA,
154 16,
155 5, 0, 5, 5, 5, 10, 1, 15,
156 0, 0, 0, 0, 0,
157 16,
158 0,
159 0,
160 PFD_MAIN_PLANE,
161 0, 0, 0, 0}
162 ,
163 {FXMESA_COLORDEPTH, 15,
164 FXMESA_DOUBLEBUFFER,
165 FXMESA_ALPHA_SIZE, 1,
166 FXMESA_DEPTH_SIZE, 16,
167 FXMESA_STENCIL_SIZE, 0,
168 FXMESA_ACCUM_SIZE, 0,
169 FXMESA_NONE}
170 }
171 ,
172 /* 32bit ARGB8888 single buffer with depth */
173 {
174 {sizeof(PIXELFORMATDESCRIPTOR), 1,
175 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
176 PFD_TYPE_RGBA,
177 32,
178 8, 0, 8, 8, 8, 16, 8, 24,
179 0, 0, 0, 0, 0,
180 24,
181 8,
182 0,
183 PFD_MAIN_PLANE,
184 0, 0, 0, 0}
185 ,
186 {FXMESA_COLORDEPTH, 32,
187 FXMESA_ALPHA_SIZE, 8,
188 FXMESA_DEPTH_SIZE, 24,
189 FXMESA_STENCIL_SIZE, 8,
190 FXMESA_ACCUM_SIZE, 0,
191 FXMESA_NONE}
192 }
193 ,
194 /* 32bit ARGB8888 double buffer with depth */
195 {
196 {sizeof(PIXELFORMATDESCRIPTOR), 1,
197 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
198 PFD_DOUBLEBUFFER | PFD_SWAP_COPY,
199 PFD_TYPE_RGBA,
200 32,
201 8, 0, 8, 8, 8, 16, 8, 24,
202 0, 0, 0, 0, 0,
203 24,
204 8,
205 0,
206 PFD_MAIN_PLANE,
207 0, 0, 0, 0}
208 ,
209 {FXMESA_COLORDEPTH, 32,
210 FXMESA_DOUBLEBUFFER,
211 FXMESA_ALPHA_SIZE, 8,
212 FXMESA_DEPTH_SIZE, 24,
213 FXMESA_STENCIL_SIZE, 8,
214 FXMESA_ACCUM_SIZE, 0,
215 FXMESA_NONE}
216 }
217 };
218
219 static fxMesaContext ctx = NULL;
220 static WNDPROC hWNDOldProc;
221 static int curPFD = 0;
222 static HDC hDC;
223 static HWND hWND;
224
225 static GLboolean haveDualHead;
226
227 /* For the in-window-rendering hack */
228
229 #ifndef GR_CONTROL_RESIZE
230 /* Apparently GR_CONTROL_RESIZE can be ignored. OK? */
231 #define GR_CONTROL_RESIZE -1
232 #endif
233
234 static GLboolean gdiWindowHack;
235 static void *dibSurfacePtr;
236 static BITMAPINFO *dibBMI;
237 static HBITMAP dibHBM;
238 static HWND dibWnd;
239
240 static int
241 env_check (const char *var, int val)
242 {
243 const char *env = getenv(var);
244 return (env && (env[0] == val));
245 }
246
247 static LRESULT APIENTRY
248 __wglMonitor (HWND hwnd, UINT message, UINT wParam, LONG lParam)
249 {
250 long ret; /* Now gives the resized window at the end to hWNDOldProc */
251
252 if (ctx && hwnd == hWND) {
253 switch (message) {
254 case WM_PAINT:
255 case WM_MOVE:
256 break;
257 case WM_DISPLAYCHANGE:
258 case WM_SIZE:
259 #if 0
260 if (wParam != SIZE_MINIMIZED) {
261 static int moving = 0;
262 if (!moving) {
263 if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
264 moving = 1;
265 SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE | SWP_NOZORDER);
266 moving = 0;
267 if (!FX_grSstControl(GR_CONTROL_RESIZE)) {
268 /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
269 PostMessage(hWND, WM_CLOSE, 0, 0);
270 }
271 }
272 /* Do the clipping in the glide library */
273 grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight());
274 /* And let the new size set in the context */
275 fxMesaUpdateScreenSize(ctx);
276 }
277 }
278 #endif
279 break;
280 case WM_ACTIVATE:
281 break;
282 case WM_SHOWWINDOW:
283 break;
284 case WM_SYSKEYDOWN:
285 case WM_SYSCHAR:
286 break;
287 }
288 }
289
290 /* Finally call the hWNDOldProc, which handles the resize with the
291 * now changed window sizes */
292 ret = CallWindowProc(hWNDOldProc, hwnd, message, wParam, lParam);
293
294 return ret;
295 }
296
297 static void
298 wgl_error (long error)
299 {
300 #define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT
301 SetLastError(0xC0000000 /* error severity */
302 |0x00070000 /* error facility (who we are) */
303 |error);
304 }
305
306 GLAPI BOOL GLAPIENTRY
307 wglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
308 {
309 return FALSE;
310 }
311
312 GLAPI HGLRC GLAPIENTRY
313 wglCreateContext (HDC hdc)
314 {
315 HWND hWnd;
316 WNDPROC oldProc;
317 int error;
318
319 if (ctx) {
320 SetLastError(0);
321 return NULL;
322 }
323
324 if (!(hWnd = WindowFromDC(hdc))) {
325 SetLastError(0);
326 return NULL;
327 }
328
329 if (curPFD == 0) {
330 wgl_error(WGL_INVALID_PIXELFORMAT);
331 return NULL;
332 }
333
334 if ((oldProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC)) != __wglMonitor) {
335 hWNDOldProc = oldProc;
336 SetWindowLong(hWnd, GWL_WNDPROC, (LONG)__wglMonitor);
337 }
338
339 /* always log when debugging, or if user demands */
340 if (TDFX_DEBUG || env_check("MESA_FX_INFO", 'r')) {
341 freopen("MESA.LOG", "w", stderr);
342 }
343
344 {
345 RECT cliRect;
346 ShowWindow(hWnd, SW_SHOWNORMAL);
347 SetForegroundWindow(hWnd);
348 Sleep(100); /* a hack for win95 */
349 if (env_check("MESA_GLX_FX", 'w') && !(GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP)) {
350 /* XXX todo - windowed modes */
351 error = !(ctx = fxMesaCreateContext((GLuint) hWnd, GR_RESOLUTION_NONE, GR_REFRESH_NONE, pix[curPFD - 1].mesaAttr));
352 } else {
353 GetClientRect(hWnd, &cliRect);
354 error = !(ctx = fxMesaCreateBestContext((GLuint) hWnd, cliRect.right, cliRect.bottom, pix[curPFD - 1].mesaAttr));
355 }
356 }
357
358 /*if (getenv("SST_DUALHEAD"))
359 haveDualHead =
360 ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE : GL_FALSE);
361 else
362 haveDualHead = GL_FALSE;*/
363
364 if (error) {
365 SetLastError(0);
366 return NULL;
367 }
368
369 hDC = hdc;
370 hWND = hWnd;
371
372 /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
373 wglMakeCurrent(hdc, (HGLRC)1);
374
375 return (HGLRC)1;
376 }
377
378 GLAPI HGLRC GLAPIENTRY
379 wglCreateLayerContext (HDC hdc, int iLayerPlane)
380 {
381 SetLastError(0);
382 return NULL;
383 }
384
385 GLAPI BOOL GLAPIENTRY
386 wglDeleteContext (HGLRC hglrc)
387 {
388 if (ctx && hglrc == (HGLRC)1) {
389
390 fxMesaDestroyContext(ctx);
391
392 SetWindowLong(WindowFromDC(hDC), GWL_WNDPROC, (LONG) hWNDOldProc);
393
394 ctx = NULL;
395 hDC = 0;
396 return TRUE;
397 }
398
399 SetLastError(0);
400
401 return FALSE;
402 }
403
404 GLAPI HGLRC GLAPIENTRY
405 wglGetCurrentContext (VOID)
406 {
407 if (ctx)
408 return (HGLRC)1;
409
410 SetLastError(0);
411 return NULL;
412 }
413
414 GLAPI HDC GLAPIENTRY
415 wglGetCurrentDC (VOID)
416 {
417 if (ctx)
418 return hDC;
419
420 SetLastError(0);
421 return NULL;
422 }
423
424 GLAPI BOOL GLAPIENTRY
425 wglSwapIntervalEXT (int interval)
426 {
427 if (ctx == NULL) {
428 return FALSE;
429 }
430 if (interval < 0) {
431 interval = 0;
432 } else if (interval > 3) {
433 interval = 3;
434 }
435 ctx->swapInterval = interval;
436 return TRUE;
437 }
438
439 GLAPI int GLAPIENTRY
440 wglGetSwapIntervalEXT (void)
441 {
442 return (ctx == NULL) ? -1 : ctx->swapInterval;
443 }
444
445 GLAPI BOOL GLAPIENTRY
446 wglGetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
447 {
448 /* gammaTable should be per-context */
449 memcpy(arrays, gammaTable, 3 * 256 * sizeof(GLushort));
450 return TRUE;
451 }
452
453 GLAPI BOOL GLAPIENTRY
454 wglSetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays)
455 {
456 GLint i, tableSize, inc, index;
457 GLushort *red, *green, *blue;
458 FxU32 gammaTableR[256], gammaTableG[256], gammaTableB[256];
459
460 /* gammaTable should be per-context */
461 memcpy(gammaTable, arrays, 3 * 256 * sizeof(GLushort));
462
463 tableSize = FX_grGetInteger(GR_GAMMA_TABLE_ENTRIES);
464 inc = 256 / tableSize;
465 red = (GLushort *)arrays;
466 green = (GLushort *)arrays + 256;
467 blue = (GLushort *)arrays + 512;
468 for (i = 0, index = 0; i < tableSize; i++, index += inc) {
469 gammaTableR[i] = red[index] >> 8;
470 gammaTableG[i] = green[index] >> 8;
471 gammaTableB[i] = blue[index] >> 8;
472 }
473
474 grLoadGammaTable(tableSize, gammaTableR, gammaTableG, gammaTableB);
475
476 return TRUE;
477 }
478
479 typedef void *HPBUFFERARB;
480
481 /* WGL_ARB_pixel_format */
482 GLAPI BOOL GLAPIENTRY
483 wglGetPixelFormatAttribivARB (HDC hdc,
484 int iPixelFormat,
485 int iLayerPlane,
486 UINT nAttributes,
487 const int *piAttributes,
488 int *piValues)
489 {
490 SetLastError(0);
491 return FALSE;
492 }
493
494 GLAPI BOOL GLAPIENTRY
495 wglGetPixelFormatAttribfvARB (HDC hdc,
496 int iPixelFormat,
497 int iLayerPlane,
498 UINT nAttributes,
499 const int *piAttributes,
500 FLOAT *pfValues)
501 {
502 SetLastError(0);
503 return FALSE;
504 }
505
506 GLAPI BOOL GLAPIENTRY
507 wglChoosePixelFormatARB (HDC hdc,
508 const int *piAttribIList,
509 const FLOAT *pfAttribFList,
510 UINT nMaxFormats,
511 int *piFormats,
512 UINT *nNumFormats)
513 {
514 SetLastError(0);
515 return FALSE;
516 }
517
518 /* WGL_ARB_render_texture */
519 GLAPI BOOL GLAPIENTRY
520 wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
521 {
522 SetLastError(0);
523 return FALSE;
524 }
525
526 GLAPI BOOL GLAPIENTRY
527 wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer)
528 {
529 SetLastError(0);
530 return FALSE;
531 }
532
533 GLAPI BOOL GLAPIENTRY
534 wglSetPbufferAttribARB (HPBUFFERARB hPbuffer,
535 const int *piAttribList)
536 {
537 SetLastError(0);
538 return FALSE;
539 }
540
541 /* WGL_ARB_pbuffer */
542 GLAPI HPBUFFERARB GLAPIENTRY
543 wglCreatePbufferARB (HDC hDC,
544 int iPixelFormat,
545 int iWidth,
546 int iHeight,
547 const int *piAttribList)
548 {
549 SetLastError(0);
550 return NULL;
551 }
552
553 GLAPI HDC GLAPIENTRY
554 wglGetPbufferDCARB (HPBUFFERARB hPbuffer)
555 {
556 SetLastError(0);
557 return NULL;
558 }
559
560 GLAPI int GLAPIENTRY
561 wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC)
562 {
563 SetLastError(0);
564 return -1;
565 }
566
567 GLAPI BOOL GLAPIENTRY
568 wglDestroyPbufferARB (HPBUFFERARB hPbuffer)
569 {
570 SetLastError(0);
571 return FALSE;
572 }
573
574 GLAPI BOOL GLAPIENTRY
575 wglQueryPbufferARB (HPBUFFERARB hPbuffer,
576 int iAttribute,
577 int *piValue)
578 {
579 SetLastError(0);
580 return FALSE;
581 }
582
583 GLAPI const char * GLAPIENTRY
584 wglGetExtensionsStringEXT (void)
585 {
586 return "WGL_3DFX_gamma_control "
587 "WGL_EXT_swap_control "
588 "WGL_EXT_extensions_string WGL_ARB_extensions_string"
589 /*WGL_ARB_pixel_format WGL_ARB_render_texture WGL_ARB_pbuffer*/;
590 }
591
592 GLAPI const char * GLAPIENTRY
593 wglGetExtensionsStringARB (HDC hdc)
594 {
595 return wglGetExtensionsStringEXT();
596 }
597
598 static struct {
599 const char *name;
600 PROC func;
601 } wgl_ext[] = {
602 {"wglGetExtensionsStringARB", (PROC)wglGetExtensionsStringARB},
603 {"wglGetExtensionsStringEXT", (PROC)wglGetExtensionsStringEXT},
604 {"wglSwapIntervalEXT", (PROC)wglSwapIntervalEXT},
605 {"wglGetSwapIntervalEXT", (PROC)wglGetSwapIntervalEXT},
606 {"wglGetDeviceGammaRamp3DFX", (PROC)wglGetDeviceGammaRamp3DFX},
607 {"wglSetDeviceGammaRamp3DFX", (PROC)wglSetDeviceGammaRamp3DFX},
608 /* WGL_ARB_pixel_format */
609 {"wglGetPixelFormatAttribivARB", (PROC)wglGetPixelFormatAttribivARB},
610 {"wglGetPixelFormatAttribfvARB", (PROC)wglGetPixelFormatAttribfvARB},
611 {"wglChoosePixelFormatARB", (PROC)wglChoosePixelFormatARB},
612 /* WGL_ARB_render_texture */
613 {"wglBindTexImageARB", (PROC)wglBindTexImageARB},
614 {"wglReleaseTexImageARB", (PROC)wglReleaseTexImageARB},
615 {"wglSetPbufferAttribARB", (PROC)wglSetPbufferAttribARB},
616 /* WGL_ARB_pbuffer */
617 {"wglCreatePbufferARB", (PROC)wglCreatePbufferARB},
618 {"wglGetPbufferDCARB", (PROC)wglGetPbufferDCARB},
619 {"wglReleasePbufferDCARB", (PROC)wglReleasePbufferDCARB},
620 {"wglDestroyPbufferARB", (PROC)wglDestroyPbufferARB},
621 {"wglQueryPbufferARB", (PROC)wglQueryPbufferARB},
622 {NULL, NULL}
623 };
624
625 GLAPI PROC GLAPIENTRY
626 wglGetProcAddress (LPCSTR lpszProc)
627 {
628 int i;
629 PROC p = (PROC)_glapi_get_proc_address((const char *)lpszProc);
630
631 /* we can't BlendColor. work around buggy applications */
632 if (p && strcmp(lpszProc, "glBlendColor")
633 && 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
814 pfd_tablen (void)
815 {
816 /* we should take an envvar for `fxMesaSelectCurrentBoard' */
817 return (fxMesaSelectCurrentBoard(0) < GR_SSTTYPE_Voodoo4)
818 ? 2 /* only 16bit entries */
819 : sizeof(pix) / sizeof(pix[0]); /* full table */
820 }
821
822 GLAPI int GLAPIENTRY
823 wglChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
824 {
825 int i, best = -1, qt_valid_pix;
826 PIXELFORMATDESCRIPTOR pfd = *ppfd;
827
828 qt_valid_pix = pfd_tablen();
829
830 #if 1 || QUAKE2 || GORE
831 /* QUAKE2: 24+32 */
832 /* GORE : 24+16 */
833 if ((pfd.cColorBits == 24) || (pfd.cColorBits == 32)) {
834 /* the first 2 entries are 16bit */
835 pfd.cColorBits = (qt_valid_pix > 2) ? 32 : 16;
836 }
837 if (pfd.cColorBits == 32) {
838 pfd.cDepthBits = 24;
839 } else if (pfd.cColorBits == 16) {
840 pfd.cDepthBits = 16;
841 }
842 #endif
843
844 if (pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR) || pfd.nVersion != 1) {
845 SetLastError(0);
846 return 0;
847 }
848
849 for (i = 0; i < qt_valid_pix; i++) {
850 if (pfd.cColorBits > 0 && pix[i].pfd.cColorBits != pfd.cColorBits)
851 continue;
852
853 if ((pfd.dwFlags & PFD_DRAW_TO_WINDOW)
854 && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue;
855 if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP)
856 && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) continue;
857 if ((pfd.dwFlags & PFD_SUPPORT_GDI)
858 && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI)) continue;
859 if ((pfd.dwFlags & PFD_SUPPORT_OPENGL)
860 && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue;
861 if (!(pfd.dwFlags & PFD_DOUBLEBUFFER_DONTCARE)
862 && ((pfd.dwFlags & PFD_DOUBLEBUFFER) !=
863 (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
864 #if 1 /* Doom3 fails here! */
865 if (!(pfd.dwFlags & PFD_STEREO_DONTCARE)
866 && ((pfd.dwFlags & PFD_STEREO) !=
867 (pix[i].pfd.dwFlags & PFD_STEREO))) continue;
868 #endif
869
870 if (pfd.cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
871 continue; /* need depth buffer */
872
873 if (pfd.cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
874 continue; /* need alpha buffer */
875
876 #if 0 /* regression bug? */
877 if (pfd.cStencilBits > 0 && pix[i].pfd.cStencilBits == 0)
878 continue; /* need stencil buffer */
879 #endif
880
881 if (pfd.iPixelType == pix[i].pfd.iPixelType) {
882 best = i + 1;
883 break;
884 }
885 }
886
887 if (best == -1) {
888 FILE *err = fopen("MESA.LOG", "w");
889 if (err != NULL) {
890 fprintf(err, "wglChoosePixelFormat failed\n");
891 fprintf(err, "\tnSize = %d\n", ppfd->nSize);
892 fprintf(err, "\tnVersion = %d\n", ppfd->nVersion);
893 fprintf(err, "\tdwFlags = %lu\n", ppfd->dwFlags);
894 fprintf(err, "\tiPixelType = %d\n", ppfd->iPixelType);
895 fprintf(err, "\tcColorBits = %d\n", ppfd->cColorBits);
896 fprintf(err, "\tcRedBits = %d\n", ppfd->cRedBits);
897 fprintf(err, "\tcRedShift = %d\n", ppfd->cRedShift);
898 fprintf(err, "\tcGreenBits = %d\n", ppfd->cGreenBits);
899 fprintf(err, "\tcGreenShift = %d\n", ppfd->cGreenShift);
900 fprintf(err, "\tcBlueBits = %d\n", ppfd->cBlueBits);
901 fprintf(err, "\tcBlueShift = %d\n", ppfd->cBlueShift);
902 fprintf(err, "\tcAlphaBits = %d\n", ppfd->cAlphaBits);
903 fprintf(err, "\tcAlphaShift = %d\n", ppfd->cAlphaShift);
904 fprintf(err, "\tcAccumBits = %d\n", ppfd->cAccumBits);
905 fprintf(err, "\tcAccumRedBits = %d\n", ppfd->cAccumRedBits);
906 fprintf(err, "\tcAccumGreenBits = %d\n", ppfd->cAccumGreenBits);
907 fprintf(err, "\tcAccumBlueBits = %d\n", ppfd->cAccumBlueBits);
908 fprintf(err, "\tcAccumAlphaBits = %d\n", ppfd->cAccumAlphaBits);
909 fprintf(err, "\tcDepthBits = %d\n", ppfd->cDepthBits);
910 fprintf(err, "\tcStencilBits = %d\n", ppfd->cStencilBits);
911 fprintf(err, "\tcAuxBuffers = %d\n", ppfd->cAuxBuffers);
912 fprintf(err, "\tiLayerType = %d\n", ppfd->iLayerType);
913 fprintf(err, "\tbReserved = %d\n", ppfd->bReserved);
914 fprintf(err, "\tdwLayerMask = %lu\n", ppfd->dwLayerMask);
915 fprintf(err, "\tdwVisibleMask = %lu\n", ppfd->dwVisibleMask);
916 fprintf(err, "\tdwDamageMask = %lu\n", ppfd->dwDamageMask);
917 fclose(err);
918 }
919
920 SetLastError(0);
921 return 0;
922 }
923
924 return best;
925 }
926
927 GLAPI int GLAPIENTRY
928 ChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
929 {
930
931 return wglChoosePixelFormat(hdc, ppfd);
932 }
933
934 GLAPI int GLAPIENTRY
935 wglDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
936 LPPIXELFORMATDESCRIPTOR ppfd)
937 {
938 int qt_valid_pix;
939
940 qt_valid_pix = pfd_tablen();
941
942 if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
943 ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
944 SetLastError(0);
945 return qt_valid_pix;
946 }
947
948 if (nBytes != 0)
949 *ppfd = pix[iPixelFormat - 1].pfd;
950
951 return qt_valid_pix;
952 }
953
954 GLAPI int GLAPIENTRY
955 DescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
956 LPPIXELFORMATDESCRIPTOR ppfd)
957 {
958 return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
959 }
960
961 GLAPI int GLAPIENTRY
962 wglGetPixelFormat (HDC hdc)
963 {
964 if (curPFD == 0) {
965 SetLastError(0);
966 return 0;
967 }
968
969 return curPFD;
970 }
971
972 GLAPI int GLAPIENTRY
973 GetPixelFormat (HDC hdc)
974 {
975 return wglGetPixelFormat(hdc);
976 }
977
978 GLAPI BOOL GLAPIENTRY
979 wglSetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
980 {
981 int qt_valid_pix;
982
983 qt_valid_pix = pfd_tablen();
984
985 if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix) {
986 if (ppfd == NULL) {
987 PIXELFORMATDESCRIPTOR my_pfd;
988 if (!wglDescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &my_pfd)) {
989 SetLastError(0);
990 return FALSE;
991 }
992 } else if (ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
993 SetLastError(0);
994 return FALSE;
995 }
996 }
997 curPFD = iPixelFormat;
998
999 return TRUE;
1000 }
1001
1002 GLAPI BOOL GLAPIENTRY
1003 wglSwapBuffers (HDC hdc)
1004 {
1005 if (!ctx) {
1006 SetLastError(0);
1007 return FALSE;
1008 }
1009
1010 fxMesaSwapBuffers();
1011
1012 return TRUE;
1013 }
1014
1015 GLAPI BOOL GLAPIENTRY
1016 SetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
1017 {
1018 return wglSetPixelFormat(hdc, iPixelFormat, ppfd);
1019 }
1020
1021 GLAPI BOOL GLAPIENTRY
1022 SwapBuffers(HDC hdc)
1023 {
1024 return wglSwapBuffers(hdc);
1025 }
1026
1027 static FIXED
1028 FixedFromDouble (double d)
1029 {
1030 struct {
1031 FIXED f;
1032 long l;
1033 } pun;
1034 pun.l = (long)(d * 65536L);
1035 return pun.f;
1036 }
1037
1038 /*
1039 ** This was yanked from windows/gdi/wgl.c
1040 */
1041 GLAPI BOOL GLAPIENTRY
1042 wglUseFontBitmapsA (HDC hdc, DWORD first, DWORD count, DWORD listBase)
1043 {
1044 int i;
1045 GLuint font_list;
1046 DWORD size;
1047 GLYPHMETRICS gm;
1048 HANDLE hBits;
1049 LPSTR lpBits;
1050 MAT2 mat;
1051 int success = TRUE;
1052
1053 font_list = listBase;
1054
1055 mat.eM11 = FixedFromDouble(1);
1056 mat.eM12 = FixedFromDouble(0);
1057 mat.eM21 = FixedFromDouble(0);
1058 mat.eM22 = FixedFromDouble(-1);
1059
1060 memset(&gm, 0, sizeof(gm));
1061
1062 /*
1063 ** If we can't get the glyph outline, it may be because this is a fixed
1064 ** font. Try processing it that way.
1065 */
1066 if (GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) == GDI_ERROR) {
1067 return wglUseFontBitmaps_FX(hdc, first, count, listBase);
1068 }
1069
1070 /*
1071 ** Otherwise process all desired characters.
1072 */
1073 for (i = 0; i < count; i++) {
1074 DWORD err;
1075
1076 glNewList(font_list + i, GL_COMPILE);
1077
1078 /* allocate space for the bitmap/outline */
1079 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
1080 if (size == GDI_ERROR) {
1081 glEndList();
1082 err = GetLastError();
1083 success = FALSE;
1084 continue;
1085 }
1086
1087 hBits = GlobalAlloc(GHND, size + 1);
1088 lpBits = GlobalLock(hBits);
1089
1090 err = GetGlyphOutline(hdc, /* handle to device context */
1091 first + i, /* character to query */
1092 GGO_BITMAP, /* format of data to return */
1093 &gm, /* pointer to structure for metrics */
1094 size, /* size of buffer for data */
1095 lpBits, /* pointer to buffer for data */
1096 &mat /* pointer to transformation */
1097 /* matrix structure */
1098 );
1099
1100 if (err == GDI_ERROR) {
1101 GlobalUnlock(hBits);
1102 GlobalFree(hBits);
1103
1104 glEndList();
1105 err = GetLastError();
1106 success = FALSE;
1107 continue;
1108 }
1109
1110 glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
1111 -gm.gmptGlyphOrigin.x,
1112 gm.gmptGlyphOrigin.y,
1113 gm.gmCellIncX, gm.gmCellIncY,
1114 (const GLubyte *)lpBits);
1115
1116 GlobalUnlock(hBits);
1117 GlobalFree(hBits);
1118
1119 glEndList();
1120 }
1121
1122 return success;
1123 }
1124
1125 GLAPI BOOL GLAPIENTRY
1126 wglDescribeLayerPlane (HDC hdc, int iPixelFormat, int iLayerPlane,
1127 UINT nBytes, LPLAYERPLANEDESCRIPTOR ppfd)
1128 {
1129 SetLastError(0);
1130 return FALSE;
1131 }
1132
1133 GLAPI int GLAPIENTRY
1134 wglGetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart,
1135 int cEntries, COLORREF *pcr)
1136 {
1137 SetLastError(0);
1138 return FALSE;
1139 }
1140
1141 GLAPI BOOL GLAPIENTRY
1142 wglRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize)
1143 {
1144 SetLastError(0);
1145 return FALSE;
1146 }
1147
1148 GLAPI int GLAPIENTRY
1149 wglSetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart,
1150 int cEntries, CONST COLORREF *pcr)
1151 {
1152 SetLastError(0);
1153 return FALSE;
1154 }
1155
1156
1157 /***************************************************************************
1158 * [dBorca] simplistic ICD implementation, based on ICD code by Gregor Anich
1159 */
1160
1161 typedef struct _icdTable {
1162 DWORD size;
1163 PROC table[336];
1164 } ICDTABLE, *PICDTABLE;
1165
1166 #ifdef USE_MGL_NAMESPACE
1167 #define GL_FUNC(func) mgl##func
1168 #else
1169 #define GL_FUNC(func) gl##func
1170 #endif
1171
1172 static ICDTABLE icdTable = { 336, {
1173 #define ICD_ENTRY(func) (PROC)GL_FUNC(func),
1174 #include "../icd/icdlist.h"
1175 #undef ICD_ENTRY
1176 } };
1177
1178
1179 GLAPI BOOL GLAPIENTRY
1180 DrvCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
1181 {
1182 return wglCopyContext(hglrcSrc, hglrcDst, mask);
1183 }
1184
1185
1186 GLAPI HGLRC GLAPIENTRY
1187 DrvCreateContext (HDC hdc)
1188 {
1189 return wglCreateContext(hdc);
1190 }
1191
1192
1193 GLAPI BOOL GLAPIENTRY
1194 DrvDeleteContext (HGLRC hglrc)
1195 {
1196 return wglDeleteContext(hglrc);
1197 }
1198
1199
1200 GLAPI HGLRC GLAPIENTRY
1201 DrvCreateLayerContext (HDC hdc, int iLayerPlane)
1202 {
1203 return wglCreateContext(hdc);
1204 }
1205
1206
1207 GLAPI PICDTABLE GLAPIENTRY
1208 DrvSetContext (HDC hdc, HGLRC hglrc, void *callback)
1209 {
1210 return wglMakeCurrent(hdc, hglrc) ? &icdTable : NULL;
1211 }
1212
1213
1214 GLAPI BOOL GLAPIENTRY
1215 DrvReleaseContext (HGLRC hglrc)
1216 {
1217 return TRUE;
1218 }
1219
1220
1221 GLAPI BOOL GLAPIENTRY
1222 DrvShareLists (HGLRC hglrc1, HGLRC hglrc2)
1223 {
1224 return wglShareLists(hglrc1, hglrc2);
1225 }
1226
1227
1228 GLAPI BOOL GLAPIENTRY
1229 DrvDescribeLayerPlane (HDC hdc, int iPixelFormat,
1230 int iLayerPlane, UINT nBytes,
1231 LPLAYERPLANEDESCRIPTOR plpd)
1232 {
1233 return wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
1234 }
1235
1236
1237 GLAPI int GLAPIENTRY
1238 DrvSetLayerPaletteEntries (HDC hdc, int iLayerPlane,
1239 int iStart, int cEntries, CONST COLORREF *pcr)
1240 {
1241 return wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
1242 }
1243
1244
1245 GLAPI int GLAPIENTRY
1246 DrvGetLayerPaletteEntries (HDC hdc, int iLayerPlane,
1247 int iStart, int cEntries, COLORREF *pcr)
1248 {
1249 return wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
1250 }
1251
1252
1253 GLAPI BOOL GLAPIENTRY
1254 DrvRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize)
1255 {
1256 return wglRealizeLayerPalette(hdc, iLayerPlane, bRealize);
1257 }
1258
1259
1260 GLAPI BOOL GLAPIENTRY
1261 DrvSwapLayerBuffers (HDC hdc, UINT fuPlanes)
1262 {
1263 return wglSwapLayerBuffers(hdc, fuPlanes);
1264 }
1265
1266 GLAPI int GLAPIENTRY
1267 DrvDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes,
1268 LPPIXELFORMATDESCRIPTOR ppfd)
1269 {
1270 return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
1271 }
1272
1273
1274 GLAPI PROC GLAPIENTRY
1275 DrvGetProcAddress (LPCSTR lpszProc)
1276 {
1277 return wglGetProcAddress(lpszProc);
1278 }
1279
1280
1281 GLAPI BOOL GLAPIENTRY
1282 DrvSetPixelFormat (HDC hdc, int iPixelFormat)
1283 {
1284 return wglSetPixelFormat(hdc, iPixelFormat, NULL);
1285 }
1286
1287
1288 GLAPI BOOL GLAPIENTRY
1289 DrvSwapBuffers (HDC hdc)
1290 {
1291 return wglSwapBuffers(hdc);
1292 }
1293
1294
1295 GLAPI BOOL GLAPIENTRY
1296 DrvValidateVersion (DWORD version)
1297 {
1298 (void)version;
1299 return TRUE;
1300 }
1301
1302
1303 #if (_MSC_VER >= 1200)
1304 #pragma warning( pop )
1305 #endif
1306
1307 #endif /* FX */