• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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