]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Implemented ready media support for the cupsGetDestMediaXxx APIs (STR #4289)
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 14 Mar 2013 18:45:49 +0000 (18:45 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Thu, 14 Mar 2013 18:45:49 +0000 (18:45 +0000)
Added new cupsFindDestDefault, cupsFindDestReady, and cupsFindDestSupported
APIs (STR #4289)

Added new cupsGetDestMediaByIndex, cupsGetDestMediaCount, and
cupsGetDestMediaDefault APIs (STR #4289)

Added new ippGet/SetOctetString APIs for getting and setting an octetString
value (STR #4289)

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@10909 7a7537e8-13f0-0310-91df-b6672ffda945

CHANGES.txt
cups/cups-private.h
cups/cups.h
cups/dest-options.c
cups/ipp.c
cups/ipp.h
doc/help/api-cups.html
doc/help/api-httpipp.html

index 17d27122cd6d7324cf5edac0b59b46235adceb09..fe7c686ef16ac35d21afab6fe93904a11f7c23d6 100644 (file)
@@ -5,6 +5,14 @@ CHANGES IN CUPS V1.7b1
 
        - Added a new "-x" option to the cancel command (STR #4103)
        - Made the PWG media handling APIs public (STR #4267)
+       - Implemented ready media support for the cupsGetDestMediaXxx APIs
+         (STR #4289)
+       - Added new cupsFindDestDefault, cupsFindDestReady, and
+         cupsFindDestSupported APIs (STR #4289)
+       - Added new cupsGetDestMediaByIndex, cupsGetDestMediaCount, and
+         cupsGetDestMediaDefault APIs (STR #4289)
+       - Added new ippGet/SetOctetString APIs for getting and setting an
+         octetString value (STR #4289)
        - Added new ippCreateRequestedArray API for generating a array of
          attributes from the requested-attributes attribute.
        - The ipptool utility now supports compression, conditional tests based
index 1debddd2741b47527d1de4b7df328000c945e3bd..cd32e6f8206917f25723b40687a48a61313933cf 100644 (file)
@@ -219,6 +219,11 @@ struct _cups_dinfo_s                       /* Destination capability and status
   cups_array_t         *media_db;      /* Media database */
   _cups_media_db_t     min_size,       /* Minimum size */
                        max_size;       /* Maximum size */
+  unsigned             cached_flags;   /* Flags used for cached media */
+  cups_array_t         *cached_db;     /* Cache of media from last index/default */
+  time_t               ready_time;     /* When xxx-ready attributes were last queried */
+  ipp_t                        *ready_attrs;   /* xxx-ready attributes */
+  cups_array_t         *ready_db;      /* media[-col]-ready media database */
 };
 
 
index b2443b0b8fe46c240879079a0cfdbbc1e67a3201..4c1ed2e729c55de20ae6dddf0169e1265daab284 100644 (file)
@@ -592,6 +592,29 @@ extern http_status_t       cupsStartDestDocument(http_t *http, cups_dest_t *dest,
                                              int last_document) _CUPS_API_1_6;
 
 /* New in CUPS 1.7 */
+extern ipp_attribute_t *cupsFindDestDefault(http_t *http, cups_dest_t *dest,
+                                            cups_dinfo_t *dinfo,
+                                            const char *option) _CUPS_API_1_7;
+extern ipp_attribute_t *cupsFindDestReady(http_t *http, cups_dest_t *dest,
+                                          cups_dinfo_t *dinfo,
+                                          const char *option) _CUPS_API_1_7;
+extern ipp_attribute_t *cupsFindDestSupported(http_t *http, cups_dest_t *dest,
+                                              cups_dinfo_t *dinfo,
+                                              const char *option)
+                                              _CUPS_API_1_7;
+extern int             cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest,
+                                               cups_dinfo_t *dinfo, int n,
+                                               unsigned flags,
+                                               cups_size_t *size)
+                                               _CUPS_API_1_7;
+extern  int            cupsGetDestMediaCount(http_t *http, cups_dest_t *dest,
+                                             cups_dinfo_t *dinfo,
+                                             unsigned flags) _CUPS_API_1_7;
+extern int             cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest,
+                                               cups_dinfo_t *dinfo,
+                                               unsigned flags,
+                                               cups_size_t *size)
+                                               _CUPS_API_1_7;
 extern void            cupsSetUserAgent(const char *user_agent) _CUPS_API_1_7;
 extern const char      *cupsUserAgent(void) _CUPS_API_1_7;
 
index 3eb644c084d8b153bb916aa185e4abb058f99eef..5201302a85054121369fcc88e0e0efd8326276a0 100644 (file)
  *                              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.
@@ -37,6 +49,7 @@
  *   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...
  */
@@ -56,11 +76,14 @@ static int          cups_compare_dconstres(_cups_dconstres_t *a,
 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,
@@ -72,6 +95,7 @@ static cups_array_t   *cups_test_constraints(cups_dinfo_t *dinfo,
                                               cups_option_t *options,
                                               int *num_conflicts,
                                               cups_option_t **conflicts);
+static void            cups_update_ready(http_t *http, cups_dinfo_t *dinfo);
 
 
 /*
@@ -623,8 +647,8 @@ cupsCopyDestInfo(
     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])),
@@ -680,6 +704,129 @@ cupsCopyDestInfo(
 }
 
 
+/*
+ * '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@.
@@ -708,12 +855,79 @@ cupsFreeDestInfo(cups_dinfo_t *dinfo)     /* I - Destination information */
 
   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.
  *
@@ -775,7 +989,7 @@ cupsGetDestMediaByName(
   * Lookup the size...
   */
 
-  return (cups_get_media_db(dinfo, pwg, flags, size));
+  return (cups_get_media_db(http, dinfo, pwg, flags, size));
 }
 
 
@@ -843,7 +1057,116 @@ cupsGetDestMediaBySize(
   * 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));
 }
 
 
@@ -944,6 +1267,66 @@ cups_copy_media_db(
 }
 
 
+/*
+ * '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.
  */
@@ -1037,7 +1420,8 @@ cups_create_defaults(
 
 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 */
@@ -1046,20 +1430,39 @@ cups_create_media_db(
                        *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 */
 
@@ -1076,15 +1479,32 @@ cups_create_media_db(
                                        /* 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)
        {
@@ -1108,7 +1528,6 @@ cups_create_media_db(
          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;
        }
       }
@@ -1168,7 +1587,7 @@ cups_create_media_db(
                                          IPP_TAG_INTEGER)) != NULL)
         mdb.top = media_attr->values[0].integer;
 
-      cupsArrayAdd(dinfo->media_db, &mdb);
+      cupsArrayAdd(db, &mdb);
     }
 
     if (custom)
@@ -1206,8 +1625,7 @@ cups_create_media_db(
       }
     }
   }
-  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))
@@ -1234,12 +1652,14 @@ cups_create_media_db(
       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;
@@ -1248,7 +1668,7 @@ cups_create_media_db(
       {
         mdb.size_name = val->string.text;
 
-        cupsArrayAdd(dinfo->media_db, &mdb);
+        cupsArrayAdd(db, &mdb);
       }
     }
   }
@@ -1285,11 +1705,13 @@ cups_free_media_db(
  */
 
 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 */
@@ -1299,8 +1721,18 @@ cups_get_media_db(cups_dinfo_t *dinfo,   /* I - Destination information */
   * 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...
@@ -1310,7 +1742,7 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
   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
@@ -1328,9 +1760,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       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)
@@ -1358,9 +1790,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       * 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)
@@ -1373,9 +1805,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       * 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) ||
@@ -1435,9 +1867,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
     * 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;
 
@@ -1455,9 +1887,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       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)
@@ -1476,9 +1908,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       * 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)
@@ -1491,9 +1923,9 @@ cups_get_media_db(cups_dinfo_t *dinfo,    /* I - Destination information */
       * 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) ||
@@ -1759,6 +2191,81 @@ cups_test_constraints(
 }
 
 
+/*
+ * '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$".
  */
index 905df5fdc1a5d4644b4e7b482a61a2ccd9bd91fe..fd6f45f40ac244b3d2c46ea83563c6ac70811922 100644 (file)
@@ -57,6 +57,7 @@
  *   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.
@@ -84,6 +85,7 @@
  *   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.
@@ -2382,6 +2384,45 @@ ippGetName(ipp_attribute_t *attr)        /* I - IPP attribute */
 }
 
 
+/*
+ * '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.
  *
@@ -3712,7 +3753,7 @@ ippReadIO(void       *src,                /* I - Data source */
  */
 
 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 */
@@ -3755,7 +3796,7 @@ ippSetBoolean(ipp_t           *ipp,       /* IO - IPP message */
 
 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 */
@@ -3803,7 +3844,7 @@ ippSetCollection(
  */
 
 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 */
@@ -3849,7 +3890,7 @@ ippSetDate(ipp_t             *ipp,        /* IO - IPP message */
 
 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 */
 {
@@ -3887,7 +3928,7 @@ ippSetGroupTag(
  */
 
 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 */
@@ -3927,7 +3968,7 @@ ippSetInteger(ipp_t           *ipp,       /* IO - IPP message */
  */
 
 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 */
 {
@@ -3957,6 +3998,94 @@ ippSetName(ipp_t           *ipp, /* IO - IPP message */
 }
 
 
+/*
+ * '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.
  *
@@ -4002,7 +4131,7 @@ ippSetOperation(ipp_t    *ipp,            /* I - 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 */
@@ -4083,7 +4212,7 @@ ippSetRequestId(ipp_t *ipp,               /* I - IPP message */
 
 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 */
@@ -4190,7 +4319,7 @@ ippSetStatusCode(ipp_t        *ipp,       /* I - IPP response or event message */
  */
 
 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 */
@@ -4257,7 +4386,7 @@ ippSetString(ipp_t           *ipp,        /* IO - IPP message */
  */
 
 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 */
@@ -4295,7 +4424,7 @@ ippSetStringf(ipp_t           *ipp,       /* IO - IPP message */
  */
 
 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 */
@@ -4448,7 +4577,7 @@ ippSetStringfv(ipp_t           *ipp,      /* IO - IPP message */
 
 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 */
 {
index 0d1b719495e27600363d821c7178e92063bd0b7e..16c54bf3c6a30a2b6e4de556bd845f787235ef84 100644 (file)
@@ -921,7 +921,12 @@ extern int         ippContainsInteger(ipp_attribute_t *attr, int value)
 extern int             ippContainsString(ipp_attribute_t *attr,
                                          const char *value) _CUPS_API_1_7;
 extern cups_array_t    *ippCreateRequestedArray(ipp_t *request) _CUPS_API_1_7;
+extern void            *ippGetOctetString(ipp_attribute_t *attr, int element,
+                                          int *datalen) _CUPS_API_1_7;
 extern ipp_t           *ippNewResponse(ipp_t *request) _CUPS_API_1_7;
+extern int             ippSetOctetString(ipp_t *ipp, ipp_attribute_t **attr,
+                                         int element, const void *data,
+                                         int datalen) _CUPS_API_1_7;
 extern int             ippSetStringf(ipp_t *ipp, ipp_attribute_t **attr,
                                      int element, const char *format,
                                      ...) _CUPS_API_1_7;
index c6bbfb77500ce8f9764195eded0bd048690d9c3d..0ce2a199ca081e7bcb8d4d87c4b41216385d4c6d 100644 (file)
@@ -415,6 +415,9 @@ destination.">cupsCopyDestInfo</a></li>
        <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
@@ -426,8 +429,13 @@ cupsCopyDestInfo.">cupsFreeDestInfo</a></li>
        <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>
@@ -1620,6 +1628,96 @@ continue enumeration or 0 to stop.<br>
 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">&nbsp;CUPS 1.7&nbsp;</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>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;CUPS 1.7&nbsp;</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>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;CUPS 1.7&nbsp;</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>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;CUPS 1.6/OS X 10.8&nbsp;</span><a name="cupsFinishDestDocument">cupsFinishDestDocument</a></h3>
 <p class="description">Finish the current document.</p>
@@ -1795,6 +1893,41 @@ not support the lpoptions-defined default printer.
 <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">&nbsp;CUPS 1.7&nbsp;</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>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int n,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;CUPS 1.6/OS X 10.8&nbsp;</span><a name="cupsGetDestMediaByName">cupsGetDestMediaByName</a></h3>
 <p class="description">Get media names, dimensions, and margins.</p>
 <p class="code">
@@ -1887,6 +2020,66 @@ The matching result (if any) is returned in the &quot;cups_size_t&quot; structur
 <br>
 Returns 1 when there is a match and 0 if there is not a match.
 
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.7&nbsp;</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>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;CUPS 1.7&nbsp;</span><a name="cupsGetDestMediaDefault">cupsGetDestMediaDefault</a></h3>
+<p class="description">Get the default size for a destination.</p>
+<p class="code">
+int cupsGetDestMediaDefault (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_t *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dinfo_t">cups_dinfo_t</a> *dinfo,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<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>
index 639571d08b4a245e130adbd6de86ca722336bc69..0395324109bb2b454f7a56f9e4d5ac9473ad7710 100644 (file)
@@ -552,6 +552,7 @@ in seconds.">ippDateToTime</a></li>
        <li><a href="#ippGetGroupTag" title="Get the group associated with an attribute.">ippGetGroupTag</a></li>
        <li><a href="#ippGetInteger" title="Get the integer/enum value for an attribute.">ippGetInteger</a></li>
        <li><a href="#ippGetName" title="Get the attribute name.">ippGetName</a></li>
+       <li><a href="#ippGetOctetString" title="Get an octetString value from an IPP attribute.">ippGetOctetString</a></li>
        <li><a href="#ippGetOperation" title="Get the operation ID in an IPP message.">ippGetOperation</a></li>
        <li><a href="#ippGetRange" title="Get a rangeOfInteger value from an attribute.">ippGetRange</a></li>
        <li><a href="#ippGetRequestId" title="Get the request ID from an IPP message.">ippGetRequestId</a></li>
@@ -578,6 +579,7 @@ in seconds.">ippDateToTime</a></li>
        <li><a href="#ippSetGroupTag" title="Set the group tag of an attribute.">ippSetGroupTag</a></li>
        <li><a href="#ippSetInteger" title="Set an integer or enum value in an attribute.">ippSetInteger</a></li>
        <li><a href="#ippSetName" title="Set the name of an attribute.">ippSetName</a></li>
+       <li><a href="#ippSetOctetString" title="Set an octetString value in an IPP attribute.">ippSetOctetString</a></li>
        <li><a href="#ippSetOperation" title="Set the operation ID in an IPP request message.">ippSetOperation</a></li>
        <li><a href="#ippSetPort" title="Set the default port number.">ippSetPort</a></li>
        <li><a href="#ippSetRange" title="Set a rangeOfInteger value in an attribute.">ippSetRange</a></li>
@@ -4176,6 +4178,30 @@ const char *ippGetName (<br>
 </dl>
 <h4 class="returnvalue">Return Value</h4>
 <p class="description">Attribute name or <code>NULL</code> for separators</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.7&nbsp;</span><a name="ippGetOctetString">ippGetOctetString</a></h3>
+<p class="description">Get an octetString value from an IPP attribute.</p>
+<p class="code">
+void *ippGetOctetString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int element,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *datalen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>attr</dt>
+<dd class="description">IPP attribute</dd>
+<dt>element</dt>
+<dd class="description">Value number (0-based)</dd>
+<dt>datalen</dt>
+<dd class="description">Length of octetString data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Pointer to octetString data</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>element</code> parameter specifies which value to get from 0 to
+<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1.
+
+</p>
 <h3 class="function"><span class="info">&nbsp;CUPS 1.6/OS X 10.8&nbsp;</span><a name="ippGetOperation">ippGetOperation</a></h3>
 <p class="description">Get the operation ID in an IPP message.</p>
 <p class="code">
@@ -4678,6 +4704,41 @@ the <a href="#ippNew"><code>ippNew</code></a>, <a href="#ippNewRequest"><code>ip
 <br>
 The <code>attr</code> parameter may be modified as a result of setting the value.
 
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.7&nbsp;</span><a name="ippSetOctetString">ippSetOctetString</a></h3>
+<p class="description">Set an octetString value in an IPP attribute.</p>
+<p class="code">
+int ippSetOctetString (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int element,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const void *data,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int datalen<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>attr</dt>
+<dd class="description">IPP attribute</dd>
+<dt>element</dt>
+<dd class="description">Value number (0-based)</dd>
+<dt>data</dt>
+<dd class="description">Pointer to octetString data</dd>
+<dt>datalen</dt>
+<dd class="description">Length of octetString data</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>ipp</code> parameter refers to an IPP message previously created using
+the <a href="#ippNew"><code>ippNew</code></a>, <a href="#ippNewRequest"><code>ippNewRequest</code></a>, or  <a href="#ippNewResponse"><code>ippNewResponse</code></a> functions.<br>
+<br>
+The <code>attr</code> parameter may be modified as a result of setting the value.<br>
+<br>
+The <code>element</code> parameter specifies which value to set from 0 to
+<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>.
+
 </p>
 <h3 class="function"><span class="info">&nbsp;CUPS 1.6/OS X 10.8&nbsp;</span><a name="ippSetOperation">ippSetOperation</a></h3>
 <p class="description">Set the operation ID in an IPP request message.</p>