Fixed 0/-1 mixup for indicating no mapping handle.
[wine/multimedia.git] / graphics / escape.c
blobcc1b315f3af945f4919c44ea252d8dc01bce6b02
1 /*
2 * Escape() function.
4 * Copyright 1994 Bob Amstadt
5 */
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"
15 DEFAULT_DEBUG_CHANNEL(driver);
17 /***********************************************************************
18 * Escape16 [GDI.38]
20 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
21 SEGPTR lpszInData, SEGPTR lpvOutData )
23 INT16 ret = 0;
24 DC * dc = DC_GetDCPtr( hdc );
25 if (dc)
27 if (dc->funcs->pEscape)
29 if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
30 ret = dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
32 GDI_ReleaseObj( hdc );
34 return ret;
37 /************************************************************************
38 * Escape [GDI32.200]
40 INT WINAPI Escape( HDC hdc, INT nEscape, INT cbInput,
41 LPCSTR lpszInData, LPVOID lpvOutData )
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;
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:
57 LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
58 *x = *(INT*)lpszInData;
59 segin = SEGPTR_GET(x);
60 cbInput = sizeof(INT16);
61 break;
64 /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
65 /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
66 /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */
68 case GETSCALINGFACTOR:
69 case GETPHYSPAGESIZE:
70 case GETPRINTINGOFFSET:
71 segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
72 cbInput = sizeof(POINT16);
73 break;
75 /* Escape(hdc,EXT_DEVICE_CAPS,LPINT,LPDWORD) */
76 case EXT_DEVICE_CAPS:
78 LPINT16 lpIndex = (LPINT16)SEGPTR_NEW(INT16);
79 LPDWORD lpCaps = (LPDWORD)SEGPTR_NEW(DWORD);
80 *lpIndex = *(INT*)lpszInData;
82 segin = SEGPTR_GET(lpIndex);
83 segout = SEGPTR_GET(lpCaps);
84 cbInput = sizeof(INT16);
85 break;
88 /* Escape(hdc,SETLINECAP,LPINT,LPINT) */
89 case SETLINECAP:
90 case SETLINEJOIN:
91 case SETMITERLIMIT:
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;
101 /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
102 case GETTECHNOLOGY: {
103 segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
104 break;
108 /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
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;
119 /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
121 case GETFACENAME: {
122 segout = SEGPTR_GET(SEGPTR_ALLOC(200));
123 break;
126 /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
127 * lpvOutData is actually a pointer to the DocInfo structure and used as
128 * a second input parameter
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;
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);
150 break;
152 case SETABORTPROC:
153 SetAbortProc(hdc, (ABORTPROC)lpszInData);
154 break;
156 /* Escape(hdc,END_PATH,PATHINFO,NULL); */
157 case END_PATH:
159 BYTE *p = SEGPTR_ALLOC(cbInput);
160 memcpy(p, lpszInData, cbInput);
161 segin = SEGPTR_GET(p);
162 break;
165 default:
166 break;
170 ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
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;
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;
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;
200 case GETTECHNOLOGY: {
201 LPSTR x=PTR_SEG_TO_LIN(segout);
202 strcpy(lpvOutData,x);
203 SEGPTR_FREE(x);
204 break;
206 case ENABLEPAIRKERNING: {
207 LPINT16 enab = (LPINT16)PTR_SEG_TO_LIN(segout);
209 *(LPINT)lpvOutData = *enab;
210 SEGPTR_FREE(enab);
211 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
212 break;
214 case GETFACENAME: {
215 LPSTR x = (LPSTR)PTR_SEG_TO_LIN(segout);
216 strcpy(lpvOutData,x);
217 SEGPTR_FREE(x);
218 break;
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;
230 case CLIP_TO_PATH:
231 case END_PATH:
232 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
233 break;
235 default:
236 break;
238 done:
239 GDI_ReleaseObj( hdc );
240 return ret;
243 /******************************************************************************
244 * ExtEscape [GDI32.95]
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
254 * RETURNS
255 * Success: >0
256 * Not implemented: 0
257 * Failure: <0
259 INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput,
260 LPCSTR lpszInData, INT cbOutput, LPSTR lpszOutData )
262 char *inBuf, *outBuf;
263 INT ret;
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);
275 return ret;
278 /*******************************************************************
279 * DrawEscape [GDI32.74]
283 INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
285 FIXME("DrawEscape, stub\n");
286 return 0;