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