]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Finish up media improvements (Issue #5167)
authorMichael Sweet <michael.r.sweet@gmail.com>
Wed, 29 Nov 2017 23:01:40 +0000 (18:01 -0500)
committerMichael Sweet <michael.r.sweet@gmail.com>
Wed, 29 Nov 2017 23:07:19 +0000 (18:07 -0500)
cups/cups.h:
- Add cupsAddDestMediaOptions API.

cups/dest-localization.c:
- Fix cupsLocalizeDestMedia API.

cups/dest-options.c:
- Synthesize a media-key value when one is not provided by the printer (!?!?)
- Add cupsAddDestMediaOptions API.

CHANGES.md
cups/cups.h
cups/dest-localization.c
cups/dest-options.c

index 5b1285f62c6b8d0e5a4585c2d50d7daf5ea5a672..fbd42bd8457812b13e99c23799ab55245b657147 100644 (file)
@@ -1,4 +1,4 @@
-CHANGES - 2.3b1 - 2017-11-28
+CHANGES - 2.3b1 - 2017-11-29
 ============================
 
 
@@ -37,6 +37,8 @@ Changes in CUPS v2.3b1
 - Added label markup to checkbox and radio button controls in the web interface
   templates (Issue #5161)
 - Fixed group validation on OpenBSD (Issue #5166)
+- Improved IPP Everywhere media support, including a new
+  `cupsAddDestMediaOptions` function (Issue #5167)
 - IPP Everywhere PPDs now include localizations of printer-specific media types,
   when available (Issue #5168)
 - The cups-driverd program incorrectly stopped scanning PPDs as soon as a loop
index 45de733e691c1ebda9a99c1e8a4de3d0defba955..225e6ca74710cbe058d2c5e207458d9e2d9453e2 100644 (file)
@@ -601,6 +601,7 @@ extern int          cupsAddIntegerOption(const char *name, int value, int num_options, c
 extern int             cupsGetIntegerOption(const char *name, int num_options, cups_option_t *options) _CUPS_API_2_2_4;
 
 /* New in CUPS 2.3 */
+extern int             cupsAddDestMediaOptions(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, cups_size_t *size, int num_options, cups_option_t **options);
 extern const char      *cupsHashString(const unsigned char *hash, size_t hashsize, char *buffer, size_t bufsize) _CUPS_API_2_3;
 
 #  ifdef __cplusplus
index 9950d6badd146caae43ee06f683f9c37e9f8c30f..d6fc8b955ab2222747e95737c718d516609bd6fc 100644 (file)
@@ -44,7 +44,7 @@ cupsLocalizeDestMedia(
   pwg_media_t          *pwg;           /* PWG media information */
   cups_array_t         *db;            /* Media database */
   _cups_media_db_t     *mdb;           /* Media database entry */
-  char                 name[1024],     /* Size name */
+  char                 lstr[1024],     /* Localized size name */
                        temp[256];      /* Temporary string */
   const char           *lsize,         /* Localized media size */
                        *lsource,       /* Localized media source */
@@ -65,41 +65,79 @@ cupsLocalizeDestMedia(
   }
 
  /*
-  * See if the localization is cached...
+  * Find the matching media database entry...
   */
 
-  if (!dinfo->localizations)
-    cups_create_localizations(http, dinfo);
+  if (flags & CUPS_MEDIA_FLAGS_READY)
+    db = dinfo->ready_db;
+  else
+    db = dinfo->media_db;
 
-  key.msg = size->media;
-  if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL)
+  DEBUG_printf(("1cupsLocalizeDestMedia: size->media=\"%s\"", size->media));
+
+  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
   {
-    DEBUG_printf(("1cupsLocalizeDestMedia: Returning \"%s\".", match->str));
-    return (match->str);
+    if (mdb->key && !strcmp(mdb->key, size->media))
+      break;
+    else if (mdb->size_name && !strcmp(mdb->size_name, size->media))
+      break;
+  }
+
+  if (!mdb)
+  {
+    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
+    {
+      if (mdb->width == size->width && mdb->length == size->length && mdb->bottom == size->bottom && mdb->left == size->left && mdb->right == size->right && mdb->top == size->top)
+       break;
+    }
   }
 
  /*
-  * If not, get the localized size, source, and type strings...
+  * See if the localization is cached...
   */
 
   lang = cupsLangDefault();
 
+  if (!dinfo->localizations)
+    cups_create_localizations(http, dinfo);
+
   snprintf(temp, sizeof(temp), "media.%s", size->media);
-  if ((lsize = _cupsLangString(lang, temp)) != NULL && strcmp(lsize, temp))
+  key.msg = temp;
+
+  if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL)
   {
-    DEBUG_printf(("1cupsLocalizeDestMedia: Returning standard localization \"%s\".", lsize));
-    return (lsize);
+    lsize = match->str;
+  }
+  else
+  {
+   /*
+    * Not a media name, try a media-key name...
+    */
+
+    snprintf(temp, sizeof(temp), "media-key.%s", size->media);
+    if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL)
+      lsize = match->str;
+    else
+      lsize = NULL;
   }
 
-  pwg = pwgMediaForSize(size->width, size->length);
+  if (!lsize && (pwg = pwgMediaForSize(size->width, size->length)) != NULL && pwg->ppd)
+  {
+   /*
+    * Get a standard localization...
+    */
 
-  if (pwg->ppd)
-    lsize = _cupsLangString(lang, pwg->ppd);
-  else
-    lsize = NULL;
+    snprintf(temp, sizeof(temp), "media.%s", pwg->pwg);
+    if ((lsize = _cupsLangString(lang, temp)) == temp)
+      lsize = NULL;
+  }
 
   if (!lsize)
   {
+   /*
+    * Make a dimensional localization...
+    */
+
     if ((size->width % 635) == 0 && (size->length % 635) == 0)
     {
      /*
@@ -120,30 +158,6 @@ cupsLocalizeDestMedia(
     lsize = temp;
   }
 
-  if (flags & CUPS_MEDIA_FLAGS_READY)
-    db = dinfo->ready_db;
-  else
-    db = dinfo->media_db;
-
-  DEBUG_printf(("1cupsLocalizeDestMedia: size->media=\"%s\"", size->media));
-
-  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
-  {
-    if (mdb->key && !strcmp(mdb->key, size->media))
-      break;
-    else if (mdb->size_name && !strcmp(mdb->size_name, size->media))
-      break;
-  }
-
-  if (!mdb)
-  {
-    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
-    {
-      if (mdb->width == size->width && mdb->length == size->length && mdb->bottom == size->bottom && mdb->left == size->left && mdb->right == size->right && mdb->top == size->top)
-       break;
-    }
-  }
-
   if (mdb)
   {
     DEBUG_printf(("1cupsLocalizeDestMedia: MATCH mdb%p [key=\"%s\" size_name=\"%s\" source=\"%s\" type=\"%s\" width=%d length=%d B%d L%d R%d T%d]", (void *)mdb, mdb->key, mdb->size_name, mdb->source, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top));
@@ -160,37 +174,37 @@ cupsLocalizeDestMedia(
   if (!lsource && !ltype)
   {
     if (!size->bottom && !size->left && !size->right && !size->top)
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless)")), lsize);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless)")), lsize);
     else
-      strlcpy(name, lsize, sizeof(name));
+      strlcpy(lstr, lsize, sizeof(lstr));
   }
   else if (!lsource)
   {
     if (!size->bottom && !size->left && !size->right && !size->top)
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, ltype);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, ltype);
     else
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s)")), lsize, ltype);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s)")), lsize, ltype);
   }
   else if (!ltype)
   {
     if (!size->bottom && !size->left && !size->right && !size->top)
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, lsource);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, lsource);
     else
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s)")), lsize, lsource);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s)")), lsize, lsource);
   }
   else
   {
     if (!size->bottom && !size->left && !size->right && !size->top)
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s, %s)")), lsize, ltype, lsource);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s, %s)")), lsize, ltype, lsource);
     else
-      snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s, %s)")), lsize, ltype, lsource);
+      snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s, %s)")), lsize, ltype, lsource);
   }
 
   if ((match = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL)
     return (NULL);
 
   match->msg = strdup(size->media);
-  match->str = strdup(name);
+  match->str = strdup(lstr);
 
   cupsArrayAdd(dinfo->localizations, match);
 
index de4841b0eb57f76394c1759c63df65746b408bf0..a2830cc1436e0451fa527944210d7acc44a5ea65 100644 (file)
@@ -52,6 +52,104 @@ static cups_array_t *cups_test_constraints(cups_dinfo_t *dinfo,
 static void            cups_update_ready(http_t *http, cups_dinfo_t *dinfo);
 
 
+/*
+ * 'cupsAddDestMediaOptions()' - Add the option corresponding to the specified media size.
+ *
+ * @since CUPS 2.3@
+ */
+
+int                                    /* O  - New number of options */
+cupsAddDestMediaOptions(
+    http_t        *http,               /* I  - Connection to destination */
+    cups_dest_t   *dest,               /* I  - Destination */
+    cups_dinfo_t  *dinfo,              /* I  - Destination information */
+    unsigned      flags,               /* I  - Media matching flags */
+    cups_size_t   *size,               /* I  - Media size */
+    int           num_options,         /* I  - Current number of options */
+    cups_option_t **options)           /* IO - Options */
+{
+  cups_array_t         *db;            /* Media database */
+  _cups_media_db_t     *mdb;           /* Media database entry */
+  char                 value[2048];    /* Option value */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!http || !dest || !dinfo || !size || !options)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+    return (num_options);
+  }
+
+ /*
+  * Find the matching media size...
+  */
+
+  if (flags & CUPS_MEDIA_FLAGS_READY)
+    db = dinfo->ready_db;
+  else
+    db = dinfo->media_db;
+
+  DEBUG_printf(("1cupsAddDestMediaOptions: size->media=\"%s\"", size->media));
+
+  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
+  {
+    if (mdb->key && !strcmp(mdb->key, size->media))
+      break;
+    else if (mdb->size_name && !strcmp(mdb->size_name, size->media))
+      break;
+  }
+
+  if (!mdb)
+  {
+    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
+    {
+      if (mdb->width == size->width && mdb->length == size->length && mdb->bottom == size->bottom && mdb->left == size->left && mdb->right == size->right && mdb->top == size->top)
+       break;
+    }
+  }
+
+  if (!mdb)
+  {
+    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db))
+    {
+      if (mdb->width == size->width && mdb->length == size->length)
+       break;
+    }
+  }
+
+  if (!mdb)
+  {
+    DEBUG_puts("1cupsAddDestMediaOptions: Unable to find matching size.");
+    return (num_options);
+  }
+
+  DEBUG_printf(("1cupsAddDestMediaOptions: MATCH mdb%p [key=\"%s\" size_name=\"%s\" source=\"%s\" type=\"%s\" width=%d length=%d B%d L%d R%d T%d]", (void *)mdb, mdb->key, mdb->size_name, mdb->source, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top));
+
+  if (mdb->source)
+  {
+    if (mdb->type)
+      snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\" media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source, mdb->type);
+    else
+      snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source);
+  }
+  else if (mdb->type)
+  {
+    snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->type);
+  }
+  else
+  {
+    snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top);
+  }
+
+  num_options = cupsAddOption("media-col", value, num_options, options);
+
+  return (num_options);
+}
+
+
 /*
  * 'cupsCheckDestSupported()' - Check that the option and value are supported
  *                              by the destination.
@@ -1507,6 +1605,7 @@ cups_create_media_db(
   pwg_media_t          *pwg;           /* PWG media info */
   cups_array_t         *db;            /* New media database array */
   _cups_media_db_t     mdb;            /* Media entry */
+  char                 media_key[255]; /* Synthesized media-key value */
 
 
   db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db,
@@ -1662,6 +1761,16 @@ cups_create_media_db(
                                          IPP_TAG_INTEGER)) != NULL)
         mdb.top = media_attr->values[0].integer;
 
+      if (!mdb.key)
+      {
+        if (flags & CUPS_MEDIA_FLAGS_READY)
+          snprintf(media_key, sizeof(media_key), "cups-media-ready-%d", i + 1);
+       else
+          snprintf(media_key, sizeof(media_key), "cups-media-%d", i + 1);
+
+        mdb.key = media_key;
+      }
+
       cupsArrayAdd(db, &mdb);
     }
 
@@ -2021,12 +2130,10 @@ cups_get_media_db(http_t       *http,   /* I - Connection to destination */
     * Return the matching size...
     */
 
-    if (!best->bottom && !best->left && !best->right && !best->top)
-      snprintf(size->media, sizeof(size->media), "%s.Borderless", pwg->ppd);
+    if (best->key)
+      strlcpy(size->media, best->key, sizeof(size->media));
     else if (best->size_name)
       strlcpy(size->media, best->size_name, sizeof(size->media));
-    else if (best->key)
-      strlcpy(size->media, best->key, sizeof(size->media));
     else
       strlcpy(size->media, pwg->pwg, sizeof(size->media));