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