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"
57 #include "main/config.h"
58 #include "glapi/glapi.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)
393 #define VERIFY(a) (void)(a)
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,
605 if (iLayerPlane == 0)
606 return wglCreateContext( hdc );
611 WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,
616 (void) hdc; (void) first; (void) count; (void) listBase;
620 WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,
627 LPGLYPHMETRICSFLOAT lpgmf)
629 (void) hdc; (void) first; (void) count;
630 (void) listBase; (void) deviation; (void) extrusion; (void) format;
636 WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,
643 LPGLYPHMETRICSFLOAT lpgmf)
645 (void) hdc; (void) first; (void) count;
646 (void) listBase; (void) deviation; (void) extrusion; (void) format;
652 WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,
656 LPLAYERPLANEDESCRIPTOR plpd)
658 (void) hdc; (void) iPixelFormat; (void) iLayerPlane;
659 (void) nBytes; (void) plpd;
664 WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,
670 (void) hdc; (void) iLayerPlane; (void) iStart;
671 (void) cEntries; (void) pcr;
676 WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,
682 (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr;
687 WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,
691 (void) hdc; (void) iLayerPlane; (void) bRealize;
696 WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,
699 (void) hdc; (void) fuPlanes;
704 WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc)
706 return "WGL_ARB_extensions_string";