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.
 
 
 
 
 
 

2550 lines
59 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
ppdproc.c
Abstract:
PS driver PPD parser - implementation of PPD entry handlers
[Notes:]
This file is not included into ppdkwd.c.
Revision History:
4/27/95 -davidx-
Created it.
dd-mm-yy -author-
description
--*/
BOOL
EqualWordString(
PCSTR pRef,
PCSTR pStr
)
/*++
Routine Description:
Check if a character string is equal to a reference string.
Arguments:
pRef - pointer to the reference string
pStr - pointer to the input string
Return Value:
TRUE - if the strings are equal
FALSE - if they are not
[Note:]
The input string doesn't have to match the reference
string exactly. It can contain the reference string
as a prefix and then followed by a space character.
--*/
{
while (*pRef && *pRef == *pStr) {
pRef++;
pStr++;
}
return (*pRef == '\0' && (*pStr == '\0' || IsSpace(*pStr)));
}
BOOL
SearchStringTable(
struct STRTABLE * pTable,
PCSTR pKeyword,
WORD * pReturn
)
/*++
Routine Description:
Search for a keyword in a table and map it to an index.
Arguments:
pTable - pointer to a table of keyword entries
pKeyword - pointer to a keyword string
pReturn - pointer to a variable for returning keyword index
Return Value:
TRUE - keyword was found in the table, its corresponding
index is returned in the variable pointed to by pReturn
FALSE - keyword was not found
[Note:]
Each entry of the keyword table has two fields. The first
field is a keyword string and the second field is the index
corresponding to that string.
The last entry of the table must contain NULL as the keyword
string.
--*/
{
while (pTable->pKeyword != NULL &&
! EqualWordString(pTable->pKeyword, pKeyword))
{
pTable++;
}
*pReturn = pTable->wValue;
return (pTable->pKeyword != NULL);
}
PPDERROR
GetBooleanValue(
BOOL * pBool,
PCSTR pStr
)
/*++
Routine Description:
Convert a character string to a boolean value.
Arguments:
pBool - pointer to a boolean variable for return value
pStr - pointer to a character string
Return Value:
PPDERR_NONE - conversion was successful
PPDERR_SYNTAX - syntax error
--*/
{
static struct STRTABLE boolStrs[] = {
{ "True", TRUE },
{ "False", FALSE },
{ NULL, FALSE }
};
WORD wBool;
if (! SearchStringTable(boolStrs, pStr, &wBool)) {
DBGMSG1(DBG_LEVEL_ERROR,
"Invalid boolean constant: '%s'\n",
pStr);
*pBool = FALSE;
return PPDERR_SYNTAX;
}
*pBool = (BOOL) wBool;
return PPDERR_NONE;
}
PPDERROR
GetIntegerValue(
DWORD * pValue,
PCSTR pStr
)
/*++
Routine Description:
Convert a character string to an integer value.
Arguments:
pValue - pointer to a DWORD variable for return value
pStr - pointer to a character string
Return Value:
PPDERR_NONE - conversion was successful
PPDERR_SYNTAX - syntax error
[Note:]
This function can only handle non-negative numbers.
All negative numbers are clamped to 0.
--*/
{
DWORD dwValue = 0;
INT cDigits = 0;
BOOL bNegative = FALSE;
// Guard against negative numbers
if (*pStr == '-') {
DBGMSG(DBG_LEVEL_WARNING,
"All negative numbers are forced to 0!\n");
pStr++;
bNegative = TRUE;
}
// Scan until a non-digit character is seen
while (IsDigit(*pStr)) {
ASSERT(dwValue <= (MAXDWORD - (DWORD) (*pStr - '0'))/10);
dwValue = dwValue*10 + (*pStr++ - '0');
cDigits++;
}
// The number must have at least one digit
if (cDigits == 0) {
DBGMSG(DBG_LEVEL_ERROR, "Invalid integer number.\n");
return PPDERR_SYNTAX;
} else {
*pValue = bNegative ? 0 : dwValue;
return PPDERR_NONE;
}
}
PPDERROR
GetRealValue(
PSREAL *pValue,
PCSTR pStr
)
/*++
Routine Description:
Convert a character string to a real value
Arguments:
pValue - pointer to a PSREAL variable for return value
pStr - pointer to a character string
Return Value:
PPDERR_NONE - the character represents a valid real value
PPDERR_SYNTAX - syntax error
[Note:]
This function can only handle non-negative numbers.
All negative numbers are clamped to 0.
--*/
{
DWORD dwInteger, dwFraction;
BOOL bNegative = FALSE;
INT cDigits = 0;
// Guard against negative numbers
if (*pStr == '-') {
DBGMSG(DBG_LEVEL_WARNING,
"All negative numbers are forced to 0!\n");
pStr++;
bNegative = TRUE;
}
// Scan the integer portion
dwInteger = dwFraction = 0;
while (IsDigit(*pStr)) {
dwInteger = dwInteger * 10 + (*pStr++ - '0');
cDigits++;
}
// Scan the fractional portion (if any)
if (*pStr == DECIMAL_CHAR) {
DWORD dwScale = 1;
// Skip the decimal point
pStr++;
// Only the first 5 fractional digits are significant
while (IsDigit(*pStr)) {
if (dwScale < MAXFRACSCALE) {
dwScale *= 10;
dwFraction = dwFraction*10 + (*pStr - '0');
}
pStr++;
cDigits++;
}
// Convert the fractional number to a fixed-point number
dwFraction = ((dwFraction << PSREALBITS) + dwScale/2) / dwScale;
}
// The number must have at least one digit
if (cDigits == 0) {
DBGMSG(DBG_LEVEL_ERROR, "Invalid real number.\n");
return PPDERR_SYNTAX;
} else {
*pValue = bNegative ? 0 : ((dwInteger << PSREALBITS) + dwFraction);
return PPDERR_NONE;
}
}
PPDERROR
GetStringValue(
PSTR * ppValue,
PBUFOBJ pBufObj,
PHEAPOBJ pHeap,
PPDVALUE valueType
)
/*++
Routine Description:
Copy string from a buffer object to a character buffer.
Convert embedded hex string if valueType is QUOTED_VALUE.
Arguments:
ppValue - pointer to a PSTR variable.
pStr - pointer to a buffer object
pHeap - pointer to a heap object from which to allocate memory
valueType - whether to convert embedded hex string
(yes if it's QUOTED_VALUE)
Return Value:
PPDERR_NONE - string value was successfully copied
PPDERR_xxx - an error occured
[Note:]
On entry, *ppValue variable contains either a NULL or
a pointer to an existing character string. If it's not
NULL, we simply return without copying anything. If it's
a NULL, a new buffer is allocated and a string is copied
from the buffer object. On return, *ppValue contains
a pointer to this newly allocated buffer.
--*/
{
PSTR pStr;
PPDERROR err;
// Avoid overwriting existing character string
if (*ppValue != NULL) {
DBGMSG(DBG_LEVEL_WARNING, "Duplicate values for an option keyword!\n");
return PPDERR_NONE;
}
// Allocate space to hold the new character string
pStr = (PSTR) HEAPOBJ_Alloc(pHeap, BUFOBJ_Length(pBufObj)+1);
if (pStr == NULL)
err = PPDERR_MEM;
else if (valueType == QUOTED_VALUE) {
// Convert embedded hex string during copying
err = BUFOBJ_CopyStringHex(pBufObj, pStr);
} else {
// Direct memory copy with no extra processing
strcpy(pStr, BUFOBJ_Buffer(pBufObj));
err = PPDERR_NONE;
}
if (err == PPDERR_NONE)
*ppValue = pStr;
return err;
}
WORD
GetWordStr(
PSTR * ppStr,
WORD wMaxLen,
PSTR pWordStr
)
/*++
Routine Description:
Extract the first word from a character string.
Arguments:
ppStr - points to a pointer to source string
wMaxLen - maximum word length
pWordStr - points to a buffer for storing the word
Return Value:
number of characters in the word
[Note:]
Upon returning, the pointer to the source string is updated
to point to the first character after the word.
The word is separated by white spaces.
--*/
{
PSTR pStr = *ppStr;
WORD wLen = 0;
ASSERT(wMaxLen > 0);
wMaxLen --;
// skip leading spaces
while (*pStr && IsSpace(*pStr))
pStr++;
// copy characters until trailing space
// truncate the extra characters if the word is too long
while (*pStr && !IsSpace(*pStr)) {
if (wLen < wMaxLen)
pWordStr[wLen++] = *pStr;
pStr++;
}
// null-terminate the word string and
// update the return pointer
*ppStr = pStr;
pWordStr[wLen] = '\0';
return wLen;
}
PUIGROUP
UIGROUP_Create(
PPPDOBJ pPpdObj,
PUIGROUPINFO pUiGroupInfo
)
{
PUIGROUP pUiGroup;
// Allocate memory space
pUiGroup = (PUIGROUP) HEAPOBJ_Alloc(pPpdObj->pHeap, sizeof(UIGROUP));
if (pUiGroup != NULL) {
// Initialize the object
memset(pUiGroup, 0, sizeof(UIGROUP));
pUiGroup->uigrpIndex = pUiGroupInfo->uigrpIndex;
if (pUiGroup->uigrpIndex < MAXUIGRP) {
pPpdObj->pPredefinedUiGroups[pUiGroup->uigrpIndex] = pUiGroup;
pUiGroup->bInstallable =
(pUiGroup->uigrpIndex == UIGRP_VMOPTION) ? TRUE : FALSE;
} else
pUiGroup->bInstallable = pPpdObj->bInstallable;
pUiGroup->wType = pUiGroupInfo->wType;
pUiGroup->dwObjectSize = pUiGroupInfo->dwObjectSize;
pUiGroup->pName = (PSTR)
HEAPOBJ_Alloc(pPpdObj->pHeap, strlen(pUiGroupInfo->pKeyword) + 1);
if (pUiGroup->pName == NULL) {
pUiGroup = NULL;
} else {
// Copy keyword corresponding to the UI group
strcpy(pUiGroup->pName, pUiGroupInfo->pKeyword);
}
}
return pUiGroup;
}
PUIOPTION
UIOPTION_Create(
PHEAPOBJ pHeap,
PBUFOBJ pOption,
PBUFOBJ pXlation,
DWORD dwObjectSize
)
{
PUIOPTION pUiOption;
// Allocate memory space
pUiOption = (PUIOPTION) HEAPOBJ_Alloc(pHeap, dwObjectSize);
if (pUiOption != NULL) {
// Initialize the object
memset(pUiOption, 0, dwObjectSize);
// Copy the option string
if (GetStringValue(
& pUiOption->pName,
pOption,
pHeap,
STRING_VALUE) != PPDERR_NONE)
{
pUiOption = NULL;
} else {
// Copy the translation string
if (! BUFOBJ_IsEmpty(pXlation) &&
GetStringValue(
& pUiOption->pXlation,
pXlation,
pHeap,
QUOTED_VALUE) != PPDERR_NONE)
{
pUiOption = NULL;
}
}
}
return pUiOption;
}
PPDERROR
CreateUiGroup(
PPPDOBJ pPpdObj,
WORD urgrpIndex,
PCSTR pKeyword,
PUIGROUP *ppUiGroup
)
{
PUIGROUP pUiGroup;
UIGROUPINFO uiGroupInfo;
// Get information about the UI group is predefined
GetUiGroupInfo(&uiGroupInfo, urgrpIndex, pKeyword);
// Check if the UI group has been created already.
pUiGroup = (PUIGROUP)
LISTOBJ_Find((PLISTOBJ) pPpdObj->pUiGroups, uiGroupInfo.pKeyword);
if (pUiGroup == NULL) {
// The UI group didn't exist. Create it.
pUiGroup = UIGROUP_Create(pPpdObj, &uiGroupInfo);
if (pUiGroup == NULL)
return PPDERR_MEM;
// Add the new UI group object to the linked list.
LISTOBJ_Add((PLISTOBJ*) &pPpdObj->pUiGroups, (PLISTOBJ) pUiGroup);
}
// Return the newly created or found UI group object
*ppUiGroup = pUiGroup;
return PPDERR_NONE;
}
PPDERROR
CreateUiOption(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj,
WORD uigrpIndex,
PUIOPTION *ppUiOption
)
{
PUIGROUP pUiGroup;
PUIOPTION pUiOption;
PPDERROR err;
// Create or find the UI group object
err = CreateUiGroup(
pPpdObj, uigrpIndex,
BUFOBJ_Buffer(& pParserObj->keyword), & pUiGroup);
if (err == PPDERR_NONE) {
// Check if the UI option has been created already.
pUiOption = (PUIOPTION)
LISTOBJ_Find(
(PLISTOBJ) pUiGroup->pUiOptions,
BUFOBJ_Buffer(& pParserObj->option));
if (pUiOption == NULL) {
// Create the UI option object if necessary
pUiOption = UIOPTION_Create(
pPpdObj->pHeap,
& pParserObj->option,
& pParserObj->xlation,
pUiGroup->dwObjectSize);
if (pUiOption == NULL)
err = PPDERR_MEM;
else {
// Add the UI option to the linked list
LISTOBJ_Add(
(PLISTOBJ*) &pUiGroup->pUiOptions, (PLISTOBJ) pUiOption);
// Return the newly created UI option object
*ppUiOption = pUiOption;
}
} else {
// Copy the translation string
if (! BUFOBJ_IsEmpty(&pParserObj->xlation) &&
pUiOption->pXlation == NULL)
{
err = GetStringValue(
&pUiOption->pXlation, &pParserObj->xlation,
pPpdObj->pHeap, QUOTED_VALUE);
}
// Return the existing UI option object
if (err == PPDERR_NONE)
*ppUiOption = pUiOption;
}
}
return err;
}
PPDERROR
CommonUiOptionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PUIOPTION pUiOption;
PPDERROR err;
PPDVALUE valueType;
// Find the specified UI option from the existing
// list or add it as a new UI option
err = CreateUiOption(pPpdObj, pParserObj, UIGRP_UNKNOWN, &pUiOption);
if (err != PPDERR_NONE)
return err;
// Store the invocation string for the UI option.
// If we're inside of JCLOpenUI/JCLCloseUI pair, then
// treat the invocation as QuotedValue.
if (pPpdObj->pOpenUi && (pPpdObj->pOpenUi->uigrpFlags & UIGF_JCLGROUP))
valueType = QUOTED_VALUE;
else
valueType = INVOCATION_VALUE;
return GetStringValue(
&pUiOption->pInvocation, &pParserObj->value,
pPpdObj->pHeap, valueType);
}
PPDERROR
CommonUiDefaultProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PUIGROUP pUiGroup;
PCSTR pKeyword;
PPDERROR err;
// Find or create the UI group
pKeyword = BUFOBJ_Buffer(& pParserObj->keyword);
err = CreateUiGroup(
pPpdObj, UIGRP_UNKNOWN,
pKeyword + strlen(defaultPrefixStr), &pUiGroup);
if (err == PPDERR_NONE) {
// Save the default UI option
ASSERT(sizeof(DWORD) == sizeof(PVOID));
err = GetStringValue(
(PSTR *) & pUiGroup->dwDefault,
& pParserObj->value,
pPpdObj->pHeap,
STRING_VALUE);
}
return err;
}
///////////////////////////////////////////////////////////////////////////////
PPDERROR
NullProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return PPDERR_NONE;
}
PPDERROR
IncludeProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
// Convert the filename from a QuotedValue to a string
// Expand the filename to fully qualified path
// Parse the included file
DBGMSG(DBG_LEVEL_WARNING, "*Include keyword not yet supported.\n");
return PPDERR_NONE;
}
PPDERROR
ColorDeviceProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
GetBooleanValue(
& pPpdObj->bColorDevice,
BUFOBJ_Buffer(& pParserObj->value));
return PPDERR_NONE;
}
PPDERROR
ProtocolsProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE protocolStrs[] = {
{ "PJL", PROTOCOL_PJL },
{ "BCP", PROTOCOL_BCP },
{ "TBCP", PROTOCOL_TBCP },
{ "SIC", PROTOCOL_SIC },
{ NULL, 0 }
};
PSTR pStr;
WORD wProtocol;
char wordStr[MaxKeywordLen];
pStr = BUFOBJ_Buffer(& pParserObj->value);
while (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) {
// Interpret protocol option
SearchStringTable(protocolStrs, wordStr, &wProtocol);
if (wProtocol != 0)
pPpdObj->wProtocols |= wProtocol;
else {
DBGMSG1(DBG_LEVEL_WARNING, "Unknown protocol: %s\n", wordStr);
}
}
return PPDERR_NONE;
}
PPDERROR
NickNameProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(
& pPpdObj->pNickName,
& pParserObj->value,
pPpdObj->pHeap,
QUOTED_VALUE);
}
PPDERROR
LanguageLevelProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetIntegerValue(
& pPpdObj->dwLangLevel,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
LanguageEncodingProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE langEncodingStrs[] = {
{ "ISOLatin1", LANGENC_ISOLATIN1 },
{ "JIS83-RKSJ", LANGENC_JIS83RKSJ },
{ "MaxStandard", LANGENC_MACSTANDARD },
{ "WindowsANSI", LANGENC_WINDOWSANSI },
{ "None", LANGENC_NONE },
{ NULL, MAXLANGENC }
};
WORD wLangEncoding;
if (! SearchStringTable(
langEncodingStrs,
BUFOBJ_Buffer(& pParserObj->value),
&wLangEncoding))
{
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown language encoding: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
} else
pPpdObj->wLangEncoding = wLangEncoding;
return PPDERR_NONE;
}
PPDERROR
LanguageVersionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE langVersionStrs[] = {
{ "English", LANGENC_ISOLATIN1 },
{ "Danish", LANGENC_ISOLATIN1 },
{ "Dutch", LANGENC_ISOLATIN1 },
{ "Finnish", LANGENC_ISOLATIN1 },
{ "French", LANGENC_ISOLATIN1 },
{ "German", LANGENC_ISOLATIN1 },
{ "Italian", LANGENC_ISOLATIN1 },
{ "Norwegian", LANGENC_ISOLATIN1 },
{ "Portuguese", LANGENC_ISOLATIN1 },
{ "Spanish", LANGENC_ISOLATIN1 },
{ "Swedish", LANGENC_ISOLATIN1 },
{ "Chinese", LANGENC_NONE },
{ "Japanese", LANGENC_JIS83RKSJ },
{ "Russian", LANGENC_NONE },
{ NULL, MAXLANGENC }
};
WORD wLangEncoding;
if (pPpdObj->wLangEncoding == LANGENC_NONE) {
if (! SearchStringTable(
langVersionStrs,
BUFOBJ_Buffer(& pParserObj->value),
&wLangEncoding))
{
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown language version: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
} else
pPpdObj->wLangEncoding = wLangEncoding;
}
return PPDERR_NONE;
}
PPDERROR
TTRasterizerProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE ttRasterizerStrs[] = {
{ "None", TTRAS_NONE },
{ "Accept68k", TTRAS_ACCEPT68K },
{ "Type42", TTRAS_TYPE42 },
{ "TrueImage", TTRAS_TRUEIMAGE },
{ NULL, MAXTTRAS }
};
WORD wTTRasterizer;
// Interpret TrueType rasterizer option
if (! SearchStringTable(
ttRasterizerStrs,
BUFOBJ_Buffer(& pParserObj->value),
&wTTRasterizer))
{
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown TrueType rasterizer: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
} else
pPpdObj->wTTRasterizer = wTTRasterizer;
return PPDERR_NONE;
}
PPDERROR
ExitServerProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(& pPpdObj->pExitServer,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
PPDERROR
PasswordProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(& pPpdObj->pPassword,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
PPDERROR
JobTimeoutProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetIntegerValue(
& pPpdObj->dwJobTimeout,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
WaitTimeoutProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetIntegerValue(
& pPpdObj->dwWaitTimeout,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
PrintPsErrorProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
GetBooleanValue(
& pPpdObj->bPrintPsErrors,
BUFOBJ_Buffer(& pParserObj->value));
return PPDERR_NONE;
}
PPDERROR
JclBeginProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(& pPpdObj->pJclBegin,
& pParserObj->value,
pPpdObj->pHeap,
QUOTED_VALUE);
}
PPDERROR
JclEndProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(& pPpdObj->pJclEnd,
& pParserObj->value,
pPpdObj->pHeap,
QUOTED_VALUE);
}
PPDERROR
JclToPsProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetStringValue(& pPpdObj->pJclToPs,
& pParserObj->value,
pPpdObj->pHeap,
QUOTED_VALUE);
}
PPDERROR
LsOrientationProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE lsoStrs[] = {
{ "Any", LSO_ANY },
{ "Plus90", LSO_PLUS90 },
{ "Minus90", LSO_MINUS90 },
{ NULL, MAXLSO },
};
WORD wLso;
SearchStringTable(lsoStrs, BUFOBJ_Buffer(& pParserObj->value), &wLso);
if (wLso < MAXLSO)
pPpdObj->wLsOrientation = wLso;
else {
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown landscape orientation: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
}
return PPDERR_NONE;
}
VOID
GetFontIndex(
WORD * pwIndex,
PCSTR pFontName
)
{
static struct STRTABLE fontNameStrs[] = {
{ "Arial", ARIAL },
{ "Arial-Bold", ARIAL_BOLD },
{ "Arial-BoldOblique", ARIAL_BOLDOBLIQUE },
{ "Arial-Oblique", ARIAL_OBLIQUE },
{ "Arial-Narrow", ARIAL_NARROW },
{ "Arial-Narrow-Bold", ARIAL_NARROW_BOLD },
{ "Arial-Narrow-BoldOblique", ARIAL_NARROW_BOLDOBLIQUE },
{ "Arial-Narrow-Oblique", ARIAL_NARROW_OBLIQUE },
{ "AvantGarde-Book", AVANTGARDE_BOOK },
{ "AvantGarde-BookOblique", AVANTGARDE_BOOKOBLIQUE },
{ "AvantGarde-Demi", AVANTGARDE_DEMI },
{ "AvantGarde-DemiOblique", AVANTGARDE_DEMIOBLIQUE },
{ "Bookman-Demi", BOOKMAN_DEMI },
{ "Bookman-DemiItalic", BOOKMAN_DEMIITALIC },
{ "Bookman-Light", BOOKMAN_LIGHT },
{ "Bookman-LightItalic", BOOKMAN_LIGHTITALIC },
{ "Courier", COURIER },
{ "Courier-Bold", COURIER_BOLD },
{ "Courier-BoldOblique", COURIER_BOLDOBLIQUE },
{ "Courier-Oblique", COURIER_OBLIQUE },
{ "Garamond-Bold", GARAMOND_BOLD },
{ "Garamond-BoldItalic", GARAMOND_BOLDITALIC },
{ "Garamond-Light", GARAMOND_LIGHT },
{ "Garamond-LightItalic", GARAMOND_LIGHTITALIC },
{ "Helvetica", HELVETICA },
{ "Helvetica-Black", HELVETICA_BLACK },
{ "Helvetica-BlackOblique", HELVETICA_BLACKOBLIQUE },
{ "Helvetica-Bold", HELVETICA_BOLD },
{ "Helvetica-BoldOblique", HELVETICA_BOLDOBLIQUE },
{ "Helvetica-Condensed", HELVETICA_CONDENSED },
{ "Helvetica-Condensed-Bold", HELVETICA_CONDENSED_BOLD },
{ "Helvetica-Condensed-BoldObl", HELVETICA_CONDENSED_BOLDOBL },
{ "Helvetica-Condensed-Oblique", HELVETICA_CONDENSED_OBLIQUE },
{ "Helvetica-Light", HELVETICA_LIGHT },
{ "Helvetica-LightOblique", HELVETICA_LIGHTOBLIQUE },
{ "Helvetica-Narrow", HELVETICA_NARROW },
{ "Helvetica-Narrow-Bold", HELVETICA_NARROW_BOLD },
{ "Helvetica-Narrow-BoldOblique", HELVETICA_NARROW_BOLDOBLIQUE },
{ "Helvetica-Narrow-Oblique", HELVETICA_NARROW_OBLIQUE },
{ "Helvetica-Oblique", HELVETICA_OBLIQUE },
{ "Korinna-Bold", KORINNA_BOLD },
{ "Korinna-KursivBold", KORINNA_KURSIVBOLD },
{ "Korinna-KursivRegular", KORINNA_KURSIVREGULAR },
{ "Korinna-Regular", KORINNA_REGULAR },
{ "LubalinGraph-Book", LUBALINGRAPH_BOOK },
{ "LubalinGraph-BookOblique", LUBALINGRAPH_BOOKOBLIQUE },
{ "LubalinGraph-Demi", LUBALINGRAPH_DEMI },
{ "LubalinGraph-DemiOblique", LUBALINGRAPH_DEMIOBLIQUE },
{ "NewCenturySchlbk-Bold", NEWCENTURYSCHLBK_BOLD },
{ "NewCenturySchlbk-BoldItalic", NEWCENTURYSCHLBK_BOLDITALIC },
{ "NewCenturySchlbk-Italic", NEWCENTURYSCHLBK_ITALIC },
{ "NewCenturySchlbk-Roman", NEWCENTURYSCHLBK_ROMAN },
{ "Palatino-Bold", PALATINO_BOLD },
{ "Palatino-BoldItalic", PALATINO_BOLDITALIC },
{ "Palatino-Italic", PALATINO_ITALIC },
{ "Palatino-Roman", PALATINO_ROMAN },
{ "Souvenir-Demi", SOUVENIR_DEMI },
{ "Souvenir-DemiItalic", SOUVENIR_DEMIITALIC },
{ "Souvenir-Light", SOUVENIR_LIGHT },
{ "Souvenir-LightItalic", SOUVENIR_LIGHTITALIC },
{ "Symbol", SYMBOL },
{ "Times-Bold", TIMES_BOLD },
{ "Times-BoldItalic", TIMES_BOLDITALIC },
{ "Times-Italic", TIMES_ITALIC },
{ "Times-Roman", TIMES_ROMAN },
{ "Times-New-Roman", TIMES_NEW_ROMAN },
{ "Times-New-Roman-Bold", TIMES_NEW_ROMAN_BOLD },
{ "Times-New-Roman-BoldItalic", TIMES_NEW_ROMAN_BOLDITALIC },
{ "Times-New-Roman-Italic", TIMES_NEW_ROMAN_ITALIC },
{ "Varitimes#Bold", VARITIMES_BOLD },
{ "Varitimes#BoldItalic", VARITIMES_BOLDITALIC },
{ "Varitimes#Italic", VARITIMES_ITALIC },
{ "Varitimes#Roman", VARITIMES_ROMAN },
{ "ZapfCalligraphic-Bold", ZAPFCALLIGRAPHIC_BOLD },
{ "ZapfCalligraphic-BoldItalic", ZAPFCALLIGRAPHIC_BOLDITALIC },
{ "ZapfCalligraphic-Italic", ZAPFCALLIGRAPHIC_ITALIC },
{ "ZapfCalligraphic-Roman", ZAPFCALLIGRAPHIC_ROMAN },
{ "ZapfChancery-MediumItalic", ZAPFCHANCERY_MEDIUMITALIC },
{ "ZapfDingbats", ZAPFDINGBATS },
{ NULL, 0 }
};
SearchStringTable(fontNameStrs, pFontName, pwIndex);
}
VOID
GetFontEncoding(
WORD * pwEncoding,
PCSTR pStr
)
{
static struct STRTABLE encodingStrs[] = {
{ "Standard", FONTENC_STANDARD },
{ "Special", FONTENC_SPECIAL },
{ "ISOLatin1", FONTENC_ISOLATIN1 },
{ "Expert", FONTENC_EXPERT },
{ "ExpertSubset", FONTENC_EXPERTSUBSET },
{ "JIS", FONTENC_JIS },
{ "RKSJ", FONTENC_RKSJ },
{ "EUC", FONTENC_EUC },
{ "Shift-JIS", FONTENC_SHIFTJIS },
{ NULL, MAXFONTENC }
};
SearchStringTable(encodingStrs, pStr, pwEncoding);
if (*pwEncoding == MAXFONTENC) {
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown font encoding option: %s\n",
pStr);
}
}
VOID
GetCharSet(
WORD * pwCharSet,
PCSTR pStr
)
{
static struct STRTABLE charsetStrs[] = {
{ "Standard", CHARSET_STANDARD },
{ "OldStandard", CHARSET_OLDSTANDARD },
{ "Special", CHARSET_SPECIAL },
{ "ISOLatin1", CHARSET_ISOLATIN1 },
{ "Expert", CHARSET_EXPERT },
{ "ExpertSubset", CHARSET_EXPERTSUBSET },
{ "JIS-83", CHARSET_JIS83 },
{ "JIS-78", CHARSET_JIS78 },
{ "83pv", CHARSET_83PV },
{ "Add", CHARSET_ADD },
{ "Ext", CHARSET_EXT },
{ "NWP", CHARSET_NWP },
{ NULL, MAXCHARSET }
};
SearchStringTable(charsetStrs, pStr, pwCharSet);
if (*pwCharSet == MAXCHARSET) {
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown character set option: %s\n",
pStr);
}
}
PPDERROR
FontProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PSTR pStr, pFontName;
WORD wIndex, wEncoding, wCharSet;
char wordStr[MaxKeywordLen];
INT count;
PDEVFONT pFontObj;
PPDERROR err;
pFontName = BUFOBJ_Buffer(& pParserObj->option);
pStr = BUFOBJ_Buffer(& pParserObj->value);
wEncoding = FONTENC_STANDARD;
wCharSet = CHARSET_STANDARD;
// We can only support those device fonts for which
// there is font metrics information.
GetFontIndex(&wIndex, pFontName);
if (wIndex == 0) {
DBGMSG1(DBG_LEVEL_VERBOSE,
"No font metrics for device font: %s\n",
pFontName);
return PPDERR_NONE;
}
// Interpret font encoding option
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) {
GetFontEncoding(& wEncoding, wordStr);
if (wEncoding < MAXFONTENC) {
// skip quoted version number
for (count=0; count<2; count++) {
while (*pStr && *pStr != QUOTE_CHAR)
pStr++;
if (*pStr == QUOTE_CHAR)
pStr++;
}
// Interpret character set option
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0)
GetCharSet(& wCharSet, wordStr);
}
}
// Make sure there is no duplicate font names
if (LISTOBJ_Find((PLISTOBJ) pPpdObj->pFontList, pFontName) != NULL) {
DBGMSG1(DBG_LEVEL_WARNING,
"Duplicate font definition: %s\n",
pFontName);
err = PPDERR_NONE;
} else {
// Instantiate a device font object
pFontObj = (PDEVFONT)
HEAPOBJ_Alloc(pPpdObj->pHeap, sizeof(DEVFONT));
if (pFontObj == NULL)
err = PPDERR_MEM;
else {
// Initialize the device font object
memset(pFontObj, 0, sizeof(DEVFONT));
pFontObj->wIndex = wIndex;
pFontObj->wEncoding = wEncoding;
pFontObj->wCharSet = wCharSet;
err = GetStringValue(
& pFontObj->pName,
& pParserObj->option,
pPpdObj->pHeap,
STRING_VALUE);
if (err == PPDERR_NONE) {
err = GetStringValue(
& pFontObj->pXlation,
& pParserObj->xlation,
pPpdObj->pHeap,
QUOTED_VALUE);
}
if (err == PPDERR_NONE) {
// Add the device font object to the linked list
LISTOBJ_Add(
(PLISTOBJ*) & pPpdObj->pFontList,
(PLISTOBJ) pFontObj);
}
}
}
return err;
}
PPDERROR
CustomPageSizeProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PPDERROR err;
BOOL bOption;
// Interpret the option keyword
err = GetBooleanValue(
& bOption,
BUFOBJ_Buffer(& pParserObj->option));
if (err == PPDERR_NONE) {
if (! bOption) {
DBGMSG(DBG_LEVEL_WARNING,
"*CustomPageSize False is meaningless.\n");
} else {
// Device supports custom page size
pPpdObj->bCustomPageSize = TRUE;
return GetStringValue(
& pPpdObj->pCustomSizeCode,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
}
// Ignore invalid boolean values instead of generating an error
return PPDERR_NONE;
}
PPDERROR
ParamCustomPageProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE customParamStrs[] = {
{ "Width", PCP_WIDTH },
{ "Height", PCP_HEIGHT },
{ "WidthOffset", PCP_WIDTHOFFSET },
{ "HeightOffset", PCP_HEIGHTOFFSET },
{ "Orientation", PCP_ORIENTATION },
{ NULL, MAXPCP }
};
static struct STRTABLE customTypeStrs[] = {
{ "int", PCPTYPE_INT },
{ "real", PCPTYPE_REAL },
{ "points", PCPTYPE_POINTS },
{ NULL, MAXPCPTYPE }
};
PPDERROR err;
char wordStr[MaxKeywordLen];
WORD wOption;
DWORD dwOrder;
WORD wType;
PSREAL minVal, maxVal;
PSTR pStr;
// Custom page size parameter option
if (! SearchStringTable(
customParamStrs,
BUFOBJ_Buffer(& pParserObj->option),
& wOption))
{
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown custom page size parameter: %s\n",
BUFOBJ_Buffer(& pParserObj->option));
return PPDERR_NONE;
}
// Custom page size parameter order
pStr = BUFOBJ_Buffer(&pParserObj->value);
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) == 0)
return PPDERR_SYNTAX;
err = GetIntegerValue(&dwOrder, wordStr);
if (err != PPDERR_NONE)
return err;
if (dwOrder < MIN_PARAMCUSTOMPAGESIZE_ORDER ||
dwOrder > MAX_PARAMCUSTOMPAGESIZE_ORDER)
{
DBGMSG(DBG_LEVEL_WARNING,
"Invalid value for *ParamCustomPageSize order.\n");
return PPDERR_SYNTAX;
}
// Custom page size parameter type
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) == 0)
return PPDERR_SYNTAX;
if (! SearchStringTable(customTypeStrs, wordStr, &wType))
return PPDERR_NONE;
// Custom page size parameter minimum value
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) == 0)
return PPDERR_SYNTAX;
err = GetRealValue(&minVal, wordStr);
if (err != PPDERR_NONE)
return err;
// Custom page size parameter maximum value
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) == 0)
return PPDERR_SYNTAX;
err = GetRealValue(&maxVal, wordStr);
if (err == PPDERR_NONE)
return err;
// Save custom page size parameters
pPpdObj->customParam[wOption].dwOrder = dwOrder;
pPpdObj->customParam[wOption].wType = wType;
pPpdObj->customParam[wOption].minVal = minVal;
pPpdObj->customParam[wOption].maxVal = maxVal;
return PPDERR_NONE;
}
PPDERROR
MaxMediaWidthProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetRealValue(
& pPpdObj->maxMediaWidth,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
MaxMediaHeightProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetRealValue(
& pPpdObj->maxMediaHeight,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
HwMarginsProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PPDERROR err;
PSTR pStr;
INT count;
PSREAL numbers[4];
char wordStr[MaxKeywordLen];
pStr = BUFOBJ_Buffer(& pParserObj->value);
err = PPDERR_NONE;
// Get four real numbers
for (count=0; count < 4 && err == PPDERR_NONE; count++) {
err = (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) ?
GetRealValue(&numbers[count], wordStr) :
PPDERR_SYNTAX;
}
// Save the numbers if there were no errors
if (err == PPDERR_NONE) {
pPpdObj->hwMargins.left = numbers[0];
pPpdObj->hwMargins.bottom = numbers[1];
pPpdObj->hwMargins.right = numbers[2];
pPpdObj->hwMargins.top = numbers[3];
// Only cut-sheet devices can have HWMargins entry
pPpdObj->bCutSheet = TRUE;
}
return err;
}
PPDERROR
PageSizeProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PMEDIAOPTION pMediaOption;
PPDERROR err;
// Find the specified media option from the existing
// list or add it as a new media option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_PAGESIZE,
(PUIOPTION*) &pMediaOption);
// Store the PageSize invocation string for the media option
if (err == PPDERR_NONE) {
err = GetStringValue(
& pMediaOption->pPageSizeCode,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
return err;
}
PPDERROR
PageRegionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PMEDIAOPTION pMediaOption;
PPDERROR err;
// Find the specified media option from the existing
// list or add it as a new media option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_PAGESIZE,
(PUIOPTION*) &pMediaOption);
// Store the PageRegion invocation string for the media option
if (err == PPDERR_NONE) {
err = GetStringValue(
& pMediaOption->pPageRgnCode,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
return err;
}
PPDERROR
ImageableAreaProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PMEDIAOPTION pMediaOption;
PPDERROR err;
PSTR pStr;
INT count;
PSREAL numbers[4];
char wordStr[MaxKeywordLen];
// Find the specified media option from the existing
// list or add it as a new media option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_PAGESIZE,
(PUIOPTION*) &pMediaOption);
pStr = BUFOBJ_Buffer(& pParserObj->value);
// Get four real numbers
for (count=0; count < 4 && err == PPDERR_NONE; count++) {
err = (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) ?
GetRealValue(&numbers[count], wordStr) :
PPDERR_SYNTAX;
}
// Save the numbers if there were no errors
if (err == PPDERR_NONE) {
pMediaOption->imageableArea.left = numbers[0] + ONE_POINT_PSREAL;
pMediaOption->imageableArea.bottom = numbers[1] + ONE_POINT_PSREAL;
pMediaOption->imageableArea.right = numbers[2];
pMediaOption->imageableArea.top = numbers[3];
}
return err;
}
PPDERROR
PaperDimensionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PMEDIAOPTION pMediaOption;
PPDERROR err;
PSTR pStr;
char wordStr[MaxKeywordLen];
// Find the specified media option from the existing
// list or add it as a new media option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_PAGESIZE,
(PUIOPTION*) &pMediaOption);
pStr = BUFOBJ_Buffer(& pParserObj->value);
// Get width and height
if (err == PPDERR_NONE) {
err = (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) ?
GetRealValue(&pMediaOption->dimension.width, wordStr) :
PPDERR_SYNTAX;
if (err == PPDERR_NONE) {
err = (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) ?
GetRealValue(&pMediaOption->dimension.height, wordStr) :
PPDERR_SYNTAX;
}
}
return err;
}
PPDERROR
InputSlotProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PINPUTSLOT pInputSlot;
PPDERROR err;
// Find the specified input slot from the existing
// list or add it as a new input slot
err = CreateUiOption(
pPpdObj, pParserObj, UIGRP_INPUTSLOT, (PUIOPTION*) &pInputSlot);
// Store the InputSlot invocation string
if (err == PPDERR_NONE) {
err = GetStringValue(
&pInputSlot->pInvocation, &pParserObj->value,
pPpdObj->pHeap, INVOCATION_VALUE);
// RequiresPageRegion by default
pInputSlot->bReqPageRgn = TRUE;
}
return err;
}
PPDERROR
RequiresPageRgnProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PINPUTSLOT pInputSlot;
PPDERROR err;
if (! BUFOBJ_IsEmpty(& pParserObj->option) &&
strcmp(BUFOBJ_Buffer(& pParserObj->option), "All") == EQUAL_STRING)
{
PUIGROUP pUiGroup;
BOOL reqPageRgn;
// Find or create the InputSlot UI group
err = CreateUiGroup(pPpdObj, UIGRP_INPUTSLOT, NULL, &pUiGroup);
if (err == PPDERR_NONE) {
err = GetBooleanValue(
&reqPageRgn, BUFOBJ_Buffer(& pParserObj->value));
if (err == PPDERR_NONE) {
if (reqPageRgn)
pUiGroup->uigrpFlags |= UIGF_REQRGNALL_TRUE;
else
pUiGroup->uigrpFlags |= UIGF_REQRGNALL_FALSE;
}
}
} else {
// Find the specified input slot from the existing
// list or add it as a new input slot
err = CreateUiOption(
pPpdObj, pParserObj, UIGRP_INPUTSLOT, (PUIOPTION*) &pInputSlot);
// Store the RequiresPageRegion value
if (err == PPDERR_NONE) {
GetBooleanValue(
&pInputSlot->bReqPageRgn, BUFOBJ_Buffer(& pParserObj->value));
}
}
return err;
}
PPDERROR
ResolutionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PRESOPTION pResOption;
PPDERROR err;
// Use normal PostScript code for setting resolution
pPpdObj->wResType = RESTYPE_NORMAL;
// Find the specified resolution option from the
// existing list or add it as a new resolution option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_RESOLUTION,
(PUIOPTION*) &pResOption);
// Store the Resolution invocation string
if (err == PPDERR_NONE) {
err = GetStringValue(
& pResOption->pInvocation,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
return err;
}
PPDERROR
JclResolutionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PRESOPTION pResOption;
PPDERROR err;
// Use JCL code for setting resolution
pPpdObj->wResType = RESTYPE_JCL;
// Find the specified resolution option from the
// existing list or add it as a new resolution option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_RESOLUTION,
(PUIOPTION*) &pResOption);
// Save the JCLResolution invocation string
if (err == PPDERR_NONE) {
err = GetStringValue(
& pResOption->pJclCode,
& pParserObj->value,
pPpdObj->pHeap,
QUOTED_VALUE);
}
return err;
}
PPDERROR
DefaultJclResProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PPDERROR err;
PUIGROUP pUiGroup;
// Find or create the Resolution UI group
err = CreateUiGroup(pPpdObj, UIGRP_RESOLUTION, NULL, &pUiGroup);
if (err == PPDERR_NONE) {
// Save the default resolution option
ASSERT(sizeof(DWORD) == sizeof(PVOID));
err = GetStringValue(
(PSTR *) & pUiGroup->dwDefault,
& pParserObj->value,
pPpdObj->pHeap,
STRING_VALUE);
}
return err;
}
PPDERROR
SetResolutionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PRESOPTION pResOption;
PPDERROR err;
// Use exitserver code for setting resolution
pPpdObj->wResType = RESTYPE_EXITSERVER;
// Find the specified resolution option from the
// existing list or add it as a new resolution option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_RESOLUTION,
(PUIOPTION*) &pResOption);
// Store the SetResolution invocation string
if (err == PPDERR_NONE) {
err = GetStringValue(
& pResOption->pSetResCode,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
return err;
}
PPDERROR
ScreenAngleProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetRealValue(
& pPpdObj->screenAngle,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
ScreenFreqProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetRealValue(
& pPpdObj->screenFreq,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
ResScreenAngleProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PRESOPTION pResOption;
PPDERROR err;
// Find the specified resolution option from the
// existing list or add it as a new resolution option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_RESOLUTION,
(PUIOPTION*) &pResOption);
// Store the ResScreenAngle value
if (err == PPDERR_NONE) {
err = GetRealValue(
& pResOption->screenAngle,
BUFOBJ_Buffer(& pParserObj->value));
}
return err;
}
PPDERROR
ResScreenFreqProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PRESOPTION pResOption;
PPDERROR err;
// Find the specified resolution option from the
// existing list or add it as a new resolution option
err = CreateUiOption(
pPpdObj,
pParserObj,
UIGRP_RESOLUTION,
(PUIOPTION*) &pResOption);
// Store the ResScreenFreq value
if (err == PPDERR_NONE) {
err = GetRealValue(
& pResOption->screenFreq,
BUFOBJ_Buffer(& pParserObj->value));
}
return err;
}
PPDERROR
FreeVmProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return GetIntegerValue(
& pPpdObj->dwFreeVm,
BUFOBJ_Buffer(& pParserObj->value));
}
PPDERROR
InstalledMemProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PVMOPTION pVmOption;
PPDERROR err;
// Find the specified VM option from the existing
// list or add it as a new VM option
err = CreateUiOption(
pPpdObj, pParserObj, UIGRP_VMOPTION, (PUIOPTION*) &pVmOption);
// Store the invocation string for the VM option
if (err == PPDERR_NONE) {
err = GetStringValue(
& pVmOption->pInvocation,
& pParserObj->value,
pPpdObj->pHeap,
INVOCATION_VALUE);
}
return err;
}
PPDERROR
VmOptionProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PVMOPTION pVmOption;
PPDERROR err;
// Find the specified VM option from the existing
// list or add it as a new VM option
err = CreateUiOption(
pPpdObj, pParserObj, UIGRP_VMOPTION, (PUIOPTION*) &pVmOption);
// Store the available memory for the VM option
if (err == PPDERR_NONE) {
err = GetIntegerValue(
& pVmOption->dwFreeVm,
BUFOBJ_Buffer(& pParserObj->value));
}
return err;
}
PPDERROR
OpenCloseGroupProc(
PPPDOBJ pPpdObj,
PCSTR pGroup,
BOOL bOpen
)
{
static char installableOptionsStr[] = "InstallableOptions";
if (EqualWordString(installableOptionsStr, pGroup)) {
if (pPpdObj->bInstallable == bOpen) {
DBGMSG(DBG_LEVEL_ERROR, "Unbalanced OpenGroup/CloseGroup\n");
return PPDERR_SYNTAX;
}
pPpdObj->bInstallable = bOpen;
} else {
DBGMSG1(DBG_LEVEL_VERBOSE, "Group '%s' ignored.\n", pGroup);
}
return PPDERR_NONE;
}
PPDERROR
OpenGroupProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return OpenCloseGroupProc(
pPpdObj,
BUFOBJ_Buffer(& pParserObj->value),
TRUE);
}
PPDERROR
CloseGroupProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
return OpenCloseGroupProc(
pPpdObj,
BUFOBJ_Buffer(& pParserObj->value),
FALSE);
}
PSTR
StripKeywordChar(
PSTR pStr
)
{
if (*pStr == KEYWORD_CHAR)
pStr++;
else {
DBGMSG1(DBG_LEVEL_ERROR,
"Missing * in front of keyword: %s\n",
pStr);
}
if (*pStr == '\0') {
DBGMSG(DBG_LEVEL_ERROR, "Null keyword string.\n");
return NULL;
} else
return pStr;
}
PPDERROR
OpenUiProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE uitypeStrs[] = {
{ "PickOne", UITYPE_PICKONE },
{ "PickMany", UITYPE_PICKMANY },
{ "Boolean", UITYPE_BOOLEAN },
{ NULL, UITYPE_PICKONE },
};
PSTR pKeyword;
WORD wType;
PPDERROR err;
PUIGROUP pUiGroup;
BOOL bJcl;
WORD uigrpIndex = UIGRP_UNKNOWN;
KEYWORD_TABLE_ENTRY *pKwdEntry;
// This function is used to process both *OpenUI
// and *JCLOpenUI keyword.
// Guard against nested OpenUI keywords
if (pPpdObj->pOpenUi != NULL) {
DBGMSG(DBG_LEVEL_ERROR, "Nested OpenUI not allowed!\n");
pPpdObj->pOpenUi = NULL;
}
// Decide whether we're dealing with JCLOpenUI
bJcl = (strncmp(BUFOBJ_Buffer(&pParserObj->keyword), "JCL", 3) == EQUAL_STRING);
// If the OpenUI keyword is predefined, it'll be handled
// elsewhere. We'll simply ignore it here.
pKeyword = StripKeywordChar(BUFOBJ_Buffer(& pParserObj->option));
if (pKeyword == NULL)
return PPDERR_SYNTAX;
if ((pKwdEntry = SearchKeyword(pKeyword)) != NULL &&
(uigrpIndex = pKwdEntry->uigrpIndex) == UIGRP_UNKNOWN)
{
return PPDERR_NONE;
}
// Parse the UI option type
if (! SearchStringTable(
uitypeStrs, BUFOBJ_Buffer(&pParserObj->value), &wType))
{
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown OpenUI type: %s\n", BUFOBJ_Buffer(&pParserObj->value));
}
// Create a UI group object
err = CreateUiGroup(pPpdObj, uigrpIndex, pKeyword, &pUiGroup);
if (err == PPDERR_NONE) {
pUiGroup->wType = wType;
if (! BUFOBJ_IsEmpty(& pParserObj->xlation)) {
err = GetStringValue(
& pUiGroup->pXlation,
& pParserObj->xlation,
pPpdObj->pHeap,
QUOTED_VALUE);
}
// Remember the currently open UI group
if (err == PPDERR_NONE && uigrpIndex == UIGRP_UNKNOWN) {
// Set flag to indicate whether this group is a JCL group
if (bJcl)
pUiGroup->uigrpFlags |= UIGF_JCLGROUP;
pPpdObj->pOpenUi = pUiGroup;
}
}
return err;
}
PPDERROR
CloseUiProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
PSTR pKeyword;
// This function is used to process both *CloseUI
// and *JCLCloseUI keyword. Two keywords are considered
// equivalent.
// Get the CloseUI keyword
BUFOBJ_StripTrailingSpaces(& pParserObj->value);
pKeyword = StripKeywordChar(BUFOBJ_Buffer(& pParserObj->value));
if (pKeyword == NULL)
return PPDERR_SYNTAX;
// Check if there is a matching OpenUI earlier
if (pPpdObj->pOpenUi != NULL &&
EqualWordString(pPpdObj->pOpenUi->pName, pKeyword))
{
// Close currently open UI group
pPpdObj->pOpenUi = NULL;
return PPDERR_NONE;
}
if (SearchKeyword(pKeyword) != NULL) {
DBGMSG1(DBG_LEVEL_VERBOSE,
"Ignore predefined CloseUI keyword: %s\n", pKeyword);
return PPDERR_NONE;
}
DBGMSG1(DBG_LEVEL_ERROR, "Unbalanced CloseUI: %s\n", pKeyword);
return PPDERR_SYNTAX;
}
PPDERROR
OrderDepProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE sectionStrs[] = {
{ "ExitServer", ODS_EXITSERVER },
{ "Prolog", ODS_PROLOG },
{ "DocumentSetup", ODS_DOCSETUP },
{ "PageSetup", ODS_PAGESETUP },
{ "JCLSetup", ODS_JCLSETUP },
{ "AnySetup", ODS_ANYSETUP },
{ NULL, ODS_ANYSETUP }
};
PSTR pStr;
char wordStr[MaxKeywordLen];
PSREAL order;
WORD wSection, wLen;
pStr = BUFOBJ_Buffer(& pParserObj->value);
// Interpret the partial-order number
if (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) {
if (GetRealValue(&order, wordStr) == PPDERR_NONE &&
GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0)
{
// Interpret the section parameter
if (! SearchStringTable(sectionStrs, wordStr, &wSection)) {
DBGMSG1(DBG_LEVEL_WARNING,
"Unknown OrderDependency section: %s\n",
wordStr);
}
// Parse the mainKeyword parameter
if ((wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr)) > 0) {
PORDERDEP pOrderDep;
PSTR pKeyword;
// Strip off * character prefix
pKeyword = StripKeywordChar(wordStr);
if (pKeyword == NULL)
return PPDERR_SYNTAX;
pOrderDep = (PORDERDEP)
HEAPOBJ_Alloc(pPpdObj->pHeap, sizeof(ORDERDEP) + wLen + 1);
if (pOrderDep == NULL)
return PPDERR_MEM;
memset(pOrderDep, 0, sizeof(ORDERDEP));
pOrderDep->order = order;
pOrderDep->wSection = wSection;
pOrderDep->pKeyword =
((PSTR) pOrderDep) + sizeof(ORDERDEP);
strcpy(pOrderDep->pKeyword, pKeyword);
// Parse the optionKeyword parameter
wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr);
if (wLen > 0) {
pOrderDep->pOption = (PSTR)
HEAPOBJ_Alloc(pPpdObj->pHeap, wLen+1);
if (pOrderDep->pOption == NULL)
return PPDERR_MEM;
strcpy(pOrderDep->pOption, wordStr);
}
// Append the new order dependency object to
// the linked list.
LISTOBJ_Add(
(PLISTOBJ*) &pPpdObj->pOrderDep,
(PLISTOBJ) pOrderDep);
return PPDERR_NONE;
}
}
}
DBGMSG1(DBG_LEVEL_ERROR,
"Invalid OrderDependency entry: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
return PPDERR_SYNTAX;
}
PPDERROR
UiConstraintsProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
WORD wLen;
PSTR pStr, pKeyword;
char wordStr[MaxKeywordLen];
PUICONSTRAINT pUiConstraints;
pStr = BUFOBJ_Buffer(& pParserObj->value);
wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr);
if (wLen > 0 && (pKeyword = StripKeywordChar(wordStr)) != NULL) {
// Extract the first keyword parameter
pUiConstraints = (PUICONSTRAINT)
HEAPOBJ_Alloc(
pPpdObj->pHeap,
sizeof(UICONSTRAINT) + wLen + 1);
if (pUiConstraints == NULL)
return PPDERR_MEM;
memset(pUiConstraints, 0, sizeof(UICONSTRAINT));
pUiConstraints->pKeyword1 =
(PSTR) pUiConstraints + sizeof(UICONSTRAINT);
strcpy(pUiConstraints->pKeyword1, pKeyword);
wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr);
if (wLen > 0 && wordStr[0] != KEYWORD_CHAR) {
// Extract the first option parameter
pUiConstraints->pOption1 = (PSTR)
HEAPOBJ_Alloc(pPpdObj->pHeap, wLen+1);
if (pUiConstraints->pOption1 == NULL)
return PPDERR_MEM;
strcpy(pUiConstraints->pOption1, wordStr);
wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr);
}
if (wLen > 0 && (pKeyword = StripKeywordChar(wordStr)) != NULL) {
// Extract the second keyword parameter
pUiConstraints->pKeyword2 = (PSTR)
HEAPOBJ_Alloc(pPpdObj->pHeap, wLen+1);
if (pUiConstraints->pKeyword2 == NULL)
return PPDERR_MEM;
strcpy(pUiConstraints->pKeyword2, pKeyword);
wLen = GetWordStr(&pStr, MaxKeywordLen, wordStr);
if (wLen > 0) {
// Extract the second option parameter
pUiConstraints->pOption2 = (PSTR)
HEAPOBJ_Alloc(pPpdObj->pHeap, wLen+1);
if (pUiConstraints->pOption2 == NULL)
return PPDERR_MEM;
strcpy(pUiConstraints->pOption2, wordStr);
}
// Add the UI constraints object to the list
LISTOBJ_Add(
(PLISTOBJ*) &pPpdObj->pUiConstraints,
(PLISTOBJ) pUiConstraints);
return PPDERR_NONE;
}
}
DBGMSG1(DBG_LEVEL_ERROR,
"Invalid UIConstraints entry: %s\n",
BUFOBJ_Buffer(& pParserObj->value));
return PPDERR_SYNTAX;
}
PPDERROR
ExtensionsProc(
PPPDOBJ pPpdObj,
PPARSEROBJ pParserObj
)
{
static struct STRTABLE extensionStrs[] = {
{ "DPS", LANGEXT_DPS },
{ "CMYK", LANGEXT_CMYK },
{ "Composite", LANGEXT_COMPOSITE },
{ "FileSystem", LANGEXT_FILESYSTEM },
{ NULL, 0 }
};
PSTR pStr;
WORD wExtension;
CHAR wordStr[MaxKeywordLen];
pStr = BUFOBJ_Buffer(& pParserObj->value);
while (GetWordStr(&pStr, MaxKeywordLen, wordStr) > 0) {
// Interpret extension options
SearchStringTable(extensionStrs, wordStr, &wExtension);
if (wExtension != 0) {
pPpdObj->wExtensions |= wExtension;
if (wExtension == LANGEXT_CMYK)
pPpdObj->bColorDevice = TRUE;
} else {
DBGMSG1(DBG_LEVEL_WARNING, "Unknown extension: %s\n", wordStr);
}
}
return PPDERR_NONE;
}