Fixed COORD structure definition.
[wine/multimedia.git] / graphics / psdrv / escape.c
blob97a029cfeaf6e414dda82632cf8dace027e4572d
1 /*
2 * PostScript driver Escape function
4 * Copyright 1998 Huw D M Davies
5 */
6 #include "windef.h"
7 #include "wingdi.h"
8 #include "wine/winuser16.h"
9 #include "psdrv.h"
10 #include "debugtools.h"
11 #include "winspool.h"
12 #include "heap.h"
14 DEFAULT_DEBUG_CHANNEL(psdrv)
17 INT PSDRV_Escape( DC *dc, INT nEscape, INT cbInput,
18 SEGPTR lpInData, SEGPTR lpOutData )
20 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
22 switch(nEscape) {
24 case NEXTBAND: {
25 RECT16 *r = (RECT16 *)PTR_SEG_TO_LIN(lpOutData);
26 if(!physDev->job.banding) {
27 physDev->job.banding = TRUE;
28 r->left = 0;
29 r->top = 0;
30 r->right = dc->w.devCaps->horzRes;
31 r->bottom = dc->w.devCaps->vertRes;
32 TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left,
33 r->top, r->right, r->bottom );
34 return 1;
36 r->left = 0;
37 r->top = 0;
38 r->right = 0;
39 r->bottom = 0;
40 TRACE("NEXTBAND rect to 0,0 - 0,0\n" );
41 physDev->job.banding = FALSE;
42 } /* Fall through */
44 case NEWFRAME:
45 TRACE("NEWFRAME\n");
47 if(!physDev->job.hJob) {
48 FIXME("hJob == 0. Now what?\n");
49 return SP_ERROR;
52 if(!PSDRV_EndPage( dc ))
53 return SP_ERROR;
54 return 1;
56 case QUERYESCSUPPORT:
57 if(cbInput < 2) {
58 WARN("cbInput < 2 (=%d) for QUERYESCSUPPORT\n", cbInput);
59 return 0;
60 } else {
61 UINT16 num = *(UINT16 *)PTR_SEG_TO_LIN(lpInData);
62 TRACE("QUERYESCSUPPORT for %d\n", num);
64 switch(num) {
65 case NEWFRAME:
66 case NEXTBAND:
67 case QUERYESCSUPPORT:
68 case SETABORTPROC:
69 case STARTDOC:
70 case ENDDOC:
71 case GETPHYSPAGESIZE:
72 case GETPRINTINGOFFSET:
73 case GETSCALINGFACTOR:
74 case SETCOPYCOUNT:
75 case GETTECHNOLOGY:
76 case SETLINECAP:
77 case SETLINEJOIN:
78 case SETMITERLIMIT:
79 case SETCHARSET:
80 case EXT_DEVICE_CAPS:
81 case SET_BOUNDS:
82 return TRUE;
84 default:
85 return FALSE;
89 case SETABORTPROC:
90 TRACE("SETABORTPROC\n");
91 return 1;
93 case STARTDOC:
95 DOCINFOA doc;
96 char *name = NULL;
97 INT16 ret;
99 TRACE("STARTDOC\n");
101 /* lpInData may not be 0 terminated so we must copy it */
102 if(lpInData) {
103 name = HeapAlloc( GetProcessHeap(), 0, cbInput+1 );
104 memcpy(name, PTR_SEG_TO_LIN(lpInData), cbInput);
105 name[cbInput] = '\0';
107 doc.cbSize = sizeof(doc);
108 doc.lpszDocName = name;
109 doc.lpszOutput = doc.lpszDatatype = NULL;
110 doc.fwType = 0;
112 ret = PSDRV_StartDoc(dc, &doc);
113 if(name) HeapFree( GetProcessHeap(), 0, name );
114 if(ret <= 0) return -1;
115 ret = PSDRV_StartPage(dc);
116 if(ret <= 0) return -1;
117 return ret;
120 case ENDDOC:
121 TRACE("ENDDOC\n");
122 return PSDRV_EndDoc( dc );
124 case GETPHYSPAGESIZE:
126 POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
128 p->x = dc->w.devCaps->horzRes;
129 p->y = dc->w.devCaps->vertRes;
130 TRACE("GETPHYSPAGESIZE: returning %dx%d\n", p->x, p->y);
131 return 1;
134 case GETPRINTINGOFFSET:
136 POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
138 p->x = p->y = 0;
139 TRACE("GETPRINTINGOFFSET: returning %dx%d\n", p->x, p->y);
140 return 1;
143 case GETSCALINGFACTOR:
145 POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
147 p->x = p->y = 0;
148 TRACE("GETSCALINGFACTOR: returning %dx%d\n", p->x, p->y);
149 return 1;
152 case SETCOPYCOUNT:
154 INT16 *NumCopies = (INT16 *)PTR_SEG_TO_LIN(lpInData);
155 INT16 *ActualCopies = (INT16 *)PTR_SEG_TO_LIN(lpOutData);
156 if(cbInput != 2) {
157 WARN("cbInput != 2 (=%d) for SETCOPYCOUNT\n", cbInput);
158 return 0;
160 TRACE("SETCOPYCOUNT %d\n", *NumCopies);
161 *ActualCopies = 1;
162 return 1;
165 case GETTECHNOLOGY:
167 LPSTR p = (LPSTR)PTR_SEG_TO_LIN(lpOutData);
168 strcpy(p, "PostScript");
169 *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */
170 return 1;
173 case SETLINECAP:
175 INT16 newCap = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
176 if(cbInput != 2) {
177 WARN("cbInput != 2 (=%d) for SETLINECAP\n", cbInput);
178 return 0;
180 TRACE("SETLINECAP %d\n", newCap);
181 return 0;
184 case SETLINEJOIN:
186 INT16 newJoin = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
187 if(cbInput != 2) {
188 WARN("cbInput != 2 (=%d) for SETLINEJOIN\n", cbInput);
189 return 0;
191 TRACE("SETLINEJOIN %d\n", newJoin);
192 return 0;
195 case SETMITERLIMIT:
197 INT16 newLimit = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
198 if(cbInput != 2) {
199 WARN("cbInput != 2 (=%d) for SETMITERLIMIT\n", cbInput);
200 return 0;
202 TRACE("SETMITERLIMIT %d\n", newLimit);
203 return 0;
206 case SETCHARSET:
207 /* Undocumented escape used by winword6.
208 Switches between ANSI and a special charset.
209 If *lpInData == 1 we require that
210 0x91 is quoteleft
211 0x92 is quoteright
212 0x93 is quotedblleft
213 0x94 is quotedblright
214 0x95 is bullet
215 0x96 is endash
216 0x97 is emdash
217 0xa0 is non break space - yeah right.
219 If *lpInData == 0 we get ANSI.
220 Since there's nothing else there, let's just make these the default
221 anyway and see what happens...
223 return 1;
225 case EXT_DEVICE_CAPS:
227 UINT16 cap = *(UINT16 *)PTR_SEG_TO_LIN(lpInData);
228 if(cbInput != 2) {
229 WARN("cbInput != 2 (=%d) for EXT_DEVICE_CAPS\n",
230 cbInput);
231 return 0;
233 TRACE("EXT_DEVICE_CAPS %d\n", cap);
234 return 0;
237 case SET_BOUNDS:
239 RECT16 *r = (RECT16 *)PTR_SEG_TO_LIN(lpInData);
240 if(cbInput != 8) {
241 WARN("cbInput != 8 (=%d) for SET_BOUNDS\n", cbInput);
242 return 0;
244 TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top,
245 r->right, r->bottom);
246 return 0;
249 default:
250 FIXME("Unimplemented code 0x%x\n", nEscape);
251 return 0;
255 /************************************************************************
256 * PSDRV_StartPage
258 INT PSDRV_StartPage( DC *dc )
260 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
262 if(!physDev->job.OutOfPage) {
263 FIXME("Already started a page?\n");
264 return 1;
266 physDev->job.PageNo++;
267 if(!PSDRV_WriteNewPage( dc ))
268 return 0;
269 physDev->job.OutOfPage = FALSE;
270 return 1;
274 /************************************************************************
275 * PSDRV_EndPage
277 INT PSDRV_EndPage( DC *dc )
279 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
281 if(physDev->job.OutOfPage) {
282 FIXME("Already ended a page?\n");
283 return 1;
285 if(!PSDRV_WriteEndPage( dc ))
286 return 0;
287 physDev->job.OutOfPage = TRUE;
288 return 1;
292 /************************************************************************
293 * PSDRV_StartDoc
295 INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc )
297 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
299 if(physDev->job.hJob) {
300 FIXME("hJob != 0. Now what?\n");
301 return 0;
304 if(doc->lpszOutput) {
305 HeapFree( PSDRV_Heap, 0, physDev->job.output );
306 physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, doc->lpszOutput );
308 physDev->job.hJob = OpenJob16(physDev->job.output, doc->lpszDocName,
309 dc->hSelf);
310 if(!physDev->job.hJob) {
311 WARN("OpenJob failed\n");
312 return 0;
314 physDev->job.banding = FALSE;
315 physDev->job.OutOfPage = TRUE;
316 physDev->job.PageNo = 0;
317 if(!PSDRV_WriteHeader( dc, doc->lpszDocName ))
318 return 0;
320 return physDev->job.hJob;
324 /************************************************************************
325 * PSDRV_EndDoc
327 INT PSDRV_EndDoc( DC *dc )
329 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
331 if(!physDev->job.hJob) {
332 FIXME("hJob == 0. Now what?\n");
333 return 0;
336 if(!physDev->job.OutOfPage) {
337 WARN("Somebody forgot a EndPage\n");
338 PSDRV_EndPage( dc );
340 if(!PSDRV_WriteFooter( dc ))
341 return 0;
343 if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
344 WARN("CloseJob error\n");
345 return 0;
347 physDev->job.hJob = 0;
348 return 1;