Alexandre Julliard : wineps.drv: Duplicate the print job support from 16-bit GDI.
Alexandre Julliard
julliard at winehq.org
Mon Dec 7 10:26:16 CST 2009
Module: wine
Branch: master
Commit: 9a05f3143fc3304ad3207a90a249517b6d5665d4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9a05f3143fc3304ad3207a90a249517b6d5665d4
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Dec 4 21:29:08 2009 +0100
wineps.drv: Duplicate the print job support from 16-bit GDI.
---
dlls/wineps.drv/escape.c | 134 +++++++++++++++++++++++++++++++++++++++++----
dlls/wineps.drv/init.c | 2 +-
dlls/wineps.drv/psdrv.h | 2 +-
dlls/wineps.drv/text.c | 2 +-
4 files changed, 125 insertions(+), 15 deletions(-)
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index 73412cc..1062b96 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -17,13 +17,26 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+
+#include "config.h"
+#include "wine/port.h"
+
#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/wingdi16.h"
-#include "wownt32.h"
+#include "winreg.h"
#include "psdrv.h"
#include "wine/debug.h"
#include "winspool.h"
@@ -33,9 +46,109 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
static const char psbegindocument[] =
"%%BeginDocument: Wine passthrough\n";
+/* FIXME: should use winspool functions instead */
+static DWORD create_job(LPCSTR pszOutput)
+{
+ int fd = -1;
+ char psCmd[1024];
+ const char *psCmdP = psCmd;
+ HKEY hkey;
+
+ /* TTD convert the 'output device' into a spool file name */
+
+ if (pszOutput == NULL || *pszOutput == '\0') return 0;
+
+ psCmd[0] = 0;
+ /* @@ Wine registry key: HKCU\Software\Wine\Printing\Spooler */
+ if(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Printing\\Spooler", &hkey))
+ {
+ DWORD type, count = sizeof(psCmd);
+ RegQueryValueExA(hkey, pszOutput, 0, &type, (LPBYTE)psCmd, &count);
+ RegCloseKey(hkey);
+ }
+ if (!psCmd[0] && !strncmp("LPR:",pszOutput,4))
+ sprintf(psCmd,"|lpr -P'%s'",pszOutput+4);
+
+ TRACE("Got printerSpoolCommand '%s' for output device '%s'\n",
+ psCmd, pszOutput);
+ if (!*psCmd)
+ psCmdP = pszOutput;
+ else
+ {
+ while (*psCmdP && isspace(*psCmdP))
+ {
+ psCmdP++;
+ }
+ if (!*psCmdP) return 0;
+ }
+ TRACE("command: '%s'\n", psCmdP);
+#ifdef HAVE_FORK
+ if (*psCmdP == '|')
+ {
+ int fds[2];
+ if (pipe(fds)) {
+ ERR("pipe() failed!\n");
+ return 0;
+ }
+ if (fork() == 0)
+ {
+ psCmdP++;
+
+ TRACE("In child need to exec %s\n",psCmdP);
+ close(0);
+ dup2(fds[0],0);
+ close (fds[1]);
+
+ /* reset signals that we previously set to SIG_IGN */
+ signal( SIGPIPE, SIG_DFL );
+ signal( SIGCHLD, SIG_DFL );
+
+ execl("/bin/sh", "/bin/sh", "-c", psCmdP, NULL);
+ _exit(1);
+
+ }
+ close (fds[0]);
+ fd = fds[1];
+ TRACE("Need to execute a cmnd and pipe the output to it\n");
+ }
+ else
+#endif
+ {
+ char *buffer;
+ WCHAR psCmdPW[MAX_PATH];
+
+ TRACE("Just assume it's a file\n");
+
+ /**
+ * The file name can be dos based, we have to find its
+ * corresponding Unix file name.
+ */
+ MultiByteToWideChar(CP_ACP, 0, psCmdP, -1, psCmdPW, MAX_PATH);
+ if ((buffer = wine_get_unix_file_name(psCmdPW)))
+ {
+ if ((fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
+ {
+ ERR("Failed to create spool file '%s' ('%s'). (error %s)\n",
+ buffer, psCmdP, strerror(errno));
+ }
+ HeapFree(GetProcessHeap(), 0, buffer);
+ }
+ }
+ return fd + 1;
+}
+
+static int close_job( DWORD id )
+{
+ int fd = id - 1;
+ close( fd );
+ return TRUE;
+}
+
DWORD write_spool( PSDRV_PDEVICE *physDev, const void *data, DWORD num )
{
- return WriteSpool16( physDev->job.hJob, (LPSTR)data, num );
+ int fd = physDev->job.id - 1;
+ if (write( fd, data, num) != num) return SP_OUTOFDISK;
+ return num;
}
/**********************************************************************
@@ -393,7 +506,7 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc )
PRINTER_INFO_5A *pi5 = (PRINTER_INFO_5A*)buf;
DWORD needed;
- if(physDev->job.hJob) {
+ if(physDev->job.id) {
FIXME("hJob != 0. Now what?\n");
return 0;
}
@@ -411,8 +524,8 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc )
ClosePrinter(hprn);
}
- physDev->job.hJob = OpenJob16(output, doc->lpszDocName, HDC_16(physDev->hdc) );
- if(!physDev->job.hJob) {
+ physDev->job.id = create_job( output );
+ if(!physDev->job.id) {
WARN("OpenJob failed\n");
return 0;
}
@@ -428,7 +541,7 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc )
} else
physDev->job.DocName = NULL;
- return physDev->job.hJob;
+ return physDev->job.id;
}
/************************************************************************
@@ -479,7 +592,7 @@ INT CDECL PSDRV_StartDoc( PSDRV_PDEVICE *physDev, const DOCINFOW *doc )
INT CDECL PSDRV_EndDoc( PSDRV_PDEVICE *physDev )
{
INT ret = 1;
- if(!physDev->job.hJob) {
+ if(!physDev->job.id) {
FIXME("hJob == 0. Now what?\n");
return 0;
}
@@ -490,11 +603,8 @@ INT CDECL PSDRV_EndDoc( PSDRV_PDEVICE *physDev )
}
PSDRV_WriteFooter( physDev );
- if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) {
- WARN("CloseJob error\n");
- ret = 0;
- }
- physDev->job.hJob = 0;
+ ret = close_job( physDev->job.id );
+ physDev->job.id = 0;
HeapFree(GetProcessHeap(), 0, physDev->job.DocName);
physDev->job.DocName = NULL;
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index 152ee03..fca0849 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -365,7 +365,7 @@ BOOL CDECL PSDRV_CreateDC( HDC hdc, PSDRV_PDEVICE **pdev, LPCWSTR driver, LPCWST
WideCharToMultiByte( CP_ACP, 0, output, -1, physDev->job.output, len, NULL, NULL );
} else
physDev->job.output = NULL;
- physDev->job.hJob = 0;
+ physDev->job.id = 0;
if(initData) {
DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, initData);
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 5fecc15..99560a7 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -335,7 +335,7 @@ typedef struct {
} PSPEN;
typedef struct {
- HANDLE16 hJob;
+ DWORD id; /* Job id */
LPSTR output; /* Output file/port */
LPSTR DocName; /* Document Name */
BOOL banding; /* Have we received a NEXTBAND */
diff --git a/dlls/wineps.drv/text.c b/dlls/wineps.drv/text.c
index 310e1cb..8ed7888 100644
--- a/dlls/wineps.drv/text.c
+++ b/dlls/wineps.drv/text.c
@@ -47,7 +47,7 @@ BOOL CDECL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
flags, debugstr_wn(str, count), count, lpDx);
- if(physDev->job.hJob == 0) return FALSE;
+ if(physDev->job.id == 0) return FALSE;
/* write font if not already written */
PSDRV_SetFont(physDev);
More information about the wine-cvs
mailing list