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
wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)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
wglCreateContext(HDC hdc)66 wglCreateContext(
67 HDC hdc )
68 {
69 overrideOpenGL32EntryPoints();
70 return (HGLRC) DrvCreateContext(hdc);
71 }
72
73 WINGDIAPI HGLRC APIENTRY
wglCreateLayerContext(HDC hdc,int iLayerPlane)74 wglCreateLayerContext(
75 HDC hdc,
76 int iLayerPlane )
77 {
78 overrideOpenGL32EntryPoints();
79 return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
80 }
81
82 WINGDIAPI BOOL APIENTRY
wglDeleteContext(HGLRC hglrc)83 wglDeleteContext(
84 HGLRC hglrc )
85 {
86 return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
87 }
88
89
90 WINGDIAPI HGLRC APIENTRY
wglGetCurrentContext(VOID)91 wglGetCurrentContext( VOID )
92 {
93 return (HGLRC)(UINT_PTR)stw_get_current_context();
94 }
95
96 WINGDIAPI HDC APIENTRY
wglGetCurrentDC(VOID)97 wglGetCurrentDC( VOID )
98 {
99 return stw_get_current_dc();
100 }
101
102 WINGDIAPI HDC APIENTRY
wglGetCurrentReadDCARB(VOID)103 wglGetCurrentReadDCARB( VOID )
104 {
105 return stw_get_current_read_dc();
106 }
107
108
109 WINGDIAPI BOOL APIENTRY
wglMakeCurrent(HDC hdc,HGLRC hglrc)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
wglSwapBuffers(HDC hdc)119 wglSwapBuffers(
120 HDC hdc )
121 {
122 return DrvSwapBuffers( hdc );
123 }
124
125
126 WINGDIAPI DWORD WINAPI
wglSwapMultipleBuffers(UINT n,CONST WGLSWAP * ps)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
wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)140 wglSwapLayerBuffers(
141 HDC hdc,
142 UINT fuPlanes )
143 {
144 return DrvSwapLayerBuffers( hdc, fuPlanes );
145 }
146
147 WINGDIAPI PROC APIENTRY
wglGetProcAddress(LPCSTR lpszProc)148 wglGetProcAddress(
149 LPCSTR lpszProc )
150 {
151 return DrvGetProcAddress( lpszProc );
152 }
153
154
155 WINGDIAPI int APIENTRY
wglChoosePixelFormat(HDC hdc,CONST PIXELFORMATDESCRIPTOR * ppfd)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
wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,LPPIXELFORMATDESCRIPTOR ppfd)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
wglGetPixelFormat(HDC hdc)189 wglGetPixelFormat(
190 HDC hdc )
191 {
192 return stw_pixelformat_get( hdc );
193 }
194
195 WINGDIAPI BOOL APIENTRY
wglSetPixelFormat(HDC hdc,int iPixelFormat,const PIXELFORMATDESCRIPTOR * ppfd)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
wglUseFontBitmapsA(HDC hdc,DWORD first,DWORD count,DWORD listBase)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
wglShareLists(HGLRC hglrc1,HGLRC hglrc2)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
wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)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
wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)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
wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)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
wglDescribeLayerPlane(HDC hdc,int iPixelFormat,int iLayerPlane,UINT nBytes,LPLAYERPLANEDESCRIPTOR plpd)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
wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,CONST COLORREF * pcr)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
wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,COLORREF * pcr)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
wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)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
overrideOpenGL32EntryPoints(void)393 overrideOpenGL32EntryPoints(void)
394 {
395 wglCreateContext_func = &wglCreateContext;
396 wglDeleteContext_func = &wglDeleteContext;
397 }
398