]> 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 6170 2007-01-02 17:26:41Z mike $"
3
4 Filter and backend API introduction for the Common UNIX Printing System (CUPS).
5
6 Copyright 1997-2006 by Easy Software Products.
7
8 These coded instructions, statements, and computer programs are the
9 property of Easy Software Products and are protected by Federal
10 copyright law. Distribution and use rights are outlined in the file
11 "LICENSE.txt" which should have been included with this file. If this
12 file is missing or damaged please contact Easy Software Products
13 at:
14
15 Attn: CUPS Licensing Information
16 Easy Software Products
17 44141 Airport View Drive, Suite 204
18 Hollywood, Maryland 20636 USA
19
20 Voice: (301) 373-9600
21 EMail: cups-info@cups.org
22 WWW: http://www.cups.org
23 -->
24
25 <h2 class='title'>Introduction</h2>
26
27 <p>The CUPS filter and backend APIs define standard exit codes
28 and provide access to the backchannel data stream. They are only
29 used when writing backends, filters, and port monitors.</p>
30
31 <h2 class='title'>General Usage</h2>
32
33 <p>The <var>&lt;cups/backend.h&gt;</var> and
34 <var>&lt;cups/cups.h&gt;</var> header files must be included to
35 use the <tt>CUPS_BACKEND_</tt> constants and
36 <tt>cupsBackChannel</tt> functions, respectively.</p>
37
38 <p>The <var>&lt;cups/sidechannel.h&gt;</var> header file must be
39 included to use the <tt>CUPS_SC_</tt> constants and <tt>cupsSideChannel</tt> functions.</p>
40
41 <p>Programs using these functions must be linked to the CUPS
42 library: <var>libcups.a</var>, <var>libcups.so.2</var>,
43 <var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
44 <var>libcups2.lib</var> depending on the platform. The following
45 command compiles <var>myprogram.c</var> using GCC and the CUPS
46 library:</p>
47
48 <pre class='command'>
49 <kbd>gcc -o myprogram myprogram.c -lcups</kbd>
50 </pre>
51
52
53 <h2 class='title'>Compatibility</h2>
54
55 <p>The <tt>cupsBackChannel</tt> functions require CUPS 1.2 or higher. The <tt>cupsSideChannel</tt> functions require CUPS 1.3 or higher.</p>
56
57
58 <h2 class='title'>Using the cupsBackChannel APIs</h2>
59
60 <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>
61
62 <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>
63
64 <pre class='command'>
65 #include &lt;cups/cups.h&gt;
66
67 char buffer[8192];
68 ssize_t bytes;
69
70 /* Use a timeout of 0.0 seconds to poll for back-channel data */
71 bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
72 </pre>
73
74 <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>
75
76 <pre class='command'>
77 #include &lt;cups/cups.h&gt;
78
79 char buffer[8192];
80 ssize_t bytes;
81
82 /* Use a timeout of 1.0 seconds to give filters a chance to read */
83 cupsBackChannelWrite(buffer, bytes, 1.0);
84 </pre>
85
86
87 <h2 class='title'>Using the cupsSideChannel APIs</h2>
88
89 <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>
90
91 <ul>
92
93 <li><tt>CUPS_SC_CMD_SOFT_RESET</tt> - Do a soft reset</li>
94 <li><tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> - Drain all pending output</li>
95 <li><tt>CUPS_SC_CMD_GET_BIDI</tt> - Return bidirectional capabilities</li>
96 <li><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> - Return the IEEE-1284 device ID</li>
97 <li><tt>CUPS_SC_CMD_GET_STATE</tt> - Return the device state</li>
98
99 </ul>
100
101
102 <h3>Sending Commands from a Filter, Driver, or Port Monitor</h3>
103
104 <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>
105
106 <pre class='command'>
107 cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
108 char *data, int *datalen,
109 double timeout);
110 </pre>
111
112 <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>
113
114 <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>
115
116 <pre class='command'>
117 #include &lt;cups/sidechannel.h&gt;
118
119 char data;
120 int datalen;
121 cups_sc_bidi_t bidi;
122 cups_sc_status_t status;
123
124 /* Tell cupsSideChannelDoRequest() how big our buffer is... */
125 datalen = 1;
126
127 /* Get the bidirectional capabilities, waiting for up to 1 second */
128 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &amp;data, &amp;datalen, 1.0);
129
130 /* Use the returned value if OK was returned and the length is still 1 */
131 if (status == CUPS_SC_STATUS_OK && datalen == 1)
132 bidi = (cups_sc_bidi_t)data;
133 else
134 bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
135 </pre>
136
137 <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>
138
139 <pre class='command'>
140 #include &lt;cups/sidechannel.h&gt;
141
142 char data[2049];
143 int datalen;
144 cups_sc_status_t status;
145
146 /* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
147 datalen = sizeof(data) - 1;
148
149 /* Get the IEEE-1284 device ID, waiting for up to 1 second */
150 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
151
152 /* Use the returned value if OK was returned and the length is non-zero */
153 if (status == CUPS_SC_STATUS_OK && datalen > 0)
154 data[datalen] = '\0';
155 else
156 data[0] = '\0';
157 </pre>
158
159 <p><tt>CUPS_SC_CMD_GET_STATE</tt> returns a single <tt>char</tt> value that tells you the current device state:</p>
160
161 <pre class='command'>
162 #include &lt;cups/sidechannel.h&gt;
163
164 char data;
165 int datalen;
166 cups_sc_state_t state;
167 cups_sc_status_t status;
168
169 /* Tell cupsSideChannelDoRequest() how big our buffer is... */
170 datalen = 1;
171
172 /* Get the bidirectional capabilities, waiting for up to 1 second */
173 status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &amp;data, &amp;datalen, 1.0);
174
175 /* Use the returned value if OK was returned and the length is still 1 */
176 if (status == CUPS_SC_STATUS_OK && datalen == 1)
177 state = (cups_sc_state_t)data;
178 else
179 state = CUPS_SC_STATE_OFFLINE;
180 </pre>
181
182
183 <h3>Handling Commands in your Backend</h3>
184
185 <p>The <tt>cupsSideChannelRead()</tt> function is used by backends to read a command from a filter, driver, or port monitor:</p>
186
187 <pre class='command'>
188 int cupsSideChannelRead(cups_sc_command_t &amp;command,
189 cups_sc_status_t &amp;status,
190 char *data, int *datalen, double timeout);
191 </pre>
192
193 <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>
194
195 <p>Once a command is processed, the backend uses the <tt>cupsSideChannelWrite()</tt> function to send its response:</p>
196
197 <pre class='command'>
198 #include &lt;cups/sidechannel.h&gt;
199
200 cups_sc_command_t command;
201 cups_sc_status_t status;
202
203 /* Poll for a command... */
204 if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
205 {
206 char data[2048];
207 int datalen;
208
209 switch (command)
210 {
211 ... handle supported commands, file data/datalen/status with values as needed ...
212
213 default :
214 status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
215 datalen = 0;
216 break;
217 }
218
219 /* Send a response... */
220 cupsSideChannelWrite(command, status, data, datalen, 1.0);
221 }
222 </pre>