Added more conversion routines (rate conversion is implemented).
[wine.git] / graphics / escape.c
blobd4dd4621c664383ec450a8fce35fb7c28b7ed32b
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 "dc.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(driver);
18 /***********************************************************************
19 * Escape16 [GDI.38]
21 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
22 SEGPTR lpszInData, SEGPTR lpvOutData )
24 INT16 ret = 0;
25 DC * dc = DC_GetDCPtr( hdc );
26 if (dc)
28 if (dc->funcs->pEscape)
30 if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
31 ret = dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
33 GDI_ReleaseObj( hdc );
35 return ret;
38 /************************************************************************
39 * Escape [GDI32.200]
41 INT WINAPI Escape( HDC hdc, INT nEscape, INT cbInput,
42 LPCSTR lpszInData, LPVOID lpvOutData )
44 SEGPTR segin,segout;
45 INT ret = 0;
46 DC * dc = DC_GetDCPtr( hdc );
47 if (!dc) return 0;
48 if (!dc->funcs->pEscape) goto done;
50 segin = (SEGPTR)lpszInData;
51 segout = (SEGPTR)lpvOutData;
52 switch (nEscape) {
53 /* Escape(hdc,QUERYESCSUPPORT,LPINT,NULL) */
54 /* Escape(hdc,CLIP_TO_PATH,LPINT,NULL) */
55 case QUERYESCSUPPORT:
56 case CLIP_TO_PATH:
58 LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
59 *x = *(INT*)lpszInData;
60 segin = SEGPTR_GET(x);
61 cbInput = sizeof(INT16);
62 break;
65 /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
66 /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
67 /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */
69 case GETSCALINGFACTOR:
70 case GETPHYSPAGESIZE:
71 case GETPRINTINGOFFSET:
72 segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
73 cbInput = sizeof(POINT16);
74 break;
76 /* Escape(hdc,EXT_DEVICE_CAPS,LPINT,LPDWORD) */
77 case EXT_DEVICE_CAPS:
79 LPINT16 lpIndex = (LPINT16)SEGPTR_NEW(INT16);
80 LPDWORD lpCaps = (LPDWORD)SEGPTR_NEW(DWORD);
81 *lpIndex = *(INT*)lpszInData;
83 segin = SEGPTR_GET(lpIndex);
84 segout = SEGPTR_GET(lpCaps);
85 cbInput = sizeof(INT16);
86 break;
89 /* Escape(hdc,SETLINECAP,LPINT,LPINT) */
90 case SETLINECAP:
91 case SETLINEJOIN:
92 case SETMITERLIMIT:
94 LPINT16 new = (LPINT16)SEGPTR_NEW(INT16);
95 LPINT16 old = (LPINT16)SEGPTR_NEW(INT16);
96 *new = *(INT*)lpszInData;
97 segin = SEGPTR_GET(new);
98 segout = SEGPTR_GET(old);
99 cbInput = sizeof(INT16);
100 break;
102 /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
103 case GETTECHNOLOGY: {
104 segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
105 break;
109 /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
111 case ENABLEPAIRKERNING: {
112 LPINT16 enab = SEGPTR_NEW(INT16);
113 segout = SEGPTR_GET(SEGPTR_NEW(INT16));
114 segin = SEGPTR_GET(enab);
115 *enab = *(INT*)lpszInData;
116 cbInput = sizeof(INT16);
117 break;
120 /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
122 case GETFACENAME: {
123 segout = SEGPTR_GET(SEGPTR_ALLOC(200));
124 break;
127 /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
128 * lpvOutData is actually a pointer to the DocInfo structure and used as
129 * a second input parameter
132 case STARTDOC: /* string may not be \0 terminated */
133 if(lpszInData) {
134 char *cp = SEGPTR_ALLOC(cbInput);
135 memcpy(cp, lpszInData, cbInput);
136 segin = SEGPTR_GET(cp);
137 } else
138 segin = 0;
140 if(lpvOutData) {
141 DOCINFO16 *lpsegdoc = SEGPTR_NEW(DOCINFO16);
142 DOCINFOA *lpdoc = lpvOutData;
143 memset(lpsegdoc, 0, sizeof(*lpsegdoc));
144 lpsegdoc->cbSize = sizeof(*lpsegdoc);
145 lpsegdoc->lpszDocName = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDocName));
146 lpsegdoc->lpszOutput = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszOutput));
147 lpsegdoc->lpszDatatype = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDatatype));
148 lpsegdoc->fwType = lpdoc->fwType;
149 segout = SEGPTR_GET(lpsegdoc);
151 break;
153 case SETABORTPROC:
154 SetAbortProc(hdc, (ABORTPROC)lpszInData);
155 break;
157 /* Escape(hdc,END_PATH,PATHINFO,NULL); */
158 case END_PATH:
160 BYTE *p = SEGPTR_ALLOC(cbInput);
161 memcpy(p, lpszInData, cbInput);
162 segin = SEGPTR_GET(p);
163 break;
166 default:
167 break;
171 ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
173 switch(nEscape) {
174 case QUERYESCSUPPORT:
175 if (ret)
176 TRACE("target DC implements Escape %d\n",nEscape);
177 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
178 break;
180 case SETLINECAP:
181 case SETLINEJOIN:
182 case SETMITERLIMIT:
183 *(LPINT)lpvOutData = *(LPINT16)PTR_SEG_TO_LIN(segout);
184 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
185 SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
186 break;
187 case GETSCALINGFACTOR:
188 case GETPRINTINGOFFSET:
189 case GETPHYSPAGESIZE: {
190 LPPOINT16 x = (LPPOINT16)PTR_SEG_TO_LIN(segout);
191 CONV_POINT16TO32(x,(LPPOINT)lpvOutData);
192 SEGPTR_FREE(x);
193 break;
195 case EXT_DEVICE_CAPS:
196 *(LPDWORD)lpvOutData = *(LPDWORD)PTR_SEG_TO_LIN(segout);
197 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
198 SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
199 break;
201 case GETTECHNOLOGY: {
202 LPSTR x=PTR_SEG_TO_LIN(segout);
203 strcpy(lpvOutData,x);
204 SEGPTR_FREE(x);
205 break;
207 case ENABLEPAIRKERNING: {
208 LPINT16 enab = (LPINT16)PTR_SEG_TO_LIN(segout);
210 *(LPINT)lpvOutData = *enab;
211 SEGPTR_FREE(enab);
212 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
213 break;
215 case GETFACENAME: {
216 LPSTR x = (LPSTR)PTR_SEG_TO_LIN(segout);
217 strcpy(lpvOutData,x);
218 SEGPTR_FREE(x);
219 break;
221 case STARTDOC: {
222 DOCINFO16 *doc = PTR_SEG_TO_LIN(segout);
223 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDocName));
224 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszOutput));
225 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDatatype));
226 SEGPTR_FREE(doc);
227 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
228 break;
231 case CLIP_TO_PATH:
232 case END_PATH:
233 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
234 break;
236 default:
237 break;
239 done:
240 GDI_ReleaseObj( hdc );
241 return ret;
244 /******************************************************************************
245 * ExtEscape [GDI32.95]
247 * PARAMS
248 * hdc [I] Handle to device context
249 * nEscape [I] Escape function
250 * cbInput [I] Number of bytes in input structure
251 * lpszInData [I] Pointer to input structure
252 * cbOutput [I] Number of bytes in output structure
253 * lpszOutData [O] Pointer to output structure
255 * RETURNS
256 * Success: >0
257 * Not implemented: 0
258 * Failure: <0
260 INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput,
261 LPCSTR lpszInData, INT cbOutput, LPSTR lpszOutData )
263 char *inBuf, *outBuf;
264 INT ret;
266 inBuf = SEGPTR_ALLOC(cbInput);
267 memcpy(inBuf, lpszInData, cbInput);
268 outBuf = cbOutput ? SEGPTR_ALLOC(cbOutput) : NULL;
269 ret = Escape16( hdc, nEscape, cbInput, SEGPTR_GET(inBuf),
270 SEGPTR_GET(outBuf) );
271 SEGPTR_FREE(inBuf);
272 if(outBuf) {
273 memcpy(lpszOutData, outBuf, cbOutput);
274 SEGPTR_FREE(outBuf);
276 return ret;
279 /*******************************************************************
280 * DrawEscape [GDI32.74]
284 INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
286 FIXME("DrawEscape, stub\n");
287 return 0;