1 /* $Id: wgl.c,v 1.5 2004/08/25 15:59:48 brianp Exp $ */
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
23 * Some things originated from the 3Dfx WGL functions
33 #define GL_GLEXT_PROTOTYPES
49 #define MAX_MESA_ATTRS 20
51 struct __pixelformat__
53 PIXELFORMATDESCRIPTOR pfd
;
54 GLboolean doubleBuffered
;
57 struct __pixelformat__ pix
[] =
59 /* Double Buffer, alpha */
60 { { sizeof(PIXELFORMATDESCRIPTOR
), 1,
61 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|PFD_GENERIC_FORMAT
|PFD_DOUBLEBUFFER
|PFD_SWAP_COPY
,
63 24, 8, 0, 8, 8, 8, 16, 8, 24,
64 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
67 /* Single Buffer, alpha */
68 { { sizeof(PIXELFORMATDESCRIPTOR
), 1,
69 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|PFD_GENERIC_FORMAT
,
71 24, 8, 0, 8, 8, 8, 16, 8, 24,
72 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
75 /* Double Buffer, no alpha */
76 { { sizeof(PIXELFORMATDESCRIPTOR
), 1,
77 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|PFD_GENERIC_FORMAT
|PFD_DOUBLEBUFFER
|PFD_SWAP_COPY
,
79 24, 8, 0, 8, 8, 8, 16, 0, 0,
80 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
83 /* Single Buffer, no alpha */
84 { { sizeof(PIXELFORMATDESCRIPTOR
), 1,
85 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|PFD_GENERIC_FORMAT
,
87 24, 8, 0, 8, 8, 8, 16, 0, 0,
88 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
93 int qt_pix
= sizeof(pix
) / sizeof(pix
[0]);
100 #define MESAWGL_CTX_MAX_COUNT 20
102 static MesaWglCtx wgl_ctx
[MESAWGL_CTX_MAX_COUNT
];
104 static unsigned ctx_count
= 0;
105 static int ctx_current
= -1;
106 static unsigned curPFD
= 0;
108 WGLAPI BOOL GLAPIENTRY
wglCopyContext(HGLRC hglrcSrc
,HGLRC hglrcDst
,UINT mask
)
110 (void) hglrcSrc
; (void) hglrcDst
; (void) mask
;
114 WGLAPI HGLRC GLAPIENTRY
wglCreateContext(HDC hdc
)
118 if(!(hWnd
= WindowFromDC(hdc
)))
125 for(i
=0;i
<MESAWGL_CTX_MAX_COUNT
;i
++)
127 wgl_ctx
[i
].ctx
= NULL
;
128 wgl_ctx
[i
].hdc
= NULL
;
131 for( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ )
133 if ( wgl_ctx
[i
].ctx
== NULL
)
135 wgl_ctx
[i
].ctx
= WMesaCreateContext( hWnd
, NULL
, GL_TRUE
,
136 pix
[curPFD
-1].doubleBuffered
,
137 pix
[curPFD
-1].pfd
.cAlphaBits
? GL_TRUE
: GL_FALSE
);
138 if (wgl_ctx
[i
].ctx
== NULL
)
140 wgl_ctx
[i
].hdc
= hdc
;
142 return ((HGLRC
)wgl_ctx
[i
].ctx
);
149 WGLAPI BOOL GLAPIENTRY
wglDeleteContext(HGLRC hglrc
)
152 for ( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ )
154 if ( wgl_ctx
[i
].ctx
== (PWMC
) hglrc
)
156 WMesaMakeCurrent((PWMC
) hglrc
);
157 WMesaDestroyContext();
158 wgl_ctx
[i
].ctx
= NULL
;
159 wgl_ctx
[i
].hdc
= NULL
;
168 WGLAPI HGLRC GLAPIENTRY
wglCreateLayerContext(HDC hdc
,int iLayerPlane
)
170 (void) hdc
; (void) iLayerPlane
;
175 WGLAPI HGLRC GLAPIENTRY
wglGetCurrentContext(VOID
)
180 return (HGLRC
) wgl_ctx
[ctx_current
].ctx
;
183 WGLAPI HDC GLAPIENTRY
wglGetCurrentDC(VOID
)
188 return wgl_ctx
[ctx_current
].hdc
;
191 WGLAPI BOOL GLAPIENTRY
wglMakeCurrent(HDC hdc
,HGLRC hglrc
)
195 /* new code suggested by Andy Sy */
196 if (!hdc
|| !hglrc
) {
197 WMesaMakeCurrent(NULL
);
202 for ( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ )
204 if ( wgl_ctx
[i
].ctx
== (PWMC
) hglrc
)
206 wgl_ctx
[i
].hdc
= hdc
;
207 WMesaMakeCurrent( (WMesaContext
) hglrc
);
215 WGLAPI BOOL GLAPIENTRY
wglShareLists(HGLRC hglrc1
,HGLRC hglrc2
)
217 (void) hglrc1
; (void) hglrc2
;
222 static FIXED
FixedFromDouble(double d
)
224 long l
= (long) (d
* 65536L);
225 return *(FIXED
*) (void *) &l
;
230 ** This is cribbed from FX/fxwgl.c, and seems to implement support
231 ** for bitmap fonts where the wglUseFontBitmapsA() code implements
232 ** support for outline fonts. In combination they hopefully give
233 ** fairly generic support for fonts.
235 static BOOL
wglUseFontBitmaps_FX(HDC fontDevice
, DWORD firstChar
,
236 DWORD numChars
, DWORD listBase
)
246 VERIFY(GetTextMetrics(fontDevice
, &metric
));
248 dibInfo
= (BITMAPINFO
*) calloc(sizeof(BITMAPINFO
) + sizeof(RGBQUAD
), 1);
249 dibInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
250 dibInfo
->bmiHeader
.biPlanes
= 1;
251 dibInfo
->bmiHeader
.biBitCount
= 1;
252 dibInfo
->bmiHeader
.biCompression
= BI_RGB
;
254 bitDevice
= CreateCompatibleDC(fontDevice
);
255 // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
256 // VERIFY(bitDevice);
258 // Swap fore and back colors so the bitmap has the right polarity
259 tempColor
= GetBkColor(bitDevice
);
260 SetBkColor(bitDevice
, GetTextColor(bitDevice
));
261 SetTextColor(bitDevice
, tempColor
);
263 // Place chars based on base line
264 VERIFY(SetTextAlign(bitDevice
, TA_BASELINE
) != GDI_ERROR
? 1 : 0);
266 for(i
= 0; i
< (int)numChars
; i
++) {
269 int charWidth
,charHeight
,bmapWidth
,bmapHeight
,numBytes
,res
;
274 curChar
= i
+ firstChar
;
276 // Find how high/wide this character is
277 VERIFY(GetTextExtentPoint32(bitDevice
, &curChar
, 1, &size
));
279 // Create the output bitmap
281 charHeight
= size
.cy
;
282 bmapWidth
= ((charWidth
+ 31) / 32) * 32; // Round up to the next multiple of 32 bits
283 bmapHeight
= charHeight
;
284 bitObject
= CreateCompatibleBitmap(bitDevice
,
289 // Assign the output bitmap to the device
290 origBmap
= SelectObject(bitDevice
, bitObject
);
291 (void) VERIFY(origBmap
);
293 VERIFY( PatBlt( bitDevice
, 0, 0, bmapWidth
, bmapHeight
,BLACKNESS
) );
295 // Use our source font on the device
296 VERIFY(SelectObject(bitDevice
, GetCurrentObject(fontDevice
,OBJ_FONT
)));
298 // Draw the character
299 VERIFY(TextOut(bitDevice
, 0, metric
.tmAscent
, &curChar
, 1));
301 // Unselect our bmap object
302 VERIFY(SelectObject(bitDevice
, origBmap
));
304 // Convert the display dependant representation to a 1 bit deep DIB
305 numBytes
= (bmapWidth
* bmapHeight
) / 8;
306 bmap
= malloc(numBytes
);
307 dibInfo
->bmiHeader
.biWidth
= bmapWidth
;
308 dibInfo
->bmiHeader
.biHeight
= bmapHeight
;
309 res
= GetDIBits(bitDevice
, bitObject
, 0, bmapHeight
, bmap
,
314 // Create the GL object
315 glNewList(i
+ listBase
, GL_COMPILE
);
316 glBitmap(bmapWidth
, bmapHeight
, 0.0, metric
.tmDescent
,
322 // Destroy the bmap object
323 DeleteObject(bitObject
);
325 // Deallocate the bitmap data
330 VERIFY(DeleteDC(bitDevice
));
338 WGLAPI BOOL GLAPIENTRY
wglUseFontBitmapsA(HDC hdc
, DWORD first
,
339 DWORD count
, DWORD listBase
)
353 font_list
= listBase
;
355 mat
.eM11
= FixedFromDouble(1);
356 mat
.eM12
= FixedFromDouble(0);
357 mat
.eM21
= FixedFromDouble(0);
358 mat
.eM22
= FixedFromDouble(-1);
360 memset(&gm
,0,sizeof(gm
));
363 ** If we can't get the glyph outline, it may be because this is a fixed
364 ** font. Try processing it that way.
366 if( GetGlyphOutline(hdc
, first
, GGO_BITMAP
, &gm
, 0, NULL
, &mat
)
369 return wglUseFontBitmaps_FX( hdc
, first
, count
, listBase
);
373 ** Otherwise process all desired characters.
375 for (i
= 0; i
< (int)count
; i
++)
379 glNewList( font_list
+i
, GL_COMPILE
);
381 /* allocate space for the bitmap/outline */
382 size
= GetGlyphOutline(hdc
, first
+ i
, GGO_BITMAP
, &gm
, 0, NULL
, &mat
);
383 if (size
== GDI_ERROR
)
386 err
= GetLastError();
391 hBits
= GlobalAlloc(GHND
, size
+1);
392 lpBits
= GlobalLock(hBits
);
395 GetGlyphOutline(hdc
, /* handle to device context */
396 first
+ i
, /* character to query */
397 GGO_BITMAP
, /* format of data to return */
398 &gm
, /* pointer to structure for metrics*/
399 size
, /* size of buffer for data */
400 lpBits
, /* pointer to buffer for data */
401 &mat
/* pointer to transformation */
402 /* matrix structure */
405 if (err
== GDI_ERROR
)
411 err
= GetLastError();
416 glBitmap(gm
.gmBlackBoxX
,gm
.gmBlackBoxY
,
417 -gm
.gmptGlyphOrigin
.x
,
418 gm
.gmptGlyphOrigin
.y
,
419 gm
.gmCellIncX
,gm
.gmCellIncY
,
420 (const GLubyte
* )lpBits
);
432 WGLAPI BOOL GLAPIENTRY
wglUseFontBitmapsW(HDC hdc
,DWORD first
,DWORD count
,DWORD listBase
)
434 (void) hdc
; (void) first
; (void) count
; (void) listBase
;
438 WGLAPI BOOL GLAPIENTRY
wglUseFontOutlinesA(HDC hdc
,DWORD first
,DWORD count
,
439 DWORD listBase
,FLOAT deviation
,
440 FLOAT extrusion
,int format
,
441 LPGLYPHMETRICSFLOAT lpgmf
)
443 (void) hdc
; (void) first
; (void) count
;
444 (void) listBase
; (void) deviation
; (void) extrusion
; (void) format
;
450 WGLAPI BOOL GLAPIENTRY
wglUseFontOutlinesW(HDC hdc
,DWORD first
,DWORD count
,
451 DWORD listBase
,FLOAT deviation
,
452 FLOAT extrusion
,int format
,
453 LPGLYPHMETRICSFLOAT lpgmf
)
455 (void) hdc
; (void) first
; (void) count
;
456 (void) listBase
; (void) deviation
; (void) extrusion
; (void) format
;
462 WGLAPI BOOL GLAPIENTRY
wglDescribeLayerPlane(HDC hdc
,int iPixelFormat
,
463 int iLayerPlane
,UINT nBytes
,
464 LPLAYERPLANEDESCRIPTOR plpd
)
466 (void) hdc
; (void) iPixelFormat
; (void) iLayerPlane
; (void) nBytes
; (void) plpd
;
471 WGLAPI
int GLAPIENTRY
wglSetLayerPaletteEntries(HDC hdc
,int iLayerPlane
,
472 int iStart
,int cEntries
,
475 (void) hdc
; (void) iLayerPlane
; (void) iStart
; (void) cEntries
; (void) pcr
;
480 WGLAPI
int GLAPIENTRY
wglGetLayerPaletteEntries(HDC hdc
,int iLayerPlane
,
481 int iStart
,int cEntries
,
484 (void) hdc
; (void) iLayerPlane
; (void) iStart
; (void) cEntries
; (void) pcr
;
489 WGLAPI BOOL GLAPIENTRY
wglRealizeLayerPalette(HDC hdc
,int iLayerPlane
,BOOL bRealize
)
491 (void) hdc
; (void) iLayerPlane
; (void) bRealize
;
496 WGLAPI BOOL GLAPIENTRY
wglSwapLayerBuffers(HDC hdc
,UINT fuPlanes
)
508 WGLAPI
int GLAPIENTRY
wglChoosePixelFormat(HDC hdc
,
509 CONST PIXELFORMATDESCRIPTOR
*ppfd
)
511 int i
,best
= -1,bestdelta
= 0x7FFFFFFF,delta
,qt_valid_pix
;
514 qt_valid_pix
= qt_pix
;
515 if(ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
) || ppfd
->nVersion
!= 1)
520 for(i
= 0;i
< qt_valid_pix
;i
++)
524 (ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
) &&
525 !(pix
[i
].pfd
.dwFlags
& PFD_DRAW_TO_WINDOW
))
528 (ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
) &&
529 !(pix
[i
].pfd
.dwFlags
& PFD_DRAW_TO_BITMAP
))
532 (ppfd
->dwFlags
& PFD_SUPPORT_GDI
) &&
533 !(pix
[i
].pfd
.dwFlags
& PFD_SUPPORT_GDI
))
536 (ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
) &&
537 !(pix
[i
].pfd
.dwFlags
& PFD_SUPPORT_OPENGL
))
540 !(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
) &&
541 ((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) != (pix
[i
].pfd
.dwFlags
& PFD_DOUBLEBUFFER
)))
544 !(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
) &&
545 ((ppfd
->dwFlags
& PFD_STEREO
) != (pix
[i
].pfd
.dwFlags
& PFD_STEREO
)))
547 if(ppfd
->iPixelType
!= pix
[i
].pfd
.iPixelType
)
549 if(ppfd
->cAlphaBits
!= pix
[i
].pfd
.cAlphaBits
)
551 if(delta
< bestdelta
)
567 WGLAPI
int GLAPIENTRY
wglDescribePixelFormat(HDC hdc
,int iPixelFormat
,UINT nBytes
,
568 LPPIXELFORMATDESCRIPTOR ppfd
)
573 qt_valid_pix
= qt_pix
;
575 return(qt_valid_pix
);
576 if(iPixelFormat
< 1 || iPixelFormat
> qt_valid_pix
|| nBytes
!= sizeof(PIXELFORMATDESCRIPTOR
))
581 *ppfd
= pix
[iPixelFormat
- 1].pfd
;
582 return(qt_valid_pix
);
586 * GetProcAddress - return the address of an appropriate extension
588 WGLAPI PROC GLAPIENTRY
wglGetProcAddress(LPCSTR lpszProc
)
590 PROC p
= (PROC
) _glapi_get_proc_address((const char *) lpszProc
);
598 WGLAPI
int GLAPIENTRY
wglGetPixelFormat(HDC hdc
)
609 WGLAPI BOOL GLAPIENTRY
wglSetPixelFormat(HDC hdc
,int iPixelFormat
,
610 PIXELFORMATDESCRIPTOR
*ppfd
)
615 qt_valid_pix
= qt_pix
;
616 if(iPixelFormat
< 1 || iPixelFormat
> qt_valid_pix
|| ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
))
621 curPFD
= iPixelFormat
;
625 WGLAPI BOOL GLAPIENTRY
wglSwapBuffers(HDC hdc
)
631 if(wgl_ctx
[ctx_current
].ctx
== NULL
) {