1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Option marking routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker *
10*5e7646d2SAndroid Build Coastguard Worker * PostScript is a trademark of Adobe Systems, Inc.
11*5e7646d2SAndroid Build Coastguard Worker */
12*5e7646d2SAndroid Build Coastguard Worker
13*5e7646d2SAndroid Build Coastguard Worker /*
14*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
15*5e7646d2SAndroid Build Coastguard Worker */
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
18*5e7646d2SAndroid Build Coastguard Worker #include "ppd-private.h"
19*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker /*
23*5e7646d2SAndroid Build Coastguard Worker * Local functions...
24*5e7646d2SAndroid Build Coastguard Worker */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
27*5e7646d2SAndroid Build Coastguard Worker static void ppd_debug_marked(ppd_file_t *ppd, const char *title);
28*5e7646d2SAndroid Build Coastguard Worker #else
29*5e7646d2SAndroid Build Coastguard Worker # define ppd_debug_marked(ppd,title)
30*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
31*5e7646d2SAndroid Build Coastguard Worker static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g);
32*5e7646d2SAndroid Build Coastguard Worker static void ppd_mark_choices(ppd_file_t *ppd, const char *s);
33*5e7646d2SAndroid Build Coastguard Worker static void ppd_mark_option(ppd_file_t *ppd, const char *option,
34*5e7646d2SAndroid Build Coastguard Worker const char *choice);
35*5e7646d2SAndroid Build Coastguard Worker
36*5e7646d2SAndroid Build Coastguard Worker
37*5e7646d2SAndroid Build Coastguard Worker /*
38*5e7646d2SAndroid Build Coastguard Worker * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
39*5e7646d2SAndroid Build Coastguard Worker *
40*5e7646d2SAndroid Build Coastguard Worker * This function maps the IPP "finishings", "media", "mirror",
41*5e7646d2SAndroid Build Coastguard Worker * "multiple-document-handling", "output-bin", "print-color-mode",
42*5e7646d2SAndroid Build Coastguard Worker * "print-quality", "printer-resolution", and "sides" attributes to their
43*5e7646d2SAndroid Build Coastguard Worker * corresponding PPD options and choices.
44*5e7646d2SAndroid Build Coastguard Worker */
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if conflicts exist, 0 otherwise */
cupsMarkOptions(ppd_file_t * ppd,int num_options,cups_option_t * options)47*5e7646d2SAndroid Build Coastguard Worker cupsMarkOptions(
48*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
49*5e7646d2SAndroid Build Coastguard Worker int num_options, /* I - Number of options */
50*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options) /* I - Options */
51*5e7646d2SAndroid Build Coastguard Worker {
52*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
53*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Pointer into string */
54*5e7646d2SAndroid Build Coastguard Worker s[255]; /* Temporary string */
55*5e7646d2SAndroid Build Coastguard Worker const char *val, /* Pointer into value */
56*5e7646d2SAndroid Build Coastguard Worker *media, /* media option */
57*5e7646d2SAndroid Build Coastguard Worker *output_bin, /* output-bin option */
58*5e7646d2SAndroid Build Coastguard Worker *page_size, /* PageSize option */
59*5e7646d2SAndroid Build Coastguard Worker *ppd_keyword, /* PPD keyword */
60*5e7646d2SAndroid Build Coastguard Worker *print_color_mode, /* print-color-mode option */
61*5e7646d2SAndroid Build Coastguard Worker *print_quality, /* print-quality option */
62*5e7646d2SAndroid Build Coastguard Worker *sides; /* sides option */
63*5e7646d2SAndroid Build Coastguard Worker cups_option_t *optptr; /* Current option */
64*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *attr; /* PPD attribute */
65*5e7646d2SAndroid Build Coastguard Worker _ppd_cache_t *cache; /* PPD cache and mapping data */
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker /*
69*5e7646d2SAndroid Build Coastguard Worker * Check arguments...
70*5e7646d2SAndroid Build Coastguard Worker */
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker if (!ppd || num_options <= 0 || !options)
73*5e7646d2SAndroid Build Coastguard Worker return (0);
74*5e7646d2SAndroid Build Coastguard Worker
75*5e7646d2SAndroid Build Coastguard Worker ppd_debug_marked(ppd, "Before...");
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker * Do special handling for finishings, media, output-bin, output-mode,
79*5e7646d2SAndroid Build Coastguard Worker * print-color-mode, print-quality, and PageSize...
80*5e7646d2SAndroid Build Coastguard Worker */
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker media = cupsGetOption("media", num_options, options);
83*5e7646d2SAndroid Build Coastguard Worker output_bin = cupsGetOption("output-bin", num_options, options);
84*5e7646d2SAndroid Build Coastguard Worker page_size = cupsGetOption("PageSize", num_options, options);
85*5e7646d2SAndroid Build Coastguard Worker print_quality = cupsGetOption("print-quality", num_options, options);
86*5e7646d2SAndroid Build Coastguard Worker sides = cupsGetOption("sides", num_options, options);
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker if ((print_color_mode = cupsGetOption("print-color-mode", num_options,
89*5e7646d2SAndroid Build Coastguard Worker options)) == NULL)
90*5e7646d2SAndroid Build Coastguard Worker print_color_mode = cupsGetOption("output-mode", num_options, options);
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker if ((media || output_bin || print_color_mode || print_quality || sides) &&
93*5e7646d2SAndroid Build Coastguard Worker !ppd->cache)
94*5e7646d2SAndroid Build Coastguard Worker {
95*5e7646d2SAndroid Build Coastguard Worker /*
96*5e7646d2SAndroid Build Coastguard Worker * Load PPD cache and mapping data as needed...
97*5e7646d2SAndroid Build Coastguard Worker */
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker ppd->cache = _ppdCacheCreateWithPPD(ppd);
100*5e7646d2SAndroid Build Coastguard Worker }
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker cache = ppd->cache;
103*5e7646d2SAndroid Build Coastguard Worker
104*5e7646d2SAndroid Build Coastguard Worker if (media)
105*5e7646d2SAndroid Build Coastguard Worker {
106*5e7646d2SAndroid Build Coastguard Worker /*
107*5e7646d2SAndroid Build Coastguard Worker * Loop through the option string, separating it at commas and marking each
108*5e7646d2SAndroid Build Coastguard Worker * individual option as long as the corresponding PPD option (PageSize,
109*5e7646d2SAndroid Build Coastguard Worker * InputSlot, etc.) is not also set.
110*5e7646d2SAndroid Build Coastguard Worker *
111*5e7646d2SAndroid Build Coastguard Worker * For PageSize, we also check for an empty option value since some versions
112*5e7646d2SAndroid Build Coastguard Worker * of macOS use it to specify auto-selection of the media based solely on
113*5e7646d2SAndroid Build Coastguard Worker * the size.
114*5e7646d2SAndroid Build Coastguard Worker */
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker for (val = media; *val;)
117*5e7646d2SAndroid Build Coastguard Worker {
118*5e7646d2SAndroid Build Coastguard Worker /*
119*5e7646d2SAndroid Build Coastguard Worker * Extract the sub-option from the string...
120*5e7646d2SAndroid Build Coastguard Worker */
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker for (ptr = s; *val && *val != ',' && (size_t)(ptr - s) < (sizeof(s) - 1);)
123*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *val++;
124*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\0';
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker if (*val == ',')
127*5e7646d2SAndroid Build Coastguard Worker val ++;
128*5e7646d2SAndroid Build Coastguard Worker
129*5e7646d2SAndroid Build Coastguard Worker /*
130*5e7646d2SAndroid Build Coastguard Worker * Mark it...
131*5e7646d2SAndroid Build Coastguard Worker */
132*5e7646d2SAndroid Build Coastguard Worker
133*5e7646d2SAndroid Build Coastguard Worker if (!page_size || !page_size[0])
134*5e7646d2SAndroid Build Coastguard Worker {
135*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(s, "Custom.", 7) || ppdPageSize(ppd, s))
136*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "PageSize", s);
137*5e7646d2SAndroid Build Coastguard Worker else if ((ppd_keyword = _ppdCacheGetPageSize(cache, NULL, s, NULL)) != NULL)
138*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "PageSize", ppd_keyword);
139*5e7646d2SAndroid Build Coastguard Worker }
140*5e7646d2SAndroid Build Coastguard Worker
141*5e7646d2SAndroid Build Coastguard Worker if (cache && cache->source_option &&
142*5e7646d2SAndroid Build Coastguard Worker !cupsGetOption(cache->source_option, num_options, options) &&
143*5e7646d2SAndroid Build Coastguard Worker (ppd_keyword = _ppdCacheGetInputSlot(cache, NULL, s)) != NULL)
144*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, cache->source_option, ppd_keyword);
145*5e7646d2SAndroid Build Coastguard Worker
146*5e7646d2SAndroid Build Coastguard Worker if (!cupsGetOption("MediaType", num_options, options) &&
147*5e7646d2SAndroid Build Coastguard Worker (ppd_keyword = _ppdCacheGetMediaType(cache, NULL, s)) != NULL)
148*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "MediaType", ppd_keyword);
149*5e7646d2SAndroid Build Coastguard Worker }
150*5e7646d2SAndroid Build Coastguard Worker }
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker if (cache)
153*5e7646d2SAndroid Build Coastguard Worker {
154*5e7646d2SAndroid Build Coastguard Worker if (!cupsGetOption("com.apple.print.DocumentTicket.PMSpoolFormat",
155*5e7646d2SAndroid Build Coastguard Worker num_options, options) &&
156*5e7646d2SAndroid Build Coastguard Worker !cupsGetOption("APPrinterPreset", num_options, options) &&
157*5e7646d2SAndroid Build Coastguard Worker (print_color_mode || print_quality))
158*5e7646d2SAndroid Build Coastguard Worker {
159*5e7646d2SAndroid Build Coastguard Worker /*
160*5e7646d2SAndroid Build Coastguard Worker * Map output-mode and print-quality to a preset...
161*5e7646d2SAndroid Build Coastguard Worker */
162*5e7646d2SAndroid Build Coastguard Worker
163*5e7646d2SAndroid Build Coastguard Worker _pwg_print_color_mode_t pwg_pcm;/* print-color-mode index */
164*5e7646d2SAndroid Build Coastguard Worker _pwg_print_quality_t pwg_pq; /* print-quality index */
165*5e7646d2SAndroid Build Coastguard Worker cups_option_t *preset;/* Current preset option */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker if (print_color_mode && !strcmp(print_color_mode, "monochrome"))
168*5e7646d2SAndroid Build Coastguard Worker pwg_pcm = _PWG_PRINT_COLOR_MODE_MONOCHROME;
169*5e7646d2SAndroid Build Coastguard Worker else
170*5e7646d2SAndroid Build Coastguard Worker pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
171*5e7646d2SAndroid Build Coastguard Worker
172*5e7646d2SAndroid Build Coastguard Worker if (print_quality)
173*5e7646d2SAndroid Build Coastguard Worker {
174*5e7646d2SAndroid Build Coastguard Worker pwg_pq = (_pwg_print_quality_t)(atoi(print_quality) - IPP_QUALITY_DRAFT);
175*5e7646d2SAndroid Build Coastguard Worker if (pwg_pq < _PWG_PRINT_QUALITY_DRAFT)
176*5e7646d2SAndroid Build Coastguard Worker pwg_pq = _PWG_PRINT_QUALITY_DRAFT;
177*5e7646d2SAndroid Build Coastguard Worker else if (pwg_pq > _PWG_PRINT_QUALITY_HIGH)
178*5e7646d2SAndroid Build Coastguard Worker pwg_pq = _PWG_PRINT_QUALITY_HIGH;
179*5e7646d2SAndroid Build Coastguard Worker }
180*5e7646d2SAndroid Build Coastguard Worker else
181*5e7646d2SAndroid Build Coastguard Worker pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker if (cache->num_presets[pwg_pcm][pwg_pq] == 0)
184*5e7646d2SAndroid Build Coastguard Worker {
185*5e7646d2SAndroid Build Coastguard Worker /*
186*5e7646d2SAndroid Build Coastguard Worker * Try to find a preset that works so that we maximize the chances of us
187*5e7646d2SAndroid Build Coastguard Worker * getting a good print using IPP attributes.
188*5e7646d2SAndroid Build Coastguard Worker */
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker if (cache->num_presets[pwg_pcm][_PWG_PRINT_QUALITY_NORMAL] > 0)
191*5e7646d2SAndroid Build Coastguard Worker pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
192*5e7646d2SAndroid Build Coastguard Worker else if (cache->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][pwg_pq] > 0)
193*5e7646d2SAndroid Build Coastguard Worker pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
194*5e7646d2SAndroid Build Coastguard Worker else
195*5e7646d2SAndroid Build Coastguard Worker {
196*5e7646d2SAndroid Build Coastguard Worker pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
197*5e7646d2SAndroid Build Coastguard Worker pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
198*5e7646d2SAndroid Build Coastguard Worker }
199*5e7646d2SAndroid Build Coastguard Worker }
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker if (cache->num_presets[pwg_pcm][pwg_pq] > 0)
202*5e7646d2SAndroid Build Coastguard Worker {
203*5e7646d2SAndroid Build Coastguard Worker /*
204*5e7646d2SAndroid Build Coastguard Worker * Copy the preset options as long as the corresponding names are not
205*5e7646d2SAndroid Build Coastguard Worker * already defined in the IPP request...
206*5e7646d2SAndroid Build Coastguard Worker */
207*5e7646d2SAndroid Build Coastguard Worker
208*5e7646d2SAndroid Build Coastguard Worker for (i = cache->num_presets[pwg_pcm][pwg_pq],
209*5e7646d2SAndroid Build Coastguard Worker preset = cache->presets[pwg_pcm][pwg_pq];
210*5e7646d2SAndroid Build Coastguard Worker i > 0;
211*5e7646d2SAndroid Build Coastguard Worker i --, preset ++)
212*5e7646d2SAndroid Build Coastguard Worker {
213*5e7646d2SAndroid Build Coastguard Worker if (!cupsGetOption(preset->name, num_options, options))
214*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, preset->name, preset->value);
215*5e7646d2SAndroid Build Coastguard Worker }
216*5e7646d2SAndroid Build Coastguard Worker }
217*5e7646d2SAndroid Build Coastguard Worker }
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker if (output_bin && !cupsGetOption("OutputBin", num_options, options) &&
220*5e7646d2SAndroid Build Coastguard Worker (ppd_keyword = _ppdCacheGetOutputBin(cache, output_bin)) != NULL)
221*5e7646d2SAndroid Build Coastguard Worker {
222*5e7646d2SAndroid Build Coastguard Worker /*
223*5e7646d2SAndroid Build Coastguard Worker * Map output-bin to OutputBin...
224*5e7646d2SAndroid Build Coastguard Worker */
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "OutputBin", ppd_keyword);
227*5e7646d2SAndroid Build Coastguard Worker }
228*5e7646d2SAndroid Build Coastguard Worker
229*5e7646d2SAndroid Build Coastguard Worker if (sides && cache->sides_option &&
230*5e7646d2SAndroid Build Coastguard Worker !cupsGetOption(cache->sides_option, num_options, options))
231*5e7646d2SAndroid Build Coastguard Worker {
232*5e7646d2SAndroid Build Coastguard Worker /*
233*5e7646d2SAndroid Build Coastguard Worker * Map sides to duplex option...
234*5e7646d2SAndroid Build Coastguard Worker */
235*5e7646d2SAndroid Build Coastguard Worker
236*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(sides, "one-sided") && cache->sides_1sided)
237*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, cache->sides_option, cache->sides_1sided);
238*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(sides, "two-sided-long-edge") &&
239*5e7646d2SAndroid Build Coastguard Worker cache->sides_2sided_long)
240*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_long);
241*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(sides, "two-sided-short-edge") &&
242*5e7646d2SAndroid Build Coastguard Worker cache->sides_2sided_short)
243*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_short);
244*5e7646d2SAndroid Build Coastguard Worker }
245*5e7646d2SAndroid Build Coastguard Worker }
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker /*
248*5e7646d2SAndroid Build Coastguard Worker * Mark other options...
249*5e7646d2SAndroid Build Coastguard Worker */
250*5e7646d2SAndroid Build Coastguard Worker
251*5e7646d2SAndroid Build Coastguard Worker for (i = num_options, optptr = options; i > 0; i --, optptr ++)
252*5e7646d2SAndroid Build Coastguard Worker {
253*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(optptr->name, "media") ||
254*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(optptr->name, "output-bin") ||
255*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(optptr->name, "output-mode") ||
256*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(optptr->name, "print-quality") ||
257*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(optptr->name, "sides"))
258*5e7646d2SAndroid Build Coastguard Worker continue;
259*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(optptr->name, "resolution") ||
260*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(optptr->name, "printer-resolution"))
261*5e7646d2SAndroid Build Coastguard Worker {
262*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "Resolution", optptr->value);
263*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "SetResolution", optptr->value);
264*5e7646d2SAndroid Build Coastguard Worker /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
265*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "JCLResolution", optptr->value);
266*5e7646d2SAndroid Build Coastguard Worker /* HP */
267*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "CNRes_PGP", optptr->value);
268*5e7646d2SAndroid Build Coastguard Worker /* Canon */
269*5e7646d2SAndroid Build Coastguard Worker }
270*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(optptr->name, "multiple-document-handling"))
271*5e7646d2SAndroid Build Coastguard Worker {
272*5e7646d2SAndroid Build Coastguard Worker if (!cupsGetOption("Collate", num_options, options) &&
273*5e7646d2SAndroid Build Coastguard Worker ppdFindOption(ppd, "Collate"))
274*5e7646d2SAndroid Build Coastguard Worker {
275*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
276*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "Collate", "True");
277*5e7646d2SAndroid Build Coastguard Worker else
278*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "Collate", "False");
279*5e7646d2SAndroid Build Coastguard Worker }
280*5e7646d2SAndroid Build Coastguard Worker }
281*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(optptr->name, "finishings"))
282*5e7646d2SAndroid Build Coastguard Worker {
283*5e7646d2SAndroid Build Coastguard Worker /*
284*5e7646d2SAndroid Build Coastguard Worker * Lookup cupsIPPFinishings attributes for each value...
285*5e7646d2SAndroid Build Coastguard Worker */
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker for (ptr = optptr->value; *ptr;)
288*5e7646d2SAndroid Build Coastguard Worker {
289*5e7646d2SAndroid Build Coastguard Worker /*
290*5e7646d2SAndroid Build Coastguard Worker * Get the next finishings number...
291*5e7646d2SAndroid Build Coastguard Worker */
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker if (!isdigit(*ptr & 255))
294*5e7646d2SAndroid Build Coastguard Worker break;
295*5e7646d2SAndroid Build Coastguard Worker
296*5e7646d2SAndroid Build Coastguard Worker if ((j = (int)strtol(ptr, &ptr, 10)) < 3)
297*5e7646d2SAndroid Build Coastguard Worker break;
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker /*
300*5e7646d2SAndroid Build Coastguard Worker * Skip separator as needed...
301*5e7646d2SAndroid Build Coastguard Worker */
302*5e7646d2SAndroid Build Coastguard Worker
303*5e7646d2SAndroid Build Coastguard Worker if (*ptr == ',')
304*5e7646d2SAndroid Build Coastguard Worker ptr ++;
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker /*
307*5e7646d2SAndroid Build Coastguard Worker * Look it up in the PPD file...
308*5e7646d2SAndroid Build Coastguard Worker */
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker snprintf(s, sizeof(s), "%d", j);
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
313*5e7646d2SAndroid Build Coastguard Worker continue;
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker /*
316*5e7646d2SAndroid Build Coastguard Worker * Apply "*Option Choice" settings from the attribute value...
317*5e7646d2SAndroid Build Coastguard Worker */
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker ppd_mark_choices(ppd, attr->value);
320*5e7646d2SAndroid Build Coastguard Worker }
321*5e7646d2SAndroid Build Coastguard Worker }
322*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(optptr->name, "APPrinterPreset"))
323*5e7646d2SAndroid Build Coastguard Worker {
324*5e7646d2SAndroid Build Coastguard Worker /*
325*5e7646d2SAndroid Build Coastguard Worker * Lookup APPrinterPreset value...
326*5e7646d2SAndroid Build Coastguard Worker */
327*5e7646d2SAndroid Build Coastguard Worker
328*5e7646d2SAndroid Build Coastguard Worker if ((attr = ppdFindAttr(ppd, "APPrinterPreset", optptr->value)) != NULL)
329*5e7646d2SAndroid Build Coastguard Worker {
330*5e7646d2SAndroid Build Coastguard Worker /*
331*5e7646d2SAndroid Build Coastguard Worker * Apply "*Option Choice" settings from the attribute value...
332*5e7646d2SAndroid Build Coastguard Worker */
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker ppd_mark_choices(ppd, attr->value);
335*5e7646d2SAndroid Build Coastguard Worker }
336*5e7646d2SAndroid Build Coastguard Worker }
337*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(optptr->name, "mirror"))
338*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "MirrorPrint", optptr->value);
339*5e7646d2SAndroid Build Coastguard Worker else
340*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, optptr->name, optptr->value);
341*5e7646d2SAndroid Build Coastguard Worker }
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker if (print_quality)
344*5e7646d2SAndroid Build Coastguard Worker {
345*5e7646d2SAndroid Build Coastguard Worker int pq = atoi(print_quality); /* print-quaity value */
346*5e7646d2SAndroid Build Coastguard Worker
347*5e7646d2SAndroid Build Coastguard Worker if (pq == IPP_QUALITY_DRAFT)
348*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "cupsPrintQuality", "Draft");
349*5e7646d2SAndroid Build Coastguard Worker else if (pq == IPP_QUALITY_HIGH)
350*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "cupsPrintQuality", "High");
351*5e7646d2SAndroid Build Coastguard Worker else
352*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, "cupsPrintQuality", "Normal");
353*5e7646d2SAndroid Build Coastguard Worker }
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker ppd_debug_marked(ppd, "After...");
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker return (ppdConflicts(ppd) > 0);
358*5e7646d2SAndroid Build Coastguard Worker }
359*5e7646d2SAndroid Build Coastguard Worker
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker /*
362*5e7646d2SAndroid Build Coastguard Worker * 'ppdFindChoice()' - Return a pointer to an option choice.
363*5e7646d2SAndroid Build Coastguard Worker */
364*5e7646d2SAndroid Build Coastguard Worker
365*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t * /* O - Choice pointer or @code NULL@ */
ppdFindChoice(ppd_option_t * o,const char * choice)366*5e7646d2SAndroid Build Coastguard Worker ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */
367*5e7646d2SAndroid Build Coastguard Worker const char *choice) /* I - Name of choice */
368*5e7646d2SAndroid Build Coastguard Worker {
369*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
370*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *c; /* Current choice */
371*5e7646d2SAndroid Build Coastguard Worker
372*5e7646d2SAndroid Build Coastguard Worker
373*5e7646d2SAndroid Build Coastguard Worker if (!o || !choice)
374*5e7646d2SAndroid Build Coastguard Worker return (NULL);
375*5e7646d2SAndroid Build Coastguard Worker
376*5e7646d2SAndroid Build Coastguard Worker if (choice[0] == '{' || !_cups_strncasecmp(choice, "Custom.", 7))
377*5e7646d2SAndroid Build Coastguard Worker choice = "Custom";
378*5e7646d2SAndroid Build Coastguard Worker
379*5e7646d2SAndroid Build Coastguard Worker for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
380*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(c->choice, choice))
381*5e7646d2SAndroid Build Coastguard Worker return (c);
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker return (NULL);
384*5e7646d2SAndroid Build Coastguard Worker }
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker
387*5e7646d2SAndroid Build Coastguard Worker /*
388*5e7646d2SAndroid Build Coastguard Worker * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
389*5e7646d2SAndroid Build Coastguard Worker */
390*5e7646d2SAndroid Build Coastguard Worker
391*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t * /* O - Pointer to choice or @code NULL@ */
ppdFindMarkedChoice(ppd_file_t * ppd,const char * option)392*5e7646d2SAndroid Build Coastguard Worker ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */
393*5e7646d2SAndroid Build Coastguard Worker const char *option) /* I - Keyword/option name */
394*5e7646d2SAndroid Build Coastguard Worker {
395*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t key, /* Search key for choice */
396*5e7646d2SAndroid Build Coastguard Worker *marked; /* Marked choice */
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker
399*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdFindMarkedChoice(ppd=%p, option=\"%s\")", ppd, option));
400*5e7646d2SAndroid Build Coastguard Worker
401*5e7646d2SAndroid Build Coastguard Worker if ((key.option = ppdFindOption(ppd, option)) == NULL)
402*5e7646d2SAndroid Build Coastguard Worker {
403*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("3ppdFindMarkedChoice: Option not found, returning NULL");
404*5e7646d2SAndroid Build Coastguard Worker return (NULL);
405*5e7646d2SAndroid Build Coastguard Worker }
406*5e7646d2SAndroid Build Coastguard Worker
407*5e7646d2SAndroid Build Coastguard Worker marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key);
408*5e7646d2SAndroid Build Coastguard Worker
409*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3ppdFindMarkedChoice: Returning %p(%s)...", marked,
410*5e7646d2SAndroid Build Coastguard Worker marked ? marked->choice : "NULL"));
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker return (marked);
413*5e7646d2SAndroid Build Coastguard Worker }
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker
416*5e7646d2SAndroid Build Coastguard Worker /*
417*5e7646d2SAndroid Build Coastguard Worker * 'ppdFindOption()' - Return a pointer to the specified option.
418*5e7646d2SAndroid Build Coastguard Worker */
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker ppd_option_t * /* O - Pointer to option or @code NULL@ */
ppdFindOption(ppd_file_t * ppd,const char * option)421*5e7646d2SAndroid Build Coastguard Worker ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */
422*5e7646d2SAndroid Build Coastguard Worker const char *option) /* I - Option/Keyword name */
423*5e7646d2SAndroid Build Coastguard Worker {
424*5e7646d2SAndroid Build Coastguard Worker /*
425*5e7646d2SAndroid Build Coastguard Worker * Range check input...
426*5e7646d2SAndroid Build Coastguard Worker */
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !option)
429*5e7646d2SAndroid Build Coastguard Worker return (NULL);
430*5e7646d2SAndroid Build Coastguard Worker
431*5e7646d2SAndroid Build Coastguard Worker if (ppd->options)
432*5e7646d2SAndroid Build Coastguard Worker {
433*5e7646d2SAndroid Build Coastguard Worker /*
434*5e7646d2SAndroid Build Coastguard Worker * Search in the array...
435*5e7646d2SAndroid Build Coastguard Worker */
436*5e7646d2SAndroid Build Coastguard Worker
437*5e7646d2SAndroid Build Coastguard Worker ppd_option_t key; /* Option search key */
438*5e7646d2SAndroid Build Coastguard Worker
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker strlcpy(key.keyword, option, sizeof(key.keyword));
441*5e7646d2SAndroid Build Coastguard Worker
442*5e7646d2SAndroid Build Coastguard Worker return ((ppd_option_t *)cupsArrayFind(ppd->options, &key));
443*5e7646d2SAndroid Build Coastguard Worker }
444*5e7646d2SAndroid Build Coastguard Worker else
445*5e7646d2SAndroid Build Coastguard Worker {
446*5e7646d2SAndroid Build Coastguard Worker /*
447*5e7646d2SAndroid Build Coastguard Worker * Search in each group...
448*5e7646d2SAndroid Build Coastguard Worker */
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
451*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *group; /* Current group */
452*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *optptr; /* Current option */
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker
455*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
456*5e7646d2SAndroid Build Coastguard Worker for (j = group->num_options, optptr = group->options;
457*5e7646d2SAndroid Build Coastguard Worker j > 0;
458*5e7646d2SAndroid Build Coastguard Worker j --, optptr ++)
459*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(optptr->keyword, option))
460*5e7646d2SAndroid Build Coastguard Worker return (optptr);
461*5e7646d2SAndroid Build Coastguard Worker
462*5e7646d2SAndroid Build Coastguard Worker return (NULL);
463*5e7646d2SAndroid Build Coastguard Worker }
464*5e7646d2SAndroid Build Coastguard Worker }
465*5e7646d2SAndroid Build Coastguard Worker
466*5e7646d2SAndroid Build Coastguard Worker
467*5e7646d2SAndroid Build Coastguard Worker /*
468*5e7646d2SAndroid Build Coastguard Worker * 'ppdIsMarked()' - Check to see if an option is marked.
469*5e7646d2SAndroid Build Coastguard Worker */
470*5e7646d2SAndroid Build Coastguard Worker
471*5e7646d2SAndroid Build Coastguard Worker int /* O - Non-zero if option is marked */
ppdIsMarked(ppd_file_t * ppd,const char * option,const char * choice)472*5e7646d2SAndroid Build Coastguard Worker ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */
473*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Option/Keyword name */
474*5e7646d2SAndroid Build Coastguard Worker const char *choice) /* I - Choice name */
475*5e7646d2SAndroid Build Coastguard Worker {
476*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t key, /* Search key */
477*5e7646d2SAndroid Build Coastguard Worker *c; /* Choice pointer */
478*5e7646d2SAndroid Build Coastguard Worker
479*5e7646d2SAndroid Build Coastguard Worker
480*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
481*5e7646d2SAndroid Build Coastguard Worker return (0);
482*5e7646d2SAndroid Build Coastguard Worker
483*5e7646d2SAndroid Build Coastguard Worker if ((key.option = ppdFindOption(ppd, option)) == NULL)
484*5e7646d2SAndroid Build Coastguard Worker return (0);
485*5e7646d2SAndroid Build Coastguard Worker
486*5e7646d2SAndroid Build Coastguard Worker if ((c = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) == NULL)
487*5e7646d2SAndroid Build Coastguard Worker return (0);
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker return (!strcmp(c->choice, choice));
490*5e7646d2SAndroid Build Coastguard Worker }
491*5e7646d2SAndroid Build Coastguard Worker
492*5e7646d2SAndroid Build Coastguard Worker
493*5e7646d2SAndroid Build Coastguard Worker /*
494*5e7646d2SAndroid Build Coastguard Worker * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
495*5e7646d2SAndroid Build Coastguard Worker */
496*5e7646d2SAndroid Build Coastguard Worker
497*5e7646d2SAndroid Build Coastguard Worker void
ppdMarkDefaults(ppd_file_t * ppd)498*5e7646d2SAndroid Build Coastguard Worker ppdMarkDefaults(ppd_file_t *ppd) /* I - PPD file record */
499*5e7646d2SAndroid Build Coastguard Worker {
500*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping variables */
501*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *g; /* Current group */
502*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *c; /* Current choice */
503*5e7646d2SAndroid Build Coastguard Worker
504*5e7646d2SAndroid Build Coastguard Worker
505*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
506*5e7646d2SAndroid Build Coastguard Worker return;
507*5e7646d2SAndroid Build Coastguard Worker
508*5e7646d2SAndroid Build Coastguard Worker /*
509*5e7646d2SAndroid Build Coastguard Worker * Clean out the marked array...
510*5e7646d2SAndroid Build Coastguard Worker */
511*5e7646d2SAndroid Build Coastguard Worker
512*5e7646d2SAndroid Build Coastguard Worker for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
513*5e7646d2SAndroid Build Coastguard Worker c;
514*5e7646d2SAndroid Build Coastguard Worker c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
515*5e7646d2SAndroid Build Coastguard Worker {
516*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, c);
517*5e7646d2SAndroid Build Coastguard Worker c->marked = 0;
518*5e7646d2SAndroid Build Coastguard Worker }
519*5e7646d2SAndroid Build Coastguard Worker
520*5e7646d2SAndroid Build Coastguard Worker /*
521*5e7646d2SAndroid Build Coastguard Worker * Then repopulate it with the defaults...
522*5e7646d2SAndroid Build Coastguard Worker */
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
525*5e7646d2SAndroid Build Coastguard Worker ppd_defaults(ppd, g);
526*5e7646d2SAndroid Build Coastguard Worker
527*5e7646d2SAndroid Build Coastguard Worker /*
528*5e7646d2SAndroid Build Coastguard Worker * Finally, tag any conflicts (API compatibility) once at the end.
529*5e7646d2SAndroid Build Coastguard Worker */
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker ppdConflicts(ppd);
532*5e7646d2SAndroid Build Coastguard Worker }
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker
535*5e7646d2SAndroid Build Coastguard Worker /*
536*5e7646d2SAndroid Build Coastguard Worker * 'ppdMarkOption()' - Mark an option in a PPD file and return the number of
537*5e7646d2SAndroid Build Coastguard Worker * conflicts.
538*5e7646d2SAndroid Build Coastguard Worker */
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of conflicts */
ppdMarkOption(ppd_file_t * ppd,const char * option,const char * choice)541*5e7646d2SAndroid Build Coastguard Worker ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */
542*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Keyword */
543*5e7646d2SAndroid Build Coastguard Worker const char *choice) /* I - Option name */
544*5e7646d2SAndroid Build Coastguard Worker {
545*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")",
546*5e7646d2SAndroid Build Coastguard Worker ppd, option, choice));
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker /*
549*5e7646d2SAndroid Build Coastguard Worker * Range check input...
550*5e7646d2SAndroid Build Coastguard Worker */
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !option || !choice)
553*5e7646d2SAndroid Build Coastguard Worker return (0);
554*5e7646d2SAndroid Build Coastguard Worker
555*5e7646d2SAndroid Build Coastguard Worker /*
556*5e7646d2SAndroid Build Coastguard Worker * Mark the option...
557*5e7646d2SAndroid Build Coastguard Worker */
558*5e7646d2SAndroid Build Coastguard Worker
559*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, option, choice);
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker /*
562*5e7646d2SAndroid Build Coastguard Worker * Return the number of conflicts...
563*5e7646d2SAndroid Build Coastguard Worker */
564*5e7646d2SAndroid Build Coastguard Worker
565*5e7646d2SAndroid Build Coastguard Worker return (ppdConflicts(ppd));
566*5e7646d2SAndroid Build Coastguard Worker }
567*5e7646d2SAndroid Build Coastguard Worker
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker /*
570*5e7646d2SAndroid Build Coastguard Worker * 'ppdFirstOption()' - Return the first option in the PPD file.
571*5e7646d2SAndroid Build Coastguard Worker *
572*5e7646d2SAndroid Build Coastguard Worker * Options are returned from all groups in ascending alphanumeric order.
573*5e7646d2SAndroid Build Coastguard Worker *
574*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
575*5e7646d2SAndroid Build Coastguard Worker */
576*5e7646d2SAndroid Build Coastguard Worker
577*5e7646d2SAndroid Build Coastguard Worker ppd_option_t * /* O - First option or @code NULL@ */
ppdFirstOption(ppd_file_t * ppd)578*5e7646d2SAndroid Build Coastguard Worker ppdFirstOption(ppd_file_t *ppd) /* I - PPD file */
579*5e7646d2SAndroid Build Coastguard Worker {
580*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
581*5e7646d2SAndroid Build Coastguard Worker return (NULL);
582*5e7646d2SAndroid Build Coastguard Worker else
583*5e7646d2SAndroid Build Coastguard Worker return ((ppd_option_t *)cupsArrayFirst(ppd->options));
584*5e7646d2SAndroid Build Coastguard Worker }
585*5e7646d2SAndroid Build Coastguard Worker
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker /*
588*5e7646d2SAndroid Build Coastguard Worker * 'ppdNextOption()' - Return the next option in the PPD file.
589*5e7646d2SAndroid Build Coastguard Worker *
590*5e7646d2SAndroid Build Coastguard Worker * Options are returned from all groups in ascending alphanumeric order.
591*5e7646d2SAndroid Build Coastguard Worker *
592*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
593*5e7646d2SAndroid Build Coastguard Worker */
594*5e7646d2SAndroid Build Coastguard Worker
595*5e7646d2SAndroid Build Coastguard Worker ppd_option_t * /* O - Next option or @code NULL@ */
ppdNextOption(ppd_file_t * ppd)596*5e7646d2SAndroid Build Coastguard Worker ppdNextOption(ppd_file_t *ppd) /* I - PPD file */
597*5e7646d2SAndroid Build Coastguard Worker {
598*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
599*5e7646d2SAndroid Build Coastguard Worker return (NULL);
600*5e7646d2SAndroid Build Coastguard Worker else
601*5e7646d2SAndroid Build Coastguard Worker return ((ppd_option_t *)cupsArrayNext(ppd->options));
602*5e7646d2SAndroid Build Coastguard Worker }
603*5e7646d2SAndroid Build Coastguard Worker
604*5e7646d2SAndroid Build Coastguard Worker
605*5e7646d2SAndroid Build Coastguard Worker /*
606*5e7646d2SAndroid Build Coastguard Worker * '_ppdParseOptions()' - Parse options from a PPD file.
607*5e7646d2SAndroid Build Coastguard Worker *
608*5e7646d2SAndroid Build Coastguard Worker * This function looks for strings of the form:
609*5e7646d2SAndroid Build Coastguard Worker *
610*5e7646d2SAndroid Build Coastguard Worker * *option choice ... *optionN choiceN
611*5e7646d2SAndroid Build Coastguard Worker * property value ... propertyN valueN
612*5e7646d2SAndroid Build Coastguard Worker *
613*5e7646d2SAndroid Build Coastguard Worker * It stops when it finds a string that doesn't match this format.
614*5e7646d2SAndroid Build Coastguard Worker */
615*5e7646d2SAndroid Build Coastguard Worker
616*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of options */
_ppdParseOptions(const char * s,int num_options,cups_option_t ** options,_ppd_parse_t which)617*5e7646d2SAndroid Build Coastguard Worker _ppdParseOptions(
618*5e7646d2SAndroid Build Coastguard Worker const char *s, /* I - String to parse */
619*5e7646d2SAndroid Build Coastguard Worker int num_options, /* I - Number of options */
620*5e7646d2SAndroid Build Coastguard Worker cups_option_t **options, /* IO - Options */
621*5e7646d2SAndroid Build Coastguard Worker _ppd_parse_t which) /* I - What to parse */
622*5e7646d2SAndroid Build Coastguard Worker {
623*5e7646d2SAndroid Build Coastguard Worker char option[PPD_MAX_NAME * 2 + 1], /* Current option/property */
624*5e7646d2SAndroid Build Coastguard Worker choice[PPD_MAX_NAME], /* Current choice/value */
625*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into option or choice */
626*5e7646d2SAndroid Build Coastguard Worker
627*5e7646d2SAndroid Build Coastguard Worker
628*5e7646d2SAndroid Build Coastguard Worker if (!s)
629*5e7646d2SAndroid Build Coastguard Worker return (num_options);
630*5e7646d2SAndroid Build Coastguard Worker
631*5e7646d2SAndroid Build Coastguard Worker /*
632*5e7646d2SAndroid Build Coastguard Worker * Read all of the "*Option Choice" and "property value" pairs from the
633*5e7646d2SAndroid Build Coastguard Worker * string, add them to an options array as we go...
634*5e7646d2SAndroid Build Coastguard Worker */
635*5e7646d2SAndroid Build Coastguard Worker
636*5e7646d2SAndroid Build Coastguard Worker while (*s)
637*5e7646d2SAndroid Build Coastguard Worker {
638*5e7646d2SAndroid Build Coastguard Worker /*
639*5e7646d2SAndroid Build Coastguard Worker * Skip leading whitespace...
640*5e7646d2SAndroid Build Coastguard Worker */
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*s))
643*5e7646d2SAndroid Build Coastguard Worker s ++;
644*5e7646d2SAndroid Build Coastguard Worker
645*5e7646d2SAndroid Build Coastguard Worker /*
646*5e7646d2SAndroid Build Coastguard Worker * Get the option/property name...
647*5e7646d2SAndroid Build Coastguard Worker */
648*5e7646d2SAndroid Build Coastguard Worker
649*5e7646d2SAndroid Build Coastguard Worker ptr = option;
650*5e7646d2SAndroid Build Coastguard Worker while (*s && !_cups_isspace(*s) && ptr < (option + sizeof(option) - 1))
651*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *s++;
652*5e7646d2SAndroid Build Coastguard Worker
653*5e7646d2SAndroid Build Coastguard Worker if (ptr == s || !_cups_isspace(*s))
654*5e7646d2SAndroid Build Coastguard Worker break;
655*5e7646d2SAndroid Build Coastguard Worker
656*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker /*
659*5e7646d2SAndroid Build Coastguard Worker * Get the choice...
660*5e7646d2SAndroid Build Coastguard Worker */
661*5e7646d2SAndroid Build Coastguard Worker
662*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*s))
663*5e7646d2SAndroid Build Coastguard Worker s ++;
664*5e7646d2SAndroid Build Coastguard Worker
665*5e7646d2SAndroid Build Coastguard Worker if (!*s)
666*5e7646d2SAndroid Build Coastguard Worker break;
667*5e7646d2SAndroid Build Coastguard Worker
668*5e7646d2SAndroid Build Coastguard Worker ptr = choice;
669*5e7646d2SAndroid Build Coastguard Worker while (*s && !_cups_isspace(*s) && ptr < (choice + sizeof(choice) - 1))
670*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *s++;
671*5e7646d2SAndroid Build Coastguard Worker
672*5e7646d2SAndroid Build Coastguard Worker if (*s && !_cups_isspace(*s))
673*5e7646d2SAndroid Build Coastguard Worker break;
674*5e7646d2SAndroid Build Coastguard Worker
675*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
676*5e7646d2SAndroid Build Coastguard Worker
677*5e7646d2SAndroid Build Coastguard Worker /*
678*5e7646d2SAndroid Build Coastguard Worker * Add it to the options array...
679*5e7646d2SAndroid Build Coastguard Worker */
680*5e7646d2SAndroid Build Coastguard Worker
681*5e7646d2SAndroid Build Coastguard Worker if (option[0] == '*' && which != _PPD_PARSE_PROPERTIES)
682*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(option + 1, choice, num_options, options);
683*5e7646d2SAndroid Build Coastguard Worker else if (option[0] != '*' && which != _PPD_PARSE_OPTIONS)
684*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(option, choice, num_options, options);
685*5e7646d2SAndroid Build Coastguard Worker }
686*5e7646d2SAndroid Build Coastguard Worker
687*5e7646d2SAndroid Build Coastguard Worker return (num_options);
688*5e7646d2SAndroid Build Coastguard Worker }
689*5e7646d2SAndroid Build Coastguard Worker
690*5e7646d2SAndroid Build Coastguard Worker
691*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
692*5e7646d2SAndroid Build Coastguard Worker /*
693*5e7646d2SAndroid Build Coastguard Worker * 'ppd_debug_marked()' - Output the marked array to stdout...
694*5e7646d2SAndroid Build Coastguard Worker */
695*5e7646d2SAndroid Build Coastguard Worker
696*5e7646d2SAndroid Build Coastguard Worker static void
ppd_debug_marked(ppd_file_t * ppd,const char * title)697*5e7646d2SAndroid Build Coastguard Worker ppd_debug_marked(ppd_file_t *ppd, /* I - PPD file data */
698*5e7646d2SAndroid Build Coastguard Worker const char *title) /* I - Title for list */
699*5e7646d2SAndroid Build Coastguard Worker {
700*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *c; /* Current choice */
701*5e7646d2SAndroid Build Coastguard Worker
702*5e7646d2SAndroid Build Coastguard Worker
703*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsMarkOptions: %s", title));
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
706*5e7646d2SAndroid Build Coastguard Worker c;
707*5e7646d2SAndroid Build Coastguard Worker c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
708*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsMarkOptions: %s=%s", c->option->keyword, c->choice));
709*5e7646d2SAndroid Build Coastguard Worker }
710*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
711*5e7646d2SAndroid Build Coastguard Worker
712*5e7646d2SAndroid Build Coastguard Worker
713*5e7646d2SAndroid Build Coastguard Worker /*
714*5e7646d2SAndroid Build Coastguard Worker * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
715*5e7646d2SAndroid Build Coastguard Worker */
716*5e7646d2SAndroid Build Coastguard Worker
717*5e7646d2SAndroid Build Coastguard Worker static void
ppd_defaults(ppd_file_t * ppd,ppd_group_t * g)718*5e7646d2SAndroid Build Coastguard Worker ppd_defaults(ppd_file_t *ppd, /* I - PPD file */
719*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *g) /* I - Group to default */
720*5e7646d2SAndroid Build Coastguard Worker {
721*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
722*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *o; /* Current option */
723*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *sg; /* Current sub-group */
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker
726*5e7646d2SAndroid Build Coastguard Worker for (i = g->num_options, o = g->options; i > 0; i --, o ++)
727*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(o->keyword, "PageRegion") != 0)
728*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, o->keyword, o->defchoice);
729*5e7646d2SAndroid Build Coastguard Worker
730*5e7646d2SAndroid Build Coastguard Worker for (i = g->num_subgroups, sg = g->subgroups; i > 0; i --, sg ++)
731*5e7646d2SAndroid Build Coastguard Worker ppd_defaults(ppd, sg);
732*5e7646d2SAndroid Build Coastguard Worker }
733*5e7646d2SAndroid Build Coastguard Worker
734*5e7646d2SAndroid Build Coastguard Worker
735*5e7646d2SAndroid Build Coastguard Worker /*
736*5e7646d2SAndroid Build Coastguard Worker * 'ppd_mark_choices()' - Mark one or more option choices from a string.
737*5e7646d2SAndroid Build Coastguard Worker */
738*5e7646d2SAndroid Build Coastguard Worker
739*5e7646d2SAndroid Build Coastguard Worker static void
ppd_mark_choices(ppd_file_t * ppd,const char * s)740*5e7646d2SAndroid Build Coastguard Worker ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */
741*5e7646d2SAndroid Build Coastguard Worker const char *s) /* I - "*Option Choice ..." string */
742*5e7646d2SAndroid Build Coastguard Worker {
743*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
744*5e7646d2SAndroid Build Coastguard Worker num_options; /* Number of options */
745*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options, /* Options */
746*5e7646d2SAndroid Build Coastguard Worker *option; /* Current option */
747*5e7646d2SAndroid Build Coastguard Worker
748*5e7646d2SAndroid Build Coastguard Worker
749*5e7646d2SAndroid Build Coastguard Worker if (!s)
750*5e7646d2SAndroid Build Coastguard Worker return;
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker options = NULL;
753*5e7646d2SAndroid Build Coastguard Worker num_options = _ppdParseOptions(s, 0, &options, 0);
754*5e7646d2SAndroid Build Coastguard Worker
755*5e7646d2SAndroid Build Coastguard Worker for (i = num_options, option = options; i > 0; i --, option ++)
756*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd, option->name, option->value);
757*5e7646d2SAndroid Build Coastguard Worker
758*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_options, options);
759*5e7646d2SAndroid Build Coastguard Worker }
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker
762*5e7646d2SAndroid Build Coastguard Worker /*
763*5e7646d2SAndroid Build Coastguard Worker * 'ppd_mark_option()' - Quick mark an option without checking for conflicts.
764*5e7646d2SAndroid Build Coastguard Worker */
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker static void
ppd_mark_option(ppd_file_t * ppd,const char * option,const char * choice)767*5e7646d2SAndroid Build Coastguard Worker ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */
768*5e7646d2SAndroid Build Coastguard Worker const char *option, /* I - Option name */
769*5e7646d2SAndroid Build Coastguard Worker const char *choice) /* I - Choice name */
770*5e7646d2SAndroid Build Coastguard Worker {
771*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
772*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *o; /* Option pointer */
773*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *c, /* Choice pointer */
774*5e7646d2SAndroid Build Coastguard Worker *oldc, /* Old choice pointer */
775*5e7646d2SAndroid Build Coastguard Worker key; /* Search key for choice */
776*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc; /* Locale data */
777*5e7646d2SAndroid Build Coastguard Worker
778*5e7646d2SAndroid Build Coastguard Worker
779*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7ppd_mark_option(ppd=%p, option=\"%s\", choice=\"%s\")",
780*5e7646d2SAndroid Build Coastguard Worker ppd, option, choice));
781*5e7646d2SAndroid Build Coastguard Worker
782*5e7646d2SAndroid Build Coastguard Worker /*
783*5e7646d2SAndroid Build Coastguard Worker * AP_D_InputSlot is the "default input slot" on macOS, and setting
784*5e7646d2SAndroid Build Coastguard Worker * it clears the regular InputSlot choices...
785*5e7646d2SAndroid Build Coastguard Worker */
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option, "AP_D_InputSlot"))
788*5e7646d2SAndroid Build Coastguard Worker {
789*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
790*5e7646d2SAndroid Build Coastguard Worker
791*5e7646d2SAndroid Build Coastguard Worker if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
792*5e7646d2SAndroid Build Coastguard Worker {
793*5e7646d2SAndroid Build Coastguard Worker key.option = o;
794*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
795*5e7646d2SAndroid Build Coastguard Worker {
796*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
797*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
798*5e7646d2SAndroid Build Coastguard Worker }
799*5e7646d2SAndroid Build Coastguard Worker }
800*5e7646d2SAndroid Build Coastguard Worker
801*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
802*5e7646d2SAndroid Build Coastguard Worker }
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker /*
805*5e7646d2SAndroid Build Coastguard Worker * Check for custom options...
806*5e7646d2SAndroid Build Coastguard Worker */
807*5e7646d2SAndroid Build Coastguard Worker
808*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
809*5e7646d2SAndroid Build Coastguard Worker
810*5e7646d2SAndroid Build Coastguard Worker o = ppdFindOption(ppd, option);
811*5e7646d2SAndroid Build Coastguard Worker
812*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
813*5e7646d2SAndroid Build Coastguard Worker
814*5e7646d2SAndroid Build Coastguard Worker if (!o)
815*5e7646d2SAndroid Build Coastguard Worker return;
816*5e7646d2SAndroid Build Coastguard Worker
817*5e7646d2SAndroid Build Coastguard Worker loc = localeconv();
818*5e7646d2SAndroid Build Coastguard Worker
819*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(choice, "Custom.", 7))
820*5e7646d2SAndroid Build Coastguard Worker {
821*5e7646d2SAndroid Build Coastguard Worker /*
822*5e7646d2SAndroid Build Coastguard Worker * Handle a custom option...
823*5e7646d2SAndroid Build Coastguard Worker */
824*5e7646d2SAndroid Build Coastguard Worker
825*5e7646d2SAndroid Build Coastguard Worker if ((c = ppdFindChoice(o, "Custom")) == NULL)
826*5e7646d2SAndroid Build Coastguard Worker return;
827*5e7646d2SAndroid Build Coastguard Worker
828*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option, "PageSize"))
829*5e7646d2SAndroid Build Coastguard Worker {
830*5e7646d2SAndroid Build Coastguard Worker /*
831*5e7646d2SAndroid Build Coastguard Worker * Handle custom page sizes...
832*5e7646d2SAndroid Build Coastguard Worker */
833*5e7646d2SAndroid Build Coastguard Worker
834*5e7646d2SAndroid Build Coastguard Worker ppdPageSize(ppd, choice);
835*5e7646d2SAndroid Build Coastguard Worker }
836*5e7646d2SAndroid Build Coastguard Worker else
837*5e7646d2SAndroid Build Coastguard Worker {
838*5e7646d2SAndroid Build Coastguard Worker /*
839*5e7646d2SAndroid Build Coastguard Worker * Handle other custom options...
840*5e7646d2SAndroid Build Coastguard Worker */
841*5e7646d2SAndroid Build Coastguard Worker
842*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
843*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Custom parameter */
844*5e7646d2SAndroid Build Coastguard Worker char *units; /* Custom points units */
845*5e7646d2SAndroid Build Coastguard Worker
846*5e7646d2SAndroid Build Coastguard Worker
847*5e7646d2SAndroid Build Coastguard Worker if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
848*5e7646d2SAndroid Build Coastguard Worker {
849*5e7646d2SAndroid Build Coastguard Worker if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL)
850*5e7646d2SAndroid Build Coastguard Worker return;
851*5e7646d2SAndroid Build Coastguard Worker
852*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
853*5e7646d2SAndroid Build Coastguard Worker {
854*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
855*5e7646d2SAndroid Build Coastguard Worker break;
856*5e7646d2SAndroid Build Coastguard Worker
857*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
858*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
859*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
860*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_real = (float)_cupsStrScand(choice + 7,
861*5e7646d2SAndroid Build Coastguard Worker NULL, loc);
862*5e7646d2SAndroid Build Coastguard Worker break;
863*5e7646d2SAndroid Build Coastguard Worker
864*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
865*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points = (float)_cupsStrScand(choice + 7,
866*5e7646d2SAndroid Build Coastguard Worker &units,
867*5e7646d2SAndroid Build Coastguard Worker loc);
868*5e7646d2SAndroid Build Coastguard Worker
869*5e7646d2SAndroid Build Coastguard Worker if (units)
870*5e7646d2SAndroid Build Coastguard Worker {
871*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(units, "cm"))
872*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 2.54f;
873*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "mm"))
874*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 25.4f;
875*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "m"))
876*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 0.0254f;
877*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "in"))
878*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f;
879*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "ft"))
880*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 12.0f * 72.0f;
881*5e7646d2SAndroid Build Coastguard Worker }
882*5e7646d2SAndroid Build Coastguard Worker break;
883*5e7646d2SAndroid Build Coastguard Worker
884*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
885*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_int = atoi(choice + 7);
886*5e7646d2SAndroid Build Coastguard Worker break;
887*5e7646d2SAndroid Build Coastguard Worker
888*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
889*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
890*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
891*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
892*5e7646d2SAndroid Build Coastguard Worker free(cparam->current.custom_string);
893*5e7646d2SAndroid Build Coastguard Worker
894*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_string = strdup(choice + 7);
895*5e7646d2SAndroid Build Coastguard Worker break;
896*5e7646d2SAndroid Build Coastguard Worker }
897*5e7646d2SAndroid Build Coastguard Worker }
898*5e7646d2SAndroid Build Coastguard Worker }
899*5e7646d2SAndroid Build Coastguard Worker
900*5e7646d2SAndroid Build Coastguard Worker /*
901*5e7646d2SAndroid Build Coastguard Worker * Make sure that we keep the option marked below...
902*5e7646d2SAndroid Build Coastguard Worker */
903*5e7646d2SAndroid Build Coastguard Worker
904*5e7646d2SAndroid Build Coastguard Worker choice = "Custom";
905*5e7646d2SAndroid Build Coastguard Worker }
906*5e7646d2SAndroid Build Coastguard Worker else if (choice[0] == '{')
907*5e7646d2SAndroid Build Coastguard Worker {
908*5e7646d2SAndroid Build Coastguard Worker /*
909*5e7646d2SAndroid Build Coastguard Worker * Handle multi-value custom options...
910*5e7646d2SAndroid Build Coastguard Worker */
911*5e7646d2SAndroid Build Coastguard Worker
912*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
913*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Custom parameter */
914*5e7646d2SAndroid Build Coastguard Worker char *units; /* Custom points units */
915*5e7646d2SAndroid Build Coastguard Worker int num_vals; /* Number of values */
916*5e7646d2SAndroid Build Coastguard Worker cups_option_t *vals, /* Values */
917*5e7646d2SAndroid Build Coastguard Worker *val; /* Value */
918*5e7646d2SAndroid Build Coastguard Worker
919*5e7646d2SAndroid Build Coastguard Worker
920*5e7646d2SAndroid Build Coastguard Worker if ((c = ppdFindChoice(o, "Custom")) == NULL)
921*5e7646d2SAndroid Build Coastguard Worker return;
922*5e7646d2SAndroid Build Coastguard Worker
923*5e7646d2SAndroid Build Coastguard Worker if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
924*5e7646d2SAndroid Build Coastguard Worker {
925*5e7646d2SAndroid Build Coastguard Worker num_vals = cupsParseOptions(choice, 0, &vals);
926*5e7646d2SAndroid Build Coastguard Worker
927*5e7646d2SAndroid Build Coastguard Worker for (i = 0, val = vals; i < num_vals; i ++, val ++)
928*5e7646d2SAndroid Build Coastguard Worker {
929*5e7646d2SAndroid Build Coastguard Worker if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL)
930*5e7646d2SAndroid Build Coastguard Worker continue;
931*5e7646d2SAndroid Build Coastguard Worker
932*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
933*5e7646d2SAndroid Build Coastguard Worker {
934*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
935*5e7646d2SAndroid Build Coastguard Worker break;
936*5e7646d2SAndroid Build Coastguard Worker
937*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
938*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
939*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
940*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_real = (float)_cupsStrScand(val->value,
941*5e7646d2SAndroid Build Coastguard Worker NULL, loc);
942*5e7646d2SAndroid Build Coastguard Worker break;
943*5e7646d2SAndroid Build Coastguard Worker
944*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
945*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points = (float)_cupsStrScand(val->value,
946*5e7646d2SAndroid Build Coastguard Worker &units,
947*5e7646d2SAndroid Build Coastguard Worker loc);
948*5e7646d2SAndroid Build Coastguard Worker
949*5e7646d2SAndroid Build Coastguard Worker if (units)
950*5e7646d2SAndroid Build Coastguard Worker {
951*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(units, "cm"))
952*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 2.54f;
953*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "mm"))
954*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 25.4f;
955*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "m"))
956*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f / 0.0254f;
957*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "in"))
958*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 72.0f;
959*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(units, "ft"))
960*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points *= 12.0f * 72.0f;
961*5e7646d2SAndroid Build Coastguard Worker }
962*5e7646d2SAndroid Build Coastguard Worker break;
963*5e7646d2SAndroid Build Coastguard Worker
964*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
965*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_int = atoi(val->value);
966*5e7646d2SAndroid Build Coastguard Worker break;
967*5e7646d2SAndroid Build Coastguard Worker
968*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
969*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
970*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
971*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
972*5e7646d2SAndroid Build Coastguard Worker free(cparam->current.custom_string);
973*5e7646d2SAndroid Build Coastguard Worker
974*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_string = strdup(val->value);
975*5e7646d2SAndroid Build Coastguard Worker break;
976*5e7646d2SAndroid Build Coastguard Worker }
977*5e7646d2SAndroid Build Coastguard Worker }
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_vals, vals);
980*5e7646d2SAndroid Build Coastguard Worker }
981*5e7646d2SAndroid Build Coastguard Worker }
982*5e7646d2SAndroid Build Coastguard Worker else
983*5e7646d2SAndroid Build Coastguard Worker {
984*5e7646d2SAndroid Build Coastguard Worker for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
985*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(c->choice, choice))
986*5e7646d2SAndroid Build Coastguard Worker break;
987*5e7646d2SAndroid Build Coastguard Worker
988*5e7646d2SAndroid Build Coastguard Worker if (!i)
989*5e7646d2SAndroid Build Coastguard Worker return;
990*5e7646d2SAndroid Build Coastguard Worker }
991*5e7646d2SAndroid Build Coastguard Worker
992*5e7646d2SAndroid Build Coastguard Worker /*
993*5e7646d2SAndroid Build Coastguard Worker * Option found; mark it and then handle unmarking any other options.
994*5e7646d2SAndroid Build Coastguard Worker */
995*5e7646d2SAndroid Build Coastguard Worker
996*5e7646d2SAndroid Build Coastguard Worker if (o->ui != PPD_UI_PICKMANY)
997*5e7646d2SAndroid Build Coastguard Worker {
998*5e7646d2SAndroid Build Coastguard Worker /*
999*5e7646d2SAndroid Build Coastguard Worker * Unmark all other choices...
1000*5e7646d2SAndroid Build Coastguard Worker */
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL)
1003*5e7646d2SAndroid Build Coastguard Worker {
1004*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
1005*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
1006*5e7646d2SAndroid Build Coastguard Worker }
1007*5e7646d2SAndroid Build Coastguard Worker
1008*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option, "PageSize") || !_cups_strcasecmp(option, "PageRegion"))
1009*5e7646d2SAndroid Build Coastguard Worker {
1010*5e7646d2SAndroid Build Coastguard Worker /*
1011*5e7646d2SAndroid Build Coastguard Worker * Mark current page size...
1012*5e7646d2SAndroid Build Coastguard Worker */
1013*5e7646d2SAndroid Build Coastguard Worker
1014*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < ppd->num_sizes; j ++)
1015*5e7646d2SAndroid Build Coastguard Worker ppd->sizes[j].marked = !_cups_strcasecmp(ppd->sizes[j].name,
1016*5e7646d2SAndroid Build Coastguard Worker choice);
1017*5e7646d2SAndroid Build Coastguard Worker
1018*5e7646d2SAndroid Build Coastguard Worker /*
1019*5e7646d2SAndroid Build Coastguard Worker * Unmark the current PageSize or PageRegion setting, as
1020*5e7646d2SAndroid Build Coastguard Worker * appropriate...
1021*5e7646d2SAndroid Build Coastguard Worker */
1022*5e7646d2SAndroid Build Coastguard Worker
1023*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
1024*5e7646d2SAndroid Build Coastguard Worker
1025*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option, "PageSize"))
1026*5e7646d2SAndroid Build Coastguard Worker {
1027*5e7646d2SAndroid Build Coastguard Worker if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
1028*5e7646d2SAndroid Build Coastguard Worker {
1029*5e7646d2SAndroid Build Coastguard Worker key.option = o;
1030*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
1031*5e7646d2SAndroid Build Coastguard Worker {
1032*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
1033*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
1034*5e7646d2SAndroid Build Coastguard Worker }
1035*5e7646d2SAndroid Build Coastguard Worker }
1036*5e7646d2SAndroid Build Coastguard Worker }
1037*5e7646d2SAndroid Build Coastguard Worker else
1038*5e7646d2SAndroid Build Coastguard Worker {
1039*5e7646d2SAndroid Build Coastguard Worker if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
1040*5e7646d2SAndroid Build Coastguard Worker {
1041*5e7646d2SAndroid Build Coastguard Worker key.option = o;
1042*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
1043*5e7646d2SAndroid Build Coastguard Worker {
1044*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
1045*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
1046*5e7646d2SAndroid Build Coastguard Worker }
1047*5e7646d2SAndroid Build Coastguard Worker }
1048*5e7646d2SAndroid Build Coastguard Worker }
1049*5e7646d2SAndroid Build Coastguard Worker
1050*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
1051*5e7646d2SAndroid Build Coastguard Worker }
1052*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(option, "InputSlot"))
1053*5e7646d2SAndroid Build Coastguard Worker {
1054*5e7646d2SAndroid Build Coastguard Worker /*
1055*5e7646d2SAndroid Build Coastguard Worker * Unmark ManualFeed option...
1056*5e7646d2SAndroid Build Coastguard Worker */
1057*5e7646d2SAndroid Build Coastguard Worker
1058*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
1059*5e7646d2SAndroid Build Coastguard Worker
1060*5e7646d2SAndroid Build Coastguard Worker if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
1061*5e7646d2SAndroid Build Coastguard Worker {
1062*5e7646d2SAndroid Build Coastguard Worker key.option = o;
1063*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
1064*5e7646d2SAndroid Build Coastguard Worker {
1065*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
1066*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
1067*5e7646d2SAndroid Build Coastguard Worker }
1068*5e7646d2SAndroid Build Coastguard Worker }
1069*5e7646d2SAndroid Build Coastguard Worker
1070*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
1071*5e7646d2SAndroid Build Coastguard Worker }
1072*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(option, "ManualFeed") &&
1073*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choice, "True"))
1074*5e7646d2SAndroid Build Coastguard Worker {
1075*5e7646d2SAndroid Build Coastguard Worker /*
1076*5e7646d2SAndroid Build Coastguard Worker * Unmark InputSlot option...
1077*5e7646d2SAndroid Build Coastguard Worker */
1078*5e7646d2SAndroid Build Coastguard Worker
1079*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(ppd->options);
1080*5e7646d2SAndroid Build Coastguard Worker
1081*5e7646d2SAndroid Build Coastguard Worker if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
1082*5e7646d2SAndroid Build Coastguard Worker {
1083*5e7646d2SAndroid Build Coastguard Worker key.option = o;
1084*5e7646d2SAndroid Build Coastguard Worker if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
1085*5e7646d2SAndroid Build Coastguard Worker {
1086*5e7646d2SAndroid Build Coastguard Worker oldc->marked = 0;
1087*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, oldc);
1088*5e7646d2SAndroid Build Coastguard Worker }
1089*5e7646d2SAndroid Build Coastguard Worker }
1090*5e7646d2SAndroid Build Coastguard Worker
1091*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(ppd->options);
1092*5e7646d2SAndroid Build Coastguard Worker }
1093*5e7646d2SAndroid Build Coastguard Worker }
1094*5e7646d2SAndroid Build Coastguard Worker
1095*5e7646d2SAndroid Build Coastguard Worker c->marked = 1;
1096*5e7646d2SAndroid Build Coastguard Worker
1097*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(ppd->marked, c);
1098*5e7646d2SAndroid Build Coastguard Worker }
1099