Support for duplex printing.
This commit is contained in:
parent
4b0fc2e341
commit
83d6e26b31
|
@ -136,7 +136,7 @@ void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
|
|||
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 @@ INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||
PSDRV_DLGINFO *di;
|
||||
int i, Cursel = 0;
|
||||
PAGESIZE *ps;
|
||||
|
||||
DUPLEX *duplex;
|
||||
|
||||
switch(msg) {
|
||||
case WM_INITDIALOG:
|
||||
|
@ -215,11 +215,25 @@ INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||
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 @@ INT_PTR CALLBACK PSDRV_PaperDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||
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 @@ DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszP
|
|||
{
|
||||
PRINTERINFO *pi;
|
||||
DEVMODEA *lpdm;
|
||||
DWORD ret;
|
||||
pi = PSDRV_FindPrinterInfo(lpszDevice);
|
||||
|
||||
TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
|
||||
|
@ -482,12 +507,6 @@ DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszP
|
|||
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 @@ DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszP
|
|||
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 @@ DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszP
|
|||
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");
|
||||
|
|
|
@ -59,7 +59,7 @@ static PSDRV_DEVMODEA DefaultDevmode =
|
|||
/* 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 @@ static PSDRV_DEVMODEA DefaultDevmode =
|
|||
/* dmDefaultSource */ DMBIN_AUTO,
|
||||
/* dmPrintQuality */ 0,
|
||||
/* dmColor */ DMCOLOR_COLOR,
|
||||
/* dmDuplex */ 0,
|
||||
/* dmDuplex */ DMDUP_SIMPLEX,
|
||||
/* dmYResolution */ 0,
|
||||
/* dmTTOption */ DMTT_SUBDEV,
|
||||
/* dmCollate */ 0,
|
||||
|
@ -682,6 +682,20 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
|
|||
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,
|
||||
0, &needed, &pi->FontSubTableSize);
|
||||
if (res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND) {
|
||||
|
|
|
@ -556,7 +556,7 @@ PPD *PSDRV_ParsePPD(char *fname)
|
|||
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 @@ PPD *PSDRV_ParsePPD(char *fname)
|
|||
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);
|
||||
|
@ -840,6 +874,24 @@ PPD *PSDRV_ParsePPD(char *fname)
|
|||
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;
|
||||
PAGESIZE *page;
|
||||
|
|
|
@ -234,6 +234,8 @@ INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title )
|
|||
char *buf;
|
||||
INPUTSLOT *slot;
|
||||
PAGESIZE *page;
|
||||
DUPLEX *duplex;
|
||||
int win_duplex;
|
||||
int llx, lly, urx, ury;
|
||||
|
||||
TRACE("'%s'\n", debugstr_a(title));
|
||||
|
@ -289,6 +291,18 @@ INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title )
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WriteSpool16( physDev->job.hJob, psendsetup, strlen(psendsetup) );
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -175,6 +175,14 @@ typedef struct _tagINPUTSLOT {
|
|||
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 @@ typedef struct {
|
|||
CONSTRAINT *Constraints;
|
||||
INPUTSLOT *InputSlots;
|
||||
RASTERIZEROPTION TTRasterizer;
|
||||
DUPLEX *Duplexes;
|
||||
DUPLEX *DefaultDuplex;
|
||||
} PPD;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 8, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 8, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -34,4 +34,7 @@ FONT 8, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 9, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 8, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -25,12 +25,15 @@ STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
|||
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
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 8, "MS Sans Serif"
|
|||
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
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ FONT 8, "Helv"
|
|||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue