*
* PPD cache implementation for CUPS.
*
- * Copyright 2010-2012 by Apple Inc.
+ * Copyright 2010-2013 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
_pwg_finishings_t *b);
static void pwg_free_finishings(_pwg_finishings_t *f);
static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
-static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize);
+static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize,
+ const char *dashchars);
/*
{
cups_file_t *fp; /* File */
_ppd_cache_t *pc; /* PWG mapping data */
- _pwg_size_t *size; /* Current size */
- _pwg_map_t *map; /* Current map */
+ pwg_size_t *size; /* Current size */
+ pwg_map_t *map; /* Current map */
_pwg_finishings_t *finishings; /* Current finishings option */
int linenum, /* Current line number */
num_bins, /* Number of bins in file */
if (!filename)
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
return (NULL);
}
if ((fp = cupsFileOpen(filename, "r")) == NULL)
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
return (NULL);
}
if (!cupsFileGets(fp, line, sizeof(line)))
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
DEBUG_puts("_ppdCacheCreateWithFile: Unable to read first line.");
cupsFileClose(fp);
return (NULL);
if (strncmp(line, "#CUPS-PPD-CACHE-", 16))
{
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
DEBUG_printf(("_ppdCacheCreateWithFile: Wrong first line \"%s\".", line));
cupsFileClose(fp);
return (NULL);
if (atoi(line + 16) != _PPD_CACHE_VERSION)
{
- _cupsSetError(IPP_INTERNAL_ERROR, _("Out of date PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Out of date PPD cache file."), 1);
DEBUG_printf(("_ppdCacheCreateWithFile: Cache file has version %s, "
"expected %d.", line + 16, _PPD_CACHE_VERSION));
cupsFileClose(fp);
if ((pc = calloc(1, sizeof(_ppd_cache_t))) == NULL)
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
DEBUG_puts("_ppdCacheCreateWithFile: Unable to allocate _ppd_cache_t.");
goto create_error;
}
+ pc->max_copies = 9999;
+
/*
* Read the file...
*/
{
DEBUG_printf(("_ppdCacheCreateWithFile: Missing value on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
else if (!_cups_strcasecmp(line, "Filter"))
if (attrs && *attrs)
{
DEBUG_puts("_ppdCacheCreateWithFile: IPP listed multiple times.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
else if (length <= 0)
{
DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP length.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
*attrs = ippNew();
if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
- *attrs) != IPP_DATA)
+ *attrs) != IPP_STATE_DATA)
{
DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP data.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
}
if (cupsFileTell(fp) != (pos + length))
{
DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP data.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
}
if (num_bins > 0)
{
DEBUG_puts("_ppdCacheCreateWithFile: NumBins listed multiple times.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumBins value %d on line "
"%d.", num_sizes, linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- if ((pc->bins = calloc(num_bins, sizeof(_pwg_map_t))) == NULL)
+ if ((pc->bins = calloc(num_bins, sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d bins.",
num_sizes));
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
goto create_error;
}
}
if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad Bin on line %d.", linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Too many Bin's on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
if (num_sizes > 0)
{
DEBUG_puts("_ppdCacheCreateWithFile: NumSizes listed multiple times.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
+ if ((num_sizes = atoi(value)) < 0 || num_sizes > 65536)
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSizes value %d on line "
"%d.", num_sizes, linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+ if (num_sizes > 0)
{
- DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
- num_sizes));
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
- goto create_error;
+ if ((pc->sizes = calloc(num_sizes, sizeof(pwg_size_t))) == NULL)
+ {
+ DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
+ num_sizes));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ goto create_error;
+ }
}
}
else if (!_cups_strcasecmp(line, "Size"))
{
DEBUG_printf(("_ppdCacheCreateWithFile: Too many Size's on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad Size on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Too many CustomSize's on line "
"%d.", linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad CustomSize on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
- pc->custom_max_width, pc->custom_max_length);
+ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
+ pc->custom_max_width, pc->custom_max_length, NULL);
pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
- _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
- pc->custom_min_width, pc->custom_min_length);
+ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
+ pc->custom_min_width, pc->custom_min_length, NULL);
pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
}
else if (!_cups_strcasecmp(line, "SourceOption"))
{
DEBUG_puts("_ppdCacheCreateWithFile: NumSources listed multiple "
"times.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSources value %d on "
"line %d.", num_sources, linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- if ((pc->sources = calloc(num_sources, sizeof(_pwg_map_t))) == NULL)
+ if ((pc->sources = calloc(num_sources, sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sources.",
num_sources));
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
goto create_error;
}
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad Source on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Too many Source's on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
if (num_types > 0)
{
DEBUG_puts("_ppdCacheCreateWithFile: NumTypes listed multiple times.");
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumTypes value %d on "
"line %d.", num_types, linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
- if ((pc->types = calloc(num_types, sizeof(_pwg_map_t))) == NULL)
+ if ((pc->types = calloc(num_types, sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d types.",
num_types));
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
goto create_error;
}
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad Type on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Too many Type's on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Bad Preset on line %d.",
linenum));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
cupsArrayAdd(pc->finishings, finishings);
}
+ else if (!_cups_strcasecmp(line, "MaxCopies"))
+ pc->max_copies = atoi(value);
+ else if (!_cups_strcasecmp(line, "ChargeInfoURI"))
+ pc->charge_info_uri = _cupsStrAlloc(value);
+ else if (!_cups_strcasecmp(line, "JobAccountId"))
+ pc->account_id = !_cups_strcasecmp(value, "true");
+ else if (!_cups_strcasecmp(line, "JobAccountingUserId"))
+ pc->accounting_user_id = !_cups_strcasecmp(value, "true");
+ else if (!_cups_strcasecmp(line, "JobPassword"))
+ pc->password = _cupsStrAlloc(value);
+ else if (!_cups_strcasecmp(line, "Mandatory"))
+ {
+ if (pc->mandatory)
+ _cupsArrayAddStrings(pc->mandatory, value, ' ');
+ else
+ pc->mandatory = _cupsArrayNewStrings(value, ' ');
+ }
+ else if (!_cups_strcasecmp(line, "SupportFile"))
+ {
+ if (!pc->support_files)
+ pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0,
+ (cups_acopy_func_t)_cupsStrAlloc,
+ (cups_afree_func_t)_cupsStrFree);
+
+ cupsArrayAdd(pc->support_files, value);
+ }
else
{
DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line,
{
DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sizes (%d < %d).",
pc->num_sizes, num_sizes));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sources (%d < %d).",
pc->num_sources, num_sources));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
{
DEBUG_printf(("_ppdCacheCreateWithFile: Not enough types (%d < %d).",
pc->num_types, num_types));
- _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
goto create_error;
}
*color_model, /* ColorModel option */
*duplex; /* Duplex option */
ppd_choice_t *choice; /* Current InputSlot/MediaType */
- _pwg_map_t *map; /* Current source/type map */
+ pwg_map_t *map; /* Current source/type map */
ppd_attr_t *ppd_attr; /* Current PPD preset attribute */
int num_options; /* Number of preset options and props */
cups_option_t *options; /* Preset options and properties */
ppd_size_t *ppd_size; /* Current PPD size */
- _pwg_size_t *pwg_size; /* Current PWG size */
+ pwg_size_t *pwg_size; /* Current PWG size */
char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3],
/* PWG keyword string */
ppd_name[PPD_MAX_NAME];
/* Normalized PPD name */
const char *pwg_name; /* Standard PWG media name */
- _pwg_media_t *pwg_media; /* PWG media data */
+ pwg_media_t *pwg_media; /* PWG media data */
_pwg_print_color_mode_t pwg_print_color_mode;
/* print-color-mode index */
_pwg_print_quality_t pwg_print_quality;
/* print-quality index */
int similar; /* Are the old and new size similar? */
- _pwg_size_t *old_size; /* Current old size */
+ pwg_size_t *old_size; /* Current old size */
int old_imageable, /* Old imageable length in 2540ths */
old_borderless, /* Old borderless state */
old_known_pwg; /* Old PWG name is well-known */
new_imageable, /* New imageable length in 2540ths */
new_borderless, /* New borderless state */
new_known_pwg; /* New PWG name is well-known */
- _pwg_size_t *new_size; /* New size to add, if any */
+ pwg_size_t *new_size; /* New size to add, if any */
const char *filter; /* Current filter */
_pwg_finishings_t *finishings; /* Current finishings value */
* Copy and convert size data...
*/
- if (ppd->num_sizes == 0)
+ if (ppd->num_sizes > 0)
{
- DEBUG_puts("_ppdCacheCreateWithPPD: No page sizes in PPD.");
- goto create_error;
- }
-
- if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
- {
- DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
- "_pwg_size_t's.", ppd->num_sizes));
- goto create_error;
- }
-
- for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
- i > 0;
- i --, ppd_size ++)
- {
- /*
- * Don't copy over custom size...
- */
-
- if (!_cups_strcasecmp(ppd_size->name, "Custom"))
- continue;
-
- /*
- * Convert the PPD size name to the corresponding PWG keyword name.
- */
-
- if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL)
+ if ((pc->sizes = calloc(ppd->num_sizes, sizeof(pwg_size_t))) == NULL)
{
- /*
- * Standard name, do we have conflicts?
- */
-
- for (j = 0; j < pc->num_sizes; j ++)
- if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
- {
- pwg_media = NULL;
- break;
- }
+ DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+ "pwg_size_t's.", ppd->num_sizes));
+ goto create_error;
}
- if (pwg_media)
+ for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
+ i > 0;
+ i --, ppd_size ++)
{
/*
- * Standard name and no conflicts, use it!
+ * Don't copy over custom size...
*/
- pwg_name = pwg_media->pwg;
- new_known_pwg = 1;
- }
- else
- {
+ if (!_cups_strcasecmp(ppd_size->name, "Custom"))
+ continue;
+
/*
- * Not a standard name; convert it to a PWG vendor name of the form:
- *
- * pp_lowerppd_WIDTHxHEIGHTuu
+ * Convert the PPD size name to the corresponding PWG keyword name.
*/
- pwg_name = pwg_keyword;
- new_known_pwg = 0;
+ if ((pwg_media = pwgMediaForPPD(ppd_size->name)) != NULL)
+ {
+ /*
+ * Standard name, do we have conflicts?
+ */
- pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name));
- _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
- _PWG_FROMPTS(ppd_size->width),
- _PWG_FROMPTS(ppd_size->length));
- }
+ for (j = 0; j < pc->num_sizes; j ++)
+ if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
+ {
+ pwg_media = NULL;
+ break;
+ }
+ }
- /*
- * If we have a similar paper with non-zero margins then we only
- * want to keep it if it has a larger imageable area length.
- */
+ if (pwg_media)
+ {
+ /*
+ * Standard name and no conflicts, use it!
+ */
- pwg_media = _pwgMediaForSize(_PWG_FROMPTS(ppd_size->width),
- _PWG_FROMPTS(ppd_size->length));
- new_width = pwg_media->width;
- new_length = pwg_media->length;
- new_left = _PWG_FROMPTS(ppd_size->left);
- new_bottom = _PWG_FROMPTS(ppd_size->bottom);
- new_right = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
- new_top = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
- new_imageable = new_length - new_top - new_bottom;
- new_borderless = new_bottom == 0 && new_top == 0 &&
- new_left == 0 && new_right == 0;
-
- for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
- k > 0 && !similar;
- k --, old_size ++)
- {
- old_imageable = old_size->length - old_size->top - old_size->bottom;
- old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
- old_size->right == 0 && old_size->top == 0;
- old_known_pwg = strncmp(old_size->map.pwg, "oe_", 3) &&
- strncmp(old_size->map.pwg, "om_", 3);
-
- similar = old_borderless == new_borderless &&
- _PWG_EQUIVALENT(old_size->width, new_width) &&
- _PWG_EQUIVALENT(old_size->length, new_length);
-
- if (similar &&
- (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+ pwg_name = pwg_media->pwg;
+ new_known_pwg = 1;
+ }
+ else
{
/*
- * The new paper has a larger imageable area so it could replace
- * the older paper. Regardless of the imageable area, we always
- * prefer the size with a well-known PWG name.
+ * Not a standard name; convert it to a PWG vendor name of the form:
+ *
+ * pp_lowerppd_WIDTHxHEIGHTuu
*/
- new_size = old_size;
- _cupsStrFree(old_size->map.ppd);
- _cupsStrFree(old_size->map.pwg);
+ pwg_name = pwg_keyword;
+ new_known_pwg = 0;
+
+ pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name), "_.");
+ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
+ PWG_FROM_POINTS(ppd_size->width),
+ PWG_FROM_POINTS(ppd_size->length), NULL);
}
- }
- if (!similar)
- {
/*
- * The paper was unique enough to deserve its own entry so add it to the
- * end.
+ * If we have a similar paper with non-zero margins then we only want to
+ * keep it if it has a larger imageable area length. The NULL check is for
+ * dimensions that are <= 0...
*/
- new_size = pwg_size ++;
- pc->num_sizes ++;
- }
+ if ((pwg_media = pwgMediaForSize(PWG_FROM_POINTS(ppd_size->width),
+ PWG_FROM_POINTS(ppd_size->length))) == NULL)
+ continue;
- if (new_size)
- {
- /*
- * Save this size...
- */
+ new_width = pwg_media->width;
+ new_length = pwg_media->length;
+ new_left = PWG_FROM_POINTS(ppd_size->left);
+ new_bottom = PWG_FROM_POINTS(ppd_size->bottom);
+ new_right = PWG_FROM_POINTS(ppd_size->width - ppd_size->right);
+ new_top = PWG_FROM_POINTS(ppd_size->length - ppd_size->top);
+ new_imageable = new_length - new_top - new_bottom;
+ new_borderless = new_bottom == 0 && new_top == 0 &&
+ new_left == 0 && new_right == 0;
+
+ for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
+ k > 0 && !similar;
+ k --, old_size ++)
+ {
+ old_imageable = old_size->length - old_size->top - old_size->bottom;
+ old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
+ old_size->right == 0 && old_size->top == 0;
+ old_known_pwg = strncmp(old_size->map.pwg, "oe_", 3) &&
+ strncmp(old_size->map.pwg, "om_", 3);
+
+ similar = old_borderless == new_borderless &&
+ _PWG_EQUIVALENT(old_size->width, new_width) &&
+ _PWG_EQUIVALENT(old_size->length, new_length);
+
+ if (similar &&
+ (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
+ {
+ /*
+ * The new paper has a larger imageable area so it could replace
+ * the older paper. Regardless of the imageable area, we always
+ * prefer the size with a well-known PWG name.
+ */
+
+ new_size = old_size;
+ _cupsStrFree(old_size->map.ppd);
+ _cupsStrFree(old_size->map.pwg);
+ }
+ }
+
+ if (!similar)
+ {
+ /*
+ * The paper was unique enough to deserve its own entry so add it to the
+ * end.
+ */
+
+ new_size = pwg_size ++;
+ pc->num_sizes ++;
+ }
- new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
- new_size->map.pwg = _cupsStrAlloc(pwg_name);
- new_size->width = new_width;
- new_size->length = new_length;
- new_size->left = new_left;
- new_size->bottom = new_bottom;
- new_size->right = new_right;
- new_size->top = new_top;
+ if (new_size)
+ {
+ /*
+ * Save this size...
+ */
+
+ new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
+ new_size->map.pwg = _cupsStrAlloc(pwg_name);
+ new_size->width = new_width;
+ new_size->length = new_length;
+ new_size->left = new_left;
+ new_size->bottom = new_bottom;
+ new_size->right = new_right;
+ new_size->top = new_top;
+ }
}
}
* Generate custom size data...
*/
- _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
- _PWG_FROMPTS(ppd->custom_max[0]),
- _PWG_FROMPTS(ppd->custom_max[1]));
+ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
+ PWG_FROM_POINTS(ppd->custom_max[0]),
+ PWG_FROM_POINTS(ppd->custom_max[1]), NULL);
pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
- pc->custom_max_width = _PWG_FROMPTS(ppd->custom_max[0]);
- pc->custom_max_length = _PWG_FROMPTS(ppd->custom_max[1]);
+ pc->custom_max_width = PWG_FROM_POINTS(ppd->custom_max[0]);
+ pc->custom_max_length = PWG_FROM_POINTS(ppd->custom_max[1]);
- _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
- _PWG_FROMPTS(ppd->custom_min[0]),
- _PWG_FROMPTS(ppd->custom_min[1]));
+ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
+ PWG_FROM_POINTS(ppd->custom_min[0]),
+ PWG_FROM_POINTS(ppd->custom_min[1]), NULL);
pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
- pc->custom_min_width = _PWG_FROMPTS(ppd->custom_min[0]);
- pc->custom_min_length = _PWG_FROMPTS(ppd->custom_min[1]);
+ pc->custom_min_width = PWG_FROM_POINTS(ppd->custom_min[0]);
+ pc->custom_min_length = PWG_FROM_POINTS(ppd->custom_min[1]);
- pc->custom_size.left = _PWG_FROMPTS(ppd->custom_margins[0]);
- pc->custom_size.bottom = _PWG_FROMPTS(ppd->custom_margins[1]);
- pc->custom_size.right = _PWG_FROMPTS(ppd->custom_margins[2]);
- pc->custom_size.top = _PWG_FROMPTS(ppd->custom_margins[3]);
+ pc->custom_size.left = PWG_FROM_POINTS(ppd->custom_margins[0]);
+ pc->custom_size.bottom = PWG_FROM_POINTS(ppd->custom_margins[1]);
+ pc->custom_size.right = PWG_FROM_POINTS(ppd->custom_margins[2]);
+ pc->custom_size.top = PWG_FROM_POINTS(ppd->custom_margins[3]);
}
/*
pc->source_option = _cupsStrAlloc(input_slot->keyword);
if ((pc->sources = calloc(input_slot->num_choices,
- sizeof(_pwg_map_t))) == NULL)
+ sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
- "_pwg_map_t's for InputSlot.", input_slot->num_choices));
+ "pwg_map_t's for InputSlot.", input_slot->num_choices));
goto create_error;
}
*/
pwg_name = pwg_keyword;
- pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword));
+ pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword),
+ "_");
}
map->pwg = _cupsStrAlloc(pwg_name);
if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
{
if ((pc->types = calloc(media_type->num_choices,
- sizeof(_pwg_map_t))) == NULL)
+ sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
- "_pwg_map_t's for MediaType.", media_type->num_choices));
+ "pwg_map_t's for MediaType.", media_type->num_choices));
goto create_error;
}
*/
pwg_name = pwg_keyword;
- pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword));
+ pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword),
+ "_");
}
map->pwg = _cupsStrAlloc(pwg_name);
if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
{
if ((pc->bins = calloc(output_bin->num_choices,
- sizeof(_pwg_map_t))) == NULL)
+ sizeof(pwg_map_t))) == NULL)
{
DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
- "_pwg_map_t's for OutputBin.", output_bin->num_choices));
+ "pwg_map_t's for OutputBin.", output_bin->num_choices));
goto create_error;
}
i > 0;
i --, choice ++, map ++)
{
- pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword));
+ pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword), "_");
map->pwg = _cupsStrAlloc(pwg_keyword);
map->ppd = _cupsStrAlloc(choice->choice);
NULL)) != NULL);
}
+ /*
+ * Max copies...
+ */
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL)
+ pc->max_copies = atoi(ppd_attr->value);
+ else if (ppd->manual_copies)
+ pc->max_copies = 1;
+ else
+ pc->max_copies = 9999;
+
+ /*
+ * cupsChargeInfoURI, cupsJobAccountId, cupsJobAccountingUserId,
+ * cupsJobPassword, and cupsMandatory.
+ */
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsChargeInfoURI", NULL)) != NULL)
+ pc->charge_info_uri = _cupsStrAlloc(ppd_attr->value);
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL)
+ pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true");
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountingUserId", NULL)) != NULL)
+ pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true");
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL)
+ pc->password = _cupsStrAlloc(ppd_attr->value);
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
+ pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
+
+ /*
+ * Support files...
+ */
+
+ pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0,
+ (cups_acopy_func_t)_cupsStrAlloc,
+ (cups_afree_func_t)_cupsStrFree);
+
+ for (ppd_attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ ppd_attr;
+ ppd_attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ cupsArrayAdd(pc->support_files, ppd_attr->value);
+
+ if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
+ cupsArrayAdd(pc->support_files, ppd_attr->value);
+
/*
* Return the cache data...
*/
create_error:
- _cupsSetError(IPP_INTERNAL_ERROR, _("Out of memory."), 1);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Out of memory."), 1);
_ppdCacheDestroy(pc);
return (NULL);
_ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */
{
int i; /* Looping var */
- _pwg_map_t *map; /* Current map */
- _pwg_size_t *size; /* Current size */
+ pwg_map_t *map; /* Current map */
+ pwg_size_t *size; /* Current size */
/*
cupsArrayDelete(pc->prefilters);
cupsArrayDelete(pc->finishings);
+ _cupsStrFree(pc->charge_info_uri);
+ _cupsStrFree(pc->password);
+
+ cupsArrayDelete(pc->mandatory);
+
+ cupsArrayDelete(pc->support_files);
+
free(pc);
}
int /* O - New number of options */
_ppdCacheGetFinishingOptions(
- _ppd_cache_t *pc, /* I - PPD cache and mapping data */
- ipp_t *job, /* I - Job attributes or NULL */
- ipp_finish_t value, /* I - IPP finishings value of IPP_FINISHINGS_NONE */
- int num_options, /* I - Number of options */
- cups_option_t **options) /* IO - Options */
+ _ppd_cache_t *pc, /* I - PPD cache and mapping data */
+ ipp_t *job, /* I - Job attributes or NULL */
+ ipp_finishings_t value, /* I - IPP finishings value of IPP_FINISHINGS_NONE */
+ int num_options, /* I - Number of options */
+ cups_option_t **options) /* IO - Options */
{
int i; /* Looping var */
_pwg_finishings_t *f, /* PWG finishings options */
ipp_attribute_t *media_col, /* media-col attribute */
*media_source; /* media-source attribute */
- _pwg_size_t size; /* Dimensional size */
+ pwg_size_t size; /* Dimensional size */
int margins_set; /* Were the margins set? */
media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
keyword = ippGetString(media_source, 0, NULL);
}
- else if (_pwgInitSize(&size, job, &margins_set))
+ else if (pwgInitSize(&size, job, &margins_set))
{
/*
* For media <= 5x7, look for a photo tray...
int *exact) /* O - 1 if exact match, 0 otherwise */
{
int i; /* Looping var */
- _pwg_size_t *size, /* Current size */
+ pwg_size_t *size, /* Current size */
*closest, /* Closest size */
jobsize; /* Size data from job */
int margins_set, /* Were the margins set? */
* media-col.
*/
- if (!_pwgInitSize(&jobsize, job, &margins_set))
+ if (!pwgInitSize(&jobsize, job, &margins_set))
return (NULL);
}
else
* Get the size using a media keyword...
*/
- _pwg_media_t *media; /* Media definition */
+ pwg_media_t *media; /* Media definition */
- if ((media = _pwgMediaForPWG(keyword)) == NULL)
- if ((media = _pwgMediaForLegacy(keyword)) == NULL)
- if ((media = _pwgMediaForPPD(keyword)) == NULL)
+ if ((media = pwgMediaForPWG(keyword)) == NULL)
+ if ((media = pwgMediaForLegacy(keyword)) == NULL)
+ if ((media = pwgMediaForPPD(keyword)) == NULL)
return (NULL);
jobsize.width = media->width;
*/
snprintf(pc->custom_ppd_size, sizeof(pc->custom_ppd_size), "Custom.%dx%d",
- (int)_PWG_TOPTS(jobsize.width), (int)_PWG_TOPTS(jobsize.length));
+ (int)PWG_TO_POINTS(jobsize.width), (int)PWG_TO_POINTS(jobsize.length));
if (margins_set && exact)
{
* '_ppdCacheGetSize()' - Get the PWG size associated with a PPD PageSize.
*/
-_pwg_size_t * /* O - PWG size or NULL */
+pwg_size_t * /* O - PWG size or NULL */
_ppdCacheGetSize(
_ppd_cache_t *pc, /* I - PPD cache and mapping data */
const char *page_size) /* I - PPD PageSize */
{
int i; /* Looping var */
- _pwg_media_t *media; /* Media */
- _pwg_size_t *size; /* Current size */
+ pwg_media_t *media; /* Media */
+ pwg_size_t *size; /* Current size */
/*
* Look up standard sizes...
*/
- if ((media = _pwgMediaForPPD(page_size)) == NULL)
- if ((media = _pwgMediaForLegacy(page_size)) == NULL)
- media = _pwgMediaForPWG(page_size);
+ if ((media = pwgMediaForPPD(page_size)) == NULL)
+ if ((media = pwgMediaForLegacy(page_size)) == NULL)
+ media = pwgMediaForPWG(page_size);
if (media)
{
const char *input_slot) /* I - PPD InputSlot */
{
int i; /* Looping var */
- _pwg_map_t *source; /* Current source */
+ pwg_map_t *source; /* Current source */
/*
const char *media_type) /* I - PPD MediaType */
{
int i; /* Looping var */
- _pwg_map_t *type; /* Current type */
+ pwg_map_t *type; /* Current type */
/*
{
int i, j, k; /* Looping vars */
cups_file_t *fp; /* Output file */
- _pwg_size_t *size; /* Current size */
- _pwg_map_t *map; /* Current map */
+ pwg_size_t *size; /* Current size */
+ pwg_map_t *map; /* Current map */
_pwg_finishings_t *f; /* Current finishing option */
cups_option_t *option; /* Current option */
const char *value; /* Filter/pre-filter value */
if (!pc || !filename)
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
return (0);
}
snprintf(newfile, sizeof(newfile), "%s.N", filename);
if ((fp = cupsFileOpen(newfile, "w9")) == NULL)
{
- _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
return (0);
}
cupsFilePutChar(fp, '\n');
}
+ /*
+ * Max copies...
+ */
+
+ cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies);
+
+ /*
+ * Accounting/quota/PIN/managed printing values...
+ */
+
+ if (pc->charge_info_uri)
+ cupsFilePutConf(fp, "ChargeInfoURI", pc->charge_info_uri);
+
+ cupsFilePrintf(fp, "AccountId %s\n", pc->account_id ? "true" : "false");
+ cupsFilePrintf(fp, "AccountingUserId %s\n",
+ pc->accounting_user_id ? "true" : "false");
+
+ if (pc->password)
+ cupsFilePutConf(fp, "Password", pc->password);
+
+ for (value = (char *)cupsArrayFirst(pc->mandatory);
+ value;
+ value = (char *)cupsArrayNext(pc->mandatory))
+ cupsFilePutConf(fp, "Mandatory", value);
+
+ /*
+ * Support files...
+ */
+
+ for (value = (char *)cupsArrayFirst(pc->support_files);
+ value;
+ value = (char *)cupsArrayNext(pc->support_files))
+ cupsFilePutConf(fp, "SupportFile", value);
+
/*
* IPP attributes, if any...
*/
{
cupsFilePrintf(fp, "IPP " CUPS_LLFMT "\n", CUPS_LLCAST ippLength(attrs));
- attrs->state = IPP_IDLE;
+ attrs->state = IPP_STATE_IDLE;
ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL, attrs);
}
const char * /* O - PageSize name */
_pwgPageSizeForMedia(
- _pwg_media_t *media, /* I - Media */
+ pwg_media_t *media, /* I - Media */
char *name, /* I - PageSize name buffer */
size_t namesize) /* I - Size of name buffer */
{
* Use a name of the form "wNNNhNNN"...
*/
- snprintf(name, namesize, "w%dh%d", (int)_PWG_TOPTS(media->width),
- (int)_PWG_TOPTS(media->length));
+ snprintf(name, namesize, "w%dh%d", (int)PWG_TO_POINTS(media->width),
+ (int)PWG_TO_POINTS(media->length));
}
else
{
static void
pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
char *name, /* I - Name buffer */
- size_t namesize) /* I - Size of name buffer */
+ size_t namesize, /* I - Size of name buffer */
+ const char *dashchars)/* I - Characters to be replaced by dashes */
{
char *ptr, /* Pointer into name buffer */
*end; /* End of name buffer */
{
if (_cups_isalnum(*ppd) || *ppd == '-')
*ptr++ = tolower(*ppd & 255);
- else if (*ppd == '_' || *ppd == '.')
+ else if (strchr(dashchars, *ppd))
*ptr++ = '-';
+ else
+ *ptr++ = *ppd;
if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
_cups_isupper(ppd[1]) && ptr < end)