Removed some of the XXX_reg macros now that we are using the standard
[wine] / dlls / wineps / escape.c
1 /*
2  *      PostScript driver Escape function
3  *
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"
13
14 DEFAULT_DEBUG_CHANNEL(psdrv)
15
16
17 INT PSDRV_Escape( DC *dc, INT nEscape, INT cbInput, 
18                   SEGPTR lpInData, SEGPTR lpOutData )
19 {
20     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
21
22     switch(nEscape) {
23
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;
35         }
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 */
43
44     case NEWFRAME:
45         TRACE("NEWFRAME\n");
46
47         if(!physDev->job.hJob) {
48             FIXME("hJob == 0. Now what?\n");
49             return SP_ERROR;
50         }
51         
52         if(!PSDRV_EndPage( dc ))
53             return SP_ERROR;
54         return 1;
55           
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);        
63
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;
83
84             default:
85                 return FALSE;
86             }
87         }
88
89     case SETABORTPROC:
90         TRACE("SETABORTPROC\n");
91         return 1;
92
93     case STARTDOC:
94       {
95         DOCINFOA doc;
96         char *name = NULL;
97         INT16 ret;
98
99         TRACE("STARTDOC\n");
100
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';
106         }
107         doc.cbSize = sizeof(doc);
108         doc.lpszDocName = name;
109         doc.lpszOutput = doc.lpszDatatype = NULL;
110         doc.fwType = 0;
111
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;
118       }
119
120     case ENDDOC:
121         TRACE("ENDDOC\n");
122         return PSDRV_EndDoc( dc );
123
124     case GETPHYSPAGESIZE:
125         {
126             POINT16 *p  = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
127             
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;
132         }
133
134     case GETPRINTINGOFFSET:
135         {
136             POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
137         
138             p->x = p->y = 0;
139             TRACE("GETPRINTINGOFFSET: returning %dx%d\n", p->x, p->y);
140             return 1;
141         }
142       
143     case GETSCALINGFACTOR:
144         {
145             POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
146         
147             p->x = p->y = 0;
148             TRACE("GETSCALINGFACTOR: returning %dx%d\n", p->x, p->y);
149             return 1;
150         }
151
152     case SETCOPYCOUNT:
153         {
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;
159             }
160             TRACE("SETCOPYCOUNT %d\n", *NumCopies);
161             *ActualCopies = 1;
162             return 1;
163         }
164
165     case GETTECHNOLOGY:
166         {
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;
171         }
172
173     case SETLINECAP:
174         {
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;
179             }                   
180             TRACE("SETLINECAP %d\n", newCap);
181             return 0;
182         }
183             
184     case SETLINEJOIN:
185         {
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;
190             }           
191             TRACE("SETLINEJOIN %d\n", newJoin);
192             return 0;
193         }
194
195     case SETMITERLIMIT:
196         {
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;
201             }           
202             TRACE("SETMITERLIMIT %d\n", newLimit);
203             return 0;
204         }
205
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.
218          
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...
222       */
223         return 1;
224
225     case EXT_DEVICE_CAPS:
226         {
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;
232             }           
233             TRACE("EXT_DEVICE_CAPS %d\n", cap);
234             return 0;
235         }
236
237     case SET_BOUNDS:
238         {
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;
243             }           
244             TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top,
245                   r->right, r->bottom);
246             return 0;
247         }
248
249     default:
250         FIXME("Unimplemented code 0x%x\n", nEscape);
251         return 0;
252     }
253 }
254
255 /************************************************************************
256  *           PSDRV_StartPage
257  */
258 INT PSDRV_StartPage( DC *dc )
259 {
260     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
261
262     if(!physDev->job.OutOfPage) {
263         FIXME("Already started a page?\n");
264         return 1;
265     }
266     physDev->job.PageNo++;
267     if(!PSDRV_WriteNewPage( dc ))
268         return 0;
269     physDev->job.OutOfPage = FALSE;
270     return 1;
271 }
272
273         
274 /************************************************************************
275  *           PSDRV_EndPage
276  */
277 INT PSDRV_EndPage( DC *dc )
278 {
279     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
280
281     if(physDev->job.OutOfPage) {
282         FIXME("Already ended a page?\n");
283         return 1;
284     }
285     if(!PSDRV_WriteEndPage( dc ))
286         return 0;
287     physDev->job.OutOfPage = TRUE;
288     return 1;
289 }
290
291
292 /************************************************************************
293  *           PSDRV_StartDoc
294  */
295 INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc )
296 {
297     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
298
299     if(physDev->job.hJob) {
300         FIXME("hJob != 0. Now what?\n");
301         return 0;
302     }
303
304     if(doc->lpszOutput) {
305         HeapFree( PSDRV_Heap, 0, physDev->job.output );
306         physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, doc->lpszOutput );
307     }
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;
313     }
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;
319
320     return physDev->job.hJob;
321 }
322
323
324 /************************************************************************
325  *           PSDRV_EndDoc
326  */
327 INT PSDRV_EndDoc( DC *dc )
328 {
329     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
330
331     if(!physDev->job.hJob) {
332         FIXME("hJob == 0. Now what?\n");
333         return 0;
334     }
335
336     if(!physDev->job.OutOfPage) {
337         WARN("Somebody forgot a EndPage\n");
338         PSDRV_EndPage( dc );
339     }
340     if(!PSDRV_WriteFooter( dc ))
341         return 0;
342
343     if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
344         WARN("CloseJob error\n");
345         return 0;
346     }
347     physDev->job.hJob = 0;
348     return 1;
349 }