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