]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-driver.cxx
4 // PPD file compiler definitions for the CUPS PPD Compiler.
6 // Copyright 2007-2009 by Apple Inc.
7 // Copyright 2002-2006 by Easy Software Products.
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/".
17 // ppdcDriver::ppdcDriver() - Create a new printer driver.
18 // ppdcDriver::~ppdcDriver() - Destroy a printer driver.
19 // ppdcDriver::find_attr() - Find an attribute.
20 // ppdcDriver::find_group() - Find a group.
21 // ppdcDriver::find_option() - Find an option.
22 // ppdcDriver::set_custom_size_code() - Set the custom page size code.
23 // ppdcDriver::set_default_font() - Set the default font name.
24 // ppdcDriver::set_default_size() - Set the default size name.
25 // ppdcDriver::set_file_name() - Set the full filename.
26 // ppdcDriver::set_manufacturer() - Set the manufacturer name.
27 // ppdcDriver::set_model_name() - Set the model name.
28 // ppdcDriver::set_pc_file_name() - Set the PC filename.
29 // ppdcDriver::set_version() - Set the version string.
30 // ppdcDriver::write_ppd_file() - Write a PPD file...
34 // Include necessary headers...
37 #include "ppdc-private.h"
38 #include <cups/globals.h>
42 // 'ppdcDriver::ppdcDriver()' - Create a new printer driver.
45 ppdcDriver::ppdcDriver(ppdcDriver
*d
) // I - Printer driver template
48 ppdcGroup
*g
; // Current group
55 // Bump the use count of any strings we inherit...
57 d
->manufacturer
->retain();
61 d
->default_font
->retain();
63 d
->default_size
->retain();
64 if (d
->custom_size_code
)
65 d
->custom_size_code
->retain();
67 // Copy all of the data from the driver template...
68 copyright
= new ppdcArray(d
->copyright
);
69 manufacturer
= d
->manufacturer
;
75 model_number
= d
->model_number
;
76 manual_copies
= d
->manual_copies
;
77 color_device
= d
->color_device
;
78 throughput
= d
->throughput
;
79 attrs
= new ppdcArray(d
->attrs
);
80 constraints
= new ppdcArray(d
->constraints
);
81 filters
= new ppdcArray(d
->filters
);
82 fonts
= new ppdcArray(d
->fonts
);
83 profiles
= new ppdcArray(d
->profiles
);
84 sizes
= new ppdcArray(d
->sizes
);
85 default_font
= d
->default_font
;
86 default_size
= d
->default_size
;
87 variable_paper_size
= d
->variable_paper_size
;
88 custom_size_code
= d
->custom_size_code
;
89 left_margin
= d
->left_margin
;
90 bottom_margin
= d
->bottom_margin
;
91 right_margin
= d
->right_margin
;
92 top_margin
= d
->top_margin
;
93 max_width
= d
->max_width
;
94 max_length
= d
->max_length
;
95 min_width
= d
->min_width
;
96 min_length
= d
->min_length
;
98 // Then copy the groups manually, since we want separate copies
99 // of the groups and options...
100 groups
= new ppdcArray();
102 for (g
= (ppdcGroup
*)d
->groups
->first(); g
; g
= (ppdcGroup
*)d
->groups
->next())
103 groups
->add(new ppdcGroup(g
));
107 // Zero all of the data in the driver...
108 copyright
= new ppdcArray();
114 type
= PPDC_DRIVER_CUSTOM
;
119 attrs
= new ppdcArray();
120 constraints
= new ppdcArray();
121 fonts
= new ppdcArray();
122 filters
= new ppdcArray();
123 groups
= new ppdcArray();
124 profiles
= new ppdcArray();
125 sizes
= new ppdcArray();
128 variable_paper_size
= 0;
129 custom_size_code
= 0;
143 // 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver.
146 ppdcDriver::~ppdcDriver()
150 copyright
->release();
153 manufacturer
->release();
155 model_name
->release();
157 file_name
->release();
159 pc_file_name
->release();
163 default_font
->release();
165 default_size
->release();
166 if (custom_size_code
)
167 custom_size_code
->release();
170 constraints
->release();
180 // 'ppdcDriver::find_attr()' - Find an attribute.
183 ppdcAttr
* // O - Attribute or NULL
184 ppdcDriver::find_attr(const char *k
, // I - Keyword string
185 const char *s
) // I - Spec string
187 ppdcAttr
*a
; // Current attribute
190 for (a
= (ppdcAttr
*)attrs
->first(); a
; a
= (ppdcAttr
*)attrs
->next())
191 if (!strcmp(a
->name
->value
, k
) &&
192 ((!s
&& (!a
->selector
->value
|| !a
->selector
->value
[0])) ||
193 (!s
&& !a
->selector
->value
&& !strcmp(a
->selector
->value
, s
))))
201 // 'ppdcDriver::find_group()' - Find a group.
204 ppdcGroup
* // O - Matching group or NULL
205 ppdcDriver::find_group(const char *n
) // I - Group name
207 ppdcGroup
*g
; // Current group
210 for (g
= (ppdcGroup
*)groups
->first(); g
; g
= (ppdcGroup
*)groups
->next())
211 if (!strcasecmp(n
, g
->name
->value
))
219 // 'ppdcDriver::find_option()' - Find an option.
222 ppdcOption
* // O - Matching option or NULL
223 ppdcDriver::find_option(const char *n
) // I - Option name
225 ppdcGroup
*g
; // Current group
226 ppdcOption
*o
; // Current option
229 for (g
= (ppdcGroup
*)groups
->first(); g
; g
= (ppdcGroup
*)groups
->next())
230 for (o
= (ppdcOption
*)g
->options
->first(); o
; o
= (ppdcOption
*)g
->options
->next())
231 if (!strcasecmp(n
, o
->name
->value
))
239 // 'ppdcDriver::set_custom_size_code()' - Set the custom page size code.
243 ppdcDriver::set_custom_size_code(
244 const char *c
) // I - CustomPageSize code
246 if (custom_size_code
)
247 custom_size_code
->release();
249 custom_size_code
= new ppdcString(c
);
254 // 'ppdcDriver::set_default_font()' - Set the default font name.
258 ppdcDriver::set_default_font(
259 ppdcFont
*f
) // I - Font
262 default_font
->release();
267 default_font
= f
->name
;
275 // 'ppdcDriver::set_default_size()' - Set the default size name.
279 ppdcDriver::set_default_size(
280 ppdcMediaSize
*m
) // I - Media size
283 default_size
->release();
288 default_size
= m
->name
;
296 // 'ppdcDriver::set_file_name()' - Set the full filename.
300 ppdcDriver::set_file_name(const char *f
)// I - Filename
303 file_name
->release();
305 file_name
= new ppdcString(f
);
310 // 'ppdcDriver::set_manufacturer()' - Set the manufacturer name.
314 ppdcDriver::set_manufacturer(
315 const char *m
) // I - Model name
318 manufacturer
->release();
320 manufacturer
= new ppdcString(m
);
325 // 'ppdcDriver::set_model_name()' - Set the model name.
329 ppdcDriver::set_model_name(
330 const char *m
) // I - Model name
333 model_name
->release();
335 model_name
= new ppdcString(m
);
340 // 'ppdcDriver::set_pc_file_name()' - Set the PC filename.
344 ppdcDriver::set_pc_file_name(
345 const char *f
) // I - Filename
348 pc_file_name
->release();
350 pc_file_name
= new ppdcString(f
);
355 // 'ppdcDriver::set_version()' - Set the version string.
359 ppdcDriver::set_version(const char *v
) // I - Version
364 version
= new ppdcString(v
);
369 // 'ppdcDriver::write_ppd_file()' - Write a PPD file...
372 int // O - 0 on success, -1 on failure
373 ppdcDriver::write_ppd_file(
374 cups_file_t
*fp
, // I - PPD file
375 ppdcCatalog
*catalog
, // I - Message catalog
376 ppdcArray
*locales
, // I - Additional languages to add
377 ppdcSource
*src
, // I - Driver source
378 ppdcLineEnding le
) // I - Line endings to use
380 bool delete_cat
; // Delete the catalog when we are done?
381 char query
[42]; // Query attribute
382 ppdcString
*s
; // Copyright string
383 ppdcGroup
*g
; // Current group
384 ppdcOption
*o
; // Current option
385 ppdcChoice
*c
; // Current choice
386 ppdcMediaSize
*m
; // Current media size
387 ppdcProfile
*p
; // Current color profile
388 ppdcFilter
*f
; // Current filter
389 ppdcFont
*fn
, // Current font
390 *bfn
; // Current base font
391 ppdcConstraint
*cn
; // Current constraint
392 ppdcAttr
*a
; // Current attribute
393 const char *lf
; // Linefeed character to use
396 // If we don't have a message catalog, use an empty (English) one...
399 catalog
= new ppdcCatalog("en");
405 // Figure out the end-of-line string...
406 if (le
== PPDC_LFONLY
)
408 else if (le
== PPDC_CRONLY
)
413 // Write the standard header stuff...
414 cupsFilePrintf(fp
, "*PPD-Adobe: \"4.3\"%s", lf
);
415 cupsFilePrintf(fp
, "*%% PPD file for %s with CUPS.%s", model_name
->value
, lf
);
417 "*%% Created by the CUPS PPD Compiler " CUPS_SVERSION
".%s",
419 for (s
= (ppdcString
*)copyright
->first();
421 s
= (ppdcString
*)copyright
->next())
422 cupsFilePrintf(fp
, "*%% %s%s", catalog
->find_message(s
->value
), lf
);
423 cupsFilePrintf(fp
, "*FormatVersion: \"4.3\"%s", lf
);
424 cupsFilePrintf(fp
, "*FileVersion: \"%s\"%s", version
->value
, lf
);
426 a
= find_attr("LanguageVersion", NULL
);
427 cupsFilePrintf(fp
, "*LanguageVersion: %s%s",
428 catalog
->find_message(a
? a
->value
->value
: "English"), lf
);
430 a
= find_attr("LanguageEncoding", NULL
);
431 cupsFilePrintf(fp
, "*LanguageEncoding: %s%s",
432 catalog
->find_message(a
? a
->value
->value
: "ISOLatin1"), lf
);
434 cupsFilePrintf(fp
, "*PCFileName: \"%s\"%s", pc_file_name
->value
, lf
);
436 for (a
= (ppdcAttr
*)attrs
->first(); a
; a
= (ppdcAttr
*)attrs
->next())
437 if (!strcmp(a
->name
->value
, "Product"))
442 for (; a
; a
= (ppdcAttr
*)attrs
->next())
443 if (!strcmp(a
->name
->value
, "Product"))
444 cupsFilePrintf(fp
, "*Product: \"%s\"%s", a
->value
->value
, lf
);
447 cupsFilePrintf(fp
, "*Product: \"(%s)\"%s", model_name
->value
, lf
);
449 cupsFilePrintf(fp
, "*Manufacturer: \"%s\"%s",
450 catalog
->find_message(manufacturer
->value
), lf
);
452 if ((a
= find_attr("ModelName", NULL
)) != NULL
)
453 cupsFilePrintf(fp
, "*ModelName: \"%s\"%s",
454 catalog
->find_message(a
->value
->value
), lf
);
455 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
456 strlen(manufacturer
->value
)))
457 cupsFilePrintf(fp
, "*ModelName: \"%s %s\"%s",
458 catalog
->find_message(manufacturer
->value
),
459 catalog
->find_message(model_name
->value
), lf
);
461 cupsFilePrintf(fp
, "*ModelName: \"%s\"%s",
462 catalog
->find_message(model_name
->value
), lf
);
464 if ((a
= find_attr("ShortNickName", NULL
)) != NULL
)
465 cupsFilePrintf(fp
, "*ShortNickName: \"%s\"%s",
466 catalog
->find_message(a
->value
->value
), lf
);
467 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
468 strlen(manufacturer
->value
)))
469 cupsFilePrintf(fp
, "*ShortNickName: \"%s %s\"%s",
470 catalog
->find_message(manufacturer
->value
),
471 catalog
->find_message(model_name
->value
), lf
);
473 cupsFilePrintf(fp
, "*ShortNickName: \"%s\"%s",
474 catalog
->find_message(model_name
->value
), lf
);
476 if ((a
= find_attr("NickName", NULL
)) != NULL
)
477 cupsFilePrintf(fp
, "*NickName: \"%s\"%s",
478 catalog
->find_message(a
->value
->value
), lf
);
479 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
480 strlen(manufacturer
->value
)))
481 cupsFilePrintf(fp
, "*NickName: \"%s %s, %s\"%s",
482 catalog
->find_message(manufacturer
->value
),
483 catalog
->find_message(model_name
->value
), version
->value
,
486 cupsFilePrintf(fp
, "*NickName: \"%s, %s\"%s",
487 catalog
->find_message(model_name
->value
), version
->value
,
490 for (a
= (ppdcAttr
*)attrs
->first(); a
; a
= (ppdcAttr
*)attrs
->next())
491 if (!strcmp(a
->name
->value
, "PSVersion"))
496 for (; a
; a
= (ppdcAttr
*)attrs
->next())
497 if (!strcmp(a
->name
->value
, "PSVersion"))
498 cupsFilePrintf(fp
, "*PSVersion: \"%s\"%s", a
->value
->value
, lf
);
501 cupsFilePrintf(fp
, "*PSVersion: \"(3010.000) 0\"%s", lf
);
503 if ((a
= find_attr("LanguageLevel", NULL
)) != NULL
)
504 cupsFilePrintf(fp
, "*LanguageLevel: \"%s\"%s", a
->value
->value
, lf
);
506 cupsFilePrintf(fp
, "*LanguageLevel: \"3\"%s", lf
);
508 cupsFilePrintf(fp
, "*ColorDevice: %s%s", color_device
? "True" : "False", lf
);
510 if ((a
= find_attr("DefaultColorSpace", NULL
)) != NULL
)
511 cupsFilePrintf(fp
, "*DefaultColorSpace: %s%s", a
->value
->value
, lf
);
513 cupsFilePrintf(fp
, "*DefaultColorSpace: %s%s",
514 color_device
? "RGB" : "Gray", lf
);
516 if ((a
= find_attr("FileSystem", NULL
)) != NULL
)
517 cupsFilePrintf(fp
, "*FileSystem: %s%s", a
->value
->value
, lf
);
519 cupsFilePrintf(fp
, "*FileSystem: False%s", lf
);
521 cupsFilePrintf(fp
, "*Throughput: \"%d\"%s", throughput
, lf
);
523 if ((a
= find_attr("LandscapeOrientation", NULL
)) != NULL
)
524 cupsFilePrintf(fp
, "*LandscapeOrientation: %s%s", a
->value
->value
, lf
);
526 cupsFilePrintf(fp
, "*LandscapeOrientation: Plus90%s", lf
);
528 if ((a
= find_attr("TTRasterizer", NULL
)) != NULL
)
529 cupsFilePrintf(fp
, "*TTRasterizer: %s%s", a
->value
->value
, lf
);
530 else if (type
!= PPDC_DRIVER_PS
)
531 cupsFilePrintf(fp
, "*TTRasterizer: Type42%s", lf
);
535 // Write driver-defined attributes...
536 cupsFilePrintf(fp
, "*%% Driver-defined attributes...%s", lf
);
537 for (a
= (ppdcAttr
*)attrs
->first(); a
; a
= (ppdcAttr
*)attrs
->next())
539 if (!strcmp(a
->name
->value
, "Product") ||
540 !strcmp(a
->name
->value
, "PSVersion") ||
541 !strcmp(a
->name
->value
, "LanguageLevel") ||
542 !strcmp(a
->name
->value
, "DefaultColorSpace") ||
543 !strcmp(a
->name
->value
, "FileSystem") ||
544 !strcmp(a
->name
->value
, "LandscapeOrientation") ||
545 !strcmp(a
->name
->value
, "TTRasterizer") ||
546 !strcmp(a
->name
->value
, "LanguageVersion") ||
547 !strcmp(a
->name
->value
, "LanguageEncoding") ||
548 !strcmp(a
->name
->value
, "ModelName") ||
549 !strcmp(a
->name
->value
, "NickName") ||
550 !strcmp(a
->name
->value
, "ShortNickName") ||
551 !strcmp(a
->name
->value
, "cupsVersion"))
554 if (a
->name
->value
[0] == '?' &&
555 (find_option(a
->name
->value
+ 1) ||
556 !strcmp(a
->name
->value
, "?ImageableArea") ||
557 !strcmp(a
->name
->value
, "?PageRegion") ||
558 !strcmp(a
->name
->value
, "?PageSize") ||
559 !strcmp(a
->name
->value
, "?PaperDimension")))
562 if (!a
->selector
->value
|| !a
->selector
->value
[0])
563 cupsFilePrintf(fp
, "*%s", a
->name
->value
);
564 else if (!a
->text
->value
|| !a
->text
->value
[0])
565 cupsFilePrintf(fp
, "*%s %s", a
->name
->value
, a
->selector
->value
);
567 cupsFilePrintf(fp
, "*%s %s/%s", a
->name
->value
, a
->selector
->value
,
570 if (strcmp(a
->value
->value
, "False") &&
571 strcmp(a
->value
->value
, "True") &&
572 strcmp(a
->name
->value
, "1284Modes") &&
573 strcmp(a
->name
->value
, "InkName") &&
574 strcmp(a
->name
->value
, "PageStackOrder") &&
575 strncmp(a
->name
->value
, "ParamCustom", 11) &&
576 strcmp(a
->name
->value
, "Protocols") &&
577 strcmp(a
->name
->value
, "ReferencePunch") &&
578 strncmp(a
->name
->value
, "Default", 7))
580 cupsFilePrintf(fp
, ": \"%s\"%s", a
->value
->value
, lf
);
582 if (strchr(a
->value
->value
, '\n'))
583 cupsFilePrintf(fp
, "*End%s", lf
);
586 cupsFilePrintf(fp
, ": %s%s", a
->value
->value
, lf
);
590 if (type
!= PPDC_DRIVER_PS
|| filters
->count
)
592 if ((a
= find_attr("cupsVersion", NULL
)) != NULL
)
593 cupsFilePrintf(fp
, "*cupsVersion: %s%s", a
->value
->value
, lf
);
595 cupsFilePrintf(fp
, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR
,
596 CUPS_VERSION_MINOR
, lf
);
597 cupsFilePrintf(fp
, "*cupsModelNumber: %d%s", model_number
, lf
);
598 cupsFilePrintf(fp
, "*cupsManualCopies: %s%s",
599 manual_copies
? "True" : "False", lf
);
603 for (f
= (ppdcFilter
*)filters
->first();
605 f
= (ppdcFilter
*)filters
->next())
606 cupsFilePrintf(fp
, "*cupsFilter: \"%s %d %s\"%s", f
->mime_type
->value
,
607 f
->cost
, f
->program
->value
, lf
);
613 case PPDC_DRIVER_LABEL
:
614 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-raster 50 "
615 "rastertolabel\"%s", lf
);
618 case PPDC_DRIVER_EPSON
:
619 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-raster 50 "
620 "rastertoepson\"%s", lf
);
623 case PPDC_DRIVER_ESCP
:
624 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-command 50 "
625 "commandtoescpx\"%s", lf
);
626 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-raster 50 "
627 "rastertoescpx\"%s", lf
);
630 case PPDC_DRIVER_HP
:
631 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-raster 50 "
632 "rastertohp\"%s", lf
);
635 case PPDC_DRIVER_PCL
:
636 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-command 50 "
637 "commandtopclx\"%s", lf
);
638 cupsFilePrintf(fp
, "*cupsFilter: \"application/vnd.cups-raster 50 "
639 "rastertopclx\"%s", lf
);
647 for (p
= (ppdcProfile
*)profiles
->first();
649 p
= (ppdcProfile
*)profiles
->next())
651 "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
652 "%.3f %.3f %.3f %.3f %.3f\"%s",
653 p
->resolution
->value
, p
->media_type
->value
,
654 p
->density
, p
->gamma
,
655 p
->profile
[0], p
->profile
[1],
656 p
->profile
[2], p
->profile
[3],
657 p
->profile
[4], p
->profile
[5],
658 p
->profile
[6], p
->profile
[7],
664 // Add localizations for additional languages...
665 ppdcString
*locale
; // Locale name
666 ppdcCatalog
*locatalog
; // Message catalog for locale
669 // Write the list of languages...
670 cupsFilePrintf(fp
, "*cupsLanguages: \"en");
672 for (locale
= (ppdcString
*)locales
->first();
674 locale
= (ppdcString
*)locales
->next())
676 // Skip (US) English...
677 if (!strcmp(locale
->value
, "en") || !strcmp(locale
->value
, "en_US"))
680 // See if we have a po file for this language...
681 if (!src
->find_po(locale
->value
))
683 // No, see if we can use the base file?
684 locatalog
= new ppdcCatalog(locale
->value
);
686 if (locatalog
->messages
->count
== 0)
688 // No, skip this one...
689 _cupsLangPrintf(stderr
,
690 _("ppdc: No message catalog provided for locale "
691 "%s!\n"), locale
->value
);
695 // Add the base file to the list...
696 src
->po_files
->add(locatalog
);
699 cupsFilePrintf(fp
, " %s", locale
->value
);
702 cupsFilePrintf(fp
, "\"%s", lf
);
705 for (cn
= (ppdcConstraint
*)constraints
->first();
707 cn
= (ppdcConstraint
*)constraints
->next())
709 // First constrain 1 against 2...
710 if (!strncmp(cn
->option1
->value
, "*Custom", 7) ||
711 !strncmp(cn
->option2
->value
, "*Custom", 7))
712 cupsFilePuts(fp
, "*NonUIConstraints: ");
714 cupsFilePuts(fp
, "*UIConstraints: ");
716 if (cn
->option1
->value
[0] != '*')
717 cupsFilePutChar(fp
, '*');
719 cupsFilePuts(fp
, cn
->option1
->value
);
721 if (cn
->choice1
->value
)
722 cupsFilePrintf(fp
, " %s", cn
->choice1
->value
);
724 cupsFilePutChar(fp
, ' ');
726 if (cn
->option2
->value
[0] != '*')
727 cupsFilePutChar(fp
, '*');
729 cupsFilePuts(fp
, cn
->option2
->value
);
731 if (cn
->choice2
->value
)
732 cupsFilePrintf(fp
, " %s", cn
->choice2
->value
);
734 cupsFilePuts(fp
, lf
);
736 // Then constrain 2 against 1...
737 if (!strncmp(cn
->option1
->value
, "*Custom", 7) ||
738 !strncmp(cn
->option2
->value
, "*Custom", 7))
739 cupsFilePuts(fp
, "*NonUIConstraints: ");
741 cupsFilePuts(fp
, "*UIConstraints: ");
743 if (cn
->option2
->value
[0] != '*')
744 cupsFilePutChar(fp
, '*');
746 cupsFilePuts(fp
, cn
->option2
->value
);
748 if (cn
->choice2
->value
)
749 cupsFilePrintf(fp
, " %s", cn
->choice2
->value
);
751 cupsFilePutChar(fp
, ' ');
753 if (cn
->option1
->value
[0] != '*')
754 cupsFilePutChar(fp
, '*');
756 cupsFilePuts(fp
, cn
->option1
->value
);
758 if (cn
->choice1
->value
)
759 cupsFilePrintf(fp
, " %s", cn
->choice1
->value
);
761 cupsFilePuts(fp
, lf
);
764 // PageSize option...
765 cupsFilePrintf(fp
, "*OpenUI *PageSize/Media Size: PickOne%s", lf
);
766 cupsFilePrintf(fp
, "*OrderDependency: 10 AnySetup *PageSize%s", lf
);
767 cupsFilePrintf(fp
, "*DefaultPageSize: %s%s",
768 default_size
? default_size
->value
: "Letter", lf
);
770 for (m
= (ppdcMediaSize
*)sizes
->first();
772 m
= (ppdcMediaSize
*)sizes
->next())
773 if (m
->size_code
->value
)
775 cupsFilePrintf(fp
, "*PageSize %s/%s: \"%s\"%s",
776 m
->name
->value
, catalog
->find_message(m
->text
->value
),
777 m
->size_code
->value
, lf
);
779 if (strchr(m
->size_code
->value
, '\n') ||
780 strchr(m
->size_code
->value
, '\r'))
781 cupsFilePrintf(fp
, "*End%s", lf
);
785 "*PageSize %s/%s: \"<</PageSize[%.0f %.0f]"
786 "/ImagingBBox null>>setpagedevice\"%s",
787 m
->name
->value
, catalog
->find_message(m
->text
->value
),
788 m
->width
, m
->length
, lf
);
790 if ((a
= find_attr("?PageSize", NULL
)) != NULL
)
792 cupsFilePrintf(fp
, "*?PageSize: \"%s\"%s", a
->value
->value
, lf
);
794 if (strchr(a
->value
->value
, '\n') ||
795 strchr(a
->value
->value
, '\r'))
796 cupsFilePrintf(fp
, "*End%s", lf
);
799 cupsFilePrintf(fp
, "*CloseUI: *PageSize%s", lf
);
801 // PageRegion option...
802 cupsFilePrintf(fp
, "*OpenUI *PageRegion/Media Size: PickOne%s", lf
);
803 cupsFilePrintf(fp
, "*OrderDependency: 10 AnySetup *PageRegion%s", lf
);
804 cupsFilePrintf(fp
, "*DefaultPageRegion: %s%s",
805 default_size
? default_size
->value
: "Letter", lf
);
807 for (m
= (ppdcMediaSize
*)sizes
->first();
809 m
= (ppdcMediaSize
*)sizes
->next())
810 if (m
->region_code
->value
)
812 cupsFilePrintf(fp
, "*PageRegion %s/%s: \"%s\"%s",
813 m
->name
->value
, catalog
->find_message(m
->text
->value
),
814 m
->region_code
->value
, lf
);
816 if (strchr(m
->region_code
->value
, '\n') ||
817 strchr(m
->region_code
->value
, '\r'))
818 cupsFilePrintf(fp
, "*End%s", lf
);
822 "*PageRegion %s/%s: \"<</PageSize[%.0f %.0f]"
823 "/ImagingBBox null>>setpagedevice\"%s",
824 m
->name
->value
, catalog
->find_message(m
->text
->value
),
825 m
->width
, m
->length
, lf
);
827 if ((a
= find_attr("?PageRegion", NULL
)) != NULL
)
829 cupsFilePrintf(fp
, "*?PageRegion: \"%s\"%s", a
->value
->value
, lf
);
831 if (strchr(a
->value
->value
, '\n') ||
832 strchr(a
->value
->value
, '\r'))
833 cupsFilePrintf(fp
, "*End%s", lf
);
836 cupsFilePrintf(fp
, "*CloseUI: *PageRegion%s", lf
);
838 // ImageableArea info...
839 cupsFilePrintf(fp
, "*DefaultImageableArea: %s%s",
840 default_size
? default_size
->value
: "Letter", lf
);
842 for (m
= (ppdcMediaSize
*)sizes
->first();
844 m
= (ppdcMediaSize
*)sizes
->next())
845 cupsFilePrintf(fp
, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
846 m
->name
->value
, catalog
->find_message(m
->text
->value
),
847 m
->left
, m
->bottom
, m
->width
- m
->right
, m
->length
- m
->top
,
850 if ((a
= find_attr("?ImageableArea", NULL
)) != NULL
)
852 cupsFilePrintf(fp
, "*?ImageableArea: \"%s\"%s", a
->value
->value
, lf
);
854 if (strchr(a
->value
->value
, '\n') ||
855 strchr(a
->value
->value
, '\r'))
856 cupsFilePrintf(fp
, "*End%s", lf
);
859 // PaperDimension info...
860 cupsFilePrintf(fp
, "*DefaultPaperDimension: %s%s",
861 default_size
? default_size
->value
: "Letter", lf
);
863 for (m
= (ppdcMediaSize
*)sizes
->first();
865 m
= (ppdcMediaSize
*)sizes
->next())
866 cupsFilePrintf(fp
, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
867 m
->name
->value
, catalog
->find_message(m
->text
->value
),
868 m
->width
, m
->length
, lf
);
870 if ((a
= find_attr("?PaperDimension", NULL
)) != NULL
)
872 cupsFilePrintf(fp
, "*?PaperDimension: \"%s\"%s", a
->value
->value
, lf
);
874 if (strchr(a
->value
->value
, '\n') ||
875 strchr(a
->value
->value
, '\r'))
876 cupsFilePrintf(fp
, "*End%s", lf
);
879 // Custom size support...
880 if (variable_paper_size
)
882 cupsFilePrintf(fp
, "*MaxMediaWidth: \"%.2f\"%s", max_width
, lf
);
883 cupsFilePrintf(fp
, "*MaxMediaHeight: \"%.2f\"%s", max_length
, lf
);
884 cupsFilePrintf(fp
, "*HWMargins: %.2f %.2f %.2f %.2f\n",
885 left_margin
, bottom_margin
, right_margin
, top_margin
);
887 if (custom_size_code
&& custom_size_code
->value
)
889 cupsFilePrintf(fp
, "*CustomPageSize True: \"%s\"%s",
890 custom_size_code
->value
, lf
);
892 if (strchr(custom_size_code
->value
, '\n') ||
893 strchr(custom_size_code
->value
, '\r'))
894 cupsFilePrintf(fp
, "*End%s", lf
);
898 "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]"
899 "/ImagingBBox null>>setpagedevice\"%s", lf
);
901 if ((a
= find_attr("ParamCustomPageSize", "Width")) != NULL
)
902 cupsFilePrintf(fp
, "*ParamCustomPageSize Width: %s%s", a
->value
->value
,
905 cupsFilePrintf(fp
, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
906 min_width
, max_width
, lf
);
908 if ((a
= find_attr("ParamCustomPageSize", "Height")) != NULL
)
909 cupsFilePrintf(fp
, "*ParamCustomPageSize Height: %s%s", a
->value
->value
,
912 cupsFilePrintf(fp
, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
913 min_length
, max_length
, lf
);
915 if ((a
= find_attr("ParamCustomPageSize", "WidthOffset")) != NULL
)
916 cupsFilePrintf(fp
, "*ParamCustomPageSize WidthOffset: %s%s",
917 a
->value
->value
, lf
);
919 cupsFilePrintf(fp
, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf
);
921 if ((a
= find_attr("ParamCustomPageSize", "HeightOffset")) != NULL
)
922 cupsFilePrintf(fp
, "*ParamCustomPageSize HeightOffset: %s%s",
923 a
->value
->value
, lf
);
925 cupsFilePrintf(fp
, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf
);
927 if ((a
= find_attr("ParamCustomPageSize", "Orientation")) != NULL
)
928 cupsFilePrintf(fp
, "*ParamCustomPageSize Orientation: %s%s",
929 a
->value
->value
, lf
);
931 cupsFilePrintf(fp
, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf
);
934 if (type
!= PPDC_DRIVER_PS
&& !find_attr("RequiresPageRegion", NULL
))
935 cupsFilePrintf(fp
, "*RequiresPageRegion All: True%s", lf
);
937 // All other options...
938 for (g
= (ppdcGroup
*)groups
->first(); g
; g
= (ppdcGroup
*)groups
->next())
940 if (!g
->options
->count
)
943 if (strcasecmp(g
->name
->value
, "General"))
944 cupsFilePrintf(fp
, "*OpenGroup: %s/%s%s", g
->name
->value
,
945 catalog
->find_message(g
->text
->value
), lf
);
947 for (o
= (ppdcOption
*)g
->options
->first();
949 o
= (ppdcOption
*)g
->options
->next())
951 if (!o
->choices
->count
)
954 if (!o
->text
->value
|| !strcmp(o
->name
->value
, o
->text
->value
))
955 cupsFilePrintf(fp
, "*OpenUI *%s/%s: ", o
->name
->value
,
956 catalog
->find_message(o
->name
->value
));
958 cupsFilePrintf(fp
, "*OpenUI *%s/%s: ", o
->name
->value
,
959 catalog
->find_message(o
->text
->value
));
964 cupsFilePrintf(fp
, "Boolean%s", lf
);
967 cupsFilePrintf(fp
, "PickOne%s", lf
);
970 cupsFilePrintf(fp
, "PickMany%s", lf
);
974 cupsFilePrintf(fp
, "*OrderDependency: %.1f ", o
->order
);
978 cupsFilePrintf(fp
, "AnySetup");
980 case PPDC_SECTION_DOCUMENT
:
981 cupsFilePrintf(fp
, "DocumentSetup");
983 case PPDC_SECTION_EXIT
:
984 cupsFilePrintf(fp
, "ExitServer");
986 case PPDC_SECTION_JCL
:
987 cupsFilePrintf(fp
, "JCLSetup");
989 case PPDC_SECTION_PAGE
:
990 cupsFilePrintf(fp
, "PageSetup");
992 case PPDC_SECTION_PROLOG
:
993 cupsFilePrintf(fp
, "Prolog");
997 cupsFilePrintf(fp
, " *%s%s", o
->name
->value
, lf
);
1001 // Use the programmer-supplied default...
1002 cupsFilePrintf(fp
, "*Default%s: %s%s", o
->name
->value
,
1003 o
->defchoice
->value
, lf
);
1007 // Make the first choice the default...
1008 c
= (ppdcChoice
*)o
->choices
->first();
1009 cupsFilePrintf(fp
, "*Default%s: %s%s", o
->name
->value
, c
->name
->value
,
1013 for (c
= (ppdcChoice
*)o
->choices
->first();
1015 c
= (ppdcChoice
*)o
->choices
->next())
1017 // Write this choice...
1018 if (!c
->text
->value
|| !strcmp(c
->name
->value
, c
->text
->value
))
1019 cupsFilePrintf(fp
, "*%s %s: \"%s\"%s", o
->name
->value
,
1020 catalog
->find_message(c
->name
->value
),
1021 c
->code
->value
, lf
);
1023 cupsFilePrintf(fp
, "*%s %s/%s: \"%s\"%s", o
->name
->value
,
1024 c
->name
->value
, catalog
->find_message(c
->text
->value
),
1025 c
->code
->value
, lf
);
1027 // Multi-line commands need a *End line to terminate them.
1028 if (strchr(c
->code
->value
, '\n') ||
1029 strchr(c
->code
->value
, '\r'))
1030 cupsFilePrintf(fp
, "*End%s", lf
);
1033 snprintf(query
, sizeof(query
), "?%s", o
->name
->value
);
1035 if ((a
= find_attr(query
, NULL
)) != NULL
)
1037 cupsFilePrintf(fp
, "*%s: \"%s\"\n", query
, a
->value
->value
);
1039 if (strchr(a
->value
->value
, '\n') ||
1040 strchr(a
->value
->value
, '\r'))
1041 cupsFilePrintf(fp
, "*End%s", lf
);
1044 cupsFilePrintf(fp
, "*CloseUI: *%s%s", o
->name
->value
, lf
);
1047 if (strcasecmp(g
->name
->value
, "General"))
1048 cupsFilePrintf(fp
, "*CloseGroup: %s%s", g
->name
->value
, lf
);
1053 // Add localizations for additional languages...
1054 ppdcString
*locale
; // Locale name
1055 ppdcCatalog
*locatalog
; // Message catalog for locale
1058 // Write the translation strings for each language...
1059 for (locale
= (ppdcString
*)locales
->first();
1061 locale
= (ppdcString
*)locales
->next())
1063 // Skip (US) English...
1064 if (!strcmp(locale
->value
, "en") || !strcmp(locale
->value
, "en_US"))
1067 // Skip missing languages...
1068 if ((locatalog
= src
->find_po(locale
->value
)) == NULL
)
1071 // Do the core stuff first...
1072 cupsFilePrintf(fp
, "*%s.Translation Manufacturer/%s: \"\"%s",
1074 locatalog
->find_message(manufacturer
->value
), lf
);
1076 if ((a
= find_attr("ModelName", NULL
)) != NULL
)
1077 cupsFilePrintf(fp
, "*%s.Translation ModelName/%s: \"\"%s",
1079 locatalog
->find_message(a
->value
->value
), lf
);
1080 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
1081 strlen(manufacturer
->value
)))
1082 cupsFilePrintf(fp
, "*%s.Translation ModelName/%s %s: \"\"%s",
1084 locatalog
->find_message(manufacturer
->value
),
1085 locatalog
->find_message(model_name
->value
), lf
);
1087 cupsFilePrintf(fp
, "*%s.Translation ModelName/%s: \"\"%s",
1089 locatalog
->find_message(model_name
->value
), lf
);
1091 if ((a
= find_attr("ShortNickName", NULL
)) != NULL
)
1092 cupsFilePrintf(fp
, "*%s.Translation ShortNickName/%s: \"\"%s",
1094 locatalog
->find_message(a
->value
->value
), lf
);
1095 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
1096 strlen(manufacturer
->value
)))
1097 cupsFilePrintf(fp
, "*%s.Translation ShortNickName/%s %s: \"\"%s",
1099 locatalog
->find_message(manufacturer
->value
),
1100 locatalog
->find_message(model_name
->value
), lf
);
1102 cupsFilePrintf(fp
, "*%s.Translation ShortNickName/%s: \"\"%s",
1104 locatalog
->find_message(model_name
->value
), lf
);
1106 if ((a
= find_attr("NickName", NULL
)) != NULL
)
1107 cupsFilePrintf(fp
, "*%s.Translation NickName/%s: \"\"%s",
1109 locatalog
->find_message(a
->value
->value
), lf
);
1110 else if (strncasecmp(model_name
->value
, manufacturer
->value
,
1111 strlen(manufacturer
->value
)))
1112 cupsFilePrintf(fp
, "*%s.Translation NickName/%s %s, %s: \"\"%s",
1114 locatalog
->find_message(manufacturer
->value
),
1115 locatalog
->find_message(model_name
->value
),
1116 version
->value
, lf
);
1118 cupsFilePrintf(fp
, "*%s.Translation NickName/%s, %s: \"\"%s",
1120 locatalog
->find_message(model_name
->value
),
1121 version
->value
, lf
);
1123 // Then the page sizes...
1124 cupsFilePrintf(fp
, "*%s.Translation PageSize/%s: \"\"%s", locale
->value
,
1125 locatalog
->find_message("Media Size"), lf
);
1127 for (m
= (ppdcMediaSize
*)sizes
->first();
1129 m
= (ppdcMediaSize
*)sizes
->next())
1131 cupsFilePrintf(fp
, "*%s.PageSize %s/%s: \"\"%s", locale
->value
,
1132 m
->name
->value
, locatalog
->find_message(m
->text
->value
),
1136 // Next the groups and options...
1137 for (g
= (ppdcGroup
*)groups
->first(); g
; g
= (ppdcGroup
*)groups
->next())
1139 if (!g
->options
->count
)
1142 if (strcasecmp(g
->name
->value
, "General"))
1143 cupsFilePrintf(fp
, "*%s.Translation %s/%s: \"\"%s", locale
->value
,
1145 locatalog
->find_message(g
->text
->value
), lf
);
1147 for (o
= (ppdcOption
*)g
->options
->first();
1149 o
= (ppdcOption
*)g
->options
->next())
1151 if (!o
->choices
->count
)
1154 cupsFilePrintf(fp
, "*%s.Translation %s/%s: \"\"%s", locale
->value
,
1156 locatalog
->find_message(o
->text
->value
?
1158 o
->name
->value
), lf
);
1160 for (c
= (ppdcChoice
*)o
->choices
->first();
1162 c
= (ppdcChoice
*)o
->choices
->next())
1164 // Write this choice...
1165 cupsFilePrintf(fp
, "*%s.%s %s/%s: \"\"%s", locale
->value
,
1166 o
->name
->value
, c
->name
->value
,
1167 locatalog
->find_message(c
->text
->value
?
1169 c
->name
->value
), lf
);
1174 // Finally the localizable attributes...
1175 for (a
= (ppdcAttr
*)attrs
->first(); a
; a
= (ppdcAttr
*)attrs
->next())
1177 if ((!a
->text
|| !a
->text
->value
|| !a
->text
->value
[0]) &&
1178 strncmp(a
->name
->value
, "Custom", 6) &&
1179 strncmp(a
->name
->value
, "ParamCustom", 11))
1182 if (!a
->localizable
&&
1183 strcmp(a
->name
->value
, "APCustomColorMatchingName") &&
1184 strcmp(a
->name
->value
, "APPrinterPreset") &&
1185 strcmp(a
->name
->value
, "cupsICCProfile") &&
1186 strcmp(a
->name
->value
, "cupsIPPReason") &&
1187 strcmp(a
->name
->value
, "cupsMarkerName") &&
1188 strncmp(a
->name
->value
, "Custom", 6) &&
1189 strncmp(a
->name
->value
, "ParamCustom", 11))
1192 cupsFilePrintf(fp
, "*%s.%s %s/%s: \"%s\"%s", locale
->value
,
1193 a
->name
->value
, a
->selector
->value
,
1194 locatalog
->find_message(a
->text
&& a
->text
->value
?
1195 a
->text
->value
: a
->name
->value
),
1196 ((a
->localizable
&& a
->value
->value
[0]) ||
1197 !strcmp(a
->name
->value
, "cupsIPPReason")) ?
1198 locatalog
->find_message(a
->value
->value
) : "",
1204 if (default_font
&& default_font
->value
)
1205 cupsFilePrintf(fp
, "*DefaultFont: %s%s", default_font
->value
, lf
);
1207 cupsFilePrintf(fp
, "*DefaultFont: Courier%s", lf
);
1209 for (fn
= (ppdcFont
*)fonts
->first(); fn
; fn
= (ppdcFont
*)fonts
->next())
1210 if (!strcmp(fn
->name
->value
, "*"))
1212 for (bfn
= (ppdcFont
*)src
->base_fonts
->first();
1214 bfn
= (ppdcFont
*)src
->base_fonts
->next())
1215 cupsFilePrintf(fp
, "*Font %s: %s \"%s\" %s %s%s",
1216 bfn
->name
->value
, bfn
->encoding
->value
,
1217 bfn
->version
->value
, bfn
->charset
->value
,
1218 bfn
->status
== PPDC_FONT_ROM
? "ROM" : "Disk", lf
);
1221 cupsFilePrintf(fp
, "*Font %s: %s \"%s\" %s %s%s",
1222 fn
->name
->value
, fn
->encoding
->value
, fn
->version
->value
,
1224 fn
->status
== PPDC_FONT_ROM
? "ROM" : "Disk", lf
);
1226 cupsFilePrintf(fp
, "*%% End of %s, %05d bytes.%s", pc_file_name
->value
,
1227 (int)(cupsFileTell(fp
) + 25 + strlen(pc_file_name
->value
)),