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 gallium frontend.
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 #include <GL/gl.h>
43
44 #include "util/u_debug.h"
45 #include "gldrv.h"
46 #include "stw_context.h"
47 #include "stw_pixelformat.h"
48 #include "stw_wgl.h"
49 #include "stw_ext_context.h"
50
51
52 static void
53 overrideOpenGL32EntryPoints(void);
54
55 WINGDIAPI BOOL APIENTRY
wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)56 wglCopyContext(
57 HGLRC hglrcSrc,
58 HGLRC hglrcDst,
59 UINT mask )
60 {
61 return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc,
62 (DHGLRC)(UINT_PTR)hglrcDst,
63 mask );
64 }
65
66 WINGDIAPI HGLRC APIENTRY
wglCreateContext(HDC hdc)67 wglCreateContext(
68 HDC hdc )
69 {
70 overrideOpenGL32EntryPoints();
71 return (HGLRC)(UINT_PTR)DrvCreateContext(hdc);
72 }
73
74 WINGDIAPI HGLRC APIENTRY
wglCreateLayerContext(HDC hdc,int iLayerPlane)75 wglCreateLayerContext(
76 HDC hdc,
77 int iLayerPlane )
78 {
79 overrideOpenGL32EntryPoints();
80 return (HGLRC)(UINT_PTR)DrvCreateLayerContext( hdc, iLayerPlane );
81 }
82
83 WINGDIAPI BOOL APIENTRY
wglDeleteContext(HGLRC hglrc)84 wglDeleteContext(
85 HGLRC hglrc )
86 {
87 return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
88 }
89
90
91 WINGDIAPI HGLRC APIENTRY
wglGetCurrentContext(VOID)92 wglGetCurrentContext( VOID )
93 {
94 return (HGLRC)(UINT_PTR)stw_get_current_context();
95 }
96
97 WINGDIAPI HDC APIENTRY
wglGetCurrentDC(VOID)98 wglGetCurrentDC( VOID )
99 {
100 return stw_get_current_dc();
101 }
102
103 WINGDIAPI HDC APIENTRY
wglGetCurrentReadDCARB(VOID)104 wglGetCurrentReadDCARB( VOID )
105 {
106 return stw_get_current_read_dc();
107 }
108
109
110 WINGDIAPI BOOL APIENTRY
wglMakeCurrent(HDC hdc,HGLRC hglrc)111 wglMakeCurrent(
112 HDC hdc,
113 HGLRC hglrc )
114 {
115 return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
116 }
117
118
119 WINGDIAPI BOOL APIENTRY
wglSwapBuffers(HDC hdc)120 wglSwapBuffers(
121 HDC hdc )
122 {
123 return DrvSwapBuffers( hdc );
124 }
125
126
127 WINGDIAPI DWORD WINAPI
wglSwapMultipleBuffers(UINT n,CONST WGLSWAP * ps)128 wglSwapMultipleBuffers(UINT n,
129 CONST WGLSWAP *ps)
130 {
131 UINT i;
132
133 for (i =0; i < n; ++i)
134 wglSwapBuffers(ps->hdc);
135
136 return 0;
137 }
138
139
140 WINGDIAPI BOOL APIENTRY
wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)141 wglSwapLayerBuffers(
142 HDC hdc,
143 UINT fuPlanes )
144 {
145 return DrvSwapLayerBuffers( hdc, fuPlanes );
146 }
147
148 WINGDIAPI PROC APIENTRY
wglGetProcAddress(LPCSTR lpszProc)149 wglGetProcAddress(
150 LPCSTR lpszProc )
151 {
152 return DrvGetProcAddress( lpszProc );
153 }
154
155
156 WINGDIAPI int APIENTRY
wglChoosePixelFormat(HDC hdc,CONST PIXELFORMATDESCRIPTOR * ppfd)157 wglChoosePixelFormat(
158 HDC hdc,
159 CONST PIXELFORMATDESCRIPTOR *ppfd )
160 {
161 if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1)
162 return 0;
163 if (ppfd->iPixelType != PFD_TYPE_RGBA)
164 return 0;
165 if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW))
166 return 0;
167 if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL))
168 return 0;
169 if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP)
170 return 0;
171 if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO))
172 return 0;
173
174 return stw_pixelformat_choose( hdc, ppfd );
175 }
176
177 WINGDIAPI int APIENTRY
wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,LPPIXELFORMATDESCRIPTOR ppfd)178 wglDescribePixelFormat(
179 HDC hdc,
180 int iPixelFormat,
181 UINT nBytes,
182 LPPIXELFORMATDESCRIPTOR ppfd )
183 {
184 return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
185 }
186
187 WINGDIAPI int APIENTRY
wglGetPixelFormat(HDC hdc)188 wglGetPixelFormat(
189 HDC hdc )
190 {
191 return stw_pixelformat_get( hdc );
192 }
193
194 WINGDIAPI BOOL APIENTRY
wglSetPixelFormat(HDC hdc,int iPixelFormat,const PIXELFORMATDESCRIPTOR * ppfd)195 wglSetPixelFormat(
196 HDC hdc,
197 int iPixelFormat,
198 const PIXELFORMATDESCRIPTOR *ppfd )
199 {
200 /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
201 * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
202 */
203 (void) ppfd;
204
205 return DrvSetPixelFormat( hdc, iPixelFormat );
206 }
207
208
209 WINGDIAPI BOOL APIENTRY
wglUseFontBitmapsA(HDC hdc,DWORD first,DWORD count,DWORD listBase)210 wglUseFontBitmapsA(
211 HDC hdc,
212 DWORD first,
213 DWORD count,
214 DWORD listBase )
215 {
216 return wglUseFontBitmapsW(hdc, first, count, listBase);
217 }
218
219 WINGDIAPI BOOL APIENTRY
wglShareLists(HGLRC hglrc1,HGLRC hglrc2)220 wglShareLists(
221 HGLRC hglrc1,
222 HGLRC hglrc2 )
223 {
224 return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1,
225 (DHGLRC)(UINT_PTR)hglrc2);
226 }
227
228 WINGDIAPI BOOL APIENTRY
wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)229 wglUseFontBitmapsW(
230 HDC hdc,
231 DWORD first,
232 DWORD count,
233 DWORD listBase )
234 {
235 GLYPHMETRICS gm;
236 MAT2 tra;
237 FIXED one, minus_one, zero;
238 void *buffer = NULL;
239 BOOL result = TRUE;
240
241 one.value = 1;
242 one.fract = 0;
243 minus_one.value = -1;
244 minus_one.fract = 0;
245 zero.value = 0;
246 zero.fract = 0;
247
248 tra.eM11 = one;
249 tra.eM22 = minus_one;
250 tra.eM12 = tra.eM21 = zero;
251
252 for (int i = 0; i < count; i++) {
253 DWORD size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0,
254 NULL, &tra);
255
256 glNewList(listBase + i, GL_COMPILE);
257
258 if (size != GDI_ERROR) {
259 if (size == 0) {
260 glBitmap(0, 0, (GLfloat)-gm.gmptGlyphOrigin.x,
261 (GLfloat)gm.gmptGlyphOrigin.y,
262 (GLfloat)gm.gmCellIncX,
263 (GLfloat)gm.gmCellIncY, NULL);
264 }
265 else {
266 buffer = realloc(buffer, size);
267 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm,
268 size, buffer, &tra);
269
270 glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
271 -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y,
272 gm.gmCellIncX, gm.gmCellIncY, buffer);
273 }
274 }
275 else {
276 result = FALSE;
277 }
278
279 glEndList();
280 }
281
282 free(buffer);
283
284 return result;
285 }
286
287 WINGDIAPI BOOL APIENTRY
wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)288 wglUseFontOutlinesA(
289 HDC hdc,
290 DWORD first,
291 DWORD count,
292 DWORD listBase,
293 FLOAT deviation,
294 FLOAT extrusion,
295 int format,
296 LPGLYPHMETRICSFLOAT lpgmf )
297 {
298 (void) hdc;
299 (void) first;
300 (void) count;
301 (void) listBase;
302 (void) deviation;
303 (void) extrusion;
304 (void) format;
305 (void) lpgmf;
306
307 assert( 0 );
308
309 return FALSE;
310 }
311
312 WINGDIAPI BOOL APIENTRY
wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)313 wglUseFontOutlinesW(
314 HDC hdc,
315 DWORD first,
316 DWORD count,
317 DWORD listBase,
318 FLOAT deviation,
319 FLOAT extrusion,
320 int format,
321 LPGLYPHMETRICSFLOAT lpgmf )
322 {
323 (void) hdc;
324 (void) first;
325 (void) count;
326 (void) listBase;
327 (void) deviation;
328 (void) extrusion;
329 (void) format;
330 (void) lpgmf;
331
332 assert( 0 );
333
334 return FALSE;
335 }
336
337 WINGDIAPI BOOL APIENTRY
wglDescribeLayerPlane(HDC hdc,int iPixelFormat,int iLayerPlane,UINT nBytes,LPLAYERPLANEDESCRIPTOR plpd)338 wglDescribeLayerPlane(
339 HDC hdc,
340 int iPixelFormat,
341 int iLayerPlane,
342 UINT nBytes,
343 LPLAYERPLANEDESCRIPTOR plpd )
344 {
345 return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
346 }
347
348 WINGDIAPI int APIENTRY
wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,CONST COLORREF * pcr)349 wglSetLayerPaletteEntries(
350 HDC hdc,
351 int iLayerPlane,
352 int iStart,
353 int cEntries,
354 CONST COLORREF *pcr )
355 {
356 return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
357 }
358
359 WINGDIAPI int APIENTRY
wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,COLORREF * pcr)360 wglGetLayerPaletteEntries(
361 HDC hdc,
362 int iLayerPlane,
363 int iStart,
364 int cEntries,
365 COLORREF *pcr )
366 {
367 return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
368 }
369
370 WINGDIAPI BOOL APIENTRY
wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)371 wglRealizeLayerPalette(
372 HDC hdc,
373 int iLayerPlane,
374 BOOL bRealize )
375 {
376 (void) hdc;
377 (void) iLayerPlane;
378 (void) bRealize;
379
380 assert( 0 );
381
382 return FALSE;
383 }
384
385
386 /* When this library is used as a opengl32.dll drop-in replacement, ensure we
387 * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll,
388 * which could happen if this library's name is not opengl32.dll exactly.
389 *
390 * For example, Qt 5.4 bundles this as opengl32sw.dll:
391 * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
392 */
393 static void
overrideOpenGL32EntryPoints(void)394 overrideOpenGL32EntryPoints(void)
395 {
396 wglCreateContext_func = &wglCreateContext;
397 wglDeleteContext_func = &wglDeleteContext;
398 }
399