*
* Copyright 2010-2017 by Apple Inc.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * missing or damaged, see the license at "http://www.cups.org/".
- *
- * This file is subject to the Apple OS-Developed Software exception.
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
*/
/*
* Local functions...
*/
+static int cups_get_url(http_t **http, const char *url, char *name, size_t namesize);
static void pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value);
static int pwg_compare_finishings(_pwg_finishings_t *a,
_pwg_finishings_t *b);
static void pwg_free_finishings(_pwg_finishings_t *f);
-static void pwg_free_material(_pwg_material_t *m);
static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize,
* attributes and values and adds them to the specified IPP request.
*/
-int /* O - New number of copies */
-_cupsConvertOptions(ipp_t *request, /* I - IPP request */
- ppd_file_t *ppd, /* I - PPD file */
- _ppd_cache_t *pc, /* I - PPD cache info */
- ipp_attribute_t *media_col_sup,
- /* I - media-col-supported values */
- ipp_attribute_t *doc_handling_sup,
- /* I - multiple-document-handling-supported values */
- ipp_attribute_t *print_color_mode_sup,
- /* I - Printer supports print-color-mode */
- const char *user, /* I - User info */
- const char *format, /* I - document-format value */
- int copies, /* I - Number of copies */
- int num_options, /* I - Number of options */
- cups_option_t *options) /* I - Options */
+int /* O - New number of copies */
+_cupsConvertOptions(
+ ipp_t *request, /* I - IPP request */
+ ppd_file_t *ppd, /* I - PPD file */
+ _ppd_cache_t *pc, /* I - PPD cache info */
+ ipp_attribute_t *media_col_sup, /* I - media-col-supported values */
+ ipp_attribute_t *doc_handling_sup, /* I - multiple-document-handling-supported values */
+ ipp_attribute_t *print_color_mode_sup,
+ /* I - Printer supports print-color-mode */
+ const char *user, /* I - User info */
+ const char *format, /* I - document-format value */
+ int copies, /* I - Number of copies */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
{
int i; /* Looping var */
const char *keyword, /* PWG keyword */
int num_finishings = 0, /* Number of finishing values */
finishings[10]; /* Finishing enum values */
ppd_choice_t *choice; /* Marked choice */
+ int finishings_copies = copies;
+ /* Number of copies for finishings */
/*
{
ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings);
- if (copies > 1 && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL)
+ if (copies != finishings_copies && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL)
{
/*
* Send job-pages-per-set attribute to apply finishings correctly...
*/
- ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / copies);
+ ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / finishings_copies);
}
}
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- else if (!_cups_strcasecmp(line, "3D"))
- {
- pc->cups_3d = _cupsStrAlloc(value);
- }
- else if (!_cups_strcasecmp(line, "LayerOrder"))
- {
- pc->cups_layer_order = _cupsStrAlloc(value);
- }
- else if (!_cups_strcasecmp(line, "Accuracy"))
- {
- sscanf(value, "%d%d%d", pc->cups_accuracy + 0, pc->cups_accuracy + 1, pc->cups_accuracy + 2);
- }
- else if (!_cups_strcasecmp(line, "Volume"))
- {
- sscanf(value, "%d%d%d", pc->cups_volume + 0, pc->cups_volume + 1, pc->cups_volume + 2);
- }
- else if (!_cups_strcasecmp(line, "Material"))
- {
- /*
- * Material key "name" name=value ... name=value
- */
-
- if ((valueptr = strchr(value, ' ')) != NULL)
- {
- _pwg_material_t *material = (_pwg_material_t *)calloc(1, sizeof(_pwg_material_t));
-
- *valueptr++ = '\0';
-
- material->key = _cupsStrAlloc(value);
-
- if (*valueptr == '\"')
- {
- value = valueptr + 1;
- if ((valueptr = strchr(value, '\"')) != NULL)
- {
- *valueptr++ = '\0';
- material->name = _cupsStrAlloc(value);
- material->num_props = cupsParseOptions(valueptr, 0, &material->props);
- }
- }
-
- if (!pc->materials)
- pc->materials = cupsArrayNew3(NULL, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_material);
-
- cupsArrayAdd(pc->materials, material);
- }
- }
else if (!_cups_strcasecmp(line, "Filter"))
{
if (!pc->filters)
else
pc->mandatory = _cupsArrayNewStrings(value, ' ');
}
+ else if (!_cups_strcasecmp(line, "StringsURI"))
+ pc->strings_uri = _cupsStrAlloc(value);
else if (!_cups_strcasecmp(line, "SupportFile"))
{
if (!pc->support_files)
if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
+ /*
+ * Strings (remote) file...
+ */
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsStringsURI", NULL)) != NULL)
+ pc->strings_uri = _cupsStrAlloc(ppd_attr->value);
+
/*
* Support files...
*/
if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
cupsArrayAdd(pc->support_files, ppd_attr->value);
- /*
- * 3D stuff...
- */
-
- if ((ppd_attr = ppdFindAttr(ppd, "cups3D", NULL)) != NULL)
- pc->cups_3d = _cupsStrAlloc(ppd_attr->value);
-
- if ((ppd_attr = ppdFindAttr(ppd, "cupsLayerOrder", NULL)) != NULL)
- pc->cups_layer_order = _cupsStrAlloc(ppd_attr->value);
-
- if ((ppd_attr = ppdFindAttr(ppd, "cupsAccuracy", NULL)) != NULL)
- sscanf(ppd_attr->value, "%d%d%d", pc->cups_accuracy + 0, pc->cups_accuracy + 1, pc->cups_accuracy + 2);
-
- if ((ppd_attr = ppdFindAttr(ppd, "cupsVolume", NULL)) != NULL)
- sscanf(ppd_attr->value, "%d%d%d", pc->cups_volume + 0, pc->cups_volume + 1, pc->cups_volume + 2);
-
- for (ppd_attr = ppdFindAttr(ppd, "cupsMaterial", NULL);
- ppd_attr;
- ppd_attr = ppdFindNextAttr(ppd, "cupsMaterial", NULL))
- {
- /*
- * *cupsMaterial key/name: "name=value ... name=value"
- */
-
- _pwg_material_t *material = (_pwg_material_t *)calloc(1, sizeof(_pwg_material_t));
-
- material->key = _cupsStrAlloc(ppd_attr->name);
- material->name = _cupsStrAlloc(ppd_attr->text);
- material->num_props = cupsParseOptions(ppd_attr->value, 0, &material->props);
-
- if (!pc->materials)
- pc->materials = cupsArrayNew3(NULL, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_material);
-
- cupsArrayAdd(pc->materials, material);
- }
-
/*
* Return the cache data...
*/
cupsArrayDelete(pc->support_files);
- _cupsStrFree(pc->cups_3d);
- _cupsStrFree(pc->cups_layer_order);
-
- cupsArrayDelete(pc->materials);
-
free(pc);
}
DEBUG_printf(("_ppdCacheGetFinishingValues(pc=%p, num_options=%d, options=%p, max_values=%d, values=%p)", pc, num_options, options, max_values, values));
- if (!pc || !pc->finishings || num_options < 1 || max_values < 1 || !values)
+ if (!pc || max_values < 1 || !values)
{
DEBUG_puts("_ppdCacheGetFinishingValues: Bad arguments, returning 0.");
return (0);
}
+ else if (!pc->finishings)
+ {
+ DEBUG_puts("_ppdCacheGetFinishingValues: No finishings support, returning 0.");
+ return (0);
+ }
/*
* Go through the finishings options and see what is set...
if (i == 0)
{
- DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d.", f->value));
+ DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d (%s)", f->value, ippEnumString("finishings", f->value)));
values[num_values ++] = f->value;
}
}
+ if (num_values == 0)
+ {
+ /*
+ * Always have at least "finishings" = 'none'...
+ */
+
+ DEBUG_puts("_ppdCacheGetFinishingValues: Adding 3 (none).");
+ values[0] = IPP_FINISHINGS_NONE;
+ num_values ++;
+ }
+
DEBUG_printf(("_ppdCacheGetFinishingValues: Returning %d.", num_values));
return (num_values);
cups_option_t *option; /* Current option */
const char *value; /* Filter/pre-filter value */
char newfile[1024]; /* New filename */
- _pwg_material_t *m; /* Material */
/*
value = (char *)cupsArrayNext(pc->mandatory))
cupsFilePutConf(fp, "Mandatory", value);
+ /*
+ * (Remote) strings file...
+ */
+
+ if (pc->strings_uri)
+ cupsFilePutConf(fp, "StringsURI", pc->strings_uri);
+
/*
* Support files...
*/
value = (char *)cupsArrayNext(pc->support_files))
cupsFilePutConf(fp, "SupportFile", value);
- /*
- * 3D stuff...
- */
-
- if (pc->cups_3d)
- cupsFilePutConf(fp, "3D", pc->cups_3d);
-
- if (pc->cups_layer_order)
- cupsFilePutConf(fp, "LayerOrder", pc->cups_layer_order);
-
- if (pc->cups_accuracy[0] || pc->cups_accuracy[0] || pc->cups_accuracy[2])
- cupsFilePrintf(fp, "Accuracy %d %d %d\n", pc->cups_accuracy[0], pc->cups_accuracy[1], pc->cups_accuracy[2]);
-
- if (pc->cups_volume[0] || pc->cups_volume[0] || pc->cups_volume[2])
- cupsFilePrintf(fp, "Volume %d %d %d\n", pc->cups_volume[0], pc->cups_volume[1], pc->cups_volume[2]);
-
- for (m = (_pwg_material_t *)cupsArrayFirst(pc->materials);
- m;
- m = (_pwg_material_t *)cupsArrayNext(pc->materials))
- {
- cupsFilePrintf(fp, "Material %s \"%s\"", m->key, m->name);
- for (i = 0; i < m->num_props; i ++)
- cupsFilePrintf(fp, " %s=%s", m->props[i].name, m->props[i].value);
- cupsFilePuts(fp, "\n");
- }
-
/*
* IPP attributes, if any...
*/
is_pwg = 0; /* Does the printer support PWG Raster? */
pwg_media_t *pwg; /* PWG media size */
int xres, yres; /* Resolution values */
+ int resolutions[1000];
+ /* Array of resolution indices */
cups_lang_t *lang = cupsLangDefault();
/* Localization info */
+ cups_array_t *strings = NULL;/* Printer strings file */
struct lconv *loc = localeconv();
/* Locale data */
+ cups_array_t *fin_options = NULL;
+ /* Finishing options */
static const char * const finishings[][2] =
{ /* Finishings strings */
{ "bale", _("Bale") },
cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
cupsFilePuts(fp, "*cupsSNMPSupplies: False\n");
- cupsFilePuts(fp, "*cupsLanguages: \"en\"\n");
+ cupsFilePrintf(fp, "*cupsLanguages: \"%s\"\n", lang->language);
+
+ if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != NULL)
+ cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL));
+
+ if ((attr = ippFindAttribute(response, "printer-charge-info-uri", IPP_TAG_URI)) != NULL)
+ cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL));
+
+ if ((attr = ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI)) != NULL)
+ {
+ http_t *http = NULL; /* Connection to printer */
+ char stringsfile[1024]; /* Temporary strings file */
+
+ if (cups_get_url(&http, ippGetString(attr, 0, NULL), stringsfile, sizeof(stringsfile)))
+ {
+ cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0, NULL));
+
+ strings = _cupsMessageLoad(stringsfile, _CUPS_MESSAGE_STRINGS | _CUPS_MESSAGE_UNQUOTE);
+
+ unlink(stringsfile);
+ }
+
+ if (http)
+ httpClose(http);
+ }
/*
* Filters...
{ "cardboard", _("Cardboard") },
{ "cardstock", _("Cardstock") },
{ "cd", _("CD") },
+ { "com.hp.advanced-photo", _("Advanced Photo Paper") }, /* HP */
+ { "com.hp.brochure-glossy", _("Glossy Brochure Paper") }, /* HP */
+ { "com.hp.brochure-matte", _("Matte Brochure Paper") }, /* HP */
+ { "com.hp.cover-matte", _("Matte Cover Paper") }, /* HP */
+ { "com.hp.ecosmart-lite", _("Office Recycled Paper") }, /* HP */
+ { "com.hp.everyday-glossy", _("Everyday Glossy Photo Paper") }, /* HP */
+ { "com.hp.everyday-matte", _("Everyday Matte Paper") }, /* HP */
+ { "com.hp.extra-heavy", _("Extra Heavyweight Paper") }, /* HP */
+ { "com.hp.intermediate", _("Multipurpose Paper") }, /* HP */
+ { "com.hp.mid-weight", _("Mid-Weight Paper") }, /* HP */
+ { "com.hp.premium-inkjet", _("Premium Inkjet Paper") }, /* HP */
+ { "com.hp.premium-photo", _("Premium Photo Glossy Paper") }, /* HP */
+ { "com.hp.premium-presentation-matte", _("Premium Presentation Matte Paper") }, /* HP */
{ "continuous", _("Continuous") },
{ "continuous-long", _("Continuous Long") },
{ "continuous-short", _("Continuous Short") },
{ "gravure-cylinder", _("Gravure Cylinder") },
{ "image-setter-paper", _("Image Setter Paper") },
{ "imaging-cylinder", _("Imaging Cylinder") },
+ { "jp.co.canon_photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */
+ { "jp.co.canon_photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */
+ { "jp.co.canon-photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */
+ { "jp.co.canon-photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */
{ "labels", _("Labels") },
{ "labels-colored", _("Colored Labels") },
{ "labels-glossy", _("Glossy Labels") },
{ "paper", _("Paper") },
{ "photo", _("Photo Paper") }, /* HP mis-spelling */
{ "photographic", _("Photo Paper") },
- { "photographic-archival", _("Photographic Archival") },
+ { "photographic-archival", _("Archival Photo Paper") },
{ "photographic-film", _("Photo Film") },
{ "photographic-glossy", _("Glossy Photo Paper") },
{ "photographic-high-gloss", _("High Gloss Photo Paper") },
{ "single-face", _("Single Face") },
{ "single-wall", _("Single Wall Cardboard") },
{ "sleeve", _("Sleeve") },
- { "stationery", _("Stationery") },
- { "stationery-archival", _("Stationery Archival") },
+ { "stationery", _("Plain Paper") },
+ { "stationery-archival", _("Archival Paper") },
{ "stationery-coated", _("Coated Paper") },
- { "stationery-cotton", _("Stationery Cotton") },
+ { "stationery-cotton", _("Cotton Paper") },
{ "stationery-fine", _("Vellum Paper") },
{ "stationery-heavyweight", _("Heavyweight Paper") },
- { "stationery-heavyweight-coated", _("Stationery Heavyweight Coated") },
- { "stationery-inkjet", _("Stationery Inkjet Paper") },
+ { "stationery-heavyweight-coated", _("Heavyweight Coated Paper") },
+ { "stationery-inkjet", _("Inkjet Paper") },
{ "stationery-letterhead", _("Letterhead") },
{ "stationery-lightweight", _("Lightweight Paper") },
{ "stationery-preprinted", _("Preprinted Paper") },
pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
for (j = 0; j < (int)(sizeof(media_types) / sizeof(media_types[0])); j ++)
- if (!strcmp(keyword, media_types[i][0]))
+ if (!strcmp(keyword, media_types[j][0]))
break;
if (j < (int)(sizeof(media_types) / sizeof(media_types[0])))
cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, _cupsLangString(lang, media_types[j][1]), ppdname);
else
- cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, keyword, ppdname);
+ {
+ char msg[256]; /* Message key */
+ const char *str; /* Localized string */
+
+ snprintf(msg, sizeof(msg), "media-type.%s", keyword);
+ if ((str = _cupsMessageLookup(strings, msg)) == msg)
+ str = keyword;
+
+ cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, str, ppdname);
+ }
}
cupsFilePuts(fp, "*CloseUI: *MediaType\n");
}
* ColorModel...
*/
- if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
- if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL)
+ if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
if ((attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) == NULL)
attr = ippFindAttribute(response, "output-mode-supported", IPP_TAG_KEYWORD);
const char *keyword = ippGetString(attr, i, NULL);
/* Keyword for color/bit depth */
- if (!strcmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
+ if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
{
if (!default_color)
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
if (!default_color)
default_color = "FastGray";
}
- else if (!strcmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
+ else if (!strcasecmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
{
if (!default_color)
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
if (!default_color || !strcmp(default_color, "FastGray"))
default_color = "Gray";
}
- else if (!strcmp(keyword, "srgb_8") || !strcmp(keyword, "SRGB24") || !strcmp(keyword, "color"))
+ else if (!strcasecmp(keyword, "srgb_8") || !strcmp(keyword, "SRGB24") || !strcmp(keyword, "color"))
{
if (!default_color)
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
default_color = "RGB";
}
- else if (!strcmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48"))
+ else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48"))
{
if (!default_color)
cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n"
"*Duplex DuplexTumble/%s: \"<</Duplex true/Tumble true>>setpagedevice\"\n"
"*CloseUI: *Duplex\n", _cupsLangString(lang, _("2-Sided Printing")), _cupsLangString(lang, _("Off (1-Sided)")), _cupsLangString(lang, _("Long-Edge (Portrait)")), _cupsLangString(lang, _("Short-Edge (Landscape)")));
- if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
+ {
+ for (i = 0, count = ippGetCount(attr); i < count; i ++)
+ {
+ const char *dm = ippGetString(attr, i, NULL);
+ /* DM value */
+
+ if (!_cups_strcasecmp(dm, "DM1"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Normal\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM2"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM3"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
+ break;
+ }
+ else if (!_cups_strcasecmp(dm, "DM4"))
+ {
+ cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
+ break;
+ }
+ }
+ }
+ else if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
{
const char *keyword = ippGetString(attr, 0, NULL);
/* Keyword value */
else
cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
}
- else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
- {
- for (i = 0, count = ippGetCount(attr); i < count; i ++)
- {
- const char *dm = ippGetString(attr, i, NULL);
- /* DM value */
-
- if (!_cups_strcasecmp(dm, "DM1"))
- {
- cupsFilePuts(fp, "*cupsBackSide: Normal\n");
- break;
- }
- else if (!_cups_strcasecmp(dm, "DM2"))
- {
- cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
- break;
- }
- else if (!_cups_strcasecmp(dm, "DM3"))
- {
- cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
- break;
- }
- else if (!_cups_strcasecmp(dm, "DM4"))
- {
- cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
- break;
- }
- }
- }
}
/*
* Finishing options...
*/
- if ((attr = ippFindAttribute(response, "finishings-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
+ if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL)
{
- ipp_t *col; /* Collection value */
- ipp_attribute_t *template; /* "finishing-template" member */
const char *name; /* String name */
- int value; /* Enum value, if any */
+ int value; /* Enum value */
cups_array_t *names; /* Names we've added */
- count = ippGetCount(attr);
- names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+ count = ippGetCount(attr);
+ names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
+ fin_options = cupsArrayNew((cups_array_func_t)strcmp, NULL);
- cupsFilePrintf(fp, "*OpenUI *cupsFinishingTemplate/%s: PickMany\n"
- "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n"
- "*DefaultcupsFinishingTemplate: none\n"
- "*cupsFinishingTemplate none/%s: \"\"\n"
- "*cupsIPPFinishings 3/none: \"*cupsFinishingTemplate none\"\n", _cupsLangString(lang, _("Finishing")), _cupsLangString(lang, _("No Finishing")));
+ /*
+ * Staple/Bind/Stitch
+ */
for (i = 0; i < count; i ++)
{
- col = ippGetCollection(attr, i);
- template = ippFindAttribute(col, "finishing-template", IPP_TAG_ZERO);
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
- if ((name = ippGetString(template, 0, NULL)) == NULL || !strcmp(name, "none"))
- continue;
+ if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) || !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch"))
+ break;
+ }
- if (cupsArrayFind(names, (char *)name))
- continue; /* Already did this finishing template */
+ if (i < count)
+ {
+ cupsArrayAdd(fin_options, "*StapleLocation");
- cupsArrayAdd(names, (char *)name);
+ cupsFilePrintf(fp, "*OpenUI *StapleLocation/%s: PickOne\n", _cupsLangString(lang, _("Staple")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n");
+ cupsFilePuts(fp, "*DefaultStapleLocation: None\n");
+ cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n", _cupsLangString(lang, _("None")));
- for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ for (; i < count; i ++)
{
- if (!strcmp(finishings[j][0], name))
- {
- cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
- value = ippEnumValue("finishings", name);
+ if (strncmp(name, "staple-", 7) && strncmp(name, "bind-", 5) && strncmp(name, "edge-stitch-", 12) && strcmp(name, "saddle-stitch"))
+ continue;
- if (value)
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*cupsFinishingTemplate %s\"\n", value, name, name);
- break;
- }
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*StapleLocation %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, name, name);
+ break;
+ }
+ }
}
+
+ cupsFilePuts(fp, "*CloseUI: *StapleLocation\n");
}
- cupsArrayDelete(names);
+ /*
+ * Fold
+ */
- cupsFilePuts(fp, "*CloseUI: *cupsFinishingTemplate\n");
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (!strncmp(name, "fold-", 5))
+ break;
+ }
+
+ if (i < count)
+ {
+ cupsArrayAdd(fin_options, "*FoldType");
+
+ cupsFilePrintf(fp, "*OpenUI *FoldType/%s: PickOne\n", _cupsLangString(lang, _("Fold")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n");
+ cupsFilePuts(fp, "*DefaultFoldType: None\n");
+ cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+
+ for (; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (strncmp(name, "fold-", 5))
+ continue;
+
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*FoldType %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, name, name);
+ break;
+ }
+ }
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *FoldType\n");
+ }
+
+ /*
+ * Punch
+ */
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (!strncmp(name, "punch-", 6))
+ break;
+ }
+
+ if (i < count)
+ {
+ cupsArrayAdd(fin_options, "*PunchMedia");
+
+ cupsFilePrintf(fp, "*OpenUI *PunchMedia/%s: PickOne\n", _cupsLangString(lang, _("Punch")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n");
+ cupsFilePuts(fp, "*DefaultPunchMedia: None\n");
+ cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n", _cupsLangString(lang, _("None")));
+
+ for (i = 0; i < count; i ++)
+ {
+ value = ippGetInteger(attr, i);
+ name = ippEnumString("finishings", value);
+
+ if (strncmp(name, "punch-", 6))
+ continue;
+
+ if (cupsArrayFind(names, (char *)name))
+ continue; /* Already did this finishing template */
+
+ cupsArrayAdd(names, (char *)name);
+
+ for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ {
+ if (!strcmp(finishings[j][0], name))
+ {
+ cupsFilePrintf(fp, "*PunchMedia %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, name, name);
+ break;
+ }
+ }
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *PunchMedia\n");
+ }
+
+ /*
+ * Booklet
+ */
+
+ if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER))
+ {
+ cupsArrayAdd(fin_options, "*Booklet");
+
+ cupsFilePrintf(fp, "*OpenUI *Booklet/%s: Boolean\n", _cupsLangString(lang, _("Booklet")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n");
+ cupsFilePuts(fp, "*DefaultBooklet: False\n");
+ cupsFilePuts(fp, "*Booklet False: \"\"\n");
+ cupsFilePuts(fp, "*Booklet True: \"\"\n");
+ cupsFilePrintf(fp, "*cupsIPPFinishings %d/booklet-maker: \"*Booklet True\"\n", IPP_FINISHINGS_BOOKLET_MAKER);
+ cupsFilePuts(fp, "*CloseUI: *Booklet\n");
+ }
+
+ cupsArrayDelete(names);
}
- else if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL && (count = ippGetCount(attr)) > 1 )
+
+ if ((attr = ippFindAttribute(response, "finishings-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
{
- const char *name; /* String name */
- int value; /* Enum value, if any */
+ ipp_t *finishing_col; /* Current finishing collection */
+ const char *template, /* Current finishing template */
+ *loctemplate; /* Localized template name */
+ cups_array_t *templates; /* Finishing templates */
- count = ippGetCount(attr);
+ cupsFilePrintf(fp, "*OpenUI *cupsFinishingTemplate/%s: PickOne\n", _cupsLangString(lang, _("Finishing Preset")));
+ cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n");
+ cupsFilePuts(fp, "*DefaultcupsFinishingTemplate: None\n");
+ cupsFilePrintf(fp, "*cupsFinishingTemplate None/%s: \"\"\n", _cupsLangString(lang, _("None")));
- cupsFilePrintf(fp, "*OpenUI *cupsFinishingTemplate/%s: PickMany\n"
- "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n"
- "*DefaultcupsFinishingTemplate: none\n"
- "*cupsFinishingTemplate none/%s: \"\"\n"
- "*cupsIPPFinishings 3/none: \"*cupsFinishingTemplate none\"\n", _cupsLangString(lang, _("Finishing")), _cupsLangString(lang, _("No Finishing")));
+ templates = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+ count = ippGetCount(attr);
for (i = 0; i < count; i ++)
{
- if ((value = ippGetInteger(attr, i)) == 3)
+ finishing_col = ippGetCollection(attr, i);
+ template = ippGetString(ippFindAttribute(finishing_col, "finishing_template", IPP_TAG_ZERO), 0, NULL);
+
+ if (!template || cupsArrayFind(templates, (void *)template))
continue;
- name = ippEnumString("finishings", value);
- for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
+ if (strncmp(template, "fold-", 5) && (strstr(template, "-bottom") || strstr(template, "-left") || strstr(template, "-right") || strstr(template, "-top")))
+ continue;
+
+ cupsArrayAdd(templates, (void *)template);
+
+ for (j = 0, loctemplate = NULL; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++)
{
- if (!strcmp(finishings[j][0], name))
- {
- cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1]));
- cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*cupsFinishingTemplate %s\"\n", value, name, name);
+ if (!strcmp(finishings[j][0], template))
+ {
+ loctemplate = _cupsLangString(lang, finishings[j][1]);
break;
- }
+ }
}
+
+ if (!loctemplate)
+ {
+ char msg[256]; /* Message key */
+
+ snprintf(msg, sizeof(msg), "finishing-template.%s", template);
+ if ((loctemplate = _cupsMessageLookup(strings, msg)) == msg)
+ loctemplate = template;
+ }
+
+ cupsFilePrintf(fp, "*cupsFinishingTemplate %s/%s: \"\"\n", template, loctemplate);
}
cupsFilePuts(fp, "*CloseUI: *cupsFinishingTemplate\n");
+
+ if (cupsArrayCount(fin_options))
+ {
+ const char *fin_option; /* Current finishing option */
+
+ cupsFilePuts(fp, "*cupsUIConstraint finisings: \"*cupsFinishingTemplate");
+ for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
+ cupsFilePrintf(fp, " %s", fin_option);
+ cupsFilePuts(fp, "\"\n");
+
+ cupsFilePuts(fp, "*cupsUIResolver finisings: \"*cupsFinishingTemplate None");
+ for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
+ cupsFilePrintf(fp, " %s None", fin_option);
+ cupsFilePuts(fp, "\"\n");
+ }
+
+ cupsArrayDelete(templates);
}
+ cupsArrayDelete(fin_options);
+
/*
* cupsPrintQuality and DefaultResolution...
*/
quality = ippFindAttribute(response, "print-quality-supported", IPP_TAG_ENUM);
- if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL)
- {
- count = ippGetCount(attr);
-
- pwg_ppdize_resolution(attr, count / 2, &xres, &yres, ppdname, sizeof(ppdname));
- cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
-
- cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
- if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT))
- {
- pwg_ppdize_resolution(attr, 0, &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres);
- }
- pwg_ppdize_resolution(attr, count / 2, &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres);
- if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH))
- {
- if (count > 1)
- pwg_ppdize_resolution(attr, count - 1, &xres, &yres, NULL, 0);
- else
- pwg_ppdize_resolution(attr, 0, &xres, &yres, NULL, 0);
- cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres);
- }
-
- cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
- }
- else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
+ if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
{
- int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
+ int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
for (i = 0, count = ippGetCount(attr); i < count; i ++)
{
const char *rs = ippGetString(attr, i, NULL);
- /* RS value */
+ /* RS value */
if (_cups_strncasecmp(rs, "RS", 2))
continue;
cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi);
cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
- "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
- "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
if ((lowdpi & 1) == 0)
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi / 2);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi / 2);
else if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
- cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi);
cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), lowdpi, lowdpi);
if (hidpi > lowdpi || ippContainsInteger(quality, IPP_QUALITY_HIGH))
- cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), hidpi, hidpi);
+ cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), hidpi, hidpi);
cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
}
}
+ else if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL)
+ {
+ /*
+ * Make a sorted list of resolutions.
+ */
+
+ count = ippGetCount(attr);
+ if (count > (int)(sizeof(resolutions) / sizeof(resolutions[0])))
+ count = (int)(sizeof(resolutions) / sizeof(resolutions[0]));
+
+ resolutions[0] = 0; /* Not in loop to silence Clang static analyzer... */
+ for (i = 1; i < count; i ++)
+ resolutions[i] = i;
+
+ for (i = 0; i < (count - 1); i ++)
+ {
+ for (j = i + 1; j < count; j ++)
+ {
+ int ix, iy, /* First X and Y resolution */
+ jx, jy, /* Second X and Y resolution */
+ temp; /* Swap variable */
+ ipp_res_t units; /* Resolution units */
+
+ ix = ippGetResolution(attr, resolutions[i], &iy, &units);
+ jx = ippGetResolution(attr, resolutions[j], &jy, &units);
+
+ if (ix > jx || (ix == jx && iy > jy))
+ {
+ /*
+ * Swap these two resolutions...
+ */
+
+ temp = resolutions[i];
+ resolutions[i] = resolutions[j];
+ resolutions[j] = temp;
+ }
+ }
+ }
+
+ /*
+ * Generate print quality options...
+ */
+
+ pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, ppdname, sizeof(ppdname));
+ cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
+
+ cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n"
+ "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
+ "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality")));
+ if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT))
+ {
+ pwg_ppdize_resolution(attr, resolutions[0], &xres, &yres, NULL, 0);
+ cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres);
+ }
+ pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, NULL, 0);
+ cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres);
+ if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH))
+ {
+ pwg_ppdize_resolution(attr, resolutions[count - 1], &xres, &yres, NULL, 0);
+ cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<</HWResolution[%d %d]>>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres);
+ }
+
+ cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
+ }
else if (is_apple || is_pwg)
goto bad_ppd;
else
}
+/*
+ * 'cups_get_url()' - Get a copy of the file at the given URL.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+cups_get_url(http_t **http, /* IO - Current HTTP connection */
+ const char *url, /* I - URL to get */
+ char *name, /* I - Temporary filename */
+ size_t namesize) /* I - Size of temporary filename buffer */
+{
+ char scheme[32], /* URL scheme */
+ userpass[256], /* URL username:password */
+ host[256], /* URL host */
+ curhost[256], /* Current host */
+ resource[256]; /* URL resource */
+ int port; /* URL port */
+ http_encryption_t encryption; /* Type of encryption to use */
+ http_status_t status; /* Status of GET request */
+ int fd; /* Temporary file */
+
+
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ return (0);
+
+ if (port == 443 || !strcmp(scheme, "https"))
+ encryption = HTTP_ENCRYPTION_ALWAYS;
+ else
+ encryption = HTTP_ENCRYPTION_IF_REQUESTED;
+
+ if (!*http || strcasecmp(host, httpGetHostname(*http, curhost, sizeof(curhost))) || httpAddrPort(httpGetAddress(*http)) != port)
+ {
+ httpClose(*http);
+ *http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 5000, NULL);
+ }
+
+ if (!*http)
+ return (0);
+
+ if ((fd = cupsTempFd(name, (int)namesize)) < 0)
+ return (0);
+
+ status = cupsGetFd(*http, resource, fd);
+
+ close(fd);
+
+ if (status != HTTP_STATUS_OK)
+ {
+ unlink(name);
+ *name = '\0';
+ return (0);
+ }
+
+ return (1);
+}
+
+
/*
* 'pwg_add_finishing()' - Add a finishings value.
*/
}
-/*
- * 'pwg_free_material()' - Free a material value.
- */
-
-static void
-pwg_free_material(_pwg_material_t *m) /* I - Material value */
-{
- _cupsStrFree(m->key);
- _cupsStrFree(m->name);
-
- cupsFreeOptions(m->num_props, m->props);
-
- free(m);
-}
-
-
/*
* 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword.
*/