This chapter describes the printing libraries used by Impressario printer drivers, filters, and applications.
The three printing libraries are described in this chapter:
"The libspool Library" is a C-language application programming interface (API) to the UNIX printer spooling systems.
"The libprintui Library" is a C-language API to the PrintBox widget that is compatible with Motif.
"The libpod Library" is a C-language API to the printer object database (POD).
In addition to the above libraries, there are two libraries described in the appendices that are also used by printer drivers and filters:
Appendix A, "Stream TIFF Data Format," describes libstiff, a C-language API for reading and writing the STIFF (Stream TIFF) data file format.
Appendix B, "Silicon Graphics Image File Format API," describes libimp, a C-language API for reading and writing Silicon Graphics Image format files.
The libspool Library is a C-language application programming interface (API) to the UNIX printer spooling systems. There are two common UNIX printer spooling systems, System V and Berkeley Software Distribution (BSD). While both of these spooling systems provide essentially the same capabilities, each has its own command set and neither provides a C-language API. The libspool library provides a single, common API to both spooling systems. The functions provided by libspool include submittal and cancellation of print jobs and control and reading of print queues.
Programs that call libspool functions must include spool.h, the header file in the /usr/include directory. The programs must also link with the libspool.a library located in /usr/lib. Use the following include directive:
#include <spool.h> |
Here is an example of the complete cc compiler command line:
cc -o myprog myprog.c -lspool |
Table 6-1 lists the libspool functions by purpose.
Table 6-1. Summary of libspool Functions
Purpose | Function Name |
|---|---|
Spooling System Selection |
|
Set the default spooling system | SLSetSpooler |
Get the default spooling system and available systems | SLGetSpooler |
Printer Information |
|
Get the list of registered printers | SLGetPrinterList |
Return information about a single printer | SLGetPrinterInfo |
Get the name of the default printer | SLGetDefPrinterName |
Get spooler and printer settings information | SLGetPrinterSettings |
Option Management |
|
Get System V spooler options | SLSysVGetSpoolerOptions |
Get System V printer options | SLSysVGetPrinterOptions |
Save System V spooler options | SLSysVSaveSpoolerOptions |
Save System V printer options | SLSysVSavePrinterOptions |
Print Job Submittal |
|
Submit a print job | SLSubmitJob |
Submit the contents of the file specified by a file descriptor for printing | SLSubmitJobFd |
Submit the contents of the specified buffer for printing | SLSubmitJobBuf |
Submit a print job using default values for all printing options | SLSubmitJobSimple |
Cancel a queued printer job | SLCancelJob |
Printer Queue Information |
|
Report the printer queue contents | SLGetQueue |
Printer Queue Control |
|
Set the spooling system printing and queueing state | SLSetSpoolerState |
Get the spooling system printing and queueing state | SLGetSpoolerState |
Execution Error Handling |
|
Print a libspool execution error message to standard error | SLPerror |
Obtain a libspool execution error message | SLErrorString |
Get spooling system error information | SLGetSpoolerError |
The libprintui library is library implementing a graphical user interface (GUI) for printing. This library provides PrintBox, a complete print job submittal solution in a single widget that is compatible with Motif, for application developers. This eliminates the need for application developers to develop a unique printing solution for each application, thereby saving considerable time and effort and making it easier to provide a robust and complete printing interface for application data.
Using the PrintBox widget in an application benefits the end user in several ways. First, PrintBox provides a consistent interface to the printer spooling system across the variety of applications on Silicon Graphics systems. Second, users can set print job options, such as number of copies, through a graphical interface, rather than through obscure command-line option flags. Finally, PrintBox uses the printer graphical options panel to provide a mechanism for the setting and saving of printer-specific options.
The PrintBox widget can be used in a number of different configurations and can accept a child manager widget to allow the display of application- specific options. The widget provides built-in System V print job submittal via the libspool library. (See "The libspool Library" for more information.) The developer can also perform application-specific processing before a job is submitted to the printing system. A variety of callback lists provide user and spooling system feedback. A print job can be submitted as a filename, as a file descriptor, or as a pointer to the buffer. The default form of PrintBox includes the following items:
A print file entry text field (for file-based jobs)
A scrolling list of available printers
Print option controls
The following action-area push buttons:
Submits the specified file or buffer for printing by the spooling system. | ||
| More Options ... | Accesses the graphical options panel for the currently selected printer. | |
| Save Options ... | Saves printer and spooling system options. | |
| Cancel | Normally used to pop down the PrintBox widget when the widget is used as a pop-up dialog. | |
| Help | Calls the functions on the helpCallback list. |
There are also four unmanaged buttons, User1 through User4, positioned between the Print and More Options ... buttons. These buttons are invisible by default; the buttons become visible when explicitly managed. The PrintBox widget also accepts one child as a work area. This area can be used for application-specific printing controls such as page range.
Figure 6-1 through Figure 6-4 illustrate four widget configurations:
Default configuration
No filename entry
No options
With a child
Programs that call the libprintui functions must include the header file /usr/include/Sgm/PrintBox.h and must link with the following libraries in the order shown:
... -lprintui -lspool -lXm -lXt -lXll -lgen ... |
The link order is important for proper link-time name resolution.
![]() | Note: Programs that subclass off the PrintBox widget must also include /usr/include/Sgm/PrintBoxP.h. |
The libprintui functions are listed in Table 6-2 . The PuiPrintBox(3X) man pages provide detailed information on the PrintBox widget.
Table 6-2. Summary of libprintui Functions
Function Name | Purpose |
|---|---|
Widget Instantiation |
|
PuiCreatePrintBox | Create a PrintBox widget |
PuiCreatePrintDialog | Create a PrintBox dialog |
Widget Component Access |
|
PuiPrintBoxGetChild | Access a PrintBox widget component |
Widget Action Functions |
|
PuiPrintBoxDoPrint | Invoke PrintBox printing |
The example program, printbox, simply instantiates a PrintBox widget. The directory /usr/impressario/src/examples/libprintui contains the source code for this program, while the directory /usr/impressario/bin/examples/libprintui contains the executable version.
To invoke the example program, type:
printbox |
The printbox program begins by setting the program instance name and initializing the X Window System[tm] applications connection. Next, the program creates the PrintBox widget with a call to the libprintui library function PuiCreatePrintBox. This widget is then added to the parent's managed set.
The program now adds the following callbacks:
The Cancel button exit routine
A help dialog display
A routine to print job information and the job ID to standard output and terminate the program
A display of error messages from the PrintBox widget (this uses the function SLGetSpoolerError from the libspool library)
A call to XtRealizeWidget now realizes the parent widget from the earlier call to PuiCreatePrintBox and all child widgets.
The program now begins an event loop. It obtains the next event from the X event queue then dispatches the event. If an early error has occurred, the error is handled and the loop continues until the application exits.
The libpod library provides printer driver developers with an API to create and maintain a Printer Object Database (POD) and provides application developers with the means to acquire detailed information about a printer, even across the network. A POD contains information on the current printer configuration, status, and job history of a single printer. Each printer physically installed on a system maintains its own POD on that system. All interaction with a printer's POD must be done through the libpod API. Do not modify the POD files directly. To create an initial set of POD files, refer to Appendix C, "Printer Object Database (POD) File Formats," and the examples provided in /usr/impressario/src/data.
A POD consists of three separate ASCII text files. The name of each POD file is formed from the printer name, followed by one of these suffixes: .config, .status, or .log. The name and contents of each file are as follows:
The configuration file contains detailed information on the printer's capabilities. Examples include the supported paper sizes and available fonts. The initial version of this file is manually created by the printer driver developer, and a copy is installed when the printer is added to the system. The contents of this file are maintained by the system administrator using the printer administration tools. Normally this file is never changed. | |
The status file contains information about the current operational status of the printer. The information in this file indicates whether the printer is busy, the type of printing media installed, detailed error codes (if errors have occurred), and so on. The contents of this file change during the course of every print job. | |
[printer_name].log | The log file contains the print job history for the printer. Information for old jobs as well as the current print job is maintained. Typically, printer filters and drivers append information to the log file while general applications treat the file as read-only. |
The global variable PDpod_path indicates the location of the POD files. The default location for POD files is /var/spool/lp/pod. If POD files are to be located in a directory other than the default, set PDpod_path to the pathname of the new location. PDpod_path is declared in the header file pod.h.[3]
See Appendix C, "Printer Object Database (POD) File Formats," for detailed information on libpod file formats.
The POD files reside on the system to which the printer is physically connected. This system is referred to as the printer host. Therefore, to provide information about a printer located on another system, libpod must be able to communicate across the network. The "standard" form of the libpod functions automatically determines whether the specified printer is located on the user's system (a local printer) or on a remote system (a remote printer). After determining where the printer is located, the standard libpod functions access the POD files on the appropriate system. Typically, user application programs such as printer status tools use the standard form of the libpod functions, since it is likely that these programs need to work with remote printers.
Since network communication carries a certain amount of performance overhead, libpod also provides the "local" functions for use by programs that are guaranteed to be run on the printer host. These functions include the word "Local" in the function name (for example, PDLocalReadInfo, PDLocalWriteStatus). A printer driver is an example of a program that should use local libpod functions.
Functions that write to POD files are available only in local form. Only printer drivers will need to write to the POD files, and printer drivers are always located on the printer host. Thus there is no need to provide writing capabilities to the standard libpod functions that are designed for use from remote machines.
There are several advantages to using the local libpod functions for programs that will always be run on the printer host. The local libpod functions have no networking overhead; they always go directly to the POD files on the local machine. This reduces the size and overhead of the resulting executable.
Programs that call libpod functions must include the header file pod.h, which is located in the directory /usr/include. The programs must also link with the library libpod.a located in /usr/lib. In addition, programs that use the standard libpod functions must link with libspool.a. Programs that use only the local libpod functions need not link with this additional library.
The compile line for the standard case is:
cc -o myprog myprog.c -lpod -lspool |
The compile line for the local case is:
cc -o myprog myprog.c -lpod |
If the global variable PDdebug is set to a nonzero value, libpod functions will print debugging information to standard error during execution. The global variable PDdebug is declared in the header file pod.h.
To provide remote printer POD information, libpod communicates over the network with the podd(1M) daemon on the remote machine. Since the network or remote machine may be unreachable when a libpod function is executed, a time-out may occur and the function will return an appropriate error code. The time-out period can be specified by setting the global variable PDnet_timeout to a value in seconds. The default time-out period is shown in the header file pod.h. While a larger time-out period is appropriate when reading printer status, a much smaller time-out may be appropriate for browsing printer configurations. For more information on the daemon, refer to the podd(1M) man page.
The libpod functions are listed in Table 6-3 . Note that a number of libpod functions have only a single version, which is used for both standard and local cases.
Table 6-3. Summary of libpod Functions
Task | Standard Function | Local Function |
|---|---|---|
Detailed Information Retrieval | PDReadInfo | PDLocalReadInfo |
Status File Manipulation | PDReadStatus | PDLocalReadStatus |
Log File Manipulation | PDReadLog | PDLocalReadLog |
Convenience Functions | PDMakeMessage PDFindPageSize PDGetSizeCodeByName PDGetNameBySizeCode PDGetCurrentResolution | n/a n/a |
Execution Error Handling | PDError PDErrorString | n/a n/a |
[3] The maximum string length for PDpod_path is PD_STR_MAX. This length includes the terminating NULL character.