Printer Device Driver Reference for OS/2
By IBM
About This Book
The Printer Device Driver Reference for OS/2 describes the printer and plotter presentation drivers as well as test tools that correspond to the source code that is supplied with the IBM Developer Connection Device Driver Kit for OS/2.
This reference also provides a roadmap to the drivers and briefly describes their functions and modules. It is intended to be used in conjunction with the Presentation Driver Reference. For additional information about graphics-engine functions and presentation drivers, see the Presentation Driver Reference.
Programmers can use the information found in this book to create printer drivers and tests as well as to test their drivers. Knowledge of C and Assembler programming languages is necessary. The programmer must be familiar with the the OS/2 operating system, the Presentation Manager interface, and 80X86 architecture. The programming concepts that should be understood before developing applications to run on the OS/2 system can be found in the Application Design Guide.
How This Book is Organized
- Generic Printer Library, describes a set of subroutine packages that can be used in the development of 32-bit hardcopy presentation drivers.
- 32-Bit PostScript Driver, describes important design and programming information about the PostScript driver. All the functions used by the PostScript driver are listed and described.
- 32-Bit Plotter Presentation Driver, describes important design and programming information about the plotter driver. All the functions used by the plotter driver are listed and described.
- The 42XX Rasterizing Driver, provides important design and programming information about the 42XX rasterizing driver. All the functions used by the 42XX rasterizing driver are listed and described.
- 32-bit Omni Presentation Driver, describes the Omni Driver, a 32-bit OS/2 Presentation Manager printer device driver.
- Printer Bidirectional Communications, provides important design and programming information about OS/2 bidirectional communications. All the functions used by the feature are listed and described.
- Font Test 32-Bit Printing Utility, describes Font Test.
Font Test is a 32-bit Presentation Manager application that allows users to browse through and print text files as well as to query presentation drivers for device, font, and hardcopy information. Font Test is very useful for testing presentation drivers. All the functions used by Font Test are listed and described, and a description of how to add a test to Font Test is included.
- Printer Test Tool (PTT), describes the Printer Test Tool (PTT) and how to run test cases. It also contains information about PTT commands and PTT command-line options. The PTT's tests are detailed, and the GPI functions called by the tests in the PTT are listed with any necessary configuration settings.
- Importing PostScript Printer Description files
- The Notices contain trademark and service-mark notices and information.
- The Glossary defines terms commonly used in the IBM Device Driver Source Kit for OS/2.
What's New
The following update has been added to this release of the Printer Device Driver Reference for OS/2:
A new section, Sample Bidirectional Parallel Port Driver which describes the code/functions associated with the port driver.
For information on items discussed in this reference that have been added to OS/2 (beginning with Warp) and their compatibility with different versions of OS/2, see OS/2 Version Compatibility Considerations.
Assistance
Technical support for device driver development is provided by the IBM Driver Development Support Center (DDSC) through a bulletin board system (BBS). You are encouraged to use the DDSC to obtain support by sending in your questions and reviewing the question and answer database which can be downloaded for off-line review.
To access the DDSC BBS, dial 512-838-9717 (using a modem) to register and access the support system. For voice support in the United States, call 512 -838-9493.
Additional assistance is available through the IBM Solution Developer Program. For membership information:
- Internet: ibmsdp@vnet.ibm.com
- US/Canada: 800-627-8363
- International: 770-835-9902
- International Fax: 770-835-9444
Ordering Information
In addition to the actual tools and source code available on The IBM Developer Connection Device Driver Kit for OS/2, it CD-ROM also includes the following DDK reference books in online format.
- The Physical Device Driver Reference
- The Storage Device Driver Reference
- The Input/Output Device Driver Reference
- The Pen for OS/2 Device Driver Reference
- The Virtual Device Driver Reference
- The Presentation Device Driver Reference
- The Display Device Driver Reference
- The Printer Device Driver Reference
- The Graphics Adapter Device Driver Reference
- The MMPM/2 Device Driver Reference (Multimedia)
To order the DDK call:
/----------------------------------------------------------------\ |U.S.A.: |1-800-633-8266 | | |--------------------+---------------------+---------------------| |Canada: |1-800-561-5293 | | |--------------------+---------------------+---------------------| |When calling from |* English |(+45) 48101500 | |Europe, the Middle |* French |(+45) 48101200 | |East, or Africa, the|* Italian |(+45) 48101600 | |number depends on |* German |(+45) 48101000 | |the language you use|* Spanish |(+45) 48101100 | |to place the order: |* Dutch |(+45) 48101400 | | |* Danish |(+45) 48101300 | | |* Finish |(+45) 48101650 | | |* Swedish |(+45) 48101150 | | |* Norwegian |(+45) 48101250 | | |* FAX |(+45) 48142207 | |--------------------+---------------------+---------------------| |When ordering from |* Bolivia | 02-35 1840 | |Latin America or |* Columbia | 01-257-0111 | |South America, the |* Dominican Republic | 566-5161 | |number depends on |* El Salvador | 02-98 5011 | |the country from |* Honduras | 32-2319 | |which you are |* Paraguay | 021-444 094 | |calling: |* Urugruay | 02-923 617 | | |* Chile | 02-633-4400 | | |* Costa Rica | 223-6222 | | |* Ecuador | 02-56 5100 | | |* Guatemala | 02-31 5859 | | |* Panama | 02-639 977 | | |* Peru | 014-36 6345 | | |* Venezuela | 02-908-8901 | | |* Argentina | 01-313-0014 | |--------------------+---------------------+---------------------| |To order from Asia/ |* All except Japan |(61) 2-354-7684 | |Pacific: |* Japan |(81) 3-3495-2045(Fax)| | | |Fax request to: | | | |DAP-J, IBM Japan | |--------------------+---------------------+---------------------| |To order from SE |(021) 800-6120(Voice)| | |Brazil: |(021) 800-6936(Fax) | | |--------------------+---------------------+---------------------| |To order from |* Mexico City |627-2444 | |Mexico: |* Country |91-800-00639 | \----------------------------------------------------------------/
Generic Printer Library
The Generic Printer Library (GenPLib) is a set of subroutine components that can be used in the development of 32-bit hardcopy presentation drivers.
Presentation-driver developers often write similar sets of code to implement functions commonly required by hardcopy devices. Heap creation, output buffering, and banding raster data are examples. The GenPLib simplifies development and decreases the development time of 32-bit OS/2 printer presentation drivers because it provides these necessary functional components.
The GenPLib consists of function packages that implement some of the more difficult code that is needed to create a printer driver. The library format is a way to realize software reuse so that other developers can benefit from code that can be made completely independent of any driver.
GenPLib appears in the IBM Developer Connection Device Driver Kit for OS/2 (DDK) as a static library that is linked to OS/2 driver code. The GenPLib code is still in its early versions; updates to the functions and header files can occur with each release of the DDK. Eventually, the GenPLib may become a system DLL; but for now, you can use any static version of GenPLib . By convention, all functions exported from GenPLib begin with the Gpl prefix.
Because of the design of the modules of the GenPLib, some functions can also be used for development in areas other than OS/2 printer drivers.
Following are some reasons to use the GenPLib:
- Allows developers to quickly, easily, and incrementally add function packages to their printer drivers.
- Written in portable C source code that can be recompiled for other processors.
- Provides 32-bit functions for new 32-bit operating-system environments, such as OS/2 2.0+SP and up-including OS/2 Warp.
- Available in Intel, PowerPC, debug, and non-debug versions. The current 16 -bit drivers cannot run in these environments.
- Provides a single, consistent source code for common functions.
- Packages are designed using data abstraction.
- Makes printer presentation-driver code more readable and maintainable.
- Produces extensive debugging and logging information for developers and service personnel.
- Implemented with the newest, most appropriate OS/2 system APIs, tailored to the underlying hardware and operating system version on which it is running (that is, system memory, paging behavior, CPU detection, etc.).
Note: The GenPLib has no 16-bit routines.
GenPLib Functional Packages
The GenPLib currently contains the following function packages:
Error Assertion Provides a consistent way of checking for errors in driver code and reporting and logging useful information for developers and field support.
Banding Simplifies the use of journaling that assists in banding pages of raster output data to printers.
Color Dithering Provides color-dithering support.
Gamma CorrectionProvides gamma-correction support.
CompressionProvides commonly used compression routines recognized by printers.
Exception ManagementProvides ways of setting errors with WinSetErrorInfo and logging appropriate warnings, exceptions, and error codes.
Memory ManagementProvides a simple way of managing global and process memory needed by presentation drivers.
Pattern CreationProvides functionality to create bitmap patterns.
Output-Thread ManagementProvides multi-threaded output and buffer management to printer devices for improved performance.
SemaphoresHelps drivers protect their data in multitasking environments. The implementation detects the current CPU level and implements semaphores based on the smallest possible set of assembly instructions.
String ManagementProvides a way to sort text strings that are being drawn to a printer output page so that they can be processed in many page orders when needed.
GenPLib Architecture
The GenPLib is a 32-bit static linking library, GENPLIB.LIB. Developers use LINK386.EXE to link the GPL with their 32-bit printer drivers.
Several C language include files (*.H) are associated with GENPLIB.LIB and define the function names and prototypes in the library. The main include file is GENPLIB.H.
GENPLIB.H includes other relevant library H files based on symbolics (INCLs ) defined to the compiler. For example, the following symbolics have a special meaning to the operation of GENPLIB.H when included by a C program:
INCL_GENPLIB_ASSERT INCL_GENPLIB_ERROR INCL_GENPLIB_HANDLER INCL_GENPLIB_JOURNAL INCL_GENPLIB_MEMORY INCL_GENPLIB_SEMAPHORES INCL_GENPLIB_STRINGSORT INCL_GENPLIB_THREAD INCL_GENPLIB_UTIL INCL_GENPLIB_PATTERNS
To include all functions, use:
INCL_GENPLIB_ALL
When a developer uses GenPLib memory-management routines, the C source file that requires GenPLib memory management would include a set of code resembling the following:
#define INCL_GENPLIB_MEMORY #include <genplib.h>
This code is included before any GenPLib memory-management functions or structures are referenced. The compiler automatically includes GPLMEM.H within GENPLIB.H.
Components of the Generic Print Library
The following sections describe the components and functions of the GenPLib .
Error Assertion
To use the GenPLib Error-Assertion package, you must include:
INCL_GENPLIB_ASSERT
The error-assertion package of the GenPLib consists of six APIs. Four are macros:
The remaining two are functions:
PMAssertValidates the return code from OS/2 Presentation Manager (PM) APIs that display the WinGetLastError() result and a supplied text string in a message box.
BaseAssertValidates OS/2 APIs that use the APIRET return code.
ASSERTT () and ASSERTF ()ASSERTT causes an error assertion if the supplied test evaluates to TRUE. ASSERTF causes an error assertion if the supplied test evaluates to FALSE. An assertion is an INT3 with kernel debug information displaying the failed test, file name, and line number of the location from which the assertion was called.
DBPRINTF (()) and DBPRINTIF (())DBPRINTF outputs the supplied text string to the kernel debugger. DBPRINTIF outputs the supplied text string to the kernel debugger if the supplied condition is TRUE.
ASSERTT () and ASSERTF ()
The ASSERTT and ASSERTF macros are very useful to precisely locate errors in code. Each is simply a test. If the test fails, the system generates a sound, stops the program, and displays a message. The more often an ASSERTT or ASSERTF macro is used, the better the chance that the first point of failure will be captured for analysis.
Use ASSERTT or ASSERTF prior to:
Pointers Assert that pointers are nonzero.
Divisors Assert that divisors are nonzero.
Strings Assert that strings are valid.
Copying Assert that enough space is present before copying.
Use ASSERTT or ASSERTF after:
OS/2 APIs and internal functions Assert result codes of OS/2 APIs and your internal functions.
Pointers Assert pointers after allocation.
Switch statements Use ASSERTT (TRUE) in the default case of switch statements
Do not use ASSERTT or ASSERTF in:
Essential Code These macros are not included in the retail build of the product. For example, ASSERTT (0 != DosRequestMutexSem (hsem))
The following is sample output on the kernel debugger:
Assertion failed on line 41 of file code.c 'rc == 0' eax=XXXXXXXX ebx=XXXXXXXX etc=XXXXXXXX edx=XXXXXXXX esi=XXXXXXXX edi=XXXXXXXX eip=XXXXXXXX esp=XXXXXXXX ebp=XXXXXXXX iopl=2 -- -- -- xx xx xx xx xx xx xx xx cs=XXXX ss=XXXX ds=XXXX es=XXXX fs=XXXX gs=XXXX cr2=XXXXXXXX cr3=XXXXXXXX program:CODE32:BREAKPOINT XXXX:XXXXXXXX cc int 3 ##
Use ASSERTT and ASSERTF under the following conditions:
ASSERTT (z);where zis a Boolean expression that should evaluate to zero or FALSE on success.
ASSERTF (nz);where nzis a Boolean expression that should evaluate to nonzero or TRUE on success.
The following example shows how to use ASSERTT and ASSERTF:
pointer = NULL; rc = DosAllocMem( &pointer, size, PAG_EXECUTE | PAG_READ | PAG_WRITE ); ASSERTT (rc); // Return code should be zero (success) ASSERTF (pointer); // Pointer should be nonzero
DBPRINTF (()) and DBPRINTIF (())
DBPRINTF uses the printf functionally of ANSI C to write messages to the kernel debugger screen. DBPRINTF is a macro; but because it can have a variable number of parameters, it must have an extra set of parentheses.
The following is the structure of DBPRINTF:
DBPRINTF( // Outputs a text string to debug terminal (like C printf command) PSZ pszFormatString, // String with same format options as printf command (...) ); // Parameter list of values to be placed in format string
The following is the structure of DBPRINTIF:
DBPRINTIF( // A conditional DBPRINTF command BOOL bDoit, // Outputs format string if this parameter evaluates to TRUE PSZ pszFormatString, // String with same format options as printf command (...) ); // Parameter list of values to be placed in format string
ASSERTT, ASSERTF, DBPRINTF, and DBPRINTIF Notes:
ASSERTT and ASSERTF as well as DBPRINTF and DBPRINTIF are macros. They are built for the debug-level build and disappear for the retail-level build.
These macros rely on the PMDD device driver to be activated. To activate the PMDD device driver, add a /Cx parameter to the following statement (where x is the COM port number):
DEVICE=C:\OS2\PMDD.SYS /Cx
PMAssert
Description
This function is similar to ASSERTT and ASSERTF, but it displays a message box if an error condition occurs. In addition to displaying a user-provided error message, the message box also displays the results of WinGetLastError (), the Presentation Manager error code. Use this function to assert OS/2 Presentation Manager APIs.
Format
PMAssert( // Display a message box with pszString, and show WinGetLastError() BOOL bDoit, // Display message box only if this expression evaluates to TRUE HAB habErr, // Anchor block handle of thread checking for a PM error PSZ pszString ); // Message to display on message box with PM error code
Parameters
bDoit(BOOL) Boolean value. If TRUE, then a message box is displayed.
habErr(HAB) Anchor block of program.
pszString(PSZ) Message string.
Returns
TRUE Evaluated to TRUE
FALSE Evaluated to FALSE
Example Code
BOOL rc; rc = GpiDestroyPS( hps ); PMAssert( rc == FALSE, hab, "GpiDestroyPS failed!" );
BaseAssert
Description
This function is similar to ASSERTT and ASSERTF, but it displays a message box if an error condition occurs. Use this function to assert return codes from those OS/2 APIs that use DOS Error-type return codes.
Format
BaseAssert( // Display message box if a base error (DOS) is passed in (ulError) ULONG ulError, // Value of base error as defined in BSEERR.H header file PSZ pszString ); // String to print out with base error code
Parameters
ulError(ULONG) Return code from OS/2 BaseAPI, either NO_ERROR (0) or one of the ERROR_xxx DOS Error codes. If ulError is not equal to NO_ERROR, a message box is displayed.
pszString(PSZ) Message string.
Returns
TRUE Evaluated to TRUE
FALSE Evaluated to FALSE
Example Code
APIRET apirc; apirc = DosAllocMem( pbuf, 1024h, PAG_READ | PAG_WRITE ); BaseAssert( "DosAllocMem failed", apirc );
Banding
This component controls all aspects of managing a journal file and banding such as:
- Calculating the band size-determines if banding is necessary based on the input parameters (resolution, bits/pel, page size, etc.).
- Creating a journal file, and managing COM_DRAW flags.
- Playing back either a full page or bands within a page, and managing the DC offset for each band.
- Offering many different play options.
- Handling destructive and non-destructive plays (if it is necessary to play more than once).
- Handling portrait and landscape cases.
- Playing bands from top-to-bottom or bottom-to-top.
To use the GenPLib Banding package, you must include:
INCL_GENPLIB_JOURNAL
Journaling Overview
A journal file is a record of all the GreXXX function calls that a driver receives between the time that it starts recording a journal file and the time it stops recording a journal file. Typically, recording starts at the beginning of a page and stops at the end of a page. After the recording has stopped, you can replay the journal file as often as necessary.
There are many reasons to record the GreXXX calls for a particular handle to a drawing context (HDC). Color sorting and banding are two examples.
- For color sorting, printer commands are output for a particular color while the journal file is recorded. Then, the journal file is played back for the remaining colors. Printer commands are output only when the current color is the color with which you are working.
- For banding, a portion of the page is defined as a bitmap and only that area is drawn in while the journal file is played back. Then, the DC origin is moved up the size of the band and the journal file is replayed. This must be done for every band on the page.
The following functions are used for journaling:
- GplQueryPhysicalMem
- GplJournalCalcBandSize
- GplJournalCreateInstance
- GplJournalPlayInstance
- GplJournalDeleteInstance
- GplJournalAbortDoc
- GplJournalResetAbortDoc
Call Flow
GplQueryPhysicalMem is the first function that you can call. It tells you how much physical RAM you have available.
GplJournalCalcBandSizeis the second function that you can call. It is an optional helper function that tells you whether or not you need to band given your memory requirements and band size.
The next function that you call is GplJournalCreateInstance. This function initializes an instance or reuses an instance.
The next function that you call is GplJournalPlayInstance. This function replays the journal file either per-page or per-band; it can also preserve or change the attributes of the page.
Finally, you call GplJournalDeleteInstanceto clean up the instance data.
GplQueryPhysicalMem
Description
This function tells you how much physical RAM is installed on your system.
The function ulPhysMem can be used in determining the amount of memory that should be reserved for banding. For the Omni driver, for example:
if( ulPhysMem <= 4 ) ulMaxBandMem = 256 * 1024; // 256K bands elseif( ulPhysMem < 12 ) ulMaxBandMem = 512 * 1024; // 512K bands elseif( ulPhysMem < 20 ) ulMaxBandMem = 1000 + 1024; // 1M bands elseif( ulPhysMem >=20 ) ulMaxBandMem = 2000 + 1024; // 2M bands
Returns
ulPhysMem Amount of physical RAM installed on system.
GplJournalCalcBandSize
Description
This function helps you decide if you need to break the page up into bands. If you do need to journal, then it will set up the band size to be constrained by the memory limit and to be a multiple of the modulus.
Based on the page size, number of bits per pel, number of color planes, etc ., the function calculates the number of bytes needed for the page bitmap. If the amount exceeds the memory limit, it calculates the number of bands into which to break the page.
Format
APIRET APIENTRY GplJournalCalcBandSize( PIJOURNAL pIJournal, // Journal data structure USHORT usBitsPerPel, // 1, 4, 8, or 24 bits per pel USHORT usNumPlanes, // Number of color planes USHORT usModulus, // Band size should be a multiple of this USHORT usDotsPerColumn, // Resolution ULONG ulMaxBandMem ); // Maximum memory available for banding
Parameters
pIJournal(PIJOURNAL) Journal data structure. The following input fields are used:
usXLengthLength of page in pels along x axis.
usYLengthLength of page in pels along y axis.
bPortraitOrientation of page-portrait or landscape.
usBitsPerPel(USHORT) Page bitmap, number of bits per pel.
usNumPlanes(USHORT) Page bitmap, number of planes.
usModulus(USHORT) The band size must be zero or a multiple of this number. This may be necessary to cause byte, word, or Dword alignment to align band size to match the width of a print head. This functionality may also be helpful if you need to send the bits in a certain column height.
usDotsPerColumn(USHORT) Resolution.
ulMaxBandMem(ULONG) Maximum memory available for banding.
This parameter is the limit to the number of bytes that your band bitmap can exceed.
Returns
FALSE Journaling is notnecessary.
TRUE Journaling isnecessary. The following is filled in and valid:
pIJournal(PIJOURNAL) Journal data structure
usBandLengthBand length in pels
pIJournalis output with usBandLengthupdated as follows:
- x-band length indicates landscape orientation.
*y-band length indicates portrait orientation.
Notes
This function should be called at COMPLETE_OPEN_DC time; because at this time, job properties have been obtained that may affect how pIJournalis filled in (for example, form size, mono/color selections).
GplJournalCreateInstance
Description
This function will create a reusable instance for a particular DC. The opposite of this function is GplJournalDeleteInstance. Following are the four cases in which this function may be called:
Case 1 Ask for the number of bytes to allocate for the handle.
Case 2 DEVESC_STARTDOC time is the first (real) time this function is called. hJournal has been allocated. Initialize hJournal's bytes to 0.
Case 3 At DEVESC_NEWFRAME time, another page, more processing. After the call to GplJournalPlayInstancehas completed, set it up for the next page.
Case 4 At DEVESC_NEWFRAME time, another page, but this time we want the information about the page to change. The call to GplJournalPlayInstance has completed.
Format
APIRET APIENTRY GplJournalCreateInstance( HJOURNAL hJournal, // Journal handle PIJOURNAL pIJournal, // Journal data structure ULONG ulFlags ); // Creation flags (defaults)
Parameters
hJournal(HJOURNAL) Handle to the journal file instance.
pIJournal(PIJOURNAL) A pointer to the input structure.
ulFlags(ULONG) This function performs different actions based on the ulFlags. The ulFlags is a bit vector (individual bits have different meanings). The options are separated into mutually exclusive groups that must have one member set.
CREATE_DRAW_WHILE_RECORDINGTurn on drawing while the journal file is being recorded.
Returns
Success TRUE
Failure FALSE
Implementation
This function will perform different actions based on the input parameters:
Case 1
The function will return the size (in the number of bytes) of a handle. It is the responsibility of the of caller to allocate and free the memory for a journal handle.
hJournal NULL.
pIJournal NULL.
Case 2
This function creates an engine journal file and starts recording to it. It also starts the accumulation of bounds. Call GplJournalPlayInstanceto stop recording and play the journal file.
hJournalAddress of newly allocated memory.
pIJournalAddress of the input structure. The structure has following format:
ulSizeSize of this structure.
hModuleModule handle of the calling program.
hdcCurrent HDC.
usXLengthPage size in pels.
usYLengthPage size in pels.
bPortraitOrientation of page.
TRUE-portrait
FALSE-landscape
usBandLengthBand height in pels.
pfunBandPointer to a callback function with the following prototype. This function is only called at the end of each band. (_System *)(PVOID, PRECTL)
pfunArgAny pointer. This will be passed to the first parameter of the previous callback function.
FlagsContains creation flags.
Case 3
The function performs the same functionality as Case 2. However, you can change any of the parameters in the input structure from the previous call to GplJournalCreateInstance.
hJournalHandle to a journal file instance.
pIJournalAddress of the input structure. The structure has following format:
ulSize Size of this structure.
hModule Module handle of the calling program.
hdc Current HDC.
usXLength Page size in pels.
usYLength Page size in pels.
bPortrait Orientation of page.
TRUE-portrait
FALSE-landscape
Case 4
For this case, a new page has been sent and you will restart the entire process (Case 2). This function uses the same parameters that were given to the original call to GplJournalCreateInstance.
hJournalHandle to a journal file instance.
pIJournalNULL.
GplJournalPlayInstance
Description
This function signifies the end of the recording. If you want to call this function multiple times for a page, then for calls 1..n-1 the flag PLAY_ NONDESTRUCTIVE should be used. On the last call, n, the flag PLAY_ DESTRUCTIVE should be used.
Format
APIRET APIENTRY GplJournalPlayInstance( HJOURNAL hJournal, ULONG ulFlags );
Parameters
hJournal(HJOURNAL) Handle to the journal file instance.
ulFlags(ULONG) This function will perform different actions based on the ulFlags. The ulFlags is a bit vector (individual bits have different meanings). The options are separated into mutually exclusive groups that must have one member set.
PLAY_JOURNAL_BANDPlay all bands at this time. The callback function that was defined at GplJournalCreateInstancetime will be called after each band has been played.
or
PLAY_JOURNAL_PAGEPlays the journal file once for this page.
PLAY_NONDESTRUCTIVEThe DC state will not be altered after the call has been completed.
or
PLAY_DESTRUCTIVEThe DC state will now have the final attributes of the page.
PLAY_TOP_TO_BOTTOMBands are played from the maximum Y value to 0.
or
PLAY_BOTTOM_TO_TOPBands are played from 0 to the maximum Y value.
Returns
Success TRUE
Failure FALSE
GplJournalDeleteInstance
Description
This function is the opposite of GplJournalCreateInstance. It should be called at DEVESC_ENDDOC or enable subfunction 11 (begin close DC) time. It is responsible for cleaning up all of the resources that it used.
Format
APIRET APIENTRY GplJournalDeleteInstance( HJOURNAL hJournal );
Parameter
hJournal(HJOURNAL) Handle to the journal file instance.
Returns
Success TRUE
Failure FALSE
GplJournalAbortDoc
Description
This function is called when a DEVESC_ABORTDOC is received.
Format
APIRET APIENTRY GplJournalAbortDoc( HJOURNAL hJournal );
Parameter
hJournal(HJOURNAL) Handle to the journal file instance.
Returns
Success TRUE
Failure FALSE
GplJournalResetAbortDoc
Description
This function is called when a DEVESC_ENDDOC is received and the job has been aborted.
Format
APIRET APIENTRY GplJournalResetAbortDoc( HJOURNAL hJournal );
Parameter
hJournal(HJOURNAL) Handle to the journal file instance.
Returns
Success TRUE
Failure FALSE
Example Code
GplQueryPhysicalMemUsage
Following is an example of GplQueryPhysicalMemusage:
case COMPLETE_OPEN_DC: // Final driver enable subfunction { // If we are enabling for a DC where we may need to journal if( OD_DIRECT == ulDCType || PM_Q_RAW == ulDataType ) { // Fill in journal information structure IJournal.ulSize = sizeof( pddc->IJournal ); IJournal.bPortrait = ( pddc->pJobProps->ulOrientation == PORTRAIT ); IJournal.hdc = pddc->hdc; // Handle to DC IJournal.hModule = globals.hModule; // Driver's module handle IJournal.pfunBand = (PJFUN)NewFrame; // Callback function IJournal.pfunArg = (PVOID)pddc; // Arguments to callback function IJournal.usXLength = pddc->pCurrentForm->hcInfo.xPels; IJournal.usYLength = pddc->pCurrentForm->hcInfo.yPels; // Find out how much physical RAM is installed on the system GplQueryPhysicalMem( &ulPhysMem ); // Omni uses ulPhysMem to determine the maximum memory for banding If( ulPhysMem <= 4 ) ulMaxBandMem = 256 * 1024; // 256K bands elseif( ulPhysMem < 12 ) ulMaxBandMem = 512 * 1024; // 512K bands elseif( ulPhysMem < 20 ) ulMaxBandMem = 1000 + 1024; // 1M bands elseif( ulPhysMem >= 20 ) ulMaxBandMem = 2000 + 1024; // 2M bands } /* end if */ } /* end case */
Following is an example of GplJournalCalcBandSizeusage during OS2_PM_DRV_ ENABLE for a dot-matrix printer:
case COMPLETE_OPEN_DC: // Final driver enable subfunction { IJournal.ulSize = sizeof( pddc->IJournal ); IJournal.bPortrait = TRUE; IJournal.hdc = hdc; IJournal.hModule = globals.hModule; IJournal.pfunBand = (PJFUN)NewFrame; IJournal.pfunArg = (PVOID)pddc; IJournal.usXLength = hcInfo.xPels; IJournal.usYLength = hcInfo.yPels; // NOTE: Modulus should be should be '1' on full-page printers or print-head width bBanding = GplJournalCalcBandSize( &IJournal, // PIJournal 1, // Bits per pel 1, // Planes 40, // Modulus 64000 ); // Maximum memory available } /* end case */
Following is an example of GplJournalCreateInstanceusage to allocate/ create a journal instance handle during processing of the start-document escape. At this point, the port is opened and the output thread is already created.
case DEVESC_STARTDOC: { if( ulDCType == OD_DIRECT || ulDataType == PM_Q_RAW ) { // If we need to band (that implies journaling) if( pddc->fBanding ) { // First call to size of memory needed for journal handle ulSize = GplJournalCreateInstance( NULL, NULL, 0 ); // Allocate memory needed for journal handle (driver's responsibility) hJournal = GplMemoryAlloc( hmcbHeap, ulSize ); // User per-DC heap // Allocate the memory for formal instance lrc = GplJournalCreateInstance( hJournal, // Journal handle &IJournal ), // Journal information structure 0 ); // Creation flags (defaults) } /* end if */ } /* end if */ /* end case */
GplJournalPlayInstanceand GplJournalDeleteInstanceUsage
Following are examples of GplJournalPlayInstanceand GplJournalDeleteInstanceduring the processing of the end-document escape:
case DEVESC_ENDDOC: { if( ulDCType == OD_DIRECT || ulDataType == PM_Q_RAW ) { // If we need to band (that implies journaling) if( pddc->fBanding ) { apiret = GplJournalPlayInstance( hJournal, PLAY_JOURNAL_BAND | PLAY_DESTRUCTIVE | PLAY_TOP_TO_BOTTOM ); apiret = GplJournalDeleteInstance( hJournal ); // Remember: Free memory allocated for journal instance handle (hjournal) } /* end if */ } /* end if */ } /* end case */
GplJournalAbortDocUsage
Following is an example of GplJournalAbortDocusage:
case DEVESC_ABORTDOC: { if( ulDCType == OD_DIRECT && ulDataType == PM_Q_RAW ) { // If we have a journal file (that is, we are banding) if( pddc->hJournal ) { // Inform journal code that abort condition is in effect GplJournalAbortDoc( pddc->hJournal ); } /* end if */ } /* end if */ } /* end case */
Following is an example of GplJournalResetAbortDocusage:
case DEVESC_ENDDOC: { if( ulDCType == OD_DIRECT && ulDataType == PM_Q_RAW ) { // If we have been called with an abort document if( pddc->fAbortDocCalled ) { // Inform journal code that abort condition is over GplJournalResetAbortDoc( pddc->hJournal ); } /* end if */ } /* end if */ } /* end case */
Color Dithering
Color dithering is technique of interleaving cyan, magenta, yellow, and optionally black so that the eye perceives another color-such as pink or orange. Color dithering converts picture pels in sizes 2, 4, 8, 16, 24, or 32 bits of RGB/K color to a 3 or 4 bitpel consisting of cyan, magenta, yellow, and optionally K(black). The best dither functions diffuse or spread out colors and also act as a low-pass filter to changes in color. The diffusion of color causes the printing of cyan, magenta, and yellow in the proper density so that from a distance, the eye perceives the correct color.
Following are the dithering functions:
Gamma-correction functions are a part of the color-dithering package and are used internally by the dithering code, but they are also available separately. See Gamma Correction.
GplDitherCreateInstance
Description
To optimize throughput, a dither handle is initialized when this function is invoked. This includes allocation and initialization of transform tables and parameters.
Format
APIRET APIENTRY GplDitherCreateInstance( PPVOID ppdh, // Returned pointer to dither handle // pointer HMCB hmcb, // User-specified memory handle PDITHEREQUEST pReq, // Pointer to dither-request structure PDITHERESULT pReply ); // Pointer to dither-reply structure
Parameters
ppdh(PPVOID) Pointer to the dither handle pointer that was created and returned by GplDitherCreateInstance.
hmcb(HMCB) If it is not zero, this parameter must be a handle (pointer to the API heap).
pReq(PDITHEREQUEST)
bReq (BYTE) Set to CMY_ALL or CMYK_ALL.
lDitherType (LONG) From JobProperties.
HT_LEVEL When selected, the following may be ORed with HT_LEVEL:
HT_PARAMETER HT_MIN_COLOR HT_PERCENT HT_FUNCTION
HT_DITHER_4x4 Use a 4x4 halftone pattern for 16 levels of perceived intensity. Also "snap.pHalftone" must be a pointer to a 16x4x4 byte array of dither patterns.
HT_DITHER_8x8 Use a 8x8 halftone pattern for 64 levels of perceived intensity. Also "snap.pHalftone" must be a pointer to a 16x8x8 byte array of dither patterns.
HT_MAGIC_SQUARES A tessalated (tiled) dither that populates a dither matrix to guarantee a semi-random color mix yet controls average occurrence of colors (randomized pattern).
HT_ORDERED_SQUARES Use recursive tesselated tiles of rectangular threshold arrays. Similar to HT_MAGIC_SQUARES, but uses a different method of populating dither matrix.
HT_ERR_DIFFUSION Stucki Error Diffusion-a nice quality filter for photograph-quality images.
HT_FAST_DIFFUSION Error diffusion with lower sampling rate, so error propagated less-essentially, a high-pass filter.
HT_STEINBERG_DIFFUSION Steinberg Error Diffusion-slightly higher pass than Stucki.
SrcOptions (SRCMODS) Flags that indicate the state of the buffer information.
fStartOfPage (BOOL) Set in users NewFrame function; initialized by SYSTEM.
fNewColors (BOOL) Set if pSrcInfo Color Table changes; initialized by SYSTEM.
fModify (BOOL) Set if pSrc may be modified for K (Black) when CMY set.
fResetErrBuf (BOOL) Set between pages or pictures when Err Buffers must be reset.
ulResetErrBufs (ULONG) 0,1,2,or 3 for Diffusion ONLY.
ulValue (ULONG) xxx << 20 value to be set as initialization value.
snap (SNAPIT) SYSTEM initialized midpoint and function control parameters.
pHalftone (PRGB2) Pointer to 4x4 8x8 or user-supplied table.
ulParm (ULONG) User-supplied midpoint or function address.
pArray (PBYTE) Pointer to 16x16 tables such as paintMixer or OrderSquares.
ulResolution (ULONG) The larger of x or y resolution.
iNumColors ( INT) Set by user (2 ** number bits per pel).
iSrcRowPels (INT) Number of pels in a source row.
iNumDitherRows (INT) Number of rows in a band.
pSrcInfo (PBITMAPINFO2) Pointer to user supplied BITMAPINFO2 structure; requires that cx and cy be set.
pbSrc (PBYTE) Printer to RGB2 input bitmap (rows are 32bit aligned).
iNumSrcRowBytes32 (INT) iDWordBytesInCMYKBandRow.
iNumDestRowBytes (INT) iBytesInSinglePlaneBandRow.
delta (DELTACOLOR) From JobProperties for tessalated-squares dithering only .
lHue (LONG) 0..360
lSaturation (LONG) 0..100
lValue (LONG) 0..100
fRemoveBlackColor (BOOL) Eliminate coincident black and color after dithering.
ulRGamma (ULONG) 3 .. 255 true gamma value; actual value times 10.
ulRBias (ULONG) 0 .. 255 gamma table minimum value.
ulGGamma (ULONG) 3 .. 255 true gamma value.
ulGBias (ULONG) 0 .. 255 gamma table minimum value.
ulBGamma (ULONG) 3 .. 255 true gamma value.
ulBBias (ULONG) 0 .. 255 gamma table minimum value.
pReply(PDITHERESULT) Reply structure is allocated and initialized on return
Returns
Success NO_ERROR 0
Failure INVALID_PARAMETER
Example Code
Following is an example of filling the dither-request structure and using GplDitherCreateInstance from the Omni driver during start-document processing:
pHandle->Req.iSrcRowPels = iBitsInArray; // Number of bytes in source, dword aligned pHandle->Req.iNumSrcRowBytes32 = iDWordBitsInArray/8; // Number of bytes in destination, byte aligned pHandle->Req.iNumDestRowBytes = iBitsInArray/8; // Fill in number of colors (derived from bitcount) pHandle->Req.iNumColors = Power ( 2, pddc->bmp.cBitCount ); pHandle->Req.iNumDitherRows = 1; if( pddc->pdb->pResInfo->ulXRes >= pddc->pdb->pResInfo->ulYRes ) pHandle->Req.ulResolution = pddc->pdb->pResInfo->ulXRes; else pHandle->Req.ulResolution = pddc->pdb->pResInfo->ulYRes;
/*-------------------*/ /* Color Technology */ /*-------------------*/ pHandle->Req.ulRGamma = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bRGamma; pHandle->Req.ulGGamma = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bGGamma; pHandle->Req.ulBGamma = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bBGamma; pHandle->Req.ulRBias = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bBias; pHandle->Req.ulGBias = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bBias; pHandle->Req.ulBBias = (ULONG)( pddc->pdb->pDriver->pGammas->pSelect+i )->bBias; pHandle->Req.ulRGamma = (ULONG)( (LONG)pHandle->Req.ulRGamma + pddc->pdb-> pJobProperties->lRedGamma ); pHandle->Req.ulGGamma = (ULONG)( (LONG)pHandle->Req.ulGGamma + pddc->pdb-> pJobProperties->lGreenGamma ); pHandle->Req.ulBGamma = (ULONG)( (LONG)pHandle->Req.ulBGamma + pddc->pdb-> pJobProperties->lBlueGamma ); pHandle->Req.ulRBias = (ULONG)( (LONG)pHandle->Req.ulRBias + pddc->pdb-> pJobProperties->lRedBias ); pHandle->Req.ulGBias = (ULONG)( (LONG)pHandle->Req.ulGBias + pddc->pdb-> pJobProperties->lGreenBias ); pHandle->Req.ulBBias = (ULONG)( (LONG)pHandle->Req.ulBBias + pddc->pdb-> pJobProperties->lBlueBias );
/*-------------------*/ /* Color Algorithm */ /*-------------------*/ switch ( pddc->pdb->pPrintMode->ulColorTech ) { case COLOR_TECH_CMYK: pHandle->Req.bReq = CMYK_ALL; break; case COLOR_TECH_CMY: pHandle->Req.bReq = CMY_ALL; break; }
/*-------------------*/ /* Color Algorithm */ /*-------------------*/ // Need gamma buffers only if printing in color (CMY/CMYK) if( pddc->pdb->pPrintMode->ulColorTech != COLOR_TECH_K ) { // Init modify flag telling Gamma/HSV that we may replace/change // values in the source bitmap. 1,2,4,8 bit pel bitmaps; then // if C,M,Y are to be printed, the RGB index will be set to white. // If 16, 24 bit bitmaps, then the R,G,B value is replaced with white. pHandle->Req.SrcOptions.fModify = TRUE;
/*-------------------*/ /* HSV */ /*-------------------*/ pHandle->Req.delta.lHue = pddc->pdb->pJobProperties->lHue; pHandle->Req.delta.lSaturation = pddc->pdb->pJobProperties->lSaturation; pHandle->Req.delta.lValue = pddc->pdb->pJobProperties->lValue;
/*-------------------*/ /* Dither */ /*-------------------*/ pHandle->Req.lDitherType = pddc->pdb->pJobProperties->ulAlgorithm; GPL_DITHER_SETUP_DEFAULTS( pHandle->Req, pddc->pdb->pJobProperties->ulLevel ) } // Set printer ' s physical head position in our ddc pddc - > ptlPrintHead . x = 0 ; if ( ORIENTATION _ PORTRAIT = = pddc - > pdb - > pJobProperties - > ulOrientation ) pddc - > ptlPrintHead . y = pddc - > pdb - > pFormInfo - > hcInfo . yPels - 1 ; else pddc - > ptlPrintHead . y = pddc - > pdb - > pFormInfo - > hcInfo . xPels - 1 ; GplDitherCreateInstance ( ( PPVOID ) & pHandle - > pdh , pddc - > pdb - > hmcbHeap , ( PDITHEREQUEST ) & pHandle - > Req , ( PDITHERESULT ) & pHandle - > Reply ) ;
/*--------------------------------*/ /* Init Dither Req struct */ /*--------------------------------*/ pCMYReq->pSrcInfo = pbmi; // Passed to choose rasterize LOOP { // Each band // Copy raster bits into our buffer pCMYReq->pbSrc = pbBitMap + iCurrentRow * pHandle->Req.iNumSrcRowBytes32; GplDitherRGBtoCMYK ( (PPVOID)&pHandle->pdh, pCMYReq, (PDITHERESULT)&pHandle->Reply );
GplDitherRGBtoCMYK
Description
This function performs the dithering.
Format
APIRET APIENTRY GplDitherRGBtoCMYK( PHDITHER pdh, PDITHEREQUEST pReq PDITHERESULT pReply );
Parameters
pdh(PHDITHER) Pointer to the dither handler that was created by GplDitherCreateInstance.
pReq(PDITHEREQUEST) If a diffusion dither algorithm is selected, use the macro GPL_SETUP_DITHER( req, ulLevel ) to set the SrcOptions structure.
or
If Magic Squares or Ordered Squares is selected, the following fields must be set:
lHue
lSaturation
lValueAddress of the API's pre-stuffed request structure. The following fields must be set by the API:
fNewColors Must be set to TRUE at the beginning of the page. This element is set to FALSE on return.
If fNewColors equals TRUE, the following two fields must be set:
ulGamma
lBias
pSrcInfo Must have the following two fields set:
cx
cy
If BitsPerPel is less than 16 and fNewColors equals TRUE, the pbmi array, argbColor[256] must be initialized.
pbSrc Pointer to the surface bitmap.
pReply(PDITHERESULT) Pointer to the reply structure.
Returns
Success NO_ERROR 0
Failure INVALID_PARAMETER
Example Code
Following is an example of dithering RGB to CMYK data from the Omni driver' s "render" callback function:
// Change logical height of band bitmap to 1 (this device chooses to dither each scanline) ulSavedcy = pddc->pbmi->cy; pddc->pbmi->cy = 1; // For each row in the current band's bitmap (each scanline) for( iCurrentRow=ulSavedcy; iCurrentRow > 0; iCurrentRow-- ) { // Set pointer to current row in our band's bitmap cmykReq.pbSrc = pbBits + iCurrentRow * iDWordBytesInCMYKBandRow; GplDitherRGBtoCMYK ( &pddc->pdh, &pddc->cmykReq, &pddc->pReply ); // Now our consecutive KCMY buffers contain dithered data to send to printer } /* end for */ // Restore bitmap height to TRUE value (no longer 1) pddc->pbmi->cy = ulSavedcy;
GplDitherRGBtoRGB
Description
This function is a shell for GplDitherRGBtoCMYK. It simply inverts the CMY pDestbuffer to RGB for a printer that requires RGB.
Format
APIRET APIENTRY GplDitherRGBtoRGB( PHDITHER pdh, PDITHEREQUEST pReq PDITHERESULT pReply );
Parameters
pdh(PHDITHER) Pointer to the dither handler that was created by GplDitherCreateInstance.
pReq(PDITHEREQUEST) Address of the API's pre-filled request structure.
pReply(PDITHERESULT) Address of the reply structure.
Returns
Success NO_ERROR
GplDitherDeleteInstance
Description
This function must be called at the end of a document so that memory that was allocated in GplDitherCreateInstancecan be freed.
Format
APIRET APIENTRY GplDitherDeleteInstance( PHDITHER pdh );
Parameter
pdh(PHDITHER) Pointer to the dither handler that was created by GplDitherCreateInstance.
Returns
Success NO_ERROR
Example Code
Following is an example of using GplDitherDeleteInstance:
// Tell the dither function to deallocate all it's buffers GplDitherDeleteInstance( (HDITHER)pHandle->pdh ); // Reminder: // Free all buffers our driver allocated on behalf of GENPLIB's dithering code // This includes error buffers for error-diffusion algorithms // as well as the destination buffers used for rendering
Gamma Correction
Printer paper, ink, resolution, and other characteristics can cause the actual printed color to be different from the desired color. This "skew" is non-linear and occurs over the entire color spectrum. A gamma-compensation curve is used for each color to approximate the non-linear skew. Because the reflected frequencies of colors can cause them to appear different than expected, you can modify the gamma of each color. Increasing the gamma will lighten an image that might otherwise look too dark.
Following are the gamma functions:
GplGammaCreateTable
Description
This function creates an RGB (K) gamma table based on input gammas and bias .
Format
APIRET APIENTRY GplGammaCreateTable( PBYTE pbGamma, LONG lRgamma, LONG lGgamma, LONG lBgamma, LONG lbias );
Parameters
pbGamma(PBYTE) A byte pointer to a 768-byte buffer.
pbGamma can be used as a PRGB2 instead of a PBYTE.
lRgamma(LONG) Red. Gamma multiplied by 10, with a range of 1 to 99.
lGgamma(LONG) Green. Gamma multiplied by 10, with a range of 1 to 99.
lBgamma(LONG) Blue. Gamma multiplied by 10, with a range of 1 to 99.
lbias(LONG) Offset, normally zero, generally for printers over 600 dpi.
Returns
Success 0
Failure INVALID_PARAMETER
GplGammaColorTableToGamma2
Description
For 8-bit pels or less, replaces an RGB color value in the PBITMAPINFO2 argbColor[0..256] structure with a gamma-corrected color value.
Format
APIRET APIENTRY GplGammaColorTableToGamma2( PBYTE pbGamma, PBITMAPINFO2 pbmi );
Parameters
pbGamma(PBYTE) A byte pointer to a 768-byte buffer.
pbGamma can be used as a PRGB2 instead of a PBYTE.
pbmi(PBITMAPINFO2) PBITMAPINFO2 is assumed to have a valid RGB2 color table as input. The following PBITMAPINFO2 fields are used:
cBitCount Bits per pel.
argbColor When cBitCount is 8 or less, this parameter must include values for 2 to the power of cBitCount (2**cBitCount).
Returns
Success 0
Failure INVALID_PARAMETER
Compression
The compression package contains routines that compress raster image data using common printer hardware-supported compression routines.
Raster printer drivers render on a per-page basis into a raster representation of an output page. As soon as rendering is completed for a given page, that raster data can be compressed into a format that the printer hardware supports. Compressed data is typically smaller than the original uncompressed data and will therefore transmit faster across communication lines to the printer.
Note:The caller of a compression routine should allocate a buffer to hold the compressed data whose size (in bytes) is as large as the the original uncompressed data.
To use the GenPLib Compression package, you must include:
INCL_GENPLIB_COMPRESS
Following are the GenPLib compression routines:
- GplCompressRLL
*GplCompressTIFF
*GplCompressDeltaRow
*GplCompressRLLDeltaRow
*GplCompressChooseMode
*GplCompressAscii85
*GplFaxG3EncodeBlock
*"GplFaxG3StartBlock"
*"GplFaxG3EndBlock"
*"GplFaxG3EndDoc"
*"GplFaxG3NewFrame"
*GplFaxG4EncodeBlock
*"GplFaxG4EndBlock"
*GplFaxTIFF2EncodeBlock
*"GplFaxTIFF2StartBlock"
*"GplFaxTIFF2EndBlock"
GplCompressRLL
Description
This function performs run-length limited (RLL) encoding.
Format
LONG APIENTRY GplCompressRLL( PBYTE pbDataIn, // Input raster data to compress (page/band) LONG cbDataIn, // Length of input data buffer (pbDataIn) PBYTE pbDataOut, // Output buffer to which compressed data is written LONG cbDataOut ); // Length count of compressed data written
Parameters
pbDataIn(PBYTE) Pointer to input data.
cbDataIn(LONG) Count of bytes in, pointed to by pbData.
pbDataOut(PBYTE) Pointer to output data.
cbDataOut(LONG) Size of buffer in bytes pointed to by pbDataOut.
Returns
Signed LONG, which is the length in bytes of the compressed data pointed to by cbDataOut.
Success Number of bytes in compressed return string.
Failure GPLCOMPRESS_ERROR (-1)
The output buffer length has been exceeded.
Notes
The input data is encoded with pairs of bytes. The first byte is the replacement count and the second byte is the data. A replacement count of 0 means that the data is not repeated.
GplCompressTIFF
Description
This function performs tagged image file format (TIFF) encoding, PackBits encoding algorithm. This function compresses a scanline.
Once in a repeated run, this function stops and emits a block if a different byte is encountered.
Once in a literal run, this function stops and emits a block if at least four repeated bytes follow. The next block will be a repeat block. Repeats of two 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.
Format
LONG APIENTRY GplCompressTIFF( PBYTE pbDataIn, // Input raster data to compress (page/band) LONG cbDataIn, // Length of input data buffer (pbDataIn) PBYTE pbDataOut, // Output buffer to which compressed data is written LONG cbDataOut ); // Length count of compressed data written
Parameters
pbDataIn(PBYTE) Pointer to input data.
cbDataIn(LONG) Count of bytes in.
pbDataOut(PBYTE) Pointer to output data.
cbDataOut(LONG) Size of buffer in bytes pointed to by pbDataOut.
Returns
Success Count of bytes put in destination.
Failure GPLCOMPRESS_ERROR (-1)
GplCompressDeltaRow
Description
This function performs delta-row encoding. This method replaces only the bytes in a new row that are different from the preceding (seed) row. Unreplaced bytes are replicated from the seed row. The new row then becomes the seed row after it is printed.
Format
INT APIENTRY GplCompressDeltaRow( INT usTotalBytes, // Bytes in the scan line PBYTE pbData, // Input raster data to compress PBYTE pbLastLine, // Previous scanline's raster data INT usMaxReturn, // Length of output buffer PBYTE pbReturn, // Output buffer with compressed data PUSHORT pDeltas ); // Differences indexes-start/end pairs
Parameters
usTotalBytes(INT) Count of bytes in, pointed to by pbData.
pbData(PBYTE) Pointer to bytes of data to compress.
pbLastLine(PBYTE) Pointer to previous scanline's raster data.
usMaxReturn(INT) Size of output buffer.
pbReturn(PBYTE) Pointer to compressed data will be written.
pDeltas(PUSHORT) Differences indexes = array of start and end pairs.
Note:This array is returned as the result of calling GplCompressChooseMode; therefore, you must call GplCompressChooseMode() before calling this function.
Returns
0 Current and previous line are identical.
>0 Length of data pointed to by pbReturn.
-1 GPLCOMPRESS_ERROR
usMaxReturn is not large enough for the compressed output.
GplCompressRLLDeltaRow
Description
This function performs RLL delta-row encoding. It compresses a string of bytes and returns the compressed string at pbReturn and the new string usLength as its return value. This method replaces only bytes in the current row that are different from the proceeding seed row. Unlike GplCompressDeltaRow, however, the replacement or delta bytes themselves are encoded.
Format
INT APIENTRY GplCompressRLLDeltaRow( INT usTotalBytes, // Bytes in the scan line PBYTE pbData, // Input raster data to compress PBYTE pbLastLine, // Previous scanline's raster data INT usMaxReturn, // Length of output buffer PBYTE pbReturn, // Output buffer with compressed data PUSHORT pDeltas ); // Differences indexes-start/end pairs
Parameters
usTotalBytes(INT) Count of bytes pointed to by pbData and pbLastLine.
pbData(PBYTE) Pointer to bytes of data to compress.
pbLastLine(PBYTE) Pointer to previous uncompressed data.
usMaxReturn(INT) Size of output buffer.
pbReturn(PBYTE) Pointer to compressed data will be written.
pDeltas(PUSHORT) Differences indexes = array of start and end pairs.
Returns
0 Current and previous line are identical.
>0 Length of data pointed to by pbReturn.
-1 GPLCOMPRESS_ERROR
usMaxOutput not large enough for the compressed output.
GplCompressChooseMode
Description
This function uses a semi-intelligent algorithm to select the compression mode that will most likely give the best compression for the row of data.
RLL Delta Rowis currently chosen if this method best and if the printer supports this compression. Delta Rowis chosen if most of the bytes are the same as the corresponding bytes in the previous row. TIFFis chosen if most of the bytes are repeated within this row. RLL is chosen if most of the bytes are repeated within this row and the printer does not support TIFF PackBits. No compression (value of 0)is chosen of most bytes are neither repeats within the row nor duplicates of the previous row.
Note:The function GplCompressChooseMode() must be run before either of the delta-compression functions GplCompressDeltaRow() or GplCompressRLLDeltaRow(). This function must be run first because pDelta is filled in by GplCompressChooseMode() while it is reading pbRow and pbLast_ Row. Performance is increased by combining GplCompressChooseMode() with either GplCompressDeltaRow() or GplCompressRLLDeltaRow().
Format
INT APIENTRY GplCompressChooseMode( PBYTE pbRow, PBYTE pbLast_Row, INT usRow_Length, ULONG CompressModes, PUSHORT pDelta );
Parameters
pbRow(PBYTE) Pointer to the current row's data.
pbLast_Row(PBYTE) Pointer to the last row's data.
usRow_Length(INT) The number of bytes in the row. Note that both the previous row and the current row are equal in size.
CompressModes(ULONG) Compression modes supported.
This is a ULONG with the follow bit positions used to represent compress modes that this printer supports:
GPLCOMPRESS_NONE
GPLCOMPRESS_RLL
GPLCOMPRESS_TIFF
GPLCOMPRESS_DELTAROW
GPLCOMPRESS_RLLDELTAROW
These values may be logically ORed together to create a bitfield of all compression methods to consider. For example,
CompressModes = GPLCOMPRESS_RLL | GPLCOMPRESS_TIFF
This tells the routine to only choose between the RLL and TIFF compression routines and GPLCOMPRESS_NONE.
pDelta(PUSHORT) Array of unsigned shorts to hold the offsets from the beginning of pbRow that differ from pbLast_Row. This data will be used by GplCompressDeltaRowand GplCompressRLLDeltaRow. Note that pDelta must have a length equal to two times usRow_Length plus one to hold the pDelta output . There is no check on the size of pDelta. You must supply a size of a minimum of two times usRow_Length plus one. This is because the maximum number of differences occur when every other byte differs from the preceding row.
Returns
The mode that will probably compress the best:
0 No compression
1 RLL (run-length limited) compression
2 TIFF (tagged image file format) compression
3 Delta-row compression
9 RLL delta-row compression
Notes
For GplCompressDeltaRowand GplCompressRLLDeltaRow, pDelta is filled with the start and end of the difference fragments. Note that a difference fragment is defined as a contiguous group of bytes in the current row that differ from those in the previous row. For example:
/-----------------------------------------------------------------------\ |Column Number |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 | |---------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---| |Current Row |7 |8 |1 |0 |4 |5 |6 |7 |23 |128|257|1 |7 |8 | |Byte Value | | | | | | | | | | | | | | | |---------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---| |Previous Row |7 |1 |3 |1 |4 |5 |9 |7 |23 |128|7 |9 |7 |8 | |Byte Value | | | | | | | | | | | | | | | \-----------------------------------------------------------------------/
There are three difference fragments:
- Fragment one begins at column 2 and ends at column 4.
*Fragment two begins at column 7 and ends at column 7.
*Fragment three begins at column 11 and ends at column 12.
The output in pDelta will be 2 4 7 7 11 12 0. Note that these are unsigned shorts and the difference array is null-terminated. If no difference fragments are found (the previous and current buffers are the same) the first unsigned short in pDelta will be 0.
pDeltaabove will point to a array of the indexes stored to used by GplCompressDeltaRow() and GplCompressRLLDeltaRow().
Example Code
Following is an example of GplCompressChooseMode usage from the Omni driver for a typical inkjet device:
iNewMode = GplCompressChooseMode( pbBuffer, // Contains current row of data pbLastLine, // Contains previous row of data iBytesInRow, // Number of bytes in output row (pbBuffer) GPLCOMPRESS_RLL | // All compression modes supported GPLCOMPRESS_TIFF, pDelta ); // Offsets into pbBuffer ((2 x pbBuffer) + 1) if( iNewMode != iCurrentMode ) { // Send command to printer to set new mode iCurrentMode = iNewMode; } /* end if */ switch( iNewMode ) { case 0: // No Compression break; case 1: iCompressed = GplCompressRLL(); break; case 2: iCompressed = GplCompressTIFF(); break; case 3: iCompressed = GplCompressDeltaRow(); break; case 9: iCompressed = GplCompressRLLDeltaRow(); break; } /* end switch */ // Write raster data transfer command and compressed data
GplCompressAscii85
Description
This function performs ASCII encoding. It encodes 4 bytes in to 5 bytes out , and it converts data from a base 256 on input to a base-85 representation on output. The output is then output in ASCII with base 85.
Buffer allocation is the responsibility of the driver.
Format
INT APIENTRY GplCompressAscii85( PBYTE pSource, // Source input data buffer (normal Hex 256) PBYTE pDest, // Destination output data buffer (ASCII 85) INT usSourceLen ); // Source buffer input length
Parameters
pSource(PBYTE) Pointer to input data buffer.
pDest(PBYTE) Pointer to output data buffer. It must be at least 5/4 size of pSource.
usSourceLen(LONG) Length of source buffer in bytes.
Returns
Success Count of bytes put in destination.
Failure GPLCOMPRESS_ERROR (-1)
GplFaxG3EncodeBlock
Description
This function performs G3 "Fax"-type compression.
It provides a run-length type compression with table-lookup replacement encodings for certain bit sequences. This type of compression is also know as "Modified Huffman."
Format
GplFaxG3EncodeBlock( HTHREAD hThread, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition, PBYTE pbInput, ULONG ulBitwide, ULONG ulBitheight, PFN pfnFlushBuffer );
Parameters
hThread(HTHREAD) Handle.
pbOutput(PBYTE) Pointer to output buffer to fill.
ulOutputSize(ULONG) Number of output bytes; must be divisible by 4.
pulBitposition(PULONG) Pointer to bit position in output buffer; gets updated and must be stored off the pddc.
pbInput(PBYTE) Input pointer to upper left corner of raster image to compress.
ulBitwide(ULONG) Width of raster image to compress in bits; must be less than or equal to 2560 + 63 = 2623.
ulBitheight(ULONG) Height of raster image to compress in bits.
pfnFlushBuffer(PFN) The prototype for this function must be:
void pfnFlushBuffer ( PVOID, PBYTE, ULONG );
PVOID Use is the same as G4.
PBYTE Unsigned char * to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1)
Related FunctionsThe following G3 "Fax"-compression related functions provide help in sending down special G3 commands.
GplFaxG3StartBlock() Modified Huffman (MH) Group 3 end of line (EOL) sent at the beginning of the first page. This function outputs the EOL to pbOutput and initializes pulBitposition to 12. It simply sends out the EOL bit sequence to signal the start of raster data (for example, '000000000001 ' binary, eleven 0's and a single 1).
Inputs
pbOutput Output buffer to fill
pulBitposition Bit-position count in the output buffer
Returns Void
GplFaxG3EndBlock() End of block flushed.
GplFaxG3EndBlock( PVOID hThread, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition PFN pfnFlushBuffer );
Inputs
hThread PVOID.
pbOutput Output buffer to fill.
ulOutputSize Size in bytes of output buffer; must be a multiple of 32 bits; must be divisible by 4.
pulBitposition Bit-position count in the output buffer; *pulBitposition gets updated and must be stored off the pddc.
pfnFlushBuffer Flush buffer function; prototype for this function must be:
void pfnFlushBuffer( PVOID, PBYTE, ULONG );
PVOID Use is the same as above.
PBYTE Unsigned char to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1).
GplFaxG3EndDoc() Modified Huffman (MH) Group 3 return to control (RTC) sent at the end of document.
GplFaxG3EndDoc( PVOID hThread, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition PFN pfnFlushBuffer );
Inputs
hThread PVOID.
pbOutput Output buffer to fill.
ulOutputSize Size in bytes of output buffer; must be a multiple of 32 bits; must be divisible by 4.
pulBitposition Bit-position count in the output buffer; gets updated and must be stored off the pddc.
pfnFlushBuffer Flush buffer function; prototype for this function must be:
void pfnFlushBuffer( PVOID, PBYTE, ULONG );
PVOID Use is the same as above.
PBYTE Unsigned char to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1).
GplFaxG3NewFrame() Modified Huffman (MH) Group 3 end of line (EOL) sent at the beginning of each new page. This function is the same as GplFaxG3EncodeBlock() except that it flushes data at this point to cause the current page to be completely sent. This call sends compressed data followed by the EOL bit sequence (see GplFaxG3StartBlock).
Instead of GplFaxG3NewFrame() you can use pfnFlushBuffer() = NULL to see whether or not the buffer for GplFaxG3EncodeBlock() is large enough. You output the bytes after GplFaxG3EncodeBlock() returns OK. You can then call GplFaxG3StartBlock(). This function places an EOL in the output buffer and sets the pulBitposition to 12.
GplFaxG3NewFrame( HTHREAD hThread, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition PFN pfnFlushBuffer );
Inputs
hThread HTHREAD
pbOutput Output buffer to fill.
ulOutputSize Size in bytes of output buffer; must be a multiple of 32 bits.
pulBitposition Bit-position count in the output buffer.
pfnFlushBuffer Flush buffer function; prototype for this function must be:
void pfnFlushBuffer( PVOID, PBYTE, ULONG );
PVOID Use is the same as above.
PBYTE Unsigned char to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1)
GplFaxG4EncodeBlock
Description
This function performs G4 "Fax"-type compression.
It is similar to GplFaxG3EncodeBlock(), but it has five extra parameters. These extra parameters are used to keep track of on/off bit runs between calls.
The driver is again responsible for all memory allocations.
Make sure all buffers for on/off bit tracking are equal to scanline DWORD aligned.
Format
GplFaxG4EncodeBlock( PVOID pddc, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition, PBYTE pbInput, ULONG ulBitwide, ULONG ulBitheight, PFN pfnFlushBuffer, PULONG pulwstartc, PULONG pulbstartc, PULONG pulwstartp, PULONG pulbstartp, ULONG ulSkipCount );
Parameters
pddc(PVOID) First parameter to pfnFlushBuffer; generally pddc or hThread.
pbOutput(PBYTE) Pointer to output buffer to fill.
ulOutputSize(ULONG) Size in bytes of output buffer; must be a multiple of 32 bits; must be divisible by 4.
pulBitposition(PULONG) Pointer to position in the output buffer; gets updated and must be unique to each print job; *pulBitposition must be zero on the first invocation of this function for a block.
pbInput(PBYTE) Input pointer to upper left corner of raster image to compress.
ulBitwide(ULONG) Width of raster image to compress in bits; must be less than or equal to 2560 + 63 = 2623.
ulBitheight(ULONG) Height of raster image to compress in bits.
pfnFlushBuffer(PFN) The prototype for this function must be:
void pfnFlushBuffer ( PVOID, PBYTE, ULONG );
PVOID Use is the same as G3; necessary parameter for separating printout; generally pddc or hThread.
PBYTE Unsigned char * to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
pfnFlushBuffer can be either NULL or point to a function that you supply that will write the compressed bytes out. If pfnFlushBuffer is not NULL, this function will be called when output buffer is full. If pfnFlushBuffer is NULL, you must write the bytes out yourself.
If pfnFlushBuffer() = NULL this function will compress the data and place it into pbOutput. If the output buffer size is not large enough for all the compressed data, the function will return with -1 = error. If pfnFlushBuffer() is not NULL, every time pbOutput is full, pfnFlushBuffer( ) is called to write the compressed bytes out. Note that the return value will the total number of bytes written even though the buffer was filled multiple times.
pulwstartc(PULONG) Pointer to array of ULONGs. Its length must be ( ulBitwide + 31 ) / 32 + 2. The 2 extra ULONGs are needed. So for an image of 371 bits width, the length of this array is ( 371 + 31 ) / 32 = 12 plus 2 more-which is 14 unsigned longs. This array is used to store the start bits of the beginning of consecutive 0 bits for the current scan line.
pulbstartc(PULONG) Size is the same calculation as above. This array is used to store the start bits of the beginning of consecutive 1 bits for the current scan line.
pulwstartp(PULONG) Size is the same calculation as above. This array is used to store the start bits of the beginning of consecutive 0 bits for the previous scan line. This must be zero filled on the first invocation of this function.
pulbstartp(PULONG) Size is the same calculation as above. This array is used to store the start bits of the beginning of consecutive 1 bits for the previous scan line. This must be zero filled on the first invocation of this function.
ulSkipCount(ULONG) Number of bytes to skip to the next row of input data to compress.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1)
Related FunctionThe following is a G4-compression related function automatically sends the "End Block" data sequence (24 bits represented by Hex 001001).
GplFaxG4EndBlock() Modified Read ( MRR) Group 4 compression with K = infinity for sending end-of-facsimile block (EOFB). This function has the same first eight parameters as GplFaxG4EncodeBlock().
GplFaxG4EndBlock( PVOID pHandle, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition, PBYTE pbInput, ULONG ulBitwide, ULONG ulBitheight, PFN pfnFlushBuffer );
Inputs
pddc PVOID; used as first parameter to the pfnFlushBuffer function; generally the pddc or HTHREAD.
pbOutput Output buffer to fill.
ulOutputSize Size in bytes of output buffer; must be a multiple of 32 bits; must be divisible by 4.
pulBitposition Bit-position count in the output buffer; gets updated and must be unique to each print job.
ulBitwide Width of the raster image in bits.
ulBitheight Height of the raster image in bits.
pfnFlushBuffer Flush buffer function; prototype for this function must be:
void pfnFlushBuffer( PVOID, PBYTE, ULONG );
PVOID Necessary parameter for separating printout; generally pddc or hThread.
PBYTE Unsigned char * to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
pfnFlushBuffer can be either NULL or point to the function you supply that will write the compressed bytes out. If pfnFlushBuffer is not NULL, this function will be called when the output buffer is full. If pfnFlushBuffer is NULL, you must write the bytes out yourself.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1)
GplFaxTIFF2EncodeBlock
Description
TIFF algorithm 2 compression. This function essentially provides a " Modified Huffman" G3 compression with no size limits. It is limited only by the byte representation of ULONG (4 Gigabytes).
Format
GplFaxTIFF2EncodeBlock( PVOID pHandle, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition, PBYTE pbInput, ULONG ulBitwide, ULONG ulBitheight, PFN pfnFlushBuffer );
Parameters
pHandle(PVOID) Pointer to a handle.
pbOutput(PBYTE) Pointer to output buffer to fill.
ulOutputSize(ULONG) Size in bytes of output buffer; must be a multiple of 32 bits; must be divisible by 4.
pulBitposition(PULONG) Pointer to position in output buffer.
pbInput(PBYTE) Input pointer to upper left corner of raster image to compress.
ulBitwide(ULONG) Width of raster image to compress in bits.
ulBitheight(ULONG) Height of raster image to compress in bits.
pfnFlushBuffer(PFN) Flush buffer function; prototype for this function must be:
void pfnFlushBuffer( PVOID, PBYTE, ULONG );
PVOID Necessary parameter for separating printout; generally pddc or hThread.
PBYTE Unsigned char * to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
Success Count of data written out (compressed data count).
Failure GPLCOMPRESS_ERROR (-1)
Related FunctionsThe following are TIFF2-compression related functions.
GplFaxTIFF2StartBlock() TIFF algorithm 2 compression start-of-document function.
Inputs
pulBitposition Bit-position count in the output buffer; *pulBitposition gets updated and must be stored off the pddc; function just sets pulBitposition to 0 (you can do this yourself).
Returns Void
GplFaxTIFF2EndBlock() TIFF algorithm 2 compression to flush output buffer.
GplFaxTIFF2EndBlock( PVOID pHandle, PBYTE pbOutput, ULONG ulOutputSize, PULONG pulBitposition, PBYTE pbInput, ULONG ulBitwide, ULONG ulBitheight, PFN pfnFlushBuffer );
Inputs
hThread HTHREAD.
pbOutput Output buffer to fill.
ulOutputSize Size in bytes of output buffer; must be divisible by 4.
pulBitposition Bit-position count in the output buffer; must be a multiple of 32 bits; gets updated and must be stored off the pddc.
pbInput Input pointer to upper left corner of raster image to compress.
ulBitwide Width of the raster image in bits.
ulBitheight Height of the raster image in bits.
pfnFlushBuffer Flush buffer function; prototype for this function must be:
int pfnFlushBuffer( HTHREAD, PBYTE, ULONG );
HTHREAD Gotten from GplThreadCreateInstance().
PBYTE Unsigned char to output buffer; same as pbOutput.
ULONG Unsigned long; size of pbOutput buffer; same as ulOutputSize.
Returns
TRUE If OK
FALSE If error
Exception Management
This package contains functions for setting errors with WinSetErrorInfo and logging appropriate warnings, exceptions, and error codes.
Four ascending severity levels are defined for error messages:
Warning The function detected a problem, took corrective action, and was able to complete processing successfully.
Error The function detected a problem for which no sensible corrective action is possible. The function is not executed and the system remains at the same state as when the function was requested.
Severe Error The function detected a problem from which the system cannot reestablish its state. The function has partially executed and the application must now make some corrective action to restore the system to a known state.
Unrecoverable Error The function detected an error from which it is impossible for the system to reestablish the state that it held at the time that the function was called. It is also impossible for the application to restore the system to a known state.
To use the GenPLib Exception-Management package, you must include:
INCL_GENPLIB_ERROR
The following functions are included in the package:
GplErrSetDosError
GplErrSetError
GplErrSetSevereError
GplErrSetWarning
GplErrSetUnrecoverableError
GplErrSetDosError
Description
This function saves DOS error.
Format
ERRORID APIENTRY GplErrSetDosError( USHORT usDosError );
Parameter
usDosError(USHORT) Any error code defined in BSEERR.H that best identifies the failing event.
Returns
Success ERRORID
Failure None
GplErrSetError
Description
This function saves an error.
Format
ERRORID APIENTRY GplErrSetError( USHORT usError );
Parameter
usError(USHORT) Any error code defined in PMERR.H that best identifies the failing event.
Returns
Success ERRORID
Failure None
GplErrSetSevereError
Description
This function saves a severe error.
Format
ERRORID APIENTRY GplErrSetSevereError( USHORT usError );
Parameter
usError(USHORT) Any error code defined in PMERR.H that best identifies the failing event.
Returns
Success ERRORID
Failure None
GplErrSetWarning
Description
This function saves the error warning.
Format
ERRORID APIENTRY GplErrSetWarning( USHORT usError );
Parameter
usError(USHORT) Any error code defined in PMERR.H that best identifies the failing event.
Returns
Success ERRORID
Failure None
GplErrSetUnrecoverableError
Description
This function saves an unrecoverable error.
Format
ERRORID APIENTRY GplErrSetUnrecoverableError( USHORT usError );
Parameter
usError(USHORT) Any error code defined in PMERR.H that best identifies the failing event.
Returns
Success ERRORID
Failure None
Memory Management
This package manages global and process (shared and non-shared) memory areas (heaps) using a single handle to a memory control block (HMCB) for all allocations. Therefore, you do not need to manage different heap or memory handles within your code.
This package calls appropriate OS/2 system APIs for memory creation and allocation. Dosxxx, SSxxx, and other API decisions are optimized for current OS/2 version performance. Examples include the underlying file system paging architecture and the number of processes in system.
Memory areas (heaps) are automatically grown when the initial memory size runs out. Committing more memory than needed is not required. Your code can use a single HMCB and underlying code will manage multiple memory areas ( heaps) if necessary.
Sets of debug trace information are displayed whenever memory is overwritten by other processes or writes to memory exceed the allocation size. Memory that has been allocated and not freed (memory leaks) is also shown as debug information.
To use the GenPLib Memory-Management package, you must include:
INCL_GENPLIB_MEMORY
The following APIs comprise the GenPLib Memory-Management package:
- GplMemoryCreateInstance
*GplMemoryDeleteInstance
*GplMemoryAlloc
*GplMemoryFree
*GplMemoryGetObjectSize
*GplMemorySetUserID
Call Flow
The GplMemoryCreateInstance() function should be the first memory API called in order to get a handle to a memory control block (HMCB). The HMCB handles all memory allocations. Using an HMCB, any number of memory allocations can be made using GplMemoryAlloc(). These allocations should be freed using GplMemoryFree.
GplMemoryDeleteInstance() is used when the HMCB is no longer needed for memory allocations.
Note:Any memory that was allocated using GplMemoryAlloc() using an HMCB being deleted by GplMemoryDeleteInstanceand not freed by a corresponding GplMemoryFree() call will be shown as debug output (with location of function where allocation was done) for developers to correct memory leaks within their code.
GplMemoryCreateInstance
Description
This function creates an MCB and a user heap.
Format
HMCB APIENTRY GplMemoryCreateInstance( ULONG ulPrimarySize, ULONG ulExtSize, ULONG ulThreshold, ULONG ulType );
Parameters
ulPrimarySize(ULONG) Initial Heap size in bytes.
ulExtSize(ULONG) Heap growth size fills in bytes.
ulThreshold(ULONG) Threshold for heap allocation. Requests larger than this will be converted to DosAllocMem.
ulType(ULONG) Heap type (process, shared). See the following notes for a description of process and shared heaps.
Returns
Success Valid handle to memory control block. Failure NULL.
WinGetLastError() will return one of the following:
PMERR_MEMORY_ALLOCATION_ERROR
PMERR_INV_OR_INCOMPAT_OPTIONS
Notes
Treat creating a memory instance like creating a memory heap. The ulSize parameter should be a reasonable amount of memory for most of your processing. It is not necessary to set ulSize to a high number so that you do not run out of memory, because the memory area will automatically grow if your processing allocates more than the amount originally set by ulSize.
When the memory area is automatically grown, the ulExtSize value is used to determine how large an additional memory area should be created. A default value of 0 (zero) may be used, and the growth size will be tailored to a reasonable amount for the OS/2 version.
The GplMemoryAlloc() API will allocate memory blocks differently based on the ulThreshold value. Typically, allocations of memory of sizes less than the threshold are allocated in a fast access memory area, and sizes larger than the threshold are allocated from a different memory pool. A default value of 0 (zero) may be used and the threshold will be automatically set to perform most efficiently on the current OS/2 version.
The ulType parameter allows you to specify the type of memory that you want to allocate. This defines the scope of accessibility to the memory within your driver or program and is one of the following:
SHARED_MEMORYUsed to create a global memory area (heap). For example, it is used for allocating global data like string tables in a printer driver.
PROCESS_MEMORYUsed to create a per process memory area (heap). For example , it is used for allocating a per device context (DC) memory in a printer driver.
GplMemoryDeleteInstance
Description
This function frees memory heap(s) for the user.
Format
APIRET APIENTRY GplMemoryDeleteInstance( HMCB hMCB );
Parameter
hMCB(HMCB) Pointer to memory allocated.
Returns
Success NO_ERROR.
Returns valid handle to memory control block. Failure ERROR_INVALID_PARA
or return values from:
SSFreeMem
DosFreeMem
DosSubUnsetMem
WinGetLastError() returns one of the following:
PM_INV_OR_INCOMPAT_OPTIONS
PMERR_MEMORY_DEALLOCATION_ERR
GplMemoryAlloc
Description
This function allocates memory for the user.
Format
PVOID APIENTRY GplMemoryAlloc( HMCB hMCB, ULONG ulSize );
Parameters
hMCB(HMCB) Handle to memory control block.
ulSize(ULONG) Amount to allocate.
Returns
Success Valid pointer to memory allocated. Failure NULL.
WinGetLastError() returns one of the following:
PMERR_INV_OR_INCOMPAT_OPTIONS
PMERR_INSUFFICIENT_MEMORY
GplMemoryFree
Description
This function frees memory for a user.
Format
APIRET APIENTRY GplMemoryFree( PVOID pData );
Parameter
pData(PVOID) Pointer to memory allocated.
Returns
Success NO_ERROR. Failure ERROR_INVALID_PARA
or return values from:
SSFreeMem
DosFreeMem
DosSubFreeMem
WinGetLastError() returns one of the following:
PM_INV_OR_INCOMPAT_OPTIONS
PMERR_MEMORY_DEALLOCATION_ERR
GplMemoryGetObjectSize
Description
This function returns the size of a memory object allocated by GplMemoryAlloc.
Format
LONG APIENTRY GplMemoryGetObjectSize( PVOID pData );
Parameter
pData(PVOID) Pointer to object.
Returns
Success Size of memory object.
(LONG) lsize
Failure 0, no size found for memory object. WinGetLastError will return PMERR_INVALID_PARAMETERS (meaning pData was invalid or NULL).
GplMemorySetUserID
Description
This function is optional, and it is helpful in debugging. You attach a pointer to the heap instance (like your pddc or pdb)-this extra pointer can then be viewed under the kernel debugger.
Format
VOID APIENTRY GplMemorySetUserID( HMCB hMCB, ULONG ulUserID );
Parameters
hMCB(HMCB) Handle to memory control block.
ulUserID(ULONG) Pointer to something helpful.
Implementation
The GenPLib Memory-Management package was created to provide consistency and to simplify the growth and management of heaps.
This package was one of the first developed for driver use. When writing a driver "from scratch" or modifying a driver to use GenPLib, begin with this package because many of the other GenPLib packages require memory allocated in the unique format of the memory-management package.
Previously, all drivers had to manage their own memory heaps, often using memory allocation packages exported from other parts of the OS/2 system-for example, the INCL_WINHEAP functions from PM WIN or the Subsystem Allocation routines in the PM Graphics Rendering Engine (GRE). It was never clear what routines should be used in a presentation driver or where they should be used (especially for portability). Many of these packages did not allow the caller to grow their heaps, provided no controls for memory leakage, and had no validation or recovery when a driver terminated unexpectedly.
A typical raster printer driver creates two types of heaps: a shared heap during Dynamic Link Library (DLL) initialization processing, and a per-DC heap when the PM GRE enables the driver during the FILL_PHYSICAL (02 Hex) subfunction. These heaps are freed during corresponding DLL termination and DISABLE_PHYSICAL calls to the driver.
In addition, a per-process heap is also created for the OS2_PM_DRV_DEVMODE entry point in a printer presentation driver. This entry point causes the driver to display its printer and job properties dialogs to the user or to retrieve printer and job property information for a specific output device/ destination.
A typical driver initially allocates a 256KB shared global heap and a 100KB per-DC heap and elects to use the memory package's default heap growth size and threshold for larger allocations (achieved by passing in 0L for parameters 2 and 3 for GplMemoryDeleteInstance).
In case of unexpected driver termination, a driver should register a per- process exception handler for each of the major presentation driver entry points. This exception handler can contain cleanup code that frees any per- process heaps created using GplMemoryCreateInstancein case any code problems cause an exception to occur.
One major benefit of the GenPLib memory code is the ability to detect memory leaks (memory a driver allocates but never frees). Whenever a call to GplMemoryDeleteInstanceis made, all memory allocated from the heap is freed so that no leaks can occur. If the debug version of the GenPLib library is used, while GplMemoryDeleteInstanceis cleaning up memory areas that a developer forgot to free, it will inform the developer on a debugging terminal which line of code allocated the memory that was not freed. This is possible because the memory-management package records the function address (and other information) from where GplMemoryAllocis called.
An OS/2 presentation driver must consider the memory constraints of the user and other programs in the system. In the past, drivers allocated large heaps, hoping the memory an application needed would never overrun the amount initially allocated and cause an exception. Under the paging architecture of OS/2 Warp, however, all the heap memory is often committed during heap creation.
All this memory could be forced in and never used by an application (for example, an application queries the driver for the devices it supports and performs no output). In this case, the driver's memory pages would not be touched, so OS/2 would slowly page it out and give it back to the applications that had it in the first place. As a result, a good deal of swapping could occur for active addressable memory, especially on low-RAM systems. The alternative was to force the driver to manage its own heap growth and consolidate multiple heaps.
Using the GenPLib Memory-Management package, the heap is identified to the driver as a generic handle to a memory control block (HMCB), not as an address into memory. This handle is supplied by GplMemoryCreateInstanceand is used to identify the heap for all subsequent memory allocations and frees.
Therefore, a reasonable initial heap can be created that is just large enough to allow the driver to enable and respond to basic queries. As applications use the driver to render graphics (or other memory-intensive operations), the memory package detects when a given GplMemoryAlloccall will overflow the current heap and grows it by a default or specified size. The caller does not ever need to know that the heap has grown because it continues to use the same HMCB, while the memory package chains these heaps together.
Example Code
Creating and Allocating From a Per-DC Heap
Following is an example of creating and allocating from a per-DC heap during a printer-driver enable via the OS2_PM_DRV_ENABLE entry point:
ULONG APIENTRY OS2_PM_DRV_ENABLE( ULONG ulSubFunc, ULONG p1, ULONG p2 ) { switch( ulSubFunc ) // Determine which enable/disable subfunction { case FILL_PHYSICAL: // Enable subfunction { // Create a per-DC memory area (heap) hmcbHeap = GplMemoryCreateInstance( LEN_DCHEAP, // Size of DC Heap (80K) 0L, // Default extent 0L, // Default threshold PROCESS_MEMORY ); // Type of heap (define in GPLMEM.H) // If GplMemoryCreateInstance succeeded if(hmcbHeap != NULL); { // Allocate PDEVICEBLOCK pddc->pdb = ( PDEVICEBLOCK ) GplMemoryAlloc( hmcbHeap, sizeof( DEVICEBLOCK ) ); } /* end if */ } /* end case */ break; } /* end switch */ } /* end OS2_PM_DRV_ENABLE */
Note:System memory must be used when passing data buffers to PrtWrite() calls.
Creating a Global Heap
Following is an example of creating a global heap:
ULONG APIENTRY _DLL_InitTerm( ULONG hThisModule, ULONG ulFlag ) { switch( ulFlag ) // Flag to determine which load/unload module subfunction { case 0: // Load module { // Create a global heap globals.pvHeap = GplMemoryCreateInstance( LEN_SHAREDHEAP, // Initial size (256K) 0, // Default extent 0, // Default threshold SHARED_MEMORY); // Type of heap (defined in GPLMEM.H) } /* end case */ break; } /* end switch */ } /* end _DLL_InitTerm */
Allocating From a Global Heap
Following is an example of allocating from a global heap:
switch( ulSubFunc ) // Determine which enable/disable subfunction { case FILL_LOGICAL: // Enable subfunction { // For every string in our driver's string resource table for( i=0; i < STRING_TABLE_SIZE; i++ ) { // Load each string from resource table (returns length) sLen = WinLoadString (szTemp); // Allocate memory to hold string just loaded from global heap globals.pbStringTable[i] = GplMemoryAlloc( globals.pvSharedHeap, sLen+1 ); // Copy string from temporary buffer to our driver's global string table strcpy( globals.pbStringTable[i], szTemp ); } /* end for */ break; } /* end case */ } /* end switch */
Deleting a Per-DC Heap
Following is an example of deleting a per-DC heap:
ULONG APIENTRY OS2_PM_DRV_ENABLE( ULONG ulSubFunc, ULONG p1, ULONG p2 ) { switch( ulSubFunc ) { case DISABLE_PHYSICAL: { // Free per-DC heap after freeing per-DC memory objects GplMemoryDeleteInstance( hmcbHeap ); } /* end case */ break; } /* end switch */ } /* end OS2_PM_DRV_ENABLE */
Deleting a Global Heap
Following is an example of deleting a global heap:
ULONG APIENTRY _DLL_InitTerm( ULONG hThisModule, ULONG ulFlag ) { switch( ulFlag ) { case 1: { // Free global heap after freeing global memory objects GplMemoryDeleteInstance( globals.pvSharedHeap ); } /* end case */ break; } /* end switch */ } /* end _DLL_InitTerm */
Output-Thread Management
The output-thread management module provides a way to create multiple output threads that will manage the sending of data buffers to the printer. This functionality has also been called second-thread code; however, the implementation allows a separate thread per physical output address (for example, LPT, COM, and file).
This package seamlessly manages multiple buffer allocations and chains them together. It adjusts the internal data buffering to always try to keep the printer busy processing data. The functions assure that buffer sizes and their reuse align for the best performance with the system-memory memory model (for example, the OS/2 paging architecture).
Note: You may override the default buffer size and the maximum number of buffers to create.
Other benefits of using the separate output-thread code in your driver include:
- Ability to pass off data buffers as fast as you can fill them without waiting for a device with slower transfer speeds
- Unknowingly, the OS/2 PM graphics engine (and other system components) might have locked down system resources, such as fonts, while calling your driver. Therefore, implementing the thread code allows you to return to the graphics engine and free up the resource for other parts of the system, such as the display. This makes the system and applications more responsive to the user.
- The package uses the GenPLib Exception-Management package for simple debug tracing.
- The package uses the GenPLib Memory-Management package for allocation of instance data.
To use the GenPLib Output-Thread Management package, you must include:
INCL_GENPLIB_THREAD
Following are the Output-Thread Management APIs:
- GplThreadCreateInstance
- GplThreadStart
- GplThreadOutput
- GplThreadEnd
- GplThreadDeleteInstance
- GplThreadAbortDoc
- GplThreadResetAbortDoc
- GplThreadFlushBuffer
- GplThreadHookDeviceWrites
Call Flow
The thread instance (data and semaphores) is initialized; but a real thread is not spun off until you are certain that the application is really sending data to be printed. Therefore, you can systematically use GplThreadCreateInstance() at enable and GplThreadStart() at the first data write. This keeps the code straightforward.
GplThreadCreateInstance
Description
This function is used to allocate and initialize thread instance data. This function must be called before making any other thread calls in order to get a thread instance handle (HTHREAD). Semaphores and buffers are not created or allocated by this call.
Format
BOOL APIENTRY GplThreadCreateInstance( HMCB hMcb HMODULE hMod, HTHREAD *phThread, PVOID pvUserData );
Parameters
hMcb(HMCB) Handle to the memory control block (See Memory Management).
hMod(HMODULE) Handle of calling module. Used for exception management and error logging.
*phThread(HTHREAD)-output Thread instance handle.
pvUserData(PVOID)-output This is used in debugging and is optional. It is recommended that you place a helpful pointer, such as your pddc or pdb pointer.
Returns
Success TRUE
Failure FALSE
GplThreadStart
Description
This function starts or updates thread parameters. It creates semaphores and buffers, committing system resources.
Format
BOOL APIENTRY GplThreadStart( HTHREAD hThread, LHANDLE hSpooler, HFILE hDev, ULONG ulBufferSize, USHORT usMaxBuffers, UCHAR ucAbortChar, ULONG ulAbortCharCount, ULONG ulAbortBufferSize, PBYTE pbAbortBuffer, PSZ pszAbortString, PSZ pszLogAddress, PSZ pszWriteError, PSZ pszDeviceDescription, LONG lDCType );
Parameters
hThread(HTHREAD) Instance handle of thread to start. Returned by GplThreadCreateInstance.
hSpooler(LHANDLE) Handle to Spooler (OD_QUEUED). Returned from SplQmOpen. May be zero (0) if hDev is supplied.
hDev(HFILE) Handle to Device (OD_DIRECT). Returned from PrtOpen. May be zero (0) if hSpooler is supplied.
ulBufferSize(ULONG) Size of buffer allocations. May be 0 to use default size.
usMaxBuffers(USHORT) Maximum number of buffers to create. May be 0 to use default # of buffers.
ucAbortChar(UCHAR) Character to send before the abort string. ucAbortChar can be used for devices that need to be sent a number of bytes before the abort string can be sent. ulAbortChar is sent first during the abort sequence.
ulAbortCharCount(ULONG) Number of ucAbortChars to send to the device.
ulAbortBufferSize(ULONG) Abort buffer size in bytes.
pbAbortBuffer(PBYTE) Pointer to buffer to send when aborting a job. Buffer must not be deleted until after GplThreadEnd. ulAbortBuffer is sent after ulAbortChar.
pszAbortString(PSZ) Abort job reset command for your specific printer language. May be NULL and no string will be sent. pszAbortString is sent last in the abort sequence.
pszLogAddress(PSZ) File or port name (for example, LPT1). Used for error reporting. May be NULL.
pszWriteError(PSZ) Error prompt string to display in a SplMsgBox (for example, "Unable to write to printer"). May be NULL.
pszDeviceDescription(PSZ) Device description to display in a SplMsgBox ( for example, "Laserprinter"). May be NULL.
lDCType(LONG) DC type (OD_QUEUED, OD_DIRECT).
Returns
Success TRUE
Failure FALSE
Notes
ulAbortChar is sent first during the abort sequence.
ulAbortBuffer is sent after ulAbortChar.
pszAbortString is sent last in the abort sequence.
GplThreadOutput
Description
This function is used to pass data to a thread instance (referenced by the thread instance handle passed in) for output. GplThreadStartmust be called prior to calling GplThreadOutput.
Format
BOOL APIENTRY GplThreadOutput( HTHREAD hThread, PBYTE pBytes, ULONG ulCount, ULONG fulDataType );
Parameters
hThread(HTHREAD) Thread instance handle.
pBytes(PBYTE) Pointer to data to buffer.
ulCount(ULONG) Size of data (byte size) pointed to by pBytes parameter
fulDataType(ULONG) Data type flag.
THREAD_DT_PRINTERLANGUAGE Data is printer language commands and only requires an abort string to be sent when aborting during this buffer. See pszAbortString in GplThreadStart.
THREAD_DT_BINARY Data is binary (raster) data and requires a series of bytes to be sent to ensure the printer is not in binary transfer mode before the abort string can be sent. See ucAbortChar in GplThreadStart.
Returns
Success TRUE
Failure FALSE
GplThreadEnd
Description
This function frees up any resources allocated by the thread instance ( semaphores and data buffers). A call to this function implies that any remaining data buffers are flushed before the return of this call. This call is the logical pair to GplThreadCreate, which allocates system resources.
Format
BOOL APIENTRY GplThreadEnd( HTHREAD hThread );
Parameter
hThread(HTHREAD) Handle to thread instance.
Returns
Success TRUE
Failure FALSE
GplThreadDeleteInstance
Description
This function is used to free thread instance data allocated by a corresponding call to GplThreadCreateInstance().
Format
BOOL APIENTRY GplThreadDeleteInstance( HTHREAD *phThread );
Parameter
phThread(HTHREAD) Pointer to the thread instance handle to be freed.
Returns
Success TRUE
Failure FALSE
GplThreadAbortDoc
Description
This function is called to abort output from the thread that is referenced by the thread instance handle that was passed in. After output is stopped, the function will attempt to restore the printer to a known state where it can process data from another print job.
The first issue to consider when using this function is that the device may be executing a command that has a large amount of data that it is expecting to receive as a block. Therefore the parameter ulAbortChar passed in on GplThreadStartis sent ulAbortCharCount times.
The second issue to consider is that the abort string 'pszAbortString' provided in GplThreadStart() is sent last.
Format
BOOL APIENTRY GplThreadAbortDoc( HTHREAD hThread );
Parameter
hThread(HTHREAD) Handle to thread instance.
Returns
Success TRUE
Failure FALSE
GplThreadResetAbortDoc
Description
This function is used to resolve any previous calls to GplThreadAbortDoc() so that another job can start printing using the same thread instance handle.
This function will wait, if necessary, for the abort processing started by GplThreadAbortDocto be completed before returning so that the thread instance can be put into a state to receive data from a new print job.
Format
BOOL APIENTRY GplThreadResetAbortDoc( HTHREAD hThread );
Parameter
hThread(HTHREAD) Handle to thread instance.
Returns
Success TRUE
Failure FALSE
GplThreadFlushBuffer
Description
This function causes all data buffers currently being managed by the thread instance to be flushed (written) to their final output destination (for example, parallel port and spool file).
This call allows a flag to be set so that all the data buffers are sent ( flushed) before this call returns (fwait == TRUE) or synchronously (fwait = = FALSE).
Format
BOOL APIENTRY GplThreadFlushBuffer( HTHREAD hThread, BOOL fWait );
Parameters
hThread(HTHREAD) Handle to thread instance.
fWait(BOOL) Flag indicating flush asynchronously or synchronously.
Returns
Success TRUE
Failure FALSE
GplThreadHookDeviceWrites
Description
This is an optional function. This call was created because a class of devices added to the Omni driver did not set status lines according to known standard protocols. Calling this function allows the Omni driver to interpret the status lines because it knows about the devices' special protocols.
Format
BOOL APIENTRY GplThreadHookDeviceWrites( HTHREAD hThread, PFN PfnPrtWrite, pddc );
Parameters
hThread(HTHREAD) Handle to thread instance.
pfnPrtWrite(PFN) Our function.
pddcParameter to our function.
Returns
Success TRUE
Failure FALSE
Implementation
After the memory-management package is implemented, the next logical package that can be added to a driver is the GenPLib Output-Thread Management package.
The best place to implement threads in a driver is when sending and buffering data to what is more than likely a slower output device (or file) . This allows the driver to return back to the application and PM GRE for rendering the next page immediately to improve system response.
The benefits of adding multiple threads are proven in tests performed on OS /2 printer drivers that have added the GenPLib thread-management package. Results have shown a 7%-12% performance increase.
A printer driver retrieves a thread handle (HTHREAD) from GenPLib by calling GplThreadCreateInstanceduring the FILL_PHYSICAL enable subfunction . This call is made only if the DC type is OD_QUEUED or OD_DIRECT (the DC types that request output). This call does not start a thread at this time but causes the GenPLib thread code to initialize its internal structures with information you supply. Once again, a corresponding call to GplThreadDeleteInstanceis made during the driver's disable subfunction DISABLE_PHYSICAL to free the thread handle.
The actual thread is started in the driver when the start-document escape code is received from the application (DEVESC_STARTDOC from the DevEscape() device call) using GplThreadStart. The GplThreadEndcall that stops the thread is placed in disable subfunction BEGIN_CLOSE_DC by the driver. It is not placed in end-document (DEVESC_ENDDOC) code because some applications choose to call many DEVESC_STARTDOC/DEVESC_ENDDOC pairs for the same DC. Placing the call in a disable subfunction assures that a thread will not start and stop many times in a row. The side effect of this is that the GenPLib thread code will receive multiple GplThreadStartcalls for the same thread. In this case, subsequent GplThreadStartcalls cause an implied flush of all data received at that time for the thread.
If you call GplThreadStartmultiple times, the thread code accepts any changed information for input parameters to this call. This allows the driver to dynamically change the buffer size and the maximum number of buffers used by the thread code.
The GplThreadAbortDoccall is also added to the driver's escape code processing routine for the abort-document call (DEVESC_ABORTDOC). This call the thread code to clear data out of all its buffers and to ignore any other data received by the thread until a GplThreadResetAbortDoccall is made to the thread. As soon as all data is flushed by GplThreadAbortDoc, the abort sequences supplied during GplThreadStartwill place the printer in a known state for the next print job.
GplThreadResetAbortDoctells the thread code that the job has ended, that no more data will be sent for this print job, and to resume sending data. This call is added during the end-document escape processing (DEVESC_ENDDOC ) in the driver. This allows applications that perform multiple DEVESC_ STARTDOC/DEVESC_ENDDOC calls for a single DC (that is, submitting multiple print jobs using one DC) to function normally.
GplThreadOutputis used to add any data to the thread's output buffers. The call has been added for the DEVESC_RAWDATA escape code. This escape code is sent to a driver to pass through raw data received from DOS or Windows applications along with a data buffer and data count. The call is also implemented wherever the driver needs to send out its own escape codes for graphical or text generating output. This data includes printer/job initialization commands, raster image data (compressed or uncompressed), font/text data, and job/printer termination commands.
The last function in the thread-management package is GplThreadFlushBuffer, which tells the thread code to send all data currently held in the thread's buffers before the call returns. This call appears just after GplThreadResetAbortDocin a driver's DEVESC_ENDDOC processing code.
Example Code
Starting a Thread With Output to a Printer
Following is an example of starting a thread with output to a printer:
case DEVESC_STARTDOC: // Escape code signals start of document { // If going to a file or direct to a printer if( OD_DIRECT == ulDCType ) { // Open output port (printer-driver version of DosOpen) rc = PrtOpen( hFile, pszLogAddress ); // Create/Update the second print thread rc = GplThreadStart( hThread, // Instance handle 0, // Handle to spooler hFile, // Handle to device 0, // Default buffer size 0, // Default number of buffers '\0', // Abort character 1024, // Abort character repeat count sizeof( pszCmdAbort ); // Length of abort command pszCmdAbort, // Our abort command pszLogAddress, // For example, LPT1 "Error", // Error string if write fails pszDeviceName, // For example, "Epson LQ2550" ulDCType ); // DC type } /* end if */ } /* end case */
Starting a Thread With Output Queuing "Raw" Data
Following is an example of starting a thread with output queuing "raw" printer escapes:
case DEVESC_STARTDOC: // Escape code signals start of document { // Else DC type is queued, not direct to a printer elseif( OD_QUEUED == ulDCType ) { if( ulDataType == PM_Q_RAW ) { if( !hspl ) { // Open appropriate queue (from DevOpenData) for output hspl = SplQmOpen( "*", 9, (PQMOPENDATA)&DevOpenData ); SplQmStartDoc( hspl, szDocumentName ); } /* end if */ // Create/Update the second print thread rc = GplThreadStart( hThread, // Instance handle hspl, // Handle to spooler 0, // Handle to device 0, // Default buffer size 0, // Default number of buffers '\0', // Abort character 1024, // Abort character repeat count sizeof( pszCmdAbort ); // Length of abort command pszCmdAbort, // Our abort command pszLogAddress, // For example, LPT1 "Error", // Error string if write fails pszDeviceName, // For example, "Epson LQ2550" ulDCType ); // DC Type } /* end if */ } /* end if */ } /* end case */
Starting a Thread With Output Queuing "Standard" Data
Following is an example of starting a thread with output queuing "standard" data:
case DEVESC_STARTDOC: // Escape code signals start of document { // Else DC type is queued, not direct to a printer elseif( OD_QUEUED == ulDCType ) { if( ulDataType == PM_Q_STD ) { SplStdStart( pddc->pdb->hdc ); // Open appropriate queue (from DevOpenData) for output hspl = SplQmOpen( "*", 9, (PQMOPENDATA)&DevOpenData ); // Signal start of document (no thread is started by Omni driver) SplQmStartDoc( hspl, szDocumentName ); } /* end if */ } /* end if */ } /* end case */
GplThreadCreateInstance and GplThreadDeleteInstance Usage
The enable and disable subfunctions FILL_PHYSICAL and DISABLE_PHYSICAL are ideal points at which to create and delete a thread instance. Following is an example of GplThreadCreateInstance() and GplThreadDeleteInstance() usage :
ULONG APIENTRY OS2_PM_DRV_ENABLE( ULONG ulSubFunc, ULONG p1, ULONG p2 ) { switch( ulSubFunc ) // Determine enable subfunction { case FILL_PHYSICAL: // An enable subfunction { // Only create a thread if we expect to output data if( (OD_QUEUED == pdb->ulType ) || (OD_DIRECT == pdb->ulType ) ) { // Create an output thread instance (do not start thread yet) bRC = GplThreadCreateInstance( hmcbHeap, globals.hmod, &hThread, pddc ); } /* end if */ } /* end case */ break; case DISABLE_PHYSICAL: // A disable subfunction { // Delete the output thread instance if allocated if( hThread ) { bRC = GplThreadDeleteInstance( &hThread ); } /* end if */ } /* end case */ break; } /* end switch */ } /* end OS2_PM_DRV_ENABLE */
GplThreadOutput Usage
Following is an example of GplThreadOutput() usage:
case DEVESC_NEWFRAME: // Page eject requested { CHAR achRasterCmd[] = "*Esc*r1Q"; // When getting a DEVESC_NEWFRAME or DEVESC_ENDDOC, // The current page's raster image can be retrieved from the // device surface and transferred to the printer // Enter raster mode by sending down escape code for current device bRC = GplThreadOutput( hThread, // Thread instance handle achRasterCmd, // Pointer to data buffer strlen(achRasterCmd), // Size of data buffer THREAD_DT_BINARY ); // Data type // Dither and/or compress raster data and send to output thread bRC = GplThreadOutput( hThread, pbRasterData, ulRasterDataLength, THREAD_DT_BINARY ); } /* end case */
GplThreadEndUsage
Following is an example of GplThreadEndusage during OS2_PM_DRV_ENABLE:
ULONG APIENTRY OS2_PM_DRV_ENABLE( ULONG ulSubFunc, ULONG p1, ULONG p2 ) { switch( ulSubFunc ) // Determine enable subfunction { case BEGIN_CLOSE_DC: { // If we created an output thread if( hThread ) { // End the second thread implied flush with wait bRC = GplThreadEnd ( hThread ) ; } / * end if * / } / * end case * / } / * end switch * / } / * end OS2 _ PM _ DRV _ ENABLE * /
GplThreadAbortDocUsage
Following is an example of GplThreadAbortDocusage for handling an abort- document escape:
case DEVESC_ABORTDOC: { // Tell second thread that an abort doc occurred GplThreadAbortDoc( hThread ); // Store a state flag in our pddc to indicate abort is in effect pddc->fAbortDocCalled = TRUE; } /* end case */
Following is an example of using GplThreadResetAbortDoc:
case DEVESC_ENDDOC: { // If we received a DEVESC_ABORTDOC if( pddc->fAbortDocCalled ) { // Notify the output thread that the abort condition is over GplThreadResetAbortDoc( hThread ); // Reset the abort state so thread will begin processing data again pddc->fAbortDocCalled = FALSE; } /* end if */ } /* end case */
GplThreadFlushBufferUsage
Following is an example of using GplThreadFlushBuffer:
case DEVESC_ENDDOC: { // If going to a file or direct to a printer if( OD_DIRECT == ulDCType ) { // Flush all data in second thread; we are done GplThreadFlushBuffer( hThread, TRUE ); } /* end if */ elseif( OD_QUEUED == ulDCType && PM_Q_RAW == ulDataType ) { // Flush all data in second thread; we are done GplThreadFlushBuffer( hThread, TRUE ); } /* end if */ } /* end case */
GplThreadHookDeviceWritesUsage
Following is an example of using GplThreadHookDeviceWrites:
case DEVESC_STARTDOC: { // We have just called thread Start GplThreadStart(); // We inform the thread that we want to subclass the write of data // to the output destination, replacing it with our callback function GplThreadHookDeviceWrites( hThread, // Thread handle pfnPrtWrite, // Our "write" function pddc ); // Parameter to our "write" function } /* end case */
Pattern Creation
This module contains functions to create bitmap patterns.
To use the GenPLib Pattern-Creation package, you must include:
INCL_GENPLIB_MEMORY INCL_GENPLIB_PATTERNS
The following functions are used to create bitmap patterns.
GplPatternCreateBitmaps
GplPatternDeleteBitmaps
GplPatternCreate
GplPatternCreateBitmaps
Description
This function fills in an array of BMAPINFO structures with the PATSYM patterns. This function is designed to be used to fill in the DEVICESURFACE structure with patterns that match the resolution of the target device. GplPattern functions use the GenPLib Memory-Management package and require that a HMCB had been created with GplMemoryCreateInstance.
Format
LONG APIENTRY GplPatternCreateBitmaps( HMCB hMcb, // Memory instance handle ULONG ulXResolution, // X device resolution ULONG ulYResolution, // Y device resolution ULONG ulWidth, // Desired pattern width ULONG ulHeight, // Desired pattern height PBMAPINFO paBmapInfo, // Array of pattern bitmaps (output) LONG lCount, // Number of bitmaps to create ULONG ulFlip ); // Flip bitmaps horiz/vertically
Parameters
hMcb(HMCB) Handle to initialized memory control block.
ulXResolution(ULONG) Target device x resolution.
ulYResolution(ULONG) Target device y resolution.
ulWidth(ULONG) Size of bitmap X.
ulHeigh(ULONG) Size of bitmap Y.
paBmapInfo(PBMAPINFO) Pointer to an array of BMAPINFO.
lCount(LONG) Number of bitmap information structures.
ulFlip(ULONG) Bit vector. If GPLPAT_INVERT_BITS is set, the bitmaps are inverted.
Returns
TRUE Success
FALSE Failure
GplPatternDeleteBitmaps
Description
This function deletes the bits and clears the array of BMAPINFO.
Format
LONG APIENTRY GplPatternDeleteBitmaps( HMCB hMcb, // Memory instance handle PBMAPINFO paBmapInfo, // Pointer to bitmaps to be freed LONG lCount ); // Count of bitmaps to be freed
Parameters
hMcb(HMCB) Handle to initialized memory control block.
paBmapInfo(PBMAPINFO) Pointer to an array of BMAPINFO.
lCount(LONG) Number of bitmap information structures.
Returns
TRUE Success
FALSE Failure
GplPatternCreate
Description
This function can be used by a presentation driver to create a bitmap representation of any one of the predefined OS/2 patterns. Typically, it is called to create all or a subset of patterns a device driver will support at the start of a print job.
Format
LONG APIENTRY GplPatternCreate( HMCB hMcb, // Memory instance handle ULONG ulXResolution, // X device resolution ULONG ulYResolution, // Y device resolution ULONG ulPatSym, // OS/2 pattern define PBMAPINFO pBmapInfo ); // A pattern bitmap (output)
Parameters
hMcb(HMCB) Handle to initialized Memory control block.
ulXResolution(ULONG) Target device x resolution.
ulYResolution(ULONG) Target device y resolution.
ulPatSym(ULONG) Pattern number as defined for OS/2 in PMDDI.H:
PATSYM_DEFAULT PATSYM_DENSE1 PATSYM_DENSE2 PATSYM_DENSE3 PATSYM_DENSE4 PATSYM_DENSE5 PATSYM_DENSE6 PATSYM_DENSE7 PATSYM_DENSE8 PATSYM_VERT PATSYM_HORIZ PATSYM_DIAG1 PATSYM_DIAG2 PATSYM_DIAG3 PATSYM_DIAG4 PATSYM_NOSHADE PATSYM_SOLID PATSYM_BLANK PATSYM_HALFTONE PATSYM_HATCH PATSYM_DIAGHATCH
pBmapInfo(PBMAPINFO) Number of bitmap information structures.
Returns
TRUE Success
FALSE Failure
Example Code
GplPatternCreateBitmaps Usage
Following is an example of using GplPatternCreateBitmaps:
// PM Graphics Rendering Engine v2.2 Device Surface Function from the Omni driver LONG APIENTRY QueryDeviceSurface( PDDC pddc, PVOID pv ) { // Initialize all fields of the device surface structure, then... if( !pddc->pdb->bAllocatedPatterns ) { if( ORIENTATION_PORTRAIT == pdb->pJobProperties->ulOrientation ) { if( GplPatternCreateBitmaps ( pddc->hmcbHeap, pddc->pResInfo->ulXRes, pddc->pResInfo->ulYRes, 64L, 64L, (PBMAPINFO)&pds->abmapinfoDefPattern, DEFAULT_PATTERNS_NUMBER, 0L ) ) { pddc->pdb->bAllocatedPatterns = TRUE; } /* end if */ } /* end if */ } /* end if */ } /* end QueryDeviceSurface */
GplPatternDeleteBitmaps Usage
Following is an example of using GplPatternDeleteBitmaps:
case BEGIN_CLOSE_DC: // Perform other disable processing, then near end of case... if( GRE_22 <= globals.ulGreVersion ) // PM Graphics Rendering Engine v2.2 or higher { PDEVICESURFACE pds; // Note: We only allocate patterns in QueryDeviceSurface for GRE v2.2 and higher pds = (PDEVICESURFACE)pddc->pdb->pDeviceSurface; if( GplPatternDeleteBitmaps( pddc->pdb->hmcbHeap, (PBMAPINFO)&pds->abmapinfoDefPattern, DEFAULT_PATTERNS_NUMBER ) ) { pddc->pdb->bAllocatedPatterns = FALSE; } /* end if */ } /* end if */
Semaphores
Printer drivers are responsible for serializing threads' access to any of their device contexts (DCs). OS/2 mutual exclusion (MUTEX) semaphores are a possible choice to implement this serialization. When two threads attempt to use the same printer DC at the same time, the second thread should receive a failing result code and PMERR_HDC_BUSY from WinGetLastError.
Given this behavior of OS/2 and its presentation drivers, most OS/2 applications use just one thread when printing. Whenever there is just one thread, there is little contention for the DC; but presentation drivers must safely manage this contention.
There is some performance overhead to consider whenever a thread calls into the OS/2 kernel, as is the case for calls to DosRequest/ReleaseMutexSem. The overhead occurs because the kernel reloads code and data selectors on kernel entry and exit. OS/2 MUTEX semaphores are always safe semaphores, however, because of this transition to the kernel.
Semaphores in the GenPLib
The semaphore package in the GenPLib implements a Ring-3 RAM semaphore when running on the 486 processor. The 486 has the CMPXCHG instruction that is not present on the 386. This single instruction implements a fast, safe, RAM semaphore at Ring 3.
On a 486, a thread requesting an unowned semaphore will remain at Ring 3 and not enter the kernel. If the semaphore is owned and the thread intends to wait, however, then it will enter the kernel to block on an event semaphore.
On a 386, the GenPLib simply uses OS/2 MUTEX semaphores. Implementing a semaphore on the 386 requires multiple instructions; thus, a switch to the kernel is required to disable interrupts while these multiple instructions execute.
For either processor, a thread may repeatedly request the same semaphore without an intervening release (nested requests). Use GplSemQueryMutexSemto query the nested use count.
The GenPLib detects the processor type at runtime.
All GenPLib semaphore APIs return 0 on success. When not zero, they return the same result codes documented for their OS/2 MUTEX semaphore counterparts.
The GenPLib semaphore APIs require a pointer to a MTXSEM data structure instead of a semaphore handle like OS/2 MUTEX semaphores. It is the responsibility of the client to allocate one of these structures per semaphore and supply its pointer to the GenPLib semaphore API.
When the MTXSEM semaphore structure resides on shared memory, it may be created with the DC_SEM_SHARED flag. Additional processes may obtain access to this shared memory and open the semaphore.
All GenPLib semaphores are created in the unowned state.
To use the GenPLib Semaphores package, you must include:
INCL_GENPLIB_SEMAPHORES
The following APIs are included in the semaphore package of GenPLib:
- GplSemCreateMutexSem
- GplSemOpenMutexSem
- GplSemRequestMutexSem
- GplSemReleaseMutexSem
- GplSemCloseMutexSem
- GplSemQueryMutexSem
With the exception of the first parameter, PMTXSEM, the parameters to the GenPLib semaphore APIs are as documented for OS/2 MUTEX semaphores.
GplSemCreateMutexSem
Description
This call creates a MUTEX semaphore.
Format
APIRET APIENTRY GplSemCreateMutexSem( PMTXSEM pmtxsem, ULONG flAttr );
Parameters
pmtxsem(PMTXSEM) Address of MTXSEM structure.
flAttr(ULONG) Creation flags. DC_SEM_SHARED is the only flag.
Returns
Success NO_ERROR Failure ERROR_INVALID_PARAMETER
or return code from:
DosQueryMem
DosCreateEventSem
DosCreateMutexSem
Notes
The caller must first allocate memory for the MTXSEM structure. See GPLSEM. H, where this structure is defined. If the memory is allocated from shared memory, the caller may specify the DC_SEM_SHARED flag for flAttr parameter.
GplSemOpenMutexSem
Description
This call opens a shared GPL Mutex semaphore.
Format
APIRET APIENTRY GplSemOpenMutexSem( PMTXSEM pmtxsem );
Parameter
pmtxsem(PMTXSEM) Address of MTXSEM structure.
Notes
When multiple processes are using a shared semaphore, then subsequent processes must open the semaphore. It is not necessary for the creating process to perform an open.
Returns
Success NO_ERROR Failure ERROR_INVALID_PARAMETER
or return code from:
DosOpenEventSem
DosOpenMutexSem
GplSemRequestMutexSem
Description
This call is used to request an OS/2 PM MUTEX semaphore.
Format
APIRET APIENTRY GplSemRequestMutexSem( PMTXSEM pmtxsem, LONG lTime );
Parameters
pmtxsem(PMTXSEM) Address of MTXSEM structure.
lTime(LONG) Time out value in milliseconds.
Returns
Success NO_ERROR
Failure Typical error returns for this function include ERROR_INVALID_ PARAMETER or return codes from DosRequestMutexSem.
ERROR_TIMEOUT (RC 640d) means that the semaphore is owned.
Notes
The caller can specify the timeout value for the request. When timeout is 0 , the call returns immediately. When timeout is -1, the call is an indefinite wait. Otherwise the call will block up to the timeout specified.
GplSemReleaseMutexSem
Description
This call will release an owned MUTEX semaphore.
Format
APIRET APIENTRY GplSemReleaseMutexSem( PMTXSEM pmtxsem );
Parameter
pmtxsem(PMTXSEM) Address of MTXSEM structure.
Returns
Success NO_ERROR Failure ERROR_INVALID_PARAMETER
ERROR_NOT_OWNER (not the owner of the MUTEX semaphore)
DosReleaseMutexSem
Notes
This call decrements the nested use count for the semaphore. When the nested use count goes to zero, the semaphore is truly released.
GplSemCloseMutexSem
Description
This call closes a GPL MUTEX semaphore for the process.
Format
APIRET APIENTRY GplSemCloseMutexSem( PMTXSEM pmtxsem );
Parameter
pmtxsem(PMTXSEM) Address of MTXSEM structure.
Returns
Success NO_ERROR Failure ERROR_INVALID_PARAMETER
DosCloseEventSem
DosCloseMutexSem
Notes
Every process using GPL semaphores should close each one with this API.
GplSemQueryMutexSem
Description
This call returns information about the semaphore.
Format
APIRET APIENTRY GplSemQueryMutexSem( PMTXSEM pmtxsem, PID *ppid, TID *ptid, PULONG pulCount );
Parameters
pmtxsem(PMTXSEM) Address of MTXSEM structure.
*ppid(PPID) Address where process ID is returned.
*ptid(PTID) Address where thread ID is returned.
pulCount(PULONG) Request count.
Returns
Success NO_ERROR Failure ERROR_INVALID_PARAMETER
or the return codes from:
DosQueryMutexSem
Notes
This API will return information about the semaphore, such as what process and thread currently owns it, and if owned, what is the nested use count.
It is important for asynchronously killed threads to make this call to determine if they own the DC semaphore. If they own the semaphore, they should release it the appropriate number of times before exiting.
Differences Between GenPLib Semaphores and Kernel Semaphores
If a nonzero request time times out, it will timeout to within 30 milliseconds of the supplied time out.
DosQueryMutexSem returns a process and thread ID even if the MUTEX sem is unowned; that is, the count returned is zero. This semaphore package returns process and thread ID of zero when the semaphore is unowned regardless of 386 or 486.
String Management
The string-management package provides string-sorting functionality for printer output devices.
Certain printer output devices can output data only in small bands, yet they are expected to keep track of strings that might be positioned anywhere on a physical output page. These devices need an independent mechanism for keeping those strings in sorted "page" order until the device is actually processing the band of that string.
This is true for raster printers that utilize a print head and must only send text strings that are drawn using device (printer) fonts within a certain range of the print head when printing graphics data. The following diagrams represent this concept:
Output Page /----------\ | | | | |xxxxxxxxxx| |xxxxxxxxxx| <--- Current band of raster output | | that can be processed by the | | output device. | Hello | | | | | <--- Text is below current band so | ABCD | we can't output it yet | | | | | | \----------/
Output Page (later) /----------\ | | | | | | | | | | |xHelloxxxx| <--- Current band of raster output |xxxxxxxxxx| that can be processed by the | | output device. Lower string still --> | ABCD | This time the text string is in not in range | | the band region and it should be | | processed at this time | | | | \----------/
Output Page (later) /----------\ | | | | | | | | | | String already --> | Hello | processed | | | | | | |xxxxABCDxx| <--- Current band of raster output |xxxxxxxxxx| that can be processed by the | | output device. | | This time the second string is in \----------/ the band region and it should be processed at this time.
The package sorts text strings passed in page order. Top-to-bottom and left -to-right is the current default page order.
Once strings are inserted, you can extract strings in respect to a rectangular area (typically the current graphics band rectangle) that you pass in.
The string-sorting package utilizes the GenPLib Memory-Management and Exception-Management packages, thereby providing very efficient system resource usage and consistent error reporting and logging.
To use the GenPLib String-Management package, you must include:
INCL_GENPLIB_STRING
The following functions comprise the string-management package:
- GplStringSorterCreateInstance
- GplStringSorterInsertString
- GplStringSorterQueryNumStrings
- GplStringSorterGetFirstString
- GplStringSorterGetNextString
- GplStringSorterRemoveStrings
- GplStringSorterReset
- GplStringSorterDeleteInstance
GplStringSorterCreateInstance
Description
This function creates a string sorter instance (memory resource allocated) and returns a handle that must be used by all other string sorter package functions.
The default heap size that is created is based on current printer driver media sizes and application text usage. A parameter is supplied so that the user can increase the initial memory area that is created to hold text strings. Otherwise a default value, based on test averages, will be used.
Format
APIRET APIENTRY GplStringSorterCreateInstance( HDC hdc, PHSORTER phStrSort, ULONG ulHeapSize, ULONG ulOptions );
Parameters
hdc(HDC) Handle to current DC.
phStrSort(PHSORTER) Pointer to the location where string-sorter handle will be placed.
ulHeapSize(ULONG) Initial size of heap to allocate for strings. This can be zero. A default memory area will be created.
ulOptions(ULONG) Creation options (for example, DBCS and TTY). This parameter is reserved for future use. This parameter must be zero.
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterInsertString
Description
This function adds a text string to a string instance. Information, including the bounding rectangle passed in and a pointer to the data, is stored with the string. You can store with the string (for example, a pointer to a structure containing font name, font ID, and color).
Currently, the sort order is determined by the top-left corner of the text box passed in. The strings are sorted in page order. Page order is the order the text would be printed by a banding device on a hardcopy page.
Format
APIRET APIENTRY GplStringSorterInsertString( HSORTER hStrSort, PSZ pszStr, RECTL rectlStr, PVOID pUserDef, PVOID pUnused );
Parameters
hStrSort(HSORTER) Handle of the string sorter to be used for insert operation.
pszStr(PSZ) Pointer to text string to insert.
rectlStr(RECTL) Bounding rectangle of string being inserted.
pUserDef(PVOID) Pointer to user-defined data to be stored with this string .
pUnused(PVOID) NULL. Reserved for future use.
Returns
Success NO_ERROR
Failure ERROR_INVALID_PARAMETER
ERROR_xxx
GplStringSorterQueryNumStrings
Description
This function returns the current number of strings in the string sorter instance (HSORTER) referenced on the call.
Format
APIRET APIENTRY GplStringSorterQueryNumStrings( HSORTER hStrSort, PULONG pulNumStr );
Parameters
hStrSort(HSORTER) Handle of string sorter instance to be queried.
pulNumStr(PULONG) Pointer to the location where number is to be returned.
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterGetFirstString
Description
This function is used to get a linked list of strings from the string sorter in relation to a band rectangle passed in.
The strings are not deleted from the linked list on this call because we allocated the information and will de-allocate on a GplStringSorterReset() call or a GplStringSorterRemoveStrings() call.
Currently, the defined relationships that can be selected are:
Option Description
STR_INCL_PART_IN_BAND Return any string whose text box intersects any part of the band passed in.
STR_INCL_ALL_IN_BAND Return any string whose text box is entirely inside the band passed in.
STR_INCL_TOPLEFT_IN_BAND Return any string whose top-left coordinate is inside the band passed in.
Notes:
1.All retrievals are inclusive on all boundaries of the rectlBandpassed in.
2.GplStringSorterGetFirstString retrievals are non-destructive. (the string remains in the string-sorter instance and are only removed by GplStringSorterRemoveStringsor GplStringSorterResetcalls).
Format
APIRET APIENTRY GplStringSorterGetFirstString( HSORTER hStrSort, ULONG ulOption, RECTL rectlBand, PSZ *ppszStr, PRECTL prectlStr, PPVOID ppUserDef );
Parameters
hStrSort(HSORTER) Handle of string-sorter instance to be used for string retrieval.
ulOption(ULONG) Option passed in to indicate the relationship to test for on the "Get" operation. See options above.
rectlBand(RECTL) The band rectangle passed in that will be used to test all text-string rectangles against.
*ppszStr(PSZ)-output Pointer to first text string meeting retrieve criteria (ulOption).
prectlStr(PRECTL)-output Pointer to the bounding rectangle of first string retrieved (passed in during GplStringSorterInsertString).
ppUserDef(PPVOID)-output Pointer to the user-defined data that was associated with text string retrieved (passed in during GplStringSorterInsertString).
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterGetNextString
Description
This function is used to retrieve the next string matching the retrieve criteria passed in on the last call to GplStringSorterGetFirstString(). The criteria is based on the ulOptionand rectlBandparameters from that function). This function can be called multiple times until an ERROR_NO_ MORE_ITEMS return code is detected. Each successful call (NO_ERROR) returns another string from the string sorter instance meeting the criteria until no more strings meet the criteria.
Format
APIRET APIENTRY GplStringSorterGetNextString( HSORTER hStrSort PSZ *ppszStr, PRECTL prectlStr PPVOID ppUserDef );
Parameters
hStrSort(HSORTER) Handle of the string-sorter instance to be used for the retrieve operation.
*ppszStr(PSZ) - output Pointer to the location that the text string will be retrieved to.
prectlStr(PRECTL) - output Bounding rectangle of the string being retrieved.
ppUserDef(PPVOID) - output Pointer to user-defined data stored with string during the insert operation.
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterRemoveStrings
Description
This function is used to delete all strings from the string sorter instance , based on a relationship (ulOption) to a rectangle (rectlBand) both passed .
See StringGetFirstStringFromSorter() and StringGetNextStringFromSorter() calls for non-destructive string retrievals.
Remove options include:
Option Description
STR_INCL_PART_IN_BAND Return any string whose text box intersects any part of the band passed in.
STR_INCL_ALL_IN_BAND Return any string whose text box is entirely inside the band passed in.
STR_INCL_TOPLEFT_IN_BAND Return any string whose top-left coordinate is inside the band passed in.
Removes are inclusive on all sides of rectlBandpassed in.
Format
APIRET APIENTRY GplStringSorterRemoveStrings( HSORTER hStrSort, ULONG ulOption, RECTL rectlBand );
Parameters
hStrSort(HSORTER) Handle of the string sorter to be used for remove operation.
ulOption(ULONG) Remove options.
rectlBand(RECTL) Rectangle that is used for comparison by the remove option.
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterReset
Description
This function resets the string sorter instance by removing all text strings inserted into the sorter.
Format
APIRET APIENTRY GplStringSorterReset( HSORTER hStrSort );
Parameter
hStrSort(HSORTER) Handle of the string sorter to be reset.
Returns
Success NO_ERROR
Failure ERROR_xxx
GplStringSorterDeleteInstance
Description
This function destroys a string sorter instance by freeing any system resources allocated on the corresponding call to GplStringSorterCreateInstance(). This function implies a GplStringSorterReset() call.
Format
APIRET APIENTRY GplStringSorterDeleteInstance( HSORTER hStrSort );
Parameter
hStrSort(HSORTER) Handle of string sorter to be destroyed. The handle is no longer valid after the call.
Returns
Success NO_ERROR
Failure ERROR_INVALID_PARAMETER
Example Code
Retrieving Strings From String Sorter During Band Processing
Following is an example of retrieving strings from string sorter during band processing in a raster printer driver:
HSORTER hSorter; CharString( PDDC pddc, ..., LONG cChars, PCH pchString, ... ) { if( bDeviceFont ) // If we have a device font to manage { if( ! hSorter ) // If we have not yet created a sorter { // Create a string sorter to handle our device fonts apiret = GplStringSorterCreateInstance( pddc,&hSorter, 0L, 0L ); } /* end if */ // Calculate text box of string from our character-width tables // Insert character string into sorter apiret = GplStringSorterInsertString( hSorter, (PSZ)pchString, rectlTextBox, (PVOID)NULL, (PVOID)NULL ); // Example: check number of strings currently in sorter apiret = GplStringSorterQueryNumStrings( hSorter,&ulNumStr ); } /* end if */ } /* end CharString */ Usage Notes: Used default values for heap size and options during 'StringCreate' API (LTR, TTB). Used default value for during 'StringInsert' API. For 'StringInsert' API, we could have allocated and filled in our own structure that helps us process this string (for example, font name, identifier, color, etc.).
Removing Strings From a String Sorter During Processing of a Graphics Band
Following is an example of removing strings from a string sorter during processing of a graphics band (banding):
ProcessBand( PDDC pddc, ...) { APIRET apiret; RECTL rectlString, rectlBand; PSZ pszString; // Retrieve first sting in the raster band we are processing apiret = GplStringSorterGetFirstString( hSorter, STR_INCL_TOP_LEFT_IN_BAND, // Retrieve strings whose Top-Left corner are in band rectlBand, // Rectangle of the graphic band we are processing &pszString, // Pointer that first string will be returned in &rectlString, // Text box of the string (PVOID)NULL ); // We had no user-defined data to retrieve // if we have a string meeting retrieval criteria while( apiret != ERROR_NO_MORE_ITEMS ) { // Get next string (uses same retrieve option as "GetFirst") apiret = GplStringSorterGetNextString( hSorter, &pszString, &rectlString, (PVOID)NULL ); } /* end while */ } /* end ProcessBand */
Removing Strings From a String Sorter After Retrieving Them
Following is an example of removing strings from a string sorter after retrieving them (during graphics band processing):
ProcessBand( PDDC pddc, ... ) { // After retrieving all strings from band and sending them to printer // See the previous example // We can remove these strings from the sorter // since we do not need to process them again apiret = GplStringSorterRemoveStrings( hSorter, STR_INCL_TOP_LEFT_IN_BAND, rectlBand ); } /* end ProcessBand */
Resetting and Destroying the String Sorter During Escape Processing
Following is an example of resetting and destroying the string sorter during escape processing in a printer driver:
Escape( PDDC pddc, ... ) { APIRET apiret; case DEVESC_NEWFRAME: { // Process all graphics bands on page // Reset sorter for next page apiret = GplStringSorterReset( hSorter ); } /* end case */ break; case DEVESC_ENDDOC: { // Process the last page (implied NewFrame) // Sorter no longer needed for this print job apiret = GplStringSorterDeleteInstance( hSorter ); } /* end case */ break; } /* end Escape */
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 reequires 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 Device Support.
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 pointhas been implemented in the driver to scale the number. For an example of sliding point, see prdl_DrawConicin POLYSTUF.C.
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:
- Memory-management routines
*Multi-threading output capabilities
*Error and debugging support routines
For further information about the GenPLib, see Generic Printer Library.
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:
- Character code points
*Character widths
*Kerning pairs
*General font information
*Font metrics
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 prda_DeviceQueryFontsin FONTS.C.
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 ConvertOFMtoPFM() in DOWNLOAD.C. 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, GplMemoryAllocand GplMemoryFreevia 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:
- 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
This is larger because it is expected to be used more extensively.
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 allthe 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 prdl_ StrokePathin PATH.C.
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 prdl_BoxBothin BOX.C.
Arcs
Arcs and curves are translated to the corresponding PostScript calls. For an example, see prdl_FullArcBothin ARCS.C.
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 prde_EnableDC). 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:
*MainKeydescribes 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 *PageSizewould 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.
Valuewill 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 Businepss 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 addfued 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 DDKfor 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:
- PostScript Printer Properties
Tray The *InputSlotkey defines the available printer trays. The Option Key identifies the tray name. If no input slot is provided, Upperis displayed as the default. The key *DefaultInputSlotidentifies the tray that is the default.
Form The *PageSizekey defines the available pages. The Option Key identifies the page name. The key *DefaultPageSizeidentifies the default page size.
Maximum Downloaded Fonts This value is calculated by obtaining the value of *FreeVMand dividing it by the approximate amount of memory needed for each font. *FreeVM contains the maximum amount of memory available to a device.
Automatic Mode Switching If the key *InitPostScriptModeis included in the PPD file at compilation, the Automatic Mode Switchingcheck box is enabled. If checked, a command will be sent to the device to automatically set the device into PostScript mode at the start of each job.
- Job Properties and PostScript Device Defaults
Resolution The *SetResolutionkey identifies the resolution to which the printer is set. If no *SetResolutionkey is provided, 300 is used as the default. The key *DefaultResolutionsets the default resolution.
Duplex Options This group is enabled only if the *Duplexkey is provided. The following Option Keys manage the following buttons:
-DuplexTumble is used if 2-Sided Flipis selected. The back page of the output will be inverted.
-DuplexNoTumble is used if 2-Sided Bookis selected. The back page of the output will not be inverted. The key *DefaultDuplexdetermines the default duplex setting.
Manual Feed This check box is enabled if *DefaultManualFeedis provided. If *DefaultManualFeedis set to TRUE, this box is initially checked.
Use Color This check box is enabled if the key *ColorDeviceis set to TRUE. If this key is either missing or set to FALSE, this check box is disabled.
PostScript level-1 compatibility This check box is enabled if the key * LanguageLevelis set to "2." If the key is missing, or if it is set to "1," this option is disabled. If this option is not checked, output is sent in PostScript level-2 format. If it is checked, ouput is sent in PostScript level-1 format.
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\PSCRIPTdirectory.
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 Propertiesor Job Propertieswill 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 Propertiesdialog box, it is better to open the Job Propertiesdialog 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: <error type> OFFENDING COMMAND: <command that caused the error> STACK: <contents of the printer's 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 GplErrSetErrorthat 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 UTLASM.ASM, 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 DDKfor 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 Propertiesand Job Propertiesdialog 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 Propertiesand Job Propertiesare 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 Propertiesand 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 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 prde_FillPdbfunction.
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:
*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
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,
- 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:
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.
In order to support the Postscript UI format, a printer driver must:
- 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 Commandbuffer, 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.
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:
ofsUIName The offset of the UI block name. In the example above, the UI block name is: PageSize.
ofsUITransString The translation string of the UI block. If no translation string exists, this value is the same as ofsUIName. In the above example, the translation string for the block is: Paper Size.
usOrderDep This contains the numeric value of where the specific UI block is to be located with respect to other UI blocks in the PPD. The UI blocks in the PPD are not necessarily listed in the order that they appear. In the PPD compiler, this value contains the numeric value taken from * OrderDependency. In the example above, usOrderDepen contains the value 20. The lower the number, the higher in priority the UI block appears in the UI list. After all the UI blocks have been parsed, this value contains the zero-based offset of where the specific UI block is listed in respect to the UI list. For example, the first UI block in the list, usOrderDep, is 0, the next UI block contains 1, etc.
uiEntry This is the variable-length array containing UI_ENTRY structures.
usDefaultEntry This contains the uiEntry array number to the default entry.
usNumOfEntries This contains the number of UI_ENTRY structures for a given block.
ucGroupType This contains the value of the type of group where the UI block belongs. The group type is defined by the *OpenGroup/*CloseGroup keywords. This field contains one of the following values:
UIGT_INSTALLABLEOPTION This is used for UI blocks that fall between the * OpenGroup InstallableOption / *CloseGroup InstallableOption keywords. UI blocks that belong to this group are displayed in Printer Properties.
UIGT_DEFAULTOPTION This is the default group type for UI blocks. Blocks that belong to this group are displayed in Job Properties.
usSelectType This identifies whether the current UI block is a single- selection UI, multiple-selection UI, or Boolean UI. This field contains one of the following values:
UI_SELECT_PICKONE The current UI only allows one selection. This is set if PickOne is specified.
UI_SELECTTYPE_PICKMANY The UI allows one or more selections. This value is set if PickMany is set.
UI_SELECT_BOOLEAN The UI allows only one selection from a TRUE/FALSE type of selection. This value is set if Boolean is provided. The selection type of the UI is determined by the string PickOne, string PickMany, or Boolean strings that appear on the same line as *OpenUI. In the example above, the string PickOne sets the value of this field to UI_SELECT_PICKONE.
ucPanelID This identifies where the block string is to be displayed. It contains one of the following values:
UIP_PREDEF_FEATURE This identifies the block as a predefined feature. A predefined feature is a UI block that is displayed in a page other than the Featurespage. Some examples of predefined features are PageSize and MediaType-these blocks are not displayed in the Featurespage, but rather in the Formspage. These UI controls are called "predefined UIs," meaning that they have a specific control that handles them and are not to be listed in the Featurespage. To define your own predefined UI, do the following:
1.The header file PPD2BIN.H contains a global structure called " szPredefined". This lists all the UI strings as predefined UIs. Insert the string for the UI that you wish to list in a page other than the Featurespage. Order is not important, but case sensitivity is necessary.
2.Change the value of MAX_PREDEFINED to the number of strings in the array .
When the PPD compiler finds a match for the string you defined, the UI block field ucPanelID is modified with the flag UIP_PREDEF_FEATURE. When the Featurespage lists all the default UI blocks, it queries the UI block to see whether or not UIP_PREDEF_FEATURE exists. If it exists, the block is not inserted.
UIP_OEM_FEATURE This setting means that this UI block is to be displayed in a special page defined for a specific device. In other words, this UI block is not listed in any of the standard dialog pages, but rather in a page for a specific device only.
UIP_OS2_FEATURE This is the default value for UI blocks. At this setting, the UI block is displayed in the Featurespage.
usUILocation As mentioned before, OrderDependency arranges the UI blocks in the order that they appear in the raw job. However, where the UI block string appears in the raw job is also important. The location where the string is sent is determined by this field. This field may contain one of the following values:
UI_ORDER_ANYSETUP This is the default value. This indicates that the data may be inserted anywhere in the job. For this driver, data with this value is inserted in the document-setup section.
UI_ORDER_JCLSETUP This value accompanies a JCL UI block. This means that the data is inserted at the beginning of the job where the JCL code is inserted.
UI_ORDER_PAGESETUP For this value, the data is inserted at the beginning of a page.
UI_ORDER_DOCSETUP For this value, the data is inserted after the prologue section at the beginning of the job.
UI_ORDER_EXITSERVER
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:
PPDLG.C contains code that maintains the Printer-Propertiesdialog box.
JPDLG.C contains code that maintains the Job-Propertiesdialog box.
DLG.C contains common code that is used by both properties.
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.
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.
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 QueryFeaturePageLoad(). 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-Propertiesdialog 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 Formspage.
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 Effectspage.
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:
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.
Driver contents The current driver stores printer-properties selections in OS2SYS.INI. The application string in the INI is in the following format:
"PM_DD_"[name of print object]","[driver name]"."[device name]
where the:
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 Settingsdialog.
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:
CONFIG.CChange HELPFILENAME to include driver name, PrintFontMem
DEVBLOCK.CBuildKeyName, prde_FillPdb
DEVMODE.COS2_PM_DRV_DEVMODE, GetPrinterName
UTLLOG.C LogIsOn
SOFTFONT.H Change string accessed by FONT_DIR_APP from "PM_PSCRIPT" to "PM_ " followed by the driver name
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".
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 driverand 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 .
Function List
/-------------------------------------------------------------\ |Function Name |Module Location | |------------------------------------+------------------------| |AllocateLDRIVDATABuffer |DEVBLOCK.C | |------------------------------------+------------------------| |AllocCNFStructure |DEVMODE.C | |------------------------------------+------------------------| |AsciiToBin |UTLCHNL.C | |------------------------------------+------------------------| |b2a |QUERYBOX.C | |------------------------------------+------------------------| |BeginImage |BITMAPS.C | |------------------------------------+------------------------| |BigMulDiv |MATH.ASM | |------------------------------------+------------------------| |BuildKeyName |DEVBLOCK.C | |------------------------------------+------------------------| |CharStringDebug |CHARSTR.C | |------------------------------------+------------------------| |CharStringKern |CHARSTR.C | |------------------------------------+------------------------| |CharStringLeftRight |CHARSTR.C | |------------------------------------+------------------------| |CharStringRect |CHARSTR.C | |------------------------------------+------------------------| |CharStringReverse |CHARSTR.C | |------------------------------------+------------------------| |CharStringRightLeft |CHARSTR.C | |------------------------------------+------------------------| |CharStringUpDown |CHARSTR.C | |------------------------------------+------------------------| |CharStringWidthVector |CHARSTR.C | |------------------------------------+------------------------| |CheckComPortName |UTLCHNL.C | |------------------------------------+------------------------| |CheckForOverwrite |FLCHKDLG.C | |------------------------------------+------------------------| |CheckNumeric |CONFIG.C | |------------------------------------+------------------------| |CheckPrinterName |DEVMODE.C | |------------------------------------+------------------------| |CheckProfileName |QUERYBOX.C | |------------------------------------+------------------------| |CleanUpHelpStubHook |CONFIG.C | |------------------------------------+------------------------| |ClearMem |DEVBLOCK.C | |------------------------------------+------------------------| |CloseChannel |UTLCHNL.C | |------------------------------------+------------------------| |ClosePSDlg |DLG.C | |------------------------------------+------------------------| |CmndInpTray |DEVBLOCK.C | |------------------------------------+------------------------| |CmndPaper |DEVBLOCK.C | |------------------------------------+------------------------| |ColorDistance |COLORTAB.C | |------------------------------------+------------------------| |CompareRealNames |QUERYBOX.C | |------------------------------------+------------------------| |CompareStri |PPDLG.C | |------------------------------------+------------------------| |CompressAscii85 |BITMAPS.C | |------------------------------------+------------------------| |CompressMode2Out |BITMAPS.C | |------------------------------------+------------------------| |ConcatXforms |CHARSTR2.C | |------------------------------------+------------------------| |ConvertColorModel |DEVBLOCK.C | |------------------------------------+------------------------| |ConvertOFMtoPFM |CHARSTR2.C | |------------------------------------+------------------------| |ConvertPFM |CHARSTR2.C | |------------------------------------+------------------------| |ConvertUIBitsToStrings |DEVBLOCK.C | |------------------------------------+------------------------| |CopyAndNormalize |MATH.ASM | |------------------------------------+------------------------| |CopyCNFData |DEVMODE.C | |------------------------------------+------------------------| |CopyLDRIVDATAToCNFDATA |DEVBLOCK.C | |------------------------------------+------------------------| |CopyStr |DOWNLOAD.C | |------------------------------------+------------------------| |CPDownLoaded |FONTS.C | |------------------------------------+------------------------| |CreateDCHeap |MEMORY.C | |------------------------------------+------------------------| |CreateProcessHeap |MEMORY.C | |------------------------------------+------------------------| |cvi |QUERYBOX.C | |------------------------------------+------------------------| |Cvi_R2 |UTLCHNL.C | |------------------------------------+------------------------| |DefaultFontCount |DOWNLOAD.C | |------------------------------------+------------------------| |DefineFormsDlgProc |PPDLG.C | |------------------------------------+------------------------| |DefinePal |BITMAPS.C | |------------------------------------+------------------------| |DeviceModes |CONFIG.C | |------------------------------------+------------------------| |DevicePalette |SURFACE.C | |------------------------------------+------------------------| |discard_clip_path_buf |PATH2.C | |------------------------------------+------------------------| |discard_path_buf |PATH2.C | |------------------------------------+------------------------| |DisplayFeaturesUIEntries |DLG.C | |------------------------------------+------------------------| |DisplayGammaValue |JPDLG.C | |------------------------------------+------------------------| |DisplayMatchingForm |PPDLG.C | |------------------------------------+------------------------| |DisplayMessageBox |DLG.C | |------------------------------------+------------------------| |DisplayTranslationString |QUERYBOX.C | |------------------------------------+------------------------| |_DLL_InitTerm |MEMORY.C | |------------------------------------+------------------------| |dodiv |STUB.ASM | |------------------------------------+------------------------| |doimul |STUB.ASM | |------------------------------------+------------------------| |DoSelectFont |UTLPS.C | |------------------------------------+------------------------| |DrawImage |BITMAPS.C | |------------------------------------+------------------------| |EA_GetVersion |QUERYBOX.C | |------------------------------------+------------------------| |EatSeper |UTLPS.C | |------------------------------------+------------------------| |EffectsPageDefaultControls |JPDLG.C | |------------------------------------+------------------------| |EffectsPageDlgProc |JPDLG.C | |------------------------------------+------------------------| |EffectsPageInitControls |JPDLG.C | |------------------------------------+------------------------| |EffectsPageSaveSettings |JPDLG.C | |------------------------------------+------------------------| |EnableDefineFormAddButton |PPDLG.C | |------------------------------------+------------------------| |EnterDriver |PRDEVECT.C | |------------------------------------+------------------------| |ExceptHandler |MEMORY.C | |------------------------------------+------------------------| |ExitDriver |PRDEVECT.C | |------------------------------------+------------------------| |Exitpdd |DEVBLOCK.C | |------------------------------------+------------------------| |FeaturePageDefaultControls |JPDLG.C | |------------------------------------+------------------------| |FeaturePageDlgProc |JPDLG.C | |------------------------------------+------------------------| |FeaturePageInitControls |JPDLG.C | |------------------------------------+------------------------| |FillEffects |QUERYBOX.C | |------------------------------------+------------------------| |FillFormList |DLG.C | |------------------------------------+------------------------| |FillOFMFont |DOWNLOAD.C | |------------------------------------+------------------------| |FillPaperNames |QUERYBOX.C | |------------------------------------+------------------------| |FillSFonts |DOWNLOAD.C | |------------------------------------+------------------------| |FillTrayList |DLG.C | |------------------------------------+------------------------| |find_arc_direction |ARCS.C | |------------------------------------+------------------------| |FindString |UTLPS.C | |------------------------------------+------------------------| |FixUpColors |JPDLG.C | |------------------------------------+------------------------| |FlushChannel |UTLCHNL.C | |------------------------------------+------------------------| |FontDownload |FONTS.C | |------------------------------------+------------------------| |FormDefPageDlgProc |PPDLG.C | |------------------------------------+------------------------| |FormPageDefaultControls |JPDLG.C | |------------------------------------+------------------------| |FormPageDlgProc |JPDLG.C | |------------------------------------+------------------------| |FormPageInitControls |JPDLG.C | |------------------------------------+------------------------| |FormPageSaveSettings |JPDLG.C | |------------------------------------+------------------------| |FormPPPageDefaultControls |PPDLG.C | |------------------------------------+------------------------| |FormPPPageInitControls |PPDLG.C | |------------------------------------+------------------------| |Fraction2A |QUERYBOX.C | |------------------------------------+------------------------| |FractionToDecimal |UTLASM.ASM | |------------------------------------+------------------------| |frdiv |ASM2C.C | |------------------------------------+------------------------| |FreeCNFStructure |DEVMODE.C | |------------------------------------+------------------------| |FreeDialogHeader |DLG.C | |------------------------------------+------------------------| |FreeFontResource |CHARSTR2.C | |------------------------------------+------------------------| |FreeMemory |DEVBLOCK.C | |------------------------------------+------------------------| |FreePathBufs |ENABLE.C | |------------------------------------+------------------------| |FreePPBResource |DEVBLOCK.C | |------------------------------------+------------------------| |frmul |ASM2C.C | |------------------------------------+------------------------| |frsqrt |ASM2C.C | |------------------------------------+------------------------| |frVectLength |ASM2C.C | |------------------------------------+------------------------| |fxmultiply |ASM2C.C | |------------------------------------+------------------------| |GammaAdjust |UTLPS.C | |------------------------------------+------------------------| |get_module_dir |CONFIG.C | |------------------------------------+------------------------| |GetAndSaveColorModel |JPDLG.C | |------------------------------------+------------------------| |GetDefaultPageSize |QUERYBOX.C | |------------------------------------+------------------------| |GetDuplexCommand |UTLPS.C | |------------------------------------+------------------------| |GetImageableArea |QUERYBOX.C | |------------------------------------+------------------------| |GetMappedFontName |UTLPS.C | |------------------------------------+------------------------| |GetOffset |JPDLG.C | |------------------------------------+------------------------| |GetPFMetrics |CHARSTR2.C | |------------------------------------+------------------------| |GetPM_Fonts |DOWNLOAD.C | |------------------------------------+------------------------| |GetPrinterName |DEVMODE.C | |------------------------------------+------------------------| |GetR3String |MEMORY.C | |------------------------------------+------------------------| |HelpErrorFilter |CONFIG.C | |------------------------------------+------------------------| |HelpStubHook |CONFIG.C | |------------------------------------+------------------------| |HexToChannel |UTLCHNL.C | |------------------------------------+------------------------| |Hook22Calls |PRDEVECT.C | |------------------------------------+------------------------| |ImageCoords |DEVBLOCK.C | |------------------------------------+------------------------| |ImageProcToChannel |BITMAPS.C | |------------------------------------+------------------------| |ImageScan |BITMAPS.C | |------------------------------------+------------------------| |init_cgs |UTLPS.C | |------------------------------------+------------------------| |init_clip_path_buf |PATH2.C | |------------------------------------+------------------------| |init_path_buf |PATH2.C | |------------------------------------+------------------------| |init_semaphores |ENABLE.C | |------------------------------------+------------------------| |InitGlobalHeap |MEMORY.C | |------------------------------------+------------------------| |InitializeCommPort |UTLCHNL.C | |------------------------------------+------------------------| |InitializeCustomForms |PPDLG.C | |------------------------------------+------------------------| |InitializeDialog |DLG.C | |------------------------------------+------------------------| |InitializeDialogHeader |DLG.C | |------------------------------------+------------------------| |InitializeHelp |CONFIG.C | |------------------------------------+------------------------| |InsertPageInNotebook |DLG.C | |------------------------------------+------------------------| |InsertSliderValues |JPDLG.C | |------------------------------------+------------------------| |InsertStringInListbox |DLG.C | |------------------------------------+------------------------| |InstallDispatchVectors |PRDEVECT.C | |------------------------------------+------------------------| |InvertTransfer |UTLPS.C | |------------------------------------+------------------------| |iqdiv |ASM2C.C | |------------------------------------+------------------------| |IsFilePipe |FLCHKDLG.C | |------------------------------------+------------------------| |isHWFont |DOWNLOAD.C | |------------------------------------+------------------------| |IsOFMFile |DOWNLOAD.C | |------------------------------------+------------------------| |JobPropertiesDlgProc |JPDLG.C | |------------------------------------+------------------------| |KillGlobalHeap |MEMORY.C | |------------------------------------+------------------------| |KillHeap |MEMORY.C | |------------------------------------+------------------------| |kprintf |UTLPRINT.C | |------------------------------------+------------------------| |ListUniqueForms |DLG.C | |------------------------------------+------------------------| |ListUserForms |QUERYBOX.C | |------------------------------------+------------------------| |LoadCurrentUISelections |DEVBLOCK.C | |------------------------------------+------------------------| |LoadFile |DOWNLOAD.C | |------------------------------------+------------------------| |LoadInfoSegment |DEVBLOCK.C | |------------------------------------+------------------------| |LoadMarkerFont |POLYSTUF.C | |------------------------------------+------------------------| |LoadPaperDim |QUERY.C | |------------------------------------+------------------------| |LoadPPBResource |DEVBLOCK.C | |------------------------------------+------------------------| |LoadProfile |DEVBLOCK.C | |------------------------------------+------------------------| |LoadStringTable |MEMORY.C | |------------------------------------+------------------------| |LoadTrayCommand |UTLPS.C | |------------------------------------+------------------------| |LoadUserForms |PROFILE.C | |------------------------------------+------------------------| |LockDevice |SURFACE.C | |------------------------------------+------------------------| |LongMulFixed |MATH.ASM | |------------------------------------+------------------------| |LongShiftRight |UTLASM.ASM | |------------------------------------+------------------------| |LongXFixed |ASM2C.C | |------------------------------------+------------------------| |MatchFaceName |FONTS.C | |------------------------------------+------------------------| |MatchHWFontName |DEVBLOCK.C | |------------------------------------+------------------------| |MatrixToChannel |UTLPS.C | |------------------------------------+------------------------| |ModeSwitchDefaultControls |PPDLG.C | |------------------------------------+------------------------| |ModeSwitchDlgProc |PPDLG.C | |------------------------------------+------------------------| |ModeSwitchInitPage |PPDLG.C | |------------------------------------+------------------------| |ModeSwitchSaveSettings |PPDLG.C | |------------------------------------+------------------------| |NameWithSC |QUERYBOX.C | |------------------------------------+------------------------| |NewUserForms |QUERY.C | |------------------------------------+------------------------| |OpenChannel |UTLCHNL.C | |------------------------------------+------------------------| |OS2_PM_DRV_DEVICENAMES | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OS2 _ PM _ DRV _ DEVMODE | DEVMODE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OS2 _ PM _ DRV _ ENABLE | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OutputPageDefaultControls | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OutputPageDlgProc | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OutputPageInitControls | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | OuputPageSaveSettings | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PageAtPaper | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PalGray | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PaperDimensions | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | perform _ std _ spooling | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PfntFromIndex | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | play _ clip _ path _ buf | PATH2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | play _ clip _ rects | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | play _ path _ buf | PATH2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PostWriteError | QUERYBOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PpdDefaults | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ BackMapChar | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ CheckFontResource | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ ComputeTextTransformMatrix | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ CopyMetrics | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ CountKernPairs | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DefaultFontIndex | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DeviceGetAttributes | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DeviceQueryFontAttributes | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DeviceQueryFonts | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DeviceSetAttributes | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DeviceSetGlobalAttribute | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ DrawLine | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ FontTransform | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetCodePage | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetImagAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetKernAmount | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetLineAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetMarkAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetPairKerningTable | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetPtrnAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ GetTextAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ LoadFontResource | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ NumPrinterFonts | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ QueryWidthTable | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ QuoteChar | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ RealizeFont | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ RemapString | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetCodePage | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetImagAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetLineAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetMarkAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetPtrnAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prda _ SetTextAttrs | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ Bitblt | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ DeviceCreateBitmap | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ DeviceDeleteBitmap | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ DeviceSelectBitmap | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ GetBitmapBits | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ GetBitmapHandle | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ GetPel | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ ImageData | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ PolyMarker | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ RestoreScreenBits | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ SaveScreenBits | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ ScrollRect | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ SetBitmapBits | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdb _ SetPel | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ CreateLogColorTable | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ GetColor | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryColorData | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryColorIndex | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryLogColorTable | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryNearestColor | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryRealColors | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ QueryRGBColor | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ RealizeColorTable | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ RGB _ to _ Solid | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ RgbToGray | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ RgbToNearestRgb | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdc _ UnRealizeColorTable | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ CharRect | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ CharStr | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ DeviceInvalidateVisRegion | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ DeviceSetAVIOFont | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ DeviceSetCursor | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ GetPickWindow | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ GetStyleRatio | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ SetColorCursor | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ SetPickWindow | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdd _ UpdateCursor | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ DeleteSavedDCs | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ DisableDC | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ DisablePdb | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ EnableDC | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ FillLdb | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ FillPdb | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ ResetDC | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ RestoreDC | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ SaveDC | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prde _ SetDDCDefaults | ENABLE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ AccumulateBounds | BOUNDS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ Death | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ DeviceSetDCOrigin | XFORMS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ ErasePS | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ GetBoundsData | BOUNDS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ GetDCOrigin | XFORMS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ LockDevice | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ NotifyTransformChange | XFORMS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ ResetBounds | BOUNDS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ Resurrection | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdg _ UnlockDevice | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BeginArea | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BeginPath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BoxBoth | BOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BoxBoundary | BOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BoxCommon | BOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BoxInterior | BOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ BoxPath | BOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ CheckConic | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ CloseFigure | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ DrawConic | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ DrawConicsInPath | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ DrawLinesInPath | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ DrawSubConic | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ EndArea | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ EndPath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ ExpandBounds | BOUNDS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FillPath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FullArcBoth | ARCS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FullArcBoundary | ARCS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FullArcCommon | ARCS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FullArcInterior | ARCS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ FullArcPath | ARCS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ GetCurrentPosition | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ GetLineOrigin | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ MemClipChange | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ ModifyPath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ NotifyClipChange | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ OutlinePath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PatGray | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PenGray | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PolyFillet | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PolyFilletSharp | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PolyLine | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ PolySpline | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ RestorePath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ SavePath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ SelectClipPath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ SetCurrentPosition | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ SetLineOrigin | POLYSTUF . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ SetStyleRatio | ATTRS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdl _ StrokePath | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ DisjointLines | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ DrawBits | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ DrawBorder | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ PolyScanline | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ PolyShortLine | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdm _ QueryDevResource | NOINSTAL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ AbortDoc | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ EndDoc | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ Escape | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ NewFrame | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ QueryDeviceBitmaps | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ QueryDeviceCaps | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ QueryEscSupport | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ QueryHardcopyCaps | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdq _ StartDoc | DEVESC . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdt _ CharString | CHARSTR . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdt _ CharStringPos | CHARSTR . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdt _ QueryCharPositions | QUERYCHR . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | prdt _ QueryTextBox | QUERYCHR . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintBool | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintChannel | UTLCHNL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintColor | BITMAPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintColorTable | COLORTAB . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintDecimal | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrinterPropertiesDlgProc | PPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintFontMem | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintFraction | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | PrintHex | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ProfileAllocStringQuery | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ clearpath | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ clip | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ closepath | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ CosmeticLine | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ effects | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ enddoc | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ fill | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ grestore | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ gsave | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ imagedata | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ init | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ lineto | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ moveto | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ movetoCP | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ newpath | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ patfill | PATFILL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ patfill _ base | PATFILL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ patfill _ common | PATFILL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ patfill _ font | PATFILL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ restoreclipmatrix | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ restorematrix | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ rotatefont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ saveclipmatrix | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ savematrix | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ scalefont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ selectfont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setdash | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setdashnow | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ SetDownloadedFont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setfont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setlinecap | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setlinejoin | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setlinewidth | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setmatrix | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ setrgbcolor | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ shearfont | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ show | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ showpage | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ startdoc | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ status | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ stroke | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ strokecurrentpath | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ sync _ cp | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ps _ upper | PPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryAddFormButtonStatus | PPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryBlockFromKeyword | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryDefDrivFromQue | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryDeviceSurface | SURFACE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryEntryFromOption | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryFeaturePageLoad | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryMappedTray | DLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryNextSubkey | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryTunerProcData | PSTUNER . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryUIOptionString | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | QueryUserForm | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | R3 _ FileCheckDialogs | UTLCHNL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | rclIsEqual | PATH . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadFormINIData | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadHeader | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadNewOrOldINIString | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadPageOptionData | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadProfile | QUERYBOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReadTrayPageMapINI | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ReleaseHelpStubHook | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | RemapBoldItalic | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | RemapCodePage | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | rwASCblock | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | rwBINblock | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SaveCurrentUISelections | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SaveGammaVals | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SaveINIGroupData | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SavePageTrayINIData | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanCustomset | QUERYBOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanDigits | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanInt | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanPercentFormat | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanString | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ScanToken | UTLPRINT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SendPFB | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetCanvasMetrics | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetHelpStubHook | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetLDBFlag | MEMORY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetSysMenuFields | DLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetTabTextSize | DLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetTextBackground | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetTextColors | CHARSTR . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SetUIOption | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SFDownload | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SFQueryFonts | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | SFReadOFMs | DOWNLOAD . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ShowCursor | QUERYBOX . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | sync _ graphic _ states | PATH2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szColonCopy | QUERY . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szCopy | UTLPS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szDCopy | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szDlmCopy | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szIsEqual | IMG2BIN . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szLength | FONTS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | szNewCopy | DEVMODE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | sznIsEqual | DEVMODE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | TerminateTranslationString | PROFILE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ToTop ( ) | CHARSTR2 . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ulNormalize | MATH . ASM | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | UnHookBitmapCalls | PRDEVECT . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | UpdateTrayList | JPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | UserFileInvalid | FLCHKDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | utl _ memcopy | ASM2C . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | utl _ MemIsEqual | XFORMS . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ValidateDriveData | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | ValidFileName | CONFIG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | VerifyAndSaveSettings | DLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | VerifyLDDCNFStructure | DEVMODE . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | VerifyTrayFormMapping | PPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | VerifyUISelectionList | DEVBLOCK . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | VerifyUniqueForm | PPDLG . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | WriteChannel | UTLCHNL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | WriteModeString | UTLCHNL . C | | ---------- ---------- ---------- ------ + ---------- ---------- ---- | | WrtQueryProfile | QUERYBOX . C | \ ---------- ---------- ---------- ------ - ---------- ---------- ---- /
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 movetocommand 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 into 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 prda_ComputeTextTransformMatrix.
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 prda_LoadFontResourceto 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.
prda_NumPrinterFonts
Scans the array of fonts offered by this printer, counting filled Full Name entries.
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.
prda_RemapString
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:
- 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.
ToTop()
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.
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 Propertiesand Job Propertiesdialog 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 OS2_PM_DRV_DEVMODEto 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.
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 Helppush 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.
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 prde_FillPdb) to the CNFDATA section:
BuildKeyName
Builds the key name in form of:
PM_DD_<printerName>,<deviceDriver>.<deviceName>
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.
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.
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:
"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.
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 *InputSlotkeyword. 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 UTLPS.C) 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.
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.
The usTermCode parameter specifies the reason the process ended. This parameter can be one of the following values:
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 LoadPPBResource.
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".
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 OS2_PM_DRV_ENABLE.
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:
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.
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:
"*OpenUI *keyword"
except the keyword should not include the asterisk.
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 then 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 OS2_PM_DRV_DEVMODEand 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 Propertiesand Job Properties.
ClosePSDlg
This function closes the dialog box for Printer Propertiesand 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 Propertiesand 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 notchecked 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 Propertiesand 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 InitializeDialogHeader().
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 Formslistbox. 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-Controlhandle, 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 SFQueryFontsand FillSFonts, 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.
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.
The OS2_PM_DRV_ENABLE entry point handles the DC management functions. Those functions can be placed in three categories:
- Transactions involved in opening a DC.
*Transactions involved in closing a DC.
*Other DC functions. This includes SaveDC, RestoreDC, and ResetDC.
Opening and Closing DCs
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, OS2_PM_DRV_DEVMODEand OS2_PM_DRV_ DEVICENAMEScalls, 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 OKor Canceland 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 OpenChannelfunction 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 OKor Canceland 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.
pfatLogFontPointer to a FATTRS structure containing logical font information if this is a RF_DEVICE_FONT command.
lFontHandleHandle of the logical font to be deleted, if this is an RF_ DELETE_FONT command.
RF_DEVICE_FONTAttempt 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_FONTReturn 0L, font can't be realized.
The driver always returns 0L.
RF_DELETE_FONTAttempt 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 Propertiesdialog 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 Effectspage. For some controls, the default values are specified in the PPD.
EffectsPageDlgProc
This is the procedure for the Effectspage in the Job Propertiesdialog box .
EffectsPageInitControls
This function initializes the controls for the Effectspage.
EffectsPageSaveSettings
This function is only called if the user selects the Savebutton. All controls for the Effectspage are saved here.
FeaturePageDefaultControls
Sets all the settings to the default values for the Featurespage. For some controls, the default values are specified in the PPD.
FeaturePageDlgProc
This function is the procedure for the Featurespage of the Job Propertiesdialog box.
FeaturePageInitControls
This function initializes the controls for the Featurespage of the Job Propertiesdialog box.
FixUpColors
If the Lock Proportionscheck 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 Formspage. For some controls, the default values are set as specified in the PPD. For the Orientationcontrol, Portraitis set as the default value.
FormPageDlgProc
This function is the procedure for the Formspage in the Job Propertiesdialog box.
FormPageInitControls
This function initializes the controls within the .Formspage 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 Savebutton. All the controls in the Formspage 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 Propertiesdialog box.
OutputPageDefaultControls
Sets all the settings to the default values for the Outputpage. For some controls, the default values are specified in the PPD.
OutputPageDlgProc
This function is the procedure for the Outputpage in the Job Propertiesdialog box.
OutputPageInitControls
This function initializes the controls within the Outputpage.
OuputPageSaveSettings
This function is only called if the user selects the Savebutton. This function saves all the settings for the Ouputpage.
QueryFeaturePageLoad
This function queries the UI list to verify whether or not the Featurespage 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 duplexand modifies the icon for the Status Barevery time a duplexoption 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 onlyif 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 prde_FillLdb). 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 OS2_PM_DRV_DEVICENAMESand OS2_PM_DRV_DEVMODE. 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 prde_FillLdb. 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.Cfor 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 prdg_LockDevice.
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 ps_patfillto download PostScript code, common to pattern filling in the PostScript printer.
ps_patfill_common
Called by several places in ps_patfillto download PostScript code, common to pattern filling in the PostScript printer.
ps_patfill_font
Called by ps_patfillif 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 Propertiesdialog 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 Formsbutton. 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 Formspage in Printer Properties.
FormPPPageDefaultControls
This function sets the default control values when the Defaultbutton is pressed. The default values are set in the PPD file.
FormPPPageInitControls
This function inserts all values into all controls for the Formspage.
InitializeCustomForms
This function initializes the data needed to display the Display Formsdialog 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 Defaultbutton is pressed.
ModeSwitchDlgProc
This is the dialog procedure for the Optionspage.
ModeSwitchInitPage
This function initializes the controls for the Optionspage.
ModeSwitchSaveSettings
This function saves the current settings in the Optionspage.
PrinterPropertiesDlgProc
This is the main procedure for the Printer Propertiesdialog box.
ps_upper
This function converts a string to uppercase.
QueryAddFormButtonStatus
This function enables or disables the Add Custom Formbutton. 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 Trayslistbox 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:
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:
"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.
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:
"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.
SaveINIGroupData
This function appends a given string to a buffer in the following format:
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.
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:
"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.
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 mighteach 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.
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:
<value count>
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.
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> <0 3>
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.
ScanToken
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.
OS/2 Version Compatibility Considerations
The following table lists items discussed in this reference that have been added to OS/2 since OS/2 Warp Version 3.0 and discusses their compatibility with different versions of OS/2.
Item Added or Changed | Date Item Added or Changed | Compatibility of Addition or Change |
---|---|---|
Omni Drivers | June 1996 | OS/2 Warp Version 3.0 and higher |
GenPLib Updates | November 1995 | OS/2 Version 2.0 Service Pack and later |
PostScript Driver Updates | November 1995 | OS/2 Version 2.0 Service Pack and later |
42xx Driver | November 1995 | OS/2 Version 2.0 Service Pack and later |
Plotter Drivers | November 1995 | OS/2 Version 2.0 Service Pack and later |
Bidirectional Communication | November 1995 | OS/2 Warp, Version 3.0 and later Earlier printer drivers should work without modification when printing to bidirectional printers; port drivers developed under DDK earlier than 3.0 should work without modification when printing to bidirectional printers, but they do not provide bidirectional communication |