| /* | |
| * PostScript driver Escape function | |
| * | |
| * Copyright 1998 Huw D M Davies | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| */ | |
| #include "windef.h" | |
| #include "wingdi.h" | |
| #include "wine/winuser16.h" | |
| #include "wownt32.h" | |
| #include "psdrv.h" | |
| #include "wine/debug.h" | |
| #include "winspool.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(psdrv); | |
| /********************************************************************** | |
| * ExtEscape (WINEPS.@) | |
| */ | |
| INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID in_data, | |
| INT cbOutput, LPVOID out_data ) | |
| { | |
| switch(nEscape) | |
| { | |
| case QUERYESCSUPPORT: | |
| if(cbInput < sizeof(INT)) | |
| { | |
| WARN("cbInput < sizeof(INT) (=%d) for QUERYESCSUPPORT\n", cbInput); | |
| return 0; | |
| } else { | |
| UINT num = *(UINT *)in_data; | |
| TRACE("QUERYESCSUPPORT for %d\n", num); | |
| switch(num) { | |
| case NEXTBAND: | |
| case SETCOPYCOUNT: | |
| case GETTECHNOLOGY: | |
| case SETLINECAP: | |
| case SETLINEJOIN: | |
| case SETMITERLIMIT: | |
| case SETCHARSET: | |
| case EXT_DEVICE_CAPS: | |
| case SET_BOUNDS: | |
| case EPSPRINTING: | |
| case PASSTHROUGH: | |
| case POSTSCRIPT_PASSTHROUGH: | |
| return TRUE; | |
| default: | |
| return FALSE; | |
| } | |
| } | |
| case NEXTBAND: | |
| { | |
| RECT *r = out_data; | |
| if(!physDev->job.banding) { | |
| physDev->job.banding = TRUE; | |
| r->left = 0; | |
| r->top = 0; | |
| r->right = physDev->horzRes; | |
| r->bottom = physDev->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; | |
| return EndPage( physDev->hdc ); | |
| } | |
| case SETCOPYCOUNT: | |
| { | |
| const INT *NumCopies = in_data; | |
| INT *ActualCopies = out_data; | |
| if(cbInput != sizeof(INT)) { | |
| WARN("cbInput != sizeof(INT) (=%d) for SETCOPYCOUNT\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETCOPYCOUNT %d\n", *NumCopies); | |
| *ActualCopies = 1; | |
| return 1; | |
| } | |
| case GETTECHNOLOGY: | |
| { | |
| LPSTR p = out_data; | |
| strcpy(p, "PostScript"); | |
| *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */ | |
| return 1; | |
| } | |
| case SETLINECAP: | |
| { | |
| INT newCap = *(INT *)in_data; | |
| if(cbInput != sizeof(INT)) { | |
| WARN("cbInput != sizeof(INT) (=%d) for SETLINECAP\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETLINECAP %d\n", newCap); | |
| return 0; | |
| } | |
| case SETLINEJOIN: | |
| { | |
| INT newJoin = *(INT *)in_data; | |
| if(cbInput != sizeof(INT)) { | |
| WARN("cbInput != sizeof(INT) (=%d) for SETLINEJOIN\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("SETLINEJOIN %d\n", newJoin); | |
| return 0; | |
| } | |
| case SETMITERLIMIT: | |
| { | |
| INT newLimit = *(INT *)in_data; | |
| if(cbInput != sizeof(INT)) { | |
| WARN("cbInput != sizeof(INT) (=%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: | |
| { | |
| UINT cap = *(UINT *)in_data; | |
| if(cbInput != sizeof(UINT)) { | |
| WARN("cbInput != sizeof(UINT) (=%d) for EXT_DEVICE_CAPS\n", cbInput); | |
| return 0; | |
| } | |
| TRACE("EXT_DEVICE_CAPS %d\n", cap); | |
| return 0; | |
| } | |
| case SET_BOUNDS: | |
| { | |
| const RECT *r = in_data; | |
| if(cbInput != sizeof(RECT)) { | |
| WARN("cbInput != sizeof(RECT) (=%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; | |
| } | |
| case EPSPRINTING: | |
| { | |
| UINT epsprint = *(UINT*)in_data; | |
| /* FIXME: In this mode we do not need to send page intros and page | |
| * ends according to the doc. But I just ignore that detail | |
| * for now. | |
| */ | |
| TRACE("EPS Printing support %sable.\n",epsprint?"en":"dis"); | |
| return 1; | |
| } | |
| case PASSTHROUGH: | |
| case POSTSCRIPT_PASSTHROUGH: | |
| { | |
| /* Write directly to spool file, bypassing normal PS driver | |
| * processing that is done along with writing PostScript code | |
| * to the spool. | |
| * (Usually we have a WORD before the data counting the size, but | |
| * cbInput is just this +2.) | |
| */ | |
| return WriteSpool16(physDev->job.hJob,((char*)in_data)+2,cbInput-2); | |
| } | |
| case GETSETPRINTORIENT: | |
| { | |
| /* If lpInData is present, it is a 20 byte structure, first 32 | |
| * bit LONG value is the orientation. if lpInData is NULL, it | |
| * returns the current orientation. | |
| */ | |
| FIXME("GETSETPRINTORIENT not implemented (data %p)!\n",in_data); | |
| return 1; | |
| } | |
| default: | |
| FIXME("Unimplemented code 0x%x\n", nEscape); | |
| return 0; | |
| } | |
| } | |
| /************************************************************************ | |
| * PSDRV_StartPage | |
| */ | |
| INT PSDRV_StartPage( PSDRV_PDEVICE *physDev ) | |
| { | |
| if(!physDev->job.OutOfPage) { | |
| FIXME("Already started a page?\n"); | |
| return 1; | |
| } | |
| physDev->job.PageNo++; | |
| if(!PSDRV_WriteNewPage( physDev )) | |
| return 0; | |
| physDev->job.OutOfPage = FALSE; | |
| return 1; | |
| } | |
| /************************************************************************ | |
| * PSDRV_EndPage | |
| */ | |
| INT PSDRV_EndPage( PSDRV_PDEVICE *physDev ) | |
| { | |
| if(physDev->job.OutOfPage) { | |
| FIXME("Already ended a page?\n"); | |
| return 1; | |
| } | |
| if(!PSDRV_WriteEndPage( physDev )) | |
| return 0; | |
| PSDRV_EmptyDownloadList(physDev); | |
| physDev->job.OutOfPage = TRUE; | |
| return 1; | |
| } | |
| /************************************************************************ | |
| * PSDRV_StartDoc | |
| */ | |
| INT PSDRV_StartDoc( PSDRV_PDEVICE *physDev, const DOCINFOA *doc ) | |
| { | |
| 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 = HeapAlloc( PSDRV_Heap, 0, strlen(doc->lpszOutput)+1 ); | |
| strcpy( physDev->job.output, doc->lpszOutput ); | |
| } | |
| physDev->job.hJob = OpenJob16(physDev->job.output, doc->lpszDocName, HDC_16(physDev->hdc) ); | |
| 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( physDev, doc->lpszDocName )) | |
| return 0; | |
| return physDev->job.hJob; | |
| } | |
| /************************************************************************ | |
| * PSDRV_EndDoc | |
| */ | |
| INT PSDRV_EndDoc( PSDRV_PDEVICE *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( physDev ); | |
| } | |
| if(!PSDRV_WriteFooter( physDev )) | |
| return 0; | |
| if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) { | |
| WARN("CloseJob error\n"); | |
| return 0; | |
| } | |
| physDev->job.hJob = 0; | |
| return 1; | |
| } |