wineps: duplex support

Huw D M Davies h.davies1 at physics.ox.ac.uk
Tue Nov 4 13:19:18 CST 2003


        Huw Davies <huw at codeweavers.com>
        Support for duplex printing

Index: dlls/wineps/driver.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/driver.c,v
retrieving revision 1.20
diff -u -r1.20 driver.c
--- dlls/wineps/driver.c	8 Aug 2003 21:07:23 -0000	1.20
+++ dlls/wineps/driver.c	4 Nov 2003 19:16:38 -0000
@@ -136,7 +136,7 @@
        dm1->dmPublic.dmPrintQuality = dm2->dmPublic.dmPrintQuality;
    if (dm2->dmPublic.dmFields & DM_COLOR )
        dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
-   if (dm2->dmPublic.dmFields & DM_DUPLEX )
+   if (dm2->dmPublic.dmFields & DM_DUPLEX && pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
        dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
    if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
        dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
@@ -201,7 +201,7 @@
   PSDRV_DLGINFO *di;
   int i, Cursel = 0;
   PAGESIZE *ps;
-
+  DUPLEX *duplex;
 
   switch(msg) {
   case WM_INITDIALOG:
@@ -215,11 +215,25 @@
 	Cursel = i;
     }
     SendDlgItemMessageA(hwnd, IDD_PAPERS, LB_SETCURSEL, Cursel, 0);
-
+    
     CheckRadioButton(hwnd, IDD_ORIENT_PORTRAIT, IDD_ORIENT_LANDSCAPE,
 		     di->pi->Devmode->dmPublic.u1.s1.dmOrientation ==
 		     DMORIENT_PORTRAIT ? IDD_ORIENT_PORTRAIT :
 		     IDD_ORIENT_LANDSCAPE);
+
+    if(!di->pi->ppd->Duplexes) {
+        ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX), SW_HIDE);
+        ShowWindow(GetDlgItem(hwnd, IDD_DUPLEX_NAME), SW_HIDE);        
+    } else {
+        Cursel = 0;
+        for(duplex = di->pi->ppd->Duplexes, i = 0; duplex; duplex = duplex->next, i++) {
+            SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_INSERTSTRING, i,
+                                (LPARAM)(duplex->FullName ? duplex->FullName : duplex->Name));
+            if(di->pi->Devmode->dmPublic.dmDuplex == duplex->WinDuplex)
+                Cursel = i;
+        }
+        SendDlgItemMessageA(hwnd, IDD_DUPLEX, CB_SETCURSEL, Cursel, 0);
+    }
     break;
 
   case WM_COMMAND:
@@ -242,6 +256,16 @@
       di->dlgdm->dmPublic.u1.s1.dmOrientation = wParam == IDD_ORIENT_PORTRAIT ?
 	DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
       break;
+    case IDD_DUPLEX:
+      if(HIWORD(wParam) == CBN_SELCHANGE) {
+	Cursel = SendDlgItemMessageA(hwnd, LOWORD(wParam), CB_GETCURSEL, 0, 0);
+	for(i = 0, duplex = di->pi->ppd->Duplexes; i < Cursel; i++, duplex = duplex->next)
+	  ;
+	TRACE("Setting duplex to item %d Winduplex = %d\n", Cursel,
+	      duplex->WinDuplex);
+	di->dlgdm->dmPublic.dmDuplex = duplex->WinDuplex;
+      }
+      break;
     }
     break;
 
@@ -417,6 +441,7 @@
 {
   PRINTERINFO *pi;
   DEVMODEA *lpdm;
+  DWORD ret;
   pi = PSDRV_FindPrinterInfo(lpszDevice);
 
   TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
@@ -482,12 +507,6 @@
       WORD *wp = (WORD *)lpszOutput;
       int i = 0;
 
-      /* We explicitly list DMBIN_AUTO first; actually while win9x does this
-	 win2000 lists DMBIN_FORMSOURCE instead. */
-      i++;
-      if(lpszOutput != NULL)
-	*wp++ = DMBIN_AUTO;
-
       for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
 	if(lpszOutput != NULL)
 	  *wp++ = slot->WinBin;
@@ -500,13 +519,6 @@
       char *cp = lpszOutput;
       int i = 0;
 
-      /* Add an entry corresponding to DMBIN_AUTO, see DC_BINS */
-      i++;
-      if(lpszOutput != NULL) {
-	strcpy(cp, "Automatically Select");
-	cp += 24;
-      }
-
       for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
 	if(lpszOutput != NULL) {
 	  lstrcpynA(cp, slot->FullName, 24);
@@ -542,8 +554,11 @@
     return -1; /* simulate that the driver supports 'RAW' */
 
   case DC_DUPLEX:
-    FIXME("DC_DUPLEX: returning %d.  Is this correct?\n", lpdm->dmDuplex);
-    return lpdm->dmDuplex;
+    ret = 0;
+    if(pi->ppd->DefaultDuplex && pi->ppd->DefaultDuplex->WinDuplex != 0)
+      ret = 1;
+    TRACE("DC_DUPLEX: returning %ld\n", ret);
+    return ret;
 
   case DC_EMF_COMPLIANT:
     FIXME("DC_EMF_COMPLIANT: stub.\n");
Index: dlls/wineps/init.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/init.c,v
retrieving revision 1.51
diff -u -r1.51 init.c
--- dlls/wineps/init.c	12 Aug 2003 20:42:18 -0000	1.51
+++ dlls/wineps/init.c	4 Nov 2003 19:16:39 -0000
@@ -59,7 +59,7 @@
 /* dmDriverExtra */	sizeof(PSDRV_DEVMODEA)-sizeof(DEVMODEA),
 /* dmFields */		DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE |
 			DM_COPIES | DM_DEFAULTSOURCE | DM_COLOR |
-			DM_DUPLEX | DM_YRESOLUTION | DM_TTOPTION,
+		        DM_YRESOLUTION | DM_TTOPTION,
    { /* u1 */
      { /* s1 */
 /* dmOrientation */	DMORIENT_PORTRAIT,
@@ -73,7 +73,7 @@
 /* dmDefaultSource */	DMBIN_AUTO,
 /* dmPrintQuality */	0,
 /* dmColor */		DMCOLOR_COLOR,
-/* dmDuplex */		0,
+/* dmDuplex */		DMDUP_SIMPLEX,
 /* dmYResolution */	0,
 /* dmTTOption */	DMTT_SUBDEV,
 /* dmCollate */		0,
@@ -680,6 +680,20 @@
     else {
 	ERR ("GetPrinterDataA returned %li\n", res);
 	goto closeprinter;
+    }
+
+    /* Duplex is indicated by the setting of the DM_DUPLEX bit in dmFields.
+       WinDuplex == 0 is a special case which means that the ppd has a
+       *DefaultDuplex: NotCapable entry.  In this case we'll try not to confuse
+       apps and set dmDuplex to DMDUP_SIMPLEX but leave the DM_DUPLEX clear.
+       PSDRV_WriteHeader understands this and copes. */
+    pi->Devmode->dmPublic.dmFields &= ~DM_DUPLEX;
+    if(pi->ppd->DefaultDuplex) {
+        pi->Devmode->dmPublic.dmDuplex = pi->ppd->DefaultDuplex->WinDuplex;
+        if(pi->Devmode->dmPublic.dmDuplex != 0)
+            pi->Devmode->dmPublic.dmFields |= DM_DUPLEX;
+        else
+            pi->Devmode->dmPublic.dmDuplex = DMDUP_SIMPLEX;
     }
 
     res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL,
Index: dlls/wineps/ppd.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/ppd.c,v
retrieving revision 1.14
diff -u -r1.14 ppd.c
--- dlls/wineps/ppd.c	5 Sep 2003 23:08:28 -0000	1.14
+++ dlls/wineps/ppd.c	4 Nov 2003 19:16:39 -0000
@@ -556,7 +556,7 @@
     FILE *fp;
     PPD *ppd;
     PPDTuple tuple;
-    char *default_pagesize = NULL;
+    char *default_pagesize = NULL, *default_duplex = NULL;
 
     TRACE("file '%s'\n", fname);
 
@@ -814,6 +814,40 @@
 	    TRACE("*TTRasterizer = %d\n", ppd->TTRasterizer);
 	}
 
+        else if(!strcmp("*Duplex", tuple.key)) {
+            DUPLEX **duplex;
+            for(duplex = &ppd->Duplexes; *duplex; duplex = &(*duplex)->next)
+                ;
+            *duplex = HeapAlloc(GetProcessHeap(), 0, sizeof(**duplex));
+            (*duplex)->Name = tuple.option;
+            (*duplex)->FullName = tuple.opttrans;
+            (*duplex)->InvocationString = tuple.value;
+            (*duplex)->next = NULL;
+            if(!strcasecmp("None", tuple.option) || !strcasecmp("False", tuple.option)
+               || !strcasecmp("Simplex", tuple.option))
+                (*duplex)->WinDuplex = DMDUP_SIMPLEX;
+            else if(!strcasecmp("DuplexNoTumble", tuple.option))
+                (*duplex)->WinDuplex = DMDUP_VERTICAL;
+            else if(!strcasecmp("DuplexTumble", tuple.option))
+                (*duplex)->WinDuplex = DMDUP_HORIZONTAL;
+            else if(!strcasecmp("Notcapable", tuple.option))
+                (*duplex)->WinDuplex = 0;
+            else {
+                FIXME("Unknown option %s for *Duplex defaulting to simplex\n", tuple.option);
+                (*duplex)->WinDuplex = DMDUP_SIMPLEX;
+            }
+            tuple.option = tuple.opttrans = tuple.value = NULL;
+        }
+
+        else if(!strcmp("*DefaultDuplex", tuple.key)) {
+            if(default_duplex) {
+                WARN("Already set default duplex\n");
+            } else {
+                default_duplex = tuple.value;
+                tuple.value = NULL;
+           }
+        }
+
 	if(tuple.key) HeapFree(PSDRV_Heap, 0, tuple.key);
 	if(tuple.option) HeapFree(PSDRV_Heap, 0, tuple.option);
 	if(tuple.value) HeapFree(PSDRV_Heap, 0, tuple.value);
@@ -839,6 +873,24 @@
         ppd->DefaultPageSize = ppd->PageSizes;
         TRACE("Setting DefaultPageSize to first in list\n");
     }
+
+    ppd->DefaultDuplex = NULL;
+    if(default_duplex) {
+	DUPLEX *duplex;
+	for(duplex = ppd->Duplexes; duplex; duplex = duplex->next) {
+            if(!strcmp(duplex->Name, default_duplex)) {
+                ppd->DefaultDuplex = duplex;
+                TRACE("DefaultDuplex: %s\n", duplex->Name);
+                break;
+            }
+        }
+        HeapFree(PSDRV_Heap, 0, default_duplex);
+    }
+    if(!ppd->DefaultDuplex) {
+        ppd->DefaultDuplex = ppd->Duplexes;
+        TRACE("Setting DefaultDuplex to first in list\n");
+    }
+
 
     {
         FONTNAME *fn;
Index: dlls/wineps/ps.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/ps.c,v
retrieving revision 1.18
diff -u -r1.18 ps.c
--- dlls/wineps/ps.c	23 Jun 2003 19:57:08 -0000	1.18
+++ dlls/wineps/ps.c	4 Nov 2003 19:16:39 -0000
@@ -234,6 +234,8 @@
     char *buf;
     INPUTSLOT *slot;
     PAGESIZE *page;
+    DUPLEX *duplex;
+    int win_duplex;
     int llx, lly, urx, ury;
 
     TRACE("'%s'\n", debugstr_a(title));
@@ -284,6 +286,18 @@
 	    if(page->InvocationString) {
 	        PSDRV_WriteFeature(physDev->job.hJob, "*PageSize", page->Name,
 			     page->InvocationString);
+		break;
+	    }
+	}
+    }
+
+    win_duplex = physDev->Devmode->dmPublic.dmFields & DM_DUPLEX ?
+        physDev->Devmode->dmPublic.dmDuplex : 0;
+    for(duplex = physDev->pi->ppd->Duplexes; duplex; duplex = duplex->next) {
+        if(duplex->WinDuplex == win_duplex) {
+	    if(duplex->InvocationString) {
+	        PSDRV_WriteFeature(physDev->job.hJob, "*Duplex", duplex->Name,
+			     duplex->InvocationString);
 		break;
 	    }
 	}
Index: dlls/wineps/psdlg.h
===================================================================
RCS file: /home/wine/wine/dlls/wineps/psdlg.h,v
retrieving revision 1.2
diff -u -r1.2 psdlg.h
--- dlls/wineps/psdlg.h	9 Mar 2002 23:44:32 -0000	1.2
+++ dlls/wineps/psdlg.h	4 Nov 2003 19:16:39 -0000
@@ -24,5 +24,6 @@
 #define IDD_PAPERS 100
 #define IDD_ORIENT_PORTRAIT  101
 #define IDD_ORIENT_LANDSCAPE 102
-
+#define IDD_DUPLEX 110
+#define IDD_DUPLEX_NAME 111
 #endif /* __WINE_PSDLG_H */
Index: dlls/wineps/psdrv.h
===================================================================
RCS file: /home/wine/wine/dlls/wineps/psdrv.h,v
retrieving revision 1.41
diff -u -r1.41 psdrv.h
--- dlls/wineps/psdrv.h	5 Sep 2003 23:08:28 -0000	1.41
+++ dlls/wineps/psdrv.h	4 Nov 2003 19:16:39 -0000
@@ -175,6 +175,14 @@
 typedef enum _RASTERIZEROPTION
   {RO_None, RO_Accept68K, RO_Type42, RO_TrueImage} RASTERIZEROPTION;
 
+typedef struct _tagDUPLEX {
+    char                        *Name;
+    char                        *FullName;
+    char                        *InvocationString;
+    WORD                        WinDuplex; /* eg DMDUP_SIMPLEX */
+    struct _tagDUPLEX           *next;
+} DUPLEX;
+
 typedef struct {
     char		*NickName;
     int			LanguageLevel;
@@ -192,6 +200,8 @@
     CONSTRAINT		*Constraints;
     INPUTSLOT		*InputSlots;
     RASTERIZEROPTION    TTRasterizer;
+    DUPLEX              *Duplexes;
+    DUPLEX              *DefaultDuplex;
 } PPD;
 
 typedef struct {
Index: dlls/wineps/wps_De.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_De.rc,v
retrieving revision 1.4
diff -u -r1.4 wps_De.rc
--- dlls/wineps/wps_De.rc	1 Jun 2002 02:55:51 -0000	1.4
+++ dlls/wineps/wps_De.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "&Querformat", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_En.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_En.rc,v
retrieving revision 1.4
diff -u -r1.4 wps_En.rc
--- dlls/wineps/wps_En.rc	1 Jun 2002 02:55:51 -0000	1.4
+++ dlls/wineps/wps_En.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "&Landscape", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Fr.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Fr.rc,v
retrieving revision 1.2
diff -u -r1.2 wps_Fr.rc
--- dlls/wineps/wps_Fr.rc	22 Sep 2003 21:16:56 -0000	1.2
+++ dlls/wineps/wps_Fr.rc	4 Nov 2003 19:16:39 -0000
@@ -34,4 +34,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "P&aysage", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Recto-verso:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Ko.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Ko.rc,v
retrieving revision 1.1
diff -u -r1.1 wps_Ko.rc
--- dlls/wineps/wps_Ko.rc	10 Jun 2002 02:32:31 -0000	1.1
+++ dlls/wineps/wps_Ko.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "&Landscape", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Pt.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Pt.rc,v
retrieving revision 1.1
diff -u -r1.1 wps_Pt.rc
--- dlls/wineps/wps_Pt.rc	30 Jun 2003 20:22:35 -0000	1.1
+++ dlls/wineps/wps_Pt.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "&Paisagem", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Ru.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Ru.rc,v
retrieving revision 1.3
diff -u -r1.3 wps_Ru.rc
--- dlls/wineps/wps_Ru.rc	1 Jun 2002 02:55:51 -0000	1.3
+++ dlls/wineps/wps_Ru.rc	4 Nov 2003 19:16:39 -0000
@@ -25,12 +25,15 @@
 CAPTION "������"
 FONT 8, "Helv"
 {
- LTEXT "&������ ������:", -1, 10, 6, 100, 8
+ LTEXT "&������ ��??��:", -1, 10, 6, 200, 8
  LISTBOX IDD_PAPERS, 10, 15, 200, 45, LBS_STANDARD | LBS_HASSTRINGS |
 	 WS_TABSTOP
  GROUPBOX "����������", -1, 10, 80, 200, 50
  CONTROL "&�������", IDD_ORIENT_PORTRAIT, "Button", BS_AUTORADIOBUTTON |
-	WS_TABSTOP, 20, 90, 60, 10
+	WS_TABSTOP, 20, 90, 180, 10
  CONTROL "&���������", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
-	 20, 110, 60, 10
+	 20, 110, 180, 10
+ LTEXT "2-� ��������� ���??�:", IDD_DUPLEX_NAME, 10, 140, 200, 8
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Si.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Si.rc,v
retrieving revision 1.1
diff -u -r1.1 wps_Si.rc
--- dlls/wineps/wps_Si.rc	16 Jun 2003 01:32:09 -0000	1.1
+++ dlls/wineps/wps_Si.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "L&e�e�a", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }
Index: dlls/wineps/wps_Sk.rc
===================================================================
RCS file: /home/wine/wine/dlls/wineps/wps_Sk.rc,v
retrieving revision 1.4
diff -u -r1.4 wps_Sk.rc
--- dlls/wineps/wps_Sk.rc	1 Jun 2002 02:55:51 -0000	1.4
+++ dlls/wineps/wps_Sk.rc	4 Nov 2003 19:16:39 -0000
@@ -31,4 +31,7 @@
 	WS_TABSTOP, 20, 90, 60, 10
  CONTROL "&Na ��rku", IDD_ORIENT_LANDSCAPE, "Button", BS_AUTORADIOBUTTON,
 	 20, 110, 60, 10
+ LTEXT "Duplex:", IDD_DUPLEX_NAME, 10, 140, 100, 8 
+ COMBOBOX IDD_DUPLEX, 10, 151, 200, 20, CBS_DROPDOWNLIST | CBS_HASSTRINGS |
+        WS_TABSTOP
 }



More information about the wine-patches mailing list