PDRREF:Graphics Engine Hardcopy Drivers

For the Presentation Manager interface, hardcopy devices, such as printers and plotters, are queued devices. When an application writes to one of these devices, the presentation driver creates a spool file and writes the data to that file. The data is printed when it is complete and the required device is free.

Two instances of a device context are required to support queued data. The first instance is opened as an OD_QUEUED device by the application. This DC buffers the data, does any processing that is required, and then writes the data to a spool file. The second instance is opened as an OD_DIRECT device by the queue processor. This DC receives data from the spool file, does any processing that is required, and by using the Prtxxx interface, sends the data to the final output destination, such as port, device, or UNC name.

When a device context is opened, the data type given (PM_Q_STD or PM_Q_RAW) is applicable only for the OD_QUEUED device context type.

Exported Entry Points
The following entry points must be exported by a hardcopy driver dynamic link library:

EXPORTS OS2_PM_DRV_DEVMODE OS2_PM_DRV_DEVICENAMES OS2_PM_DRV_ENABLE DrvInstall               /* Optional */ DrvRemove                /* Optional */ DialogProc   @2


 * Note: DialogProc is exported by ordinal. The entry point is used by the Presentation Manager interface to manage the dialog initiated by the OS2_PM_DRV_DEVMODE.

Additional information on Exported Entry Points, including detailed descriptions of the functions and subfunctions can be found in Exported Driver Function Reference and OS2_PM_DRV_DEVMODE.

InnerGre Entries
The InnerGre entries are important to some 32-bit hardcopy presentation drivers that are coded in the "shadow DC" style. A shadow DC is actually a display OD_MEMORY DC. It is created by a printer driver to "steal" rasterization services from the currently installed display driver, and therefore save writing some code.

GRE Macro Expansion
For the following GRE macro:

GreCreateBitmap( hdc, pbmiHeader, flUsage, pBits, pbmi );

the compiler expands the call as follows:

Gre32Entry7( hdc, pbmiHeader, flUsage, pBits, pbmi, NULL, NGreCreateBitmap );

Note the two additional parameters. The NULL is a pointer to instance data for the device drawing context (DC). The graphics engine supplies the correct pointer when it dispatches the function to the device driver. NGreCreateBitmap is a combination of command drawing flags in the high word and requested function number in the low word. The graphics engine sets the command flags when it dispatches the function to the device driver.

InnerGre Macros
For each Gre32Entry there is also an InnerGre32Entry. Some 32-bit hardcopy drivers call both the standard GRE entries as well as the InnerGre entry. These hardcopy drivers use a shadow device context, which is an OD_MEMORY device context in the currently installed display driver, to assist with rasterization. When called to perform a drawing function, these hardcopy drivers relay the work to the shadow DC (thus the display driver) by substituting the hardcopy DC handle with the shadow DC handle and calling the appropriate engine entry. This style of hardcopy driver coding made necessary the InnerGre entries.

The InnerGre entries differ from normal GRE entries in these ways:


 * For the InnerGre entries, the graphic engine does not reload the command flags parameter (the last parameter). Instead, the engine uses the command flags parameter exactly as supplied by the caller.
 * The graphics engine will not transform coordinates when called at the InnerGre level. The InnerGre entries always expect device coordinates.
 * The graphics engine does not perform validation on the supplied device context handle when called at the InnerGre level.

The Developer's Toolkit for OS/2 does not provide an include file for InnerGre macros. Refer to to INNERGRE.H in the MiniDriver code sample in the IBM Device Driver Source Kit for OS/2, (Version 1.1 or higher). The MiniDriver is an example of a hardcopy driver that uses a shadow device context.

File System EMulation
Presentation drivers for hardcopy devices use an internal interface to communicate with the device. Hardcopy drivers do not differentiate between different types of ports- LPT1 (parallel) and COM1 (serial). The Prtxxx API routes the data to the appropriate physical device driver. This API also handles semaphoring the port so that two threads do not intermix their output.

The internal interface is based on the DOS file system calls DosOpen, DosClose, DosWrite, and so forth. Presentation drivers open a device and receive a handle that identifies the device as a file. Subsequent operations such as writing to the device are implemented by writing to the returned handle.

The handle returned by PrtOpen is not an OS/2 file handle, and can only be used in other Prtxxxx APIs.

The following functions are used by the presentation driver:


 * PrtAbort
 * PrtClose
 * PrtDevIOCtl
 * PrtOpen
 * PrtWrite

The following functions are new for OS/2 Warp, Version 3:
 * PrtAbortDoc
 * PrtResetAbort
 * PrtNewPage

Spooler Support for POM_Q_STD Data Type
The following functions are available to help the hardcopy driver create a spool file containing PM_Q_STD data:
 * SplStdClose
 * SplStdDelete
 * SplStdGetBits
 * SplStdOpen
 * SplStdQueryLength
 * SplStdStart
 * SplStdStop

Spooler Componets
The spooler interface (Spl...) is implemented in two libraries, PMSPL.DLL and PMPRINT.QPR, which support four activities:


 * Management of spool buffers for PM_Q_STD data (SplStdxxx interface)
 * Management of queued files (SplQmxxx interface)
 * Processing of queued files (SplQpxxx interface)
 * Displaying messages on the screen (SplMessageBox)

Output Strategy
The following illustration summarizes the spooler and direct output strategies.



Output Strategy

Spool File Creation
The steps taken by the presentation driver to create a spool file are determined by the data type for which the DC was enabled. All presentation drivers must support PM_Q_STD and PM_Q_RAW. Overviews of creating a spool file for these data types are shown below. See the following illustration.

Data types can be defined by the user. A name should be chosen that is not likely to conflict with other user-defined data types. The name must be a string of up to 16 characters in the ranges 'A' through 'Z', '0' through '9', or _. Note that the data type is only useful to applications that know about it, and with presentation drivers that implement it.

Print jobs must be spooled by using the data type given on the call to OS2_PM_DRV_ENABLE Subfunction 02H - FillPhysicalDeviceBlock. Therefore, print jobs queued PM_Q_STD can be printed with queue processor options applied to the job.

Output Directly to Device
The handling of an OD_DIRECT DC is similar to an OD_QUEUED PM_Q_RAW DC, except that PRTxxx calls are used to write the data. You should use a second thread for writing to the device so that the application's thread is not blocked for long periods of time during a device timeout situation.

The following illustration shows this output method.



Output to Device - OD_DIRECT

PM_Q_STD
PM_Q_STD data is a file of Gpixxx calls that describe the output document. This data type is independent of the device and the presentation driver. The presentation driver invokes the spooler's standard interface (SplStdxxx). All subsequent Gpixxx calls and some escape codes sent to the DC are recorded in a spool buffer. When DEVESC_ENDDOC is detected, the presentation driver ends the recording and invokes the spooler's interface (SplQmxxx) to write the buffered data into a spool file.

Normal Sequence of Events;
1.Application calls DevOpenDC to open an OD_QUEUED device for printing PM_Q_STD data.

2.Hardcopy driver calls SplStdOpen to open a recording.

3.Application calls DevEscape with DEVESC_STARTDOC.
 * a.Hardcopy driver calls SplStdStart to start recording.
 * b.Hardcopy driver calls SplQmOpen and SplQmStartDoc to open and start a spool file.
 * c.Spooler records all Gpixxx calls and some escape codes in the spool buffer.


 * Note: Recording does not stop the flow of Gpixxx calls through the system. These calls are processed and the resulting Grexxx calls are passed on to handling routines in the graphics engine and presentation driver. Special considerations apply for escape codes. For details, see the individual escape codes under GreEscape.
 * d.Hardcopy driver DC is OD_INFO. The presentation driver tracks the current position, does any bounds calculation required, and responds to queries from the application. In particular, the presentation driver must be able to understand and reply to:


 * DevQueryCaps
 * DevQueryHardCopyCaps
 * DevQueryDeviceNames
 * DevPostDeviceModes

4.Application calls DevEscape with DEVESC_NEWFRAME.
 * a.Hardcopy driver resets current position and bounds.

5.Application calls DevEscape with DEVESC_ENDDOC.
 * a.Hardcopy driver calls SplStdStop to stop the recording.
 * b.Hardcopy driver calls SplStdQueryLength to get the length, in bytes, of the spooled data.
 * c.Hardcopy driver calls SplStdGetBits to get data from the spool buffer into memory that is owned by the presentation driver. (The driver might need to loop on this step and the next if the spooled data is larger than the available memory.)
 * d.Hardcopy driver calls SplQmWrite to write the data in the spool file.
 * e.Hardcopy driver calls SplStdDelete to delete the data in the spool buffer.
 * f.Hardcopy driver calls SplQmEndDoc to stop the spool file, and returns the Job ID to the application's DevEscape with DEVESC_ENDDOC.

6.Application calls DevEscape with DEVESC_STARTDOC (repeat Step 2).

7.Application calls DevEscape with DEVESC_NEWFRAME (repeat Step 3).

8.Application calls DevEscape with DEVESC_ENDDOC to spool the second job (repeat Step 4).

9.Application calls DevCloseDC.
 * a.Hardcopy driver calls SplStdClose and SplQmClose to close the spool buffer and the spool file.

End Sequence of Events
1.Application calls DevOpenDC to open an OD_QUEUED device for printing PM_Q_STD data.
 * a.Hardcopy driver calls SplStdOpen to open a recording.

2.Application calls DevEscape with DEVESC_STARTDOC.
 * a.Hardcopy driver calls SplStdStart to start recording, and SplQmOpen to open a spool file if one is not yet open.
 * b.Spooler records all Gpixxx calls and some escape codes in the spool buffer.


 * Note: Recording does not stop the flow of Gpixxx calls through the system. These calls are processed and the resulting Grexxx calls are passed on to handling routines in the graphics engine and presentation driver. Special considerations apply for escape codes. For details, see the individual escape codes under GreEscape.
 * c.Hardcopy driver performs as if the DC was opened as OD_INFO. The presentation driver tracks the current position, does any bounds calculation required, and responds to queries from the application. In particular, the presentation driver must be able to understand and reply to:


 * DevQueryCaps
 * DevQueryHardCopyCaps
 * DevQueryDeviceNames
 * DevPostDeviceModes

The calls can be journaled, but the journal file is not saved.

3.Application calls DevEscape with DEVESC_ABORTDOC to end the document.
 * a.Hardcopy driver calls GreStopJournalFile.
 * b.Hardcopy driver calls GreDeleteJournalFile.
 * c.Hardcopy driver calls SplStdStop to stop the recording.
 * d.Hardcopy driver calls SplStdDelete to delete the data in the spool buffer.
 * e.Hardcopy driver calls SplQmAbortDoc to stop the spool file.

4.The application calls DevCloseDC.
 * a.Hardcopy driver calls SplStdClose and SplQmClose to close the recording and the spool file.

This method of spool file creation is shown in the following illustration.



Spool File Creation - OD_QUEUED PM_Q_STD

PM_Q_RAW
PM_Q_RAW data is a device-dependent bit stream.

Normal Sequence of Events
1.Application calls DevOpenDC to open an OD_QUEUED device for printing PM_Q_RAW data.

2.Application calls DevEscape with DEVESC_STARTDOC.
 * a.Hardcopy driver calls SplQmOpen to open a spool file if one is not yet opened.
 * b.Hardcopy driver calls GreCreateJournalFile to create a journal file.
 * c.Hardcopy driver calls SplQmStartDoc to start the spool file.
 * d.Hardcopy driver calls GreStartJournalFile to start recording Grexxx calls.


 * Note: Recording does not block the flow of Grexxx calls to handling routines in the graphics engine and presentation driver.
 * e.Hardcopy driver processes the incoming Grexxx calls to create the first band of data for the spool file.

3.Application calls DevEscape with DEVESC_NEWFRAME to start a new page.
 * a.Hardcopy driver calls GreStopJournalFile to stop the journal file.
 * b.Hardcopy driver calls SplQmWrite to write the first band in the spool file.
 * c.Hardcopy driver moves clip rectangle to next band in presentation space.
 * d.Hardcopy driver calls GrePlayJournalFile to play the journal file.
 * e.Hardcopy driver processes each Grexxx call to create the second band of data for the spool file.
 * f.Hardcopy driver calls SplQmWrite to write the second band in the spool file.
 * g.Hardcopy driver plays the journal file repeatedly until all the bands have been processed and passed to the spooler.
 * h.Hardcopy driver issues a page eject, if necessary.
 * i.Hardcopy driver calls GreDeleteJournalFile.
 * j.Hardcopy driver calls SplQmEndDoc to stop the spool file, and returns the Job ID to the application's DevEscape with DEVESC_ENDDOC.


 * Note: If no Grexxx calls have been made (that is, no output is required), only Steps 1 and 8 are executed.

4.Application calls DevEscape with DEVESC_ENDDOC to end the document.
 * a.Hardcopy driver calls GreStopJournalFile to stop the journal file.
 * b.Hardcopy driver calls SplQmWrite to write the first band in the spool file.
 * c.Hardcopy driver calls GrePlayJournalFile to play the journal file.
 * d.Hardcopy driver processes each Grexxx call to create the second band of data for the spool file.
 * e.Hardcopy driver calls SplQmWrite to write the second band in the spool file.
 * f.Hardcopy driver plays the journal file repeatedly until all the bands have been processed and passed to the spooler.
 * g.Hardcopy driver calls GreDeleteJournalFile.
 * h.Hardcopy driver calls SplQmEndDoc to stop the spool file, and returns the Job ID to the application's DevEscape with DEVESC_ENDDOC.


 * Note: If no Grexxx calls have been made (that is, no output is required), only Steps 3.a, 3.i, and 3.j are executed. No page is ejected.

5.Application calls DevEscape with DEVESC_STARTDOC (repeat Step 2).

6.Application calls DevEscape with DEVESC_NEWFRAME to start new page (repeat Step 3 under Normal Sequence of Events).

7.Application calls DevEscape with DEVESC_ENDDOC to spool the second job (repeat Step 4).

8.Application calls DevCloseDC.


 * a.Hardcopy driver calls SplQmClose.

End Sequence of Events
1.Application calls DevOpenDC to open an OD_QUEUED device for printing PM_Q_RAW data.

2.Application calls DevEscape with DEVESC_STARTDOC to start the document.
 * a.Hardcopy driver calls SplStdOpen to open a spool file.
 * b.Hardcopy driver calls GreCreateJournalFile to create a journal file.
 * c.Hardcopy driver calls SplQmStartDoc to start the spool file.
 * d.Hardcopy driver calls GreStartJournalFile to start recording Grexxx calls.


 * Note: Recording does not block the flow of Grexxx calls to handling routines in the graphics engine and presentation driver.
 * e.Hardcopy driver processes the incoming Grexxx calls to create the first band of data for the spool file.

3.Application calls DevEscape with DEVESC_ABORTDOC to end the document.
 * a.Hardcopy driver calls GreStopJournalFile
 * b.Hardcopy driver calls GreDeleteJournalFile
 * c.Hardcopy driver calls SplQmAbortDoc to stop the spool file.


 * Note: The hardcopy driver can be processing the DEVESC_ENDDOC (banding, for example) and a DEVESC_ABORT comes into the hardcopy driver on another thread.

4.Application calls DevCloseDC.
 * a.Hardcopy driver calls SplQmClose to close the spool file.

This method of spool file creation is shown in the following illustration.



Spool File Creation - OD_QUEUED PM_Q_RAW

Querying and Setting Configuration Data
The configuration of printers and queues is stored in OS2SYS.INI. For optimum performance, use the SplxxxDevice and SplxxxQueue functions together as a high-level interface into OS2SYS.INI. Refer to the OS/2 Presentation Manager Programming Reference for further information.

Spooler Support Functions
The purpose of the spooler is to control the queues, create new spool files, and invoke the queue processor when a job is ready for printing. The spooler also provides a function, SplMessageBox, that can be called to display a message to the user.

The following functions are available in the spooler:


 * SplMessageBox
 * SplQmAbort
 * SplQmAbortDoc
 * SplQmClose
 * SplQmEndDoc
 * SplQmOpen
 * SplQmStartDoc
 * SplQmWrite

The following functions are new for OS/2 Warp, Version 3:


 * SplQmNewPage
 * SplQmGetJobID

For a complete description of each of the functions listed in this chapter, see Device Support Function Reference. They are listed alphabetically in the index table for that chapter.