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.
 
 
 
 
 
 

1249 lines
26 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
ppdobj.c
Abstract:
PostScript driver PPD parser
Revision History:
04/18/95 -davidx-
Created it.
07/17/95 -davidx-
Renamed to ppdobj.c
mm/dd/yy -author-
description
--*/
#include "pslib.h"
#include "ppdfile.h"
#include "ppdparse.h"
#include "ppdchar.h"
#include "ppdkwd.h"
// Forward declaration of local functions.
// Initialize PPDOBJ object to its default state.
VOID
PPDOBJ_SetDefaults(
PPPDOBJ pPpdObj
);
// Interpret one entry of a PPD file.
PPDERROR
PPDOBJ_InterpretEntry(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
);
// Parse a PPD file and merge the information from
// the PPD file into the input PPDOBJ object.
BOOL
PPDOBJ_ParseFile(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj,
PCWSTR pwstrFilename
);
PPPDOBJ
PPDOBJ_Create(
PCWSTR pwstrFilename
)
/*++
Routine Description:
Load a PPD file from disk and parse its contents
Arguments:
pwstrFilename - fully qualified PPD filename
Return Value:
Pointer to parsed PPDOBJ object.
NULL if an error occurred.
[Note:]
This function is not multithread safe. You should protect
it in a critical section in a multithreaded environment.
--*/
{
PPARSEROBJ pParserObj = NULL;
PHEAPOBJ pHeap = NULL;
PPPDOBJ pPpdObj;
ASSERT(pwstrFilename != NULL);
// Allocate a temporary PARSEROBJ object.
// This is not allocated from the heap because
// it's always freed before the function returns.
pParserObj = PARSEROBJ_Create();
if (pParserObj == NULL)
goto handleError;
// Create a memory heap
pHeap = HEAPOBJ_Create();
if (pHeap == NULL)
goto handleError;
// Allocate space to hold PPDOBJ object.
// Initialize its contents to zero.
pPpdObj = (PPPDOBJ) HEAPOBJ_Alloc(pHeap, sizeof(PPDOBJ));
if (pPpdObj == NULL)
goto handleError;
memset(pPpdObj, 0, sizeof(PPDOBJ));
pPpdObj->pHeap = pHeap;
// Initialize PPDOBJ object
pPpdObj->pwstrFilename = (PWSTR)
HEAPOBJ_Alloc(pHeap, sizeof(WCHAR) * (wcslen(pwstrFilename) + 1));
if (pPpdObj->pwstrFilename == NULL)
goto handleError;
wcscpy(pPpdObj->pwstrFilename, pwstrFilename);
PPDOBJ_SetDefaults(pPpdObj);
// Initialize the keyword search table
InitKeywordTable();
// Parse PPD file
if (PPDOBJ_ParseFile(pPpdObj, pParserObj, pwstrFilename)) {
// For debugging purposes only
#if DBG
if (CHECK_DBG_LEVEL(DBG_LEVEL_VERBOSE)) {
HEAPOBJ_Dump(pPpdObj->pHeap);
PPDOBJ_Dump(pPpdObj);
}
#endif
// PPD file was successfully loaded. Free the temporary
// PARSEROBJ object and return the PPDOBJ object.
PARSEROBJ_Delete(pParserObj);
return pPpdObj;
}
handleError:
// PPD file was not loaded successfully.
// Clean up and return NULL.
DBGMSG(DBG_LEVEL_ERROR,
"Couldn't load the PPD file due to an error.\n");
if (pHeap != NULL) {
HEAPOBJ_Delete(pHeap);
}
if (pParserObj != NULL) {
PARSEROBJ_Delete(pParserObj);
}
return NULL;
}
VOID
PPDOBJ_Delete(
PPPDOBJ ppdobj
)
/*++
Routine Description:
Unload a PPD file previously loaded by PPDOBJ_Create.
Arguments:
ppdobj - Pointer to a PPDOBJ object
Return Value:
NONE
--*/
{
ASSERT(ppdobj != NULL);
// Delete the memory heap.
HEAPOBJ_Delete(ppdobj->pHeap);
// PPDOBJ object itself is allocated from the heap
// and is automatically freed when the heap is deleted.
}
BOOL
PPDOBJ_ParseFile(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj,
PCWSTR pwstrFilename
)
/*++
Routine Description:
Parse a PPD file and merge the information from
the PPD file into the input PPDOBJ object.
Arguments:
pPpdObj - Pointer to a PPDOBJ object
pParserObj - Pointer to a temporary parser object
pwstrFilename - Pointer to fully qualified PPD filename
[Note:]
This function must be reentrant. It calls itself
recursively while processing *Include keyword.
Return Value:
TRUE if the PPD file is parsed successfully.
FALSE if there is an error during parsing.
--*/
{
PPDERROR err = PPDERR_FILE;
PFILEOBJ pFileObj;
// Create a file object
pFileObj = FILEOBJ_Create(pwstrFilename, &pPpdObj->wChecksum);
if (pFileObj != NULL) {
do {
// Parse one entry from the PPD file.
// The return value is one of the following:
// PPDERR_NONE - entry is valid
// PPDERR_xxx - an error has occured
err = PARSEROBJ_ParseEntry(pParserObj, pFileObj);
// If the entry is valid, interpret it
if (err == PPDERR_NONE) {
// For debugging purpose only
// Dump a parsed PPD entry
#if DBG
if (CHECK_DBG_LEVEL(DBG_LEVEL_VERBOSE)) {
PARSEROBJ_Dump(pParserObj);
}
#endif
err = PPDOBJ_InterpretEntry(pPpdObj, pParserObj);
}
// Continue after a syntax error
if (err == PPDERR_SYNTAX) {
DBGMSG(DBG_LEVEL_VERBOSE,
"Ignoring syntax error found in the PPD file!\n");
}
} while (err == PPDERR_NONE || err == PPDERR_SYNTAX);
// Delete the file object
FILEOBJ_Delete(pFileObj);
}
// Parsing is considered successful only when the
// end-of-file is reached and there is no error.
if (err == PPDERR_EOF)
return TRUE;
else {
DBGMSG1(DBG_LEVEL_ERROR,
"ParseFile failed: error code = %d\n",
err);
return FALSE;
}
}
PPDERROR
PPDOBJ_InterpretEntry(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
/*++
Routine Description:
Interpret one entry of a PPD file. The entry is
into the temporary parser object.
Arguments:
pPpdObj - Pointer to a PPDOBJ object
pParserObj - Pointer to a parser object
Return Value:
PPDERR_NONE - the entry was successfully interpreted
PPDERR_SYNTAX - found a syntax error in the entry
--*/
{
KEYWORD_TABLE_ENTRY * pKwdEntry;
PSTR pKeyword;
PPDERROR err = PPDERR_NONE;
// Get a pointer to the keyword string
pKeyword = pParserObj->keyword.pBuffer;
// If the keyword is a query, simply ignore it.
if (*pKeyword == QUERY_CHAR)
return PPDERR_NONE;
// If there is a currently open UI group,
// look for the OpenUI keyword.
if (pPpdObj->pOpenUi != NULL) {
INT len;
// Keyword matches the OpenUI keyword?
if (strcmp(pKeyword, pPpdObj->pOpenUi->pName) == EQUAL_STRING)
return CommonUiOptionProc(pPpdObj, pParserObj);
// Keyword matches the Default + OpenUI keyword?
len = strlen(defaultPrefixStr);
if (strncmp(pKeyword, defaultPrefixStr, len) == EQUAL_STRING &&
strcmp(pKeyword+len, pPpdObj->pOpenUi->pName) == EQUAL_STRING)
{
return CommonUiDefaultProc(pPpdObj, pParserObj);
}
}
// Map keyword string to a keyword table entry. If the
// keyword is not supported, the return value is NULL.
//
// Note: There are two alternatives for processing keywords:
// 1) The keyword table entry contains a function pointer
// field. We use this function pointer to invoke the handler.
// 2) The keyword table entry contains a keyword index. We
// use the index in a big switch statement to process all
// the keywords. The first approach is cleaner but may result
// in larger code size.
pKwdEntry = SearchKeyword(pKeyword);
if (pKwdEntry == NULL) {
// DBGMSG1(DBG_LEVEL_VERBOSE,
// "Keyword *%s not supported\n",
// pKeyword);
} else {
// Handle the keyword through the function pointer in
// the keyword table entry.
if (pKwdEntry->pHandler == NULL) {
DBGMSG1(DBG_LEVEL_VERBOSE,
"Keyword *%s ignored\n",
pKeyword);
} else if (! CheckKeywordParams(pKwdEntry, pParserObj)) {
// Preliminary syntax check failed
err = PPDERR_SYNTAX;
} else if (! CheckKeywordDuplicates(pKwdEntry)) {
// If we've seen this keyword before and it's
// not allowed to occur multiple times, then
// we simply ignore the last occurances.
DBGMSG1(DBG_LEVEL_WARNING,
"Duplicate occurance of *%s ignored.\n",
pKeyword);
} else {
err = (pKwdEntry->pHandler)(pPpdObj, pParserObj);
if (err != PPDERR_NONE) {
DBGMSG1(DBG_LEVEL_ERROR,
"Syntax error in keyword entry *%s\n",
pKeyword);
} else {
// Mark the keyword as seen before
pKwdEntry->wFlags |= KWF_SEENBEFORE;
}
}
}
return err;
}
VOID
PPDOBJ_SetDefaults(
PPPDOBJ pPpdObj
)
/*++
Routine Description:
Initialize a PPDOBJ object to its default state per
"PostScript Printer Description File Format Specification"
Version 4.2.
Arguments:
pPpdObj - Pointer to PPDOBJ object to be initialized
Return Value:
NONE
[Note:]
We assume all fields are initially zeroed out before
this function is called.
--*/
{
pPpdObj->wChecksum = 0;
pPpdObj->bColorDevice = FALSE;
pPpdObj->dwLangLevel = 1;
pPpdObj->bPrintPsErrors = FALSE;
pPpdObj->dwJobTimeout = DEFAULT_JOB_TIMEOUT;
pPpdObj->dwWaitTimeout = DEFAULT_WAIT_TIMEOUT;
pPpdObj->bCustomPageSize = FALSE;
pPpdObj->screenAngle = INT2PSREAL(45);
pPpdObj->screenFreq = INT2PSREAL(60);
pPpdObj->wResType = RESTYPE_NORMAL;
}
VOID
LISTOBJ_Add(
PLISTOBJ * ppListObj,
PLISTOBJ pItem
)
/*++
Routine Description:
Add a new item to the end of a linked list
Arguments:
ppListObj - pointer to a linked list.
pItem - pointer to the new item to be added
Return Value:
NONE
[Note:]
The first parameter is declared as PLISTOBJ* because
we need to modify the pointer to linked list itself
in case it was originally empty.
--*/
{
PLISTOBJ pLast, pNext;
// Compute the hash value for the new item
pItem->dwHash = HashKeyword(pItem->pName);
// Go to the end of the linked list
pLast = pNext = *ppListObj;
while (pNext != NULL) {
pLast = pNext;
pNext = pLast->pNext;
}
// Append the new item to the end if the list wasn't empty.
// Otherwise, create a linked with a single item.
if (pLast != NULL)
pLast->pNext = pItem;
else
*ppListObj = pItem;
}
PLISTOBJ
LISTOBJ_Find(
PLISTOBJ pListObj,
PCSTR pName
)
/*++
Routine Description:
Find a named item from a linked list and
return a pointer to the item found.
Arguments:
pListObj - Pointer to the head of linked list
pName - Name of the item to be found
Return Value:
Pointer to the named item on the linked list
NULL if the named item is not found
--*/
{
DWORD dwHash;
dwHash = HashKeyword(pName);
while ((pListObj != NULL) &&
(dwHash != pListObj->dwHash ||
strcmp(pName, pListObj->pName) != EQUAL_STRING))
{
pListObj = pListObj->pNext;
}
return pListObj;
}
PLISTOBJ
LISTOBJ_FindItemIndex(
PLISTOBJ pListObj,
PCSTR pName,
WORD *pItemIndex
)
/*++
Routine Description:
Find a named item from a linked list and
return a zero-based item index.
Arguments:
pListObj - Pointer to the head of linked list
pName - Name of the item to be found
Return Value:
Pointer to the named item on the linked list
NULL if the named item is not found
pItemIndex contains either the index of the specified item
in the list or OPTION_INDEX_NONE if the item is not found.
[Note:]
This function breaks when your list approaches 64K items!
--*/
{
WORD index = 0;
DWORD dwHash;
dwHash = HashKeyword(pName);
while ((pListObj != NULL) &&
(dwHash != pListObj->dwHash ||
strcmp(pName, pListObj->pName) != EQUAL_STRING))
{
pListObj = pListObj->pNext;
index++;
}
*pItemIndex = (pListObj == NULL) ? OPTION_INDEX_NONE : index;
return pListObj;
}
PLISTOBJ
LISTOBJ_Enum(
PLISTOBJ pListObj,
LISTENUMPROC pProc,
DWORD dwParam
)
/*++
Routine Description:
Enumerate through a linked list. Call pProc with each item
of the list as the parameter until the end of the list is
reached or pProc returns FALSE.
Arguments:
pListObj - pointer to a list object
pProc - enumeration callback procedure
Return Value:
NULL if the entire list is enumerated. Or,
Pointer to the list item which caused the enumeration to terminated.
[Note:]
The callback function takes two parameters: the first is a pointer
to the current linked list item, the second is dwParam. It can
process the item whichever way it desires but it must not modify
the link pointer field. Otherwise, the result will be undefined.
The callback function should return FALSE if it wants to stop
the enumeration process. Otherwise, it should return TRUE.
BOOL EnumCallbackProc(PLISTOBJ pItem, DWORD dwParam);
--*/
{
while (pListObj != NULL && pProc(pListObj, dwParam))
pListObj = pListObj->pNext;
return pListObj;
}
DWORD
LISTOBJ_Count(
PLISTOBJ pListObj
)
/*++
Routine Description:
Count the number of items in a linked list
Arguments:
pListObj pointer to list object
Return Value:
Number of items in the list
--*/
{
DWORD count = 0;
while (pListObj != NULL) {
pListObj = pListObj->pNext;
count++;
}
return count;
}
PLISTOBJ
LISTOBJ_FindIndexed(
PLISTOBJ pListObj,
DWORD index
)
/*++
Routine Description:
Find an item from a linked list using index
Arguments:
pListObj pointer to list object
index index of the item to be found (0 = the first item)
Return Value:
pointer to the indexed item
NULL if the indexed item is not found
--*/
{
while (pListObj != NULL && index-- > 0)
pListObj = pListObj->pNext;
return pListObj;
}
DWORD
UIGROUP_CountOptions(
PUIGROUP pUiGroup
)
/*++
Routine Description:
Count the number options in a UI group
Arguments:
pUiGroup Pointer to a UI group object
Return Value:
Number of options in a UI group
--*/
{
return (pUiGroup == NULL) ? 0 :
LISTOBJ_Count((PLISTOBJ) pUiGroup->pUiOptions);
}
PUIOPTION
UIGROUP_GetOptions(
PUIGROUP pUiGroup
)
/*++
Routine Description:
Return the list of options in a UI group
Arguments:
pUiGroup - Pointer to a UIGROUP object
Return Value:
Pointer to a list of UI options
--*/
{
return (pUiGroup == NULL) ? NULL : pUiGroup->pUiOptions;
}
PUIOPTION
UIGROUP_GetDefaultOption(
PUIGROUP pUiGroup
)
/*++
Routine Description:
Find the default UI option in a UI group
Arguments:
pUiGroup Pointer to a UIGROUP object
Return Value:
Pointer to the default UI option. NULL if there isn't any.
--*/
{
return (pUiGroup == NULL) ? NULL :
(PUIOPTION) LISTOBJ_FindIndexed(
(PLISTOBJ) pUiGroup->pUiOptions, pUiGroup->dwDefault);
}
// Conversion from PostScript point represented as 24.8 fixed-point
// number to device pixel:
// (psreal) * (resolution) / (PS_RESOLUTION<<PSREALBITS)
LONG
PSRealToPixel(
PSREAL psreal,
LONG resolution
)
{
#ifdef KERNEL_MODE
FLOATOBJ floatobj;
// Use floating-point arithmetic to avoid overflow
FLOATOBJ_SetLong(&floatobj, psreal);
FLOATOBJ_MulLong(&floatobj, resolution);
FLOATOBJ_DivLong(&floatobj, PS_RESOLUTION<<PSREALBITS);
return FLOATOBJ_GetLong(&floatobj);
#else //!KERNEL_MODE
return (LONG) ((float) psreal * resolution / (PS_RESOLUTION<<PSREALBITS));
#endif //!KERNEL_MODE
}
// Conversion from .001 mm to PostScript point represented as
// 24.8 fixed-point number:
// (micron) * (PS_RESOLUTION<<PSREALBITS) / 25400
PSREAL
MicronToPSReal(
LONG micron
)
{
#ifdef KERNEL_MODE
FLOATOBJ floatobj;
// Use floating-point arithmetic to avoid overflow
FLOATOBJ_SetLong(&floatobj, micron);
FLOATOBJ_MulLong(&floatobj, PS_RESOLUTION<<PSREALBITS);
FLOATOBJ_DivLong(&floatobj, 25400);
return (PSREAL) FLOATOBJ_GetLong(&floatobj);
#else //!KERNEL_MODE
return (PSREAL) ((float) micron * (PS_RESOLUTION<<PSREALBITS) / 25400);
#endif //!KERNEL_MODE
}
// Conversion from PostScript point represented as 24.8 fixed point
// number to .001 mm:
// (psreal) * 25400 / (PS_RESOLUTION<<PSREALBITS)
LONG
PSRealToMicron(
PSREAL psreal
)
{
#ifdef KERNEL_MODE
FLOATOBJ floatobj;
// Use floating-point arithmetic to avoid overflow
FLOATOBJ_SetLong(&floatobj, psreal);
FLOATOBJ_MulLong(&floatobj, 25400);
FLOATOBJ_DivLong(&floatobj, PS_RESOLUTION<<PSREALBITS);
return FLOATOBJ_GetLong(&floatobj);
#else //!KERNEL_MODE
return (LONG) ((float) psreal * 25400 / (PS_RESOLUTION<<PSREALBITS));
#endif //!KERNEL_MODE
}
///////////////////////////////////////////////////////////////////////////////
// Code for debugging purposes only
///////////////////////////////////////////////////////////////////////////////
#if DBG
#define BOOLSTR(bool) ((bool) ? "True" : "False")
#define SAFESTR(str) (((str) != NULL) ? (str) : "")
// Dump a PSREAL number
VOID
DumpPsReal(
PSREAL r
)
{
DWORD frac, scale;
DBGPRINT("%d", PSREAL2INT(r));
frac = PSREALFRAC(r);
if (frac != 0) {
DBGPRINT(".");
scale = MAXFRACSCALE;
frac = (frac * scale) / (1<<PSREALBITS);
while (frac > 0) {
scale /= 10;
DBGPRINT("%c", frac/scale + '0');
frac %= scale;
}
}
DBGPRINT(" ");
}
// Dump a PSRECT structure
VOID
DumpPsRect(
PSRECT * pRect
)
{
DumpPsReal(pRect->left);
DumpPsReal(pRect->bottom);
DumpPsReal(pRect->right);
DumpPsReal(pRect->top);
}
// Dump a device font
BOOL
DumpFont(
PDEVFONT pFont,
DWORD dwParam
)
{
DBGPRINT("Font %s, encoding = %d, charset = %d\n",
pFont->pName, pFont->wEncoding, pFont->wCharSet);
return TRUE;
}
// Dump a UI option
BOOL
DumpUiOption(
PUIOPTION pUiOption,
DWORD dwParam
)
{
DBGPRINT("%s", pUiOption->pName);
if (pUiOption->pXlation)
DBGPRINT(" / %s", pUiOption->pXlation);
DBGPRINT(": %s\n", SAFESTR(pUiOption->pInvocation));
return TRUE;
}
// Dump a media option
BOOL
DumpMediaOption(
PMEDIAOPTION pMediaOption,
DWORD dwParam
)
{
ASSERT(pMediaOption->pName != NULL);
DBGPRINT("%s", pMediaOption->pName);
if (pMediaOption->pXlation)
DBGPRINT(" / %s", pMediaOption->pXlation);
DBGPRINT(":\n");
DBGPRINT(" PageSize code: %s\n", SAFESTR(pMediaOption->pPageSizeCode));
DBGPRINT(" PageRegion code: %s\n", SAFESTR(pMediaOption->pPageRgnCode));
DBGPRINT(" Dimension (width x height): ");
DumpPsReal(pMediaOption->dimension.width);
DumpPsReal(pMediaOption->dimension.height);
DBGPRINT("\n");
DBGPRINT(" Imageable area: ");
DumpPsRect(&pMediaOption->imageableArea);
DBGPRINT("\n");
return TRUE;
}
// Dump an input slot
BOOL
DumpInputSlot(
PINPUTSLOT pInputSlot,
DWORD dwParam
)
{
DBGPRINT("%s", pInputSlot->pName);
if (pInputSlot->pXlation)
DBGPRINT(" / %s", pInputSlot->pXlation);
DBGPRINT(":\n");
DBGPRINT(" Invocation: %s\n", SAFESTR(pInputSlot->pInvocation));
DBGPRINT(" Require PageRegion: %s\n", BOOLSTR(pInputSlot->bReqPageRgn));
return TRUE;
}
// Dump a resolution option
BOOL
DumpResOption(
PRESOPTION pResOption,
DWORD dwParam
)
{
DBGPRINT("%s", pResOption->pName);
if (pResOption->pXlation)
DBGPRINT(" / %s", pResOption->pXlation);
DBGPRINT(":\n");
DBGPRINT(" PS code: %s\n", SAFESTR(pResOption->pInvocation));
DBGPRINT(" JCL code: %s\n", SAFESTR(pResOption->pJclCode));
DBGPRINT(" SetResolution code: %s\n", SAFESTR(pResOption->pSetResCode));
DBGPRINT(" Screen angle: ");
DumpPsReal(pResOption->screenAngle);
DBGPRINT("\n");
DBGPRINT(" Screen freq: ");
DumpPsReal(pResOption->screenFreq);
DBGPRINT("\n");
return TRUE;
}
// Dump a VM option
BOOL
DumpVmOption(
PVMOPTION pVmOption,
DWORD dwParam
)
{
DBGPRINT("%s", pVmOption->pName);
if (pVmOption->pXlation)
DBGPRINT(" / %s", pVmOption->pXlation);
DBGPRINT(":\n");
DBGPRINT(" Invocation: %s\n", SAFESTR(pVmOption->pInvocation));
DBGPRINT(" FreeVM: %d\n", pVmOption->dwFreeVm);
return TRUE;
}
// Dump a UI group
BOOL
DumpUiGroup(
PUIGROUP pUiGroup,
DWORD dwParam
)
{
LISTENUMPROC pProc;
DBGPRINT("*%s", pUiGroup->pName);
if (pUiGroup->pXlation)
DBGPRINT(" / %s", pUiGroup->pXlation);
DBGPRINT("\n");
DBGPRINT(" Default: %s\n", SAFESTR((PSTR) pUiGroup->dwDefault));
DBGPRINT(" Type: %d\n", pUiGroup->wType);
DBGPRINT(" Installable: %s\n", BOOLSTR(pUiGroup->bInstallable));
switch (pUiGroup->uigrpIndex) {
case UIGRP_PAGESIZE:
pProc = (LISTENUMPROC) DumpMediaOption;
break;
case UIGRP_INPUTSLOT:
pProc = (LISTENUMPROC) DumpInputSlot;
break;
case UIGRP_RESOLUTION:
pProc = (LISTENUMPROC) DumpResOption;
break;
case UIGRP_VMOPTION:
pProc = (LISTENUMPROC) DumpVmOption;
break;
default:
pProc = (LISTENUMPROC) DumpUiOption;
break;
}
LISTOBJ_Enum((PLISTOBJ) pUiGroup->pUiOptions, pProc, dwParam);
DBGPRINT("\n");
return TRUE;
}
// Dump an order dependency entry
BOOL
DumpOrderDep(
PORDERDEP pOrderDep,
DWORD dwParam
)
{
DBGPRINT("*%s", pOrderDep->pKeyword);
if (pOrderDep->pOption)
DBGPRINT(" %s", pOrderDep->pOption);
DBGPRINT(": ");
DumpPsReal(pOrderDep->order);
DBGPRINT("%d\n", pOrderDep->wSection);
return TRUE;
}
// Dump a UI constraint entry
BOOL
DumpUiConstraint(
PUICONSTRAINT pUiConstraint,
DWORD dwParam
)
{
DBGPRINT("*%s", pUiConstraint->pKeyword1);
if (pUiConstraint->pOption1)
DBGPRINT(" %s", pUiConstraint->pOption1);
DBGPRINT(" - ");
DBGPRINT("*%s", pUiConstraint->pKeyword2);
if (pUiConstraint->pOption2)
DBGPRINT(" %s", pUiConstraint->pOption2);
DBGPRINT("\n");
return TRUE;
}
// Dump PPDOBJ contents
VOID
PPDOBJ_Dump(
PPPDOBJ pPpdObj
)
{
DBGPRINT("PPD file contents for: %s\n", SAFESTR(pPpdObj->pNickName));
DBGPRINT("Color device: %s\n", BOOLSTR(pPpdObj->bColorDevice));
DBGPRINT("Protocols: %02x\n", pPpdObj->wProtocols);
DBGPRINT("Landscape orientation: %d\n", pPpdObj->wLsOrientation);
DBGPRINT("TrueType rasterizer: %d\n", pPpdObj->wTTRasterizer);
DBGPRINT("Language encoding: %d\n", pPpdObj->wLangEncoding);
DBGPRINT("Free VM: %d\n", pPpdObj->dwFreeVm);
DBGPRINT("Language level: %d\n", pPpdObj->dwLangLevel);
DBGPRINT("Password: %s\n", SAFESTR(pPpdObj->pPassword));
DBGPRINT("Exit server code: %s\n", SAFESTR(pPpdObj->pExitServer));
DBGPRINT("Job timeout: %d\n", pPpdObj->dwJobTimeout);
DBGPRINT("Wait timeout: %d\n", pPpdObj->dwWaitTimeout);
DBGPRINT("Print PS errors: %s\n", BOOLSTR(pPpdObj->bPrintPsErrors));
DBGPRINT("\nDEVICE FONTS:\n\n");
LISTOBJ_Enum((PLISTOBJ) pPpdObj->pFontList, (LISTENUMPROC) DumpFont, 0);
DBGPRINT("\nOpenUI/CloseUI GROUPS:\n\n");
LISTOBJ_Enum((PLISTOBJ) pPpdObj->pUiGroups, (LISTENUMPROC) DumpUiGroup, 0);
DBGPRINT("\n");
DBGPRINT("Support custom page size: %s\n",
BOOLSTR(pPpdObj->bCustomPageSize));
if (pPpdObj->bCustomPageSize) {
INT index;
DBGPRINT("Cut-sheet device: %s\n", BOOLSTR(pPpdObj->bCutSheet));
DBGPRINT("Hardware margins: ");
DumpPsRect(& pPpdObj->hwMargins);
DBGPRINT("\n");
DBGPRINT("Custom page size code: %s\n",
SAFESTR(pPpdObj->pCustomSizeCode));
DBGPRINT("Custom page size parameters:\n");
for (index=0; index<MAXPCP; index++) {
DBGPRINT(" order = %d type = %d min = ",
pPpdObj->customParam[index].dwOrder,
pPpdObj->customParam[index].wType);
DumpPsReal(pPpdObj->customParam[index].minVal);
DBGPRINT("max = ");
DumpPsReal(pPpdObj->customParam[index].maxVal);
DBGPRINT("\n");
}
DBGPRINT("Max media size (width x height): ");
DumpPsReal(pPpdObj->maxMediaWidth);
DumpPsReal(pPpdObj->maxMediaHeight);
DBGPRINT("\n");
}
DBGPRINT("Resolution type: %d\n", pPpdObj->wResType);
DBGPRINT("Default screen angle: ");
DumpPsReal(pPpdObj->screenAngle);
DBGPRINT("\n");
DBGPRINT("Default screen freq: ");
DumpPsReal(pPpdObj->screenFreq);
DBGPRINT("\n");
DBGPRINT("JCL prefix: %s\n", SAFESTR(pPpdObj->pJclBegin));
DBGPRINT("JCL postfix: %s\n", SAFESTR(pPpdObj->pJclEnd));
DBGPRINT("JCL to PS: %s\n", SAFESTR(pPpdObj->pJclToPs));
DBGPRINT("\nORDER DEPENDENCIES:\n\n");
LISTOBJ_Enum((PLISTOBJ) pPpdObj->pOrderDep, (LISTENUMPROC) DumpOrderDep, 0);
DBGPRINT("\nUI CONSTRAINTS:\n\n");
LISTOBJ_Enum(
(PLISTOBJ) pPpdObj->pUiConstraints,
(LISTENUMPROC) DumpUiConstraint,
0);
DBGPRINT("\n");
}
#endif // DBG