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