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