1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * PPD code emission 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 "debug-internal.h"
19*5e7646d2SAndroid Build Coastguard Worker #include "ppd.h"
20*5e7646d2SAndroid Build Coastguard Worker #if defined(_WIN32) || defined(__EMX__)
21*5e7646d2SAndroid Build Coastguard Worker # include <io.h>
22*5e7646d2SAndroid Build Coastguard Worker #else
23*5e7646d2SAndroid Build Coastguard Worker # include <unistd.h>
24*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 || __EMX__ */
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 ppd_compare_cparams(ppd_cparam_t *a, ppd_cparam_t *b);
32*5e7646d2SAndroid Build Coastguard Worker static void ppd_handle_media(ppd_file_t *ppd);
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker
35*5e7646d2SAndroid Build Coastguard Worker /*
36*5e7646d2SAndroid Build Coastguard Worker * Local globals...
37*5e7646d2SAndroid Build Coastguard Worker */
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker static const char ppd_custom_code[] =
40*5e7646d2SAndroid Build Coastguard Worker "pop pop pop\n"
41*5e7646d2SAndroid Build Coastguard Worker "<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n";
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker /*
45*5e7646d2SAndroid Build Coastguard Worker * 'ppdCollect()' - Collect all marked options that reside in the specified
46*5e7646d2SAndroid Build Coastguard Worker * section.
47*5e7646d2SAndroid Build Coastguard Worker *
48*5e7646d2SAndroid Build Coastguard Worker * The choices array should be freed using @code free@ when you are
49*5e7646d2SAndroid Build Coastguard Worker * finished with it.
50*5e7646d2SAndroid Build Coastguard Worker */
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of options marked */
ppdCollect(ppd_file_t * ppd,ppd_section_t section,ppd_choice_t *** choices)53*5e7646d2SAndroid Build Coastguard Worker ppdCollect(ppd_file_t *ppd, /* I - PPD file data */
54*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section, /* I - Section to collect */
55*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t ***choices) /* O - Pointers to choices */
56*5e7646d2SAndroid Build Coastguard Worker {
57*5e7646d2SAndroid Build Coastguard Worker return (ppdCollect2(ppd, section, 0.0, choices));
58*5e7646d2SAndroid Build Coastguard Worker }
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker
61*5e7646d2SAndroid Build Coastguard Worker /*
62*5e7646d2SAndroid Build Coastguard Worker * 'ppdCollect2()' - Collect all marked options that reside in the
63*5e7646d2SAndroid Build Coastguard Worker * specified section and minimum order.
64*5e7646d2SAndroid Build Coastguard Worker *
65*5e7646d2SAndroid Build Coastguard Worker * The choices array should be freed using @code free@ when you are
66*5e7646d2SAndroid Build Coastguard Worker * finished with it.
67*5e7646d2SAndroid Build Coastguard Worker *
68*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
69*5e7646d2SAndroid Build Coastguard Worker */
70*5e7646d2SAndroid Build Coastguard Worker
71*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of options marked */
ppdCollect2(ppd_file_t * ppd,ppd_section_t section,float min_order,ppd_choice_t *** choices)72*5e7646d2SAndroid Build Coastguard Worker ppdCollect2(ppd_file_t *ppd, /* I - PPD file data */
73*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section, /* I - Section to collect */
74*5e7646d2SAndroid Build Coastguard Worker float min_order, /* I - Minimum OrderDependency value */
75*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t ***choices) /* O - Pointers to choices */
76*5e7646d2SAndroid Build Coastguard Worker {
77*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *c; /* Current choice */
78*5e7646d2SAndroid Build Coastguard Worker ppd_section_t csection; /* Current section */
79*5e7646d2SAndroid Build Coastguard Worker float corder; /* Current OrderDependency value */
80*5e7646d2SAndroid Build Coastguard Worker int count; /* Number of choices collected */
81*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t **collect; /* Collected choices */
82*5e7646d2SAndroid Build Coastguard Worker float *orders; /* Collected order values */
83*5e7646d2SAndroid Build Coastguard Worker
84*5e7646d2SAndroid Build Coastguard Worker
85*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ppdCollect2(ppd=%p, section=%d, min_order=%f, choices=%p)",
86*5e7646d2SAndroid Build Coastguard Worker ppd, section, min_order, choices));
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !choices)
89*5e7646d2SAndroid Build Coastguard Worker {
90*5e7646d2SAndroid Build Coastguard Worker if (choices)
91*5e7646d2SAndroid Build Coastguard Worker *choices = NULL;
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker return (0);
94*5e7646d2SAndroid Build Coastguard Worker }
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker /*
97*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for up to N selected choices...
98*5e7646d2SAndroid Build Coastguard Worker */
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker count = 0;
101*5e7646d2SAndroid Build Coastguard Worker if ((collect = calloc(sizeof(ppd_choice_t *),
102*5e7646d2SAndroid Build Coastguard Worker (size_t)cupsArrayCount(ppd->marked))) == NULL)
103*5e7646d2SAndroid Build Coastguard Worker {
104*5e7646d2SAndroid Build Coastguard Worker *choices = NULL;
105*5e7646d2SAndroid Build Coastguard Worker return (0);
106*5e7646d2SAndroid Build Coastguard Worker }
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker if ((orders = calloc(sizeof(float), (size_t)cupsArrayCount(ppd->marked))) == NULL)
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker *choices = NULL;
111*5e7646d2SAndroid Build Coastguard Worker free(collect);
112*5e7646d2SAndroid Build Coastguard Worker return (0);
113*5e7646d2SAndroid Build Coastguard Worker }
114*5e7646d2SAndroid Build Coastguard Worker
115*5e7646d2SAndroid Build Coastguard Worker /*
116*5e7646d2SAndroid Build Coastguard Worker * Loop through all options and add choices as needed...
117*5e7646d2SAndroid Build Coastguard Worker */
118*5e7646d2SAndroid Build Coastguard Worker
119*5e7646d2SAndroid Build Coastguard Worker for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
120*5e7646d2SAndroid Build Coastguard Worker c;
121*5e7646d2SAndroid Build Coastguard Worker c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
122*5e7646d2SAndroid Build Coastguard Worker {
123*5e7646d2SAndroid Build Coastguard Worker csection = c->option->section;
124*5e7646d2SAndroid Build Coastguard Worker corder = c->option->order;
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(c->choice, "Custom"))
127*5e7646d2SAndroid Build Coastguard Worker {
128*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *attr; /* NonUIOrderDependency value */
129*5e7646d2SAndroid Build Coastguard Worker float aorder; /* Order value */
130*5e7646d2SAndroid Build Coastguard Worker char asection[17], /* Section name */
131*5e7646d2SAndroid Build Coastguard Worker amain[PPD_MAX_NAME + 1],
132*5e7646d2SAndroid Build Coastguard Worker aoption[PPD_MAX_NAME];
133*5e7646d2SAndroid Build Coastguard Worker /* *CustomFoo and True */
134*5e7646d2SAndroid Build Coastguard Worker
135*5e7646d2SAndroid Build Coastguard Worker
136*5e7646d2SAndroid Build Coastguard Worker for (attr = ppdFindAttr(ppd, "NonUIOrderDependency", NULL);
137*5e7646d2SAndroid Build Coastguard Worker attr;
138*5e7646d2SAndroid Build Coastguard Worker attr = ppdFindNextAttr(ppd, "NonUIOrderDependency", NULL))
139*5e7646d2SAndroid Build Coastguard Worker if (attr->value &&
140*5e7646d2SAndroid Build Coastguard Worker sscanf(attr->value, "%f%16s%41s%40s", &aorder, asection, amain,
141*5e7646d2SAndroid Build Coastguard Worker aoption) == 4 &&
142*5e7646d2SAndroid Build Coastguard Worker !strncmp(amain, "*Custom", 7) &&
143*5e7646d2SAndroid Build Coastguard Worker !strcmp(amain + 7, c->option->keyword) && !strcmp(aoption, "True"))
144*5e7646d2SAndroid Build Coastguard Worker {
145*5e7646d2SAndroid Build Coastguard Worker /*
146*5e7646d2SAndroid Build Coastguard Worker * Use this NonUIOrderDependency...
147*5e7646d2SAndroid Build Coastguard Worker */
148*5e7646d2SAndroid Build Coastguard Worker
149*5e7646d2SAndroid Build Coastguard Worker corder = aorder;
150*5e7646d2SAndroid Build Coastguard Worker
151*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(asection, "DocumentSetup"))
152*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_DOCUMENT;
153*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(asection, "ExitServer"))
154*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_EXIT;
155*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(asection, "JCLSetup"))
156*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_JCL;
157*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(asection, "PageSetup"))
158*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_PAGE;
159*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(asection, "Prolog"))
160*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_PROLOG;
161*5e7646d2SAndroid Build Coastguard Worker else
162*5e7646d2SAndroid Build Coastguard Worker csection = PPD_ORDER_ANY;
163*5e7646d2SAndroid Build Coastguard Worker
164*5e7646d2SAndroid Build Coastguard Worker break;
165*5e7646d2SAndroid Build Coastguard Worker }
166*5e7646d2SAndroid Build Coastguard Worker }
167*5e7646d2SAndroid Build Coastguard Worker
168*5e7646d2SAndroid Build Coastguard Worker if (csection == section && corder >= min_order)
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker collect[count] = c;
171*5e7646d2SAndroid Build Coastguard Worker orders[count] = corder;
172*5e7646d2SAndroid Build Coastguard Worker count ++;
173*5e7646d2SAndroid Build Coastguard Worker }
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker /*
177*5e7646d2SAndroid Build Coastguard Worker * If we have more than 1 marked choice, sort them...
178*5e7646d2SAndroid Build Coastguard Worker */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker if (count > 1)
181*5e7646d2SAndroid Build Coastguard Worker {
182*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < (count - 1); i ++)
185*5e7646d2SAndroid Build Coastguard Worker for (j = i + 1; j < count; j ++)
186*5e7646d2SAndroid Build Coastguard Worker if (orders[i] > orders[j])
187*5e7646d2SAndroid Build Coastguard Worker {
188*5e7646d2SAndroid Build Coastguard Worker c = collect[i];
189*5e7646d2SAndroid Build Coastguard Worker corder = orders[i];
190*5e7646d2SAndroid Build Coastguard Worker collect[i] = collect[j];
191*5e7646d2SAndroid Build Coastguard Worker orders[i] = orders[j];
192*5e7646d2SAndroid Build Coastguard Worker collect[j] = c;
193*5e7646d2SAndroid Build Coastguard Worker orders[j] = corder;
194*5e7646d2SAndroid Build Coastguard Worker }
195*5e7646d2SAndroid Build Coastguard Worker }
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker free(orders);
198*5e7646d2SAndroid Build Coastguard Worker
199*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdCollect2: %d marked choices...", count));
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker /*
202*5e7646d2SAndroid Build Coastguard Worker * Return the array and number of choices; if 0, free the array since
203*5e7646d2SAndroid Build Coastguard Worker * it isn't needed.
204*5e7646d2SAndroid Build Coastguard Worker */
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker if (count > 0)
207*5e7646d2SAndroid Build Coastguard Worker {
208*5e7646d2SAndroid Build Coastguard Worker *choices = collect;
209*5e7646d2SAndroid Build Coastguard Worker return (count);
210*5e7646d2SAndroid Build Coastguard Worker }
211*5e7646d2SAndroid Build Coastguard Worker else
212*5e7646d2SAndroid Build Coastguard Worker {
213*5e7646d2SAndroid Build Coastguard Worker *choices = NULL;
214*5e7646d2SAndroid Build Coastguard Worker free(collect);
215*5e7646d2SAndroid Build Coastguard Worker return (0);
216*5e7646d2SAndroid Build Coastguard Worker }
217*5e7646d2SAndroid Build Coastguard Worker }
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker /*
221*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmit()' - Emit code for marked options to a file.
222*5e7646d2SAndroid Build Coastguard Worker */
223*5e7646d2SAndroid Build Coastguard Worker
224*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
ppdEmit(ppd_file_t * ppd,FILE * fp,ppd_section_t section)225*5e7646d2SAndroid Build Coastguard Worker ppdEmit(ppd_file_t *ppd, /* I - PPD file record */
226*5e7646d2SAndroid Build Coastguard Worker FILE *fp, /* I - File to write to */
227*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section) /* I - Section to write */
228*5e7646d2SAndroid Build Coastguard Worker {
229*5e7646d2SAndroid Build Coastguard Worker return (ppdEmitAfterOrder(ppd, fp, section, 0, 0.0));
230*5e7646d2SAndroid Build Coastguard Worker }
231*5e7646d2SAndroid Build Coastguard Worker
232*5e7646d2SAndroid Build Coastguard Worker
233*5e7646d2SAndroid Build Coastguard Worker /*
234*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmitAfterOrder()' - Emit a subset of the code for marked options to a file.
235*5e7646d2SAndroid Build Coastguard Worker *
236*5e7646d2SAndroid Build Coastguard Worker * When "limit" is non-zero, this function only emits options whose
237*5e7646d2SAndroid Build Coastguard Worker * OrderDependency value is greater than or equal to "min_order".
238*5e7646d2SAndroid Build Coastguard Worker *
239*5e7646d2SAndroid Build Coastguard Worker * When "limit" is zero, this function is identical to ppdEmit().
240*5e7646d2SAndroid Build Coastguard Worker *
241*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
242*5e7646d2SAndroid Build Coastguard Worker */
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
ppdEmitAfterOrder(ppd_file_t * ppd,FILE * fp,ppd_section_t section,int limit,float min_order)245*5e7646d2SAndroid Build Coastguard Worker ppdEmitAfterOrder(
246*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file record */
247*5e7646d2SAndroid Build Coastguard Worker FILE *fp, /* I - File to write to */
248*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section, /* I - Section to write */
249*5e7646d2SAndroid Build Coastguard Worker int limit, /* I - Non-zero to use min_order */
250*5e7646d2SAndroid Build Coastguard Worker float min_order) /* I - Lowest OrderDependency */
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker char *buffer; /* Option code */
253*5e7646d2SAndroid Build Coastguard Worker int status; /* Return status */
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker
256*5e7646d2SAndroid Build Coastguard Worker /*
257*5e7646d2SAndroid Build Coastguard Worker * Range check input...
258*5e7646d2SAndroid Build Coastguard Worker */
259*5e7646d2SAndroid Build Coastguard Worker
260*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !fp)
261*5e7646d2SAndroid Build Coastguard Worker return (-1);
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker /*
264*5e7646d2SAndroid Build Coastguard Worker * Get the string...
265*5e7646d2SAndroid Build Coastguard Worker */
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker buffer = ppdEmitString(ppd, section, limit ? min_order : 0.0f);
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker /*
270*5e7646d2SAndroid Build Coastguard Worker * Write it as needed and return...
271*5e7646d2SAndroid Build Coastguard Worker */
272*5e7646d2SAndroid Build Coastguard Worker
273*5e7646d2SAndroid Build Coastguard Worker if (buffer)
274*5e7646d2SAndroid Build Coastguard Worker {
275*5e7646d2SAndroid Build Coastguard Worker status = fputs(buffer, fp) < 0 ? -1 : 0;
276*5e7646d2SAndroid Build Coastguard Worker
277*5e7646d2SAndroid Build Coastguard Worker free(buffer);
278*5e7646d2SAndroid Build Coastguard Worker }
279*5e7646d2SAndroid Build Coastguard Worker else
280*5e7646d2SAndroid Build Coastguard Worker status = 0;
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker return (status);
283*5e7646d2SAndroid Build Coastguard Worker }
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker
286*5e7646d2SAndroid Build Coastguard Worker /*
287*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmitFd()' - Emit code for marked options to a file.
288*5e7646d2SAndroid Build Coastguard Worker */
289*5e7646d2SAndroid Build Coastguard Worker
290*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
ppdEmitFd(ppd_file_t * ppd,int fd,ppd_section_t section)291*5e7646d2SAndroid Build Coastguard Worker ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
292*5e7646d2SAndroid Build Coastguard Worker int fd, /* I - File to write to */
293*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section) /* I - Section to write */
294*5e7646d2SAndroid Build Coastguard Worker {
295*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* Option code */
296*5e7646d2SAndroid Build Coastguard Worker *bufptr; /* Pointer into code */
297*5e7646d2SAndroid Build Coastguard Worker size_t buflength; /* Length of option code */
298*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes written */
299*5e7646d2SAndroid Build Coastguard Worker int status; /* Return status */
300*5e7646d2SAndroid Build Coastguard Worker
301*5e7646d2SAndroid Build Coastguard Worker
302*5e7646d2SAndroid Build Coastguard Worker /*
303*5e7646d2SAndroid Build Coastguard Worker * Range check input...
304*5e7646d2SAndroid Build Coastguard Worker */
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker if (!ppd || fd < 0)
307*5e7646d2SAndroid Build Coastguard Worker return (-1);
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker /*
310*5e7646d2SAndroid Build Coastguard Worker * Get the string...
311*5e7646d2SAndroid Build Coastguard Worker */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker buffer = ppdEmitString(ppd, section, 0.0);
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker /*
316*5e7646d2SAndroid Build Coastguard Worker * Write it as needed and return...
317*5e7646d2SAndroid Build Coastguard Worker */
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker if (buffer)
320*5e7646d2SAndroid Build Coastguard Worker {
321*5e7646d2SAndroid Build Coastguard Worker buflength = strlen(buffer);
322*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
323*5e7646d2SAndroid Build Coastguard Worker bytes = 0;
324*5e7646d2SAndroid Build Coastguard Worker
325*5e7646d2SAndroid Build Coastguard Worker while (buflength > 0)
326*5e7646d2SAndroid Build Coastguard Worker {
327*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
328*5e7646d2SAndroid Build Coastguard Worker if ((bytes = (ssize_t)write(fd, bufptr, (unsigned)buflength)) < 0)
329*5e7646d2SAndroid Build Coastguard Worker #else
330*5e7646d2SAndroid Build Coastguard Worker if ((bytes = write(fd, bufptr, buflength)) < 0)
331*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
332*5e7646d2SAndroid Build Coastguard Worker {
333*5e7646d2SAndroid Build Coastguard Worker if (errno == EAGAIN || errno == EINTR)
334*5e7646d2SAndroid Build Coastguard Worker continue;
335*5e7646d2SAndroid Build Coastguard Worker
336*5e7646d2SAndroid Build Coastguard Worker break;
337*5e7646d2SAndroid Build Coastguard Worker }
338*5e7646d2SAndroid Build Coastguard Worker
339*5e7646d2SAndroid Build Coastguard Worker buflength -= (size_t)bytes;
340*5e7646d2SAndroid Build Coastguard Worker bufptr += bytes;
341*5e7646d2SAndroid Build Coastguard Worker }
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker status = bytes < 0 ? -1 : 0;
344*5e7646d2SAndroid Build Coastguard Worker
345*5e7646d2SAndroid Build Coastguard Worker free(buffer);
346*5e7646d2SAndroid Build Coastguard Worker }
347*5e7646d2SAndroid Build Coastguard Worker else
348*5e7646d2SAndroid Build Coastguard Worker status = 0;
349*5e7646d2SAndroid Build Coastguard Worker
350*5e7646d2SAndroid Build Coastguard Worker return (status);
351*5e7646d2SAndroid Build Coastguard Worker }
352*5e7646d2SAndroid Build Coastguard Worker
353*5e7646d2SAndroid Build Coastguard Worker
354*5e7646d2SAndroid Build Coastguard Worker /*
355*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmitJCL()' - Emit code for JCL options to a file.
356*5e7646d2SAndroid Build Coastguard Worker */
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
ppdEmitJCL(ppd_file_t * ppd,FILE * fp,int job_id,const char * user,const char * title)359*5e7646d2SAndroid Build Coastguard Worker ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
360*5e7646d2SAndroid Build Coastguard Worker FILE *fp, /* I - File to write to */
361*5e7646d2SAndroid Build Coastguard Worker int job_id, /* I - Job ID */
362*5e7646d2SAndroid Build Coastguard Worker const char *user, /* I - Username */
363*5e7646d2SAndroid Build Coastguard Worker const char *title) /* I - Title */
364*5e7646d2SAndroid Build Coastguard Worker {
365*5e7646d2SAndroid Build Coastguard Worker char *ptr; /* Pointer into JCL string */
366*5e7646d2SAndroid Build Coastguard Worker char temp[65], /* Local title string */
367*5e7646d2SAndroid Build Coastguard Worker displaymsg[33]; /* Local display string */
368*5e7646d2SAndroid Build Coastguard Worker
369*5e7646d2SAndroid Build Coastguard Worker
370*5e7646d2SAndroid Build Coastguard Worker /*
371*5e7646d2SAndroid Build Coastguard Worker * Range check the input...
372*5e7646d2SAndroid Build Coastguard Worker */
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !ppd->jcl_begin || !ppd->jcl_ps)
375*5e7646d2SAndroid Build Coastguard Worker return (0);
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker /*
378*5e7646d2SAndroid Build Coastguard Worker * See if the printer supports HP PJL...
379*5e7646d2SAndroid Build Coastguard Worker */
380*5e7646d2SAndroid Build Coastguard Worker
381*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(ppd->jcl_begin, "\033%-12345X@", 10))
382*5e7646d2SAndroid Build Coastguard Worker {
383*5e7646d2SAndroid Build Coastguard Worker /*
384*5e7646d2SAndroid Build Coastguard Worker * This printer uses HP PJL commands for output; filter the output
385*5e7646d2SAndroid Build Coastguard Worker * so that we only have a single "@PJL JOB" command in the header...
386*5e7646d2SAndroid Build Coastguard Worker *
387*5e7646d2SAndroid Build Coastguard Worker * To avoid bugs in the PJL implementation of certain vendors' products
388*5e7646d2SAndroid Build Coastguard Worker * (Xerox in particular), we add a dummy "@PJL" command at the beginning
389*5e7646d2SAndroid Build Coastguard Worker * of the PJL commands to initialize PJL processing.
390*5e7646d2SAndroid Build Coastguard Worker */
391*5e7646d2SAndroid Build Coastguard Worker
392*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *charset; /* PJL charset */
393*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *display; /* PJL display command */
394*5e7646d2SAndroid Build Coastguard Worker
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker if ((charset = ppdFindAttr(ppd, "cupsPJLCharset", NULL)) != NULL)
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker if (!charset->value || _cups_strcasecmp(charset->value, "UTF-8"))
399*5e7646d2SAndroid Build Coastguard Worker charset = NULL;
400*5e7646d2SAndroid Build Coastguard Worker }
401*5e7646d2SAndroid Build Coastguard Worker
402*5e7646d2SAndroid Build Coastguard Worker if ((display = ppdFindAttr(ppd, "cupsPJLDisplay", NULL)) != NULL)
403*5e7646d2SAndroid Build Coastguard Worker {
404*5e7646d2SAndroid Build Coastguard Worker if (!display->value)
405*5e7646d2SAndroid Build Coastguard Worker display = NULL;
406*5e7646d2SAndroid Build Coastguard Worker }
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker fputs("\033%-12345X@PJL\n", fp);
409*5e7646d2SAndroid Build Coastguard Worker for (ptr = ppd->jcl_begin + 9; *ptr;)
410*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(ptr, "@PJL JOB", 8))
411*5e7646d2SAndroid Build Coastguard Worker {
412*5e7646d2SAndroid Build Coastguard Worker /*
413*5e7646d2SAndroid Build Coastguard Worker * Skip job command...
414*5e7646d2SAndroid Build Coastguard Worker */
415*5e7646d2SAndroid Build Coastguard Worker
416*5e7646d2SAndroid Build Coastguard Worker for (;*ptr; ptr ++)
417*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\n')
418*5e7646d2SAndroid Build Coastguard Worker break;
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
421*5e7646d2SAndroid Build Coastguard Worker ptr ++;
422*5e7646d2SAndroid Build Coastguard Worker }
423*5e7646d2SAndroid Build Coastguard Worker else
424*5e7646d2SAndroid Build Coastguard Worker {
425*5e7646d2SAndroid Build Coastguard Worker /*
426*5e7646d2SAndroid Build Coastguard Worker * Copy line...
427*5e7646d2SAndroid Build Coastguard Worker */
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker for (;*ptr; ptr ++)
430*5e7646d2SAndroid Build Coastguard Worker {
431*5e7646d2SAndroid Build Coastguard Worker putc(*ptr, fp);
432*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\n')
433*5e7646d2SAndroid Build Coastguard Worker break;
434*5e7646d2SAndroid Build Coastguard Worker }
435*5e7646d2SAndroid Build Coastguard Worker
436*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
437*5e7646d2SAndroid Build Coastguard Worker ptr ++;
438*5e7646d2SAndroid Build Coastguard Worker }
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker /*
441*5e7646d2SAndroid Build Coastguard Worker * Clean up the job title...
442*5e7646d2SAndroid Build Coastguard Worker */
443*5e7646d2SAndroid Build Coastguard Worker
444*5e7646d2SAndroid Build Coastguard Worker if (!title)
445*5e7646d2SAndroid Build Coastguard Worker title = "Unknown";
446*5e7646d2SAndroid Build Coastguard Worker
447*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strrchr(title, '/')) != NULL)
448*5e7646d2SAndroid Build Coastguard Worker {
449*5e7646d2SAndroid Build Coastguard Worker /*
450*5e7646d2SAndroid Build Coastguard Worker * Only show basename of file path...
451*5e7646d2SAndroid Build Coastguard Worker */
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker title = ptr + 1;
454*5e7646d2SAndroid Build Coastguard Worker }
455*5e7646d2SAndroid Build Coastguard Worker
456*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(title, "smbprn.", 7))
457*5e7646d2SAndroid Build Coastguard Worker {
458*5e7646d2SAndroid Build Coastguard Worker /*
459*5e7646d2SAndroid Build Coastguard Worker * Skip leading smbprn.######## from Samba jobs...
460*5e7646d2SAndroid Build Coastguard Worker */
461*5e7646d2SAndroid Build Coastguard Worker
462*5e7646d2SAndroid Build Coastguard Worker for (title += 7; *title && isdigit(*title & 255); title ++);
463*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*title))
464*5e7646d2SAndroid Build Coastguard Worker title ++;
465*5e7646d2SAndroid Build Coastguard Worker
466*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strstr(title, " - ")) != NULL)
467*5e7646d2SAndroid Build Coastguard Worker {
468*5e7646d2SAndroid Build Coastguard Worker /*
469*5e7646d2SAndroid Build Coastguard Worker * Skip application name in "Some Application - Title of job"...
470*5e7646d2SAndroid Build Coastguard Worker */
471*5e7646d2SAndroid Build Coastguard Worker
472*5e7646d2SAndroid Build Coastguard Worker title = ptr + 3;
473*5e7646d2SAndroid Build Coastguard Worker }
474*5e7646d2SAndroid Build Coastguard Worker }
475*5e7646d2SAndroid Build Coastguard Worker
476*5e7646d2SAndroid Build Coastguard Worker /*
477*5e7646d2SAndroid Build Coastguard Worker * Replace double quotes with single quotes and UTF-8 characters with
478*5e7646d2SAndroid Build Coastguard Worker * question marks so that the title does not cause a PJL syntax error.
479*5e7646d2SAndroid Build Coastguard Worker */
480*5e7646d2SAndroid Build Coastguard Worker
481*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, title, sizeof(temp));
482*5e7646d2SAndroid Build Coastguard Worker
483*5e7646d2SAndroid Build Coastguard Worker for (ptr = temp; *ptr; ptr ++)
484*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\"')
485*5e7646d2SAndroid Build Coastguard Worker *ptr = '\'';
486*5e7646d2SAndroid Build Coastguard Worker else if (!charset && (*ptr & 128))
487*5e7646d2SAndroid Build Coastguard Worker *ptr = '?';
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker /*
490*5e7646d2SAndroid Build Coastguard Worker * CUPS STR #3125: Long PJL JOB NAME causes problems with some printers
491*5e7646d2SAndroid Build Coastguard Worker *
492*5e7646d2SAndroid Build Coastguard Worker * Generate the display message, truncating at 32 characters + nul to avoid
493*5e7646d2SAndroid Build Coastguard Worker * issues with some printer's PJL implementations...
494*5e7646d2SAndroid Build Coastguard Worker */
495*5e7646d2SAndroid Build Coastguard Worker
496*5e7646d2SAndroid Build Coastguard Worker if (!user)
497*5e7646d2SAndroid Build Coastguard Worker user = "anonymous";
498*5e7646d2SAndroid Build Coastguard Worker
499*5e7646d2SAndroid Build Coastguard Worker snprintf(displaymsg, sizeof(displaymsg), "%d %s %s", job_id, user, temp);
500*5e7646d2SAndroid Build Coastguard Worker
501*5e7646d2SAndroid Build Coastguard Worker /*
502*5e7646d2SAndroid Build Coastguard Worker * Send PJL JOB and PJL RDYMSG commands before we enter PostScript mode...
503*5e7646d2SAndroid Build Coastguard Worker */
504*5e7646d2SAndroid Build Coastguard Worker
505*5e7646d2SAndroid Build Coastguard Worker if (display && strcmp(display->value, "job"))
506*5e7646d2SAndroid Build Coastguard Worker fprintf(fp, "@PJL JOB NAME = \"%s\"\n", temp);
507*5e7646d2SAndroid Build Coastguard Worker else if (display && !strcmp(display->value, "rdymsg"))
508*5e7646d2SAndroid Build Coastguard Worker fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg);
509*5e7646d2SAndroid Build Coastguard Worker else
510*5e7646d2SAndroid Build Coastguard Worker fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%s\"\n", temp,
511*5e7646d2SAndroid Build Coastguard Worker displaymsg);
512*5e7646d2SAndroid Build Coastguard Worker
513*5e7646d2SAndroid Build Coastguard Worker /*
514*5e7646d2SAndroid Build Coastguard Worker * Replace double quotes with single quotes and UTF-8 characters with
515*5e7646d2SAndroid Build Coastguard Worker * question marks so that the user does not cause a PJL syntax error.
516*5e7646d2SAndroid Build Coastguard Worker */
517*5e7646d2SAndroid Build Coastguard Worker
518*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, user, sizeof(temp));
519*5e7646d2SAndroid Build Coastguard Worker
520*5e7646d2SAndroid Build Coastguard Worker for (ptr = temp; *ptr; ptr ++)
521*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\"')
522*5e7646d2SAndroid Build Coastguard Worker *ptr = '\'';
523*5e7646d2SAndroid Build Coastguard Worker else if (!charset && (*ptr & 128))
524*5e7646d2SAndroid Build Coastguard Worker *ptr = '?';
525*5e7646d2SAndroid Build Coastguard Worker
526*5e7646d2SAndroid Build Coastguard Worker fprintf(fp, "@PJL SET USERNAME = \"%s\"\n", temp);
527*5e7646d2SAndroid Build Coastguard Worker }
528*5e7646d2SAndroid Build Coastguard Worker else
529*5e7646d2SAndroid Build Coastguard Worker fputs(ppd->jcl_begin, fp);
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker ppdEmit(ppd, fp, PPD_ORDER_JCL);
532*5e7646d2SAndroid Build Coastguard Worker fputs(ppd->jcl_ps, fp);
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker return (0);
535*5e7646d2SAndroid Build Coastguard Worker }
536*5e7646d2SAndroid Build Coastguard Worker
537*5e7646d2SAndroid Build Coastguard Worker
538*5e7646d2SAndroid Build Coastguard Worker /*
539*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmitJCLEnd()' - Emit JCLEnd code to a file.
540*5e7646d2SAndroid Build Coastguard Worker *
541*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
542*5e7646d2SAndroid Build Coastguard Worker */
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
ppdEmitJCLEnd(ppd_file_t * ppd,FILE * fp)545*5e7646d2SAndroid Build Coastguard Worker ppdEmitJCLEnd(ppd_file_t *ppd, /* I - PPD file record */
546*5e7646d2SAndroid Build Coastguard Worker FILE *fp) /* I - File to write to */
547*5e7646d2SAndroid Build Coastguard Worker {
548*5e7646d2SAndroid Build Coastguard Worker /*
549*5e7646d2SAndroid Build Coastguard Worker * Range check the input...
550*5e7646d2SAndroid Build Coastguard Worker */
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
553*5e7646d2SAndroid Build Coastguard Worker return (0);
554*5e7646d2SAndroid Build Coastguard Worker
555*5e7646d2SAndroid Build Coastguard Worker if (!ppd->jcl_end)
556*5e7646d2SAndroid Build Coastguard Worker {
557*5e7646d2SAndroid Build Coastguard Worker if (ppd->num_filters == 0)
558*5e7646d2SAndroid Build Coastguard Worker putc(0x04, fp);
559*5e7646d2SAndroid Build Coastguard Worker
560*5e7646d2SAndroid Build Coastguard Worker return (0);
561*5e7646d2SAndroid Build Coastguard Worker }
562*5e7646d2SAndroid Build Coastguard Worker
563*5e7646d2SAndroid Build Coastguard Worker /*
564*5e7646d2SAndroid Build Coastguard Worker * See if the printer supports HP PJL...
565*5e7646d2SAndroid Build Coastguard Worker */
566*5e7646d2SAndroid Build Coastguard Worker
567*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(ppd->jcl_end, "\033%-12345X@", 10))
568*5e7646d2SAndroid Build Coastguard Worker {
569*5e7646d2SAndroid Build Coastguard Worker /*
570*5e7646d2SAndroid Build Coastguard Worker * This printer uses HP PJL commands for output; filter the output
571*5e7646d2SAndroid Build Coastguard Worker * so that we only have a single "@PJL JOB" command in the header...
572*5e7646d2SAndroid Build Coastguard Worker *
573*5e7646d2SAndroid Build Coastguard Worker * To avoid bugs in the PJL implementation of certain vendors' products
574*5e7646d2SAndroid Build Coastguard Worker * (Xerox in particular), we add a dummy "@PJL" command at the beginning
575*5e7646d2SAndroid Build Coastguard Worker * of the PJL commands to initialize PJL processing.
576*5e7646d2SAndroid Build Coastguard Worker */
577*5e7646d2SAndroid Build Coastguard Worker
578*5e7646d2SAndroid Build Coastguard Worker fputs("\033%-12345X@PJL\n", fp);
579*5e7646d2SAndroid Build Coastguard Worker fputs("@PJL RDYMSG DISPLAY = \"\"\n", fp);
580*5e7646d2SAndroid Build Coastguard Worker fputs(ppd->jcl_end + 9, fp);
581*5e7646d2SAndroid Build Coastguard Worker }
582*5e7646d2SAndroid Build Coastguard Worker else
583*5e7646d2SAndroid Build Coastguard Worker fputs(ppd->jcl_end, fp);
584*5e7646d2SAndroid Build Coastguard Worker
585*5e7646d2SAndroid Build Coastguard Worker return (0);
586*5e7646d2SAndroid Build Coastguard Worker }
587*5e7646d2SAndroid Build Coastguard Worker
588*5e7646d2SAndroid Build Coastguard Worker
589*5e7646d2SAndroid Build Coastguard Worker /*
590*5e7646d2SAndroid Build Coastguard Worker * 'ppdEmitString()' - Get a string containing the code for marked options.
591*5e7646d2SAndroid Build Coastguard Worker *
592*5e7646d2SAndroid Build Coastguard Worker * When "min_order" is greater than zero, this function only includes options
593*5e7646d2SAndroid Build Coastguard Worker * whose OrderDependency value is greater than or equal to "min_order".
594*5e7646d2SAndroid Build Coastguard Worker * Otherwise, all options in the specified section are included in the
595*5e7646d2SAndroid Build Coastguard Worker * returned string.
596*5e7646d2SAndroid Build Coastguard Worker *
597*5e7646d2SAndroid Build Coastguard Worker * The return string is allocated on the heap and should be freed using
598*5e7646d2SAndroid Build Coastguard Worker * @code free@ when you are done with it.
599*5e7646d2SAndroid Build Coastguard Worker *
600*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
601*5e7646d2SAndroid Build Coastguard Worker */
602*5e7646d2SAndroid Build Coastguard Worker
603*5e7646d2SAndroid Build Coastguard Worker char * /* O - String containing option code or @code NULL@ if there is no option code */
ppdEmitString(ppd_file_t * ppd,ppd_section_t section,float min_order)604*5e7646d2SAndroid Build Coastguard Worker ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */
605*5e7646d2SAndroid Build Coastguard Worker ppd_section_t section, /* I - Section to write */
606*5e7646d2SAndroid Build Coastguard Worker float min_order) /* I - Lowest OrderDependency */
607*5e7646d2SAndroid Build Coastguard Worker {
608*5e7646d2SAndroid Build Coastguard Worker int i, j, /* Looping vars */
609*5e7646d2SAndroid Build Coastguard Worker count; /* Number of choices */
610*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t **choices; /* Choices */
611*5e7646d2SAndroid Build Coastguard Worker ppd_size_t *size; /* Custom page size */
612*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
613*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Custom parameter */
614*5e7646d2SAndroid Build Coastguard Worker size_t bufsize; /* Size of string buffer needed */
615*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* String buffer */
616*5e7646d2SAndroid Build Coastguard Worker *bufptr, /* Pointer into buffer */
617*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
618*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc; /* Locale data */
619*5e7646d2SAndroid Build Coastguard Worker
620*5e7646d2SAndroid Build Coastguard Worker
621*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("ppdEmitString(ppd=%p, section=%d, min_order=%f)",
622*5e7646d2SAndroid Build Coastguard Worker ppd, section, min_order));
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker /*
625*5e7646d2SAndroid Build Coastguard Worker * Range check input...
626*5e7646d2SAndroid Build Coastguard Worker */
627*5e7646d2SAndroid Build Coastguard Worker
628*5e7646d2SAndroid Build Coastguard Worker if (!ppd)
629*5e7646d2SAndroid Build Coastguard Worker return (NULL);
630*5e7646d2SAndroid Build Coastguard Worker
631*5e7646d2SAndroid Build Coastguard Worker /*
632*5e7646d2SAndroid Build Coastguard Worker * Use PageSize or PageRegion as required...
633*5e7646d2SAndroid Build Coastguard Worker */
634*5e7646d2SAndroid Build Coastguard Worker
635*5e7646d2SAndroid Build Coastguard Worker ppd_handle_media(ppd);
636*5e7646d2SAndroid Build Coastguard Worker
637*5e7646d2SAndroid Build Coastguard Worker /*
638*5e7646d2SAndroid Build Coastguard Worker * Collect the options we need to emit...
639*5e7646d2SAndroid Build Coastguard Worker */
640*5e7646d2SAndroid Build Coastguard Worker
641*5e7646d2SAndroid Build Coastguard Worker if ((count = ppdCollect2(ppd, section, min_order, &choices)) == 0)
642*5e7646d2SAndroid Build Coastguard Worker return (NULL);
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker /*
645*5e7646d2SAndroid Build Coastguard Worker * Count the number of bytes that are required to hold all of the
646*5e7646d2SAndroid Build Coastguard Worker * option code...
647*5e7646d2SAndroid Build Coastguard Worker */
648*5e7646d2SAndroid Build Coastguard Worker
649*5e7646d2SAndroid Build Coastguard Worker for (i = 0, bufsize = 1; i < count; i ++)
650*5e7646d2SAndroid Build Coastguard Worker {
651*5e7646d2SAndroid Build Coastguard Worker if (section == PPD_ORDER_JCL)
652*5e7646d2SAndroid Build Coastguard Worker {
653*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choices[i]->choice, "Custom") &&
654*5e7646d2SAndroid Build Coastguard Worker (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword))
655*5e7646d2SAndroid Build Coastguard Worker != NULL)
656*5e7646d2SAndroid Build Coastguard Worker {
657*5e7646d2SAndroid Build Coastguard Worker /*
658*5e7646d2SAndroid Build Coastguard Worker * Add space to account for custom parameter substitution...
659*5e7646d2SAndroid Build Coastguard Worker */
660*5e7646d2SAndroid Build Coastguard Worker
661*5e7646d2SAndroid Build Coastguard Worker for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
662*5e7646d2SAndroid Build Coastguard Worker cparam;
663*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
664*5e7646d2SAndroid Build Coastguard Worker {
665*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
666*5e7646d2SAndroid Build Coastguard Worker {
667*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
668*5e7646d2SAndroid Build Coastguard Worker break;
669*5e7646d2SAndroid Build Coastguard Worker
670*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
671*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
672*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
673*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
674*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
675*5e7646d2SAndroid Build Coastguard Worker bufsize += 10;
676*5e7646d2SAndroid Build Coastguard Worker break;
677*5e7646d2SAndroid Build Coastguard Worker
678*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
679*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
680*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
681*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
682*5e7646d2SAndroid Build Coastguard Worker bufsize += strlen(cparam->current.custom_string);
683*5e7646d2SAndroid Build Coastguard Worker break;
684*5e7646d2SAndroid Build Coastguard Worker }
685*5e7646d2SAndroid Build Coastguard Worker }
686*5e7646d2SAndroid Build Coastguard Worker }
687*5e7646d2SAndroid Build Coastguard Worker }
688*5e7646d2SAndroid Build Coastguard Worker else if (section != PPD_ORDER_EXIT)
689*5e7646d2SAndroid Build Coastguard Worker {
690*5e7646d2SAndroid Build Coastguard Worker bufsize += 3; /* [{\n */
691*5e7646d2SAndroid Build Coastguard Worker
692*5e7646d2SAndroid Build Coastguard Worker if ((!_cups_strcasecmp(choices[i]->option->keyword, "PageSize") ||
693*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choices[i]->option->keyword, "PageRegion")) &&
694*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choices[i]->choice, "Custom"))
695*5e7646d2SAndroid Build Coastguard Worker {
696*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("2ppdEmitString: Custom size set!");
697*5e7646d2SAndroid Build Coastguard Worker
698*5e7646d2SAndroid Build Coastguard Worker bufsize += 37; /* %%BeginFeature: *CustomPageSize True\n */
699*5e7646d2SAndroid Build Coastguard Worker bufsize += 50; /* Five 9-digit numbers + newline */
700*5e7646d2SAndroid Build Coastguard Worker }
701*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choices[i]->choice, "Custom") &&
702*5e7646d2SAndroid Build Coastguard Worker (coption = ppdFindCustomOption(ppd,
703*5e7646d2SAndroid Build Coastguard Worker choices[i]->option->keyword))
704*5e7646d2SAndroid Build Coastguard Worker != NULL)
705*5e7646d2SAndroid Build Coastguard Worker {
706*5e7646d2SAndroid Build Coastguard Worker bufsize += 23 + strlen(choices[i]->option->keyword) + 6;
707*5e7646d2SAndroid Build Coastguard Worker /* %%BeginFeature: *Customkeyword True\n */
708*5e7646d2SAndroid Build Coastguard Worker
709*5e7646d2SAndroid Build Coastguard Worker
710*5e7646d2SAndroid Build Coastguard Worker for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
711*5e7646d2SAndroid Build Coastguard Worker cparam;
712*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
713*5e7646d2SAndroid Build Coastguard Worker {
714*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
715*5e7646d2SAndroid Build Coastguard Worker {
716*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
717*5e7646d2SAndroid Build Coastguard Worker break;
718*5e7646d2SAndroid Build Coastguard Worker
719*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
720*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
721*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
722*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
723*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
724*5e7646d2SAndroid Build Coastguard Worker bufsize += 10;
725*5e7646d2SAndroid Build Coastguard Worker break;
726*5e7646d2SAndroid Build Coastguard Worker
727*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
728*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
729*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
730*5e7646d2SAndroid Build Coastguard Worker bufsize += 3;
731*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
732*5e7646d2SAndroid Build Coastguard Worker bufsize += 4 * strlen(cparam->current.custom_string);
733*5e7646d2SAndroid Build Coastguard Worker break;
734*5e7646d2SAndroid Build Coastguard Worker }
735*5e7646d2SAndroid Build Coastguard Worker }
736*5e7646d2SAndroid Build Coastguard Worker }
737*5e7646d2SAndroid Build Coastguard Worker else
738*5e7646d2SAndroid Build Coastguard Worker bufsize += 17 + strlen(choices[i]->option->keyword) + 1 +
739*5e7646d2SAndroid Build Coastguard Worker strlen(choices[i]->choice) + 1;
740*5e7646d2SAndroid Build Coastguard Worker /* %%BeginFeature: *keyword choice\n */
741*5e7646d2SAndroid Build Coastguard Worker
742*5e7646d2SAndroid Build Coastguard Worker bufsize += 13; /* %%EndFeature\n */
743*5e7646d2SAndroid Build Coastguard Worker bufsize += 22; /* } stopped cleartomark\n */
744*5e7646d2SAndroid Build Coastguard Worker }
745*5e7646d2SAndroid Build Coastguard Worker
746*5e7646d2SAndroid Build Coastguard Worker if (choices[i]->code)
747*5e7646d2SAndroid Build Coastguard Worker bufsize += strlen(choices[i]->code) + 1;
748*5e7646d2SAndroid Build Coastguard Worker else
749*5e7646d2SAndroid Build Coastguard Worker bufsize += strlen(ppd_custom_code);
750*5e7646d2SAndroid Build Coastguard Worker }
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker /*
753*5e7646d2SAndroid Build Coastguard Worker * Allocate memory...
754*5e7646d2SAndroid Build Coastguard Worker */
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdEmitString: Allocating %d bytes for string...",
757*5e7646d2SAndroid Build Coastguard Worker (int)bufsize));
758*5e7646d2SAndroid Build Coastguard Worker
759*5e7646d2SAndroid Build Coastguard Worker if ((buffer = calloc(1, bufsize)) == NULL)
760*5e7646d2SAndroid Build Coastguard Worker {
761*5e7646d2SAndroid Build Coastguard Worker free(choices);
762*5e7646d2SAndroid Build Coastguard Worker return (NULL);
763*5e7646d2SAndroid Build Coastguard Worker }
764*5e7646d2SAndroid Build Coastguard Worker
765*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + bufsize - 1;
766*5e7646d2SAndroid Build Coastguard Worker loc = localeconv();
767*5e7646d2SAndroid Build Coastguard Worker
768*5e7646d2SAndroid Build Coastguard Worker /*
769*5e7646d2SAndroid Build Coastguard Worker * Copy the option code to the buffer...
770*5e7646d2SAndroid Build Coastguard Worker */
771*5e7646d2SAndroid Build Coastguard Worker
772*5e7646d2SAndroid Build Coastguard Worker for (i = 0, bufptr = buffer; i < count; i ++, bufptr += strlen(bufptr))
773*5e7646d2SAndroid Build Coastguard Worker if (section == PPD_ORDER_JCL)
774*5e7646d2SAndroid Build Coastguard Worker {
775*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choices[i]->choice, "Custom") &&
776*5e7646d2SAndroid Build Coastguard Worker choices[i]->code &&
777*5e7646d2SAndroid Build Coastguard Worker (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword))
778*5e7646d2SAndroid Build Coastguard Worker != NULL)
779*5e7646d2SAndroid Build Coastguard Worker {
780*5e7646d2SAndroid Build Coastguard Worker /*
781*5e7646d2SAndroid Build Coastguard Worker * Handle substitutions in custom JCL options...
782*5e7646d2SAndroid Build Coastguard Worker */
783*5e7646d2SAndroid Build Coastguard Worker
784*5e7646d2SAndroid Build Coastguard Worker char *cptr; /* Pointer into code */
785*5e7646d2SAndroid Build Coastguard Worker int pnum; /* Parameter number */
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker for (cptr = choices[i]->code; *cptr && bufptr < bufend;)
789*5e7646d2SAndroid Build Coastguard Worker {
790*5e7646d2SAndroid Build Coastguard Worker if (*cptr == '\\')
791*5e7646d2SAndroid Build Coastguard Worker {
792*5e7646d2SAndroid Build Coastguard Worker cptr ++;
793*5e7646d2SAndroid Build Coastguard Worker
794*5e7646d2SAndroid Build Coastguard Worker if (isdigit(*cptr & 255))
795*5e7646d2SAndroid Build Coastguard Worker {
796*5e7646d2SAndroid Build Coastguard Worker /*
797*5e7646d2SAndroid Build Coastguard Worker * Substitute parameter...
798*5e7646d2SAndroid Build Coastguard Worker */
799*5e7646d2SAndroid Build Coastguard Worker
800*5e7646d2SAndroid Build Coastguard Worker pnum = *cptr++ - '0';
801*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*cptr & 255))
802*5e7646d2SAndroid Build Coastguard Worker pnum = pnum * 10 + *cptr++ - '0';
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
805*5e7646d2SAndroid Build Coastguard Worker cparam;
806*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
807*5e7646d2SAndroid Build Coastguard Worker if (cparam->order == pnum)
808*5e7646d2SAndroid Build Coastguard Worker break;
809*5e7646d2SAndroid Build Coastguard Worker
810*5e7646d2SAndroid Build Coastguard Worker if (cparam)
811*5e7646d2SAndroid Build Coastguard Worker {
812*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
813*5e7646d2SAndroid Build Coastguard Worker {
814*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
815*5e7646d2SAndroid Build Coastguard Worker break;
816*5e7646d2SAndroid Build Coastguard Worker
817*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
818*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
819*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
820*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
821*5e7646d2SAndroid Build Coastguard Worker bufptr = _cupsStrFormatd(bufptr, bufend,
822*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_real,
823*5e7646d2SAndroid Build Coastguard Worker loc);
824*5e7646d2SAndroid Build Coastguard Worker break;
825*5e7646d2SAndroid Build Coastguard Worker
826*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
827*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr), "%d", cparam->current.custom_int);
828*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
829*5e7646d2SAndroid Build Coastguard Worker break;
830*5e7646d2SAndroid Build Coastguard Worker
831*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
832*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
833*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
834*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
835*5e7646d2SAndroid Build Coastguard Worker {
836*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, cparam->current.custom_string, (size_t)(bufend - bufptr));
837*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
838*5e7646d2SAndroid Build Coastguard Worker }
839*5e7646d2SAndroid Build Coastguard Worker break;
840*5e7646d2SAndroid Build Coastguard Worker }
841*5e7646d2SAndroid Build Coastguard Worker }
842*5e7646d2SAndroid Build Coastguard Worker }
843*5e7646d2SAndroid Build Coastguard Worker else if (*cptr)
844*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *cptr++;
845*5e7646d2SAndroid Build Coastguard Worker }
846*5e7646d2SAndroid Build Coastguard Worker else
847*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *cptr++;
848*5e7646d2SAndroid Build Coastguard Worker }
849*5e7646d2SAndroid Build Coastguard Worker }
850*5e7646d2SAndroid Build Coastguard Worker else if (choices[i]->code)
851*5e7646d2SAndroid Build Coastguard Worker {
852*5e7646d2SAndroid Build Coastguard Worker /*
853*5e7646d2SAndroid Build Coastguard Worker * Otherwise just copy the option code directly...
854*5e7646d2SAndroid Build Coastguard Worker */
855*5e7646d2SAndroid Build Coastguard Worker
856*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, choices[i]->code, (size_t)(bufend - bufptr + 1));
857*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
858*5e7646d2SAndroid Build Coastguard Worker }
859*5e7646d2SAndroid Build Coastguard Worker }
860*5e7646d2SAndroid Build Coastguard Worker else if (section != PPD_ORDER_EXIT)
861*5e7646d2SAndroid Build Coastguard Worker {
862*5e7646d2SAndroid Build Coastguard Worker /*
863*5e7646d2SAndroid Build Coastguard Worker * Add wrapper commands to prevent printer errors for unsupported
864*5e7646d2SAndroid Build Coastguard Worker * options...
865*5e7646d2SAndroid Build Coastguard Worker */
866*5e7646d2SAndroid Build Coastguard Worker
867*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, "[{\n", (size_t)(bufend - bufptr + 1));
868*5e7646d2SAndroid Build Coastguard Worker bufptr += 3;
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker /*
871*5e7646d2SAndroid Build Coastguard Worker * Send DSC comments with option...
872*5e7646d2SAndroid Build Coastguard Worker */
873*5e7646d2SAndroid Build Coastguard Worker
874*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdEmitString: Adding code for %s=%s...",
875*5e7646d2SAndroid Build Coastguard Worker choices[i]->option->keyword, choices[i]->choice));
876*5e7646d2SAndroid Build Coastguard Worker
877*5e7646d2SAndroid Build Coastguard Worker if ((!_cups_strcasecmp(choices[i]->option->keyword, "PageSize") ||
878*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choices[i]->option->keyword, "PageRegion")) &&
879*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(choices[i]->choice, "Custom"))
880*5e7646d2SAndroid Build Coastguard Worker {
881*5e7646d2SAndroid Build Coastguard Worker /*
882*5e7646d2SAndroid Build Coastguard Worker * Variable size; write out standard size options, using the
883*5e7646d2SAndroid Build Coastguard Worker * parameter positions defined in the PPD file...
884*5e7646d2SAndroid Build Coastguard Worker */
885*5e7646d2SAndroid Build Coastguard Worker
886*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *attr; /* PPD attribute */
887*5e7646d2SAndroid Build Coastguard Worker int pos, /* Position of custom value */
888*5e7646d2SAndroid Build Coastguard Worker orientation; /* Orientation to use */
889*5e7646d2SAndroid Build Coastguard Worker float values[5]; /* Values for custom command */
890*5e7646d2SAndroid Build Coastguard Worker
891*5e7646d2SAndroid Build Coastguard Worker
892*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, "%%BeginFeature: *CustomPageSize True\n", (size_t)(bufend - bufptr + 1));
893*5e7646d2SAndroid Build Coastguard Worker bufptr += 37;
894*5e7646d2SAndroid Build Coastguard Worker
895*5e7646d2SAndroid Build Coastguard Worker size = ppdPageSize(ppd, "Custom");
896*5e7646d2SAndroid Build Coastguard Worker
897*5e7646d2SAndroid Build Coastguard Worker memset(values, 0, sizeof(values));
898*5e7646d2SAndroid Build Coastguard Worker
899*5e7646d2SAndroid Build Coastguard Worker if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Width")) != NULL)
900*5e7646d2SAndroid Build Coastguard Worker {
901*5e7646d2SAndroid Build Coastguard Worker pos = atoi(attr->value) - 1;
902*5e7646d2SAndroid Build Coastguard Worker
903*5e7646d2SAndroid Build Coastguard Worker if (pos < 0 || pos > 4)
904*5e7646d2SAndroid Build Coastguard Worker pos = 0;
905*5e7646d2SAndroid Build Coastguard Worker }
906*5e7646d2SAndroid Build Coastguard Worker else
907*5e7646d2SAndroid Build Coastguard Worker pos = 0;
908*5e7646d2SAndroid Build Coastguard Worker
909*5e7646d2SAndroid Build Coastguard Worker values[pos] = size->width;
910*5e7646d2SAndroid Build Coastguard Worker
911*5e7646d2SAndroid Build Coastguard Worker if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Height")) != NULL)
912*5e7646d2SAndroid Build Coastguard Worker {
913*5e7646d2SAndroid Build Coastguard Worker pos = atoi(attr->value) - 1;
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker if (pos < 0 || pos > 4)
916*5e7646d2SAndroid Build Coastguard Worker pos = 1;
917*5e7646d2SAndroid Build Coastguard Worker }
918*5e7646d2SAndroid Build Coastguard Worker else
919*5e7646d2SAndroid Build Coastguard Worker pos = 1;
920*5e7646d2SAndroid Build Coastguard Worker
921*5e7646d2SAndroid Build Coastguard Worker values[pos] = size->length;
922*5e7646d2SAndroid Build Coastguard Worker
923*5e7646d2SAndroid Build Coastguard Worker /*
924*5e7646d2SAndroid Build Coastguard Worker * According to the Adobe PPD specification, an orientation of 1
925*5e7646d2SAndroid Build Coastguard Worker * will produce a print that comes out upside-down with the X
926*5e7646d2SAndroid Build Coastguard Worker * axis perpendicular to the direction of feed, which is exactly
927*5e7646d2SAndroid Build Coastguard Worker * what we want to be consistent with non-PS printers.
928*5e7646d2SAndroid Build Coastguard Worker *
929*5e7646d2SAndroid Build Coastguard Worker * We could also use an orientation of 3 to produce output that
930*5e7646d2SAndroid Build Coastguard Worker * comes out rightside-up (this is the default for many large format
931*5e7646d2SAndroid Build Coastguard Worker * printer PPDs), however for consistency we will stick with the
932*5e7646d2SAndroid Build Coastguard Worker * value 1.
933*5e7646d2SAndroid Build Coastguard Worker *
934*5e7646d2SAndroid Build Coastguard Worker * If we wanted to get fancy, we could use orientations of 0 or
935*5e7646d2SAndroid Build Coastguard Worker * 2 and swap the width and length, however we don't want to get
936*5e7646d2SAndroid Build Coastguard Worker * fancy, we just want it to work consistently.
937*5e7646d2SAndroid Build Coastguard Worker *
938*5e7646d2SAndroid Build Coastguard Worker * The orientation value is range limited by the Orientation
939*5e7646d2SAndroid Build Coastguard Worker * parameter definition, so certain non-PS printer drivers that
940*5e7646d2SAndroid Build Coastguard Worker * only support an Orientation of 0 will get the value 0 as
941*5e7646d2SAndroid Build Coastguard Worker * expected.
942*5e7646d2SAndroid Build Coastguard Worker */
943*5e7646d2SAndroid Build Coastguard Worker
944*5e7646d2SAndroid Build Coastguard Worker orientation = 1;
945*5e7646d2SAndroid Build Coastguard Worker
946*5e7646d2SAndroid Build Coastguard Worker if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize",
947*5e7646d2SAndroid Build Coastguard Worker "Orientation")) != NULL)
948*5e7646d2SAndroid Build Coastguard Worker {
949*5e7646d2SAndroid Build Coastguard Worker int min_orient, max_orient; /* Minimum and maximum orientations */
950*5e7646d2SAndroid Build Coastguard Worker
951*5e7646d2SAndroid Build Coastguard Worker
952*5e7646d2SAndroid Build Coastguard Worker if (sscanf(attr->value, "%d%*s%d%d", &pos, &min_orient,
953*5e7646d2SAndroid Build Coastguard Worker &max_orient) != 3)
954*5e7646d2SAndroid Build Coastguard Worker pos = 4;
955*5e7646d2SAndroid Build Coastguard Worker else
956*5e7646d2SAndroid Build Coastguard Worker {
957*5e7646d2SAndroid Build Coastguard Worker pos --;
958*5e7646d2SAndroid Build Coastguard Worker
959*5e7646d2SAndroid Build Coastguard Worker if (pos < 0 || pos > 4)
960*5e7646d2SAndroid Build Coastguard Worker pos = 4;
961*5e7646d2SAndroid Build Coastguard Worker
962*5e7646d2SAndroid Build Coastguard Worker if (orientation > max_orient)
963*5e7646d2SAndroid Build Coastguard Worker orientation = max_orient;
964*5e7646d2SAndroid Build Coastguard Worker else if (orientation < min_orient)
965*5e7646d2SAndroid Build Coastguard Worker orientation = min_orient;
966*5e7646d2SAndroid Build Coastguard Worker }
967*5e7646d2SAndroid Build Coastguard Worker }
968*5e7646d2SAndroid Build Coastguard Worker else
969*5e7646d2SAndroid Build Coastguard Worker pos = 4;
970*5e7646d2SAndroid Build Coastguard Worker
971*5e7646d2SAndroid Build Coastguard Worker values[pos] = (float)orientation;
972*5e7646d2SAndroid Build Coastguard Worker
973*5e7646d2SAndroid Build Coastguard Worker for (pos = 0; pos < 5; pos ++)
974*5e7646d2SAndroid Build Coastguard Worker {
975*5e7646d2SAndroid Build Coastguard Worker bufptr = _cupsStrFormatd(bufptr, bufend, values[pos], loc);
976*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\n';
977*5e7646d2SAndroid Build Coastguard Worker }
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker if (!choices[i]->code)
980*5e7646d2SAndroid Build Coastguard Worker {
981*5e7646d2SAndroid Build Coastguard Worker /*
982*5e7646d2SAndroid Build Coastguard Worker * This can happen with certain buggy PPD files that don't include
983*5e7646d2SAndroid Build Coastguard Worker * a CustomPageSize command sequence... We just use a generic
984*5e7646d2SAndroid Build Coastguard Worker * Level 2 command sequence...
985*5e7646d2SAndroid Build Coastguard Worker */
986*5e7646d2SAndroid Build Coastguard Worker
987*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, ppd_custom_code, (size_t)(bufend - bufptr + 1));
988*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
989*5e7646d2SAndroid Build Coastguard Worker }
990*5e7646d2SAndroid Build Coastguard Worker }
991*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(choices[i]->choice, "Custom") &&
992*5e7646d2SAndroid Build Coastguard Worker (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword))
993*5e7646d2SAndroid Build Coastguard Worker != NULL)
994*5e7646d2SAndroid Build Coastguard Worker {
995*5e7646d2SAndroid Build Coastguard Worker /*
996*5e7646d2SAndroid Build Coastguard Worker * Custom option...
997*5e7646d2SAndroid Build Coastguard Worker */
998*5e7646d2SAndroid Build Coastguard Worker
999*5e7646d2SAndroid Build Coastguard Worker const char *s; /* Pointer into string value */
1000*5e7646d2SAndroid Build Coastguard Worker cups_array_t *params; /* Parameters in the correct output order */
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker
1003*5e7646d2SAndroid Build Coastguard Worker params = cupsArrayNew((cups_array_func_t)ppd_compare_cparams, NULL);
1004*5e7646d2SAndroid Build Coastguard Worker
1005*5e7646d2SAndroid Build Coastguard Worker for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
1006*5e7646d2SAndroid Build Coastguard Worker cparam;
1007*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
1008*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(params, cparam);
1009*5e7646d2SAndroid Build Coastguard Worker
1010*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%%%%BeginFeature: *Custom%s True\n", coption->keyword);
1011*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1012*5e7646d2SAndroid Build Coastguard Worker
1013*5e7646d2SAndroid Build Coastguard Worker for (cparam = (ppd_cparam_t *)cupsArrayFirst(params);
1014*5e7646d2SAndroid Build Coastguard Worker cparam;
1015*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(params))
1016*5e7646d2SAndroid Build Coastguard Worker {
1017*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
1018*5e7646d2SAndroid Build Coastguard Worker {
1019*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
1020*5e7646d2SAndroid Build Coastguard Worker break;
1021*5e7646d2SAndroid Build Coastguard Worker
1022*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
1023*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
1024*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
1025*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
1026*5e7646d2SAndroid Build Coastguard Worker bufptr = _cupsStrFormatd(bufptr, bufend,
1027*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_real, loc);
1028*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\n';
1029*5e7646d2SAndroid Build Coastguard Worker break;
1030*5e7646d2SAndroid Build Coastguard Worker
1031*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
1032*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%d\n", cparam->current.custom_int);
1033*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1034*5e7646d2SAndroid Build Coastguard Worker break;
1035*5e7646d2SAndroid Build Coastguard Worker
1036*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
1037*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
1038*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
1039*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '(';
1040*5e7646d2SAndroid Build Coastguard Worker
1041*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
1042*5e7646d2SAndroid Build Coastguard Worker {
1043*5e7646d2SAndroid Build Coastguard Worker for (s = cparam->current.custom_string; *s; s ++)
1044*5e7646d2SAndroid Build Coastguard Worker {
1045*5e7646d2SAndroid Build Coastguard Worker if (*s < ' ' || *s == '(' || *s == ')' || *s >= 127)
1046*5e7646d2SAndroid Build Coastguard Worker {
1047*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr + 1), "\\%03o", *s & 255);
1048*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1049*5e7646d2SAndroid Build Coastguard Worker }
1050*5e7646d2SAndroid Build Coastguard Worker else
1051*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *s;
1052*5e7646d2SAndroid Build Coastguard Worker }
1053*5e7646d2SAndroid Build Coastguard Worker }
1054*5e7646d2SAndroid Build Coastguard Worker
1055*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = ')';
1056*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\n';
1057*5e7646d2SAndroid Build Coastguard Worker break;
1058*5e7646d2SAndroid Build Coastguard Worker }
1059*5e7646d2SAndroid Build Coastguard Worker }
1060*5e7646d2SAndroid Build Coastguard Worker
1061*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(params);
1062*5e7646d2SAndroid Build Coastguard Worker }
1063*5e7646d2SAndroid Build Coastguard Worker else
1064*5e7646d2SAndroid Build Coastguard Worker {
1065*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%%%%BeginFeature: *%s %s\n", choices[i]->option->keyword, choices[i]->choice);
1066*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1067*5e7646d2SAndroid Build Coastguard Worker }
1068*5e7646d2SAndroid Build Coastguard Worker
1069*5e7646d2SAndroid Build Coastguard Worker if (choices[i]->code && choices[i]->code[0])
1070*5e7646d2SAndroid Build Coastguard Worker {
1071*5e7646d2SAndroid Build Coastguard Worker j = (int)strlen(choices[i]->code);
1072*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, choices[i]->code, (size_t)j);
1073*5e7646d2SAndroid Build Coastguard Worker bufptr += j;
1074*5e7646d2SAndroid Build Coastguard Worker
1075*5e7646d2SAndroid Build Coastguard Worker if (choices[i]->code[j - 1] != '\n')
1076*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\n';
1077*5e7646d2SAndroid Build Coastguard Worker }
1078*5e7646d2SAndroid Build Coastguard Worker
1079*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, "%%EndFeature\n"
1080*5e7646d2SAndroid Build Coastguard Worker "} stopped cleartomark\n", (size_t)(bufend - bufptr + 1));
1081*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1082*5e7646d2SAndroid Build Coastguard Worker
1083*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdEmitString: Offset in string is %d...",
1084*5e7646d2SAndroid Build Coastguard Worker (int)(bufptr - buffer)));
1085*5e7646d2SAndroid Build Coastguard Worker }
1086*5e7646d2SAndroid Build Coastguard Worker else if (choices[i]->code)
1087*5e7646d2SAndroid Build Coastguard Worker {
1088*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, choices[i]->code, (size_t)(bufend - bufptr + 1));
1089*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
1090*5e7646d2SAndroid Build Coastguard Worker }
1091*5e7646d2SAndroid Build Coastguard Worker
1092*5e7646d2SAndroid Build Coastguard Worker /*
1093*5e7646d2SAndroid Build Coastguard Worker * Nul-terminate, free, and return...
1094*5e7646d2SAndroid Build Coastguard Worker */
1095*5e7646d2SAndroid Build Coastguard Worker
1096*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
1097*5e7646d2SAndroid Build Coastguard Worker
1098*5e7646d2SAndroid Build Coastguard Worker free(choices);
1099*5e7646d2SAndroid Build Coastguard Worker
1100*5e7646d2SAndroid Build Coastguard Worker return (buffer);
1101*5e7646d2SAndroid Build Coastguard Worker }
1102*5e7646d2SAndroid Build Coastguard Worker
1103*5e7646d2SAndroid Build Coastguard Worker
1104*5e7646d2SAndroid Build Coastguard Worker /*
1105*5e7646d2SAndroid Build Coastguard Worker * 'ppd_compare_cparams()' - Compare the order of two custom parameters.
1106*5e7646d2SAndroid Build Coastguard Worker */
1107*5e7646d2SAndroid Build Coastguard Worker
1108*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
ppd_compare_cparams(ppd_cparam_t * a,ppd_cparam_t * b)1109*5e7646d2SAndroid Build Coastguard Worker ppd_compare_cparams(ppd_cparam_t *a, /* I - First parameter */
1110*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *b) /* I - Second parameter */
1111*5e7646d2SAndroid Build Coastguard Worker {
1112*5e7646d2SAndroid Build Coastguard Worker return (a->order - b->order);
1113*5e7646d2SAndroid Build Coastguard Worker }
1114*5e7646d2SAndroid Build Coastguard Worker
1115*5e7646d2SAndroid Build Coastguard Worker
1116*5e7646d2SAndroid Build Coastguard Worker /*
1117*5e7646d2SAndroid Build Coastguard Worker * 'ppd_handle_media()' - Handle media selection...
1118*5e7646d2SAndroid Build Coastguard Worker */
1119*5e7646d2SAndroid Build Coastguard Worker
1120*5e7646d2SAndroid Build Coastguard Worker static void
ppd_handle_media(ppd_file_t * ppd)1121*5e7646d2SAndroid Build Coastguard Worker ppd_handle_media(ppd_file_t *ppd) /* I - PPD file */
1122*5e7646d2SAndroid Build Coastguard Worker {
1123*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *manual_feed, /* ManualFeed choice, if any */
1124*5e7646d2SAndroid Build Coastguard Worker *input_slot; /* InputSlot choice, if any */
1125*5e7646d2SAndroid Build Coastguard Worker ppd_size_t *size; /* Current media size */
1126*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *rpr; /* RequiresPageRegion value */
1127*5e7646d2SAndroid Build Coastguard Worker
1128*5e7646d2SAndroid Build Coastguard Worker
1129*5e7646d2SAndroid Build Coastguard Worker /*
1130*5e7646d2SAndroid Build Coastguard Worker * This function determines what page size code to use, if any, for the
1131*5e7646d2SAndroid Build Coastguard Worker * current media size, InputSlot, and ManualFeed selections.
1132*5e7646d2SAndroid Build Coastguard Worker *
1133*5e7646d2SAndroid Build Coastguard Worker * We use the PageSize code if:
1134*5e7646d2SAndroid Build Coastguard Worker *
1135*5e7646d2SAndroid Build Coastguard Worker * 1. A custom media size is selected.
1136*5e7646d2SAndroid Build Coastguard Worker * 2. ManualFeed and InputSlot are not selected (or do not exist).
1137*5e7646d2SAndroid Build Coastguard Worker * 3. ManualFeed is selected but is False and InputSlot is not selected or
1138*5e7646d2SAndroid Build Coastguard Worker * the selection has no code - the latter check done to support "auto" or
1139*5e7646d2SAndroid Build Coastguard Worker * "printer default" InputSlot options.
1140*5e7646d2SAndroid Build Coastguard Worker *
1141*5e7646d2SAndroid Build Coastguard Worker * We use the PageRegion code if:
1142*5e7646d2SAndroid Build Coastguard Worker *
1143*5e7646d2SAndroid Build Coastguard Worker * 4. RequiresPageRegion does not exist and the PPD contains cupsFilter
1144*5e7646d2SAndroid Build Coastguard Worker * keywords, indicating this is a CUPS-based driver.
1145*5e7646d2SAndroid Build Coastguard Worker * 5. RequiresPageRegion exists for the selected InputSlot (or "All" for any
1146*5e7646d2SAndroid Build Coastguard Worker * InputSlot or ManualFeed selection) and is True.
1147*5e7646d2SAndroid Build Coastguard Worker *
1148*5e7646d2SAndroid Build Coastguard Worker * If none of the 5 conditions are true, no page size code is used and we
1149*5e7646d2SAndroid Build Coastguard Worker * unmark any existing PageSize or PageRegion choices.
1150*5e7646d2SAndroid Build Coastguard Worker */
1151*5e7646d2SAndroid Build Coastguard Worker
1152*5e7646d2SAndroid Build Coastguard Worker if ((size = ppdPageSize(ppd, NULL)) == NULL)
1153*5e7646d2SAndroid Build Coastguard Worker return;
1154*5e7646d2SAndroid Build Coastguard Worker
1155*5e7646d2SAndroid Build Coastguard Worker manual_feed = ppdFindMarkedChoice(ppd, "ManualFeed");
1156*5e7646d2SAndroid Build Coastguard Worker input_slot = ppdFindMarkedChoice(ppd, "InputSlot");
1157*5e7646d2SAndroid Build Coastguard Worker
1158*5e7646d2SAndroid Build Coastguard Worker if (input_slot != NULL)
1159*5e7646d2SAndroid Build Coastguard Worker rpr = ppdFindAttr(ppd, "RequiresPageRegion", input_slot->choice);
1160*5e7646d2SAndroid Build Coastguard Worker else
1161*5e7646d2SAndroid Build Coastguard Worker rpr = NULL;
1162*5e7646d2SAndroid Build Coastguard Worker
1163*5e7646d2SAndroid Build Coastguard Worker if (!rpr)
1164*5e7646d2SAndroid Build Coastguard Worker rpr = ppdFindAttr(ppd, "RequiresPageRegion", "All");
1165*5e7646d2SAndroid Build Coastguard Worker
1166*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(size->name, "Custom") ||
1167*5e7646d2SAndroid Build Coastguard Worker (!manual_feed && !input_slot) ||
1168*5e7646d2SAndroid Build Coastguard Worker (manual_feed && !_cups_strcasecmp(manual_feed->choice, "False") &&
1169*5e7646d2SAndroid Build Coastguard Worker (!input_slot || (input_slot->code && !input_slot->code[0]))) ||
1170*5e7646d2SAndroid Build Coastguard Worker (!rpr && ppd->num_filters > 0))
1171*5e7646d2SAndroid Build Coastguard Worker {
1172*5e7646d2SAndroid Build Coastguard Worker /*
1173*5e7646d2SAndroid Build Coastguard Worker * Use PageSize code...
1174*5e7646d2SAndroid Build Coastguard Worker */
1175*5e7646d2SAndroid Build Coastguard Worker
1176*5e7646d2SAndroid Build Coastguard Worker ppdMarkOption(ppd, "PageSize", size->name);
1177*5e7646d2SAndroid Build Coastguard Worker }
1178*5e7646d2SAndroid Build Coastguard Worker else if (rpr && rpr->value && !_cups_strcasecmp(rpr->value, "True"))
1179*5e7646d2SAndroid Build Coastguard Worker {
1180*5e7646d2SAndroid Build Coastguard Worker /*
1181*5e7646d2SAndroid Build Coastguard Worker * Use PageRegion code...
1182*5e7646d2SAndroid Build Coastguard Worker */
1183*5e7646d2SAndroid Build Coastguard Worker
1184*5e7646d2SAndroid Build Coastguard Worker ppdMarkOption(ppd, "PageRegion", size->name);
1185*5e7646d2SAndroid Build Coastguard Worker }
1186*5e7646d2SAndroid Build Coastguard Worker else
1187*5e7646d2SAndroid Build Coastguard Worker {
1188*5e7646d2SAndroid Build Coastguard Worker /*
1189*5e7646d2SAndroid Build Coastguard Worker * Do not use PageSize or PageRegion code...
1190*5e7646d2SAndroid Build Coastguard Worker */
1191*5e7646d2SAndroid Build Coastguard Worker
1192*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *page; /* PageSize/Region choice, if any */
1193*5e7646d2SAndroid Build Coastguard Worker
1194*5e7646d2SAndroid Build Coastguard Worker if ((page = ppdFindMarkedChoice(ppd, "PageSize")) != NULL)
1195*5e7646d2SAndroid Build Coastguard Worker {
1196*5e7646d2SAndroid Build Coastguard Worker /*
1197*5e7646d2SAndroid Build Coastguard Worker * Unmark PageSize...
1198*5e7646d2SAndroid Build Coastguard Worker */
1199*5e7646d2SAndroid Build Coastguard Worker
1200*5e7646d2SAndroid Build Coastguard Worker page->marked = 0;
1201*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, page);
1202*5e7646d2SAndroid Build Coastguard Worker }
1203*5e7646d2SAndroid Build Coastguard Worker
1204*5e7646d2SAndroid Build Coastguard Worker if ((page = ppdFindMarkedChoice(ppd, "PageRegion")) != NULL)
1205*5e7646d2SAndroid Build Coastguard Worker {
1206*5e7646d2SAndroid Build Coastguard Worker /*
1207*5e7646d2SAndroid Build Coastguard Worker * Unmark PageRegion...
1208*5e7646d2SAndroid Build Coastguard Worker */
1209*5e7646d2SAndroid Build Coastguard Worker
1210*5e7646d2SAndroid Build Coastguard Worker page->marked = 0;
1211*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(ppd->marked, page);
1212*5e7646d2SAndroid Build Coastguard Worker }
1213*5e7646d2SAndroid Build Coastguard Worker }
1214*5e7646d2SAndroid Build Coastguard Worker }
1215