1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * PPD cache implementation for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2010-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker *
6*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker * information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #include "ppd-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #include <math.h>
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker * Macro to test for two almost-equal PWG measurements.
22*5e7646d2SAndroid Build Coastguard Worker */
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker #define _PWG_EQUIVALENT(x, y) (abs((x)-(y)) < 2)
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker * Local functions...
29*5e7646d2SAndroid Build Coastguard Worker */
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker static int cups_get_url(http_t **http, const char *url, char *name, size_t namesize);
32*5e7646d2SAndroid Build Coastguard Worker static void pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value);
33*5e7646d2SAndroid Build Coastguard Worker static void pwg_add_message(cups_array_t *a, const char *msg, const char *str);
34*5e7646d2SAndroid Build Coastguard Worker static int pwg_compare_finishings(_pwg_finishings_t *a, _pwg_finishings_t *b);
35*5e7646d2SAndroid Build Coastguard Worker static int pwg_compare_sizes(cups_size_t *a, cups_size_t *b);
36*5e7646d2SAndroid Build Coastguard Worker static cups_size_t *pwg_copy_size(cups_size_t *size);
37*5e7646d2SAndroid Build Coastguard Worker static void pwg_free_finishings(_pwg_finishings_t *f);
38*5e7646d2SAndroid Build Coastguard Worker static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
39*5e7646d2SAndroid Build Coastguard Worker static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
40*5e7646d2SAndroid Build Coastguard Worker static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize,
41*5e7646d2SAndroid Build Coastguard Worker const char *dashchars);
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker /*
45*5e7646d2SAndroid Build Coastguard Worker * '_cupsConvertOptions()' - Convert printer options to standard IPP attributes.
46*5e7646d2SAndroid Build Coastguard Worker *
47*5e7646d2SAndroid Build Coastguard Worker * This functions converts PPD and CUPS-specific options to their standard IPP
48*5e7646d2SAndroid Build Coastguard Worker * attributes and values and adds them to the specified IPP request.
49*5e7646d2SAndroid Build Coastguard Worker */
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker int /* O - New number of copies */
_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)52*5e7646d2SAndroid Build Coastguard Worker _cupsConvertOptions(
53*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* I - IPP request */
54*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
55*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache info */
56*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *media_col_sup, /* I - media-col-supported values */
57*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *doc_handling_sup, /* I - multiple-document-handling-supported values */
58*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *print_color_mode_sup,
59*5e7646d2SAndroid Build Coastguard Worker /* I - Printer supports print-color-mode */
60*5e7646d2SAndroid Build Coastguard Worker const char *user, /* I - User info */
61*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - document-format value */
62*5e7646d2SAndroid Build Coastguard Worker int copies, /* I - Number of copies */
63*5e7646d2SAndroid Build Coastguard Worker int num_options, /* I - Number of options */
64*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options) /* I - Options */
65*5e7646d2SAndroid Build Coastguard Worker {
66*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
67*5e7646d2SAndroid Build Coastguard Worker const char *keyword, /* PWG keyword */
68*5e7646d2SAndroid Build Coastguard Worker *password; /* Password string */
69*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size; /* PWG media size */
70*5e7646d2SAndroid Build Coastguard Worker ipp_t *media_col, /* media-col value */
71*5e7646d2SAndroid Build Coastguard Worker *media_size; /* media-size value */
72*5e7646d2SAndroid Build Coastguard Worker const char *media_source, /* media-source value */
73*5e7646d2SAndroid Build Coastguard Worker *media_type, /* media-type value */
74*5e7646d2SAndroid Build Coastguard Worker *collate_str, /* multiple-document-handling value */
75*5e7646d2SAndroid Build Coastguard Worker *color_attr_name, /* Supported color attribute */
76*5e7646d2SAndroid Build Coastguard Worker *mandatory, /* Mandatory attributes */
77*5e7646d2SAndroid Build Coastguard Worker *finishing_template; /* Finishing template */
78*5e7646d2SAndroid Build Coastguard Worker int num_finishings = 0, /* Number of finishing values */
79*5e7646d2SAndroid Build Coastguard Worker finishings[10]; /* Finishing enum values */
80*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *choice; /* Marked choice */
81*5e7646d2SAndroid Build Coastguard Worker int finishings_copies = copies,
82*5e7646d2SAndroid Build Coastguard Worker /* Number of copies for finishings */
83*5e7646d2SAndroid Build Coastguard Worker job_pages = 0, /* job-pages value */
84*5e7646d2SAndroid Build Coastguard Worker number_up = 1; /* number-up value */
85*5e7646d2SAndroid Build Coastguard Worker const char *value; /* Option value */
86*5e7646d2SAndroid Build Coastguard Worker
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker /*
89*5e7646d2SAndroid Build Coastguard Worker * Send standard IPP attributes...
90*5e7646d2SAndroid Build Coastguard Worker */
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker if (pc->password && (password = cupsGetOption("job-password", num_options, options)) != NULL && ippGetOperation(request) != IPP_OP_VALIDATE_JOB)
93*5e7646d2SAndroid Build Coastguard Worker {
94*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr = NULL; /* job-password attribute */
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("job-password-encryption", num_options, options)) == NULL)
97*5e7646d2SAndroid Build Coastguard Worker keyword = "none";
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "none"))
100*5e7646d2SAndroid Build Coastguard Worker {
101*5e7646d2SAndroid Build Coastguard Worker /*
102*5e7646d2SAndroid Build Coastguard Worker * Add plain-text job-password...
103*5e7646d2SAndroid Build Coastguard Worker */
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker attr = ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", password, (int)strlen(password));
106*5e7646d2SAndroid Build Coastguard Worker }
107*5e7646d2SAndroid Build Coastguard Worker else
108*5e7646d2SAndroid Build Coastguard Worker {
109*5e7646d2SAndroid Build Coastguard Worker /*
110*5e7646d2SAndroid Build Coastguard Worker * Add hashed job-password...
111*5e7646d2SAndroid Build Coastguard Worker */
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker unsigned char hash[64]; /* Hash of password */
114*5e7646d2SAndroid Build Coastguard Worker ssize_t hashlen; /* Length of hash */
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker if ((hashlen = cupsHashData(keyword, password, strlen(password), hash, sizeof(hash))) > 0)
117*5e7646d2SAndroid Build Coastguard Worker attr = ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", hash, (int)hashlen);
118*5e7646d2SAndroid Build Coastguard Worker }
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker if (attr)
121*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "job-password-encryption", NULL, keyword);
122*5e7646d2SAndroid Build Coastguard Worker }
123*5e7646d2SAndroid Build Coastguard Worker
124*5e7646d2SAndroid Build Coastguard Worker if (pc->account_id)
125*5e7646d2SAndroid Build Coastguard Worker {
126*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("job-account-id", num_options, options)) == NULL)
127*5e7646d2SAndroid Build Coastguard Worker keyword = cupsGetOption("job-billing", num_options, options);
128*5e7646d2SAndroid Build Coastguard Worker
129*5e7646d2SAndroid Build Coastguard Worker if (keyword)
130*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id", NULL, keyword);
131*5e7646d2SAndroid Build Coastguard Worker }
132*5e7646d2SAndroid Build Coastguard Worker
133*5e7646d2SAndroid Build Coastguard Worker if (pc->accounting_user_id)
134*5e7646d2SAndroid Build Coastguard Worker {
135*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("job-accounting-user-id", num_options, options)) == NULL)
136*5e7646d2SAndroid Build Coastguard Worker keyword = user;
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker if (keyword)
139*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-accounting-user-id", NULL, keyword);
140*5e7646d2SAndroid Build Coastguard Worker }
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker for (mandatory = (const char *)cupsArrayFirst(pc->mandatory); mandatory; mandatory = (const char *)cupsArrayNext(pc->mandatory))
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker if (strcmp(mandatory, "copies") &&
145*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "destination-uris") &&
146*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "finishings") &&
147*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "finishings-col") &&
148*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "finishing-template") &&
149*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "job-account-id") &&
150*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "job-accounting-user-id") &&
151*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "job-password") &&
152*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "job-password-encryption") &&
153*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "media") &&
154*5e7646d2SAndroid Build Coastguard Worker strncmp(mandatory, "media-col", 9) &&
155*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "multiple-document-handling") &&
156*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "output-bin") &&
157*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "print-color-mode") &&
158*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "print-quality") &&
159*5e7646d2SAndroid Build Coastguard Worker strcmp(mandatory, "sides") &&
160*5e7646d2SAndroid Build Coastguard Worker (keyword = cupsGetOption(mandatory, num_options, options)) != NULL)
161*5e7646d2SAndroid Build Coastguard Worker {
162*5e7646d2SAndroid Build Coastguard Worker _ipp_option_t *opt = _ippFindOption(mandatory);
163*5e7646d2SAndroid Build Coastguard Worker /* Option type */
164*5e7646d2SAndroid Build Coastguard Worker ipp_tag_t value_tag = opt ? opt->value_tag : IPP_TAG_NAME;
165*5e7646d2SAndroid Build Coastguard Worker /* Value type */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker switch (value_tag)
168*5e7646d2SAndroid Build Coastguard Worker {
169*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_INTEGER :
170*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_ENUM :
171*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, value_tag, mandatory, atoi(keyword));
172*5e7646d2SAndroid Build Coastguard Worker break;
173*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_BOOLEAN :
174*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(request, IPP_TAG_JOB, mandatory, !_cups_strcasecmp(keyword, "true"));
175*5e7646d2SAndroid Build Coastguard Worker break;
176*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_RANGE :
177*5e7646d2SAndroid Build Coastguard Worker {
178*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Range */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker if (sscanf(keyword, "%d-%d", &lower, &upper) != 2)
181*5e7646d2SAndroid Build Coastguard Worker lower = upper = atoi(keyword);
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker ippAddRange(request, IPP_TAG_JOB, mandatory, lower, upper);
184*5e7646d2SAndroid Build Coastguard Worker }
185*5e7646d2SAndroid Build Coastguard Worker break;
186*5e7646d2SAndroid Build Coastguard Worker case IPP_TAG_STRING :
187*5e7646d2SAndroid Build Coastguard Worker ippAddOctetString(request, IPP_TAG_JOB, mandatory, keyword, (int)strlen(keyword));
188*5e7646d2SAndroid Build Coastguard Worker break;
189*5e7646d2SAndroid Build Coastguard Worker default :
190*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(mandatory, "print-color-mode") && !strcmp(keyword, "monochrome"))
191*5e7646d2SAndroid Build Coastguard Worker {
192*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
193*5e7646d2SAndroid Build Coastguard Worker keyword = "auto-monochrome";
194*5e7646d2SAndroid Build Coastguard Worker else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
195*5e7646d2SAndroid Build Coastguard Worker keyword = "process-monochrome";
196*5e7646d2SAndroid Build Coastguard Worker }
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, value_tag, mandatory, NULL, keyword);
199*5e7646d2SAndroid Build Coastguard Worker break;
200*5e7646d2SAndroid Build Coastguard Worker }
201*5e7646d2SAndroid Build Coastguard Worker }
202*5e7646d2SAndroid Build Coastguard Worker }
203*5e7646d2SAndroid Build Coastguard Worker
204*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("PageSize", num_options, options)) == NULL)
205*5e7646d2SAndroid Build Coastguard Worker keyword = cupsGetOption("media", num_options, options);
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker media_source = _ppdCacheGetSource(pc, cupsGetOption("InputSlot", num_options, options));
208*5e7646d2SAndroid Build Coastguard Worker media_type = _ppdCacheGetType(pc, cupsGetOption("MediaType", num_options, options));
209*5e7646d2SAndroid Build Coastguard Worker size = _ppdCacheGetSize(pc, keyword);
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker if (size || media_source || media_type)
212*5e7646d2SAndroid Build Coastguard Worker {
213*5e7646d2SAndroid Build Coastguard Worker /*
214*5e7646d2SAndroid Build Coastguard Worker * Add a media-col value...
215*5e7646d2SAndroid Build Coastguard Worker */
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker media_col = ippNew();
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker if (size)
220*5e7646d2SAndroid Build Coastguard Worker {
221*5e7646d2SAndroid Build Coastguard Worker media_size = ippNew();
222*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER,
223*5e7646d2SAndroid Build Coastguard Worker "x-dimension", size->width);
224*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER,
225*5e7646d2SAndroid Build Coastguard Worker "y-dimension", size->length);
226*5e7646d2SAndroid Build Coastguard Worker
227*5e7646d2SAndroid Build Coastguard Worker ippAddCollection(media_col, IPP_TAG_ZERO, "media-size", media_size);
228*5e7646d2SAndroid Build Coastguard Worker }
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < media_col_sup->num_values; i ++)
231*5e7646d2SAndroid Build Coastguard Worker {
232*5e7646d2SAndroid Build Coastguard Worker if (size && !strcmp(media_col_sup->values[i].string.text, "media-left-margin"))
233*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-left-margin", size->left);
234*5e7646d2SAndroid Build Coastguard Worker else if (size && !strcmp(media_col_sup->values[i].string.text, "media-bottom-margin"))
235*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom);
236*5e7646d2SAndroid Build Coastguard Worker else if (size && !strcmp(media_col_sup->values[i].string.text, "media-right-margin"))
237*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-right-margin", size->right);
238*5e7646d2SAndroid Build Coastguard Worker else if (size && !strcmp(media_col_sup->values[i].string.text, "media-top-margin"))
239*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(media_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, "media-top-margin", size->top);
240*5e7646d2SAndroid Build Coastguard Worker else if (media_source && !strcmp(media_col_sup->values[i].string.text, "media-source"))
241*5e7646d2SAndroid Build Coastguard Worker ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "media-source", NULL, media_source);
242*5e7646d2SAndroid Build Coastguard Worker else if (media_type && !strcmp(media_col_sup->values[i].string.text, "media-type"))
243*5e7646d2SAndroid Build Coastguard Worker ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "media-type", NULL, media_type);
244*5e7646d2SAndroid Build Coastguard Worker }
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker ippAddCollection(request, IPP_TAG_JOB, "media-col", media_col);
247*5e7646d2SAndroid Build Coastguard Worker }
248*5e7646d2SAndroid Build Coastguard Worker
249*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("output-bin", num_options, options)) == NULL)
250*5e7646d2SAndroid Build Coastguard Worker {
251*5e7646d2SAndroid Build Coastguard Worker if ((choice = ppdFindMarkedChoice(ppd, "OutputBin")) != NULL)
252*5e7646d2SAndroid Build Coastguard Worker keyword = _ppdCacheGetBin(pc, choice->choice);
253*5e7646d2SAndroid Build Coastguard Worker }
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker if (keyword)
256*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin", NULL, keyword);
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker color_attr_name = print_color_mode_sup ? "print-color-mode" : "output-mode";
259*5e7646d2SAndroid Build Coastguard Worker
260*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("print-color-mode", num_options, options)) == NULL)
261*5e7646d2SAndroid Build Coastguard Worker {
262*5e7646d2SAndroid Build Coastguard Worker if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL)
263*5e7646d2SAndroid Build Coastguard Worker {
264*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choice->choice, "Gray"))
265*5e7646d2SAndroid Build Coastguard Worker keyword = "monochrome";
266*5e7646d2SAndroid Build Coastguard Worker else
267*5e7646d2SAndroid Build Coastguard Worker keyword = "color";
268*5e7646d2SAndroid Build Coastguard Worker }
269*5e7646d2SAndroid Build Coastguard Worker }
270*5e7646d2SAndroid Build Coastguard Worker
271*5e7646d2SAndroid Build Coastguard Worker if (keyword && !strcmp(keyword, "monochrome"))
272*5e7646d2SAndroid Build Coastguard Worker {
273*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
274*5e7646d2SAndroid Build Coastguard Worker keyword = "auto-monochrome";
275*5e7646d2SAndroid Build Coastguard Worker else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
276*5e7646d2SAndroid Build Coastguard Worker keyword = "process-monochrome";
277*5e7646d2SAndroid Build Coastguard Worker }
278*5e7646d2SAndroid Build Coastguard Worker
279*5e7646d2SAndroid Build Coastguard Worker if (keyword)
280*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name, NULL, keyword);
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("print-quality", num_options, options)) != NULL)
283*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", atoi(keyword));
284*5e7646d2SAndroid Build Coastguard Worker else if ((choice = ppdFindMarkedChoice(ppd, "cupsPrintQuality")) != NULL)
285*5e7646d2SAndroid Build Coastguard Worker {
286*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choice->choice, "draft"))
287*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_DRAFT);
288*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "normal"))
289*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_NORMAL);
290*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "high"))
291*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality", IPP_QUALITY_HIGH);
292*5e7646d2SAndroid Build Coastguard Worker }
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("sides", num_options, options)) != NULL)
295*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, keyword);
296*5e7646d2SAndroid Build Coastguard Worker else if (pc->sides_option && (choice = ppdFindMarkedChoice(ppd, pc->sides_option)) != NULL)
297*5e7646d2SAndroid Build Coastguard Worker {
298*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_1sided && !_cups_strcasecmp(choice->choice, pc->sides_1sided))
299*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "one-sided");
300*5e7646d2SAndroid Build Coastguard Worker else if (pc->sides_2sided_long && !_cups_strcasecmp(choice->choice, pc->sides_2sided_long))
301*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-long-edge");
302*5e7646d2SAndroid Build Coastguard Worker else if (pc->sides_2sided_short && !_cups_strcasecmp(choice->choice, pc->sides_2sided_short))
303*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-short-edge");
304*5e7646d2SAndroid Build Coastguard Worker }
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker /*
307*5e7646d2SAndroid Build Coastguard Worker * Copies...
308*5e7646d2SAndroid Build Coastguard Worker */
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker if ((keyword = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
311*5e7646d2SAndroid Build Coastguard Worker {
312*5e7646d2SAndroid Build Coastguard Worker if (strstr(keyword, "uncollated"))
313*5e7646d2SAndroid Build Coastguard Worker keyword = "false";
314*5e7646d2SAndroid Build Coastguard Worker else
315*5e7646d2SAndroid Build Coastguard Worker keyword = "true";
316*5e7646d2SAndroid Build Coastguard Worker }
317*5e7646d2SAndroid Build Coastguard Worker else if ((keyword = cupsGetOption("collate", num_options, options)) == NULL)
318*5e7646d2SAndroid Build Coastguard Worker keyword = "true";
319*5e7646d2SAndroid Build Coastguard Worker
320*5e7646d2SAndroid Build Coastguard Worker if (format)
321*5e7646d2SAndroid Build Coastguard Worker {
322*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(format, "image/gif") ||
323*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(format, "image/jp2") ||
324*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(format, "image/jpeg") ||
325*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(format, "image/png") ||
326*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(format, "image/tiff") ||
327*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(format, "image/x-", 8))
328*5e7646d2SAndroid Build Coastguard Worker {
329*5e7646d2SAndroid Build Coastguard Worker /*
330*5e7646d2SAndroid Build Coastguard Worker * Collation makes no sense for single page image formats...
331*5e7646d2SAndroid Build Coastguard Worker */
332*5e7646d2SAndroid Build Coastguard Worker
333*5e7646d2SAndroid Build Coastguard Worker keyword = "false";
334*5e7646d2SAndroid Build Coastguard Worker }
335*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(format, "image/", 6) ||
336*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(format, "application/vnd.cups-raster"))
337*5e7646d2SAndroid Build Coastguard Worker {
338*5e7646d2SAndroid Build Coastguard Worker /*
339*5e7646d2SAndroid Build Coastguard Worker * Multi-page image formats will have copies applied by the upstream
340*5e7646d2SAndroid Build Coastguard Worker * filters...
341*5e7646d2SAndroid Build Coastguard Worker */
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker copies = 1;
344*5e7646d2SAndroid Build Coastguard Worker }
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker
347*5e7646d2SAndroid Build Coastguard Worker if (doc_handling_sup)
348*5e7646d2SAndroid Build Coastguard Worker {
349*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(keyword, "true"))
350*5e7646d2SAndroid Build Coastguard Worker collate_str = "separate-documents-collated-copies";
351*5e7646d2SAndroid Build Coastguard Worker else
352*5e7646d2SAndroid Build Coastguard Worker collate_str = "separate-documents-uncollated-copies";
353*5e7646d2SAndroid Build Coastguard Worker
354*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < doc_handling_sup->num_values; i ++)
355*5e7646d2SAndroid Build Coastguard Worker {
356*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(doc_handling_sup->values[i].string.text, collate_str))
357*5e7646d2SAndroid Build Coastguard Worker {
358*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "multiple-document-handling", NULL, collate_str);
359*5e7646d2SAndroid Build Coastguard Worker break;
360*5e7646d2SAndroid Build Coastguard Worker }
361*5e7646d2SAndroid Build Coastguard Worker }
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker if (i >= doc_handling_sup->num_values)
364*5e7646d2SAndroid Build Coastguard Worker copies = 1;
365*5e7646d2SAndroid Build Coastguard Worker }
366*5e7646d2SAndroid Build Coastguard Worker
367*5e7646d2SAndroid Build Coastguard Worker /*
368*5e7646d2SAndroid Build Coastguard Worker * Map finishing options...
369*5e7646d2SAndroid Build Coastguard Worker */
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker if (copies != finishings_copies)
372*5e7646d2SAndroid Build Coastguard Worker {
373*5e7646d2SAndroid Build Coastguard Worker // Figure out the proper job-pages-per-set value...
374*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption("job-pages", num_options, options)) == NULL)
375*5e7646d2SAndroid Build Coastguard Worker value = cupsGetOption("com.apple.print.PrintSettings.PMTotalBeginPages..n.", num_options, options);
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker if (value)
378*5e7646d2SAndroid Build Coastguard Worker job_pages = atoi(value);
379*5e7646d2SAndroid Build Coastguard Worker
380*5e7646d2SAndroid Build Coastguard Worker // Adjust for number-up
381*5e7646d2SAndroid Build Coastguard Worker if ((value = cupsGetOption("number-up", num_options, options)) != NULL)
382*5e7646d2SAndroid Build Coastguard Worker number_up = atoi(value);
383*5e7646d2SAndroid Build Coastguard Worker
384*5e7646d2SAndroid Build Coastguard Worker job_pages = (job_pages + number_up - 1) / number_up;
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker // When duplex printing, raster data will include an extra (blank) page to
387*5e7646d2SAndroid Build Coastguard Worker // make the total number of pages even. Make sure this is reflected in the
388*5e7646d2SAndroid Build Coastguard Worker // page count...
389*5e7646d2SAndroid Build Coastguard Worker if ((job_pages & 1) && (keyword = cupsGetOption("sides", num_options, options)) != NULL && strcmp(keyword, "one-sided"))
390*5e7646d2SAndroid Build Coastguard Worker job_pages ++;
391*5e7646d2SAndroid Build Coastguard Worker }
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker if ((finishing_template = cupsGetOption("cupsFinishingTemplate", num_options, options)) == NULL)
394*5e7646d2SAndroid Build Coastguard Worker finishing_template = cupsGetOption("finishing-template", num_options, options);
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker if (finishing_template && strcmp(finishing_template, "none"))
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker ipp_t *fin_col = ippNew(); /* finishings-col value */
399*5e7646d2SAndroid Build Coastguard Worker
400*5e7646d2SAndroid Build Coastguard Worker ippAddString(fin_col, IPP_TAG_JOB, IPP_TAG_KEYWORD, "finishing-template", NULL, finishing_template);
401*5e7646d2SAndroid Build Coastguard Worker ippAddCollection(request, IPP_TAG_JOB, "finishings-col", fin_col);
402*5e7646d2SAndroid Build Coastguard Worker ippDelete(fin_col);
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker if (copies != finishings_copies && job_pages > 0)
405*5e7646d2SAndroid Build Coastguard Worker {
406*5e7646d2SAndroid Build Coastguard Worker /*
407*5e7646d2SAndroid Build Coastguard Worker * Send job-pages-per-set attribute to apply finishings correctly...
408*5e7646d2SAndroid Build Coastguard Worker */
409*5e7646d2SAndroid Build Coastguard Worker
410*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", job_pages);
411*5e7646d2SAndroid Build Coastguard Worker }
412*5e7646d2SAndroid Build Coastguard Worker }
413*5e7646d2SAndroid Build Coastguard Worker else
414*5e7646d2SAndroid Build Coastguard Worker {
415*5e7646d2SAndroid Build Coastguard Worker num_finishings = _ppdCacheGetFinishingValues(ppd, pc, (int)(sizeof(finishings) / sizeof(finishings[0])), finishings);
416*5e7646d2SAndroid Build Coastguard Worker if (num_finishings > 0)
417*5e7646d2SAndroid Build Coastguard Worker {
418*5e7646d2SAndroid Build Coastguard Worker ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings);
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker if (copies != finishings_copies && job_pages > 0)
421*5e7646d2SAndroid Build Coastguard Worker {
422*5e7646d2SAndroid Build Coastguard Worker /*
423*5e7646d2SAndroid Build Coastguard Worker * Send job-pages-per-set attribute to apply finishings correctly...
424*5e7646d2SAndroid Build Coastguard Worker */
425*5e7646d2SAndroid Build Coastguard Worker
426*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", job_pages);
427*5e7646d2SAndroid Build Coastguard Worker }
428*5e7646d2SAndroid Build Coastguard Worker }
429*5e7646d2SAndroid Build Coastguard Worker }
430*5e7646d2SAndroid Build Coastguard Worker
431*5e7646d2SAndroid Build Coastguard Worker return (copies);
432*5e7646d2SAndroid Build Coastguard Worker }
433*5e7646d2SAndroid Build Coastguard Worker
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker /*
436*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheCreateWithFile()' - Create PPD cache and mapping data from a
437*5e7646d2SAndroid Build Coastguard Worker * written file.
438*5e7646d2SAndroid Build Coastguard Worker *
439*5e7646d2SAndroid Build Coastguard Worker * Use the @link _ppdCacheWriteFile@ function to write PWG mapping data to a
440*5e7646d2SAndroid Build Coastguard Worker * file.
441*5e7646d2SAndroid Build Coastguard Worker */
442*5e7646d2SAndroid Build Coastguard Worker
443*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t * /* O - PPD cache and mapping data */
_ppdCacheCreateWithFile(const char * filename,ipp_t ** attrs)444*5e7646d2SAndroid Build Coastguard Worker _ppdCacheCreateWithFile(
445*5e7646d2SAndroid Build Coastguard Worker const char *filename, /* I - File to read */
446*5e7646d2SAndroid Build Coastguard Worker ipp_t **attrs) /* IO - IPP attributes, if any */
447*5e7646d2SAndroid Build Coastguard Worker {
448*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* File */
449*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc; /* PWG mapping data */
450*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size; /* Current size */
451*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *map; /* Current map */
452*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *finishings; /* Current finishings option */
453*5e7646d2SAndroid Build Coastguard Worker int linenum, /* Current line number */
454*5e7646d2SAndroid Build Coastguard Worker num_bins, /* Number of bins in file */
455*5e7646d2SAndroid Build Coastguard Worker num_sizes, /* Number of sizes in file */
456*5e7646d2SAndroid Build Coastguard Worker num_sources, /* Number of sources in file */
457*5e7646d2SAndroid Build Coastguard Worker num_types; /* Number of types in file */
458*5e7646d2SAndroid Build Coastguard Worker char line[2048], /* Current line */
459*5e7646d2SAndroid Build Coastguard Worker *value, /* Pointer to value in line */
460*5e7646d2SAndroid Build Coastguard Worker *valueptr, /* Pointer into value */
461*5e7646d2SAndroid Build Coastguard Worker pwg_keyword[128], /* PWG keyword */
462*5e7646d2SAndroid Build Coastguard Worker ppd_keyword[PPD_MAX_NAME];
463*5e7646d2SAndroid Build Coastguard Worker /* PPD keyword */
464*5e7646d2SAndroid Build Coastguard Worker _pwg_print_color_mode_t print_color_mode;
465*5e7646d2SAndroid Build Coastguard Worker /* Print color mode for preset */
466*5e7646d2SAndroid Build Coastguard Worker _pwg_print_quality_t print_quality; /* Print quality for preset */
467*5e7646d2SAndroid Build Coastguard Worker
468*5e7646d2SAndroid Build Coastguard Worker
469*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile(filename=\"%s\")", filename));
470*5e7646d2SAndroid Build Coastguard Worker
471*5e7646d2SAndroid Build Coastguard Worker /*
472*5e7646d2SAndroid Build Coastguard Worker * Range check input...
473*5e7646d2SAndroid Build Coastguard Worker */
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (attrs)
476*5e7646d2SAndroid Build Coastguard Worker *attrs = NULL;
477*5e7646d2SAndroid Build Coastguard Worker
478*5e7646d2SAndroid Build Coastguard Worker if (!filename)
479*5e7646d2SAndroid Build Coastguard Worker {
480*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
481*5e7646d2SAndroid Build Coastguard Worker return (NULL);
482*5e7646d2SAndroid Build Coastguard Worker }
483*5e7646d2SAndroid Build Coastguard Worker
484*5e7646d2SAndroid Build Coastguard Worker /*
485*5e7646d2SAndroid Build Coastguard Worker * Open the file...
486*5e7646d2SAndroid Build Coastguard Worker */
487*5e7646d2SAndroid Build Coastguard Worker
488*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen(filename, "r")) == NULL)
489*5e7646d2SAndroid Build Coastguard Worker {
490*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
491*5e7646d2SAndroid Build Coastguard Worker return (NULL);
492*5e7646d2SAndroid Build Coastguard Worker }
493*5e7646d2SAndroid Build Coastguard Worker
494*5e7646d2SAndroid Build Coastguard Worker /*
495*5e7646d2SAndroid Build Coastguard Worker * Read the first line and make sure it has "#CUPS-PPD-CACHE-version" in it...
496*5e7646d2SAndroid Build Coastguard Worker */
497*5e7646d2SAndroid Build Coastguard Worker
498*5e7646d2SAndroid Build Coastguard Worker if (!cupsFileGets(fp, line, sizeof(line)))
499*5e7646d2SAndroid Build Coastguard Worker {
500*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
501*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: Unable to read first line.");
502*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
503*5e7646d2SAndroid Build Coastguard Worker return (NULL);
504*5e7646d2SAndroid Build Coastguard Worker }
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker if (strncmp(line, "#CUPS-PPD-CACHE-", 16))
507*5e7646d2SAndroid Build Coastguard Worker {
508*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
509*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Wrong first line \"%s\".", line));
510*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
511*5e7646d2SAndroid Build Coastguard Worker return (NULL);
512*5e7646d2SAndroid Build Coastguard Worker }
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker if (atoi(line + 16) != _PPD_CACHE_VERSION)
515*5e7646d2SAndroid Build Coastguard Worker {
516*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Out of date PPD cache file."), 1);
517*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Cache file has version %s, "
518*5e7646d2SAndroid Build Coastguard Worker "expected %d.", line + 16, _PPD_CACHE_VERSION));
519*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
520*5e7646d2SAndroid Build Coastguard Worker return (NULL);
521*5e7646d2SAndroid Build Coastguard Worker }
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker /*
524*5e7646d2SAndroid Build Coastguard Worker * Allocate the mapping data structure...
525*5e7646d2SAndroid Build Coastguard Worker */
526*5e7646d2SAndroid Build Coastguard Worker
527*5e7646d2SAndroid Build Coastguard Worker if ((pc = calloc(1, sizeof(_ppd_cache_t))) == NULL)
528*5e7646d2SAndroid Build Coastguard Worker {
529*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
530*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: Unable to allocate _ppd_cache_t.");
531*5e7646d2SAndroid Build Coastguard Worker goto create_error;
532*5e7646d2SAndroid Build Coastguard Worker }
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker pc->max_copies = 9999;
535*5e7646d2SAndroid Build Coastguard Worker
536*5e7646d2SAndroid Build Coastguard Worker /*
537*5e7646d2SAndroid Build Coastguard Worker * Read the file...
538*5e7646d2SAndroid Build Coastguard Worker */
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker linenum = 0;
541*5e7646d2SAndroid Build Coastguard Worker num_bins = 0;
542*5e7646d2SAndroid Build Coastguard Worker num_sizes = 0;
543*5e7646d2SAndroid Build Coastguard Worker num_sources = 0;
544*5e7646d2SAndroid Build Coastguard Worker num_types = 0;
545*5e7646d2SAndroid Build Coastguard Worker
546*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
547*5e7646d2SAndroid Build Coastguard Worker {
548*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: line=\"%s\", value=\"%s\", "
549*5e7646d2SAndroid Build Coastguard Worker "linenum=%d", line, value, linenum));
550*5e7646d2SAndroid Build Coastguard Worker
551*5e7646d2SAndroid Build Coastguard Worker if (!value)
552*5e7646d2SAndroid Build Coastguard Worker {
553*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Missing value on line %d.",
554*5e7646d2SAndroid Build Coastguard Worker linenum));
555*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
556*5e7646d2SAndroid Build Coastguard Worker goto create_error;
557*5e7646d2SAndroid Build Coastguard Worker }
558*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Filter"))
559*5e7646d2SAndroid Build Coastguard Worker {
560*5e7646d2SAndroid Build Coastguard Worker if (!pc->filters)
561*5e7646d2SAndroid Build Coastguard Worker pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
562*5e7646d2SAndroid Build Coastguard Worker
563*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters, value);
564*5e7646d2SAndroid Build Coastguard Worker }
565*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "PreFilter"))
566*5e7646d2SAndroid Build Coastguard Worker {
567*5e7646d2SAndroid Build Coastguard Worker if (!pc->prefilters)
568*5e7646d2SAndroid Build Coastguard Worker pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
569*5e7646d2SAndroid Build Coastguard Worker
570*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->prefilters, value);
571*5e7646d2SAndroid Build Coastguard Worker }
572*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Product"))
573*5e7646d2SAndroid Build Coastguard Worker {
574*5e7646d2SAndroid Build Coastguard Worker pc->product = strdup(value);
575*5e7646d2SAndroid Build Coastguard Worker }
576*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "SingleFile"))
577*5e7646d2SAndroid Build Coastguard Worker {
578*5e7646d2SAndroid Build Coastguard Worker pc->single_file = !_cups_strcasecmp(value, "true");
579*5e7646d2SAndroid Build Coastguard Worker }
580*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "IPP"))
581*5e7646d2SAndroid Build Coastguard Worker {
582*5e7646d2SAndroid Build Coastguard Worker off_t pos = cupsFileTell(fp), /* Position in file */
583*5e7646d2SAndroid Build Coastguard Worker length = strtol(value, NULL, 10);
584*5e7646d2SAndroid Build Coastguard Worker /* Length of IPP attributes */
585*5e7646d2SAndroid Build Coastguard Worker
586*5e7646d2SAndroid Build Coastguard Worker if (attrs && *attrs)
587*5e7646d2SAndroid Build Coastguard Worker {
588*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: IPP listed multiple times.");
589*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
590*5e7646d2SAndroid Build Coastguard Worker goto create_error;
591*5e7646d2SAndroid Build Coastguard Worker }
592*5e7646d2SAndroid Build Coastguard Worker else if (length <= 0)
593*5e7646d2SAndroid Build Coastguard Worker {
594*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP length.");
595*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
596*5e7646d2SAndroid Build Coastguard Worker goto create_error;
597*5e7646d2SAndroid Build Coastguard Worker }
598*5e7646d2SAndroid Build Coastguard Worker
599*5e7646d2SAndroid Build Coastguard Worker if (attrs)
600*5e7646d2SAndroid Build Coastguard Worker {
601*5e7646d2SAndroid Build Coastguard Worker /*
602*5e7646d2SAndroid Build Coastguard Worker * Read IPP attributes into the provided variable...
603*5e7646d2SAndroid Build Coastguard Worker */
604*5e7646d2SAndroid Build Coastguard Worker
605*5e7646d2SAndroid Build Coastguard Worker *attrs = ippNew();
606*5e7646d2SAndroid Build Coastguard Worker
607*5e7646d2SAndroid Build Coastguard Worker if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
608*5e7646d2SAndroid Build Coastguard Worker *attrs) != IPP_STATE_DATA)
609*5e7646d2SAndroid Build Coastguard Worker {
610*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP data.");
611*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
612*5e7646d2SAndroid Build Coastguard Worker goto create_error;
613*5e7646d2SAndroid Build Coastguard Worker }
614*5e7646d2SAndroid Build Coastguard Worker }
615*5e7646d2SAndroid Build Coastguard Worker else
616*5e7646d2SAndroid Build Coastguard Worker {
617*5e7646d2SAndroid Build Coastguard Worker /*
618*5e7646d2SAndroid Build Coastguard Worker * Skip the IPP data entirely...
619*5e7646d2SAndroid Build Coastguard Worker */
620*5e7646d2SAndroid Build Coastguard Worker
621*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(fp, pos + length);
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker if (cupsFileTell(fp) != (pos + length))
625*5e7646d2SAndroid Build Coastguard Worker {
626*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: Bad IPP data.");
627*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
628*5e7646d2SAndroid Build Coastguard Worker goto create_error;
629*5e7646d2SAndroid Build Coastguard Worker }
630*5e7646d2SAndroid Build Coastguard Worker }
631*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "NumBins"))
632*5e7646d2SAndroid Build Coastguard Worker {
633*5e7646d2SAndroid Build Coastguard Worker if (num_bins > 0)
634*5e7646d2SAndroid Build Coastguard Worker {
635*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: NumBins listed multiple times.");
636*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
637*5e7646d2SAndroid Build Coastguard Worker goto create_error;
638*5e7646d2SAndroid Build Coastguard Worker }
639*5e7646d2SAndroid Build Coastguard Worker
640*5e7646d2SAndroid Build Coastguard Worker if ((num_bins = atoi(value)) <= 0 || num_bins > 65536)
641*5e7646d2SAndroid Build Coastguard Worker {
642*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumBins value %d on line "
643*5e7646d2SAndroid Build Coastguard Worker "%d.", num_sizes, linenum));
644*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
645*5e7646d2SAndroid Build Coastguard Worker goto create_error;
646*5e7646d2SAndroid Build Coastguard Worker }
647*5e7646d2SAndroid Build Coastguard Worker
648*5e7646d2SAndroid Build Coastguard Worker if ((pc->bins = calloc((size_t)num_bins, sizeof(pwg_map_t))) == NULL)
649*5e7646d2SAndroid Build Coastguard Worker {
650*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d bins.",
651*5e7646d2SAndroid Build Coastguard Worker num_sizes));
652*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
653*5e7646d2SAndroid Build Coastguard Worker goto create_error;
654*5e7646d2SAndroid Build Coastguard Worker }
655*5e7646d2SAndroid Build Coastguard Worker }
656*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Bin"))
657*5e7646d2SAndroid Build Coastguard Worker {
658*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
659*5e7646d2SAndroid Build Coastguard Worker {
660*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad Bin on line %d.", linenum));
661*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
662*5e7646d2SAndroid Build Coastguard Worker goto create_error;
663*5e7646d2SAndroid Build Coastguard Worker }
664*5e7646d2SAndroid Build Coastguard Worker
665*5e7646d2SAndroid Build Coastguard Worker if (pc->num_bins >= num_bins)
666*5e7646d2SAndroid Build Coastguard Worker {
667*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Too many Bin's on line %d.",
668*5e7646d2SAndroid Build Coastguard Worker linenum));
669*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
670*5e7646d2SAndroid Build Coastguard Worker goto create_error;
671*5e7646d2SAndroid Build Coastguard Worker }
672*5e7646d2SAndroid Build Coastguard Worker
673*5e7646d2SAndroid Build Coastguard Worker map = pc->bins + pc->num_bins;
674*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_keyword);
675*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(ppd_keyword);
676*5e7646d2SAndroid Build Coastguard Worker
677*5e7646d2SAndroid Build Coastguard Worker pc->num_bins ++;
678*5e7646d2SAndroid Build Coastguard Worker }
679*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "NumSizes"))
680*5e7646d2SAndroid Build Coastguard Worker {
681*5e7646d2SAndroid Build Coastguard Worker if (num_sizes > 0)
682*5e7646d2SAndroid Build Coastguard Worker {
683*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: NumSizes listed multiple times.");
684*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
685*5e7646d2SAndroid Build Coastguard Worker goto create_error;
686*5e7646d2SAndroid Build Coastguard Worker }
687*5e7646d2SAndroid Build Coastguard Worker
688*5e7646d2SAndroid Build Coastguard Worker if ((num_sizes = atoi(value)) < 0 || num_sizes > 65536)
689*5e7646d2SAndroid Build Coastguard Worker {
690*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSizes value %d on line "
691*5e7646d2SAndroid Build Coastguard Worker "%d.", num_sizes, linenum));
692*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
693*5e7646d2SAndroid Build Coastguard Worker goto create_error;
694*5e7646d2SAndroid Build Coastguard Worker }
695*5e7646d2SAndroid Build Coastguard Worker
696*5e7646d2SAndroid Build Coastguard Worker if (num_sizes > 0)
697*5e7646d2SAndroid Build Coastguard Worker {
698*5e7646d2SAndroid Build Coastguard Worker if ((pc->sizes = calloc((size_t)num_sizes, sizeof(pwg_size_t))) == NULL)
699*5e7646d2SAndroid Build Coastguard Worker {
700*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
701*5e7646d2SAndroid Build Coastguard Worker num_sizes));
702*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
703*5e7646d2SAndroid Build Coastguard Worker goto create_error;
704*5e7646d2SAndroid Build Coastguard Worker }
705*5e7646d2SAndroid Build Coastguard Worker }
706*5e7646d2SAndroid Build Coastguard Worker }
707*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Size"))
708*5e7646d2SAndroid Build Coastguard Worker {
709*5e7646d2SAndroid Build Coastguard Worker if (pc->num_sizes >= num_sizes)
710*5e7646d2SAndroid Build Coastguard Worker {
711*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Too many Size's on line %d.",
712*5e7646d2SAndroid Build Coastguard Worker linenum));
713*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
714*5e7646d2SAndroid Build Coastguard Worker goto create_error;
715*5e7646d2SAndroid Build Coastguard Worker }
716*5e7646d2SAndroid Build Coastguard Worker
717*5e7646d2SAndroid Build Coastguard Worker size = pc->sizes + pc->num_sizes;
718*5e7646d2SAndroid Build Coastguard Worker
719*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%127s%40s%d%d%d%d%d%d", pwg_keyword, ppd_keyword,
720*5e7646d2SAndroid Build Coastguard Worker &(size->width), &(size->length), &(size->left),
721*5e7646d2SAndroid Build Coastguard Worker &(size->bottom), &(size->right), &(size->top)) != 8)
722*5e7646d2SAndroid Build Coastguard Worker {
723*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad Size on line %d.",
724*5e7646d2SAndroid Build Coastguard Worker linenum));
725*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
726*5e7646d2SAndroid Build Coastguard Worker goto create_error;
727*5e7646d2SAndroid Build Coastguard Worker }
728*5e7646d2SAndroid Build Coastguard Worker
729*5e7646d2SAndroid Build Coastguard Worker size->map.pwg = strdup(pwg_keyword);
730*5e7646d2SAndroid Build Coastguard Worker size->map.ppd = strdup(ppd_keyword);
731*5e7646d2SAndroid Build Coastguard Worker
732*5e7646d2SAndroid Build Coastguard Worker pc->num_sizes ++;
733*5e7646d2SAndroid Build Coastguard Worker }
734*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "CustomSize"))
735*5e7646d2SAndroid Build Coastguard Worker {
736*5e7646d2SAndroid Build Coastguard Worker if (pc->custom_max_width > 0)
737*5e7646d2SAndroid Build Coastguard Worker {
738*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Too many CustomSize's on line "
739*5e7646d2SAndroid Build Coastguard Worker "%d.", linenum));
740*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
741*5e7646d2SAndroid Build Coastguard Worker goto create_error;
742*5e7646d2SAndroid Build Coastguard Worker }
743*5e7646d2SAndroid Build Coastguard Worker
744*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%d%d%d%d%d%d%d%d", &(pc->custom_max_width),
745*5e7646d2SAndroid Build Coastguard Worker &(pc->custom_max_length), &(pc->custom_min_width),
746*5e7646d2SAndroid Build Coastguard Worker &(pc->custom_min_length), &(pc->custom_size.left),
747*5e7646d2SAndroid Build Coastguard Worker &(pc->custom_size.bottom), &(pc->custom_size.right),
748*5e7646d2SAndroid Build Coastguard Worker &(pc->custom_size.top)) != 8)
749*5e7646d2SAndroid Build Coastguard Worker {
750*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad CustomSize on line %d.",
751*5e7646d2SAndroid Build Coastguard Worker linenum));
752*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
753*5e7646d2SAndroid Build Coastguard Worker goto create_error;
754*5e7646d2SAndroid Build Coastguard Worker }
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
757*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_width, pc->custom_max_length, NULL);
758*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_keyword = strdup(pwg_keyword);
759*5e7646d2SAndroid Build Coastguard Worker
760*5e7646d2SAndroid Build Coastguard Worker pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
761*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_width, pc->custom_min_length, NULL);
762*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_keyword = strdup(pwg_keyword);
763*5e7646d2SAndroid Build Coastguard Worker }
764*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "SourceOption"))
765*5e7646d2SAndroid Build Coastguard Worker {
766*5e7646d2SAndroid Build Coastguard Worker pc->source_option = strdup(value);
767*5e7646d2SAndroid Build Coastguard Worker }
768*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "NumSources"))
769*5e7646d2SAndroid Build Coastguard Worker {
770*5e7646d2SAndroid Build Coastguard Worker if (num_sources > 0)
771*5e7646d2SAndroid Build Coastguard Worker {
772*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: NumSources listed multiple "
773*5e7646d2SAndroid Build Coastguard Worker "times.");
774*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
775*5e7646d2SAndroid Build Coastguard Worker goto create_error;
776*5e7646d2SAndroid Build Coastguard Worker }
777*5e7646d2SAndroid Build Coastguard Worker
778*5e7646d2SAndroid Build Coastguard Worker if ((num_sources = atoi(value)) <= 0 || num_sources > 65536)
779*5e7646d2SAndroid Build Coastguard Worker {
780*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSources value %d on "
781*5e7646d2SAndroid Build Coastguard Worker "line %d.", num_sources, linenum));
782*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
783*5e7646d2SAndroid Build Coastguard Worker goto create_error;
784*5e7646d2SAndroid Build Coastguard Worker }
785*5e7646d2SAndroid Build Coastguard Worker
786*5e7646d2SAndroid Build Coastguard Worker if ((pc->sources = calloc((size_t)num_sources, sizeof(pwg_map_t))) == NULL)
787*5e7646d2SAndroid Build Coastguard Worker {
788*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sources.",
789*5e7646d2SAndroid Build Coastguard Worker num_sources));
790*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
791*5e7646d2SAndroid Build Coastguard Worker goto create_error;
792*5e7646d2SAndroid Build Coastguard Worker }
793*5e7646d2SAndroid Build Coastguard Worker }
794*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Source"))
795*5e7646d2SAndroid Build Coastguard Worker {
796*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
797*5e7646d2SAndroid Build Coastguard Worker {
798*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad Source on line %d.",
799*5e7646d2SAndroid Build Coastguard Worker linenum));
800*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
801*5e7646d2SAndroid Build Coastguard Worker goto create_error;
802*5e7646d2SAndroid Build Coastguard Worker }
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker if (pc->num_sources >= num_sources)
805*5e7646d2SAndroid Build Coastguard Worker {
806*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Too many Source's on line %d.",
807*5e7646d2SAndroid Build Coastguard Worker linenum));
808*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
809*5e7646d2SAndroid Build Coastguard Worker goto create_error;
810*5e7646d2SAndroid Build Coastguard Worker }
811*5e7646d2SAndroid Build Coastguard Worker
812*5e7646d2SAndroid Build Coastguard Worker map = pc->sources + pc->num_sources;
813*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_keyword);
814*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(ppd_keyword);
815*5e7646d2SAndroid Build Coastguard Worker
816*5e7646d2SAndroid Build Coastguard Worker pc->num_sources ++;
817*5e7646d2SAndroid Build Coastguard Worker }
818*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "NumTypes"))
819*5e7646d2SAndroid Build Coastguard Worker {
820*5e7646d2SAndroid Build Coastguard Worker if (num_types > 0)
821*5e7646d2SAndroid Build Coastguard Worker {
822*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithFile: NumTypes listed multiple times.");
823*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
824*5e7646d2SAndroid Build Coastguard Worker goto create_error;
825*5e7646d2SAndroid Build Coastguard Worker }
826*5e7646d2SAndroid Build Coastguard Worker
827*5e7646d2SAndroid Build Coastguard Worker if ((num_types = atoi(value)) <= 0 || num_types > 65536)
828*5e7646d2SAndroid Build Coastguard Worker {
829*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumTypes value %d on "
830*5e7646d2SAndroid Build Coastguard Worker "line %d.", num_types, linenum));
831*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
832*5e7646d2SAndroid Build Coastguard Worker goto create_error;
833*5e7646d2SAndroid Build Coastguard Worker }
834*5e7646d2SAndroid Build Coastguard Worker
835*5e7646d2SAndroid Build Coastguard Worker if ((pc->types = calloc((size_t)num_types, sizeof(pwg_map_t))) == NULL)
836*5e7646d2SAndroid Build Coastguard Worker {
837*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d types.",
838*5e7646d2SAndroid Build Coastguard Worker num_types));
839*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
840*5e7646d2SAndroid Build Coastguard Worker goto create_error;
841*5e7646d2SAndroid Build Coastguard Worker }
842*5e7646d2SAndroid Build Coastguard Worker }
843*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Type"))
844*5e7646d2SAndroid Build Coastguard Worker {
845*5e7646d2SAndroid Build Coastguard Worker if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
846*5e7646d2SAndroid Build Coastguard Worker {
847*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad Type on line %d.",
848*5e7646d2SAndroid Build Coastguard Worker linenum));
849*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
850*5e7646d2SAndroid Build Coastguard Worker goto create_error;
851*5e7646d2SAndroid Build Coastguard Worker }
852*5e7646d2SAndroid Build Coastguard Worker
853*5e7646d2SAndroid Build Coastguard Worker if (pc->num_types >= num_types)
854*5e7646d2SAndroid Build Coastguard Worker {
855*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Too many Type's on line %d.",
856*5e7646d2SAndroid Build Coastguard Worker linenum));
857*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
858*5e7646d2SAndroid Build Coastguard Worker goto create_error;
859*5e7646d2SAndroid Build Coastguard Worker }
860*5e7646d2SAndroid Build Coastguard Worker
861*5e7646d2SAndroid Build Coastguard Worker map = pc->types + pc->num_types;
862*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_keyword);
863*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(ppd_keyword);
864*5e7646d2SAndroid Build Coastguard Worker
865*5e7646d2SAndroid Build Coastguard Worker pc->num_types ++;
866*5e7646d2SAndroid Build Coastguard Worker }
867*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Preset"))
868*5e7646d2SAndroid Build Coastguard Worker {
869*5e7646d2SAndroid Build Coastguard Worker /*
870*5e7646d2SAndroid Build Coastguard Worker * Preset output-mode print-quality name=value ...
871*5e7646d2SAndroid Build Coastguard Worker */
872*5e7646d2SAndroid Build Coastguard Worker
873*5e7646d2SAndroid Build Coastguard Worker print_color_mode = (_pwg_print_color_mode_t)strtol(value, &valueptr, 10);
874*5e7646d2SAndroid Build Coastguard Worker print_quality = (_pwg_print_quality_t)strtol(valueptr, &valueptr, 10);
875*5e7646d2SAndroid Build Coastguard Worker
876*5e7646d2SAndroid Build Coastguard Worker if (print_color_mode < _PWG_PRINT_COLOR_MODE_MONOCHROME ||
877*5e7646d2SAndroid Build Coastguard Worker print_color_mode >= _PWG_PRINT_COLOR_MODE_MAX ||
878*5e7646d2SAndroid Build Coastguard Worker print_quality < _PWG_PRINT_QUALITY_DRAFT ||
879*5e7646d2SAndroid Build Coastguard Worker print_quality >= _PWG_PRINT_QUALITY_MAX ||
880*5e7646d2SAndroid Build Coastguard Worker valueptr == value || !*valueptr)
881*5e7646d2SAndroid Build Coastguard Worker {
882*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Bad Preset on line %d.",
883*5e7646d2SAndroid Build Coastguard Worker linenum));
884*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
885*5e7646d2SAndroid Build Coastguard Worker goto create_error;
886*5e7646d2SAndroid Build Coastguard Worker }
887*5e7646d2SAndroid Build Coastguard Worker
888*5e7646d2SAndroid Build Coastguard Worker pc->num_presets[print_color_mode][print_quality] =
889*5e7646d2SAndroid Build Coastguard Worker cupsParseOptions(valueptr, 0,
890*5e7646d2SAndroid Build Coastguard Worker pc->presets[print_color_mode] + print_quality);
891*5e7646d2SAndroid Build Coastguard Worker }
892*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "SidesOption"))
893*5e7646d2SAndroid Build Coastguard Worker pc->sides_option = strdup(value);
894*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Sides1Sided"))
895*5e7646d2SAndroid Build Coastguard Worker pc->sides_1sided = strdup(value);
896*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Sides2SidedLong"))
897*5e7646d2SAndroid Build Coastguard Worker pc->sides_2sided_long = strdup(value);
898*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Sides2SidedShort"))
899*5e7646d2SAndroid Build Coastguard Worker pc->sides_2sided_short = strdup(value);
900*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Finishings"))
901*5e7646d2SAndroid Build Coastguard Worker {
902*5e7646d2SAndroid Build Coastguard Worker if (!pc->finishings)
903*5e7646d2SAndroid Build Coastguard Worker pc->finishings =
904*5e7646d2SAndroid Build Coastguard Worker cupsArrayNew3((cups_array_func_t)pwg_compare_finishings,
905*5e7646d2SAndroid Build Coastguard Worker NULL, NULL, 0, NULL,
906*5e7646d2SAndroid Build Coastguard Worker (cups_afree_func_t)pwg_free_finishings);
907*5e7646d2SAndroid Build Coastguard Worker
908*5e7646d2SAndroid Build Coastguard Worker if ((finishings = calloc(1, sizeof(_pwg_finishings_t))) == NULL)
909*5e7646d2SAndroid Build Coastguard Worker goto create_error;
910*5e7646d2SAndroid Build Coastguard Worker
911*5e7646d2SAndroid Build Coastguard Worker finishings->value = (ipp_finishings_t)strtol(value, &valueptr, 10);
912*5e7646d2SAndroid Build Coastguard Worker finishings->num_options = cupsParseOptions(valueptr, 0,
913*5e7646d2SAndroid Build Coastguard Worker &(finishings->options));
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->finishings, finishings);
916*5e7646d2SAndroid Build Coastguard Worker }
917*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "FinishingTemplate"))
918*5e7646d2SAndroid Build Coastguard Worker {
919*5e7646d2SAndroid Build Coastguard Worker if (!pc->templates)
920*5e7646d2SAndroid Build Coastguard Worker pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
921*5e7646d2SAndroid Build Coastguard Worker
922*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->templates, value);
923*5e7646d2SAndroid Build Coastguard Worker }
924*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "MaxCopies"))
925*5e7646d2SAndroid Build Coastguard Worker pc->max_copies = atoi(value);
926*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "ChargeInfoURI"))
927*5e7646d2SAndroid Build Coastguard Worker pc->charge_info_uri = strdup(value);
928*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "JobAccountId"))
929*5e7646d2SAndroid Build Coastguard Worker pc->account_id = !_cups_strcasecmp(value, "true");
930*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "JobAccountingUserId"))
931*5e7646d2SAndroid Build Coastguard Worker pc->accounting_user_id = !_cups_strcasecmp(value, "true");
932*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "JobPassword"))
933*5e7646d2SAndroid Build Coastguard Worker pc->password = strdup(value);
934*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Mandatory"))
935*5e7646d2SAndroid Build Coastguard Worker {
936*5e7646d2SAndroid Build Coastguard Worker if (pc->mandatory)
937*5e7646d2SAndroid Build Coastguard Worker _cupsArrayAddStrings(pc->mandatory, value, ' ');
938*5e7646d2SAndroid Build Coastguard Worker else
939*5e7646d2SAndroid Build Coastguard Worker pc->mandatory = _cupsArrayNewStrings(value, ' ');
940*5e7646d2SAndroid Build Coastguard Worker }
941*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "SupportFile"))
942*5e7646d2SAndroid Build Coastguard Worker {
943*5e7646d2SAndroid Build Coastguard Worker if (!pc->support_files)
944*5e7646d2SAndroid Build Coastguard Worker pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
945*5e7646d2SAndroid Build Coastguard Worker
946*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->support_files, value);
947*5e7646d2SAndroid Build Coastguard Worker }
948*5e7646d2SAndroid Build Coastguard Worker else
949*5e7646d2SAndroid Build Coastguard Worker {
950*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line,
951*5e7646d2SAndroid Build Coastguard Worker linenum));
952*5e7646d2SAndroid Build Coastguard Worker }
953*5e7646d2SAndroid Build Coastguard Worker }
954*5e7646d2SAndroid Build Coastguard Worker
955*5e7646d2SAndroid Build Coastguard Worker if (pc->num_sizes < num_sizes)
956*5e7646d2SAndroid Build Coastguard Worker {
957*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sizes (%d < %d).",
958*5e7646d2SAndroid Build Coastguard Worker pc->num_sizes, num_sizes));
959*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
960*5e7646d2SAndroid Build Coastguard Worker goto create_error;
961*5e7646d2SAndroid Build Coastguard Worker }
962*5e7646d2SAndroid Build Coastguard Worker
963*5e7646d2SAndroid Build Coastguard Worker if (pc->num_sources < num_sources)
964*5e7646d2SAndroid Build Coastguard Worker {
965*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sources (%d < %d).",
966*5e7646d2SAndroid Build Coastguard Worker pc->num_sources, num_sources));
967*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
968*5e7646d2SAndroid Build Coastguard Worker goto create_error;
969*5e7646d2SAndroid Build Coastguard Worker }
970*5e7646d2SAndroid Build Coastguard Worker
971*5e7646d2SAndroid Build Coastguard Worker if (pc->num_types < num_types)
972*5e7646d2SAndroid Build Coastguard Worker {
973*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithFile: Not enough types (%d < %d).",
974*5e7646d2SAndroid Build Coastguard Worker pc->num_types, num_types));
975*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
976*5e7646d2SAndroid Build Coastguard Worker goto create_error;
977*5e7646d2SAndroid Build Coastguard Worker }
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
980*5e7646d2SAndroid Build Coastguard Worker
981*5e7646d2SAndroid Build Coastguard Worker return (pc);
982*5e7646d2SAndroid Build Coastguard Worker
983*5e7646d2SAndroid Build Coastguard Worker /*
984*5e7646d2SAndroid Build Coastguard Worker * If we get here the file was bad - free any data and return...
985*5e7646d2SAndroid Build Coastguard Worker */
986*5e7646d2SAndroid Build Coastguard Worker
987*5e7646d2SAndroid Build Coastguard Worker create_error:
988*5e7646d2SAndroid Build Coastguard Worker
989*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
990*5e7646d2SAndroid Build Coastguard Worker _ppdCacheDestroy(pc);
991*5e7646d2SAndroid Build Coastguard Worker
992*5e7646d2SAndroid Build Coastguard Worker if (attrs)
993*5e7646d2SAndroid Build Coastguard Worker {
994*5e7646d2SAndroid Build Coastguard Worker ippDelete(*attrs);
995*5e7646d2SAndroid Build Coastguard Worker *attrs = NULL;
996*5e7646d2SAndroid Build Coastguard Worker }
997*5e7646d2SAndroid Build Coastguard Worker
998*5e7646d2SAndroid Build Coastguard Worker return (NULL);
999*5e7646d2SAndroid Build Coastguard Worker }
1000*5e7646d2SAndroid Build Coastguard Worker
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker /*
1003*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheCreateWithPPD()' - Create PWG mapping data from a PPD file.
1004*5e7646d2SAndroid Build Coastguard Worker */
1005*5e7646d2SAndroid Build Coastguard Worker
1006*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t * /* O - PPD cache and mapping data */
_ppdCacheCreateWithPPD(ppd_file_t * ppd)1007*5e7646d2SAndroid Build Coastguard Worker _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
1008*5e7646d2SAndroid Build Coastguard Worker {
1009*5e7646d2SAndroid Build Coastguard Worker int i, j, k; /* Looping vars */
1010*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc; /* PWG mapping data */
1011*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *input_slot, /* InputSlot option */
1012*5e7646d2SAndroid Build Coastguard Worker *media_type, /* MediaType option */
1013*5e7646d2SAndroid Build Coastguard Worker *output_bin, /* OutputBin option */
1014*5e7646d2SAndroid Build Coastguard Worker *color_model, /* ColorModel option */
1015*5e7646d2SAndroid Build Coastguard Worker *duplex, /* Duplex option */
1016*5e7646d2SAndroid Build Coastguard Worker *ppd_option; /* Other PPD option */
1017*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *choice; /* Current InputSlot/MediaType */
1018*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *map; /* Current source/type map */
1019*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *ppd_attr; /* Current PPD preset attribute */
1020*5e7646d2SAndroid Build Coastguard Worker int num_options; /* Number of preset options and props */
1021*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options; /* Preset options and properties */
1022*5e7646d2SAndroid Build Coastguard Worker ppd_size_t *ppd_size; /* Current PPD size */
1023*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *pwg_size; /* Current PWG size */
1024*5e7646d2SAndroid Build Coastguard Worker char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3],
1025*5e7646d2SAndroid Build Coastguard Worker /* PWG keyword string */
1026*5e7646d2SAndroid Build Coastguard Worker ppd_name[PPD_MAX_NAME];
1027*5e7646d2SAndroid Build Coastguard Worker /* Normalized PPD name */
1028*5e7646d2SAndroid Build Coastguard Worker const char *pwg_name; /* Standard PWG media name */
1029*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *pwg_media; /* PWG media data */
1030*5e7646d2SAndroid Build Coastguard Worker _pwg_print_color_mode_t pwg_print_color_mode;
1031*5e7646d2SAndroid Build Coastguard Worker /* print-color-mode index */
1032*5e7646d2SAndroid Build Coastguard Worker _pwg_print_quality_t pwg_print_quality;
1033*5e7646d2SAndroid Build Coastguard Worker /* print-quality index */
1034*5e7646d2SAndroid Build Coastguard Worker int similar; /* Are the old and new size similar? */
1035*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *old_size; /* Current old size */
1036*5e7646d2SAndroid Build Coastguard Worker int old_imageable, /* Old imageable length in 2540ths */
1037*5e7646d2SAndroid Build Coastguard Worker old_borderless, /* Old borderless state */
1038*5e7646d2SAndroid Build Coastguard Worker old_known_pwg; /* Old PWG name is well-known */
1039*5e7646d2SAndroid Build Coastguard Worker int new_width, /* New width in 2540ths */
1040*5e7646d2SAndroid Build Coastguard Worker new_length, /* New length in 2540ths */
1041*5e7646d2SAndroid Build Coastguard Worker new_left, /* New left margin in 2540ths */
1042*5e7646d2SAndroid Build Coastguard Worker new_bottom, /* New bottom margin in 2540ths */
1043*5e7646d2SAndroid Build Coastguard Worker new_right, /* New right margin in 2540ths */
1044*5e7646d2SAndroid Build Coastguard Worker new_top, /* New top margin in 2540ths */
1045*5e7646d2SAndroid Build Coastguard Worker new_imageable, /* New imageable length in 2540ths */
1046*5e7646d2SAndroid Build Coastguard Worker new_borderless, /* New borderless state */
1047*5e7646d2SAndroid Build Coastguard Worker new_known_pwg; /* New PWG name is well-known */
1048*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *new_size; /* New size to add, if any */
1049*5e7646d2SAndroid Build Coastguard Worker const char *filter; /* Current filter */
1050*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *finishings; /* Current finishings value */
1051*5e7646d2SAndroid Build Coastguard Worker char msg_id[256]; /* Message identifier */
1052*5e7646d2SAndroid Build Coastguard Worker
1053*5e7646d2SAndroid Build Coastguard Worker
1054*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithPPD(ppd=%p)", ppd));
1055*5e7646d2SAndroid Build Coastguard Worker
1056*5e7646d2SAndroid Build Coastguard Worker /*
1057*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1058*5e7646d2SAndroid Build Coastguard Worker */
1059*5e7646d2SAndroid Build Coastguard Worker
1060*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
1061*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1062*5e7646d2SAndroid Build Coastguard Worker
1063*5e7646d2SAndroid Build Coastguard Worker /*
1064*5e7646d2SAndroid Build Coastguard Worker * Allocate memory...
1065*5e7646d2SAndroid Build Coastguard Worker */
1066*5e7646d2SAndroid Build Coastguard Worker
1067*5e7646d2SAndroid Build Coastguard Worker if ((pc = calloc(1, sizeof(_ppd_cache_t))) == NULL)
1068*5e7646d2SAndroid Build Coastguard Worker {
1069*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheCreateWithPPD: Unable to allocate _ppd_cache_t.");
1070*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1071*5e7646d2SAndroid Build Coastguard Worker }
1072*5e7646d2SAndroid Build Coastguard Worker
1073*5e7646d2SAndroid Build Coastguard Worker pc->strings = _cupsMessageNew(NULL);
1074*5e7646d2SAndroid Build Coastguard Worker
1075*5e7646d2SAndroid Build Coastguard Worker /*
1076*5e7646d2SAndroid Build Coastguard Worker * Copy and convert size data...
1077*5e7646d2SAndroid Build Coastguard Worker */
1078*5e7646d2SAndroid Build Coastguard Worker
1079*5e7646d2SAndroid Build Coastguard Worker if (ppd->num_sizes > 0)
1080*5e7646d2SAndroid Build Coastguard Worker {
1081*5e7646d2SAndroid Build Coastguard Worker if ((pc->sizes = calloc((size_t)ppd->num_sizes, sizeof(pwg_size_t))) == NULL)
1082*5e7646d2SAndroid Build Coastguard Worker {
1083*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
1084*5e7646d2SAndroid Build Coastguard Worker "pwg_size_t's.", ppd->num_sizes));
1085*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1086*5e7646d2SAndroid Build Coastguard Worker }
1087*5e7646d2SAndroid Build Coastguard Worker
1088*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
1089*5e7646d2SAndroid Build Coastguard Worker i > 0;
1090*5e7646d2SAndroid Build Coastguard Worker i --, ppd_size ++)
1091*5e7646d2SAndroid Build Coastguard Worker {
1092*5e7646d2SAndroid Build Coastguard Worker /*
1093*5e7646d2SAndroid Build Coastguard Worker * Don't copy over custom size...
1094*5e7646d2SAndroid Build Coastguard Worker */
1095*5e7646d2SAndroid Build Coastguard Worker
1096*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ppd_size->name, "Custom"))
1097*5e7646d2SAndroid Build Coastguard Worker continue;
1098*5e7646d2SAndroid Build Coastguard Worker
1099*5e7646d2SAndroid Build Coastguard Worker /*
1100*5e7646d2SAndroid Build Coastguard Worker * Convert the PPD size name to the corresponding PWG keyword name.
1101*5e7646d2SAndroid Build Coastguard Worker */
1102*5e7646d2SAndroid Build Coastguard Worker
1103*5e7646d2SAndroid Build Coastguard Worker if ((pwg_media = pwgMediaForSize(PWG_FROM_POINTS(ppd_size->width), PWG_FROM_POINTS(ppd_size->length))) != NULL)
1104*5e7646d2SAndroid Build Coastguard Worker {
1105*5e7646d2SAndroid Build Coastguard Worker /*
1106*5e7646d2SAndroid Build Coastguard Worker * Standard name, do we have conflicts?
1107*5e7646d2SAndroid Build Coastguard Worker */
1108*5e7646d2SAndroid Build Coastguard Worker
1109*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < pc->num_sizes; j ++)
1110*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
1111*5e7646d2SAndroid Build Coastguard Worker {
1112*5e7646d2SAndroid Build Coastguard Worker pwg_media = NULL;
1113*5e7646d2SAndroid Build Coastguard Worker break;
1114*5e7646d2SAndroid Build Coastguard Worker }
1115*5e7646d2SAndroid Build Coastguard Worker }
1116*5e7646d2SAndroid Build Coastguard Worker
1117*5e7646d2SAndroid Build Coastguard Worker if (pwg_media)
1118*5e7646d2SAndroid Build Coastguard Worker {
1119*5e7646d2SAndroid Build Coastguard Worker /*
1120*5e7646d2SAndroid Build Coastguard Worker * Standard name and no conflicts, use it!
1121*5e7646d2SAndroid Build Coastguard Worker */
1122*5e7646d2SAndroid Build Coastguard Worker
1123*5e7646d2SAndroid Build Coastguard Worker pwg_name = pwg_media->pwg;
1124*5e7646d2SAndroid Build Coastguard Worker new_known_pwg = 1;
1125*5e7646d2SAndroid Build Coastguard Worker }
1126*5e7646d2SAndroid Build Coastguard Worker else
1127*5e7646d2SAndroid Build Coastguard Worker {
1128*5e7646d2SAndroid Build Coastguard Worker /*
1129*5e7646d2SAndroid Build Coastguard Worker * Not a standard name; convert it to a PWG vendor name of the form:
1130*5e7646d2SAndroid Build Coastguard Worker *
1131*5e7646d2SAndroid Build Coastguard Worker * pp_lowerppd_WIDTHxHEIGHTuu
1132*5e7646d2SAndroid Build Coastguard Worker */
1133*5e7646d2SAndroid Build Coastguard Worker
1134*5e7646d2SAndroid Build Coastguard Worker pwg_name = pwg_keyword;
1135*5e7646d2SAndroid Build Coastguard Worker new_known_pwg = 0;
1136*5e7646d2SAndroid Build Coastguard Worker
1137*5e7646d2SAndroid Build Coastguard Worker pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name), "_.");
1138*5e7646d2SAndroid Build Coastguard Worker pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name,
1139*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd_size->width),
1140*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd_size->length), NULL);
1141*5e7646d2SAndroid Build Coastguard Worker }
1142*5e7646d2SAndroid Build Coastguard Worker
1143*5e7646d2SAndroid Build Coastguard Worker /*
1144*5e7646d2SAndroid Build Coastguard Worker * If we have a similar paper with non-zero margins then we only want to
1145*5e7646d2SAndroid Build Coastguard Worker * keep it if it has a larger imageable area length. The NULL check is for
1146*5e7646d2SAndroid Build Coastguard Worker * dimensions that are <= 0...
1147*5e7646d2SAndroid Build Coastguard Worker */
1148*5e7646d2SAndroid Build Coastguard Worker
1149*5e7646d2SAndroid Build Coastguard Worker if ((pwg_media = _pwgMediaNearSize(PWG_FROM_POINTS(ppd_size->width),
1150*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd_size->length),
1151*5e7646d2SAndroid Build Coastguard Worker 0)) == NULL)
1152*5e7646d2SAndroid Build Coastguard Worker continue;
1153*5e7646d2SAndroid Build Coastguard Worker
1154*5e7646d2SAndroid Build Coastguard Worker new_width = pwg_media->width;
1155*5e7646d2SAndroid Build Coastguard Worker new_length = pwg_media->length;
1156*5e7646d2SAndroid Build Coastguard Worker new_left = PWG_FROM_POINTS(ppd_size->left);
1157*5e7646d2SAndroid Build Coastguard Worker new_bottom = PWG_FROM_POINTS(ppd_size->bottom);
1158*5e7646d2SAndroid Build Coastguard Worker new_right = PWG_FROM_POINTS(ppd_size->width - ppd_size->right);
1159*5e7646d2SAndroid Build Coastguard Worker new_top = PWG_FROM_POINTS(ppd_size->length - ppd_size->top);
1160*5e7646d2SAndroid Build Coastguard Worker new_imageable = new_length - new_top - new_bottom;
1161*5e7646d2SAndroid Build Coastguard Worker new_borderless = new_bottom == 0 && new_top == 0 &&
1162*5e7646d2SAndroid Build Coastguard Worker new_left == 0 && new_right == 0;
1163*5e7646d2SAndroid Build Coastguard Worker
1164*5e7646d2SAndroid Build Coastguard Worker for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
1165*5e7646d2SAndroid Build Coastguard Worker k > 0 && !similar;
1166*5e7646d2SAndroid Build Coastguard Worker k --, old_size ++)
1167*5e7646d2SAndroid Build Coastguard Worker {
1168*5e7646d2SAndroid Build Coastguard Worker old_imageable = old_size->length - old_size->top - old_size->bottom;
1169*5e7646d2SAndroid Build Coastguard Worker old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
1170*5e7646d2SAndroid Build Coastguard Worker old_size->right == 0 && old_size->top == 0;
1171*5e7646d2SAndroid Build Coastguard Worker old_known_pwg = strncmp(old_size->map.pwg, "oe_", 3) &&
1172*5e7646d2SAndroid Build Coastguard Worker strncmp(old_size->map.pwg, "om_", 3);
1173*5e7646d2SAndroid Build Coastguard Worker
1174*5e7646d2SAndroid Build Coastguard Worker similar = old_borderless == new_borderless &&
1175*5e7646d2SAndroid Build Coastguard Worker _PWG_EQUIVALENT(old_size->width, new_width) &&
1176*5e7646d2SAndroid Build Coastguard Worker _PWG_EQUIVALENT(old_size->length, new_length);
1177*5e7646d2SAndroid Build Coastguard Worker
1178*5e7646d2SAndroid Build Coastguard Worker if (similar &&
1179*5e7646d2SAndroid Build Coastguard Worker (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable)))
1180*5e7646d2SAndroid Build Coastguard Worker {
1181*5e7646d2SAndroid Build Coastguard Worker /*
1182*5e7646d2SAndroid Build Coastguard Worker * The new paper has a larger imageable area so it could replace
1183*5e7646d2SAndroid Build Coastguard Worker * the older paper. Regardless of the imageable area, we always
1184*5e7646d2SAndroid Build Coastguard Worker * prefer the size with a well-known PWG name.
1185*5e7646d2SAndroid Build Coastguard Worker */
1186*5e7646d2SAndroid Build Coastguard Worker
1187*5e7646d2SAndroid Build Coastguard Worker new_size = old_size;
1188*5e7646d2SAndroid Build Coastguard Worker free(old_size->map.ppd);
1189*5e7646d2SAndroid Build Coastguard Worker free(old_size->map.pwg);
1190*5e7646d2SAndroid Build Coastguard Worker }
1191*5e7646d2SAndroid Build Coastguard Worker }
1192*5e7646d2SAndroid Build Coastguard Worker
1193*5e7646d2SAndroid Build Coastguard Worker if (!similar)
1194*5e7646d2SAndroid Build Coastguard Worker {
1195*5e7646d2SAndroid Build Coastguard Worker /*
1196*5e7646d2SAndroid Build Coastguard Worker * The paper was unique enough to deserve its own entry so add it to the
1197*5e7646d2SAndroid Build Coastguard Worker * end.
1198*5e7646d2SAndroid Build Coastguard Worker */
1199*5e7646d2SAndroid Build Coastguard Worker
1200*5e7646d2SAndroid Build Coastguard Worker new_size = pwg_size ++;
1201*5e7646d2SAndroid Build Coastguard Worker pc->num_sizes ++;
1202*5e7646d2SAndroid Build Coastguard Worker }
1203*5e7646d2SAndroid Build Coastguard Worker
1204*5e7646d2SAndroid Build Coastguard Worker if (new_size)
1205*5e7646d2SAndroid Build Coastguard Worker {
1206*5e7646d2SAndroid Build Coastguard Worker /*
1207*5e7646d2SAndroid Build Coastguard Worker * Save this size...
1208*5e7646d2SAndroid Build Coastguard Worker */
1209*5e7646d2SAndroid Build Coastguard Worker
1210*5e7646d2SAndroid Build Coastguard Worker new_size->map.ppd = strdup(ppd_size->name);
1211*5e7646d2SAndroid Build Coastguard Worker new_size->map.pwg = strdup(pwg_name);
1212*5e7646d2SAndroid Build Coastguard Worker new_size->width = new_width;
1213*5e7646d2SAndroid Build Coastguard Worker new_size->length = new_length;
1214*5e7646d2SAndroid Build Coastguard Worker new_size->left = new_left;
1215*5e7646d2SAndroid Build Coastguard Worker new_size->bottom = new_bottom;
1216*5e7646d2SAndroid Build Coastguard Worker new_size->right = new_right;
1217*5e7646d2SAndroid Build Coastguard Worker new_size->top = new_top;
1218*5e7646d2SAndroid Build Coastguard Worker }
1219*5e7646d2SAndroid Build Coastguard Worker }
1220*5e7646d2SAndroid Build Coastguard Worker }
1221*5e7646d2SAndroid Build Coastguard Worker
1222*5e7646d2SAndroid Build Coastguard Worker if (ppd->variable_sizes)
1223*5e7646d2SAndroid Build Coastguard Worker {
1224*5e7646d2SAndroid Build Coastguard Worker /*
1225*5e7646d2SAndroid Build Coastguard Worker * Generate custom size data...
1226*5e7646d2SAndroid Build Coastguard Worker */
1227*5e7646d2SAndroid Build Coastguard Worker
1228*5e7646d2SAndroid Build Coastguard Worker pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
1229*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd->custom_max[0]),
1230*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd->custom_max[1]), NULL);
1231*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_keyword = strdup(pwg_keyword);
1232*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_width = PWG_FROM_POINTS(ppd->custom_max[0]);
1233*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_length = PWG_FROM_POINTS(ppd->custom_max[1]);
1234*5e7646d2SAndroid Build Coastguard Worker
1235*5e7646d2SAndroid Build Coastguard Worker pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
1236*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd->custom_min[0]),
1237*5e7646d2SAndroid Build Coastguard Worker PWG_FROM_POINTS(ppd->custom_min[1]), NULL);
1238*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_keyword = strdup(pwg_keyword);
1239*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_width = PWG_FROM_POINTS(ppd->custom_min[0]);
1240*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_length = PWG_FROM_POINTS(ppd->custom_min[1]);
1241*5e7646d2SAndroid Build Coastguard Worker
1242*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.left = PWG_FROM_POINTS(ppd->custom_margins[0]);
1243*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.bottom = PWG_FROM_POINTS(ppd->custom_margins[1]);
1244*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.right = PWG_FROM_POINTS(ppd->custom_margins[2]);
1245*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.top = PWG_FROM_POINTS(ppd->custom_margins[3]);
1246*5e7646d2SAndroid Build Coastguard Worker }
1247*5e7646d2SAndroid Build Coastguard Worker
1248*5e7646d2SAndroid Build Coastguard Worker /*
1249*5e7646d2SAndroid Build Coastguard Worker * Copy and convert InputSlot data...
1250*5e7646d2SAndroid Build Coastguard Worker */
1251*5e7646d2SAndroid Build Coastguard Worker
1252*5e7646d2SAndroid Build Coastguard Worker if ((input_slot = ppdFindOption(ppd, "InputSlot")) == NULL)
1253*5e7646d2SAndroid Build Coastguard Worker input_slot = ppdFindOption(ppd, "HPPaperSource");
1254*5e7646d2SAndroid Build Coastguard Worker
1255*5e7646d2SAndroid Build Coastguard Worker if (input_slot)
1256*5e7646d2SAndroid Build Coastguard Worker {
1257*5e7646d2SAndroid Build Coastguard Worker pc->source_option = strdup(input_slot->keyword);
1258*5e7646d2SAndroid Build Coastguard Worker
1259*5e7646d2SAndroid Build Coastguard Worker if ((pc->sources = calloc((size_t)input_slot->num_choices, sizeof(pwg_map_t))) == NULL)
1260*5e7646d2SAndroid Build Coastguard Worker {
1261*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
1262*5e7646d2SAndroid Build Coastguard Worker "pwg_map_t's for InputSlot.", input_slot->num_choices));
1263*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1264*5e7646d2SAndroid Build Coastguard Worker }
1265*5e7646d2SAndroid Build Coastguard Worker
1266*5e7646d2SAndroid Build Coastguard Worker pc->num_sources = input_slot->num_choices;
1267*5e7646d2SAndroid Build Coastguard Worker
1268*5e7646d2SAndroid Build Coastguard Worker for (i = input_slot->num_choices, choice = input_slot->choices,
1269*5e7646d2SAndroid Build Coastguard Worker map = pc->sources;
1270*5e7646d2SAndroid Build Coastguard Worker i > 0;
1271*5e7646d2SAndroid Build Coastguard Worker i --, choice ++, map ++)
1272*5e7646d2SAndroid Build Coastguard Worker {
1273*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(choice->choice, "Auto", 4) ||
1274*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "Default"))
1275*5e7646d2SAndroid Build Coastguard Worker pwg_name = "auto";
1276*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Cassette"))
1277*5e7646d2SAndroid Build Coastguard Worker pwg_name = "main";
1278*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "PhotoTray"))
1279*5e7646d2SAndroid Build Coastguard Worker pwg_name = "photo";
1280*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "CDTray"))
1281*5e7646d2SAndroid Build Coastguard Worker pwg_name = "disc";
1282*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Multipurpose", 12) ||
1283*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "MP") ||
1284*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "MPTray"))
1285*5e7646d2SAndroid Build Coastguard Worker pwg_name = "by-pass-tray";
1286*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "LargeCapacity"))
1287*5e7646d2SAndroid Build Coastguard Worker pwg_name = "large-capacity";
1288*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Lower", 5))
1289*5e7646d2SAndroid Build Coastguard Worker pwg_name = "bottom";
1290*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Middle", 6))
1291*5e7646d2SAndroid Build Coastguard Worker pwg_name = "middle";
1292*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Upper", 5))
1293*5e7646d2SAndroid Build Coastguard Worker pwg_name = "top";
1294*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Side", 4))
1295*5e7646d2SAndroid Build Coastguard Worker pwg_name = "side";
1296*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Roll"))
1297*5e7646d2SAndroid Build Coastguard Worker pwg_name = "main-roll";
1298*5e7646d2SAndroid Build Coastguard Worker else
1299*5e7646d2SAndroid Build Coastguard Worker {
1300*5e7646d2SAndroid Build Coastguard Worker /*
1301*5e7646d2SAndroid Build Coastguard Worker * Convert PPD name to lowercase...
1302*5e7646d2SAndroid Build Coastguard Worker */
1303*5e7646d2SAndroid Build Coastguard Worker
1304*5e7646d2SAndroid Build Coastguard Worker pwg_name = pwg_keyword;
1305*5e7646d2SAndroid Build Coastguard Worker pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword),
1306*5e7646d2SAndroid Build Coastguard Worker "_");
1307*5e7646d2SAndroid Build Coastguard Worker }
1308*5e7646d2SAndroid Build Coastguard Worker
1309*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_name);
1310*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(choice->choice);
1311*5e7646d2SAndroid Build Coastguard Worker
1312*5e7646d2SAndroid Build Coastguard Worker /*
1313*5e7646d2SAndroid Build Coastguard Worker * Add localized text for PWG keyword to message catalog...
1314*5e7646d2SAndroid Build Coastguard Worker */
1315*5e7646d2SAndroid Build Coastguard Worker
1316*5e7646d2SAndroid Build Coastguard Worker snprintf(msg_id, sizeof(msg_id), "media-source.%s", pwg_name);
1317*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(pc->strings, msg_id, choice->text);
1318*5e7646d2SAndroid Build Coastguard Worker }
1319*5e7646d2SAndroid Build Coastguard Worker }
1320*5e7646d2SAndroid Build Coastguard Worker
1321*5e7646d2SAndroid Build Coastguard Worker /*
1322*5e7646d2SAndroid Build Coastguard Worker * Copy and convert MediaType data...
1323*5e7646d2SAndroid Build Coastguard Worker */
1324*5e7646d2SAndroid Build Coastguard Worker
1325*5e7646d2SAndroid Build Coastguard Worker if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
1326*5e7646d2SAndroid Build Coastguard Worker {
1327*5e7646d2SAndroid Build Coastguard Worker if ((pc->types = calloc((size_t)media_type->num_choices, sizeof(pwg_map_t))) == NULL)
1328*5e7646d2SAndroid Build Coastguard Worker {
1329*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
1330*5e7646d2SAndroid Build Coastguard Worker "pwg_map_t's for MediaType.", media_type->num_choices));
1331*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1332*5e7646d2SAndroid Build Coastguard Worker }
1333*5e7646d2SAndroid Build Coastguard Worker
1334*5e7646d2SAndroid Build Coastguard Worker pc->num_types = media_type->num_choices;
1335*5e7646d2SAndroid Build Coastguard Worker
1336*5e7646d2SAndroid Build Coastguard Worker for (i = media_type->num_choices, choice = media_type->choices,
1337*5e7646d2SAndroid Build Coastguard Worker map = pc->types;
1338*5e7646d2SAndroid Build Coastguard Worker i > 0;
1339*5e7646d2SAndroid Build Coastguard Worker i --, choice ++, map ++)
1340*5e7646d2SAndroid Build Coastguard Worker {
1341*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(choice->choice, "Auto", 4) ||
1342*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "Any") ||
1343*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "Default"))
1344*5e7646d2SAndroid Build Coastguard Worker pwg_name = "auto";
1345*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Card", 4))
1346*5e7646d2SAndroid Build Coastguard Worker pwg_name = "cardstock";
1347*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Env", 3))
1348*5e7646d2SAndroid Build Coastguard Worker pwg_name = "envelope";
1349*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Gloss", 5))
1350*5e7646d2SAndroid Build Coastguard Worker pwg_name = "photographic-glossy";
1351*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "HighGloss"))
1352*5e7646d2SAndroid Build Coastguard Worker pwg_name = "photographic-high-gloss";
1353*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Matte"))
1354*5e7646d2SAndroid Build Coastguard Worker pwg_name = "photographic-matte";
1355*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Plain", 5))
1356*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery";
1357*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Coated", 6))
1358*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery-coated";
1359*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Inkjet"))
1360*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery-inkjet";
1361*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Letterhead"))
1362*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery-letterhead";
1363*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Preprint", 8))
1364*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery-preprinted";
1365*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choice->choice, "Recycled"))
1366*5e7646d2SAndroid Build Coastguard Worker pwg_name = "stationery-recycled";
1367*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(choice->choice, "Transparen", 10))
1368*5e7646d2SAndroid Build Coastguard Worker pwg_name = "transparency";
1369*5e7646d2SAndroid Build Coastguard Worker else
1370*5e7646d2SAndroid Build Coastguard Worker {
1371*5e7646d2SAndroid Build Coastguard Worker /*
1372*5e7646d2SAndroid Build Coastguard Worker * Convert PPD name to lowercase...
1373*5e7646d2SAndroid Build Coastguard Worker */
1374*5e7646d2SAndroid Build Coastguard Worker
1375*5e7646d2SAndroid Build Coastguard Worker pwg_name = pwg_keyword;
1376*5e7646d2SAndroid Build Coastguard Worker pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword),
1377*5e7646d2SAndroid Build Coastguard Worker "_");
1378*5e7646d2SAndroid Build Coastguard Worker }
1379*5e7646d2SAndroid Build Coastguard Worker
1380*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_name);
1381*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(choice->choice);
1382*5e7646d2SAndroid Build Coastguard Worker
1383*5e7646d2SAndroid Build Coastguard Worker /*
1384*5e7646d2SAndroid Build Coastguard Worker * Add localized text for PWG keyword to message catalog...
1385*5e7646d2SAndroid Build Coastguard Worker */
1386*5e7646d2SAndroid Build Coastguard Worker
1387*5e7646d2SAndroid Build Coastguard Worker snprintf(msg_id, sizeof(msg_id), "media-type.%s", pwg_name);
1388*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(pc->strings, msg_id, choice->text);
1389*5e7646d2SAndroid Build Coastguard Worker }
1390*5e7646d2SAndroid Build Coastguard Worker }
1391*5e7646d2SAndroid Build Coastguard Worker
1392*5e7646d2SAndroid Build Coastguard Worker /*
1393*5e7646d2SAndroid Build Coastguard Worker * Copy and convert OutputBin data...
1394*5e7646d2SAndroid Build Coastguard Worker */
1395*5e7646d2SAndroid Build Coastguard Worker
1396*5e7646d2SAndroid Build Coastguard Worker if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
1397*5e7646d2SAndroid Build Coastguard Worker {
1398*5e7646d2SAndroid Build Coastguard Worker if ((pc->bins = calloc((size_t)output_bin->num_choices, sizeof(pwg_map_t))) == NULL)
1399*5e7646d2SAndroid Build Coastguard Worker {
1400*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
1401*5e7646d2SAndroid Build Coastguard Worker "pwg_map_t's for OutputBin.", output_bin->num_choices));
1402*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1403*5e7646d2SAndroid Build Coastguard Worker }
1404*5e7646d2SAndroid Build Coastguard Worker
1405*5e7646d2SAndroid Build Coastguard Worker pc->num_bins = output_bin->num_choices;
1406*5e7646d2SAndroid Build Coastguard Worker
1407*5e7646d2SAndroid Build Coastguard Worker for (i = output_bin->num_choices, choice = output_bin->choices,
1408*5e7646d2SAndroid Build Coastguard Worker map = pc->bins;
1409*5e7646d2SAndroid Build Coastguard Worker i > 0;
1410*5e7646d2SAndroid Build Coastguard Worker i --, choice ++, map ++)
1411*5e7646d2SAndroid Build Coastguard Worker {
1412*5e7646d2SAndroid Build Coastguard Worker pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword), "_");
1413*5e7646d2SAndroid Build Coastguard Worker
1414*5e7646d2SAndroid Build Coastguard Worker map->pwg = strdup(pwg_keyword);
1415*5e7646d2SAndroid Build Coastguard Worker map->ppd = strdup(choice->choice);
1416*5e7646d2SAndroid Build Coastguard Worker
1417*5e7646d2SAndroid Build Coastguard Worker /*
1418*5e7646d2SAndroid Build Coastguard Worker * Add localized text for PWG keyword to message catalog...
1419*5e7646d2SAndroid Build Coastguard Worker */
1420*5e7646d2SAndroid Build Coastguard Worker
1421*5e7646d2SAndroid Build Coastguard Worker snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_keyword);
1422*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(pc->strings, msg_id, choice->text);
1423*5e7646d2SAndroid Build Coastguard Worker }
1424*5e7646d2SAndroid Build Coastguard Worker }
1425*5e7646d2SAndroid Build Coastguard Worker
1426*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL)
1427*5e7646d2SAndroid Build Coastguard Worker {
1428*5e7646d2SAndroid Build Coastguard Worker /*
1429*5e7646d2SAndroid Build Coastguard Worker * Copy and convert APPrinterPreset (output-mode + print-quality) data...
1430*5e7646d2SAndroid Build Coastguard Worker */
1431*5e7646d2SAndroid Build Coastguard Worker
1432*5e7646d2SAndroid Build Coastguard Worker const char *quality, /* com.apple.print.preset.quality value */
1433*5e7646d2SAndroid Build Coastguard Worker *output_mode, /* com.apple.print.preset.output-mode value */
1434*5e7646d2SAndroid Build Coastguard Worker *color_model_val, /* ColorModel choice */
1435*5e7646d2SAndroid Build Coastguard Worker *graphicsType, /* com.apple.print.preset.graphicsType value */
1436*5e7646d2SAndroid Build Coastguard Worker *media_front_coating; /* com.apple.print.preset.media-front-coating value */
1437*5e7646d2SAndroid Build Coastguard Worker
1438*5e7646d2SAndroid Build Coastguard Worker do
1439*5e7646d2SAndroid Build Coastguard Worker {
1440*5e7646d2SAndroid Build Coastguard Worker /*
1441*5e7646d2SAndroid Build Coastguard Worker * Add localized text for PWG keyword to message catalog...
1442*5e7646d2SAndroid Build Coastguard Worker */
1443*5e7646d2SAndroid Build Coastguard Worker
1444*5e7646d2SAndroid Build Coastguard Worker snprintf(msg_id, sizeof(msg_id), "preset-name.%s", ppd_attr->spec);
1445*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(pc->strings, msg_id, ppd_attr->text);
1446*5e7646d2SAndroid Build Coastguard Worker
1447*5e7646d2SAndroid Build Coastguard Worker /*
1448*5e7646d2SAndroid Build Coastguard Worker * Get the options for this preset...
1449*5e7646d2SAndroid Build Coastguard Worker */
1450*5e7646d2SAndroid Build Coastguard Worker
1451*5e7646d2SAndroid Build Coastguard Worker num_options = _ppdParseOptions(ppd_attr->value, 0, &options,
1452*5e7646d2SAndroid Build Coastguard Worker _PPD_PARSE_ALL);
1453*5e7646d2SAndroid Build Coastguard Worker
1454*5e7646d2SAndroid Build Coastguard Worker if ((quality = cupsGetOption("com.apple.print.preset.quality",
1455*5e7646d2SAndroid Build Coastguard Worker num_options, options)) != NULL)
1456*5e7646d2SAndroid Build Coastguard Worker {
1457*5e7646d2SAndroid Build Coastguard Worker /*
1458*5e7646d2SAndroid Build Coastguard Worker * Get the print-quality for this preset...
1459*5e7646d2SAndroid Build Coastguard Worker */
1460*5e7646d2SAndroid Build Coastguard Worker
1461*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(quality, "low"))
1462*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
1463*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(quality, "high"))
1464*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality = _PWG_PRINT_QUALITY_HIGH;
1465*5e7646d2SAndroid Build Coastguard Worker else
1466*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality = _PWG_PRINT_QUALITY_NORMAL;
1467*5e7646d2SAndroid Build Coastguard Worker
1468*5e7646d2SAndroid Build Coastguard Worker /*
1469*5e7646d2SAndroid Build Coastguard Worker * Ignore graphicsType "Photo" presets that are not high quality.
1470*5e7646d2SAndroid Build Coastguard Worker */
1471*5e7646d2SAndroid Build Coastguard Worker
1472*5e7646d2SAndroid Build Coastguard Worker graphicsType = cupsGetOption("com.apple.print.preset.graphicsType",
1473*5e7646d2SAndroid Build Coastguard Worker num_options, options);
1474*5e7646d2SAndroid Build Coastguard Worker
1475*5e7646d2SAndroid Build Coastguard Worker if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH && graphicsType &&
1476*5e7646d2SAndroid Build Coastguard Worker !strcmp(graphicsType, "Photo"))
1477*5e7646d2SAndroid Build Coastguard Worker continue;
1478*5e7646d2SAndroid Build Coastguard Worker
1479*5e7646d2SAndroid Build Coastguard Worker /*
1480*5e7646d2SAndroid Build Coastguard Worker * Ignore presets for normal and draft quality where the coating
1481*5e7646d2SAndroid Build Coastguard Worker * isn't "none" or "autodetect".
1482*5e7646d2SAndroid Build Coastguard Worker */
1483*5e7646d2SAndroid Build Coastguard Worker
1484*5e7646d2SAndroid Build Coastguard Worker media_front_coating = cupsGetOption(
1485*5e7646d2SAndroid Build Coastguard Worker "com.apple.print.preset.media-front-coating",
1486*5e7646d2SAndroid Build Coastguard Worker num_options, options);
1487*5e7646d2SAndroid Build Coastguard Worker
1488*5e7646d2SAndroid Build Coastguard Worker if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH &&
1489*5e7646d2SAndroid Build Coastguard Worker media_front_coating &&
1490*5e7646d2SAndroid Build Coastguard Worker strcmp(media_front_coating, "none") &&
1491*5e7646d2SAndroid Build Coastguard Worker strcmp(media_front_coating, "autodetect"))
1492*5e7646d2SAndroid Build Coastguard Worker continue;
1493*5e7646d2SAndroid Build Coastguard Worker
1494*5e7646d2SAndroid Build Coastguard Worker /*
1495*5e7646d2SAndroid Build Coastguard Worker * Get the output mode for this preset...
1496*5e7646d2SAndroid Build Coastguard Worker */
1497*5e7646d2SAndroid Build Coastguard Worker
1498*5e7646d2SAndroid Build Coastguard Worker output_mode = cupsGetOption("com.apple.print.preset.output-mode",
1499*5e7646d2SAndroid Build Coastguard Worker num_options, options);
1500*5e7646d2SAndroid Build Coastguard Worker color_model_val = cupsGetOption("ColorModel", num_options, options);
1501*5e7646d2SAndroid Build Coastguard Worker
1502*5e7646d2SAndroid Build Coastguard Worker if (output_mode)
1503*5e7646d2SAndroid Build Coastguard Worker {
1504*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(output_mode, "monochrome"))
1505*5e7646d2SAndroid Build Coastguard Worker pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
1506*5e7646d2SAndroid Build Coastguard Worker else
1507*5e7646d2SAndroid Build Coastguard Worker pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
1508*5e7646d2SAndroid Build Coastguard Worker }
1509*5e7646d2SAndroid Build Coastguard Worker else if (color_model_val)
1510*5e7646d2SAndroid Build Coastguard Worker {
1511*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(color_model_val, "Gray"))
1512*5e7646d2SAndroid Build Coastguard Worker pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
1513*5e7646d2SAndroid Build Coastguard Worker else
1514*5e7646d2SAndroid Build Coastguard Worker pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
1515*5e7646d2SAndroid Build Coastguard Worker }
1516*5e7646d2SAndroid Build Coastguard Worker else
1517*5e7646d2SAndroid Build Coastguard Worker pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
1518*5e7646d2SAndroid Build Coastguard Worker
1519*5e7646d2SAndroid Build Coastguard Worker /*
1520*5e7646d2SAndroid Build Coastguard Worker * Save the options for this combination as needed...
1521*5e7646d2SAndroid Build Coastguard Worker */
1522*5e7646d2SAndroid Build Coastguard Worker
1523*5e7646d2SAndroid Build Coastguard Worker if (!pc->num_presets[pwg_print_color_mode][pwg_print_quality])
1524*5e7646d2SAndroid Build Coastguard Worker pc->num_presets[pwg_print_color_mode][pwg_print_quality] =
1525*5e7646d2SAndroid Build Coastguard Worker _ppdParseOptions(ppd_attr->value, 0,
1526*5e7646d2SAndroid Build Coastguard Worker pc->presets[pwg_print_color_mode] +
1527*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality, _PPD_PARSE_OPTIONS);
1528*5e7646d2SAndroid Build Coastguard Worker }
1529*5e7646d2SAndroid Build Coastguard Worker
1530*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_options, options);
1531*5e7646d2SAndroid Build Coastguard Worker }
1532*5e7646d2SAndroid Build Coastguard Worker while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) != NULL);
1533*5e7646d2SAndroid Build Coastguard Worker }
1534*5e7646d2SAndroid Build Coastguard Worker
1535*5e7646d2SAndroid Build Coastguard Worker if (!pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
1536*5e7646d2SAndroid Build Coastguard Worker !pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
1537*5e7646d2SAndroid Build Coastguard Worker !pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH])
1538*5e7646d2SAndroid Build Coastguard Worker {
1539*5e7646d2SAndroid Build Coastguard Worker /*
1540*5e7646d2SAndroid Build Coastguard Worker * Try adding some common color options to create grayscale presets. These
1541*5e7646d2SAndroid Build Coastguard Worker * are listed in order of popularity...
1542*5e7646d2SAndroid Build Coastguard Worker */
1543*5e7646d2SAndroid Build Coastguard Worker
1544*5e7646d2SAndroid Build Coastguard Worker const char *color_option = NULL, /* Color control option */
1545*5e7646d2SAndroid Build Coastguard Worker *gray_choice = NULL; /* Choice to select grayscale */
1546*5e7646d2SAndroid Build Coastguard Worker
1547*5e7646d2SAndroid Build Coastguard Worker if ((color_model = ppdFindOption(ppd, "ColorModel")) != NULL &&
1548*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(color_model, "Gray"))
1549*5e7646d2SAndroid Build Coastguard Worker {
1550*5e7646d2SAndroid Build Coastguard Worker color_option = "ColorModel";
1551*5e7646d2SAndroid Build Coastguard Worker gray_choice = "Gray";
1552*5e7646d2SAndroid Build Coastguard Worker }
1553*5e7646d2SAndroid Build Coastguard Worker else if ((color_model = ppdFindOption(ppd, "HPColorMode")) != NULL &&
1554*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(color_model, "grayscale"))
1555*5e7646d2SAndroid Build Coastguard Worker {
1556*5e7646d2SAndroid Build Coastguard Worker color_option = "HPColorMode";
1557*5e7646d2SAndroid Build Coastguard Worker gray_choice = "grayscale";
1558*5e7646d2SAndroid Build Coastguard Worker }
1559*5e7646d2SAndroid Build Coastguard Worker else if ((color_model = ppdFindOption(ppd, "BRMonoColor")) != NULL &&
1560*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(color_model, "Mono"))
1561*5e7646d2SAndroid Build Coastguard Worker {
1562*5e7646d2SAndroid Build Coastguard Worker color_option = "BRMonoColor";
1563*5e7646d2SAndroid Build Coastguard Worker gray_choice = "Mono";
1564*5e7646d2SAndroid Build Coastguard Worker }
1565*5e7646d2SAndroid Build Coastguard Worker else if ((color_model = ppdFindOption(ppd, "CNIJSGrayScale")) != NULL &&
1566*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(color_model, "1"))
1567*5e7646d2SAndroid Build Coastguard Worker {
1568*5e7646d2SAndroid Build Coastguard Worker color_option = "CNIJSGrayScale";
1569*5e7646d2SAndroid Build Coastguard Worker gray_choice = "1";
1570*5e7646d2SAndroid Build Coastguard Worker }
1571*5e7646d2SAndroid Build Coastguard Worker else if ((color_model = ppdFindOption(ppd, "HPColorAsGray")) != NULL &&
1572*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(color_model, "True"))
1573*5e7646d2SAndroid Build Coastguard Worker {
1574*5e7646d2SAndroid Build Coastguard Worker color_option = "HPColorAsGray";
1575*5e7646d2SAndroid Build Coastguard Worker gray_choice = "True";
1576*5e7646d2SAndroid Build Coastguard Worker }
1577*5e7646d2SAndroid Build Coastguard Worker
1578*5e7646d2SAndroid Build Coastguard Worker if (color_option && gray_choice)
1579*5e7646d2SAndroid Build Coastguard Worker {
1580*5e7646d2SAndroid Build Coastguard Worker /*
1581*5e7646d2SAndroid Build Coastguard Worker * Copy and convert ColorModel (output-mode) data...
1582*5e7646d2SAndroid Build Coastguard Worker */
1583*5e7646d2SAndroid Build Coastguard Worker
1584*5e7646d2SAndroid Build Coastguard Worker cups_option_t *coption, /* Color option */
1585*5e7646d2SAndroid Build Coastguard Worker *moption; /* Monochrome option */
1586*5e7646d2SAndroid Build Coastguard Worker
1587*5e7646d2SAndroid Build Coastguard Worker for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
1588*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
1589*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality ++)
1590*5e7646d2SAndroid Build Coastguard Worker {
1591*5e7646d2SAndroid Build Coastguard Worker if (pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][pwg_print_quality])
1592*5e7646d2SAndroid Build Coastguard Worker {
1593*5e7646d2SAndroid Build Coastguard Worker /*
1594*5e7646d2SAndroid Build Coastguard Worker * Copy the color options...
1595*5e7646d2SAndroid Build Coastguard Worker */
1596*5e7646d2SAndroid Build Coastguard Worker
1597*5e7646d2SAndroid Build Coastguard Worker num_options = pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR]
1598*5e7646d2SAndroid Build Coastguard Worker [pwg_print_quality];
1599*5e7646d2SAndroid Build Coastguard Worker options = calloc(sizeof(cups_option_t), (size_t)num_options);
1600*5e7646d2SAndroid Build Coastguard Worker
1601*5e7646d2SAndroid Build Coastguard Worker if (options)
1602*5e7646d2SAndroid Build Coastguard Worker {
1603*5e7646d2SAndroid Build Coastguard Worker for (i = num_options, moption = options,
1604*5e7646d2SAndroid Build Coastguard Worker coption = pc->presets[_PWG_PRINT_COLOR_MODE_COLOR]
1605*5e7646d2SAndroid Build Coastguard Worker [pwg_print_quality];
1606*5e7646d2SAndroid Build Coastguard Worker i > 0;
1607*5e7646d2SAndroid Build Coastguard Worker i --, moption ++, coption ++)
1608*5e7646d2SAndroid Build Coastguard Worker {
1609*5e7646d2SAndroid Build Coastguard Worker moption->name = _cupsStrRetain(coption->name);
1610*5e7646d2SAndroid Build Coastguard Worker moption->value = _cupsStrRetain(coption->value);
1611*5e7646d2SAndroid Build Coastguard Worker }
1612*5e7646d2SAndroid Build Coastguard Worker
1613*5e7646d2SAndroid Build Coastguard Worker pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
1614*5e7646d2SAndroid Build Coastguard Worker num_options;
1615*5e7646d2SAndroid Build Coastguard Worker pc->presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
1616*5e7646d2SAndroid Build Coastguard Worker options;
1617*5e7646d2SAndroid Build Coastguard Worker }
1618*5e7646d2SAndroid Build Coastguard Worker }
1619*5e7646d2SAndroid Build Coastguard Worker else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL)
1620*5e7646d2SAndroid Build Coastguard Worker continue;
1621*5e7646d2SAndroid Build Coastguard Worker
1622*5e7646d2SAndroid Build Coastguard Worker /*
1623*5e7646d2SAndroid Build Coastguard Worker * Add the grayscale option to the preset...
1624*5e7646d2SAndroid Build Coastguard Worker */
1625*5e7646d2SAndroid Build Coastguard Worker
1626*5e7646d2SAndroid Build Coastguard Worker pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
1627*5e7646d2SAndroid Build Coastguard Worker cupsAddOption(color_option, gray_choice,
1628*5e7646d2SAndroid Build Coastguard Worker pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME]
1629*5e7646d2SAndroid Build Coastguard Worker [pwg_print_quality],
1630*5e7646d2SAndroid Build Coastguard Worker pc->presets[_PWG_PRINT_COLOR_MODE_MONOCHROME] +
1631*5e7646d2SAndroid Build Coastguard Worker pwg_print_quality);
1632*5e7646d2SAndroid Build Coastguard Worker }
1633*5e7646d2SAndroid Build Coastguard Worker }
1634*5e7646d2SAndroid Build Coastguard Worker }
1635*5e7646d2SAndroid Build Coastguard Worker
1636*5e7646d2SAndroid Build Coastguard Worker /*
1637*5e7646d2SAndroid Build Coastguard Worker * Copy and convert Duplex (sides) data...
1638*5e7646d2SAndroid Build Coastguard Worker */
1639*5e7646d2SAndroid Build Coastguard Worker
1640*5e7646d2SAndroid Build Coastguard Worker if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL)
1641*5e7646d2SAndroid Build Coastguard Worker if ((duplex = ppdFindOption(ppd, "JCLDuplex")) == NULL)
1642*5e7646d2SAndroid Build Coastguard Worker if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL)
1643*5e7646d2SAndroid Build Coastguard Worker if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL)
1644*5e7646d2SAndroid Build Coastguard Worker duplex = ppdFindOption(ppd, "KD03Duplex");
1645*5e7646d2SAndroid Build Coastguard Worker
1646*5e7646d2SAndroid Build Coastguard Worker if (duplex)
1647*5e7646d2SAndroid Build Coastguard Worker {
1648*5e7646d2SAndroid Build Coastguard Worker pc->sides_option = strdup(duplex->keyword);
1649*5e7646d2SAndroid Build Coastguard Worker
1650*5e7646d2SAndroid Build Coastguard Worker for (i = duplex->num_choices, choice = duplex->choices;
1651*5e7646d2SAndroid Build Coastguard Worker i > 0;
1652*5e7646d2SAndroid Build Coastguard Worker i --, choice ++)
1653*5e7646d2SAndroid Build Coastguard Worker {
1654*5e7646d2SAndroid Build Coastguard Worker if ((!_cups_strcasecmp(choice->choice, "None") ||
1655*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "False")) && !pc->sides_1sided)
1656*5e7646d2SAndroid Build Coastguard Worker pc->sides_1sided = strdup(choice->choice);
1657*5e7646d2SAndroid Build Coastguard Worker else if ((!_cups_strcasecmp(choice->choice, "DuplexNoTumble") ||
1658*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "LongEdge") ||
1659*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "Top")) && !pc->sides_2sided_long)
1660*5e7646d2SAndroid Build Coastguard Worker pc->sides_2sided_long = strdup(choice->choice);
1661*5e7646d2SAndroid Build Coastguard Worker else if ((!_cups_strcasecmp(choice->choice, "DuplexTumble") ||
1662*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "ShortEdge") ||
1663*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice->choice, "Bottom")) &&
1664*5e7646d2SAndroid Build Coastguard Worker !pc->sides_2sided_short)
1665*5e7646d2SAndroid Build Coastguard Worker pc->sides_2sided_short = strdup(choice->choice);
1666*5e7646d2SAndroid Build Coastguard Worker }
1667*5e7646d2SAndroid Build Coastguard Worker }
1668*5e7646d2SAndroid Build Coastguard Worker
1669*5e7646d2SAndroid Build Coastguard Worker /*
1670*5e7646d2SAndroid Build Coastguard Worker * Copy filters and pre-filters...
1671*5e7646d2SAndroid Build Coastguard Worker */
1672*5e7646d2SAndroid Build Coastguard Worker
1673*5e7646d2SAndroid Build Coastguard Worker pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
1674*5e7646d2SAndroid Build Coastguard Worker
1675*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters,
1676*5e7646d2SAndroid Build Coastguard Worker "application/vnd.cups-raw application/octet-stream 0 -");
1677*5e7646d2SAndroid Build Coastguard Worker
1678*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsFilter2", NULL)) != NULL)
1679*5e7646d2SAndroid Build Coastguard Worker {
1680*5e7646d2SAndroid Build Coastguard Worker do
1681*5e7646d2SAndroid Build Coastguard Worker {
1682*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters, ppd_attr->value);
1683*5e7646d2SAndroid Build Coastguard Worker }
1684*5e7646d2SAndroid Build Coastguard Worker while ((ppd_attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL);
1685*5e7646d2SAndroid Build Coastguard Worker }
1686*5e7646d2SAndroid Build Coastguard Worker else if (ppd->num_filters > 0)
1687*5e7646d2SAndroid Build Coastguard Worker {
1688*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < ppd->num_filters; i ++)
1689*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters, ppd->filters[i]);
1690*5e7646d2SAndroid Build Coastguard Worker }
1691*5e7646d2SAndroid Build Coastguard Worker else
1692*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters, "application/vnd.cups-postscript 0 -");
1693*5e7646d2SAndroid Build Coastguard Worker
1694*5e7646d2SAndroid Build Coastguard Worker /*
1695*5e7646d2SAndroid Build Coastguard Worker * See if we have a command filter...
1696*5e7646d2SAndroid Build Coastguard Worker */
1697*5e7646d2SAndroid Build Coastguard Worker
1698*5e7646d2SAndroid Build Coastguard Worker for (filter = (const char *)cupsArrayFirst(pc->filters);
1699*5e7646d2SAndroid Build Coastguard Worker filter;
1700*5e7646d2SAndroid Build Coastguard Worker filter = (const char *)cupsArrayNext(pc->filters))
1701*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(filter, "application/vnd.cups-command", 28) &&
1702*5e7646d2SAndroid Build Coastguard Worker _cups_isspace(filter[28]))
1703*5e7646d2SAndroid Build Coastguard Worker break;
1704*5e7646d2SAndroid Build Coastguard Worker
1705*5e7646d2SAndroid Build Coastguard Worker if (!filter &&
1706*5e7646d2SAndroid Build Coastguard Worker ((ppd_attr = ppdFindAttr(ppd, "cupsCommands", NULL)) == NULL ||
1707*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(ppd_attr->value, "none")))
1708*5e7646d2SAndroid Build Coastguard Worker {
1709*5e7646d2SAndroid Build Coastguard Worker /*
1710*5e7646d2SAndroid Build Coastguard Worker * No command filter and no cupsCommands keyword telling us not to use one.
1711*5e7646d2SAndroid Build Coastguard Worker * See if this is a PostScript printer, and if so add a PostScript command
1712*5e7646d2SAndroid Build Coastguard Worker * filter...
1713*5e7646d2SAndroid Build Coastguard Worker */
1714*5e7646d2SAndroid Build Coastguard Worker
1715*5e7646d2SAndroid Build Coastguard Worker for (filter = (const char *)cupsArrayFirst(pc->filters);
1716*5e7646d2SAndroid Build Coastguard Worker filter;
1717*5e7646d2SAndroid Build Coastguard Worker filter = (const char *)cupsArrayNext(pc->filters))
1718*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(filter, "application/vnd.cups-postscript", 31) &&
1719*5e7646d2SAndroid Build Coastguard Worker _cups_isspace(filter[31]))
1720*5e7646d2SAndroid Build Coastguard Worker break;
1721*5e7646d2SAndroid Build Coastguard Worker
1722*5e7646d2SAndroid Build Coastguard Worker if (filter)
1723*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->filters,
1724*5e7646d2SAndroid Build Coastguard Worker "application/vnd.cups-command application/postscript 100 "
1725*5e7646d2SAndroid Build Coastguard Worker "commandtops");
1726*5e7646d2SAndroid Build Coastguard Worker }
1727*5e7646d2SAndroid Build Coastguard Worker
1728*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL)
1729*5e7646d2SAndroid Build Coastguard Worker {
1730*5e7646d2SAndroid Build Coastguard Worker pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
1731*5e7646d2SAndroid Build Coastguard Worker
1732*5e7646d2SAndroid Build Coastguard Worker do
1733*5e7646d2SAndroid Build Coastguard Worker {
1734*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->prefilters, ppd_attr->value);
1735*5e7646d2SAndroid Build Coastguard Worker }
1736*5e7646d2SAndroid Build Coastguard Worker while ((ppd_attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) != NULL);
1737*5e7646d2SAndroid Build Coastguard Worker }
1738*5e7646d2SAndroid Build Coastguard Worker
1739*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsSingleFile", NULL)) != NULL)
1740*5e7646d2SAndroid Build Coastguard Worker pc->single_file = !_cups_strcasecmp(ppd_attr->value, "true");
1741*5e7646d2SAndroid Build Coastguard Worker
1742*5e7646d2SAndroid Build Coastguard Worker /*
1743*5e7646d2SAndroid Build Coastguard Worker * Copy the product string, if any...
1744*5e7646d2SAndroid Build Coastguard Worker */
1745*5e7646d2SAndroid Build Coastguard Worker
1746*5e7646d2SAndroid Build Coastguard Worker if (ppd->product)
1747*5e7646d2SAndroid Build Coastguard Worker pc->product = strdup(ppd->product);
1748*5e7646d2SAndroid Build Coastguard Worker
1749*5e7646d2SAndroid Build Coastguard Worker /*
1750*5e7646d2SAndroid Build Coastguard Worker * Copy finishings mapping data...
1751*5e7646d2SAndroid Build Coastguard Worker */
1752*5e7646d2SAndroid Build Coastguard Worker
1753*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsIPPFinishings", NULL)) != NULL)
1754*5e7646d2SAndroid Build Coastguard Worker {
1755*5e7646d2SAndroid Build Coastguard Worker /*
1756*5e7646d2SAndroid Build Coastguard Worker * Have proper vendor mapping of IPP finishings values to PPD options...
1757*5e7646d2SAndroid Build Coastguard Worker */
1758*5e7646d2SAndroid Build Coastguard Worker
1759*5e7646d2SAndroid Build Coastguard Worker pc->finishings = cupsArrayNew3((cups_array_func_t)pwg_compare_finishings,
1760*5e7646d2SAndroid Build Coastguard Worker NULL, NULL, 0, NULL,
1761*5e7646d2SAndroid Build Coastguard Worker (cups_afree_func_t)pwg_free_finishings);
1762*5e7646d2SAndroid Build Coastguard Worker
1763*5e7646d2SAndroid Build Coastguard Worker do
1764*5e7646d2SAndroid Build Coastguard Worker {
1765*5e7646d2SAndroid Build Coastguard Worker if ((finishings = calloc(1, sizeof(_pwg_finishings_t))) == NULL)
1766*5e7646d2SAndroid Build Coastguard Worker goto create_error;
1767*5e7646d2SAndroid Build Coastguard Worker
1768*5e7646d2SAndroid Build Coastguard Worker finishings->value = (ipp_finishings_t)atoi(ppd_attr->spec);
1769*5e7646d2SAndroid Build Coastguard Worker finishings->num_options = _ppdParseOptions(ppd_attr->value, 0,
1770*5e7646d2SAndroid Build Coastguard Worker &(finishings->options),
1771*5e7646d2SAndroid Build Coastguard Worker _PPD_PARSE_OPTIONS);
1772*5e7646d2SAndroid Build Coastguard Worker
1773*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->finishings, finishings);
1774*5e7646d2SAndroid Build Coastguard Worker }
1775*5e7646d2SAndroid Build Coastguard Worker while ((ppd_attr = ppdFindNextAttr(ppd, "cupsIPPFinishings",
1776*5e7646d2SAndroid Build Coastguard Worker NULL)) != NULL);
1777*5e7646d2SAndroid Build Coastguard Worker }
1778*5e7646d2SAndroid Build Coastguard Worker else
1779*5e7646d2SAndroid Build Coastguard Worker {
1780*5e7646d2SAndroid Build Coastguard Worker /*
1781*5e7646d2SAndroid Build Coastguard Worker * No IPP mapping data, try to map common/standard PPD keywords...
1782*5e7646d2SAndroid Build Coastguard Worker */
1783*5e7646d2SAndroid Build Coastguard Worker
1784*5e7646d2SAndroid Build Coastguard Worker pc->finishings = cupsArrayNew3((cups_array_func_t)pwg_compare_finishings, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_finishings);
1785*5e7646d2SAndroid Build Coastguard Worker
1786*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "StapleLocation")) != NULL)
1787*5e7646d2SAndroid Build Coastguard Worker {
1788*5e7646d2SAndroid Build Coastguard Worker /*
1789*5e7646d2SAndroid Build Coastguard Worker * Add staple finishings...
1790*5e7646d2SAndroid Build Coastguard Worker */
1791*5e7646d2SAndroid Build Coastguard Worker
1792*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "SinglePortrait"))
1793*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_STAPLE_TOP_LEFT, "StapleLocation", "SinglePortrait");
1794*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "UpperLeft")) /* Ricoh extension */
1795*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_STAPLE_TOP_LEFT, "StapleLocation", "UpperLeft");
1796*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "UpperRight")) /* Ricoh extension */
1797*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_STAPLE_TOP_RIGHT, "StapleLocation", "UpperRight");
1798*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "SingleLandscape"))
1799*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_STAPLE_BOTTOM_LEFT, "StapleLocation", "SingleLandscape");
1800*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "DualLandscape"))
1801*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_STAPLE_DUAL_LEFT, "StapleLocation", "DualLandscape");
1802*5e7646d2SAndroid Build Coastguard Worker }
1803*5e7646d2SAndroid Build Coastguard Worker
1804*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "RIPunch")) != NULL)
1805*5e7646d2SAndroid Build Coastguard Worker {
1806*5e7646d2SAndroid Build Coastguard Worker /*
1807*5e7646d2SAndroid Build Coastguard Worker * Add (Ricoh) punch finishings...
1808*5e7646d2SAndroid Build Coastguard Worker */
1809*5e7646d2SAndroid Build Coastguard Worker
1810*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Left2"))
1811*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_DUAL_LEFT, "RIPunch", "Left2");
1812*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Left3"))
1813*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_TRIPLE_LEFT, "RIPunch", "Left3");
1814*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Left4"))
1815*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_QUAD_LEFT, "RIPunch", "Left4");
1816*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Right2"))
1817*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_DUAL_RIGHT, "RIPunch", "Right2");
1818*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Right3"))
1819*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_TRIPLE_RIGHT, "RIPunch", "Right3");
1820*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Right4"))
1821*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_QUAD_RIGHT, "RIPunch", "Right4");
1822*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Upper2"))
1823*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_DUAL_TOP, "RIPunch", "Upper2");
1824*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Upper3"))
1825*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_TRIPLE_TOP, "RIPunch", "Upper3");
1826*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Upper4"))
1827*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_PUNCH_QUAD_TOP, "RIPunch", "Upper4");
1828*5e7646d2SAndroid Build Coastguard Worker }
1829*5e7646d2SAndroid Build Coastguard Worker
1830*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "BindEdge")) != NULL)
1831*5e7646d2SAndroid Build Coastguard Worker {
1832*5e7646d2SAndroid Build Coastguard Worker /*
1833*5e7646d2SAndroid Build Coastguard Worker * Add bind finishings...
1834*5e7646d2SAndroid Build Coastguard Worker */
1835*5e7646d2SAndroid Build Coastguard Worker
1836*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Left"))
1837*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_BIND_LEFT, "BindEdge", "Left");
1838*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Right"))
1839*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_BIND_RIGHT, "BindEdge", "Right");
1840*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Top"))
1841*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_BIND_TOP, "BindEdge", "Top");
1842*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Bottom"))
1843*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_BIND_BOTTOM, "BindEdge", "Bottom");
1844*5e7646d2SAndroid Build Coastguard Worker }
1845*5e7646d2SAndroid Build Coastguard Worker
1846*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "FoldType")) != NULL)
1847*5e7646d2SAndroid Build Coastguard Worker {
1848*5e7646d2SAndroid Build Coastguard Worker /*
1849*5e7646d2SAndroid Build Coastguard Worker * Add (Adobe) fold finishings...
1850*5e7646d2SAndroid Build Coastguard Worker */
1851*5e7646d2SAndroid Build Coastguard Worker
1852*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "ZFold"))
1853*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_Z, "FoldType", "ZFold");
1854*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Saddle"))
1855*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_HALF, "FoldType", "Saddle");
1856*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "DoubleGate"))
1857*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_DOUBLE_GATE, "FoldType", "DoubleGate");
1858*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "LeftGate"))
1859*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_LEFT_GATE, "FoldType", "LeftGate");
1860*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "RightGate"))
1861*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_RIGHT_GATE, "FoldType", "RightGate");
1862*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "Letter"))
1863*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_LETTER, "FoldType", "Letter");
1864*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "XFold"))
1865*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_POSTER, "FoldType", "XFold");
1866*5e7646d2SAndroid Build Coastguard Worker }
1867*5e7646d2SAndroid Build Coastguard Worker
1868*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "RIFoldType")) != NULL)
1869*5e7646d2SAndroid Build Coastguard Worker {
1870*5e7646d2SAndroid Build Coastguard Worker /*
1871*5e7646d2SAndroid Build Coastguard Worker * Add (Ricoh) fold finishings...
1872*5e7646d2SAndroid Build Coastguard Worker */
1873*5e7646d2SAndroid Build Coastguard Worker
1874*5e7646d2SAndroid Build Coastguard Worker if (ppdFindChoice(ppd_option, "OutsideTwoFold"))
1875*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(pc->finishings, IPP_FINISHINGS_FOLD_LETTER, "RIFoldType", "OutsideTwoFold");
1876*5e7646d2SAndroid Build Coastguard Worker }
1877*5e7646d2SAndroid Build Coastguard Worker
1878*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(pc->finishings) == 0)
1879*5e7646d2SAndroid Build Coastguard Worker {
1880*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->finishings);
1881*5e7646d2SAndroid Build Coastguard Worker pc->finishings = NULL;
1882*5e7646d2SAndroid Build Coastguard Worker }
1883*5e7646d2SAndroid Build Coastguard Worker }
1884*5e7646d2SAndroid Build Coastguard Worker
1885*5e7646d2SAndroid Build Coastguard Worker if ((ppd_option = ppdFindOption(ppd, "cupsFinishingTemplate")) != NULL)
1886*5e7646d2SAndroid Build Coastguard Worker {
1887*5e7646d2SAndroid Build Coastguard Worker pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
1888*5e7646d2SAndroid Build Coastguard Worker
1889*5e7646d2SAndroid Build Coastguard Worker for (choice = ppd_option->choices, i = ppd_option->num_choices; i > 0; choice ++, i --)
1890*5e7646d2SAndroid Build Coastguard Worker {
1891*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->templates, (void *)choice->choice);
1892*5e7646d2SAndroid Build Coastguard Worker
1893*5e7646d2SAndroid Build Coastguard Worker /*
1894*5e7646d2SAndroid Build Coastguard Worker * Add localized text for PWG keyword to message catalog...
1895*5e7646d2SAndroid Build Coastguard Worker */
1896*5e7646d2SAndroid Build Coastguard Worker
1897*5e7646d2SAndroid Build Coastguard Worker snprintf(msg_id, sizeof(msg_id), "finishing-template.%s", choice->choice);
1898*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(pc->strings, msg_id, choice->text);
1899*5e7646d2SAndroid Build Coastguard Worker }
1900*5e7646d2SAndroid Build Coastguard Worker }
1901*5e7646d2SAndroid Build Coastguard Worker
1902*5e7646d2SAndroid Build Coastguard Worker /*
1903*5e7646d2SAndroid Build Coastguard Worker * Max copies...
1904*5e7646d2SAndroid Build Coastguard Worker */
1905*5e7646d2SAndroid Build Coastguard Worker
1906*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL)
1907*5e7646d2SAndroid Build Coastguard Worker pc->max_copies = atoi(ppd_attr->value);
1908*5e7646d2SAndroid Build Coastguard Worker else if (ppd->manual_copies)
1909*5e7646d2SAndroid Build Coastguard Worker pc->max_copies = 1;
1910*5e7646d2SAndroid Build Coastguard Worker else
1911*5e7646d2SAndroid Build Coastguard Worker pc->max_copies = 9999;
1912*5e7646d2SAndroid Build Coastguard Worker
1913*5e7646d2SAndroid Build Coastguard Worker /*
1914*5e7646d2SAndroid Build Coastguard Worker * cupsChargeInfoURI, cupsJobAccountId, cupsJobAccountingUserId,
1915*5e7646d2SAndroid Build Coastguard Worker * cupsJobPassword, and cupsMandatory.
1916*5e7646d2SAndroid Build Coastguard Worker */
1917*5e7646d2SAndroid Build Coastguard Worker
1918*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsChargeInfoURI", NULL)) != NULL)
1919*5e7646d2SAndroid Build Coastguard Worker pc->charge_info_uri = strdup(ppd_attr->value);
1920*5e7646d2SAndroid Build Coastguard Worker
1921*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL)
1922*5e7646d2SAndroid Build Coastguard Worker pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true");
1923*5e7646d2SAndroid Build Coastguard Worker
1924*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountingUserId", NULL)) != NULL)
1925*5e7646d2SAndroid Build Coastguard Worker pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true");
1926*5e7646d2SAndroid Build Coastguard Worker
1927*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL)
1928*5e7646d2SAndroid Build Coastguard Worker pc->password = strdup(ppd_attr->value);
1929*5e7646d2SAndroid Build Coastguard Worker
1930*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
1931*5e7646d2SAndroid Build Coastguard Worker pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
1932*5e7646d2SAndroid Build Coastguard Worker
1933*5e7646d2SAndroid Build Coastguard Worker /*
1934*5e7646d2SAndroid Build Coastguard Worker * Support files...
1935*5e7646d2SAndroid Build Coastguard Worker */
1936*5e7646d2SAndroid Build Coastguard Worker
1937*5e7646d2SAndroid Build Coastguard Worker pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
1938*5e7646d2SAndroid Build Coastguard Worker
1939*5e7646d2SAndroid Build Coastguard Worker for (ppd_attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
1940*5e7646d2SAndroid Build Coastguard Worker ppd_attr;
1941*5e7646d2SAndroid Build Coastguard Worker ppd_attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
1942*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->support_files, ppd_attr->value);
1943*5e7646d2SAndroid Build Coastguard Worker
1944*5e7646d2SAndroid Build Coastguard Worker if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
1945*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(pc->support_files, ppd_attr->value);
1946*5e7646d2SAndroid Build Coastguard Worker
1947*5e7646d2SAndroid Build Coastguard Worker /*
1948*5e7646d2SAndroid Build Coastguard Worker * Return the cache data...
1949*5e7646d2SAndroid Build Coastguard Worker */
1950*5e7646d2SAndroid Build Coastguard Worker
1951*5e7646d2SAndroid Build Coastguard Worker return (pc);
1952*5e7646d2SAndroid Build Coastguard Worker
1953*5e7646d2SAndroid Build Coastguard Worker /*
1954*5e7646d2SAndroid Build Coastguard Worker * If we get here we need to destroy the PWG mapping data and return NULL...
1955*5e7646d2SAndroid Build Coastguard Worker */
1956*5e7646d2SAndroid Build Coastguard Worker
1957*5e7646d2SAndroid Build Coastguard Worker create_error:
1958*5e7646d2SAndroid Build Coastguard Worker
1959*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Out of memory."), 1);
1960*5e7646d2SAndroid Build Coastguard Worker _ppdCacheDestroy(pc);
1961*5e7646d2SAndroid Build Coastguard Worker
1962*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1963*5e7646d2SAndroid Build Coastguard Worker }
1964*5e7646d2SAndroid Build Coastguard Worker
1965*5e7646d2SAndroid Build Coastguard Worker
1966*5e7646d2SAndroid Build Coastguard Worker /*
1967*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheDestroy()' - Free all memory used for PWG mapping data.
1968*5e7646d2SAndroid Build Coastguard Worker */
1969*5e7646d2SAndroid Build Coastguard Worker
1970*5e7646d2SAndroid Build Coastguard Worker void
_ppdCacheDestroy(_ppd_cache_t * pc)1971*5e7646d2SAndroid Build Coastguard Worker _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */
1972*5e7646d2SAndroid Build Coastguard Worker {
1973*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1974*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *map; /* Current map */
1975*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size; /* Current size */
1976*5e7646d2SAndroid Build Coastguard Worker
1977*5e7646d2SAndroid Build Coastguard Worker
1978*5e7646d2SAndroid Build Coastguard Worker /*
1979*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1980*5e7646d2SAndroid Build Coastguard Worker */
1981*5e7646d2SAndroid Build Coastguard Worker
1982*5e7646d2SAndroid Build Coastguard Worker if (!pc)
1983*5e7646d2SAndroid Build Coastguard Worker return;
1984*5e7646d2SAndroid Build Coastguard Worker
1985*5e7646d2SAndroid Build Coastguard Worker /*
1986*5e7646d2SAndroid Build Coastguard Worker * Free memory as needed...
1987*5e7646d2SAndroid Build Coastguard Worker */
1988*5e7646d2SAndroid Build Coastguard Worker
1989*5e7646d2SAndroid Build Coastguard Worker if (pc->bins)
1990*5e7646d2SAndroid Build Coastguard Worker {
1991*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++)
1992*5e7646d2SAndroid Build Coastguard Worker {
1993*5e7646d2SAndroid Build Coastguard Worker free(map->pwg);
1994*5e7646d2SAndroid Build Coastguard Worker free(map->ppd);
1995*5e7646d2SAndroid Build Coastguard Worker }
1996*5e7646d2SAndroid Build Coastguard Worker
1997*5e7646d2SAndroid Build Coastguard Worker free(pc->bins);
1998*5e7646d2SAndroid Build Coastguard Worker }
1999*5e7646d2SAndroid Build Coastguard Worker
2000*5e7646d2SAndroid Build Coastguard Worker if (pc->sizes)
2001*5e7646d2SAndroid Build Coastguard Worker {
2002*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
2003*5e7646d2SAndroid Build Coastguard Worker {
2004*5e7646d2SAndroid Build Coastguard Worker free(size->map.pwg);
2005*5e7646d2SAndroid Build Coastguard Worker free(size->map.ppd);
2006*5e7646d2SAndroid Build Coastguard Worker }
2007*5e7646d2SAndroid Build Coastguard Worker
2008*5e7646d2SAndroid Build Coastguard Worker free(pc->sizes);
2009*5e7646d2SAndroid Build Coastguard Worker }
2010*5e7646d2SAndroid Build Coastguard Worker
2011*5e7646d2SAndroid Build Coastguard Worker free(pc->source_option);
2012*5e7646d2SAndroid Build Coastguard Worker
2013*5e7646d2SAndroid Build Coastguard Worker if (pc->sources)
2014*5e7646d2SAndroid Build Coastguard Worker {
2015*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++)
2016*5e7646d2SAndroid Build Coastguard Worker {
2017*5e7646d2SAndroid Build Coastguard Worker free(map->pwg);
2018*5e7646d2SAndroid Build Coastguard Worker free(map->ppd);
2019*5e7646d2SAndroid Build Coastguard Worker }
2020*5e7646d2SAndroid Build Coastguard Worker
2021*5e7646d2SAndroid Build Coastguard Worker free(pc->sources);
2022*5e7646d2SAndroid Build Coastguard Worker }
2023*5e7646d2SAndroid Build Coastguard Worker
2024*5e7646d2SAndroid Build Coastguard Worker if (pc->types)
2025*5e7646d2SAndroid Build Coastguard Worker {
2026*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_types, map = pc->types; i > 0; i --, map ++)
2027*5e7646d2SAndroid Build Coastguard Worker {
2028*5e7646d2SAndroid Build Coastguard Worker free(map->pwg);
2029*5e7646d2SAndroid Build Coastguard Worker free(map->ppd);
2030*5e7646d2SAndroid Build Coastguard Worker }
2031*5e7646d2SAndroid Build Coastguard Worker
2032*5e7646d2SAndroid Build Coastguard Worker free(pc->types);
2033*5e7646d2SAndroid Build Coastguard Worker }
2034*5e7646d2SAndroid Build Coastguard Worker
2035*5e7646d2SAndroid Build Coastguard Worker free(pc->custom_max_keyword);
2036*5e7646d2SAndroid Build Coastguard Worker free(pc->custom_min_keyword);
2037*5e7646d2SAndroid Build Coastguard Worker
2038*5e7646d2SAndroid Build Coastguard Worker free(pc->product);
2039*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->filters);
2040*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->prefilters);
2041*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->finishings);
2042*5e7646d2SAndroid Build Coastguard Worker
2043*5e7646d2SAndroid Build Coastguard Worker free(pc->charge_info_uri);
2044*5e7646d2SAndroid Build Coastguard Worker free(pc->password);
2045*5e7646d2SAndroid Build Coastguard Worker
2046*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->mandatory);
2047*5e7646d2SAndroid Build Coastguard Worker
2048*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->support_files);
2049*5e7646d2SAndroid Build Coastguard Worker
2050*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(pc->strings);
2051*5e7646d2SAndroid Build Coastguard Worker
2052*5e7646d2SAndroid Build Coastguard Worker free(pc);
2053*5e7646d2SAndroid Build Coastguard Worker }
2054*5e7646d2SAndroid Build Coastguard Worker
2055*5e7646d2SAndroid Build Coastguard Worker
2056*5e7646d2SAndroid Build Coastguard Worker /*
2057*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetBin()' - Get the PWG output-bin keyword associated with a PPD
2058*5e7646d2SAndroid Build Coastguard Worker * OutputBin.
2059*5e7646d2SAndroid Build Coastguard Worker */
2060*5e7646d2SAndroid Build Coastguard Worker
2061*5e7646d2SAndroid Build Coastguard Worker const char * /* O - output-bin or NULL */
_ppdCacheGetBin(_ppd_cache_t * pc,const char * output_bin)2062*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetBin(
2063*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2064*5e7646d2SAndroid Build Coastguard Worker const char *output_bin) /* I - PPD OutputBin string */
2065*5e7646d2SAndroid Build Coastguard Worker {
2066*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2067*5e7646d2SAndroid Build Coastguard Worker
2068*5e7646d2SAndroid Build Coastguard Worker
2069*5e7646d2SAndroid Build Coastguard Worker /*
2070*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2071*5e7646d2SAndroid Build Coastguard Worker */
2072*5e7646d2SAndroid Build Coastguard Worker
2073*5e7646d2SAndroid Build Coastguard Worker if (!pc || !output_bin)
2074*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2075*5e7646d2SAndroid Build Coastguard Worker
2076*5e7646d2SAndroid Build Coastguard Worker /*
2077*5e7646d2SAndroid Build Coastguard Worker * Look up the OutputBin string...
2078*5e7646d2SAndroid Build Coastguard Worker */
2079*5e7646d2SAndroid Build Coastguard Worker
2080*5e7646d2SAndroid Build Coastguard Worker
2081*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < pc->num_bins; i ++)
2082*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(output_bin, pc->bins[i].ppd))
2083*5e7646d2SAndroid Build Coastguard Worker return (pc->bins[i].pwg);
2084*5e7646d2SAndroid Build Coastguard Worker
2085*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2086*5e7646d2SAndroid Build Coastguard Worker }
2087*5e7646d2SAndroid Build Coastguard Worker
2088*5e7646d2SAndroid Build Coastguard Worker
2089*5e7646d2SAndroid Build Coastguard Worker /*
2090*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetFinishingOptions()' - Get PPD finishing options for the given
2091*5e7646d2SAndroid Build Coastguard Worker * IPP finishings value(s).
2092*5e7646d2SAndroid Build Coastguard Worker */
2093*5e7646d2SAndroid Build Coastguard Worker
2094*5e7646d2SAndroid Build Coastguard Worker int /* O - New number of options */
_ppdCacheGetFinishingOptions(_ppd_cache_t * pc,ipp_t * job,ipp_finishings_t value,int num_options,cups_option_t ** options)2095*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetFinishingOptions(
2096*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2097*5e7646d2SAndroid Build Coastguard Worker ipp_t *job, /* I - Job attributes or NULL */
2098*5e7646d2SAndroid Build Coastguard Worker ipp_finishings_t value, /* I - IPP finishings value of IPP_FINISHINGS_NONE */
2099*5e7646d2SAndroid Build Coastguard Worker int num_options, /* I - Number of options */
2100*5e7646d2SAndroid Build Coastguard Worker cups_option_t **options) /* IO - Options */
2101*5e7646d2SAndroid Build Coastguard Worker {
2102*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2103*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *f, /* PWG finishings options */
2104*5e7646d2SAndroid Build Coastguard Worker key; /* Search key */
2105*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Finishings attribute */
2106*5e7646d2SAndroid Build Coastguard Worker cups_option_t *option; /* Current finishings option */
2107*5e7646d2SAndroid Build Coastguard Worker
2108*5e7646d2SAndroid Build Coastguard Worker
2109*5e7646d2SAndroid Build Coastguard Worker /*
2110*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2111*5e7646d2SAndroid Build Coastguard Worker */
2112*5e7646d2SAndroid Build Coastguard Worker
2113*5e7646d2SAndroid Build Coastguard Worker if (!pc || cupsArrayCount(pc->finishings) == 0 || !options ||
2114*5e7646d2SAndroid Build Coastguard Worker (!job && value == IPP_FINISHINGS_NONE))
2115*5e7646d2SAndroid Build Coastguard Worker return (num_options);
2116*5e7646d2SAndroid Build Coastguard Worker
2117*5e7646d2SAndroid Build Coastguard Worker /*
2118*5e7646d2SAndroid Build Coastguard Worker * Apply finishing options...
2119*5e7646d2SAndroid Build Coastguard Worker */
2120*5e7646d2SAndroid Build Coastguard Worker
2121*5e7646d2SAndroid Build Coastguard Worker if (job && (attr = ippFindAttribute(job, "finishings", IPP_TAG_ENUM)) != NULL)
2122*5e7646d2SAndroid Build Coastguard Worker {
2123*5e7646d2SAndroid Build Coastguard Worker int num_values = ippGetCount(attr); /* Number of values */
2124*5e7646d2SAndroid Build Coastguard Worker
2125*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_values; i ++)
2126*5e7646d2SAndroid Build Coastguard Worker {
2127*5e7646d2SAndroid Build Coastguard Worker key.value = (ipp_finishings_t)ippGetInteger(attr, i);
2128*5e7646d2SAndroid Build Coastguard Worker
2129*5e7646d2SAndroid Build Coastguard Worker if ((f = cupsArrayFind(pc->finishings, &key)) != NULL)
2130*5e7646d2SAndroid Build Coastguard Worker {
2131*5e7646d2SAndroid Build Coastguard Worker int j; /* Another looping var */
2132*5e7646d2SAndroid Build Coastguard Worker
2133*5e7646d2SAndroid Build Coastguard Worker for (j = f->num_options, option = f->options; j > 0; j --, option ++)
2134*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(option->name, option->value,
2135*5e7646d2SAndroid Build Coastguard Worker num_options, options);
2136*5e7646d2SAndroid Build Coastguard Worker }
2137*5e7646d2SAndroid Build Coastguard Worker }
2138*5e7646d2SAndroid Build Coastguard Worker }
2139*5e7646d2SAndroid Build Coastguard Worker else if (value != IPP_FINISHINGS_NONE)
2140*5e7646d2SAndroid Build Coastguard Worker {
2141*5e7646d2SAndroid Build Coastguard Worker key.value = value;
2142*5e7646d2SAndroid Build Coastguard Worker
2143*5e7646d2SAndroid Build Coastguard Worker if ((f = cupsArrayFind(pc->finishings, &key)) != NULL)
2144*5e7646d2SAndroid Build Coastguard Worker {
2145*5e7646d2SAndroid Build Coastguard Worker int j; /* Another looping var */
2146*5e7646d2SAndroid Build Coastguard Worker
2147*5e7646d2SAndroid Build Coastguard Worker for (j = f->num_options, option = f->options; j > 0; j --, option ++)
2148*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(option->name, option->value,
2149*5e7646d2SAndroid Build Coastguard Worker num_options, options);
2150*5e7646d2SAndroid Build Coastguard Worker }
2151*5e7646d2SAndroid Build Coastguard Worker }
2152*5e7646d2SAndroid Build Coastguard Worker
2153*5e7646d2SAndroid Build Coastguard Worker return (num_options);
2154*5e7646d2SAndroid Build Coastguard Worker }
2155*5e7646d2SAndroid Build Coastguard Worker
2156*5e7646d2SAndroid Build Coastguard Worker
2157*5e7646d2SAndroid Build Coastguard Worker /*
2158*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetFinishingValues()' - Get IPP finishings value(s) from the given
2159*5e7646d2SAndroid Build Coastguard Worker * PPD options.
2160*5e7646d2SAndroid Build Coastguard Worker */
2161*5e7646d2SAndroid Build Coastguard Worker
2162*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of finishings values */
_ppdCacheGetFinishingValues(ppd_file_t * ppd,_ppd_cache_t * pc,int max_values,int * values)2163*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetFinishingValues(
2164*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - Marked PPD file */
2165*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2166*5e7646d2SAndroid Build Coastguard Worker int max_values, /* I - Maximum number of finishings values */
2167*5e7646d2SAndroid Build Coastguard Worker int *values) /* O - Finishings values */
2168*5e7646d2SAndroid Build Coastguard Worker {
2169*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
2170*5e7646d2SAndroid Build Coastguard Worker num_values = 0; /* Number of values */
2171*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *f; /* Current finishings option */
2172*5e7646d2SAndroid Build Coastguard Worker cups_option_t *option; /* Current option */
2173*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *choice; /* Marked PPD choice */
2174*5e7646d2SAndroid Build Coastguard Worker
2175*5e7646d2SAndroid Build Coastguard Worker
2176*5e7646d2SAndroid Build Coastguard Worker /*
2177*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2178*5e7646d2SAndroid Build Coastguard Worker */
2179*5e7646d2SAndroid Build Coastguard Worker
2180*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetFinishingValues(ppd=%p, pc=%p, max_values=%d, values=%p)", ppd, pc, max_values, values));
2181*5e7646d2SAndroid Build Coastguard Worker
2182*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !pc || max_values < 1 || !values)
2183*5e7646d2SAndroid Build Coastguard Worker {
2184*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheGetFinishingValues: Bad arguments, returning 0.");
2185*5e7646d2SAndroid Build Coastguard Worker return (0);
2186*5e7646d2SAndroid Build Coastguard Worker }
2187*5e7646d2SAndroid Build Coastguard Worker else if (!pc->finishings)
2188*5e7646d2SAndroid Build Coastguard Worker {
2189*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheGetFinishingValues: No finishings support, returning 0.");
2190*5e7646d2SAndroid Build Coastguard Worker return (0);
2191*5e7646d2SAndroid Build Coastguard Worker }
2192*5e7646d2SAndroid Build Coastguard Worker
2193*5e7646d2SAndroid Build Coastguard Worker /*
2194*5e7646d2SAndroid Build Coastguard Worker * Go through the finishings options and see what is set...
2195*5e7646d2SAndroid Build Coastguard Worker */
2196*5e7646d2SAndroid Build Coastguard Worker
2197*5e7646d2SAndroid Build Coastguard Worker for (f = (_pwg_finishings_t *)cupsArrayFirst(pc->finishings);
2198*5e7646d2SAndroid Build Coastguard Worker f;
2199*5e7646d2SAndroid Build Coastguard Worker f = (_pwg_finishings_t *)cupsArrayNext(pc->finishings))
2200*5e7646d2SAndroid Build Coastguard Worker {
2201*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetFinishingValues: Checking %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value)));
2202*5e7646d2SAndroid Build Coastguard Worker
2203*5e7646d2SAndroid Build Coastguard Worker for (i = f->num_options, option = f->options; i > 0; i --, option ++)
2204*5e7646d2SAndroid Build Coastguard Worker {
2205*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetFinishingValues: %s=%s?", option->name, option->value));
2206*5e7646d2SAndroid Build Coastguard Worker
2207*5e7646d2SAndroid Build Coastguard Worker if ((choice = ppdFindMarkedChoice(ppd, option->name)) == NULL || _cups_strcasecmp(option->value, choice->choice))
2208*5e7646d2SAndroid Build Coastguard Worker {
2209*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheGetFinishingValues: NO");
2210*5e7646d2SAndroid Build Coastguard Worker break;
2211*5e7646d2SAndroid Build Coastguard Worker }
2212*5e7646d2SAndroid Build Coastguard Worker }
2213*5e7646d2SAndroid Build Coastguard Worker
2214*5e7646d2SAndroid Build Coastguard Worker if (i == 0)
2215*5e7646d2SAndroid Build Coastguard Worker {
2216*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value)));
2217*5e7646d2SAndroid Build Coastguard Worker
2218*5e7646d2SAndroid Build Coastguard Worker values[num_values ++] = (int)f->value;
2219*5e7646d2SAndroid Build Coastguard Worker
2220*5e7646d2SAndroid Build Coastguard Worker if (num_values >= max_values)
2221*5e7646d2SAndroid Build Coastguard Worker break;
2222*5e7646d2SAndroid Build Coastguard Worker }
2223*5e7646d2SAndroid Build Coastguard Worker }
2224*5e7646d2SAndroid Build Coastguard Worker
2225*5e7646d2SAndroid Build Coastguard Worker if (num_values == 0)
2226*5e7646d2SAndroid Build Coastguard Worker {
2227*5e7646d2SAndroid Build Coastguard Worker /*
2228*5e7646d2SAndroid Build Coastguard Worker * Always have at least "finishings" = 'none'...
2229*5e7646d2SAndroid Build Coastguard Worker */
2230*5e7646d2SAndroid Build Coastguard Worker
2231*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("_ppdCacheGetFinishingValues: Adding 3 (none).");
2232*5e7646d2SAndroid Build Coastguard Worker values[0] = IPP_FINISHINGS_NONE;
2233*5e7646d2SAndroid Build Coastguard Worker num_values ++;
2234*5e7646d2SAndroid Build Coastguard Worker }
2235*5e7646d2SAndroid Build Coastguard Worker
2236*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetFinishingValues: Returning %d.", num_values));
2237*5e7646d2SAndroid Build Coastguard Worker
2238*5e7646d2SAndroid Build Coastguard Worker return (num_values);
2239*5e7646d2SAndroid Build Coastguard Worker }
2240*5e7646d2SAndroid Build Coastguard Worker
2241*5e7646d2SAndroid Build Coastguard Worker
2242*5e7646d2SAndroid Build Coastguard Worker /*
2243*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetInputSlot()' - Get the PPD InputSlot associated with the job
2244*5e7646d2SAndroid Build Coastguard Worker * attributes or a keyword string.
2245*5e7646d2SAndroid Build Coastguard Worker */
2246*5e7646d2SAndroid Build Coastguard Worker
2247*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PPD InputSlot or NULL */
_ppdCacheGetInputSlot(_ppd_cache_t * pc,ipp_t * job,const char * keyword)2248*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetInputSlot(
2249*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2250*5e7646d2SAndroid Build Coastguard Worker ipp_t *job, /* I - Job attributes or NULL */
2251*5e7646d2SAndroid Build Coastguard Worker const char *keyword) /* I - Keyword string or NULL */
2252*5e7646d2SAndroid Build Coastguard Worker {
2253*5e7646d2SAndroid Build Coastguard Worker /*
2254*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2255*5e7646d2SAndroid Build Coastguard Worker */
2256*5e7646d2SAndroid Build Coastguard Worker
2257*5e7646d2SAndroid Build Coastguard Worker if (!pc || pc->num_sources == 0 || (!job && !keyword))
2258*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2259*5e7646d2SAndroid Build Coastguard Worker
2260*5e7646d2SAndroid Build Coastguard Worker if (job && !keyword)
2261*5e7646d2SAndroid Build Coastguard Worker {
2262*5e7646d2SAndroid Build Coastguard Worker /*
2263*5e7646d2SAndroid Build Coastguard Worker * Lookup the media-col attribute and any media-source found there...
2264*5e7646d2SAndroid Build Coastguard Worker */
2265*5e7646d2SAndroid Build Coastguard Worker
2266*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *media_col, /* media-col attribute */
2267*5e7646d2SAndroid Build Coastguard Worker *media_source; /* media-source attribute */
2268*5e7646d2SAndroid Build Coastguard Worker pwg_size_t size; /* Dimensional size */
2269*5e7646d2SAndroid Build Coastguard Worker int margins_set; /* Were the margins set? */
2270*5e7646d2SAndroid Build Coastguard Worker
2271*5e7646d2SAndroid Build Coastguard Worker media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
2272*5e7646d2SAndroid Build Coastguard Worker if (media_col &&
2273*5e7646d2SAndroid Build Coastguard Worker (media_source = ippFindAttribute(ippGetCollection(media_col, 0),
2274*5e7646d2SAndroid Build Coastguard Worker "media-source",
2275*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) != NULL)
2276*5e7646d2SAndroid Build Coastguard Worker {
2277*5e7646d2SAndroid Build Coastguard Worker /*
2278*5e7646d2SAndroid Build Coastguard Worker * Use the media-source value from media-col...
2279*5e7646d2SAndroid Build Coastguard Worker */
2280*5e7646d2SAndroid Build Coastguard Worker
2281*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(media_source, 0, NULL);
2282*5e7646d2SAndroid Build Coastguard Worker }
2283*5e7646d2SAndroid Build Coastguard Worker else if (pwgInitSize(&size, job, &margins_set))
2284*5e7646d2SAndroid Build Coastguard Worker {
2285*5e7646d2SAndroid Build Coastguard Worker /*
2286*5e7646d2SAndroid Build Coastguard Worker * For media <= 5x7, look for a photo tray...
2287*5e7646d2SAndroid Build Coastguard Worker */
2288*5e7646d2SAndroid Build Coastguard Worker
2289*5e7646d2SAndroid Build Coastguard Worker if (size.width <= (5 * 2540) && size.length <= (7 * 2540))
2290*5e7646d2SAndroid Build Coastguard Worker keyword = "photo";
2291*5e7646d2SAndroid Build Coastguard Worker }
2292*5e7646d2SAndroid Build Coastguard Worker }
2293*5e7646d2SAndroid Build Coastguard Worker
2294*5e7646d2SAndroid Build Coastguard Worker if (keyword)
2295*5e7646d2SAndroid Build Coastguard Worker {
2296*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2297*5e7646d2SAndroid Build Coastguard Worker
2298*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < pc->num_sources; i ++)
2299*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(keyword, pc->sources[i].pwg))
2300*5e7646d2SAndroid Build Coastguard Worker return (pc->sources[i].ppd);
2301*5e7646d2SAndroid Build Coastguard Worker }
2302*5e7646d2SAndroid Build Coastguard Worker
2303*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2304*5e7646d2SAndroid Build Coastguard Worker }
2305*5e7646d2SAndroid Build Coastguard Worker
2306*5e7646d2SAndroid Build Coastguard Worker
2307*5e7646d2SAndroid Build Coastguard Worker /*
2308*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetMediaType()' - Get the PPD MediaType associated with the job
2309*5e7646d2SAndroid Build Coastguard Worker * attributes or a keyword string.
2310*5e7646d2SAndroid Build Coastguard Worker */
2311*5e7646d2SAndroid Build Coastguard Worker
2312*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PPD MediaType or NULL */
_ppdCacheGetMediaType(_ppd_cache_t * pc,ipp_t * job,const char * keyword)2313*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetMediaType(
2314*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2315*5e7646d2SAndroid Build Coastguard Worker ipp_t *job, /* I - Job attributes or NULL */
2316*5e7646d2SAndroid Build Coastguard Worker const char *keyword) /* I - Keyword string or NULL */
2317*5e7646d2SAndroid Build Coastguard Worker {
2318*5e7646d2SAndroid Build Coastguard Worker /*
2319*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2320*5e7646d2SAndroid Build Coastguard Worker */
2321*5e7646d2SAndroid Build Coastguard Worker
2322*5e7646d2SAndroid Build Coastguard Worker if (!pc || pc->num_types == 0 || (!job && !keyword))
2323*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2324*5e7646d2SAndroid Build Coastguard Worker
2325*5e7646d2SAndroid Build Coastguard Worker if (job && !keyword)
2326*5e7646d2SAndroid Build Coastguard Worker {
2327*5e7646d2SAndroid Build Coastguard Worker /*
2328*5e7646d2SAndroid Build Coastguard Worker * Lookup the media-col attribute and any media-source found there...
2329*5e7646d2SAndroid Build Coastguard Worker */
2330*5e7646d2SAndroid Build Coastguard Worker
2331*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *media_col, /* media-col attribute */
2332*5e7646d2SAndroid Build Coastguard Worker *media_type; /* media-type attribute */
2333*5e7646d2SAndroid Build Coastguard Worker
2334*5e7646d2SAndroid Build Coastguard Worker media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
2335*5e7646d2SAndroid Build Coastguard Worker if (media_col)
2336*5e7646d2SAndroid Build Coastguard Worker {
2337*5e7646d2SAndroid Build Coastguard Worker if ((media_type = ippFindAttribute(media_col->values[0].collection,
2338*5e7646d2SAndroid Build Coastguard Worker "media-type",
2339*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_KEYWORD)) == NULL)
2340*5e7646d2SAndroid Build Coastguard Worker media_type = ippFindAttribute(media_col->values[0].collection,
2341*5e7646d2SAndroid Build Coastguard Worker "media-type", IPP_TAG_NAME);
2342*5e7646d2SAndroid Build Coastguard Worker
2343*5e7646d2SAndroid Build Coastguard Worker if (media_type)
2344*5e7646d2SAndroid Build Coastguard Worker keyword = media_type->values[0].string.text;
2345*5e7646d2SAndroid Build Coastguard Worker }
2346*5e7646d2SAndroid Build Coastguard Worker }
2347*5e7646d2SAndroid Build Coastguard Worker
2348*5e7646d2SAndroid Build Coastguard Worker if (keyword)
2349*5e7646d2SAndroid Build Coastguard Worker {
2350*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2351*5e7646d2SAndroid Build Coastguard Worker
2352*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < pc->num_types; i ++)
2353*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(keyword, pc->types[i].pwg))
2354*5e7646d2SAndroid Build Coastguard Worker return (pc->types[i].ppd);
2355*5e7646d2SAndroid Build Coastguard Worker }
2356*5e7646d2SAndroid Build Coastguard Worker
2357*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2358*5e7646d2SAndroid Build Coastguard Worker }
2359*5e7646d2SAndroid Build Coastguard Worker
2360*5e7646d2SAndroid Build Coastguard Worker
2361*5e7646d2SAndroid Build Coastguard Worker /*
2362*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetOutputBin()' - Get the PPD OutputBin associated with the keyword
2363*5e7646d2SAndroid Build Coastguard Worker * string.
2364*5e7646d2SAndroid Build Coastguard Worker */
2365*5e7646d2SAndroid Build Coastguard Worker
2366*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PPD OutputBin or NULL */
_ppdCacheGetOutputBin(_ppd_cache_t * pc,const char * output_bin)2367*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetOutputBin(
2368*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2369*5e7646d2SAndroid Build Coastguard Worker const char *output_bin) /* I - Keyword string */
2370*5e7646d2SAndroid Build Coastguard Worker {
2371*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2372*5e7646d2SAndroid Build Coastguard Worker
2373*5e7646d2SAndroid Build Coastguard Worker
2374*5e7646d2SAndroid Build Coastguard Worker /*
2375*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2376*5e7646d2SAndroid Build Coastguard Worker */
2377*5e7646d2SAndroid Build Coastguard Worker
2378*5e7646d2SAndroid Build Coastguard Worker if (!pc || !output_bin)
2379*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2380*5e7646d2SAndroid Build Coastguard Worker
2381*5e7646d2SAndroid Build Coastguard Worker /*
2382*5e7646d2SAndroid Build Coastguard Worker * Look up the OutputBin string...
2383*5e7646d2SAndroid Build Coastguard Worker */
2384*5e7646d2SAndroid Build Coastguard Worker
2385*5e7646d2SAndroid Build Coastguard Worker
2386*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < pc->num_bins; i ++)
2387*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(output_bin, pc->bins[i].pwg))
2388*5e7646d2SAndroid Build Coastguard Worker return (pc->bins[i].ppd);
2389*5e7646d2SAndroid Build Coastguard Worker
2390*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2391*5e7646d2SAndroid Build Coastguard Worker }
2392*5e7646d2SAndroid Build Coastguard Worker
2393*5e7646d2SAndroid Build Coastguard Worker
2394*5e7646d2SAndroid Build Coastguard Worker /*
2395*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetPageSize()' - Get the PPD PageSize associated with the job
2396*5e7646d2SAndroid Build Coastguard Worker * attributes or a keyword string.
2397*5e7646d2SAndroid Build Coastguard Worker */
2398*5e7646d2SAndroid Build Coastguard Worker
2399*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PPD PageSize or NULL */
_ppdCacheGetPageSize(_ppd_cache_t * pc,ipp_t * job,const char * keyword,int * exact)2400*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetPageSize(
2401*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2402*5e7646d2SAndroid Build Coastguard Worker ipp_t *job, /* I - Job attributes or NULL */
2403*5e7646d2SAndroid Build Coastguard Worker const char *keyword, /* I - Keyword string or NULL */
2404*5e7646d2SAndroid Build Coastguard Worker int *exact) /* O - 1 if exact match, 0 otherwise */
2405*5e7646d2SAndroid Build Coastguard Worker {
2406*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2407*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size, /* Current size */
2408*5e7646d2SAndroid Build Coastguard Worker *closest, /* Closest size */
2409*5e7646d2SAndroid Build Coastguard Worker jobsize; /* Size data from job */
2410*5e7646d2SAndroid Build Coastguard Worker int margins_set, /* Were the margins set? */
2411*5e7646d2SAndroid Build Coastguard Worker dwidth, /* Difference in width */
2412*5e7646d2SAndroid Build Coastguard Worker dlength, /* Difference in length */
2413*5e7646d2SAndroid Build Coastguard Worker dleft, /* Difference in left margins */
2414*5e7646d2SAndroid Build Coastguard Worker dright, /* Difference in right margins */
2415*5e7646d2SAndroid Build Coastguard Worker dbottom, /* Difference in bottom margins */
2416*5e7646d2SAndroid Build Coastguard Worker dtop, /* Difference in top margins */
2417*5e7646d2SAndroid Build Coastguard Worker dmin, /* Minimum difference */
2418*5e7646d2SAndroid Build Coastguard Worker dclosest; /* Closest difference */
2419*5e7646d2SAndroid Build Coastguard Worker const char *ppd_name; /* PPD media name */
2420*5e7646d2SAndroid Build Coastguard Worker
2421*5e7646d2SAndroid Build Coastguard Worker
2422*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_ppdCacheGetPageSize(pc=%p, job=%p, keyword=\"%s\", exact=%p)",
2423*5e7646d2SAndroid Build Coastguard Worker pc, job, keyword, exact));
2424*5e7646d2SAndroid Build Coastguard Worker
2425*5e7646d2SAndroid Build Coastguard Worker /*
2426*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2427*5e7646d2SAndroid Build Coastguard Worker */
2428*5e7646d2SAndroid Build Coastguard Worker
2429*5e7646d2SAndroid Build Coastguard Worker if (!pc || (!job && !keyword))
2430*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2431*5e7646d2SAndroid Build Coastguard Worker
2432*5e7646d2SAndroid Build Coastguard Worker if (exact)
2433*5e7646d2SAndroid Build Coastguard Worker *exact = 0;
2434*5e7646d2SAndroid Build Coastguard Worker
2435*5e7646d2SAndroid Build Coastguard Worker ppd_name = keyword;
2436*5e7646d2SAndroid Build Coastguard Worker
2437*5e7646d2SAndroid Build Coastguard Worker if (job)
2438*5e7646d2SAndroid Build Coastguard Worker {
2439*5e7646d2SAndroid Build Coastguard Worker /*
2440*5e7646d2SAndroid Build Coastguard Worker * Try getting the PPD media name from the job attributes...
2441*5e7646d2SAndroid Build Coastguard Worker */
2442*5e7646d2SAndroid Build Coastguard Worker
2443*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Job attribute */
2444*5e7646d2SAndroid Build Coastguard Worker
2445*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job, "PageSize", IPP_TAG_ZERO)) == NULL)
2446*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(job, "PageRegion", IPP_TAG_ZERO)) == NULL)
2447*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(job, "media", IPP_TAG_ZERO);
2448*5e7646d2SAndroid Build Coastguard Worker
2449*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
2450*5e7646d2SAndroid Build Coastguard Worker if (attr)
2451*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: Found attribute %s (%s)",
2452*5e7646d2SAndroid Build Coastguard Worker attr->name, ippTagString(attr->value_tag)));
2453*5e7646d2SAndroid Build Coastguard Worker else
2454*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_ppdCacheGetPageSize: Did not find media attribute.");
2455*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
2456*5e7646d2SAndroid Build Coastguard Worker
2457*5e7646d2SAndroid Build Coastguard Worker if (attr && (attr->value_tag == IPP_TAG_NAME ||
2458*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_KEYWORD))
2459*5e7646d2SAndroid Build Coastguard Worker ppd_name = attr->values[0].string.text;
2460*5e7646d2SAndroid Build Coastguard Worker }
2461*5e7646d2SAndroid Build Coastguard Worker
2462*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: ppd_name=\"%s\"", ppd_name));
2463*5e7646d2SAndroid Build Coastguard Worker
2464*5e7646d2SAndroid Build Coastguard Worker if (ppd_name)
2465*5e7646d2SAndroid Build Coastguard Worker {
2466*5e7646d2SAndroid Build Coastguard Worker /*
2467*5e7646d2SAndroid Build Coastguard Worker * Try looking up the named PPD size first...
2468*5e7646d2SAndroid Build Coastguard Worker */
2469*5e7646d2SAndroid Build Coastguard Worker
2470*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
2471*5e7646d2SAndroid Build Coastguard Worker {
2472*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2_ppdCacheGetPageSize: size[%d]=[\"%s\" \"%s\"]",
2473*5e7646d2SAndroid Build Coastguard Worker (int)(size - pc->sizes), size->map.pwg, size->map.ppd));
2474*5e7646d2SAndroid Build Coastguard Worker
2475*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ppd_name, size->map.ppd) ||
2476*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(ppd_name, size->map.pwg))
2477*5e7646d2SAndroid Build Coastguard Worker {
2478*5e7646d2SAndroid Build Coastguard Worker if (exact)
2479*5e7646d2SAndroid Build Coastguard Worker *exact = 1;
2480*5e7646d2SAndroid Build Coastguard Worker
2481*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\"", ppd_name));
2482*5e7646d2SAndroid Build Coastguard Worker
2483*5e7646d2SAndroid Build Coastguard Worker return (size->map.ppd);
2484*5e7646d2SAndroid Build Coastguard Worker }
2485*5e7646d2SAndroid Build Coastguard Worker }
2486*5e7646d2SAndroid Build Coastguard Worker }
2487*5e7646d2SAndroid Build Coastguard Worker
2488*5e7646d2SAndroid Build Coastguard Worker if (job && !keyword)
2489*5e7646d2SAndroid Build Coastguard Worker {
2490*5e7646d2SAndroid Build Coastguard Worker /*
2491*5e7646d2SAndroid Build Coastguard Worker * Get the size using media-col or media, with the preference being
2492*5e7646d2SAndroid Build Coastguard Worker * media-col.
2493*5e7646d2SAndroid Build Coastguard Worker */
2494*5e7646d2SAndroid Build Coastguard Worker
2495*5e7646d2SAndroid Build Coastguard Worker if (!pwgInitSize(&jobsize, job, &margins_set))
2496*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2497*5e7646d2SAndroid Build Coastguard Worker }
2498*5e7646d2SAndroid Build Coastguard Worker else
2499*5e7646d2SAndroid Build Coastguard Worker {
2500*5e7646d2SAndroid Build Coastguard Worker /*
2501*5e7646d2SAndroid Build Coastguard Worker * Get the size using a media keyword...
2502*5e7646d2SAndroid Build Coastguard Worker */
2503*5e7646d2SAndroid Build Coastguard Worker
2504*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *media; /* Media definition */
2505*5e7646d2SAndroid Build Coastguard Worker
2506*5e7646d2SAndroid Build Coastguard Worker
2507*5e7646d2SAndroid Build Coastguard Worker if ((media = pwgMediaForPWG(keyword)) == NULL)
2508*5e7646d2SAndroid Build Coastguard Worker if ((media = pwgMediaForLegacy(keyword)) == NULL)
2509*5e7646d2SAndroid Build Coastguard Worker if ((media = pwgMediaForPPD(keyword)) == NULL)
2510*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2511*5e7646d2SAndroid Build Coastguard Worker
2512*5e7646d2SAndroid Build Coastguard Worker jobsize.width = media->width;
2513*5e7646d2SAndroid Build Coastguard Worker jobsize.length = media->length;
2514*5e7646d2SAndroid Build Coastguard Worker margins_set = 0;
2515*5e7646d2SAndroid Build Coastguard Worker }
2516*5e7646d2SAndroid Build Coastguard Worker
2517*5e7646d2SAndroid Build Coastguard Worker /*
2518*5e7646d2SAndroid Build Coastguard Worker * Now that we have the dimensions and possibly the margins, look at the
2519*5e7646d2SAndroid Build Coastguard Worker * available sizes and find the match...
2520*5e7646d2SAndroid Build Coastguard Worker */
2521*5e7646d2SAndroid Build Coastguard Worker
2522*5e7646d2SAndroid Build Coastguard Worker closest = NULL;
2523*5e7646d2SAndroid Build Coastguard Worker dclosest = 999999999;
2524*5e7646d2SAndroid Build Coastguard Worker
2525*5e7646d2SAndroid Build Coastguard Worker if (!ppd_name || _cups_strncasecmp(ppd_name, "Custom.", 7) ||
2526*5e7646d2SAndroid Build Coastguard Worker _cups_strncasecmp(ppd_name, "custom_", 7))
2527*5e7646d2SAndroid Build Coastguard Worker {
2528*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
2529*5e7646d2SAndroid Build Coastguard Worker {
2530*5e7646d2SAndroid Build Coastguard Worker /*
2531*5e7646d2SAndroid Build Coastguard Worker * Adobe uses a size matching algorithm with an epsilon of 5 points, which
2532*5e7646d2SAndroid Build Coastguard Worker * is just about 176/2540ths...
2533*5e7646d2SAndroid Build Coastguard Worker */
2534*5e7646d2SAndroid Build Coastguard Worker
2535*5e7646d2SAndroid Build Coastguard Worker dwidth = size->width - jobsize.width;
2536*5e7646d2SAndroid Build Coastguard Worker dlength = size->length - jobsize.length;
2537*5e7646d2SAndroid Build Coastguard Worker
2538*5e7646d2SAndroid Build Coastguard Worker if (dwidth <= -176 || dwidth >= 176 || dlength <= -176 || dlength >= 176)
2539*5e7646d2SAndroid Build Coastguard Worker continue;
2540*5e7646d2SAndroid Build Coastguard Worker
2541*5e7646d2SAndroid Build Coastguard Worker if (margins_set)
2542*5e7646d2SAndroid Build Coastguard Worker {
2543*5e7646d2SAndroid Build Coastguard Worker /*
2544*5e7646d2SAndroid Build Coastguard Worker * Use a tighter epsilon of 1 point (35/2540ths) for margins...
2545*5e7646d2SAndroid Build Coastguard Worker */
2546*5e7646d2SAndroid Build Coastguard Worker
2547*5e7646d2SAndroid Build Coastguard Worker dleft = size->left - jobsize.left;
2548*5e7646d2SAndroid Build Coastguard Worker dright = size->right - jobsize.right;
2549*5e7646d2SAndroid Build Coastguard Worker dtop = size->top - jobsize.top;
2550*5e7646d2SAndroid Build Coastguard Worker dbottom = size->bottom - jobsize.bottom;
2551*5e7646d2SAndroid Build Coastguard Worker
2552*5e7646d2SAndroid Build Coastguard Worker if (dleft <= -35 || dleft >= 35 || dright <= -35 || dright >= 35 ||
2553*5e7646d2SAndroid Build Coastguard Worker dtop <= -35 || dtop >= 35 || dbottom <= -35 || dbottom >= 35)
2554*5e7646d2SAndroid Build Coastguard Worker {
2555*5e7646d2SAndroid Build Coastguard Worker dleft = dleft < 0 ? -dleft : dleft;
2556*5e7646d2SAndroid Build Coastguard Worker dright = dright < 0 ? -dright : dright;
2557*5e7646d2SAndroid Build Coastguard Worker dbottom = dbottom < 0 ? -dbottom : dbottom;
2558*5e7646d2SAndroid Build Coastguard Worker dtop = dtop < 0 ? -dtop : dtop;
2559*5e7646d2SAndroid Build Coastguard Worker dmin = dleft + dright + dbottom + dtop;
2560*5e7646d2SAndroid Build Coastguard Worker
2561*5e7646d2SAndroid Build Coastguard Worker if (dmin < dclosest)
2562*5e7646d2SAndroid Build Coastguard Worker {
2563*5e7646d2SAndroid Build Coastguard Worker dclosest = dmin;
2564*5e7646d2SAndroid Build Coastguard Worker closest = size;
2565*5e7646d2SAndroid Build Coastguard Worker }
2566*5e7646d2SAndroid Build Coastguard Worker
2567*5e7646d2SAndroid Build Coastguard Worker continue;
2568*5e7646d2SAndroid Build Coastguard Worker }
2569*5e7646d2SAndroid Build Coastguard Worker }
2570*5e7646d2SAndroid Build Coastguard Worker
2571*5e7646d2SAndroid Build Coastguard Worker if (exact)
2572*5e7646d2SAndroid Build Coastguard Worker *exact = 1;
2573*5e7646d2SAndroid Build Coastguard Worker
2574*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\"", size->map.ppd));
2575*5e7646d2SAndroid Build Coastguard Worker
2576*5e7646d2SAndroid Build Coastguard Worker return (size->map.ppd);
2577*5e7646d2SAndroid Build Coastguard Worker }
2578*5e7646d2SAndroid Build Coastguard Worker }
2579*5e7646d2SAndroid Build Coastguard Worker
2580*5e7646d2SAndroid Build Coastguard Worker if (closest)
2581*5e7646d2SAndroid Build Coastguard Worker {
2582*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\" (closest)",
2583*5e7646d2SAndroid Build Coastguard Worker closest->map.ppd));
2584*5e7646d2SAndroid Build Coastguard Worker
2585*5e7646d2SAndroid Build Coastguard Worker return (closest->map.ppd);
2586*5e7646d2SAndroid Build Coastguard Worker }
2587*5e7646d2SAndroid Build Coastguard Worker
2588*5e7646d2SAndroid Build Coastguard Worker /*
2589*5e7646d2SAndroid Build Coastguard Worker * If we get here we need to check for custom page size support...
2590*5e7646d2SAndroid Build Coastguard Worker */
2591*5e7646d2SAndroid Build Coastguard Worker
2592*5e7646d2SAndroid Build Coastguard Worker if (jobsize.width >= pc->custom_min_width &&
2593*5e7646d2SAndroid Build Coastguard Worker jobsize.width <= pc->custom_max_width &&
2594*5e7646d2SAndroid Build Coastguard Worker jobsize.length >= pc->custom_min_length &&
2595*5e7646d2SAndroid Build Coastguard Worker jobsize.length <= pc->custom_max_length)
2596*5e7646d2SAndroid Build Coastguard Worker {
2597*5e7646d2SAndroid Build Coastguard Worker /*
2598*5e7646d2SAndroid Build Coastguard Worker * In range, format as Custom.WWWWxLLLL (points).
2599*5e7646d2SAndroid Build Coastguard Worker */
2600*5e7646d2SAndroid Build Coastguard Worker
2601*5e7646d2SAndroid Build Coastguard Worker snprintf(pc->custom_ppd_size, sizeof(pc->custom_ppd_size), "Custom.%dx%d",
2602*5e7646d2SAndroid Build Coastguard Worker (int)PWG_TO_POINTS(jobsize.width), (int)PWG_TO_POINTS(jobsize.length));
2603*5e7646d2SAndroid Build Coastguard Worker
2604*5e7646d2SAndroid Build Coastguard Worker if (margins_set && exact)
2605*5e7646d2SAndroid Build Coastguard Worker {
2606*5e7646d2SAndroid Build Coastguard Worker dleft = pc->custom_size.left - jobsize.left;
2607*5e7646d2SAndroid Build Coastguard Worker dright = pc->custom_size.right - jobsize.right;
2608*5e7646d2SAndroid Build Coastguard Worker dtop = pc->custom_size.top - jobsize.top;
2609*5e7646d2SAndroid Build Coastguard Worker dbottom = pc->custom_size.bottom - jobsize.bottom;
2610*5e7646d2SAndroid Build Coastguard Worker
2611*5e7646d2SAndroid Build Coastguard Worker if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 &&
2612*5e7646d2SAndroid Build Coastguard Worker dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35)
2613*5e7646d2SAndroid Build Coastguard Worker *exact = 1;
2614*5e7646d2SAndroid Build Coastguard Worker }
2615*5e7646d2SAndroid Build Coastguard Worker else if (exact)
2616*5e7646d2SAndroid Build Coastguard Worker *exact = 1;
2617*5e7646d2SAndroid Build Coastguard Worker
2618*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\" (custom)",
2619*5e7646d2SAndroid Build Coastguard Worker pc->custom_ppd_size));
2620*5e7646d2SAndroid Build Coastguard Worker
2621*5e7646d2SAndroid Build Coastguard Worker return (pc->custom_ppd_size);
2622*5e7646d2SAndroid Build Coastguard Worker }
2623*5e7646d2SAndroid Build Coastguard Worker
2624*5e7646d2SAndroid Build Coastguard Worker /*
2625*5e7646d2SAndroid Build Coastguard Worker * No custom page size support or the size is out of range - return NULL.
2626*5e7646d2SAndroid Build Coastguard Worker */
2627*5e7646d2SAndroid Build Coastguard Worker
2628*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_ppdCacheGetPageSize: Returning NULL");
2629*5e7646d2SAndroid Build Coastguard Worker
2630*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2631*5e7646d2SAndroid Build Coastguard Worker }
2632*5e7646d2SAndroid Build Coastguard Worker
2633*5e7646d2SAndroid Build Coastguard Worker
2634*5e7646d2SAndroid Build Coastguard Worker /*
2635*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetSize()' - Get the PWG size associated with a PPD PageSize.
2636*5e7646d2SAndroid Build Coastguard Worker */
2637*5e7646d2SAndroid Build Coastguard Worker
2638*5e7646d2SAndroid Build Coastguard Worker pwg_size_t * /* O - PWG size or NULL */
_ppdCacheGetSize(_ppd_cache_t * pc,const char * page_size)2639*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetSize(
2640*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2641*5e7646d2SAndroid Build Coastguard Worker const char *page_size) /* I - PPD PageSize */
2642*5e7646d2SAndroid Build Coastguard Worker {
2643*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2644*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *media; /* Media */
2645*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size; /* Current size */
2646*5e7646d2SAndroid Build Coastguard Worker
2647*5e7646d2SAndroid Build Coastguard Worker
2648*5e7646d2SAndroid Build Coastguard Worker /*
2649*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2650*5e7646d2SAndroid Build Coastguard Worker */
2651*5e7646d2SAndroid Build Coastguard Worker
2652*5e7646d2SAndroid Build Coastguard Worker if (!pc || !page_size)
2653*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2654*5e7646d2SAndroid Build Coastguard Worker
2655*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(page_size, "Custom.", 7))
2656*5e7646d2SAndroid Build Coastguard Worker {
2657*5e7646d2SAndroid Build Coastguard Worker /*
2658*5e7646d2SAndroid Build Coastguard Worker * Custom size; size name can be one of the following:
2659*5e7646d2SAndroid Build Coastguard Worker *
2660*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTHin - Size in inches
2661*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTHft - Size in feet
2662*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTHcm - Size in centimeters
2663*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTHmm - Size in millimeters
2664*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTHm - Size in meters
2665*5e7646d2SAndroid Build Coastguard Worker * Custom.WIDTHxLENGTH[pt] - Size in points
2666*5e7646d2SAndroid Build Coastguard Worker */
2667*5e7646d2SAndroid Build Coastguard Worker
2668*5e7646d2SAndroid Build Coastguard Worker double w, l; /* Width and length of page */
2669*5e7646d2SAndroid Build Coastguard Worker char *ptr; /* Pointer into PageSize */
2670*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc; /* Locale data */
2671*5e7646d2SAndroid Build Coastguard Worker
2672*5e7646d2SAndroid Build Coastguard Worker loc = localeconv();
2673*5e7646d2SAndroid Build Coastguard Worker w = (float)_cupsStrScand(page_size + 7, &ptr, loc);
2674*5e7646d2SAndroid Build Coastguard Worker if (!ptr || *ptr != 'x')
2675*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2676*5e7646d2SAndroid Build Coastguard Worker
2677*5e7646d2SAndroid Build Coastguard Worker l = (float)_cupsStrScand(ptr + 1, &ptr, loc);
2678*5e7646d2SAndroid Build Coastguard Worker if (!ptr)
2679*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2680*5e7646d2SAndroid Build Coastguard Worker
2681*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(ptr, "in"))
2682*5e7646d2SAndroid Build Coastguard Worker {
2683*5e7646d2SAndroid Build Coastguard Worker w *= 2540.0;
2684*5e7646d2SAndroid Build Coastguard Worker l *= 2540.0;
2685*5e7646d2SAndroid Build Coastguard Worker }
2686*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ptr, "ft"))
2687*5e7646d2SAndroid Build Coastguard Worker {
2688*5e7646d2SAndroid Build Coastguard Worker w *= 12.0 * 2540.0;
2689*5e7646d2SAndroid Build Coastguard Worker l *= 12.0 * 2540.0;
2690*5e7646d2SAndroid Build Coastguard Worker }
2691*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ptr, "mm"))
2692*5e7646d2SAndroid Build Coastguard Worker {
2693*5e7646d2SAndroid Build Coastguard Worker w *= 100.0;
2694*5e7646d2SAndroid Build Coastguard Worker l *= 100.0;
2695*5e7646d2SAndroid Build Coastguard Worker }
2696*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ptr, "cm"))
2697*5e7646d2SAndroid Build Coastguard Worker {
2698*5e7646d2SAndroid Build Coastguard Worker w *= 1000.0;
2699*5e7646d2SAndroid Build Coastguard Worker l *= 1000.0;
2700*5e7646d2SAndroid Build Coastguard Worker }
2701*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(ptr, "m"))
2702*5e7646d2SAndroid Build Coastguard Worker {
2703*5e7646d2SAndroid Build Coastguard Worker w *= 100000.0;
2704*5e7646d2SAndroid Build Coastguard Worker l *= 100000.0;
2705*5e7646d2SAndroid Build Coastguard Worker }
2706*5e7646d2SAndroid Build Coastguard Worker else
2707*5e7646d2SAndroid Build Coastguard Worker {
2708*5e7646d2SAndroid Build Coastguard Worker w *= 2540.0 / 72.0;
2709*5e7646d2SAndroid Build Coastguard Worker l *= 2540.0 / 72.0;
2710*5e7646d2SAndroid Build Coastguard Worker }
2711*5e7646d2SAndroid Build Coastguard Worker
2712*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.width = (int)w;
2713*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.length = (int)l;
2714*5e7646d2SAndroid Build Coastguard Worker
2715*5e7646d2SAndroid Build Coastguard Worker return (&(pc->custom_size));
2716*5e7646d2SAndroid Build Coastguard Worker }
2717*5e7646d2SAndroid Build Coastguard Worker
2718*5e7646d2SAndroid Build Coastguard Worker /*
2719*5e7646d2SAndroid Build Coastguard Worker * Not a custom size - look it up...
2720*5e7646d2SAndroid Build Coastguard Worker */
2721*5e7646d2SAndroid Build Coastguard Worker
2722*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
2723*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(page_size, size->map.ppd) ||
2724*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(page_size, size->map.pwg))
2725*5e7646d2SAndroid Build Coastguard Worker return (size);
2726*5e7646d2SAndroid Build Coastguard Worker
2727*5e7646d2SAndroid Build Coastguard Worker /*
2728*5e7646d2SAndroid Build Coastguard Worker * Look up standard sizes...
2729*5e7646d2SAndroid Build Coastguard Worker */
2730*5e7646d2SAndroid Build Coastguard Worker
2731*5e7646d2SAndroid Build Coastguard Worker if ((media = pwgMediaForPPD(page_size)) == NULL)
2732*5e7646d2SAndroid Build Coastguard Worker if ((media = pwgMediaForLegacy(page_size)) == NULL)
2733*5e7646d2SAndroid Build Coastguard Worker media = pwgMediaForPWG(page_size);
2734*5e7646d2SAndroid Build Coastguard Worker
2735*5e7646d2SAndroid Build Coastguard Worker if (media)
2736*5e7646d2SAndroid Build Coastguard Worker {
2737*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.width = media->width;
2738*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.length = media->length;
2739*5e7646d2SAndroid Build Coastguard Worker
2740*5e7646d2SAndroid Build Coastguard Worker return (&(pc->custom_size));
2741*5e7646d2SAndroid Build Coastguard Worker }
2742*5e7646d2SAndroid Build Coastguard Worker
2743*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2744*5e7646d2SAndroid Build Coastguard Worker }
2745*5e7646d2SAndroid Build Coastguard Worker
2746*5e7646d2SAndroid Build Coastguard Worker
2747*5e7646d2SAndroid Build Coastguard Worker /*
2748*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetSource()' - Get the PWG media-source associated with a PPD
2749*5e7646d2SAndroid Build Coastguard Worker * InputSlot.
2750*5e7646d2SAndroid Build Coastguard Worker */
2751*5e7646d2SAndroid Build Coastguard Worker
2752*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PWG media-source keyword */
_ppdCacheGetSource(_ppd_cache_t * pc,const char * input_slot)2753*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetSource(
2754*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2755*5e7646d2SAndroid Build Coastguard Worker const char *input_slot) /* I - PPD InputSlot */
2756*5e7646d2SAndroid Build Coastguard Worker {
2757*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2758*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *source; /* Current source */
2759*5e7646d2SAndroid Build Coastguard Worker
2760*5e7646d2SAndroid Build Coastguard Worker
2761*5e7646d2SAndroid Build Coastguard Worker /*
2762*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2763*5e7646d2SAndroid Build Coastguard Worker */
2764*5e7646d2SAndroid Build Coastguard Worker
2765*5e7646d2SAndroid Build Coastguard Worker if (!pc || !input_slot)
2766*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2767*5e7646d2SAndroid Build Coastguard Worker
2768*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sources, source = pc->sources; i > 0; i --, source ++)
2769*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(input_slot, source->ppd))
2770*5e7646d2SAndroid Build Coastguard Worker return (source->pwg);
2771*5e7646d2SAndroid Build Coastguard Worker
2772*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2773*5e7646d2SAndroid Build Coastguard Worker }
2774*5e7646d2SAndroid Build Coastguard Worker
2775*5e7646d2SAndroid Build Coastguard Worker
2776*5e7646d2SAndroid Build Coastguard Worker /*
2777*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheGetType()' - Get the PWG media-type associated with a PPD
2778*5e7646d2SAndroid Build Coastguard Worker * MediaType.
2779*5e7646d2SAndroid Build Coastguard Worker */
2780*5e7646d2SAndroid Build Coastguard Worker
2781*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PWG media-type keyword */
_ppdCacheGetType(_ppd_cache_t * pc,const char * media_type)2782*5e7646d2SAndroid Build Coastguard Worker _ppdCacheGetType(
2783*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2784*5e7646d2SAndroid Build Coastguard Worker const char *media_type) /* I - PPD MediaType */
2785*5e7646d2SAndroid Build Coastguard Worker {
2786*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2787*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *type; /* Current type */
2788*5e7646d2SAndroid Build Coastguard Worker
2789*5e7646d2SAndroid Build Coastguard Worker
2790*5e7646d2SAndroid Build Coastguard Worker /*
2791*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2792*5e7646d2SAndroid Build Coastguard Worker */
2793*5e7646d2SAndroid Build Coastguard Worker
2794*5e7646d2SAndroid Build Coastguard Worker if (!pc || !media_type)
2795*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2796*5e7646d2SAndroid Build Coastguard Worker
2797*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_types, type = pc->types; i > 0; i --, type ++)
2798*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(media_type, type->ppd))
2799*5e7646d2SAndroid Build Coastguard Worker return (type->pwg);
2800*5e7646d2SAndroid Build Coastguard Worker
2801*5e7646d2SAndroid Build Coastguard Worker return (NULL);
2802*5e7646d2SAndroid Build Coastguard Worker }
2803*5e7646d2SAndroid Build Coastguard Worker
2804*5e7646d2SAndroid Build Coastguard Worker
2805*5e7646d2SAndroid Build Coastguard Worker /*
2806*5e7646d2SAndroid Build Coastguard Worker * '_ppdCacheWriteFile()' - Write PWG mapping data to a file.
2807*5e7646d2SAndroid Build Coastguard Worker */
2808*5e7646d2SAndroid Build Coastguard Worker
2809*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
_ppdCacheWriteFile(_ppd_cache_t * pc,const char * filename,ipp_t * attrs)2810*5e7646d2SAndroid Build Coastguard Worker _ppdCacheWriteFile(
2811*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *pc, /* I - PPD cache and mapping data */
2812*5e7646d2SAndroid Build Coastguard Worker const char *filename, /* I - File to write */
2813*5e7646d2SAndroid Build Coastguard Worker ipp_t *attrs) /* I - Attributes to write, if any */
2814*5e7646d2SAndroid Build Coastguard Worker {
2815*5e7646d2SAndroid Build Coastguard Worker int i, j, k; /* Looping vars */
2816*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* Output file */
2817*5e7646d2SAndroid Build Coastguard Worker pwg_size_t *size; /* Current size */
2818*5e7646d2SAndroid Build Coastguard Worker pwg_map_t *map; /* Current map */
2819*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *f; /* Current finishing option */
2820*5e7646d2SAndroid Build Coastguard Worker cups_option_t *option; /* Current option */
2821*5e7646d2SAndroid Build Coastguard Worker const char *value; /* String value */
2822*5e7646d2SAndroid Build Coastguard Worker char newfile[1024]; /* New filename */
2823*5e7646d2SAndroid Build Coastguard Worker
2824*5e7646d2SAndroid Build Coastguard Worker
2825*5e7646d2SAndroid Build Coastguard Worker /*
2826*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2827*5e7646d2SAndroid Build Coastguard Worker */
2828*5e7646d2SAndroid Build Coastguard Worker
2829*5e7646d2SAndroid Build Coastguard Worker if (!pc || !filename)
2830*5e7646d2SAndroid Build Coastguard Worker {
2831*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
2832*5e7646d2SAndroid Build Coastguard Worker return (0);
2833*5e7646d2SAndroid Build Coastguard Worker }
2834*5e7646d2SAndroid Build Coastguard Worker
2835*5e7646d2SAndroid Build Coastguard Worker /*
2836*5e7646d2SAndroid Build Coastguard Worker * Open the file and write with compression...
2837*5e7646d2SAndroid Build Coastguard Worker */
2838*5e7646d2SAndroid Build Coastguard Worker
2839*5e7646d2SAndroid Build Coastguard Worker snprintf(newfile, sizeof(newfile), "%s.N", filename);
2840*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen(newfile, "w9")) == NULL)
2841*5e7646d2SAndroid Build Coastguard Worker {
2842*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
2843*5e7646d2SAndroid Build Coastguard Worker return (0);
2844*5e7646d2SAndroid Build Coastguard Worker }
2845*5e7646d2SAndroid Build Coastguard Worker
2846*5e7646d2SAndroid Build Coastguard Worker /*
2847*5e7646d2SAndroid Build Coastguard Worker * Standard header...
2848*5e7646d2SAndroid Build Coastguard Worker */
2849*5e7646d2SAndroid Build Coastguard Worker
2850*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "#CUPS-PPD-CACHE-%d\n", _PPD_CACHE_VERSION);
2851*5e7646d2SAndroid Build Coastguard Worker
2852*5e7646d2SAndroid Build Coastguard Worker /*
2853*5e7646d2SAndroid Build Coastguard Worker * Output bins...
2854*5e7646d2SAndroid Build Coastguard Worker */
2855*5e7646d2SAndroid Build Coastguard Worker
2856*5e7646d2SAndroid Build Coastguard Worker if (pc->num_bins > 0)
2857*5e7646d2SAndroid Build Coastguard Worker {
2858*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NumBins %d\n", pc->num_bins);
2859*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++)
2860*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Bin %s %s\n", map->pwg, map->ppd);
2861*5e7646d2SAndroid Build Coastguard Worker }
2862*5e7646d2SAndroid Build Coastguard Worker
2863*5e7646d2SAndroid Build Coastguard Worker /*
2864*5e7646d2SAndroid Build Coastguard Worker * Media sizes...
2865*5e7646d2SAndroid Build Coastguard Worker */
2866*5e7646d2SAndroid Build Coastguard Worker
2867*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NumSizes %d\n", pc->num_sizes);
2868*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
2869*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Size %s %s %d %d %d %d %d %d\n", size->map.pwg,
2870*5e7646d2SAndroid Build Coastguard Worker size->map.ppd, size->width, size->length, size->left,
2871*5e7646d2SAndroid Build Coastguard Worker size->bottom, size->right, size->top);
2872*5e7646d2SAndroid Build Coastguard Worker if (pc->custom_max_width > 0)
2873*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "CustomSize %d %d %d %d %d %d %d %d\n",
2874*5e7646d2SAndroid Build Coastguard Worker pc->custom_max_width, pc->custom_max_length,
2875*5e7646d2SAndroid Build Coastguard Worker pc->custom_min_width, pc->custom_min_length,
2876*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.left, pc->custom_size.bottom,
2877*5e7646d2SAndroid Build Coastguard Worker pc->custom_size.right, pc->custom_size.top);
2878*5e7646d2SAndroid Build Coastguard Worker
2879*5e7646d2SAndroid Build Coastguard Worker /*
2880*5e7646d2SAndroid Build Coastguard Worker * Media sources...
2881*5e7646d2SAndroid Build Coastguard Worker */
2882*5e7646d2SAndroid Build Coastguard Worker
2883*5e7646d2SAndroid Build Coastguard Worker if (pc->source_option)
2884*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "SourceOption %s\n", pc->source_option);
2885*5e7646d2SAndroid Build Coastguard Worker
2886*5e7646d2SAndroid Build Coastguard Worker if (pc->num_sources > 0)
2887*5e7646d2SAndroid Build Coastguard Worker {
2888*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NumSources %d\n", pc->num_sources);
2889*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++)
2890*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Source %s %s\n", map->pwg, map->ppd);
2891*5e7646d2SAndroid Build Coastguard Worker }
2892*5e7646d2SAndroid Build Coastguard Worker
2893*5e7646d2SAndroid Build Coastguard Worker /*
2894*5e7646d2SAndroid Build Coastguard Worker * Media types...
2895*5e7646d2SAndroid Build Coastguard Worker */
2896*5e7646d2SAndroid Build Coastguard Worker
2897*5e7646d2SAndroid Build Coastguard Worker if (pc->num_types > 0)
2898*5e7646d2SAndroid Build Coastguard Worker {
2899*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "NumTypes %d\n", pc->num_types);
2900*5e7646d2SAndroid Build Coastguard Worker for (i = pc->num_types, map = pc->types; i > 0; i --, map ++)
2901*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd);
2902*5e7646d2SAndroid Build Coastguard Worker }
2903*5e7646d2SAndroid Build Coastguard Worker
2904*5e7646d2SAndroid Build Coastguard Worker /*
2905*5e7646d2SAndroid Build Coastguard Worker * Presets...
2906*5e7646d2SAndroid Build Coastguard Worker */
2907*5e7646d2SAndroid Build Coastguard Worker
2908*5e7646d2SAndroid Build Coastguard Worker for (i = _PWG_PRINT_COLOR_MODE_MONOCHROME; i < _PWG_PRINT_COLOR_MODE_MAX; i ++)
2909*5e7646d2SAndroid Build Coastguard Worker for (j = _PWG_PRINT_QUALITY_DRAFT; j < _PWG_PRINT_QUALITY_MAX; j ++)
2910*5e7646d2SAndroid Build Coastguard Worker if (pc->num_presets[i][j])
2911*5e7646d2SAndroid Build Coastguard Worker {
2912*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Preset %d %d", i, j);
2913*5e7646d2SAndroid Build Coastguard Worker for (k = pc->num_presets[i][j], option = pc->presets[i][j];
2914*5e7646d2SAndroid Build Coastguard Worker k > 0;
2915*5e7646d2SAndroid Build Coastguard Worker k --, option ++)
2916*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, " %s=%s", option->name, option->value);
2917*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(fp, '\n');
2918*5e7646d2SAndroid Build Coastguard Worker }
2919*5e7646d2SAndroid Build Coastguard Worker
2920*5e7646d2SAndroid Build Coastguard Worker /*
2921*5e7646d2SAndroid Build Coastguard Worker * Duplex/sides...
2922*5e7646d2SAndroid Build Coastguard Worker */
2923*5e7646d2SAndroid Build Coastguard Worker
2924*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_option)
2925*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "SidesOption %s\n", pc->sides_option);
2926*5e7646d2SAndroid Build Coastguard Worker
2927*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_1sided)
2928*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Sides1Sided %s\n", pc->sides_1sided);
2929*5e7646d2SAndroid Build Coastguard Worker
2930*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_2sided_long)
2931*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Sides2SidedLong %s\n", pc->sides_2sided_long);
2932*5e7646d2SAndroid Build Coastguard Worker
2933*5e7646d2SAndroid Build Coastguard Worker if (pc->sides_2sided_short)
2934*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Sides2SidedShort %s\n", pc->sides_2sided_short);
2935*5e7646d2SAndroid Build Coastguard Worker
2936*5e7646d2SAndroid Build Coastguard Worker /*
2937*5e7646d2SAndroid Build Coastguard Worker * Product, cupsFilter, cupsFilter2, and cupsPreFilter...
2938*5e7646d2SAndroid Build Coastguard Worker */
2939*5e7646d2SAndroid Build Coastguard Worker
2940*5e7646d2SAndroid Build Coastguard Worker if (pc->product)
2941*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Product", pc->product);
2942*5e7646d2SAndroid Build Coastguard Worker
2943*5e7646d2SAndroid Build Coastguard Worker for (value = (const char *)cupsArrayFirst(pc->filters);
2944*5e7646d2SAndroid Build Coastguard Worker value;
2945*5e7646d2SAndroid Build Coastguard Worker value = (const char *)cupsArrayNext(pc->filters))
2946*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Filter", value);
2947*5e7646d2SAndroid Build Coastguard Worker
2948*5e7646d2SAndroid Build Coastguard Worker for (value = (const char *)cupsArrayFirst(pc->prefilters);
2949*5e7646d2SAndroid Build Coastguard Worker value;
2950*5e7646d2SAndroid Build Coastguard Worker value = (const char *)cupsArrayNext(pc->prefilters))
2951*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "PreFilter", value);
2952*5e7646d2SAndroid Build Coastguard Worker
2953*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "SingleFile %s\n", pc->single_file ? "true" : "false");
2954*5e7646d2SAndroid Build Coastguard Worker
2955*5e7646d2SAndroid Build Coastguard Worker /*
2956*5e7646d2SAndroid Build Coastguard Worker * Finishing options...
2957*5e7646d2SAndroid Build Coastguard Worker */
2958*5e7646d2SAndroid Build Coastguard Worker
2959*5e7646d2SAndroid Build Coastguard Worker for (f = (_pwg_finishings_t *)cupsArrayFirst(pc->finishings);
2960*5e7646d2SAndroid Build Coastguard Worker f;
2961*5e7646d2SAndroid Build Coastguard Worker f = (_pwg_finishings_t *)cupsArrayNext(pc->finishings))
2962*5e7646d2SAndroid Build Coastguard Worker {
2963*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Finishings %d", f->value);
2964*5e7646d2SAndroid Build Coastguard Worker for (i = f->num_options, option = f->options; i > 0; i --, option ++)
2965*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, " %s=%s", option->name, option->value);
2966*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(fp, '\n');
2967*5e7646d2SAndroid Build Coastguard Worker }
2968*5e7646d2SAndroid Build Coastguard Worker
2969*5e7646d2SAndroid Build Coastguard Worker for (value = (const char *)cupsArrayFirst(pc->templates); value; value = (const char *)cupsArrayNext(pc->templates))
2970*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "FinishingTemplate", value);
2971*5e7646d2SAndroid Build Coastguard Worker
2972*5e7646d2SAndroid Build Coastguard Worker /*
2973*5e7646d2SAndroid Build Coastguard Worker * Max copies...
2974*5e7646d2SAndroid Build Coastguard Worker */
2975*5e7646d2SAndroid Build Coastguard Worker
2976*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies);
2977*5e7646d2SAndroid Build Coastguard Worker
2978*5e7646d2SAndroid Build Coastguard Worker /*
2979*5e7646d2SAndroid Build Coastguard Worker * Accounting/quota/PIN/managed printing values...
2980*5e7646d2SAndroid Build Coastguard Worker */
2981*5e7646d2SAndroid Build Coastguard Worker
2982*5e7646d2SAndroid Build Coastguard Worker if (pc->charge_info_uri)
2983*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "ChargeInfoURI", pc->charge_info_uri);
2984*5e7646d2SAndroid Build Coastguard Worker
2985*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "JobAccountId %s\n", pc->account_id ? "true" : "false");
2986*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "JobAccountingUserId %s\n",
2987*5e7646d2SAndroid Build Coastguard Worker pc->accounting_user_id ? "true" : "false");
2988*5e7646d2SAndroid Build Coastguard Worker
2989*5e7646d2SAndroid Build Coastguard Worker if (pc->password)
2990*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "JobPassword", pc->password);
2991*5e7646d2SAndroid Build Coastguard Worker
2992*5e7646d2SAndroid Build Coastguard Worker for (value = (char *)cupsArrayFirst(pc->mandatory);
2993*5e7646d2SAndroid Build Coastguard Worker value;
2994*5e7646d2SAndroid Build Coastguard Worker value = (char *)cupsArrayNext(pc->mandatory))
2995*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Mandatory", value);
2996*5e7646d2SAndroid Build Coastguard Worker
2997*5e7646d2SAndroid Build Coastguard Worker /*
2998*5e7646d2SAndroid Build Coastguard Worker * Support files...
2999*5e7646d2SAndroid Build Coastguard Worker */
3000*5e7646d2SAndroid Build Coastguard Worker
3001*5e7646d2SAndroid Build Coastguard Worker for (value = (char *)cupsArrayFirst(pc->support_files);
3002*5e7646d2SAndroid Build Coastguard Worker value;
3003*5e7646d2SAndroid Build Coastguard Worker value = (char *)cupsArrayNext(pc->support_files))
3004*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "SupportFile", value);
3005*5e7646d2SAndroid Build Coastguard Worker
3006*5e7646d2SAndroid Build Coastguard Worker /*
3007*5e7646d2SAndroid Build Coastguard Worker * IPP attributes, if any...
3008*5e7646d2SAndroid Build Coastguard Worker */
3009*5e7646d2SAndroid Build Coastguard Worker
3010*5e7646d2SAndroid Build Coastguard Worker if (attrs)
3011*5e7646d2SAndroid Build Coastguard Worker {
3012*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "IPP " CUPS_LLFMT "\n", CUPS_LLCAST ippLength(attrs));
3013*5e7646d2SAndroid Build Coastguard Worker
3014*5e7646d2SAndroid Build Coastguard Worker attrs->state = IPP_STATE_IDLE;
3015*5e7646d2SAndroid Build Coastguard Worker ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL, attrs);
3016*5e7646d2SAndroid Build Coastguard Worker }
3017*5e7646d2SAndroid Build Coastguard Worker
3018*5e7646d2SAndroid Build Coastguard Worker /*
3019*5e7646d2SAndroid Build Coastguard Worker * Close and return...
3020*5e7646d2SAndroid Build Coastguard Worker */
3021*5e7646d2SAndroid Build Coastguard Worker
3022*5e7646d2SAndroid Build Coastguard Worker if (cupsFileClose(fp))
3023*5e7646d2SAndroid Build Coastguard Worker {
3024*5e7646d2SAndroid Build Coastguard Worker unlink(newfile);
3025*5e7646d2SAndroid Build Coastguard Worker return (0);
3026*5e7646d2SAndroid Build Coastguard Worker }
3027*5e7646d2SAndroid Build Coastguard Worker
3028*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
3029*5e7646d2SAndroid Build Coastguard Worker return (!rename(newfile, filename));
3030*5e7646d2SAndroid Build Coastguard Worker }
3031*5e7646d2SAndroid Build Coastguard Worker
3032*5e7646d2SAndroid Build Coastguard Worker
3033*5e7646d2SAndroid Build Coastguard Worker /*
3034*5e7646d2SAndroid Build Coastguard Worker * '_ppdCreateFromIPP()' - Create a PPD file describing the capabilities
3035*5e7646d2SAndroid Build Coastguard Worker * of an IPP printer.
3036*5e7646d2SAndroid Build Coastguard Worker */
3037*5e7646d2SAndroid Build Coastguard Worker
3038*5e7646d2SAndroid Build Coastguard Worker char * /* O - PPD filename or @code NULL@ on error */
_ppdCreateFromIPP(char * buffer,size_t bufsize,ipp_t * response)3039*5e7646d2SAndroid Build Coastguard Worker _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
3040*5e7646d2SAndroid Build Coastguard Worker size_t bufsize, /* I - Size of filename buffer */
3041*5e7646d2SAndroid Build Coastguard Worker ipp_t *response) /* I - Get-Printer-Attributes response */
3042*5e7646d2SAndroid Build Coastguard Worker {
3043*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* PPD file */
3044*5e7646d2SAndroid Build Coastguard Worker cups_array_t *sizes; /* Media sizes supported by printer */
3045*5e7646d2SAndroid Build Coastguard Worker cups_size_t *size; /* Current media size */
3046*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* xxx-supported */
3047*5e7646d2SAndroid Build Coastguard Worker *defattr, /* xxx-default */
3048*5e7646d2SAndroid Build Coastguard Worker *quality, /* print-quality-supported */
3049*5e7646d2SAndroid Build Coastguard Worker *x_dim, *y_dim; /* Media dimensions */
3050*5e7646d2SAndroid Build Coastguard Worker ipp_t *media_col, /* Media collection */
3051*5e7646d2SAndroid Build Coastguard Worker *media_size; /* Media size collection */
3052*5e7646d2SAndroid Build Coastguard Worker char make[256], /* Make and model */
3053*5e7646d2SAndroid Build Coastguard Worker *model, /* Model name */
3054*5e7646d2SAndroid Build Coastguard Worker ppdname[PPD_MAX_NAME];
3055*5e7646d2SAndroid Build Coastguard Worker /* PPD keyword */
3056*5e7646d2SAndroid Build Coastguard Worker int i, j, /* Looping vars */
3057*5e7646d2SAndroid Build Coastguard Worker count, /* Number of values */
3058*5e7646d2SAndroid Build Coastguard Worker bottom, /* Largest bottom margin */
3059*5e7646d2SAndroid Build Coastguard Worker left, /* Largest left margin */
3060*5e7646d2SAndroid Build Coastguard Worker right, /* Largest right margin */
3061*5e7646d2SAndroid Build Coastguard Worker top, /* Largest top margin */
3062*5e7646d2SAndroid Build Coastguard Worker max_length = 0, /* Maximum custom size */
3063*5e7646d2SAndroid Build Coastguard Worker max_width = 0,
3064*5e7646d2SAndroid Build Coastguard Worker min_length = INT_MAX,
3065*5e7646d2SAndroid Build Coastguard Worker /* Minimum custom size */
3066*5e7646d2SAndroid Build Coastguard Worker min_width = INT_MAX,
3067*5e7646d2SAndroid Build Coastguard Worker is_apple = 0, /* Does the printer support Apple raster? */
3068*5e7646d2SAndroid Build Coastguard Worker is_pdf = 0, /* Does the printer support PDF? */
3069*5e7646d2SAndroid Build Coastguard Worker is_pwg = 0; /* Does the printer support PWG Raster? */
3070*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *pwg; /* PWG media size */
3071*5e7646d2SAndroid Build Coastguard Worker int xres, yres; /* Resolution values */
3072*5e7646d2SAndroid Build Coastguard Worker int resolutions[1000];
3073*5e7646d2SAndroid Build Coastguard Worker /* Array of resolution indices */
3074*5e7646d2SAndroid Build Coastguard Worker char msgid[256]; /* Message identifier (attr.value) */
3075*5e7646d2SAndroid Build Coastguard Worker const char *keyword, /* Keyword value */
3076*5e7646d2SAndroid Build Coastguard Worker *msgstr; /* Localized string */
3077*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *lang = cupsLangDefault();
3078*5e7646d2SAndroid Build Coastguard Worker /* Localization info */
3079*5e7646d2SAndroid Build Coastguard Worker cups_array_t *strings = NULL;/* Printer strings file */
3080*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc = localeconv();
3081*5e7646d2SAndroid Build Coastguard Worker /* Locale data */
3082*5e7646d2SAndroid Build Coastguard Worker cups_array_t *fin_options = NULL;
3083*5e7646d2SAndroid Build Coastguard Worker /* Finishing options */
3084*5e7646d2SAndroid Build Coastguard Worker
3085*5e7646d2SAndroid Build Coastguard Worker
3086*5e7646d2SAndroid Build Coastguard Worker /*
3087*5e7646d2SAndroid Build Coastguard Worker * Range check input...
3088*5e7646d2SAndroid Build Coastguard Worker */
3089*5e7646d2SAndroid Build Coastguard Worker
3090*5e7646d2SAndroid Build Coastguard Worker if (buffer)
3091*5e7646d2SAndroid Build Coastguard Worker *buffer = '\0';
3092*5e7646d2SAndroid Build Coastguard Worker
3093*5e7646d2SAndroid Build Coastguard Worker if (!buffer || bufsize < 1)
3094*5e7646d2SAndroid Build Coastguard Worker {
3095*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
3096*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3097*5e7646d2SAndroid Build Coastguard Worker }
3098*5e7646d2SAndroid Build Coastguard Worker
3099*5e7646d2SAndroid Build Coastguard Worker if (!response)
3100*5e7646d2SAndroid Build Coastguard Worker {
3101*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No IPP attributes."), 1);
3102*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3103*5e7646d2SAndroid Build Coastguard Worker }
3104*5e7646d2SAndroid Build Coastguard Worker
3105*5e7646d2SAndroid Build Coastguard Worker /*
3106*5e7646d2SAndroid Build Coastguard Worker * Open a temporary file for the PPD...
3107*5e7646d2SAndroid Build Coastguard Worker */
3108*5e7646d2SAndroid Build Coastguard Worker
3109*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL)
3110*5e7646d2SAndroid Build Coastguard Worker {
3111*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
3112*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3113*5e7646d2SAndroid Build Coastguard Worker }
3114*5e7646d2SAndroid Build Coastguard Worker
3115*5e7646d2SAndroid Build Coastguard Worker /*
3116*5e7646d2SAndroid Build Coastguard Worker * Standard stuff for PPD file...
3117*5e7646d2SAndroid Build Coastguard Worker */
3118*5e7646d2SAndroid Build Coastguard Worker
3119*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*PPD-Adobe: \"4.3\"\n");
3120*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*FormatVersion: \"4.3\"\n");
3121*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*FileVersion: \"%d.%d\"\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
3122*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*LanguageVersion: English\n");
3123*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*LanguageEncoding: ISOLatin1\n");
3124*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*PSVersion: \"(3010.000) 0\"\n");
3125*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*LanguageLevel: \"3\"\n");
3126*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*FileSystem: False\n");
3127*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*PCFileName: \"ippeve.ppd\"\n");
3128*5e7646d2SAndroid Build Coastguard Worker
3129*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL)
3130*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make));
3131*5e7646d2SAndroid Build Coastguard Worker else
3132*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "Unknown Printer", sizeof(make));
3133*5e7646d2SAndroid Build Coastguard Worker
3134*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) ||
3135*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(make, "Hewlett-Packard ", 16))
3136*5e7646d2SAndroid Build Coastguard Worker {
3137*5e7646d2SAndroid Build Coastguard Worker model = make + 16;
3138*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "HP", sizeof(make));
3139*5e7646d2SAndroid Build Coastguard Worker }
3140*5e7646d2SAndroid Build Coastguard Worker else if ((model = strchr(make, ' ')) != NULL)
3141*5e7646d2SAndroid Build Coastguard Worker *model++ = '\0';
3142*5e7646d2SAndroid Build Coastguard Worker else
3143*5e7646d2SAndroid Build Coastguard Worker model = make;
3144*5e7646d2SAndroid Build Coastguard Worker
3145*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make);
3146*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*ModelName: \"%s\"\n", model);
3147*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*Product: \"(%s)\"\n", model);
3148*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*NickName: \"%s - IPP Everywhere\"\n", model);
3149*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*ShortNickName: \"%s - IPP Everywhere\"\n", model);
3150*5e7646d2SAndroid Build Coastguard Worker
3151*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0))
3152*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*ColorDevice: True\n");
3153*5e7646d2SAndroid Build Coastguard Worker else
3154*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*ColorDevice: False\n");
3155*5e7646d2SAndroid Build Coastguard Worker
3156*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
3157*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsSNMPSupplies: False\n");
3158*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsLanguages: \"%s\"\n", lang->language);
3159*5e7646d2SAndroid Build Coastguard Worker
3160*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != NULL)
3161*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL));
3162*5e7646d2SAndroid Build Coastguard Worker
3163*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-charge-info-uri", IPP_TAG_URI)) != NULL)
3164*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL));
3165*5e7646d2SAndroid Build Coastguard Worker
3166*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI)) != NULL)
3167*5e7646d2SAndroid Build Coastguard Worker {
3168*5e7646d2SAndroid Build Coastguard Worker http_t *http = NULL; /* Connection to printer */
3169*5e7646d2SAndroid Build Coastguard Worker char stringsfile[1024]; /* Temporary strings file */
3170*5e7646d2SAndroid Build Coastguard Worker
3171*5e7646d2SAndroid Build Coastguard Worker if (cups_get_url(&http, ippGetString(attr, 0, NULL), stringsfile, sizeof(stringsfile)))
3172*5e7646d2SAndroid Build Coastguard Worker {
3173*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0, NULL));
3174*5e7646d2SAndroid Build Coastguard Worker
3175*5e7646d2SAndroid Build Coastguard Worker strings = _cupsMessageLoad(stringsfile, _CUPS_MESSAGE_STRINGS | _CUPS_MESSAGE_UNQUOTE);
3176*5e7646d2SAndroid Build Coastguard Worker
3177*5e7646d2SAndroid Build Coastguard Worker unlink(stringsfile);
3178*5e7646d2SAndroid Build Coastguard Worker }
3179*5e7646d2SAndroid Build Coastguard Worker
3180*5e7646d2SAndroid Build Coastguard Worker if (http)
3181*5e7646d2SAndroid Build Coastguard Worker httpClose(http);
3182*5e7646d2SAndroid Build Coastguard Worker }
3183*5e7646d2SAndroid Build Coastguard Worker
3184*5e7646d2SAndroid Build Coastguard Worker /*
3185*5e7646d2SAndroid Build Coastguard Worker * Accounting...
3186*5e7646d2SAndroid Build Coastguard Worker */
3187*5e7646d2SAndroid Build Coastguard Worker
3188*5e7646d2SAndroid Build Coastguard Worker if (ippGetBoolean(ippFindAttribute(response, "job-account-id-supported", IPP_TAG_BOOLEAN), 0))
3189*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsJobAccountId: True\n");
3190*5e7646d2SAndroid Build Coastguard Worker
3191*5e7646d2SAndroid Build Coastguard Worker if (ippGetBoolean(ippFindAttribute(response, "job-accounting-user-id-supported", IPP_TAG_BOOLEAN), 0))
3192*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsJobAccountingUserId: True\n");
3193*5e7646d2SAndroid Build Coastguard Worker
3194*5e7646d2SAndroid Build Coastguard Worker /*
3195*5e7646d2SAndroid Build Coastguard Worker * Password/PIN printing...
3196*5e7646d2SAndroid Build Coastguard Worker */
3197*5e7646d2SAndroid Build Coastguard Worker
3198*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "job-password-supported", IPP_TAG_INTEGER)) != NULL)
3199*5e7646d2SAndroid Build Coastguard Worker {
3200*5e7646d2SAndroid Build Coastguard Worker char pattern[33]; /* Password pattern */
3201*5e7646d2SAndroid Build Coastguard Worker int maxlen = ippGetInteger(attr, 0);
3202*5e7646d2SAndroid Build Coastguard Worker /* Maximum length */
3203*5e7646d2SAndroid Build Coastguard Worker const char *repertoire = ippGetString(ippFindAttribute(response, "job-password-repertoire-configured", IPP_TAG_KEYWORD), 0, NULL);
3204*5e7646d2SAndroid Build Coastguard Worker /* Type of password */
3205*5e7646d2SAndroid Build Coastguard Worker
3206*5e7646d2SAndroid Build Coastguard Worker if (maxlen > (int)(sizeof(pattern) - 1))
3207*5e7646d2SAndroid Build Coastguard Worker maxlen = (int)sizeof(pattern) - 1;
3208*5e7646d2SAndroid Build Coastguard Worker
3209*5e7646d2SAndroid Build Coastguard Worker if (!repertoire || !strcmp(repertoire, "iana_us-ascii_digits"))
3210*5e7646d2SAndroid Build Coastguard Worker memset(pattern, '1', (size_t)maxlen);
3211*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(repertoire, "iana_us-ascii_letters"))
3212*5e7646d2SAndroid Build Coastguard Worker memset(pattern, 'A', (size_t)maxlen);
3213*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(repertoire, "iana_us-ascii_complex"))
3214*5e7646d2SAndroid Build Coastguard Worker memset(pattern, 'C', (size_t)maxlen);
3215*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(repertoire, "iana_us-ascii_any"))
3216*5e7646d2SAndroid Build Coastguard Worker memset(pattern, '.', (size_t)maxlen);
3217*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(repertoire, "iana_utf-8_digits"))
3218*5e7646d2SAndroid Build Coastguard Worker memset(pattern, 'N', (size_t)maxlen);
3219*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(repertoire, "iana_utf-8_letters"))
3220*5e7646d2SAndroid Build Coastguard Worker memset(pattern, 'U', (size_t)maxlen);
3221*5e7646d2SAndroid Build Coastguard Worker else
3222*5e7646d2SAndroid Build Coastguard Worker memset(pattern, '*', (size_t)maxlen);
3223*5e7646d2SAndroid Build Coastguard Worker
3224*5e7646d2SAndroid Build Coastguard Worker pattern[maxlen] = '\0';
3225*5e7646d2SAndroid Build Coastguard Worker
3226*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsJobPassword: \"%s\"\n", pattern);
3227*5e7646d2SAndroid Build Coastguard Worker }
3228*5e7646d2SAndroid Build Coastguard Worker
3229*5e7646d2SAndroid Build Coastguard Worker /*
3230*5e7646d2SAndroid Build Coastguard Worker * Filters...
3231*5e7646d2SAndroid Build Coastguard Worker */
3232*5e7646d2SAndroid Build Coastguard Worker
3233*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL)
3234*5e7646d2SAndroid Build Coastguard Worker {
3235*5e7646d2SAndroid Build Coastguard Worker is_apple = ippContainsString(attr, "image/urf");
3236*5e7646d2SAndroid Build Coastguard Worker is_pdf = ippContainsString(attr, "application/pdf");
3237*5e7646d2SAndroid Build Coastguard Worker is_pwg = ippContainsString(attr, "image/pwg-raster") && !is_apple;
3238*5e7646d2SAndroid Build Coastguard Worker
3239*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(attr, "image/jpeg"))
3240*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"image/jpeg image/jpeg 0 -\"\n");
3241*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(attr, "image/png"))
3242*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"image/png image/png 0 -\"\n");
3243*5e7646d2SAndroid Build Coastguard Worker if (is_pdf)
3244*5e7646d2SAndroid Build Coastguard Worker {
3245*5e7646d2SAndroid Build Coastguard Worker /*
3246*5e7646d2SAndroid Build Coastguard Worker * Don't locally filter PDF content when printing to a CUPS shared
3247*5e7646d2SAndroid Build Coastguard Worker * printer, otherwise the options will be applied twice...
3248*5e7646d2SAndroid Build Coastguard Worker */
3249*5e7646d2SAndroid Build Coastguard Worker
3250*5e7646d2SAndroid Build Coastguard Worker if (ippContainsString(attr, "application/vnd.cups-pdf"))
3251*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"application/pdf application/pdf 0 -\"\n");
3252*5e7646d2SAndroid Build Coastguard Worker else
3253*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n");
3254*5e7646d2SAndroid Build Coastguard Worker }
3255*5e7646d2SAndroid Build Coastguard Worker else
3256*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsManualCopies: True\n");
3257*5e7646d2SAndroid Build Coastguard Worker if (is_apple)
3258*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n");
3259*5e7646d2SAndroid Build Coastguard Worker if (is_pwg)
3260*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFilter2: \"image/pwg-raster image/pwg-raster 100 -\"\n");
3261*5e7646d2SAndroid Build Coastguard Worker }
3262*5e7646d2SAndroid Build Coastguard Worker
3263*5e7646d2SAndroid Build Coastguard Worker if (!is_apple && !is_pdf && !is_pwg)
3264*5e7646d2SAndroid Build Coastguard Worker goto bad_ppd;
3265*5e7646d2SAndroid Build Coastguard Worker
3266*5e7646d2SAndroid Build Coastguard Worker /*
3267*5e7646d2SAndroid Build Coastguard Worker * PageSize/PageRegion/ImageableArea/PaperDimension
3268*5e7646d2SAndroid Build Coastguard Worker */
3269*5e7646d2SAndroid Build Coastguard Worker
3270*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL)
3271*5e7646d2SAndroid Build Coastguard Worker {
3272*5e7646d2SAndroid Build Coastguard Worker for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
3273*5e7646d2SAndroid Build Coastguard Worker if (ippGetInteger(attr, i) > bottom)
3274*5e7646d2SAndroid Build Coastguard Worker bottom = ippGetInteger(attr, i);
3275*5e7646d2SAndroid Build Coastguard Worker }
3276*5e7646d2SAndroid Build Coastguard Worker else
3277*5e7646d2SAndroid Build Coastguard Worker bottom = 1270;
3278*5e7646d2SAndroid Build Coastguard Worker
3279*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL)
3280*5e7646d2SAndroid Build Coastguard Worker {
3281*5e7646d2SAndroid Build Coastguard Worker for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
3282*5e7646d2SAndroid Build Coastguard Worker if (ippGetInteger(attr, i) > left)
3283*5e7646d2SAndroid Build Coastguard Worker left = ippGetInteger(attr, i);
3284*5e7646d2SAndroid Build Coastguard Worker }
3285*5e7646d2SAndroid Build Coastguard Worker else
3286*5e7646d2SAndroid Build Coastguard Worker left = 635;
3287*5e7646d2SAndroid Build Coastguard Worker
3288*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL)
3289*5e7646d2SAndroid Build Coastguard Worker {
3290*5e7646d2SAndroid Build Coastguard Worker for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
3291*5e7646d2SAndroid Build Coastguard Worker if (ippGetInteger(attr, i) > right)
3292*5e7646d2SAndroid Build Coastguard Worker right = ippGetInteger(attr, i);
3293*5e7646d2SAndroid Build Coastguard Worker }
3294*5e7646d2SAndroid Build Coastguard Worker else
3295*5e7646d2SAndroid Build Coastguard Worker right = 635;
3296*5e7646d2SAndroid Build Coastguard Worker
3297*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL)
3298*5e7646d2SAndroid Build Coastguard Worker {
3299*5e7646d2SAndroid Build Coastguard Worker for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
3300*5e7646d2SAndroid Build Coastguard Worker if (ippGetInteger(attr, i) > top)
3301*5e7646d2SAndroid Build Coastguard Worker top = ippGetInteger(attr, i);
3302*5e7646d2SAndroid Build Coastguard Worker }
3303*5e7646d2SAndroid Build Coastguard Worker else
3304*5e7646d2SAndroid Build Coastguard Worker top = 1270;
3305*5e7646d2SAndroid Build Coastguard Worker
3306*5e7646d2SAndroid Build Coastguard Worker if ((defattr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION)) != NULL)
3307*5e7646d2SAndroid Build Coastguard Worker {
3308*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-size", IPP_TAG_BEGIN_COLLECTION)) != NULL)
3309*5e7646d2SAndroid Build Coastguard Worker {
3310*5e7646d2SAndroid Build Coastguard Worker media_size = ippGetCollection(attr, 0);
3311*5e7646d2SAndroid Build Coastguard Worker x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
3312*5e7646d2SAndroid Build Coastguard Worker y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
3313*5e7646d2SAndroid Build Coastguard Worker
3314*5e7646d2SAndroid Build Coastguard Worker if (x_dim && y_dim && (pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL)
3315*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
3316*5e7646d2SAndroid Build Coastguard Worker else
3317*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "Unknown", sizeof(ppdname));
3318*5e7646d2SAndroid Build Coastguard Worker }
3319*5e7646d2SAndroid Build Coastguard Worker else
3320*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "Unknown", sizeof(ppdname));
3321*5e7646d2SAndroid Build Coastguard Worker }
3322*5e7646d2SAndroid Build Coastguard Worker else if ((pwg = pwgMediaForPWG(ippGetString(ippFindAttribute(response, "media-default", IPP_TAG_ZERO), 0, NULL))) != NULL)
3323*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
3324*5e7646d2SAndroid Build Coastguard Worker else
3325*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "Unknown", sizeof(ppdname));
3326*5e7646d2SAndroid Build Coastguard Worker
3327*5e7646d2SAndroid Build Coastguard Worker sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0, (cups_acopy_func_t)pwg_copy_size, (cups_afree_func_t)free);
3328*5e7646d2SAndroid Build Coastguard Worker
3329*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
3330*5e7646d2SAndroid Build Coastguard Worker {
3331*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3332*5e7646d2SAndroid Build Coastguard Worker {
3333*5e7646d2SAndroid Build Coastguard Worker cups_size_t temp; /* Current size */
3334*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *margin; /* media-xxx-margin attribute */
3335*5e7646d2SAndroid Build Coastguard Worker
3336*5e7646d2SAndroid Build Coastguard Worker media_col = ippGetCollection(attr, i);
3337*5e7646d2SAndroid Build Coastguard Worker media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0);
3338*5e7646d2SAndroid Build Coastguard Worker x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
3339*5e7646d2SAndroid Build Coastguard Worker y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
3340*5e7646d2SAndroid Build Coastguard Worker pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
3341*5e7646d2SAndroid Build Coastguard Worker
3342*5e7646d2SAndroid Build Coastguard Worker if (pwg)
3343*5e7646d2SAndroid Build Coastguard Worker {
3344*5e7646d2SAndroid Build Coastguard Worker temp.width = pwg->width;
3345*5e7646d2SAndroid Build Coastguard Worker temp.length = pwg->length;
3346*5e7646d2SAndroid Build Coastguard Worker
3347*5e7646d2SAndroid Build Coastguard Worker if ((margin = ippFindAttribute(media_col, "media-bottom-margin", IPP_TAG_INTEGER)) != NULL)
3348*5e7646d2SAndroid Build Coastguard Worker temp.bottom = ippGetInteger(margin, 0);
3349*5e7646d2SAndroid Build Coastguard Worker else
3350*5e7646d2SAndroid Build Coastguard Worker temp.bottom = bottom;
3351*5e7646d2SAndroid Build Coastguard Worker
3352*5e7646d2SAndroid Build Coastguard Worker if ((margin = ippFindAttribute(media_col, "media-left-margin", IPP_TAG_INTEGER)) != NULL)
3353*5e7646d2SAndroid Build Coastguard Worker temp.left = ippGetInteger(margin, 0);
3354*5e7646d2SAndroid Build Coastguard Worker else
3355*5e7646d2SAndroid Build Coastguard Worker temp.left = left;
3356*5e7646d2SAndroid Build Coastguard Worker
3357*5e7646d2SAndroid Build Coastguard Worker if ((margin = ippFindAttribute(media_col, "media-right-margin", IPP_TAG_INTEGER)) != NULL)
3358*5e7646d2SAndroid Build Coastguard Worker temp.right = ippGetInteger(margin, 0);
3359*5e7646d2SAndroid Build Coastguard Worker else
3360*5e7646d2SAndroid Build Coastguard Worker temp.right = right;
3361*5e7646d2SAndroid Build Coastguard Worker
3362*5e7646d2SAndroid Build Coastguard Worker if ((margin = ippFindAttribute(media_col, "media-top-margin", IPP_TAG_INTEGER)) != NULL)
3363*5e7646d2SAndroid Build Coastguard Worker temp.top = ippGetInteger(margin, 0);
3364*5e7646d2SAndroid Build Coastguard Worker else
3365*5e7646d2SAndroid Build Coastguard Worker temp.top = top;
3366*5e7646d2SAndroid Build Coastguard Worker
3367*5e7646d2SAndroid Build Coastguard Worker if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
3368*5e7646d2SAndroid Build Coastguard Worker snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
3369*5e7646d2SAndroid Build Coastguard Worker else
3370*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
3371*5e7646d2SAndroid Build Coastguard Worker
3372*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(sizes, &temp))
3373*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(sizes, &temp);
3374*5e7646d2SAndroid Build Coastguard Worker }
3375*5e7646d2SAndroid Build Coastguard Worker else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3376*5e7646d2SAndroid Build Coastguard Worker {
3377*5e7646d2SAndroid Build Coastguard Worker /*
3378*5e7646d2SAndroid Build Coastguard Worker * Custom size - record the min/max values...
3379*5e7646d2SAndroid Build Coastguard Worker */
3380*5e7646d2SAndroid Build Coastguard Worker
3381*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Range values */
3382*5e7646d2SAndroid Build Coastguard Worker
3383*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
3384*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(x_dim, 0, &upper);
3385*5e7646d2SAndroid Build Coastguard Worker else
3386*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(x_dim, 0);
3387*5e7646d2SAndroid Build Coastguard Worker
3388*5e7646d2SAndroid Build Coastguard Worker if (lower < min_width)
3389*5e7646d2SAndroid Build Coastguard Worker min_width = lower;
3390*5e7646d2SAndroid Build Coastguard Worker if (upper > max_width)
3391*5e7646d2SAndroid Build Coastguard Worker max_width = upper;
3392*5e7646d2SAndroid Build Coastguard Worker
3393*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3394*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(y_dim, 0, &upper);
3395*5e7646d2SAndroid Build Coastguard Worker else
3396*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(y_dim, 0);
3397*5e7646d2SAndroid Build Coastguard Worker
3398*5e7646d2SAndroid Build Coastguard Worker if (lower < min_length)
3399*5e7646d2SAndroid Build Coastguard Worker min_length = lower;
3400*5e7646d2SAndroid Build Coastguard Worker if (upper > max_length)
3401*5e7646d2SAndroid Build Coastguard Worker max_length = upper;
3402*5e7646d2SAndroid Build Coastguard Worker }
3403*5e7646d2SAndroid Build Coastguard Worker }
3404*5e7646d2SAndroid Build Coastguard Worker
3405*5e7646d2SAndroid Build Coastguard Worker if ((max_width == 0 || max_length == 0) && (attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
3406*5e7646d2SAndroid Build Coastguard Worker {
3407*5e7646d2SAndroid Build Coastguard Worker /*
3408*5e7646d2SAndroid Build Coastguard Worker * Some printers don't list custom size support in media-col-database...
3409*5e7646d2SAndroid Build Coastguard Worker */
3410*5e7646d2SAndroid Build Coastguard Worker
3411*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3412*5e7646d2SAndroid Build Coastguard Worker {
3413*5e7646d2SAndroid Build Coastguard Worker media_size = ippGetCollection(attr, i);
3414*5e7646d2SAndroid Build Coastguard Worker x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
3415*5e7646d2SAndroid Build Coastguard Worker y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
3416*5e7646d2SAndroid Build Coastguard Worker
3417*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3418*5e7646d2SAndroid Build Coastguard Worker {
3419*5e7646d2SAndroid Build Coastguard Worker /*
3420*5e7646d2SAndroid Build Coastguard Worker * Custom size - record the min/max values...
3421*5e7646d2SAndroid Build Coastguard Worker */
3422*5e7646d2SAndroid Build Coastguard Worker
3423*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Range values */
3424*5e7646d2SAndroid Build Coastguard Worker
3425*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
3426*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(x_dim, 0, &upper);
3427*5e7646d2SAndroid Build Coastguard Worker else
3428*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(x_dim, 0);
3429*5e7646d2SAndroid Build Coastguard Worker
3430*5e7646d2SAndroid Build Coastguard Worker if (lower < min_width)
3431*5e7646d2SAndroid Build Coastguard Worker min_width = lower;
3432*5e7646d2SAndroid Build Coastguard Worker if (upper > max_width)
3433*5e7646d2SAndroid Build Coastguard Worker max_width = upper;
3434*5e7646d2SAndroid Build Coastguard Worker
3435*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3436*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(y_dim, 0, &upper);
3437*5e7646d2SAndroid Build Coastguard Worker else
3438*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(y_dim, 0);
3439*5e7646d2SAndroid Build Coastguard Worker
3440*5e7646d2SAndroid Build Coastguard Worker if (lower < min_length)
3441*5e7646d2SAndroid Build Coastguard Worker min_length = lower;
3442*5e7646d2SAndroid Build Coastguard Worker if (upper > max_length)
3443*5e7646d2SAndroid Build Coastguard Worker max_length = upper;
3444*5e7646d2SAndroid Build Coastguard Worker }
3445*5e7646d2SAndroid Build Coastguard Worker }
3446*5e7646d2SAndroid Build Coastguard Worker }
3447*5e7646d2SAndroid Build Coastguard Worker }
3448*5e7646d2SAndroid Build Coastguard Worker else if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
3449*5e7646d2SAndroid Build Coastguard Worker {
3450*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3451*5e7646d2SAndroid Build Coastguard Worker {
3452*5e7646d2SAndroid Build Coastguard Worker cups_size_t temp; /* Current size */
3453*5e7646d2SAndroid Build Coastguard Worker
3454*5e7646d2SAndroid Build Coastguard Worker media_size = ippGetCollection(attr, i);
3455*5e7646d2SAndroid Build Coastguard Worker x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO);
3456*5e7646d2SAndroid Build Coastguard Worker y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO);
3457*5e7646d2SAndroid Build Coastguard Worker pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
3458*5e7646d2SAndroid Build Coastguard Worker
3459*5e7646d2SAndroid Build Coastguard Worker if (pwg)
3460*5e7646d2SAndroid Build Coastguard Worker {
3461*5e7646d2SAndroid Build Coastguard Worker temp.width = pwg->width;
3462*5e7646d2SAndroid Build Coastguard Worker temp.length = pwg->length;
3463*5e7646d2SAndroid Build Coastguard Worker temp.bottom = bottom;
3464*5e7646d2SAndroid Build Coastguard Worker temp.left = left;
3465*5e7646d2SAndroid Build Coastguard Worker temp.right = right;
3466*5e7646d2SAndroid Build Coastguard Worker temp.top = top;
3467*5e7646d2SAndroid Build Coastguard Worker
3468*5e7646d2SAndroid Build Coastguard Worker if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
3469*5e7646d2SAndroid Build Coastguard Worker snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
3470*5e7646d2SAndroid Build Coastguard Worker else
3471*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
3472*5e7646d2SAndroid Build Coastguard Worker
3473*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(sizes, &temp))
3474*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(sizes, &temp);
3475*5e7646d2SAndroid Build Coastguard Worker }
3476*5e7646d2SAndroid Build Coastguard Worker else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3477*5e7646d2SAndroid Build Coastguard Worker {
3478*5e7646d2SAndroid Build Coastguard Worker /*
3479*5e7646d2SAndroid Build Coastguard Worker * Custom size - record the min/max values...
3480*5e7646d2SAndroid Build Coastguard Worker */
3481*5e7646d2SAndroid Build Coastguard Worker
3482*5e7646d2SAndroid Build Coastguard Worker int lower, upper; /* Range values */
3483*5e7646d2SAndroid Build Coastguard Worker
3484*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(x_dim) == IPP_TAG_RANGE)
3485*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(x_dim, 0, &upper);
3486*5e7646d2SAndroid Build Coastguard Worker else
3487*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(x_dim, 0);
3488*5e7646d2SAndroid Build Coastguard Worker
3489*5e7646d2SAndroid Build Coastguard Worker if (lower < min_width)
3490*5e7646d2SAndroid Build Coastguard Worker min_width = lower;
3491*5e7646d2SAndroid Build Coastguard Worker if (upper > max_width)
3492*5e7646d2SAndroid Build Coastguard Worker max_width = upper;
3493*5e7646d2SAndroid Build Coastguard Worker
3494*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(y_dim) == IPP_TAG_RANGE)
3495*5e7646d2SAndroid Build Coastguard Worker lower = ippGetRange(y_dim, 0, &upper);
3496*5e7646d2SAndroid Build Coastguard Worker else
3497*5e7646d2SAndroid Build Coastguard Worker lower = upper = ippGetInteger(y_dim, 0);
3498*5e7646d2SAndroid Build Coastguard Worker
3499*5e7646d2SAndroid Build Coastguard Worker if (lower < min_length)
3500*5e7646d2SAndroid Build Coastguard Worker min_length = lower;
3501*5e7646d2SAndroid Build Coastguard Worker if (upper > max_length)
3502*5e7646d2SAndroid Build Coastguard Worker max_length = upper;
3503*5e7646d2SAndroid Build Coastguard Worker }
3504*5e7646d2SAndroid Build Coastguard Worker }
3505*5e7646d2SAndroid Build Coastguard Worker }
3506*5e7646d2SAndroid Build Coastguard Worker else if ((attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO)) != NULL)
3507*5e7646d2SAndroid Build Coastguard Worker {
3508*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3509*5e7646d2SAndroid Build Coastguard Worker {
3510*5e7646d2SAndroid Build Coastguard Worker const char *pwg_size = ippGetString(attr, i, NULL);
3511*5e7646d2SAndroid Build Coastguard Worker /* PWG size name */
3512*5e7646d2SAndroid Build Coastguard Worker cups_size_t temp; /* Current size */
3513*5e7646d2SAndroid Build Coastguard Worker
3514*5e7646d2SAndroid Build Coastguard Worker if ((pwg = pwgMediaForPWG(pwg_size)) != NULL)
3515*5e7646d2SAndroid Build Coastguard Worker {
3516*5e7646d2SAndroid Build Coastguard Worker if (strstr(pwg_size, "_max_") || strstr(pwg_size, "_max."))
3517*5e7646d2SAndroid Build Coastguard Worker {
3518*5e7646d2SAndroid Build Coastguard Worker if (pwg->width > max_width)
3519*5e7646d2SAndroid Build Coastguard Worker max_width = pwg->width;
3520*5e7646d2SAndroid Build Coastguard Worker if (pwg->length > max_length)
3521*5e7646d2SAndroid Build Coastguard Worker max_length = pwg->length;
3522*5e7646d2SAndroid Build Coastguard Worker }
3523*5e7646d2SAndroid Build Coastguard Worker else if (strstr(pwg_size, "_min_") || strstr(pwg_size, "_min."))
3524*5e7646d2SAndroid Build Coastguard Worker {
3525*5e7646d2SAndroid Build Coastguard Worker if (pwg->width < min_width)
3526*5e7646d2SAndroid Build Coastguard Worker min_width = pwg->width;
3527*5e7646d2SAndroid Build Coastguard Worker if (pwg->length < min_length)
3528*5e7646d2SAndroid Build Coastguard Worker min_length = pwg->length;
3529*5e7646d2SAndroid Build Coastguard Worker }
3530*5e7646d2SAndroid Build Coastguard Worker else
3531*5e7646d2SAndroid Build Coastguard Worker {
3532*5e7646d2SAndroid Build Coastguard Worker temp.width = pwg->width;
3533*5e7646d2SAndroid Build Coastguard Worker temp.length = pwg->length;
3534*5e7646d2SAndroid Build Coastguard Worker temp.bottom = bottom;
3535*5e7646d2SAndroid Build Coastguard Worker temp.left = left;
3536*5e7646d2SAndroid Build Coastguard Worker temp.right = right;
3537*5e7646d2SAndroid Build Coastguard Worker temp.top = top;
3538*5e7646d2SAndroid Build Coastguard Worker
3539*5e7646d2SAndroid Build Coastguard Worker if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0)
3540*5e7646d2SAndroid Build Coastguard Worker snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd);
3541*5e7646d2SAndroid Build Coastguard Worker else
3542*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp.media, pwg->ppd, sizeof(temp.media));
3543*5e7646d2SAndroid Build Coastguard Worker
3544*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(sizes, &temp))
3545*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(sizes, &temp);
3546*5e7646d2SAndroid Build Coastguard Worker }
3547*5e7646d2SAndroid Build Coastguard Worker }
3548*5e7646d2SAndroid Build Coastguard Worker }
3549*5e7646d2SAndroid Build Coastguard Worker }
3550*5e7646d2SAndroid Build Coastguard Worker
3551*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(sizes) > 0)
3552*5e7646d2SAndroid Build Coastguard Worker {
3553*5e7646d2SAndroid Build Coastguard Worker /*
3554*5e7646d2SAndroid Build Coastguard Worker * List all of the standard sizes...
3555*5e7646d2SAndroid Build Coastguard Worker */
3556*5e7646d2SAndroid Build Coastguard Worker
3557*5e7646d2SAndroid Build Coastguard Worker char tleft[256], /* Left string */
3558*5e7646d2SAndroid Build Coastguard Worker tbottom[256], /* Bottom string */
3559*5e7646d2SAndroid Build Coastguard Worker tright[256], /* Right string */
3560*5e7646d2SAndroid Build Coastguard Worker ttop[256], /* Top string */
3561*5e7646d2SAndroid Build Coastguard Worker twidth[256], /* Width string */
3562*5e7646d2SAndroid Build Coastguard Worker tlength[256]; /* Length string */
3563*5e7646d2SAndroid Build Coastguard Worker
3564*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *PageSize: PickOne\n"
3565*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *PageSize\n"
3566*5e7646d2SAndroid Build Coastguard Worker "*DefaultPageSize: %s\n", ppdname);
3567*5e7646d2SAndroid Build Coastguard Worker for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
3568*5e7646d2SAndroid Build Coastguard Worker {
3569*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
3570*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
3571*5e7646d2SAndroid Build Coastguard Worker
3572*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageSize %s: \"<</PageSize[%s %s]>>setpagedevice\"\n", size->media, twidth, tlength);
3573*5e7646d2SAndroid Build Coastguard Worker }
3574*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *PageSize\n");
3575*5e7646d2SAndroid Build Coastguard Worker
3576*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *PageRegion: PickOne\n"
3577*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *PageRegion\n"
3578*5e7646d2SAndroid Build Coastguard Worker "*DefaultPageRegion: %s\n", ppdname);
3579*5e7646d2SAndroid Build Coastguard Worker for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
3580*5e7646d2SAndroid Build Coastguard Worker {
3581*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
3582*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
3583*5e7646d2SAndroid Build Coastguard Worker
3584*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageRegion %s: \"<</PageSize[%s %s]>>setpagedevice\"\n", size->media, twidth, tlength);
3585*5e7646d2SAndroid Build Coastguard Worker }
3586*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *PageRegion\n");
3587*5e7646d2SAndroid Build Coastguard Worker
3588*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultImageableArea: %s\n"
3589*5e7646d2SAndroid Build Coastguard Worker "*DefaultPaperDimension: %s\n", ppdname, ppdname);
3590*5e7646d2SAndroid Build Coastguard Worker
3591*5e7646d2SAndroid Build Coastguard Worker for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes))
3592*5e7646d2SAndroid Build Coastguard Worker {
3593*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tleft, tleft + sizeof(tleft), size->left * 72.0 / 2540.0, loc);
3594*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), size->bottom * 72.0 / 2540.0, loc);
3595*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tright, tright + sizeof(tright), (size->width - size->right) * 72.0 / 2540.0, loc);
3596*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(ttop, ttop + sizeof(ttop), (size->length - size->top) * 72.0 / 2540.0, loc);
3597*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc);
3598*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc);
3599*5e7646d2SAndroid Build Coastguard Worker
3600*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", size->media, tleft, tbottom, tright, ttop);
3601*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", size->media, twidth, tlength);
3602*5e7646d2SAndroid Build Coastguard Worker }
3603*5e7646d2SAndroid Build Coastguard Worker
3604*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(sizes);
3605*5e7646d2SAndroid Build Coastguard Worker
3606*5e7646d2SAndroid Build Coastguard Worker /*
3607*5e7646d2SAndroid Build Coastguard Worker * Custom size support...
3608*5e7646d2SAndroid Build Coastguard Worker */
3609*5e7646d2SAndroid Build Coastguard Worker
3610*5e7646d2SAndroid Build Coastguard Worker if (max_width > 0 && min_width < INT_MAX && max_length > 0 && min_length < INT_MAX)
3611*5e7646d2SAndroid Build Coastguard Worker {
3612*5e7646d2SAndroid Build Coastguard Worker char tmax[256], tmin[256]; /* Min/max values */
3613*5e7646d2SAndroid Build Coastguard Worker
3614*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tleft, tleft + sizeof(tleft), left * 72.0 / 2540.0, loc);
3615*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), bottom * 72.0 / 2540.0, loc);
3616*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tright, tright + sizeof(tright), right * 72.0 / 2540.0, loc);
3617*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(ttop, ttop + sizeof(ttop), top * 72.0 / 2540.0, loc);
3618*5e7646d2SAndroid Build Coastguard Worker
3619*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*HWMargins: \"%s %s %s %s\"\n", tleft, tbottom, tright, ttop);
3620*5e7646d2SAndroid Build Coastguard Worker
3621*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_width * 72.0 / 2540.0, loc);
3622*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_width * 72.0 / 2540.0, loc);
3623*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s\n", tmin, tmax);
3624*5e7646d2SAndroid Build Coastguard Worker
3625*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_length * 72.0 / 2540.0, loc);
3626*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_length * 72.0 / 2540.0, loc);
3627*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s\n", tmin, tmax);
3628*5e7646d2SAndroid Build Coastguard Worker
3629*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0\n");
3630*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0\n");
3631*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*ParamCustomPageSize Orientation: 5 int 0 3\n");
3632*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\"\n");
3633*5e7646d2SAndroid Build Coastguard Worker }
3634*5e7646d2SAndroid Build Coastguard Worker }
3635*5e7646d2SAndroid Build Coastguard Worker else
3636*5e7646d2SAndroid Build Coastguard Worker {
3637*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(sizes);
3638*5e7646d2SAndroid Build Coastguard Worker goto bad_ppd;
3639*5e7646d2SAndroid Build Coastguard Worker }
3640*5e7646d2SAndroid Build Coastguard Worker
3641*5e7646d2SAndroid Build Coastguard Worker /*
3642*5e7646d2SAndroid Build Coastguard Worker * InputSlot...
3643*5e7646d2SAndroid Build Coastguard Worker */
3644*5e7646d2SAndroid Build Coastguard Worker
3645*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_ZERO)) != NULL)
3646*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
3647*5e7646d2SAndroid Build Coastguard Worker else
3648*5e7646d2SAndroid Build Coastguard Worker ppdname[0] = '\0';
3649*5e7646d2SAndroid Build Coastguard Worker
3650*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
3651*5e7646d2SAndroid Build Coastguard Worker {
3652*5e7646d2SAndroid Build Coastguard Worker int have_default = ppdname[0] != '\0';
3653*5e7646d2SAndroid Build Coastguard Worker /* Do we have a default InputSlot? */
3654*5e7646d2SAndroid Build Coastguard Worker static const char * const sources[] =
3655*5e7646d2SAndroid Build Coastguard Worker { /* Standard "media-source" strings */
3656*5e7646d2SAndroid Build Coastguard Worker "auto",
3657*5e7646d2SAndroid Build Coastguard Worker "main",
3658*5e7646d2SAndroid Build Coastguard Worker "alternate",
3659*5e7646d2SAndroid Build Coastguard Worker "large-capacity",
3660*5e7646d2SAndroid Build Coastguard Worker "manual",
3661*5e7646d2SAndroid Build Coastguard Worker "envelope",
3662*5e7646d2SAndroid Build Coastguard Worker "disc",
3663*5e7646d2SAndroid Build Coastguard Worker "photo",
3664*5e7646d2SAndroid Build Coastguard Worker "hagaki",
3665*5e7646d2SAndroid Build Coastguard Worker "main-roll",
3666*5e7646d2SAndroid Build Coastguard Worker "alternate-roll",
3667*5e7646d2SAndroid Build Coastguard Worker "top",
3668*5e7646d2SAndroid Build Coastguard Worker "middle",
3669*5e7646d2SAndroid Build Coastguard Worker "bottom",
3670*5e7646d2SAndroid Build Coastguard Worker "side",
3671*5e7646d2SAndroid Build Coastguard Worker "left",
3672*5e7646d2SAndroid Build Coastguard Worker "right",
3673*5e7646d2SAndroid Build Coastguard Worker "center",
3674*5e7646d2SAndroid Build Coastguard Worker "rear",
3675*5e7646d2SAndroid Build Coastguard Worker "by-pass-tray",
3676*5e7646d2SAndroid Build Coastguard Worker "tray-1",
3677*5e7646d2SAndroid Build Coastguard Worker "tray-2",
3678*5e7646d2SAndroid Build Coastguard Worker "tray-3",
3679*5e7646d2SAndroid Build Coastguard Worker "tray-4",
3680*5e7646d2SAndroid Build Coastguard Worker "tray-5",
3681*5e7646d2SAndroid Build Coastguard Worker "tray-6",
3682*5e7646d2SAndroid Build Coastguard Worker "tray-7",
3683*5e7646d2SAndroid Build Coastguard Worker "tray-8",
3684*5e7646d2SAndroid Build Coastguard Worker "tray-9",
3685*5e7646d2SAndroid Build Coastguard Worker "tray-10",
3686*5e7646d2SAndroid Build Coastguard Worker "tray-11",
3687*5e7646d2SAndroid Build Coastguard Worker "tray-12",
3688*5e7646d2SAndroid Build Coastguard Worker "tray-13",
3689*5e7646d2SAndroid Build Coastguard Worker "tray-14",
3690*5e7646d2SAndroid Build Coastguard Worker "tray-15",
3691*5e7646d2SAndroid Build Coastguard Worker "tray-16",
3692*5e7646d2SAndroid Build Coastguard Worker "tray-17",
3693*5e7646d2SAndroid Build Coastguard Worker "tray-18",
3694*5e7646d2SAndroid Build Coastguard Worker "tray-19",
3695*5e7646d2SAndroid Build Coastguard Worker "tray-20",
3696*5e7646d2SAndroid Build Coastguard Worker "roll-1",
3697*5e7646d2SAndroid Build Coastguard Worker "roll-2",
3698*5e7646d2SAndroid Build Coastguard Worker "roll-3",
3699*5e7646d2SAndroid Build Coastguard Worker "roll-4",
3700*5e7646d2SAndroid Build Coastguard Worker "roll-5",
3701*5e7646d2SAndroid Build Coastguard Worker "roll-6",
3702*5e7646d2SAndroid Build Coastguard Worker "roll-7",
3703*5e7646d2SAndroid Build Coastguard Worker "roll-8",
3704*5e7646d2SAndroid Build Coastguard Worker "roll-9",
3705*5e7646d2SAndroid Build Coastguard Worker "roll-10"
3706*5e7646d2SAndroid Build Coastguard Worker };
3707*5e7646d2SAndroid Build Coastguard Worker
3708*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *InputSlot: PickOne\n"
3709*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *InputSlot\n");
3710*5e7646d2SAndroid Build Coastguard Worker if (have_default)
3711*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname);
3712*5e7646d2SAndroid Build Coastguard Worker
3713*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3714*5e7646d2SAndroid Build Coastguard Worker {
3715*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(attr, i, NULL);
3716*5e7646d2SAndroid Build Coastguard Worker
3717*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
3718*5e7646d2SAndroid Build Coastguard Worker
3719*5e7646d2SAndroid Build Coastguard Worker if (i == 0 && !have_default)
3720*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname);
3721*5e7646d2SAndroid Build Coastguard Worker
3722*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++)
3723*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(sources[j], keyword))
3724*5e7646d2SAndroid Build Coastguard Worker {
3725*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "media-source.%s", keyword);
3726*5e7646d2SAndroid Build Coastguard Worker
3727*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
3728*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
3729*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
3730*5e7646d2SAndroid Build Coastguard Worker
3731*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*InputSlot %s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, j);
3732*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, msgstr);
3733*5e7646d2SAndroid Build Coastguard Worker break;
3734*5e7646d2SAndroid Build Coastguard Worker }
3735*5e7646d2SAndroid Build Coastguard Worker }
3736*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *InputSlot\n");
3737*5e7646d2SAndroid Build Coastguard Worker }
3738*5e7646d2SAndroid Build Coastguard Worker
3739*5e7646d2SAndroid Build Coastguard Worker /*
3740*5e7646d2SAndroid Build Coastguard Worker * MediaType...
3741*5e7646d2SAndroid Build Coastguard Worker */
3742*5e7646d2SAndroid Build Coastguard Worker
3743*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-type", IPP_TAG_ZERO)) != NULL)
3744*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
3745*5e7646d2SAndroid Build Coastguard Worker else
3746*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "Unknown", sizeof(ppdname));
3747*5e7646d2SAndroid Build Coastguard Worker
3748*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "media-type-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1)
3749*5e7646d2SAndroid Build Coastguard Worker {
3750*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *MediaType: PickOne\n"
3751*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *MediaType\n"
3752*5e7646d2SAndroid Build Coastguard Worker "*DefaultMediaType: %s\n", ppdname);
3753*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3754*5e7646d2SAndroid Build Coastguard Worker {
3755*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(attr, i, NULL);
3756*5e7646d2SAndroid Build Coastguard Worker
3757*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
3758*5e7646d2SAndroid Build Coastguard Worker
3759*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "media-type.%s", keyword);
3760*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
3761*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
3762*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
3763*5e7646d2SAndroid Build Coastguard Worker
3764*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*MediaType %s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, ppdname);
3765*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.MediaType %s/%s: \"\"\n", lang->language, ppdname, msgstr);
3766*5e7646d2SAndroid Build Coastguard Worker }
3767*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *MediaType\n");
3768*5e7646d2SAndroid Build Coastguard Worker }
3769*5e7646d2SAndroid Build Coastguard Worker
3770*5e7646d2SAndroid Build Coastguard Worker /*
3771*5e7646d2SAndroid Build Coastguard Worker * ColorModel...
3772*5e7646d2SAndroid Build Coastguard Worker */
3773*5e7646d2SAndroid Build Coastguard Worker
3774*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL)
3775*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
3776*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) == NULL)
3777*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "output-mode-supported", IPP_TAG_KEYWORD);
3778*5e7646d2SAndroid Build Coastguard Worker
3779*5e7646d2SAndroid Build Coastguard Worker if (attr)
3780*5e7646d2SAndroid Build Coastguard Worker {
3781*5e7646d2SAndroid Build Coastguard Worker int wrote_color = 0;
3782*5e7646d2SAndroid Build Coastguard Worker const char *default_color = NULL; /* Default */
3783*5e7646d2SAndroid Build Coastguard Worker
3784*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%% ColorModel from %s\n", ippGetName(attr));
3785*5e7646d2SAndroid Build Coastguard Worker
3786*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3787*5e7646d2SAndroid Build Coastguard Worker {
3788*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(attr, i, NULL);
3789*5e7646d2SAndroid Build Coastguard Worker
3790*5e7646d2SAndroid Build Coastguard Worker #define PRINTF_COLORMODEL if (!wrote_color) { cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n*OrderDependency: 10 AnySetup *ColorModel\n*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode"))); wrote_color = 1; }
3791*5e7646d2SAndroid Build Coastguard Worker #define PRINTF_COLOROPTION(name,text,cspace,bpp) { cupsFilePrintf(fp, "*ColorModel %s: \"<</cupsColorSpace %d/cupsBitsPerColor %d/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n", name, cspace, bpp); cupsFilePrintf(fp, "*%s.ColorModel %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, text)); }
3792*5e7646d2SAndroid Build Coastguard Worker
3793*5e7646d2SAndroid Build Coastguard Worker if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
3794*5e7646d2SAndroid Build Coastguard Worker {
3795*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3796*5e7646d2SAndroid Build Coastguard Worker
3797*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("FastGray", _("Fast Grayscale"), CUPS_CSPACE_K, 1)
3798*5e7646d2SAndroid Build Coastguard Worker
3799*5e7646d2SAndroid Build Coastguard Worker if (!default_color)
3800*5e7646d2SAndroid Build Coastguard Worker default_color = "FastGray";
3801*5e7646d2SAndroid Build Coastguard Worker }
3802*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
3803*5e7646d2SAndroid Build Coastguard Worker {
3804*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3805*5e7646d2SAndroid Build Coastguard Worker
3806*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("Gray", _("Grayscale"), CUPS_CSPACE_SW, 8)
3807*5e7646d2SAndroid Build Coastguard Worker
3808*5e7646d2SAndroid Build Coastguard Worker if (!default_color || !strcmp(default_color, "FastGray"))
3809*5e7646d2SAndroid Build Coastguard Worker default_color = "Gray";
3810*5e7646d2SAndroid Build Coastguard Worker }
3811*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "sgray_16") || !strcmp(keyword, "W8-16"))
3812*5e7646d2SAndroid Build Coastguard Worker {
3813*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3814*5e7646d2SAndroid Build Coastguard Worker
3815*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "W8-16"))
3816*5e7646d2SAndroid Build Coastguard Worker {
3817*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("Gray", _("Grayscale"), CUPS_CSPACE_SW, 8)
3818*5e7646d2SAndroid Build Coastguard Worker
3819*5e7646d2SAndroid Build Coastguard Worker if (!default_color || !strcmp(default_color, "FastGray"))
3820*5e7646d2SAndroid Build Coastguard Worker default_color = "Gray";
3821*5e7646d2SAndroid Build Coastguard Worker }
3822*5e7646d2SAndroid Build Coastguard Worker
3823*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("Gray16", _("Deep Gray"), CUPS_CSPACE_SW, 16)
3824*5e7646d2SAndroid Build Coastguard Worker }
3825*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "srgb_8") || !strncmp(keyword, "SRGB24", 7) || !strcmp(keyword, "color"))
3826*5e7646d2SAndroid Build Coastguard Worker {
3827*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3828*5e7646d2SAndroid Build Coastguard Worker
3829*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("RGB", _("Color"), CUPS_CSPACE_SRGB, 8)
3830*5e7646d2SAndroid Build Coastguard Worker
3831*5e7646d2SAndroid Build Coastguard Worker default_color = "RGB";
3832*5e7646d2SAndroid Build Coastguard Worker
3833*5e7646d2SAndroid Build Coastguard Worker // Apparently some printers only advertise color support, so make sure
3834*5e7646d2SAndroid Build Coastguard Worker // we also do grayscale for these printers...
3835*5e7646d2SAndroid Build Coastguard Worker if (!ippContainsString(attr, "sgray_8") && !ippContainsString(attr, "black_1") && !ippContainsString(attr, "black_8") && !ippContainsString(attr, "W8") && !ippContainsString(attr, "W8-16"))
3836*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("Gray", _("GrayScale"), CUPS_CSPACE_SW, 8)
3837*5e7646d2SAndroid Build Coastguard Worker }
3838*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48") || !strcmp(keyword, "ADOBERGB24-48"))
3839*5e7646d2SAndroid Build Coastguard Worker {
3840*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3841*5e7646d2SAndroid Build Coastguard Worker
3842*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("AdobeRGB", _("Deep Color"), CUPS_CSPACE_ADOBERGB, 16)
3843*5e7646d2SAndroid Build Coastguard Worker
3844*5e7646d2SAndroid Build Coastguard Worker if (!default_color)
3845*5e7646d2SAndroid Build Coastguard Worker default_color = "AdobeRGB";
3846*5e7646d2SAndroid Build Coastguard Worker }
3847*5e7646d2SAndroid Build Coastguard Worker else if ((!strcasecmp(keyword, "adobe-rgb_8") && !ippContainsString(attr, "adobe-rgb_16")) || !strcmp(keyword, "ADOBERGB24"))
3848*5e7646d2SAndroid Build Coastguard Worker {
3849*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3850*5e7646d2SAndroid Build Coastguard Worker
3851*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("AdobeRGB", _("Deep Color"), CUPS_CSPACE_ADOBERGB, 8)
3852*5e7646d2SAndroid Build Coastguard Worker
3853*5e7646d2SAndroid Build Coastguard Worker if (!default_color)
3854*5e7646d2SAndroid Build Coastguard Worker default_color = "AdobeRGB";
3855*5e7646d2SAndroid Build Coastguard Worker }
3856*5e7646d2SAndroid Build Coastguard Worker else if ((!strcasecmp(keyword, "black_8") && !ippContainsString(attr, "black_16")) || !strcmp(keyword, "DEVW8"))
3857*5e7646d2SAndroid Build Coastguard Worker {
3858*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3859*5e7646d2SAndroid Build Coastguard Worker
3860*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("DeviceGray", _("Device Gray"), CUPS_CSPACE_W, 8)
3861*5e7646d2SAndroid Build Coastguard Worker }
3862*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "black_16") || !strcmp(keyword, "DEVW16") || !strcmp(keyword, "DEVW8-16"))
3863*5e7646d2SAndroid Build Coastguard Worker {
3864*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3865*5e7646d2SAndroid Build Coastguard Worker
3866*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("DeviceGray", _("Device Gray"), CUPS_CSPACE_W, 16)
3867*5e7646d2SAndroid Build Coastguard Worker }
3868*5e7646d2SAndroid Build Coastguard Worker else if ((!strcasecmp(keyword, "cmyk_8") && !ippContainsString(attr, "cmyk_16")) || !strcmp(keyword, "DEVCMYK32"))
3869*5e7646d2SAndroid Build Coastguard Worker {
3870*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3871*5e7646d2SAndroid Build Coastguard Worker
3872*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("CMYK", _("Device CMYK"), CUPS_CSPACE_CMYK, 8)
3873*5e7646d2SAndroid Build Coastguard Worker }
3874*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "cmyk_16") || !strcmp(keyword, "DEVCMYK32-64") || !strcmp(keyword, "DEVCMYK64"))
3875*5e7646d2SAndroid Build Coastguard Worker {
3876*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3877*5e7646d2SAndroid Build Coastguard Worker
3878*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("CMYK", _("Device CMYK"), CUPS_CSPACE_CMYK, 16)
3879*5e7646d2SAndroid Build Coastguard Worker }
3880*5e7646d2SAndroid Build Coastguard Worker else if ((!strcasecmp(keyword, "rgb_8") && ippContainsString(attr, "rgb_16")) || !strcmp(keyword, "DEVRGB24"))
3881*5e7646d2SAndroid Build Coastguard Worker {
3882*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3883*5e7646d2SAndroid Build Coastguard Worker
3884*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("DeviceRGB", _("Device RGB"), CUPS_CSPACE_RGB, 8)
3885*5e7646d2SAndroid Build Coastguard Worker }
3886*5e7646d2SAndroid Build Coastguard Worker else if (!strcasecmp(keyword, "rgb_16") || !strcmp(keyword, "DEVRGB24-48") || !strcmp(keyword, "DEVRGB48"))
3887*5e7646d2SAndroid Build Coastguard Worker {
3888*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLORMODEL
3889*5e7646d2SAndroid Build Coastguard Worker
3890*5e7646d2SAndroid Build Coastguard Worker PRINTF_COLOROPTION("DeviceRGB", _("Device RGB"), CUPS_CSPACE_RGB, 16)
3891*5e7646d2SAndroid Build Coastguard Worker }
3892*5e7646d2SAndroid Build Coastguard Worker }
3893*5e7646d2SAndroid Build Coastguard Worker
3894*5e7646d2SAndroid Build Coastguard Worker if (default_color)
3895*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultColorModel: %s\n", default_color);
3896*5e7646d2SAndroid Build Coastguard Worker if (wrote_color)
3897*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *ColorModel\n");
3898*5e7646d2SAndroid Build Coastguard Worker }
3899*5e7646d2SAndroid Build Coastguard Worker
3900*5e7646d2SAndroid Build Coastguard Worker /*
3901*5e7646d2SAndroid Build Coastguard Worker * Duplex...
3902*5e7646d2SAndroid Build Coastguard Worker */
3903*5e7646d2SAndroid Build Coastguard Worker
3904*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "sides-supported", IPP_TAG_KEYWORD)) != NULL && ippContainsString(attr, "two-sided-long-edge"))
3905*5e7646d2SAndroid Build Coastguard Worker {
3906*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *Duplex: PickOne\n"
3907*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *Duplex\n"
3908*5e7646d2SAndroid Build Coastguard Worker "*%s.Translation Duplex/%s: \"\"\n"
3909*5e7646d2SAndroid Build Coastguard Worker "*DefaultDuplex: None\n"
3910*5e7646d2SAndroid Build Coastguard Worker "*Duplex None: \"<</Duplex false>>setpagedevice\"\n"
3911*5e7646d2SAndroid Build Coastguard Worker "*%s.Duplex None/%s: \"\"\n"
3912*5e7646d2SAndroid Build Coastguard Worker "*Duplex DuplexNoTumble: \"<</Duplex true/Tumble false>>setpagedevice\"\n"
3913*5e7646d2SAndroid Build Coastguard Worker "*%s.Duplex DuplexNoTumble/%s: \"\"\n"
3914*5e7646d2SAndroid Build Coastguard Worker "*Duplex DuplexTumble: \"<</Duplex true/Tumble true>>setpagedevice\"\n"
3915*5e7646d2SAndroid Build Coastguard Worker "*%s.Duplex DuplexTumble/%s: \"\"\n"
3916*5e7646d2SAndroid Build Coastguard Worker "*CloseUI: *Duplex\n", lang->language, _cupsLangString(lang, _("2-Sided Printing")), lang->language, _cupsLangString(lang, _("Off (1-Sided)")), lang->language, _cupsLangString(lang, _("Long-Edge (Portrait)")), lang->language, _cupsLangString(lang, _("Short-Edge (Landscape)")));
3917*5e7646d2SAndroid Build Coastguard Worker
3918*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
3919*5e7646d2SAndroid Build Coastguard Worker {
3920*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
3921*5e7646d2SAndroid Build Coastguard Worker {
3922*5e7646d2SAndroid Build Coastguard Worker const char *dm = ippGetString(attr, i, NULL);
3923*5e7646d2SAndroid Build Coastguard Worker /* DM value */
3924*5e7646d2SAndroid Build Coastguard Worker
3925*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(dm, "DM1"))
3926*5e7646d2SAndroid Build Coastguard Worker {
3927*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Normal\n");
3928*5e7646d2SAndroid Build Coastguard Worker break;
3929*5e7646d2SAndroid Build Coastguard Worker }
3930*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(dm, "DM2"))
3931*5e7646d2SAndroid Build Coastguard Worker {
3932*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
3933*5e7646d2SAndroid Build Coastguard Worker break;
3934*5e7646d2SAndroid Build Coastguard Worker }
3935*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(dm, "DM3"))
3936*5e7646d2SAndroid Build Coastguard Worker {
3937*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
3938*5e7646d2SAndroid Build Coastguard Worker break;
3939*5e7646d2SAndroid Build Coastguard Worker }
3940*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(dm, "DM4"))
3941*5e7646d2SAndroid Build Coastguard Worker {
3942*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
3943*5e7646d2SAndroid Build Coastguard Worker break;
3944*5e7646d2SAndroid Build Coastguard Worker }
3945*5e7646d2SAndroid Build Coastguard Worker }
3946*5e7646d2SAndroid Build Coastguard Worker }
3947*5e7646d2SAndroid Build Coastguard Worker else if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
3948*5e7646d2SAndroid Build Coastguard Worker {
3949*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(attr, 0, NULL);
3950*5e7646d2SAndroid Build Coastguard Worker
3951*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "flipped"))
3952*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
3953*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(keyword, "manual-tumble"))
3954*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
3955*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(keyword, "normal"))
3956*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Normal\n");
3957*5e7646d2SAndroid Build Coastguard Worker else
3958*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
3959*5e7646d2SAndroid Build Coastguard Worker }
3960*5e7646d2SAndroid Build Coastguard Worker }
3961*5e7646d2SAndroid Build Coastguard Worker
3962*5e7646d2SAndroid Build Coastguard Worker /*
3963*5e7646d2SAndroid Build Coastguard Worker * Output bin...
3964*5e7646d2SAndroid Build Coastguard Worker */
3965*5e7646d2SAndroid Build Coastguard Worker
3966*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "output-bin-default", IPP_TAG_ZERO)) != NULL)
3967*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
3968*5e7646d2SAndroid Build Coastguard Worker else
3969*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "Unknown", sizeof(ppdname));
3970*5e7646d2SAndroid Build Coastguard Worker
3971*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 0)
3972*5e7646d2SAndroid Build Coastguard Worker {
3973*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *trays = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING);
3974*5e7646d2SAndroid Build Coastguard Worker /* printer-output-tray attribute, if any */
3975*5e7646d2SAndroid Build Coastguard Worker const char *tray_ptr; /* printer-output-tray value */
3976*5e7646d2SAndroid Build Coastguard Worker int tray_len; /* Len of printer-output-tray value */
3977*5e7646d2SAndroid Build Coastguard Worker char tray[IPP_MAX_OCTETSTRING];
3978*5e7646d2SAndroid Build Coastguard Worker /* printer-output-tray string value */
3979*5e7646d2SAndroid Build Coastguard Worker
3980*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *OutputBin: PickOne\n"
3981*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *OutputBin\n"
3982*5e7646d2SAndroid Build Coastguard Worker "*DefaultOutputBin: %s\n", ppdname);
3983*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(ppdname, "FaceUp"))
3984*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultOutputOrder: Reverse\n");
3985*5e7646d2SAndroid Build Coastguard Worker else
3986*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultOutputOrder: Normal\n");
3987*5e7646d2SAndroid Build Coastguard Worker
3988*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
3989*5e7646d2SAndroid Build Coastguard Worker {
3990*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(attr, i, NULL);
3991*5e7646d2SAndroid Build Coastguard Worker
3992*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
3993*5e7646d2SAndroid Build Coastguard Worker
3994*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "output-bin.%s", keyword);
3995*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
3996*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
3997*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
3998*5e7646d2SAndroid Build Coastguard Worker
3999*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OutputBin %s: \"\"\n", ppdname);
4000*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.OutputBin %s/%s: \"\"\n", lang->language, ppdname, msgstr);
4001*5e7646d2SAndroid Build Coastguard Worker
4002*5e7646d2SAndroid Build Coastguard Worker if ((tray_ptr = ippGetOctetString(trays, i, &tray_len)) != NULL)
4003*5e7646d2SAndroid Build Coastguard Worker {
4004*5e7646d2SAndroid Build Coastguard Worker if (tray_len >= (int)sizeof(tray))
4005*5e7646d2SAndroid Build Coastguard Worker tray_len = (int)sizeof(tray) - 1;
4006*5e7646d2SAndroid Build Coastguard Worker
4007*5e7646d2SAndroid Build Coastguard Worker memcpy(tray, tray_ptr, (size_t)tray_len);
4008*5e7646d2SAndroid Build Coastguard Worker tray[tray_len] = '\0';
4009*5e7646d2SAndroid Build Coastguard Worker
4010*5e7646d2SAndroid Build Coastguard Worker if (strstr(tray, "stackingorder=lastToFirst;"))
4011*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname);
4012*5e7646d2SAndroid Build Coastguard Worker else
4013*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname);
4014*5e7646d2SAndroid Build Coastguard Worker }
4015*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(ppdname, "FaceUp"))
4016*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname);
4017*5e7646d2SAndroid Build Coastguard Worker else
4018*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname);
4019*5e7646d2SAndroid Build Coastguard Worker }
4020*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *OutputBin\n");
4021*5e7646d2SAndroid Build Coastguard Worker }
4022*5e7646d2SAndroid Build Coastguard Worker
4023*5e7646d2SAndroid Build Coastguard Worker /*
4024*5e7646d2SAndroid Build Coastguard Worker * Finishing options...
4025*5e7646d2SAndroid Build Coastguard Worker */
4026*5e7646d2SAndroid Build Coastguard Worker
4027*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL)
4028*5e7646d2SAndroid Build Coastguard Worker {
4029*5e7646d2SAndroid Build Coastguard Worker int value; /* Enum value */
4030*5e7646d2SAndroid Build Coastguard Worker const char *ppd_keyword; /* PPD keyword for enum */
4031*5e7646d2SAndroid Build Coastguard Worker cups_array_t *names; /* Names we've added */
4032*5e7646d2SAndroid Build Coastguard Worker static const char * const base_keywords[] =
4033*5e7646d2SAndroid Build Coastguard Worker { /* Base STD 92 keywords */
4034*5e7646d2SAndroid Build Coastguard Worker NULL, /* none */
4035*5e7646d2SAndroid Build Coastguard Worker "SingleAuto", /* staple */
4036*5e7646d2SAndroid Build Coastguard Worker "SingleAuto", /* punch */
4037*5e7646d2SAndroid Build Coastguard Worker NULL, /* cover */
4038*5e7646d2SAndroid Build Coastguard Worker "BindAuto", /* bind */
4039*5e7646d2SAndroid Build Coastguard Worker "SaddleStitch", /* saddle-stitch */
4040*5e7646d2SAndroid Build Coastguard Worker "EdgeStitchAuto", /* edge-stitch */
4041*5e7646d2SAndroid Build Coastguard Worker "Auto", /* fold */
4042*5e7646d2SAndroid Build Coastguard Worker NULL, /* trim */
4043*5e7646d2SAndroid Build Coastguard Worker NULL, /* bale */
4044*5e7646d2SAndroid Build Coastguard Worker NULL, /* booklet-maker */
4045*5e7646d2SAndroid Build Coastguard Worker NULL, /* jog-offset */
4046*5e7646d2SAndroid Build Coastguard Worker NULL, /* coat */
4047*5e7646d2SAndroid Build Coastguard Worker NULL /* laminate */
4048*5e7646d2SAndroid Build Coastguard Worker };
4049*5e7646d2SAndroid Build Coastguard Worker
4050*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
4051*5e7646d2SAndroid Build Coastguard Worker names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
4052*5e7646d2SAndroid Build Coastguard Worker fin_options = cupsArrayNew((cups_array_func_t)strcmp, NULL);
4053*5e7646d2SAndroid Build Coastguard Worker
4054*5e7646d2SAndroid Build Coastguard Worker /*
4055*5e7646d2SAndroid Build Coastguard Worker * Staple/Bind/Stitch
4056*5e7646d2SAndroid Build Coastguard Worker */
4057*5e7646d2SAndroid Build Coastguard Worker
4058*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4059*5e7646d2SAndroid Build Coastguard Worker {
4060*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4061*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4062*5e7646d2SAndroid Build Coastguard Worker
4063*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(keyword, "staple-", 7) || !strncmp(keyword, "bind-", 5) || !strncmp(keyword, "edge-stitch-", 12) || !strcmp(keyword, "saddle-stitch"))
4064*5e7646d2SAndroid Build Coastguard Worker break;
4065*5e7646d2SAndroid Build Coastguard Worker }
4066*5e7646d2SAndroid Build Coastguard Worker
4067*5e7646d2SAndroid Build Coastguard Worker if (i < count)
4068*5e7646d2SAndroid Build Coastguard Worker {
4069*5e7646d2SAndroid Build Coastguard Worker static const char * const staple_keywords[] =
4070*5e7646d2SAndroid Build Coastguard Worker { /* StapleLocation keywords */
4071*5e7646d2SAndroid Build Coastguard Worker "SinglePortrait",
4072*5e7646d2SAndroid Build Coastguard Worker "SingleRevLandscape",
4073*5e7646d2SAndroid Build Coastguard Worker "SingleLandscape",
4074*5e7646d2SAndroid Build Coastguard Worker "SingleRevPortrait",
4075*5e7646d2SAndroid Build Coastguard Worker "EdgeStitchPortrait",
4076*5e7646d2SAndroid Build Coastguard Worker "EdgeStitchLandscape",
4077*5e7646d2SAndroid Build Coastguard Worker "EdgeStitchRevPortrait",
4078*5e7646d2SAndroid Build Coastguard Worker "EdgeStitchRevLandscape",
4079*5e7646d2SAndroid Build Coastguard Worker "DualPortrait",
4080*5e7646d2SAndroid Build Coastguard Worker "DualLandscape",
4081*5e7646d2SAndroid Build Coastguard Worker "DualRevPortrait",
4082*5e7646d2SAndroid Build Coastguard Worker "DualRevLandscape",
4083*5e7646d2SAndroid Build Coastguard Worker "TriplePortrait",
4084*5e7646d2SAndroid Build Coastguard Worker "TripleLandscape",
4085*5e7646d2SAndroid Build Coastguard Worker "TripleRevPortrait",
4086*5e7646d2SAndroid Build Coastguard Worker "TripleRevLandscape"
4087*5e7646d2SAndroid Build Coastguard Worker };
4088*5e7646d2SAndroid Build Coastguard Worker static const char * const bind_keywords[] =
4089*5e7646d2SAndroid Build Coastguard Worker { /* StapleLocation binding keywords */
4090*5e7646d2SAndroid Build Coastguard Worker "BindPortrait",
4091*5e7646d2SAndroid Build Coastguard Worker "BindLandscape",
4092*5e7646d2SAndroid Build Coastguard Worker "BindRevPortrait",
4093*5e7646d2SAndroid Build Coastguard Worker "BindRevLandscape"
4094*5e7646d2SAndroid Build Coastguard Worker };
4095*5e7646d2SAndroid Build Coastguard Worker
4096*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(fin_options, "*StapleLocation");
4097*5e7646d2SAndroid Build Coastguard Worker
4098*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *StapleLocation: PickOne\n");
4099*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n");
4100*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation StapleLocation/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Staple")));
4101*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultStapleLocation: None\n");
4102*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*StapleLocation None: \"\"\n");
4103*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.StapleLocation None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
4104*5e7646d2SAndroid Build Coastguard Worker
4105*5e7646d2SAndroid Build Coastguard Worker for (; i < count; i ++)
4106*5e7646d2SAndroid Build Coastguard Worker {
4107*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4108*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4109*5e7646d2SAndroid Build Coastguard Worker
4110*5e7646d2SAndroid Build Coastguard Worker if (strncmp(keyword, "staple-", 7) && strncmp(keyword, "bind-", 5) && strncmp(keyword, "edge-stitch-", 12) && strcmp(keyword, "saddle-stitch"))
4111*5e7646d2SAndroid Build Coastguard Worker continue;
4112*5e7646d2SAndroid Build Coastguard Worker
4113*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(names, (char *)keyword))
4114*5e7646d2SAndroid Build Coastguard Worker continue; /* Already did this finishing template */
4115*5e7646d2SAndroid Build Coastguard Worker
4116*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(names, (char *)keyword);
4117*5e7646d2SAndroid Build Coastguard Worker
4118*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "finishings.%d", value);
4119*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
4120*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
4121*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
4122*5e7646d2SAndroid Build Coastguard Worker
4123*5e7646d2SAndroid Build Coastguard Worker if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
4124*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
4125*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_STAPLE_TOP_LEFT && value <= IPP_FINISHINGS_STAPLE_TRIPLE_BOTTOM)
4126*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = staple_keywords[value - IPP_FINISHINGS_STAPLE_TOP_LEFT];
4127*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_BIND_LEFT && value <= IPP_FINISHINGS_BIND_BOTTOM)
4128*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = bind_keywords[value - IPP_FINISHINGS_BIND_LEFT];
4129*5e7646d2SAndroid Build Coastguard Worker else
4130*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = NULL;
4131*5e7646d2SAndroid Build Coastguard Worker
4132*5e7646d2SAndroid Build Coastguard Worker if (!ppd_keyword)
4133*5e7646d2SAndroid Build Coastguard Worker continue;
4134*5e7646d2SAndroid Build Coastguard Worker
4135*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", ppd_keyword);
4136*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
4137*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, keyword, ppd_keyword);
4138*5e7646d2SAndroid Build Coastguard Worker }
4139*5e7646d2SAndroid Build Coastguard Worker
4140*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *StapleLocation\n");
4141*5e7646d2SAndroid Build Coastguard Worker }
4142*5e7646d2SAndroid Build Coastguard Worker
4143*5e7646d2SAndroid Build Coastguard Worker /*
4144*5e7646d2SAndroid Build Coastguard Worker * Fold
4145*5e7646d2SAndroid Build Coastguard Worker */
4146*5e7646d2SAndroid Build Coastguard Worker
4147*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4148*5e7646d2SAndroid Build Coastguard Worker {
4149*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4150*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4151*5e7646d2SAndroid Build Coastguard Worker
4152*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(keyword, "cups-fold-", 10) || !strcmp(keyword, "fold") || !strncmp(keyword, "fold-", 5))
4153*5e7646d2SAndroid Build Coastguard Worker break;
4154*5e7646d2SAndroid Build Coastguard Worker }
4155*5e7646d2SAndroid Build Coastguard Worker
4156*5e7646d2SAndroid Build Coastguard Worker if (i < count)
4157*5e7646d2SAndroid Build Coastguard Worker {
4158*5e7646d2SAndroid Build Coastguard Worker static const char * const fold_keywords[] =
4159*5e7646d2SAndroid Build Coastguard Worker { /* FoldType keywords */
4160*5e7646d2SAndroid Build Coastguard Worker "Accordion",
4161*5e7646d2SAndroid Build Coastguard Worker "DoubleGate",
4162*5e7646d2SAndroid Build Coastguard Worker "Gate",
4163*5e7646d2SAndroid Build Coastguard Worker "Half",
4164*5e7646d2SAndroid Build Coastguard Worker "HalfZ",
4165*5e7646d2SAndroid Build Coastguard Worker "LeftGate",
4166*5e7646d2SAndroid Build Coastguard Worker "Letter",
4167*5e7646d2SAndroid Build Coastguard Worker "Parallel",
4168*5e7646d2SAndroid Build Coastguard Worker "XFold",
4169*5e7646d2SAndroid Build Coastguard Worker "RightGate",
4170*5e7646d2SAndroid Build Coastguard Worker "ZFold",
4171*5e7646d2SAndroid Build Coastguard Worker "EngineeringZ"
4172*5e7646d2SAndroid Build Coastguard Worker };
4173*5e7646d2SAndroid Build Coastguard Worker
4174*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(fin_options, "*FoldType");
4175*5e7646d2SAndroid Build Coastguard Worker
4176*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *FoldType: PickOne\n");
4177*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n");
4178*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation FoldType/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Fold")));
4179*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultFoldType: None\n");
4180*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*FoldType None: \"\"\n");
4181*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.FoldType None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
4182*5e7646d2SAndroid Build Coastguard Worker
4183*5e7646d2SAndroid Build Coastguard Worker for (; i < count; i ++)
4184*5e7646d2SAndroid Build Coastguard Worker {
4185*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4186*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4187*5e7646d2SAndroid Build Coastguard Worker
4188*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(keyword, "cups-fold-", 10))
4189*5e7646d2SAndroid Build Coastguard Worker keyword += 5;
4190*5e7646d2SAndroid Build Coastguard Worker else if (strcmp(keyword, "fold") && strncmp(keyword, "fold-", 5))
4191*5e7646d2SAndroid Build Coastguard Worker continue;
4192*5e7646d2SAndroid Build Coastguard Worker
4193*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(names, (char *)keyword))
4194*5e7646d2SAndroid Build Coastguard Worker continue; /* Already did this finishing template */
4195*5e7646d2SAndroid Build Coastguard Worker
4196*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(names, (char *)keyword);
4197*5e7646d2SAndroid Build Coastguard Worker
4198*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "finishings.%d", value);
4199*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
4200*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
4201*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
4202*5e7646d2SAndroid Build Coastguard Worker
4203*5e7646d2SAndroid Build Coastguard Worker if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
4204*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
4205*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_FOLD_ACCORDION && value <= IPP_FINISHINGS_FOLD_ENGINEERING_Z)
4206*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = fold_keywords[value - IPP_FINISHINGS_FOLD_ACCORDION];
4207*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_CUPS_FOLD_ACCORDION && value <= IPP_FINISHINGS_CUPS_FOLD_Z)
4208*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = fold_keywords[value - IPP_FINISHINGS_CUPS_FOLD_ACCORDION];
4209*5e7646d2SAndroid Build Coastguard Worker else
4210*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = NULL;
4211*5e7646d2SAndroid Build Coastguard Worker
4212*5e7646d2SAndroid Build Coastguard Worker if (!ppd_keyword)
4213*5e7646d2SAndroid Build Coastguard Worker continue;
4214*5e7646d2SAndroid Build Coastguard Worker
4215*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*FoldType %s: \"\"\n", ppd_keyword);
4216*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
4217*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, keyword, ppd_keyword);
4218*5e7646d2SAndroid Build Coastguard Worker }
4219*5e7646d2SAndroid Build Coastguard Worker
4220*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *FoldType\n");
4221*5e7646d2SAndroid Build Coastguard Worker }
4222*5e7646d2SAndroid Build Coastguard Worker
4223*5e7646d2SAndroid Build Coastguard Worker /*
4224*5e7646d2SAndroid Build Coastguard Worker * Punch
4225*5e7646d2SAndroid Build Coastguard Worker */
4226*5e7646d2SAndroid Build Coastguard Worker
4227*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4228*5e7646d2SAndroid Build Coastguard Worker {
4229*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4230*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4231*5e7646d2SAndroid Build Coastguard Worker
4232*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(keyword, "cups-punch-", 11) || !strncmp(keyword, "punch-", 6))
4233*5e7646d2SAndroid Build Coastguard Worker break;
4234*5e7646d2SAndroid Build Coastguard Worker }
4235*5e7646d2SAndroid Build Coastguard Worker
4236*5e7646d2SAndroid Build Coastguard Worker if (i < count)
4237*5e7646d2SAndroid Build Coastguard Worker {
4238*5e7646d2SAndroid Build Coastguard Worker static const char * const punch_keywords[] =
4239*5e7646d2SAndroid Build Coastguard Worker { /* PunchMedia keywords */
4240*5e7646d2SAndroid Build Coastguard Worker "SinglePortrait",
4241*5e7646d2SAndroid Build Coastguard Worker "SingleRevLandscape",
4242*5e7646d2SAndroid Build Coastguard Worker "SingleLandscape",
4243*5e7646d2SAndroid Build Coastguard Worker "SingleRevPortrait",
4244*5e7646d2SAndroid Build Coastguard Worker "DualPortrait",
4245*5e7646d2SAndroid Build Coastguard Worker "DualLandscape",
4246*5e7646d2SAndroid Build Coastguard Worker "DualRevPortrait",
4247*5e7646d2SAndroid Build Coastguard Worker "DualRevLandscape",
4248*5e7646d2SAndroid Build Coastguard Worker "TriplePortrait",
4249*5e7646d2SAndroid Build Coastguard Worker "TripleLandscape",
4250*5e7646d2SAndroid Build Coastguard Worker "TripleRevPortrait",
4251*5e7646d2SAndroid Build Coastguard Worker "TripleRevLandscape",
4252*5e7646d2SAndroid Build Coastguard Worker "QuadPortrait",
4253*5e7646d2SAndroid Build Coastguard Worker "QuadLandscape",
4254*5e7646d2SAndroid Build Coastguard Worker "QuadRevPortrait",
4255*5e7646d2SAndroid Build Coastguard Worker "QuadRevLandscape",
4256*5e7646d2SAndroid Build Coastguard Worker "MultiplePortrait",
4257*5e7646d2SAndroid Build Coastguard Worker "MultipleLandscape",
4258*5e7646d2SAndroid Build Coastguard Worker "MultipleRevPortrait",
4259*5e7646d2SAndroid Build Coastguard Worker "MultipleRevLandscape"
4260*5e7646d2SAndroid Build Coastguard Worker };
4261*5e7646d2SAndroid Build Coastguard Worker
4262*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(fin_options, "*PunchMedia");
4263*5e7646d2SAndroid Build Coastguard Worker
4264*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *PunchMedia: PickOne\n");
4265*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n");
4266*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation PunchMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Punch")));
4267*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultPunchMedia: None\n");
4268*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*PunchMedia None: \"\"\n");
4269*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.PunchMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
4270*5e7646d2SAndroid Build Coastguard Worker
4271*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4272*5e7646d2SAndroid Build Coastguard Worker {
4273*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4274*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4275*5e7646d2SAndroid Build Coastguard Worker
4276*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(keyword, "cups-punch-", 11))
4277*5e7646d2SAndroid Build Coastguard Worker keyword += 5;
4278*5e7646d2SAndroid Build Coastguard Worker else if (strncmp(keyword, "punch-", 6))
4279*5e7646d2SAndroid Build Coastguard Worker continue;
4280*5e7646d2SAndroid Build Coastguard Worker
4281*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(names, (char *)keyword))
4282*5e7646d2SAndroid Build Coastguard Worker continue; /* Already did this finishing template */
4283*5e7646d2SAndroid Build Coastguard Worker
4284*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(names, (char *)keyword);
4285*5e7646d2SAndroid Build Coastguard Worker
4286*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "finishings.%d", value);
4287*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
4288*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
4289*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
4290*5e7646d2SAndroid Build Coastguard Worker
4291*5e7646d2SAndroid Build Coastguard Worker if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE)
4292*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE];
4293*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_PUNCH_TOP_LEFT && value <= IPP_FINISHINGS_PUNCH_MULTIPLE_BOTTOM)
4294*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = punch_keywords[value - IPP_FINISHINGS_PUNCH_TOP_LEFT];
4295*5e7646d2SAndroid Build Coastguard Worker else if (value >= IPP_FINISHINGS_CUPS_PUNCH_TOP_LEFT && value <= IPP_FINISHINGS_CUPS_PUNCH_QUAD_BOTTOM)
4296*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = punch_keywords[value - IPP_FINISHINGS_CUPS_PUNCH_TOP_LEFT];
4297*5e7646d2SAndroid Build Coastguard Worker else
4298*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = NULL;
4299*5e7646d2SAndroid Build Coastguard Worker
4300*5e7646d2SAndroid Build Coastguard Worker if (!ppd_keyword)
4301*5e7646d2SAndroid Build Coastguard Worker continue;
4302*5e7646d2SAndroid Build Coastguard Worker
4303*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", ppd_keyword);
4304*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
4305*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, keyword, ppd_keyword);
4306*5e7646d2SAndroid Build Coastguard Worker }
4307*5e7646d2SAndroid Build Coastguard Worker
4308*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *PunchMedia\n");
4309*5e7646d2SAndroid Build Coastguard Worker }
4310*5e7646d2SAndroid Build Coastguard Worker
4311*5e7646d2SAndroid Build Coastguard Worker /*
4312*5e7646d2SAndroid Build Coastguard Worker * Booklet
4313*5e7646d2SAndroid Build Coastguard Worker */
4314*5e7646d2SAndroid Build Coastguard Worker
4315*5e7646d2SAndroid Build Coastguard Worker if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER))
4316*5e7646d2SAndroid Build Coastguard Worker {
4317*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(fin_options, "*Booklet");
4318*5e7646d2SAndroid Build Coastguard Worker
4319*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *Booklet: Boolean\n");
4320*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n");
4321*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation Booklet/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Booklet")));
4322*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultBooklet: False\n");
4323*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*Booklet False: \"\"\n");
4324*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*Booklet True: \"\"\n");
4325*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsIPPFinishings %d/booklet-maker: \"*Booklet True\"\n", IPP_FINISHINGS_BOOKLET_MAKER);
4326*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *Booklet\n");
4327*5e7646d2SAndroid Build Coastguard Worker }
4328*5e7646d2SAndroid Build Coastguard Worker
4329*5e7646d2SAndroid Build Coastguard Worker /*
4330*5e7646d2SAndroid Build Coastguard Worker * CutMedia
4331*5e7646d2SAndroid Build Coastguard Worker */
4332*5e7646d2SAndroid Build Coastguard Worker
4333*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4334*5e7646d2SAndroid Build Coastguard Worker {
4335*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4336*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4337*5e7646d2SAndroid Build Coastguard Worker
4338*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "trim") || !strncmp(keyword, "trim-", 5))
4339*5e7646d2SAndroid Build Coastguard Worker break;
4340*5e7646d2SAndroid Build Coastguard Worker }
4341*5e7646d2SAndroid Build Coastguard Worker
4342*5e7646d2SAndroid Build Coastguard Worker if (i < count)
4343*5e7646d2SAndroid Build Coastguard Worker {
4344*5e7646d2SAndroid Build Coastguard Worker static const char * const trim_keywords[] =
4345*5e7646d2SAndroid Build Coastguard Worker { /* CutMedia keywords */
4346*5e7646d2SAndroid Build Coastguard Worker "EndOfPage",
4347*5e7646d2SAndroid Build Coastguard Worker "EndOfDoc",
4348*5e7646d2SAndroid Build Coastguard Worker "EndOfSet",
4349*5e7646d2SAndroid Build Coastguard Worker "EndOfJob"
4350*5e7646d2SAndroid Build Coastguard Worker };
4351*5e7646d2SAndroid Build Coastguard Worker
4352*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(fin_options, "*CutMedia");
4353*5e7646d2SAndroid Build Coastguard Worker
4354*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *CutMedia: PickOne\n");
4355*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *CutMedia\n");
4356*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation CutMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Cut")));
4357*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultCutMedia: None\n");
4358*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CutMedia None: \"\"\n");
4359*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.CutMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
4360*5e7646d2SAndroid Build Coastguard Worker
4361*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4362*5e7646d2SAndroid Build Coastguard Worker {
4363*5e7646d2SAndroid Build Coastguard Worker value = ippGetInteger(attr, i);
4364*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", value);
4365*5e7646d2SAndroid Build Coastguard Worker
4366*5e7646d2SAndroid Build Coastguard Worker if (strcmp(keyword, "trim") && strncmp(keyword, "trim-", 5))
4367*5e7646d2SAndroid Build Coastguard Worker continue;
4368*5e7646d2SAndroid Build Coastguard Worker
4369*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(names, (char *)keyword))
4370*5e7646d2SAndroid Build Coastguard Worker continue; /* Already did this finishing template */
4371*5e7646d2SAndroid Build Coastguard Worker
4372*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(names, (char *)keyword);
4373*5e7646d2SAndroid Build Coastguard Worker
4374*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "finishings.%d", value);
4375*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
4376*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
4377*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
4378*5e7646d2SAndroid Build Coastguard Worker
4379*5e7646d2SAndroid Build Coastguard Worker if (value == IPP_FINISHINGS_TRIM)
4380*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = "Auto";
4381*5e7646d2SAndroid Build Coastguard Worker else
4382*5e7646d2SAndroid Build Coastguard Worker ppd_keyword = trim_keywords[value - IPP_FINISHINGS_TRIM_AFTER_PAGES];
4383*5e7646d2SAndroid Build Coastguard Worker
4384*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*CutMedia %s: \"\"\n", ppd_keyword);
4385*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.CutMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr);
4386*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*CutMedia %s\"\n", value, keyword, ppd_keyword);
4387*5e7646d2SAndroid Build Coastguard Worker }
4388*5e7646d2SAndroid Build Coastguard Worker
4389*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *CutMedia\n");
4390*5e7646d2SAndroid Build Coastguard Worker }
4391*5e7646d2SAndroid Build Coastguard Worker
4392*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(names);
4393*5e7646d2SAndroid Build Coastguard Worker }
4394*5e7646d2SAndroid Build Coastguard Worker
4395*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "finishings-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
4396*5e7646d2SAndroid Build Coastguard Worker {
4397*5e7646d2SAndroid Build Coastguard Worker ipp_t *finishing_col; /* Current finishing collection */
4398*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *finishing_attr; /* Current finishing member attribute */
4399*5e7646d2SAndroid Build Coastguard Worker cups_array_t *templates; /* Finishing templates */
4400*5e7646d2SAndroid Build Coastguard Worker
4401*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OpenUI *cupsFinishingTemplate: PickOne\n");
4402*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n");
4403*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.Translation cupsFinishingTemplate/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Finishing Preset")));
4404*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*DefaultcupsFinishingTemplate: none\n");
4405*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsFinishingTemplate none: \"\"\n");
4406*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.cupsFinishingTemplate none/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None")));
4407*5e7646d2SAndroid Build Coastguard Worker
4408*5e7646d2SAndroid Build Coastguard Worker templates = cupsArrayNew((cups_array_func_t)strcmp, NULL);
4409*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
4410*5e7646d2SAndroid Build Coastguard Worker
4411*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < count; i ++)
4412*5e7646d2SAndroid Build Coastguard Worker {
4413*5e7646d2SAndroid Build Coastguard Worker finishing_col = ippGetCollection(attr, i);
4414*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(ippFindAttribute(finishing_col, "finishing-template", IPP_TAG_ZERO), 0, NULL);
4415*5e7646d2SAndroid Build Coastguard Worker
4416*5e7646d2SAndroid Build Coastguard Worker if (!keyword || cupsArrayFind(templates, (void *)keyword))
4417*5e7646d2SAndroid Build Coastguard Worker continue;
4418*5e7646d2SAndroid Build Coastguard Worker
4419*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "none"))
4420*5e7646d2SAndroid Build Coastguard Worker continue;
4421*5e7646d2SAndroid Build Coastguard Worker
4422*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(templates, (void *)keyword);
4423*5e7646d2SAndroid Build Coastguard Worker
4424*5e7646d2SAndroid Build Coastguard Worker snprintf(msgid, sizeof(msgid), "finishing-template.%s", keyword);
4425*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr))
4426*5e7646d2SAndroid Build Coastguard Worker if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid)
4427*5e7646d2SAndroid Build Coastguard Worker msgstr = keyword;
4428*5e7646d2SAndroid Build Coastguard Worker
4429*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsFinishingTemplate %s: \"\n", keyword);
4430*5e7646d2SAndroid Build Coastguard Worker for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr; finishing_attr = ippNextAttribute(finishing_col))
4431*5e7646d2SAndroid Build Coastguard Worker {
4432*5e7646d2SAndroid Build Coastguard Worker if (ippGetValueTag(finishing_attr) == IPP_TAG_BEGIN_COLLECTION)
4433*5e7646d2SAndroid Build Coastguard Worker {
4434*5e7646d2SAndroid Build Coastguard Worker const char *name = ippGetName(finishing_attr);
4435*5e7646d2SAndroid Build Coastguard Worker /* Member attribute name */
4436*5e7646d2SAndroid Build Coastguard Worker
4437*5e7646d2SAndroid Build Coastguard Worker if (strcmp(name, "media-size"))
4438*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "%% %s\n", name);
4439*5e7646d2SAndroid Build Coastguard Worker }
4440*5e7646d2SAndroid Build Coastguard Worker }
4441*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "\"\n");
4442*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.cupsFinishingTemplate %s/%s: \"\"\n", lang->language, keyword, msgstr);
4443*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*End\n");
4444*5e7646d2SAndroid Build Coastguard Worker }
4445*5e7646d2SAndroid Build Coastguard Worker
4446*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *cupsFinishingTemplate\n");
4447*5e7646d2SAndroid Build Coastguard Worker
4448*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(fin_options))
4449*5e7646d2SAndroid Build Coastguard Worker {
4450*5e7646d2SAndroid Build Coastguard Worker const char *fin_option; /* Current finishing option */
4451*5e7646d2SAndroid Build Coastguard Worker
4452*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsUIConstraint finishing-template: \"*cupsFinishingTemplate");
4453*5e7646d2SAndroid Build Coastguard Worker for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
4454*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, " %s", fin_option);
4455*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "\"\n");
4456*5e7646d2SAndroid Build Coastguard Worker
4457*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*cupsUIResolver finishing-template: \"*cupsFinishingTemplate None");
4458*5e7646d2SAndroid Build Coastguard Worker for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options))
4459*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, " %s None", fin_option);
4460*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "\"\n");
4461*5e7646d2SAndroid Build Coastguard Worker }
4462*5e7646d2SAndroid Build Coastguard Worker
4463*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(templates);
4464*5e7646d2SAndroid Build Coastguard Worker }
4465*5e7646d2SAndroid Build Coastguard Worker
4466*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(fin_options);
4467*5e7646d2SAndroid Build Coastguard Worker
4468*5e7646d2SAndroid Build Coastguard Worker /*
4469*5e7646d2SAndroid Build Coastguard Worker * cupsPrintQuality and DefaultResolution...
4470*5e7646d2SAndroid Build Coastguard Worker */
4471*5e7646d2SAndroid Build Coastguard Worker
4472*5e7646d2SAndroid Build Coastguard Worker quality = ippFindAttribute(response, "print-quality-supported", IPP_TAG_ENUM);
4473*5e7646d2SAndroid Build Coastguard Worker
4474*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
4475*5e7646d2SAndroid Build Coastguard Worker {
4476*5e7646d2SAndroid Build Coastguard Worker int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
4477*5e7646d2SAndroid Build Coastguard Worker
4478*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
4479*5e7646d2SAndroid Build Coastguard Worker {
4480*5e7646d2SAndroid Build Coastguard Worker const char *rs = ippGetString(attr, i, NULL);
4481*5e7646d2SAndroid Build Coastguard Worker /* RS value */
4482*5e7646d2SAndroid Build Coastguard Worker
4483*5e7646d2SAndroid Build Coastguard Worker if (_cups_strncasecmp(rs, "RS", 2))
4484*5e7646d2SAndroid Build Coastguard Worker continue;
4485*5e7646d2SAndroid Build Coastguard Worker
4486*5e7646d2SAndroid Build Coastguard Worker lowdpi = atoi(rs + 2);
4487*5e7646d2SAndroid Build Coastguard Worker if ((rs = strrchr(rs, '-')) != NULL)
4488*5e7646d2SAndroid Build Coastguard Worker hidpi = atoi(rs + 1);
4489*5e7646d2SAndroid Build Coastguard Worker else
4490*5e7646d2SAndroid Build Coastguard Worker hidpi = lowdpi;
4491*5e7646d2SAndroid Build Coastguard Worker break;
4492*5e7646d2SAndroid Build Coastguard Worker }
4493*5e7646d2SAndroid Build Coastguard Worker
4494*5e7646d2SAndroid Build Coastguard Worker if (lowdpi == 0)
4495*5e7646d2SAndroid Build Coastguard Worker {
4496*5e7646d2SAndroid Build Coastguard Worker /*
4497*5e7646d2SAndroid Build Coastguard Worker * Invalid "urf-supported" value...
4498*5e7646d2SAndroid Build Coastguard Worker */
4499*5e7646d2SAndroid Build Coastguard Worker
4500*5e7646d2SAndroid Build Coastguard Worker goto bad_ppd;
4501*5e7646d2SAndroid Build Coastguard Worker }
4502*5e7646d2SAndroid Build Coastguard Worker else
4503*5e7646d2SAndroid Build Coastguard Worker {
4504*5e7646d2SAndroid Build Coastguard Worker /*
4505*5e7646d2SAndroid Build Coastguard Worker * Generate print qualities based on low and high DPIs...
4506*5e7646d2SAndroid Build Coastguard Worker */
4507*5e7646d2SAndroid Build Coastguard Worker
4508*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi);
4509*5e7646d2SAndroid Build Coastguard Worker
4510*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
4511*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
4512*5e7646d2SAndroid Build Coastguard Worker "*%s.Translation cupsPrintQuality/%s: \"\"\n"
4513*5e7646d2SAndroid Build Coastguard Worker "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
4514*5e7646d2SAndroid Build Coastguard Worker if ((lowdpi & 1) == 0)
4515*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi / 2, lang->language, _cupsLangString(lang, _("Draft")));
4516*5e7646d2SAndroid Build Coastguard Worker else if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
4517*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Draft")));
4518*5e7646d2SAndroid Build Coastguard Worker
4519*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Normal")));
4520*5e7646d2SAndroid Build Coastguard Worker
4521*5e7646d2SAndroid Build Coastguard Worker if (hidpi > lowdpi || ippContainsInteger(quality, IPP_QUALITY_HIGH))
4522*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", hidpi, hidpi, lang->language, _cupsLangString(lang, _("High")));
4523*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
4524*5e7646d2SAndroid Build Coastguard Worker }
4525*5e7646d2SAndroid Build Coastguard Worker }
4526*5e7646d2SAndroid Build Coastguard Worker else if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL)
4527*5e7646d2SAndroid Build Coastguard Worker {
4528*5e7646d2SAndroid Build Coastguard Worker /*
4529*5e7646d2SAndroid Build Coastguard Worker * Make a sorted list of resolutions.
4530*5e7646d2SAndroid Build Coastguard Worker */
4531*5e7646d2SAndroid Build Coastguard Worker
4532*5e7646d2SAndroid Build Coastguard Worker count = ippGetCount(attr);
4533*5e7646d2SAndroid Build Coastguard Worker if (count > (int)(sizeof(resolutions) / sizeof(resolutions[0])))
4534*5e7646d2SAndroid Build Coastguard Worker count = (int)(sizeof(resolutions) / sizeof(resolutions[0]));
4535*5e7646d2SAndroid Build Coastguard Worker
4536*5e7646d2SAndroid Build Coastguard Worker resolutions[0] = 0; /* Not in loop to silence Clang static analyzer... */
4537*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < count; i ++)
4538*5e7646d2SAndroid Build Coastguard Worker resolutions[i] = i;
4539*5e7646d2SAndroid Build Coastguard Worker
4540*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < (count - 1); i ++)
4541*5e7646d2SAndroid Build Coastguard Worker {
4542*5e7646d2SAndroid Build Coastguard Worker for (j = i + 1; j < count; j ++)
4543*5e7646d2SAndroid Build Coastguard Worker {
4544*5e7646d2SAndroid Build Coastguard Worker int ix, iy, /* First X and Y resolution */
4545*5e7646d2SAndroid Build Coastguard Worker jx, jy, /* Second X and Y resolution */
4546*5e7646d2SAndroid Build Coastguard Worker temp; /* Swap variable */
4547*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Resolution units */
4548*5e7646d2SAndroid Build Coastguard Worker
4549*5e7646d2SAndroid Build Coastguard Worker ix = ippGetResolution(attr, resolutions[i], &iy, &units);
4550*5e7646d2SAndroid Build Coastguard Worker jx = ippGetResolution(attr, resolutions[j], &jy, &units);
4551*5e7646d2SAndroid Build Coastguard Worker
4552*5e7646d2SAndroid Build Coastguard Worker if (ix > jx || (ix == jx && iy > jy))
4553*5e7646d2SAndroid Build Coastguard Worker {
4554*5e7646d2SAndroid Build Coastguard Worker /*
4555*5e7646d2SAndroid Build Coastguard Worker * Swap these two resolutions...
4556*5e7646d2SAndroid Build Coastguard Worker */
4557*5e7646d2SAndroid Build Coastguard Worker
4558*5e7646d2SAndroid Build Coastguard Worker temp = resolutions[i];
4559*5e7646d2SAndroid Build Coastguard Worker resolutions[i] = resolutions[j];
4560*5e7646d2SAndroid Build Coastguard Worker resolutions[j] = temp;
4561*5e7646d2SAndroid Build Coastguard Worker }
4562*5e7646d2SAndroid Build Coastguard Worker }
4563*5e7646d2SAndroid Build Coastguard Worker }
4564*5e7646d2SAndroid Build Coastguard Worker
4565*5e7646d2SAndroid Build Coastguard Worker /*
4566*5e7646d2SAndroid Build Coastguard Worker * Generate print quality options...
4567*5e7646d2SAndroid Build Coastguard Worker */
4568*5e7646d2SAndroid Build Coastguard Worker
4569*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, ppdname, sizeof(ppdname));
4570*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
4571*5e7646d2SAndroid Build Coastguard Worker
4572*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
4573*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
4574*5e7646d2SAndroid Build Coastguard Worker "*%s.Translation cupsPrintQuality/%s: \"\"\n"
4575*5e7646d2SAndroid Build Coastguard Worker "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
4576*5e7646d2SAndroid Build Coastguard Worker if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT))
4577*5e7646d2SAndroid Build Coastguard Worker {
4578*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(attr, resolutions[0], &xres, &yres, NULL, 0);
4579*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
4580*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.cupsPrintQuality Draft/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Draft")));
4581*5e7646d2SAndroid Build Coastguard Worker }
4582*5e7646d2SAndroid Build Coastguard Worker
4583*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, NULL, 0);
4584*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
4585*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.cupsPrintQuality Normal/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Normal")));
4586*5e7646d2SAndroid Build Coastguard Worker
4587*5e7646d2SAndroid Build Coastguard Worker if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH))
4588*5e7646d2SAndroid Build Coastguard Worker {
4589*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(attr, resolutions[count - 1], &xres, &yres, NULL, 0);
4590*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
4591*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.cupsPrintQuality High/%s: \"\"\n", lang->language, _cupsLangString(lang, _("High")));
4592*5e7646d2SAndroid Build Coastguard Worker }
4593*5e7646d2SAndroid Build Coastguard Worker
4594*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
4595*5e7646d2SAndroid Build Coastguard Worker }
4596*5e7646d2SAndroid Build Coastguard Worker else if (is_apple || is_pwg)
4597*5e7646d2SAndroid Build Coastguard Worker goto bad_ppd;
4598*5e7646d2SAndroid Build Coastguard Worker else
4599*5e7646d2SAndroid Build Coastguard Worker {
4600*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
4601*5e7646d2SAndroid Build Coastguard Worker {
4602*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(attr, 0, &xres, &yres, ppdname, sizeof(ppdname));
4603*5e7646d2SAndroid Build Coastguard Worker }
4604*5e7646d2SAndroid Build Coastguard Worker else
4605*5e7646d2SAndroid Build Coastguard Worker {
4606*5e7646d2SAndroid Build Coastguard Worker xres = yres = 300;
4607*5e7646d2SAndroid Build Coastguard Worker strlcpy(ppdname, "300dpi", sizeof(ppdname));
4608*5e7646d2SAndroid Build Coastguard Worker }
4609*5e7646d2SAndroid Build Coastguard Worker
4610*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
4611*5e7646d2SAndroid Build Coastguard Worker
4612*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n"
4613*5e7646d2SAndroid Build Coastguard Worker "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
4614*5e7646d2SAndroid Build Coastguard Worker "*%s.Translation cupsPrintQuality/%s: \"\"\n"
4615*5e7646d2SAndroid Build Coastguard Worker "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality")));
4616*5e7646d2SAndroid Build Coastguard Worker if (ippContainsInteger(quality, IPP_QUALITY_DRAFT))
4617*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Draft")));
4618*5e7646d2SAndroid Build Coastguard Worker
4619*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Normal")));
4620*5e7646d2SAndroid Build Coastguard Worker
4621*5e7646d2SAndroid Build Coastguard Worker if (ippContainsInteger(quality, IPP_QUALITY_HIGH))
4622*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("High")));
4623*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
4624*5e7646d2SAndroid Build Coastguard Worker }
4625*5e7646d2SAndroid Build Coastguard Worker
4626*5e7646d2SAndroid Build Coastguard Worker /*
4627*5e7646d2SAndroid Build Coastguard Worker * Presets...
4628*5e7646d2SAndroid Build Coastguard Worker */
4629*5e7646d2SAndroid Build Coastguard Worker
4630*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "job-presets-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
4631*5e7646d2SAndroid Build Coastguard Worker {
4632*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(attr); i < count; i ++)
4633*5e7646d2SAndroid Build Coastguard Worker {
4634*5e7646d2SAndroid Build Coastguard Worker ipp_t *preset = ippGetCollection(attr, i);
4635*5e7646d2SAndroid Build Coastguard Worker /* Preset collection */
4636*5e7646d2SAndroid Build Coastguard Worker const char *preset_name = ippGetString(ippFindAttribute(preset, "preset-name", IPP_TAG_ZERO), 0, NULL),
4637*5e7646d2SAndroid Build Coastguard Worker /* Preset name */
4638*5e7646d2SAndroid Build Coastguard Worker *localized_name; /* Localized preset name */
4639*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *member; /* Member attribute in preset */
4640*5e7646d2SAndroid Build Coastguard Worker const char *member_name; /* Member attribute name */
4641*5e7646d2SAndroid Build Coastguard Worker char member_value[256]; /* Member attribute value */
4642*5e7646d2SAndroid Build Coastguard Worker
4643*5e7646d2SAndroid Build Coastguard Worker if (!preset || !preset_name)
4644*5e7646d2SAndroid Build Coastguard Worker continue;
4645*5e7646d2SAndroid Build Coastguard Worker
4646*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*APPrinterPreset %s: \"\n", preset_name);
4647*5e7646d2SAndroid Build Coastguard Worker for (member = ippFirstAttribute(preset); member; member = ippNextAttribute(preset))
4648*5e7646d2SAndroid Build Coastguard Worker {
4649*5e7646d2SAndroid Build Coastguard Worker member_name = ippGetName(member);
4650*5e7646d2SAndroid Build Coastguard Worker
4651*5e7646d2SAndroid Build Coastguard Worker if (!member_name || !strcmp(member_name, "preset-name"))
4652*5e7646d2SAndroid Build Coastguard Worker continue;
4653*5e7646d2SAndroid Build Coastguard Worker
4654*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(member_name, "finishings"))
4655*5e7646d2SAndroid Build Coastguard Worker {
4656*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(member); i < count; i ++)
4657*5e7646d2SAndroid Build Coastguard Worker {
4658*5e7646d2SAndroid Build Coastguard Worker const char *option = NULL; /* PPD option name */
4659*5e7646d2SAndroid Build Coastguard Worker
4660*5e7646d2SAndroid Build Coastguard Worker keyword = ippEnumString("finishings", ippGetInteger(member, i));
4661*5e7646d2SAndroid Build Coastguard Worker
4662*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "booklet-maker"))
4663*5e7646d2SAndroid Build Coastguard Worker {
4664*5e7646d2SAndroid Build Coastguard Worker option = "Booklet";
4665*5e7646d2SAndroid Build Coastguard Worker keyword = "True";
4666*5e7646d2SAndroid Build Coastguard Worker }
4667*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(keyword, "fold-", 5))
4668*5e7646d2SAndroid Build Coastguard Worker option = "FoldType";
4669*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(keyword, "punch-", 6))
4670*5e7646d2SAndroid Build Coastguard Worker option = "PunchMedia";
4671*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(keyword, "bind-", 5) || !strncmp(keyword, "edge-stitch-", 12) || !strcmp(keyword, "saddle-stitch") || !strncmp(keyword, "staple-", 7))
4672*5e7646d2SAndroid Build Coastguard Worker option = "StapleLocation";
4673*5e7646d2SAndroid Build Coastguard Worker
4674*5e7646d2SAndroid Build Coastguard Worker if (option && keyword)
4675*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s %s\n", option, keyword);
4676*5e7646d2SAndroid Build Coastguard Worker }
4677*5e7646d2SAndroid Build Coastguard Worker }
4678*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "finishings-col"))
4679*5e7646d2SAndroid Build Coastguard Worker {
4680*5e7646d2SAndroid Build Coastguard Worker ipp_t *fin_col; /* finishings-col value */
4681*5e7646d2SAndroid Build Coastguard Worker
4682*5e7646d2SAndroid Build Coastguard Worker for (i = 0, count = ippGetCount(member); i < count; i ++)
4683*5e7646d2SAndroid Build Coastguard Worker {
4684*5e7646d2SAndroid Build Coastguard Worker fin_col = ippGetCollection(member, i);
4685*5e7646d2SAndroid Build Coastguard Worker
4686*5e7646d2SAndroid Build Coastguard Worker if ((keyword = ippGetString(ippFindAttribute(fin_col, "finishing-template", IPP_TAG_ZERO), 0, NULL)) != NULL)
4687*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsFinishingTemplate %s\n", keyword);
4688*5e7646d2SAndroid Build Coastguard Worker }
4689*5e7646d2SAndroid Build Coastguard Worker }
4690*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "media"))
4691*5e7646d2SAndroid Build Coastguard Worker {
4692*5e7646d2SAndroid Build Coastguard Worker /*
4693*5e7646d2SAndroid Build Coastguard Worker * Map media to PageSize...
4694*5e7646d2SAndroid Build Coastguard Worker */
4695*5e7646d2SAndroid Build Coastguard Worker
4696*5e7646d2SAndroid Build Coastguard Worker if ((pwg = pwgMediaForPWG(ippGetString(member, 0, NULL))) != NULL && pwg->ppd)
4697*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd);
4698*5e7646d2SAndroid Build Coastguard Worker }
4699*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "media-col"))
4700*5e7646d2SAndroid Build Coastguard Worker {
4701*5e7646d2SAndroid Build Coastguard Worker media_col = ippGetCollection(member, 0);
4702*5e7646d2SAndroid Build Coastguard Worker
4703*5e7646d2SAndroid Build Coastguard Worker if ((media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0)) != NULL)
4704*5e7646d2SAndroid Build Coastguard Worker {
4705*5e7646d2SAndroid Build Coastguard Worker x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
4706*5e7646d2SAndroid Build Coastguard Worker y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
4707*5e7646d2SAndroid Build Coastguard Worker if ((pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL && pwg->ppd)
4708*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd);
4709*5e7646d2SAndroid Build Coastguard Worker }
4710*5e7646d2SAndroid Build Coastguard Worker
4711*5e7646d2SAndroid Build Coastguard Worker if ((keyword = ippGetString(ippFindAttribute(media_col, "media-source", IPP_TAG_ZERO), 0, NULL)) != NULL)
4712*5e7646d2SAndroid Build Coastguard Worker {
4713*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
4714*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*InputSlot %s\n", keyword);
4715*5e7646d2SAndroid Build Coastguard Worker }
4716*5e7646d2SAndroid Build Coastguard Worker
4717*5e7646d2SAndroid Build Coastguard Worker if ((keyword = ippGetString(ippFindAttribute(media_col, "media-type", IPP_TAG_ZERO), 0, NULL)) != NULL)
4718*5e7646d2SAndroid Build Coastguard Worker {
4719*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(keyword, ppdname, sizeof(ppdname));
4720*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*MediaType %s\n", keyword);
4721*5e7646d2SAndroid Build Coastguard Worker }
4722*5e7646d2SAndroid Build Coastguard Worker }
4723*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "print-quality"))
4724*5e7646d2SAndroid Build Coastguard Worker {
4725*5e7646d2SAndroid Build Coastguard Worker /*
4726*5e7646d2SAndroid Build Coastguard Worker * Map print-quality to cupsPrintQuality...
4727*5e7646d2SAndroid Build Coastguard Worker */
4728*5e7646d2SAndroid Build Coastguard Worker
4729*5e7646d2SAndroid Build Coastguard Worker int qval = ippGetInteger(member, 0);
4730*5e7646d2SAndroid Build Coastguard Worker /* print-quality value */
4731*5e7646d2SAndroid Build Coastguard Worker static const char * const qualities[] = { "Draft", "Normal", "High" };
4732*5e7646d2SAndroid Build Coastguard Worker /* cupsPrintQuality values */
4733*5e7646d2SAndroid Build Coastguard Worker
4734*5e7646d2SAndroid Build Coastguard Worker if (qval >= IPP_QUALITY_DRAFT && qval <= IPP_QUALITY_HIGH)
4735*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*cupsPrintQuality %s\n", qualities[qval - IPP_QUALITY_DRAFT]);
4736*5e7646d2SAndroid Build Coastguard Worker }
4737*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "output-bin"))
4738*5e7646d2SAndroid Build Coastguard Worker {
4739*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(ippGetString(member, 0, NULL), ppdname, sizeof(ppdname));
4740*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*OutputBin %s\n", ppdname);
4741*5e7646d2SAndroid Build Coastguard Worker }
4742*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(member_name, "sides"))
4743*5e7646d2SAndroid Build Coastguard Worker {
4744*5e7646d2SAndroid Build Coastguard Worker keyword = ippGetString(member, 0, NULL);
4745*5e7646d2SAndroid Build Coastguard Worker if (keyword && !strcmp(keyword, "one-sided"))
4746*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*Duplex None\n");
4747*5e7646d2SAndroid Build Coastguard Worker else if (keyword && !strcmp(keyword, "two-sided-long-edge"))
4748*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*Duplex DuplexNoTumble\n");
4749*5e7646d2SAndroid Build Coastguard Worker else if (keyword && !strcmp(keyword, "two-sided-short-edge"))
4750*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "*Duplex DuplexTumble\n");
4751*5e7646d2SAndroid Build Coastguard Worker }
4752*5e7646d2SAndroid Build Coastguard Worker else
4753*5e7646d2SAndroid Build Coastguard Worker {
4754*5e7646d2SAndroid Build Coastguard Worker /*
4755*5e7646d2SAndroid Build Coastguard Worker * Add attribute name and value as-is...
4756*5e7646d2SAndroid Build Coastguard Worker */
4757*5e7646d2SAndroid Build Coastguard Worker
4758*5e7646d2SAndroid Build Coastguard Worker ippAttributeString(member, member_value, sizeof(member_value));
4759*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s %s\n", member_name, member_value);
4760*5e7646d2SAndroid Build Coastguard Worker }
4761*5e7646d2SAndroid Build Coastguard Worker }
4762*5e7646d2SAndroid Build Coastguard Worker
4763*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "\"\n*End\n");
4764*5e7646d2SAndroid Build Coastguard Worker
4765*5e7646d2SAndroid Build Coastguard Worker if ((localized_name = _cupsMessageLookup(strings, preset_name)) != preset_name)
4766*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "*%s.APPrinterPreset %s/%s: \"\"\n", lang->language, preset_name, localized_name);
4767*5e7646d2SAndroid Build Coastguard Worker }
4768*5e7646d2SAndroid Build Coastguard Worker }
4769*5e7646d2SAndroid Build Coastguard Worker
4770*5e7646d2SAndroid Build Coastguard Worker /*
4771*5e7646d2SAndroid Build Coastguard Worker * Close up and return...
4772*5e7646d2SAndroid Build Coastguard Worker */
4773*5e7646d2SAndroid Build Coastguard Worker
4774*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
4775*5e7646d2SAndroid Build Coastguard Worker
4776*5e7646d2SAndroid Build Coastguard Worker return (buffer);
4777*5e7646d2SAndroid Build Coastguard Worker
4778*5e7646d2SAndroid Build Coastguard Worker /*
4779*5e7646d2SAndroid Build Coastguard Worker * If we get here then there was a problem creating the PPD...
4780*5e7646d2SAndroid Build Coastguard Worker */
4781*5e7646d2SAndroid Build Coastguard Worker
4782*5e7646d2SAndroid Build Coastguard Worker bad_ppd:
4783*5e7646d2SAndroid Build Coastguard Worker
4784*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
4785*5e7646d2SAndroid Build Coastguard Worker unlink(buffer);
4786*5e7646d2SAndroid Build Coastguard Worker *buffer = '\0';
4787*5e7646d2SAndroid Build Coastguard Worker
4788*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Printer does not support required IPP attributes or document formats."), 1);
4789*5e7646d2SAndroid Build Coastguard Worker
4790*5e7646d2SAndroid Build Coastguard Worker return (NULL);
4791*5e7646d2SAndroid Build Coastguard Worker }
4792*5e7646d2SAndroid Build Coastguard Worker
4793*5e7646d2SAndroid Build Coastguard Worker
4794*5e7646d2SAndroid Build Coastguard Worker /*
4795*5e7646d2SAndroid Build Coastguard Worker * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG
4796*5e7646d2SAndroid Build Coastguard Worker * media-source.
4797*5e7646d2SAndroid Build Coastguard Worker */
4798*5e7646d2SAndroid Build Coastguard Worker
4799*5e7646d2SAndroid Build Coastguard Worker const char * /* O - InputSlot name */
_pwgInputSlotForSource(const char * media_source,char * name,size_t namesize)4800*5e7646d2SAndroid Build Coastguard Worker _pwgInputSlotForSource(
4801*5e7646d2SAndroid Build Coastguard Worker const char *media_source, /* I - PWG media-source */
4802*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
4803*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of name buffer */
4804*5e7646d2SAndroid Build Coastguard Worker {
4805*5e7646d2SAndroid Build Coastguard Worker /*
4806*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4807*5e7646d2SAndroid Build Coastguard Worker */
4808*5e7646d2SAndroid Build Coastguard Worker
4809*5e7646d2SAndroid Build Coastguard Worker if (!media_source || !name || namesize < PPD_MAX_NAME)
4810*5e7646d2SAndroid Build Coastguard Worker return (NULL);
4811*5e7646d2SAndroid Build Coastguard Worker
4812*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(media_source, "main"))
4813*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Cassette", namesize);
4814*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "alternate"))
4815*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Multipurpose", namesize);
4816*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "large-capacity"))
4817*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "LargeCapacity", namesize);
4818*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "bottom"))
4819*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Lower", namesize);
4820*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "middle"))
4821*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Middle", namesize);
4822*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "top"))
4823*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Upper", namesize);
4824*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "rear"))
4825*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Rear", namesize);
4826*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "side"))
4827*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Side", namesize);
4828*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "envelope"))
4829*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Envelope", namesize);
4830*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "main-roll"))
4831*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Roll", namesize);
4832*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_source, "alternate-roll"))
4833*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Roll2", namesize);
4834*5e7646d2SAndroid Build Coastguard Worker else
4835*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(media_source, name, namesize);
4836*5e7646d2SAndroid Build Coastguard Worker
4837*5e7646d2SAndroid Build Coastguard Worker return (name);
4838*5e7646d2SAndroid Build Coastguard Worker }
4839*5e7646d2SAndroid Build Coastguard Worker
4840*5e7646d2SAndroid Build Coastguard Worker
4841*5e7646d2SAndroid Build Coastguard Worker /*
4842*5e7646d2SAndroid Build Coastguard Worker * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG
4843*5e7646d2SAndroid Build Coastguard Worker * media-type.
4844*5e7646d2SAndroid Build Coastguard Worker */
4845*5e7646d2SAndroid Build Coastguard Worker
4846*5e7646d2SAndroid Build Coastguard Worker const char * /* O - MediaType name */
_pwgMediaTypeForType(const char * media_type,char * name,size_t namesize)4847*5e7646d2SAndroid Build Coastguard Worker _pwgMediaTypeForType(
4848*5e7646d2SAndroid Build Coastguard Worker const char *media_type, /* I - PWG media-type */
4849*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
4850*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of name buffer */
4851*5e7646d2SAndroid Build Coastguard Worker {
4852*5e7646d2SAndroid Build Coastguard Worker /*
4853*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4854*5e7646d2SAndroid Build Coastguard Worker */
4855*5e7646d2SAndroid Build Coastguard Worker
4856*5e7646d2SAndroid Build Coastguard Worker if (!media_type || !name || namesize < PPD_MAX_NAME)
4857*5e7646d2SAndroid Build Coastguard Worker return (NULL);
4858*5e7646d2SAndroid Build Coastguard Worker
4859*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(media_type, "auto"))
4860*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Auto", namesize);
4861*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "cardstock"))
4862*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Cardstock", namesize);
4863*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "envelope"))
4864*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Envelope", namesize);
4865*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "photographic-glossy"))
4866*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Glossy", namesize);
4867*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "photographic-high-gloss"))
4868*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "HighGloss", namesize);
4869*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "photographic-matte"))
4870*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Matte", namesize);
4871*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "stationery"))
4872*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Plain", namesize);
4873*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "stationery-coated"))
4874*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Coated", namesize);
4875*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "stationery-inkjet"))
4876*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Inkjet", namesize);
4877*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "stationery-letterhead"))
4878*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Letterhead", namesize);
4879*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "stationery-preprinted"))
4880*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Preprinted", namesize);
4881*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(media_type, "transparency"))
4882*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, "Transparency", namesize);
4883*5e7646d2SAndroid Build Coastguard Worker else
4884*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(media_type, name, namesize);
4885*5e7646d2SAndroid Build Coastguard Worker
4886*5e7646d2SAndroid Build Coastguard Worker return (name);
4887*5e7646d2SAndroid Build Coastguard Worker }
4888*5e7646d2SAndroid Build Coastguard Worker
4889*5e7646d2SAndroid Build Coastguard Worker
4890*5e7646d2SAndroid Build Coastguard Worker /*
4891*5e7646d2SAndroid Build Coastguard Worker * '_pwgPageSizeForMedia()' - Get the PageSize name for the given media.
4892*5e7646d2SAndroid Build Coastguard Worker */
4893*5e7646d2SAndroid Build Coastguard Worker
4894*5e7646d2SAndroid Build Coastguard Worker const char * /* O - PageSize name */
_pwgPageSizeForMedia(pwg_media_t * media,char * name,size_t namesize)4895*5e7646d2SAndroid Build Coastguard Worker _pwgPageSizeForMedia(
4896*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *media, /* I - Media */
4897*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - PageSize name buffer */
4898*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of name buffer */
4899*5e7646d2SAndroid Build Coastguard Worker {
4900*5e7646d2SAndroid Build Coastguard Worker const char *sizeptr, /* Pointer to size in PWG name */
4901*5e7646d2SAndroid Build Coastguard Worker *dimptr; /* Pointer to dimensions in PWG name */
4902*5e7646d2SAndroid Build Coastguard Worker
4903*5e7646d2SAndroid Build Coastguard Worker
4904*5e7646d2SAndroid Build Coastguard Worker /*
4905*5e7646d2SAndroid Build Coastguard Worker * Range check input...
4906*5e7646d2SAndroid Build Coastguard Worker */
4907*5e7646d2SAndroid Build Coastguard Worker
4908*5e7646d2SAndroid Build Coastguard Worker if (!media || !name || namesize < PPD_MAX_NAME)
4909*5e7646d2SAndroid Build Coastguard Worker return (NULL);
4910*5e7646d2SAndroid Build Coastguard Worker
4911*5e7646d2SAndroid Build Coastguard Worker /*
4912*5e7646d2SAndroid Build Coastguard Worker * Copy or generate a PageSize name...
4913*5e7646d2SAndroid Build Coastguard Worker */
4914*5e7646d2SAndroid Build Coastguard Worker
4915*5e7646d2SAndroid Build Coastguard Worker if (media->ppd)
4916*5e7646d2SAndroid Build Coastguard Worker {
4917*5e7646d2SAndroid Build Coastguard Worker /*
4918*5e7646d2SAndroid Build Coastguard Worker * Use a standard Adobe name...
4919*5e7646d2SAndroid Build Coastguard Worker */
4920*5e7646d2SAndroid Build Coastguard Worker
4921*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, media->ppd, namesize);
4922*5e7646d2SAndroid Build Coastguard Worker }
4923*5e7646d2SAndroid Build Coastguard Worker else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) ||
4924*5e7646d2SAndroid Build Coastguard Worker (sizeptr = strchr(media->pwg, '_')) == NULL ||
4925*5e7646d2SAndroid Build Coastguard Worker (dimptr = strchr(sizeptr + 1, '_')) == NULL ||
4926*5e7646d2SAndroid Build Coastguard Worker (size_t)(dimptr - sizeptr) > namesize)
4927*5e7646d2SAndroid Build Coastguard Worker {
4928*5e7646d2SAndroid Build Coastguard Worker /*
4929*5e7646d2SAndroid Build Coastguard Worker * Use a name of the form "wNNNhNNN"...
4930*5e7646d2SAndroid Build Coastguard Worker */
4931*5e7646d2SAndroid Build Coastguard Worker
4932*5e7646d2SAndroid Build Coastguard Worker snprintf(name, namesize, "w%dh%d", (int)PWG_TO_POINTS(media->width),
4933*5e7646d2SAndroid Build Coastguard Worker (int)PWG_TO_POINTS(media->length));
4934*5e7646d2SAndroid Build Coastguard Worker }
4935*5e7646d2SAndroid Build Coastguard Worker else
4936*5e7646d2SAndroid Build Coastguard Worker {
4937*5e7646d2SAndroid Build Coastguard Worker /*
4938*5e7646d2SAndroid Build Coastguard Worker * Copy the size name from class_sizename_dimensions...
4939*5e7646d2SAndroid Build Coastguard Worker */
4940*5e7646d2SAndroid Build Coastguard Worker
4941*5e7646d2SAndroid Build Coastguard Worker memcpy(name, sizeptr + 1, (size_t)(dimptr - sizeptr - 1));
4942*5e7646d2SAndroid Build Coastguard Worker name[dimptr - sizeptr - 1] = '\0';
4943*5e7646d2SAndroid Build Coastguard Worker }
4944*5e7646d2SAndroid Build Coastguard Worker
4945*5e7646d2SAndroid Build Coastguard Worker return (name);
4946*5e7646d2SAndroid Build Coastguard Worker }
4947*5e7646d2SAndroid Build Coastguard Worker
4948*5e7646d2SAndroid Build Coastguard Worker
4949*5e7646d2SAndroid Build Coastguard Worker /*
4950*5e7646d2SAndroid Build Coastguard Worker * 'cups_get_url()' - Get a copy of the file at the given URL.
4951*5e7646d2SAndroid Build Coastguard Worker */
4952*5e7646d2SAndroid Build Coastguard Worker
4953*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success, 0 on failure */
cups_get_url(http_t ** http,const char * url,char * name,size_t namesize)4954*5e7646d2SAndroid Build Coastguard Worker cups_get_url(http_t **http, /* IO - Current HTTP connection */
4955*5e7646d2SAndroid Build Coastguard Worker const char *url, /* I - URL to get */
4956*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Temporary filename */
4957*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of temporary filename buffer */
4958*5e7646d2SAndroid Build Coastguard Worker {
4959*5e7646d2SAndroid Build Coastguard Worker char scheme[32], /* URL scheme */
4960*5e7646d2SAndroid Build Coastguard Worker userpass[256], /* URL username:password */
4961*5e7646d2SAndroid Build Coastguard Worker host[256], /* URL host */
4962*5e7646d2SAndroid Build Coastguard Worker curhost[256], /* Current host */
4963*5e7646d2SAndroid Build Coastguard Worker resource[256]; /* URL resource */
4964*5e7646d2SAndroid Build Coastguard Worker int port; /* URL port */
4965*5e7646d2SAndroid Build Coastguard Worker http_encryption_t encryption; /* Type of encryption to use */
4966*5e7646d2SAndroid Build Coastguard Worker http_status_t status; /* Status of GET request */
4967*5e7646d2SAndroid Build Coastguard Worker int fd; /* Temporary file */
4968*5e7646d2SAndroid Build Coastguard Worker
4969*5e7646d2SAndroid Build Coastguard Worker
4970*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
4971*5e7646d2SAndroid Build Coastguard Worker return (0);
4972*5e7646d2SAndroid Build Coastguard Worker
4973*5e7646d2SAndroid Build Coastguard Worker if (port == 443 || !strcmp(scheme, "https"))
4974*5e7646d2SAndroid Build Coastguard Worker encryption = HTTP_ENCRYPTION_ALWAYS;
4975*5e7646d2SAndroid Build Coastguard Worker else
4976*5e7646d2SAndroid Build Coastguard Worker encryption = HTTP_ENCRYPTION_IF_REQUESTED;
4977*5e7646d2SAndroid Build Coastguard Worker
4978*5e7646d2SAndroid Build Coastguard Worker if (!*http || strcasecmp(host, httpGetHostname(*http, curhost, sizeof(curhost))) || httpAddrPort(httpGetAddress(*http)) != port)
4979*5e7646d2SAndroid Build Coastguard Worker {
4980*5e7646d2SAndroid Build Coastguard Worker httpClose(*http);
4981*5e7646d2SAndroid Build Coastguard Worker *http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 5000, NULL);
4982*5e7646d2SAndroid Build Coastguard Worker }
4983*5e7646d2SAndroid Build Coastguard Worker
4984*5e7646d2SAndroid Build Coastguard Worker if (!*http)
4985*5e7646d2SAndroid Build Coastguard Worker return (0);
4986*5e7646d2SAndroid Build Coastguard Worker
4987*5e7646d2SAndroid Build Coastguard Worker if ((fd = cupsTempFd(name, (int)namesize)) < 0)
4988*5e7646d2SAndroid Build Coastguard Worker return (0);
4989*5e7646d2SAndroid Build Coastguard Worker
4990*5e7646d2SAndroid Build Coastguard Worker status = cupsGetFd(*http, resource, fd);
4991*5e7646d2SAndroid Build Coastguard Worker
4992*5e7646d2SAndroid Build Coastguard Worker close(fd);
4993*5e7646d2SAndroid Build Coastguard Worker
4994*5e7646d2SAndroid Build Coastguard Worker if (status != HTTP_STATUS_OK)
4995*5e7646d2SAndroid Build Coastguard Worker {
4996*5e7646d2SAndroid Build Coastguard Worker unlink(name);
4997*5e7646d2SAndroid Build Coastguard Worker *name = '\0';
4998*5e7646d2SAndroid Build Coastguard Worker return (0);
4999*5e7646d2SAndroid Build Coastguard Worker }
5000*5e7646d2SAndroid Build Coastguard Worker
5001*5e7646d2SAndroid Build Coastguard Worker return (1);
5002*5e7646d2SAndroid Build Coastguard Worker }
5003*5e7646d2SAndroid Build Coastguard Worker
5004*5e7646d2SAndroid Build Coastguard Worker
5005*5e7646d2SAndroid Build Coastguard Worker /*
5006*5e7646d2SAndroid Build Coastguard Worker * 'pwg_add_finishing()' - Add a finishings value.
5007*5e7646d2SAndroid Build Coastguard Worker */
5008*5e7646d2SAndroid Build Coastguard Worker
5009*5e7646d2SAndroid Build Coastguard Worker static void
pwg_add_finishing(cups_array_t * finishings,ipp_finishings_t template,const char * name,const char * value)5010*5e7646d2SAndroid Build Coastguard Worker pwg_add_finishing(
5011*5e7646d2SAndroid Build Coastguard Worker cups_array_t *finishings, /* I - Finishings array */
5012*5e7646d2SAndroid Build Coastguard Worker ipp_finishings_t template, /* I - Finishing template */
5013*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - PPD option */
5014*5e7646d2SAndroid Build Coastguard Worker const char *value) /* I - PPD choice */
5015*5e7646d2SAndroid Build Coastguard Worker {
5016*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *f; /* New finishings value */
5017*5e7646d2SAndroid Build Coastguard Worker
5018*5e7646d2SAndroid Build Coastguard Worker
5019*5e7646d2SAndroid Build Coastguard Worker if ((f = (_pwg_finishings_t *)calloc(1, sizeof(_pwg_finishings_t))) != NULL)
5020*5e7646d2SAndroid Build Coastguard Worker {
5021*5e7646d2SAndroid Build Coastguard Worker f->value = template;
5022*5e7646d2SAndroid Build Coastguard Worker f->num_options = cupsAddOption(name, value, 0, &f->options);
5023*5e7646d2SAndroid Build Coastguard Worker
5024*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(finishings, f);
5025*5e7646d2SAndroid Build Coastguard Worker }
5026*5e7646d2SAndroid Build Coastguard Worker }
5027*5e7646d2SAndroid Build Coastguard Worker
5028*5e7646d2SAndroid Build Coastguard Worker
5029*5e7646d2SAndroid Build Coastguard Worker /*
5030*5e7646d2SAndroid Build Coastguard Worker * 'pwg_add_message()' - Add a message to the PPD cached strings.
5031*5e7646d2SAndroid Build Coastguard Worker */
5032*5e7646d2SAndroid Build Coastguard Worker
5033*5e7646d2SAndroid Build Coastguard Worker static void
pwg_add_message(cups_array_t * a,const char * msg,const char * str)5034*5e7646d2SAndroid Build Coastguard Worker pwg_add_message(cups_array_t *a, /* I - Message catalog */
5035*5e7646d2SAndroid Build Coastguard Worker const char *msg, /* I - Message identifier */
5036*5e7646d2SAndroid Build Coastguard Worker const char *str) /* I - Localized string */
5037*5e7646d2SAndroid Build Coastguard Worker {
5038*5e7646d2SAndroid Build Coastguard Worker _cups_message_t *m; /* New message */
5039*5e7646d2SAndroid Build Coastguard Worker
5040*5e7646d2SAndroid Build Coastguard Worker
5041*5e7646d2SAndroid Build Coastguard Worker if ((m = calloc(1, sizeof(_cups_message_t))) != NULL)
5042*5e7646d2SAndroid Build Coastguard Worker {
5043*5e7646d2SAndroid Build Coastguard Worker m->msg = strdup(msg);
5044*5e7646d2SAndroid Build Coastguard Worker m->str = strdup(str);
5045*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(a, m);
5046*5e7646d2SAndroid Build Coastguard Worker }
5047*5e7646d2SAndroid Build Coastguard Worker }
5048*5e7646d2SAndroid Build Coastguard Worker
5049*5e7646d2SAndroid Build Coastguard Worker
5050*5e7646d2SAndroid Build Coastguard Worker /*
5051*5e7646d2SAndroid Build Coastguard Worker * 'pwg_compare_finishings()' - Compare two finishings values.
5052*5e7646d2SAndroid Build Coastguard Worker */
5053*5e7646d2SAndroid Build Coastguard Worker
5054*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
pwg_compare_finishings(_pwg_finishings_t * a,_pwg_finishings_t * b)5055*5e7646d2SAndroid Build Coastguard Worker pwg_compare_finishings(
5056*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *a, /* I - First finishings value */
5057*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *b) /* I - Second finishings value */
5058*5e7646d2SAndroid Build Coastguard Worker {
5059*5e7646d2SAndroid Build Coastguard Worker return ((int)b->value - (int)a->value);
5060*5e7646d2SAndroid Build Coastguard Worker }
5061*5e7646d2SAndroid Build Coastguard Worker
5062*5e7646d2SAndroid Build Coastguard Worker
5063*5e7646d2SAndroid Build Coastguard Worker /*
5064*5e7646d2SAndroid Build Coastguard Worker * 'pwg_compare_sizes()' - Compare two media sizes...
5065*5e7646d2SAndroid Build Coastguard Worker */
5066*5e7646d2SAndroid Build Coastguard Worker
5067*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
pwg_compare_sizes(cups_size_t * a,cups_size_t * b)5068*5e7646d2SAndroid Build Coastguard Worker pwg_compare_sizes(cups_size_t *a, /* I - First media size */
5069*5e7646d2SAndroid Build Coastguard Worker cups_size_t *b) /* I - Second media size */
5070*5e7646d2SAndroid Build Coastguard Worker {
5071*5e7646d2SAndroid Build Coastguard Worker return (strcmp(a->media, b->media));
5072*5e7646d2SAndroid Build Coastguard Worker }
5073*5e7646d2SAndroid Build Coastguard Worker
5074*5e7646d2SAndroid Build Coastguard Worker
5075*5e7646d2SAndroid Build Coastguard Worker /*
5076*5e7646d2SAndroid Build Coastguard Worker * 'pwg_copy_size()' - Copy a media size.
5077*5e7646d2SAndroid Build Coastguard Worker */
5078*5e7646d2SAndroid Build Coastguard Worker
5079*5e7646d2SAndroid Build Coastguard Worker static cups_size_t * /* O - New media size */
pwg_copy_size(cups_size_t * size)5080*5e7646d2SAndroid Build Coastguard Worker pwg_copy_size(cups_size_t *size) /* I - Media size to copy */
5081*5e7646d2SAndroid Build Coastguard Worker {
5082*5e7646d2SAndroid Build Coastguard Worker cups_size_t *newsize = (cups_size_t *)calloc(1, sizeof(cups_size_t));
5083*5e7646d2SAndroid Build Coastguard Worker /* New media size */
5084*5e7646d2SAndroid Build Coastguard Worker
5085*5e7646d2SAndroid Build Coastguard Worker if (newsize)
5086*5e7646d2SAndroid Build Coastguard Worker memcpy(newsize, size, sizeof(cups_size_t));
5087*5e7646d2SAndroid Build Coastguard Worker
5088*5e7646d2SAndroid Build Coastguard Worker return (newsize);
5089*5e7646d2SAndroid Build Coastguard Worker }
5090*5e7646d2SAndroid Build Coastguard Worker
5091*5e7646d2SAndroid Build Coastguard Worker
5092*5e7646d2SAndroid Build Coastguard Worker /*
5093*5e7646d2SAndroid Build Coastguard Worker * 'pwg_free_finishings()' - Free a finishings value.
5094*5e7646d2SAndroid Build Coastguard Worker */
5095*5e7646d2SAndroid Build Coastguard Worker
5096*5e7646d2SAndroid Build Coastguard Worker static void
pwg_free_finishings(_pwg_finishings_t * f)5097*5e7646d2SAndroid Build Coastguard Worker pwg_free_finishings(
5098*5e7646d2SAndroid Build Coastguard Worker _pwg_finishings_t *f) /* I - Finishings value */
5099*5e7646d2SAndroid Build Coastguard Worker {
5100*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(f->num_options, f->options);
5101*5e7646d2SAndroid Build Coastguard Worker free(f);
5102*5e7646d2SAndroid Build Coastguard Worker }
5103*5e7646d2SAndroid Build Coastguard Worker
5104*5e7646d2SAndroid Build Coastguard Worker
5105*5e7646d2SAndroid Build Coastguard Worker /*
5106*5e7646d2SAndroid Build Coastguard Worker * 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword.
5107*5e7646d2SAndroid Build Coastguard Worker */
5108*5e7646d2SAndroid Build Coastguard Worker
5109*5e7646d2SAndroid Build Coastguard Worker static void
pwg_ppdize_name(const char * ipp,char * name,size_t namesize)5110*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
5111*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
5112*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of name buffer */
5113*5e7646d2SAndroid Build Coastguard Worker {
5114*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Pointer into name buffer */
5115*5e7646d2SAndroid Build Coastguard Worker *end; /* End of name buffer */
5116*5e7646d2SAndroid Build Coastguard Worker
5117*5e7646d2SAndroid Build Coastguard Worker
5118*5e7646d2SAndroid Build Coastguard Worker if (!ipp)
5119*5e7646d2SAndroid Build Coastguard Worker {
5120*5e7646d2SAndroid Build Coastguard Worker *name = '\0';
5121*5e7646d2SAndroid Build Coastguard Worker return;
5122*5e7646d2SAndroid Build Coastguard Worker }
5123*5e7646d2SAndroid Build Coastguard Worker
5124*5e7646d2SAndroid Build Coastguard Worker *name = (char)toupper(*ipp++);
5125*5e7646d2SAndroid Build Coastguard Worker
5126*5e7646d2SAndroid Build Coastguard Worker for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
5127*5e7646d2SAndroid Build Coastguard Worker {
5128*5e7646d2SAndroid Build Coastguard Worker if (*ipp == '-' && _cups_isalnum(ipp[1]))
5129*5e7646d2SAndroid Build Coastguard Worker {
5130*5e7646d2SAndroid Build Coastguard Worker ipp ++;
5131*5e7646d2SAndroid Build Coastguard Worker *ptr++ = (char)toupper(*ipp++ & 255);
5132*5e7646d2SAndroid Build Coastguard Worker }
5133*5e7646d2SAndroid Build Coastguard Worker else
5134*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *ipp++;
5135*5e7646d2SAndroid Build Coastguard Worker }
5136*5e7646d2SAndroid Build Coastguard Worker
5137*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
5138*5e7646d2SAndroid Build Coastguard Worker }
5139*5e7646d2SAndroid Build Coastguard Worker
5140*5e7646d2SAndroid Build Coastguard Worker
5141*5e7646d2SAndroid Build Coastguard Worker /*
5142*5e7646d2SAndroid Build Coastguard Worker * 'pwg_ppdize_resolution()' - Convert PWG resolution values to PPD values.
5143*5e7646d2SAndroid Build Coastguard Worker */
5144*5e7646d2SAndroid Build Coastguard Worker
5145*5e7646d2SAndroid Build Coastguard Worker static void
pwg_ppdize_resolution(ipp_attribute_t * attr,int element,int * xres,int * yres,char * name,size_t namesize)5146*5e7646d2SAndroid Build Coastguard Worker pwg_ppdize_resolution(
5147*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr, /* I - Attribute to convert */
5148*5e7646d2SAndroid Build Coastguard Worker int element, /* I - Element to convert */
5149*5e7646d2SAndroid Build Coastguard Worker int *xres, /* O - X resolution in DPI */
5150*5e7646d2SAndroid Build Coastguard Worker int *yres, /* O - Y resolution in DPI */
5151*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
5152*5e7646d2SAndroid Build Coastguard Worker size_t namesize) /* I - Size of name buffer */
5153*5e7646d2SAndroid Build Coastguard Worker {
5154*5e7646d2SAndroid Build Coastguard Worker ipp_res_t units; /* Units for resolution */
5155*5e7646d2SAndroid Build Coastguard Worker
5156*5e7646d2SAndroid Build Coastguard Worker
5157*5e7646d2SAndroid Build Coastguard Worker *xres = ippGetResolution(attr, element, yres, &units);
5158*5e7646d2SAndroid Build Coastguard Worker
5159*5e7646d2SAndroid Build Coastguard Worker if (units == IPP_RES_PER_CM)
5160*5e7646d2SAndroid Build Coastguard Worker {
5161*5e7646d2SAndroid Build Coastguard Worker *xres = (int)(*xres * 2.54);
5162*5e7646d2SAndroid Build Coastguard Worker *yres = (int)(*yres * 2.54);
5163*5e7646d2SAndroid Build Coastguard Worker }
5164*5e7646d2SAndroid Build Coastguard Worker
5165*5e7646d2SAndroid Build Coastguard Worker if (name && namesize > 4)
5166*5e7646d2SAndroid Build Coastguard Worker {
5167*5e7646d2SAndroid Build Coastguard Worker if (*xres == *yres)
5168*5e7646d2SAndroid Build Coastguard Worker snprintf(name, namesize, "%ddpi", *xres);
5169*5e7646d2SAndroid Build Coastguard Worker else
5170*5e7646d2SAndroid Build Coastguard Worker snprintf(name, namesize, "%dx%ddpi", *xres, *yres);
5171*5e7646d2SAndroid Build Coastguard Worker }
5172*5e7646d2SAndroid Build Coastguard Worker }
5173*5e7646d2SAndroid Build Coastguard Worker
5174*5e7646d2SAndroid Build Coastguard Worker
5175*5e7646d2SAndroid Build Coastguard Worker /*
5176*5e7646d2SAndroid Build Coastguard Worker * 'pwg_unppdize_name()' - Convert a PPD keyword to a lowercase IPP keyword.
5177*5e7646d2SAndroid Build Coastguard Worker */
5178*5e7646d2SAndroid Build Coastguard Worker
5179*5e7646d2SAndroid Build Coastguard Worker static void
pwg_unppdize_name(const char * ppd,char * name,size_t namesize,const char * dashchars)5180*5e7646d2SAndroid Build Coastguard Worker pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
5181*5e7646d2SAndroid Build Coastguard Worker char *name, /* I - Name buffer */
5182*5e7646d2SAndroid Build Coastguard Worker size_t namesize, /* I - Size of name buffer */
5183*5e7646d2SAndroid Build Coastguard Worker const char *dashchars)/* I - Characters to be replaced by dashes */
5184*5e7646d2SAndroid Build Coastguard Worker {
5185*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Pointer into name buffer */
5186*5e7646d2SAndroid Build Coastguard Worker *end; /* End of name buffer */
5187*5e7646d2SAndroid Build Coastguard Worker int nodash = 1; /* Next char in IPP name cannot be a
5188*5e7646d2SAndroid Build Coastguard Worker dash (first char or after a dash) */
5189*5e7646d2SAndroid Build Coastguard Worker
5190*5e7646d2SAndroid Build Coastguard Worker
5191*5e7646d2SAndroid Build Coastguard Worker if (_cups_islower(*ppd))
5192*5e7646d2SAndroid Build Coastguard Worker {
5193*5e7646d2SAndroid Build Coastguard Worker /*
5194*5e7646d2SAndroid Build Coastguard Worker * Already lowercase name, use as-is?
5195*5e7646d2SAndroid Build Coastguard Worker */
5196*5e7646d2SAndroid Build Coastguard Worker
5197*5e7646d2SAndroid Build Coastguard Worker const char *ppdptr; /* Pointer into PPD keyword */
5198*5e7646d2SAndroid Build Coastguard Worker
5199*5e7646d2SAndroid Build Coastguard Worker for (ppdptr = ppd + 1; *ppdptr; ppdptr ++)
5200*5e7646d2SAndroid Build Coastguard Worker if (_cups_isupper(*ppdptr) || strchr(dashchars, *ppdptr) ||
5201*5e7646d2SAndroid Build Coastguard Worker (*ppdptr == '-' && *(ppdptr - 1) == '-') ||
5202*5e7646d2SAndroid Build Coastguard Worker (*ppdptr == '-' && *(ppdptr + 1) == '\0'))
5203*5e7646d2SAndroid Build Coastguard Worker break;
5204*5e7646d2SAndroid Build Coastguard Worker
5205*5e7646d2SAndroid Build Coastguard Worker if (!*ppdptr)
5206*5e7646d2SAndroid Build Coastguard Worker {
5207*5e7646d2SAndroid Build Coastguard Worker strlcpy(name, ppd, namesize);
5208*5e7646d2SAndroid Build Coastguard Worker return;
5209*5e7646d2SAndroid Build Coastguard Worker }
5210*5e7646d2SAndroid Build Coastguard Worker }
5211*5e7646d2SAndroid Build Coastguard Worker
5212*5e7646d2SAndroid Build Coastguard Worker for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++)
5213*5e7646d2SAndroid Build Coastguard Worker {
5214*5e7646d2SAndroid Build Coastguard Worker if (_cups_isalnum(*ppd))
5215*5e7646d2SAndroid Build Coastguard Worker {
5216*5e7646d2SAndroid Build Coastguard Worker *ptr++ = (char)tolower(*ppd & 255);
5217*5e7646d2SAndroid Build Coastguard Worker nodash = 0;
5218*5e7646d2SAndroid Build Coastguard Worker }
5219*5e7646d2SAndroid Build Coastguard Worker else if (*ppd == '-' || strchr(dashchars, *ppd))
5220*5e7646d2SAndroid Build Coastguard Worker {
5221*5e7646d2SAndroid Build Coastguard Worker if (nodash == 0)
5222*5e7646d2SAndroid Build Coastguard Worker {
5223*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '-';
5224*5e7646d2SAndroid Build Coastguard Worker nodash = 1;
5225*5e7646d2SAndroid Build Coastguard Worker }
5226*5e7646d2SAndroid Build Coastguard Worker }
5227*5e7646d2SAndroid Build Coastguard Worker else
5228*5e7646d2SAndroid Build Coastguard Worker {
5229*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *ppd;
5230*5e7646d2SAndroid Build Coastguard Worker nodash = 0;
5231*5e7646d2SAndroid Build Coastguard Worker }
5232*5e7646d2SAndroid Build Coastguard Worker
5233*5e7646d2SAndroid Build Coastguard Worker if (nodash == 0)
5234*5e7646d2SAndroid Build Coastguard Worker {
5235*5e7646d2SAndroid Build Coastguard Worker if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
5236*5e7646d2SAndroid Build Coastguard Worker _cups_isupper(ppd[1]) && ptr < end)
5237*5e7646d2SAndroid Build Coastguard Worker {
5238*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '-';
5239*5e7646d2SAndroid Build Coastguard Worker nodash = 1;
5240*5e7646d2SAndroid Build Coastguard Worker }
5241*5e7646d2SAndroid Build Coastguard Worker else if (!isdigit(*ppd & 255) && isdigit(ppd[1] & 255))
5242*5e7646d2SAndroid Build Coastguard Worker {
5243*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '-';
5244*5e7646d2SAndroid Build Coastguard Worker nodash = 1;
5245*5e7646d2SAndroid Build Coastguard Worker }
5246*5e7646d2SAndroid Build Coastguard Worker }
5247*5e7646d2SAndroid Build Coastguard Worker }
5248*5e7646d2SAndroid Build Coastguard Worker
5249*5e7646d2SAndroid Build Coastguard Worker /* Remove trailing dashes */
5250*5e7646d2SAndroid Build Coastguard Worker while (ptr > name && *(ptr - 1) == '-')
5251*5e7646d2SAndroid Build Coastguard Worker ptr --;
5252*5e7646d2SAndroid Build Coastguard Worker
5253*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
5254*5e7646d2SAndroid Build Coastguard Worker }
5255