It appears that StartDoc sends the STARTDOC escape with the DOCINFO
[wine] / graphics / escape.c
1 /*
2  * Escape() function.
3  *
4  * Copyright 1994  Bob Amstadt
5  */
6
7 #include <string.h>
8 #include "wingdi.h"
9 #include "gdi.h"
10 #include "heap.h"
11 #include "ldt.h"
12 #include "dc.h"
13 #include "debugtools.h"
14
15 DEFAULT_DEBUG_CHANNEL(driver)
16
17 /***********************************************************************
18  *            Escape16  [GDI.38]
19  */
20 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
21                        SEGPTR lpszInData, SEGPTR lpvOutData )
22 {
23     DC * dc = DC_GetDCPtr( hdc );
24     if (!dc || !dc->funcs->pEscape) return 0;
25     if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
26     return dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
27 }
28
29 /************************************************************************
30  *             Escape  [GDI32.200]
31  */
32 INT WINAPI Escape( HDC hdc, INT nEscape, INT cbInput,
33                    LPCSTR lpszInData, LPVOID lpvOutData )
34 {
35     SEGPTR      segin,segout;
36     INT ret;
37     DC * dc = DC_GetDCPtr( hdc );
38     if (!dc || !dc->funcs->pEscape) return 0;
39
40     segin       = (SEGPTR)lpszInData;
41     segout      = (SEGPTR)lpvOutData;
42     switch (nEscape) {
43         /* Escape(hdc,QUERYESCSUPPORT,LPINT,NULL) */
44         /* Escape(hdc,CLIP_TO_PATH,LPINT,NULL) */
45     case QUERYESCSUPPORT:
46     case CLIP_TO_PATH:
47       {
48         LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
49         *x = *(INT*)lpszInData;
50         segin = SEGPTR_GET(x);
51         cbInput = sizeof(INT16);
52         break;
53       }
54
55         /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
56         /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
57         /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */
58
59     case GETSCALINGFACTOR:
60     case GETPHYSPAGESIZE:
61     case GETPRINTINGOFFSET:
62         segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
63         cbInput = sizeof(POINT16);
64         break;
65
66         /* Escape(hdc,EXT_DEVICE_CAPS,LPINT,LPDWORD) */
67     case EXT_DEVICE_CAPS:
68       {
69         LPINT16 lpIndex = (LPINT16)SEGPTR_NEW(INT16);
70         LPDWORD lpCaps = (LPDWORD)SEGPTR_NEW(DWORD);
71         *lpIndex = *(INT*)lpszInData;
72         
73         segin = SEGPTR_GET(lpIndex);
74         segout = SEGPTR_GET(lpCaps);
75         cbInput = sizeof(INT16);
76         break;
77       }
78
79         /* Escape(hdc,SETLINECAP,LPINT,LPINT) */
80     case SETLINECAP:
81     case SETLINEJOIN:
82     case SETMITERLIMIT:
83       {
84         LPINT16 new = (LPINT16)SEGPTR_NEW(INT16);
85         LPINT16 old = (LPINT16)SEGPTR_NEW(INT16);
86         *new = *(INT*)lpszInData;
87         segin = SEGPTR_GET(new);
88         segout = SEGPTR_GET(old);
89         cbInput = sizeof(INT16);
90         break;
91       }
92       /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
93     case GETTECHNOLOGY: {
94         segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
95         break;
96
97     }
98
99       /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
100
101     case ENABLEPAIRKERNING: {
102         LPINT16 enab = SEGPTR_NEW(INT16);
103         segout = SEGPTR_GET(SEGPTR_NEW(INT16));
104         segin = SEGPTR_GET(enab);
105         *enab = *(INT*)lpszInData;
106         cbInput = sizeof(INT16);
107         break;
108     }
109
110       /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
111
112     case GETFACENAME: {
113         segout = SEGPTR_GET(SEGPTR_ALLOC(200));
114         break;
115     }
116
117       /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
118        * lpvOutData is actually a pointer to the DocInfo structure and used as
119        * a second input parameter
120        */
121
122     case STARTDOC: /* string may not be \0 terminated */
123         if(lpszInData) {
124             char *cp = SEGPTR_ALLOC(cbInput);
125             memcpy(cp, lpszInData, cbInput);
126             segin = SEGPTR_GET(cp);
127         } else
128             segin = 0;
129
130         if(lpvOutData) {
131             DOCINFO16 *lpsegdoc = SEGPTR_NEW(DOCINFO16);
132             DOCINFOA *lpdoc = lpvOutData;
133             memset(lpsegdoc, 0, sizeof(*lpsegdoc));
134             lpsegdoc->cbSize = sizeof(*lpsegdoc);
135             lpsegdoc->lpszDocName = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDocName));
136             lpsegdoc->lpszOutput = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszOutput));
137             lpsegdoc->lpszDatatype = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDatatype));
138             lpsegdoc->fwType = lpdoc->fwType;
139             segout = SEGPTR_GET(lpsegdoc);
140         }
141         break;
142
143     case SETABORTPROC:
144         SetAbortProc(hdc, (ABORTPROC)lpszInData);
145         break;
146
147       /* Escape(hdc,END_PATH,PATHINFO,NULL); */
148     case END_PATH:
149       {
150         BYTE *p = SEGPTR_ALLOC(cbInput);
151         memcpy(p, lpszInData, cbInput);
152         segin = SEGPTR_GET(p);
153         break;
154       }
155
156     default:
157         break;
158
159     }
160
161     ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
162
163     switch(nEscape) {
164     case QUERYESCSUPPORT:
165         if (ret)
166                 TRACE("target DC implements Escape %d\n",nEscape);
167         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
168         break;
169
170     case SETLINECAP:
171     case SETLINEJOIN:
172     case SETMITERLIMIT:
173         *(LPINT)lpvOutData = *(LPINT16)PTR_SEG_TO_LIN(segout);
174         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
175         SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
176         break;
177     case GETSCALINGFACTOR:
178     case GETPRINTINGOFFSET:
179     case GETPHYSPAGESIZE: {
180         LPPOINT16 x = (LPPOINT16)PTR_SEG_TO_LIN(segout);
181         CONV_POINT16TO32(x,(LPPOINT)lpvOutData);
182         SEGPTR_FREE(x);
183         break;
184     }
185     case EXT_DEVICE_CAPS:
186         *(LPDWORD)lpvOutData = *(LPDWORD)PTR_SEG_TO_LIN(segout);
187         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
188         SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
189         break;
190
191     case GETTECHNOLOGY: {
192         LPSTR x=PTR_SEG_TO_LIN(segout);
193         lstrcpyA(lpvOutData,x);
194         SEGPTR_FREE(x);
195         break;
196     }
197     case ENABLEPAIRKERNING: {
198         LPINT16 enab = (LPINT16)PTR_SEG_TO_LIN(segout);
199
200         *(LPINT)lpvOutData = *enab;
201         SEGPTR_FREE(enab);
202         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
203         break;
204     }
205     case GETFACENAME: {
206         LPSTR x = (LPSTR)PTR_SEG_TO_LIN(segout);
207         lstrcpyA(lpvOutData,x);
208         SEGPTR_FREE(x);
209         break;
210     }
211     case STARTDOC: {
212         DOCINFO16 *doc = PTR_SEG_TO_LIN(segout);
213         SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDocName));
214         SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszOutput));
215         SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDatatype));
216         SEGPTR_FREE(doc);
217         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
218         break;
219     }
220
221     case CLIP_TO_PATH:
222     case END_PATH:
223         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
224         break;
225
226     default:
227         break;
228     }
229     return ret;
230 }
231
232 /******************************************************************************
233  *              ExtEscape       [GDI32.95]
234  *
235  * PARAMS
236  *    hdc         [I] Handle to device context
237  *    nEscape     [I] Escape function
238  *    cbInput     [I] Number of bytes in input structure
239  *    lpszInData  [I] Pointer to input structure
240  *    cbOutput    [I] Number of bytes in output structure
241  *    lpszOutData [O] Pointer to output structure
242  *
243  * RETURNS
244  *    Success: >0
245  *    Not implemented: 0
246  *    Failure: <0
247  */
248 INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput, 
249                       LPCSTR lpszInData, INT cbOutput, LPSTR lpszOutData )
250 {
251     char *inBuf, *outBuf;
252     INT ret;
253
254     inBuf = SEGPTR_ALLOC(cbInput);
255     memcpy(inBuf, lpszInData, cbInput);
256     outBuf = cbOutput ? SEGPTR_ALLOC(cbOutput) : NULL;
257     ret = Escape16( hdc, nEscape, cbInput, SEGPTR_GET(inBuf),
258                     SEGPTR_GET(outBuf) );
259     SEGPTR_FREE(inBuf);
260     if(outBuf) {
261         memcpy(lpszOutData, outBuf, cbOutput);
262         SEGPTR_FREE(outBuf);
263     }
264     return ret;
265 }
266
267 /*******************************************************************
268  *      DrawEscape [GDI32.74]
269  *
270  *
271  */
272 INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
273 {
274     FIXME("DrawEscape, stub\n");
275     return 0;
276 }