No longer directly accessing debuggee memory.
[wine] / graphics / psdrv / 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             SetRect16( r, 0, 0, dc->w.devCaps->horzRes,
29                                      dc->w.devCaps->vertRes );
30             TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left,
31                   r->top, r->right, r->bottom );
32             return 1;
33         }
34         SetRect16( r, 0, 0, 0, 0 );
35         TRACE("NEXTBAND rect to 0,0 - 0,0\n" );
36         physDev->job.banding = FALSE;
37     }   /* Fall through */
38
39     case NEWFRAME:
40         TRACE("NEWFRAME\n");
41
42         if(!physDev->job.hJob) {
43             FIXME("hJob == 0. Now what?\n");
44             return SP_ERROR;
45         }
46         
47         if(!PSDRV_EndPage( dc ))
48             return SP_ERROR;
49         return 1;
50           
51     case QUERYESCSUPPORT:
52         if(cbInput < 2) {
53             WARN("cbInput < 2 (=%d) for QUERYESCSUPPORT\n", cbInput);
54             return 0;
55         } else {
56             UINT16 num = *(UINT16 *)PTR_SEG_TO_LIN(lpInData);
57             TRACE("QUERYESCSUPPORT for %d\n", num);        
58
59             switch(num) {
60             case NEWFRAME:
61             case NEXTBAND:
62             case QUERYESCSUPPORT:
63             case SETABORTPROC:
64             case STARTDOC:
65             case ENDDOC:
66             case GETPHYSPAGESIZE:
67             case GETPRINTINGOFFSET:
68             case GETSCALINGFACTOR:
69             case SETCOPYCOUNT:
70             case GETTECHNOLOGY:
71             case SETLINECAP:
72             case SETLINEJOIN:
73             case SETMITERLIMIT:
74             case SETCHARSET:
75             case EXT_DEVICE_CAPS:
76             case SET_BOUNDS:
77                 return TRUE;
78
79             default:
80                 return FALSE;
81             }
82         }
83
84     case SETABORTPROC:
85         TRACE("SETABORTPROC\n");
86         return 1;
87
88     case STARTDOC:
89       {
90         DOCINFOA doc;
91         char *name = NULL;
92         INT16 ret;
93
94         TRACE("STARTDOC\n");
95
96         /* lpInData may not be 0 terminated so we must copy it */
97         if(lpInData) {
98             name = HeapAlloc( GetProcessHeap(), 0, cbInput+1 );
99             memcpy(name, PTR_SEG_TO_LIN(lpInData), cbInput);
100             name[cbInput] = '\0';
101         }
102         doc.cbSize = sizeof(doc);
103         doc.lpszDocName = name;
104         doc.lpszOutput = doc.lpszDatatype = NULL;
105         doc.fwType = 0;
106
107         ret = PSDRV_StartDoc(dc, &doc);
108         if(name) HeapFree( GetProcessHeap(), 0, name );
109         if(ret <= 0) return -1;
110         ret = PSDRV_StartPage(dc);
111         if(ret <= 0) return -1;
112         return ret;
113       }
114
115     case ENDDOC:
116         TRACE("ENDDOC\n");
117         return PSDRV_EndDoc( dc );
118
119     case GETPHYSPAGESIZE:
120         {
121             POINT16 *p  = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
122             
123             p->x = dc->w.devCaps->horzRes;
124             p->y = dc->w.devCaps->vertRes;
125             TRACE("GETPHYSPAGESIZE: returning %dx%d\n", p->x, p->y);
126             return 1;
127         }
128
129     case GETPRINTINGOFFSET:
130         {
131             POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
132         
133             p->x = p->y = 0;
134             TRACE("GETPRINTINGOFFSET: returning %dx%d\n", p->x, p->y);
135             return 1;
136         }
137       
138     case GETSCALINGFACTOR:
139         {
140             POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData);
141         
142             p->x = p->y = 0;
143             TRACE("GETSCALINGFACTOR: returning %dx%d\n", p->x, p->y);
144             return 1;
145         }
146
147     case SETCOPYCOUNT:
148         {
149             INT16 *NumCopies = (INT16 *)PTR_SEG_TO_LIN(lpInData);
150             INT16 *ActualCopies = (INT16 *)PTR_SEG_TO_LIN(lpOutData);
151             if(cbInput != 2) {
152                 WARN("cbInput != 2 (=%d) for SETCOPYCOUNT\n", cbInput);
153                 return 0;
154             }
155             TRACE("SETCOPYCOUNT %d\n", *NumCopies);
156             *ActualCopies = 1;
157             return 1;
158         }
159
160     case GETTECHNOLOGY:
161         {
162             LPSTR p = (LPSTR)PTR_SEG_TO_LIN(lpOutData);
163             strcpy(p, "PostScript");
164             *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */
165             return 1;
166         }
167
168     case SETLINECAP:
169         {
170             INT16 newCap = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
171             if(cbInput != 2) {
172                 WARN("cbInput != 2 (=%d) for SETLINECAP\n", cbInput);
173                 return 0;
174             }                   
175             TRACE("SETLINECAP %d\n", newCap);
176             return 0;
177         }
178             
179     case SETLINEJOIN:
180         {
181             INT16 newJoin = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
182             if(cbInput != 2) {
183                 WARN("cbInput != 2 (=%d) for SETLINEJOIN\n", cbInput);
184                 return 0;
185             }           
186             TRACE("SETLINEJOIN %d\n", newJoin);
187             return 0;
188         }
189
190     case SETMITERLIMIT:
191         {
192             INT16 newLimit = *(INT16 *)PTR_SEG_TO_LIN(lpInData);
193             if(cbInput != 2) {
194                 WARN("cbInput != 2 (=%d) for SETMITERLIMIT\n", cbInput);
195                 return 0;
196             }           
197             TRACE("SETMITERLIMIT %d\n", newLimit);
198             return 0;
199         }
200
201     case SETCHARSET: 
202       /* Undocumented escape used by winword6.
203          Switches between ANSI and a special charset.
204          If *lpInData == 1 we require that
205          0x91 is quoteleft
206          0x92 is quoteright
207          0x93 is quotedblleft
208          0x94 is quotedblright
209          0x95 is bullet
210          0x96 is endash
211          0x97 is emdash
212          0xa0 is non break space - yeah right.
213          
214          If *lpInData == 0 we get ANSI.
215          Since there's nothing else there, let's just make these the default
216          anyway and see what happens...
217       */
218         return 1;
219
220     case EXT_DEVICE_CAPS:
221         {
222             UINT16 cap = *(UINT16 *)PTR_SEG_TO_LIN(lpInData);
223             if(cbInput != 2) {
224                 WARN("cbInput != 2 (=%d) for EXT_DEVICE_CAPS\n",
225                      cbInput);
226                 return 0;
227             }           
228             TRACE("EXT_DEVICE_CAPS %d\n", cap);
229             return 0;
230         }
231
232     case SET_BOUNDS:
233         {
234             RECT16 *r = (RECT16 *)PTR_SEG_TO_LIN(lpInData);
235             if(cbInput != 8) {
236                 WARN("cbInput != 8 (=%d) for SET_BOUNDS\n", cbInput);
237                 return 0;
238             }           
239             TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top,
240                   r->right, r->bottom);
241             return 0;
242         }
243
244     default:
245         FIXME("Unimplemented code 0x%x\n", nEscape);
246         return 0;
247     }
248 }
249
250 /************************************************************************
251  *           PSDRV_StartPage
252  */
253 INT PSDRV_StartPage( DC *dc )
254 {
255     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
256
257     if(!physDev->job.OutOfPage) {
258         FIXME("Already started a page?\n");
259         return 1;
260     }
261     physDev->job.PageNo++;
262     if(!PSDRV_WriteNewPage( dc ))
263         return 0;
264     physDev->job.OutOfPage = FALSE;
265     return 1;
266 }
267
268         
269 /************************************************************************
270  *           PSDRV_EndPage
271  */
272 INT PSDRV_EndPage( DC *dc )
273 {
274     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
275
276     if(physDev->job.OutOfPage) {
277         FIXME("Already ended a page?\n");
278         return 1;
279     }
280     if(!PSDRV_WriteEndPage( dc ))
281         return 0;
282     physDev->job.OutOfPage = TRUE;
283     return 1;
284 }
285
286
287 /************************************************************************
288  *           PSDRV_StartDoc
289  */
290 INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc )
291 {
292     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
293
294     if(physDev->job.hJob) {
295         FIXME("hJob != 0. Now what?\n");
296         return 0;
297     }
298
299     if(doc->lpszOutput) {
300         HeapFree( PSDRV_Heap, 0, physDev->job.output );
301         physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, doc->lpszOutput );
302     }
303     physDev->job.hJob = OpenJob16(physDev->job.output,  doc->lpszDocName,
304                                   dc->hSelf);
305     if(!physDev->job.hJob) {
306         WARN("OpenJob failed\n");
307         return 0;
308     }
309     physDev->job.banding = FALSE;
310     physDev->job.OutOfPage = TRUE;
311     physDev->job.PageNo = 0;
312     if(!PSDRV_WriteHeader( dc, doc->lpszDocName ))
313         return 0;
314
315     return physDev->job.hJob;
316 }
317
318
319 /************************************************************************
320  *           PSDRV_EndDoc
321  */
322 INT PSDRV_EndDoc( DC *dc )
323 {
324     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
325
326     if(!physDev->job.hJob) {
327         FIXME("hJob == 0. Now what?\n");
328         return 0;
329     }
330
331     if(!physDev->job.OutOfPage) {
332         WARN("Somebody forgot a EndPage\n");
333         PSDRV_EndPage( dc );
334     }
335     if(!PSDRV_WriteFooter( dc ))
336         return 0;
337
338     if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
339         WARN("CloseJob error\n");
340         return 0;
341     }
342     physDev->job.hJob = 0;
343     return 1;
344 }