• 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 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