Add new API for generic printer options/IPP attributes #3925

michaelrsweet opened this Issue Aug 17, 2011 · 5 comments


None yet
1 participant

michaelrsweet commented Aug 17, 2011

Version: 1.6-feature User: mike

In the continuing march towards IPP Everywhere, we need an API that exposes the supported and default job template attributes along with the constraints.

Initially this will be provided by the existing PPD mapping code, but long term we should be able to simply discover what a printer can handle and act accordingly.


michaelrsweet commented Jan 13, 2012 User: mike

Doing development on cups-api-1.6 branch...

The new PPD replacement APIs address the standard option names and values (all
from IPP/AirPrint) along with getting the supported and "ready" options and
values, media sizes and margins, and localizations of options and values,

/* Number of copies; option values are integers as strings */

#define CUPS_COPIES "copies"

/* Finishings; applied to the job as a whole, also see IPP_FINISHINGS_xxx in
<cups/ipp.h> */

#define CUPS_FINISHINGS "finishings"

/* Media (size); when looking up supported values, CUPS_MEDIA contains all of
the possible values while CUPS_MEDIA_READY contains the media that is loaded
in the printer (if the printer supported media sensing). Use
cupsGetDestMedia to get the dimensions and margins for a given name. */

#define CUPS_MEDIA "media"
#define CUPS_MEDIA_READY "media-ready"
#define CUPS_MEDIA_3X5 "na_index-3x5_3x5in"
#define CUPS_MEDIA_4X6 "na_index-4x6_4x6in"
#define CUPS_MEDIA_5X7 "na_5x7_5x7in"
#define CUPS_MEDIA_8X10 "na_govt-letter_8x10in"
#define CUPS_MEDIA_A3 "iso_a3_297x420mm"
#define CUPS_MEDIA_A4 "iso_a4_210x297mm"
#define CUPS_MEDIA_A5 "iso_a5_148x210mm"
#define CUPS_MEDIA_A6 "iso_a6_105x148mm"
#define CUPS_MEDIA_ENV10 "na_number-10_4.125x9.5in"
#define CUPS_MEDIA_ENVDL "iso_dl_110x220mm"
#define CUPS_MEDIA_LEGAL "na_legal_8.5x14in"
#define CUPS_MEDIA_LETTER "na_letter_8.5x11in"
#define CUPS_MEDIA_PHOTO_L "oe_photo-l_3.5x5in"
#define CUPS_MEDIA_SUPERBA3 "na_super-b_13x19in"
#define CUPS_MEDIA_TABLOID "na_ledger_11x17in"

/* Media source; "auto" is the default */

#define CUPS_MEDIA_SOURCE "media-source"

/* Media type; "auto" is the default */

#define CUPS_MEDIA_TYPE "media-type"
#define CUPS_MEDIA_TYPE_AUTO "auto"
#define CUPS_MEDIA_TYPE_ENVELOPE "envelope"
#define CUPS_MEDIA_TYPE_LABELS "labels"
#define CUPS_MEDIA_TYPE_LETTERHEAD "stationery-letterhead"
#define CUPS_MEDIA_TYPE_PHOTO "photographic"
#define CUPS_MEDIA_TYPE_PHOTO_GLOSSY "photographic-glossy"
#define CUPS_MEDIA_TYPE_PHOTO_MATTE "photographic-matte"
#define CUPS_MEDIA_TYPE_PLAIN "stationery"
#define CUPS_MEDIA_TYPE_TRANSPARENCY "transparency"

/* Number-up; option values are integers as strings */

#define CUPS_NUMBER_UP "number-up"

/* Orientation; also see the ipp_orient_t values in <cups/ipp.h> */

#define CUPS_ORIENTATION "orientation-requested"

/* Color mode; "auto" is the default, "monochrome" and "color" force the
corresponding output. */

#define CUPS_PRINT_COLOR_MODE "print-color-mode"

/* Print quality; also see the IPP_QUALITY_xxx values in <cups/ipp.h> */

#define CUPS_PRINT_QUALITY "print-quality"

/* Duplex mode; long-edge is typically for portrait output and short-edge for
landscape output */

#define CUPS_SIDES "sides"
#define CUPS_SIDES_ONE_SIDED "one-sided"
#define CUPS_SIDES_TWO_SIDED_PORTRAIT "two-sided-long-edge"
#define CUPS_SIDES_TWO_SIDED_LANDSCAPE "two-sided-short-edge"

/* Get the supported values/capabilities for the destination as an IPP
message. The caller is responsible for calling ippDelete() on the
return value. NULL is returned on error.

Replaces ppdOpen */

ipp_t *cupsCopyDestSupported(http_t *http, cups_dest_t *dest);

/* Get media names, dimensions, and margins - replaces ppdPageSize and others.
The "media" string is a PWG media name, while "width" and "length" are the
dimensions in hundredths of millimeters. "flags" provides some matching
guidance (multiple flags can be combined):

CUPS_MEDIA_FLAGS_DEFAULT = find the closest size supported by the printer
CUPS_MEDIA_FLAGS_BORDERLESS = find a borderless size
CUPS_MEDIA_FLAGS_DUPLEX = find a size compatible with 2-sided printing
CUPS_MEDIA_FLAGS_EXACT = find an exact match for the size
CUPS_MEDIA_FLAGS_READY = if the printer supports media sensing, find the
size amongst the "ready" media.

The matching result (if any) is returned in the "cups_size_t" structure.

Returns 1 when there is a match and 0 if there is not a match.


typedef struct _cups_size_s
char media[128]; /* Media name to use /
int width, /
Width in hundredths of millimeters /
length, /
Length in hundredths of millimeters /
bottom. /
Bottom margin in hundredths of millimeters /
left. /
Left margin in hundredths of millimeters /
right, /
Right margin in hundredths of millimeters /
top; /
Top margin in hundredths of millimeters */
} cups_size_t;

int cupsGetDestMediaByName(http_t *http, cups_dest_t *dest, ipp_t *supported,
const char *media, unsigned flags,
cups_size_t *size);
int cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest, ipp_t *supported,
int width, int length, unsigned flags,
cups_size_t *size);

/* Check that the option and value are supported by the destination - replaces
ppdFindChoice() and ppdInstallableConflict(). Returns 1 if supported, 0
otherwise. */

int cupsCheckDestSupported(http_t *http, cups_dest_t *dest, ipp_t *supported,
const char *option, const char *value);

/* Get conflicts and resolutions for a new option/value pair. This single API
replaces ppdConflicts, cupsGetConflicts, and cupsResolveConflicts.

"num_options" and "options" represent the currently selected options by the
user. "new_option" and "new_value" are the setting the user has just

Returns 1 if there is a conflict and 0 otherwise.

If "num_conflicts" and "conflicts" are not NULL, they are set to contain the
list of conflicting option/value pairs. Similarly, if "num_resolved" and
"resolved" are not NULL they will be set to the list of changes needed to
resolve the conflict.

If cupsCopyDestConflicts returns 1 but "num_resolved" and "resolved" are set
to 0 and NULL, respectively, then the conflict cannot be resolved. */

int cupsCopyDestConflicts(http_t _http, cups_dest_t *dest, ipp_t *supported,
int num_options, cups_option_t *options,
const char *new_option, const char *new_value,
int *num_conflicts, cups_option_t *_conflicts,
int _num_resolved, cups_option_t *_resolved);

/* Get localization information for the current locale from the destination,
with English as the fallback - replaces ppdLocalize*.

The caller must call cupsArrayDelete on the returned array. */

cups_array_t *cupsCopyDestLocalizations(http_t *http, cups_dest_t *dest);

/* Get the localized string for a destination option - replaces ppdLocalize and
the lookup in the ppd_option_t structure.

The returned string is stored in the localization array and will become
invalid if the localization array is deleted. */

const char *cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
cups_array_t *localization,
const char *option);

/* Get the localized string for a destination option+value pair - replaces
ppdLocalize* and the lookup in the ppd_choice_t structure.

The returned string is stored in the localization array and will become
invalid if the localization array is deleted. */

const char *cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
cups_array_t *localization,
const char *option, const char *value);


michaelrsweet commented Jan 13, 2012 User: mike

The primary focus of the new print job APIs is to use a cups_dest_t pointer
instead of a printer name (== PrintCore's queue ID). The new document
submission API also allows for per-document options, although current CUPS
does not support the document object extension of IPP.

/* Cancel a job on a destination - replaces cupsCancelJob/cupsCancelJob2.
The "job_id" is the number returned by cupsCreateDestJob. When "purge" is
non-zero and the current user has admin privileges, the job is also removed
from the job history.

Returns IPP_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on
failure. */

ipp_status_t cupsCancelDestJob(http_t *http, cups_dest_t *dest, int job_id,
int purge);

/* Create a job on a destination - replaces cupsCreateJob*.

Returns IPP_OK or IPP_OK_SUBST on success, saving the job ID in the variable
pointed to by "job_id". */

ipp_status_t cupsCreateDestJob(http_t *http, cups_dest_t *dest, int *job_id,
const char *title,
int num_options, cups_option_t *options);

/* Start a new document - replaces cupsStartDocument. "job_id" is the job ID
returned by cupsCreateDestJob. "docname" is the name of the document/file
being printed, "format" is the MIME media type for the document (see
CUPS_FORMAT_xxx constants), and "num_options" and "options" are the options
do be applied to the document. "last_document" should be 1 if this is the
last document to be submitted in the job. Returns HTTP_CONTINUE on
success. */

http_status_t cupsStartDestDocument(http_t *http, cups_dest_t *dest, int job_id,
const char *docname, const char *format,
int num_options, cups_option_t *options,
int last_document);

/* Finish the current document - replaces cupsFinishDocument. Returns IPP_OK
on success. */

ipp_status_t cupsFinishDestDocument(http_t *http, cups_dest_t *dest);

/* Close a job and start printing - used when the last call to cupsStartDocument
passed 0 for "last_document". "job_id" is the job ID returned by
cupsCreateDestJob. Returns IPP_OK on success. */

ipp_status_t cupsCloseDestJob(http_t *http, cups_dest_t *dest, int job_id);


michaelrsweet commented Mar 16, 2012 User: mike

Remaining to implement:

dest-job.c: Everything
dest-localization.c: Everything
dest-options.c: cupsCopyDestConflicts


michaelrsweet commented Mar 17, 2012 User: mike

dest-job.c is done.


michaelrsweet commented May 23, 2012 User: mike

Fixed in Subversion repository.

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment