1 /************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /** 29 * @file 30 * 31 * Fake WGL API implementation. 32 * 33 * These functions implement the WGL API, on top of the ICD DDI, so that the 34 * resulting DLL can be used as a drop-in replacement for the system's 35 * opengl32.dll. 36 * 37 * These functions never get called for ICD drivers, which use exclusively the 38 * ICD DDI, i.e., the Drv* entrypoints. 39 */ 40 41 #include <windows.h> 42 43 #include "util/u_debug.h" 44 #include "stw_icd.h" 45 #include "stw_context.h" 46 #include "stw_pixelformat.h" 47 #include "stw_wgl.h" 48 #include "stw_ext_context.h" 49 50 51 static void 52 overrideOpenGL32EntryPoints(void); 53 54 WINGDIAPI BOOL APIENTRY 55 wglCopyContext( 56 HGLRC hglrcSrc, 57 HGLRC hglrcDst, 58 UINT mask ) 59 { 60 return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc, 61 (DHGLRC)(UINT_PTR)hglrcDst, 62 mask ); 63 } 64 65 WINGDIAPI HGLRC APIENTRY 66 wglCreateContext( 67 HDC hdc ) 68 { 69 overrideOpenGL32EntryPoints(); 70 return (HGLRC) DrvCreateContext(hdc); 71 } 72 73 WINGDIAPI HGLRC APIENTRY 74 wglCreateLayerContext( 75 HDC hdc, 76 int iLayerPlane ) 77 { 78 overrideOpenGL32EntryPoints(); 79 return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane ); 80 } 81 82 WINGDIAPI BOOL APIENTRY 83 wglDeleteContext( 84 HGLRC hglrc ) 85 { 86 return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc ); 87 } 88 89 90 WINGDIAPI HGLRC APIENTRY 91 wglGetCurrentContext( VOID ) 92 { 93 return (HGLRC)(UINT_PTR)stw_get_current_context(); 94 } 95 96 WINGDIAPI HDC APIENTRY 97 wglGetCurrentDC( VOID ) 98 { 99 return stw_get_current_dc(); 100 } 101 102 WINGDIAPI HDC APIENTRY 103 wglGetCurrentReadDCARB( VOID ) 104 { 105 return stw_get_current_read_dc(); 106 } 107 108 109 WINGDIAPI BOOL APIENTRY 110 wglMakeCurrent( 111 HDC hdc, 112 HGLRC hglrc ) 113 { 114 return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE; 115 } 116 117 118 WINGDIAPI BOOL APIENTRY 119 wglSwapBuffers( 120 HDC hdc ) 121 { 122 return DrvSwapBuffers( hdc ); 123 } 124 125 126 WINGDIAPI DWORD WINAPI 127 wglSwapMultipleBuffers(UINT n, 128 CONST WGLSWAP *ps) 129 { 130 UINT i; 131 132 for (i =0; i < n; ++i) 133 wglSwapBuffers(ps->hdc); 134 135 return 0; 136 } 137 138 139 WINGDIAPI BOOL APIENTRY 140 wglSwapLayerBuffers( 141 HDC hdc, 142 UINT fuPlanes ) 143 { 144 return DrvSwapLayerBuffers( hdc, fuPlanes ); 145 } 146 147 WINGDIAPI PROC APIENTRY 148 wglGetProcAddress( 149 LPCSTR lpszProc ) 150 { 151 return DrvGetProcAddress( lpszProc ); 152 } 153 154 155 WINGDIAPI int APIENTRY 156 wglChoosePixelFormat( 157 HDC hdc, 158 CONST PIXELFORMATDESCRIPTOR *ppfd ) 159 { 160 if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1) 161 return 0; 162 if (ppfd->iPixelType != PFD_TYPE_RGBA) 163 return 0; 164 if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW)) 165 return 0; 166 if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL)) 167 return 0; 168 if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) 169 return 0; 170 if (ppfd->dwFlags & PFD_SUPPORT_GDI) 171 return 0; 172 if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO)) 173 return 0; 174 175 return stw_pixelformat_choose( hdc, ppfd ); 176 } 177 178 WINGDIAPI int APIENTRY 179 wglDescribePixelFormat( 180 HDC hdc, 181 int iPixelFormat, 182 UINT nBytes, 183 LPPIXELFORMATDESCRIPTOR ppfd ) 184 { 185 return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd ); 186 } 187 188 WINGDIAPI int APIENTRY 189 wglGetPixelFormat( 190 HDC hdc ) 191 { 192 return stw_pixelformat_get( hdc ); 193 } 194 195 WINGDIAPI BOOL APIENTRY 196 wglSetPixelFormat( 197 HDC hdc, 198 int iPixelFormat, 199 const PIXELFORMATDESCRIPTOR *ppfd ) 200 { 201 /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per 202 * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx 203 */ 204 (void) ppfd; 205 206 return DrvSetPixelFormat( hdc, iPixelFormat ); 207 } 208 209 210 WINGDIAPI BOOL APIENTRY 211 wglUseFontBitmapsA( 212 HDC hdc, 213 DWORD first, 214 DWORD count, 215 DWORD listBase ) 216 { 217 return wglUseFontBitmapsW(hdc, first, count, listBase); 218 } 219 220 WINGDIAPI BOOL APIENTRY 221 wglShareLists( 222 HGLRC hglrc1, 223 HGLRC hglrc2 ) 224 { 225 return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1, 226 (DHGLRC)(UINT_PTR)hglrc2); 227 } 228 229 WINGDIAPI BOOL APIENTRY 230 wglUseFontBitmapsW( 231 HDC hdc, 232 DWORD first, 233 DWORD count, 234 DWORD listBase ) 235 { 236 GLYPHMETRICS gm; 237 MAT2 tra; 238 FIXED one, minus_one, zero; 239 void *buffer = NULL; 240 BOOL result = TRUE; 241 242 one.value = 1; 243 one.fract = 0; 244 minus_one.value = -1; 245 minus_one.fract = 0; 246 zero.value = 0; 247 zero.fract = 0; 248 249 tra.eM11 = one; 250 tra.eM22 = minus_one; 251 tra.eM12 = tra.eM21 = zero; 252 253 for (int i = 0; i < count; i++) { 254 DWORD size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, 255 NULL, &tra); 256 257 glNewList(listBase + i, GL_COMPILE); 258 259 if (size != GDI_ERROR) { 260 if (size == 0) { 261 glBitmap(0, 0, -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y, 262 gm.gmCellIncX, gm.gmCellIncY, NULL); 263 } 264 else { 265 buffer = realloc(buffer, size); 266 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 267 size, buffer, &tra); 268 269 glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, 270 -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y, 271 gm.gmCellIncX, gm.gmCellIncY, buffer); 272 } 273 } 274 else { 275 result = FALSE; 276 } 277 278 glEndList(); 279 } 280 281 free(buffer); 282 283 return result; 284 } 285 286 WINGDIAPI BOOL APIENTRY 287 wglUseFontOutlinesA( 288 HDC hdc, 289 DWORD first, 290 DWORD count, 291 DWORD listBase, 292 FLOAT deviation, 293 FLOAT extrusion, 294 int format, 295 LPGLYPHMETRICSFLOAT lpgmf ) 296 { 297 (void) hdc; 298 (void) first; 299 (void) count; 300 (void) listBase; 301 (void) deviation; 302 (void) extrusion; 303 (void) format; 304 (void) lpgmf; 305 306 assert( 0 ); 307 308 return FALSE; 309 } 310 311 WINGDIAPI BOOL APIENTRY 312 wglUseFontOutlinesW( 313 HDC hdc, 314 DWORD first, 315 DWORD count, 316 DWORD listBase, 317 FLOAT deviation, 318 FLOAT extrusion, 319 int format, 320 LPGLYPHMETRICSFLOAT lpgmf ) 321 { 322 (void) hdc; 323 (void) first; 324 (void) count; 325 (void) listBase; 326 (void) deviation; 327 (void) extrusion; 328 (void) format; 329 (void) lpgmf; 330 331 assert( 0 ); 332 333 return FALSE; 334 } 335 336 WINGDIAPI BOOL APIENTRY 337 wglDescribeLayerPlane( 338 HDC hdc, 339 int iPixelFormat, 340 int iLayerPlane, 341 UINT nBytes, 342 LPLAYERPLANEDESCRIPTOR plpd ) 343 { 344 return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); 345 } 346 347 WINGDIAPI int APIENTRY 348 wglSetLayerPaletteEntries( 349 HDC hdc, 350 int iLayerPlane, 351 int iStart, 352 int cEntries, 353 CONST COLORREF *pcr ) 354 { 355 return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); 356 } 357 358 WINGDIAPI int APIENTRY 359 wglGetLayerPaletteEntries( 360 HDC hdc, 361 int iLayerPlane, 362 int iStart, 363 int cEntries, 364 COLORREF *pcr ) 365 { 366 return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); 367 } 368 369 WINGDIAPI BOOL APIENTRY 370 wglRealizeLayerPalette( 371 HDC hdc, 372 int iLayerPlane, 373 BOOL bRealize ) 374 { 375 (void) hdc; 376 (void) iLayerPlane; 377 (void) bRealize; 378 379 assert( 0 ); 380 381 return FALSE; 382 } 383 384 385 /* When this library is used as a opengl32.dll drop-in replacement, ensure we 386 * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll, 387 * which could happen if this library's name is not opengl32.dll exactly. 388 * 389 * For example, Qt 5.4 bundles this as opengl32sw.dll: 390 * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/ 391 */ 392 static void 393 overrideOpenGL32EntryPoints(void) 394 { 395 wglCreateContext_func = &wglCreateContext; 396 wglDeleteContext_func = &wglDeleteContext; 397 } 398