Chapter 5. Printing Libraries
Prev |  | Next

## 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:

- “The libspool Library” is a C application program interface (API) to the UNIX printer spooling systems.

- “The libprintui Library” is a C-language API to the PrintBox, a widget 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

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

Task | Function Name | Purpose
--- | --- | ---
Spooling System Selection | SLSetSpooler() SLGetSpooler() | Set the default spooling system. Get the default spooling system and available systems.
Printer Information | SLGetPrinterList() SLGetPrinterInfo() SLGetDefPrinterName() SLGetPrinterSettings() | 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 | SLSysVGetSpoolerOptions() SLSysVGetPrinterOptions() SLSysVSaveSpoolerOptions() SLSysVSavePrinterOptions() | Get System V spooler options. Get System V printer options. Save System V spooler options. Save System V printer options.
Print Job Submission | SLSubmitJob() SLSubmitJobFd() SLSubmitJobBuf() SLSubmitJobSimple() | 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 | SLCancelJob() | Cancel a queued printer job.
Printer Queue Information | SLGetQueue() | Report the printer queue contents.
Printer Queue Control | SLSetSpoolerState() SLGetSpoolerState() | Set the spooling system printing and queueing state. Get the spooling system printing and queueing state.
Execution Error Handling | SLPerror() SLErrorString() SLGetSpoolerError() | 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:

  Print |  | 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, 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-2. PrintBox Widget: No Filename Entry Box

  Figure 5-3. PrintBox Widget: No Options Box

  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

Task | Function | Purpose
--- | --- | ---
Widget Instantiation | PuiCreatePrintBox() PuiCreatePrintDialog() | Create a PrintBox widget. Create a PrintBox dialog.
Widget Component Access | PuiPrintBoxGetChild() | Access a PrintBox widget component.
Widget Action Functions | PuiPrintBoxDoPrint() | 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:

    printbox

#### 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:

[printer_name]`.config` | 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.
[printer_name]`.status` | 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 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

Task | Standard Function | Local Function
--- | --- | ---
Detailed Information Retrieval | PDReadInfo() | PDLocalReadInfo() PDLocalWriteInfo()
Status File Manipulation | PDReadStatus() PDReadOpStatus() | PDLocalReadStatus() PDLocalWriteStatus() PDLocalReadOpStatus()
Log File Manipulation | PDReadLog() | PDLocalReadLog() PDLocalWriteLog()
Convenience Functions | PDMakeMessage() PDFindPageSize() PDGetSizeCodeByName() PDGetNameBySizeCode() PDGetCurrentResolution() | n/a n/a n/a n/a n/a n/a
Execution Error Handling | PDError() PDErrorString() | n/a n/a

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

Prev | Table of Contents | Next
Chapter 4. Printer Graphical Options Panel |  | Chapter 6. Scanner Drivers