This chapter provides an overview of printer driver processing, followed by a detailed analysis and discussion of an example printer driver. The required printer filter/driver options and the reserved and unreserved printer filter/driver options are also covered.
The topics discussed in this chapter are:
![]() | Note: Printer application developers need not read chapters 3 through 5, but can skip to chapter 6. |
A printer driver must perform the following tasks:
Receive and process an input file.
Send formatted data to the printer.
Query and receive printer status information.
Read and write the printer object database (POD) files.
All printer drivers must read the POD files to determine printer-specific defaults and to maintain the active status file of the POD so that other clients can determine printer status. Chapter 6, "Printing Libraries," describes libpod, the library that provides an API to the POD. Appendix C, "Printer Object Database (POD) File Formats," defines the file formats for the printer configuration file, the printer status file, and the printer log file in the POD.
Figure 3-1 is an overview of printer driver processing. Note that this is a simplified overview; the actual steps might be more complex.
Two example printer drivers are provided: laserjet for HP LaserJet printers and phandler for generic parallel printers. The source code files for laserjet are in the directory /usr/impressario/src/drivers/laserjet and the source code files for phandler are in the directory /usr/impressario/src/drivers/phandler. Both drivers follow the steps shown in Figure 3-1 , but the laserjet driver is more complex because it also performs data compression. Since this added complexity is not necessary for our examples, we will focus on the phandler driver example in this session.
The example printer driver phandler checks the status of the parallel port while passing data through to the printer. It treats the input as a byte stream and updates the printer status database at various stages of processing.
Among the include files in this program is pod.h, which contains printer status error codes and other defines related to printing. The include file plp.h contains information related to the parallel port.
The command-line interface for phandler is:
phandler -P printer_name [-e] [-s] [-w] [-D...] [-L logfile]
[-R][-B bufsize] [filename]
|
Arguments:
| -P printer_name | Name of the installed printer (required). | |
| -e | Exit immediately on error. The default is not to exit on error. | |
| -s | Update printer status only and return. | |
| -w | Suppress warning messages. | |
| -D | Enable debugging. -D is the lowest level of detail, -D -D is the second level, and -D -D -D is the highest level of detail. The debugging information is written to the log file. | |
| -L logfile | Specify the log file for debugging information and errors. The default log file is standard error, which is redirected to the spooler log file by the SVR3 lp spooler. | |
| -R | Reset the parallel port before sending data. | |
| -B bufsize | Set the byte size of the internal transfer buffer. The default is 1024 bytes. Larger buffers enable more page buffering, which may free upstream filters to do more processing while data is being sent to the printer. | |
| filename | Specify the name of the file sent to the printer. The default is to read the data from standard input. |
This section is a detailed discussion of the phandler driver. A more detailed example driver is supplied in the /usr/impressario/src/drivers/laserjet directory.
![]() | Note: The Impressario guidelines strictly require drivers to retry errors. Error exits are to be avoided whenever possible so that print jobs do not disappear before the user has a chance to fix the error condition. |
Open the port. If there is an error and you requested exit on error when invoking phandler, then the program writes an error message and exits. Otherwise, when an error occurs, the program will continue trying to open the port. It checks every n seconds (where n is the value of error_retry_wait) and writes an error message to the .log file after each failed attempt to open the port.
If phandler successfully opens the port, it updates the current printer status to "Busy" in the printer active status file. If the command line contained the -s option (status only), then phandler exits after updating the status. (The kernel closes the port when it exits the program.)
If the command line contained the -R option (reset the parallel port before sending data), then reset the parallel port.
If any level of debugging information was requested, write the message "Resetting parallel port..." to errfile along with the program name.
If an error occurs, and if exit on error was requested with the -e option, then the program writes an error message and exits. Otherwise, the program prints the message "Could not reset the parallel port" to errfile, along with the program name, and waits for error_retry_wait seconds before retrying.
Allocate and set up the buffer. If phandler cannot allocate the buffer, the program exits with an error message. (We exit only because memory allocation errors are very rarely recoverable.)
Read status from the printer.
Update the printer status configuration file.
Begin reading from the input and sending data to the parallel port.
Your driver will probably need to process the input data into an appropriate printable format before sending the data to the printer.
If an unrecoverable error occurs while writing to the parallel port, write an error message to the log, write the faulted state to the printer status configuration file, and exit.
If the input file is empty or unreadable, write an error message to the log, update the status file, and exit.
The driver uses signal handling to ensure that it is not interrupted in "critical regions," during which an interrupt could destroy vital files or the printer state.
The command-line options listed in this section must be implemented as specified for any printing filter or driver to be compatible with Impressario. Switch letters have been chosen to maximize the intuitive correlation with function. Additional functionality beyond that listed here must use unreserved switch settings. Please note the following points:
All switches are case sensitive. That is, -P does not have the same meaning as -p.
Printer drivers must accept and ignore all reserved options that are not supported.
Printer drivers must conform to getopts conventions. (See getopts(2) for more information.)
Multiple options on a single line have right-to-left precedence. For example:
-n 1 -n 2 |
has the same effect as
-n 2 |
Drivers must accept and parse command-line options when included as part of the STIFF image header. See the laserjet example driver and Appendix A, "Stream TIFF Data Format," for more details.
A good example is the header containing a number-of-copies command, such as would be generated by a PostScript #copies command.
These switches must be supported by all drivers:
| -e | Exit immediately on fault without waiting for faults to clear. The default behavior is to wait indefinitely for faults to clear, polling the device at the error-retry intervals specified in the POD config file. This option is used when only a quick query should be done. | ||
| -s | Update the status file. Exit only after successfully updating the status file. This switch has the highest precedence. If the -e switch is given, exit after one try at reading status. | ||
| -w | Do not report warnings in the status file. Report errors only. | ||
| -D | Enable debugging information. Optionally, more -D switches increase the level of debugging detail. For example, entering
| ||
enables a second level of debugging detail. At least one level of debugging must be supported. | |||
| -P string | The value of string defines the printer name. The printer name is used to find the POD. The printer name is the name given to the printer at installation time. See the libpod(3) man page for more information. This option is also a required option whenever the driver is invoked. |
Impressario printer drivers must read the libpod printer object database to:
Determine defaults.
Maintain the active status portion of the POD database.
Enable other clients to determine printer status.
The following switches are reserved and are to be implemented by drivers whose hardware supports them, or by inline filters that process the options before the driver is invoked. You need not implement all options, but every driver must accept or ignore any unimplemented options on this list.
Raster-specific options include:
| -f | Flip the image, as if in a mirror. The image is rotated horizontally about the y-axis. Useful for transparencies or decals. | |
| -p int | Scale the image as if it were being printed on a device with the designated resolution specified in pixels per inch. This is a convenience switch, since the same effect can be obtained by computing the appropriate scale factor for the image size and destination resolution. | |
| -r int | Rotate the image counter-clockwise by an angle specified in degrees. Values outside the range 0..359 should be accepted and modulo converted to a value between 0..359. | |
| -z float | Zoom the image using proportional scaling, where the floating-point argument is nonnegative. Some values are: |
Engine-specific options include:
Output-specific options include:
| -L filename | Log errors to filename instead of standard error. The file specified should be opened in append mode. If the file cannot be opened, errors should be reported to standard error instead. | |
| -O filename | Output data to filename instead of the device port or standard output. The file specified should be opened. If the file cannot be opened, data should instead be written to the device or standard output, as appropriate. If this option is used, all status reporting is disabled, since the printer driver is not communicating with the actual device. |