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