]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
2 | * "$Id: mark.c 4494 2005-02-18 02:18:11Z mike $" | |
3 | * | |
4 | * Option marking routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 1997-2005 by Easy Software Products, all rights reserved. | |
7 | * | |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE.txt" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636 USA | |
19 | * | |
20 | * Voice: (301) 373-9600 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * PostScript is a trademark of Adobe Systems, Inc. | |
25 | * | |
26 | * This file is subject to the Apple OS-Developed Software exception. | |
27 | * | |
28 | * Contents: | |
29 | * | |
30 | * ppdConflicts() - Check to see if there are any conflicts. | |
31 | * ppdFindChoice() - Return a pointer to an option choice. | |
32 | * ppdFindMarkedChoice() - Return the marked choice for the specified option. | |
33 | * ppdFindOption() - Return a pointer to the specified option. | |
34 | * ppdIsMarked() - Check to see if an option is marked... | |
35 | * ppdMarkDefaults() - Mark all default options in the PPD file. | |
36 | * ppdMarkOption() - Mark an option in a PPD file. | |
37 | * ppd_defaults() - Set the defaults for this group and all sub-groups. | |
38 | */ | |
39 | ||
40 | /* | |
41 | * Include necessary headers... | |
42 | */ | |
43 | ||
44 | #include "ppd.h" | |
45 | #include "string.h" | |
46 | #include "debug.h" | |
47 | ||
48 | ||
49 | /* | |
50 | * Local functions... | |
51 | */ | |
52 | ||
53 | static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g); | |
54 | ||
55 | ||
56 | /* | |
57 | * 'ppdConflicts()' - Check to see if there are any conflicts. | |
58 | */ | |
59 | ||
60 | int /* O - Number of conflicts found */ | |
61 | ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ | |
62 | { | |
63 | int i, j, k, /* Looping variables */ | |
64 | conflicts; /* Number of conflicts */ | |
65 | ppd_const_t *c; /* Current constraint */ | |
66 | ppd_group_t *g, *sg; /* Groups */ | |
67 | ppd_option_t *o1, *o2; /* Options */ | |
68 | ppd_choice_t *c1, *c2; /* Choices */ | |
69 | ||
70 | ||
71 | if (ppd == NULL) | |
72 | return (0); | |
73 | ||
74 | /* | |
75 | * Clear all conflicts... | |
76 | */ | |
77 | ||
78 | conflicts = 0; | |
79 | ||
80 | for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) | |
81 | { | |
82 | for (j = g->num_options, o1 = g->options; j > 0; j --, o1 ++) | |
83 | o1->conflicted = 0; | |
84 | ||
85 | for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++) | |
86 | for (k = sg->num_options, o1 = sg->options; k > 0; k --, o1 ++) | |
87 | o1->conflicted = 0; | |
88 | } | |
89 | ||
90 | /* | |
91 | * Loop through all of the UI constraints and flag any options | |
92 | * that conflict... | |
93 | */ | |
94 | ||
95 | for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) | |
96 | { | |
97 | /* | |
98 | * Grab pointers to the first option... | |
99 | */ | |
100 | ||
101 | o1 = ppdFindOption(ppd, c->option1); | |
102 | ||
103 | if (o1 == NULL) | |
104 | continue; | |
105 | else if (c->choice1[0] != '\0') | |
106 | { | |
107 | /* | |
108 | * This constraint maps to a specific choice. | |
109 | */ | |
110 | ||
111 | c1 = ppdFindChoice(o1, c->choice1); | |
112 | } | |
113 | else | |
114 | { | |
115 | /* | |
116 | * This constraint applies to any choice for this option. | |
117 | */ | |
118 | ||
119 | for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++) | |
120 | if (c1->marked) | |
121 | break; | |
122 | ||
123 | if (j == 0 || | |
124 | strcasecmp(c1->choice, "None") == 0 || | |
125 | strcasecmp(c1->choice, "Off") == 0 || | |
126 | strcasecmp(c1->choice, "False") == 0) | |
127 | c1 = NULL; | |
128 | } | |
129 | ||
130 | /* | |
131 | * Grab pointers to the second option... | |
132 | */ | |
133 | ||
134 | o2 = ppdFindOption(ppd, c->option2); | |
135 | ||
136 | if (o2 == NULL) | |
137 | continue; | |
138 | else if (c->choice2[0] != '\0') | |
139 | { | |
140 | /* | |
141 | * This constraint maps to a specific choice. | |
142 | */ | |
143 | ||
144 | c2 = ppdFindChoice(o2, c->choice2); | |
145 | } | |
146 | else | |
147 | { | |
148 | /* | |
149 | * This constraint applies to any choice for this option. | |
150 | */ | |
151 | ||
152 | for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++) | |
153 | if (c2->marked) | |
154 | break; | |
155 | ||
156 | if (j == 0 || | |
157 | strcasecmp(c2->choice, "None") == 0 || | |
158 | strcasecmp(c2->choice, "Off") == 0 || | |
159 | strcasecmp(c2->choice, "False") == 0) | |
160 | c2 = NULL; | |
161 | } | |
162 | ||
163 | /* | |
164 | * If both options are marked then there is a conflict... | |
165 | */ | |
166 | ||
167 | if (c1 != NULL && c1->marked && | |
168 | c2 != NULL && c2->marked) | |
169 | { | |
170 | DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n", | |
171 | o1->keyword, c1->choice, o2->keyword, c2->choice, | |
172 | c->option1, c->choice1, c->option2, c->choice2)); | |
173 | conflicts ++; | |
174 | o1->conflicted = 1; | |
175 | o2->conflicted = 1; | |
176 | } | |
177 | } | |
178 | ||
179 | /* | |
180 | * Return the number of conflicts found... | |
181 | */ | |
182 | ||
183 | return (conflicts); | |
184 | } | |
185 | ||
186 | ||
187 | /* | |
188 | * 'ppdFindChoice()' - Return a pointer to an option choice. | |
189 | */ | |
190 | ||
191 | ppd_choice_t * /* O - Choice pointer or NULL */ | |
192 | ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */ | |
193 | const char *choice) /* I - Name of choice */ | |
194 | { | |
195 | int i; /* Looping var */ | |
196 | ppd_choice_t *c; /* Current choice */ | |
197 | ||
198 | ||
199 | if (o == NULL || choice == NULL) | |
200 | return (NULL); | |
201 | ||
202 | for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) | |
203 | if (strcasecmp(c->choice, choice) == 0) | |
204 | return (c); | |
205 | ||
206 | return (NULL); | |
207 | } | |
208 | ||
209 | ||
210 | /* | |
211 | * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option. | |
212 | */ | |
213 | ||
214 | ppd_choice_t * /* O - Pointer to choice or NULL */ | |
215 | ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */ | |
216 | const char *option) /* I - Keyword/option name */ | |
217 | { | |
218 | int i; /* Looping var */ | |
219 | ppd_option_t *o; /* Pointer to option */ | |
220 | ppd_choice_t *c; /* Pointer to choice */ | |
221 | ||
222 | ||
223 | if ((o = ppdFindOption(ppd, option)) == NULL) | |
224 | return (NULL); | |
225 | ||
226 | for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) | |
227 | if (c->marked) | |
228 | return (c); | |
229 | ||
230 | return (NULL); | |
231 | } | |
232 | ||
233 | ||
234 | /* | |
235 | * 'ppdFindOption()' - Return a pointer to the specified option. | |
236 | */ | |
237 | ||
238 | ppd_option_t * /* O - Pointer to option or NULL */ | |
239 | ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */ | |
240 | const char *option) /* I - Option/Keyword name */ | |
241 | { | |
242 | int i, j, k; /* Looping vars */ | |
243 | ppd_option_t *o; /* Pointer to option */ | |
244 | ppd_group_t *g, /* Pointer to group */ | |
245 | *sg; /* Pointer to subgroup */ | |
246 | ||
247 | ||
248 | if (ppd == NULL || option == NULL) | |
249 | return (NULL); | |
250 | ||
251 | for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) | |
252 | { | |
253 | for (j = g->num_options, o = g->options; j > 0; j --, o ++) | |
254 | if (strcasecmp(o->keyword, option) == 0) | |
255 | return (o); | |
256 | ||
257 | for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++) | |
258 | for (k = sg->num_options, o = sg->options; k > 0; k --, o ++) | |
259 | if (strcasecmp(o->keyword, option) == 0) | |
260 | return (o); | |
261 | } | |
262 | ||
263 | return (NULL); | |
264 | } | |
265 | ||
266 | ||
267 | /* | |
268 | * 'ppdIsMarked()' - Check to see if an option is marked... | |
269 | */ | |
270 | ||
271 | int /* O - Non-zero if option is marked */ | |
272 | ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ | |
273 | const char *option, /* I - Option/Keyword name */ | |
274 | const char *choice) /* I - Choice name */ | |
275 | { | |
276 | ppd_option_t *o; /* Option pointer */ | |
277 | ppd_choice_t *c; /* Choice pointer */ | |
278 | ||
279 | ||
280 | if (ppd == NULL) | |
281 | return (0); | |
282 | ||
283 | if ((o = ppdFindOption(ppd, option)) == NULL) | |
284 | return (0); | |
285 | ||
286 | if ((c = ppdFindChoice(o, choice)) == NULL) | |
287 | return (0); | |
288 | ||
289 | return (c->marked); | |
290 | } | |
291 | ||
292 | ||
293 | /* | |
294 | * 'ppdMarkDefaults()' - Mark all default options in the PPD file. | |
295 | */ | |
296 | ||
297 | void | |
298 | ppdMarkDefaults(ppd_file_t *ppd)/* I - PPD file record */ | |
299 | { | |
300 | int i; /* Looping variables */ | |
301 | ppd_group_t *g; /* Current group */ | |
302 | ||
303 | ||
304 | if (ppd == NULL) | |
305 | return; | |
306 | ||
307 | for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) | |
308 | ppd_defaults(ppd, g); | |
309 | } | |
310 | ||
311 | ||
312 | /* | |
313 | * 'ppdMarkOption()' - Mark an option in a PPD file. | |
314 | * | |
315 | * Notes: | |
316 | * | |
317 | * -1 is returned if the given option would conflict with any currently | |
318 | * selected option. | |
319 | */ | |
320 | ||
321 | int /* O - Number of conflicts */ | |
322 | ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ | |
323 | const char *option, /* I - Keyword */ | |
324 | const char *choice) /* I - Option name */ | |
325 | { | |
326 | int i; /* Looping var */ | |
327 | ppd_option_t *o; /* Option pointer */ | |
328 | ppd_choice_t *c; /* Choice pointer */ | |
329 | ||
330 | ||
331 | if (ppd == NULL) | |
332 | return (0); | |
333 | ||
334 | if (strcasecmp(option, "PageSize") == 0 && strncasecmp(choice, "Custom.", 7) == 0) | |
335 | { | |
336 | /* | |
337 | * Handle variable page sizes... | |
338 | */ | |
339 | ||
340 | ppdPageSize(ppd, choice); | |
341 | choice = "Custom"; | |
342 | } | |
343 | ||
344 | if ((o = ppdFindOption(ppd, option)) == NULL) | |
345 | return (0); | |
346 | ||
347 | for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) | |
348 | if (strcasecmp(c->choice, choice) == 0) | |
349 | break; | |
350 | ||
351 | if (i) | |
352 | { | |
353 | /* | |
354 | * Option found; mark it and then handle unmarking any other options. | |
355 | */ | |
356 | ||
357 | c->marked = 1; | |
358 | ||
359 | if (o->ui != PPD_UI_PICKMANY) | |
360 | for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) | |
361 | if (strcasecmp(c->choice, choice) != 0) | |
362 | c->marked = 0; | |
363 | ||
364 | if (strcasecmp(option, "PageSize") == 0 || strcasecmp(option, "PageRegion") == 0) | |
365 | { | |
366 | /* | |
367 | * Mark current page size... | |
368 | */ | |
369 | ||
370 | for (i = 0; i < ppd->num_sizes; i ++) | |
371 | ppd->sizes[i].marked = strcasecmp(ppd->sizes[i].name, choice) == 0; | |
372 | ||
373 | /* | |
374 | * Unmark the current PageSize or PageRegion setting, as appropriate... | |
375 | */ | |
376 | ||
377 | if (strcasecmp(option, "PageSize") == 0) | |
378 | { | |
379 | if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) | |
380 | for (i = 0; i < o->num_choices; i ++) | |
381 | o->choices[i].marked = 0; | |
382 | } | |
383 | else | |
384 | { | |
385 | if ((o = ppdFindOption(ppd, "PageSize")) != NULL) | |
386 | for (i = 0; i < o->num_choices; i ++) | |
387 | o->choices[i].marked = 0; | |
388 | } | |
389 | } | |
390 | else if (strcasecmp(option, "InputSlot") == 0) | |
391 | { | |
392 | /* | |
393 | * Unmark ManualFeed option... | |
394 | */ | |
395 | ||
396 | if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) | |
397 | for (i = 0; i < o->num_choices; i ++) | |
398 | o->choices[i].marked = 0; | |
399 | } | |
400 | else if (strcasecmp(option, "ManualFeed") == 0) | |
401 | { | |
402 | /* | |
403 | * Unmark InputSlot option... | |
404 | */ | |
405 | ||
406 | if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) | |
407 | for (i = 0; i < o->num_choices; i ++) | |
408 | o->choices[i].marked = 0; | |
409 | } | |
410 | } | |
411 | ||
412 | return (ppdConflicts(ppd)); | |
413 | } | |
414 | ||
415 | ||
416 | /* | |
417 | * 'ppd_defaults()' - Set the defaults for this group and all sub-groups. | |
418 | */ | |
419 | ||
420 | static void | |
421 | ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ | |
422 | ppd_group_t *g) /* I - Group to default */ | |
423 | { | |
424 | int i; /* Looping var */ | |
425 | ppd_option_t *o; /* Current option */ | |
426 | ppd_group_t *sg; /* Current sub-group */ | |
427 | ||
428 | ||
429 | if (g == NULL) | |
430 | return; | |
431 | ||
432 | for (i = g->num_options, o = g->options; i > 0; i --, o ++) | |
433 | if (strcasecmp(o->keyword, "PageRegion") != 0) | |
434 | ppdMarkOption(ppd, o->keyword, o->defchoice); | |
435 | ||
436 | for (i = g->num_subgroups, sg = g->subgroups; i > 0; i --, sg ++) | |
437 | ppd_defaults(ppd, sg); | |
438 | } | |
439 | ||
440 | ||
441 | /* | |
442 | * End of "$Id: mark.c 4494 2005-02-18 02:18:11Z mike $". | |
443 | */ |