gdi32: Quote the printer name prior to passing it to the shell.
[wine] / dlls / gdi32 / opengl.c
1 /*
2  * OpenGL function forwarding to the display driver
3  *
4  * Copyright (c) 1999 Lionel Ulmer
5  * Copyright (c) 2005 Raphael Junqueira
6  * Copyright (c) 2006 Roderick Colenbrander
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <stdarg.h>
27 #include <string.h>
28 #include <stdlib.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winerror.h"
34 #include "winternl.h"
35 #include "winnt.h"
36 #include "gdi_private.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
40
41 static HDC default_hdc = 0;
42
43 typedef struct opengl_context
44 {
45     HDC hdc;
46 } *OPENGL_Context;
47
48 /* We route all wgl functions from opengl32.dll through gdi32.dll to
49  * the display driver. Various wgl calls have a hDC as one of their parameters.
50  * Using DC_GetDCPtr we get access to the functions exported by the driver.
51  * Some functions don't receive a hDC. This function creates a global hdc and
52  * if there's already a global hdc, it returns it.
53  */
54 static DC* OPENGL_GetDefaultDC(void)
55 {
56     if(!default_hdc)
57         default_hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
58         
59     return DC_GetDCPtr(default_hdc);
60 }
61
62 /***********************************************************************
63  *              wglCreateContext (OPENGL32.@)
64  */
65 HGLRC WINAPI wglCreateContext(HDC hdc)
66 {
67     HGLRC ret = 0;
68     DC * dc = DC_GetDCPtr( hdc );
69
70     TRACE("(%p)\n",hdc);
71
72     if (!dc) return 0;
73
74     if (!dc->funcs->pwglCreateContext) FIXME(" :stub\n");
75     else ret = dc->funcs->pwglCreateContext(dc->physDev);
76
77     DC_ReleaseDCPtr( dc );
78     return ret;
79 }
80
81
82 /***********************************************************************
83  *              wglDeleteContext (OPENGL32.@)
84  */
85 BOOL WINAPI wglDeleteContext(HGLRC hglrc)
86 {
87     DC *dc;
88     BOOL ret = FALSE;
89     OPENGL_Context ctx = (OPENGL_Context)hglrc;
90
91     TRACE("hglrc: (%p)\n", hglrc);
92     if(ctx == NULL)
93         return FALSE;
94
95     /* Retrieve the HDC associated with the context to access the display driver */
96     dc = DC_GetDCPtr(ctx->hdc);
97     if (!dc) return FALSE;
98
99     if (!dc->funcs->pwglDeleteContext) FIXME(" :stub\n");
100     else ret = dc->funcs->pwglDeleteContext(hglrc);
101
102     DC_ReleaseDCPtr( dc );
103     return ret;
104 }
105
106 /***********************************************************************
107  *              wglGetCurrentContext (OPENGL32.@)
108  */
109 HGLRC WINAPI wglGetCurrentContext(void)
110 {
111     HGLRC ret = NtCurrentTeb()->glContext;
112     TRACE(" returning %p\n", ret);
113     return ret;
114 }
115
116 /***********************************************************************
117  *              wglGetCurrentDC (OPENGL32.@)
118  */
119 HDC WINAPI wglGetCurrentDC(void)
120 {
121     OPENGL_Context ctx = (OPENGL_Context)wglGetCurrentContext();
122
123     TRACE(" found context: %p\n", ctx);
124     if(ctx == NULL)
125         return NULL;
126
127     /* Retrieve the current DC from the active context */
128     TRACE(" returning hdc: %p\n", ctx->hdc);
129     return ctx->hdc;
130 }
131
132 /***********************************************************************
133  *              wglGetPbufferDCARB
134  */
135 static HDC WINAPI wglGetPbufferDCARB(void *pbuffer)
136 {
137     HDC ret = 0;
138
139     /* Create a device context to associate with the pbuffer */
140     HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
141     DC *dc = DC_GetDCPtr(hdc);
142
143     TRACE("(%p)\n", pbuffer);
144
145     if (!dc) return FALSE;
146
147     /* The display driver has to do the rest of the work because
148      * we need access to lowlevel datatypes which we can't access here
149      */
150     if (!dc->funcs->pwglGetPbufferDCARB) FIXME(" :stub\n");
151     else ret = dc->funcs->pwglGetPbufferDCARB(dc->physDev, pbuffer);
152
153     TRACE("(%p), hdc=%p\n", pbuffer, ret);
154     
155     DC_ReleaseDCPtr( dc );
156     return ret;
157 }
158
159 /***********************************************************************
160  *              wglMakeCurrent (OPENGL32.@)
161  */
162 BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
163 {
164     BOOL ret = FALSE;
165     DC * dc = NULL;
166
167     /* When the context hglrc is NULL, the HDC is ignored and can be NULL.
168      * In that case use the global hDC to get access to the driver.  */
169     if(hglrc == NULL)
170         dc = OPENGL_GetDefaultDC();
171     else
172         dc = DC_GetDCUpdate( hdc );
173
174     TRACE("hdc: (%p), hglrc: (%p)\n", hdc, hglrc);
175
176     if (!dc) return FALSE;
177
178     if (!dc->funcs->pwglMakeCurrent) FIXME(" :stub\n");
179     else ret = dc->funcs->pwglMakeCurrent(dc->physDev,hglrc);
180
181     DC_ReleaseDCPtr( dc );
182     return ret;
183 }
184
185 /***********************************************************************
186  *              wglMakeContextCurrentARB
187  */
188 static BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
189 {
190     BOOL ret = FALSE;
191     DC *DrawDC;
192     DC *ReadDC;
193
194     TRACE("hDrawDC: (%p), hReadDC: (%p) hglrc: (%p)\n", hDrawDC, hReadDC, hglrc);
195
196     /* Both hDrawDC and hReadDC need to be valid */
197     DrawDC = DC_GetDCPtr( hDrawDC);
198     if (!DrawDC) return FALSE;
199
200     ReadDC = DC_GetDCPtr( hReadDC);
201     if (!ReadDC) {
202         DC_ReleaseDCPtr(DrawDC);
203         return FALSE;
204     }
205
206     if (!DrawDC->funcs->pwglMakeContextCurrentARB) FIXME(" :stub\n");
207     else ret = DrawDC->funcs->pwglMakeContextCurrentARB(DrawDC->physDev, ReadDC->physDev, hglrc);
208
209     DC_ReleaseDCPtr(DrawDC);
210     DC_ReleaseDCPtr(ReadDC);
211
212     return ret;
213 }
214
215 /***********************************************************************
216  *              wglShareLists (OPENGL32.@)
217  */
218 BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
219 {
220     DC *dc;
221     BOOL ret = FALSE;
222     OPENGL_Context ctx = (OPENGL_Context)hglrc1;
223
224     TRACE("hglrc1: (%p); hglrc: (%p)\n", hglrc1, hglrc2);
225     if(ctx == NULL)
226         return FALSE;
227     
228     /* Retrieve the HDC associated with the context to access the display driver */
229     dc = DC_GetDCPtr(ctx->hdc);
230     if (!dc) return FALSE;
231
232     if (!dc->funcs->pwglShareLists) FIXME(" :stub\n");
233     else ret = dc->funcs->pwglShareLists(hglrc1, hglrc2);
234
235     DC_ReleaseDCPtr( dc );
236     return ret;
237 }
238
239 /***********************************************************************
240  *              wglUseFontBitmapsA (OPENGL32.@)
241  */
242 BOOL WINAPI wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase)
243 {
244     BOOL ret = FALSE;
245     DC * dc = DC_GetDCPtr( hdc );
246
247     TRACE("(%p, %d, %d, %d)\n", hdc, first, count, listBase);
248
249     if (!dc) return FALSE;
250
251     if (!dc->funcs->pwglUseFontBitmapsA) FIXME(" :stub\n");
252     else ret = dc->funcs->pwglUseFontBitmapsA(dc->physDev, first, count, listBase);
253
254     DC_ReleaseDCPtr( dc );
255     return ret;
256 }
257
258 /***********************************************************************
259  *              wglUseFontBitmapsW (OPENGL32.@)
260  */
261 BOOL WINAPI wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase)
262 {
263     BOOL ret = FALSE;
264     DC * dc = DC_GetDCPtr( hdc );
265
266     TRACE("(%p, %d, %d, %d)\n", hdc, first, count, listBase);
267
268     if (!dc) return FALSE;
269
270     if (!dc->funcs->pwglUseFontBitmapsW) FIXME(" :stub\n");
271     else ret = dc->funcs->pwglUseFontBitmapsW(dc->physDev, first, count, listBase);
272
273     DC_ReleaseDCPtr( dc );
274     return ret;
275 }
276
277 /***********************************************************************
278  *              Internal wglGetProcAddress for retrieving WGL extensions
279  */
280 PROC WINAPI wglGetProcAddress(LPCSTR func)
281 {
282     PROC ret = NULL;
283     DC *dc;
284
285     if(!func)
286         return NULL;
287
288     TRACE("func: '%p'\n", func);
289
290     /* Retrieve the global hDC to get access to the driver.  */
291     dc = OPENGL_GetDefaultDC();
292     if (!dc) return FALSE;
293
294     if (!dc->funcs->pwglGetProcAddress) FIXME(" :stub\n");
295     else ret = dc->funcs->pwglGetProcAddress(func);
296
297     DC_ReleaseDCPtr( dc );
298
299     /* At the moment we implement one WGL extension which requires a HDC. When we
300      * are looking up this call and when the Extension is available (that is the case
301      * when a non-NULL value is returned by wglGetProcAddress), we return the address
302      * of a wrapper function which will handle the HDC->PhysDev conversion.
303      */
304     if(ret && strcmp(func, "wglMakeContextCurrentARB") == 0)
305         return (PROC)wglMakeContextCurrentARB;
306     else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0)
307         return (PROC)wglGetPbufferDCARB;
308
309     return ret;
310 }