From: Michael Sweet Date: Wed, 29 Nov 2017 23:01:40 +0000 (-0500) Subject: Finish up media improvements (Issue #5167) X-Git-Tag: v2.3b1~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71dc43af7ac3172e091c53d147bb9e4fa1a2210a;p=thirdparty%2Fcups.git Finish up media improvements (Issue #5167) 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. --- diff --git a/CHANGES.md b/CHANGES.md index 5b1285f62c..fbd42bd845 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 diff --git a/cups/cups.h b/cups/cups.h index 45de733e69..225e6ca747 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -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 diff --git a/cups/dest-localization.c b/cups/dest-localization.c index 9950d6badd..d6fc8b955a 100644 --- a/cups/dest-localization.c +++ b/cups/dest-localization.c @@ -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); diff --git a/cups/dest-options.c b/cups/dest-options.c index de4841b0eb..a2830cc143 100644 --- a/cups/dest-options.c +++ b/cups/dest-options.c @@ -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));