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