2 * PostScript driver Escape function
4 * Copyright 1998 Huw D M Davies
8 #include "wine/winuser16.h"
10 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(psdrv);
16 INT PSDRV_Escape( DC *dc, INT nEscape, INT cbInput,
17 SEGPTR lpInData, SEGPTR lpOutData )
19 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
24 RECT16 *r = MapSL(lpOutData);
25 if(!physDev->job.banding) {
26 physDev->job.banding = TRUE;
29 r->right = physDev->horzRes;
30 r->bottom = physDev->vertRes;
31 TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left,
32 r->top, r->right, r->bottom );
39 TRACE("NEXTBAND rect to 0,0 - 0,0\n" );
40 physDev->job.banding = FALSE;
46 if(!physDev->job.hJob) {
47 FIXME("hJob == 0. Now what?\n");
51 if(!PSDRV_EndPage( dc ))
57 WARN("cbInput < 2 (=%d) for QUERYESCSUPPORT\n", cbInput);
60 UINT16 num = *(UINT16 *)MapSL(lpInData);
61 TRACE("QUERYESCSUPPORT for %d\n", num);
71 case GETPRINTINGOFFSET:
72 case GETSCALINGFACTOR:
83 case POSTSCRIPT_PASSTHROUGH:
92 TRACE("SETABORTPROC\n");
103 /* lpInData may not be 0 terminated so we must copy it */
105 name = HeapAlloc( GetProcessHeap(), 0, cbInput+1 );
106 memcpy(name, MapSL(lpInData), cbInput);
107 name[cbInput] = '\0';
109 doc.cbSize = sizeof(doc);
110 doc.lpszDocName = name;
111 doc.lpszOutput = doc.lpszDatatype = NULL;
114 ret = PSDRV_StartDoc(dc, &doc);
115 if(name) HeapFree( GetProcessHeap(), 0, name );
116 if(ret <= 0) return -1;
117 ret = PSDRV_StartPage(dc);
118 if(ret <= 0) return -1;
124 return PSDRV_EndDoc( dc );
126 case GETPHYSPAGESIZE:
128 PSDRV_PDEVICE *pdev = (PSDRV_PDEVICE *)(dc->physDev);
129 POINT16 *p = MapSL(lpOutData);
133 if ((pdev->Devmode->dmPublic.dmFields & DM_PAPERSIZE) != 0 &&
134 pdev->Devmode->dmPublic.u1.s1.dmPaperSize != 0)
136 PAGESIZE *page = pdev->pi->ppd->PageSizes;
141 pdev->Devmode->dmPublic.u1.s1.dmPaperSize)
148 ERR("No entry for papersize %u in PPD file for '%s'\n",
149 pdev->Devmode->dmPublic.u1.s1.dmPaperSize,
150 pdev->pi->FriendlyName);
154 TRACE("Found '%s' for paper size %u\n", page->FullName,
155 pdev->Devmode->dmPublic.u1.s1.dmPaperSize);
157 p->x = page->PaperDimension->x * physDev->logPixelsX / 72;
158 p->y = page->PaperDimension->y * physDev->logPixelsY / 72;
160 TRACE("%fx%f PostScript points = %ix%i device units\n",
161 page->PaperDimension->x, page->PaperDimension->y,
165 /* These are in tenths of a millimeter */
167 if ((pdev->Devmode->dmPublic.dmFields & DM_PAPERWIDTH) != 0 &&
168 pdev->Devmode->dmPublic.u1.s1.dmPaperWidth != 0)
170 p->x = (pdev->Devmode->dmPublic.u1.s1.dmPaperWidth *
171 physDev->logPixelsX) / 254;
172 TRACE("dmPaperWidth = %i device units\n", p->x);
175 if ((pdev->Devmode->dmPublic.dmFields & DM_PAPERLENGTH) != 0 &&
176 pdev->Devmode->dmPublic.u1.s1.dmPaperLength != 0)
178 p->y = (pdev->Devmode->dmPublic.u1.s1.dmPaperLength *
179 physDev->logPixelsY) / 254;
180 TRACE("dmPaperLength = %i device units\n", p->y);
183 if (p->x == 0 || p->y == 0)
185 ERR("Paper size not properly set for '%s'\n",
186 pdev->pi->FriendlyName);
190 if ((pdev->Devmode->dmPublic.dmFields & DM_ORIENTATION) != 0 &&
191 pdev->Devmode->dmPublic.u1.s1.dmOrientation ==
194 register INT16 temp = p->y;
202 case GETPRINTINGOFFSET:
204 POINT16 *p = MapSL(lpOutData);
207 TRACE("GETPRINTINGOFFSET: returning %dx%d\n", p->x, p->y);
211 case GETSCALINGFACTOR:
213 POINT16 *p = MapSL(lpOutData);
216 TRACE("GETSCALINGFACTOR: returning %dx%d\n", p->x, p->y);
222 INT16 *NumCopies = MapSL(lpInData);
223 INT16 *ActualCopies = MapSL(lpOutData);
225 WARN("cbInput != 2 (=%d) for SETCOPYCOUNT\n", cbInput);
228 TRACE("SETCOPYCOUNT %d\n", *NumCopies);
235 LPSTR p = MapSL(lpOutData);
236 strcpy(p, "PostScript");
237 *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */
243 INT16 newCap = *(INT16 *)MapSL(lpInData);
245 WARN("cbInput != 2 (=%d) for SETLINECAP\n", cbInput);
248 TRACE("SETLINECAP %d\n", newCap);
254 INT16 newJoin = *(INT16 *)MapSL(lpInData);
256 WARN("cbInput != 2 (=%d) for SETLINEJOIN\n", cbInput);
259 TRACE("SETLINEJOIN %d\n", newJoin);
265 INT16 newLimit = *(INT16 *)MapSL(lpInData);
267 WARN("cbInput != 2 (=%d) for SETMITERLIMIT\n", cbInput);
270 TRACE("SETMITERLIMIT %d\n", newLimit);
275 /* Undocumented escape used by winword6.
276 Switches between ANSI and a special charset.
277 If *lpInData == 1 we require that
281 0x94 is quotedblright
285 0xa0 is non break space - yeah right.
287 If *lpInData == 0 we get ANSI.
288 Since there's nothing else there, let's just make these the default
289 anyway and see what happens...
293 case EXT_DEVICE_CAPS:
295 UINT16 cap = *(UINT16 *)MapSL(lpInData);
297 WARN("cbInput != 2 (=%d) for EXT_DEVICE_CAPS\n",
301 TRACE("EXT_DEVICE_CAPS %d\n", cap);
307 RECT16 *r = MapSL(lpInData);
309 WARN("cbInput != 8 (=%d) for SET_BOUNDS\n", cbInput);
312 TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top,
313 r->right, r->bottom);
319 UINT16 epsprint = *(UINT16*)MapSL(lpInData);
320 /* FIXME: In this mode we do not need to send page intros and page
321 * ends according to the doc. But I just ignore that detail
324 TRACE("EPS Printing support %sable.\n",epsprint?"en":"dis");
328 case POSTSCRIPT_PASSTHROUGH:
330 /* Write directly to spool file, bypassing normal PS driver
331 * processing that is done along with writing PostScript code
333 * (Usually we have a WORD before the data counting the size, but
334 * cbInput is just this +2.)
336 return WriteSpool16(physDev->job.hJob,((char*)lpInData)+2,cbInput-2);
339 case GETSETPRINTORIENT:
341 /* If lpInData is present, it is a 20 byte structure, first 32
342 * bit LONG value is the orientation. if lpInData is NULL, it
343 * returns the current orientation.
345 FIXME("GETSETPRINTORIENT not implemented (lpInData %ld)!\n",lpInData);
349 FIXME("Unimplemented code 0x%x\n", nEscape);
354 /************************************************************************
357 INT PSDRV_StartPage( DC *dc )
359 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
361 if(!physDev->job.OutOfPage) {
362 FIXME("Already started a page?\n");
365 physDev->job.PageNo++;
366 if(!PSDRV_WriteNewPage( dc ))
368 physDev->job.OutOfPage = FALSE;
373 /************************************************************************
376 INT PSDRV_EndPage( DC *dc )
378 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
380 if(physDev->job.OutOfPage) {
381 FIXME("Already ended a page?\n");
384 if(!PSDRV_WriteEndPage( dc ))
386 physDev->job.OutOfPage = TRUE;
391 /************************************************************************
394 INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc )
396 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
398 if(physDev->job.hJob) {
399 FIXME("hJob != 0. Now what?\n");
403 if(doc->lpszOutput) {
404 HeapFree( PSDRV_Heap, 0, physDev->job.output );
405 physDev->job.output = HeapAlloc( PSDRV_Heap, 0, strlen(doc->lpszOutput)+1 );
406 strcpy( physDev->job.output, doc->lpszOutput );
408 physDev->job.hJob = OpenJob16(physDev->job.output, doc->lpszDocName,
410 if(!physDev->job.hJob) {
411 WARN("OpenJob failed\n");
414 physDev->job.banding = FALSE;
415 physDev->job.OutOfPage = TRUE;
416 physDev->job.PageNo = 0;
417 if(!PSDRV_WriteHeader( dc, doc->lpszDocName ))
420 return physDev->job.hJob;
424 /************************************************************************
427 INT PSDRV_EndDoc( DC *dc )
429 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
431 if(!physDev->job.hJob) {
432 FIXME("hJob == 0. Now what?\n");
436 if(!physDev->job.OutOfPage) {
437 WARN("Somebody forgot a EndPage\n");
440 if(!PSDRV_WriteFooter( dc ))
443 if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
444 WARN("CloseJob error\n");
447 physDev->job.hJob = 0;