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