]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/mark.c
2 * "$Id: mark.c 6477 2007-04-25 19:55:45Z mike $"
4 * Option marking routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * PostScript is a trademark of Adobe Systems, Inc.
26 * This file is subject to the Apple OS-Developed Software exception.
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 * ppdFirstOption() - Return the first option in the PPD file.
35 * ppdNextOption() - Return the next option in the PPD file.
36 * ppdIsMarked() - Check to see if an option is marked...
37 * ppdMarkDefaults() - Mark all default options in the PPD file.
38 * ppdMarkOption() - Mark an option in a PPD file.
39 * ppd_defaults() - Set the defaults for this group and all sub-groups.
43 * Include necessary headers...
55 static void ppd_defaults(ppd_file_t
*ppd
, ppd_group_t
*g
);
59 * 'ppdConflicts()' - Check to see if there are any conflicts.
62 int /* O - Number of conflicts found */
63 ppdConflicts(ppd_file_t
*ppd
) /* I - PPD to check */
65 int i
, /* Looping variable */
66 conflicts
; /* Number of conflicts */
67 ppd_const_t
*c
; /* Current constraint */
68 ppd_option_t
*o1
, *o2
; /* Options */
69 ppd_choice_t
*c1
, *c2
; /* Choices */
70 ppd_choice_t key
; /* Search key */
77 * Clear all conflicts...
82 for (o1
= ppdFirstOption(ppd
); o1
; o1
= ppdNextOption(ppd
))
86 * Loop through all of the UI constraints and flag any options
90 for (i
= ppd
->num_consts
, c
= ppd
->consts
, o1
= o2
= NULL
, c1
= c2
= NULL
;
95 * Grab pointers to the first option...
98 if (!o1
|| strcmp(c
->option1
, o1
->keyword
))
100 o1
= ppdFindOption(ppd
, c
->option1
);
106 else if (c
->choice1
[0] && (!c1
|| strcmp(c
->choice1
, c1
->choice
)))
109 * This constraint maps to a specific choice.
114 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
121 * This constraint applies to any choice for this option.
126 if ((c1
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
127 (!strcasecmp(c1
->choice
, "None") || !strcasecmp(c1
->choice
, "Off") ||
128 !strcasecmp(c1
->choice
, "False")))
133 * Grab pointers to the second option...
136 if (!o2
|| strcmp(c
->option2
, o2
->keyword
))
138 o2
= ppdFindOption(ppd
, c
->option2
);
144 else if (c
->choice2
[0] && (!c2
|| strcmp(c
->choice2
, c2
->choice
)))
147 * This constraint maps to a specific choice.
152 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
159 * This constraint applies to any choice for this option.
164 if ((c2
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
&&
165 (!strcasecmp(c2
->choice
, "None") || !strcasecmp(c2
->choice
, "Off") ||
166 !strcasecmp(c2
->choice
, "False")))
171 * If both options are marked then there is a conflict...
174 if (c1
&& c1
->marked
&& c2
&& c2
->marked
)
176 DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
177 o1
->keyword
, c1
->choice
, o2
->keyword
, c2
->choice
,
178 c
->option1
, c
->choice1
, c
->option2
, c
->choice2
));
186 * Return the number of conflicts found...
194 * 'ppdFindChoice()' - Return a pointer to an option choice.
197 ppd_choice_t
* /* O - Choice pointer or NULL */
198 ppdFindChoice(ppd_option_t
*o
, /* I - Pointer to option */
199 const char *choice
) /* I - Name of choice */
201 int i
; /* Looping var */
202 ppd_choice_t
*c
; /* Current choice */
205 if (o
== NULL
|| choice
== NULL
)
208 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
209 if (strcasecmp(c
->choice
, choice
) == 0)
217 * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
220 ppd_choice_t
* /* O - Pointer to choice or NULL */
221 ppdFindMarkedChoice(ppd_file_t
*ppd
, /* I - PPD file */
222 const char *option
) /* I - Keyword/option name */
224 ppd_choice_t key
; /* Search key for choice */
227 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
230 return ((ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
));
235 * 'ppdFindOption()' - Return a pointer to the specified option.
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 */
243 * Range check input...
252 * Search in the array...
255 ppd_option_t key
; /* Option search key */
258 strlcpy(key
.keyword
, option
, sizeof(key
.keyword
));
260 return ((ppd_option_t
*)cupsArrayFind(ppd
->options
, &key
));
265 * Search in each group...
268 int i
, j
; /* Looping vars */
269 ppd_group_t
*group
; /* Current group */
270 ppd_option_t
*optptr
; /* Current option */
273 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
274 for (j
= group
->num_options
, optptr
= group
->options
;
277 if (!strcasecmp(optptr
->keyword
, option
))
286 * 'ppdIsMarked()' - Check to see if an option is marked...
289 int /* O - Non-zero if option is marked */
290 ppdIsMarked(ppd_file_t
*ppd
, /* I - PPD file data */
291 const char *option
, /* I - Option/Keyword name */
292 const char *choice
) /* I - Choice name */
294 ppd_choice_t key
, /* Search key */
295 *c
; /* Choice pointer */
301 if ((key
.option
= ppdFindOption(ppd
, option
)) == NULL
)
304 if ((c
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) == NULL
)
307 return (!strcmp(c
->choice
, choice
));
312 * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
316 ppdMarkDefaults(ppd_file_t
*ppd
) /* I - PPD file record */
318 int i
; /* Looping variables */
319 ppd_group_t
*g
; /* Current group */
320 ppd_choice_t
*c
; /* Current choice */
327 * Clean out the marked array...
330 for (c
= (ppd_choice_t
*)cupsArrayFirst(ppd
->marked
);
332 c
= (ppd_choice_t
*)cupsArrayNext(ppd
->marked
))
333 cupsArrayRemove(ppd
->marked
, c
);
336 * Then repopulate it with the defaults...
339 for (i
= ppd
->num_groups
, g
= ppd
->groups
; i
> 0; i
--, g
++)
340 ppd_defaults(ppd
, g
);
345 * 'ppdMarkOption()' - Mark an option in a PPD file.
349 * -1 is returned if the given option would conflict with any currently
353 int /* O - Number of conflicts */
354 ppdMarkOption(ppd_file_t
*ppd
, /* I - PPD file record */
355 const char *option
, /* I - Keyword */
356 const char *choice
) /* I - Option name */
358 int i
, j
; /* Looping vars */
359 ppd_option_t
*o
; /* Option pointer */
360 ppd_choice_t
*c
, /* Choice pointer */
361 *oldc
, /* Old choice pointer */
362 key
; /* Search key for choice */
363 struct lconv
*loc
; /* Locale data */
366 DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")\n",
367 ppd
, option
, choice
));
370 * Range check input...
373 if (!ppd
|| !option
|| !choice
)
377 * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
378 * it clears the regular InputSlot choices...
381 if (!strcasecmp(option
, "AP_D_InputSlot"))
383 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
386 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
389 cupsArrayRemove(ppd
->marked
, oldc
);
395 * Check for custom options...
398 if ((o
= ppdFindOption(ppd
, option
)) == NULL
)
403 if (!strncasecmp(choice
, "Custom.", 7))
406 * Handle a custom option...
409 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
412 if (!strcasecmp(option
, "PageSize"))
415 * Handle custom page sizes...
418 ppdPageSize(ppd
, choice
);
423 * Handle other custom options...
426 ppd_coption_t
*coption
; /* Custom option */
427 ppd_cparam_t
*cparam
; /* Custom parameter */
428 char *units
; /* Custom points units */
431 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
433 if ((cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
)) == NULL
)
436 switch (cparam
->type
)
438 case PPD_CUSTOM_CURVE
:
439 case PPD_CUSTOM_INVCURVE
:
440 case PPD_CUSTOM_REAL
:
441 cparam
->current
.custom_real
= (float)_cupsStrScand(choice
+ 7,
445 case PPD_CUSTOM_POINTS
:
446 cparam
->current
.custom_points
= (float)_cupsStrScand(choice
+ 7,
452 if (!strcasecmp(units
, "cm"))
453 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
454 else if (!strcasecmp(units
, "mm"))
455 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
456 else if (!strcasecmp(units
, "m"))
457 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
458 else if (!strcasecmp(units
, "in"))
459 cparam
->current
.custom_points
*= 72.0f
;
460 else if (!strcasecmp(units
, "ft"))
461 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
465 case PPD_CUSTOM_INT
:
466 cparam
->current
.custom_int
= atoi(choice
+ 7);
469 case PPD_CUSTOM_PASSCODE
:
470 case PPD_CUSTOM_PASSWORD
:
471 case PPD_CUSTOM_STRING
:
472 if (cparam
->current
.custom_string
)
473 free(cparam
->current
.custom_string
);
475 cparam
->current
.custom_string
= strdup(choice
+ 7);
482 * Make sure that we keep the option marked below...
487 else if (choice
[0] == '{')
490 * Handle multi-value custom options...
493 ppd_coption_t
*coption
; /* Custom option */
494 ppd_cparam_t
*cparam
; /* Custom parameter */
495 char *units
; /* Custom points units */
496 int num_vals
; /* Number of values */
497 cups_option_t
*vals
, /* Values */
501 if ((c
= ppdFindChoice(o
, "Custom")) == NULL
)
504 if ((coption
= ppdFindCustomOption(ppd
, option
)) != NULL
)
506 num_vals
= cupsParseOptions(choice
+ 1, 0, &vals
);
508 for (i
= 0, val
= vals
; i
< num_vals
; i
++, val
++)
510 if ((cparam
= ppdFindCustomParam(coption
, val
->name
)) == NULL
)
513 switch (cparam
->type
)
515 case PPD_CUSTOM_CURVE
:
516 case PPD_CUSTOM_INVCURVE
:
517 case PPD_CUSTOM_REAL
:
518 cparam
->current
.custom_real
= (float)_cupsStrScand(val
->value
,
522 case PPD_CUSTOM_POINTS
:
523 cparam
->current
.custom_points
= (float)_cupsStrScand(val
->value
,
529 if (!strcasecmp(units
, "cm"))
530 cparam
->current
.custom_points
*= 72.0f
/ 2.54f
;
531 else if (!strcasecmp(units
, "mm"))
532 cparam
->current
.custom_points
*= 72.0f
/ 25.4f
;
533 else if (!strcasecmp(units
, "m"))
534 cparam
->current
.custom_points
*= 72.0f
/ 0.0254f
;
535 else if (!strcasecmp(units
, "in"))
536 cparam
->current
.custom_points
*= 72.0f
;
537 else if (!strcasecmp(units
, "ft"))
538 cparam
->current
.custom_points
*= 12.0f
* 72.0f
;
542 case PPD_CUSTOM_INT
:
543 cparam
->current
.custom_int
= atoi(val
->value
);
546 case PPD_CUSTOM_PASSCODE
:
547 case PPD_CUSTOM_PASSWORD
:
548 case PPD_CUSTOM_STRING
:
549 if (cparam
->current
.custom_string
)
550 free(cparam
->current
.custom_string
);
552 cparam
->current
.custom_string
= strdup(val
->value
);
557 cupsFreeOptions(num_vals
, vals
);
562 for (i
= o
->num_choices
, c
= o
->choices
; i
> 0; i
--, c
++)
563 if (!strcasecmp(c
->choice
, choice
))
571 * Option found; mark it and then handle unmarking any other options.
574 if (o
->ui
!= PPD_UI_PICKMANY
)
577 * Unmark all other choices...
580 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, c
)) != NULL
)
583 cupsArrayRemove(ppd
->marked
, oldc
);
586 if (!strcasecmp(option
, "PageSize") || !strcasecmp(option
, "PageRegion"))
589 * Mark current page size...
592 for (j
= 0; j
< ppd
->num_sizes
; j
++)
593 ppd
->sizes
[j
].marked
= !strcasecmp(ppd
->sizes
[j
].name
,
597 * Unmark the current PageSize or PageRegion setting, as
601 if (!strcasecmp(option
, "PageSize"))
603 if ((o
= ppdFindOption(ppd
, "PageRegion")) != NULL
)
606 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
609 cupsArrayRemove(ppd
->marked
, oldc
);
615 if ((o
= ppdFindOption(ppd
, "PageSize")) != NULL
)
618 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
621 cupsArrayRemove(ppd
->marked
, oldc
);
626 else if (!strcasecmp(option
, "InputSlot"))
629 * Unmark ManualFeed True and possibly mark ManualFeed False
633 if ((o
= ppdFindOption(ppd
, "ManualFeed")) != NULL
)
636 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
639 cupsArrayRemove(ppd
->marked
, oldc
);
643 else if (!strcasecmp(option
, "ManualFeed") &&
644 !strcasecmp(choice
, "True"))
647 * Unmark InputSlot option...
650 if ((o
= ppdFindOption(ppd
, "InputSlot")) != NULL
)
653 if ((oldc
= (ppd_choice_t
*)cupsArrayFind(ppd
->marked
, &key
)) != NULL
)
656 cupsArrayRemove(ppd
->marked
, oldc
);
664 cupsArrayAdd(ppd
->marked
, c
);
667 * Return the number of conflicts...
670 return (ppdConflicts(ppd
));
675 * 'ppdFirstOption()' - Return the first option in the PPD file.
677 * Options are returned from all groups in sorted order.
682 ppd_option_t
* /* O - First option or NULL */
683 ppdFirstOption(ppd_file_t
*ppd
) /* I - PPD file */
688 return ((ppd_option_t
*)cupsArrayFirst(ppd
->options
));
693 * 'ppdNextOption()' - Return the next option in the PPD file.
695 * Options are returned from all groups in sorted order.
700 ppd_option_t
* /* O - Next option or NULL */
701 ppdNextOption(ppd_file_t
*ppd
) /* I - PPD file */
706 return ((ppd_option_t
*)cupsArrayNext(ppd
->options
));
711 * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
715 ppd_defaults(ppd_file_t
*ppd
, /* I - PPD file */
716 ppd_group_t
*g
) /* I - Group to default */
718 int i
; /* Looping var */
719 ppd_option_t
*o
; /* Current option */
720 ppd_group_t
*sg
; /* Current sub-group */
723 for (i
= g
->num_options
, o
= g
->options
; i
> 0; i
--, o
++)
724 if (strcasecmp(o
->keyword
, "PageRegion") != 0)
725 ppdMarkOption(ppd
, o
->keyword
, o
->defchoice
);
727 for (i
= g
->num_subgroups
, sg
= g
->subgroups
; i
> 0; i
--, sg
++)
728 ppd_defaults(ppd
, sg
);
733 * End of "$Id: mark.c 6477 2007-04-25 19:55:45Z mike $".