3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the Free
15 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
22 * Some things originated from the 3Dfx WGL functions
26 * This file contains the implementation of the wgl* functions for
27 * Mesa on Windows. Since these functions are provided by Windows in
28 * GDI/OpenGL, we must supply our versions that work with Mesa here.
32 /* We're essentially building part of GDI here, so define this so that
33 * we get the right export linkage. */
41 # if defined(BUILD_GL32)
42 # define WINGDIAPI __declspec(dllexport)
44 # define __W32API_USE_DLLIMPORT__
48 #include "GL/mesa_wgl.h"
59 #include "GL/wmesa.h" /* protos for wmesa* functions */
62 * Pixel Format Descriptors
65 /* Extend the PFD to include DB flag */
66 struct __pixelformat__
68 PIXELFORMATDESCRIPTOR pfd
;
69 GLboolean doubleBuffered
;
74 /* These are the PFD's supported by this driver. */
75 struct __pixelformat__ pfd
[] =
78 /* Double Buffer, alpha */
81 sizeof(PIXELFORMATDESCRIPTOR
), 1,
82 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|
83 PFD_GENERIC_FORMAT
|PFD_DOUBLEBUFFER
|PFD_SWAP_COPY
,
91 DEFAULT_SOFTWARE_DEPTH_BITS
, 8,
97 /* Single Buffer, alpha */
100 sizeof(PIXELFORMATDESCRIPTOR
), 1,
101 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|
110 DEFAULT_SOFTWARE_DEPTH_BITS
, 8,
117 /* Double Buffer, no alpha */
120 sizeof(PIXELFORMATDESCRIPTOR
), 1,
121 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|
122 PFD_GENERIC_FORMAT
|PFD_DOUBLEBUFFER
|PFD_SWAP_COPY
,
130 DEFAULT_SOFTWARE_DEPTH_BITS
, 8,
136 /* Single Buffer, no alpha */
139 sizeof(PIXELFORMATDESCRIPTOR
), 1,
140 PFD_DRAW_TO_WINDOW
|PFD_SUPPORT_OPENGL
|
149 DEFAULT_SOFTWARE_DEPTH_BITS
, 8,
157 int npfd
= sizeof(pfd
) / sizeof(pfd
[0]);
168 #define MESAWGL_CTX_MAX_COUNT 20
170 static MesaWglCtx wgl_ctx
[MESAWGL_CTX_MAX_COUNT
];
172 static unsigned ctx_count
= 0;
173 static int ctx_current
= -1;
174 static unsigned curPFD
= 0;
176 static HDC CurrentHDC
= 0;
179 WINGDIAPI HGLRC GLAPIENTRY
wglCreateContext(HDC hdc
)
183 for(i
=0;i
<MESAWGL_CTX_MAX_COUNT
;i
++) {
184 wgl_ctx
[i
].ctx
= NULL
;
187 for( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ ) {
188 if ( wgl_ctx
[i
].ctx
== NULL
) {
190 WMesaCreateContext(hdc
, NULL
, (GLboolean
)GL_TRUE
,
191 (GLboolean
) (pfd
[curPFD
-1].doubleBuffered
?
193 (GLboolean
)(pfd
[curPFD
-1].pfd
.cAlphaBits
?
194 GL_TRUE
: GL_FALSE
) );
195 if (wgl_ctx
[i
].ctx
== NULL
)
198 return ((HGLRC
)wgl_ctx
[i
].ctx
);
205 WINGDIAPI BOOL GLAPIENTRY
wglDeleteContext(HGLRC hglrc
)
208 for ( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ ) {
209 if ( wgl_ctx
[i
].ctx
== (WMesaContext
) hglrc
){
210 WMesaMakeCurrent((WMesaContext
) hglrc
, NULL
);
211 WMesaDestroyContext(wgl_ctx
[i
].ctx
);
212 wgl_ctx
[i
].ctx
= NULL
;
221 WINGDIAPI HGLRC GLAPIENTRY
wglGetCurrentContext(VOID
)
226 return (HGLRC
) wgl_ctx
[ctx_current
].ctx
;
229 WINGDIAPI HDC GLAPIENTRY
wglGetCurrentDC(VOID
)
234 WINGDIAPI BOOL GLAPIENTRY
wglMakeCurrent(HDC hdc
, HGLRC hglrc
)
240 if (!hdc
|| !hglrc
) {
241 WMesaMakeCurrent(NULL
, NULL
);
246 for ( i
= 0; i
< MESAWGL_CTX_MAX_COUNT
; i
++ ) {
247 if ( wgl_ctx
[i
].ctx
== (WMesaContext
) hglrc
) {
248 WMesaMakeCurrent( (WMesaContext
) hglrc
, hdc
);
257 WINGDIAPI
int GLAPIENTRY
wglChoosePixelFormat(HDC hdc
,
259 PIXELFORMATDESCRIPTOR
*ppfd
)
261 int i
,best
= -1,bestdelta
= 0x7FFFFFFF,delta
;
264 if(ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
) || ppfd
->nVersion
!= 1)
269 for(i
= 0; i
< npfd
;i
++)
273 (ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
) &&
274 !(pfd
[i
].pfd
.dwFlags
& PFD_DRAW_TO_WINDOW
))
277 (ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
) &&
278 !(pfd
[i
].pfd
.dwFlags
& PFD_DRAW_TO_BITMAP
))
281 (ppfd
->dwFlags
& PFD_SUPPORT_GDI
) &&
282 !(pfd
[i
].pfd
.dwFlags
& PFD_SUPPORT_GDI
))
285 (ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
) &&
286 !(pfd
[i
].pfd
.dwFlags
& PFD_SUPPORT_OPENGL
))
289 !(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
) &&
290 ((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) !=
291 (pfd
[i
].pfd
.dwFlags
& PFD_DOUBLEBUFFER
)))
294 !(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
) &&
295 ((ppfd
->dwFlags
& PFD_STEREO
) !=
296 (pfd
[i
].pfd
.dwFlags
& PFD_STEREO
)))
298 if(ppfd
->iPixelType
!= pfd
[i
].pfd
.iPixelType
)
300 if(ppfd
->cAlphaBits
!= pfd
[i
].pfd
.cAlphaBits
)
302 if(delta
< bestdelta
)
318 WINGDIAPI
int GLAPIENTRY
wglDescribePixelFormat(HDC hdc
,
321 LPPIXELFORMATDESCRIPTOR ppfd
)
327 if(iPixelFormat
< 1 || iPixelFormat
> npfd
||
328 nBytes
!= sizeof(PIXELFORMATDESCRIPTOR
))
333 *ppfd
= pfd
[iPixelFormat
- 1].pfd
;
337 WINGDIAPI PROC GLAPIENTRY
wglGetProcAddress(LPCSTR lpszProc
)
339 PROC p
= (PROC
) _glapi_get_proc_address((const char *) lpszProc
);
347 WINGDIAPI
int GLAPIENTRY
wglGetPixelFormat(HDC hdc
)
357 WINGDIAPI BOOL GLAPIENTRY
wglSetPixelFormat(HDC hdc
,int iPixelFormat
,
358 const PIXELFORMATDESCRIPTOR
*ppfd
)
362 if(iPixelFormat
< 1 || iPixelFormat
> npfd
||
363 ppfd
->nSize
!= sizeof(PIXELFORMATDESCRIPTOR
)) {
367 curPFD
= iPixelFormat
;
371 WINGDIAPI BOOL GLAPIENTRY
wglSwapBuffers(HDC hdc
)
373 WMesaSwapBuffers(hdc
);
377 static FIXED
FixedFromDouble(double d
)
379 long l
= (long) (d
* 65536L);
380 return *(FIXED
*) (void *) &l
;
385 ** This is cribbed from FX/fxwgl.c, and seems to implement support
386 ** for bitmap fonts where the wglUseFontBitmapsA() code implements
387 ** support for outline fonts. In combination they hopefully give
388 ** fairly generic support for fonts.
390 static BOOL
wglUseFontBitmaps_FX(HDC fontDevice
, DWORD firstChar
,
391 DWORD numChars
, DWORD listBase
)
401 VERIFY(GetTextMetrics(fontDevice
, &metric
));
403 dibInfo
= (BITMAPINFO
*) calloc(sizeof(BITMAPINFO
) + sizeof(RGBQUAD
), 1);
404 dibInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
405 dibInfo
->bmiHeader
.biPlanes
= 1;
406 dibInfo
->bmiHeader
.biBitCount
= 1;
407 dibInfo
->bmiHeader
.biCompression
= BI_RGB
;
409 bitDevice
= CreateCompatibleDC(fontDevice
);
411 /* Swap fore and back colors so the bitmap has the right polarity */
412 tempColor
= GetBkColor(bitDevice
);
413 SetBkColor(bitDevice
, GetTextColor(bitDevice
));
414 SetTextColor(bitDevice
, tempColor
);
416 /* Place chars based on base line */
417 VERIFY(SetTextAlign(bitDevice
, TA_BASELINE
) != GDI_ERROR
? 1 : 0);
419 for(i
= 0; i
< (int)numChars
; i
++) {
422 int charWidth
,charHeight
,bmapWidth
,bmapHeight
,numBytes
,res
;
427 curChar
= (char)(i
+ firstChar
);
429 /* Find how high/wide this character is */
430 VERIFY(GetTextExtentPoint32(bitDevice
, &curChar
, 1, &size
));
432 /* Create the output bitmap */
434 charHeight
= size
.cy
;
435 /* Round up to the next multiple of 32 bits */
436 bmapWidth
= ((charWidth
+ 31) / 32) * 32;
437 bmapHeight
= charHeight
;
438 bitObject
= CreateCompatibleBitmap(bitDevice
,
441 /* VERIFY(bitObject); */
443 /* Assign the output bitmap to the device */
444 origBmap
= SelectObject(bitDevice
, bitObject
);
445 (void) VERIFY(origBmap
);
447 VERIFY( PatBlt( bitDevice
, 0, 0, bmapWidth
, bmapHeight
,BLACKNESS
) );
449 /* Use our source font on the device */
450 VERIFY(SelectObject(bitDevice
, GetCurrentObject(fontDevice
,OBJ_FONT
)));
452 /* Draw the character */
453 VERIFY(TextOut(bitDevice
, 0, metric
.tmAscent
, &curChar
, 1));
455 /* Unselect our bmap object */
456 VERIFY(SelectObject(bitDevice
, origBmap
));
458 /* Convert the display dependant representation to a 1 bit deep DIB */
459 numBytes
= (bmapWidth
* bmapHeight
) / 8;
460 bmap
= malloc(numBytes
);
461 dibInfo
->bmiHeader
.biWidth
= bmapWidth
;
462 dibInfo
->bmiHeader
.biHeight
= bmapHeight
;
463 res
= GetDIBits(bitDevice
, bitObject
, 0, bmapHeight
, bmap
,
468 /* Create the GL object */
469 glNewList(i
+ listBase
, GL_COMPILE
);
470 glBitmap(bmapWidth
, bmapHeight
, 0.0, (GLfloat
)metric
.tmDescent
,
471 (GLfloat
)charWidth
, 0.0,
476 /* Destroy the bmap object */
477 DeleteObject(bitObject
);
479 /* Deallocate the bitmap data */
484 VERIFY(DeleteDC(bitDevice
));
492 WINGDIAPI BOOL GLAPIENTRY
wglUseFontBitmapsA(HDC hdc
, DWORD first
,
493 DWORD count
, DWORD listBase
)
507 font_list
= listBase
;
509 mat
.eM11
= FixedFromDouble(1);
510 mat
.eM12
= FixedFromDouble(0);
511 mat
.eM21
= FixedFromDouble(0);
512 mat
.eM22
= FixedFromDouble(-1);
514 memset(&gm
,0,sizeof(gm
));
517 ** If we can't get the glyph outline, it may be because this is a fixed
518 ** font. Try processing it that way.
520 if( GetGlyphOutline(hdc
, first
, GGO_BITMAP
, &gm
, 0, NULL
, &mat
)
522 return wglUseFontBitmaps_FX( hdc
, first
, count
, listBase
);
526 ** Otherwise process all desired characters.
528 for (i
= 0; i
< (int)count
; i
++) {
531 glNewList( font_list
+i
, GL_COMPILE
);
533 /* allocate space for the bitmap/outline */
534 size
= GetGlyphOutline(hdc
, first
+ i
, GGO_BITMAP
,
536 if (size
== GDI_ERROR
) {
538 err
= GetLastError();
543 hBits
= GlobalAlloc(GHND
, size
+1);
544 lpBits
= GlobalLock(hBits
);
547 GetGlyphOutline(hdc
, /* handle to device context */
548 first
+ i
, /* character to query */
549 GGO_BITMAP
, /* format of data to return */
550 &gm
, /* ptr to structure for metrics*/
551 size
, /* size of buffer for data */
552 lpBits
, /* pointer to buffer for data */
553 &mat
/* pointer to transformation */
554 /* matrix structure */
557 if (err
== GDI_ERROR
) {
562 err
= GetLastError();
567 glBitmap(gm
.gmBlackBoxX
,gm
.gmBlackBoxY
,
568 (GLfloat
)-gm
.gmptGlyphOrigin
.x
,
569 (GLfloat
)gm
.gmptGlyphOrigin
.y
,
570 (GLfloat
)gm
.gmCellIncX
,
571 (GLfloat
)gm
.gmCellIncY
,
572 (const GLubyte
* )lpBits
);
583 WINGDIAPI BOOL GLAPIENTRY
wglShareLists(HGLRC hglrc1
,
586 WMesaShareLists((WMesaContext
)hglrc1
, (WMesaContext
)hglrc2
);
592 /* NOT IMPLEMENTED YET */
593 WINGDIAPI BOOL GLAPIENTRY
wglCopyContext(HGLRC hglrcSrc
,
597 (void) hglrcSrc
; (void) hglrcDst
; (void) mask
;
601 WINGDIAPI HGLRC GLAPIENTRY
wglCreateLayerContext(HDC hdc
,
604 (void) hdc
; (void) iLayerPlane
;
610 WINGDIAPI BOOL GLAPIENTRY
wglUseFontBitmapsW(HDC hdc
,
615 (void) hdc
; (void) first
; (void) count
; (void) listBase
;
619 WINGDIAPI BOOL GLAPIENTRY
wglUseFontOutlinesA(HDC hdc
,
626 LPGLYPHMETRICSFLOAT lpgmf
)
628 (void) hdc
; (void) first
; (void) count
;
629 (void) listBase
; (void) deviation
; (void) extrusion
; (void) format
;
635 WINGDIAPI BOOL GLAPIENTRY
wglUseFontOutlinesW(HDC hdc
,
642 LPGLYPHMETRICSFLOAT lpgmf
)
644 (void) hdc
; (void) first
; (void) count
;
645 (void) listBase
; (void) deviation
; (void) extrusion
; (void) format
;
651 WINGDIAPI BOOL GLAPIENTRY
wglDescribeLayerPlane(HDC hdc
,
655 LPLAYERPLANEDESCRIPTOR plpd
)
657 (void) hdc
; (void) iPixelFormat
; (void) iLayerPlane
;
658 (void) nBytes
; (void) plpd
;
663 WINGDIAPI
int GLAPIENTRY
wglSetLayerPaletteEntries(HDC hdc
,
669 (void) hdc
; (void) iLayerPlane
; (void) iStart
;
670 (void) cEntries
; (void) pcr
;
675 WINGDIAPI
int GLAPIENTRY
wglGetLayerPaletteEntries(HDC hdc
,
681 (void) hdc
; (void) iLayerPlane
; (void) iStart
; (void) cEntries
; (void) pcr
;
686 WINGDIAPI BOOL GLAPIENTRY
wglRealizeLayerPalette(HDC hdc
,
690 (void) hdc
; (void) iLayerPlane
; (void) bRealize
;
695 WINGDIAPI BOOL GLAPIENTRY
wglSwapLayerBuffers(HDC hdc
,
698 (void) hdc
; (void) fuPlanes
;
703 WINGDIAPI
const char * GLAPIENTRY
wglGetExtensionsStringARB(HDC hdc
)
705 return "WGL_ARB_extensions_string";