Update shell xxxAW wrapper prototypes for fixed SHLWAPI functions.
[wine] / dlls / wineps / escape.c
1 /*
2  *      PostScript driver Escape function
3  *
4  *      Copyright 1998  Huw D M Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include "windef.h"
21 #include "wingdi.h"
22 #include "wine/winuser16.h"
23 #include "psdrv.h"
24 #include "wine/debug.h"
25 #include "winspool.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
28
29
30 /**********************************************************************
31  *           ExtEscape  (WINEPS.@)
32  */
33 INT PSDRV_ExtEscape( DC *dc, INT nEscape, INT cbInput, LPCVOID in_data,
34                      INT cbOutput, LPVOID out_data )
35 {
36     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
37
38     switch(nEscape)
39     {
40     case QUERYESCSUPPORT:
41         if(cbInput < sizeof(INT))
42         {
43             WARN("cbInput < sizeof(INT) (=%d) for QUERYESCSUPPORT\n", cbInput);
44             return 0;
45         } else {
46             UINT num = *(UINT *)in_data;
47             TRACE("QUERYESCSUPPORT for %d\n", num);
48
49             switch(num) {
50             case NEXTBAND:
51             case SETCOPYCOUNT:
52             case GETTECHNOLOGY:
53             case SETLINECAP:
54             case SETLINEJOIN:
55             case SETMITERLIMIT:
56             case SETCHARSET:
57             case EXT_DEVICE_CAPS:
58             case SET_BOUNDS:
59             case EPSPRINTING:
60             case PASSTHROUGH:
61             case POSTSCRIPT_PASSTHROUGH:
62                 return TRUE;
63
64             default:
65                 return FALSE;
66             }
67         }
68
69     case NEXTBAND:
70     {
71         RECT *r = out_data;
72         if(!physDev->job.banding) {
73             physDev->job.banding = TRUE;
74             r->left   = 0;
75             r->top    = 0;
76             r->right  = physDev->horzRes;
77             r->bottom = physDev->vertRes;
78             TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left, r->top, r->right, r->bottom );
79             return 1;
80         }
81         r->left   = 0;
82         r->top    = 0;
83         r->right  = 0;
84         r->bottom = 0;
85         TRACE("NEXTBAND rect to 0,0 - 0,0\n" );
86         physDev->job.banding = FALSE;
87         return EndPage( dc->hSelf );
88     }
89
90     case SETCOPYCOUNT:
91         {
92             const INT *NumCopies = in_data;
93             INT *ActualCopies = out_data;
94             if(cbInput != sizeof(INT)) {
95                 WARN("cbInput != sizeof(INT) (=%d) for SETCOPYCOUNT\n", cbInput);
96                 return 0;
97             }
98             TRACE("SETCOPYCOUNT %d\n", *NumCopies);
99             *ActualCopies = 1;
100             return 1;
101         }
102
103     case GETTECHNOLOGY:
104         {
105             LPSTR p = out_data;
106             strcpy(p, "PostScript");
107             *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */
108             return 1;
109         }
110
111     case SETLINECAP:
112         {
113             INT newCap = *(INT *)in_data;
114             if(cbInput != sizeof(INT)) {
115                 WARN("cbInput != sizeof(INT) (=%d) for SETLINECAP\n", cbInput);
116                 return 0;
117             }
118             TRACE("SETLINECAP %d\n", newCap);
119             return 0;
120         }
121
122     case SETLINEJOIN:
123         {
124             INT newJoin = *(INT *)in_data;
125             if(cbInput != sizeof(INT)) {
126                 WARN("cbInput != sizeof(INT) (=%d) for SETLINEJOIN\n", cbInput);
127                 return 0;
128             }
129             TRACE("SETLINEJOIN %d\n", newJoin);
130             return 0;
131         }
132
133     case SETMITERLIMIT:
134         {
135             INT newLimit = *(INT *)in_data;
136             if(cbInput != sizeof(INT)) {
137                 WARN("cbInput != sizeof(INT) (=%d) for SETMITERLIMIT\n", cbInput);
138                 return 0;
139             }
140             TRACE("SETMITERLIMIT %d\n", newLimit);
141             return 0;
142         }
143
144     case SETCHARSET: 
145       /* Undocumented escape used by winword6.
146          Switches between ANSI and a special charset.
147          If *lpInData == 1 we require that
148          0x91 is quoteleft
149          0x92 is quoteright
150          0x93 is quotedblleft
151          0x94 is quotedblright
152          0x95 is bullet
153          0x96 is endash
154          0x97 is emdash
155          0xa0 is non break space - yeah right.
156          
157          If *lpInData == 0 we get ANSI.
158          Since there's nothing else there, let's just make these the default
159          anyway and see what happens...
160       */
161         return 1;
162
163     case EXT_DEVICE_CAPS:
164         {
165             UINT cap = *(UINT *)in_data;
166             if(cbInput != sizeof(UINT)) {
167                 WARN("cbInput != sizeof(UINT) (=%d) for EXT_DEVICE_CAPS\n", cbInput);
168                 return 0;
169             }
170             TRACE("EXT_DEVICE_CAPS %d\n", cap);
171             return 0;
172         }
173
174     case SET_BOUNDS:
175         {
176             const RECT *r = in_data;
177             if(cbInput != sizeof(RECT)) {
178                 WARN("cbInput != sizeof(RECT) (=%d) for SET_BOUNDS\n", cbInput);
179                 return 0;
180             }
181             TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top,
182                   r->right, r->bottom);
183             return 0;
184         }
185
186     case EPSPRINTING:
187         {
188             UINT epsprint = *(UINT*)in_data;
189             /* FIXME: In this mode we do not need to send page intros and page
190              * ends according to the doc. But I just ignore that detail
191              * for now.
192              */
193             TRACE("EPS Printing support %sable.\n",epsprint?"en":"dis");
194             return 1;
195         }
196     case PASSTHROUGH:
197     case POSTSCRIPT_PASSTHROUGH:
198         {
199             /* Write directly to spool file, bypassing normal PS driver
200              * processing that is done along with writing PostScript code
201              * to the spool.
202              * (Usually we have a WORD before the data counting the size, but
203              * cbInput is just this +2.)
204              */
205             return WriteSpool16(physDev->job.hJob,((char*)in_data)+2,cbInput-2);
206         }
207
208     case GETSETPRINTORIENT:
209         {
210             /* If lpInData is present, it is a 20 byte structure, first 32
211              * bit LONG value is the orientation. if lpInData is NULL, it
212              * returns the current orientation.
213              */
214             FIXME("GETSETPRINTORIENT not implemented (data %p)!\n",in_data);
215             return 1;
216         }
217     default:
218         FIXME("Unimplemented code 0x%x\n", nEscape);
219         return 0;
220     }
221 }
222
223 /************************************************************************
224  *           PSDRV_StartPage
225  */
226 INT PSDRV_StartPage( DC *dc )
227 {
228     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
229
230     if(!physDev->job.OutOfPage) {
231         FIXME("Already started a page?\n");
232         return 1;
233     }
234     physDev->job.PageNo++;
235     if(!PSDRV_WriteNewPage( dc ))
236         return 0;
237     physDev->job.OutOfPage = FALSE;
238     return 1;
239 }
240
241         
242 /************************************************************************
243  *           PSDRV_EndPage
244  */
245 INT PSDRV_EndPage( DC *dc )
246 {
247     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
248
249     if(physDev->job.OutOfPage) {
250         FIXME("Already ended a page?\n");
251         return 1;
252     }
253     if(!PSDRV_WriteEndPage( dc ))
254         return 0;
255     physDev->job.OutOfPage = TRUE;
256     return 1;
257 }
258
259
260 /************************************************************************
261  *           PSDRV_StartDoc
262  */
263 INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc )
264 {
265     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
266
267     if(physDev->job.hJob) {
268         FIXME("hJob != 0. Now what?\n");
269         return 0;
270     }
271
272     if(doc->lpszOutput) {
273         HeapFree( PSDRV_Heap, 0, physDev->job.output );
274         physDev->job.output = HeapAlloc( PSDRV_Heap, 0, strlen(doc->lpszOutput)+1 );
275         strcpy( physDev->job.output, doc->lpszOutput );
276     }
277     physDev->job.hJob = OpenJob16(physDev->job.output,  doc->lpszDocName,
278                                   dc->hSelf);
279     if(!physDev->job.hJob) {
280         WARN("OpenJob failed\n");
281         return 0;
282     }
283     physDev->job.banding = FALSE;
284     physDev->job.OutOfPage = TRUE;
285     physDev->job.PageNo = 0;
286     if(!PSDRV_WriteHeader( dc, doc->lpszDocName ))
287         return 0;
288
289     return physDev->job.hJob;
290 }
291
292
293 /************************************************************************
294  *           PSDRV_EndDoc
295  */
296 INT PSDRV_EndDoc( DC *dc )
297 {
298     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
299
300     if(!physDev->job.hJob) {
301         FIXME("hJob == 0. Now what?\n");
302         return 0;
303     }
304
305     if(!physDev->job.OutOfPage) {
306         WARN("Somebody forgot a EndPage\n");
307         PSDRV_EndPage( dc );
308     }
309     if(!PSDRV_WriteFooter( dc ))
310         return 0;
311
312     if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
313         WARN("CloseJob error\n");
314         return 0;
315     }
316     physDev->job.hJob = 0;
317     return 1;
318 }