From: msweet Date: Wed, 28 Jan 2015 21:05:25 +0000 (+0000) Subject: Move CUPS->IPP mapping code to libcups. X-Git-Tag: v2.2b1~374 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=07eca067cf47d001a270be338ed27be95d34c573;p=thirdparty%2Fcups.git Move CUPS->IPP mapping code to libcups. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12439 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/backend/ipp.c b/backend/ipp.c index ee482058ad..dc7d8bb7db 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -2556,19 +2556,10 @@ new_request( ipp_attribute_t *print_color_mode_sup) /* I - Printer supports print-color-mode */ { - int i; /* Looping var */ ipp_t *request; /* Request data */ const char *keyword; /* PWG keyword */ - _pwg_size_t *size; /* PWG media size */ - ipp_t *media_col, /* media-col value */ - *media_size; /* media-size value */ - const char *media_source, /* media-source value */ - *media_type, /* media-type value */ - *collate_str, /* multiple-document-handling value */ - *mandatory; /* Mandatory attributes */ ipp_tag_t group; /* Current group */ ipp_attribute_t *attr; /* Current attribute */ - const char *color_attr_name; /* Supported color attribute */ char buffer[1024]; /* Value buffer */ @@ -2588,36 +2579,31 @@ new_request( * Add standard attributes... */ - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); fprintf(stderr, "DEBUG: printer-uri=\"%s\"\n", uri); if (user && *user) { - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, - "requesting-user-name", NULL, user); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); fprintf(stderr, "DEBUG: requesting-user-name=\"%s\"\n", user); } if (title && *title) { - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, - title); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); fprintf(stderr, "DEBUG: job-name=\"%s\"\n", title); } if (format && op != IPP_CREATE_JOB) { - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, - "document-format", NULL, format); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); fprintf(stderr, "DEBUG: document-format=\"%s\"\n", format); } #ifdef HAVE_LIBZ if (compression && op != IPP_OP_CREATE_JOB && op != IPP_OP_VALIDATE_JOB) { - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "compression", NULL, compression); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "compression", NULL, compression); fprintf(stderr, "DEBUG: compression=\"%s\"\n", compression); } #endif /* HAVE_LIBZ */ @@ -2630,324 +2616,13 @@ new_request( { if (pc) { - int num_finishings = 0, /* Number of finishing values */ - finishings[10]; /* Finishing enum values */ - ppd_choice_t *choice; /* Marked choice */ - /* * Send standard IPP attributes... */ fputs("DEBUG: Adding standard IPP operation/job attributes.\n", stderr); - if (pc->password && - (keyword = cupsGetOption("job-password", num_options, - options)) != NULL) - { - ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", keyword, (int)strlen(keyword)); - - if ((keyword = cupsGetOption("job-password-encryption", num_options, - options)) == NULL) - keyword = "none"; - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "job-password-encryption", NULL, keyword); - } - - if (pc->account_id) - { - if ((keyword = cupsGetOption("job-account-id", num_options, - options)) == NULL) - keyword = cupsGetOption("job-billing", num_options, options); - - if (keyword) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id", - NULL, keyword); - } - - if (pc->accounting_user_id) - { - if ((keyword = cupsGetOption("job-accounting-user-id", num_options, - options)) == NULL) - keyword = user; - - if (keyword) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, - "job-accounting-user-id", NULL, keyword); - } - - for (mandatory = (char *)cupsArrayFirst(pc->mandatory); - mandatory; - mandatory = (char *)cupsArrayNext(pc->mandatory)) - { - if (strcmp(mandatory, "copies") && - strcmp(mandatory, "destination-uris") && - strcmp(mandatory, "finishings") && - strcmp(mandatory, "job-account-id") && - strcmp(mandatory, "job-accounting-user-id") && - strcmp(mandatory, "job-password") && - strcmp(mandatory, "job-password-encryption") && - strcmp(mandatory, "media") && - strncmp(mandatory, "media-col", 9) && - strcmp(mandatory, "multiple-document-handling") && - strcmp(mandatory, "output-bin") && - strcmp(mandatory, "print-color-mode") && - strcmp(mandatory, "print-quality") && - strcmp(mandatory, "sides") && - (keyword = cupsGetOption(mandatory, num_options, options)) != NULL) - { - _ipp_option_t *opt = _ippFindOption(mandatory); - /* Option type */ - ipp_tag_t value_tag = opt ? opt->value_tag : IPP_TAG_NAME; - /* Value type */ - - switch (value_tag) - { - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - ippAddInteger(request, IPP_TAG_JOB, value_tag, mandatory, - atoi(keyword)); - break; - case IPP_TAG_BOOLEAN : - ippAddBoolean(request, IPP_TAG_JOB, mandatory, - !_cups_strcasecmp(keyword, "true")); - break; - case IPP_TAG_RANGE : - { - int lower, upper; /* Range */ - - if (sscanf(keyword, "%d-%d", &lower, &upper) != 2) - lower = upper = atoi(keyword); - - ippAddRange(request, IPP_TAG_JOB, mandatory, lower, upper); - } - break; - case IPP_TAG_STRING : - ippAddOctetString(request, IPP_TAG_JOB, mandatory, keyword, (int)strlen(keyword)); - break; - default : - if (!strcmp(mandatory, "print-color-mode") && !strcmp(keyword, "monochrome")) - { - if (ippContainsString(print_color_mode_sup, "auto-monochrome")) - keyword = "auto-monochrome"; - else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome")) - keyword = "process-monochrome"; - } - - ippAddString(request, IPP_TAG_JOB, value_tag, mandatory, - NULL, keyword); - break; - } - } - } - - if ((keyword = cupsGetOption("PageSize", num_options, options)) == NULL) - keyword = cupsGetOption("media", num_options, options); - - if ((size = _ppdCacheGetSize(pc, keyword)) != NULL) - { - /* - * Add a media-col value... - */ - - media_size = ippNew(); - ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "x-dimension", size->width); - ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "y-dimension", size->length); - - media_col = ippNew(); - ippAddCollection(media_col, IPP_TAG_ZERO, "media-size", media_size); - - media_source = _ppdCacheGetSource(pc, cupsGetOption("InputSlot", - num_options, - options)); - media_type = _ppdCacheGetType(pc, cupsGetOption("MediaType", - num_options, - options)); - - for (i = 0; i < media_col_sup->num_values; i ++) - { - if (!strcmp(media_col_sup->values[i].string.text, - "media-left-margin")) - ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "media-left-margin", size->left); - else if (!strcmp(media_col_sup->values[i].string.text, - "media-bottom-margin")) - ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "media-bottom-margin", size->bottom); - else if (!strcmp(media_col_sup->values[i].string.text, - "media-right-margin")) - ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "media-right-margin", size->right); - else if (!strcmp(media_col_sup->values[i].string.text, - "media-top-margin")) - ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, - "media-top-margin", size->top); - else if (!strcmp(media_col_sup->values[i].string.text, - "media-source") && media_source) - ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, - "media-source", NULL, media_source); - else if (!strcmp(media_col_sup->values[i].string.text, - "media-type") && media_type) - ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, - "media-type", NULL, media_type); - } - - ippAddCollection(request, IPP_TAG_JOB, "media-col", media_col); - } - - if ((keyword = cupsGetOption("output-bin", num_options, - options)) == NULL) - { - if ((choice = ppdFindMarkedChoice(ppd, "OutputBin")) != NULL) - keyword = _ppdCacheGetBin(pc, choice->choice); - } - - if (keyword) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin", - NULL, keyword); - - color_attr_name = print_color_mode_sup ? "print-color-mode" : "output-mode"; - - if ((keyword = cupsGetOption("print-color-mode", num_options, - options)) == NULL) - { - if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL) - { - if (!_cups_strcasecmp(choice->choice, "Gray")) - keyword = "monochrome"; - else - keyword = "color"; - } - } - - if (keyword && !strcmp(keyword, "monochrome")) - { - if (ippContainsString(print_color_mode_sup, "auto-monochrome")) - keyword = "auto-monochrome"; - else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome")) - keyword = "process-monochrome"; - } - - if (keyword) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name, - NULL, keyword); - - if ((keyword = cupsGetOption("print-quality", num_options, - options)) != NULL) - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", - atoi(keyword)); - else if ((choice = ppdFindMarkedChoice(ppd, "cupsPrintQuality")) != NULL) - { - if (!_cups_strcasecmp(choice->choice, "draft")) - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", - IPP_QUALITY_DRAFT); - else if (!_cups_strcasecmp(choice->choice, "normal")) - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", - IPP_QUALITY_NORMAL); - else if (!_cups_strcasecmp(choice->choice, "high")) - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", - IPP_QUALITY_HIGH); - } - - if ((keyword = cupsGetOption("sides", num_options, options)) != NULL) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", - NULL, keyword); - else if (pc->sides_option && - (choice = ppdFindMarkedChoice(ppd, pc->sides_option)) != NULL) - { - if (!_cups_strcasecmp(choice->choice, pc->sides_1sided)) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", - NULL, "one-sided"); - else if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_long)) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", - NULL, "two-sided-long-edge"); - if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_short)) - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", - NULL, "two-sided-short-edge"); - } - - if ((keyword = cupsGetOption("multiple-document-handling", - num_options, options)) != NULL) - { - if (strstr(keyword, "uncollated")) - keyword = "false"; - else - keyword = "true"; - } - else if ((keyword = cupsGetOption("collate", num_options, - options)) == NULL) - keyword = "true"; - - if (format) - { - if (!_cups_strcasecmp(format, "image/gif") || - !_cups_strcasecmp(format, "image/jp2") || - !_cups_strcasecmp(format, "image/jpeg") || - !_cups_strcasecmp(format, "image/png") || - !_cups_strcasecmp(format, "image/tiff") || - !_cups_strncasecmp(format, "image/x-", 8)) - { - /* - * Collation makes no sense for single page image formats... - */ - - keyword = "false"; - } - else if (!_cups_strncasecmp(format, "image/", 6) || - !_cups_strcasecmp(format, "application/vnd.cups-raster")) - { - /* - * Multi-page image formats will have copies applied by the upstream - * filters... - */ - - copies = 1; - } - } - - if (doc_handling_sup) - { - if (!_cups_strcasecmp(keyword, "true")) - collate_str = "separate-documents-collated-copies"; - else - collate_str = "separate-documents-uncollated-copies"; - - for (i = 0; i < doc_handling_sup->num_values; i ++) - if (!strcmp(doc_handling_sup->values[i].string.text, collate_str)) - { - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, - "multiple-document-handling", NULL, collate_str); - break; - } - - if (i >= doc_handling_sup->num_values) - copies = 1; - } - - /* - * Map finishing options... - */ - - num_finishings = _ppdCacheGetFinishingValues(pc, num_options, options, - (int)(sizeof(finishings) / - sizeof(finishings[0])), - finishings); - if (num_finishings > 0) - { - ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", - num_finishings, finishings); - - if (copies > 1 && (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); - } - } + copies = _cupsConvertOptions(request, ppd, pc, media_col_sup, doc_handling_sup, print_color_mode_sup, user, format, copies, num_options, options); /* * Map FaxOut options... diff --git a/cups/cups-private.h b/cups/cups-private.h index 8e2d69295c..1d24c2f639 100644 --- a/cups/cups-private.h +++ b/cups/cups-private.h @@ -3,7 +3,7 @@ * * Private definitions for CUPS. * - * Copyright 2007-2013 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -244,6 +244,7 @@ extern char *_cupsBufferGet(size_t size); extern void _cupsBufferRelease(char *b); extern http_t *_cupsConnect(void); +extern int _cupsConvertOptions(ipp_t *request, ppd_file_t *ppd, _ppd_cache_t *pc, ipp_attribute_t *media_col_sup, ipp_attribute_t *doc_handling_sup, ipp_attribute_t *print_color_mode_sup, const char *user, const char *format, int copies, int num_options, cups_option_t *options); extern int _cupsGet1284Values(const char *device_id, cups_option_t **values); extern const char *_cupsGetDestResource(cups_dest_t *dest, char *resource, diff --git a/cups/encode.c b/cups/encode.c index ced37798d5..62dd8d7b3f 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -3,7 +3,7 @@ * * Option encoding routines for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -322,6 +322,321 @@ static const _ipp_option_t ipp_options[] = static int compare_ipp_options(_ipp_option_t *a, _ipp_option_t *b); +/* + * '_cupsConvertOptions()' - Convert printer options to standard IPP attributes. + * + * This functions converts PPD and CUPS-specific options to their standard IPP + * 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 i; /* Looping var */ + const char *keyword; /* PWG keyword */ + pwg_size_t *size; /* PWG media size */ + ipp_t *media_col, /* media-col value */ + *media_size; /* media-size value */ + const char *media_source, /* media-source value */ + *media_type, /* media-type value */ + *collate_str, /* multiple-document-handling value */ + *color_attr_name, /* Supported color attribute */ + *mandatory; /* Mandatory attributes */ + int num_finishings = 0, /* Number of finishing values */ + finishings[10]; /* Finishing enum values */ + ppd_choice_t *choice; /* Marked choice */ + + + /* + * Send standard IPP attributes... + */ + + if (pc->password && (keyword = cupsGetOption("job-password", num_options, options)) != NULL) + { + ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", keyword, (int)strlen(keyword)); + + if ((keyword = cupsGetOption("job-password-encryption", num_options, options)) == NULL) + keyword = "none"; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "job-password-encryption", NULL, keyword); + } + + if (pc->account_id) + { + if ((keyword = cupsGetOption("job-account-id", num_options, options)) == NULL) + keyword = cupsGetOption("job-billing", num_options, options); + + if (keyword) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id", NULL, keyword); + } + + if (pc->accounting_user_id) + { + if ((keyword = cupsGetOption("job-accounting-user-id", num_options, options)) == NULL) + keyword = user; + + if (keyword) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-accounting-user-id", NULL, keyword); + } + + for (mandatory = (const char *)cupsArrayFirst(pc->mandatory); mandatory; mandatory = (const char *)cupsArrayNext(pc->mandatory)) + { + if (strcmp(mandatory, "copies") && + strcmp(mandatory, "destination-uris") && + strcmp(mandatory, "finishings") && + strcmp(mandatory, "job-account-id") && + strcmp(mandatory, "job-accounting-user-id") && + strcmp(mandatory, "job-password") && + strcmp(mandatory, "job-password-encryption") && + strcmp(mandatory, "media") && + strncmp(mandatory, "media-col", 9) && + strcmp(mandatory, "multiple-document-handling") && + strcmp(mandatory, "output-bin") && + strcmp(mandatory, "print-color-mode") && + strcmp(mandatory, "print-quality") && + strcmp(mandatory, "sides") && + (keyword = cupsGetOption(mandatory, num_options, options)) != NULL) + { + _ipp_option_t *opt = _ippFindOption(mandatory); + /* Option type */ + ipp_tag_t value_tag = opt ? opt->value_tag : IPP_TAG_NAME; + /* Value type */ + + switch (value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + ippAddInteger(request, IPP_TAG_JOB, value_tag, mandatory, atoi(keyword)); + break; + case IPP_TAG_BOOLEAN : + ippAddBoolean(request, IPP_TAG_JOB, mandatory, !_cups_strcasecmp(keyword, "true")); + break; + case IPP_TAG_RANGE : + { + int lower, upper; /* Range */ + + if (sscanf(keyword, "%d-%d", &lower, &upper) != 2) + lower = upper = atoi(keyword); + + ippAddRange(request, IPP_TAG_JOB, mandatory, lower, upper); + } + break; + case IPP_TAG_STRING : + ippAddOctetString(request, IPP_TAG_JOB, mandatory, keyword, (int)strlen(keyword)); + break; + default : + if (!strcmp(mandatory, "print-color-mode") && !strcmp(keyword, "monochrome")) + { + if (ippContainsString(print_color_mode_sup, "auto-monochrome")) + keyword = "auto-monochrome"; + else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome")) + keyword = "process-monochrome"; + } + + ippAddString(request, IPP_TAG_JOB, value_tag, mandatory, NULL, keyword); + break; + } + } + } + + if ((keyword = cupsGetOption("PageSize", num_options, options)) == NULL) + keyword = cupsGetOption("media", num_options, options); + + if ((size = _ppdCacheGetSize(pc, keyword)) != NULL) + { + /* + * Add a media-col value... + */ + + media_size = ippNew(); + ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "x-dimension", size->width); + ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "y-dimension", size->length); + + media_col = ippNew(); + ippAddCollection(media_col, IPP_TAG_ZERO, "media-size", media_size); + + media_source = _ppdCacheGetSource(pc, cupsGetOption("InputSlot", + num_options, + options)); + media_type = _ppdCacheGetType(pc, cupsGetOption("MediaType", + num_options, + options)); + + for (i = 0; i < media_col_sup->num_values; i ++) + { + if (!strcmp(media_col_sup->values[i].string.text, "media-left-margin")) + ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-left-margin", size->left); + else if (!strcmp(media_col_sup->values[i].string.text, "media-bottom-margin")) + ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom); + else if (!strcmp(media_col_sup->values[i].string.text, "media-right-margin")) + ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-right-margin", size->right); + else if (!strcmp(media_col_sup->values[i].string.text, "media-top-margin")) + ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-top-margin", size->top); + else if (!strcmp(media_col_sup->values[i].string.text, "media-source") && media_source) + ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "media-source", NULL, media_source); + else if (!strcmp(media_col_sup->values[i].string.text, "media-type") && media_type) + ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "media-type", NULL, media_type); + } + + ippAddCollection(request, IPP_TAG_JOB, "media-col", media_col); + } + + if ((keyword = cupsGetOption("output-bin", num_options, options)) == NULL) + { + if ((choice = ppdFindMarkedChoice(ppd, "OutputBin")) != NULL) + keyword = _ppdCacheGetBin(pc, choice->choice); + } + + if (keyword) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin", NULL, keyword); + + color_attr_name = print_color_mode_sup ? "print-color-mode" : "output-mode"; + + if ((keyword = cupsGetOption("print-color-mode", num_options, options)) == NULL) + { + if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL) + { + if (!_cups_strcasecmp(choice->choice, "Gray")) + keyword = "monochrome"; + else + keyword = "color"; + } + } + + if (keyword && !strcmp(keyword, "monochrome")) + { + if (ippContainsString(print_color_mode_sup, "auto-monochrome")) + keyword = "auto-monochrome"; + else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome")) + keyword = "process-monochrome"; + } + + if (keyword) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name, NULL, keyword); + + if ((keyword = cupsGetOption("print-quality", num_options, options)) != NULL) + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", atoi(keyword)); + else if ((choice = ppdFindMarkedChoice(ppd, "cupsPrintQuality")) != NULL) + { + if (!_cups_strcasecmp(choice->choice, "draft")) + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_DRAFT); + else if (!_cups_strcasecmp(choice->choice, "normal")) + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_NORMAL); + else if (!_cups_strcasecmp(choice->choice, "high")) + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_HIGH); + } + + if ((keyword = cupsGetOption("sides", num_options, options)) != NULL) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, keyword); + else if (pc->sides_option && (choice = ppdFindMarkedChoice(ppd, pc->sides_option)) != NULL) + { + if (!_cups_strcasecmp(choice->choice, pc->sides_1sided)) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "one-sided"); + else if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_long)) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-long-edge"); + if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_short)) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-short-edge"); + } + + /* + * Copies... + */ + + if ((keyword = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) + { + if (strstr(keyword, "uncollated")) + keyword = "false"; + else + keyword = "true"; + } + else if ((keyword = cupsGetOption("collate", num_options, options)) == NULL) + keyword = "true"; + + if (format) + { + if (!_cups_strcasecmp(format, "image/gif") || + !_cups_strcasecmp(format, "image/jp2") || + !_cups_strcasecmp(format, "image/jpeg") || + !_cups_strcasecmp(format, "image/png") || + !_cups_strcasecmp(format, "image/tiff") || + !_cups_strncasecmp(format, "image/x-", 8)) + { + /* + * Collation makes no sense for single page image formats... + */ + + keyword = "false"; + } + else if (!_cups_strncasecmp(format, "image/", 6) || + !_cups_strcasecmp(format, "application/vnd.cups-raster")) + { + /* + * Multi-page image formats will have copies applied by the upstream + * filters... + */ + + copies = 1; + } + } + + if (doc_handling_sup) + { + if (!_cups_strcasecmp(keyword, "true")) + collate_str = "separate-documents-collated-copies"; + else + collate_str = "separate-documents-uncollated-copies"; + + for (i = 0; i < doc_handling_sup->num_values; i ++) + { + if (!strcmp(doc_handling_sup->values[i].string.text, collate_str)) + { + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "multiple-document-handling", NULL, collate_str); + break; + } + } + + if (i >= doc_handling_sup->num_values) + copies = 1; + } + + /* + * Map finishing options... + */ + + num_finishings = _ppdCacheGetFinishingValues(pc, num_options, options, (int)(sizeof(finishings) / sizeof(finishings[0])), finishings); + if (num_finishings > 0) + { + ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings); + + if (copies > 1 && (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); + } + } + + return (copies); +} + + /* * 'cupsEncodeOptions()' - Encode printer options into IPP attributes. * diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index 49166c3b9e..c49ac7f563 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -2081,8 +2081,6 @@ 274FF67313333B0A00317ECB /* commands */ = { isa = PBXGroup; children = ( - 274EE27F1A03EE41003213D1 /* ippproxy.c */, - 274EE27D1A03EE0B003213D1 /* ippinfra.c */, 2732E089137A3F5200FAFEF6 /* cancel.c */, 2732E08A137A3F5200FAFEF6 /* cupsaccept.c */, 276684101337FA7C000D33D0 /* cupsaddsmb.c */, @@ -2091,6 +2089,8 @@ 2732E08B137A3F5200FAFEF6 /* cupstestdsc.c */, 72F75A5B1336F988004BB496 /* cupstestppd.c */, 72CF95F218A19165000FCAE4 /* ippfind.c */, + 274EE27D1A03EE0B003213D1 /* ippinfra.c */, + 274EE27F1A03EE41003213D1 /* ippproxy.c */, 726AD701135E8A90002C930D /* ippserver.c */, 276683F91337F7A9000D33D0 /* ipptool.c */, 2732E08C137A3F5200FAFEF6 /* lp.c */,