]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/mark.c
2 * "$Id: mark.c 6649 2007-07-11 21:46:42Z 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
))
77 * Loop through all of the UI constraints and flag any options
81 for (i
= ppd
->num_consts
, c
= ppd
->consts
, o1
= o2
= NULL
, c1
= c2
= NULL
;
86 * Grab pointers to the first option...
89 if (!o1
|| strcmp(c
->option1
, o1
->keyword
))
91 o1
= ppdFindOption(ppd
, c
->option1
);
97 else if (c
->choice1
[0] && (!c1
|| strcmp(c
->choice1
, c1
->choice
)))
100 * This constraint maps to a specific choice.
105 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
106 (!c1
->marked
|| strcmp(c
->choice1
, c1
->choice
)))
112 * This constraint applies to any choice for this option.
117 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
118 (!strcasecmp(c1
->choice
, "None") || !strcasecmp(c1
->choice
, "Off") ||
119 !strcasecmp(c1
->choice
, "False")))
124 * Grab pointers to the second option...
127 if (!o2
|| strcmp(c
->option2
, o2
->keyword
))
129 o2
= ppdFindOption(ppd
, c
->option2
);
135 else if (c
->choice2
[0] && (!c2
|| strcmp(c
->choice2
, c2
->choice
)))
138 * This constraint maps to a specific choice.
143 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
144 (!c2
->marked
|| strcmp(c
->choice2
, c2
->choice
)))
150 * This constraint applies to any choice for this option.
155 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
156 (!strcasecmp(c2
->choice
, "None") || !strcasecmp(c2
->choice
, "Off") ||
157 !strcasecmp(c2
->choice
, "False")))
162 * If both options are marked then there is a conflict...
165 if (c1
&& c1
->marked
&& c2
&& c2
->marked
)
167 DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
168 o1
->keyword
, c1
->choice
, o2
->keyword
, c2
->choice
,
169 c
->option1
, c
->choice1
, c
->option2
, c
->choice2
));
177 * Return the number of conflicts found...
185 * 'ppdFindChoice()' - Return a pointer to an option choice.
188 ppd_choice_t
* /* O - Choice pointer or NULL */
189 ppdFindChoice(ppd_option_t
*o
, /* I - Pointer to option */
190 const char *choice
) /* I - Name of choice */
192 int i
; /* Looping var */
193 ppd_choice_t
*c
; /* Current choice */
196 if (o
== NULL
|| choice
== NULL
)
199 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
200 if (strcasecmp(c
->choice
, choice
) == 0)
208 * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
211 ppd_choice_t
* /* O - Pointer to choice or NULL */
212 ppdFindMarkedChoice(ppd_file_t
*ppd
, /* I - PPD file */
213 const char *option
) /* I - Keyword/option name */
215 ppd_choice_t key
; /* Search key for choice */
218 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
221 return ((ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
));
226 * 'ppdFindOption()' - Return a pointer to the specified option.
229 ppd_option_t
* /* O - Pointer to option or NULL */
230 ppdFindOption(ppd_file_t
*ppd
, /* I - PPD file data */
231 const char *option
) /* I - Option/Keyword name */
234 * Range check input...
243 * Search in the array...
246 ppd_option_t key
; /* Option search key */
249 strlcpy(key
.keyword
, option
, sizeof(key
.keyword
));
251 return ((ppd_option_t
*)cupsArrayFind(ppd
->options
, &key
));
256 * Search in each group...
259 int i
, j
; /* Looping vars */
260 ppd_group_t
*group
; /* Current group */
261 ppd_option_t
*optptr
; /* Current option */
264 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
265 for (j
= group
->num_options
, optptr
= group
->options
;
268 if (!strcasecmp(optptr
->keyword
, option
))
277 * 'ppdIsMarked()' - Check to see if an option is marked...
280 int /* O - Non-zero if option is marked */
281 ppdIsMarked(ppd_file_t
*ppd
, /* I - PPD file data */
282 const char *option
, /* I - Option/Keyword name */
283 const char *choice
) /* I - Choice name */
285 ppd_choice_t key
, /* Search key */
286 *c
; /* Choice pointer */
292 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
295 if ((c
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) == NULL
)
298 return (!strcmp(c
->choice
, choice
));
303 * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
307 ppdMarkDefaults(ppd_file_t
*ppd
) /* I - PPD file record */
309 int i
; /* Looping variables */
310 ppd_group_t
*g
; /* Current group */
311 ppd_choice_t
*c
; /* Current choice */
318 * Clean out the marked array...
321 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
323 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
324 cupsArrayRemove(ppd
->marked
, c
);
327 * Then repopulate it with the defaults...
330 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
331 ppd_defaults(ppd
, g
);
336 * 'ppdMarkOption()' - Mark an option in a PPD file.
340 * -1 is returned if the given option would conflict with any currently
344 int /* O - Number of conflicts */
345 ppdMarkOption(ppd_file_t
*ppd
, /* I - PPD file record */
346 const char *option
, /* I - Keyword */
347 const char *choice
) /* I - Option name */
349 int i
, j
; /* Looping vars */
350 ppd_option_t
*o
; /* Option pointer */
351 ppd_choice_t
*c
, /* Choice pointer */
352 *oldc
, /* Old choice pointer */
353 key
; /* Search key for choice */
354 struct lconv
*loc
; /* Locale data */
357 DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")\n",
358 ppd
, option
, choice
));
361 * Range check input...
364 if (!ppd
|| !option
|| !choice
)
368 * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
369 * it clears the regular InputSlot choices...
372 if (!strcasecmp(option
, "AP_D_InputSlot"))
374 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
377 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
380 cupsArrayRemove(ppd
->marked
, oldc
);
386 * Check for custom options...
389 if ((o
= ppdFindOption(ppd
, option
)) == NULL
)
394 if (!strncasecmp(choice
, "Custom.", 7))
397 * Handle a custom option...
400 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
403 if (!strcasecmp(option
, "PageSize"))
406 * Handle custom page sizes...
409 ppdPageSize(ppd
, choice
);
414 * Handle other custom options...
417 ppd_coption_t
*coption
; /* Custom option */
418 ppd_cparam_t
*cparam
; /* Custom parameter */
419 char *units
; /* Custom points units */
422 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
424 if ((cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
)) == NULL
)
427 switch (cparam
->type
)
429 case PPD_CUSTOM_CURVE
:
430 case PPD_CUSTOM_INVCURVE
:
431 case PPD_CUSTOM_REAL
:
432 cparam
->current
.custom_real
= (float)_cupsStrScand(choice
+ 7,
436 case PPD_CUSTOM_POINTS
:
437 cparam
->current
.custom_points
= (float)_cupsStrScand(choice
+ 7,
443 if (!strcasecmp(units
, "cm"))
444 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
445 else if (!strcasecmp(units
, "mm"))
446 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
447 else if (!strcasecmp(units
, "m"))
448 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
449 else if (!strcasecmp(units
, "in"))
450 cparam
->current
.custom_points
*= 72.0f
;
451 else if (!strcasecmp(units
, "ft"))
452 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
456 case PPD_CUSTOM_INT
:
457 cparam
->current
.custom_int
= atoi(choice
+ 7);
460 case PPD_CUSTOM_PASSCODE
:
461 case PPD_CUSTOM_PASSWORD
:
462 case PPD_CUSTOM_STRING
:
463 if (cparam
->current
.custom_string
)
464 free(cparam
->current
.custom_string
);
466 cparam
->current
.custom_string
= strdup(choice
+ 7);
473 * Make sure that we keep the option marked below...
478 else if (choice
[0] == '{')
481 * Handle multi-value custom options...
484 ppd_coption_t
*coption
; /* Custom option */
485 ppd_cparam_t
*cparam
; /* Custom parameter */
486 char *units
; /* Custom points units */
487 int num_vals
; /* Number of values */
488 cups_option_t
*vals
, /* Values */
492 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
495 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
497 num_vals
= cupsParseOptions(choice
+ 1, 0, &vals
);
499 for (i
= 0, val
= vals
; i
< num_vals
; i
++, val
++)
501 if ((cparam
= ppdFindCustomParam(coption
, val
->name
)) == NULL
)
504 switch (cparam
->type
)
506 case PPD_CUSTOM_CURVE
:
507 case PPD_CUSTOM_INVCURVE
:
508 case PPD_CUSTOM_REAL
:
509 cparam
->current
.custom_real
= (float)_cupsStrScand(val
->value
,
513 case PPD_CUSTOM_POINTS
:
514 cparam
->current
.custom_points
= (float)_cupsStrScand(val
->value
,
520 if (!strcasecmp(units
, "cm"))
521 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
522 else if (!strcasecmp(units
, "mm"))
523 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
524 else if (!strcasecmp(units
, "m"))
525 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
526 else if (!strcasecmp(units
, "in"))
527 cparam
->current
.custom_points
*= 72.0f
;
528 else if (!strcasecmp(units
, "ft"))
529 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
533 case PPD_CUSTOM_INT
:
534 cparam
->current
.custom_int
= atoi(val
->value
);
537 case PPD_CUSTOM_PASSCODE
:
538 case PPD_CUSTOM_PASSWORD
:
539 case PPD_CUSTOM_STRING
:
540 if (cparam
->current
.custom_string
)
541 free(cparam
->current
.custom_string
);
543 cparam
->current
.custom_string
= strdup(val
->value
);
548 cupsFreeOptions(num_vals
, vals
);
553 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
554 if (!strcasecmp(c
->choice
, choice
))
562 * Option found; mark it and then handle unmarking any other options.
565 if (o
->ui
!= PPD_UI_PICKMANY
)
568 * Unmark all other choices...
571 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, c
)) != NULL
)
574 cupsArrayRemove(ppd
->marked
, oldc
);
577 if (!strcasecmp(option
, "PageSize") || !strcasecmp(option
, "PageRegion"))
580 * Mark current page size...
583 for (j
= 0; j
< ppd
->num_sizes
; j
++)
584 ppd
->sizes
[j
].marked
= !strcasecmp(ppd
->sizes
[j
].name
,
588 * Unmark the current PageSize or PageRegion setting, as
592 if (!strcasecmp(option
, "PageSize"))
594 if ((o
= ppdFindOption(ppd
, "PageRegion")) != NULL
)
597 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
600 cupsArrayRemove(ppd
->marked
, oldc
);
606 if ((o
= ppdFindOption(ppd
, "PageSize")) != NULL
)
609 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
612 cupsArrayRemove(ppd
->marked
, oldc
);
617 else if (!strcasecmp(option
, "InputSlot"))
620 * Unmark ManualFeed True and possibly mark ManualFeed False
624 if ((o
= ppdFindOption(ppd
, "ManualFeed")) != NULL
)
627 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
630 cupsArrayRemove(ppd
->marked
, oldc
);
634 else if (!strcasecmp(option
, "ManualFeed") &&
635 !strcasecmp(choice
, "True"))
638 * Unmark InputSlot option...
641 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
644 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
647 cupsArrayRemove(ppd
->marked
, oldc
);
655 cupsArrayAdd(ppd
->marked
, c
);
658 * Return the number of conflicts...
661 return (ppdConflicts(ppd
));
666 * 'ppdFirstOption()' - Return the first option in the PPD file.
668 * Options are returned from all groups in sorted order.
673 ppd_option_t
* /* O - First option or NULL */
674 ppdFirstOption(ppd_file_t
*ppd
) /* I - PPD file */
679 return ((ppd_option_t
*)cupsArrayFirst(ppd
->options
));
684 * 'ppdNextOption()' - Return the next option in the PPD file.
686 * Options are returned from all groups in sorted order.
691 ppd_option_t
* /* O - Next option or NULL */
692 ppdNextOption(ppd_file_t
*ppd
) /* I - PPD file */
697 return ((ppd_option_t
*)cupsArrayNext(ppd
->options
));
702 * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
706 ppd_defaults(ppd_file_t
*ppd
, /* I - PPD file */
707 ppd_group_t
*g
) /* I - Group to default */
709 int i
; /* Looping var */
710 ppd_option_t
*o
; /* Current option */
711 ppd_group_t
*sg
; /* Current sub-group */
714 for (i
= g
->num_options
, o
= g
->options
; i
> 0; i
--, o
++)
715 if (strcasecmp(o
->keyword
, "PageRegion") != 0)
716 ppdMarkOption(ppd
, o
->keyword
, o
->defchoice
);
718 for (i
= g
->num_subgroups
, sg
= g
->subgroups
; i
> 0; i
--, sg
++)
719 ppd_defaults(ppd
, sg
);
724 * End of "$Id: mark.c 6649 2007-07-11 21:46:42Z mike $".