Home | History | Annotate | Download | only in cups
      1 <!--
      2   PPD API introduction for CUPS.
      3 
      4   Copyright 2007-2012 by Apple Inc.
      5   Copyright 1997-2006 by Easy Software Products, all rights reserved.
      6 
      7   These coded instructions, statements, and computer programs are the
      8   property of Apple Inc. and are protected by Federal copyright
      9   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
     10   which should have been included with this file.  If this file is
     11   file is missing or damaged, see the license at "http://www.cups.org/".
     12 -->
     13 
     14 <h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
     15 
     16 <blockquote>The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the <a href="api-cups.html">CUPS API</a> documentation. These functions will be removed in a future release of CUPS.</blockquote>
     17 
     18 <p>The CUPS PPD API provides read-only access the data in PostScript Printer
     19 Description ("PPD") files which are used for all printers with a driver. With
     20 it you can obtain the data necessary to display printer options to users, mark
     21 option choices and check for conflicting choices, and output marked choices in
     22 PostScript output. The <a href="#ppd_file_t"><code>ppd_file_t</code></a>
     23 structure contains all of the information in a PPD file.</p>
     24 
     25 <blockquote><b>Note:</b>
     26 
     27 <p>The CUPS PPD API uses the terms "option" and "choice" instead of the Adobe
     28 terms "MainKeyword" and "OptionKeyword" to refer to specific printer options and
     29 features. CUPS also treats option ("MainKeyword") and choice ("OptionKeyword")
     30 values as case-insensitive strings, so option "InputSlot" and choice "Upper"
     31 are equivalent to "inputslot" and "upper", respectively.</p>
     32 </blockquote>
     33 
     34 <h3><a name="LOADING">Loading a PPD File</a></h3>
     35 
     36 <p>The <a href="#ppdOpenFile"><code>ppdOpenFile</code></a> function "opens" a
     37 PPD file and loads it into memory. For example, the following code opens the
     38 current printer's PPD file in a CUPS filter:</p>
     39 
     40 <pre class="example">
     41 #include &lt;cups/ppd.h&gt;
     42 
     43 <a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
     44 </pre>
     45 
     46 <p>The return value is a pointer to a new
     47 <a href="#ppd_file_t"><code>ppd_file_t</code></a> structure or <code>NULL</code>
     48 if the PPD file does not exist or cannot be loaded. The
     49 <a href="#ppdClose"><code>ppdClose</code></a> function frees the memory used
     50 by the structure:</p>
     51 
     52 <pre class="example">
     53 #include &lt;cups/ppd.h&gt;
     54 
     55 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
     56 
     57 <a href="#ppdClose">ppdClose</a>(ppd);
     58 </pre>
     59 
     60 <p>Once closed, pointers to the <a href="#ppd_file_t"><code>ppd_file_t</code></a>
     61 structure and any data in it will no longer be valid.</p>
     62 
     63 <h3><a name="OPTIONS_AND_GROUPS">Options and Groups</a></h3>
     64 
     65 <p>PPD files support multiple options, which are stored in arrays of
     66 <a href="#ppd_option_t"><code>ppd_option_t</code></a> and
     67 <a href="#ppd_choice_t"><code>ppd_choice_t</code></a> structures.</p>
     68 
     69 <p>Each option in turn is associated with a group stored in a
     70 <a href="#ppd_group_t"><code>ppd_group_t</code></a> structure. Groups can be
     71 specified in the PPD file; if an option is not associated with a group
     72 then it is put in an automatically-generated "General" group. Groups can also
     73 have sub-groups, however CUPS currently ignores sub-groups because of past
     74 abuses of this functionality.</p>
     75 
     76 <p>Option choices are selected by marking them using one of three functions. The
     77 first is <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> which
     78 selects all of the default options in the PPD file:</p>
     79 
     80 <pre class="example">
     81 #include &lt;cups/ppd.h&gt;
     82 
     83 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
     84 
     85 <a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
     86 </pre>
     87 
     88 <p>The second is <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>
     89 which selects a single option choice in the PPD file. For example, the following
     90 code selects the upper paper tray:</p>
     91 
     92 <pre class="example">
     93 #include &lt;cups/ppd.h&gt;
     94 
     95 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
     96 
     97 <a href="#ppdMarkOption">ppdMarkOption</a>(ppd, "InputSlot", "Upper");
     98 </pre>
     99 
    100 <p>The last function is
    101 <a href="#cupsMarkOptions"><code>cupsMarkOptions</code></a> which selects
    102 multiple option choices in the PPD file from an array of CUPS options, mapping
    103 IPP attributes like "media" and "sides" to their corresponding PPD options. You
    104 typically use this function in a print filter with
    105 <code>cupsParseOptions</code> and
    106 <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> to select all of
    107 the option choices needed for the job, for example:</p>
    108 
    109 <pre class="example">
    110 #include &lt;cups/ppd.h&gt;
    111 
    112 <a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
    113 cups_option_t *options = NULL;
    114 int num_options = cupsParseOptions(argv[5], 0, &amp;options);
    115 
    116 <a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
    117 <a href="#cupsMarkOptions">cupsMarkOptions</a>(ppd, num_options, options);
    118 cupsFreeOptions(num_options, options);
    119 </pre>
    120 
    121 <h3><a name="CONSTRAINTS">Constraints</a></h3>
    122 
    123 <p>PPD files support specification of conflict conditions, called
    124 constraints, between different options. Constraints are stored in an array of
    125 <a href="#ppd_const_t"><code>ppd_const_t</code></a> structures which specify
    126 the options and choices that conflict with each other. The
    127 <a href="#ppdConflicts"><code>ppdConflicts</code></a> function tells you
    128 how many of the selected options are incompatible. Since constraints are
    129 normally specified in pairs, the returned value is typically an even number.</p>
    130 
    131 <h3><a name="PAGE_SIZES">Page Sizes</a></h3>
    132 
    133 <p>Page sizes are special options which have physical dimensions and margins
    134 associated with them. The size information is stored in
    135 <a href="#ppd_size_t"><code>ppd_size_t</code></a> structures and is available
    136 by looking up the named size with the
    137 <a href="#ppdPageSize"><code>ppdPageSize</code></a> function. The page size and
    138 margins are returned in units called points; there are 72 points per inch. If
    139 you pass <code>NULL</code> for the size, the currently selected size is
    140 returned:</p>
    141 
    142 <pre class="example">
    143 #include &lt;cups/ppd.h&gt;
    144 
    145 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
    146 <a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, NULL);
    147 </pre>
    148 
    149 <p>Besides the standard page sizes listed in a PPD file, some printers
    150 support variable or custom page sizes. Custom page sizes are supported if the
    151 <code>variables_sizes</code> member of the
    152 <a href="#ppd_file_t"><code>ppd_file_t</code></a> structure is non-zero.
    153 The <code>custom_min</code>, <code>custom_max</code>, and
    154 <code>custom_margins</code> members of the
    155 <a href="#ppd_file_t"><code>ppd_file_t</code></a> structure define the limits
    156 of the printable area. To get the resulting media size, use a page size string
    157 of the form "Custom.<I>width</I>x<I>length</I>", where "width" and "length" are
    158 in points. Custom page size names can also be specified in inches
    159 ("Custom.<i>width</i>x<i>height</i>in"), centimeters
    160 ("Custom.<i>width</i>x<i>height</i>cm"), or millimeters
    161 ("Custom.<i>width</i>x<i>height</i>mm"):</p>
    162 
    163 <pre class="example">
    164 #include &lt;cups/ppd.h&gt;
    165 
    166 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
    167 
    168 /* Get an 576x720 point custom page size */
    169 <a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.576x720");
    170 
    171 /* Get an 8x10 inch custom page size */
    172 <a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.8x10in");
    173 
    174 /* Get a 100x200 millimeter custom page size */
    175 <a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.100x200mm");
    176 
    177 /* Get a 12.7x34.5 centimeter custom page size */
    178 <a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.12.7x34.5cm");
    179 </pre>
    180 
    181 <p>If the PPD does not support variable page sizes, the
    182 <a href="#ppdPageSize"><code>ppdPageSize</code></a> function will return
    183 <code>NULL</code>.</p>
    184 
    185 <h3><a name="ATTRIBUTES">Attributes</a></h3>
    186 
    187 <p>Every PPD file is composed of one or more attributes. Most of these
    188 attributes are used to define groups, options, choices, and page sizes,
    189 however several informational attributes may be present which you can access
    190 in your program or filter. Attributes normally look like one of the following
    191 examples in a PPD file:</p>
    192 
    193 <pre class="example">
    194 *name: "value"
    195 *name spec: "value"
    196 *name spec/text: "value"
    197 </pre>
    198 
    199 <p>The <a href="#ppdFindAttr"><code>ppdFindAttr</code></a> and
    200 <a href="#ppdFindNextAttr"><code>ppdFindNextAttr</code></a> functions find the
    201 first and next instances, respectively, of the named attribute with the given
    202 "spec" string and return a <a href="#ppd_attr_t"><code>ppd_attr_t</code></a>
    203 structure. If you provide a NULL specifier string, all attributes with the
    204 given name will be returned. For example, the following code lists all of the
    205 <code>Product</code> attributes in a PPD file:</p>
    206 
    207 <pre class="example">
    208 #include &lt;cups/ppd.h&gt;
    209 
    210 <a href="#ppd_file_t">ppd_file_t</a> *ppd;
    211 <a href="#ppd_attr_t">ppd_attr_t</a> *attr;
    212 
    213 for (attr = <a href="#ppdFindAttr">ppdFindAttr</a>(ppd, "Product", NULL);
    214      attr != NULL;
    215      attr = <a href="#ppdFindNextAttr">ppdFindNextAttr</a>(ppd, "Product", NULL))
    216   puts(attr->value);
    217 </pre>
    218