]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/cupspm.md
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[thirdparty/cups.git] / cups / cupspm.md
CommitLineData
abacc52b
MS
1---
2title: CUPS Programming Manual
3author: Michael R Sweet
859ea448
SA
4copyright: Copyright © 2007-2022 by Apple Inc. All Rights Reserved.
5version: 2.3.6
abacc52b
MS
6...
7
1da024d1
MS
8> Please [file issues on Github](https://github.com/apple/cups/issues) to
9> provide feedback on this document.
798d6e29
MS
10
11
abacc52b
MS
12# Introduction
13
14CUPS provides the "cups" library to talk to the different parts of CUPS and with
15Internet Printing Protocol (IPP) printers. The "cups" library functions are
16accessed by including the `<cups/cups.h>` header.
17
18CUPS is based on the Internet Printing Protocol ("IPP"), which allows clients
19(applications) to communicate with a server (the scheduler, printers, etc.) to
20get a list of destinations, send print jobs, and so forth. You identify which
21server 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
23the CUPS scheduler.
24
25
26## Guidelines
27
73721e3e 28When writing software (other than printer drivers) that uses the "cups" library:
abacc52b
MS
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
35CUPS is designed to insulate users and developers from the implementation
36details of printers and file formats. The goal is to allow an application to
37supply a print file in a standard format with the user intent ("print four
38copies, two-sided on A4 media, and staple each copy") and have the printing
39system manage the printer communication and format conversion needed.
40
41Similarly, printer and job management applications can use standard query
42operations to obtain the status information in a common, generic form and use
43standard management operations to control the state of those printers and jobs.
44
73721e3e
MS
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
abacc52b
MS
52
53## Terms Used in This Document
54
55A *Destination* is a printer or print queue that accepts print jobs. A
73721e3e
MS
56*Print Job* is a collection of one or more documents that are processed by a
57destination using options supplied when creating the job. A *Document* is a
58file (JPEG image, PDF file, etc.) suitable for printing. An *Option* controls
59some aspect of printing, such as the media used. *Media* is the sheets or roll
60that is printed on. An *Attribute* is an option encoded for an Internet
61Printing Protocol (IPP) request.
abacc52b
MS
62
63
64## Compiling Programs That Use the CUPS API
65
66The CUPS libraries can be used from any C, C++, or Objective C program.
67The method of compiling against the libraries varies depending on the
68operating system and installation of CUPS. The following sections show how
69to compile a simple program (shown below) in two common environments.
70
71The 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
96In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N),
97then select the *Command Line Tool* under the macOS Application project type.
98Click *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
101In the project window, click on the *Build Phases* group and expand the
102*Link Binary with Libraries* section. Click *+*, type "libcups" to show the
103library, and then double-click on `libcups.tbd`.
104
105Finally, click on the `main.c` file in the sidebar and copy the example program
106to the file. Build and run (CMD+R) to see the list of destinations.
107
108
109### Compiling with GCC
110
bea505c3 111From the command-line, create a file called `simple.c` using your favorite
abacc52b
MS
112editor, copy the example to this file, and save. Then run the following command
113to compile it with GCC and run it:
114
115 gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
116 ./simple
117
118The `cups-config` command provides the compiler flags (`cups-config --cflags`)
119and libraries (`cups-config --libs`) needed for the local system.
120
121
122# Working with Destinations
123
798d6e29 124Destinations, which in CUPS represent individual printers or classes
9c44e2cb
MS
125(collections or pools) of printers, are represented by the `cups_dest_t`
126structure which includes the name \(`name`), instance \(`instance`, saved
127options/settings), whether the destination is the default for the user
128\(`is_default`), and the options and basic information associated with that
129destination \(`num_options` and `options`).
abacc52b 130
798d6e29
MS
131Historically destinations have been manually maintained by the administrator of
132a system or network, but CUPS also supports dynamic discovery of destinations on
133the current network.
abacc52b 134
abacc52b 135
798d6e29 136## Finding Available Destinations
abacc52b 137
798d6e29
MS
138The `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
145The `flags` argument specifies enumeration options, which at present must be
146`CUPS_DEST_FLAGS_NONE`.
147
148The `msec` argument specifies the maximum amount of time that should be used for
149enumeration in milliseconds - interactive applications should keep this value to
1505000 or less when run on the main thread.
151
152The `cancel` argument points to an integer variable that, when set to a non-zero
153value, will cause enumeration to stop as soon as possible. It can be `NULL` if
154not needed.
155
156The `type` and `mask` arguments are bitfields that allow the caller to filter
157the 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`
159value when filtering. For example, to only enumerate destinations that are
160hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument
f50db552
MS
161and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants
162can be used for filtering:
798d6e29
MS
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
f50db552
MS
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.
798d6e29
MS
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
186The `cb` argument specifies a function to call for every destination that is
187found:
188
189 typedef int (*cups_dest_cb_t)(void *user_data,
190 unsigned flags,
191 cups_dest_t *dest);
192
193The callback function receives a copy of the `user_data` argument along with a
194bitfield \(`flags`) and the destination that was found. The `flags` argument
195can 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
203The callback function returns 0 to stop enumeration or 1 to continue.
204
73721e3e
MS
205> **Note:**
206>
207> The callback function will likely be called multiple times for the
500fca27
MS
208> same destination, so it is up to the caller to suppress any duplicate
209> destinations.
210
798d6e29
MS
211The following example shows how to use `cupsEnumDests` to get a filtered array
212of destinations:
213
214 typedef struct
215 {
216 int num_dests;
217 cups_dest_t *dests;
218 } my_user_data_t;
abacc52b 219
798d6e29
MS
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 */
abacc52b 240
798d6e29
MS
241 user_data->num_dests =
242 cupsCopyDest(dest, user_data->num_dests,
243 &(user_data->dests));
244 }
abacc52b 245
798d6e29
MS
246 return (1);
247 }
abacc52b 248
798d6e29
MS
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 };
abacc52b 254
798d6e29
MS
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 */
abacc52b 263
798d6e29 264 cupsFreeDests(user_data.num_dests, user_dasta.dests);
abacc52b 265
798d6e29 266 *dests = NULL;
abacc52b 267
798d6e29
MS
268 return (0);
269 }
abacc52b 270
798d6e29
MS
271 /*
272 * Return the destination array...
273 */
abacc52b 274
798d6e29 275 *dests = user_data.dests;
abacc52b 276
798d6e29
MS
277 return (user_data.num_dests);
278 }
abacc52b 279
abacc52b 280
798d6e29
MS
281## Basic Destination Information
282
283The `num_options` and `options` members of the `cups_dest_t` structure provide
284basic attributes about the destination in addition to the user default options
285and values for that destination. The following names are predefined for various
286destination 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.
53af7f21
MS
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.
798d6e29
MS
310
311Use the `cupsGetOption` function to retrieve the value. For example, the
312following 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
53af7f21 318
798d6e29
MS
319## Detailed Destination Information
320
321Once a destination has been chosen, the `cupsCopyDestInfo` function can be used
322to gather detailed information about the destination:
323
324 cups_dinfo_t *
325 cupsCopyDestInfo(http_t *http, cups_dest_t *dest);
326
327The `http` argument specifies a connection to the CUPS scheduler and is
328typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the
329destination to query.
330
331The `cups_dinfo_t` structure that is returned contains a snapshot of the
332supported options and their supported, ready, and default values. It also can
333report constraints between different options and values, and recommend changes
334to resolve those constraints.
abacc52b 335
53af7f21 336
798d6e29 337### Getting Supported Options and Values
abacc52b 338
798d6e29
MS
339The `cupsCheckDestSupported` function can be used to test whether a particular
340option 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
348The `option` argument specifies the name of the option to check. The following
349constants 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
384If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns
385whether the option is supported by the destination. Otherwise, the function
386returns whether the specified value of the option is supported.
387
388The `cupsFindDestSupported` function returns the IPP attribute containing the
389supported 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
396For example, the following code prints the supported finishing processes for a
397destination, 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.");
abacc52b 416
798d6e29
MS
417The "job-creation-attributes" option can be queried to get a list of supported
418options. For example, the following code prints the list of supported options
419to the standard output:
abacc52b 420
798d6e29
MS
421 ipp_attribute_t *attrs =
422 cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info,
423 "job-creation-attributes");
424 int i, count = ippGetCount(attrs);
abacc52b 425
798d6e29
MS
426 for (i = 0; i < count; i ++)
427 puts(ippGetString(attrs, i, NULL));
abacc52b
MS
428
429
798d6e29 430### Getting Default Values
abacc52b 431
798d6e29
MS
432There 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
434destination defaults that available via the `cups_dinfo_t` structure and the
435`cupsFindDestDefault` function which returns the IPP attribute containing the
436default value(s) for a given option:
abacc52b 437
798d6e29
MS
438 ipp_attribute_t *
439 cupsFindDestDefault(http_t *http, cups_dest_t *dest,
440 cups_dinfo_t *dinfo,
441 const char *option);
abacc52b 442
798d6e29
MS
443The user defaults from `cupsGetOption` should always take preference over the
444destination defaults. For example, the following code prints the default
445finishings value(s) to the standard output:
abacc52b 446
798d6e29
MS
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);
abacc52b 453
798d6e29
MS
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);
abacc52b 461
798d6e29
MS
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 }
abacc52b
MS
468
469
798d6e29 470### Getting Ready (Loaded) Values
abacc52b 471
798d6e29
MS
472The finishings and media options also support queries for the ready, or loaded,
473values. For example, a printer may have punch and staple finishers installed
474but be out of staples - the supported values will list both punch and staple
475finishing processes but the ready values will only list the punch processes.
476Similarly, a printer may support hundreds of different sizes of media but only
477have a single size loaded at any given time - the ready values are limited to
478the media that is actually in the printer.
abacc52b 479
798d6e29
MS
480The `cupsFindDestReady` function finds the IPP attribute containing the ready
481values for a given option:
abacc52b 482
798d6e29
MS
483 ipp_attribute_t *
484 cupsFindDestReady(http_t *http, cups_dest_t *dest,
485 cups_dinfo_t *dinfo, const char *option);
abacc52b 486
798d6e29 487For example, the following code lists the ready finishing processes:
abacc52b 488
798d6e29
MS
489 ipp_attribute_t *ready_finishings =
490 cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info,
491 CUPS_FINISHINGS);
abacc52b 492
798d6e29
MS
493 if (ready_finishings != NULL)
494 {
495 int i, count = ippGetCount(ready_finishings);
abacc52b 496
798d6e29
MS
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.");
abacc52b 503
abacc52b 504
798d6e29 505### Media Size Options
abacc52b 506
798d6e29
MS
507CUPS provides functions for querying the dimensions and margins for each of the
508supported media size options. The `cups_size_t` structure is used to describe a
509media size:
abacc52b 510
798d6e29
MS
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
518The `width` and `length` members specify the dimensions of the media in
519hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`,
520and `top` members specify the margins of the printable area, also in hundredths
521of millimeters.
522
523The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the
524media size information using a standard media size name or dimensions in
525hundredths 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
539The `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
550If a matching size is found for the destination, the size information is stored
551in the structure pointed to by the `size` argument and 1 is returned. Otherwise
5520 is returned.
553
554For example, the following code prints the margins for two-sided printing on US
555Letter 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))
abacc52b 562 {
798d6e29
MS
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);
abacc52b 568 }
798d6e29
MS
569 else
570 puts("Margins for duplex US Letter are not available.");
abacc52b 571
798d6e29
MS
572You can also enumerate all of the sizes that match a given `flags` value using
573the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions:
abacc52b 574
798d6e29
MS
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);
abacc52b 579
798d6e29
MS
580 int
581 cupsGetDestMediaCount(http_t *http, cups_dest_t *dest,
582 cups_dinfo_t *dinfo, unsigned flags);
abacc52b 583
798d6e29
MS
584For example, the following code prints the list of ready media and corresponding
585margins:
abacc52b 586
798d6e29
MS
587 cups_size_t size;
588 int i;
589 int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT,
590 dest, info,
591 CUPS_MEDIA_FLAGS_READY);
abacc52b 592
798d6e29
MS
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 }
abacc52b 608
798d6e29 609Finally, the `cupsGetDestMediaDefault` function returns the default media size:
abacc52b 610
798d6e29
MS
611 int
612 cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest,
613 cups_dinfo_t *dinfo, unsigned flags,
614 cups_size_t *size);
abacc52b 615
abacc52b 616
798d6e29 617### Localizing Options and Values
abacc52b 618
6ad44eeb
MS
619CUPS provides three functions to get localized, human-readable strings in the
620user's current locale for options and values: `cupsLocalizeDestMedia`,
621`cupsLocalizeDestOption`, and `cupsLocalizeDestValue`:
abacc52b 622
798d6e29
MS
623 const char *
624 cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest,
625 cups_dinfo_t *info, unsigned flags,
626 cups_size_t *size);
abacc52b 627
798d6e29
MS
628 const char *
629 cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
630 cups_dinfo_t *info,
631 const char *option);
abacc52b 632
798d6e29
MS
633 const char *
634 cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
635 cups_dinfo_t *info,
636 const char *option, const char *value);
abacc52b 637
abacc52b 638
798d6e29 639## Submitting a Print Job
abacc52b 640
798d6e29
MS
641Once 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
650The `title` argument specifies a name for the print job such as "My Document".
651The `num_options` and `options` arguments specify the options for the print
652job which are allocated using the `cupsAddOption` function.
653
654When successful, the job's numeric identifier is stored in the integer pointed
655to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP
656error status is returned.
657
658For example, the following code creates a new job that will print 42 copies of a
659two-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
681Once the job is created, you submit documents for the job using the
682`cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument`
683functions:
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
702The `docname` argument specifies the name of the document, typically the
703original filename. The `format` argument specifies the MIME media type of the
704document, 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
711The `num_options` and `options` arguments specify per-document print options,
712which at present must be 0 and `NULL`. The `last_document` argument specifies
713whether this is the last document in the job.
714
715For example, the following code submits a PDF file to the job that was just
716created:
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)
abacc52b 725 {
798d6e29
MS
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());
abacc52b 737 }
798d6e29
MS
738
739 fclose(fp);
65bebeac
MS
740
741
742# Sending IPP Requests
743
b0fb2d75
MS
744CUPS provides a rich API for sending IPP requests to the scheduler or printers,
745typically from management or utility applications whose primary purpose is not
746to send print jobs.
747
748
65bebeac
MS
749## Connecting to the Scheduler or Printer
750
b0fb2d75
MS
751The connection to the scheduler or printer is represented by the HTTP connection
752type `http_t`. The `cupsConnectDest` function connects to the scheduler or
753printer 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
761The `dest` argument specifies the destination to connect to.
762
763The `flags` argument specifies whether you want to connect to the scheduler
764(`CUPS_DEST_FLAGS_NONE`) or device/printer (`CUPS_DEST_FLAGS_DEVICE`) associated
765with the destination.
766
767The `msec` argument specifies how long you are willing to wait for the
768connection to be established in milliseconds. Specify a value of `-1` to wait
769indefinitely.
770
771The `cancel` argument specifies the address of an integer variable that can be
772set to a non-zero value to cancel the connection. Specify a value of `NULL`
773to not provide a cancel variable.
774
775The `resource` and `resourcesize` arguments specify the address and size of a
776character string array to hold the path to use when sending an IPP request.
777
778The `cb` and `user_data` arguments specify a destination callback function that
779returns 1 to continue connecting or 0 to stop. The destination callback work
780the same way as the one used for the `cupsEnumDests` function.
65bebeac 781
b0fb2d75
MS
782On success, a HTTP connection is returned that can be used to send IPP requests
783and get IPP responses.
784
785For example, the following code connects to the printer associated with a
786destination 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);
65bebeac
MS
792
793
794## Creating an IPP Request
795
b0fb2d75
MS
796IPP requests are represented by the IPP message type `ipp_t` and each IPP
797attribute in the request is representing using the type `ipp_attribute_t`. Each
798IPP request includes an operation code (`IPP_OP_CREATE_JOB`,
799`IPP_OP_GET_PRINTER_ATTRIBUTES`, etc.) and a 32-bit integer identifier.
800
801The `ippNewRequest` function creates a new IPP request:
802
803 ipp_t *
804 ippNewRequest(ipp_op_t op);
805
806The `op` argument specifies the IPP operation code for the request. For
807example, the following code creates an IPP Get-Printer-Attributes request:
808
809 ipp_t *request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
810
811The request identifier is automatically set to a unique value for the current
812process.
813
814Each IPP request starts with two IPP attributes, "attributes-charset" and
815"attributes-natural-language", followed by IPP attribute(s) that specify the
816target of the operation. The `ippNewRequest` automatically adds the correct
817"attributes-charset" and "attributes-natural-language" attributes, but you must
818add the target attribute(s). For example, the following code adds the
819"printer-uri" attribute to the IPP Get-Printer-Attributes request to specify
820which 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
73721e3e
MS
829> **Note:**
830>
831> If we wanted to query the scheduler instead of the device, we would look
b0fb2d75
MS
832> up the "printer-uri-supported" option instead of the "device-uri" value.
833
834The `ippAddString` function adds the "printer-uri" attribute the the IPP
835request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part
836of the operation. The `IPP_TAG_URI` argument specifies that the value is a
837Universal Resource Identifier (URI) string. The `NULL` argument specifies there
838is no language (English, French, Japanese, etc.) associated with the string, and
839the `printer_uri` argument specifies the string value.
840
841The IPP Get-Printer-Attributes request also supports an IPP attribute called
842"requested-attributes" that lists the attributes and values you are interested
843in. 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
856The `ippAddStrings` function adds an attribute with one or more strings, in this
857case three. The `IPP_TAG_KEYWORD` argument specifies that the strings are
858keyword values, which are used for attribute names. All strings use the same
859language (`NULL`), and the attribute will contain the three strings in the
860array `requested_attributes`.
861
862CUPS 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
65bebeac
MS
887## Sending the IPP Request
888
b0fb2d75
MS
889Once you have created the IPP request, you can send it using the
890`cupsDoRequest` function. For example, the following code sends the IPP
891Get-Printer-Attributes request to the destination and saves the response:
892
893 ipp_t *response = cupsDoRequest(http, request, resource);
894
895For requests like Send-Document that include a file, the `cupsDoFileRequest`
896function should be used:
897
898 ipp_t *response = cupsDoFileRequest(http, request, resource,
899 filename);
900
901Both `cupsDoRequest` and `cupsDoFileRequest` free the IPP request. If a valid
902IPP response is received, it is stored in a new IPP message (`ipp_t`) and
903returned to the caller. Otherwise `NULL` is returned.
904
905The status from the most recent request can be queried using the `cupsLastError`
906function, for example:
907
908 if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST)
909 {
910 /* request failed */
911 }
912
913A human-readable error message is also available using the `cupsLastErrorString`
914function:
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
925Each response to an IPP request is also an IPP message (`ipp_t`) with its own
926IPP 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
928identifier from the request.
929
930For example, the following code finds the printer state attributes and prints
931their 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",
db5424ea 939 ippEnumString("printer-state", ippGetInteger(attr, 0)));
b0fb2d75
MS
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
961The `ippGetCount` function returns the number of values in an attribute.
962
963The `ippGetInteger` and `ippGetString` functions return a single integer or
964string value from an attribute.
965
db5424ea 966The `ippEnumString` function converts a enum value to its keyword (string)
b0fb2d75
MS
967equivalent.
968
969Once you are done using the IPP response message, free it using the `ippDelete`
970function:
971
972 ippDelete(response);
973
65bebeac
MS
974
975## Authentication
b0fb2d75
MS
976
977CUPS normally handles authentication through the console. GUI applications
978should set a password callback using the `cupsSetPasswordCB2` function:
979
980 void
981 cupsSetPasswordCB2(cups_password_cb2_t cb, void *user_data);
982
983The password callback will be called when needed and is responsible for setting
984the 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
991The `prompt` argument is a string from CUPS that should be displayed to the
992user.
993
994The `http` argument is the connection hosting the request that is being
995authenticated. The password callback can call the `httpGetField` and
996`httpGetSubField` functions to look for additional details concerning the
997authentication challenge.
998
999The `method` argument specifies the HTTP method used for the request and is
1000typically "POST".
1001
1002The `resource` argument specifies the path used for the request.
1003
1004The `user_data` argument provides the user data pointer from the
1005`cupsSetPasswordCB2` call.