source: trunk/src/opengl/mesa/3dfx/fxwgl.c

Last change on this file was 5394, checked in by sandervl, 25 years ago

* empty log message *

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