* option/value pair.
* cupsCopyDestInfo() - Get the supported values/capabilities for the
* destination.
+ * cupsFindDestDefault() - Find the default value(s) for the given
+ * option.
+ * cupsFindDestReady() - Find the default value(s) for the given
+ * option.
+ * cupsFindDestSupported() - Find the default value(s) for the given
+ * option.
* cupsFreeDestInfo() - Free destination information obtained using
* @link cupsCopyDestInfo@.
+ * cupsGetDestMediaByIndex() - Get a media name, dimension, and margins for a
+ * specific size.
* cupsGetDestMediaByName() - Get media names, dimensions, and margins.
* cupsGetDestMediaBySize() - Get media names, dimensions, and margins.
+ * cupsGetDestMediaCount() - Get the number of sizes supported by a
+ * destination.
+ * cupsGetDestMediaDefault() - Get the default size for a destination.
* cups_add_dconstres() - Add a constraint or resolver to an array.
* cups_compare_dconstres() - Compare to resolver entries.
* cups_compare_media_db() - Compare two media entries.
* cups_copy_media_db() - Copy a media entry.
+ * cups_create_cached() - Create the media selection cache.
* cups_create_constraints() - Create the constraints and resolvers arrays.
* cups_create_defaults() - Create the -default option array.
* cups_create_media_db() - Create the media database.
* cups_is_close_media_db() - Compare two media entries to see if they are
* close to the same size.
* cups_test_constraints() - Test constraints.
+ * cups_update_ready() - Update xxx-ready attributes for the printer.
*/
/*
#include "cups-private.h"
+/*
+ * Local constants...
+ */
+
+#define _CUPS_MEDIA_READY_TTL 30 /* Life of xxx-ready values */
+
+
/*
* Local functions...
*/
static int cups_compare_media_db(_cups_media_db_t *a,
_cups_media_db_t *b);
static _cups_media_db_t *cups_copy_media_db(_cups_media_db_t *mdb);
+static void cups_create_cached(http_t *http, cups_dinfo_t *dinfo,
+ unsigned flags);
static void cups_create_constraints(cups_dinfo_t *dinfo);
static void cups_create_defaults(cups_dinfo_t *dinfo);
-static void cups_create_media_db(cups_dinfo_t *dinfo);
+static void cups_create_media_db(cups_dinfo_t *dinfo,
+ unsigned flags);
static void cups_free_media_db(_cups_media_db_t *mdb);
-static int cups_get_media_db(cups_dinfo_t *dinfo,
+static int cups_get_media_db(http_t *http, cups_dinfo_t *dinfo,
pwg_media_t *pwg, unsigned flags,
cups_size_t *size);
static int cups_is_close_media_db(_cups_media_db_t *a,
cups_option_t *options,
int *num_conflicts,
cups_option_t **conflicts);
+static void cups_update_ready(http_t *http, cups_dinfo_t *dinfo);
/*
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
uri);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes",
(int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])),
}
+/*
+ * 'cupsFindDestDefault()' - Find the default value(s) for the given option.
+ *
+ * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
+ * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
+ * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
+ * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
+ * functions to inspect the default value(s) as needed.
+ *
+ * @since CUPS 1.7@
+ */
+
+ipp_attribute_t * /* O - Default attribute or @code NULL@ for none */
+cupsFindDestDefault(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ const char *option) /* I - Option/attribute name */
+{
+ char name[IPP_MAX_NAME]; /* Attribute name */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!http || !dest || !dinfo || !option)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (NULL);
+ }
+
+ /*
+ * Find and return the attribute...
+ */
+
+ snprintf(name, sizeof(name), "%s-default", option);
+ return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
+}
+
+/*
+ * 'cupsFindDestReady()' - Find the default value(s) for the given option.
+ *
+ * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
+ * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
+ * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
+ * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
+ * functions to inspect the default value(s) as needed.
+ *
+ * @since CUPS 1.7@
+ */
+
+ipp_attribute_t * /* O - Default attribute or @code NULL@ for none */
+cupsFindDestReady(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ const char *option) /* I - Option/attribute name */
+{
+ char name[IPP_MAX_NAME]; /* Attribute name */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!http || !dest || !dinfo || !option)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (NULL);
+ }
+
+ /*
+ * Find and return the attribute...
+ */
+
+ cups_update_ready(http, dinfo);
+
+ snprintf(name, sizeof(name), "%s-ready", option);
+ return (ippFindAttribute(dinfo->ready_attrs, name, IPP_TAG_ZERO));
+}
+
+/*
+ * 'cupsFindDestSupported()' - Find the default value(s) for the given option.
+ *
+ * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
+ * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
+ * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
+ * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
+ * functions to inspect the default value(s) as needed.
+ *
+ * @since CUPS 1.7@
+ */
+
+ipp_attribute_t * /* O - Default attribute or @code NULL@ for none */
+cupsFindDestSupported(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ const char *option) /* I - Option/attribute name */
+{
+ char name[IPP_MAX_NAME]; /* Attribute name */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!http || !dest || !dinfo || !option)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (NULL);
+ }
+
+ /*
+ * Find and return the attribute...
+ */
+
+ snprintf(name, sizeof(name), "%s-supported", option);
+ return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
+}
+
+
/*
* 'cupsFreeDestInfo()' - Free destination information obtained using
* @link cupsCopyDestInfo@.
cupsArrayDelete(dinfo->media_db);
+ cupsArrayDelete(dinfo->cached_db);
+
+ ippDelete(dinfo->ready_attrs);
+ cupsArrayDelete(dinfo->ready_db);
+
ippDelete(dinfo->attrs);
free(dinfo);
}
+/*
+ * 'cupsGetDestMediaByIndex()' - Get a media name, dimension, and margins for a
+ * specific size.
+ *
+ * The @code flags@ parameter determines which set of media are indexed. For
+ * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will get the Nth
+ * borderless size supported by the printer.
+ *
+ * @since CUPS 1.7@
+ */
+
+int /* O - 1 on success, 0 on failure */
+cupsGetDestMediaByIndex(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ int n, /* I - Media size number (0-based) */
+ unsigned flags, /* I - Media flags */
+ cups_size_t *size) /* O - Media size information */
+{
+ cups_size_t *nsize; /* Size for N */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (size)
+ memset(size, 0, sizeof(cups_size_t));
+
+ if (!http || !dest || !dinfo || n < 0 || !size)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (0);
+ }
+
+ /*
+ * Load media list as needed...
+ */
+
+ if (flags & CUPS_MEDIA_FLAGS_READY)
+ cups_update_ready(http, dinfo);
+
+ if (!dinfo->cached_db || dinfo->cached_flags != flags)
+ cups_create_cached(http, dinfo, flags);
+
+ /*
+ * Copy the size over and return...
+ */
+
+ if ((nsize = (cups_size_t *)cupsArrayIndex(dinfo->cached_db, n)) == NULL)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (0);
+ }
+
+ memcpy(size, nsize, sizeof(cups_size_t));
+
+ return (1);
+}
+
+
/*
* 'cupsGetDestMediaByName()' - Get media names, dimensions, and margins.
*
* Lookup the size...
*/
- return (cups_get_media_db(dinfo, pwg, flags, size));
+ return (cups_get_media_db(http, dinfo, pwg, flags, size));
}
* Lookup the size...
*/
- return (cups_get_media_db(dinfo, pwg, flags, size));
+ return (cups_get_media_db(http, dinfo, pwg, flags, size));
+}
+
+
+/*
+ * 'cupsGetDestMediaCount()' - Get the number of sizes supported by a
+ * destination.
+ *
+ * The @code flags@ parameter determines the set of media sizes that are
+ * counted. For example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return
+ * the number of borderless sizes.
+ *
+ * @since CUPS 1.7@
+ */
+
+int /* O - Number of sizes */
+cupsGetDestMediaCount(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ unsigned flags) /* I - Media flags */
+{
+ /*
+ * Range check input...
+ */
+
+ if (!http || !dest || !dinfo)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (0);
+ }
+
+ /*
+ * Load media list as needed...
+ */
+
+ if (flags & CUPS_MEDIA_FLAGS_READY)
+ cups_update_ready(http, dinfo);
+
+ if (!dinfo->cached_db || dinfo->cached_flags != flags)
+ cups_create_cached(http, dinfo, flags);
+
+ return (cupsArrayCount(dinfo->cached_db));
+}
+
+
+/*
+ * 'cupsGetDestMediaDefault()' - Get the default size for a destination.
+ *
+ * The @code flags@ parameter determines which default size is returned. For
+ * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return the default
+ * borderless size, typically US Letter or A4, but sometimes 4x6 photo media.
+ *
+ * @since CUPS 1.7@
+ */
+
+int /* O - 1 on success, 0 on failure */
+cupsGetDestMediaDefault(
+ http_t *http, /* I - Connection to destination */
+ cups_dest_t *dest, /* I - Destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ unsigned flags, /* I - Media flags */
+ cups_size_t *size) /* O - Media size information */
+{
+ const char *media; /* Default media size */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (size)
+ memset(size, 0, sizeof(cups_size_t));
+
+ if (!http || !dest || !dinfo || !size)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+ return (0);
+ }
+
+ /*
+ * Get the default media size, if any...
+ */
+
+ if ((media = cupsGetOption("media", dest->num_options,
+ dest->options)) == NULL)
+ media = "na_letter_8.5x11in";
+
+ if (cupsGetDestMediaByName(http, dest, dinfo, media, flags, size))
+ return (1);
+
+ if (strcmp(media, "na_letter_8.5x11in") &&
+ cupsGetDestMediaByName(http, dest, dinfo, "iso_a4_210x297mm", flags,
+ size))
+ return (1);
+
+ if (strcmp(media, "iso_a4_210x297mm") &&
+ cupsGetDestMediaByName(http, dest, dinfo, "na_letter_8.5x11in", flags,
+ size))
+ return (1);
+
+ if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) &&
+ cupsGetDestMediaByName(http, dest, dinfo, "na_index_4x6in", flags, size))
+ return (1);
+
+ /*
+ * Fall back to the first matching media size...
+ */
+
+ return (cupsGetDestMediaByIndex(http, dest, dinfo, flags, 0, size));
}
}
+/*
+ * 'cups_create_cached()' - Create the media selection cache.
+ */
+
+static void
+cups_create_cached(http_t *http, /* I - Connection to destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ unsigned flags) /* I - Media selection flags */
+{
+ cups_array_t *db; /* Media database array to use */
+ _cups_media_db_t *mdb, /* Media database entry */
+ *first; /* First entry this size */
+
+
+ if (dinfo->cached_db)
+ cupsArrayDelete(dinfo->cached_db);
+
+ dinfo->cached_db = cupsArrayNew(NULL, NULL);
+ dinfo->cached_flags = flags;
+
+ if (flags & CUPS_MEDIA_FLAGS_READY)
+ {
+ cups_update_ready(http, dinfo);
+ db = dinfo->ready_db;
+ }
+ else
+ {
+ if (!dinfo->media_db)
+ cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);
+
+ db = dinfo->media_db;
+ }
+
+ for (mdb = (_cups_media_db_t *)cupsArrayFirst(db), first = mdb;
+ mdb;
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
+ {
+ if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
+ {
+ if (!mdb->left && !mdb->right && !mdb->top && !mdb->bottom)
+ cupsArrayAdd(dinfo->cached_db, mdb);
+ }
+ else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
+ {
+ if (first->width != mdb->width || first->length != mdb->length)
+ {
+ cupsArrayAdd(dinfo->cached_db, first);
+ first = mdb;
+ }
+ else if (mdb->left >= first->left && mdb->right >= first->right &&
+ mdb->top >= first->top && mdb->bottom >= first->bottom)
+ first = mdb;
+ }
+ }
+
+ if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
+ cupsArrayAdd(dinfo->cached_db, first);
+}
+
+
/*
* 'cups_create_constraints()' - Create the constraints and resolvers arrays.
*/
static void
cups_create_media_db(
- cups_dinfo_t *dinfo) /* I - Destination information */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ unsigned flags) /* I - Media flags */
{
int i; /* Looping var */
_ipp_value_t *val; /* Current value */
*x_dimension, /* x-dimension */
*y_dimension; /* y-dimension */
pwg_media_t *pwg; /* PWG media info */
+ cups_array_t *db; /* New media database array */
_cups_media_db_t mdb; /* Media entry */
- dinfo->media_db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db,
- NULL, NULL, 0,
- (cups_acopy_func_t)cups_copy_media_db,
- (cups_afree_func_t)cups_free_media_db);
- dinfo->min_size.width = INT_MAX;
- dinfo->min_size.length = INT_MAX;
- dinfo->max_size.width = 0;
- dinfo->max_size.length = 0;
+ db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db,
+ NULL, NULL, 0,
+ (cups_acopy_func_t)cups_copy_media_db,
+ (cups_afree_func_t)cups_free_media_db);
- if ((media_col_db = ippFindAttribute(dinfo->attrs, "media-col-database",
- IPP_TAG_BEGIN_COLLECTION)) != NULL)
+ if (flags == CUPS_MEDIA_FLAGS_READY)
+ {
+ dinfo->ready_db = db;
+
+ media_col_db = ippFindAttribute(dinfo->ready_attrs, "media-col-ready",
+ IPP_TAG_BEGIN_COLLECTION);
+ media_attr = ippFindAttribute(dinfo->ready_attrs, "media-ready",
+ IPP_TAG_ZERO);
+ }
+ else
+ {
+ dinfo->media_db = db;
+ dinfo->min_size.width = INT_MAX;
+ dinfo->min_size.length = INT_MAX;
+ dinfo->max_size.width = 0;
+ dinfo->max_size.length = 0;
+
+ media_col_db = ippFindAttribute(dinfo->attrs, "media-col-database",
+ IPP_TAG_BEGIN_COLLECTION);
+ media_attr = ippFindAttribute(dinfo->attrs, "media-supported",
+ IPP_TAG_ZERO);
+ }
+
+ if (media_col_db)
{
_ipp_value_t *custom = NULL; /* Custom size range value */
/* media-size collection value */
if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
- IPP_TAG_INTEGER)) != NULL &&
+ IPP_TAG_INTEGER)) != NULL &&
(y_dimension = ippFindAttribute(media_size, "y-dimension",
IPP_TAG_INTEGER)) != NULL)
{
+ /*
+ * Fixed size...
+ */
+
mdb.width = x_dimension->values[0].integer;
mdb.length = y_dimension->values[0].integer;
}
- else if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
- IPP_TAG_RANGE)) != NULL &&
+ else if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
+ IPP_TAG_INTEGER)) != NULL &&
+ (y_dimension = ippFindAttribute(media_size, "y-dimension",
+ IPP_TAG_RANGE)) != NULL)
+ {
+ /*
+ * Roll limits...
+ */
+
+ mdb.width = x_dimension->values[0].integer;
+ mdb.length = y_dimension->values[0].range.upper;
+ }
+ else if (flags != CUPS_MEDIA_FLAGS_READY &&
+ (x_dimension = ippFindAttribute(media_size, "x-dimension",
+ IPP_TAG_RANGE)) != NULL &&
(y_dimension = ippFindAttribute(media_size, "y-dimension",
IPP_TAG_RANGE)) != NULL)
{
dinfo->max_size.right = 635; /* Default 1/4" side margins */
dinfo->max_size.top =
dinfo->max_size.bottom = 1270; /* Default 1/2" top/bottom margins */
-
continue;
}
}
IPP_TAG_INTEGER)) != NULL)
mdb.top = media_attr->values[0].integer;
- cupsArrayAdd(dinfo->media_db, &mdb);
+ cupsArrayAdd(db, &mdb);
}
if (custom)
}
}
}
- else if ((media_attr = ippFindAttribute(dinfo->attrs, "media-supported",
- IPP_TAG_ZERO)) != NULL &&
+ else if (media_attr &&
(media_attr->value_tag == IPP_TAG_NAME ||
media_attr->value_tag == IPP_TAG_NAMELANG ||
media_attr->value_tag == IPP_TAG_KEYWORD))
mdb.width = pwg->width;
mdb.length = pwg->length;
- if (!strncmp(val->string.text, "custom_min_", 11))
+ if (flags != CUPS_MEDIA_FLAGS_READY &&
+ !strncmp(val->string.text, "custom_min_", 11))
{
mdb.size_name = NULL;
dinfo->min_size = mdb;
}
- else if (!strncmp(val->string.text, "custom_max_", 11))
+ else if (flags != CUPS_MEDIA_FLAGS_READY &&
+ !strncmp(val->string.text, "custom_max_", 11))
{
mdb.size_name = NULL;
dinfo->max_size = mdb;
{
mdb.size_name = val->string.text;
- cupsArrayAdd(dinfo->media_db, &mdb);
+ cupsArrayAdd(db, &mdb);
}
}
}
*/
static int /* O - 1 on match, 0 on failure */
-cups_get_media_db(cups_dinfo_t *dinfo, /* I - Destination information */
- pwg_media_t *pwg, /* I - PWG media info */
+cups_get_media_db(http_t *http, /* I - Connection to destination */
+ cups_dinfo_t *dinfo, /* I - Destination information */
+ pwg_media_t *pwg, /* I - PWG media info */
unsigned flags, /* I - Media matching flags */
- cups_size_t *size) /* O - Media size/margin/name info */
+ cups_size_t *size) /* O - Media size/margin/name info */
{
+ cups_array_t *db; /* Which media database to query */
_cups_media_db_t *mdb, /* Current media database entry */
*best = NULL, /* Best matching entry */
key; /* Search key */
* Create the media database as needed...
*/
- if (!dinfo->media_db)
- cups_create_media_db(dinfo);
+ if (flags & CUPS_MEDIA_FLAGS_READY)
+ {
+ cups_update_ready(http, dinfo);
+ db = dinfo->ready_db;
+ }
+ else
+ {
+ if (!dinfo->media_db)
+ cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);
+
+ db = dinfo->media_db;
+ }
/*
* Find a match...
key.width = pwg->width;
key.length = pwg->length;
- if ((mdb = cupsArrayFind(dinfo->media_db, &key)) != NULL)
+ if ((mdb = cupsArrayFind(db, &key)) != NULL)
{
/*
* Found an exact match, let's figure out the best margins for the flags
if (best->left != 0 || best->right != 0 || best->top != 0 ||
best->bottom != 0)
{
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && !cups_compare_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (mdb->left <= best->left && mdb->right <= best->right &&
mdb->top <= best->top && mdb->bottom <= best->bottom)
* Look for the largest margins...
*/
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && !cups_compare_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (mdb->left >= best->left && mdb->right >= best->right &&
mdb->top >= best->top && mdb->bottom >= best->bottom)
* Look for the smallest non-zero margins...
*/
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && !cups_compare_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
((mdb->right > 0 && mdb->right <= best->right) ||
* Find a close size...
*/
- for (mdb = (_cups_media_db_t *)cupsArrayFirst(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayFirst(db);
mdb;
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
if (cups_is_close_media_db(mdb, &key))
break;
if (best->left != 0 || best->right != 0 || best->top != 0 ||
best->bottom != 0)
{
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && cups_is_close_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (mdb->left <= best->left && mdb->right <= best->right &&
mdb->top <= best->top && mdb->bottom <= best->bottom)
* Look for the largest margins...
*/
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && cups_is_close_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (mdb->left >= best->left && mdb->right >= best->right &&
mdb->top >= best->top && mdb->bottom >= best->bottom)
* Look for the smallest non-zero margins...
*/
- for (mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db);
+ for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
mdb && cups_is_close_media_db(mdb, &key);
- mdb = (_cups_media_db_t *)cupsArrayNext(dinfo->media_db))
+ mdb = (_cups_media_db_t *)cupsArrayNext(db))
{
if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
((mdb->right > 0 && mdb->right <= best->right) ||
}
+/*
+ * 'cups_update_ready()' - Update xxx-ready attributes for the printer.
+ */
+
+static void
+cups_update_ready(http_t *http, /* I - Connection to destination */
+ cups_dinfo_t *dinfo) /* I - Destination information */
+{
+ ipp_t *request; /* Get-Printer-Attributes request */
+ static const char * const pattrs[] = /* Printer attributes we want */
+ {
+ "finishings-col-ready",
+ "finishings-ready",
+ "job-finishings-col-ready",
+ "job-finishings-ready",
+ "media-col-ready",
+ "media-ready"
+ };
+
+
+ /*
+ * Don't update more than once every 30 seconds...
+ */
+
+ if ((time(NULL) - dinfo->ready_time) < _CUPS_MEDIA_READY_TTL)
+ return;
+
+ /*
+ * Free any previous results...
+ */
+
+ if (dinfo->cached_flags & CUPS_MEDIA_FLAGS_READY)
+ {
+ cupsArrayDelete(dinfo->cached_db);
+ dinfo->cached_db = NULL;
+ dinfo->cached_flags = CUPS_MEDIA_FLAGS_DEFAULT;
+ }
+
+ ippDelete(dinfo->ready_attrs);
+ dinfo->ready_attrs = NULL;
+
+ cupsArrayDelete(dinfo->ready_db);
+ dinfo->ready_db = NULL;
+
+ /*
+ * Query the xxx-ready values...
+ */
+
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
+ ippSetVersion(request, dinfo->version / 10, dinfo->version % 10);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ dinfo->uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+ ippAddStrings(request, IPP_TAG_OPERATION,
+ IPP_TAG_KEYWORD | IPP_TAG_CUPS_CONST, "requested-attributes",
+ (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
+
+ dinfo->ready_attrs = cupsDoRequest(http, request, dinfo->resource);
+
+ /*
+ * Update the ready media database...
+ */
+
+ cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_READY);
+
+ /*
+ * Update last lookup time and return...
+ */
+
+ dinfo->ready_time = time(NULL);
+}
+
+
/*
* End of "$Id$".
*/
* ippGetGroupTag() - Get the group associated with an attribute.
* ippGetInteger() - Get the integer/enum value for an attribute.
* ippGetName() - Get the attribute name.
+ * ippGetOctetString() - Get an octetString value from an IPP attribute.
* ippGetOperation() - Get the operation ID in an IPP message.
* ippGetRange() - Get a rangeOfInteger value from an attribute.
* ippGetRequestId() - Get the request ID from an IPP message.
* ippSetGroupTag() - Set the group tag of an attribute.
* ippSetInteger() - Set an integer or enum value in an attribute.
* ippSetName() - Set the name of an attribute.
+ * ippSetOctetString() - Set an octetString value in an IPP attribute.
* ippSetOperation() - Set the operation ID in an IPP request message.
* ippSetRange() - Set a rangeOfInteger value in an attribute.
* ippSetRequestId() - Set the request ID in an IPP message.
}
+/*
+ * 'ippGetOctetString()' - Get an octetString value from an IPP attribute.
+ *
+ * The @code element@ parameter specifies which value to get from 0 to
+ * @link ippGetCount(attr)@ - 1.
+ *
+ * @since CUPS 1.7@
+ */
+
+void * /* O - Pointer to octetString data */
+ippGetOctetString(
+ ipp_attribute_t *attr, /* I - IPP attribute */
+ int element, /* I - Value number (0-based) */
+ int *datalen) /* O - Length of octetString data */
+{
+ /*
+ * Range check input...
+ */
+
+ if (!attr || attr->value_tag != IPP_TAG_STRING ||
+ element < 0 || element >= attr->num_values)
+ {
+ if (datalen)
+ *datalen = 0;
+
+ return (NULL);
+ }
+
+ /*
+ * Return the values...
+ */
+
+ if (datalen)
+ *datalen = attr->values[element].unknown.length;
+
+ return (attr->values[element].unknown.data);
+}
+
+
/*
* 'ippGetOperation()' - Get the operation ID in an IPP message.
*
*/
int /* O - 1 on success, 0 on failure */
-ippSetBoolean(ipp_t *ipp, /* IO - IPP message */
+ippSetBoolean(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
int boolvalue)/* I - Boolean value */
int /* O - 1 on success, 0 on failure */
ippSetCollection(
- ipp_t *ipp, /* IO - IPP message */
+ ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
ipp_t *colvalue) /* I - Collection value */
*/
int /* O - 1 on success, 0 on failure */
-ippSetDate(ipp_t *ipp, /* IO - IPP message */
+ippSetDate(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
const ipp_uchar_t *datevalue)/* I - Date value */
int /* O - 1 on success, 0 on failure */
ippSetGroupTag(
- ipp_t *ipp, /* IO - IPP message */
+ ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - Attribute */
ipp_tag_t group_tag) /* I - Group tag */
{
*/
int /* O - 1 on success, 0 on failure */
-ippSetInteger(ipp_t *ipp, /* IO - IPP message */
+ippSetInteger(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
int intvalue) /* I - Integer/enum value */
*/
int /* O - 1 on success, 0 on failure */
-ippSetName(ipp_t *ipp, /* IO - IPP message */
+ippSetName(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
const char *name) /* I - Attribute name */
{
}
+/*
+ * 'ippSetOctetString()' - Set an octetString value in an IPP attribute.
+ *
+ * The @code ipp@ parameter refers to an IPP message previously created using
+ * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions.
+ *
+ * The @code attr@ parameter may be modified as a result of setting the value.
+ *
+ * The @code element@ parameter specifies which value to set from 0 to
+ * @link ippGetCount(attr)@.
+ *
+ * @since CUPS 1.7@
+ */
+
+int /* O - 1 on success, 0 on failure */
+ippSetOctetString(
+ ipp_t *ipp, /* I - IPP message */
+ ipp_attribute_t **attr, /* IO - IPP attribute */
+ int element, /* I - Value number (0-based) */
+ const void *data, /* I - Pointer to octetString data */
+ int datalen) /* I - Length of octetString data */
+{
+ _ipp_value_t *value; /* Current value */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_STRING ||
+ element < 0 || element > (*attr)->num_values ||
+ datalen < 0 || datalen > IPP_MAX_LENGTH)
+ return (0);
+
+ /*
+ * Set the value and return...
+ */
+
+ if ((value = ipp_set_value(ipp, attr, element)) != NULL)
+ {
+ if ((int)((*attr)->value_tag) & IPP_TAG_CUPS_CONST)
+ {
+ /*
+ * Just copy the pointer...
+ */
+
+ value->unknown.data = (void *)data;
+ value->unknown.length = datalen;
+ }
+ else
+ {
+ /*
+ * Copy the data...
+ */
+
+ if (value->unknown.data)
+ {
+ /*
+ * Free previous data...
+ */
+
+ free(value->unknown.data);
+
+ value->unknown.data = NULL;
+ value->unknown.length = 0;
+ }
+
+ if (datalen > 0)
+ {
+ void *temp; /* Temporary data pointer */
+
+ if ((temp = malloc(datalen)) != NULL)
+ {
+ memcpy(temp, data, datalen);
+
+ value->unknown.data = temp;
+ value->unknown.length = datalen;
+ }
+ else
+ return (0);
+ }
+ }
+ }
+
+ return (value != NULL);
+}
+
+
/*
* 'ippSetOperation()' - Set the operation ID in an IPP request message.
*
*/
int /* O - 1 on success, 0 on failure */
-ippSetRange(ipp_t *ipp, /* IO - IPP message */
+ippSetRange(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
int lowervalue, /* I - Lower bound for range */
int /* O - 1 on success, 0 on failure */
ippSetResolution(
- ipp_t *ipp, /* IO - IPP message */
+ ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
ipp_res_t unitsvalue, /* I - Resolution units */
*/
int /* O - 1 on success, 0 on failure */
-ippSetString(ipp_t *ipp, /* IO - IPP message */
+ippSetString(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
const char *strvalue) /* I - String value */
*/
int /* O - 1 on success, 0 on failure */
-ippSetStringf(ipp_t *ipp, /* IO - IPP message */
+ippSetStringf(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
const char *format, /* I - Printf-style format string */
*/
int /* O - 1 on success, 0 on failure */
-ippSetStringfv(ipp_t *ipp, /* IO - IPP message */
+ippSetStringfv(ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
int element, /* I - Value number (0-based) */
const char *format, /* I - Printf-style format string */
int /* O - 1 on success, 0 on failure */
ippSetValueTag(
- ipp_t *ipp, /* IO - IPP message */
+ ipp_t *ipp, /* I - IPP message */
ipp_attribute_t **attr, /* IO - IPP attribute */
ipp_tag_t value_tag) /* I - Value tag */
{
<li><a href="#cupsEncryption" title="Get the current encryption settings.">cupsEncryption</a></li>
<li><a href="#cupsEnumDests" title="Enumerate available destinations with a callback function.">cupsEnumDests</a></li>
<li><a href="#cupsEnumDestsBlock" title="Enumerate available destinations with a block.">cupsEnumDestsBlock</a></li>
+ <li><a href="#cupsFindDestDefault" title="Find the default value(s) for the given option.">cupsFindDestDefault</a></li>
+ <li><a href="#cupsFindDestReady" title="Find the default value(s) for the given option.">cupsFindDestReady</a></li>
+ <li><a href="#cupsFindDestSupported" title="Find the default value(s) for the given option.">cupsFindDestSupported</a></li>
<li><a href="#cupsFinishDestDocument" title="Finish the current document.">cupsFinishDestDocument</a></li>
<li><a href="#cupsFinishDocument" title="Finish sending a document.">cupsFinishDocument</a></li>
<li><a href="#cupsFreeDestInfo" title="Free destination information obtained using
<li><a href="#cupsGetDefault" title="Get the default printer or class for the default server.">cupsGetDefault</a></li>
<li><a href="#cupsGetDefault2" title="Get the default printer or class for the specified server.">cupsGetDefault2</a></li>
<li><a href="#cupsGetDest" title="Get the named destination from the list.">cupsGetDest</a></li>
+ <li><a href="#cupsGetDestMediaByIndex" title="Get a media name, dimension, and margins for a
+specific size.">cupsGetDestMediaByIndex</a></li>
<li><a href="#cupsGetDestMediaByName" title="Get media names, dimensions, and margins.">cupsGetDestMediaByName</a></li>
<li><a href="#cupsGetDestMediaBySize" title="Get media names, dimensions, and margins.">cupsGetDestMediaBySize</a></li>
+ <li><a href="#cupsGetDestMediaCount" title="Get the number of sizes supported by a
+destination.">cupsGetDestMediaCount</a></li>
+ <li><a href="#cupsGetDestMediaDefault" title="Get the default size for a destination.">cupsGetDestMediaDefault</a></li>
<li><a href="#cupsGetDests" title="Get the list of destinations from the default server.">cupsGetDests</a></li>
<li><a href="#cupsGetDests2" title="Get the list of destinations from the specified server.">cupsGetDests2</a></li>
<li><a href="#cupsGetJobs" title="Get the jobs from the default server.">cupsGetJobs</a></li>
Enumeration happens on the current thread and does not return until all
destinations have been enumerated or the block returns 0.
+</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsFindDestDefault">cupsFindDestDefault</a></h3>
+<p class="description">Find the default value(s) for the given option.</p>
+<p class="code">
+ipp_attribute_t *cupsFindDestDefault (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ const char *option<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>option</dt>
+<dd class="description">Option/attribute name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default attribute or <code>NULL</code> for none</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned value is an IPP attribute. Use the <code>ippGetBoolean</code>,
+<code>ippGetCollection</code>, <code>ippGetCount</code>, <code>ippGetDate</code>,
+<code>ippGetInteger</code>, <code>ippGetOctetString</code>, <code>ippGetRange</code>,
+<code>ippGetResolution</code>, <code>ippGetString</code>, and <code>ippGetValueTag</code>
+functions to inspect the default value(s) as needed.
+
+</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsFindDestReady">cupsFindDestReady</a></h3>
+<p class="description">Find the default value(s) for the given option.</p>
+<p class="code">
+ipp_attribute_t *cupsFindDestReady (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ const char *option<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>option</dt>
+<dd class="description">Option/attribute name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default attribute or <code>NULL</code> for none</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned value is an IPP attribute. Use the <code>ippGetBoolean</code>,
+<code>ippGetCollection</code>, <code>ippGetCount</code>, <code>ippGetDate</code>,
+<code>ippGetInteger</code>, <code>ippGetOctetString</code>, <code>ippGetRange</code>,
+<code>ippGetResolution</code>, <code>ippGetString</code>, and <code>ippGetValueTag</code>
+functions to inspect the default value(s) as needed.
+
+</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsFindDestSupported">cupsFindDestSupported</a></h3>
+<p class="description">Find the default value(s) for the given option.</p>
+<p class="code">
+ipp_attribute_t *cupsFindDestSupported (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ const char *option<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>option</dt>
+<dd class="description">Option/attribute name</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default attribute or <code>NULL</code> for none</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The returned value is an IPP attribute. Use the <code>ippGetBoolean</code>,
+<code>ippGetCollection</code>, <code>ippGetCount</code>, <code>ippGetDate</code>,
+<code>ippGetInteger</code>, <code>ippGetOctetString</code>, <code>ippGetRange</code>,
+<code>ippGetResolution</code>, <code>ippGetString</code>, and <code>ippGetValueTag</code>
+functions to inspect the default value(s) as needed.
+
</p>
<h3 class="function"><span class="info"> CUPS 1.6/OS X 10.8 </span><a name="cupsFinishDestDocument">cupsFinishDestDocument</a></h3>
<p class="description">Finish the current document.</p>
<h4 class="discussion">Discussion</h4>
<p class="discussion">Use the <a href="#cupsGetDests"><code>cupsGetDests</code></a> or <a href="#cupsGetDests2"><code>cupsGetDests2</code></a> functions to get a
list of supported destinations for the current user.</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsGetDestMediaByIndex">cupsGetDestMediaByIndex</a></h3>
+<p class="description">Get a media name, dimension, and margins for a
+specific size.</p>
+<p class="code">
+int cupsGetDestMediaByIndex (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ int n,<br>
+ unsigned flags,<br>
+ <a href="#cups_size_t">cups_size_t</a> *size<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>n</dt>
+<dd class="description">Media size number (0-based)</dd>
+<dt>flags</dt>
+<dd class="description">Media flags</dd>
+<dt>size</dt>
+<dd class="description">Media size information</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>flags</code> parameter determines which set of media are indexed. For
+example, passing <code>CUPS_MEDIA_FLAGS_BORDERLESS</code> will get the Nth
+borderless size supported by the printer.
+
+</p>
<h3 class="function"><span class="info"> CUPS 1.6/OS X 10.8 </span><a name="cupsGetDestMediaByName">cupsGetDestMediaByName</a></h3>
<p class="description">Get media names, dimensions, and margins.</p>
<p class="code">
<br>
Returns 1 when there is a match and 0 if there is not a match.
+</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsGetDestMediaCount">cupsGetDestMediaCount</a></h3>
+<p class="description">Get the number of sizes supported by a
+destination.</p>
+<p class="code">
+int cupsGetDestMediaCount (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ unsigned flags<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>flags</dt>
+<dd class="description">Media flags</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of sizes</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>flags</code> parameter determines the set of media sizes that are
+counted. For example, passing <code>CUPS_MEDIA_FLAGS_BORDERLESS</code> will return
+the number of borderless sizes.
+
+</p>
+<h3 class="function"><span class="info"> CUPS 1.7 </span><a name="cupsGetDestMediaDefault">cupsGetDestMediaDefault</a></h3>
+<p class="description">Get the default size for a destination.</p>
+<p class="code">
+int cupsGetDestMediaDefault (<br>
+ http_t *http,<br>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ <a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+ unsigned flags,<br>
+ <a href="#cups_size_t">cups_size_t</a> *size<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to destination</dd>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>dinfo</dt>
+<dd class="description">Destination information</dd>
+<dt>flags</dt>
+<dd class="description">Media flags</dd>
+<dt>size</dt>
+<dd class="description">Media size information</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>flags</code> parameter determines which default size is returned. For
+example, passing <code>CUPS_MEDIA_FLAGS_BORDERLESS</code> will return the default
+borderless size, typically US Letter or A4, but sometimes 4x6 photo media.
+
</p>
<h3 class="function"><a name="cupsGetDests">cupsGetDests</a></h3>
<p class="description">Get the list of destinations from the default server.</p>