|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
ps.c
Abstract:
This file handles Postscript specific UI options
Environment:
Win32 subsystem, DriverUI module, user mode
Revision History:
02/25/97 -davidx- Finish PS-specific items.
02/04/97 -davidx- Reorganize driver UI to separate ps and uni DLLs.
12/17/96 -amandan- Created it.
--*/
#include "precomp.h"
#include <ntverp.h>
BOOL BSearchConstraintList(PUIINFO, DWORD, DWORD, DWORD);
static CONST WORD ScaleItemInfo[] = { IDS_CPSUI_SCALING, TVITEM_LEVEL1, DMPUB_SCALE, SCALE_ITEM, HELP_INDEX_SCALE, 2, TVOT_UDARROW, IDS_CPSUI_PERCENT, IDI_CPSUI_SCALING, 0, MIN_SCALE, ITEM_INFO_SIGNATURE };
BOOL _BPackItemScale( PUIDATA pUiData )
/*++
Routine Description:
Pack scaling option.
Arguments:
pUiData - Points to UIDATA structure
Return Value:
TRUE if successful, FALSE if there is an error.
--*/
{ return BPackUDArrowItemTemplate( pUiData, ScaleItemInfo, pUiData->ci.pdm->dmScale, pUiData->ci.pUIInfo->dwMaxScale, NULL); }
DWORD _DwEnumPersonalities( PCOMMONINFO pci, PWSTR pwstrOutput )
/*++
Routine Description:
Enumerate the list of supported printer description languages
Arguments:
pci - Points to common printer info pwstrOutput - Points to output buffer
Return Value:
Number of personalities supported GDI_ERROR if there is an error
--*/
{ if (pwstrOutput) CopyString(pwstrOutput, TEXT("PostScript"), CCHLANGNAME);
return 1; }
DWORD _DwGetOrientationAngle( PUIINFO pUIInfo, PDEVMODE pdm ) /*++
Routine Description:
Get the orienation angle requested by DrvDeviceCapabilities(DC_ORIENTATION)
Arguments:
pUIInfo - Pointer to UIINFO pdm - Pointer to DEVMODE
Return Value:
The angle (90 or 270 or landscape rotation)
--*/
{ DWORD dwRet; PPSDRVEXTRA pdmPrivate;
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
//
// Normal landscape rotates counterclockwise
// Rotated landscape rotates clockwise
//
if (pUIInfo->dwFlags & FLAG_ROTATE90) dwRet = (pdmPrivate->dwFlags & PSDEVMODE_LSROTATE) ? 270 : 90; else dwRet = (pdmPrivate->dwFlags & PSDEVMODE_LSROTATE) ? 90 : 270;
return dwRet; }
static CONST WORD PSOrientItemInfo[] = { IDS_CPSUI_ORIENTATION, TVITEM_LEVEL1, DMPUB_ORIENTATION, ORIENTATION_ITEM, HELP_INDEX_ORIENTATION, 3, TVOT_3STATES, IDS_CPSUI_PORTRAIT, IDI_CPSUI_PORTRAIT, IDS_CPSUI_LANDSCAPE, IDI_CPSUI_LANDSCAPE, IDS_CPSUI_ROT_LAND, IDI_CPSUI_ROT_LAND, ITEM_INFO_SIGNATURE };
BOOL _BPackOrientationItem( IN OUT PUIDATA pUiData ) /*++
Routine Description:
Synthesize the orientation feature for Doc property sheet
Arguments:
pUiData - Points to UIDATA structure
Return Value:
TRUE for success and FALSE for failure
Note:
Always synthesize orienation for PostScript
--*/
{ PFEATURE pFeature; DWORD dwSelection;
//
// If there is no predefined orientation feature, we displays it ourselves.
//
if ((pUiData->ci.pdm->dmFields & DM_ORIENTATION) && (pUiData->ci.pdm->dmOrientation == DMORIENT_LANDSCAPE)) { PPSDRVEXTRA pdmPrivate;
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pUiData->ci.pdm); dwSelection = pdmPrivate->dwFlags & PSDEVMODE_LSROTATE ? 2 : 1; } else dwSelection = 0;
//
// Synthesize the feature ourselves
//
return BPackOptItemTemplate(pUiData, PSOrientItemInfo, dwSelection, NULL); }
static CONST WORD PSOutputOptionItemInfo[] = { IDS_PSOUTPUT_OPTION, TVITEM_LEVEL2, DMPUB_NONE, PSOUTPUT_OPTION_ITEM, HELP_INDEX_PSOUTPUT_OPTION, 4, TVOT_LISTBOX, IDS_PSOPT_SPEED, IDI_PSOPT_SPEED, IDS_PSOPT_PORTABILITY, IDI_PSOPT_PORTABILITY, IDS_PSOPT_EPS, IDI_PSOPT_EPS, IDS_PSOPT_ARCHIVE, IDI_PSOPT_ARCHIVE, ITEM_INFO_SIGNATURE };
BOOL BPackItemPSOutputOption( PUIDATA pUiData, PPSDRVEXTRA pdmPrivate )
/*++
Routine Description:
Pack PostScript output option item
Arguments:
pUiData - Points to UIDATA structure pdmPrivate - Points to pscript private devmode
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwSel;
switch (pdmPrivate->iDialect) { case PORTABILITY: dwSel = 1; break;
case EPS: dwSel = 2; break;
case ARCHIVE: dwSel = 3; break;
case SPEED: default: dwSel = 0; break; }
return BPackOptItemTemplate(pUiData, PSOutputOptionItemInfo, dwSel, NULL); }
static CONST WORD PSTTDLFormatItemInfo[] = { IDS_PSTT_DLFORMAT, TVITEM_LEVEL2, DMPUB_NONE, PSTT_DLFORMAT_ITEM, HELP_INDEX_PSTT_DLFORMAT, 4, TVOT_LISTBOX, IDS_TTDL_DEFAULT, IDI_PSTT_DLFORMAT, IDS_TTDL_TYPE1, IDI_PSTT_DLFORMAT, IDS_TTDL_TYPE3, IDI_PSTT_DLFORMAT, IDS_TTDL_TYPE42, IDI_PSTT_DLFORMAT, ITEM_INFO_SIGNATURE };
BOOL BPackItemTTDownloadFormat( PUIDATA pUiData, PPSDRVEXTRA pdmPrivate )
/*++
Routine Description:
Pack PostScript TrueType download option item
Arguments:
pUiData - Points to UIDATA structure pdmPrivate - Points to pscript private devmode
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwSel; BOOL bSupportType42; POPTTYPE pOptType = pUiData->pOptType;
bSupportType42 = (pUiData->ci.pUIInfo->dwTTRasterizer == TTRAS_TYPE42);
switch (pdmPrivate->iTTDLFmt) { case TYPE_1: dwSel = 1; break;
case TYPE_3: dwSel = 2; break;
case TYPE_42:
dwSel = bSupportType42 ? 3 : 0; break;
case TT_DEFAULT: default: dwSel = 0; break; }
if (! BPackOptItemTemplate(pUiData, PSTTDLFormatItemInfo, dwSel, NULL)) return FALSE;
//
// if printer doesn't support Type42, hide Type42 option
//
if (pOptType && !bSupportType42) pOptType->pOptParam[3].Flags |= OPTPF_HIDE;
return TRUE; }
static CONST WORD PSLevelItemInfo[] = { IDS_PSLEVEL, TVITEM_LEVEL2, DMPUB_NONE, PSLEVEL_ITEM, HELP_INDEX_SCALE, 2, TVOT_UDARROW, 0, IDI_PSLEVEL, 0,
//
// Adobe doesn't want to support level 1
//
#ifdef ADOBE
2, #else
1, #endif
ITEM_INFO_SIGNATURE };
BOOL BPackItemPSLevel( PUIDATA pUiData, PPSDRVEXTRA pdmPrivate )
/*++
Routine Description:
Pack PostScript output option item
Arguments:
pUiData - Points to UIDATA structure pdmPrivate - Points to pscript private devmode
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwSel = pdmPrivate->iPSLevel; DWORD dwLangLevel = pUiData->ci.pUIInfo->dwLangLevel;
//
// we don't expect language level to be higher than 4
//
if (dwLangLevel <= 1) return TRUE;
if (dwLangLevel > 4) dwLangLevel = 4;
//
// make sure the current selection is sensible
//
if (dwSel == 0 || dwSel > dwLangLevel) dwSel = dwLangLevel;
return BPackUDArrowItemTemplate(pUiData, PSLevelItemInfo, dwSel, dwLangLevel, NULL); }
static CONST WORD EHandlerItemInfo[] = { IDS_PSERROR_HANDLER, TVITEM_LEVEL2, DMPUB_NONE, PSERROR_HANDLER_ITEM, HELP_INDEX_PSERROR_HANDLER, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD MirrorItemInfo[] = { IDS_MIRROR, TVITEM_LEVEL2, DMPUB_NONE, MIRROR_ITEM, HELP_INDEX_MIRROR, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD NegativeItemInfo[] = { IDS_NEGATIVE_PRINT, TVITEM_LEVEL2, DMPUB_NONE, NEGATIVE_ITEM, HELP_INDEX_NEGATIVE, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD CompressBmpItemInfo[] = { IDS_COMPRESSBMP, TVITEM_LEVEL2, DMPUB_NONE, COMPRESSBMP_ITEM, HELP_INDEX_COMPRESSBMP, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
BOOL _BPackDocumentOptions( IN OUT PUIDATA pUiData )
/*++
Routine Description:
Pack PostScript specific options such as Job Control etc.
Arguments:
pUiData - Points to UIDATA structure
Return Value:
TRUE for success and FALSE for failure
--*/
{ POPTITEM pOptItem; PPSDRVEXTRA pdmPrivate; DWORD dwFlags;
pdmPrivate = pUiData->ci.pdmPrivate; dwFlags = pdmPrivate->dwFlags; pOptItem = pUiData->pOptItem;
VPackOptItemGroupHeader(pUiData, IDS_PSOPTIONS, IDI_CPSUI_POSTSCRIPT, HELP_INDEX_PSOPTIONS);
if (pOptItem) pOptItem->Flags |= OPTIF_COLLAPSE;
return BPackItemPSOutputOption(pUiData, pdmPrivate) && BPackItemTTDownloadFormat(pUiData, pdmPrivate) && BPackItemPSLevel(pUiData, pdmPrivate) && BPackOptItemTemplate( pUiData, EHandlerItemInfo, (dwFlags & PSDEVMODE_EHANDLER) ? 0 : 1, NULL) && (pUiData->ci.pUIInfo->dwLangLevel > 1 || BPackOptItemTemplate( pUiData, CompressBmpItemInfo, (dwFlags & PSDEVMODE_COMPRESSBMP) ? 0 : 1, NULL)) && BPackOptItemTemplate( pUiData, MirrorItemInfo, (dwFlags & PSDEVMODE_MIRROR) ? 0 : 1, NULL) && (IS_COLOR_DEVICE(pUiData->ci.pUIInfo) || BPackOptItemTemplate( pUiData, NegativeItemInfo, (dwFlags & PSDEVMODE_NEG) ? 0 : 1, NULL)); }
VOID _VUnpackDocumentOptions( POPTITEM pOptItem, PDEVMODE pdm )
/*++
Routine Description:
Extract Postscript devmode information from an OPTITEM Stored it back into Postscript devmode.
Arguments:
pOptItem - Pointer to an OPTITEM pdm - Pointer to Postscript DEVMODE structure
Return Value:
None
--*/
{ PPSDRVEXTRA pdmPrivate;
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
switch (GETUSERDATAITEM(pOptItem->UserData)) { case ORIENTATION_ITEM:
pdm->dmFields |= DM_ORIENTATION; pdm->dmOrientation = (pOptItem->Sel == 0) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
if (pOptItem->Sel != 2) pdmPrivate->dwFlags &= ~PSDEVMODE_LSROTATE; else pdmPrivate->dwFlags |= PSDEVMODE_LSROTATE;
break;
case PSOUTPUT_OPTION_ITEM:
switch (pOptItem->Sel) { case 1: pdmPrivate->iDialect = PORTABILITY; break;
case 2: pdmPrivate->iDialect = EPS; break;
case 3: pdmPrivate->iDialect = ARCHIVE; break;
case 0: default: pdmPrivate->iDialect = SPEED; break; } break;
case PSTT_DLFORMAT_ITEM:
switch (pOptItem->Sel) { case 1: pdmPrivate->iTTDLFmt = TYPE_1; break;
case 2: pdmPrivate->iTTDLFmt = TYPE_3; break;
case 3: pdmPrivate->iTTDLFmt = TYPE_42; break;
case 0: default: pdmPrivate->iTTDLFmt = TT_DEFAULT; break; } break;
case PSLEVEL_ITEM:
pdmPrivate->iPSLevel = pOptItem->Sel; break;
case PSERROR_HANDLER_ITEM:
if (pOptItem->Sel == 0) pdmPrivate->dwFlags |= PSDEVMODE_EHANDLER; else pdmPrivate->dwFlags &= ~PSDEVMODE_EHANDLER; break;
case PSHALFTONE_FREQ_ITEM: case PSHALFTONE_ANGLE_ITEM:
// DCR - not implemented yet
break;
case MIRROR_ITEM:
if (pOptItem->Sel == 0) pdmPrivate->dwFlags |= PSDEVMODE_MIRROR; else pdmPrivate->dwFlags &= ~PSDEVMODE_MIRROR; break;
case NEGATIVE_ITEM:
if (pOptItem->Sel == 0) pdmPrivate->dwFlags |= PSDEVMODE_NEG; else pdmPrivate->dwFlags &= ~PSDEVMODE_NEG; break;
case COMPRESSBMP_ITEM:
if (pOptItem->Sel == 0) pdmPrivate->dwFlags |= PSDEVMODE_COMPRESSBMP; else pdmPrivate->dwFlags &= ~PSDEVMODE_COMPRESSBMP; break; } }
static CONST WORD IgnoreDevFontItemInfo[] = { IDS_USE_DEVFONTS, TVITEM_LEVEL1, DMPUB_NONE, IGNORE_DEVFONT_ITEM, HELP_INDEX_IGNORE_DEVFONT, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
BOOL _BPackFontSubstItems( IN OUT PUIDATA pUiData )
/*++
Routine Description:
Pack font substitution related items (printer-sticky)
Arguments:
pUiData - Points to UIDATA structure
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ BOOL bNoDeviceFont;
bNoDeviceFont = (pUiData->ci.pPrinterData->dwFlags & PFLAGS_IGNORE_DEVFONT);
//
// On non-1252 code page systems, gives user the option
// to disable all device fonts
//
// Note: On non-1252 CodePage systems (Cs-Ct-Ja-Ko & Cyr-Grk-Tur, etc),
// PScript NT4 had difficulty mapping printer font Encodings to GDI strings.
// AdobePS5/PScript5 is supposed to handle these correctly. So Adobe wants
// this choice to be suppressed on all code pages.
//
// Fix MS bug #121883, Adobe bug #235417
//
if (FALSE && GetACP() != 1252 && !BPackOptItemTemplate(pUiData, IgnoreDevFontItemInfo, bNoDeviceFont ? 1 : 0, NULL)) { return FALSE; }
//
// Don't display the font substitution table if device font is disabled
//
if (bNoDeviceFont) return TRUE;
return BPackItemFontSubstTable(pUiData); }
static CONST WORD ProtocolItemInfo[] = { IDS_PSPROTOCOL, TVITEM_LEVEL1, DMPUB_NONE, PSPROTOCOL_ITEM, HELP_INDEX_PSPROTOCOL, 4, TVOT_LISTBOX, IDS_PSPROTOCOL_ASCII, IDI_PSPROTOCOL, IDS_PSPROTOCOL_BCP, IDI_PSPROTOCOL, IDS_PSPROTOCOL_TBCP, IDI_PSPROTOCOL, IDS_PSPROTOCOL_BINARY, IDI_PSPROTOCOL, ITEM_INFO_SIGNATURE };
BOOL BPackPSProtocolItem( IN OUT PUIDATA pUiData )
/*++
Routine Description:
Pack PostScript communication protocol item
Arguments:
pUiData - Points to UIDATA structure
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwSel; POPTITEM pOptItem; POPTPARAM pOptParam; PUIINFO pUIInfo;
pOptItem = pUiData->pOptItem;
if (! BPackOptItemTemplate(pUiData, ProtocolItemInfo, 0, NULL)) return FALSE;
if (pOptItem) { //
// Hide those selections which are not supported on the printer
//
pOptParam = pOptItem->pOptType->pOptParam; pUIInfo = pUiData->ci.pUIInfo;
if (! (pUIInfo->dwProtocols & PROTOCOL_BCP)) pOptParam[1].Flags |= OPTPF_HIDE;
if (! (pUIInfo->dwProtocols & PROTOCOL_TBCP)) pOptParam[2].Flags |= OPTPF_HIDE;
if (! (pUIInfo->dwProtocols & PROTOCOL_BINARY)) pOptParam[3].Flags |= OPTPF_HIDE;
switch (pUiData->ci.pPrinterData->wProtocol) { case PROTOCOL_BCP: dwSel = 1; break;
case PROTOCOL_TBCP: dwSel = 2; break;
case PROTOCOL_BINARY: dwSel = 3; break;
default: dwSel = 0; break; }
if (pOptParam[dwSel].Flags & OPTPF_HIDE) pOptItem->Sel = 0; else pOptItem->Sel = dwSel; }
return TRUE; }
//
// We will use different lower limit for Printer VM
// based on printer level. The 10th element of this
// ItemInfo must be filled with correct lower limit
// number before begin used.
//
static WORD PrinterVMItemInfo[] = { IDS_POSTSCRIPT_VM, TVITEM_LEVEL1, DMPUB_NONE, PRINTER_VM_ITEM, HELP_INDEX_PRINTER_VM, 2, TVOT_UDARROW, IDS_KBYTES, IDI_CPSUI_MEM, 0, 0, ITEM_INFO_SIGNATURE };
static CONST WORD JobTimeoutItemInfo[] = { IDS_JOBTIMEOUT, TVITEM_LEVEL1, DMPUB_NONE, JOB_TIMEOUT_ITEM, HELP_INDEX_JOB_TIMEOUT, 2, TVOT_UDARROW, IDS_SECONDS, IDI_USE_DEFAULT, 0, 0, ITEM_INFO_SIGNATURE };
static CONST WORD WaitTimeoutItemInfo[] = { IDS_WAITTIMEOUT, TVITEM_LEVEL1, DMPUB_NONE, WAIT_TIMEOUT_ITEM, HELP_INDEX_WAIT_TIMEOUT, 2, TVOT_UDARROW, IDS_SECONDS, IDI_USE_DEFAULT, 0, 0, ITEM_INFO_SIGNATURE };
static CONST WORD CtrlDBeforeItemInfo[] = { IDS_CTRLD_BEFORE, TVITEM_LEVEL1, DMPUB_NONE, CTRLD_BEFORE_ITEM, HELP_INDEX_CTRLD_BEFORE, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD CtrlDAfterItemInfo[] = { IDS_CTRLD_AFTER, TVITEM_LEVEL1, DMPUB_NONE, CTRLD_AFTER_ITEM, HELP_INDEX_CTRLD_AFTER, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD TrueGrayTextItemInfo[] = { IDS_TRUE_GRAY_TEXT, TVITEM_LEVEL1, DMPUB_NONE, TRUE_GRAY_TEXT_ITEM, HELP_INDEX_TRUE_GRAY_TEXT, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD TrueGrayGraphItemInfo[] = { IDS_TRUE_GRAY_GRAPH, TVITEM_LEVEL1, DMPUB_NONE, TRUE_GRAY_GRAPH_ITEM, HELP_INDEX_TRUE_GRAY_GRAPH, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD AddEuroItemInfo[] = { IDS_ADD_EURO, TVITEM_LEVEL1, DMPUB_NONE, ADD_EURO_ITEM, HELP_INDEX_ADD_EURO, 2, TVOT_2STATES, IDS_CPSUI_YES, IDI_CPSUI_YES, IDS_CPSUI_NO, IDI_CPSUI_NO, ITEM_INFO_SIGNATURE };
static CONST WORD MinOutlineItemInfo[] = { IDS_PSMINOUTLINE, TVITEM_LEVEL1, DMPUB_NONE, PSMINOUTLINE_ITEM, HELP_INDEX_PSMINOUTLINE, 2, TVOT_UDARROW, IDS_PIXELS, IDI_USE_DEFAULT, 0, 0, ITEM_INFO_SIGNATURE };
static CONST WORD MaxBitmapItemInfo[] = { IDS_PSMAXBITMAP, TVITEM_LEVEL1, DMPUB_NONE, PSMAXBITMAP_ITEM, HELP_INDEX_PSMAXBITMAP, 2, TVOT_UDARROW, IDS_PIXELS, IDI_USE_DEFAULT, 0, 0, ITEM_INFO_SIGNATURE };
BOOL _BPackPrinterOptions( IN OUT PUIDATA pUiData )
/*++
Routine Description:
Pack driver-specific options (printer-sticky)
Arguments:
pUiData - Points to a UIDATA structure
Return Value:
TRUE for success and FALSE for failure
--*/
{ PPRINTERDATA pPrinterData = pUiData->ci.pPrinterData; BOOL rc;
//
// Fill in the lower limit number of PrinterVMItemInfo
// based on printer level.
//
PrinterVMItemInfo[10] = (pUiData->ci.pUIInfo->dwLangLevel <= 1 ? MIN_FREEMEM_L1 : MIN_FREEMEM_L2) / KBYTES;
rc = BPackUDArrowItemTemplate( pUiData, PrinterVMItemInfo, pPrinterData->dwFreeMem / KBYTES, 0x7fff, NULL) && BPackPSProtocolItem(pUiData) && BPackOptItemTemplate( pUiData, CtrlDBeforeItemInfo, (pPrinterData->dwFlags & PFLAGS_CTRLD_BEFORE) ? 0 : 1, NULL) && BPackOptItemTemplate( pUiData, CtrlDAfterItemInfo, (pPrinterData->dwFlags & PFLAGS_CTRLD_AFTER) ? 0 : 1, NULL) && BPackOptItemTemplate( pUiData, TrueGrayTextItemInfo, (pPrinterData->dwFlags & PFLAGS_TRUE_GRAY_TEXT) ? 0 : 1, NULL) && BPackOptItemTemplate( pUiData, TrueGrayGraphItemInfo, (pPrinterData->dwFlags & PFLAGS_TRUE_GRAY_GRAPH) ? 0 : 1, NULL); if (!rc) return FALSE;
if (pUiData->ci.pUIInfo->dwLangLevel > 1) { rc = BPackOptItemTemplate( pUiData, AddEuroItemInfo, (pPrinterData->dwFlags & PFLAGS_ADD_EURO) ? 0 : 1, NULL); if (!rc) return FALSE; }
return BPackUDArrowItemTemplate( pUiData, JobTimeoutItemInfo, pPrinterData->dwJobTimeout, 0x7fff, NULL) && BPackUDArrowItemTemplate( pUiData, WaitTimeoutItemInfo, pPrinterData->dwWaitTimeout, 0x7fff, NULL) && BPackUDArrowItemTemplate( pUiData, MinOutlineItemInfo, pPrinterData->wMinoutlinePPEM, 0x7fff, NULL) && BPackUDArrowItemTemplate( pUiData, MaxBitmapItemInfo, pPrinterData->wMaxbitmapPPEM, 0x7fff, NULL); }
VOID _VUnpackDriverPrnPropItem( PUIDATA pUiData, POPTITEM pOptItem )
/*++
Routine Description:
Unpack driver-specific printer property items
Arguments:
pUiData - Points to our UIDATA structure pOptItem - Specifies the OPTITEM to be unpacked
Return Value:
NONE
--*/
{ PPRINTERDATA pPrinterData = pUiData->ci.pPrinterData;
switch (GETUSERDATAITEM(pOptItem->UserData)) { case PRINTER_VM_ITEM:
if (pUiData->ci.dwFlags & FLAG_USER_CHANGED_FREEMEM) { pPrinterData->dwFreeMem = pOptItem->Sel * KBYTES; } break;
case PSPROTOCOL_ITEM:
switch (pOptItem->Sel) { case 1: pPrinterData->wProtocol = PROTOCOL_BCP; break;
case 2: pPrinterData->wProtocol = PROTOCOL_TBCP; break;
case 3: pPrinterData->wProtocol = PROTOCOL_BINARY; break;
default: pPrinterData->wProtocol = PROTOCOL_ASCII; break; } break;
case CTRLD_BEFORE_ITEM:
if (pOptItem->Sel == 0) pPrinterData->dwFlags |= PFLAGS_CTRLD_BEFORE; else pPrinterData->dwFlags &= ~PFLAGS_CTRLD_BEFORE; break;
case CTRLD_AFTER_ITEM:
if (pOptItem->Sel == 0) pPrinterData->dwFlags |= PFLAGS_CTRLD_AFTER; else pPrinterData->dwFlags &= ~PFLAGS_CTRLD_AFTER; break;
case TRUE_GRAY_TEXT_ITEM:
if (pOptItem->Sel == 0) pPrinterData->dwFlags |= PFLAGS_TRUE_GRAY_TEXT; else pPrinterData->dwFlags &= ~PFLAGS_TRUE_GRAY_TEXT; break; case TRUE_GRAY_GRAPH_ITEM:
if (pOptItem->Sel == 0) pPrinterData->dwFlags |= PFLAGS_TRUE_GRAY_GRAPH; else pPrinterData->dwFlags &= ~PFLAGS_TRUE_GRAY_GRAPH; break;
case ADD_EURO_ITEM:
if (pOptItem->Sel == 0) pPrinterData->dwFlags |= PFLAGS_ADD_EURO; else pPrinterData->dwFlags &= ~PFLAGS_ADD_EURO;
pPrinterData->dwFlags |= PFLAGS_EURO_SET; break;
case PSMINOUTLINE_ITEM:
pPrinterData->wMinoutlinePPEM = (WORD) pOptItem->Sel; break;
case PSMAXBITMAP_ITEM:
pPrinterData->wMaxbitmapPPEM = (WORD) pOptItem->Sel; break; } }
BOOL BUpdateModelNtfFilename( PCOMMONINFO pci )
/*++
Routine Description:
Save model-specific NTF filename under PrinterDriverData registry key for compatibility with the new NT4 driver.
Arguments:
pci - Points to basic printer information
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ //
// Get the list of driver dependent files and
// save it in registry for NT4 compatibility
//
PTSTR ptstr, ptstrNext, ptstrDependentFiles, ptstrCopy, ptstrFileNamesWithoutPath; DWORD dwCharCount = 0; BOOL bResult;
if ((ptstrDependentFiles = pci->pDriverInfo3->pDependentFiles) == NULL) { return BSetPrinterDataString(pci->hPrinter, REGVAL_DEPFILES, ptstrDependentFiles, REG_MULTI_SZ); }
//
// First pass of the MULTI_SZ string to get file names char count
//
while (*ptstrDependentFiles != NUL) { //
// Go the end of current string
//
ptstr = ptstrDependentFiles + _tcslen(ptstrDependentFiles); ptstrNext = ptstr + 1;
dwCharCount++; // for the NUL char of current string
//
// Search backward for '\' path separator
//
while (--ptstr >= ptstrDependentFiles) { if (*ptstr == TEXT(PATH_SEPARATOR)) { break; }
dwCharCount++; }
ptstrDependentFiles = ptstrNext; }
dwCharCount++; // for the last NUL of the MULTI_SZ string
if ((ptstrFileNamesWithoutPath = MemAllocZ(dwCharCount * sizeof(TCHAR))) == NULL) { ERR(("Memory allocation failed\n")); return FALSE; }
//
// Second pass of the MULTI_SZ string to copy the file names
//
ptstrDependentFiles = pci->pDriverInfo3->pDependentFiles; ptstrCopy = ptstrFileNamesWithoutPath;
while (*ptstrDependentFiles != NUL) { INT iNameLen;
//
// Go the end of current string
//
ptstr = ptstrDependentFiles + _tcslen(ptstrDependentFiles); ptstrNext = ptstr + 1;
//
// Search backward for '\' path separator
//
while (--ptstr >= ptstrDependentFiles) { if (*ptstr == TEXT(PATH_SEPARATOR)) { break; } }
ptstr++; // point to the char after '\'
iNameLen = _tcslen(ptstr);
CopyMemory(ptstrCopy, ptstr, iNameLen * sizeof(TCHAR)); ptstrCopy += iNameLen + 1;
ptstrDependentFiles = ptstrNext; }
bResult = BSetPrinterDataString(pci->hPrinter, REGVAL_DEPFILES, ptstrFileNamesWithoutPath, REG_MULTI_SZ);
MemFree(ptstrFileNamesWithoutPath);
return bResult; }
#ifdef WINNT_40
BOOL BUpdateVMErrorMessageID( PCOMMONINFO pci ) /*++
Routine Description:
Save the VM Error message ID calculated from the current user's locale under PrinterDriverData registry key.
Arguments:
pci - Points to basic printer information
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwVMErrorMessageID = DWGetVMErrorMessageID();
return BSetPrinterDataDWord(pci->hPrinter, REGVAL_VMERRORMESSAGEID, dwVMErrorMessageID); }
#endif // WINNT_40
INT _IListDevFontNames( HDC hdc, PWSTR pwstrBuf, INT iSize )
{ DWORD dwParam = QUERY_FAMILYNAME;
//
// Ask the driver graphics module for the list of permanant device fonts
//
return ExtEscape(hdc, DRIVERESC_QUERY_DEVFONTS, sizeof(dwParam), (PCSTR) &dwParam, iSize, (PSTR) pwstrBuf); }
INT_PTR CALLBACK _AboutDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
/*++
Routine Description:
Procedure for handling "Printer Properties" proerty sheet page
Arguments:
hDlg - Identifies the property sheet page message - Specifies the message wParam - Specifies additional message-specific information lParam - Specifies additional message-specific information
Return Value:
Depends on the value of message parameter
--*/
{ PUIDATA pUiData; PWSTR pPpdFilename; CHAR achBuf[64] = {0}; CHAR achMsg[136] = {0}; PPDDATA *pPpdData;
switch (message) { case WM_INITDIALOG:
//
// Initialize the About dialog box
//
pUiData = (PUIDATA) lParam; ASSERT(VALIDUIDATA(pUiData));
if (LoadStringA(ghInstance, IDS_PS_VERSION, achBuf, sizeof(achBuf) - 1)) { #ifdef WINNT_40
if (FAILED(StringCchPrintfA(achMsg, CCHOF(achMsg), "%s (" VER_54DRIVERVERSION_STR ")", achBuf)))
#else // WINNT_40
if (FAILED(StringCchPrintfA(achMsg, CCHOF(achMsg), "%s (" VER_PRODUCTVERSION_STR ")", achBuf)))
#endif // WINNT_40
{ WARNING(("Device Settings About box version string truncated.\n")); } } else { WARNING(("Device Setting About box attempt to load version string failed.\n")); }
SetDlgItemTextA(hDlg, IDC_WINNT_VER, achMsg);
SetDlgItemText(hDlg, IDC_MODELNAME, pUiData->ci.pDriverInfo3->pName);
if (pPpdFilename = pUiData->ci.pDriverInfo3->pDataFile) { if (pPpdFilename = wcsrchr(pPpdFilename, TEXT(PATH_SEPARATOR))) pPpdFilename++; else pPpdFilename = pUiData->ci.pDriverInfo3->pDataFile;
SetDlgItemText(hDlg, IDC_PPD_FILENAME, pPpdFilename);
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER(pUiData->ci.pInfoHeader);
ASSERT(pPpdData != NULL);
StringCchPrintfA(achBuf, CCHOF(achBuf), "%d.%d", HIWORD(pPpdData->dwPpdFilever), LOWORD(pPpdData->dwPpdFilever));
SetDlgItemTextA(hDlg, IDC_PPD_FILEVER, achBuf); }
return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; }
return FALSE; }
//
// Determine whether the printer supports stapling
//
BOOL _BSupportStapling( PCOMMONINFO pci )
{ PFEATURE pFeature, pFeatureY; DWORD dwIndex; BOOL bStapleFeatureExist = FALSE;
//
// Except for *StapleOrientation (whose None option doesn't mean stapling off),
// if any of following stapling keywords appear in the PPD file, we check if that
// feature is supported with current installable option selections.
//
// *StapleLocation
// *StapleX
// *StapleY
// *StapleWhen
//
// PPD spec says that a PPD file can contain either *StapleLocation or
// *StapleX and *StapleY but not both.
//
if (pFeature = PGetNamedFeature(pci->pUIInfo, "StapleLocation", &dwIndex)) { bStapleFeatureExist = TRUE;
if (!_BSupportFeature(pci, GID_UNKNOWN, pFeature)) { return FALSE; } } else if ( (pFeature = PGetNamedFeature(pci->pUIInfo, "StapleX", &dwIndex)) && (pFeatureY = PGetNamedFeature(pci->pUIInfo, "StapleY", &dwIndex)) ) { bStapleFeatureExist = TRUE;
if (!_BSupportFeature(pci, GID_UNKNOWN, pFeature) || !_BSupportFeature(pci, GID_UNKNOWN, pFeatureY)) { return FALSE; } }
if (pFeature = PGetNamedFeature(pci->pUIInfo, "StapleWhen", &dwIndex)) { bStapleFeatureExist = TRUE;
if (!_BSupportFeature(pci, GID_UNKNOWN, pFeature)) { return FALSE; } }
//
// We didn't find any constraints on the stapling features caused by installable options,
// so we will assume the printer can support stapling if any of the standard PPD stapling
// keywords are present.
//
return bStapleFeatureExist || PGetNamedFeature(pci->pUIInfo, "StapleOrientation", &dwIndex) != NULL; }
BOOL BFeatureIsConstrained( PUIINFO pUIInfo, PFEATURE pFeature, DWORD dwFeatureIndex, DWORD dwOptionCount, DWORD dwConstraintList, PBYTE aubConstrainedOption, DWORD dwGid )
/*++
Routine Description:
Determine whether the particular constraint list constrains feature options.
Arguments:
pUIInfo - Points to a UIINFO structure pFeature - Points to feature structure to be checked whether constraint or not dwFeatureIndex - index for the feature dwOptionCount - number of options for the feature dwConstraintList - Specifies the constraint list to be searched aubConstrainedOption - Byte array of option constrained flag dwGid - GID_DUPLEX, GID_COLLATE or GID_UNKNOWN to allow feature specific don't cares
Return Value:
TRUE if the feature is constrained by the constraint list, FALSE otherwise.
--*/
{ POPTION pOption; DWORD dwOptionIndex;
ASSERT(dwOptionCount < MAX_PRINTER_OPTIONS);
if (dwConstraintList == NULL_CONSTRAINT) return FALSE;
for (dwOptionIndex = 0; dwOptionIndex < dwOptionCount; dwOptionIndex++) { pOption = PGetIndexedOption(pUIInfo, pFeature, dwOptionIndex);
ASSERT(pOption != NULL);
switch(dwGid) { case GID_COLLATE:
//
// don't care about constraints for no-collate
//
if (((PCOLLATE) pOption)->dwCollateID == DMCOLLATE_FALSE) continue; break;
case GID_DUPLEX:
//
// don't care about constraints for non-duplex
//
if (((PDUPLEX) pOption)->dwDuplexID == DMDUP_SIMPLEX) continue; break;
case GID_UNKNOWN: default:
//
// skip the check for None/False option
//
if (pFeature->dwNoneFalseOptIndex == dwOptionIndex) continue; break; }
if (BSearchConstraintList(pUIInfo, dwConstraintList, dwFeatureIndex, dwOptionIndex)) { aubConstrainedOption[dwOptionIndex] = 1; }
//
// If one option is unconstrained, the feature is not constrained by the
// constraint list
//
if (!aubConstrainedOption[dwOptionIndex]) return FALSE; }
return TRUE; }
BOOL _BSupportFeature( PCOMMONINFO pci, DWORD dwGid, PFEATURE pFeatureIn )
/*++
Routine Description:
Determine whether the printer supports a feature based on current printer-sticky feature selections.
Arguments:
pci - Points to basic printer information dwGid - the GID of the feature to check for constraints. (currently only GID_COLLATE or GID_DUPLEX if pFeatureIn is NULL) pFeatureIn - pointer to the feature structure if the feature doesn't have predefined GID_xxx value
Return Value:
TRUE if feature can be supported, FALSE otherwise.
--*/
{ POPTSELECT pCombinedOptions = pci->pCombinedOptions; PUIINFO pUIInfo = pci->pUIInfo; PFEATURE pCheckFeature, pFeature; POPTION pOption; BYTE aubConstrainedOption[MAX_PRINTER_OPTIONS]; DWORD dwCheckFeatureIndex, dwCheckOptionCount; DWORD dwFeatureIndex; BYTE ubCurOptIndex, ubNext;
if (!pCombinedOptions) return FALSE;
if (pFeatureIn) { //
// If the input feature pointer is provided, dwGid should be GID_UNKNOWN.
//
ASSERT(dwGid == GID_UNKNOWN);
pCheckFeature = pFeatureIn; } else { //
// If no input feature pointer, use dwGid to find the feature. dwGid should be
// either GID_DUPLEX or GID_COLLATE.
//
ASSERT((dwGid == GID_DUPLEX) || (dwGid == GID_COLLATE));
if (!(pCheckFeature = GET_PREDEFINED_FEATURE(pUIInfo, dwGid))) return FALSE; }
dwCheckFeatureIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pCheckFeature);
dwCheckOptionCount = pCheckFeature->Options.dwCount;
//
// Mark all options of the checked feature as non-constrained.
//
memset(aubConstrainedOption, 0, sizeof(aubConstrainedOption));
//
// Scan the feature list to check if it will be constrained by current selections
//
if (!(pFeature = OFFSET_TO_POINTER(pUIInfo->pInfoHeader, pUIInfo->loFeatureList))) return FALSE;
//
// We only care about printer-sticky features
//
pFeature += pUIInfo->dwDocumentFeatures;
for (dwFeatureIndex = pUIInfo->dwDocumentFeatures; dwFeatureIndex < pUIInfo->dwDocumentFeatures + pUIInfo->dwPrinterFeatures; dwFeatureIndex++, pFeature++) { //
// If the feature's current selection is not None/False, it may constrain the checked feature
//
if ((DWORD)pCombinedOptions[dwFeatureIndex].ubCurOptIndex != pFeature->dwNoneFalseOptIndex) { if (BFeatureIsConstrained(pUIInfo, pCheckFeature, dwCheckFeatureIndex, dwCheckOptionCount, pFeature->dwUIConstraintList, aubConstrainedOption, dwGid)) return FALSE; }
ubNext = (BYTE)dwFeatureIndex; while (1) { ubCurOptIndex = pCombinedOptions[ubNext].ubCurOptIndex; pOption = PGetIndexedOption(pUIInfo, pFeature, ubCurOptIndex == OPTION_INDEX_ANY ? 0 : ubCurOptIndex);
if (pOption && BFeatureIsConstrained(pUIInfo, pCheckFeature, dwCheckFeatureIndex, dwCheckOptionCount, pOption->dwUIConstraintList, aubConstrainedOption, dwGid)) return FALSE;
if ((ubNext = pCombinedOptions[ubNext].ubNext) == NULL_OPTSELECT) break; } }
//
// No constraints found, so the feature can be supported.
//
return TRUE; }
VOID VSyncRevPrintAndOutputOrder( PUIDATA pUiData, POPTITEM pCurItem )
/*++
Routine Description:
For PostScript driver, PPD could have "*OpenUI *OutputOrder", which enables user to select "Normal" or "Reverse" output order. In order to avoid spooler performing reverse printing simulation, we will ssync up option selections between REVPRINT_ITEM and "OutputOrder".
Arguments:
pUiData - Pointer to UIDATA structure pCurItem - Pointer to currently selected option item. It will be non-NULL for REVPRINT_ITEM, and will be NULL otherwise.
Return Value:
None.
--*/
{ PUIINFO pUIInfo; PPPDDATA pPpdData; PFEATURE pFeature; POPTION pOption; PCSTR pstrKeywordName; POPTITEM pRevPrintItem, pOutputOrderItem; BOOL bReverse;
ASSERT(VALIDUIDATA(pUiData));
pUIInfo = pUiData->ci.pUIInfo;
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER((PINFOHEADER)pUiData->ci.pRawData);
ASSERT(pPpdData != NULL);
if (pPpdData->dwOutputOrderIndex != INVALID_FEATURE_INDEX && (pOutputOrderItem = PFindOptItemWithKeyword(pUiData, "OutputOrder")) && pOutputOrderItem->Sel < 2 && (pFeature = PGetIndexedFeature(pUIInfo, pPpdData->dwOutputOrderIndex)) && (pOption = PGetIndexedOption(pUIInfo, pFeature, pOutputOrderItem->Sel)) && (pstrKeywordName = OFFSET_TO_POINTER(pUIInfo->pubResourceData, pOption->loKeywordName))) { //
// "OutputOrder" feature is available.
//
if (strcmp(pstrKeywordName, "Reverse") == EQUAL_STRING) bReverse = TRUE; else bReverse = FALSE;
if (pCurItem) { //
// Currently selected item is REVPRINT_ITEM. We should change "OutputOrder" option
// if needed to match the requested output order.
//
if ((pCurItem->Sel == 0 && bReverse) || (pCurItem->Sel == 1 && !bReverse)) { pOutputOrderItem->Sel = 1 - pOutputOrderItem->Sel; pOutputOrderItem->Flags |= OPTIF_CHANGED;
//
// Save the new settings in the options array
//
VUnpackDocumentPropertiesItems(pUiData, pOutputOrderItem, 1);
//
// The change could trigger constraints.
//
if (ICheckConstraintsDlg(pUiData, pOutputOrderItem, 1, FALSE) == CONFLICT_CANCEL) { //
// If there is a conflict and the user clicked CANCEL,
// we need to restore the origianl selection.
//
pCurItem->Sel = 1 - pCurItem->Sel; pCurItem->Flags |= OPTIF_CHANGED;
VUnpackDocumentPropertiesItems(pUiData, pCurItem, 1);
pOutputOrderItem->Sel = 1 - pOutputOrderItem->Sel; pOutputOrderItem->Flags |= OPTIF_CHANGED;
VUnpackDocumentPropertiesItems(pUiData, pOutputOrderItem, 1); } } } else { //
// Sync up REVPRINT_ITEM selection based on "OutputOrder" selection.
//
if ((pRevPrintItem = PFindOptItemWithUserData(pUiData, REVPRINT_ITEM)) && ((pRevPrintItem->Sel == 0 && bReverse) || (pRevPrintItem->Sel == 1 && !bReverse))) { pRevPrintItem->Sel = 1 - pRevPrintItem->Sel; pRevPrintItem->Flags |= OPTIF_CHANGED;
//
// Save the new settings in the options array
//
VUnpackDocumentPropertiesItems(pUiData, pRevPrintItem, 1); } } } }
|