The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the CUPS API documentation. These functions will be removed in a future release of CUPS.
The CUPS PPD API provides read-only access the data in PostScript Printer
Description ("PPD") files which are used for all printers with a driver. With
it you can obtain the data necessary to display printer options to users, mark
option choices and check for conflicting choices, and output marked choices in
PostScript output. The ppd_file_t
structure contains all of the information in a PPD file.
Note:The CUPS PPD API uses the terms "option" and "choice" instead of the Adobe terms "MainKeyword" and "OptionKeyword" to refer to specific printer options and features. CUPS also treats option ("MainKeyword") and choice ("OptionKeyword") values as case-insensitive strings, so option "InputSlot" and choice "Upper" are equivalent to "inputslot" and "upper", respectively.
The ppdOpenFile
function "opens" a
PPD file and loads it into memory. For example, the following code opens the
current printer's PPD file in a CUPS filter:
#include <cups/ppd.h> ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
The return value is a pointer to a new
ppd_file_t
structure or NULL
if the PPD file does not exist or cannot be loaded. The
ppdClose
function frees the memory used
by the structure:
#include <cups/ppd.h> ppd_file_t *ppd; ppdClose(ppd);
Once closed, pointers to the ppd_file_t
structure and any data in it will no longer be valid.
PPD files support multiple options, which are stored in arrays of
ppd_option_t
and
ppd_choice_t
structures.
Each option in turn is associated with a group stored in a
ppd_group_t
structure. Groups can be
specified in the PPD file; if an option is not associated with a group
then it is put in an automatically-generated "General" group. Groups can also
have sub-groups, however CUPS currently ignores sub-groups because of past
abuses of this functionality.
Option choices are selected by marking them using one of three functions. The
first is ppdMarkDefaults
which
selects all of the default options in the PPD file:
#include <cups/ppd.h> ppd_file_t *ppd; ppdMarkDefaults(ppd);
The second is ppdMarkOption
which selects a single option choice in the PPD file. For example, the following
code selects the upper paper tray:
#include <cups/ppd.h> ppd_file_t *ppd; ppdMarkOption(ppd, "InputSlot", "Upper");
The last function is
cupsMarkOptions
which selects
multiple option choices in the PPD file from an array of CUPS options, mapping
IPP attributes like "media" and "sides" to their corresponding PPD options. You
typically use this function in a print filter with
cupsParseOptions
and
ppdMarkDefaults
to select all of
the option choices needed for the job, for example:
#include <cups/ppd.h> ppd_file_t *ppd = ppdOpenFile(getenv("PPD")); cups_option_t *options = NULL; int num_options = cupsParseOptions(argv[5], 0, &options); ppdMarkDefaults(ppd); cupsMarkOptions(ppd, num_options, options); cupsFreeOptions(num_options, options);
PPD files support specification of conflict conditions, called
constraints, between different options. Constraints are stored in an array of
ppd_const_t
structures which specify
the options and choices that conflict with each other. The
ppdConflicts
function tells you
how many of the selected options are incompatible. Since constraints are
normally specified in pairs, the returned value is typically an even number.
Page sizes are special options which have physical dimensions and margins
associated with them. The size information is stored in
ppd_size_t
structures and is available
by looking up the named size with the
ppdPageSize
function. The page size and
margins are returned in units called points; there are 72 points per inch. If
you pass NULL
for the size, the currently selected size is
returned:
#include <cups/ppd.h> ppd_file_t *ppd; ppd_size_t *size = ppdPageSize(ppd, NULL);
Besides the standard page sizes listed in a PPD file, some printers
support variable or custom page sizes. Custom page sizes are supported if the
variables_sizes
member of the
ppd_file_t
structure is non-zero.
The custom_min
, custom_max
, and
custom_margins
members of the
ppd_file_t
structure define the limits
of the printable area. To get the resulting media size, use a page size string
of the form "Custom.widthxlength", where "width" and "length" are
in points. Custom page size names can also be specified in inches
("Custom.widthxheightin"), centimeters
("Custom.widthxheightcm"), or millimeters
("Custom.widthxheightmm"):
#include <cups/ppd.h> ppd_file_t *ppd; /* Get an 576x720 point custom page size */ ppd_size_t *size = ppdPageSize(ppd, "Custom.576x720"); /* Get an 8x10 inch custom page size */ ppd_size_t *size = ppdPageSize(ppd, "Custom.8x10in"); /* Get a 100x200 millimeter custom page size */ ppd_size_t *size = ppdPageSize(ppd, "Custom.100x200mm"); /* Get a 12.7x34.5 centimeter custom page size */ ppd_size_t *size = ppdPageSize(ppd, "Custom.12.7x34.5cm");
If the PPD does not support variable page sizes, the
ppdPageSize
function will return
NULL
.
Every PPD file is composed of one or more attributes. Most of these attributes are used to define groups, options, choices, and page sizes, however several informational attributes may be present which you can access in your program or filter. Attributes normally look like one of the following examples in a PPD file:
*name: "value" *name spec: "value" *name spec/text: "value"
The ppdFindAttr
and
ppdFindNextAttr
functions find the
first and next instances, respectively, of the named attribute with the given
"spec" string and return a ppd_attr_t
structure. If you provide a NULL specifier string, all attributes with the
given name will be returned. For example, the following code lists all of the
Product
attributes in a PPD file:
#include <cups/ppd.h> ppd_file_t *ppd; ppd_attr_t *attr; for (attr = ppdFindAttr(ppd, "Product", NULL); attr != NULL; attr = ppdFindNextAttr(ppd, "Product", NULL)) puts(attr->value);