2 "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
4 Filter and backend programming introduction for the Common UNIX Printing
7 Copyright 2007-2008 by Apple Inc.
8 Copyright 1997-2006 by Easy Software Products, all rights reserved.
10 These coded instructions, statements, and computer programs are the
11 property of Apple Inc. and are protected by Federal copyright
12 law. Distribution and use rights are outlined in the file "LICENSE.txt"
13 which should have been included with this file. If this file is
14 file is missing or damaged, see the license at "http://www.cups.org/".
17 <h2 class='title'><a name="OVERVIEW">Overview</a></h2>
19 <p>Filters, printer drivers, port monitors, and backends use a common interface
20 for processing print jobs and communicating status information to the scheduler.
21 Each filter is run with a standard set of command-line arguments:<p>
29 <dd>The user printing the job</dd>
32 <dd>The job name/title</dd>
35 <dd>The number of copies to print</dd>
38 <dd>The options that were provided when the job was submitted</dd>
41 <dd>The file to print (first filter only)</dd>
44 <p>The scheduler runs one or more of these programs to print any given job. The
45 first filter reads from the print file and writes to the standard output, while
46 the remaining filters read from the standard input and write to the standard
47 output. The backend is the last filter in the chain and writes to the
50 <h3><a name="EXITCODES">Exit Codes</a></h3>
52 <p>Filters must exit with status 0 when they successfully generate print data
53 or 1 when they encounter an error. Backends can return any of the
54 <a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
56 <h3><a name="ENVIRONMENT">Environment Variables</a></h3>
58 <p>The following environment variables are defined by the printing system:</p>
62 <dt>APPLE_LANGUAGES</dt>
63 <dd>The Apple language identifier associated with the job
67 <dd>The job character set, typically "utf-8".</dd>
70 <dd>When a job is submitted to a printer class, contains the name of
71 the destination printer class. Otherwise this environment
72 variable will not be set.</dd>
75 <dd>The MIME type associated with the file (e.g.
76 application/postscript).</dd>
78 <dt>CUPS_CACHEDIR</dt>
79 <dd>The directory where cache files can be stored.</dd>
82 <dd>The directory where data files can be found.</dd>
84 <dt>CUPS_SERVERROOT</dt>
85 <dd>The root directory of the server.</dd>
88 <dd>The device-uri associated with the printer.</dd>
90 <dt>FINAL_CONTENT_TYPE</dt>
91 <dd>The MIME type associated with the printer (e.g.
92 application/vnd.cups-postscript).</dd>
95 <dd>The language locale associated with the job.</dd>
98 <dd>The full pathname of the PostScript Printer Description (PPD)
99 file for this printer.</dd>
102 <dd>The name of the printer.</dd>
105 <dd>The recommended amount of memory to use for Raster Image
106 Processors (RIPs).</dd>
110 <h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
112 <p>Filters and backends communicate wih the scheduler by writing messages
113 to the standard error file. For example, the following code sets the current
114 printer state message to "Printing page 5":</p>
116 <pre class="example">
119 fprintf(stderr, "INFO: Printing page %d\n", page);
122 <p>Each message is a single line of text starting with one of the following
127 <dt>ALERT: message</dt>
128 <dd>Sets the printer-state-message attribute and adds the specified
129 message to the current error log file using the "alert" log level.</dd>
131 <dt>ATTR: attribute=value [attribute=value]</dt>
132 <dd>Sets the named printer or job attribute(s). Typically this is used
133 to set the <code>marker-colors</code>, <code>marker-levels</code>,
134 <code>marker-names</code>, <code>marker-types</code>,
135 <code>printer-alert</code>, and <code>printer-alert-description</code>
136 printer attributes.</dd>
138 <dt>CRIT: message</dt>
139 <dd>Sets the printer-state-message attribute and adds the specified
140 message to the current error log file using the "critical" log
143 <dt>DEBUG: message</dt>
144 <dd>Sets the printer-state-message attribute and adds the specified
145 message to the current error log file using the "debug" log level.</dd>
147 <dt>DEBUG2: message</dt>
148 <dd>Sets the printer-state-message attribute and adds the specified
149 message to the current error log file using the "debug2" log level.</dd>
151 <dt>EMERG: message</dt>
152 <dd>Sets the printer-state-message attribute and adds the specified
153 message to the current error log file using the "emergency" log
156 <dt>ERROR: message</dt>
157 <dd>Sets the printer-state-message attribute and adds the specified
158 message to the current error log file using the "error" log level.</dd>
160 <dt>INFO: message</dt>
161 <dd>Sets the printer-state-message attribute. If the current log level
162 is set to "debug2", also adds the specified message to the current error
163 log file using the "info" log level.</dd>
165 <dt>NOTICE: message</dt>
166 <dd>Sets the printer-state-message attribute and adds the specified
167 message to the current error log file using the "notice" log level.</dd>
169 <dt>PAGE: page-number #-copies</dt>
170 <dt>PAGE: total #-pages</dt>
171 <dd>Adds an entry to the current page log file. The first form adds
172 #-copies to the job-media-sheets-completed attribute. The second
173 form sets the job-media-sheets-completed attribute to #-pages.</dd>
175 <dt>STATE: printer-state-reason [printer-state-reason ...]</dt>
176 <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
177 <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
178 <dd>Sets, adds, or removes printer-state-reason keywords to the
179 current queue. Typically this is used to indicate media, ink, and
180 toner conditions on a printer.</dd>
182 <dt>WARNING: message</dt>
183 <dd>Sets the printer-state-message attribute and adds the specified
184 message to the current error log file using the "warning" log
189 <p>Messages without one of these prefixes are treated as if they began with
190 the "DEBUG:" prefix string.</p>
192 <h3><a name="COMMUNICATING">Communicating with the Backend</a></h3>
194 <p>Filters can communicate with the backend via the
195 <a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
196 <a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
198 <a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
199 reads data that has been sent back from the device and is typically used to
200 obtain status and configuration information. For example, the following code
201 polls the backend for back-channel data:</p>
203 <pre class="example">
204 #include <cups/cups.h>
209 /* Use a timeout of 0.0 seconds to poll for back-channel data */
210 bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
214 <a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
215 function allows you to get out-of-band status information and do synchronization
216 with the device. For example, the following code gets the current IEEE-1284
217 device ID string from the backend:</p>
219 <pre class="example">
220 #include <cups/sidechannel.h>
224 <a href="#cups_sc_status_t">cups_sc_status_t</a> status;
226 /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
227 datalen = sizeof(data) - 1;
229 /* Get the IEEE-1284 device ID, waiting for up to 1 second */
230 status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &datalen, 1.0);
232 /* Use the returned value if OK was returned and the length is non-zero */
233 if (status == CUPS_SC_STATUS_OK && datalen > 0)
234 data[datalen] = '\0';
239 <p>Backends communicate with filters using the reciprocal functions
240 <a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
241 <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
242 <a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
243 recommend writing back-channel data using a timeout of 1.0 seconds:</p>
245 <pre class="example">
246 #include <cups/cups.h>
251 /* Use a timeout of 1.0 seconds to give filters a chance to read */
252 cupsBackChannelWrite(buffer, bytes, 1.0);
255 <p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
256 function reads a side-channel command from a filter, driver, or port monitor.
257 Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
258 indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
259 separate thread for that purpose), or use <code>select</code> or
260 <code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
261 input and output on several file descriptors at the same time. Backends can pass
262 <code>NULL</code> for the <code>data</code> and <code>datalen</code> parameters
263 since none of the commands sent by upstream filters contain any data at this
266 <p>Once a command is processed, the backend uses the
267 <a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
268 to send its response. For example, the following code shows how to poll for a
269 side-channel command and respond to it:</p>
271 <pre class="example">
272 #include <cups/sidechannel.h>
274 <a href="#cups_sc_command_t">cups_sc_command_t</a> command;
275 <a href="#cups_sc_status_t">cups_sc_status_t</a> status;
277 /* Poll for a command... */
278 if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&command, &status, NULL, NULL, 0.0))
285 /* handle supported commands, file data/datalen/status with values as needed */
288 status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
293 /* Send a response... */
294 <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);