Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

570 lines
12 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
devmode.c
Abstract:
Functions for manipulating devmode inforation.
[Environment:]
Win32 subsystem, PostScript driver, kernel and user mode
[Notes:]
Revision History:
06/26/96 -davidx-
Ported from Daytona.
mm/dd/yy -author-
description
--*/
#include "pslib.h"
BOOL
SetDefaultDevMode(
PDEVMODE pdm,
PWSTR pDeviceName,
HPPD hppd,
BOOL bMetric
)
/*++
Routine Description:
Initialize a devmode structure with defaults
Arguments:
pdm Pointer to devmode structure
pDeviceName Pointer to device name
hppd Pointer to printer PPD object
bMetric Whether the system is running in a metric country
Return Value:
TRUE if successful, FALSE otherwise.
--*/
{
PRIVATEDEVMODE *pdmPrivate;
LPTSTR pFormName;
memset(pdm, 0, sizeof(PSDEVMODE));
if (pDeviceName) {
CopyStringW(pdm->dmDeviceName, pDeviceName, CCHDEVICENAME);
}
pdm->dmDriverVersion = DRIVER_VERSION;
pdm->dmSpecVersion = DM_SPECVERSION;
pdm->dmSize = sizeof(DEVMODE);
pdm->dmDriverExtra = sizeof(PRIVATEDEVMODE);
pdm->dmFields =
DM_ORIENTATION | DM_PAPERSIZE | DM_FORMNAME | DM_SCALE |
DM_COPIES | DM_PRINTQUALITY | DM_TTOPTION | DM_DEFAULTSOURCE;
pdm->dmOrientation = DMORIENT_PORTRAIT;
pdm->dmDuplex = DMDUP_SIMPLEX;
pdm->dmCollate = DMCOLLATE_FALSE;
pdm->dmTTOption = DMTT_SUBDEV;
pdm->dmColor = DMCOLOR_MONOCHROME;
pdm->dmDefaultSource = DMBIN_FORMSOURCE;
// The default form depends on the country:
// Letter for non-metric countries
// A4 for metric countries
if (bMetric) {
pFormName = STDSTR_A4_FORM_NAME;
pdm->dmPaperSize = DMPAPER_A4;
} else {
pFormName = STDSTR_LETTER_FORM_NAME;
pdm->dmPaperSize = DMPAPER_LETTER;
}
CopyStringW(pdm->dmFormName, pFormName, CCHFORMNAME);
pdm->dmScale = 100;
pdm->dmCopies = 1;
pdm->dmPrintQuality = (SHORT) PpdDefaultResolution(hppd);
if (hppd->bColorDevice) {
pdm->dmColor = DMCOLOR_COLOR;
pdm->dmFields |= DM_COLOR;
}
if (PpdSupportDuplex(hppd))
pdm->dmFields |= DM_DUPLEX;
if (PpdSupportCollation(hppd))
pdm->dmFields |= DM_COLLATE;
// Fill in the private portion of devmode
pdmPrivate = (PRIVATEDEVMODE *) GetPrivateDevMode(pdm);
pdmPrivate->dwPrivDATA = PSDEVMODE_SIGNATURE;
pdmPrivate->dwFlags = 0;
#ifndef KERNEL_MODE
// Set up some devmode flag bits for compatibility
// with previous versions of the driver
// To behave the same as in ee win31, by default do not substitute
// device fonts for tt if code page is not 1252. Also if cp != 1252,
// do not enumerate printer resident fonts, for they all have cp 1252.
if (GetACP() == 1252) {
pdmPrivate->dwFlags |=
(PSDEVMODE_FONTSUBST|PSDEVMODE_ENUMPRINTERFONTS);
}
#endif
// Send ^D after each job by default
pdmPrivate->dwFlags |= PSDEVMODE_CTRLD_AFTER;
// Use printer default landscape rotation
if (hppd->wLsOrientation == LSO_MINUS90)
pdmPrivate->dwFlags |= PSDEVMODE_LSROTATE;
// Don't do bitmap compression on level 1 devices
if (Level2Device(hppd))
pdmPrivate->dwFlags |= PSDEVMODE_COMPRESSBMP;
pdmPrivate->coloradj = DefHTClrAdj;
// default printer options
pdmPrivate->wChecksum = hppd->wChecksum;
pdmPrivate->wOptionCount =
PpdDefaultDocumentStickyFeatures(hppd, pdmPrivate->options);
return TRUE;
}
BOOL
ValidateSetDevMode(
PDEVMODE pdmDest,
PDEVMODE pdmSrc,
HPPD hppd
)
/*++
Routine Description:
Verify the source devmode and merge it with destination devmode
Arguments:
pdmDest Pointer to destination devmode
pdmSrc Pointer to source devmode
hppd Pointer to printer PPD object
Return Value:
TRUE if source devmode is valid and successfully merged
FALSE otherwise
[Note:]
pdmDest must point to a valid PSDEVMODE when this function is called.
--*/
{
PDEVMODE pdm;
PRIVATEDEVMODE *privDest, *privSrc;
// If source pointer is NULL, do nothing
if (pdmSrc == NULL)
return TRUE;
// Convert the source devmode into a local buffer
if ((pdm = MEMALLOC(sizeof(PSDEVMODE))) == NULL)
return FALSE;
ASSERT(pdmDest->dmSpecVersion == DM_SPECVERSION &&
pdmDest->dmDriverVersion == DRIVER_VERSION);
memcpy(pdm, pdmDest, sizeof(PSDEVMODE));
if (ConvertDevmode(pdmSrc, pdm) <= 0) {
DBGERRMSG("ConvertDevMode");
MEMFREE(pdm);
return FALSE;
}
pdmSrc = pdm;
// Copy dmDefaultSource field
if (pdmSrc->dmFields & DM_DEFAULTSOURCE) {
pdmDest->dmDefaultSource = pdmSrc->dmDefaultSource;
pdmDest->dmFields |= DM_DEFAULTSOURCE;
}
// Copy dmOrientation field
if (pdmSrc->dmFields & DM_ORIENTATION) {
pdmDest->dmFields |= DM_ORIENTATION;
if ((pdmSrc->dmOrientation != DMORIENT_PORTRAIT) &&
(pdmSrc->dmOrientation != DMORIENT_LANDSCAPE))
pdmDest->dmOrientation = DMORIENT_PORTRAIT;
else
pdmDest->dmOrientation = pdmSrc->dmOrientation;
}
// If both DM_PAPERLENGTH and DM_PAPERWIDTH are set, copy
// dmPaperLength and dmPaperWidth fields. If DM_PAPERSIZE
// is set, copy dmPaperSize field. Otherwise, if DM_FORMNAME
// is set, copy dmFormName field.
if (IsCustomForm(pdmSrc) && ValidCustomForm(pdmSrc)) {
pdmDest->dmPaperLength = pdmSrc->dmPaperLength;
pdmDest->dmPaperWidth = pdmSrc->dmPaperWidth;
pdmDest->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
pdmDest->dmFields &= ~(DM_PAPERSIZE | DM_FORMNAME);
} else if (pdmSrc->dmFields & DM_PAPERSIZE) {
pdmDest->dmPaperSize = pdmSrc->dmPaperSize;
pdmDest->dmFields |= DM_PAPERSIZE;
pdmDest->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_FORMNAME);
} else if (pdmSrc->dmFields & DM_FORMNAME) {
CopyStringW(pdmDest->dmFormName, pdmSrc->dmFormName, CCHFORMNAME);
pdmDest->dmFields |= DM_FORMNAME;
pdmDest->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_PAPERSIZE);
}
// Copy dmScale field
if (pdmSrc->dmFields & DM_SCALE) {
pdmDest->dmFields |= DM_SCALE;
if ((pdmSrc->dmScale < MIN_SCALE) ||
(pdmSrc->dmScale > MAX_SCALE))
pdmDest->dmScale = 100;
else
pdmDest->dmScale = pdmSrc->dmScale;
}
// Copy dmCopies field
if (pdmSrc->dmFields & DM_COPIES) {
pdmDest->dmFields |= DM_COPIES;
if ((pdmSrc->dmCopies < MIN_COPIES) ||
(pdmSrc->dmCopies > MAX_COPIES))
pdmDest->dmCopies = 1;
else
pdmDest->dmCopies = pdmSrc->dmCopies;
}
// Copy dmPrintQuality field
if (pdmSrc->dmFields & DM_PRINTQUALITY) {
pdmDest->dmFields |= DM_PRINTQUALITY;
pdmDest->dmPrintQuality =
(SHORT) PpdDefaultResolution(hppd);
if (pdmSrc->dmPrintQuality > 0 &&
PpdFindResolution(hppd, pdmSrc->dmPrintQuality))
{
pdmDest->dmPrintQuality = pdmSrc->dmPrintQuality;
}
}
// Copy dmColor field
if (pdmSrc->dmFields & DM_COLOR) {
pdmDest->dmFields |= DM_COLOR;
if (pdmSrc->dmColor == DMCOLOR_COLOR)
pdmDest->dmColor = DMCOLOR_COLOR;
else
pdmDest->dmColor = DMCOLOR_MONOCHROME;
}
// Copy dmDuplex field
if (pdmSrc->dmFields & DM_DUPLEX) {
if (!PpdSupportDuplex(hppd) ||
((pdmSrc->dmDuplex != DMDUP_SIMPLEX) &&
(pdmSrc->dmDuplex != DMDUP_HORIZONTAL) &&
(pdmSrc->dmDuplex != DMDUP_VERTICAL)))
{
pdmDest->dmDuplex = DMDUP_SIMPLEX;
} else {
pdmDest->dmFields |= DM_DUPLEX;
pdmDest->dmDuplex = pdmSrc->dmDuplex;
}
}
// Copy dmCollate field
if (pdmSrc->dmFields & DM_COLLATE) {
if (!PpdSupportCollation(hppd) ||
((pdmSrc->dmCollate != DMCOLLATE_TRUE) &&
(pdmSrc->dmCollate != DMCOLLATE_FALSE)))
{
pdmDest->dmCollate = DMCOLLATE_FALSE;
} else {
pdmDest->dmFields |= DM_COLLATE;
pdmDest->dmCollate = pdmSrc->dmCollate;
}
}
// If the source devmode has a private portion, then check
// to see if belongs to us. Copy the private portion to
// the destination devmode if it does.
ASSERT(pdmSrc->dmDriverExtra == sizeof(PRIVATEDEVMODE));
privDest = (PRIVATEDEVMODE *) GetPrivateDevMode(pdmDest);
privSrc = (PRIVATEDEVMODE *) GetPrivateDevMode(pdmSrc);
if (privSrc->dwPrivDATA == PSDEVMODE_SIGNATURE) {
memcpy(privDest, privSrc, sizeof(PRIVATEDEVMODE));
if (privDest->wChecksum != hppd->wChecksum) {
DBGMSG(DBG_LEVEL_WARNING, "Devmode checksum mismatch.\n");
privDest->wChecksum = hppd->wChecksum;
privDest->wOptionCount =
PpdDefaultDocumentStickyFeatures(hppd, privDest->options);
}
}
MEMFREE(pdm);
return TRUE;
}
DWORD
PickDefaultHTPatSize(
DWORD xDPI,
DWORD yDPI,
BOOL HTFormat8BPP
)
/*++
Routine Description:
This function return default halftone pattern size used for a particular
device resolution
Arguments:
xDPI - Device LOGPIXELS X
yDPI - Device LOGPIXELS Y
8BitHalftone - If a 8-bit halftone will be used
Return Value:
DWORD HT_PATSIZE_xxxx
Author:
29-Jun-1993 Tue 14:46:49 created -by- Daniel Chou (danielc)
Revision History:
--*/
{
DWORD HTPatSize;
//
// use the smaller resolution as the pattern guide
//
if (xDPI > yDPI) {
xDPI = yDPI;
}
if (xDPI >= 2400) {
HTPatSize = HT_PATSIZE_16x16_M;
} else if (xDPI >= 1800) {
HTPatSize = HT_PATSIZE_14x14_M;
} else if (xDPI >= 1200) {
HTPatSize = HT_PATSIZE_12x12_M;
} else if (xDPI >= 900) {
HTPatSize = HT_PATSIZE_10x10_M;
} else if (xDPI >= 400) {
HTPatSize = HT_PATSIZE_8x8_M;
} else if (xDPI >= 180) {
HTPatSize = HT_PATSIZE_6x6_M;
} else {
HTPatSize = HT_PATSIZE_4x4_M;
}
if (HTFormat8BPP) {
HTPatSize -= 2;
}
return(HTPatSize);
}
#ifndef KERNEL_MODE
BOOL
IsMetricCountry(
VOID
)
/*++
Routine Description:
Determine if the current country is using metric system.
Arguments:
NONE
Return Value:
TRUE if the current country uses metric system
FALSE otherwise
--*/
{
INT cChar;
PWSTR pwstr;
PSTR pstr;
LONG lCountryCode;
BOOL bMetric = FALSE;
// Determine the size of the buffer needed to retrieve information.
cChar = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ICOUNTRY, NULL, 0);
if (cChar == 0) {
// Default to non-metric US standards if there was a problem.
DBGERRMSG("GetLocaleInfoW");
return(FALSE);
}
// Allocate the necessary buffers.
pwstr = (WCHAR *) MEMALLOC(cChar * sizeof(WCHAR));
pstr = (CHAR *) MEMALLOC(cChar * sizeof(CHAR));
if (pwstr != NULL && pstr != NULL) {
// We now have a buffer, so get the country code.
cChar = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ICOUNTRY,
pwstr, cChar);
if (cChar > 0) {
// pwstr now points to a UNICODE string representing
// the country code. Convert it to ANSI string.
UNICODETOMULTIBYTE(pstr, cChar, NULL, pwstr, cChar*sizeof(WCHAR));
// Now convert country code to integer.
lCountryCode = atol(pstr);
// This is the Win31 algorithm based on AT&T international
// dialing codes.
bMetric =
((lCountryCode == CTRY_UNITED_STATES) ||
(lCountryCode == CTRY_CANADA) ||
(lCountryCode >= 50 && lCountryCode < 60) ||
(lCountryCode >= 500 && lCountryCode < 600)) ? FALSE : TRUE;
} else {
DBGERRMSG("GetLocaleInfoW");
}
} else {
DBGERRMSG("MEMALLOC");
}
// Free memory buffers if necessary
if (pstr != NULL) {
MEMFREE(pstr);
}
if (pwstr != NULL) {
MEMFREE(pwstr);
}
return bMetric;
}
#endif //!KERNEL_MODE