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