]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/api-filter.shtml
Merge changes from CUPS 1.4svn-r7282.
[thirdparty/cups.git] / cups / api-filter.shtml
CommitLineData
ef416fc2 1<!--
bc44d920 2 "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
ef416fc2 3
5a738aea
MS
4 Filter and backend programming introduction for the Common UNIX Printing
5 System (CUPS).
ef416fc2 6
5a738aea 7 Copyright 2007-2008 by Apple Inc.
bc44d920 8 Copyright 1997-2006 by Easy Software Products, all rights reserved.
ef416fc2 9
10 These coded instructions, statements, and computer programs are the
bc44d920 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/".
ef416fc2 15-->
16
5a738aea 17<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
ef416fc2 18
5a738aea
MS
19<p>Filters, printer drivers, port monitors, and backends use a common interface
20for processing print jobs and communicating status information to the scheduler.
21Each filter is run with a standard set of command-line arguments:<p>
ef416fc2 22
5a738aea 23<dl class="code">
ef416fc2 24
5a738aea
MS
25 <dt>argv[1]</dt>
26 <dd>The job ID</dd>
ef416fc2 27
5a738aea
MS
28 <dt>argv[2]</dt>
29 <dd>The user printing the job</dd>
f7deaa1a 30
5a738aea
MS
31 <dt>argv[3]</dt>
32 <dd>The job name/title</dd>
ef416fc2 33
5a738aea
MS
34 <dt>argv[4]</dt>
35 <dd>The number of copies to print</dd>
ef416fc2 36
5a738aea
MS
37 <dt>argv[5]</dt>
38 <dd>The options that were provided when the job was submitted</dd>
f7deaa1a 39
5a738aea
MS
40 <dt>argv[6]</dt>
41 <dd>The file to print (first filter only)</dd>
42</dl>
ef416fc2 43
5a738aea
MS
44<p>The scheduler runs one or more of these programs to print any given job. The
45first filter reads from the print file and writes to the standard output, while
46the remaining filters read from the standard input and write to the standard
47output. The backend is the last filter in the chain and writes to the
48device.</p>
f7deaa1a 49
5a738aea 50<h3><a name="EXITCODES">Exit Codes</a></h3>
f7deaa1a 51
5a738aea
MS
52<p>Filters must exit with status 0 when they successfully generate print data
53or 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>
f7deaa1a 55
5a738aea 56<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
f7deaa1a 57
5a738aea 58<p>The following environment variables are defined by the printing system:</p>
f7deaa1a 59
5a738aea 60<dl class="code">
f7deaa1a 61
5a738aea
MS
62 <dt>APPLE_LANGUAGES</dt>
63 <dd>The Apple language identifier associated with the job
64 (Mac OS X only).</dd>
f7deaa1a 65
5a738aea
MS
66 <dt>CHARSET</dt>
67 <dd>The job character set, typically "utf-8".</dd>
f7deaa1a 68
5a738aea
MS
69 <dt>CLASS</dt>
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>
f7deaa1a 73
5a738aea
MS
74 <dt>CONTENT_TYPE</dt>
75 <dd>The MIME type associated with the file (e.g.
76 application/postscript).</dd>
f7deaa1a 77
5a738aea
MS
78 <dt>CUPS_CACHEDIR</dt>
79 <dd>The directory where cache files can be stored.</dd>
f7deaa1a 80
5a738aea
MS
81 <dt>CUPS_DATADIR</dt>
82 <dd>The directory where data files can be found.</dd>
f7deaa1a 83
5a738aea
MS
84 <dt>CUPS_SERVERROOT</dt>
85 <dd>The root directory of the server.</dd>
f7deaa1a 86
5a738aea
MS
87 <dt>DEVICE_URI</dt>
88 <dd>The device-uri associated with the printer.</dd>
f7deaa1a 89
5a738aea
MS
90 <dt>FINAL_CONTENT_TYPE</dt>
91 <dd>The MIME type associated with the printer (e.g.
92 application/vnd.cups-postscript).</dd>
f7deaa1a 93
5a738aea
MS
94 <dt>LANG</dt>
95 <dd>The language locale associated with the job.</dd>
f7deaa1a 96
5a738aea
MS
97 <dt>PPD</dt>
98 <dd>The full pathname of the PostScript Printer Description (PPD)
99 file for this printer.</dd>
f7deaa1a 100
5a738aea
MS
101 <dt>PRINTER</dt>
102 <dd>The name of the printer.</dd>
f7deaa1a 103
5a738aea
MS
104 <dt>RIP_CACHE</dt>
105 <dd>The recommended amount of memory to use for Raster Image
106 Processors (RIPs).</dd>
f7deaa1a 107
5a738aea 108</dl>
f7deaa1a 109
5a738aea 110<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
f7deaa1a 111
5a738aea
MS
112<p>Filters and backends communicate wih the scheduler by writing messages
113to the standard error file. For example, the following code sets the current
114printer state message to "Printing page 5":</p>
f7deaa1a 115
5a738aea
MS
116<pre class="example">
117int page = 5;
f7deaa1a 118
5a738aea
MS
119fprintf(stderr, "INFO: Printing page %d\n", page);
120</pre>
f7deaa1a 121
5a738aea
MS
122<p>Each message is a single line of text starting with one of the following
123prefix strings:</p>
124
125<dl class="code">
126
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>
130
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>
137
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
141 level.</dd>
142
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>
146
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>
150
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
154 level.</dd>
155
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>
159
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>
164
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>
168
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>
174
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>
181
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
185 level.</dd>
186
187</dl>
188
189<p>Messages without one of these prefixes are treated as if they began with
190the "DEBUG:" prefix string.</p>
191
192<h3><a name="COMMUNICATING">Communicating with the Backend</a></h3>
193
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>
197functions. The
198<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
199reads data that has been sent back from the device and is typically used to
200obtain status and configuration information. For example, the following code
201polls the backend for back-channel data:</p>
202
203<pre class="example">
204#include &lt;cups/cups.h&gt;
f7deaa1a 205
5a738aea
MS
206char buffer[8192];
207ssize_t bytes;
f7deaa1a 208
5a738aea
MS
209/* Use a timeout of 0.0 seconds to poll for back-channel data */
210bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
f7deaa1a 211</pre>
212
5a738aea
MS
213The
214<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
215function allows you to get out-of-band status information and do synchronization
216with the device. For example, the following code gets the current IEEE-1284
217device ID string from the backend:</p>
f7deaa1a 218
5a738aea 219<pre class="example">
f7deaa1a 220#include &lt;cups/sidechannel.h&gt;
221
222char data[2049];
223int datalen;
5a738aea 224<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
f7deaa1a 225
226/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
227datalen = sizeof(data) - 1;
228
229/* Get the IEEE-1284 device ID, waiting for up to 1 second */
5a738aea 230status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
f7deaa1a 231
232/* Use the returned value if OK was returned and the length is non-zero */
233if (status == CUPS_SC_STATUS_OK && datalen > 0)
234 data[datalen] = '\0';
235else
236 data[0] = '\0';
237</pre>
238
5a738aea
MS
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
243recommend writing back-channel data using a timeout of 1.0 seconds:</p>
f7deaa1a 244
5a738aea
MS
245<pre class="example">
246#include &lt;cups/cups.h&gt;
f7deaa1a 247
5a738aea
MS
248char buffer[8192];
249ssize_t bytes;
f7deaa1a 250
5a738aea
MS
251/* Use a timeout of 1.0 seconds to give filters a chance to read */
252cupsBackChannelWrite(buffer, bytes, 1.0);
f7deaa1a 253</pre>
254
5a738aea
MS
255<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
256function reads a side-channel command from a filter, driver, or port monitor.
257Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
258indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
259separate 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
261input 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
263since none of the commands sent by upstream filters contain any data at this
264time.</p>
265
266<p>Once a command is processed, the backend uses the
267<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
268to send its response. For example, the following code shows how to poll for a
269side-channel command and respond to it:</p>
270
271<pre class="example">
f7deaa1a 272#include &lt;cups/sidechannel.h&gt;
273
5a738aea
MS
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;
f7deaa1a 276
277/* Poll for a command... */
5a738aea 278if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, NULL, NULL, 0.0))
f7deaa1a 279{
280 char data[2048];
281 int datalen;
282
283 switch (command)
284 {
5a738aea 285 /* handle supported commands, file data/datalen/status with values as needed */
f7deaa1a 286
287 default :
288 status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
289 datalen = 0;
290 break;
291 }
292
293 /* Send a response... */
5a738aea 294 <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
f7deaa1a 295}
296</pre>