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 BOOL APIENTRY
wglMakeCurrent(HDC hdc,HGLRC hglrc)103 wglMakeCurrent(
104 HDC hdc,
105 HGLRC hglrc )
106 {
107 return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
108 }
109
110
111 WINGDIAPI BOOL APIENTRY
wglSwapBuffers(HDC hdc)112 wglSwapBuffers(
113 HDC hdc )
114 {
115 return DrvSwapBuffers( hdc );
116 }
117
118
119 WINGDIAPI DWORD WINAPI
wglSwapMultipleBuffers(UINT n,CONST WGLSWAP * ps)120 wglSwapMultipleBuffers(UINT n,
121 CONST WGLSWAP *ps)
122 {
123 UINT i;
124
125 for (i =0; i < n; ++i)
126 wglSwapBuffers(ps->hdc);
127
128 return 0;
129 }
130
131
132 WINGDIAPI BOOL APIENTRY
wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)133 wglSwapLayerBuffers(
134 HDC hdc,
135 UINT fuPlanes )
136 {
137 return DrvSwapLayerBuffers( hdc, fuPlanes );
138 }
139
140 WINGDIAPI PROC APIENTRY
wglGetProcAddress(LPCSTR lpszProc)141 wglGetProcAddress(
142 LPCSTR lpszProc )
143 {
144 return DrvGetProcAddress( lpszProc );
145 }
146
147
148 WINGDIAPI int APIENTRY
wglChoosePixelFormat(HDC hdc,CONST PIXELFORMATDESCRIPTOR * ppfd)149 wglChoosePixelFormat(
150 HDC hdc,
151 CONST PIXELFORMATDESCRIPTOR *ppfd )
152 {
153 if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1)
154 return 0;
155 if (ppfd->iPixelType != PFD_TYPE_RGBA)
156 return 0;
157 if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW))
158 return 0;
159 if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL))
160 return 0;
161 if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP)
162 return 0;
163 if (ppfd->dwFlags & PFD_SUPPORT_GDI)
164 return 0;
165 if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO))
166 return 0;
167
168 return stw_pixelformat_choose( hdc, ppfd );
169 }
170
171 WINGDIAPI int APIENTRY
wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,LPPIXELFORMATDESCRIPTOR ppfd)172 wglDescribePixelFormat(
173 HDC hdc,
174 int iPixelFormat,
175 UINT nBytes,
176 LPPIXELFORMATDESCRIPTOR ppfd )
177 {
178 return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
179 }
180
181 WINGDIAPI int APIENTRY
wglGetPixelFormat(HDC hdc)182 wglGetPixelFormat(
183 HDC hdc )
184 {
185 return stw_pixelformat_get( hdc );
186 }
187
188 WINGDIAPI BOOL APIENTRY
wglSetPixelFormat(HDC hdc,int iPixelFormat,const PIXELFORMATDESCRIPTOR * ppfd)189 wglSetPixelFormat(
190 HDC hdc,
191 int iPixelFormat,
192 const PIXELFORMATDESCRIPTOR *ppfd )
193 {
194 /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
195 * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
196 */
197 (void) ppfd;
198
199 return DrvSetPixelFormat( hdc, iPixelFormat );
200 }
201
202
203 WINGDIAPI BOOL APIENTRY
wglUseFontBitmapsA(HDC hdc,DWORD first,DWORD count,DWORD listBase)204 wglUseFontBitmapsA(
205 HDC hdc,
206 DWORD first,
207 DWORD count,
208 DWORD listBase )
209 {
210 (void) hdc;
211 (void) first;
212 (void) count;
213 (void) listBase;
214
215 assert( 0 );
216
217 return FALSE;
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 (void) hdc;
237 (void) first;
238 (void) count;
239 (void) listBase;
240
241 assert( 0 );
242
243 return FALSE;
244 }
245
246 WINGDIAPI BOOL APIENTRY
wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)247 wglUseFontOutlinesA(
248 HDC hdc,
249 DWORD first,
250 DWORD count,
251 DWORD listBase,
252 FLOAT deviation,
253 FLOAT extrusion,
254 int format,
255 LPGLYPHMETRICSFLOAT lpgmf )
256 {
257 (void) hdc;
258 (void) first;
259 (void) count;
260 (void) listBase;
261 (void) deviation;
262 (void) extrusion;
263 (void) format;
264 (void) lpgmf;
265
266 assert( 0 );
267
268 return FALSE;
269 }
270
271 WINGDIAPI BOOL APIENTRY
wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,DWORD listBase,FLOAT deviation,FLOAT extrusion,int format,LPGLYPHMETRICSFLOAT lpgmf)272 wglUseFontOutlinesW(
273 HDC hdc,
274 DWORD first,
275 DWORD count,
276 DWORD listBase,
277 FLOAT deviation,
278 FLOAT extrusion,
279 int format,
280 LPGLYPHMETRICSFLOAT lpgmf )
281 {
282 (void) hdc;
283 (void) first;
284 (void) count;
285 (void) listBase;
286 (void) deviation;
287 (void) extrusion;
288 (void) format;
289 (void) lpgmf;
290
291 assert( 0 );
292
293 return FALSE;
294 }
295
296 WINGDIAPI BOOL APIENTRY
wglDescribeLayerPlane(HDC hdc,int iPixelFormat,int iLayerPlane,UINT nBytes,LPLAYERPLANEDESCRIPTOR plpd)297 wglDescribeLayerPlane(
298 HDC hdc,
299 int iPixelFormat,
300 int iLayerPlane,
301 UINT nBytes,
302 LPLAYERPLANEDESCRIPTOR plpd )
303 {
304 return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
305 }
306
307 WINGDIAPI int APIENTRY
wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,CONST COLORREF * pcr)308 wglSetLayerPaletteEntries(
309 HDC hdc,
310 int iLayerPlane,
311 int iStart,
312 int cEntries,
313 CONST COLORREF *pcr )
314 {
315 return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
316 }
317
318 WINGDIAPI int APIENTRY
wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,int iStart,int cEntries,COLORREF * pcr)319 wglGetLayerPaletteEntries(
320 HDC hdc,
321 int iLayerPlane,
322 int iStart,
323 int cEntries,
324 COLORREF *pcr )
325 {
326 return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
327 }
328
329 WINGDIAPI BOOL APIENTRY
wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)330 wglRealizeLayerPalette(
331 HDC hdc,
332 int iLayerPlane,
333 BOOL bRealize )
334 {
335 (void) hdc;
336 (void) iLayerPlane;
337 (void) bRealize;
338
339 assert( 0 );
340
341 return FALSE;
342 }
343
344
345 /* When this library is used as a opengl32.dll drop-in replacement, ensure we
346 * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll,
347 * which could happen if this library's name is not opengl32.dll exactly.
348 *
349 * For example, Qt 5.4 bundles this as opengl32sw.dll:
350 * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
351 */
352 static void
overrideOpenGL32EntryPoints(void)353 overrideOpenGL32EntryPoints(void)
354 {
355 wglCreateContext_func = &wglCreateContext;
356 wglDeleteContext_func = &wglDeleteContext;
357 }
358