]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/cupspm.md
Use codedoc now instead of mxmldoc.
[thirdparty/cups.git] / cups / cupspm.md
1 ---
2 title: CUPS Programming Manual
3 author: Michael R Sweet
4 copyright: Copyright © 2007-2018 by Apple Inc. All Rights Reserved.
5 version: 2.3.0
6 ...
7
8 > Please [file issues on Github](https://github.com/apple/cups/issues) to
9 > provide feedback on this document.
10
11
12 # Introduction
13
14 CUPS provides the "cups" library to talk to the different parts of CUPS and with
15 Internet Printing Protocol (IPP) printers. The "cups" library functions are
16 accessed by including the `<cups/cups.h>` header.
17
18 CUPS is based on the Internet Printing Protocol ("IPP"), which allows clients
19 (applications) to communicate with a server (the scheduler, printers, etc.) to
20 get a list of destinations, send print jobs, and so forth. You identify which
21 server you want to communicate with using a pointer to the opaque structure
22 `http_t`. The `CUPS_HTTP_DEFAULT` constant can be used when you want to talk to
23 the CUPS scheduler.
24
25
26 ## Guidelines
27
28 When writing software that uses the "cups" library:
29
30 - Do not use undocumented or deprecated APIs,
31 - Do not rely on pre-configured printers,
32 - Do not assume that printers support specific features or formats, and
33 - Do not rely on implementation details (PPDs, etc.)
34
35 CUPS is designed to insulate users and developers from the implementation
36 details of printers and file formats. The goal is to allow an application to
37 supply a print file in a standard format with the user intent ("print four
38 copies, two-sided on A4 media, and staple each copy") and have the printing
39 system manage the printer communication and format conversion needed.
40
41 Similarly, printer and job management applications can use standard query
42 operations to obtain the status information in a common, generic form and use
43 standard management operations to control the state of those printers and jobs.
44
45
46 ## Terms Used in This Document
47
48 A *Destination* is a printer or print queue that accepts print jobs. A
49 *Print Job* is one or more documents that are processed by a destination
50 using options supplied when creating the job. A *Document* is a file (JPEG
51 image, PDF file, etc.) suitable for printing. An *Option* controls some aspect
52 of printing, such as the media used. *Media* is the sheets or roll that is
53 printed on. An *Attribute* is an option encoded for an Internet Printing
54 Protocol (IPP) request.
55
56
57 ## Compiling Programs That Use the CUPS API
58
59 The CUPS libraries can be used from any C, C++, or Objective C program.
60 The method of compiling against the libraries varies depending on the
61 operating system and installation of CUPS. The following sections show how
62 to compile a simple program (shown below) in two common environments.
63
64 The following simple program lists the available destinations:
65
66 #include <stdio.h>
67 #include <cups/cups.h>
68
69 int print_dest(void *user_data, unsigned flags, cups_dest_t *dest)
70 {
71 if (dest->instance)
72 printf("%s/%s\n", dest->name, dest->instance);
73 else
74 puts(dest->name);
75
76 return (1);
77 }
78
79 int main(void)
80 {
81 cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0, print_dest, NULL);
82
83 return (0);
84 }
85
86
87 ### Compiling with Xcode
88
89 In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N),
90 then select the *Command Line Tool* under the macOS Application project type.
91 Click *Next* and enter a name for the project, for example "firstcups". Click
92 *Next* and choose a project directory. The click *Next* to create the project.
93
94 In the project window, click on the *Build Phases* group and expand the
95 *Link Binary with Libraries* section. Click *+*, type "libcups" to show the
96 library, and then double-click on `libcups.tbd`.
97
98 Finally, click on the `main.c` file in the sidebar and copy the example program
99 to the file. Build and run (CMD+R) to see the list of destinations.
100
101
102 ### Compiling with GCC
103
104 From the command-line, create a file called `sample.c` using your favorite
105 editor, copy the example to this file, and save. Then run the following command
106 to compile it with GCC and run it:
107
108 gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
109 ./simple
110
111 The `cups-config` command provides the compiler flags (`cups-config --cflags`)
112 and libraries (`cups-config --libs`) needed for the local system.
113
114
115 # Working with Destinations
116
117 Destinations, which in CUPS represent individual printers or classes
118 (collections or pools) of printers, are represented by the `cups_dest_t`
119 structure which includes the name \(`name`), instance \(`instance`, saved
120 options/settings), whether the destination is the default for the user
121 \(`is_default`), and the options and basic information associated with that
122 destination \(`num_options` and `options`).
123
124 Historically destinations have been manually maintained by the administrator of
125 a system or network, but CUPS also supports dynamic discovery of destinations on
126 the current network.
127
128
129 ## Finding Available Destinations
130
131 The `cupsEnumDests` function finds all of the available destinations:
132
133 int
134 cupsEnumDests(unsigned flags, int msec, int *cancel,
135 cups_ptype_t type, cups_ptype_t mask,
136 cups_dest_cb_t cb, void *user_data)
137
138 The `flags` argument specifies enumeration options, which at present must be
139 `CUPS_DEST_FLAGS_NONE`.
140
141 The `msec` argument specifies the maximum amount of time that should be used for
142 enumeration in milliseconds - interactive applications should keep this value to
143 5000 or less when run on the main thread.
144
145 The `cancel` argument points to an integer variable that, when set to a non-zero
146 value, will cause enumeration to stop as soon as possible. It can be `NULL` if
147 not needed.
148
149 The `type` and `mask` arguments are bitfields that allow the caller to filter
150 the destinations based on categories and/or capabilities. The destination's
151 "printer-type" value is masked by the `mask` value and compared to the `type`
152 value when filtering. For example, to only enumerate destinations that are
153 hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument
154 and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants
155 can be used for filtering:
156
157 - `CUPS_PRINTER_CLASS`: A collection of destinations.
158 - `CUPS_PRINTER_FAX`: A facsimile device.
159 - `CUPS_PRINTER_LOCAL`: A local printer or class. This constant has the value 0
160 (no bits set) and is only used for the `type` argument and is paired with the
161 `CUPS_PRINTER_REMOTE` or `CUPS_PRINTER_DISCOVERED` constant passed in the
162 `mask` argument.
163 - `CUPS_PRINTER_REMOTE`: A remote (shared) printer or class.
164 - `CUPS_PRINTER_DISCOVERED`: An available network printer or class.
165 - `CUPS_PRINTER_BW`: Can do B&W printing.
166 - `CUPS_PRINTER_COLOR`: Can do color printing.
167 - `CUPS_PRINTER_DUPLEX`: Can do two-sided printing.
168 - `CUPS_PRINTER_STAPLE`: Can staple output.
169 - `CUPS_PRINTER_COLLATE`: Can quickly collate copies.
170 - `CUPS_PRINTER_PUNCH`: Can punch output.
171 - `CUPS_PRINTER_COVER`: Can cover output.
172 - `CUPS_PRINTER_BIND`: Can bind output.
173 - `CUPS_PRINTER_SORT`: Can sort output (mailboxes, etc.)
174 - `CUPS_PRINTER_SMALL`: Can print on Letter/Legal/A4-size media.
175 - `CUPS_PRINTER_MEDIUM`: Can print on Tabloid/B/C/A3/A2-size media.
176 - `CUPS_PRINTER_LARGE`: Can print on D/E/A1/A0-size media.
177 - `CUPS_PRINTER_VARIABLE`: Can print on rolls and custom-size media.
178
179 The `cb` argument specifies a function to call for every destination that is
180 found:
181
182 typedef int (*cups_dest_cb_t)(void *user_data,
183 unsigned flags,
184 cups_dest_t *dest);
185
186 The callback function receives a copy of the `user_data` argument along with a
187 bitfield \(`flags`) and the destination that was found. The `flags` argument
188 can have any of the following constant (bit) values set:
189
190 - `CUPS_DEST_FLAGS_MORE`: There are more destinations coming.
191 - `CUPS_DEST_FLAGS_REMOVED`: The destination has gone away and should be removed
192 from the list of destinations a user can select.
193 - `CUPS_DEST_FLAGS_ERROR`: An error occurred. The reason for the error can be
194 found by calling the `cupsLastError` and/or `cupsLastErrorString` functions.
195
196 The callback function returns 0 to stop enumeration or 1 to continue.
197
198 > Note that the callback function will likely be called multiple times for the
199 > same destination, so it is up to the caller to suppress any duplicate
200 > destinations.
201
202 The following example shows how to use `cupsEnumDests` to get a filtered array
203 of destinations:
204
205 typedef struct
206 {
207 int num_dests;
208 cups_dest_t *dests;
209 } my_user_data_t;
210
211 int
212 my_dest_cb(my_user_data_t *user_data, unsigned flags,
213 cups_dest_t *dest)
214 {
215 if (flags & CUPS_DEST_FLAGS_REMOVED)
216 {
217 /*
218 * Remove destination from array...
219 */
220
221 user_data->num_dests =
222 cupsRemoveDest(dest->name, dest->instance,
223 user_data->num_dests,
224 &(user_data->dests));
225 }
226 else
227 {
228 /*
229 * Add destination to array...
230 */
231
232 user_data->num_dests =
233 cupsCopyDest(dest, user_data->num_dests,
234 &(user_data->dests));
235 }
236
237 return (1);
238 }
239
240 int
241 my_get_dests(cups_ptype_t type, cups_ptype_t mask,
242 cups_dest_t **dests)
243 {
244 my_user_data_t user_data = { 0, NULL };
245
246 if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type,
247 mask, (cups_dest_cb_t)my_dest_cb,
248 &user_data))
249 {
250 /*
251 * An error occurred, free all of the destinations and
252 * return...
253 */
254
255 cupsFreeDests(user_data.num_dests, user_dasta.dests);
256
257 *dests = NULL;
258
259 return (0);
260 }
261
262 /*
263 * Return the destination array...
264 */
265
266 *dests = user_data.dests;
267
268 return (user_data.num_dests);
269 }
270
271
272 ## Basic Destination Information
273
274 The `num_options` and `options` members of the `cups_dest_t` structure provide
275 basic attributes about the destination in addition to the user default options
276 and values for that destination. The following names are predefined for various
277 destination attributes:
278
279 - "auth-info-required": The type of authentication required for printing to this
280 destination: "none", "username,password", "domain,username,password", or
281 "negotiate" (Kerberos).
282 - "printer-info": The human-readable description of the destination such as "My
283 Laser Printer".
284 - "printer-is-accepting-jobs": "true" if the destination is accepting new jobs,
285 "false" otherwise.
286 - "printer-is-shared": "true" if the destination is being shared with other
287 computers, "false" otherwise.
288 - "printer-location": The human-readable location of the destination such as
289 "Lab 4".
290 - "printer-make-and-model": The human-readable make and model of the destination
291 such as "ExampleCorp LaserPrinter 4000 Series".
292 - "printer-state": "3" if the destination is idle, "4" if the destination is
293 printing a job, and "5" if the destination is stopped.
294 - "printer-state-change-time": The UNIX time when the destination entered the
295 current state.
296 - "printer-state-reasons": Additional comma-delimited state keywords for the
297 destination such as "media-tray-empty-error" and "toner-low-warning".
298 - "printer-type": The `cups_ptype_t` value associated with the destination.
299 - "printer-uri-supported": The URI associated with the destination; if not set,
300 this destination was discovered but is not yet setup as a local printer.
301
302 Use the `cupsGetOption` function to retrieve the value. For example, the
303 following code gets the make and model of a destination:
304
305 const char *model = cupsGetOption("printer-make-and-model",
306 dest->num_options,
307 dest->options);
308
309
310 ## Detailed Destination Information
311
312 Once a destination has been chosen, the `cupsCopyDestInfo` function can be used
313 to gather detailed information about the destination:
314
315 cups_dinfo_t *
316 cupsCopyDestInfo(http_t *http, cups_dest_t *dest);
317
318 The `http` argument specifies a connection to the CUPS scheduler and is
319 typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the
320 destination to query.
321
322 The `cups_dinfo_t` structure that is returned contains a snapshot of the
323 supported options and their supported, ready, and default values. It also can
324 report constraints between different options and values, and recommend changes
325 to resolve those constraints.
326
327
328 ### Getting Supported Options and Values
329
330 The `cupsCheckDestSupported` function can be used to test whether a particular
331 option or option and value is supported:
332
333 int
334 cupsCheckDestSupported(http_t *http, cups_dest_t *dest,
335 cups_dinfo_t *info,
336 const char *option,
337 const char *value);
338
339 The `option` argument specifies the name of the option to check. The following
340 constants can be used to check the various standard options:
341
342 - `CUPS_COPIES`: Controls the number of copies that are produced.
343 - `CUPS_FINISHINGS`: A comma-delimited list of integer constants that control
344 the finishing processes that are applied to the job, including stapling,
345 punching, and folding.
346 - `CUPS_MEDIA`: Controls the media size that is used, typically one of the
347 following: `CUPS_MEDIA_3X5`, `CUPS_MEDIA_4X6`, `CUPS_MEDIA_5X7`,
348 `CUPS_MEDIA_8X10`, `CUPS_MEDIA_A3`, `CUPS_MEDIA_A4`, `CUPS_MEDIA_A5`,
349 `CUPS_MEDIA_A6`, `CUPS_MEDIA_ENV10`, `CUPS_MEDIA_ENVDL`, `CUPS_MEDIA_LEGAL`,
350 `CUPS_MEDIA_LETTER`, `CUPS_MEDIA_PHOTO_L`, `CUPS_MEDIA_SUPERBA3`, or
351 `CUPS_MEDIA_TABLOID`.
352 - `CUPS_MEDIA_SOURCE`: Controls where the media is pulled from, typically either
353 `CUPS_MEDIA_SOURCE_AUTO` or `CUPS_MEDIA_SOURCE_MANUAL`.
354 - `CUPS_MEDIA_TYPE`: Controls the type of media that is used, typically one of
355 the following: `CUPS_MEDIA_TYPE_AUTO`, `CUPS_MEDIA_TYPE_ENVELOPE`,
356 `CUPS_MEDIA_TYPE_LABELS`, `CUPS_MEDIA_TYPE_LETTERHEAD`,
357 `CUPS_MEDIA_TYPE_PHOTO`, `CUPS_MEDIA_TYPE_PHOTO_GLOSSY`,
358 `CUPS_MEDIA_TYPE_PHOTO_MATTE`, `CUPS_MEDIA_TYPE_PLAIN`, or
359 `CUPS_MEDIA_TYPE_TRANSPARENCY`.
360 - `CUPS_NUMBER_UP`: Controls the number of document pages that are placed on
361 each media side.
362 - `CUPS_ORIENTATION`: Controls the orientation of document pages placed on the
363 media: `CUPS_ORIENTATION_PORTRAIT` or `CUPS_ORIENTATION_LANDSCAPE`.
364 - `CUPS_PRINT_COLOR_MODE`: Controls whether the output is in color
365 \(`CUPS_PRINT_COLOR_MODE_COLOR`), grayscale
366 \(`CUPS_PRINT_COLOR_MODE_MONOCHROME`), or either
367 \(`CUPS_PRINT_COLOR_MODE_AUTO`).
368 - `CUPS_PRINT_QUALITY`: Controls the generate quality of the output:
369 `CUPS_PRINT_QUALITY_DRAFT`, `CUPS_PRINT_QUALITY_NORMAL`, or
370 `CUPS_PRINT_QUALITY_HIGH`.
371 - `CUPS_SIDES`: Controls whether prints are placed on one or both sides of the
372 media: `CUPS_SIDES_ONE_SIDED`, `CUPS_SIDES_TWO_SIDED_PORTRAIT`, or
373 `CUPS_SIDES_TWO_SIDED_LANDSCAPE`.
374
375 If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns
376 whether the option is supported by the destination. Otherwise, the function
377 returns whether the specified value of the option is supported.
378
379 The `cupsFindDestSupported` function returns the IPP attribute containing the
380 supported values for a given option:
381
382 ipp_attribute_t *
383 cupsFindDestSupported(http_t *http, cups_dest_t *dest,
384 cups_dinfo_t *dinfo,
385 const char *option);
386
387 For example, the following code prints the supported finishing processes for a
388 destination, if any, to the standard output:
389
390 cups_dinfo_t *info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT,
391 dest);
392
393 if (cupsCheckDestSupported(CUPS_HTTP_DEFAULT, dest, info,
394 CUPS_FINISHINGS, NULL))
395 {
396 ipp_attribute_t *finishings =
397 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
398 CUPS_FINISHINGS);
399 int i, count = ippGetCount(finishings);
400
401 puts("finishings supported:");
402 for (i = 0; i < count; i ++)
403 printf(" %d\n", ippGetInteger(finishings, i));
404 }
405 else
406 puts("finishings not supported.");
407
408 The "job-creation-attributes" option can be queried to get a list of supported
409 options. For example, the following code prints the list of supported options
410 to the standard output:
411
412 ipp_attribute_t *attrs =
413 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
414 "job-creation-attributes");
415 int i, count = ippGetCount(attrs);
416
417 for (i = 0; i < count; i ++)
418 puts(ippGetString(attrs, i, NULL));
419
420
421 ### Getting Default Values
422
423 There are two sets of default values - user defaults that are available via the
424 `num_options` and `options` members of the `cups_dest_t` structure, and
425 destination defaults that available via the `cups_dinfo_t` structure and the
426 `cupsFindDestDefault` function which returns the IPP attribute containing the
427 default value(s) for a given option:
428
429 ipp_attribute_t *
430 cupsFindDestDefault(http_t *http, cups_dest_t *dest,
431 cups_dinfo_t *dinfo,
432 const char *option);
433
434 The user defaults from `cupsGetOption` should always take preference over the
435 destination defaults. For example, the following code prints the default
436 finishings value(s) to the standard output:
437
438 const char *def_value =
439 cupsGetOption(CUPS_FINISHINGS, dest->num_options,
440 dest->options);
441 ipp_attribute_t *def_attr =
442 cupsFindDestDefault(CUPS_HTTP_DEFAULT, dest, info,
443 CUPS_FINISHINGS);
444
445 if (def_value != NULL)
446 {
447 printf("Default finishings: %s\n", def_value);
448 }
449 else
450 {
451 int i, count = ippGetCount(def_attr);
452
453 printf("Default finishings: %d",
454 ippGetInteger(def_attr, 0));
455 for (i = 1; i < count; i ++)
456 printf(",%d", ippGetInteger(def_attr, i));
457 putchar('\n');
458 }
459
460
461 ### Getting Ready (Loaded) Values
462
463 The finishings and media options also support queries for the ready, or loaded,
464 values. For example, a printer may have punch and staple finishers installed
465 but be out of staples - the supported values will list both punch and staple
466 finishing processes but the ready values will only list the punch processes.
467 Similarly, a printer may support hundreds of different sizes of media but only
468 have a single size loaded at any given time - the ready values are limited to
469 the media that is actually in the printer.
470
471 The `cupsFindDestReady` function finds the IPP attribute containing the ready
472 values for a given option:
473
474 ipp_attribute_t *
475 cupsFindDestReady(http_t *http, cups_dest_t *dest,
476 cups_dinfo_t *dinfo, const char *option);
477
478 For example, the following code lists the ready finishing processes:
479
480 ipp_attribute_t *ready_finishings =
481 cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info,
482 CUPS_FINISHINGS);
483
484 if (ready_finishings != NULL)
485 {
486 int i, count = ippGetCount(ready_finishings);
487
488 puts("finishings ready:");
489 for (i = 0; i < count; i ++)
490 printf(" %d\n", ippGetInteger(ready_finishings, i));
491 }
492 else
493 puts("no finishings are ready.");
494
495
496 ### Media Size Options
497
498 CUPS provides functions for querying the dimensions and margins for each of the
499 supported media size options. The `cups_size_t` structure is used to describe a
500 media size:
501
502 typedef struct cups_size_s
503 {
504 char media[128];
505 int width, length;
506 int bottom, left, right, top;
507 } cups_size_t;
508
509 The `width` and `length` members specify the dimensions of the media in
510 hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`,
511 and `top` members specify the margins of the printable area, also in hundredths
512 of millimeters.
513
514 The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the
515 media size information using a standard media size name or dimensions in
516 hundredths of millimeters:
517
518 int
519 cupsGetDestMediaByName(http_t *http, cups_dest_t *dest,
520 cups_dinfo_t *dinfo,
521 const char *media,
522 unsigned flags, cups_size_t *size);
523
524 int
525 cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest,
526 cups_dinfo_t *dinfo,
527 int width, int length,
528 unsigned flags, cups_size_t *size);
529
530 The `media`, `width`, and `length` arguments specify the size to lookup. The
531 `flags` argument specifies a bitfield controlling various lookup options:
532
533 - `CUPS_MEDIA_FLAGS_DEFAULT`: Find the closest size supported by the printer.
534 - `CUPS_MEDIA_FLAGS_BORDERLESS`: Find a borderless size.
535 - `CUPS_MEDIA_FLAGS_DUPLEX`: Find a size compatible with two-sided printing.
536 - `CUPS_MEDIA_FLAGS_EXACT`: Find an exact match for the size.
537 - `CUPS_MEDIA_FLAGS_READY`: If the printer supports media sensing or
538 configuration of the media in each tray/source, find the size amongst the
539 "ready" media.
540
541 If a matching size is found for the destination, the size information is stored
542 in the structure pointed to by the `size` argument and 1 is returned. Otherwise
543 0 is returned.
544
545 For example, the following code prints the margins for two-sided printing on US
546 Letter media:
547
548 cups_size_t size;
549
550 if (cupsGetDestMediaByName(CUPS_HTTP_DEFAULT, dest, info,
551 CUPS_MEDIA_LETTER,
552 CUPS_MEDIA_FLAGS_DUPLEX, &size))
553 {
554 puts("Margins for duplex US Letter:");
555 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
556 printf(" Left: %.2fin\n", size.left / 2540.0);
557 printf(" Right: %.2fin\n", size.right / 2540.0);
558 printf(" Top: %.2fin\n", size.top / 2540.0);
559 }
560 else
561 puts("Margins for duplex US Letter are not available.");
562
563 You can also enumerate all of the sizes that match a given `flags` value using
564 the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions:
565
566 int
567 cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest,
568 cups_dinfo_t *dinfo, int n,
569 unsigned flags, cups_size_t *size);
570
571 int
572 cupsGetDestMediaCount(http_t *http, cups_dest_t *dest,
573 cups_dinfo_t *dinfo, unsigned flags);
574
575 For example, the following code prints the list of ready media and corresponding
576 margins:
577
578 cups_size_t size;
579 int i;
580 int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT,
581 dest, info,
582 CUPS_MEDIA_FLAGS_READY);
583
584 for (i = 0; i < count; i ++)
585 {
586 if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, info,
587 i, CUPS_MEDIA_FLAGS_READY,
588 &size))
589 {
590 printf("%s:\n", size.name);
591 printf(" Width: %.2fin\n", size.width / 2540.0);
592 printf(" Length: %.2fin\n", size.length / 2540.0);
593 printf(" Bottom: %.2fin\n", size.bottom / 2540.0);
594 printf(" Left: %.2fin\n", size.left / 2540.0);
595 printf(" Right: %.2fin\n", size.right / 2540.0);
596 printf(" Top: %.2fin\n", size.top / 2540.0);
597 }
598 }
599
600 Finally, the `cupsGetDestMediaDefault` function returns the default media size:
601
602 int
603 cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest,
604 cups_dinfo_t *dinfo, unsigned flags,
605 cups_size_t *size);
606
607
608 ### Localizing Options and Values
609
610 CUPS provides three functions to get localized, human-readable strings in the
611 user's current locale for options and values: `cupsLocalizeDestMedia`,
612 `cupsLocalizeDestOption`, and `cupsLocalizeDestValue`:
613
614 const char *
615 cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest,
616 cups_dinfo_t *info, unsigned flags,
617 cups_size_t *size);
618
619 const char *
620 cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
621 cups_dinfo_t *info,
622 const char *option);
623
624 const char *
625 cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
626 cups_dinfo_t *info,
627 const char *option, const char *value);
628
629
630 ## Submitting a Print Job
631
632 Once you are ready to submit a print job, you create a job using the
633 `cupsCreateDestJob` function:
634
635 ipp_status_t
636 cupsCreateDestJob(http_t *http, cups_dest_t *dest,
637 cups_dinfo_t *info, int *job_id,
638 const char *title, int num_options,
639 cups_option_t *options);
640
641 The `title` argument specifies a name for the print job such as "My Document".
642 The `num_options` and `options` arguments specify the options for the print
643 job which are allocated using the `cupsAddOption` function.
644
645 When successful, the job's numeric identifier is stored in the integer pointed
646 to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP
647 error status is returned.
648
649 For example, the following code creates a new job that will print 42 copies of a
650 two-sided US Letter document:
651
652 int job_id = 0;
653 int num_options = 0;
654 cups_option_t *options = NULL;
655
656 num_options = cupsAddOption(CUPS_COPIES, "42",
657 num_options, &options);
658 num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_LETTER,
659 num_options, &options);
660 num_options = cupsAddOption(CUPS_SIDES,
661 CUPS_SIDES_TWO_SIDED_PORTRAIT,
662 num_options, &options);
663
664 if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info,
665 &job_id, "My Document", num_options,
666 options) == IPP_STATUS_OK)
667 printf("Created job: %d\n", job_id);
668 else
669 printf("Unable to create job: %s\n",
670 cupsLastErrorString());
671
672 Once the job is created, you submit documents for the job using the
673 `cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument`
674 functions:
675
676 http_status_t
677 cupsStartDestDocument(http_t *http, cups_dest_t *dest,
678 cups_dinfo_t *info, int job_id,
679 const char *docname,
680 const char *format,
681 int num_options,
682 cups_option_t *options,
683 int last_document);
684
685 http_status_t
686 cupsWriteRequestData(http_t *http, const char *buffer,
687 size_t length);
688
689 ipp_status_t
690 cupsFinishDestDocument(http_t *http, cups_dest_t *dest,
691 cups_dinfo_t *info);
692
693 The `docname` argument specifies the name of the document, typically the
694 original filename. The `format` argument specifies the MIME media type of the
695 document, including the following constants:
696
697 - `CUPS_FORMAT_JPEG`: "image/jpeg"
698 - `CUPS_FORMAT_PDF`: "application/pdf"
699 - `CUPS_FORMAT_POSTSCRIPT`: "application/postscript"
700 - `CUPS_FORMAT_TEXT`: "text/plain"
701
702 The `num_options` and `options` arguments specify per-document print options,
703 which at present must be 0 and `NULL`. The `last_document` argument specifies
704 whether this is the last document in the job.
705
706 For example, the following code submits a PDF file to the job that was just
707 created:
708
709 FILE *fp = fopen("filename.pdf", "rb");
710 size_t bytes;
711 char buffer[65536];
712
713 if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info,
714 job_id, "filename.pdf", 0, NULL,
715 1) == HTTP_STATUS_CONTINUE)
716 {
717 while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
718 if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer,
719 bytes) != HTTP_STATUS_CONTINUE)
720 break;
721
722 if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest,
723 info) == IPP_STATUS_OK)
724 puts("Document send succeeded.");
725 else
726 printf("Document send failed: %s\n",
727 cupsLastErrorString());
728 }
729
730 fclose(fp);
731
732
733 # Sending IPP Requests
734
735 CUPS provides a rich API for sending IPP requests to the scheduler or printers,
736 typically from management or utility applications whose primary purpose is not
737 to send print jobs.
738
739
740 ## Connecting to the Scheduler or Printer
741
742 The connection to the scheduler or printer is represented by the HTTP connection
743 type `http_t`. The `cupsConnectDest` function connects to the scheduler or
744 printer associated with the destination:
745
746 http_t *
747 cupsConnectDest(cups_dest_t *dest, unsigned flags, int msec,
748 int *cancel, char *resource,
749 size_t resourcesize, cups_dest_cb_t cb,
750 void *user_data);
751
752 The `dest` argument specifies the destination to connect to.
753
754 The `flags` argument specifies whether you want to connect to the scheduler
755 (`CUPS_DEST_FLAGS_NONE`) or device/printer (`CUPS_DEST_FLAGS_DEVICE`) associated
756 with the destination.
757
758 The `msec` argument specifies how long you are willing to wait for the
759 connection to be established in milliseconds. Specify a value of `-1` to wait
760 indefinitely.
761
762 The `cancel` argument specifies the address of an integer variable that can be
763 set to a non-zero value to cancel the connection. Specify a value of `NULL`
764 to not provide a cancel variable.
765
766 The `resource` and `resourcesize` arguments specify the address and size of a
767 character string array to hold the path to use when sending an IPP request.
768
769 The `cb` and `user_data` arguments specify a destination callback function that
770 returns 1 to continue connecting or 0 to stop. The destination callback work
771 the same way as the one used for the `cupsEnumDests` function.
772
773 On success, a HTTP connection is returned that can be used to send IPP requests
774 and get IPP responses.
775
776 For example, the following code connects to the printer associated with a
777 destination with a 30 second timeout:
778
779 char resource[256];
780 http_t *http = cupsConnectDest(dest, CUPS_DEST_FLAGS_DEVICE,
781 30000, NULL, resource,
782 sizeof(resource), NULL, NULL);
783
784
785 ## Creating an IPP Request
786
787 IPP requests are represented by the IPP message type `ipp_t` and each IPP
788 attribute in the request is representing using the type `ipp_attribute_t`. Each
789 IPP request includes an operation code (`IPP_OP_CREATE_JOB`,
790 `IPP_OP_GET_PRINTER_ATTRIBUTES`, etc.) and a 32-bit integer identifier.
791
792 The `ippNewRequest` function creates a new IPP request:
793
794 ipp_t *
795 ippNewRequest(ipp_op_t op);
796
797 The `op` argument specifies the IPP operation code for the request. For
798 example, the following code creates an IPP Get-Printer-Attributes request:
799
800 ipp_t *request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
801
802 The request identifier is automatically set to a unique value for the current
803 process.
804
805 Each IPP request starts with two IPP attributes, "attributes-charset" and
806 "attributes-natural-language", followed by IPP attribute(s) that specify the
807 target of the operation. The `ippNewRequest` automatically adds the correct
808 "attributes-charset" and "attributes-natural-language" attributes, but you must
809 add the target attribute(s). For example, the following code adds the
810 "printer-uri" attribute to the IPP Get-Printer-Attributes request to specify
811 which printer is being queried:
812
813 const char *printer_uri = cupsGetOption("device-uri",
814 dest->num_options,
815 dest->options);
816
817 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
818 "printer-uri", NULL, printer_uri);
819
820 > Note: If we wanted to query the scheduler instead of the device, we would look
821 > up the "printer-uri-supported" option instead of the "device-uri" value.
822
823 The `ippAddString` function adds the "printer-uri" attribute the the IPP
824 request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part
825 of the operation. The `IPP_TAG_URI` argument specifies that the value is a
826 Universal Resource Identifier (URI) string. The `NULL` argument specifies there
827 is no language (English, French, Japanese, etc.) associated with the string, and
828 the `printer_uri` argument specifies the string value.
829
830 The IPP Get-Printer-Attributes request also supports an IPP attribute called
831 "requested-attributes" that lists the attributes and values you are interested
832 in. For example, the following code requests the printer state attributes:
833
834 static const char * const requested_attributes[] =
835 {
836 "printer-state",
837 "printer-state-message",
838 "printer-state-reasons"
839 };
840
841 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
842 "requested-attributes", 3, NULL,
843 requested_attributes);
844
845 The `ippAddStrings` function adds an attribute with one or more strings, in this
846 case three. The `IPP_TAG_KEYWORD` argument specifies that the strings are
847 keyword values, which are used for attribute names. All strings use the same
848 language (`NULL`), and the attribute will contain the three strings in the
849 array `requested_attributes`.
850
851 CUPS provides many functions to adding attributes of different types:
852
853 - `ippAddBoolean` adds a boolean (`IPP_TAG_BOOLEAN`) attribute with one value.
854 - `ippAddInteger` adds an enum (`IPP_TAG_ENUM`) or integer (`IPP_TAG_INTEGER`)
855 attribute with one value.
856 - `ippAddIntegers` adds an enum or integer attribute with one or more values.
857 - `ippAddOctetString` adds an octetString attribute with one value.
858 - `ippAddOutOfBand` adds a admin-defined (`IPP_TAG_ADMINDEFINE`), default
859 (`IPP_TAG_DEFAULT`), delete-attribute (`IPP_TAG_DELETEATTR`), no-value
860 (`IPP_TAG_NOVALUE`), not-settable (`IPP_TAG_NOTSETTABLE`), unknown
861 (`IPP_TAG_UNKNOWN`), or unsupported (`IPP_TAG_UNSUPPORTED_VALUE`) out-of-band
862 attribute.
863 - `ippAddRange` adds a rangeOfInteger attribute with one range.
864 - `ippAddRanges` adds a rangeOfInteger attribute with one or more ranges.
865 - `ippAddResolution` adds a resolution attribute with one resolution.
866 - `ippAddResolutions` adds a resolution attribute with one or more resolutions.
867 - `ippAddString` adds a charset (`IPP_TAG_CHARSET`), keyword (`IPP_TAG_KEYWORD`),
868 mimeMediaType (`IPP_TAG_MIMETYPE`), name (`IPP_TAG_NAME` and
869 `IPP_TAG_NAMELANG`), naturalLanguage (`IPP_TAG_NATURAL_LANGUAGE`), text
870 (`IPP_TAG_TEXT` and `IPP_TAG_TEXTLANG`), uri (`IPP_TAG_URI`), or uriScheme
871 (`IPP_TAG_URISCHEME`) attribute with one value.
872 - `ippAddStrings` adds a charset, keyword, mimeMediaType, name, naturalLanguage,
873 text, uri, or uriScheme attribute with one or more values.
874
875
876 ## Sending the IPP Request
877
878 Once you have created the IPP request, you can send it using the
879 `cupsDoRequest` function. For example, the following code sends the IPP
880 Get-Printer-Attributes request to the destination and saves the response:
881
882 ipp_t *response = cupsDoRequest(http, request, resource);
883
884 For requests like Send-Document that include a file, the `cupsDoFileRequest`
885 function should be used:
886
887 ipp_t *response = cupsDoFileRequest(http, request, resource,
888 filename);
889
890 Both `cupsDoRequest` and `cupsDoFileRequest` free the IPP request. If a valid
891 IPP response is received, it is stored in a new IPP message (`ipp_t`) and
892 returned to the caller. Otherwise `NULL` is returned.
893
894 The status from the most recent request can be queried using the `cupsLastError`
895 function, for example:
896
897 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
898 {
899 /* request failed */
900 }
901
902 A human-readable error message is also available using the `cupsLastErrorString`
903 function:
904
905 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
906 {
907 /* request failed */
908 printf("Request failed: %s\n", cupsLastErrorString());
909 }
910
911
912 ## Processing the IPP Response
913
914 Each response to an IPP request is also an IPP message (`ipp_t`) with its own
915 IPP attributes (`ipp_attribute_t`) that includes a status code (`IPP_STATUS_OK`,
916 `IPP_STATUS_ERROR_BAD_REQUEST`, etc.) and the corresponding 32-bit integer
917 identifier from the request.
918
919 For example, the following code finds the printer state attributes and prints
920 their values:
921
922 ipp_attribute_t *attr;
923
924 if ((attr = ippFindAttribute(response, "printer-state",
925 IPP_TAG_ENUM)) != NULL)
926 {
927 printf("printer-state=%s\n",
928 ippEnumString("printer-state", ippGetInteger(attr, 0)));
929 }
930 else
931 puts("printer-state=unknown");
932
933 if ((attr = ippFindAttribute(response, "printer-state-message",
934 IPP_TAG_TEXT)) != NULL)
935 {
936 printf("printer-state-message=\"%s\"\n",
937 ippGetString(attr, 0, NULL)));
938 }
939
940 if ((attr = ippFindAttribute(response, "printer-state-reasons",
941 IPP_TAG_KEYWORD)) != NULL)
942 {
943 int i, count = ippGetCount(attr);
944
945 puts("printer-state-reasons=");
946 for (i = 0; i < count; i ++)
947 printf(" %s\n", ippGetString(attr, i, NULL)));
948 }
949
950 The `ippGetCount` function returns the number of values in an attribute.
951
952 The `ippGetInteger` and `ippGetString` functions return a single integer or
953 string value from an attribute.
954
955 The `ippEnumString` function converts a enum value to its keyword (string)
956 equivalent.
957
958 Once you are done using the IPP response message, free it using the `ippDelete`
959 function:
960
961 ippDelete(response);
962
963
964 ## Authentication
965
966 CUPS normally handles authentication through the console. GUI applications
967 should set a password callback using the `cupsSetPasswordCB2` function:
968
969 void
970 cupsSetPasswordCB2(cups_password_cb2_t cb, void *user_data);
971
972 The password callback will be called when needed and is responsible for setting
973 the current user name using `cupsSetUser` and returning a string:
974
975 const char *
976 cups_password_cb2(const char *prompt, http_t *http,
977 const char *method, const char *resource,
978 void *user_data);
979
980 The `prompt` argument is a string from CUPS that should be displayed to the
981 user.
982
983 The `http` argument is the connection hosting the request that is being
984 authenticated. The password callback can call the `httpGetField` and
985 `httpGetSubField` functions to look for additional details concerning the
986 authentication challenge.
987
988 The `method` argument specifies the HTTP method used for the request and is
989 typically "POST".
990
991 The `resource` argument specifies the path used for the request.
992
993 The `user_data` argument provides the user data pointer from the
994 `cupsSetPasswordCB2` call.