]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/mark.c
2 * "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $"
4 * Option marking routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * PostScript is a trademark of Adobe Systems, Inc.
17 * This file is subject to the Apple OS-Developed Software exception.
21 * ppdConflicts() - Check to see if there are any conflicts.
22 * ppdFindChoice() - Return a pointer to an option choice.
23 * ppdFindMarkedChoice() - Return the marked choice for the specified option.
24 * ppdFindOption() - Return a pointer to the specified option.
25 * ppdFirstOption() - Return the first option in the PPD file.
26 * ppdNextOption() - Return the next option in the PPD file.
27 * ppdIsMarked() - Check to see if an option is marked...
28 * ppdMarkDefaults() - Mark all default options in the PPD file.
29 * ppdMarkOption() - Mark an option in a PPD file.
30 * ppd_defaults() - Set the defaults for this group and all sub-groups.
34 * Include necessary headers...
46 static void ppd_defaults(ppd_file_t
*ppd
, ppd_group_t
*g
);
50 * 'ppdConflicts()' - Check to see if there are any conflicts.
53 int /* O - Number of conflicts found */
54 ppdConflicts(ppd_file_t
*ppd
) /* I - PPD to check */
56 int i
, /* Looping variable */
57 conflicts
; /* Number of conflicts */
58 ppd_const_t
*c
; /* Current constraint */
59 ppd_option_t
*o1
, *o2
; /* Options */
60 ppd_choice_t
*c1
, *c2
; /* Choices */
61 ppd_choice_t key
; /* Search key */
68 * Clear all conflicts...
73 for (o1
= ppdFirstOption(ppd
); o1
; o1
= ppdNextOption(ppd
))
76 cupsArraySave(ppd
->marked
);
79 * Loop through all of the UI constraints and flag any options
83 for (i
= ppd
->num_consts
, c
= ppd
->consts
, o1
= o2
= NULL
, c1
= c2
= NULL
;
88 * Grab pointers to the first option...
91 if (!o1
|| strcmp(c
->option1
, o1
->keyword
))
93 o1
= ppdFindOption(ppd
, c
->option1
);
99 else if (c
->choice1
[0] && (!c1
|| strcmp(c
->choice1
, c1
->choice
)))
102 * This constraint maps to a specific choice.
107 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
108 (!c1
->marked
|| strcmp(c
->choice1
, c1
->choice
)))
114 * This constraint applies to any choice for this option.
119 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
120 (!strcasecmp(c1
->choice
, "None") || !strcasecmp(c1
->choice
, "Off") ||
121 !strcasecmp(c1
->choice
, "False")))
126 * Grab pointers to the second option...
129 if (!o2
|| strcmp(c
->option2
, o2
->keyword
))
131 o2
= ppdFindOption(ppd
, c
->option2
);
137 else if (c
->choice2
[0] && (!c2
|| strcmp(c
->choice2
, c2
->choice
)))
140 * This constraint maps to a specific choice.
145 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
146 (!c2
->marked
|| strcmp(c
->choice2
, c2
->choice
)))
152 * This constraint applies to any choice for this option.
157 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
158 (!strcasecmp(c2
->choice
, "None") || !strcasecmp(c2
->choice
, "Off") ||
159 !strcasecmp(c2
->choice
, "False")))
164 * If both options are marked then there is a conflict...
167 if (c1
&& c1
->marked
&& c2
&& c2
->marked
)
169 DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
170 o1
->keyword
, c1
->choice
, o2
->keyword
, c2
->choice
,
171 c
->option1
, c
->choice1
, c
->option2
, c
->choice2
));
178 cupsArrayRestore(ppd
->marked
);
181 * Return the number of conflicts found...
189 * 'ppdFindChoice()' - Return a pointer to an option choice.
192 ppd_choice_t
* /* O - Choice pointer or NULL */
193 ppdFindChoice(ppd_option_t
*o
, /* I - Pointer to option */
194 const char *choice
) /* I - Name of choice */
196 int i
; /* Looping var */
197 ppd_choice_t
*c
; /* Current choice */
200 if (o
== NULL
|| choice
== NULL
)
203 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
204 if (strcasecmp(c
->choice
, choice
) == 0)
212 * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
215 ppd_choice_t
* /* O - Pointer to choice or NULL */
216 ppdFindMarkedChoice(ppd_file_t
*ppd
, /* I - PPD file */
217 const char *option
) /* I - Keyword/option name */
219 ppd_choice_t key
; /* Search key for choice */
222 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
225 return ((ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
));
230 * 'ppdFindOption()' - Return a pointer to the specified option.
233 ppd_option_t
* /* O - Pointer to option or NULL */
234 ppdFindOption(ppd_file_t
*ppd
, /* I - PPD file data */
235 const char *option
) /* I - Option/Keyword name */
238 * Range check input...
247 * Search in the array...
250 ppd_option_t key
; /* Option search key */
253 strlcpy(key
.keyword
, option
, sizeof(key
.keyword
));
255 return ((ppd_option_t
*)cupsArrayFind(ppd
->options
, &key
));
260 * Search in each group...
263 int i
, j
; /* Looping vars */
264 ppd_group_t
*group
; /* Current group */
265 ppd_option_t
*optptr
; /* Current option */
268 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
269 for (j
= group
->num_options
, optptr
= group
->options
;
272 if (!strcasecmp(optptr
->keyword
, option
))
281 * 'ppdIsMarked()' - Check to see if an option is marked...
284 int /* O - Non-zero if option is marked */
285 ppdIsMarked(ppd_file_t
*ppd
, /* I - PPD file data */
286 const char *option
, /* I - Option/Keyword name */
287 const char *choice
) /* I - Choice name */
289 ppd_choice_t key
, /* Search key */
290 *c
; /* Choice pointer */
296 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
299 if ((c
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) == NULL
)
302 return (!strcmp(c
->choice
, choice
));
307 * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
311 ppdMarkDefaults(ppd_file_t
*ppd
) /* I - PPD file record */
313 int i
; /* Looping variables */
314 ppd_group_t
*g
; /* Current group */
315 ppd_choice_t
*c
; /* Current choice */
322 * Clean out the marked array...
325 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
327 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
328 cupsArrayRemove(ppd
->marked
, c
);
331 * Then repopulate it with the defaults...
334 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
335 ppd_defaults(ppd
, g
);
340 * 'ppdMarkOption()' - Mark an option in a PPD file.
344 * -1 is returned if the given option would conflict with any currently
348 int /* O - Number of conflicts */
349 ppdMarkOption(ppd_file_t
*ppd
, /* I - PPD file record */
350 const char *option
, /* I - Keyword */
351 const char *choice
) /* I - Option name */
353 int i
, j
; /* Looping vars */
354 ppd_option_t
*o
; /* Option pointer */
355 ppd_choice_t
*c
, /* Choice pointer */
356 *oldc
, /* Old choice pointer */
357 key
; /* Search key for choice */
358 struct lconv
*loc
; /* Locale data */
361 DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")\n",
362 ppd
, option
, choice
));
365 * Range check input...
368 if (!ppd
|| !option
|| !choice
)
372 * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
373 * it clears the regular InputSlot choices...
376 if (!strcasecmp(option
, "AP_D_InputSlot"))
378 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
381 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
384 cupsArrayRemove(ppd
->marked
, oldc
);
390 * Check for custom options...
393 if ((o
= ppdFindOption(ppd
, option
)) == NULL
)
398 if (!strncasecmp(choice
, "Custom.", 7))
401 * Handle a custom option...
404 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
407 if (!strcasecmp(option
, "PageSize"))
410 * Handle custom page sizes...
413 ppdPageSize(ppd
, choice
);
418 * Handle other custom options...
421 ppd_coption_t
*coption
; /* Custom option */
422 ppd_cparam_t
*cparam
; /* Custom parameter */
423 char *units
; /* Custom points units */
426 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
428 if ((cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
)) == NULL
)
431 switch (cparam
->type
)
433 case PPD_CUSTOM_CURVE
:
434 case PPD_CUSTOM_INVCURVE
:
435 case PPD_CUSTOM_REAL
:
436 cparam
->current
.custom_real
= (float)_cupsStrScand(choice
+ 7,
440 case PPD_CUSTOM_POINTS
:
441 cparam
->current
.custom_points
= (float)_cupsStrScand(choice
+ 7,
447 if (!strcasecmp(units
, "cm"))
448 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
449 else if (!strcasecmp(units
, "mm"))
450 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
451 else if (!strcasecmp(units
, "m"))
452 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
453 else if (!strcasecmp(units
, "in"))
454 cparam
->current
.custom_points
*= 72.0f
;
455 else if (!strcasecmp(units
, "ft"))
456 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
460 case PPD_CUSTOM_INT
:
461 cparam
->current
.custom_int
= atoi(choice
+ 7);
464 case PPD_CUSTOM_PASSCODE
:
465 case PPD_CUSTOM_PASSWORD
:
466 case PPD_CUSTOM_STRING
:
467 if (cparam
->current
.custom_string
)
468 _cupsStrFree(cparam
->current
.custom_string
);
470 cparam
->current
.custom_string
= _cupsStrAlloc(choice
+ 7);
477 * Make sure that we keep the option marked below...
482 else if (choice
[0] == '{')
485 * Handle multi-value custom options...
488 ppd_coption_t
*coption
; /* Custom option */
489 ppd_cparam_t
*cparam
; /* Custom parameter */
490 char *units
; /* Custom points units */
491 int num_vals
; /* Number of values */
492 cups_option_t
*vals
, /* Values */
496 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
499 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
501 num_vals
= cupsParseOptions(choice
+ 1, 0, &vals
);
503 for (i
= 0, val
= vals
; i
< num_vals
; i
++, val
++)
505 if ((cparam
= ppdFindCustomParam(coption
, val
->name
)) == NULL
)
508 switch (cparam
->type
)
510 case PPD_CUSTOM_CURVE
:
511 case PPD_CUSTOM_INVCURVE
:
512 case PPD_CUSTOM_REAL
:
513 cparam
->current
.custom_real
= (float)_cupsStrScand(val
->value
,
517 case PPD_CUSTOM_POINTS
:
518 cparam
->current
.custom_points
= (float)_cupsStrScand(val
->value
,
524 if (!strcasecmp(units
, "cm"))
525 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
526 else if (!strcasecmp(units
, "mm"))
527 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
528 else if (!strcasecmp(units
, "m"))
529 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
530 else if (!strcasecmp(units
, "in"))
531 cparam
->current
.custom_points
*= 72.0f
;
532 else if (!strcasecmp(units
, "ft"))
533 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
537 case PPD_CUSTOM_INT
:
538 cparam
->current
.custom_int
= atoi(val
->value
);
541 case PPD_CUSTOM_PASSCODE
:
542 case PPD_CUSTOM_PASSWORD
:
543 case PPD_CUSTOM_STRING
:
544 if (cparam
->current
.custom_string
)
545 _cupsStrFree(cparam
->current
.custom_string
);
547 cparam
->current
.custom_string
= _cupsStrAlloc(val
->value
);
552 cupsFreeOptions(num_vals
, vals
);
557 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
558 if (!strcasecmp(c
->choice
, choice
))
566 * Option found; mark it and then handle unmarking any other options.
569 if (o
->ui
!= PPD_UI_PICKMANY
)
572 * Unmark all other choices...
575 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, c
)) != NULL
)
578 cupsArrayRemove(ppd
->marked
, oldc
);
581 if (!strcasecmp(option
, "PageSize") || !strcasecmp(option
, "PageRegion"))
584 * Mark current page size...
587 for (j
= 0; j
< ppd
->num_sizes
; j
++)
588 ppd
->sizes
[j
].marked
= !strcasecmp(ppd
->sizes
[j
].name
,
592 * Unmark the current PageSize or PageRegion setting, as
596 if (!strcasecmp(option
, "PageSize"))
598 if ((o
= ppdFindOption(ppd
, "PageRegion")) != NULL
)
601 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
604 cupsArrayRemove(ppd
->marked
, oldc
);
610 if ((o
= ppdFindOption(ppd
, "PageSize")) != NULL
)
613 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
616 cupsArrayRemove(ppd
->marked
, oldc
);
621 else if (!strcasecmp(option
, "InputSlot"))
624 * Unmark ManualFeed option...
627 if ((o
= ppdFindOption(ppd
, "ManualFeed")) != NULL
)
630 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
633 cupsArrayRemove(ppd
->marked
, oldc
);
637 else if (!strcasecmp(option
, "ManualFeed") &&
638 !strcasecmp(choice
, "True"))
641 * Unmark InputSlot option...
644 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
647 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
650 cupsArrayRemove(ppd
->marked
, oldc
);
658 cupsArrayAdd(ppd
->marked
, c
);
661 * Return the number of conflicts...
664 return (ppdConflicts(ppd
));
669 * 'ppdFirstOption()' - Return the first option in the PPD file.
671 * Options are returned from all groups in sorted order.
676 ppd_option_t
* /* O - First option or NULL */
677 ppdFirstOption(ppd_file_t
*ppd
) /* I - PPD file */
682 return ((ppd_option_t
*)cupsArrayFirst(ppd
->options
));
687 * 'ppdNextOption()' - Return the next option in the PPD file.
689 * Options are returned from all groups in sorted order.
694 ppd_option_t
* /* O - Next option or NULL */
695 ppdNextOption(ppd_file_t
*ppd
) /* I - PPD file */
700 return ((ppd_option_t
*)cupsArrayNext(ppd
->options
));
705 * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
709 ppd_defaults(ppd_file_t
*ppd
, /* I - PPD file */
710 ppd_group_t
*g
) /* I - Group to default */
712 int i
; /* Looping var */
713 ppd_option_t
*o
; /* Current option */
714 ppd_group_t
*sg
; /* Current sub-group */
717 for (i
= g
->num_options
, o
= g
->options
; i
> 0; i
--, o
++)
718 if (strcasecmp(o
->keyword
, "PageRegion") != 0)
719 ppdMarkOption(ppd
, o
->keyword
, o
->defchoice
);
721 for (i
= g
->num_subgroups
, sg
= g
->subgroups
; i
> 0; i
--, sg
++)
722 ppd_defaults(ppd
, sg
);
727 * End of "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $".