Chapter 5. Printing Libraries

This chapter describes the printing libraries used by Impressario printer drivers, filters, and applications.

Three printing libraries are described in this chapter:

In addition to the above libraries, there are two libraries described in the appendices that are also used by printer drivers and filters:

The libspool Library

The libspool library is a C application program interface to the UNIX printer spooling systems. There are two common UNIX printer spooling systems, System V and Berkeley Software Distribution (BSD). While 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 submission and cancellation of print jobs, and control and reading of print queues.

Compiling Programs With libspool

Programs that call libspool functions must include spool.h, the header file in the /usr/include directory. Use the following #include directive:

#include <spool.h>

The programs must also link with the libspool.a library located in /usr/lib. Here is an example of the complete cc compiler command line:

cc -o myprog myprog.c -lspool 

libspool Library Functions

Table 5-1 lists the libspool functions by purpose.

Table 5-1. Summary of libspool Functions


Function Name


Spooling System Selection



Set the default spooling system.

Get the default spooling system and available systems.

Printer Information





Get the list of registered printers

Return information about a printer.

Get the name of the default printer.

Get spooler and printer settings.

Option Management





Get System V spooler options.

Get System V printer options.

Save System V spooler options.

Save System V printer options.

Print Job Submission





Submit a job for printing.

Submit the contents of the file specified by a file descriptor.

Submit contents of specified buffer.

Submit a print job using default values for all printing options.

Print Job Cancellation


Cancel a queued printer job.

Printer Queue Information


Report the printer queue contents.

Printer Queue Control



Set the spooling system printing and queueing state.

Get the spooling system printing and queueing state.

Execution Error Handling




Print a libspool execution error message to standard error.

Get a libspool execution error msg.

Get spooling system error info.

The libprintui Library

The libprintui library implements a graphical user interface (GUI) for printing. The library provides PrintBox, a complete solution for print-job submission, to application developers. A widget that is compatible with Motif, PrintBox eliminates the need to create custom printing solutions for each application. This widget saves application developers time and effort, and makes it easier for them to provide a robust, complete printing interface.

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 varied 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 submission 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.


    Normally used to pop down the PrintBox widget when the widget is used as a pop-up dialog.


    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, invisible by default, become visible when explicitly managed by your application. The PrintBox widget also accepts one child process as a work area. This area can be used for application-specific printing controls such as page range.

Example Widget Configurations

Figure 5-1 through Figure 5-4 illustrate four widget configurations:

  • the default configuration

  • without a filename entry box

  • without an options box

  • with a child process

    Figure 5-1. PrintBox Widget: Default Configuration

    Figure 5-1 PrintBox Widget: Default Configuration

    Figure 5-2. PrintBox Widget: No Filename Entry Box

    Figure 5-2 PrintBox Widget: No Filename Entry Box

    Figure 5-3. PrintBox Widget: No Options Box

    Figure 5-3 PrintBox Widget: No Options Box

    Figure 5-4. PrintBox Widget: With a Child Process

    Figure 5-4 PrintBox Widget: With a Child Process

Compiling Programs With libprintui

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 from the PrintBox widget must also include /usr/include/Sgm/PrintBoxP.h.

Library Functions Listed by Purpose

The libprintui functions are listed in Table 5-2. The PuiPrintBox(3X) reference pages provide detailed information on the PrintBox widget.

Table 5-2. Summary of libprintui Functions




Widget Instantiation



Create a PrintBox widget.

Create a PrintBox dialog.

Widget Component Access


Access a PrintBox widget component.

Widget Action Functions


Invoke PrintBox printing.

Example Program

The example program, printbox, instantiates a simple 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, enter:


Initial Program Processing

The printbox program begins by setting the program instance name and initializing an X Window System connection. Next, the program creates the PrintBox widget with a call to the libprintui library function PuiCreatePrintBox() and adds the widget to the parent's managed set.

Add Callbacks

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)

Realize All Widgets

A call to XtRealizeWidget() now realizes (creates a window for) the parent widget, created by the earlier call to PuiCreatePrintBox(), and all child widgets.

Process Events

The program now begins an event loop. It obtains the next event from the X event queue and dispatches the event. If an early error has occurred, the error is handled and the loop continues until the application exits.

Additional Examples

Refer to the directory /usr/impressario/src/examples/libprintui for additional sample program source code.

The libpod Library

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 driver 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.

POD Files

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.


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 the POD files is /var/spool/lp/pod. If the POD files are to be located in a directory other than the default, set PDpod_path to the path name of the new location. PDpod_path is declared in the header file pod.h.[2]

See Appendix C, “Printer Object Database (POD) File Formats,” for detailed information on libpod file formats.

Standard and Local libpod Functions

The print server is the system that controls the printer. The POD files reside on the print server. To provide POD information to a system other than the print server, that is, to a print client, libpod must be able to communicate across the network. For any specified printer, the “standard” libpod functions automatically determine whether the user's system is the print server or a print client. After determining which system is the print server, the standard libpod functions are able to access the POD files on that system. Because they typically run on print clients, user application programs such as printer status tools use the standard form of the libpod functions.

To avoid the overhead that network communication entails, libpod also provides “local” functions. These functions, such as PDLocalReadInfo() and PDLocalWriteStatus(), contain the word “Local” in their names and use the POD files on the system on which they are running, that is, the local system. Because they have no networking overhead, their use reduces the size and overhead of the resulting executable files. They are intended for programs, such as printer drivers, that are used only on print servers.

Functions that write to POD files are available only in the local form. Only printer drivers write to POD files and these drivers always run locally on print servers, never remotely on print clients. Thus, there is no need to provide standard libpod functions that write to POD files.

Compiling Programs With libpod

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 using the standard functions is

cc -o myprog myprog.c -lpod -lspool 

The compile line for using the local functions is

cc -o myprog myprog.c -lpod 

Debugging With libpod

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.

Network Communications

To provide remote printer POD information, libpod communicates over the network with the podd 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 with the function returning 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 contained in the header file pod.h. The time-out period for reading printer status is usually much larger than that for browsing printer configurations. For more specific information on the daemon, refer to the podd(1M) reference page.

Library Functions Listed by Purpose

The libpod functions are listed in Table 5-3. Note that a number of libpod functions have only a single version, which is used for both standard and local cases.

Table 5-3. Summary of libpod Functions


Standard Function

Local Function

Detailed Information Retrieval



Status File Manipulation




Log File Manipulation



Convenience Functions








Execution Error Handling





[2] The maximum string length for PDpod_path is PD_STR_MAX. This length includes the terminating NULL character.