Detect DCs without fonts and return an error in wglUseBitmapFonts.
[wine] / graphics / escape.c
1 /*
2  * Escape() function.
3  *
4  * Copyright 1994  Bob Amstadt
5  * Copyright 2001  Alexandre Julliard
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <string.h>
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "gdi.h"
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(driver);
29
30 /***********************************************************************
31  *            Escape  [GDI.38]
32  */
33 INT16 WINAPI Escape16( HDC16 hdc, INT16 escape, INT16 in_count,
34                        SEGPTR in_data, LPVOID out_data )
35 {
36     INT ret;
37
38     switch(escape)
39     {
40     /* Escape(hdc,CLIP_TO_PATH,LPINT16,NULL) */
41     /* Escape(hdc,DRAFTMODE,LPINT16,NULL) */
42     /* Escape(hdc,ENUMPAPERBINS,LPINT16,LPSTR); */
43     /* Escape(hdc,EPSPRINTING,LPINT16,NULL) */
44     /* Escape(hdc,EXT_DEVICE_CAPS,LPINT16,LPDWORD) */
45     /* Escape(hdc,GETCOLORTABLE,LPINT16,LPDWORD) */
46     /* Escape(hdc,MOUSETRAILS,LPINT16,NULL) */
47     /* Escape(hdc,POSTSCRIPT_IGNORE,LPINT16,NULL) */
48     /* Escape(hdc,QUERYESCSUPPORT,LPINT16,NULL) */
49     /* Escape(hdc,SET_ARC_DIRECTION,LPINT16,NULL) */
50     /* Escape(hdc,SET_POLY_MODE,LPINT16,NULL) */
51     /* Escape(hdc,SET_SCREEN_ANGLE,LPINT16,NULL) */
52     /* Escape(hdc,SET_SPREAD,LPINT16,NULL) */
53     case CLIP_TO_PATH:
54     case DRAFTMODE:
55     case ENUMPAPERBINS:
56     case EPSPRINTING:
57     case EXT_DEVICE_CAPS:
58     case GETCOLORTABLE:
59     case MOUSETRAILS:
60     case POSTSCRIPT_IGNORE:
61     case QUERYESCSUPPORT:
62     case SET_ARC_DIRECTION:
63     case SET_POLY_MODE:
64     case SET_SCREEN_ANGLE:
65     case SET_SPREAD:
66     {
67         INT16 *ptr = MapSL(in_data);
68         INT data = *ptr;
69         return Escape( hdc, escape, sizeof(data), (LPCSTR)&data, out_data );
70     }
71
72     /* Escape(hdc,ENABLEDUPLEX,LPUINT16,NULL) */
73     case ENABLEDUPLEX:
74     {
75         UINT16 *ptr = MapSL(in_data);
76         UINT data = *ptr;
77         return Escape( hdc, escape, sizeof(data), (LPCSTR)&data, NULL );
78     }
79
80     /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT16) */
81     /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT16) */
82     /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT16) */
83     case GETPHYSPAGESIZE:
84     case GETPRINTINGOFFSET:
85     case GETSCALINGFACTOR:
86     {
87         POINT16 *ptr = out_data;
88         POINT pt32;
89         ret = Escape( hdc, escape, 0, NULL, &pt32 );
90         ptr->x = pt32.x;
91         ptr->y = pt32.y;
92         return ret;
93     }
94
95     /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
96     /* Escape(hdc,ENABLERELATIVEWIDTHS,LPINT16,LPINT16); */
97     /* Escape(hdc,SETCOPYCOUNT,LPINT16,LPINT16) */
98     /* Escape(hdc,SETKERNTRACK,LPINT16,LPINT16) */
99     /* Escape(hdc,SETLINECAP,LPINT16,LPINT16) */
100     /* Escape(hdc,SETLINEJOIN,LPINT16,LPINT16) */
101     /* Escape(hdc,SETMITERLIMIT,LPINT16,LPINT16) */
102     case ENABLEPAIRKERNING:
103     case ENABLERELATIVEWIDTHS:
104     case SETCOPYCOUNT:
105     case SETKERNTRACK:
106     case SETLINECAP:
107     case SETLINEJOIN:
108     case SETMITERLIMIT:
109     {
110         INT16 *new = MapSL(in_data);
111         INT16 *old = out_data;
112         INT out, in = *new;
113         ret = Escape( hdc, escape, sizeof(in), (LPCSTR)&in, &out );
114         *old = out;
115         return ret;
116     }
117
118     /* Escape(hdc,SETABORTPROC,ABORTPROC,NULL); */
119     case SETABORTPROC:
120         return SetAbortProc16( hdc, (ABORTPROC16)in_data );
121
122     /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFO16);
123      * lpvOutData is actually a pointer to the DocInfo structure and used as
124      * a second input parameter */
125     case STARTDOC:
126         if (out_data)
127         {
128             ret = StartDoc16( hdc, out_data );
129             if (ret > 0) ret = StartPage( hdc );
130             return ret;
131         }
132         return Escape( hdc, escape, in_count, MapSL(in_data), NULL );
133
134     /* Escape(hdc,SET_BOUNDS,LPRECT16,NULL); */
135     /* Escape(hdc,SET_CLIP_BOX,LPRECT16,NULL); */
136     case SET_BOUNDS:
137     case SET_CLIP_BOX:
138     {
139         RECT16 *rc16 = MapSL(in_data);
140         RECT rc;
141         rc.left   = rc16->left;
142         rc.top    = rc16->top;
143         rc.right  = rc16->right;
144         rc.bottom = rc16->bottom;
145         return Escape( hdc, escape, sizeof(rc), (LPCSTR)&rc, NULL );
146     }
147
148     /* Escape(hdc,NEXTBAND,NULL,LPRECT16); */
149     case NEXTBAND:
150     {
151         RECT rc;
152         RECT16 *rc16 = out_data;
153         ret = Escape( hdc, escape, 0, NULL, &rc );
154         rc16->left   = rc.left;
155         rc16->top    = rc.top;
156         rc16->right  = rc.right;
157         rc16->bottom = rc.bottom;
158         return ret;
159     }
160
161     /* Escape(hdc,ABORTDOC,NULL,NULL); */
162     /* Escape(hdc,BANDINFO,BANDINFOSTRUCT*,BANDINFOSTRUCT*); */
163     /* Escape(hdc,BEGIN_PATH,NULL,NULL); */
164     /* Escape(hdc,DRAWPATTERNRECT,PRECT_STRUCT*,NULL); */
165     /* Escape(hdc,ENDDOC,NULL,NULL); */
166     /* Escape(hdc,END_PATH,PATHINFO,NULL); */
167     /* Escape(hdc,EXTTEXTOUT,EXTTEXT_STRUCT*,NULL); */
168     /* Escape(hdc,FLUSHOUTPUT,NULL,NULL); */
169     /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
170     /* Escape(hdc,GETPAIRKERNTABLE,NULL,KERNPAIR*); */
171     /* Escape(hdc,GETSETPAPERBINS,BinInfo*,BinInfo*); */
172     /* Escape(hdc,GETSETPRINTORIENT,ORIENT*,NULL); */
173     /* Escape(hdc,GETSETSCREENPARAMS,SCREENPARAMS*,SCREENPARAMS*); */
174     /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
175     /* Escape(hdc,GETTRACKKERNTABLE,NULL,KERNTRACK*); */
176     /* Escape(hdc,MFCOMMENT,LPSTR,NULL); */
177     /* Escape(hdc,NEWFRAME,NULL,NULL); */
178     /* Escape(hdc,PASSTHROUGH,LPSTR,NULL); */
179     /* Escape(hdc,RESTORE_CTM,NULL,NULL); */
180     /* Escape(hdc,SAVE_CTM,NULL,NULL); */
181     /* Escape(hdc,SETALLJUSTVALUES,EXTTEXTDATA*,NULL); */
182     /* Escape(hdc,SETCOLORTABLE,COLORTABLE_STRUCT*,LPDWORD); */
183     /* Escape(hdc,SET_BACKGROUND_COLOR,LPDWORD,LPDWORD); */
184     /* Escape(hdc,TRANSFORM_CTM,LPSTR,NULL); */
185     case ABORTDOC:
186     case BANDINFO:
187     case BEGIN_PATH:
188     case DRAWPATTERNRECT:
189     case ENDDOC:
190     case END_PATH:
191     case EXTTEXTOUT:
192     case FLUSHOUTPUT:
193     case GETFACENAME:
194     case GETPAIRKERNTABLE:
195     case GETSETPAPERBINS:
196     case GETSETPRINTORIENT:
197     case GETSETSCREENPARAMS:
198     case GETTECHNOLOGY:
199     case GETTRACKKERNTABLE:
200     case MFCOMMENT:
201     case NEWFRAME:
202     case PASSTHROUGH:
203     case RESTORE_CTM:
204     case SAVE_CTM:
205     case SETALLJUSTVALUES:
206     case SETCOLORTABLE:
207     case SET_BACKGROUND_COLOR:
208     case TRANSFORM_CTM:
209         /* pass it unmodified to the 32-bit function */
210         return Escape( hdc, escape, in_count, MapSL(in_data), out_data );
211
212     /* Escape(hdc,ENUMPAPERMETRICS,LPINT16,LPRECT16); */
213     /* Escape(hdc,GETEXTENDEDTEXTMETRICS,LPUINT16,EXTTEXTMETRIC*); */
214     /* Escape(hdc,GETEXTENTTABLE,LPSTR,LPINT16); */
215     /* Escape(hdc,GETSETPAPERMETRICS,LPRECT16,LPRECT16); */
216     /* Escape(hdc,GETVECTORBRUSHSIZE,LPLOGBRUSH16,LPPOINT16); */
217     /* Escape(hdc,GETVECTORPENSIZE,LPLOGPEN16,LPPOINT16); */
218     case ENUMPAPERMETRICS:
219     case GETEXTENDEDTEXTMETRICS:
220     case GETEXTENTTABLE:
221     case GETSETPAPERMETRICS:
222     case GETVECTORBRUSHSIZE:
223     case GETVECTORPENSIZE:
224     default:
225         FIXME("unknown/unsupported 16-bit escape %x (%d,%p,%p\n",
226               escape, in_count, MapSL(in_data), out_data );
227         return Escape( hdc, escape, in_count, MapSL(in_data), out_data );
228     }
229 }
230
231
232 /************************************************************************
233  *             Escape  [GDI32.@]
234  */
235 INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data )
236 {
237     INT ret;
238     POINT *pt;
239
240     switch (escape)
241     {
242     case ABORTDOC:
243         return AbortDoc( hdc );
244
245     case ENDDOC:
246         return EndDoc( hdc );
247
248     case GETPHYSPAGESIZE:
249         pt = out_data;
250         pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH );
251         pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT );
252         return 1;
253
254     case GETPRINTINGOFFSET:
255         pt = out_data;
256         pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX );
257         pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY );
258         return 1;
259
260     case GETSCALINGFACTOR:
261         pt = out_data;
262         pt->x = GetDeviceCaps( hdc, SCALINGFACTORX );
263         pt->y = GetDeviceCaps( hdc, SCALINGFACTORY );
264         return 1;
265
266     case NEWFRAME:
267         return EndPage( hdc );
268
269     case SETABORTPROC:
270         return SetAbortProc( hdc, (ABORTPROC)in_data );
271
272     case STARTDOC:
273         {
274             DOCINFOA doc;
275             char *name = NULL;
276
277             /* in_data may not be 0 terminated so we must copy it */
278             if (in_data)
279             {
280                 name = HeapAlloc( GetProcessHeap(), 0, in_count+1 );
281                 memcpy( name, in_data, in_count );
282                 name[in_count] = 0;
283             }
284             /* out_data is actually a pointer to the DocInfo structure and used as
285              * a second input parameter */
286             if (out_data) doc = *(DOCINFOA *)out_data;
287             else
288             {
289                 doc.cbSize = sizeof(doc);
290                 doc.lpszOutput = NULL;
291                 doc.lpszDatatype = NULL;
292                 doc.fwType = 0;
293             }
294             doc.lpszDocName = name;
295             ret = StartDocA( hdc, &doc );
296             if (name) HeapFree( GetProcessHeap(), 0, name );
297             if (ret > 0) ret = StartPage( hdc );
298             return ret;
299         }
300
301     case QUERYESCSUPPORT:
302         {
303             INT *ptr = (INT *)in_data;
304             if (in_count < sizeof(INT)) return 0;
305             switch(*ptr)
306             {
307             case ABORTDOC:
308             case ENDDOC:
309             case GETPHYSPAGESIZE:
310             case GETPRINTINGOFFSET:
311             case GETSCALINGFACTOR:
312             case NEWFRAME:
313             case QUERYESCSUPPORT:
314             case SETABORTPROC:
315             case STARTDOC:
316                 return TRUE;
317             }
318             break;
319         }
320     }
321
322     /* if not handled internally, pass it to the driver */
323     return ExtEscape( hdc, escape, in_count, in_data, 0, out_data );
324 }
325
326
327 /******************************************************************************
328  *              ExtEscape       [GDI32.@]
329  *
330  * PARAMS
331  *    hdc         [I] Handle to device context
332  *    nEscape     [I] Escape function
333  *    cbInput     [I] Number of bytes in input structure
334  *    lpszInData  [I] Pointer to input structure
335  *    cbOutput    [I] Number of bytes in output structure
336  *    lpszOutData [O] Pointer to output structure
337  *
338  * RETURNS
339  *    Success: >0
340  *    Not implemented: 0
341  *    Failure: <0
342  */
343 INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData,
344                       INT cbOutput, LPSTR lpszOutData )
345 {
346     INT ret = 0;
347     DC * dc = DC_GetDCPtr( hdc );
348     if (dc)
349     {
350         if (dc->funcs->pExtEscape)
351             ret = dc->funcs->pExtEscape( dc->physDev, nEscape, cbInput, lpszInData, cbOutput, lpszOutData );
352         GDI_ReleaseObj( hdc );
353     }
354     return ret;
355 }
356
357
358 /*******************************************************************
359  *      DrawEscape [GDI32.@]
360  *
361  *
362  */
363 INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
364 {
365     FIXME("DrawEscape, stub\n");
366     return 0;
367 }