PDDR/2 - 32-Bit PostScript Driver

=32-Bit PostScript Driver= The PostScript driver is a 32-bit presentation driver that converts graphics engine calls to the PostScript language.

The PostScript driver is known as a "high-level" driver because it can hook many graphics calls at a high level. It rarely must call back to the graphics engine to have high-level calls simplified. Most other printer drivers, except the plotter driver, are raster devices (their primary output is a bit map). These drivers allow the engine and display driver (or shadow DC) to do most of the work.

PostScript is a vector device. Its output is a series of high-level commands that tell the printer to perform actions such as draw a line, clip to an area, create and scale a font. The PostScript driver hooks all the path, region, clipping and fonts directly. This method is more efficient than calling back to the graphics engine, but it requires that the driver be responsible for this additional support. Both PostScript and the GPI/GRE have analogous constructs, so mapping between them can be almost one-to-one.

The PostScript driver currently supports 214 printer configurations. New printers are easily added by updating a list and running a complier on the PostScript Printer Description (PPD) file. For more information about PPD files, see.

Because the PostScript driver is 32 bit, it has a direct path to the 32-bit engine (no thunking). Therefore, the driver can get some large values in certain calls. The values can be so large that they can overflow the floating point representation (16bits integer : 16bits fraction). Sliding point has been implemented in the driver to scale the number. For an example of sliding point, see in.

Generic Printer Library (GenPLib)
The GenPLib is a set of subroutines that are useful for 32-bit presentation drivers. The PostScript driver takes advantage of the following GenPLib functions: For further information about the GenPLib, see Generic Printer Library.
 * Memory-management routines
 * Multi-threading output capabilities
 * Error and debugging support routines

Font Support
The driver supports two types of fonts: built-in and downloadable. Built- in fonts are stored as resources during driver build time. Downloadable fonts come from the system font manager.

Built-In Fonts
Currently, 69 fonts are built into the driver. When a "compiler" is built, it extracts information from the Adobe Font Metrics (AFM) file and creates a .PFM file. The following are stored in each .PFM: The font compiler (afm2bin) pre-processes the font metrics so that it does not have to be generated each time the driver is asked for FontMetrics. For an example, see in.
 * Character code points
 * Character widths
 * Kerning pairs
 * General font information
 * Font metrics

DownLoadable Fonts
The driver can also use the system OS/2 font metrics (OFM) fonts. These files are created by the Adobe Type Manager (ATM) subsystem. The OFM files contain packed font information from the ATM files (they are more extensive than a PFM). The format of the OFM file is in OFM.H. When the DC is initialized, the INI file is queried for the location of the .OFM and .PFB files. These fonts are added to the list of device fonts. If there is a is conflict, the device font is kept. The list of printer fonts will consist of real device fonts and OFM/downloaded fonts. When the user requests a list of fonts, the driver reports its fonts and the engine adds its outline fonts. This can result in a font that is listed twice to the user, once by the driver and once by the engine. The engine fonts are indicated by the ON setting of the GENERIC bit.

When a user requests an outline font, the driver will always first look for a downloaded font. The driver will not substitute a device font for a generic font, but will try to find a downloaded font before returning GPI_ ALTERROR on realizefont. Therefore, the font will be stroked, which generates a large number of PS commands.

Conversions
The OFM file must be converted to the internal format. This conversion is done by in. The built-in fonts are slightly modified by adding character bounding box information to each character.

Downloading
Because of page saving, fonts are sent to the printer twice, once in the middle of the page and once at the top of the next page, before the page state is saved. This method is inefficient, but the driver has no way to know at the beginning of the page what fonts will be needed on that and following pages.

Creating the Font List
When a PPD for a printer is compiled, the hardware device fonts are put in the PostScript Printer Binary (PPB) resource. The printer information that is loaded during FillPhysicalDeviceBlock provides the names of the fonts that the hardware supports. These fonts must be in the list of built-in fonts.

Memory Management
In the driver, all memory requests and frees are done through two calls, GplMemoryAlloc and GplMemoryFree via the GenPLib. Through these calls, the user is relieved of the task of keeping track of where the memory came from.

The PostScript driver creates two heaps: This is larger because it is expected to be used more extensively.
 * A per-process heap that is used when there is possibly no DC ( DevPostDeviceModes, DevQueryDeviceNames)
 * A DC heap that is the main source of memory for the driver

High-Level Support
This section contains three examples of high-level support for the PostScript driver:
 * Paths
 * Boxes
 * Arcs

Paths
The driver hooks high-level path calls, such as BeginPath and EndPath calls. The hooking of these calls makes the driver it responsible for all the path calls because the engine has no record of the path. When a BeginPath is encountered, the driver stops outputting PostScript to the printer and begins placing the PostScript in an internal buffer. When the EndPath is received, the driver begins outputting to the printer again. Normally, a command dealing with a path comes in from the graphics engine. This command can include SetClipPath, StrokePath, and FillPath. The driver then dumps the path buffer to the printer and issues the appropriate PostScript command to the printer to complete the action. For an example, see in.

Boxes
The driver can give direct support on Box calls such as BoxBoth, BoxBoundary, BoxInterior. These calls can be translated to PostScript line and fill commands. For an example, see in.

Arcs
Arcs and curves are translated to the corresponding PostScript calls. For an example, see in.

Shadow DC
Because the driver cannot handle bit maps, the driver must use the graphics engine and display device. The driver creates a shadow memory DC in display for each DC enabled for the printer (done in ). If the driver is enabling a memory DC, the shadow memory DC will be used for all calls. Otherwise, the shadow memory DC will be used mainly for handling the bit maps.

In some functions, usually main entry points, the DC type is checked against memory. If the DC is memory, the call is routed to hdcMemory using an InnerGRE entry point.

Device Support
PostScript supports many different devices that handle different page sizes, duplexing options, and font availability. The driver requires information for each device it supports so the driver can invoke those features by sending a series of PostScript commands. Information for each device is provided to the driver by means of a PPD file.

A PPD file is a text file that contains PostScript commands for specific device functions. These commands are used to invoke the features of a specific device. PPD files are parsed into binary data that is stored as a resource in the driver. Currently, the PostScript driver supports version-3 PPD files.

A PPD file contains multiple entries, each referring to a specific device feature and matching PostScript commands needed to invoke that feature. A standard PPD entry is broken down into the following format: *MainKey [OptionKey][/Translation String]]: Value where:

*MainKey describes a class of features such as page sizes, duplex options, and fonts. A mainkey always begins with an asterisk. *PageSize, an example of a mainkey, defines types of pages.

OptionKey (optional) identifies a specific option for the feature. If there is more than one option key for each mainkey, a separate entry is needed for each option. For example, several options for *PageSize would be Letter, Legal, and Envelope.

Translation string (optional) clarifies the matching option to the user in simpler terms or in another language. Because each mainkey can have more than one option, it might be necessary to provide some text for each option that the user can understand.

Value will either contain actual PostScript code that is sent to the printer when the feature is selected or a reference to another resource that contains more PPD and PostScript information.

The following is an example of a standard PPD entry: *PageSize CommEnv/Business Envelope& "statusdict /commenv get exec" The mainkey in the above line is *PageSize. The option key is CommEnv. The translation string is Business Envelope The value is statusdict /commenv get exec. It is sent to the device when Business Envelope is selected.

PPD Compiler
A PPD file is parsed to binary data before it is used by the driver. Before the binary data is added as a resource in the driver, it is stored into a PPB file. The process of converting standard PostScript PPD text into OS/2 PPB data is done by an OS/2 PPD compiler. This compiler, called PPD2BIN.EXE, is located in the IBM Device Driver Source Kit for OS/2. See Using Your DDK for a 'roadmap' of the directory structures on the IBM Device Driver Source Kit for OS/2. The compiler opens a file that contains a list of PPD files, and converts each one into a PPB file of the same name. Each PPB file is later added as a driver resource by the C compiler.

Dialog Mapping
The following identifies all dialog-box fields used in the driver and the PPD keywords that are used to modify these fields. These keywords are case sensitive:

Debugging Tips
This section describes debugging tips and techniques for the PostScript driver. This information is provided under the assumption that you know how to use the kernal debugger, that you have a debugging terminal installed and ready, and that PSCRIPT.DRV and PSCRIPT.SYM are installed in the \OS2\ DLL\PSCRIPT directory.

General Tips
You can set the driver to send the job to a file rather than to the printer. (One reason to do this is to save paper.)

The driver is loaded in memory at the first job and remains in memory until the system is restarted. While loaded, PSCRIPT.DRV cannot be modified or deleted. If the driver is not currently loaded, however, accessing Printer Properties or Job Properties will not load the driver. Therefore, the driver can still be modified or deleted if either dialog box has been previously opened.

If there is a trap while using the Job Properties dialog box, it is better to open the Job Properties dialog box from an application rather than from the Printer Object. This will cause the application to terminate rather than the Workplace Shell.

The driver does not process "raw" PostScript jobs. The driver receives the job and passes it directly to the device through DEVESC_RAWDATA.

The PostScript driver only handles OS/2 and, in some cases, WIN-OS/2* jobs. For the driver to support WIN-OS/2, the port setting in the WIN-OS/2 session must be set to the port name with ".OS2" appended (for example, " LPT1.OS2"). In WIN-OS/2, all other port settings will cause the job to be handled by a Windows-compatible driver. OS/2-DOS uses standard DOS drivers and is completely ignored by this driver.

To make debugging easier, you can compile the source code (no linking necessary) using the "/Fa+" option. This will generate the source code with matching assembler code, which will virtually match the assembler output on the debugger.

If a job contains any invalid characters, with the exception of the last character (ASCII 4, the diamond character), or the first line (the first line might contain characters that set the device in PostScript mode), the device will end the job. For more information about valid and invalid characters, refer to a PostScript manual. Even with little knowledge of the PostScript language, it is usually not difficult to identify invalid characters in a job.

The compiler can produce a file that contains both the source and matching assembler code. These files contain the extension ".OUT". To generate such a file, type:

NMAKE ALL COD=1

Any C source file that is compiled will generate a matching file that contains both C and assembler.

Error Handler
If a PostScript job does not print when sent, it could mean that there was an invalid command or limit check in the job and the device terminated that job. All PostScript printers will abort the entire job if an error is found.

There is a way to identify errors in a job. The driver contains an error handler that, when sent to the printer, reports any errors it finds. The job will still be aborted, but an error will be reported. Once loaded in the printer, the error handler will remain in the printer's memory until the printer is turned off, so it is only necessary to load the error handler once. In fact, if the error handler is loaded more than once while the printer is on, an error will be generated as the printer tries to reload the error handler.

To send the error handler, go to the Job Properties dialog and then to the 'Output' page. You will see a button called "Download error handler". Select that button to send the error handler. The printer will indicate that it is receiving data, but no output will be sent. After that, every time the printer encounters an error, it prints the error in the following format: ERROR: OFFENDING COMMAND: 

STACK:  The error handler will only report errors it has found. It will not report the location in the job where the error occurred. Because one job might contain the same command more than once, it is important to locate the exact place in the job where the error occurred. To accomplish this, insert specific invalid characters (such as "$$$") in the first column anywhere in the job. If the error handler reports the invalid characters you inserted first, the true error is after those invalid characters. You can either move the characters to another spot in the file and resend the job, or use several sets of invalid characters and eliminate the topmost set, one at a time after each output, until the real error is displayed. Eventually, you will be able to find the command that the error handler reported.

Breakpoints
This section contains symbols that are helpful when setting breakpoints during debugging.

The driver accesses a function from the GenPLib called GplErrSetError that reports errors that have occurred in the driver. By setting a breakpoint at this function, it is possible to identy the calling function that generated the error. To identify the function with the error, display a stack trace when the breakpoint stops at GplErrSetError. The first function name in the list is the function that generated the error.

It is possible for a trap to occur early in the driver before you are able to set a breakpoint. Instead of inserting an INT 3 in the code, you can insert a breakpoint at the location ENDDEBUGLOADSYMMTE. This routine is called after the symbol file is loaded, but before the driver is executed. First, set up a test case to the point just before accessing the driver; and then, set a breakpoint at ENDDEBUGLOADSYMMTE. When the test case invokes the driver, the breakpoint will be encountered immediately after the PostScript driver and symbols are loaded. Now insert breakpoints in the driver. If the driver responds with an error when inserting driver breakpoints, it might be necessary to run GO four or five times before the debugger understands the symbol names. However, if you prefer to use interrupt 3 (INT 3), there is a function in, called Int3, that accesses the interrupt. Because this function is currently commented out, you must "un-comment" the function to access it.

Makefile
The makefile used for this driver is called "makefile" and is located in the IBM Developer Connection Device Driver Kit for OS/2. Refer to Using Your DDK for a roadmap of the file structure.

This makefile can be used to build either a retail or debug version of the driver for the Intel or PowerPC version of OS/2. The syntax is as follows:

nmake [RET | DBG][PPC | OS2C]

where
 * RET builds a retail version.
 * DBG builds a debug version.
 * PPC builds a driver for the PowerPC version of OS/2.
 * OS2C builds a driver for the intel version of OS/2.

To build a retail Intel driver, for example, use: "nmake retos2c". To build a debug PowerPC driver, use "nmake dbgppc".

Driver Entry Points
The driver uses the following entry points:
 * OS2_PM_DRV_ENABLE:Calls subfunctions that initialize this driver, the device, and the device context. This is called when a job is sent.
 * OS2_PM_DRV_DEVMODE:Used to query or change device information or to display the Printer Properties and Job Properties dialog boxes.
 * OS2_PM_DRV_DEVICENAMES:Returns device names and information that is supported by this driver.

Primary Structures
Although the driver uses many structures, there are one buffer and three structures that are primary to the driver's function:

PostScript Command Buffer This buffer contains the actual strings retrieved from the PPD file. These include the translation strings that are displayed in the dialog box.

This buffer is accessed by a base pointer. This base pointer can be accessed by apResources[ RESBUF ], by the DESPPD structure, or by the dialog header when Printer Properties and Job Properties are displayed (DLGHDR.pIemsBuff).

DESPPD structure (located in PPDIALOG.H) This contains the data take from the PPD structure. This is the only structure that is used by PPD compiler. Most fields contain an offset value that, when added to the base pointer to the PostScript Command buffer, will yield an address to the desired data. One access to this structure is through apResources[ PPDRES ].

This contains the following:
 * The PostScript command strings that are sent out to the job. These command strings include such things as which paper size to use, the input slot from which to pull the paper, etc.
 * The UI structure (UI_LIST).
 * There is a pointer called pPSStringBuff that points to the PostScript Command buffer.

CNFDATA structure (located in PPDIALOG.H) The CNFDATA structure contains the current settings specified by the user in Job Properties and Printer Properties. This includes such things as whether the user specified portrait or landscape printing. One access to this structure is through apResources[ CNFRES ].

DV structure (located in PRDPTYPT.H) This structure is passed along with the PDDC that is sent along with the job. Any data that is to be used during a job may be stored in the structure. The data is passed to the DV structure in the function.

User-Interface Features
Before reading this section, we recommend that you read the Adobe Postscript Printer Description Document, version 4.2, to understand the PostScript user-interface (UI) format. In that document, refer specifically to the "User Interface" section.

The UI format gives printers the ability to support specific features that may not be available on other printers. The following is an example taken from the PPD file: Each PPD file may contain a variable number of *OpenUI/*CloseUI groups. The text within each *OpenUI/*CloseUI group is known in this document as a "block" (or a "feature"). Within each block, there are a variable number of options, each one known here as an entry. In the example above,
 * OpenUI *PageSize/Paper Size: PickOne
 * OrderDependency: 20 AnySetup *PageSize
 * DefaultPageSize: Letter
 * PageSize Letter/Letter 8.5 x 11: "statusdict /letter get exec"
 * PageSize Legal/Legal 8.5 x 14: "statusdict /legal get exec"
 * PageSize Executive/Executive Envelope: "statusdict/executive get exec"
 * PageSize Monarch/MonarchEnvelope: "statusdict /monarch getexec"
 * CloseUI: *PageSize
 * the UI block is called "PageSize" and covers the text between *OpenUI and *CloseUI.
 * there are four entries, each named after the UI block name.
 * the default entry is referenced by the string *Default string followed by the UI block name.

Not only can PPDs contain a variable number of UI blocks, but each block can contain a variable number of UI entries. In addition, there are three types of selections available to a UI block:

In order to support the Postscript UI format, a printer driver must:
 * PickOne||Only one entry in a UI block may be selected at a time.
 * PickMany||One or more entries in a UI block may be selected at a time.
 * Boolean||This is similar to PickOne, but it provides a TRUE/FALSE type selection. In the OS/2 Postscript driver, Boolean values are treated like PickOne values.
 * }
 * Boolean||This is similar to PickOne, but it provides a TRUE/FALSE type selection. In the OS/2 Postscript driver, Boolean values are treated like PickOne values.
 * }
 * support a variable number of UI blocks
 * support a variable number of UI entries within each block
 * minimize the amount of overhead as much as possible

Note: All of our OS/2 UI structures are located in PPDIALOG.H.

UI Entries
Each UI entry is supported by the UI_ENTRY structure. This structure contains three fields. Each field contains an offset value which, when added to the base pointer to the Postscript Command buffer, yields the desired string. There may be up to and including thirty-two UI entries per block. The fields in the UI_ENTRY structure are as follows:


 * ofsOption||This contains the offset where the option string for the current entry can be found. In the above example, the entry options for the PageSize UI block would be: Letter, Legal, Executive, and Monarch.
 * ofsTransString||This contains the offset value of the entry's translation string. The translation string is optional and contains the string that is displayed for the user to see. If no translation string exists, ofsTransString contains the same value as ofsOption. In the above example, the translation string for the Letter entry is: Letter 8.5 x 11.
 * ofsValue||This contains the Postscript string that is sent with the job if the user has selected that entry. In the above example, the value for the Legal entry is: statusdict /legal get exec.
 * }
 * ofsValue||This contains the Postscript string that is sent with the job if the user has selected that entry. In the above example, the value for the Legal entry is: statusdict /legal get exec.
 * }

UI Blocks
Each entry is part of a larger structure, the UI_BLOCK structure. Each UI block in the PPD has a matching structure. The end of the UI_BLOCK structure contains a variable-length UI_ENTRY array. This allows the support of a variable number of UI entries.

Each UI_BLOCK contains the following fields:

UI List
All UI blocks are grouped together to make up the UI list. The UI_LIST structure contains a pointer to the beginning of the list of UI blocks as well as the number of blocks and number of bytes that make up the list. The PPD compiler orders the UI blocks in the list, according to the OrderDependency key. The lower a block's OrderDependency value, the higher it is placed in the UI list.

Each block in the UI list is referenced by an offset value. For example, the first UI block in the list is at offset zero, the second block is at offset one, and so on. This is important to know in order to access the current selection the user has made for that block.

For each UI block, there is a matching UI-Selection value. A UI-Selection value is a 32-bit value that contains the current selection(s) the user has made for the matching UI block. Each bit in a UI-Selection value (otherwise known as UI_SEL) corresponds to a UI entry for a given block. Bit 0 corresponds to the first entry, bit 1 corresponds to the second entry, and so on. If a selection has been made for that entry, the bit is set to 1; if a selection has not been made for that entry, the bit is set to 0. Normally, no UI-Selection values will be 0 because there must be at least one selection. This way, it is possible to support multiple UI selections with minimal overhead; but, it also means that there can be no more than 32 entries for a given block.

Each UI_SEL value is part of the UI-Selection list. This list is accessed by a base pointer. To access a UI_SEL value for a specific UI block, it is important to know the offset of that UI block with respect to the UI list. Add that offset to the base pointer to get the UI-Selection value. To query the UI-Selection entry for MEDIATYPE, for example, assume that the MEDIATYPE UI block is the fourth block in the list. This means that the offset value for the MEDIATYPE block is 3. Add three to the base pointer, and that will yield the UI-Selection value for MEDIATYPE.

The UI-Selection list is stored in the buffer immediately following the CNFDATA structure. To query the UI-Selection list base pointer, use the macro ASSIGN_UISELLIST_PTR with the only macro being the pointer to the CNFDATA structure.

When the UI-Selection list is first queried at initialization, the list is re-initialized if any UI_SEL values are 0.

UI Controls
Because UI features require special processing, there is a special procedure that handles the UI data. This type of control is called a "UI control". Normally, UI controls are drop-down listboxes. Standard listboxes are used for multiple-selection UIs, however, and the duplex UI uses three radio buttons.

Dialog-Box Format
There are three C files that are used for the PostScript dialogs:

Each page in the dialog's notebook is a separate dialog box, and each page handles data internally. There is a structure called the dialog header (DLGHDR). The address of the dialog header is stored in the reserved doubleword of each dialog page.
 * PPDLG.C||contains code that maintains the Printer-Properties dialog box.
 * JPDLG.C||contains code that maintains the Job-Properties dialog box.
 * DLG.C||contains common code that is used by both properties.
 * }
 * DLG.C||contains common code that is used by both properties.
 * }

Each page dialog must handle the following messages:
 * WMPS_INITSETTINGS:This is sent to all dialog pages after the dialog header initializes. The WM_INITDLG message is sent before this message; at this time, the dialog header has not yet been initialized. A rule of thumb is that controls can be set up when the WM_INITDLG message is received. For example, spin buttons can be set to their minimum and maximum values. At the WMPS_INITSETTINGS message, the control is initialized with the values from the dialog header. Processing of this message is optional.
 * WMPS_VERIFYSETTINGS:This indicates that the page dialog should verify that the settings within the page are valid. If all the control settings are valid, or if no verification is needed, the return code should be set to PSDRC_VERIFY_SUCCESS. If an invalid setting exists, the page should return another return code, which will cause the dialog to display a message indicating that an error exists. Processing of this message is required.
 * WMPS_SAVESETTINGS:This indicates that the page dialog should save the settings within its controls. The page dialog must return PSDRC_SAVE_ SUCCESS to indicate that all was saved successfully. Processing of this message is required only if you wish to save any settings.
 * There is a structure called the "dialog template" (DLG_TMPL). This structure contains information that is used by the dialog functions at initialization. The DLG_TMPL structure is broken down as follows:


 * uiDialogID||This contains the ID of the dialog to be inserted.
 * pfnDlgProc||This contains the dialog procedure.
 * usTabID||This contains a string ID. This is the string that is inserted in the page's tab.
 * chTabID||This is reserved.
 * - style="vertical-align: top;"
 * pfnQueryLoadFn||This is optional. It contains a function to verify whether or not the page should be loaded. If the page should be inserted, the function should return TRUE; otherwise, the function should return FALSE. The only input argument is a PVOID to the dialog header. The function returns a BOOL value. Before inserting the "Features" page, for example, the dialog calls the function . If there are enough features that warrant this page, the function returns TRUE. If no function is provided, the page is always loaded.
 * }
 * - style="vertical-align: top;"
 * pfnQueryLoadFn||This is optional. It contains a function to verify whether or not the page should be loaded. If the page should be inserted, the function should return TRUE; otherwise, the function should return FALSE. The only input argument is a PVOID to the dialog header. The function returns a BOOL value. Before inserting the "Features" page, for example, the dialog calls the function . If there are enough features that warrant this page, the function returns TRUE. If no function is provided, the page is always loaded.
 * }

Status Bar
At the bottom of the Job-Properties dialog box, there is a row of icons that make up the Status Bar. The purpose of the Status Bar is to continuously display general printer settings. No matter what page you're on, the Status Bar displays at least some current settings. Each reserved doubleword in the Status Bar contains the icon ID that is currently displayed. If a status icon needs to be repainted, the doubleword is queried and the icon is re-loaded in memory and repainted. Each icon in the Status Bar also has a matching icon in the respective control; both icons are always the same.

The first icon makes up orientation and is modified every time Portrait or Landscape is selected in the Forms page.

The second icon makes up a color or monochrome value. If color is supported and enabled, a colored icon is displayed. This is modified every time Color is selected in the Effects page.

The third icon makes up duplex. For single sided, two forms appear-one with a red arrow pointing up,indicating how the text will appear. The second side is blank. For 2-page book, both forms appear with a red arrow pointing up, indicating how text will appear. For 2-sided flip, both forms appear with inverse arrows-indicating that text will be flipped.

The fourth icon indicates where the job will be sent-to the printer, to an encapsulated Postscript file, or to a standard file.

Changing the Driver Name
Although the code provided in the DDK builds to "PSCRIPT.DRV", it is recommended that you use a name other than "PSCRIPT.DRV" for your own driver. This section describes how to change the driver's name.

To change the file name of the driver, the following components must be altered:

where the:
 * - style="vertical-align: top;"
 * style="width:11%;"|Extended attributes||Extended attributes are read by the print object that installs the driver in a specific path. The path is \OS2\DLL followed by a path that has the same name as the driver. For example, the path for the OS /2 PostScript driver is \OS2\DLL\PSCRIPT.
 * - style="vertical-align: top;"
 * Driver contents||The current driver stores printer-properties selections in OS2SYS.INI. The application string in the INI is in the following format:
 * name of print object is the name of the printer object where printer properties were stored
 * driver name is the name of the driver file-for the OS/2 PostScript driver, the string is "PSCRIPT"
 * device name is the name of the printer that is displayed in the print object's Settings dialog.

To set and retrieve data from the INI file, the driver uses the hard-coded string "PSCRIPT" to create a string that is then used to set/query the data in the INI file. If you change the name of the driver, you must also change the name of this string; otherwise, you may be querying and setting the wrong INI entry. The following example shows you how to change the name of the driver " PSCRIPT.DRV" to "SAMPLE.DRV":
 * }

1.First, change the contents of a file called "PKGPS.CMD". This batch file sets the extended attributes for the driver. Change all occurrences of " PSCRIPT" to the name of your driver-e.g., change "PSCRIPT" to "SAMPLE".

2.Make changes to several functions of the driver where "PSCRIPT" is hard coded. Replace the string "PSCRIPT" with the name of your driver-e.g., change "PSCRIPT" to "SAMPLE". Below is a list of source files that need to be changed and the locations where changes are needed:

3.Change the makefile. In the makefile, the minimum change that you must make is to change all occurrences of "PSCRIPT.DRV" and "PSCRIPT.HLP" to include the name of your driver-e.g., "SAMPLE.DRV" and "SAMPLE.HLP".
 * ||Change HELPFILENAME to include driver name,
 * ||,
 * ||,
 * ||
 * UTLLOG.C||LogIsOn
 * SOFTFONT.H||Change string accessed by FONT_DIR_APP from "PM_PSCRIPT" to "PM_ " followed by the driver name
 * }
 * UTLLOG.C||LogIsOn
 * SOFTFONT.H||Change string accessed by FONT_DIR_APP from "PM_PSCRIPT" to "PM_ " followed by the driver name
 * }
 * SOFTFONT.H||Change string accessed by FONT_DIR_APP from "PM_PSCRIPT" to "PM_ " followed by the driver name
 * }

You can also change all other occurrences of "PSCRIPT", including path names and other file names; but this is not required.

4.The conversion is now complete, and you are ready to rebuild the new driver. When installing from the print object, select Other OS/2 printer driver and specify the path of your driver. Your driver will install on the path OS2\DLL followed by the name of your driver-e.g., SAMPLE.DRV will install on \OS2\DLL\SAMPLE. This path will include SAMPLE.DRV and SAMPLE. HLP.

PostScript Modules and Functions
This section provides a layout of the PostScript source code. Refer the DDK CD for the PostScript source code and to the "Using Your DDK", also available on the DDK CD, for a roadmap of the file structure used by the PostScript source code.

The first part of this section lists all functions of PostScript in alphabetical order. The module in which each function is found is listed next to the function.

The second part of this section lists the modules that comprise PostScript and the functions that comprise each module. Each function is followed by a description.

Notes:

1.If a function is not listed in this document, it has been commented out in the source code.

2.Some functions have the same name but are used for different executables.

Module and Function Descriptions
This section describes the modules that comprise the PostScript driver and the functions that comprise each module. Each function is followed by a description. The functions in each module are listed in alphabetical order.

ARCS.C
This module contains functions that handle drawing for arcs and circles.


 * find_arc_direction:Finds the direction the arc should be drawn. This is dependent on the arc parameters. If p * q > r * s, the arc is drawn counter clockwise; otherwise, it is drawn clockwise.
 * prdl_FullArcBoth:Draws both the boundary and interior of a fullarc, centered at the current position.
 * prdl_FullArcBoundary:Draws the full boundary of an arc, centered at the current position.
 * prdl_FullArcCommon:Draws the interior of a fullarc, centered at the current position.
 * prdl_FullArcInterior:Draws the full interior of a fullarc, centered at the current position.
 * prdl_FullArcPath:Sends PostScript commands relating to any arc drawing.

ASM2C.C
This module contains math routines for the driver.


 * frdiv:Divides two fixed numbers and returns a fixed number.
 * frmul:Multiplies two fixed numbers and returns a fixed number.
 * frsqrt:Calculates the square root of a fixed number.
 * frVectLength:Computes the length of a vector, given the X and Y components as fixed point numbers, and returns the square root as a fixed point value.
 * fxmultiply:Multiplies two fixed numbers and returns a fixed number. The passed QUAD is filled in with the quad intermediate result. The overflow flag is always zero.
 * iqdiv:Divides a Quad by a long number, returning a fixed number.
 * LongXFixed:Multiplies a fixed and long and returns a long. This saves two shifts converting long to and from fixed. As a result, the function is simpler than frmul. Method: (long x fixed_fraction), and then shift off fraction and add in long X fixed_integer.
 * utl_memcopy:Passthru to C memcpy.

ATTRS.C
This module contains functions that maintain image and device attributes.


 * prda_DeviceGetAttributes:Returns selected device attributes.
 * prda_DeviceSetAttributes:Sets selected device attributes.
 * prda_DeviceSetGlobalAttribute:Sets selected global attributes.
 * prda_GetImagAttrs:Returns selected image attributes.
 * prda_GetLineAttrs:Returns selected line attributes.
 * prda_GetMarkAttrs:Returns selected marker attributes.
 * prda_GetPtrnAttrs:Returns selected pattern attributes.
 * prda_GetTextAttrs:Returns selected text attributes.
 * prda_SetImagAttrs:Sets selected image attributes.
 * prda_SetLineAttrs:Sets selected line attributes.
 * prda_SetMarkAttrs:Sets selected marker attributes.
 * prda_SetPtrnAttrs:Sets selected pattern attributes.
 * prda_SetTextAttrs:Sets selected text attributes.
 * prdl_GetCurrentPosition:Returns the current position.
 * prdl_PatGray:Establishes the current pattern attributes used to fill a path.
 * prdl_PenGray:Establishes the current pen attributes used to stroke a path.
 * prdl_SetCurrentPosition:Sets the current position in the DDC, and outputs a moveto command to the PostScript printer. As soon as this command is completed, the PostScript printer and the DDC will have the same current position.
 * prdl_SetStyleRatio:Informs the display driver of the aspect ratio of the pixels. Because PostScript does its own drawing, this function has no effect.

BITMAPS.C
This module contains functions that are used for bit map handling.


 * BeginImage:Outputs the PostScript code for the image command appropriate for the bit map format.
 * CompressAscii85:Encodes 4 bytes in to 5 bytes out, converting from a base 256 representation on input to a base 85 representation on output. The output is then output in ASCII with base 85 (zero digit = !) and base 85 (84 digit = u)
 * CompressMode2Out:Compresses a scanline. The compression is done according to LJ IIP Mode 2 compression: mixed binary and run-length encoding.
 * Once in a repeated run, if a different byte is encountered, the driver stops and emits a block.
 * Once in a literal run, if at least 4 repeated bytes follow, the driver stops and emits a block. The next block will be a repeat block. Repeats of 2 or more instances of a byte b are represented by -(n-1) b. Literal runs of different bytes b1 b2 b3 .. bn are represented by (n-1) b1 b2 b3 .. bn.


 * DefinePal:Defines the color table in PostScript that is used to translate between the sample indexes and the color values.
 * DrawImage:Projects an image of a rectangle on the source DC's bit map onto the printer.
 * ImageProcToChannel:Outputs the scanline data for the appropriate bit map format.
 * ImageScan:Outputs the scanline data for the appropriate bit map format.
 * PalGray:Converts an RGB color value into an 8-bit PostScript grayshade image value. Image values range from 0 to 255 where zero corresponds to black and 255 corresponds to white. Returns the grayshade value.
 * prdb_Bitblt:The GpiBitBlt function copies a bit map from one presentation space to another. It can also modify the bit map within a rectangle in a presentation space. The exact operation carried out by GpiBitBlt depends on the raster operation specified by the lRop parameter.
 * If lRop directs GpiBitBlt to copy a bit map, the function copies the bit map from a source presentation space specified by hpsSrc to a target presentation space specified by hpsTarg. Each presentation space must be associated with a device context for the display, for memory, or for some other suitable raster device. The target and source presentation spaces can be the same if desired. The aptl parameter points to an array of points that specify the corners of a rectangle containing the bit map in the source presentation space as well as the corners of the rectangle in the target presentation space to receive the bit map. If the source and target rectangles are not the same, GpiBitBlt stretches or compresses the bit map to fit the target rectangle.

If lRop directs GpiBitBlt to modify a bit map, the function uses the raster operation to determine how to alter the bits in a rectangle in the target presentation space. Raster operations include changes such as inverting target bits, replacing target bits with pattern bits, and mixing target and pattern bits to create new colors. For some raster operations, the function mixes the bits of a bit map from a source presentation space with the target or pattern bits, or both.

Comments:

The source and target presentation spaces can be associated with any device context having raster capabilities. Some raster devices, such as banded printers, can receive bit maps but cannot supply them. These devices cannot be used as sources.

GpiBitBlt does not affect the pels in the upper and right boundaries of the target rectangle. This means the function draws up to but does not include those pels.

If lRop includes a pattern, GpiBitBlt uses the current area color, area background color, pattern set, and pattern symbol of the target presentation space. Although the function may stretch or compress the bit map, it never stretches or compresses the pattern.

If the target and source presentation spaces are associated with device contexts that have different color formats, GpiBitBlt converts the bit map color format as it copies the bit map. This applies to bit maps copied to or from a device context having a monochrome format. To convert a monochrome bit map to a color bit map, GpiBitBlt converts one pel to the target's foreground color, and no pels to the current area background color. To convert a color bit map to a monochrome bit map, GpiBitBlt converts pels with the source's background color to the target's background color, and all other pels to the target's foreground color.

The bit map associated with a source presentation space is always a finite size. Although GpiBitBlt will copy a bit map when given a source rectangle that is larger than the source bit map or extends past the boundaries of the source bit map, any pels not associated with the source bit map are undefined.

Example:

This example uses GpiBitBlt to copy and compress a bit map in a presentation space. The function copies the bit map that is 100 pels wide and 100 pels high into a 50-by-50-pel rectangle at the location (300,400). Because the raster operation is ROP_SRCCOPY, GpiBitBlt replaces the image previously in the target rectangle. The function compresses the bit map to fit the new rectangle by discarding extra rows and columns as specified by the BBO_IGNORE option.


 * prdb_GetBitmapHandle:Returns the bit map handle.
 * prdb_ImageData:Outputs a scanline from a bit map.
 * prdb_SetPel:Sets the color value for a given pixel.
 * PrintColor:Outputs the RGB color in hex format on the output channel.

BOUNDS.C
This module contains routines for handling bounds.


 * prdg_AccumulateBounds:Causes the driver to add an additional rectangle to the bounds that it is accumulating.
 * prdg_GetBoundsData:This routine returns the current bounds rectangle that the driver has accumulated. A default rectangle is returned if no bounds data has yet been accumulated.
 * prdg_ResetBounds:Resets the driver's bounds accumulation.
 * prdl_ExpandBounds:This routine is the essential primitive for implementing accumulate bounds. The bounds rectangle in the DC instance is stretched so that it contains the new point passed in as a parameter.

BOX.C
This module contains box drawing routines.


 * prdl_BoxBoth:Draws the boundary of a rounded corner box and fills its interior.
 * prdl_BoxBoundary:Draws a boundary around a rounded corner box.
 * prdl_BoxCommon:Draws the boundary of a rounded corner box and fills its interior.
 * prdl_BoxInterior:Fills the interior of a rounded corner box.
 * prdl_BoxPath:Creates a path corresponding to the box primitives of the engine. Rounded corner boxes are implemented using Bezier curves and straight line segments.

CHARSTR.C
This module contains functions that are used in handling character strings.


 * CharStringDebug:This function is for debugging only. It writes character information options to the log file. Character information options includes starting point and clipping rectangle.
 * CharStringKern:Returns adjustments for kerning.
 * CharStringLeftRight:Displays a character string from left to right.
 * CharStringRect:Clips or fills the given rectangle, as requested.
 * CharStringReverse:Reverses a specified number of characters in a string, starting with the first ncharacters.
 * CharStringRightLeft:Displays a character string from right to left.
 * CharStringUpDown:Prints text vertically, in either an up or down direction.
 * CharStringWidthVector:Prints characters, accounting for a given width vector.
 * prdt_CharString:Draws a character string starting at the current position.
 * prdt_CharStringPos:Draws a character string starting either at a specified position or at the current position.
 * SetTextColors:Sets the background color and draws the background if necessary. It then sets the foreground color for the text.

CHARSTR2.C
This module contains functions used in font resource, character, and color handling.


 * ConcatXforms:Performs calculations for the concatenation of two transform matrixes that were provided from the function.
 * ConvertOFMtoPFM:Converts an OFM file to a PFM format.
 * ConvertPFM:Adds bounding box information to the PFM data.
 * FreeFontResource:Frees the memory of the font resource for this font.
 * GetPFMetrics:Given a pointer to a font resource, returns a pointer to the FONTMETRICS.
 * PfntFromIndex:Turn a font index into a pointer to the PFNT structure.
 * prda_BackMapChar:Determines what code point in the current code page corresponds to a given glyph (character pattern). If a match is found, this function returns it. If no match is found, it returns -1. If there is no code page vector, this font does not offer Winthorn multi-code page support. In this case, the provided glyph ID is simply returned as the code point.
 * prda_CheckFontResource:Confirms that the resource for the currently selected font is loaded. This function calls to load the resource corresponding to the currently selected font. A pointer to the header of this resource and a pointer to the font metrics within the resource are placed in the display context instance data.
 * prda_ComputeTextTransformMatrix:Computes a new text transform matrix from the character attribute bundle stored in the display context instance, and puts the new transform in the instance as well. This function recalculates the transform from scratch. This is necessary when any of the cell size, angle, or shear entries in the character attribute bundle change.

Warnings:

The transform matrix that is created will be suitable for converting points from Adobe style (1000x1000) units to world coordinate space. Because often the values already in world coordinate space need only to be rotated, the cosine and sine values that are calculated are also saved.


 * prda_CopyMetrics:Copies font metrics from the font resource to the caller's buffer, rescales the data to world coordinates, and inserts an lMatch value into the appropriate field of the caller's buffer.

This function copies the entire FONTMETRICS structure to a temporary buffer, rescales all values, inserts the lMatch field, and then copies the number of bytes requested to the destination buffer.

Warnings:

The number of bytes requested to be copied to the destination must not exceed the size of the font metrics structure, presently 208 bytes in length.


 * prda_DefaultFontIndex:Scans the list of all fonts offered by the current printer until one is found that matches the default font. The index of this matching font is then returned.

Warnings:

If no match is found, zero is returned. This will cause the first font in the printer's list of supported fonts to be used as if it were the default font. This situation should never arise naturally.


 * prda_DrawLine:Draws a line from the current position (assumed to be the end of the text) to the provided position (start of the text) at the specified elevation with regard to the text baseline and of the specified thickness. If no path is open, a line is drawn and stroked from the end of the text to the beginning of the text, adjusting both endpoints for the provided elevation. Current position, line type, line thickness, and line cap are all destroyed . If a path is open, a subpath is created and added to the current path. The subpath is actually a rectangle that outlines the requested line. The subpath is necessary for outline text and text pattern clipping. The current position and line attributes are destroyed.

Warnings:

It is assumed that the current position is on the baseline at end of the string that is being underscored or struck out. It is assumed that the major function has saved the current position and line attributes and will restore them later. This function must not be called if the draw bit is turned off.


 * prda_FontTransform:Transforms a point given in Adobe style (1000x1000) units into world coordinate space.

Applies the current text transform, held in the display context instance data, to the given point and returns the new point.


 * prda_GetKernAmount:Determines the amount of kerning space appropriate between the two given characters. This is in Adobe style (1000x1000) units. The value is signed; a negative value indicates that the characters should be pulled closer together and a positive value indicates that they should be pushed further apart.

Warnings:

The code points provided must be in the code page the font is designed for, not the code page the application is using. For fonts with Winthorn multi- code page support, this indicated that the code points must be in extended code page 850 form (presently a value 1-316).


 * prda_LoadFontResource:Loads the resource corresponding to the specified font and returns a pointer to the resource data.

Consults an internal table to convert the requested font into a resource number. Then DosGetResource is called upon to actually load the resource. If this is successful, a pointer to the loaded resource is returned.

Scans the array of fonts offered by this printer, counting filled Full Name entries.
 * prda_NumPrinterFonts:


 * prda_QuoteChar:Given a character code 0-255, the function puts the proper information into the buffer so that a show command in PostScript will display the character with this code. This will be one, two, or four bytes of printable ASCII characters. Codes, such as 65 (A) and 33 (!), are copied directly. Non- printable codes, such as 255, are put in the buffer in octal form (for example, \377). Some special characters (such as parentheses) require a backslash to be placed in front of them.

Warnings:

If enough buffer space is not available to hold the quoted form of the character code, the buffer is left unchanged and a value of zero is returned.

Converts an the text string of an application into a string suitable for sending to PostScript as an argument to a SHOW command. This conversion requires that the following four procedures be completed:
 * prda_RemapString:
 * Convert code points to the right code page
 * Possibly download a new font remapping to PostScript
 * Add backslashes before parentheses
 * Use octal for non-ASCII characters

This function scans the string, looking for troublesome code points (characters without a numeric value in the Adobe Standard Encoding). If the string contains any such characters and a font remap has not yet been downloaded to the printer, the remap is downloaded. Next, the string is scanned a second time, converting each code point to the proper code page, adding backslashes and octal digits as needed, and storing the final string in a buffer in the display context instance data.

Warnings:
 * The font remapping is downloaded only if absolutely necessary. The download causes a loss of performance.
 * The text buffer in the display context instance is limited in size (presently 256 bytes long). If the provided string is too long, it will be truncated. Therefore, it is the responsibility of the major functions to make sure this never happens. For example, CharStringPos will automatically break longer strings into shorter ones to avoid truncated text.


 * SetTextBackground:Used to paint the background of the area where text will be placed in order to simulate a background mix mode of overpaint. This function sets the color to either the current background color or to the color provided in the bundle. It then makes a path of the provided bounding box and fills the box.

Warnings:

This function should not be called if the draw bit is turned off.

Moves a member of font cache to top of list. The function keeps exchanging two ajacent members until the element is "bubbled" to the top.
 * ToTop:

COLORTAB.C
This module contains color table functions.


 * ColorDistance:Computes the distance between two RGB color values. The distance is the average of the absolute values of the differences between each of the primary color values. The difference ranges from 0 to 255. If the device is a greyscale printer, the color differences are weighted according to the response of the human eye to the primary color.
 * prdc_CreateLogColorTable:Creates the driver's color table.
 * prdc_GetColor:Performs a color table lookup to convert an engine color value into an RGB color.
 * prdc_QueryColorData:Allows the application to determine the format and size of the color table.
 * prdc_QueryColorIndex:Searches the color table for an RGB value and returns the color table index of the closest color.
 * prdc_QueryLogColorTable:Returns the RGB color values stored in the logical color table with no conversion.
 * prdc_QueryNearestColor:Takes an RGB color value as input and returns the closest RGB color value that can be drawn on the device. Because PostScript processes shades of gray, this will be an RGB triplet with each of the components set to equal values.
 * prdc_QueryRealColors:Allows the application to determine if the RGB color values are in the color table as they are realized on the device.
 * prdc_QueryRGBColor:Allows the application to determine if the RGB color values are in the color table.
 * prdc_RGB_to_Solid:Returns a solid color for that device.
 * prdc_RgbToGray:Converts an RGB color to the a grayshade value that ranges from 0.0 to 1.0 (fixed point).
 * prdc_RgbToNearestRgb:Converts an RGB color to the nearest color available on the output device. For black-and-white printers, this will be one of the half-tone grayshades.
 * PrintColorTable:Used only for debugging. This function dumps color table information to the log file.

CONFIG.C
This module contains functions for the Printer Properties and Job Properties dialog boxes and for the help function.


 * CheckNumeric:Checks the string to see if it is a valid numeric string. The plus and minus signs as well as the decimal point are checked. Only one decimal point is allowed per string.
 * CleanUpHelpStubHook:Exit list routine that ensures that the stub HK_HELP hook is always removed before exiting.
 * DeviceModes:Called from to perform tasks such as open printer descriptor resources and display dialog boxes.
 * get_module_dir:Returns the size of the directory path.
 * HelpErrorFilter:Checks for a recoverable help manager initialization error. If a recoverable error is detected, a message box pops up. The message box describes the error and asks if the user wants to retry.
 * HelpStubHook:Placed in the HK_HELP hook chain to catch the first time that the user presses PF1 or selects a Help push button. The help instance is then initialized and the user's help request is passed back into the HK_HELP chain again by making a call to the private function WinCallHelpHook.
 * InitializeHelp:Initializes help. If an attempt to create a help instance has already been made, the function returns immediately.
 * PrintFontMem:Sends a status page to the printer. The sheet contains the amount of printer memory and the number of suggested fonts for that amount of memory.
 * QueryUserForm:Retrieves a form name from a given form size. It searches OS2SYS.INI if a form name cannot be found.
 * ReleaseHelpStubHook:Removes the stub HK_HELP hook from the hook chain, if it has been successfully added via.
 * SetHelpStubHook:Adds the stub HK_HELP hook to the hook chain. This gives the driver control the first time that the user presses PF1 or selects a Help push button.
 * szDlmCopy:Copies a string from the source to the destination. If the string is NULL- terminated, the copy action stops when the terminator is encountered. If the source string encounters a semicolon, the copy action stops; otherwise, the copy action continues for the number of bytes passed in.
 * szNewCopy:Copies a string from the source to the destination. If the string is NULL- terminated, the copy action stops when the terminator is encountered; otherwise, the copy action continues for the number of bytes passed in.
 * sznIsEqual:Compares two NULL-terminated strings. This function returns TRUE if the strings match and FALSE if the strings do not match. The comparison is case sensitive.
 * ValidFileName:Checks if the file name specified in pszBuffer is valid. The check is purely syntactic. No check for the existence of the file is performed. If an error is not discovered in this function, DosOpen can return an error code at a later time.

DEVBLOCK.C
This module contains routines that verify data for the driver and maintain the physical and logical device blocks.

PM_DD_,. The informaton is extracted from the INI file under the key of PM_SPOOLER_ PRINTER. If the information cannot be found, the defaults can be used as long as the type of device is known.
 * AllocateLDRIVDATABuffer:This function creates an LDRIVDATA structure for output, copies the data from the incoming LDRIVDATA structure (DRIVDATA part only) to the DRIVDATA section, and copies the local CNFDATA structure (allocated in ) to the CNFDATA section:
 * BuildKeyName:Builds the key name in form of:
 * ClearMem:Clears the first cbytes of a buffer (sets all bytes in the buffer to zero).
 * CmndInpTray:Returns a pointer to the input tray select command.
 * CmndPaper:Returns the paper select command.
 * ConvertColorModel:In PPD version 4.2 and later, the UI string "ColorModel" allows the printer to render a job to the supported color or grayscale. This enables the printer to convert jobs to grayscale if selected; the driver can also convert color internally to grayscale if selected. It is preferred that the printer do the conversion because the printer is fine-tuned for better output.
 * In earlier versions of the driver, ColorModel was not supported and the driver did all the conversion. In order to be backward compatible, this driver needs to know when to let the printer do the conversion or when it should do the conversion.
 * This function is responsible for assuring that the correct flags are set so that the right component does the conversion. This is only needed when printing across the LAN since that is the only case where it should be possible to encounter earlier versions of the driver.

"KEYWORD1,OPTION1A,OPTION1B,...OPTION1N;KEYWORD2,OPTION2A,...OPTION2N" with the KEYWORD being the block name and OPTION being the UI entry corresponding to each bit that was set in the UI_SEL list.
 * ConvertUIBitsToStrings:With a given list of selected bits from the UI_SEL array in the CNFDATA structure, this function converts the bits to matching strings in the following format:

The reason for this is to be compatible with other versions of the OS/2 keyword selection. If a printer adds a new keyword name and this is passed across the LAN, no matter what keywords are added, the keyword will always remain the same. If new keywords are added, the comparison will be against the string rather than against the UI_SEL bits (which can change if a new keyword is added). This string buffer is stored in PDV, which is passed onto the spooler.

The only exception in this conversion is with the *InputSlot keyword. The user may have selected Auto Tray Select, meaning that no InputSlot command should be sent. This is so that the printer can select the tray. If this is the case, the UI selection for InputSlot will be -1. If it is -1, the string AUTOTRAYSELECT is inserted. When the function OutputPrinterUIFeatures (in ) queries the InputSlot block for AUTOTRAYSELECT, it will return an error indicating that the string could not be found. Therefore, no InputSlot command will be sent out. The usTermCode parameter specifies the reason the process ended. This parameter can be one of the following values:
 * CopyLDRIVDATAToCNFDATA:The purpose of this function is to copy the CNFDATA and UI-Selection contents from an LDRIVDATA structure to a CNFDATA structure. LDRIVDATA structure is passed in to FillPhysicalDeviceBlock and is initialized by an outside component. The (output) CNFDATA structure is a locally allocated buffer.
 * Exitpdd:Called when processes are terminated.
 * Value Meaning
 * TC_EXIT Normal exit
 * TC_HARDERROR Hard-error abort
 * TC_KILLPROCESS Un-intercepted DosKillProcess
 * TC_TRAP Trap operation

The important reason for using this routine is that the process might have ended unexpectedly, such as by a General Protection fault. If the process is holding a semaphore, it must be released so that the termination of this process does not cause the entire system to lock up while waiting on a semaphore that will never be freed.


 * FreeMemory:Frees all the memory allocated from heap.
 * FreePPBResource:This function frees all the buffers allocated in.
 * ImageCoords:Returns a pointer that contains the size, in pels, of the image coordinates.
 * LoadCurrentUISelections:This function loads the current UI (printer feature) data into the CNFDATA structure. It first looks into the INI file for the selections. If found, they are loaded. If not, the default UI selections are read from the PPB resource (taken from the *Default... key in the *OpenUI/*CloseUI).


 * LoadInfoSegment:The printer information data is located in the variable SegName. This routine locates the segment and loads it into memory resident tables. If the load is successful, it returns TRUE; otherwise, it returns FALSE.
 * LoadPPBResource:With a given device name, this function returns the matching PPB resource.
 * LoadProfile:Loads the configuration data from OS2SYS.INI.
 * MatchHWFontName:Scans the list of all fonts offered by the current printer until one is found that matches the requested font. The index of this matching font is then returned. If no match is found, 0 is returned.

Warnings:

Fonts have two different names. The FullName is the most complete (for example, "ITC Avant Garde Gothic Book Oblique"). However, the font names used in the printer font list have an abbreviated form, such as "AvantGarde -BookOblique".

This function sets up the dispatch table for the graphics engine, calls display.dll to get a dispatch table for its entry points, and sets the return flags to tell the engine that:
 * PaperDimensions:Returns a pointer that contains the size, in pels, of the page dimensions.
 * PpdDefaults:Reads in default values from a PPD information segment into default types if they still do not contain any values.
 * prde_DisablePdb:Disables the pDeviceBlock subfunction.
 * prde_FillLdb:This is Enable Subfunction 1 of.
 * Bit 0 == 1 Each DC requires its own physical device block.
 * Bit 1 == 0 Multiple DCs might coexist.

Device/File names in the DevOpenStruc are significant. When the display driver is loaded, the PostScript driver calls the display driver as if the PostScript driver were the graphics engine module. This continues while the PostScript driver is using the display driver as its imaging engine. The display driver sees the DC as a memory DC while the engine sees it as a printer DC.

Note: The initialization process is serialized with semaphores because it is possible for more than one process to have performed an OpenDC at the same time. However, the process must first be placed in the ExitList because when any process grabs a semaphore, the driver must be able to free the semaphore if the process terminates unexpectedly.
 * prde_FillPdb:The information supplied on this call is required only for Direct and Indirect DCs, but at this stage the DC Type is not known. It is supplied on the Enable DC subfunction.
 * The function acquires pDeviceBlock Instance Data (from the global Device Driver Heap) for all DCs, and (optionally) releases it when the DC Type is known.

"*OpenUI *keyword" except the keyword should not include the asterisk.
 * ProfileAllocStringQuery:Queries the size, in bytes, of a buffer needed for a string from the OS2. INI file. It then allocates the memory and copies the profile string to the buffer. This is used to retrieve profile strings of variable sizes. This function frees the profile-string buffer if an error occurs, but it is the programmer's responsibility to free the buffer if this function returns successfully. This function uses PSAllocMem to allocate memory to the buffer, so PSFreeMem should be used to free memory.
 * QueryBlockFromKeyword:With a given keyword string, this function finds the matching block for the given keyword. The keyword must be the same keyword that is found in the PPD:

This function not only returns the pointer to the matching block, but it also returns (if requested) the zero-based offset of the returned block in respect to the location of that block in the list. For example, if the block returned is the first block in the list, 0 is returned; if the block returned is the second block in the list, 1 is returned.
 * QueryDefDrivFromQue:If a pointer to a DRIVDATA is invalid, this function queries the current queue for the current DRIVDATA.
 * A DRIVDATA is considered invalid if the pointer is NULL or if the size is smaller than the DRIVDATA size of OS/2 version 1.3. In either case, the DRIVDATA from the queue is queried.
 * Memory is allocated to a return pointer and the queue's DRIVDATA is copied.


 * QueryEntryFromOption:With a given option string, this function finds the matching entry within a given block for the matching option.
 * QueryUIOptionString:This function retrieves a given keyword (UI block name) and returns the first option (UI entry name) that is selected. For multiple selections, this function can be called in succession; and it returns the next selected option found until the end occurs. This function returns a pointer to the option string. The option string is stored in pdesppd->pPSStringBuff.
 * SaveCurrentUISelections:This function saves the current UI selections made by the user. The UI data are stored as strings in the INI file. The key string used for the UI strings is UI.
 * ScanString:This function searches for a given substring within a string. It returns TRUE if the substring is found.
 * SetCanvasMetrics:Sets the canvas metrics (size and orientation) for the physical device.
 * SetUIOption:This function retrieves a given keyword (UI block name) and option string ( UI Entry name) and sets the matching bit in the UI-Selection entry for the given string data.
 * szDCopy:Duplicates an NULL-terminated or delimiter-terminated string with bounds checking to prevent overflow of the destination buffer.
 * ValidateDriveData:Performs some checking to make certain that valid drive data is passed in. This routine returns TRUE if the drive data is valid; otherwise, it returns FALSE.
 * VerifyUISelectionList:This function verifies that the data in the UI-Selection list is valid. Each bit in each entry of the UI-Selection list corresponds to a selection that the user has made in Job Properties. There are at most 32 selections for a given entry. If a bit is 1, the selection was made. This allows a user to make multiple selections (if available) for a given UI entry.

DEVESC.C
This module contains driver escape routines.


 * perform_std_spooling:At the end of spooling activities, this function writes the metafile data to the spooler.
 * prdq_AbortDoc:Terminates a document and sends commands to reset the device.
 * prdq_EndDoc:Ends a document. This routine is supported only if an OD_QUEUED DC is provided. This routine is used to establish the end of a spooler print job.
 * prdq_Escape:Dispatches to the appropriate escape function.
 * prdq_NewFrame:Handles the DEVESC_NEWFRAME call (a form feed).
 * prdq_QueryEscSupport:Returns TRUE or FALSE, specifying whether the given escape routine is supported by the driver.
 * prdq_StartDoc:Starts a document. This routine is only supported if an OD_QUEUED DC is provided. This routine is used to establish the start of a new spooler print job.

DEVMODE.C
This module contains the function and other functions used to retrieve the printer name.


 * AllocCNFStructure:This function allocates memory for the CNFDATA structure. This includes memory allocation for pSourcePaper and the UI-Selection list. The UI- Selection list is a buffer that immediately follows the CNFDATA structure in the buffer.
 * CheckPrinterName:Given logical name of printer, this function will check if it has any PostScript printers of the requested type.
 * CopyCNFData:This function copies the contents from one CNFDATA structure to another. This copy includes copying data from one pSourcePaper and the UI-Selection buffer to another of their respective buffers. This is providing that there is a buffer to be copied.
 * FreeCNFStructure:This function frees the CNF structure and all buffers that are used by pointers within the structure.
 * GetPrinterName:Checks the default device, and then all other devices, for the first match of the requested device name.
 * OS2_PM_DRV_DEVMODE:The DevPostDeviceModes function causes a device driver to post a dialog box so that the user can set options, such as resolution and font cartridges, for the device.
 * The application can call this function first with a NULL data pointer to determine how much storage is needed for the data buffer. It then calls the function a second time to have the buffer filled with data. The returned data is then passed to the DevOpenDC function as the buffer data pointed to by the pbDriverData parameter.


 * VerifyLDDCNFStructure:This function verifies whether or not the contents of the CNFDATA structure within the LDRIVDATA structure are valid. Verification includes whether or not:
 * The UI-Selection buffer offset (ofsSelectList) contains the current offset value where the UI-Selection buffer is located. This value is the size of the CNFDATA structure.
 * The UI-Selection buffer contains valid data.

DLG.C
This file contains common functions accessed by both Printer Properties and Job Properties.


 * ClosePSDlg:This function closes the dialog box for Printer Properties and Job Properties.
 * DisplayFeaturesUIEntries:Every time a feature is selected in Features, this function displays the available list of features in the lower listbox. If the feature supports only one selection, the options are displayed in a drop-down listbox. If the features supports multiple selections, the options are displayed in a standard listbox.
 * DisplayMessageBox:With a given message ID, this function queries the message and displays a message box with that message string. An optional title ID may be provided. If no title ID is provided, the string Error is displayed as the message- box title.
 * FillFormList:This function displays all available form names (both printer-defined and unique forms) in Printer Properties and Job Properties.
 * For Printer Properties, it displays all available forms defined by the printer as well as all unique forms (provided that bDisplayUnqForms is TRUE ). For Job Properties, it displays all forms if "Display assigned forms only" is not checked in Printer Properties. If it is checked, then this function will only display the forms that are mapped to one or more trays. It will also list the default form (provided by pszDefString). If pszDefString is NULL, then no form is highlighted.


 * FillTrayList:This function displays all available tray names in Printer Properties and Job Properties.
 * For Printer Properties, it displays all available trays defined by the printer. "No Forms Selected" is also on the list for any form that is not mapped to a tray.
 * For Job Properties, it displays all trays that have been mapped to a given form (this mapping is defined in Printer Properties). If a given form has no (zero) mapped trays or two or more mapped trays, then "Auto Tray Select" is displayed. This allows the printer to decide where to select the form.
 * If a default tray is provided, and a matching tray string is found in the tray list, then the matching tray string is highlighted. If pszDefString is NULL, then no form is highlighted. If a default handle is provided, then all tray entries are set to that handle. If none is provided, then the handle for each tray entry is the zero-based offset of that tray entry as it is found in the PPD. For example, if "Upper" is the first tray in the PPD, then the handle is 0. All trays are listed in the same order as they are found in the PPD.


 * FreeDialogHeader:This function frees all memory allocated in.
 * InitializeDialog:This function initializes the dialog box. This includes inserting the pages into the notebook and setting the title string.
 * InitializeDialogHeader:Initializes the DLGHDR structure. This is the dialog header containing data used by the dialog box.
 * InsertPageInNotebook:Inserts a dialog into the notebook and sets up the status text line on top of each page. This includes inserting the address of the dialog header in the dialog's reserved doubleword (QWL_USER).
 * InsertStringInListbox:This function inserts a given string in the listbox, associates a given handle with the listbox string (if provided), and returns the index in the listbox where the string is located. If a default string is provided and the inserted string matches the default, the string is highlighted.
 * ListUniqueForms:This function lists all user-defined and custom forms in the Forms listbox. It sets the handle of each entry to the offset of where the mapped form is in the UI list. The high word bit is set to 1, however, indicating that the form is a unique form.
 * QueryMappedTray:With a given UI-Control handle, this function returns an address to the Dialog Header.
 * SetSysMenuFields:This function removes the following menu items from the System Menu: Restore, Size, Minimize, Maximize, and Hide.
 * SetTabTextSize:This sets the notebook tab size to the largest tab string used.
 * VerifyAndSaveSettings:This function sends a WMPS_VERIFYSETTINGS message to all of the pages in the notebook. If all pages return a successful code (PSDRC_VERIFY_SUCCESS), a WMPS_SAVESETTINGS message is sent to all of the pages. If this function is called from Printer Properties, the UI data is saved in the OS2SYS.INI file.

DOWNLOAD.C
This module contains functions that are used in downloading fonts.


 * CopyStr:Copies a string from the source to the destination.
 * DefaultFontCount:Returns the number of default fonts available for given printer memory.
 * FillOFMFont:Reads OS2.INI for any OFM fonts and loads their names into memory.
 * FillSFonts:Fills in the FNT structure for each of the available soft fonts at the specified address.
 * GetPM_Fonts:Retrieves a list of font file names from the OS2.INI file.
 * isHWFont:Verifies if a given font name is a printer font. Returns TRUE if the font is a printer font.
 * IsOFMFile:Verifies if a file is a valid OFM file by checking for the extension .OFM.
 * LoadFile:Opens and reads in a file and returns a pointer to it.
 * ReadHeader:Reads the PPB file header. This function returns TRUE if it is valid (and not EOF). Writes out ASCII portion of the PFB structure and the binary part, converting it to hex.
 * rwASCblock:Writes out the ASCII part of PFB.
 * rwBINblock:Writes out the binary part, converting it to hex.
 * SendPFB:Parses and sends a PFB file.
 * SFDownload:Downloads a soft font.
 * SFQueryFonts:Queries the number of soft fonts available. This function returns the number of soft fonts available, or 0 for an error.
 * SFReadOFMs:Acts as combined and, depending on what arguments are passed in. If cFnt is 0, a count is returned. Otherwise, a list of OFM files is received from .INI and the FNT structure is loaded from the OFM files.

ENABLE.C
This module contains functions that are used when the device context is initialized or disabled.

The OS2_PM_DRV_ENABLE entry point handles the DC management functions. Those functions can be placed in three categories: Opening and Closing DCs
 * FreePathBufs:Frees the path buffer and the clip buffer.
 * init_semaphores:Creates semaphores that are used to control access to ports (LPTx and COMx).
 * OS2_PM_DRV_ENABLE:Switches to the required Enable subfunction.
 * Transactions involved in opening a DC.
 * Transactions involved in closing a DC.
 * Other DC functions. This includes SaveDC, RestoreDC, and ResetDC.

The open and close transaction sequences are symmetric:
 * Open Transactions Close Transactions
 * FillLogDevBlk No Equivalent
 * FillPhyDevBlk DisablePhyDevBlk
 * EnableDC DisableDC
 * CompleteOpenDC BeginCloseDC

Each of the Close Transactions undoes the actions taken by its corresponding Open transaction. For example, the EnableDC function allocates the DDC data area within the driver and returns the HDDC handle to identify that area. The corresponding Disable DC function invalidates the HDDC handle and deallocates the DDC data area.

The FillLogDevBlk transaction occurs when some thread of a process opens the first instance of a DC for this driver. During this transaction, a dispatch table will be created for later use by the graphics engine.

Except for the OS2_PM_DRV_ENABLE, and  calls, all DDI interface calls are dispatched through the function table created here. This means that most calls go directly to the correct function rather than indirectly through a hierarchy of function layers.

The FillPhyDevBlk transaction will occur only if the result flags from the FillLogDevBlk transaction indicate that it is necessary. It is used by device drivers that support multiple types of physical devices. It will occur during the DevOpen for the first DC associated with a particular type of physical device.

This function is responsible for memory allocations and initializations relating to a physical device.

During the EnableDC transaction, the driver will allocate and format the driver-specific data (the DDC) associated with the DC being constructed.

At CompleteOpenDC time the DC is completely constructed and initialized. This transaction gives the driver an opportunity to make final adjustments to the DC before the application gains access to it.

Saving and Restoring DCs

These functions manage a stack of entries that correspond to most of the states of a DC. SaveDC pushes an entry on the stack. RestoreDC retrieves one of the pushed entries and uses it to revert the DC back to its earlier saved state. Note that a particular RevertDC call might pop more than one entry from stack of SaveDC entries.

Resetting DCs

This call resets a DC to its original initialized state as it was just after the CompleteOpenDC transaction.


 * prde_DeleteSavedDCs:Frees all heap space used by extra DDC structures that were created by Save DC requests.
 * prde_DisableDC:Disables the DDC and releases its memory.


 * prde_EnableDC:Implements subfunction 5 of the enable entry point called by the engine. This subfunction is called to create a driver device context (DDC). This DDC will be linked to the device descriptor structure (DV) that was already created. Every engine DC will have its own DDC and DV in the driver. Also, a memory DC will be opened in the display driver for use with this DC. The types of DC are:
 * OD_QUEUED Produces spooled output
 * OD_DIRECT Sends output directly to a file
 * OD_INFO Used to retrieve information, but no output is updated.
 * OD_METAFILE Not currently supported
 * OD_MEMORY Uses display driver to manipulate bit maps

If this function is called to open a memory DC, only a portion of the DDC structure will be created because the display driver will be doing most of the work.


 * prde_ResetDC:This routine is Enable subfunction 9. It resets the DDC state.
 * prde_RestoreDC:This routine is the RestoreDC Enable subfunction. It restores the DDC to a previously saved state.
 * prde_SaveDC:This routine is the SaveDC Enable subfunction. It saves the DDC state.
 * prde_SetDDCDefaults:Initializes the values in the DC instance data structure to their default values.

ERRORCHK.ASM
This module contains functions that are not used by the 32-bit driver.

FLCHKDLG.C
This module contains functions that verify PostScript devices and open a dialog box to confirm if the user wants to overwrite an existing PostScript file.


 * CheckForOverwrite:Responds to commands received from user input. The user can select OK or Cancel and change the file name entry field. If file name is not changed when user selects OK, the dialog box will return the OVERWRITE message to the calling function.


 * IsFilePipe:Checks for file pipe.


 * R3_FileCheckDialogs:Performs one of the following three actions. The actions depend on various parameters.
 * If the file to which the PostScript output is destined already exists, a dialog box is displayed that asks if the user wishes to overwrite the displayed file.
 * If the file name is valid and does not exist, control is returned to the function where output to the file will continue normally.
 * If the user specifies an invalid file for output, a dialog box asking the user to enter another file name is displayed.


 * UserFileInvalid:Responds to commands received from user input. The user can press OK or Cancel and change the file name entry field.

FONTS.C
This module contains font support functions.


 * CPDownLoaded:Returns TRUE if the passed in code page has been downloaded to the printer; otherwise, it returns FALSE.
 * FontDownload:Downloads a soft font, if necessary.


 * MatchFaceName:Scans the list of all fonts offered by the current printer until one is found whose face name is the same as that requested. The index of this matching font is then returned. If no match is found, -1 is returned.

Warnings:

Fonts have two different names. The full name is the most complete (for example, "ITC Avant Garde Gothic Book Oblique"). This is the name used for matching. However, the font names used in the printer font list have an abbreviated form, such as "AvantGarde-BookOblique".


 * prda_CountKernPairs:Counts the number of kerning pairs that are available for the current font and code page. This number can be different from the maximum number of kerning pairs available if some kerned characters are not in the current code page.


 * prda_DeviceQueryFontAttributes:Copies the entire FONTMETRICS data structure to a temporary buffer, rescales it, and copies the requested amount to the caller's buffer.

Warnings:

A request for more bytes of information than are contained in a FONTMETRICS structure will be silently reduced to a request for exactly as many bytes as are in a FONTMETRICS structure.


 * prda_DeviceQueryFonts:Copies the FONTMETRICS data for the requested font to the caller's buffer. If the given face name is null, the data for all fonts will be returned, buffer size permitting.

On return, pulNumFonts will have been changed from the maximum number of fonts the caller would like returned to the actual number of fonts returned in the caller's buffer. This will either be zero (an invalid font face name was given), one (a legitimate face name was given), or a larger number. The latter case would occur if the caller gave a null font face name. In that situation as many fonts would be returned as could be fit into the caller's buffer.

Warnings:

A request for more bytes of information than are contained in a FONTMETRICS structure will return an error.

Because the driver currently does not distinguish between public and private fonts, the options parameter is ignored.


 * prda_GetCodePage:Returns the code page that will be used for characters written with the default font.

Warnings:

This routine returns the code page only for the default font. If the current font is a logical font, the code page number returned here might not be the same as the code page number currently in use.


 * prda_GetPairKerningTable:Copies kerning pairs from the internal table to the caller's buffer.

This function scans the internal kerning table and copies entries one at a time to the caller's buffer until it reaches the end of the table or has copied the desired number of pairs. The internal kerning table lists code points in the font's code page (usually extended code page 850). The kerning amount is converted into world coordinates before being returned to the caller.

Warnings:

If the font supports extended code page 850 and the caller is using a code page that is a subset of this, it is possible for a kerning pair to refer to a character that does not exist in the caller's code page. Such kerning pairs will not be returned to the caller. Therefore, it is possible for the caller to get back fewer kerning pairs than were requested, even if the caller asked for the exact number of kerning pairs offered by the font.

This function does not sort the kerning pairs in any order.


 * prda_QueryWidthTable:Returns the widths of characters in the currently selected font. This function copies a portion of the character width table of the currently selected font into the caller's buffer, converting it into world coordinates and translating points into the caller's code page.

Warnings:

The width of the default character will be returned in the place of any invalid character. An invalid character is one with a code point less than zero, greater than 255, or outside the range supported by the font.


 * prda_RealizeFont:Attempts to match a device font to a requested logical font and returns a LONG handle to the font if successful.
 * pfatLogFont:Pointer to a FATTRS structure containing logical font information if this is a RF_DEVICE_FONT command.
 * lFontHandle:Handle of the logical font to be deleted, if this is an RF_ DELETE_FONT command.
 * RF_DEVICE_FONT:Attempt to match font, return handle.
 * The PostScript driver will always return a matching device font unless a code page is requested that we cannot support. If a legitimate code page is requested but no match is provided and the facename cannot be matched, the default font will be used. The algorithm used is:
 * Check the lMatch field of the FATTRS structure. If it is positive, it is downloaded as a PFB. If it is negative, the font is treated as a device font; otherwise, if a font name is provided, the driver attempts to match it to one of the font names in the list of fonts supported by the current printer. If a match is found, the matched font is selected. If a match is not found or if the font name is null, the default font is chosen.
 * As soon as a font has been chosen, the driver must handle code pages. If the usCodePage field of the FATTRS structure is zero, the driver simply chooses the code page provided by the font. Otherwise, it tries to get a mapping vector from the requested code page to the code page supported by the font. If the driver cannot get such a vector, the font is not realizable, and the driver returns zero to the engine.
 * As soon as a font has been chosen and a suitable code page mapping vector has been found, the driver looks for space in the logical font information table in the PDDC. If an entry is free, the driver allocates it, initializes its records, and returns the negative of the index as the 32- bit handle. If the table is full, an error must be returned.


 * RF_LOAD_ENGINE_FONT:Return 0L, font can't be realized.
 * The driver always returns 0L.


 * RF_DELETE_FONT:Attempt to delete font with handle specified.
 * If the handle provided is legitimate, the driver erases the corresponding font from the logical font information table and returns 1L. Otherwise, it must return an error. If the provided handle corresponds to the logical font currently in use, the driver selects the default font before deleting the logical font.


 * prda_SetCodePage:Sets the code page for characters written with the default font.
 * This function stores the requested code page number in the DDC. If the default font is currently selected, the current code page number is changed as well.

Warnings:

This routine is only used to change the code page of the default font. A logical font's code page is selected at CreateLogicalFont time and cannot be changed.


 * RemapBoldItalic:Called when the driver is about to realize a font and the BOLD or ITALIC, or both attributes have been set. This routine maps the given font into the appropriate font, depending on which attributes have been set. For example, if the user chooses Courier as the font and has the BOLD attribute set, this routine will select Courier-Bold as the font.
 * RemapCodePage:Called by the driver to download a new font definition to the PostScript printer.
 * szLength:Calculates the length of a given string, including the terminating NULL.

IMG2BIN.C
This module reads a file containing a list of PostScript commands for handling images and stores the commands in a binary file which is later added as resource to the driver by the C compiler. Each set of commands in the list is used to tell the device how much image data (in bits) is to be processed at a time.

This module contains functions that are used in image handling.
 * szIsEqual:Compares two strings (case sensitive). Returns TRUE if the strings are equal; otherwise, it returns FALSE.

JPDLG.C
This module contains functions needed to maintain the Job Properties dialog box. The functions are listed below.


 * DisplayGammaValue:Displays the gamma value for the "Red"," Green," or "Blue" gamma values. Since all gamma values are stored internally in multiples of ten, the values are divided by ten before being displayed. For example, a gamma value of 25 is displayed as "2.5".


 * EffectsPageDefaultControls:Sets all the settings to the default values for the Effects page. For some controls, the default values are specified in the PPD.
 * EffectsPageDlgProc:This is the procedure for the Effects page in the Job Properties dialog box.
 * EffectsPageInitControls:This function initializes the controls for the Effects page.
 * EffectsPageSaveSettings:This function is only called if the user selects the Save button. All controls for the Effects page are saved here.


 * FeaturePageDefaultControls:Sets all the settings to the default values for the Features page. For some controls, the default values are specified in the PPD.
 * FeaturePageDlgProc:This function is the procedure for the Features page of the Job Properties dialog box.
 * FeaturePageInitControls:This function initializes the controls for the Features page of the Job Properties dialog box.
 * FixUpColors:If the Lock Proportions check box is selected, this increments or decrements the other two sliders every time one slider is incremented or decremented.
 * FormPageDefaultControls:Sets all the settings to the default values for the Forms page. For some controls, the default values are set as specified in the PPD. For the Orientation control, Portrait is set as the default value.
 * FormPageDlgProc:This function is the procedure for the Forms page in the Job Properties dialog box.
 * FormPageInitControls:This function initializes the controls within the .Forms page in Job Properties. Initialization includes setting minimum and maximum values as well as setting the intitial settings.
 * FormPageSaveSettings:This function is only called if the user selects the Save button. All the controls in the Forms page are saved here.
 * GetAndSaveColorModel:Sets the current color setting and sets the matching color icon in the Status Bar. If the color device supports ColorModel, the setting is saved in the User-Interface (UI) selection; otherwise, the setting is saved in the CNFDATA structure.
 * GetOffset:Queries the current slider position, and calculates the gamma value from that position.
 * InsertSliderValues:Displays the numeric values that are displayed above each slider control.
 * JobPropertiesDlgProc:This is the procedure that maintains the Job Properties dialog box.
 * OutputPageDefaultControls:Sets all the settings to the default values for the Output page. For some controls, the default values are specified in the PPD.
 * OutputPageDlgProc:This function is the procedure for the Output page in the Job Properties dialog box.
 * OutputPageInitControls:This function initializes the controls within the Output page.
 * OuputPageSaveSettings:This function is only called if the user selects the Save button. This function saves all the settings for the Ouput page.
 * QueryFeaturePageLoad:This function queries the UI list to verify whether or not the Features page is to be loaded. For Printer Properties, the list is queried to see whether or not there are any installable options. For Job Properties, the list is queried to see whether or not there are any non-predefined or non- OEM features. If any of the above conditions exists, the function returns TRUE; otherwise, FALSE is returned.
 * SaveGammaVals:Queries the slider position, and saves the gamma value.
 * UpdateDuplexSelection:This function modifies the UI selection for duplex and modifies the icon for the Status Bar every time a duplex option is selected.
 * UpdateTrayList:This function updates the tray listbox with trays that were mapped to forms in Printer Properties. The only trays displayed are the ones that were mapped to the currently selected form in the "Forms" listbox. In addition to the trays, "Manual Feed" is displayed at the bottom of the list. "Auto Tray Select" is displayed at the top of the list only if more than one tray or no trays are mapped to the current form. This is because the driver must be able to display all the forms in Job Properties, whether they are mapped to a tray or not. If a form is selected with no mapped trays, then "Manual Feed" is the only string displayed that will not be highlighted (unless selected), so the listbox entry field may be empty. To prevent this, "Auto Tray Select" is added to the list.

The currently selected tray is retrieved from aTraySelected in CNFDATA and highlighted. If aTraySelected does not contain a string, then the default tray is retrieved from the PPD. If "Auto Tray Select", "Manual Feed", and any other tray is not selected for some reason, the first item in the listbox is selected.

MATH.ASM
This module contains math routines for the driver.


 * BigMulDiv:Extended precision multiply-divide routine. The first two long-word parameters are multiplied and the product is divided by the third long-word parameter.
 * CopyAndNormalize:Interface between copy_and_normalize and the PostScript code.
 * LongMulFixed:Extended precision multiply routine, intended to emulate 80386 mul instruction.
 * ulNormalize:Returns the number of shifts needed to shift the passed ULONG number so that the highest order bit is 1.

MEMORY.C
This file contains memory handling routines for the PostScript printer driver for Presentation Manager (PM). A global heap is created permanently when the logical device block is filled (in ). This is a permanent heap because, under OS/2, as soon as a device driver has opened a DC, the driver is loaded in memory until the maching is turned off or restarted. The global heap can also be created by and. If the logical device block exists at the time either of these routines is called, no new heap is created. These two routines will just use the global heap created by. If, however, the logical device block does not exist at the time either of these routines is called, they will create and initialize the global heap, and then destroy it.


 * _DLL_InitTerm:Called when a process loads or unloads the driver DLL. See the LIBRARY statement in the .DEF file.
 * CreateDCHeap:Allocates an object, and then creates the driver's process heap in that segment.
 * CreateProcessHeap:Allocates an object, and then creates the driver's process heap in that segment.
 * ExceptHandler:Handler for exception management.
 * GetR3String:Given a string ID, this function returns to the caller the pointer to that given string. It is called by ring 2 routines, which need to access these ring 3 strings in StringTable.
 * InitGlobalHeap:Creates the driver's heap, gets and stores the driver's module handle, and then loads the string table from the resources.
 * KillGlobalHeap:Deletes the driver's heap and resets some global heap variables.
 * KillHeap:Deletes the driver's heap.
 * LoadStringTable:Loads a string table from the resource file into a global data structure.
 * SetLDBFlag:Sets the fLogicalDeviceBlock to TRUE, indicating that the logical device block now exists.

MANDFUNC.C
The functions in this module have been moved to NOINSTAL.C for the 32-bit driver. For more information about the functions found in this file, see NOINSTAL.C.

NOINSTAL.C
This module contains functions that hook graphics engine routines. It contains stubs for routines that are not supported by the PostScript driver. These functions will usually return an error or will not perform any processing, except in certain circumstances.


 * prdb_DeviceCreateBitmap:Hook function that calls InnerGreCreateBitmap for creating a bit map. PostScript does not support this function call. If InnerGreCreateBitmap is called, the driver will return an error.
 * prdb_DeviceDeleteBitmap:Hook function that initializes a bit map and memory DC. PostScript does not support this function call. If InnerGreDeleteBitmap is called, the driver will return an error.
 * prdb_DeviceSelectBitmap:Hook function that calls InnerGreSelectBitmap. PostScript does not support this function call. If InnerGreSelectBitmap is called, the driver will return an error.
 * prdb_GetBitmapBits:Hook function that retrieves the bit map information and calls InnerGreGetBitmapBits. PostScript does not support this function call. If InnerGreGetBitmapBits is called, the driver will return an error.
 * prdb_GetPel:Hook function that calls InnerGreGetPel. PostScript does not support this function call. If InnerGreGetPel is called, the driver will return an error.
 * prdb_RestoreScreenBits:Hook function that transfers control to the display driver.
 * prdb_SaveScreenBits:Hook function that transfers control to the display driver. PostScript does not support this function call. If InnerGreSaveScreenBits is called, the driver will return an error.
 * prdb_ScrollRect:Hook function that transfers control to the display driver.
 * prdb_SetBitmapBits:Hook function that calls InnerGreSetBitmapBits. PostScript does not support this function call. If InnerGreSetBitmapBits is called, the driver will return an error.
 * prdc_RealizeColorTable:Called to alter the device's hardware color table so that it matches the logical color table. PostScript does not handle this type of call. If this function is called, no processing is performed.
 * prdc_UnRealizeColorTable:This function is called to reverse the effects of the RealizeColorTable call. PostScript does not handle this type of call. If this function is called, no processing is performed.
 * prdd_CharRect:This function is called if an attempt is made to call GreCharRect. PostScript does not support this function call. If GreCharRect is called, the driver will return an error.
 * prdd_CharStr:This function is called if an attempt is made to call GreCharStr. PostScript does not support this function call. If GreCharStr is called, the driver will return an error.
 * prdd_DeviceInvalidateVisRegion:This function is called if an attempt is made to call GreDeviceInvalidateVisRegion. PostScript does not support this function call. If GreDeviceInvalidateVisRegion is called, the driver will return an error.
 * prdd_DeviceSetAVIOFont:This function is called if an attempt is made to call GreDeviceSetAVIOFont. PostScript does not support this function call. If GreDeviceSetAVIOFont is called, the driver will return an error.
 * prdd_DeviceSetCursor:This function is called if an attempt is made to call GreDeviceSetCursor. PostScript does not support this function call. If GreDeviceSetCursor is called, the driver will return an error.
 * prdd_GetPickWindow:This function is called if an attempt is made to call GreGetPickWindow. PostScript does not support this function call. If GreGetPickWindow is called, the driver will return an error.
 * prdd_GetStyleRatio:This function stores, at the location addressed by pRatio, the style ratio x and y direction step values.
 * prdd_SetColorCursor:This function is called if an attempt is made to call GreSetColorCursor. PostScript does not support this function call. If GreSetColorCursor is called, the driver will return an error.
 * prdd_SetPickWindow:This function is called if an attempt is made to call GreSetPickWindow. PostScript does not support this function call. If GreSetPickWindow is called, the driver will return an error.
 * prdd_UpdateCursor:This function is called if an attempt is made to call GreUpdateCursor. PostScript does not support this function call. If GreUpdateCursor is called, the driver will return an error.
 * prdg_Death:Notifies the driver at the termination of a screen group. PostScript does not handle this type of call. If this function is called, no processing is performed.
 * prdg_ErasePS:Erases the media. PostScript does not handle this type of call. If this function is called, no processing is performed.
 * prdg_LockDevice:Locks out other threads from executing the driver.
 * prdg_Resurrection:Notifies the driver when a screen group is reinstored. PostScript does not handle this type of call. If this function is called, no processing is performed.
 * prdg_UnlockDevice:Enables other threads that were locked out from.
 * prdl_DrawConicsInPath:If the DC is not memory, this function returns an error; otherwise, it calls GreDrawConicsInPath.
 * prdl_DrawLinesInPath:If the DC is not memory, this function returns an error; otherwise, it calls GreDrawConicsInPath.
 * prdm_DisjointLines:Called if an attempt is made to call GreDisjointLines. If the type of DC is memory, this function calls GreDisjointLines. Otherwise, it reports an error because GreDisjointLines is not supported for a non-memory DC.
 * prdm_DrawBits:Called if an attempt is made to call GreDrawBits. If the type of DC is memory, this function calls GreDrawBits. Otherwise, it reports an error because GreDrawBits is not supported for a non-memory DC.
 * prdm_DrawBorder:Called if an attempt is made to call GreDrawBorder. If the type of DC is memory, this function calls GreDrawBorder. Otherwise, it reports an error because GreDrawBorder is not supported for a non-memory DC.
 * prdm_PolyScanline:Called if an attempt is made to call GrePolyScanLine. If the type of DC is memory, this function calls GrePolyScanLine. Otherwise, it reports an error because GrePolyScanLine is not supported for a non-memory DC.
 * prdm_PolyShortLine:Called if an attempt is made to call GrePolyShortLine. If the type of DC is memory, this function calls GrePolyShortLine. Otherwise, it reports an error because GrePolyShortLine is not supported for a non-memory DC.
 * prdm_QueryDevResource:Called if an attempt is made to call GreQueryDevResource. If the type of DC is memory, this function calls GreDevResource. Otherwise, it reports an error because GreDevResource is not supported for a non-memory DC.

PATFILL.C
This module contains the code for pattern filling.
 * ps_patfill:Called for all path or area filling in the PostScript driver. If no path is defined, it returns SUCCESS. This routine supports all of the standard PM patterns as well as user-defined bit map patterns.
 * ps_patfill_base:Called by several places in to download PostScript code, common to pattern filling in the PostScript printer.
 * ps_patfill_common:Called by several places in to download PostScript code, common to pattern filling in the PostScript printer.
 * ps_patfill_font:Called by ps_patfill if the pattern to be used is a Logical Font. When used, it will be stored in pddc->pddcb->pat.usfFontLoaded.

PATH.C
This module contains path and area routines.


 * play_clip_rects:Replays all the clip rectangles to the current path.
 * prdl_BeginArea:Sets the proper flags in the DDC and outputs a new path command to the PostScript printer to indicate that a new area definition is starting.
 * prdl_BeginPath:Sets the proper flags in the DDC and outputs a newpath command to the PostScript printer to indicate that a new path definition is starting.


 * prdl_CloseFigure:Closes a figure within a path definition. The current figure is closed by appending a straight line from the current position to the starting point of the figure.
 * prdl_EndArea:If the cancel flag is set, this function discards the current path without drawing anything. Otherwise, the area is defined because the last BeginArea call is filled, and if requested, stroked. If the area is empty, nothing is done.
 * prdl_EndPath:If the cancel flag is set, this function discards the current path. Otherwise, the definition of the current path is ended.
 * prdl_FillPath:Given a path, this function fills the interior of the closed figures defined in the path, using the specified rule (even odd or winding) and the current pattern attributes. Before filling the figures, this function closes any open figures within the current path.
 * prdl_ModifyPath:Replaces the current path with a path enclosing the shape produced by stroking the path, using the current geometric wide line attribute. Any open figures within the path are not closed.
 * prdl_MemClipChange:Sets the clipping region of the shadow memory DC. It copies the DC region of the DC and sets it in the shadow memory DC. As a result, both will be synchronized.
 * prdl_NotifyClipChange:Adds rectangles from the clipping region to the current clip path.
 * prdl_OutlinePath:Closes a figure within a path definition. The current figure is closed by appending a straight line from the current position to the start point of the figure.
 * prdl_RestorePath:Restores the previously saved transform matrix, if the function RestoreDC was called.
 * prdl_SavePath:Hooked to GreSavePath because this driver handles all the path processing itself. No processing is performed by this function.
 * prdl_SelectClipPath:Creates the clip path by closing any open figures. It then releases any existing clip path (deleting the previous path, if any) and sets the specified path as the clip path. After a path is set as the clip path, it cannot be used again. However, its identifier is free to use for another path.

The clip path specifies a path in device space that the system uses to clip output. The clip path includes all points inside and on the boundary of the path specified by idPath. Because the path coordinates are assumed to be device coordinates, no conversion is applied.


 * prdl_StrokePath:Strokes the current path with a line width as set by the geometric line width.
 * rclIsEqual:Compares two rectangles and returns TRUE if they are equal.

PATH2.C
This module contains path- and area-related routines.


 * discard_clip_path_buf:Discards the clip path buffer.
 * discard_path_buf:Discards the current path buffer.
 * init_clip_path_buf:Allocates memory for the clip path buffer and copies the current path buffer into it.
 * init_path_buf:Allocates and initializes the path buffer.
 * play_clip_path_buf:Plays the clip path buffer to the channel.
 * play_path_buf:Plays the current path buffer to the channel.
 * sync_graphic_states:Resets the correct values in the graphic state of the printer. This function is usually used after a grestore.

POLYSTUF.C
This module contains routines that support polylines.


 * LoadMarkerFont:Downloads the code that defines the marker font to the PostScript printer.
 * prdb_PolyMarker:Draws NumberOfPoints markers centered at the positions in the Points array. The marker definitions can be the defaults or a font and are pointed to by the defSet field of the device marker bundle.
 * prdl_CheckConic:Given the three vertexes of the conic triangle and the sharpness, this routine converts the conic to a Bezier curve and outputs the appropriate PostScript code to append the conic to the current path.
 * First the conic is subdivided at the parameter t = 1/2. If the sharpness of the subdivided conic is large, it is subdivided further.


 * prdl_DrawConic:Given the three vertexes of the conic triangle and the sharpness, this routine converts the conic to a Bezier curve and outputs the appropriate PostScript code to append the conic to the current path. The original conic is bisected into two sub-conics because it is impossible to closely approximate the conics using a single Bezier.
 * prdl_DrawSubConic:Given the three vertexes of the conic triangle and the sharpness, this routine converts the conic to a Bezier curve and outputs the appropriate PostScript code to append the conic to the current path.
 * prdl_GetLineOrigin:Stores the current line position from the DC instance into a PPOINT structure.
 * prdl_PolyFillet:Draws a series of fillets.
 * prdl_PolyFilletSharp:Draw a series of conic fillets. The fillet is drawn from point A to point C of triangle ABC with sharpness S.
 * prdl_PolyLine:Draws a sequence of one or more lines starting at a certain position. As each line is drawn, its end point becomes the starting point for the next line.
 * prdl_PolySpline:Draws a series of connected Bezier curves.
 * prdl_SetLineOrigin:Sets the current style state in the PDDC, and in the current position. The style is two SHORTs. If the value of the high short is 0, the first pel is not drawn. If the value of the high short is not 0, the first pel is drawn. The PostScript driver will ignore this information. The low SHORT has 2 parts. The low BYTE is the position in the style mask. The high BYTE is the style error term. The PostScript driver will also ignore the style information, as PostScript strokes the entire path at one time.

PPDLG.C
This file contains the functions needed to maintain the Printer Properties dialog box.


 * CompareStri:This function compares two strings without regard to whether the strings are in upper or lower case.
 * DefineFormsDlgProc:This is the procedure for the dialog box when used to define custom forms. A custom form is a form with a user-defined, unique name. The custom form may also support user-defined form sizes if supported by the device.
 * EnableDefineFormAddButton:This function is responsible for enabling or disabling the Add Unique Forms button. The button is enabled if the number of unique forms defined does not exceed a maximum value.
 * DisplayMatchingForm:This function queries the current tray selection and displays the form selected for that tray.
 * FormDefPageDlgProc:This is the procedure for the Forms page in Printer Properties.
 * FormPPPageDefaultControls:This function sets the default control values when the Default button is pressed. The default values are set in the PPD file.
 * FormPPPageInitControls:This function inserts all values into all controls for the Forms page.
 * InitializeCustomForms:This function initializes the data needed to display the Display Forms dialog box and displays the dialog box. This includes initializing the structure that contains the unique form data.
 * ModeSwitchDefaultControls:This function sets the default control values when the Default button is pressed.
 * ModeSwitchDlgProc:This is the dialog procedure for the Options page.
 * ModeSwitchInitPage:This function initializes the controls for the Options page.
 * ModeSwitchSaveSettings:This function saves the current settings in the Options page.
 * PrinterPropertiesDlgProc:This is the main procedure for the Printer Properties dialog box.
 * ps_upper:This function converts a string to uppercase.
 * QueryAddFormButtonStatus:This function enables or disables the Add Custom Form button. The button is enabled if the number of user-defined forms has not exceeded a maximum value. Otherwise, the button is disabled.
 * VerifyTrayFormMapping:This function verifies that at least one tray in the Trays listbox is mapped to a valid form. If a tray is set to a valid form, the function returns TRUE.
 * VerifyUniqueForm:With a given user-defined form name, this function queries all form names. This function returns -1 if the user-defined form contains a unique name. A unique name is a name that is not the same as the name of any other form.

PRDEVECT.C
This module contains routines used in routing tasks to the graphics engine.
 * EnterDriver:Locates the DDC structure corresponding to the display HDDC that the engine placed on the stack. It validates the DDC structure and attempts to lock the DDC on behalf of the calling thread. If the DDC is already locked on behalf of some other process ID (pid) or thread ID (tid), it will fail.
 * ExitDriver:Performs all necessary cleanup before exiting the driver. Currently, the cleanup consists of decrementing the usage count for the current DDC, and unlocking the DDC if the count becomes zero.
 * Hook22Calls:Hooks functions required for the OS/2 graphics engine (version 2.2 and later).
 * InstallDispatchVectors:Installs the vectors to the printer function handler routines into the engine's dispatch table. It also retrieves a copy of the vectors to the display driver's function handler routines. These will be used when performing operations on a memory DC.
 * UnHookBitmapCalls:Unhooks all bitmap calls, except BitBlt, for the OS/2 graphics engine (version 2.2 and later).

PROFILE.C
This module contains the following functions:

"Mainkey1,Subkey1a,Subkey1b,...;Mainkey2,Subkey2a,Subkey2b,...;" This function reads the next available string in the above format up to, but not including, the semicolon or comma. The string is copied to another buffer. The pointer to the above string format is incremented to point to the next available string. The function returns a code, indicating whether or not the end of a subkey is found. This is true if a semicolon is found. If a comma is found, the substring still exists. "TRAYNAME1,FORMNAME1;TRAYNAME2,FORMNAME2;...\0" where "FORMNAME" is the string name of the form (found in the PPD) that is mapped to TRAYNAME (also found in the PPD). This function parses the INI string data and stores the data in the PSOURCE structure. If a buffer is already provided (pReturnBuffer), the INI data is stored in the return buffer. This function also is backward compatible in regard to the INI string. This function can read previous forms: "FORMNAME1;FORMNAME2;...;FORMNAMEn" In this format, the form names are mapped to tray names that are organized according to the PPD. For example, FORMNAME1 maps to the first tray found in the PPD. STRING11,STRING12,...STRING1N;STRING21,STRING22,...,STRING2N;... If a string is provided, a comma is first appended to the end of the buffer to separate the new string. The string is then appended to the buffer. If no string is provided, the semicolon is appended to the string, thereby separating the groups of strings from other groups. The above string is NULL-terminated.
 * LoadUserForms:This function loads the user-defined forms from the INI file. The key name it searches for is USERFORMS. If that string can not be found, it searches for USERFORMSDEF.
 * QueryNextSubkey:This function reads the following INI string format:
 * ReadFormINIData:This function reads the form data from the INI file. For the form data, the application name is the device name and the key name is PAPERTYPE.
 * ReadNewOrOldINIString:This function reads an INI string from the OS2SYS.INI file. The application name is the printer name. The caller must provide the current key name for the application and (optionally) may provide an older key name. The current key profile is read. If the key doesn't exist and the caller provided an older key name, the older key name is read. If an older key name is not provided (NULL), the function returns. The reason for being able to read older INI key data is to provide compatibility with older driver INI strings. Older INI strings contain translation strings that, officially, should not be included in the INI since translation strings can be changed at any time. This also provides backward compatibility so that an older driver can be used-and the older INI key can be accessed-if the user decides to go back to an older version. The older INI data is not modified.
 * ReadPageOptionData:This function reads the data that handles display forms for mapped trays. The key name it searches for is INCLUDEMAPPEDFORMS.
 * ReadTrayPageMapINI:This function reads the mapped tray and page data from the OS2SYS.INI file. The application name is the printer/device name and the key name is Papertype. The data is stored in the form:
 * SaveINIGroupData:This function appends a given string to a buffer in the following format:

"TRAYNAME1,FORMNAME1;TRAYNAME2,FORMNAME2;...\0" where "FORMNAME" is the string name of the form (found in the PPD) that is mapped to TRAYNAME (also found in the PPD). This form-tray mapping is set by the user in Printer Properties. This is saved under the key string PAPERTYPE. The mapped form display selection is set in Printer Properties. This is the checkbox Limit Jobs To Selected Forms. If this checkbox is set, 1 is stored as a binary value; otherwise, 0 is stored as a binary value. This is saved under the key string PAPEROPT.
 * SavePageTrayINIData:This function saves both the form-tray map string and the mapped form display selection in the OS2SYS.INI file. The form-tray map string is in the form:
 * TerminateTranslationString:This function searches for a slash in a given string. If a slash is found, the slash is replaced with a NULL terminator to separate the name from the translation string.

PSTUNER.C
This module contains a page tuning function.


 * QueryTunerProcData:This function is only used when page-tuning. It returns a pointer to the global TUNERPROCDATA structure, which is defined on a per-process basis. This is used by a profiling hook to determine the minimum number of pages needed by this driver. This function is exported.

QUERY.C
This module contains routines used to query different information for the driver.


 * LoadPaperDim:This routine returns pointers to currently selected paper dimensions. The currently selected paper is indicated by PDDC, the input argument.
 * NewUserForms:Returns the number of user-defined forms.
 * OS2_PM_DRV_DEVICENAMES:Returns the device names, descriptions, and data types supported by the specified device driver.
 * The application can call OS2_PM_DRV_DEVICENAMES with the pdn and pdt parameters set to zero in order to find how much storage is needed for the data buffers. Having allocated the storage, the application then calls the function a second time in order to have the buffers filled with data.


 * PageAtPaper:Given a page number, this routine determines which page is to be printed.
 * prdq_QueryDeviceBitmaps:Returns the number of planes and bits per pixel that this device supports.
 * prdq_QueryDeviceCaps:Sets the color value for a given pixel.
 * prdq_QueryHardcopyCaps:If the application is asking for the number of forms, it will pass in zero as the form count. In this case, the driver just returns the number of forms available on the printer.
 * szColonCopy:Duplicates a NULL-terminated or delimiter-terminated string with bounds checking to prevent the overflow of the destination buffer.

QUERYBOX.C
This module contains support routines for raising Printer configuration dialog box.


 * b2a:Convert a binary number to ASCII, stores it in the pointer, and returns the length of stored string.
 * cvi:Converts a numeric string into a binary number.
 * CheckProfileName:Checks for printer profile data in the INI file under the old application name that was the printer name (for example, QMS PS-810). If the printer profile data is found, the function will move it to a new name format and delete the old one.
 * CompareRealNames:Compares two strings that might each contain a translation string. If a translation string exists for either string, the slash that starts the string is temporarily set to 0, making the real name NULL-terminated. Both strings are compared using strcmp. For any string that contains a translation string, the slash is reinserted after the compare. This function returns the return code generated by strcmp.
 * DisplayTranslationString:A PPD line may include a combination of a PPD value and a matching translation string in the form "NAME/TRANSLATION STRING". If the translation string exists, display the translation string only in the specific window (provided by hWnd). This is done by moving pointer to the next character after the forward slash and displaying the string. If there is no translation string or if there is a terminator (0) after the slash, NAME is displayed.
 * EA_GetVersion:Retrieves the EA .VERSION from driver file.
 * FillEffects:Retrieves effects from OS2.INI into the PCNFDATA structure.
 * FillPaperNames:Stores paper names from OS2.INI onto the PCNFDATA structure.
 * Fraction2A:Converts a fractional number into a fractional string.
 * GetDefaultPageSize:Gets a pointer to the default page size.
 * GetImageableArea:Retrieves the imageable area from the currently selected form.
 * ListUserForms:Inserts all the user-defined forms into list handle hWnd.
 * NameWithSC:Transfers the NULL-terminated string to the destination buffer and returns the length of the string (plus the delimiting semicolon) that was copied.
 * PostWriteError:Displays a message indicating that data cannot be written to the OS2.INI file.
 * ReadProfile:Reads the textual values of orientation, paper name, paper input tray, paper output tray, and default font and saves the retrieved values in the respective globals.


 * ScanCustomset:Scans for the presence of the string szScan in szSource and returns TRUE if it is found.
 * ShowCursor:Shows a cursor in the window specified by handle hWnd.
 * WrtQueryProfile:Writes the various values of the obtained printer characteristics to OS2. INI.

QUERYCHR.C
This module contains functions used to query text information.


 * prdt_QueryCharPositions:Returns the positions (world coordinates) in which the printer will place each given character, taking into account kerning and extra vectors provided by the caller.
 * prdt_QueryTextBox:Processes the specified string as if it were to be drawn, using the current character attributes and returns an array of up to 5 coordinate pairs. The first four coordinate pairs are the coordinates of the top-left, bottom- left, top-right, and bottom-right corners of the parallelogram which encompasses the string when it is drawn. The fifth point is the concatenation point. The points on the borders of the parallelogram are included within the parallelogram.

STUB.ASM
This module contains functions that perform math functions.


 * dodiv:Divides a quad by long.
 * doimul:Multiplies 2 longs and places the result in a passed quad.

SURFACE.C
This module contains functions that perform surface routines.


 * DevicePalette:Stub routine for new Warp engine. Returns TRUE in all cases.
 * LockDevice:Stub to return NULL to callers.
 * QueryDeviceSurface:Required by the OS/2 grapics engine (version 2.2 and later). Gives engine description of raster surface and performs some modifications to the device surface structure.

UTLASM.ASM
This module contains low-level helper routines for the utilities module.


 * FractionToDecimal:Converts the fractional part of a number to a string.
 * LongShiftRight:Shifts the bits in a doubleword a specified number of times to the right.

UTLCHNL.C
This module contains various utilities functions for COM output.


 * AsciiToBin:Converts a numeric string to a binary value.
 * CheckComPortName:Checks if the passed COM port is any name starting with "COM" and followed with any integer greater than or equal to 1.
 * CloseChannel:Closes the printer's output channel. The output channel could be connected to the spooler, or directly to the output port.
 * Cvi_R2:Converts a string of ASCII digits to integer value. The string is in hex.
 * FlushChannel:Flushes the buffered output data through the output channel. If any errors occur, the output channel is closed.
 * HexToChannel:Given a character string, this function converts each character in the string to its hex equivalent, and then outputs it to the output buffer for the DC instance passed in.
 * InitializeCommPort:Attempts to read the COM port settings from the OS2.INI file and fills a private structure containing the information it found. It is assumed that the logical address has been validated prior to calling this function, and that it points to either COM1,COM2, or COM3. FALSE is returned if an error is detected. The format of an OS2.INI entry for a COM port is baud rate; parity;word length;stop bits;handshaking;
 * This function initializes the COM port baud rate, stop bits, and handshaking. It first determines if the logical is address is either COM1, COM2, or COM3. If this is true, get_ini_comm_info is called to fill a structure that contains the information needed to initialize the COM port. If this function is successful, the driver attempts to set up the port.

where it begins with a less than sign followed by the value in hex (for example, ESC = 1B), one space, an optional repeat count in HEX, followed by a closing greater than sign.
 * OpenChannel:Opens an output I/O channel.
 * PrintChannel:Sends formatted output to the output channel. A printf-style format string specifies the format of the output.
 * WriteChannel:Sends output data to the spooler or directly to the output port, depending on the state of the spool flag.
 * WriteModeString:Writes out the InitPostScriptMode and TermPostScriptMode strings from the PPD file. The string can be the actual characters and escape sequences. The escape sequence is in the form of:

This code does not perform any error checking because it is in a PPD file that contains data that is assumed to be correct.

For example, the string 1b 5b 4b 10 20 00 00 00 can be entered as: <1b>YK<10>

UTLPRINT.C
This module contains the core code for implementing various printf-style output formatting routines.


 * kprintf:This is the printf kernel entry point that is used by all the variations on printf, such as the entry point logging routine. This function performs the formatting of the print string.
 * PrintBool:Converts the value of its parameter to a TRUE or FALSE ASCII string.
 * PrintDecimal:Converts the value of its parameter to ASCII in decimal format.
 * PrintFraction:Converts the fixed point 16.16 value of its parameter into ASCII.
 * PrintHex:Converts the value of its parameter to ASCII in hex format.
 * ScanDigits:Scans the digit count value in the format string and converts it from ASCII to decimal format.
 * ScanPercentFormat:Scans a percent format specifier in a printf style format string.
 * ScanTokeng:Scans a printf style format string and sets the relevant global variables that describe the next format specifier.

UTLPS.C
This module is the low-level interface to the PostScript machine. The functions in this module mirror the functionality present in PostScript. As calls are made to this module, the state of the PostScript machine is maintained so that redundant output can be eliminated.


 * DoSelectFont:Issues commands to the printer that cause the current font stored in the graphics state to be selected.
 * EatSeper:Moves the buffer pointer forward to the next non-white character. This routine skips commas.
 * FindString:Moves the buffer pointer forward to the character following a specified string. This routine returns TRUE if it is found. Otherwise, it returns FALSE.
 * GammaAdjust:Applies the gamma correction to the color passed in.
 * GetDuplexCommand:Retrieves the proper duplex command from the PPB and copies it to the supplied buffer.
 * GetMappedFontName:When a font is remapped to support various code pages it is necessary to create a pseudonym for the font. This routine creates the pseudo-font-name, based on the font number stored in the DDC.
 * init_cgs:Initializes the current graphics state.
 * InvertTransfer:Sets the transfer function. For the first page, it sets the boundary to black.
 * LoadTrayCommand:Returns pointers to currently selected paper dimensions. The currently selected paper is indicated by PDDC (the input argument). The additional parameters are pointers to the paper command buffer, input tray command buffer, and output tray command buffer. If successful, the routine returns TRUE. Otherwise, it returns FALSE.
 * MatrixToChannel:Outputs a transform matrix to the print channel. The first four elements of the matrix are in fixed point (16.16) format and the last two elements (translation components) are long integers.
 * ps_clearpath:Destroys the current path by outputting a newpathcommand to the printer and setting a flag in the DDC.
 * ps_clip:Intersects the current path with the current clipping path and makes this the new clipping path. The winding number rule is used to determine the area clipped.
 * ps_closepath:Called by the driver to close the current path.
 * ps_CosmeticLine:Writes out the cosmetic line command. If the multiplier is one or zero, it uses the old "wc" command. If the multiplier is greater than 1, it uses the "wcx", which takes a parameter.
 * ps_effects:Sets up the printer for user-selected effects.
 * ps_enddoc:Called by the driver when it is finished with the current document. The routine ejects the last page, if it has not already been ejected, and closes the channel.
 * ps_fill:Called by the driver to fill the current path using the winding number rule . The current path is automatically closed if it has not been explicitly closed.
 * ps_grestore:Called by the driver to restore the current graphics state from the gsave stack.
 * ps_gsave:Called by the driver to save the current graphics state.
 * ps_imagedata:Outputs a scan line of image data.
 * ps_init:Prepares the utlps module for operation.
 * ps_lineto:Called by the driver to draw a line from the current point to the new endpoint.
 * ps_moveto:Called by the driver to change the logical pen coordinates.
 * If pptl is different from the current position, a MOVETO command is issued and a flag is set indicating that the driver is in a path.


 * ps_movetoCP:Checks to see if a path exists. If no path exists, a MOVETO command is output to set the printer's current position equal to that in the PDDC. The driver also sets a flag, stating that a path now exists.
 * ps_newpath:Called by the driver to destroy the current path, if it exists.
 * ps_restoreclipmatrix:Restores the previously saved transformation matrix.
 * ps_restorematrix:Restores the previously saved transformation matrix.
 * ps_rotatefont:Called by the driver to specify the font rotation.
 * AngleX, AngleY are the end coordinates of a line originating at (0,0). These new values are saved in ps.gsNew.fxFontAngleX and ps.gsNew. fxFontAngleY, and flag an angle change.


 * ps_saveclipmatrix:Saves the current transformation matrix so that it can be restored later.
 * ps_savematrix:Saves the current transformation matrix so that it can be restored later.
 * ps_scalefont:Called by the driver to specify the font size.
 * ps_selectfont:External entry point for the local DoSelectFont routine.
 * ps_setdash:Sets the line-type style corresponding to a solid or one of the various dashed line styles.
 * ps_setdashnow:Sets dash to the currently defined style.
 * ps_SetDownloadedFont:Called by the driver to select a new font that was created and downloaded to the PostScript device.
 * ps_setfont:Called by the driver to select a new font name.
 * ps_setlinecap:Called by the driver to specify the "linecap" type for lines that are " stroked". The linecap values are used in PostScript.
 * ps_setlinejoin:The driver calls this routine to specify the "linejoin" type for lines that are "stroked". The linejoin values are used in PostScript.
 * ps_setlinewidth:Called by the driver to specify the width of lines that are "stroked".
 * ps_setmatrix:Sets the current transformation matrix.
 * ps_setrgbcolor:Called by the driver to set the current color used to perform such functions as draw lines and fill. For non-color printers, it is implemented by converting the RGB color triplet to a gray-level between 0.0 (black) and 1.0 (white).
 * ps_shearfont:Called by the driver to specify the font shear.
 * ShearX, ShearY are the end coordinates of a line originating at (0,0). The angle must be computed from the vertical, and this angle must then be multiplied by the current point size (fxHeight).


 * ps_show:Called by the driver to output text in the current font.
 * ps_showpage:Called by the driver to eject a page from the printer.
 * ps_startdoc:Initializes a print job when a document is sent.
 * ps_status:Returns either SUCCESS or FAILURE depending on whether an error has occurred on the I/O channel.
 * ps_stroke:Called by the driver to stroke the current path using the current pen attributes.
 * ps_strokecurrentpath:Strokes the current path using the current pen attributes.
 * ps_sync_cp:Called by the driver to change the logical pen coordinates.
 * ScanInt:Parses a positive ASCII decimal number from the input file stream and returns its value.
 * szCopy:Duplicates a NULL-terminated string with bounds checking to prevent the overflow of the destination buffer.

XFORMS.C
This module contains PostScript-driver transform code.
 * prdg_DeviceSetDCOrigin:Simply returns success. The DC origin is always left at (0,0).
 * prdg_GetDCOrigin:Returns the DC origin (always zero).
 * prdg_NotifyTransformChange:Called by the engine when the transformation matrix has been changed.
 * utl_MemIsEqual:Compares two memory regions.