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