You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1864 lines
43 KiB
1864 lines
43 KiB
/*++
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|