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