Home | History | Annotate | Download | only in gdi
      1 
      2 /*
      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.
      7  *
      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.
     12  *
     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.
     16  *
     17  */
     18 
     19 /*
     20  * File name 	: wgl.c
     21  * WGL stuff. Added by Oleg Letsinsky, ajl (at) ultersys.ru
     22  * Some things originated from the 3Dfx WGL functions
     23  */
     24 
     25 /*
     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.
     29  */
     30 
     31 
     32 #include <windows.h>
     33 
     34 #include "main/config.h"
     35 #include "glapi/glapi.h"
     36 #include "swrast/swrast.h"
     37 #include "GL/wmesa.h"   /* protos for wmesa* functions */
     38 
     39 /*
     40  * Pixel Format Descriptors
     41  */
     42 
     43 /* Extend the PFD to include DB flag */
     44 struct __pixelformat__
     45 {
     46     PIXELFORMATDESCRIPTOR pfd;
     47     GLboolean doubleBuffered;
     48 };
     49 
     50 
     51 
     52 /* These are the PFD's supported by this driver. */
     53 struct __pixelformat__	pfd[] =
     54 {
     55 #if 0
     56     /* Double Buffer, alpha */
     57     {
     58 	{
     59 	    sizeof(PIXELFORMATDESCRIPTOR),	1,
     60 	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
     61 	    PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
     62 	    PFD_TYPE_RGBA,
     63 	    24,
     64 	    8, 0,
     65 	    8, 8,
     66 	    8, 16,
     67 	    8, 24,
     68 	    0, 0, 0, 0, 0,
     69 	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,
     70 	    0, 0, 0,
     71 	    0, 0, 0
     72 	},
     73         GL_TRUE
     74     },
     75     /* Single Buffer, alpha */
     76     {
     77 	{
     78 	    sizeof(PIXELFORMATDESCRIPTOR),	1,
     79 	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
     80 	    PFD_GENERIC_FORMAT,
     81 	    PFD_TYPE_RGBA,
     82 	    24,
     83 	    8, 0,
     84 	    8, 8,
     85 	    8, 16,
     86 	    8, 24,
     87 	    0, 0, 0, 0,	0,
     88 	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,
     89 	    0, 0, 0,
     90 	    0, 0, 0
     91 	},
     92         GL_FALSE
     93     },
     94 #endif
     95     /* Double Buffer, no alpha */
     96     {
     97 	{
     98 	    sizeof(PIXELFORMATDESCRIPTOR),	1,
     99 	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
    100 	    PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
    101 	    PFD_TYPE_RGBA,
    102 	    24,
    103 	    8, 0,
    104 	    8, 8,
    105 	    8, 16,
    106 	    0, 0,
    107 	    0, 0, 0, 0,	0,
    108 	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,
    109 	    0, 0, 0,
    110 	    0, 0, 0
    111 	},
    112         GL_TRUE
    113     },
    114     /* Single Buffer, no alpha */
    115     {
    116 	{
    117 	    sizeof(PIXELFORMATDESCRIPTOR),	1,
    118 	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
    119 	    PFD_GENERIC_FORMAT,
    120 	    PFD_TYPE_RGBA,
    121 	    24,
    122 	    8, 0,
    123 	    8, 8,
    124 	    8, 16,
    125 	    0, 0,
    126 	    0, 0, 0, 0,	0,
    127 	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,
    128 	    0, 0, 0,
    129 	    0, 0, 0
    130 	},
    131         GL_FALSE
    132     },
    133 };
    134 
    135 int npfd = sizeof(pfd) / sizeof(pfd[0]);
    136 
    137 
    138 /*
    139  * Contexts
    140  */
    141 
    142 typedef struct {
    143     WMesaContext ctx;
    144 } MesaWglCtx;
    145 
    146 #define MESAWGL_CTX_MAX_COUNT 20
    147 
    148 static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];
    149 
    150 static unsigned ctx_count = 0;
    151 static int ctx_current = -1;
    152 static unsigned curPFD = 0;
    153 
    154 static HDC CurrentHDC = 0;
    155 
    156 
    157 WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
    158 {
    159     int i = 0;
    160     if (!ctx_count) {
    161 	for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) {
    162 	    wgl_ctx[i].ctx = NULL;
    163 	}
    164     }
    165     for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
    166         if ( wgl_ctx[i].ctx == NULL ) {
    167             wgl_ctx[i].ctx =
    168 		WMesaCreateContext(hdc, NULL, (GLboolean)GL_TRUE,
    169 				   (GLboolean) (pfd[curPFD-1].doubleBuffered ?
    170                                    GL_TRUE : GL_FALSE),
    171 				   (GLboolean)(pfd[curPFD-1].pfd.cAlphaBits ?
    172 				   GL_TRUE : GL_FALSE) );
    173             if (wgl_ctx[i].ctx == NULL)
    174                 break;
    175             ctx_count++;
    176             return ((HGLRC)wgl_ctx[i].ctx);
    177         }
    178     }
    179     SetLastError(0);
    180     return(NULL);
    181 }
    182 
    183 WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
    184 {
    185     int i;
    186     for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
    187     	if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ){
    188             WMesaMakeCurrent((WMesaContext) hglrc, NULL);
    189             WMesaDestroyContext(wgl_ctx[i].ctx);
    190             wgl_ctx[i].ctx = NULL;
    191             ctx_count--;
    192             return(TRUE);
    193     	}
    194     }
    195     SetLastError(0);
    196     return(FALSE);
    197 }
    198 
    199 WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
    200 {
    201     if (ctx_current < 0)
    202 	return 0;
    203     else
    204 	return (HGLRC) wgl_ctx[ctx_current].ctx;
    205 }
    206 
    207 WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
    208 {
    209     return CurrentHDC;
    210 }
    211 
    212 WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc)
    213 {
    214     int i;
    215 
    216     CurrentHDC = hdc;
    217 
    218     if (!hdc || !hglrc) {
    219 	WMesaMakeCurrent(NULL, NULL);
    220 	ctx_current = -1;
    221 	return TRUE;
    222     }
    223 
    224     for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
    225 	if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ) {
    226 	    WMesaMakeCurrent( (WMesaContext) hglrc, hdc );
    227 	    ctx_current = i;
    228 	    return TRUE;
    229 	}
    230     }
    231     return FALSE;
    232 }
    233 
    234 
    235 WINGDIAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
    236 					      CONST
    237 					      PIXELFORMATDESCRIPTOR *ppfd)
    238 {
    239     int		i,best = -1,bestdelta = 0x7FFFFFFF,delta;
    240     (void) hdc;
    241 
    242     if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
    243 	{
    244 	    SetLastError(0);
    245 	    return(0);
    246 	}
    247     for(i = 0; i < npfd;i++)
    248 	{
    249 	    delta = 0;
    250 	    if(
    251 		(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
    252 		!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
    253 		continue;
    254 	    if(
    255 		(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
    256 		!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
    257 		continue;
    258 	    if(
    259 		(ppfd->dwFlags & PFD_SUPPORT_GDI) &&
    260 		!(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI))
    261 		continue;
    262 	    if(
    263 		(ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
    264 		!(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
    265 		continue;
    266 	    if(
    267 		!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
    268 		((ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
    269 		 (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
    270 		continue;
    271 	    if(
    272 		!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
    273 		((ppfd->dwFlags & PFD_STEREO) !=
    274 		 (pfd[i].pfd.dwFlags & PFD_STEREO)))
    275 		continue;
    276 	    if(ppfd->iPixelType != pfd[i].pfd.iPixelType)
    277 		delta++;
    278 	    if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits)
    279 		delta++;
    280 	    if(delta < bestdelta)
    281 		{
    282 		    best = i + 1;
    283 		    bestdelta = delta;
    284 		    if(bestdelta == 0)
    285 			break;
    286 		}
    287 	}
    288     if(best == -1)
    289 	{
    290 	    SetLastError(0);
    291 	    return(0);
    292 	}
    293     return(best);
    294 }
    295 
    296 WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,
    297 					        int iPixelFormat,
    298 					        UINT nBytes,
    299 					        LPPIXELFORMATDESCRIPTOR ppfd)
    300 {
    301     (void) hdc;
    302 
    303     if(ppfd == NULL)
    304 	return(npfd);
    305     if(iPixelFormat < 1 || iPixelFormat > npfd ||
    306        nBytes != sizeof(PIXELFORMATDESCRIPTOR))
    307 	{
    308 	    SetLastError(0);
    309 	    return(0);
    310 	}
    311     *ppfd = pfd[iPixelFormat - 1].pfd;
    312     return(npfd);
    313 }
    314 
    315 WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
    316 {
    317     PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
    318     if (p)
    319 	return p;
    320 
    321     SetLastError(0);
    322     return(NULL);
    323 }
    324 
    325 WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
    326 {
    327     (void) hdc;
    328     if(curPFD == 0) {
    329 	SetLastError(0);
    330 	return(0);
    331     }
    332     return(curPFD);
    333 }
    334 
    335 WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
    336 					const PIXELFORMATDESCRIPTOR *ppfd)
    337 {
    338     (void) hdc;
    339 
    340     /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
    341      * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
    342      */
    343     (void) ppfd;
    344 
    345     if(iPixelFormat < 1 || iPixelFormat > npfd) {
    346 	SetLastError(0);
    347 	return(FALSE);
    348     }
    349     curPFD = iPixelFormat;
    350     return(TRUE);
    351 }
    352 
    353 WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
    354 {
    355     WMesaSwapBuffers(hdc);
    356     return TRUE;
    357 }
    358 
    359 static FIXED FixedFromDouble(double d)
    360 {
    361    long l = (long) (d * 65536L);
    362    return *(FIXED *) (void *) &l;
    363 }
    364 
    365 
    366 /*
    367 ** This is cribbed from FX/fxwgl.c, and seems to implement support
    368 ** for bitmap fonts where the wglUseFontBitmapsA() code implements
    369 ** support for outline fonts.  In combination they hopefully give
    370 ** fairly generic support for fonts.
    371 */
    372 static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
    373                                  DWORD numChars, DWORD listBase)
    374 {
    375 #define VERIFY(a) (void)(a)
    376 
    377     TEXTMETRIC metric;
    378     BITMAPINFO *dibInfo;
    379     HDC bitDevice;
    380     COLORREF tempColor;
    381     int i;
    382 
    383     VERIFY(GetTextMetrics(fontDevice, &metric));
    384 
    385     dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
    386     dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    387     dibInfo->bmiHeader.biPlanes = 1;
    388     dibInfo->bmiHeader.biBitCount = 1;
    389     dibInfo->bmiHeader.biCompression = BI_RGB;
    390 
    391     bitDevice = CreateCompatibleDC(fontDevice);
    392 
    393     /* Swap fore and back colors so the bitmap has the right polarity */
    394     tempColor = GetBkColor(bitDevice);
    395     SetBkColor(bitDevice, GetTextColor(bitDevice));
    396     SetTextColor(bitDevice, tempColor);
    397 
    398     /* Place chars based on base line */
    399     VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0);
    400 
    401     for(i = 0; i < (int)numChars; i++) {
    402 	SIZE size;
    403 	char curChar;
    404 	int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
    405 	HBITMAP bitObject;
    406 	HGDIOBJ origBmap;
    407 	unsigned char *bmap;
    408 
    409 	curChar = (char)(i + firstChar);
    410 
    411 	/* Find how high/wide this character is */
    412 	VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
    413 
    414 	/* Create the output bitmap */
    415 	charWidth = size.cx;
    416 	charHeight = size.cy;
    417 	/* Round up to the next multiple of 32 bits */
    418 	bmapWidth = ((charWidth + 31) / 32) * 32;
    419 	bmapHeight = charHeight;
    420 	bitObject = CreateCompatibleBitmap(bitDevice,
    421 					   bmapWidth,
    422 					   bmapHeight);
    423 	/* VERIFY(bitObject); */
    424 
    425 	/* Assign the output bitmap to the device */
    426 	origBmap = SelectObject(bitDevice, bitObject);
    427 	(void) VERIFY(origBmap);
    428 
    429 	VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
    430 
    431 	/* Use our source font on the device */
    432 	VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
    433 
    434 	/* Draw the character */
    435 	VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
    436 
    437 	/* Unselect our bmap object */
    438 	VERIFY(SelectObject(bitDevice, origBmap));
    439 
    440 	/* Convert the display dependant representation to a 1 bit deep DIB */
    441 	numBytes = (bmapWidth * bmapHeight) / 8;
    442 	bmap = malloc(numBytes);
    443 	dibInfo->bmiHeader.biWidth = bmapWidth;
    444 	dibInfo->bmiHeader.biHeight = bmapHeight;
    445 	res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
    446 			dibInfo,
    447 			DIB_RGB_COLORS);
    448 	/* VERIFY(res); */
    449 
    450 	/* Create the GL object */
    451 	glNewList(i + listBase, GL_COMPILE);
    452 	glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent,
    453 		 (GLfloat)charWidth, 0.0,
    454 		 bmap);
    455 	glEndList();
    456 	/* CheckGL(); */
    457 
    458 	/* Destroy the bmap object */
    459 	DeleteObject(bitObject);
    460 
    461 	/* Deallocate the bitmap data */
    462 	free(bmap);
    463     }
    464 
    465     /* Destroy the DC */
    466     VERIFY(DeleteDC(bitDevice));
    467 
    468     free(dibInfo);
    469 
    470     return TRUE;
    471 #undef VERIFY
    472 }
    473 
    474 WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first,
    475 					     DWORD count, DWORD listBase)
    476 {
    477     int i;
    478     GLuint font_list;
    479     DWORD size;
    480     GLYPHMETRICS gm;
    481     HANDLE hBits;
    482     LPSTR lpBits;
    483     MAT2 mat;
    484     int  success = TRUE;
    485 
    486     if (count == 0)
    487 	return FALSE;
    488 
    489     font_list = listBase;
    490 
    491     mat.eM11 = FixedFromDouble(1);
    492     mat.eM12 = FixedFromDouble(0);
    493     mat.eM21 = FixedFromDouble(0);
    494     mat.eM22 = FixedFromDouble(-1);
    495 
    496     memset(&gm,0,sizeof(gm));
    497 
    498     /*
    499     ** If we can't get the glyph outline, it may be because this is a fixed
    500     ** font.  Try processing it that way.
    501     */
    502     if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat)
    503 	== GDI_ERROR ) {
    504 	return wglUseFontBitmaps_FX( hdc, first, count, listBase );
    505     }
    506 
    507     /*
    508     ** Otherwise process all desired characters.
    509     */
    510     for (i = 0; i < (int)count; i++) {
    511 	DWORD err;
    512 
    513 	glNewList( font_list+i, GL_COMPILE );
    514 
    515 	/* allocate space for the bitmap/outline */
    516 	size = GetGlyphOutline(hdc, first + i, GGO_BITMAP,
    517 			       &gm, 0, NULL, &mat);
    518 	if (size == GDI_ERROR) {
    519 	    glEndList( );
    520 	    err = GetLastError();
    521 	    success = FALSE;
    522 	    continue;
    523 	}
    524 
    525 	hBits  = GlobalAlloc(GHND, size+1);
    526 	lpBits = GlobalLock(hBits);
    527 
    528 	err =
    529 	    GetGlyphOutline(hdc,         /* handle to device context */
    530 			    first + i,   /* character to query */
    531 			    GGO_BITMAP,  /* format of data to return */
    532 			    &gm,         /* ptr to structure for metrics*/
    533 			    size,        /* size of buffer for data */
    534 			    lpBits,      /* pointer to buffer for data */
    535 			    &mat         /* pointer to transformation */
    536 			    /* matrix structure */
    537 		);
    538 
    539 	if (err == GDI_ERROR) {
    540 	    GlobalUnlock(hBits);
    541 	    GlobalFree(hBits);
    542 
    543 	    glEndList( );
    544 	    err = GetLastError();
    545 	    success = FALSE;
    546 	    continue;
    547 	}
    548 
    549 	glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
    550 		 (GLfloat)-gm.gmptGlyphOrigin.x,
    551 		 (GLfloat)gm.gmptGlyphOrigin.y,
    552 		 (GLfloat)gm.gmCellIncX,
    553 		 (GLfloat)gm.gmCellIncY,
    554 		 (const GLubyte * )lpBits);
    555 
    556 	GlobalUnlock(hBits);
    557 	GlobalFree(hBits);
    558 
    559 	glEndList( );
    560     }
    561 
    562     return success;
    563 }
    564 
    565 WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,
    566 					HGLRC hglrc2)
    567 {
    568     WMesaShareLists((WMesaContext)hglrc1, (WMesaContext)hglrc2);
    569     return(TRUE);
    570 }
    571 
    572 
    573 
    574 /* NOT IMPLEMENTED YET */
    575 WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,
    576 					 HGLRC hglrcDst,
    577 					 UINT mask)
    578 {
    579     (void) hglrcSrc; (void) hglrcDst; (void) mask;
    580     return(FALSE);
    581 }
    582 
    583 WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,
    584 						 int iLayerPlane)
    585 {
    586     SetLastError(0);
    587     if (iLayerPlane == 0)
    588         return wglCreateContext( hdc );
    589     return(NULL);
    590 }
    591 
    592 
    593 WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,
    594 					     DWORD first,
    595 					     DWORD count,
    596 					     DWORD listBase)
    597 {
    598     (void) hdc; (void) first; (void) count; (void) listBase;
    599     return FALSE;
    600 }
    601 
    602 WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,
    603 					      DWORD first,
    604 					      DWORD count,
    605 					      DWORD listBase,
    606 					      FLOAT deviation,
    607 					      FLOAT extrusion,
    608 					      int format,
    609 					      LPGLYPHMETRICSFLOAT lpgmf)
    610 {
    611     (void) hdc; (void) first; (void) count;
    612     (void) listBase; (void) deviation; (void) extrusion; (void) format;
    613     (void) lpgmf;
    614     SetLastError(0);
    615     return(FALSE);
    616 }
    617 
    618 WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,
    619 					      DWORD first,
    620 					      DWORD count,
    621 					      DWORD listBase,
    622 					      FLOAT deviation,
    623 					      FLOAT extrusion,
    624 					      int format,
    625 					      LPGLYPHMETRICSFLOAT lpgmf)
    626 {
    627     (void) hdc; (void) first; (void) count;
    628     (void) listBase; (void) deviation; (void) extrusion; (void) format;
    629     (void) lpgmf;
    630     SetLastError(0);
    631     return(FALSE);
    632 }
    633 
    634 WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,
    635 						int iPixelFormat,
    636 						int iLayerPlane,
    637 						UINT nBytes,
    638 						LPLAYERPLANEDESCRIPTOR plpd)
    639 {
    640     (void) hdc; (void) iPixelFormat; (void) iLayerPlane;
    641     (void) nBytes; (void) plpd;
    642     SetLastError(0);
    643     return(FALSE);
    644 }
    645 
    646 WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,
    647 						   int iLayerPlane,
    648 						   int iStart,
    649 						   int cEntries,
    650 						   CONST COLORREF *pcr)
    651 {
    652     (void) hdc; (void) iLayerPlane; (void) iStart;
    653     (void) cEntries; (void) pcr;
    654     SetLastError(0);
    655     return(0);
    656 }
    657 
    658 WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,
    659 						   int iLayerPlane,
    660 						   int iStart,
    661 						   int cEntries,
    662 						   COLORREF *pcr)
    663 {
    664     (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr;
    665     SetLastError(0);
    666     return(0);
    667 }
    668 
    669 WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,
    670 						 int iLayerPlane,
    671 						 BOOL bRealize)
    672 {
    673     (void) hdc; (void) iLayerPlane; (void) bRealize;
    674     SetLastError(0);
    675     return(FALSE);
    676 }
    677 
    678 WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,
    679 					      UINT fuPlanes)
    680 {
    681     (void) hdc; (void) fuPlanes;
    682     SetLastError(0);
    683     return(FALSE);
    684 }
    685 
    686 WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc)
    687 {
    688     return "WGL_ARB_extensions_string";
    689 }
    690