]>
Commit | Line | Data |
---|---|---|
abacc52b MS |
1 | --- |
2 | title: CUPS Programming Manual | |
3 | author: Michael R Sweet | |
9c44e2cb | 4 | copyright: Copyright © 2007-2017 by Apple Inc. All Rights Reserved. |
abacc52b MS |
5 | version: 2.2.4 |
6 | ... | |
7 | ||
798d6e29 MS |
8 | > Note: This document is under active development and is incomplete, with a goal |
9 | > completing it prior to releasing CUPS 2.2.4. Please | |
10 | > [file issues on Github](https://github.com/apple/cups/issues) | |
11 | > to provide any feedback. | |
12 | ||
13 | ||
abacc52b MS |
14 | # Introduction |
15 | ||
16 | CUPS provides the "cups" library to talk to the different parts of CUPS and with | |
17 | Internet Printing Protocol (IPP) printers. The "cups" library functions are | |
18 | accessed by including the `<cups/cups.h>` header. | |
19 | ||
20 | CUPS is based on the Internet Printing Protocol ("IPP"), which allows clients | |
21 | (applications) to communicate with a server (the scheduler, printers, etc.) to | |
22 | get a list of destinations, send print jobs, and so forth. You identify which | |
23 | server you want to communicate with using a pointer to the opaque structure | |
24 | `http_t`. The `CUPS_HTTP_DEFAULT` constant can be used when you want to talk to | |
25 | the CUPS scheduler. | |
26 | ||
27 | ||
28 | ## Guidelines | |
29 | ||
30 | When writing software that uses the "cups" library: | |
31 | ||
32 | - Do not use undocumented or deprecated APIs, | |
33 | - Do not rely on pre-configured printers, | |
34 | - Do not assume that printers support specific features or formats, and | |
35 | - Do not rely on implementation details (PPDs, etc.) | |
36 | ||
37 | CUPS is designed to insulate users and developers from the implementation | |
38 | details of printers and file formats. The goal is to allow an application to | |
39 | supply a print file in a standard format with the user intent ("print four | |
40 | copies, two-sided on A4 media, and staple each copy") and have the printing | |
41 | system manage the printer communication and format conversion needed. | |
42 | ||
43 | Similarly, printer and job management applications can use standard query | |
44 | operations to obtain the status information in a common, generic form and use | |
45 | standard management operations to control the state of those printers and jobs. | |
46 | ||
47 | ||
48 | ## Terms Used in This Document | |
49 | ||
50 | A *Destination* is a printer or print queue that accepts print jobs. A | |
51 | *Print Job* is one or more documents that are processed by a destination | |
52 | using options supplied when creating the job. A *Document* is a file (JPEG | |
53 | image, PDF file, etc.) suitable for printing. An *Option* controls some aspect | |
54 | of printing, such as the media used. *Media* is the sheets or roll that is | |
55 | printed on. An *Attribute* is an option encoded for an Internet Printing | |
56 | Protocol (IPP) request. | |
57 | ||
58 | ||
59 | ## Compiling Programs That Use the CUPS API | |
60 | ||
61 | The CUPS libraries can be used from any C, C++, or Objective C program. | |
62 | The method of compiling against the libraries varies depending on the | |
63 | operating system and installation of CUPS. The following sections show how | |
64 | to compile a simple program (shown below) in two common environments. | |
65 | ||
66 | The following simple program lists the available destinations: | |
67 | ||
68 | #include <stdio.h> | |
69 | #include <cups/cups.h> | |
70 | ||
71 | int print_dest(void *user_data, unsigned flags, cups_dest_t *dest) | |
72 | { | |
73 | if (dest->instance) | |
74 | printf("%s/%s\n", dest->name, dest->instance); | |
75 | else | |
76 | puts(dest->name); | |
77 | ||
78 | return (1); | |
79 | } | |
80 | ||
81 | int main(void) | |
82 | { | |
83 | cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0, print_dest, NULL); | |
84 | ||
85 | return (0); | |
86 | } | |
87 | ||
88 | ||
89 | ### Compiling with Xcode | |
90 | ||
91 | In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N), | |
92 | then select the *Command Line Tool* under the macOS Application project type. | |
93 | Click *Next* and enter a name for the project, for example "firstcups". Click | |
94 | *Next* and choose a project directory. The click *Next* to create the project. | |
95 | ||
96 | In the project window, click on the *Build Phases* group and expand the | |
97 | *Link Binary with Libraries* section. Click *+*, type "libcups" to show the | |
98 | library, and then double-click on `libcups.tbd`. | |
99 | ||
100 | Finally, click on the `main.c` file in the sidebar and copy the example program | |
101 | to the file. Build and run (CMD+R) to see the list of destinations. | |
102 | ||
103 | ||
104 | ### Compiling with GCC | |
105 | ||
106 | From the command-line, create a file called `sample.c` using your favorite | |
107 | editor, copy the example to this file, and save. Then run the following command | |
108 | to compile it with GCC and run it: | |
109 | ||
110 | gcc -o simple `cups-config --cflags` simple.c `cups-config --libs` | |
111 | ./simple | |
112 | ||
113 | The `cups-config` command provides the compiler flags (`cups-config --cflags`) | |
114 | and libraries (`cups-config --libs`) needed for the local system. | |
115 | ||
116 | ||
117 | # Working with Destinations | |
118 | ||
798d6e29 | 119 | Destinations, which in CUPS represent individual printers or classes |
9c44e2cb MS |
120 | (collections or pools) of printers, are represented by the `cups_dest_t` |
121 | structure which includes the name \(`name`), instance \(`instance`, saved | |
122 | options/settings), whether the destination is the default for the user | |
123 | \(`is_default`), and the options and basic information associated with that | |
124 | destination \(`num_options` and `options`). | |
abacc52b | 125 | |
798d6e29 MS |
126 | Historically destinations have been manually maintained by the administrator of |
127 | a system or network, but CUPS also supports dynamic discovery of destinations on | |
128 | the current network. | |
abacc52b | 129 | |
abacc52b | 130 | |
798d6e29 | 131 | ## Finding Available Destinations |
abacc52b | 132 | |
798d6e29 MS |
133 | The `cupsEnumDests` function finds all of the available destinations: |
134 | ||
135 | int | |
136 | cupsEnumDests(unsigned flags, int msec, int *cancel, | |
137 | cups_ptype_t type, cups_ptype_t mask, | |
138 | cups_dest_cb_t cb, void *user_data) | |
139 | ||
140 | The `flags` argument specifies enumeration options, which at present must be | |
141 | `CUPS_DEST_FLAGS_NONE`. | |
142 | ||
143 | The `msec` argument specifies the maximum amount of time that should be used for | |
144 | enumeration in milliseconds - interactive applications should keep this value to | |
145 | 5000 or less when run on the main thread. | |
146 | ||
147 | The `cancel` argument points to an integer variable that, when set to a non-zero | |
148 | value, will cause enumeration to stop as soon as possible. It can be `NULL` if | |
149 | not needed. | |
150 | ||
151 | The `type` and `mask` arguments are bitfields that allow the caller to filter | |
152 | the destinations based on categories and/or capabilities. The destination's | |
153 | "printer-type" value is masked by the `mask` value and compared to the `type` | |
154 | value when filtering. For example, to only enumerate destinations that are | |
155 | hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument | |
f50db552 MS |
156 | and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants |
157 | can be used for filtering: | |
798d6e29 MS |
158 | |
159 | - `CUPS_PRINTER_CLASS`: A collection of destinations. | |
160 | - `CUPS_PRINTER_FAX`: A facsimile device. | |
161 | - `CUPS_PRINTER_LOCAL`: A local printer or class. This constant has the value 0 | |
162 | (no bits set) and is only used for the `type` argument and is paired with the | |
f50db552 MS |
163 | `CUPS_PRINTER_REMOTE` or `CUPS_PRINTER_DISCOVERED` constant passed in the |
164 | `mask` argument. | |
165 | - `CUPS_PRINTER_REMOTE`: A remote (shared) printer or class. | |
166 | - `CUPS_PRINTER_DISCOVERED`: An available network printer or class. | |
798d6e29 MS |
167 | - `CUPS_PRINTER_BW`: Can do B&W printing. |
168 | - `CUPS_PRINTER_COLOR`: Can do color printing. | |
169 | - `CUPS_PRINTER_DUPLEX`: Can do two-sided printing. | |
170 | - `CUPS_PRINTER_STAPLE`: Can staple output. | |
171 | - `CUPS_PRINTER_COLLATE`: Can quickly collate copies. | |
172 | - `CUPS_PRINTER_PUNCH`: Can punch output. | |
173 | - `CUPS_PRINTER_COVER`: Can cover output. | |
174 | - `CUPS_PRINTER_BIND`: Can bind output. | |
175 | - `CUPS_PRINTER_SORT`: Can sort output (mailboxes, etc.) | |
176 | - `CUPS_PRINTER_SMALL`: Can print on Letter/Legal/A4-size media. | |
177 | - `CUPS_PRINTER_MEDIUM`: Can print on Tabloid/B/C/A3/A2-size media. | |
178 | - `CUPS_PRINTER_LARGE`: Can print on D/E/A1/A0-size media. | |
179 | - `CUPS_PRINTER_VARIABLE`: Can print on rolls and custom-size media. | |
180 | ||
181 | The `cb` argument specifies a function to call for every destination that is | |
182 | found: | |
183 | ||
184 | typedef int (*cups_dest_cb_t)(void *user_data, | |
185 | unsigned flags, | |
186 | cups_dest_t *dest); | |
187 | ||
188 | The callback function receives a copy of the `user_data` argument along with a | |
189 | bitfield \(`flags`) and the destination that was found. The `flags` argument | |
190 | can have any of the following constant (bit) values set: | |
191 | ||
192 | - `CUPS_DEST_FLAGS_MORE`: There are more destinations coming. | |
193 | - `CUPS_DEST_FLAGS_REMOVED`: The destination has gone away and should be removed | |
194 | from the list of destinations a user can select. | |
195 | - `CUPS_DEST_FLAGS_ERROR`: An error occurred. The reason for the error can be | |
196 | found by calling the `cupsLastError` and/or `cupsLastErrorString` functions. | |
197 | ||
198 | The callback function returns 0 to stop enumeration or 1 to continue. | |
199 | ||
200 | The following example shows how to use `cupsEnumDests` to get a filtered array | |
201 | of destinations: | |
202 | ||
203 | typedef struct | |
204 | { | |
205 | int num_dests; | |
206 | cups_dest_t *dests; | |
207 | } my_user_data_t; | |
abacc52b | 208 | |
798d6e29 MS |
209 | int |
210 | my_dest_cb(my_user_data_t *user_data, unsigned flags, | |
211 | cups_dest_t *dest) | |
212 | { | |
213 | if (flags & CUPS_DEST_FLAGS_REMOVED) | |
214 | { | |
215 | /* | |
216 | * Remove destination from array... | |
217 | */ | |
218 | ||
219 | user_data->num_dests = | |
220 | cupsRemoveDest(dest->name, dest->instance, | |
221 | user_data->num_dests, | |
222 | &(user_data->dests)); | |
223 | } | |
224 | else | |
225 | { | |
226 | /* | |
227 | * Add destination to array... | |
228 | */ | |
abacc52b | 229 | |
798d6e29 MS |
230 | user_data->num_dests = |
231 | cupsCopyDest(dest, user_data->num_dests, | |
232 | &(user_data->dests)); | |
233 | } | |
abacc52b | 234 | |
798d6e29 MS |
235 | return (1); |
236 | } | |
abacc52b | 237 | |
798d6e29 MS |
238 | int |
239 | my_get_dests(cups_ptype_t type, cups_ptype_t mask, | |
240 | cups_dest_t **dests) | |
241 | { | |
242 | my_user_data_t user_data = { 0, NULL }; | |
abacc52b | 243 | |
798d6e29 MS |
244 | if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type, |
245 | mask, (cups_dest_cb_t)my_dest_cb, | |
246 | &user_data)) | |
247 | { | |
248 | /* | |
249 | * An error occurred, free all of the destinations and | |
250 | * return... | |
251 | */ | |
abacc52b | 252 | |
798d6e29 | 253 | cupsFreeDests(user_data.num_dests, user_dasta.dests); |
abacc52b | 254 | |
798d6e29 | 255 | *dests = NULL; |
abacc52b | 256 | |
798d6e29 MS |
257 | return (0); |
258 | } | |
abacc52b | 259 | |
798d6e29 MS |
260 | /* |
261 | * Return the destination array... | |
262 | */ | |
abacc52b | 263 | |
798d6e29 | 264 | *dests = user_data.dests; |
abacc52b | 265 | |
798d6e29 MS |
266 | return (user_data.num_dests); |
267 | } | |
abacc52b | 268 | |
abacc52b | 269 | |
798d6e29 MS |
270 | ## Basic Destination Information |
271 | ||
272 | The `num_options` and `options` members of the `cups_dest_t` structure provide | |
273 | basic attributes about the destination in addition to the user default options | |
274 | and values for that destination. The following names are predefined for various | |
275 | destination attributes: | |
276 | ||
277 | - "auth-info-required": The type of authentication required for printing to this | |
278 | destination: "none", "username,password", "domain,username,password", or | |
279 | "negotiate" (Kerberos). | |
280 | - "printer-info": The human-readable description of the destination such as "My | |
281 | Laser Printer". | |
282 | - "printer-is-accepting-jobs": "true" if the destination is accepting new jobs, | |
283 | "false" otherwise. | |
284 | - "printer-is-shared": "true" if the destination is being shared with other | |
285 | computers, "false" otherwise. | |
286 | - "printer-location": The human-readable location of the destination such as | |
287 | "Lab 4". | |
288 | - "printer-make-and-model": The human-readable make and model of the destination | |
289 | such as "ExampleCorp LaserPrinter 4000 Series". | |
290 | - "printer-state": "3" if the destination is idle, "4" if the destination is | |
291 | printing a job, and "5" if the destination is stopped. | |
292 | - "printer-state-change-time": The UNIX time when the destination entered the | |
293 | current state. | |
294 | - "printer-state-reasons": Additional comma-delimited state keywords for the | |
295 | destination such as "media-tray-empty-error" and "toner-low-warning". | |
296 | - "printer-type": The `cups_ptype_t` value associated with the destination. | |
f50db552 MS |
297 | - "printer-uri": The URI associated with the destination; if not set, this |
298 | destination was discovered but is not yet setup as a local printer. | |
798d6e29 MS |
299 | |
300 | Use the `cupsGetOption` function to retrieve the value. For example, the | |
301 | following code gets the make and model of a destination: | |
302 | ||
303 | const char *model = cupsGetOption("printer-make-and-model", | |
304 | dest->num_options, | |
305 | dest->options); | |
306 | ||
307 | ## Detailed Destination Information | |
308 | ||
309 | Once a destination has been chosen, the `cupsCopyDestInfo` function can be used | |
310 | to gather detailed information about the destination: | |
311 | ||
312 | cups_dinfo_t * | |
313 | cupsCopyDestInfo(http_t *http, cups_dest_t *dest); | |
314 | ||
315 | The `http` argument specifies a connection to the CUPS scheduler and is | |
316 | typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the | |
317 | destination to query. | |
318 | ||
319 | The `cups_dinfo_t` structure that is returned contains a snapshot of the | |
320 | supported options and their supported, ready, and default values. It also can | |
321 | report constraints between different options and values, and recommend changes | |
322 | to resolve those constraints. | |
abacc52b | 323 | |
798d6e29 | 324 | ### Getting Supported Options and Values |
abacc52b | 325 | |
798d6e29 MS |
326 | The `cupsCheckDestSupported` function can be used to test whether a particular |
327 | option or option and value is supported: | |
328 | ||
329 | int | |
330 | cupsCheckDestSupported(http_t *http, cups_dest_t *dest, | |
331 | cups_dinfo_t *info, | |
332 | const char *option, | |
333 | const char *value); | |
334 | ||
335 | The `option` argument specifies the name of the option to check. The following | |
336 | constants can be used to check the various standard options: | |
337 | ||
338 | - `CUPS_COPIES`: Controls the number of copies that are produced. | |
339 | - `CUPS_FINISHINGS`: A comma-delimited list of integer constants that control | |
340 | the finishing processes that are applied to the job, including stapling, | |
341 | punching, and folding. | |
342 | - `CUPS_MEDIA`: Controls the media size that is used, typically one of the | |
343 | following: `CUPS_MEDIA_3X5`, `CUPS_MEDIA_4X6`, `CUPS_MEDIA_5X7`, | |
344 | `CUPS_MEDIA_8X10`, `CUPS_MEDIA_A3`, `CUPS_MEDIA_A4`, `CUPS_MEDIA_A5`, | |
345 | `CUPS_MEDIA_A6`, `CUPS_MEDIA_ENV10`, `CUPS_MEDIA_ENVDL`, `CUPS_MEDIA_LEGAL`, | |
346 | `CUPS_MEDIA_LETTER`, `CUPS_MEDIA_PHOTO_L`, `CUPS_MEDIA_SUPERBA3`, or | |
347 | `CUPS_MEDIA_TABLOID`. | |
348 | - `CUPS_MEDIA_SOURCE`: Controls where the media is pulled from, typically either | |
349 | `CUPS_MEDIA_SOURCE_AUTO` or `CUPS_MEDIA_SOURCE_MANUAL`. | |
350 | - `CUPS_MEDIA_TYPE`: Controls the type of media that is used, typically one of | |
351 | the following: `CUPS_MEDIA_TYPE_AUTO`, `CUPS_MEDIA_TYPE_ENVELOPE`, | |
352 | `CUPS_MEDIA_TYPE_LABELS`, `CUPS_MEDIA_TYPE_LETTERHEAD`, | |
353 | `CUPS_MEDIA_TYPE_PHOTO`, `CUPS_MEDIA_TYPE_PHOTO_GLOSSY`, | |
354 | `CUPS_MEDIA_TYPE_PHOTO_MATTE`, `CUPS_MEDIA_TYPE_PLAIN`, or | |
355 | `CUPS_MEDIA_TYPE_TRANSPARENCY`. | |
356 | - `CUPS_NUMBER_UP`: Controls the number of document pages that are placed on | |
357 | each media side. | |
358 | - `CUPS_ORIENTATION`: Controls the orientation of document pages placed on the | |
359 | media: `CUPS_ORIENTATION_PORTRAIT` or `CUPS_ORIENTATION_LANDSCAPE`. | |
360 | - `CUPS_PRINT_COLOR_MODE`: Controls whether the output is in color | |
361 | \(`CUPS_PRINT_COLOR_MODE_COLOR`), grayscale | |
362 | \(`CUPS_PRINT_COLOR_MODE_MONOCHROME`), or either | |
363 | \(`CUPS_PRINT_COLOR_MODE_AUTO`). | |
364 | - `CUPS_PRINT_QUALITY`: Controls the generate quality of the output: | |
365 | `CUPS_PRINT_QUALITY_DRAFT`, `CUPS_PRINT_QUALITY_NORMAL`, or | |
366 | `CUPS_PRINT_QUALITY_HIGH`. | |
367 | - `CUPS_SIDES`: Controls whether prints are placed on one or both sides of the | |
368 | media: `CUPS_SIDES_ONE_SIDED`, `CUPS_SIDES_TWO_SIDED_PORTRAIT`, or | |
369 | `CUPS_SIDES_TWO_SIDED_LANDSCAPE`. | |
370 | ||
371 | If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns | |
372 | whether the option is supported by the destination. Otherwise, the function | |
373 | returns whether the specified value of the option is supported. | |
374 | ||
375 | The `cupsFindDestSupported` function returns the IPP attribute containing the | |
376 | supported values for a given option: | |
377 | ||
378 | ipp_attribute_t * | |
379 | cupsFindDestSupported(http_t *http, cups_dest_t *dest, | |
380 | cups_dinfo_t *dinfo, | |
381 | const char *option); | |
382 | ||
383 | For example, the following code prints the supported finishing processes for a | |
384 | destination, if any, to the standard output: | |
385 | ||
386 | cups_dinfo_t *info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, | |
387 | dest); | |
388 | ||
389 | if (cupsCheckDestSupported(CUPS_HTTP_DEFAULT, dest, info, | |
390 | CUPS_FINISHINGS, NULL)) | |
391 | { | |
392 | ipp_attribute_t *finishings = | |
393 | cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info, | |
394 | CUPS_FINISHINGS); | |
395 | int i, count = ippGetCount(finishings); | |
396 | ||
397 | puts("finishings supported:"); | |
398 | for (i = 0; i < count; i ++) | |
399 | printf(" %d\n", ippGetInteger(finishings, i)); | |
400 | } | |
401 | else | |
402 | puts("finishings not supported."); | |
abacc52b | 403 | |
798d6e29 MS |
404 | The "job-creation-attributes" option can be queried to get a list of supported |
405 | options. For example, the following code prints the list of supported options | |
406 | to the standard output: | |
abacc52b | 407 | |
798d6e29 MS |
408 | ipp_attribute_t *attrs = |
409 | cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info, | |
410 | "job-creation-attributes"); | |
411 | int i, count = ippGetCount(attrs); | |
abacc52b | 412 | |
798d6e29 MS |
413 | for (i = 0; i < count; i ++) |
414 | puts(ippGetString(attrs, i, NULL)); | |
abacc52b MS |
415 | |
416 | ||
798d6e29 | 417 | ### Getting Default Values |
abacc52b | 418 | |
798d6e29 MS |
419 | There are two sets of default values - user defaults that are available via the |
420 | `num_options` and `options` members of the `cups_dest_t` structure, and | |
421 | destination defaults that available via the `cups_dinfo_t` structure and the | |
422 | `cupsFindDestDefault` function which returns the IPP attribute containing the | |
423 | default value(s) for a given option: | |
abacc52b | 424 | |
798d6e29 MS |
425 | ipp_attribute_t * |
426 | cupsFindDestDefault(http_t *http, cups_dest_t *dest, | |
427 | cups_dinfo_t *dinfo, | |
428 | const char *option); | |
abacc52b | 429 | |
798d6e29 MS |
430 | The user defaults from `cupsGetOption` should always take preference over the |
431 | destination defaults. For example, the following code prints the default | |
432 | finishings value(s) to the standard output: | |
abacc52b | 433 | |
798d6e29 MS |
434 | const char *def_value = |
435 | cupsGetOption(CUPS_FINISHINGS, dest->num_options, | |
436 | dest->options); | |
437 | ipp_attribute_t *def_attr = | |
438 | cupsFindDestDefault(CUPS_HTTP_DEFAULT, dest, info, | |
439 | CUPS_FINISHINGS); | |
abacc52b | 440 | |
798d6e29 MS |
441 | if (def_value != NULL) |
442 | { | |
443 | printf("Default finishings: %s\n", def_value); | |
444 | } | |
445 | else | |
446 | { | |
447 | int i, count = ippGetCount(def_attr); | |
abacc52b | 448 | |
798d6e29 MS |
449 | printf("Default finishings: %d", |
450 | ippGetInteger(def_attr, 0)); | |
451 | for (i = 1; i < count; i ++) | |
452 | printf(",%d", ippGetInteger(def_attr, i)); | |
453 | putchar('\n'); | |
454 | } | |
abacc52b MS |
455 | |
456 | ||
798d6e29 | 457 | ### Getting Ready (Loaded) Values |
abacc52b | 458 | |
798d6e29 MS |
459 | The finishings and media options also support queries for the ready, or loaded, |
460 | values. For example, a printer may have punch and staple finishers installed | |
461 | but be out of staples - the supported values will list both punch and staple | |
462 | finishing processes but the ready values will only list the punch processes. | |
463 | Similarly, a printer may support hundreds of different sizes of media but only | |
464 | have a single size loaded at any given time - the ready values are limited to | |
465 | the media that is actually in the printer. | |
abacc52b | 466 | |
798d6e29 MS |
467 | The `cupsFindDestReady` function finds the IPP attribute containing the ready |
468 | values for a given option: | |
abacc52b | 469 | |
798d6e29 MS |
470 | ipp_attribute_t * |
471 | cupsFindDestReady(http_t *http, cups_dest_t *dest, | |
472 | cups_dinfo_t *dinfo, const char *option); | |
abacc52b | 473 | |
798d6e29 | 474 | For example, the following code lists the ready finishing processes: |
abacc52b | 475 | |
798d6e29 MS |
476 | ipp_attribute_t *ready_finishings = |
477 | cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info, | |
478 | CUPS_FINISHINGS); | |
abacc52b | 479 | |
798d6e29 MS |
480 | if (ready_finishings != NULL) |
481 | { | |
482 | int i, count = ippGetCount(ready_finishings); | |
abacc52b | 483 | |
798d6e29 MS |
484 | puts("finishings ready:"); |
485 | for (i = 0; i < count; i ++) | |
486 | printf(" %d\n", ippGetInteger(ready_finishings, i)); | |
487 | } | |
488 | else | |
489 | puts("no finishings are ready."); | |
abacc52b | 490 | |
abacc52b | 491 | |
798d6e29 | 492 | ### Media Size Options |
abacc52b | 493 | |
798d6e29 MS |
494 | CUPS provides functions for querying the dimensions and margins for each of the |
495 | supported media size options. The `cups_size_t` structure is used to describe a | |
496 | media size: | |
abacc52b | 497 | |
798d6e29 MS |
498 | typedef struct cups_size_s |
499 | { | |
500 | char media[128]; | |
501 | int width, length; | |
502 | int bottom, left, right, top; | |
503 | } cups_size_t; | |
504 | ||
505 | The `width` and `length` members specify the dimensions of the media in | |
506 | hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`, | |
507 | and `top` members specify the margins of the printable area, also in hundredths | |
508 | of millimeters. | |
509 | ||
510 | The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the | |
511 | media size information using a standard media size name or dimensions in | |
512 | hundredths of millimeters: | |
513 | ||
514 | int | |
515 | cupsGetDestMediaByName(http_t *http, cups_dest_t *dest, | |
516 | cups_dinfo_t *dinfo, | |
517 | const char *media, | |
518 | unsigned flags, cups_size_t *size); | |
519 | ||
520 | int | |
521 | cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest, | |
522 | cups_dinfo_t *dinfo, | |
523 | int width, int length, | |
524 | unsigned flags, cups_size_t *size); | |
525 | ||
526 | The `media`, `width`, and `length` arguments specify the size to lookup. The | |
527 | `flags` argument specifies a bitfield controlling various lookup options: | |
528 | ||
529 | - `CUPS_MEDIA_FLAGS_DEFAULT`: Find the closest size supported by the printer. | |
530 | - `CUPS_MEDIA_FLAGS_BORDERLESS`: Find a borderless size. | |
531 | - `CUPS_MEDIA_FLAGS_DUPLEX`: Find a size compatible with two-sided printing. | |
532 | - `CUPS_MEDIA_FLAGS_EXACT`: Find an exact match for the size. | |
533 | - `CUPS_MEDIA_FLAGS_READY`: If the printer supports media sensing or | |
534 | configuration of the media in each tray/source, find the size amongst the | |
535 | "ready" media. | |
536 | ||
537 | If a matching size is found for the destination, the size information is stored | |
538 | in the structure pointed to by the `size` argument and 1 is returned. Otherwise | |
539 | 0 is returned. | |
540 | ||
541 | For example, the following code prints the margins for two-sided printing on US | |
542 | Letter media: | |
543 | ||
544 | cups_size_t size; | |
545 | ||
546 | if (cupsGetDestMediaByName(CUPS_HTTP_DEFAULT, dest, info, | |
547 | CUPS_MEDIA_LETTER, | |
548 | CUPS_MEDIA_FLAGS_DUPLEX, &size)) | |
abacc52b | 549 | { |
798d6e29 MS |
550 | puts("Margins for duplex US Letter:"); |
551 | printf(" Bottom: %.2fin\n", size.bottom / 2540.0); | |
552 | printf(" Left: %.2fin\n", size.left / 2540.0); | |
553 | printf(" Right: %.2fin\n", size.right / 2540.0); | |
554 | printf(" Top: %.2fin\n", size.top / 2540.0); | |
abacc52b | 555 | } |
798d6e29 MS |
556 | else |
557 | puts("Margins for duplex US Letter are not available."); | |
abacc52b | 558 | |
798d6e29 MS |
559 | You can also enumerate all of the sizes that match a given `flags` value using |
560 | the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions: | |
abacc52b | 561 | |
798d6e29 MS |
562 | int |
563 | cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest, | |
564 | cups_dinfo_t *dinfo, int n, | |
565 | unsigned flags, cups_size_t *size); | |
abacc52b | 566 | |
798d6e29 MS |
567 | int |
568 | cupsGetDestMediaCount(http_t *http, cups_dest_t *dest, | |
569 | cups_dinfo_t *dinfo, unsigned flags); | |
abacc52b | 570 | |
798d6e29 MS |
571 | For example, the following code prints the list of ready media and corresponding |
572 | margins: | |
abacc52b | 573 | |
798d6e29 MS |
574 | cups_size_t size; |
575 | int i; | |
576 | int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT, | |
577 | dest, info, | |
578 | CUPS_MEDIA_FLAGS_READY); | |
abacc52b | 579 | |
798d6e29 MS |
580 | for (i = 0; i < count; i ++) |
581 | { | |
582 | if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, info, | |
583 | i, CUPS_MEDIA_FLAGS_READY, | |
584 | &size)) | |
585 | { | |
586 | printf("%s:\n", size.name); | |
587 | printf(" Width: %.2fin\n", size.width / 2540.0); | |
588 | printf(" Length: %.2fin\n", size.length / 2540.0); | |
589 | printf(" Bottom: %.2fin\n", size.bottom / 2540.0); | |
590 | printf(" Left: %.2fin\n", size.left / 2540.0); | |
591 | printf(" Right: %.2fin\n", size.right / 2540.0); | |
592 | printf(" Top: %.2fin\n", size.top / 2540.0); | |
593 | } | |
594 | } | |
abacc52b | 595 | |
798d6e29 | 596 | Finally, the `cupsGetDestMediaDefault` function returns the default media size: |
abacc52b | 597 | |
798d6e29 MS |
598 | int |
599 | cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest, | |
600 | cups_dinfo_t *dinfo, unsigned flags, | |
601 | cups_size_t *size); | |
abacc52b | 602 | |
abacc52b | 603 | |
798d6e29 | 604 | ### Localizing Options and Values |
abacc52b | 605 | |
798d6e29 MS |
606 | CUPS provides three functions to get localized versions of options and values: |
607 | `cupsLocalizeDestMedia`, `cupsLocalizeDestOption`, and `cupsLocalizeDestValue`: | |
abacc52b | 608 | |
798d6e29 MS |
609 | const char * |
610 | cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest, | |
611 | cups_dinfo_t *info, unsigned flags, | |
612 | cups_size_t *size); | |
abacc52b | 613 | |
798d6e29 MS |
614 | const char * |
615 | cupsLocalizeDestOption(http_t *http, cups_dest_t *dest, | |
616 | cups_dinfo_t *info, | |
617 | const char *option); | |
abacc52b | 618 | |
798d6e29 MS |
619 | const char * |
620 | cupsLocalizeDestValue(http_t *http, cups_dest_t *dest, | |
621 | cups_dinfo_t *info, | |
622 | const char *option, const char *value); | |
abacc52b | 623 | |
abacc52b | 624 | |
798d6e29 | 625 | ## Submitting a Print Job |
abacc52b | 626 | |
798d6e29 MS |
627 | Once you are ready to submit a print job, you create a job using the |
628 | `cupsCreateDestJob` function: | |
629 | ||
630 | ipp_status_t | |
631 | cupsCreateDestJob(http_t *http, cups_dest_t *dest, | |
632 | cups_dinfo_t *info, int *job_id, | |
633 | const char *title, int num_options, | |
634 | cups_option_t *options); | |
635 | ||
636 | The `title` argument specifies a name for the print job such as "My Document". | |
637 | The `num_options` and `options` arguments specify the options for the print | |
638 | job which are allocated using the `cupsAddOption` function. | |
639 | ||
640 | When successful, the job's numeric identifier is stored in the integer pointed | |
641 | to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP | |
642 | error status is returned. | |
643 | ||
644 | For example, the following code creates a new job that will print 42 copies of a | |
645 | two-sided US Letter document: | |
646 | ||
647 | int job_id = 0; | |
648 | int num_options = 0; | |
649 | cups_option_t *options = NULL; | |
650 | ||
651 | num_options = cupsAddOption(CUPS_COPIES, "42", | |
652 | num_options, &options); | |
653 | num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_LETTER, | |
654 | num_options, &options); | |
655 | num_options = cupsAddOption(CUPS_SIDES, | |
656 | CUPS_SIDES_TWO_SIDED_PORTRAIT, | |
657 | num_options, &options); | |
658 | ||
659 | if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info, | |
660 | &job_id, "My Document", num_options, | |
661 | options) == IPP_STATUS_OK) | |
662 | printf("Created job: %d\n", job_id); | |
663 | else | |
664 | printf("Unable to create job: %s\n", | |
665 | cupsLastErrorString()); | |
666 | ||
667 | Once the job is created, you submit documents for the job using the | |
668 | `cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument` | |
669 | functions: | |
670 | ||
671 | http_status_t | |
672 | cupsStartDestDocument(http_t *http, cups_dest_t *dest, | |
673 | cups_dinfo_t *info, int job_id, | |
674 | const char *docname, | |
675 | const char *format, | |
676 | int num_options, | |
677 | cups_option_t *options, | |
678 | int last_document); | |
679 | ||
680 | http_status_t | |
681 | cupsWriteRequestData(http_t *http, const char *buffer, | |
682 | size_t length); | |
683 | ||
684 | ipp_status_t | |
685 | cupsFinishDestDocument(http_t *http, cups_dest_t *dest, | |
686 | cups_dinfo_t *info); | |
687 | ||
688 | The `docname` argument specifies the name of the document, typically the | |
689 | original filename. The `format` argument specifies the MIME media type of the | |
690 | document, including the following constants: | |
691 | ||
692 | - `CUPS_FORMAT_JPEG`: "image/jpeg" | |
693 | - `CUPS_FORMAT_PDF`: "application/pdf" | |
694 | - `CUPS_FORMAT_POSTSCRIPT`: "application/postscript" | |
695 | - `CUPS_FORMAT_TEXT`: "text/plain" | |
696 | ||
697 | The `num_options` and `options` arguments specify per-document print options, | |
698 | which at present must be 0 and `NULL`. The `last_document` argument specifies | |
699 | whether this is the last document in the job. | |
700 | ||
701 | For example, the following code submits a PDF file to the job that was just | |
702 | created: | |
703 | ||
704 | FILE *fp = fopen("filename.pdf", "rb"); | |
705 | size_t bytes; | |
706 | char buffer[65536]; | |
707 | ||
708 | if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info, | |
709 | job_id, "filename.pdf", 0, NULL, | |
710 | 1) == HTTP_STATUS_CONTINUE) | |
abacc52b | 711 | { |
798d6e29 MS |
712 | while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) |
713 | if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, | |
714 | bytes) != HTTP_STATUS_CONTINUE) | |
715 | break; | |
716 | ||
717 | if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest, | |
718 | info) == IPP_STATUS_OK) | |
719 | puts("Document send succeeded."); | |
720 | else | |
721 | printf("Document send failed: %s\n", | |
722 | cupsLastErrorString()); | |
abacc52b | 723 | } |
798d6e29 MS |
724 | |
725 | fclose(fp); |