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