]> git.ipfire.org Git - thirdparty/cups.git/blame - ppdc/ppdc-driver.cxx
Merge changes from CUPS 1.5svn-r8857.
[thirdparty/cups.git] / ppdc / ppdc-driver.cxx
CommitLineData
ac884b6a
MS
1//
2// "$Id$"
3//
4// PPD file compiler definitions for the CUPS PPD Compiler.
5//
d2354e63 6// Copyright 2007-2009 by Apple Inc.
ac884b6a
MS
7// Copyright 2002-2006 by Easy Software Products.
8//
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/".
14//
15// Contents:
16//
94da7e34
MS
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.
97c9a8d7 22// ppdcDriver::find_option_group() - Find an option and its group.
94da7e34
MS
23// ppdcDriver::set_custom_size_code() - Set the custom page size code.
24// ppdcDriver::set_default_font() - Set the default font name.
25// ppdcDriver::set_default_size() - Set the default size name.
26// ppdcDriver::set_file_name() - Set the full filename.
27// ppdcDriver::set_manufacturer() - Set the manufacturer name.
28// ppdcDriver::set_model_name() - Set the model name.
29// ppdcDriver::set_pc_file_name() - Set the PC filename.
30// ppdcDriver::set_version() - Set the version string.
31// ppdcDriver::write_ppd_file() - Write a PPD file...
ac884b6a
MS
32//
33
34//
35// Include necessary headers...
36//
37
38e73f87 38#include "ppdc-private.h"
61cf44e2 39#include <cups/globals.h>
ac884b6a
MS
40
41
42//
43// 'ppdcDriver::ppdcDriver()' - Create a new printer driver.
44//
45
46ppdcDriver::ppdcDriver(ppdcDriver *d) // I - Printer driver template
94da7e34 47 : ppdcShared()
ac884b6a
MS
48{
49 ppdcGroup *g; // Current group
50
51
94da7e34
MS
52 PPDC_NEW;
53
ac884b6a
MS
54 if (d)
55 {
56 // Bump the use count of any strings we inherit...
57 if (d->manufacturer)
e4572d57 58 d->manufacturer->retain();
ac884b6a 59 if (d->version)
e4572d57 60 d->version->retain();
ac884b6a 61 if (d->default_font)
e4572d57 62 d->default_font->retain();
ac884b6a 63 if (d->default_size)
e4572d57 64 d->default_size->retain();
ac884b6a 65 if (d->custom_size_code)
e4572d57 66 d->custom_size_code->retain();
ac884b6a
MS
67
68 // Copy all of the data from the driver template...
69 copyright = new ppdcArray(d->copyright);
70 manufacturer = d->manufacturer;
71 model_name = 0;
bdd6c45b 72 file_name = 0;
ac884b6a
MS
73 pc_file_name = 0;
74 type = d->type;
75 version = d->version;
76 model_number = d->model_number;
77 manual_copies = d->manual_copies;
78 color_device = d->color_device;
79 throughput = d->throughput;
80 attrs = new ppdcArray(d->attrs);
81 constraints = new ppdcArray(d->constraints);
82 filters = new ppdcArray(d->filters);
83 fonts = new ppdcArray(d->fonts);
84 profiles = new ppdcArray(d->profiles);
85 sizes = new ppdcArray(d->sizes);
86 default_font = d->default_font;
87 default_size = d->default_size;
88 variable_paper_size = d->variable_paper_size;
89 custom_size_code = d->custom_size_code;
90 left_margin = d->left_margin;
91 bottom_margin = d->bottom_margin;
92 right_margin = d->right_margin;
93 top_margin = d->top_margin;
94 max_width = d->max_width;
95 max_length = d->max_length;
96 min_width = d->min_width;
97 min_length = d->min_length;
98
99 // Then copy the groups manually, since we want separate copies
100 // of the groups and options...
101 groups = new ppdcArray();
102
103 for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next())
104 groups->add(new ppdcGroup(g));
105 }
106 else
107 {
108 // Zero all of the data in the driver...
109 copyright = new ppdcArray();
110 manufacturer = 0;
111 model_name = 0;
bdd6c45b 112 file_name = 0;
ac884b6a
MS
113 pc_file_name = 0;
114 version = 0;
115 type = PPDC_DRIVER_CUSTOM;
116 model_number = 0;
117 manual_copies = 0;
118 color_device = 0;
119 throughput = 1;
120 attrs = new ppdcArray();
121 constraints = new ppdcArray();
122 fonts = new ppdcArray();
123 filters = new ppdcArray();
124 groups = new ppdcArray();
125 profiles = new ppdcArray();
126 sizes = new ppdcArray();
127 default_font = 0;
128 default_size = 0;
129 variable_paper_size = 0;
130 custom_size_code = 0;
131 left_margin = 0;
132 bottom_margin = 0;
133 right_margin = 0;
134 top_margin = 0;
135 max_width = 0;
136 max_length = 0;
137 min_width = 0;
138 min_length = 0;
139 }
140}
141
142
143//
144// 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver.
145//
146
147ppdcDriver::~ppdcDriver()
148{
94da7e34
MS
149 PPDC_DELETE;
150
e4572d57 151 copyright->release();
ac884b6a
MS
152
153 if (manufacturer)
154 manufacturer->release();
155 if (model_name)
156 model_name->release();
bdd6c45b
MS
157 if (file_name)
158 file_name->release();
ac884b6a
MS
159 if (pc_file_name)
160 pc_file_name->release();
161 if (version)
162 version->release();
163 if (default_font)
164 default_font->release();
165 if (default_size)
166 default_size->release();
167 if (custom_size_code)
168 custom_size_code->release();
169
e4572d57
MS
170 attrs->release();
171 constraints->release();
172 filters->release();
173 fonts->release();
174 groups->release();
175 profiles->release();
176 sizes->release();
ac884b6a
MS
177}
178
179
180//
181// 'ppdcDriver::find_attr()' - Find an attribute.
182//
183
184ppdcAttr * // O - Attribute or NULL
185ppdcDriver::find_attr(const char *k, // I - Keyword string
186 const char *s) // I - Spec string
187{
188 ppdcAttr *a; // Current attribute
189
190
191 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
192 if (!strcmp(a->name->value, k) &&
193 ((!s && (!a->selector->value || !a->selector->value[0])) ||
f11a948a 194 (s && a->selector->value && !strcmp(a->selector->value, s))))
ac884b6a
MS
195 return (a);
196
197 return (NULL);
198}
199
200
201//
202// 'ppdcDriver::find_group()' - Find a group.
203//
204
205ppdcGroup * // O - Matching group or NULL
206ppdcDriver::find_group(const char *n) // I - Group name
207{
208 ppdcGroup *g; // Current group
209
210
211 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
212 if (!strcasecmp(n, g->name->value))
213 return (g);
214
215 return (0);
216}
217
218
219//
220// 'ppdcDriver::find_option()' - Find an option.
221//
222
223ppdcOption * // O - Matching option or NULL
224ppdcDriver::find_option(const char *n) // I - Option name
97c9a8d7
MS
225{
226 return (find_option_group(n, (ppdcGroup **)0));
227}
228
229
230//
231// 'ppdcDriver::find_option_group()' - Find an option and its group.
232//
233
234ppdcOption * // O - Matching option or NULL
235ppdcDriver::find_option_group(
236 const char *n, // I - Option name
237 ppdcGroup **mg) // O - Matching group or NULL
ac884b6a
MS
238{
239 ppdcGroup *g; // Current group
240 ppdcOption *o; // Current option
241
242
243 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
244 for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
245 if (!strcasecmp(n, o->name->value))
97c9a8d7
MS
246 {
247 if (mg)
248 *mg = g;
249
ac884b6a 250 return (o);
97c9a8d7
MS
251 }
252
253 if (mg)
254 *mg = (ppdcGroup *)0;
ac884b6a
MS
255
256 return (0);
257}
258
259
260//
261// 'ppdcDriver::set_custom_size_code()' - Set the custom page size code.
262//
263
264void
bdd6c45b
MS
265ppdcDriver::set_custom_size_code(
266 const char *c) // I - CustomPageSize code
ac884b6a
MS
267{
268 if (custom_size_code)
269 custom_size_code->release();
270
271 custom_size_code = new ppdcString(c);
272}
273
274
275//
276// 'ppdcDriver::set_default_font()' - Set the default font name.
277//
278
279void
bdd6c45b
MS
280ppdcDriver::set_default_font(
281 ppdcFont *f) // I - Font
ac884b6a
MS
282{
283 if (default_font)
284 default_font->release();
285
286 if (f)
287 {
e4572d57 288 f->name->retain();
ac884b6a
MS
289 default_font = f->name;
290 }
291 else
292 default_font = 0;
293}
294
295
296//
297// 'ppdcDriver::set_default_size()' - Set the default size name.
298//
299
300void
bdd6c45b
MS
301ppdcDriver::set_default_size(
302 ppdcMediaSize *m) // I - Media size
ac884b6a
MS
303{
304 if (default_size)
305 default_size->release();
306
307 if (m)
308 {
e4572d57 309 m->name->retain();
ac884b6a
MS
310 default_size = m->name;
311 }
312 else
313 default_size = 0;
314}
315
316
bdd6c45b
MS
317//
318// 'ppdcDriver::set_file_name()' - Set the full filename.
319//
320
321void
322ppdcDriver::set_file_name(const char *f)// I - Filename
323{
324 if (file_name)
325 file_name->release();
326
327 file_name = new ppdcString(f);
328}
329
330
ac884b6a
MS
331//
332// 'ppdcDriver::set_manufacturer()' - Set the manufacturer name.
333//
334
335void
bdd6c45b
MS
336ppdcDriver::set_manufacturer(
337 const char *m) // I - Model name
ac884b6a
MS
338{
339 if (manufacturer)
340 manufacturer->release();
341
342 manufacturer = new ppdcString(m);
343}
344
345
346//
347// 'ppdcDriver::set_model_name()' - Set the model name.
348//
349
350void
bdd6c45b
MS
351ppdcDriver::set_model_name(
352 const char *m) // I - Model name
ac884b6a
MS
353{
354 if (model_name)
355 model_name->release();
356
357 model_name = new ppdcString(m);
358}
359
360
361//
362// 'ppdcDriver::set_pc_file_name()' - Set the PC filename.
363//
364
365void
bdd6c45b
MS
366ppdcDriver::set_pc_file_name(
367 const char *f) // I - Filename
ac884b6a
MS
368{
369 if (pc_file_name)
370 pc_file_name->release();
371
372 pc_file_name = new ppdcString(f);
373}
374
375
376//
377// 'ppdcDriver::set_version()' - Set the version string.
378//
379
380void
381ppdcDriver::set_version(const char *v) // I - Version
382{
383 if (version)
384 version->release();
385
386 version = new ppdcString(v);
387}
388
389
390//
391// 'ppdcDriver::write_ppd_file()' - Write a PPD file...
392//
393
394int // O - 0 on success, -1 on failure
395ppdcDriver::write_ppd_file(
396 cups_file_t *fp, // I - PPD file
397 ppdcCatalog *catalog, // I - Message catalog
398 ppdcArray *locales, // I - Additional languages to add
399 ppdcSource *src, // I - Driver source
400 ppdcLineEnding le) // I - Line endings to use
401{
402 bool delete_cat; // Delete the catalog when we are done?
f11a948a
MS
403 char query[42], // Query attribute
404 custom[42]; // Custom attribute
ac884b6a
MS
405 ppdcString *s; // Copyright string
406 ppdcGroup *g; // Current group
407 ppdcOption *o; // Current option
408 ppdcChoice *c; // Current choice
409 ppdcMediaSize *m; // Current media size
410 ppdcProfile *p; // Current color profile
411 ppdcFilter *f; // Current filter
412 ppdcFont *fn, // Current font
413 *bfn; // Current base font
414 ppdcConstraint *cn; // Current constraint
415 ppdcAttr *a; // Current attribute
416 const char *lf; // Linefeed character to use
417
418
419 // If we don't have a message catalog, use an empty (English) one...
420 if (!catalog)
421 {
422 catalog = new ppdcCatalog("en");
423 delete_cat = true;
424 }
425 else
426 delete_cat = false;
427
428 // Figure out the end-of-line string...
429 if (le == PPDC_LFONLY)
430 lf = "\n";
431 else if (le == PPDC_CRONLY)
432 lf = "\r";
433 else
434 lf = "\r\n";
435
436 // Write the standard header stuff...
437 cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
f11a948a
MS
438 cupsFilePrintf(fp, "*%%%%%%%% PPD file for %s with CUPS.%s",
439 model_name->value, lf);
ac884b6a 440 cupsFilePrintf(fp,
f11a948a
MS
441 "*%%%%%%%% Created by the CUPS PPD Compiler " CUPS_SVERSION
442 ".%s", lf);
ac884b6a
MS
443 for (s = (ppdcString *)copyright->first();
444 s;
445 s = (ppdcString *)copyright->next())
446 cupsFilePrintf(fp, "*%% %s%s", catalog->find_message(s->value), lf);
447 cupsFilePrintf(fp, "*FormatVersion: \"4.3\"%s", lf);
448 cupsFilePrintf(fp, "*FileVersion: \"%s\"%s", version->value, lf);
449
450 a = find_attr("LanguageVersion", NULL);
451 cupsFilePrintf(fp, "*LanguageVersion: %s%s",
452 catalog->find_message(a ? a->value->value : "English"), lf);
453
454 a = find_attr("LanguageEncoding", NULL);
455 cupsFilePrintf(fp, "*LanguageEncoding: %s%s",
456 catalog->find_message(a ? a->value->value : "ISOLatin1"), lf);
457
458 cupsFilePrintf(fp, "*PCFileName: \"%s\"%s", pc_file_name->value, lf);
459
460 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
461 if (!strcmp(a->name->value, "Product"))
462 break;
463
464 if (a)
465 {
466 for (; a; a = (ppdcAttr *)attrs->next())
467 if (!strcmp(a->name->value, "Product"))
468 cupsFilePrintf(fp, "*Product: \"%s\"%s", a->value->value, lf);
469 }
470 else
bdd6c45b 471 cupsFilePrintf(fp, "*Product: \"(%s)\"%s", model_name->value, lf);
ac884b6a
MS
472
473 cupsFilePrintf(fp, "*Manufacturer: \"%s\"%s",
474 catalog->find_message(manufacturer->value), lf);
475
476 if ((a = find_attr("ModelName", NULL)) != NULL)
477 cupsFilePrintf(fp, "*ModelName: \"%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, "*ModelName: \"%s %s\"%s",
482 catalog->find_message(manufacturer->value),
483 catalog->find_message(model_name->value), lf);
484 else
485 cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
486 catalog->find_message(model_name->value), lf);
487
488 if ((a = find_attr("ShortNickName", NULL)) != NULL)
489 cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
490 catalog->find_message(a->value->value), lf);
491 else if (strncasecmp(model_name->value, manufacturer->value,
492 strlen(manufacturer->value)))
493 cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s",
494 catalog->find_message(manufacturer->value),
495 catalog->find_message(model_name->value), lf);
496 else
497 cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
498 catalog->find_message(model_name->value), lf);
499
500 if ((a = find_attr("NickName", NULL)) != NULL)
501 cupsFilePrintf(fp, "*NickName: \"%s\"%s",
502 catalog->find_message(a->value->value), lf);
503 else if (strncasecmp(model_name->value, manufacturer->value,
504 strlen(manufacturer->value)))
505 cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s",
506 catalog->find_message(manufacturer->value),
507 catalog->find_message(model_name->value), version->value,
508 lf);
509 else
510 cupsFilePrintf(fp, "*NickName: \"%s, %s\"%s",
511 catalog->find_message(model_name->value), version->value,
512 lf);
513
514 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
515 if (!strcmp(a->name->value, "PSVersion"))
516 break;
517
518 if (a)
519 {
520 for (; a; a = (ppdcAttr *)attrs->next())
521 if (!strcmp(a->name->value, "PSVersion"))
522 cupsFilePrintf(fp, "*PSVersion: \"%s\"%s", a->value->value, lf);
523 }
524 else
bdd6c45b 525 cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 0\"%s", lf);
ac884b6a
MS
526
527 if ((a = find_attr("LanguageLevel", NULL)) != NULL)
528 cupsFilePrintf(fp, "*LanguageLevel: \"%s\"%s", a->value->value, lf);
529 else
530 cupsFilePrintf(fp, "*LanguageLevel: \"3\"%s", lf);
531
532 cupsFilePrintf(fp, "*ColorDevice: %s%s", color_device ? "True" : "False", lf);
533
534 if ((a = find_attr("DefaultColorSpace", NULL)) != NULL)
535 cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", a->value->value, lf);
536 else
537 cupsFilePrintf(fp, "*DefaultColorSpace: %s%s",
538 color_device ? "RGB" : "Gray", lf);
539
540 if ((a = find_attr("FileSystem", NULL)) != NULL)
541 cupsFilePrintf(fp, "*FileSystem: %s%s", a->value->value, lf);
542 else
543 cupsFilePrintf(fp, "*FileSystem: False%s", lf);
544
545 cupsFilePrintf(fp, "*Throughput: \"%d\"%s", throughput, lf);
546
547 if ((a = find_attr("LandscapeOrientation", NULL)) != NULL)
548 cupsFilePrintf(fp, "*LandscapeOrientation: %s%s", a->value->value, lf);
549 else
550 cupsFilePrintf(fp, "*LandscapeOrientation: Plus90%s", lf);
551
552 if ((a = find_attr("TTRasterizer", NULL)) != NULL)
553 cupsFilePrintf(fp, "*TTRasterizer: %s%s", a->value->value, lf);
554 else if (type != PPDC_DRIVER_PS)
555 cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
556
7a0cbd5e
MS
557 struct lconv *loc = localeconv();
558
ac884b6a
MS
559 if (attrs->count)
560 {
561 // Write driver-defined attributes...
562 cupsFilePrintf(fp, "*%% Driver-defined attributes...%s", lf);
563 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
564 {
565 if (!strcmp(a->name->value, "Product") ||
566 !strcmp(a->name->value, "PSVersion") ||
567 !strcmp(a->name->value, "LanguageLevel") ||
568 !strcmp(a->name->value, "DefaultColorSpace") ||
569 !strcmp(a->name->value, "FileSystem") ||
570 !strcmp(a->name->value, "LandscapeOrientation") ||
571 !strcmp(a->name->value, "TTRasterizer") ||
572 !strcmp(a->name->value, "LanguageVersion") ||
573 !strcmp(a->name->value, "LanguageEncoding") ||
574 !strcmp(a->name->value, "ModelName") ||
575 !strcmp(a->name->value, "NickName") ||
576 !strcmp(a->name->value, "ShortNickName") ||
4509bb49 577 !strcmp(a->name->value, "cupsVersion"))
ac884b6a
MS
578 continue;
579
4509bb49
MS
580 if (a->name->value[0] == '?' &&
581 (find_option(a->name->value + 1) ||
582 !strcmp(a->name->value, "?ImageableArea") ||
583 !strcmp(a->name->value, "?PageRegion") ||
584 !strcmp(a->name->value, "?PageSize") ||
585 !strcmp(a->name->value, "?PaperDimension")))
586 continue;
587
f11a948a
MS
588 if (!strncmp(a->name->value, "Custom", 6) &&
589 find_option(a->name->value + 6))
590 continue;
591
592 if (!strncmp(a->name->value, "ParamCustom", 11) &&
593 find_option(a->name->value + 11))
594 continue;
595
ac884b6a
MS
596 if (!a->selector->value || !a->selector->value[0])
597 cupsFilePrintf(fp, "*%s", a->name->value);
598 else if (!a->text->value || !a->text->value[0])
599 cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
600 else
601 cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
602 a->text->value);
603
604 if (strcmp(a->value->value, "False") &&
605 strcmp(a->value->value, "True") &&
606 strcmp(a->name->value, "1284Modes") &&
607 strcmp(a->name->value, "InkName") &&
608 strcmp(a->name->value, "PageStackOrder") &&
609 strncmp(a->name->value, "ParamCustom", 11) &&
610 strcmp(a->name->value, "Protocols") &&
611 strcmp(a->name->value, "ReferencePunch") &&
612 strncmp(a->name->value, "Default", 7))
613 {
614 cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
615
f11a948a 616 if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
ac884b6a
MS
617 cupsFilePrintf(fp, "*End%s", lf);
618 }
619 else
620 cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
621 }
622 }
623
624 if (type != PPDC_DRIVER_PS || filters->count)
625 {
626 if ((a = find_attr("cupsVersion", NULL)) != NULL)
627 cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf);
628 else
629 cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR,
630 CUPS_VERSION_MINOR, lf);
631 cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf);
632 cupsFilePrintf(fp, "*cupsManualCopies: %s%s",
633 manual_copies ? "True" : "False", lf);
634
635 if (filters->count)
636 {
637 for (f = (ppdcFilter *)filters->first();
638 f;
639 f = (ppdcFilter *)filters->next())
640 cupsFilePrintf(fp, "*cupsFilter: \"%s %d %s\"%s", f->mime_type->value,
641 f->cost, f->program->value, lf);
642 }
643 else
644 {
645 switch (type)
646 {
647 case PPDC_DRIVER_LABEL :
648 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
649 "rastertolabel\"%s", lf);
650 break;
651
652 case PPDC_DRIVER_EPSON :
653 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
654 "rastertoepson\"%s", lf);
655 break;
656
657 case PPDC_DRIVER_ESCP :
658 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
659 "commandtoescpx\"%s", lf);
660 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
661 "rastertoescpx\"%s", lf);
662 break;
663
664 case PPDC_DRIVER_HP :
665 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
666 "rastertohp\"%s", lf);
667 break;
668
669 case PPDC_DRIVER_PCL :
670 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
671 "commandtopclx\"%s", lf);
672 cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
673 "rastertopclx\"%s", lf);
674 break;
675
676 default :
677 break;
678 }
679 }
680
681 for (p = (ppdcProfile *)profiles->first();
682 p;
683 p = (ppdcProfile *)profiles->next())
7a0cbd5e
MS
684 {
685 char density[255], gamma[255], profile[9][255];
686
687 _cupsStrFormatd(density, density + sizeof(density), p->density, loc);
688 _cupsStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc);
689
690 for (int i = 0; i < 9; i ++)
691 _cupsStrFormatd(profile[i], profile[i] + sizeof(profile[0]),
692 p->profile[i], loc);
693
ac884b6a 694 cupsFilePrintf(fp,
7a0cbd5e
MS
695 "*cupsColorProfile %s/%s: \"%s %s %s %s %s %s %s %s %s %s "
696 "%s\"%s", p->resolution->value, p->media_type->value,
697 density, gamma, profile[0], profile[1], profile[2],
698 profile[3], profile[4], profile[5], profile[6], profile[7],
699 profile[8], lf);
700 }
ac884b6a
MS
701 }
702
703 if (locales)
704 {
705 // Add localizations for additional languages...
706 ppdcString *locale; // Locale name
707 ppdcCatalog *locatalog; // Message catalog for locale
708
709
710 // Write the list of languages...
711 cupsFilePrintf(fp, "*cupsLanguages: \"en");
712
713 for (locale = (ppdcString *)locales->first();
714 locale;
715 locale = (ppdcString *)locales->next())
716 {
717 // Skip (US) English...
718 if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
719 continue;
720
721 // See if we have a po file for this language...
722 if (!src->find_po(locale->value))
723 {
724 // No, see if we can use the base file?
725 locatalog = new ppdcCatalog(locale->value);
726
727 if (locatalog->messages->count == 0)
728 {
729 // No, skip this one...
61cf44e2
MS
730 _cupsLangPrintf(stderr,
731 _("ppdc: No message catalog provided for locale "
4d301e69 732 "%s\n"), locale->value);
ac884b6a
MS
733 continue;
734 }
735
736 // Add the base file to the list...
737 src->po_files->add(locatalog);
738 }
739
740 cupsFilePrintf(fp, " %s", locale->value);
741 }
742
743 cupsFilePrintf(fp, "\"%s", lf);
744 }
745
746 for (cn = (ppdcConstraint *)constraints->first();
747 cn;
748 cn = (ppdcConstraint *)constraints->next())
749 {
750 // First constrain 1 against 2...
751 if (!strncmp(cn->option1->value, "*Custom", 7) ||
752 !strncmp(cn->option2->value, "*Custom", 7))
61cf44e2 753 cupsFilePuts(fp, "*NonUIConstraints: ");
ac884b6a 754 else
61cf44e2 755 cupsFilePuts(fp, "*UIConstraints: ");
ac884b6a
MS
756
757 if (cn->option1->value[0] != '*')
758 cupsFilePutChar(fp, '*');
759
61cf44e2 760 cupsFilePuts(fp, cn->option1->value);
ac884b6a
MS
761
762 if (cn->choice1->value)
763 cupsFilePrintf(fp, " %s", cn->choice1->value);
764
765 cupsFilePutChar(fp, ' ');
766
767 if (cn->option2->value[0] != '*')
768 cupsFilePutChar(fp, '*');
769
61cf44e2 770 cupsFilePuts(fp, cn->option2->value);
ac884b6a
MS
771
772 if (cn->choice2->value)
773 cupsFilePrintf(fp, " %s", cn->choice2->value);
774
61cf44e2 775 cupsFilePuts(fp, lf);
ac884b6a
MS
776
777 // Then constrain 2 against 1...
778 if (!strncmp(cn->option1->value, "*Custom", 7) ||
779 !strncmp(cn->option2->value, "*Custom", 7))
61cf44e2 780 cupsFilePuts(fp, "*NonUIConstraints: ");
ac884b6a 781 else
61cf44e2 782 cupsFilePuts(fp, "*UIConstraints: ");
ac884b6a
MS
783
784 if (cn->option2->value[0] != '*')
785 cupsFilePutChar(fp, '*');
786
61cf44e2 787 cupsFilePuts(fp, cn->option2->value);
ac884b6a
MS
788
789 if (cn->choice2->value)
790 cupsFilePrintf(fp, " %s", cn->choice2->value);
791
792 cupsFilePutChar(fp, ' ');
793
794 if (cn->option1->value[0] != '*')
795 cupsFilePutChar(fp, '*');
796
61cf44e2 797 cupsFilePuts(fp, cn->option1->value);
ac884b6a
MS
798
799 if (cn->choice1->value)
800 cupsFilePrintf(fp, " %s", cn->choice1->value);
801
802 cupsFilePuts(fp, lf);
803 }
804
805 // PageSize option...
806 cupsFilePrintf(fp, "*OpenUI *PageSize/Media Size: PickOne%s", lf);
807 cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageSize%s", lf);
808 cupsFilePrintf(fp, "*DefaultPageSize: %s%s",
809 default_size ? default_size->value : "Letter", lf);
810
811 for (m = (ppdcMediaSize *)sizes->first();
812 m;
813 m = (ppdcMediaSize *)sizes->next())
814 if (m->size_code->value)
815 {
816 cupsFilePrintf(fp, "*PageSize %s/%s: \"%s\"%s",
817 m->name->value, catalog->find_message(m->text->value),
818 m->size_code->value, lf);
819
820 if (strchr(m->size_code->value, '\n') ||
821 strchr(m->size_code->value, '\r'))
822 cupsFilePrintf(fp, "*End%s", lf);
823 }
824 else
825 cupsFilePrintf(fp,
826 "*PageSize %s/%s: \"<</PageSize[%.0f %.0f]"
827 "/ImagingBBox null>>setpagedevice\"%s",
828 m->name->value, catalog->find_message(m->text->value),
829 m->width, m->length, lf);
830
831 if ((a = find_attr("?PageSize", NULL)) != NULL)
832 {
833 cupsFilePrintf(fp, "*?PageSize: \"%s\"%s", a->value->value, lf);
834
835 if (strchr(a->value->value, '\n') ||
836 strchr(a->value->value, '\r'))
837 cupsFilePrintf(fp, "*End%s", lf);
838 }
839
840 cupsFilePrintf(fp, "*CloseUI: *PageSize%s", lf);
841
842 // PageRegion option...
843 cupsFilePrintf(fp, "*OpenUI *PageRegion/Media Size: PickOne%s", lf);
844 cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageRegion%s", lf);
845 cupsFilePrintf(fp, "*DefaultPageRegion: %s%s",
846 default_size ? default_size->value : "Letter", lf);
847
848 for (m = (ppdcMediaSize *)sizes->first();
849 m;
850 m = (ppdcMediaSize *)sizes->next())
851 if (m->region_code->value)
852 {
853 cupsFilePrintf(fp, "*PageRegion %s/%s: \"%s\"%s",
854 m->name->value, catalog->find_message(m->text->value),
855 m->region_code->value, lf);
856
857 if (strchr(m->region_code->value, '\n') ||
858 strchr(m->region_code->value, '\r'))
859 cupsFilePrintf(fp, "*End%s", lf);
860 }
861 else
862 cupsFilePrintf(fp,
863 "*PageRegion %s/%s: \"<</PageSize[%.0f %.0f]"
864 "/ImagingBBox null>>setpagedevice\"%s",
865 m->name->value, catalog->find_message(m->text->value),
866 m->width, m->length, lf);
867
868 if ((a = find_attr("?PageRegion", NULL)) != NULL)
869 {
870 cupsFilePrintf(fp, "*?PageRegion: \"%s\"%s", a->value->value, lf);
871
872 if (strchr(a->value->value, '\n') ||
873 strchr(a->value->value, '\r'))
874 cupsFilePrintf(fp, "*End%s", lf);
875 }
876
877 cupsFilePrintf(fp, "*CloseUI: *PageRegion%s", lf);
878
879 // ImageableArea info...
880 cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
881 default_size ? default_size->value : "Letter", lf);
882
7a0cbd5e
MS
883 char left[255], right[255], bottom[255], top[255];
884
ac884b6a
MS
885 for (m = (ppdcMediaSize *)sizes->first();
886 m;
887 m = (ppdcMediaSize *)sizes->next())
7a0cbd5e
MS
888 {
889 _cupsStrFormatd(left, left + sizeof(left), m->left, loc);
890 _cupsStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc);
891 _cupsStrFormatd(right, right + sizeof(right), m->width - m->right, loc);
892 _cupsStrFormatd(top, top + sizeof(top), m->length - m->top, loc);
893
894 cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%s %s %s %s\"%s",
ac884b6a 895 m->name->value, catalog->find_message(m->text->value),
7a0cbd5e
MS
896 left, bottom, right, top, lf);
897 }
ac884b6a
MS
898
899 if ((a = find_attr("?ImageableArea", NULL)) != NULL)
900 {
901 cupsFilePrintf(fp, "*?ImageableArea: \"%s\"%s", a->value->value, lf);
902
903 if (strchr(a->value->value, '\n') ||
904 strchr(a->value->value, '\r'))
905 cupsFilePrintf(fp, "*End%s", lf);
906 }
907
908 // PaperDimension info...
909 cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
910 default_size ? default_size->value : "Letter", lf);
911
7a0cbd5e
MS
912 char width[255], length[255];
913
ac884b6a
MS
914 for (m = (ppdcMediaSize *)sizes->first();
915 m;
916 m = (ppdcMediaSize *)sizes->next())
7a0cbd5e
MS
917 {
918 _cupsStrFormatd(width, width + sizeof(width), m->width, loc);
919 _cupsStrFormatd(length, length + sizeof(length), m->length, loc);
920
921 cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%s %s\"%s",
ac884b6a 922 m->name->value, catalog->find_message(m->text->value),
7a0cbd5e
MS
923 width, length, lf);
924 }
ac884b6a
MS
925
926 if ((a = find_attr("?PaperDimension", NULL)) != NULL)
927 {
928 cupsFilePrintf(fp, "*?PaperDimension: \"%s\"%s", a->value->value, lf);
929
930 if (strchr(a->value->value, '\n') ||
931 strchr(a->value->value, '\r'))
932 cupsFilePrintf(fp, "*End%s", lf);
933 }
934
935 // Custom size support...
936 if (variable_paper_size)
937 {
7a0cbd5e
MS
938 _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
939 _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
940
941 _cupsStrFormatd(left, left + sizeof(left), left_margin, loc);
942 _cupsStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc);
943 _cupsStrFormatd(right, right + sizeof(right), right_margin, loc);
944 _cupsStrFormatd(top, top + sizeof(top), top_margin, loc);
945
946 cupsFilePrintf(fp, "*MaxMediaWidth: \"%s\"%s", width, lf);
947 cupsFilePrintf(fp, "*MaxMediaHeight: \"%s\"%s", length, lf);
948 cupsFilePrintf(fp, "*HWMargins: %s %s %s %s%s", left, bottom, right, top,
949 lf);
ac884b6a
MS
950
951 if (custom_size_code && custom_size_code->value)
952 {
953 cupsFilePrintf(fp, "*CustomPageSize True: \"%s\"%s",
954 custom_size_code->value, lf);
955
956 if (strchr(custom_size_code->value, '\n') ||
957 strchr(custom_size_code->value, '\r'))
958 cupsFilePrintf(fp, "*End%s", lf);
959 }
960 else
961 cupsFilePrintf(fp,
962 "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]"
963 "/ImagingBBox null>>setpagedevice\"%s", lf);
964
965 if ((a = find_attr("ParamCustomPageSize", "Width")) != NULL)
966 cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
967 lf);
968 else
7a0cbd5e
MS
969 {
970 char width0[255];
971
972 _cupsStrFormatd(width0, width0 + sizeof(width0), min_width, loc);
973 _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
974
975 cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s%s",
976 width0, width, lf);
977 }
ac884b6a
MS
978
979 if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
980 cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
981 lf);
982 else
7a0cbd5e
MS
983 {
984 char length0[255];
985
986 _cupsStrFormatd(length0, length0 + sizeof(length0), min_length, loc);
987 _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
988
989 cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s%s",
990 length0, length, lf);
991 }
ac884b6a
MS
992
993 if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
994 cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
995 a->value->value, lf);
996 else
997 cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf);
998
999 if ((a = find_attr("ParamCustomPageSize", "HeightOffset")) != NULL)
1000 cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: %s%s",
1001 a->value->value, lf);
1002 else
1003 cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf);
1004
1005 if ((a = find_attr("ParamCustomPageSize", "Orientation")) != NULL)
1006 cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: %s%s",
1007 a->value->value, lf);
1008 else
1009 cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
1010 }
1011
ac884b6a
MS
1012 // All other options...
1013 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
1014 {
1015 if (!g->options->count)
1016 continue;
1017
1018 if (strcasecmp(g->name->value, "General"))
1019 cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value,
1020 catalog->find_message(g->text->value), lf);
1021
1022 for (o = (ppdcOption *)g->options->first();
1023 o;
1024 o = (ppdcOption *)g->options->next())
1025 {
1026 if (!o->choices->count)
1027 continue;
1028
1029 if (!o->text->value || !strcmp(o->name->value, o->text->value))
d1c13e16 1030 cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
d2354e63 1031 catalog->find_message(o->name->value));
ac884b6a
MS
1032 else
1033 cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
1034 catalog->find_message(o->text->value));
1035
1036 switch (o->type)
1037 {
1038 case PPDC_BOOLEAN :
1039 cupsFilePrintf(fp, "Boolean%s", lf);
1040 break;
1041 default :
1042 cupsFilePrintf(fp, "PickOne%s", lf);
1043 break;
1044 case PPDC_PICKMANY :
1045 cupsFilePrintf(fp, "PickMany%s", lf);
1046 break;
1047 }
1048
7a0cbd5e
MS
1049 char order[255];
1050 _cupsStrFormatd(order, order + sizeof(order), o->order, loc);
1051
1052 cupsFilePrintf(fp, "*OrderDependency: %s ", order);
ac884b6a
MS
1053 switch (o->section)
1054 {
1055 default :
1056 cupsFilePrintf(fp, "AnySetup");
1057 break;
1058 case PPDC_SECTION_DOCUMENT :
1059 cupsFilePrintf(fp, "DocumentSetup");
1060 break;
1061 case PPDC_SECTION_EXIT :
1062 cupsFilePrintf(fp, "ExitServer");
1063 break;
1064 case PPDC_SECTION_JCL :
1065 cupsFilePrintf(fp, "JCLSetup");
1066 break;
1067 case PPDC_SECTION_PAGE :
1068 cupsFilePrintf(fp, "PageSetup");
1069 break;
1070 case PPDC_SECTION_PROLOG :
1071 cupsFilePrintf(fp, "Prolog");
1072 break;
1073 }
1074
1075 cupsFilePrintf(fp, " *%s%s", o->name->value, lf);
1076
1077 if (o->defchoice)
1078 {
1079 // Use the programmer-supplied default...
1080 cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value,
1081 o->defchoice->value, lf);
1082 }
1083 else
1084 {
1085 // Make the first choice the default...
1086 c = (ppdcChoice *)o->choices->first();
1087 cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, c->name->value,
1088 lf);
1089 }
1090
1091 for (c = (ppdcChoice *)o->choices->first();
1092 c;
1093 c = (ppdcChoice *)o->choices->next())
1094 {
1095 // Write this choice...
1096 if (!c->text->value || !strcmp(c->name->value, c->text->value))
d2354e63
MS
1097 cupsFilePrintf(fp, "*%s %s: \"%s\"%s", o->name->value,
1098 catalog->find_message(c->name->value),
ac884b6a
MS
1099 c->code->value, lf);
1100 else
1101 cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
1102 c->name->value, catalog->find_message(c->text->value),
1103 c->code->value, lf);
1104
1105 // Multi-line commands need a *End line to terminate them.
1106 if (strchr(c->code->value, '\n') ||
1107 strchr(c->code->value, '\r'))
1108 cupsFilePrintf(fp, "*End%s", lf);
1109 }
1110
1111 snprintf(query, sizeof(query), "?%s", o->name->value);
1112
1113 if ((a = find_attr(query, NULL)) != NULL)
1114 {
f11a948a 1115 cupsFilePrintf(fp, "*%s: \"%s\"%s", query, a->value->value, lf);
ac884b6a
MS
1116
1117 if (strchr(a->value->value, '\n') ||
1118 strchr(a->value->value, '\r'))
1119 cupsFilePrintf(fp, "*End%s", lf);
1120 }
1121
1122 cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
f11a948a
MS
1123
1124 snprintf(custom, sizeof(custom), "Custom%s", o->name->value);
1125 if ((a = find_attr(custom, "True")) != NULL)
1126 {
1127 // Output custom option information...
1128 cupsFilePrintf(fp, "*%s True: \"%s\"%s", custom, a->value->value, lf);
1129 if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
1130 cupsFilePrintf(fp, "*End%s", lf);
1131
1132 snprintf(custom, sizeof(custom), "ParamCustom%s", o->name->value);
1133 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
1134 {
1135 if (strcmp(a->name->value, custom))
1136 continue;
1137
1138 if (!a->selector->value || !a->selector->value[0])
1139 cupsFilePrintf(fp, "*%s", a->name->value);
1140 else if (!a->text->value || !a->text->value[0])
1141 cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
1142 else
1143 cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
1144 a->text->value);
1145
1146 cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
1147 }
1148 }
ac884b6a
MS
1149 }
1150
1151 if (strcasecmp(g->name->value, "General"))
1152 cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf);
1153 }
1154
1155 if (locales)
1156 {
1157 // Add localizations for additional languages...
1158 ppdcString *locale; // Locale name
1159 ppdcCatalog *locatalog; // Message catalog for locale
1160
1161
1162 // Write the translation strings for each language...
1163 for (locale = (ppdcString *)locales->first();
1164 locale;
1165 locale = (ppdcString *)locales->next())
1166 {
1167 // Skip (US) English...
1168 if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
1169 continue;
1170
1171 // Skip missing languages...
1172 if ((locatalog = src->find_po(locale->value)) == NULL)
1173 continue;
1174
1175 // Do the core stuff first...
1176 cupsFilePrintf(fp, "*%s.Translation Manufacturer/%s: \"\"%s",
1177 locale->value,
1178 locatalog->find_message(manufacturer->value), lf);
1179
1180 if ((a = find_attr("ModelName", NULL)) != NULL)
1181 cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
1182 locale->value,
1183 locatalog->find_message(a->value->value), lf);
1184 else if (strncasecmp(model_name->value, manufacturer->value,
1185 strlen(manufacturer->value)))
1186 cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s",
1187 locale->value,
1188 locatalog->find_message(manufacturer->value),
1189 locatalog->find_message(model_name->value), lf);
1190 else
1191 cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
1192 locale->value,
1193 locatalog->find_message(model_name->value), lf);
1194
1195 if ((a = find_attr("ShortNickName", NULL)) != NULL)
1196 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
1197 locale->value,
1198 locatalog->find_message(a->value->value), lf);
1199 else if (strncasecmp(model_name->value, manufacturer->value,
1200 strlen(manufacturer->value)))
1201 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s",
1202 locale->value,
1203 locatalog->find_message(manufacturer->value),
1204 locatalog->find_message(model_name->value), lf);
1205 else
1206 cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
1207 locale->value,
1208 locatalog->find_message(model_name->value), lf);
1209
1210 if ((a = find_attr("NickName", NULL)) != NULL)
1211 cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s",
1212 locale->value,
1213 locatalog->find_message(a->value->value), lf);
1214 else if (strncasecmp(model_name->value, manufacturer->value,
1215 strlen(manufacturer->value)))
1216 cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s",
1217 locale->value,
1218 locatalog->find_message(manufacturer->value),
1219 locatalog->find_message(model_name->value),
1220 version->value, lf);
1221 else
1222 cupsFilePrintf(fp, "*%s.Translation NickName/%s, %s: \"\"%s",
1223 locale->value,
1224 locatalog->find_message(model_name->value),
1225 version->value, lf);
1226
1227 // Then the page sizes...
1228 cupsFilePrintf(fp, "*%s.Translation PageSize/%s: \"\"%s", locale->value,
1229 locatalog->find_message("Media Size"), lf);
1230
1231 for (m = (ppdcMediaSize *)sizes->first();
1232 m;
1233 m = (ppdcMediaSize *)sizes->next())
1234 {
1235 cupsFilePrintf(fp, "*%s.PageSize %s/%s: \"\"%s", locale->value,
1236 m->name->value, locatalog->find_message(m->text->value),
1237 lf);
1238 }
1239
1240 // Next the groups and options...
1241 for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
1242 {
1243 if (!g->options->count)
1244 continue;
1245
1246 if (strcasecmp(g->name->value, "General"))
1247 cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
1248 g->name->value,
1249 locatalog->find_message(g->text->value), lf);
1250
1251 for (o = (ppdcOption *)g->options->first();
1252 o;
1253 o = (ppdcOption *)g->options->next())
1254 {
1255 if (!o->choices->count)
1256 continue;
1257
1258 cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
1259 o->name->value,
1260 locatalog->find_message(o->text->value ?
1261 o->text->value :
1262 o->name->value), lf);
1263
1264 for (c = (ppdcChoice *)o->choices->first();
1265 c;
1266 c = (ppdcChoice *)o->choices->next())
1267 {
1268 // Write this choice...
1269 cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"%s", locale->value,
1270 o->name->value, c->name->value,
1271 locatalog->find_message(c->text->value ?
1272 c->text->value :
1273 c->name->value), lf);
1274 }
1275 }
1276 }
1277
1278 // Finally the localizable attributes...
1279 for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
1280 {
1281 if ((!a->text || !a->text->value || !a->text->value[0]) &&
1282 strncmp(a->name->value, "Custom", 6) &&
1283 strncmp(a->name->value, "ParamCustom", 11))
1284 continue;
1285
bdd6c45b
MS
1286 if (!a->localizable &&
1287 strcmp(a->name->value, "APCustomColorMatchingName") &&
ac884b6a
MS
1288 strcmp(a->name->value, "APPrinterPreset") &&
1289 strcmp(a->name->value, "cupsICCProfile") &&
1290 strcmp(a->name->value, "cupsIPPReason") &&
bdd6c45b 1291 strcmp(a->name->value, "cupsMarkerName") &&
ac884b6a
MS
1292 strncmp(a->name->value, "Custom", 6) &&
1293 strncmp(a->name->value, "ParamCustom", 11))
1294 continue;
1295
1296 cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value,
1297 a->name->value, a->selector->value,
1298 locatalog->find_message(a->text && a->text->value ?
1299 a->text->value : a->name->value),
bdd6c45b
MS
1300 ((a->localizable && a->value->value[0]) ||
1301 !strcmp(a->name->value, "cupsIPPReason")) ?
ac884b6a
MS
1302 locatalog->find_message(a->value->value) : "",
1303 lf);
1304 }
1305 }
1306 }
1307
1308 if (default_font && default_font->value)
1309 cupsFilePrintf(fp, "*DefaultFont: %s%s", default_font->value, lf);
1310 else
1311 cupsFilePrintf(fp, "*DefaultFont: Courier%s", lf);
1312
1313 for (fn = (ppdcFont *)fonts->first(); fn; fn = (ppdcFont *)fonts->next())
1314 if (!strcmp(fn->name->value, "*"))
1315 {
1316 for (bfn = (ppdcFont *)src->base_fonts->first();
1317 bfn;
1318 bfn = (ppdcFont *)src->base_fonts->next())
1319 cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
1320 bfn->name->value, bfn->encoding->value,
1321 bfn->version->value, bfn->charset->value,
1322 bfn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
1323 }
1324 else
1325 cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
1326 fn->name->value, fn->encoding->value, fn->version->value,
1327 fn->charset->value,
1328 fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
1329
1330 cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value,
1331 (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
1332 lf);
1333
1334 if (delete_cat)
e4572d57 1335 catalog->release();
ac884b6a
MS
1336
1337 return (0);
1338}
1339
1340
1341//
1342// End of "$Id$".
1343//