]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/api-filter.shtml
Load cups into easysw/current.
[thirdparty/cups.git] / cups / api-filter.shtml
1 <!--
2 "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
3
4 Filter and backend API introduction for the Common UNIX Printing System (CUPS).
5
6 Copyright 2007 by Apple Inc.
7 Copyright 1997-2006 by Easy Software Products, all rights reserved.
8
9 These coded instructions, statements, and computer programs are the
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/".
14 -->
15
16 <h2 class='title'>Introduction</h2>
17
18 <p>The CUPS filter and backend APIs define standard exit codes
19 and provide access to the backchannel data stream. They are only
20 used when writing backends, filters, and port monitors.</p>
21
22 <h2 class='title'>General Usage</h2>
23
24 <p>The <var>&lt;cups/backend.h&gt;</var> and
25 <var>&lt;cups/cups.h&gt;</var> header files must be included to
26 use the <tt>CUPS_BACKEND_</tt> constants and
27 <tt>cupsBackChannel</tt> functions, respectively.</p>
28
29 <p>The <var>&lt;cups/sidechannel.h&gt;</var> header file must be
30 included to use the <tt>CUPS_SC_</tt> constants and <tt>cupsSideChannel</tt> functions.</p>
31
32 <p>Programs using these functions must be linked to the CUPS
33 library: <var>libcups.a</var>, <var>libcups.so.2</var>,
34 <var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
35 <var>libcups2.lib</var> depending on the platform. The following
36 command compiles <var>myprogram.c</var> using GCC and the CUPS
37 library:</p>
38
39 <pre class='command'>
40 <kbd>gcc -o myprogram myprogram.c -lcups</kbd>
41 </pre>
42
43
44 <h2 class='title'>Compatibility</h2>
45
46 <p>The <tt>cupsBackChannel</tt> functions require CUPS 1.2 or higher. The <tt>cupsSideChannel</tt> functions require CUPS 1.3 or higher.</p>
47
48
49 <h2 class='title'>Using the cupsBackChannel APIs</h2>
50
51 <p>The <tt>cupsBackChannel</tt> APIs allow your filters, drivers, and port monitors to read data back from a printer and your backends to send data from a printer to the filters, drivers, and port monitors associated with the current job. Back-channel data is normally sent by the printer in response to a command sent from your program to the printer via <tt>stdout</tt>.</p>
52
53 <p>The <tt>cupsBackChannelRead()</tt> function reads data from the printer via the backend. You provide a timeout in seconds along with a buffer pointer and the size of that buffer. It returns the number of bytes or -1 if there was an error. The following code example shows how to poll for back-channel data in your program:</p>
54
55 <pre class='command'>
56 #include &lt;cups/cups.h&gt;
57
58 char buffer[8192];
59 ssize_t bytes;
60
61 /* Use a timeout of 0.0 seconds to poll for back-channel data */
62 bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
63 </pre>
64
65 <p>If you are writing a backend, the <tt>cupsBackChannelWrite()</tt> function sends any back-channel data you have received from the printer to upstream filters in the print filter chain. We recommend using a timeout of 1.0 seconds:</p>
66
67 <pre class='command'>
68 #include &lt;cups/cups.h&gt;
69
70 char buffer[8192];
71 ssize_t bytes;
72
73 /* Use a timeout of 1.0 seconds to give filters a chance to read */
74 cupsBackChannelWrite(buffer, bytes, 1.0);
75 </pre>
76
77
78 <h2 class='title'>Using the cupsSideChannel APIs</h2>
79
80 <p>The <tt>cupsSideChannel</tt> APIs allow your filters, drivers, port monitors, and backend to send and receive the following out-of-band commands:</p>
81
82 <ul>
83
84 <li><tt>CUPS_SC_CMD_SOFT_RESET</tt> - Do a soft reset</li>
85 <li><tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> - Drain all pending output</li>
86 <li><tt>CUPS_SC_CMD_GET_BIDI</tt> - Return bidirectional capabilities</li>
87 <li><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> - Return the IEEE-1284 device ID</li>
88 <li><tt>CUPS_SC_CMD_GET_STATE</tt> - Return the device state</li>
89
90 </ul>
91
92
93 <h3>Sending Commands from a Filter, Driver, or Port Monitor</h3>
94
95 <p>The <tt>cupsSideChannelDoRequest()</tt> function is used by filters, drivers, and port monitors to send a command to the backend and read back a response:</p>
96
97 <pre class='command'>
98 cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
99 char *data, int *datalen,
100 double timeout);
101 </pre>
102
103 <p>The <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> commands do not return any data values, while the others return one or more bytes. The <tt>timeout</tt> parameter allows your program to poll or wait for the command to complete - use a timeout of 30 seconds for <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> and a timeout of 1 second for all other commands.</p>
104
105 <p><tt>CUPS_SC_CMD_GET_BIDI</tt> returns a single <tt>char</tt> value that tells you whether the backend supports bidirectional communications:</p>
106
107 <pre class='command'>
108 #include &lt;cups/sidechannel.h&gt;
109
110 char data;
111 int datalen;
112 cups_sc_bidi_t bidi;
113 cups_sc_status_t status;
114
115 /* Tell cupsSideChannelDoRequest() how big our buffer is... */
116 datalen = 1;
117
118 /* Get the bidirectional capabilities, waiting for up to 1 second */
119 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &amp;data, &amp;datalen, 1.0);
120
121 /* Use the returned value if OK was returned and the length is still 1 */
122 if (status == CUPS_SC_STATUS_OK && datalen == 1)
123 bidi = (cups_sc_bidi_t)data;
124 else
125 bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
126 </pre>
127
128 <p><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> returns a string of characters containing the IEEE-1284 device ID for the connected printer:</p>
129
130 <pre class='command'>
131 #include &lt;cups/sidechannel.h&gt;
132
133 char data[2049];
134 int datalen;
135 cups_sc_status_t status;
136
137 /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
138 datalen = sizeof(data) - 1;
139
140 /* Get the IEEE-1284 device ID, waiting for up to 1 second */
141 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
142
143 /* Use the returned value if OK was returned and the length is non-zero */
144 if (status == CUPS_SC_STATUS_OK && datalen > 0)
145 data[datalen] = '\0';
146 else
147 data[0] = '\0';
148 </pre>
149
150 <p><tt>CUPS_SC_CMD_GET_STATE</tt> returns a single <tt>char</tt> value that tells you the current device state:</p>
151
152 <pre class='command'>
153 #include &lt;cups/sidechannel.h&gt;
154
155 char data;
156 int datalen;
157 cups_sc_state_t state;
158 cups_sc_status_t status;
159
160 /* Tell cupsSideChannelDoRequest() how big our buffer is... */
161 datalen = 1;
162
163 /* Get the bidirectional capabilities, waiting for up to 1 second */
164 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &amp;data, &amp;datalen, 1.0);
165
166 /* Use the returned value if OK was returned and the length is still 1 */
167 if (status == CUPS_SC_STATUS_OK && datalen == 1)
168 state = (cups_sc_state_t)data;
169 else
170 state = CUPS_SC_STATE_OFFLINE;
171 </pre>
172
173
174 <h3>Handling Commands in your Backend</h3>
175
176 <p>The <tt>cupsSideChannelRead()</tt> function is used by backends to read a command from a filter, driver, or port monitor:</p>
177
178 <pre class='command'>
179 int cupsSideChannelRead(cups_sc_command_t &amp;command,
180 cups_sc_status_t &amp;status,
181 char *data, int *datalen, double timeout);
182 </pre>
183
184 <p>Backends can either poll for commands using a <tt>timeout</tt> of 0.0, wait indefinitely for commands using a <tt>timeout</tt> of -1.0 (probably in a separate thread for that purpose), or use <tt>select()</tt> or <tt>poll()</tt> on the <tt>CUPS_SC_FD</tt> file descriptor (4) to handle input and output on several file descriptors at the same time. Backends can pass <tt>NULL</tt> for the <tt>data</tt> and <tt>datalen</tt> parameters, since none of the commands sent by upstream filters contain any data at this time.</p>
185
186 <p>Once a command is processed, the backend uses the <tt>cupsSideChannelWrite()</tt> function to send its response:</p>
187
188 <pre class='command'>
189 #include &lt;cups/sidechannel.h&gt;
190
191 cups_sc_command_t command;
192 cups_sc_status_t status;
193
194 /* Poll for a command... */
195 if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
196 {
197 char data[2048];
198 int datalen;
199
200 switch (command)
201 {
202 ... handle supported commands, file data/datalen/status with values as needed ...
203
204 default :
205 status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
206 datalen = 0;
207 break;
208 }
209
210 /* Send a response... */
211 cupsSideChannelWrite(command, status, data, datalen, 1.0);
212 }
213 </pre>