| /* | |
| * PostScript driver Escape function | |
| * | |
| * Copyright 1998 Huw D M Davies | |
| */ | |
| #include "windef.h" | |
| #include "wingdi.h" | |
| #include "wine/winuser16.h" | |
| #include "psdrv.h" | |
| #include "debugtools.h" | |
| #include "winspool.h" | |
| #include "heap.h" | |
| DEFAULT_DEBUG_CHANNEL(psdrv) | |
| INT PSDRV_Escape( DC *dc, INT nEscape, INT cbInput, | |
| SEGPTR lpInData, SEGPTR lpOutData ) | |
| { | |
| PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; | |
| switch(nEscape) { | |
| case NEXTBAND: { | |
| RECT16 *r = (RECT16 *)PTR_SEG_TO_LIN(lpOutData); | |
| if(!physDev->job.banding) { | |
| physDev->job.banding = TRUE; | |
| r->left = 0; | |
| r->top = 0; | |
| r->right = dc->w.devCaps->horzRes; | |
| r->bottom = dc->w.devCaps->vertRes; | |
| TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left, | |
| r->top, r->right, r->bottom ); | |
| return 1; | |
| } | |
| r->left = 0; | |
| r->top = 0; | |
| r->right = 0; | |
| r->bottom = 0; | |
| TRACE("NEXTBAND rect to 0,0 - 0,0\n" ); | |
| physDev->job.banding = FALSE; | |
| } /* Fall through */ | |
| case NEWFRAME: | |
| TRACE("NEWFRAME\n"); | |
| if(!physDev->job.hJob) { | |
| FIXME("hJob == 0. Now what?\n"); | |
| return SP_ERROR; | |
| } | |
| if(!PSDRV_EndPage( dc )) | |
| return SP_ERROR; | |
| return 1; | |
| case QUERYESCSUPPORT: | |
| if(cbInput < 2) { | |
| WARN("cbInput < 2 (=%d) for QUERYESCSUPPORT\n", cbInput); | |
| return 0; | |
| } else { | |
| UINT16 num = *(UINT16 *)PTR_SEG_TO_LIN(lpInData); | |
| TRACE("QUERYESCSUPPORT for %d\n", num); | |
| switch(num) { | |
| case NEWFRAME: | |
| case NEXTBAND: | |
| case QUERYESCSUPPORT: | |
| case SETABORTPROC: | |
| case STARTDOC: | |
| case ENDDOC: | |
| case GETPHYSPAGESIZE: | |
| case GETPRINTINGOFFSET: | |
| case GETSCALINGFACTOR: | |
| case SETCOPYCOUNT: | |
| case GETTECHNOLOGY: | |
| case SETLINECAP: | |
| case SETLINEJOIN: | |
| case SETMITERLIMIT: | |
| case SETCHARSET: | |
| case EXT_DEVICE_CAPS: | |
| case SET_BOUNDS: | |
| return TRUE; | |
| default: | |
| return FALSE; | |
| } | |
| } | |
| case SETABORTPROC: | |
| TRACE("SETABORTPROC\n"); | |
| return 1; | |
| case STARTDOC: | |
| { | |
| DOCINFOA doc; | |
| char *name = NULL; | |
| INT16 ret; | |
| TRACE("STARTDOC\n"); | |
| /* lpInData may not be 0 terminated so we must copy it */ | |
| if(lpInData) { | |
| name = HeapAlloc( GetProcessHeap(), 0, cbInput+1 ); | |
| memcpy(name, PTR_SEG_TO_LIN(lpInData), cbInput); | |
| name[cbInput] = '\0'; | |
| } | |
| doc.cbSize = sizeof(doc); | |
| doc.lpszDocName = name; | |
| doc.lpszOutput = doc.lpszDatatype = NULL; | |
| doc.fwType = 0; | |
| ret = PSDRV_StartDoc(dc, &doc); | |
| if(name) HeapFree( GetProcessHeap(), 0, name ); | |
| if(ret <= 0) return -1; | |
| ret = PSDRV_StartPage(dc); | |
| if(ret <= 0) return -1; | |
| return ret; | |
| } | |
| case ENDDOC: | |
| TRACE("ENDDOC\n"); | |
| return PSDRV_EndDoc( dc ); | |
| case GETPHYSPAGESIZE: | |
| { | |
| POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData); | |
| p->x = dc->w.devCaps->horzRes; | |
| p->y = dc->w.devCaps->vertRes; | |
| TRACE("GETPHYSPAGESIZE: returning %dx%d\n", p->x, p->y); | |
| return 1; | |
| } | |
| case GETPRINTINGOFFSET: | |
| { | |
| POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData); | |
| p->x = p->y = 0; | |
| TRACE("GETPRINTINGOFFSET: returning %dx%d\n", p->x, p->y); | |
| return 1; | |
| } | |
| case GETSCALINGFACTOR: | |
| { | |
| POINT16 *p = (POINT16 *)PTR_SEG_TO_LIN(lpOutData); | |
| p->x = p->y = 0; | |
| TRACE("GETSCALINGFACTOR: returning %dx%d\n", p->x, p->y); | |
| return 1; | |
| } | |
| case SETCOPYCOUNT: | |
| { | |
| INT16 *NumCopies = (INT16 *)PTR_SEG_TO_LIN(lpInData); | |
| INT16 *ActualCopies = (INT16 *)PTR_SEG_TO_LIN(lpOutData); | |
| if(cbInput != 2) { | |
| WARN("cbInput != 2 (=%d) for SETCOPYCOUNT\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETCOPYCOUNT %d\n", *NumCopies); | |
| *ActualCopies = 1; | |
| return 1; | |
| } | |
| case GETTECHNOLOGY: | |
| { | |
| LPSTR p = (LPSTR)PTR_SEG_TO_LIN(lpOutData); | |
| strcpy(p, "PostScript"); | |
| *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */ | |
| return 1; | |
| } | |
| case SETLINECAP: | |
| { | |
| INT16 newCap = *(INT16 *)PTR_SEG_TO_LIN(lpInData); | |
| if(cbInput != 2) { | |
| WARN("cbInput != 2 (=%d) for SETLINECAP\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETLINECAP %d\n", newCap); | |
| return 0; | |
| } | |
| case SETLINEJOIN: | |
| { | |
| INT16 newJoin = *(INT16 *)PTR_SEG_TO_LIN(lpInData); | |
| if(cbInput != 2) { | |
| WARN("cbInput != 2 (=%d) for SETLINEJOIN\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETLINEJOIN %d\n", newJoin); | |
| return 0; | |
| } | |
| case SETMITERLIMIT: | |
| { | |
| INT16 newLimit = *(INT16 *)PTR_SEG_TO_LIN(lpInData); | |
| if(cbInput != 2) { | |
| WARN("cbInput != 2 (=%d) for SETMITERLIMIT\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETMITERLIMIT %d\n", newLimit); | |
| return 0; | |
| } | |
| case SETCHARSET: | |
| /* Undocumented escape used by winword6. | |
| Switches between ANSI and a special charset. | |
| If *lpInData == 1 we require that | |
| 0x91 is quoteleft | |
| 0x92 is quoteright | |
| 0x93 is quotedblleft | |
| 0x94 is quotedblright | |
| 0x95 is bullet | |
| 0x96 is endash | |
| 0x97 is emdash | |
| 0xa0 is non break space - yeah right. | |
| If *lpInData == 0 we get ANSI. | |
| Since there's nothing else there, let's just make these the default | |
| anyway and see what happens... | |
| */ | |
| return 1; | |
| case EXT_DEVICE_CAPS: | |
| { | |
| UINT16 cap = *(UINT16 *)PTR_SEG_TO_LIN(lpInData); | |
| if(cbInput != 2) { | |
| WARN("cbInput != 2 (=%d) for EXT_DEVICE_CAPS\n", | |
| cbInput); | |
| return 0; | |
| } | |
| TRACE("EXT_DEVICE_CAPS %d\n", cap); | |
| return 0; | |
| } | |
| case SET_BOUNDS: | |
| { | |
| RECT16 *r = (RECT16 *)PTR_SEG_TO_LIN(lpInData); | |
| if(cbInput != 8) { | |
| WARN("cbInput != 8 (=%d) for SET_BOUNDS\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SET_BOUNDS (%d,%d) - (%d,%d)\n", r->left, r->top, | |
| r->right, r->bottom); | |
| return 0; | |
| } | |
| default: | |
| FIXME("Unimplemented code 0x%x\n", nEscape); | |
| return 0; | |
| } | |
| } | |
| /************************************************************************ | |
| * PSDRV_StartPage | |
| */ | |
| INT PSDRV_StartPage( DC *dc ) | |
| { | |
| PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; | |
| if(!physDev->job.OutOfPage) { | |
| FIXME("Already started a page?\n"); | |
| return 1; | |
| } | |
| physDev->job.PageNo++; | |
| if(!PSDRV_WriteNewPage( dc )) | |
| return 0; | |
| physDev->job.OutOfPage = FALSE; | |
| return 1; | |
| } | |
| /************************************************************************ | |
| * PSDRV_EndPage | |
| */ | |
| INT PSDRV_EndPage( DC *dc ) | |
| { | |
| PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; | |
| if(physDev->job.OutOfPage) { | |
| FIXME("Already ended a page?\n"); | |
| return 1; | |
| } | |
| if(!PSDRV_WriteEndPage( dc )) | |
| return 0; | |
| physDev->job.OutOfPage = TRUE; | |
| return 1; | |
| } | |
| /************************************************************************ | |
| * PSDRV_StartDoc | |
| */ | |
| INT PSDRV_StartDoc( DC *dc, const DOCINFOA *doc ) | |
| { | |
| PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; | |
| if(physDev->job.hJob) { | |
| FIXME("hJob != 0. Now what?\n"); | |
| return 0; | |
| } | |
| if(doc->lpszOutput) { | |
| HeapFree( PSDRV_Heap, 0, physDev->job.output ); | |
| physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, doc->lpszOutput ); | |
| } | |
| physDev->job.hJob = OpenJob16(physDev->job.output, doc->lpszDocName, | |
| dc->hSelf); | |
| if(!physDev->job.hJob) { | |
| WARN("OpenJob failed\n"); | |
| return 0; | |
| } | |
| physDev->job.banding = FALSE; | |
| physDev->job.OutOfPage = TRUE; | |
| physDev->job.PageNo = 0; | |
| if(!PSDRV_WriteHeader( dc, doc->lpszDocName )) | |
| return 0; | |
| return physDev->job.hJob; | |
| } | |
| /************************************************************************ | |
| * PSDRV_EndDoc | |
| */ | |
| INT PSDRV_EndDoc( DC *dc ) | |
| { | |
| PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; | |
| if(!physDev->job.hJob) { | |
| FIXME("hJob == 0. Now what?\n"); | |
| return 0; | |
| } | |
| if(!physDev->job.OutOfPage) { | |
| WARN("Somebody forgot a EndPage\n"); | |
| PSDRV_EndPage( dc ); | |
| } | |
| if(!PSDRV_WriteFooter( dc )) | |
| return 0; | |
| if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) { | |
| WARN("CloseJob error\n"); | |
| return 0; | |
| } | |
| physDev->job.hJob = 0; | |
| return 1; | |
| } |