1 /* $Id: fxwgl.c,v 1.17 2003/08/19 15:52:53 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
33 /* fxwgl.c - Microsoft wgl functions emulation for
34 * 3Dfx VooDoo/Mesa interface
46 #define GL_GLEXT_PROTOTYPES
55 #include "GL/fxmesa.h"
60 #define MAX_MESA_ATTRS 20
68 struct __pixelformat__
70 PIXELFORMATDESCRIPTOR pfd
;
71 GLint mesaAttr
[MAX_MESA_ATTRS
];
74 WINGDIAPI
void GLAPIENTRY
gl3DfxSetPaletteEXT(GLuint
*);
76 struct __pixelformat__ pix
[] = {
81 sizeof(PIXELFORMATDESCRIPTOR
), 1,
82 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
83 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
86 5, 11, 6, 5, 5, 0, 0, 0,
95 FXMESA_COLORDEPTH
, 16,
99 FXMESA_STENCIL_SIZE
, 0,
100 FXMESA_ACCUM_SIZE
, 0,
108 sizeof(PIXELFORMATDESCRIPTOR
), 1,
109 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
110 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
113 5, 10, 5, 5, 5, 0, 1, 15,
122 FXMESA_COLORDEPTH
, 15,
124 FXMESA_ALPHA_SIZE
, 1,
125 FXMESA_DEPTH_SIZE
, 0,
126 FXMESA_STENCIL_SIZE
, 0,
127 FXMESA_ACCUM_SIZE
, 0,
135 sizeof(PIXELFORMATDESCRIPTOR
), 1,
136 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
137 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
140 5, 11, 6, 5, 5, 0, 0, 0,
149 FXMESA_COLORDEPTH
, 16,
151 FXMESA_ALPHA_SIZE
, 0,
152 FXMESA_DEPTH_SIZE
, 16,
153 FXMESA_STENCIL_SIZE
, 0,
154 FXMESA_ACCUM_SIZE
, 0,
162 sizeof(PIXELFORMATDESCRIPTOR
), 1,
163 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
164 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
167 8, 16, 8, 8, 8, 0, 0, 0,
176 FXMESA_COLORDEPTH
, 32,
178 FXMESA_ALPHA_SIZE
, 0,
179 FXMESA_DEPTH_SIZE
, 0,
180 FXMESA_STENCIL_SIZE
, 0,
181 FXMESA_ACCUM_SIZE
, 0,
189 sizeof(PIXELFORMATDESCRIPTOR
), 1,
190 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
191 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
194 8, 16, 8, 8, 8, 0, 8, 24,
203 FXMESA_COLORDEPTH
, 32,
205 FXMESA_ALPHA_SIZE
, 8,
206 FXMESA_DEPTH_SIZE
, 0,
207 FXMESA_STENCIL_SIZE
, 0,
208 FXMESA_ACCUM_SIZE
, 0,
216 sizeof(PIXELFORMATDESCRIPTOR
), 1,
217 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
218 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
221 8, 16, 8, 8, 8, 0, 0, 0,
230 FXMESA_COLORDEPTH
, 32,
232 FXMESA_ALPHA_SIZE
, 0,
233 FXMESA_DEPTH_SIZE
, 16,
234 FXMESA_STENCIL_SIZE
, 0,
235 FXMESA_ACCUM_SIZE
, 0,
241 {sizeof(PIXELFORMATDESCRIPTOR
), 1,
242 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
243 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
246 5, 11, 6, 5, 5, 0, 0, 0,
254 {FXMESA_COLORDEPTH
, 16,
256 FXMESA_ALPHA_SIZE
, 0,
257 FXMESA_DEPTH_SIZE
, 16,
258 FXMESA_STENCIL_SIZE
, 0,
259 FXMESA_ACCUM_SIZE
, 0,
265 {sizeof(PIXELFORMATDESCRIPTOR
), 1,
266 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
267 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
270 5, 10, 5, 5, 5, 0, 1, 15,
278 {FXMESA_COLORDEPTH
, 15,
280 FXMESA_ALPHA_SIZE
, 1,
281 FXMESA_DEPTH_SIZE
, 16,
282 FXMESA_STENCIL_SIZE
, 0,
283 FXMESA_ACCUM_SIZE
, 0,
289 {sizeof(PIXELFORMATDESCRIPTOR
), 1,
290 PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
|
291 PFD_DOUBLEBUFFER
| PFD_SWAP_COPY
,
294 8, 16, 8, 8, 8, 0, 8, 24,
302 {FXMESA_COLORDEPTH
, 32,
304 FXMESA_ALPHA_SIZE
, 8,
305 FXMESA_DEPTH_SIZE
, 24,
306 FXMESA_STENCIL_SIZE
, 0,
307 FXMESA_ACCUM_SIZE
, 0,
311 static int qt_pix
= sizeof(pix
) / sizeof(pix
[0]);
313 static fxMesaContext ctx
= NULL
;
314 static WNDPROC hWNDOldProc
;
315 static int curPFD
= 0;
319 static GLboolean haveDualHead
;
321 /* For the in-window-rendering hack */
323 #ifndef GR_CONTROL_RESIZE
324 /* Apparently GR_CONTROL_RESIZE can be ignored. OK? */
325 #define GR_CONTROL_RESIZE -1
328 static GLboolean gdiWindowHack
;
329 static void *dibSurfacePtr
;
330 static BITMAPINFO
*dibBMI
;
331 static HBITMAP dibHBM
;
335 __wglMonitor(HWND hwnd
, UINT message
, UINT wParam
, LONG lParam
)
337 long ret
; /* Now gives the resized window at the end to hWNDOldProc */
339 if (ctx
&& hwnd
== hWND
) {
344 case WM_DISPLAYCHANGE
:
346 if (wParam
!= SIZE_MINIMIZED
) {
347 static int moving
= 0;
349 if (!FX_grSstControl(GR_CONTROL_RESIZE
)) {
351 SetWindowPos(hwnd
, 0, 0, 0, 300, 300, SWP_NOMOVE
| SWP_NOZORDER
);
353 if (!FX_grSstControl(GR_CONTROL_RESIZE
)) {
354 /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK); */
355 PostMessage(hWND
, WM_CLOSE
, 0, 0);
358 /* Do the clipping in the glide library */
359 grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight());
360 /* And let the new size set in the context */
361 fxMesaUpdateScreenSize(ctx
);
375 /* Finaly call the hWNDOldProc, which handles the resize witch the
376 now changed window sizes */
377 ret
= CallWindowProc(hWNDOldProc
, hwnd
, message
, wParam
, lParam
);
383 wglCopyContext(HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
389 wglCreateContext(HDC hdc
)
400 if (!(hWnd
= WindowFromDC(hdc
))) {
410 if ((oldProc
= (WNDPROC
) GetWindowLong(hWnd
, GWL_WNDPROC
)) != __wglMonitor
) {
411 hWNDOldProc
= oldProc
;
412 SetWindowLong(hWnd
, GWL_WNDPROC
, (LONG
) __wglMonitor
);
416 freopen("MESA.LOG", "w", stderr
);
421 ShowWindow(hWnd
, SW_SHOWNORMAL
);
422 SetForegroundWindow(hWnd
);
423 Sleep(100); /* a hack for win95 */
424 GetClientRect(hWnd
, &cliRect
);
425 error
= !(ctx
= fxMesaCreateBestContext((GLuint
) hWnd
, cliRect
.right
, cliRect
.bottom
, pix
[curPFD
- 1].mesaAttr
));
428 if (getenv("SST_DUALHEAD"))
430 ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE
: GL_FALSE
);
432 haveDualHead
= GL_FALSE
;
442 /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
443 wglMakeCurrent(hdc
, (HGLRC
) 1);
449 wglCreateLayerContext(HDC hdc
, int iLayerPlane
)
456 wglDeleteContext(HGLRC hglrc
)
458 if (ctx
&& hglrc
== (HGLRC
) 1) {
460 fxMesaDestroyContext(ctx
);
462 SetWindowLong(WindowFromDC(hDC
), GWL_WNDPROC
, (LONG
) hWNDOldProc
);
475 wglGetCurrentContext(VOID
)
485 wglGetCurrentDC(VOID
)
495 wglGetProcAddress(LPCSTR lpszProc
)
497 PROC p
= (PROC
) _glapi_get_proc_address((const char *) lpszProc
);
506 wglMakeCurrent(HDC hdc
, HGLRC hglrc
)
508 if ((hdc
== NULL
) && (hglrc
== NULL
))
511 if (!ctx
|| hglrc
!= (HGLRC
) 1 || WindowFromDC(hdc
) != hWND
) {
518 fxMesaMakeCurrent(ctx
);
524 wglShareLists(HGLRC hglrc1
, HGLRC hglrc2
)
526 if (!ctx
|| hglrc1
!= (HGLRC
) 1 || hglrc1
!= hglrc2
) {
535 wglUseFontBitmaps(HDC fontDevice
, DWORD firstChar
, DWORD numChars
,
546 VERIFY(GetTextMetrics(fontDevice
, &metric
));
548 dibInfo
= (BITMAPINFO
*) calloc(sizeof(BITMAPINFO
) + sizeof(RGBQUAD
), 1);
549 dibInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
550 dibInfo
->bmiHeader
.biPlanes
= 1;
551 dibInfo
->bmiHeader
.biBitCount
= 1;
552 dibInfo
->bmiHeader
.biCompression
= BI_RGB
;
554 bitDevice
= CreateCompatibleDC(fontDevice
);
555 // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
556 // VERIFY(bitDevice);
558 // Swap fore and back colors so the bitmap has the right polarity
559 tempColor
= GetBkColor(bitDevice
);
560 SetBkColor(bitDevice
, GetTextColor(bitDevice
));
561 SetTextColor(bitDevice
, tempColor
);
563 // Place chars based on base line
564 VERIFY(SetTextAlign(bitDevice
, TA_BASELINE
) >= 0 ? 1 : 0);
566 for (i
= 0; i
< (int)numChars
; i
++) {
569 int charWidth
, charHeight
, bmapWidth
, bmapHeight
, numBytes
, res
;
574 curChar
= (char)(i
+ firstChar
); // [koolsmoky] explicit cast
576 // Find how high/wide this character is
577 VERIFY(GetTextExtentPoint32(bitDevice
, &curChar
, 1, &size
));
579 // Create the output bitmap
581 charHeight
= size
.cy
;
582 bmapWidth
= ((charWidth
+ 31) / 32) * 32; // Round up to the next multiple of 32 bits
583 bmapHeight
= charHeight
;
584 bitObject
= CreateCompatibleBitmap(bitDevice
, bmapWidth
, bmapHeight
);
587 // Assign the output bitmap to the device
588 origBmap
= SelectObject(bitDevice
, bitObject
);
591 VERIFY(PatBlt(bitDevice
, 0, 0, bmapWidth
, bmapHeight
, BLACKNESS
));
593 // Use our source font on the device
594 VERIFY(SelectObject(bitDevice
, GetCurrentObject(fontDevice
, OBJ_FONT
)));
596 // Draw the character
597 VERIFY(TextOut(bitDevice
, 0, metric
.tmAscent
, &curChar
, 1));
599 // Unselect our bmap object
600 VERIFY(SelectObject(bitDevice
, origBmap
));
602 // Convert the display dependant representation to a 1 bit deep DIB
603 numBytes
= (bmapWidth
* bmapHeight
) / 8;
604 bmap
= MALLOC(numBytes
);
605 dibInfo
->bmiHeader
.biWidth
= bmapWidth
;
606 dibInfo
->bmiHeader
.biHeight
= bmapHeight
;
607 res
= GetDIBits(bitDevice
, bitObject
, 0, bmapHeight
, bmap
,
608 dibInfo
, DIB_RGB_COLORS
);
611 // Create the GL object
612 glNewList(i
+ listBase
, GL_COMPILE
);
613 glBitmap(bmapWidth
, bmapHeight
, 0.0, metric
.tmDescent
,
614 charWidth
, 0.0, bmap
);
618 // Destroy the bmap object
619 DeleteObject(bitObject
);
621 // Deallocate the bitmap data
626 VERIFY(DeleteDC(bitDevice
));
635 wglUseFontBitmapsW(HDC hdc
, DWORD first
, DWORD count
, DWORD listBase
)
641 wglUseFontOutlinesA(HDC hdc
, DWORD first
, DWORD count
,
642 DWORD listBase
, FLOAT deviation
,
643 FLOAT extrusion
, int format
, LPGLYPHMETRICSFLOAT lpgmf
)
650 wglUseFontOutlinesW(HDC hdc
, DWORD first
, DWORD count
,
651 DWORD listBase
, FLOAT deviation
,
652 FLOAT extrusion
, int format
, LPGLYPHMETRICSFLOAT lpgmf
)
660 wglSwapLayerBuffers(HDC hdc
, UINT fuPlanes
)
662 if (ctx
&& WindowFromDC(hdc
) == hWND
) {
673 wglChoosePixelFormat(HDC hdc
, CONST PIXELFORMATDESCRIPTOR
* ppfd
)
675 int i
, best
= -1, qt_valid_pix
;
677 qt_valid_pix
= qt_pix
;
679 if (ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
) || ppfd
->nVersion
!= 1) {
684 for (i
= 0; i
< qt_valid_pix
; i
++) {
685 if (ppfd
->cColorBits
> 0 && pix
[i
].pfd
.cColorBits
!= ppfd
->cColorBits
)
688 if ((ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
)
689 && !(pix
[i
].pfd
.dwFlags
& PFD_DRAW_TO_WINDOW
)) continue;
690 if ((ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
)
691 && !(pix
[i
].pfd
.dwFlags
& PFD_DRAW_TO_BITMAP
)) continue;
692 if ((ppfd
->dwFlags
& PFD_SUPPORT_GDI
)
693 && !(pix
[i
].pfd
.dwFlags
& PFD_SUPPORT_GDI
)) continue;
694 if ((ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
)
695 && !(pix
[i
].pfd
.dwFlags
& PFD_SUPPORT_OPENGL
)) continue;
696 if (!(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
)
697 && ((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) !=
698 (pix
[i
].pfd
.dwFlags
& PFD_DOUBLEBUFFER
))) continue;
699 if (!(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
)
700 && ((ppfd
->dwFlags
& PFD_STEREO
) !=
701 (pix
[i
].pfd
.dwFlags
& PFD_STEREO
))) continue;
703 if (ppfd
->cDepthBits
> 0 && pix
[i
].pfd
.cDepthBits
== 0)
704 continue; /* need depth buffer */
706 if (ppfd
->cAlphaBits
> 0 && pix
[i
].pfd
.cAlphaBits
== 0)
707 continue; /* need alpha buffer */
709 if (ppfd
->iPixelType
== pix
[i
].pfd
.iPixelType
) {
724 ChoosePixelFormat(HDC hdc
, CONST PIXELFORMATDESCRIPTOR
* ppfd
)
726 return wglChoosePixelFormat(hdc
, ppfd
);
730 wglDescribePixelFormat(HDC hdc
, int iPixelFormat
, UINT nBytes
,
731 LPPIXELFORMATDESCRIPTOR ppfd
)
735 qt_valid_pix
= qt_pix
;
737 if (iPixelFormat
< 1 || iPixelFormat
> qt_valid_pix
||
738 ((nBytes
!= sizeof(PIXELFORMATDESCRIPTOR
)) && (nBytes
!= 0))) {
744 *ppfd
= pix
[iPixelFormat
- 1].pfd
;
746 return (qt_valid_pix
);
750 DescribePixelFormat(HDC hdc
, int iPixelFormat
, UINT nBytes
,
751 LPPIXELFORMATDESCRIPTOR ppfd
)
753 return wglDescribePixelFormat(hdc
, iPixelFormat
, nBytes
, ppfd
);
757 wglGetPixelFormat(HDC hdc
)
768 GetPixelFormat(HDC hdc
)
770 return wglGetPixelFormat(hdc
);
774 wglSetPixelFormat(HDC hdc
, int iPixelFormat
,
775 CONST PIXELFORMATDESCRIPTOR
* ppfd
)
779 qt_valid_pix
= qt_pix
;
781 if (iPixelFormat
< 1 || iPixelFormat
> qt_valid_pix
782 || ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
)) {
786 curPFD
= iPixelFormat
;
792 wglSwapBuffers(HDC hdc
)
805 SetPixelFormat(HDC hdc
, int iPixelFormat
, CONST PIXELFORMATDESCRIPTOR
* ppfd
)
807 return wglSetPixelFormat(hdc
, iPixelFormat
, ppfd
);
813 return wglSwapBuffers(hdc
);