summaryrefslogtreecommitdiff
path: root/ppdc/ppdc-driver.cxx
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-02-16 00:27:39 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-02-16 00:27:39 +0000
commitac884b6a1c1c3dfe73ef7e770d91ea225002a2c3 (patch)
tree09fb84a85bf308c6a6dd45f7293c64c40fe5acdc /ppdc/ppdc-driver.cxx
parent5a738aeaea5c4dd9384a8601cc5c99be683b69ca (diff)
downloadcups-ac884b6a1c1c3dfe73ef7e770d91ea225002a2c3.tar.gz
Merge CUPS 1.4svn-r7319.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@624 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'ppdc/ppdc-driver.cxx')
-rw-r--r--ppdc/ppdc-driver.cxx1209
1 files changed, 1209 insertions, 0 deletions
diff --git a/ppdc/ppdc-driver.cxx b/ppdc/ppdc-driver.cxx
new file mode 100644
index 000000000..d59b275a1
--- /dev/null
+++ b/ppdc/ppdc-driver.cxx
@@ -0,0 +1,1209 @@
+//
+// "$Id$"
+//
+// PPD file compiler definitions for the CUPS PPD Compiler.
+//
+// Copyright 2007 by Apple Inc.
+// Copyright 2002-2006 by Easy Software Products.
+//
+// These coded instructions, statements, and computer programs are the
+// property of Apple Inc. and are protected by Federal copyright
+// law. Distribution and use rights are outlined in the file "LICENSE.txt"
+// which should have been included with this file. If this file is
+// file is missing or damaged, see the license at "http://www.cups.org/".
+//
+// Contents:
+//
+// ppdcDriver::ppdcDriver() - Create a new printer driver.
+// ppdcDriver::~ppdcDriver() - Destroy a printer driver.
+// ppdcDriver::find_attr() - Find an attribute.
+// ppdcDriver::find_group() - Find a group.
+// ppdcDriver::find_option() - Find an option.
+// ppdcDriver::set_default_size() - Set the default size name.
+// ppdcDriver::set_manufacturer() - Set the manufacturer name.
+// ppdcDriver::set_model_name() - Set the model name.
+// ppdcDriver::set_pc_file_name() - Set the PC filename.
+// ppdcDriver::set_version() - Set the version string.
+// ppdcDriver::write_ppd_file() - Write a PPD file...
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/cups.h>
+
+
+//
+// 'ppdcDriver::ppdcDriver()' - Create a new printer driver.
+//
+
+ppdcDriver::ppdcDriver(ppdcDriver *d) // I - Printer driver template
+{
+ ppdcGroup *g; // Current group
+
+
+ if (d)
+ {
+ // Bump the use count of any strings we inherit...
+ if (d->manufacturer)
+ d->manufacturer->get();
+ if (d->version)
+ d->version->get();
+ if (d->default_font)
+ d->default_font->get();
+ if (d->default_size)
+ d->default_size->get();
+ if (d->custom_size_code)
+ d->custom_size_code->get();
+
+ // Copy all of the data from the driver template...
+ copyright = new ppdcArray(d->copyright);
+ manufacturer = d->manufacturer;
+ model_name = 0;
+ pc_file_name = 0;
+ type = d->type;
+ version = d->version;
+ model_number = d->model_number;
+ manual_copies = d->manual_copies;
+ color_device = d->color_device;
+ throughput = d->throughput;
+ attrs = new ppdcArray(d->attrs);
+ constraints = new ppdcArray(d->constraints);
+ filters = new ppdcArray(d->filters);
+ fonts = new ppdcArray(d->fonts);
+ profiles = new ppdcArray(d->profiles);
+ sizes = new ppdcArray(d->sizes);
+ default_font = d->default_font;
+ default_size = d->default_size;
+ variable_paper_size = d->variable_paper_size;
+ custom_size_code = d->custom_size_code;
+ left_margin = d->left_margin;
+ bottom_margin = d->bottom_margin;
+ right_margin = d->right_margin;
+ top_margin = d->top_margin;
+ max_width = d->max_width;
+ max_length = d->max_length;
+ min_width = d->min_width;
+ min_length = d->min_length;
+
+ // Then copy the groups manually, since we want separate copies
+ // of the groups and options...
+ groups = new ppdcArray();
+
+ for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next())
+ groups->add(new ppdcGroup(g));
+ }
+ else
+ {
+ // Zero all of the data in the driver...
+ copyright = new ppdcArray();
+ manufacturer = 0;
+ model_name = 0;
+ pc_file_name = 0;
+ version = 0;
+ type = PPDC_DRIVER_CUSTOM;
+ model_number = 0;
+ manual_copies = 0;
+ color_device = 0;
+ throughput = 1;
+ attrs = new ppdcArray();
+ constraints = new ppdcArray();
+ fonts = new ppdcArray();
+ filters = new ppdcArray();
+ groups = new ppdcArray();
+ profiles = new ppdcArray();
+ sizes = new ppdcArray();
+ default_font = 0;
+ default_size = 0;
+ variable_paper_size = 0;
+ custom_size_code = 0;
+ left_margin = 0;
+ bottom_margin = 0;
+ right_margin = 0;
+ top_margin = 0;
+ max_width = 0;
+ max_length = 0;
+ min_width = 0;
+ min_length = 0;
+ }
+}
+
+
+//
+// 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver.
+//
+
+ppdcDriver::~ppdcDriver()
+{
+ delete copyright;
+
+ if (manufacturer)
+ manufacturer->release();
+ if (model_name)
+ model_name->release();
+ if (pc_file_name)
+ pc_file_name->release();
+ if (version)
+ version->release();
+ if (default_font)
+ default_font->release();
+ if (default_size)
+ default_size->release();
+ if (custom_size_code)
+ custom_size_code->release();
+
+ delete attrs;
+ delete constraints;
+ delete filters;
+ delete fonts;
+ delete groups;
+ delete profiles;
+ delete sizes;
+}
+
+
+//
+// 'ppdcDriver::find_attr()' - Find an attribute.
+//
+
+ppdcAttr * // O - Attribute or NULL
+ppdcDriver::find_attr(const char *k, // I - Keyword string
+ const char *s) // I - Spec string
+{
+ ppdcAttr *a; // Current attribute
+
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, k) &&
+ ((!s && (!a->selector->value || !a->selector->value[0])) ||
+ (!s && !a->selector->value && !strcmp(a->selector->value, s))))
+ return (a);
+
+ return (NULL);
+}
+
+
+//
+// 'ppdcDriver::find_group()' - Find a group.
+//
+
+ppdcGroup * // O - Matching group or NULL
+ppdcDriver::find_group(const char *n) // I - Group name
+{
+ ppdcGroup *g; // Current group
+
+
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ if (!strcasecmp(n, g->name->value))
+ return (g);
+
+ return (0);
+}
+
+
+//
+// 'ppdcDriver::find_option()' - Find an option.
+//
+
+ppdcOption * // O - Matching option or NULL
+ppdcDriver::find_option(const char *n) // I - Option name
+{
+ ppdcGroup *g; // Current group
+ ppdcOption *o; // Current option
+
+
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
+ if (!strcasecmp(n, o->name->value))
+ return (o);
+
+ return (0);
+}
+
+
+//
+// 'ppdcDriver::set_custom_size_code()' - Set the custom page size code.
+//
+
+void
+ppdcDriver::set_custom_size_code(const char *c)
+ // I - CustomPageSize code
+{
+ if (custom_size_code)
+ custom_size_code->release();
+
+ custom_size_code = new ppdcString(c);
+}
+
+
+//
+// 'ppdcDriver::set_default_font()' - Set the default font name.
+//
+
+void
+ppdcDriver::set_default_font(ppdcFont *f)
+ // I - Font
+{
+ if (default_font)
+ default_font->release();
+
+ if (f)
+ {
+ f->name->get();
+ default_font = f->name;
+ }
+ else
+ default_font = 0;
+}
+
+
+//
+// 'ppdcDriver::set_default_size()' - Set the default size name.
+//
+
+void
+ppdcDriver::set_default_size(ppdcMediaSize *m)
+ // I - Media size
+{
+ if (default_size)
+ default_size->release();
+
+ if (m)
+ {
+ m->name->get();
+ default_size = m->name;
+ }
+ else
+ default_size = 0;
+}
+
+
+//
+// 'ppdcDriver::set_manufacturer()' - Set the manufacturer name.
+//
+
+void
+ppdcDriver::set_manufacturer(const char *m)
+ // I - Model name
+{
+ if (manufacturer)
+ manufacturer->release();
+
+ manufacturer = new ppdcString(m);
+}
+
+
+//
+// 'ppdcDriver::set_model_name()' - Set the model name.
+//
+
+void
+ppdcDriver::set_model_name(const char *m)
+ // I - Model name
+{
+ if (model_name)
+ model_name->release();
+
+ model_name = new ppdcString(m);
+}
+
+
+//
+// 'ppdcDriver::set_pc_file_name()' - Set the PC filename.
+//
+
+void
+ppdcDriver::set_pc_file_name(const char *f)
+ // I - Filename
+{
+ if (pc_file_name)
+ pc_file_name->release();
+
+ pc_file_name = new ppdcString(f);
+}
+
+
+//
+// 'ppdcDriver::set_version()' - Set the version string.
+//
+
+void
+ppdcDriver::set_version(const char *v) // I - Version
+{
+ if (version)
+ version->release();
+
+ version = new ppdcString(v);
+}
+
+
+//
+// 'ppdcDriver::write_ppd_file()' - Write a PPD file...
+//
+
+int // O - 0 on success, -1 on failure
+ppdcDriver::write_ppd_file(
+ cups_file_t *fp, // I - PPD file
+ ppdcCatalog *catalog, // I - Message catalog
+ ppdcArray *locales, // I - Additional languages to add
+ ppdcSource *src, // I - Driver source
+ ppdcLineEnding le) // I - Line endings to use
+{
+ bool delete_cat; // Delete the catalog when we are done?
+ char query[42]; // Query attribute
+ ppdcString *s; // Copyright string
+ ppdcGroup *g; // Current group
+ ppdcOption *o; // Current option
+ ppdcChoice *c; // Current choice
+ ppdcMediaSize *m; // Current media size
+ ppdcProfile *p; // Current color profile
+ ppdcFilter *f; // Current filter
+ ppdcFont *fn, // Current font
+ *bfn; // Current base font
+ ppdcConstraint *cn; // Current constraint
+ ppdcAttr *a; // Current attribute
+ const char *lf; // Linefeed character to use
+
+
+ // If we don't have a message catalog, use an empty (English) one...
+ if (!catalog)
+ {
+ catalog = new ppdcCatalog("en");
+ delete_cat = true;
+ }
+ else
+ delete_cat = false;
+
+ // Figure out the end-of-line string...
+ if (le == PPDC_LFONLY)
+ lf = "\n";
+ else if (le == PPDC_CRONLY)
+ lf = "\r";
+ else
+ lf = "\r\n";
+
+ // Write the standard header stuff...
+ cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
+ cupsFilePrintf(fp, "*%% PPD file for %s with CUPS.%s", model_name->value, lf);
+ cupsFilePrintf(fp,
+ "*%% Created by the CUPS PPD Compiler " CUPS_SVERSION ".%s",
+ lf);
+ for (s = (ppdcString *)copyright->first();
+ s;
+ s = (ppdcString *)copyright->next())
+ cupsFilePrintf(fp, "*%% %s%s", catalog->find_message(s->value), lf);
+ cupsFilePrintf(fp, "*FormatVersion: \"4.3\"%s", lf);
+ cupsFilePrintf(fp, "*FileVersion: \"%s\"%s", version->value, lf);
+
+ a = find_attr("LanguageVersion", NULL);
+ cupsFilePrintf(fp, "*LanguageVersion: %s%s",
+ catalog->find_message(a ? a->value->value : "English"), lf);
+
+ a = find_attr("LanguageEncoding", NULL);
+ cupsFilePrintf(fp, "*LanguageEncoding: %s%s",
+ catalog->find_message(a ? a->value->value : "ISOLatin1"), lf);
+
+ cupsFilePrintf(fp, "*PCFileName: \"%s\"%s", pc_file_name->value, lf);
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "Product"))
+ break;
+
+ if (a)
+ {
+ for (; a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "Product"))
+ cupsFilePrintf(fp, "*Product: \"%s\"%s", a->value->value, lf);
+ }
+ else
+ {
+ cupsFilePrintf(fp, "*Product: \"(ESP Ghostscript)\"%s", lf);
+ cupsFilePrintf(fp, "*Product: \"(GPL Ghostscript)\"%s", lf);
+ cupsFilePrintf(fp, "*Product: \"(GNU Ghostscript)\"%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*Manufacturer: \"%s\"%s",
+ catalog->find_message(manufacturer->value), lf);
+
+ if ((a = find_attr("ModelName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*ModelName: \"%s %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
+ catalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("ShortNickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
+ catalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("NickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*NickName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), version->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*NickName: \"%s, %s\"%s",
+ catalog->find_message(model_name->value), version->value,
+ lf);
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "PSVersion"))
+ break;
+
+ if (a)
+ {
+ for (; a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "PSVersion"))
+ cupsFilePrintf(fp, "*PSVersion: \"%s\"%s", a->value->value, lf);
+ }
+ else
+ {
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 705\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 707\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 815\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 853\"%s", lf);
+ }
+
+ if ((a = find_attr("LanguageLevel", NULL)) != NULL)
+ cupsFilePrintf(fp, "*LanguageLevel: \"%s\"%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*LanguageLevel: \"3\"%s", lf);
+
+ cupsFilePrintf(fp, "*ColorDevice: %s%s", color_device ? "True" : "False", lf);
+
+ if ((a = find_attr("DefaultColorSpace", NULL)) != NULL)
+ cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*DefaultColorSpace: %s%s",
+ color_device ? "RGB" : "Gray", lf);
+
+ if ((a = find_attr("FileSystem", NULL)) != NULL)
+ cupsFilePrintf(fp, "*FileSystem: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*FileSystem: False%s", lf);
+
+ cupsFilePrintf(fp, "*Throughput: \"%d\"%s", throughput, lf);
+
+ if ((a = find_attr("LandscapeOrientation", NULL)) != NULL)
+ cupsFilePrintf(fp, "*LandscapeOrientation: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*LandscapeOrientation: Plus90%s", lf);
+
+ if ((a = find_attr("TTRasterizer", NULL)) != NULL)
+ cupsFilePrintf(fp, "*TTRasterizer: %s%s", a->value->value, lf);
+ else if (type != PPDC_DRIVER_PS)
+ cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
+
+ if (attrs->count)
+ {
+ // Write driver-defined attributes...
+ cupsFilePrintf(fp, "*%% Driver-defined attributes...%s", lf);
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ {
+ if (!strcmp(a->name->value, "Product") ||
+ !strcmp(a->name->value, "PSVersion") ||
+ !strcmp(a->name->value, "LanguageLevel") ||
+ !strcmp(a->name->value, "DefaultColorSpace") ||
+ !strcmp(a->name->value, "FileSystem") ||
+ !strcmp(a->name->value, "LandscapeOrientation") ||
+ !strcmp(a->name->value, "TTRasterizer") ||
+ !strcmp(a->name->value, "LanguageVersion") ||
+ !strcmp(a->name->value, "LanguageEncoding") ||
+ !strcmp(a->name->value, "ModelName") ||
+ !strcmp(a->name->value, "NickName") ||
+ !strcmp(a->name->value, "ShortNickName") ||
+ !strcmp(a->name->value, "cupsVersion") ||
+ a->name->value[0] == '?')
+ continue;
+
+ if (!a->selector->value || !a->selector->value[0])
+ cupsFilePrintf(fp, "*%s", a->name->value);
+ else if (!a->text->value || !a->text->value[0])
+ cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
+ else
+ cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
+ a->text->value);
+
+ if (strcmp(a->value->value, "False") &&
+ strcmp(a->value->value, "True") &&
+ strcmp(a->name->value, "1284Modes") &&
+ strcmp(a->name->value, "InkName") &&
+ strcmp(a->name->value, "PageStackOrder") &&
+ strncmp(a->name->value, "ParamCustom", 11) &&
+ strcmp(a->name->value, "Protocols") &&
+ strcmp(a->name->value, "ReferencePunch") &&
+ strncmp(a->name->value, "Default", 7))
+ {
+ cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
+ }
+ }
+
+ if (type != PPDC_DRIVER_PS || filters->count)
+ {
+ if ((a = find_attr("cupsVersion", NULL)) != NULL)
+ cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR,
+ CUPS_VERSION_MINOR, lf);
+ cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf);
+ cupsFilePrintf(fp, "*cupsManualCopies: %s%s",
+ manual_copies ? "True" : "False", lf);
+
+ if (filters->count)
+ {
+ for (f = (ppdcFilter *)filters->first();
+ f;
+ f = (ppdcFilter *)filters->next())
+ cupsFilePrintf(fp, "*cupsFilter: \"%s %d %s\"%s", f->mime_type->value,
+ f->cost, f->program->value, lf);
+ }
+ else
+ {
+ switch (type)
+ {
+ case PPDC_DRIVER_LABEL :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertolabel\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_EPSON :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertoepson\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_ESCP :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
+ "commandtoescpx\"%s", lf);
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertoescpx\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_HP :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertohp\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_PCL :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
+ "commandtopclx\"%s", lf);
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertopclx\"%s", lf);
+ break;
+
+ default :
+ break;
+ }
+ }
+
+ for (p = (ppdcProfile *)profiles->first();
+ p;
+ p = (ppdcProfile *)profiles->next())
+ cupsFilePrintf(fp,
+ "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
+ "%.3f %.3f %.3f %.3f %.3f\"%s",
+ p->resolution->value, p->media_type->value,
+ p->density, p->gamma,
+ p->profile[0], p->profile[1],
+ p->profile[2], p->profile[3],
+ p->profile[4], p->profile[5],
+ p->profile[6], p->profile[7],
+ p->profile[8], lf);
+ }
+
+ if (locales)
+ {
+ // Add localizations for additional languages...
+ ppdcString *locale; // Locale name
+ ppdcCatalog *locatalog; // Message catalog for locale
+
+
+ // Write the list of languages...
+ cupsFilePrintf(fp, "*cupsLanguages: \"en");
+
+ for (locale = (ppdcString *)locales->first();
+ locale;
+ locale = (ppdcString *)locales->next())
+ {
+ // Skip (US) English...
+ if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
+ continue;
+
+ // See if we have a po file for this language...
+ if (!src->find_po(locale->value))
+ {
+ // No, see if we can use the base file?
+ locatalog = new ppdcCatalog(locale->value);
+
+ if (locatalog->messages->count == 0)
+ {
+ // No, skip this one...
+ fprintf(stderr, "ppdc: No message catalog provided for locale %s!\n",
+ locale->value);
+ continue;
+ }
+
+ // Add the base file to the list...
+ src->po_files->add(locatalog);
+ }
+
+ cupsFilePrintf(fp, " %s", locale->value);
+ }
+
+ cupsFilePrintf(fp, "\"%s", lf);
+ }
+
+ for (cn = (ppdcConstraint *)constraints->first();
+ cn;
+ cn = (ppdcConstraint *)constraints->next())
+ {
+ // First constrain 1 against 2...
+ if (!strncmp(cn->option1->value, "*Custom", 7) ||
+ !strncmp(cn->option2->value, "*Custom", 7))
+ cupsFilePrintf(fp, "*NonUIConstraints: ");
+ else
+ cupsFilePrintf(fp, "*UIConstraints: ");
+
+ if (cn->option1->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option1->value);
+
+ if (cn->choice1->value)
+ cupsFilePrintf(fp, " %s", cn->choice1->value);
+
+ cupsFilePutChar(fp, ' ');
+
+ if (cn->option2->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option2->value);
+
+ if (cn->choice2->value)
+ cupsFilePrintf(fp, " %s", cn->choice2->value);
+
+ cupsFilePrintf(fp, "%s", lf);
+
+ // Then constrain 2 against 1...
+ if (!strncmp(cn->option1->value, "*Custom", 7) ||
+ !strncmp(cn->option2->value, "*Custom", 7))
+ cupsFilePrintf(fp, "*NonUIConstraints: ");
+ else
+ cupsFilePrintf(fp, "*UIConstraints: ");
+
+ if (cn->option2->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option2->value);
+
+ if (cn->choice2->value)
+ cupsFilePrintf(fp, " %s", cn->choice2->value);
+
+ cupsFilePutChar(fp, ' ');
+
+ if (cn->option1->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option1->value);
+
+ if (cn->choice1->value)
+ cupsFilePrintf(fp, " %s", cn->choice1->value);
+
+ cupsFilePuts(fp, lf);
+ }
+
+ // PageSize option...
+ cupsFilePrintf(fp, "*OpenUI *PageSize/Media Size: PickOne%s", lf);
+ cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageSize%s", lf);
+ cupsFilePrintf(fp, "*DefaultPageSize: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ if (m->size_code->value)
+ {
+ cupsFilePrintf(fp, "*PageSize %s/%s: \"%s\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->size_code->value, lf);
+
+ if (strchr(m->size_code->value, '\n') ||
+ strchr(m->size_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*PageSize %s/%s: \"<</PageSize[%.0f %.0f]"
+ "/ImagingBBox null>>setpagedevice\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PageSize", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PageSize: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *PageSize%s", lf);
+
+ // PageRegion option...
+ cupsFilePrintf(fp, "*OpenUI *PageRegion/Media Size: PickOne%s", lf);
+ cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageRegion%s", lf);
+ cupsFilePrintf(fp, "*DefaultPageRegion: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ if (m->region_code->value)
+ {
+ cupsFilePrintf(fp, "*PageRegion %s/%s: \"%s\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->region_code->value, lf);
+
+ if (strchr(m->region_code->value, '\n') ||
+ strchr(m->region_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*PageRegion %s/%s: \"<</PageSize[%.0f %.0f]"
+ "/ImagingBBox null>>setpagedevice\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PageRegion", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PageRegion: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *PageRegion%s", lf);
+
+ // ImageableArea info...
+ cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->left, m->bottom, m->width - m->right, m->length - m->top,
+ lf);
+
+ if ((a = find_attr("?ImageableArea", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?ImageableArea: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ // PaperDimension info...
+ cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PaperDimension", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PaperDimension: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ // Custom size support...
+ if (variable_paper_size)
+ {
+ cupsFilePrintf(fp, "*MaxMediaWidth: \"%.2f\"%s", max_width, lf);
+ cupsFilePrintf(fp, "*MaxMediaHeight: \"%.2f\"%s", max_length, lf);
+ cupsFilePrintf(fp, "*HWMargins: %.2f %.2f %.2f %.2f\n",
+ left_margin, bottom_margin, right_margin, top_margin);
+
+ if (custom_size_code && custom_size_code->value)
+ {
+ cupsFilePrintf(fp, "*CustomPageSize True: \"%s\"%s",
+ custom_size_code->value, lf);
+
+ if (strchr(custom_size_code->value, '\n') ||
+ strchr(custom_size_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]"
+ "/ImagingBBox null>>setpagedevice\"%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Width")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
+ min_width, max_width, lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
+ min_length, max_length, lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "HeightOffset")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Orientation")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
+ }
+
+ if (type != PPDC_DRIVER_PS && !find_attr("RequiresPageRegion", NULL))
+ cupsFilePrintf(fp, "*RequiresPageRegion All: True%s", lf);
+
+ // All other options...
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ {
+ if (!g->options->count)
+ continue;
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value,
+ catalog->find_message(g->text->value), lf);
+
+ for (o = (ppdcOption *)g->options->first();
+ o;
+ o = (ppdcOption *)g->options->next())
+ {
+ if (!o->choices->count)
+ continue;
+
+ if (!o->text->value || !strcmp(o->name->value, o->text->value))
+ cupsFilePrintf(fp, "*OpenUI *%s: ", o->name->value);
+ else
+ cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
+ catalog->find_message(o->text->value));
+
+ switch (o->type)
+ {
+ case PPDC_BOOLEAN :
+ cupsFilePrintf(fp, "Boolean%s", lf);
+ break;
+ default :
+ cupsFilePrintf(fp, "PickOne%s", lf);
+ break;
+ case PPDC_PICKMANY :
+ cupsFilePrintf(fp, "PickMany%s", lf);
+ break;
+ }
+
+ cupsFilePrintf(fp, "*OrderDependency: %.1f ", o->order);
+ switch (o->section)
+ {
+ default :
+ cupsFilePrintf(fp, "AnySetup");
+ break;
+ case PPDC_SECTION_DOCUMENT :
+ cupsFilePrintf(fp, "DocumentSetup");
+ break;
+ case PPDC_SECTION_EXIT :
+ cupsFilePrintf(fp, "ExitServer");
+ break;
+ case PPDC_SECTION_JCL :
+ cupsFilePrintf(fp, "JCLSetup");
+ break;
+ case PPDC_SECTION_PAGE :
+ cupsFilePrintf(fp, "PageSetup");
+ break;
+ case PPDC_SECTION_PROLOG :
+ cupsFilePrintf(fp, "Prolog");
+ break;
+ }
+
+ cupsFilePrintf(fp, " *%s%s", o->name->value, lf);
+
+ if (o->defchoice)
+ {
+ // Use the programmer-supplied default...
+ cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value,
+ o->defchoice->value, lf);
+ }
+ else
+ {
+ // Make the first choice the default...
+ c = (ppdcChoice *)o->choices->first();
+ cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, c->name->value,
+ lf);
+ }
+
+ for (c = (ppdcChoice *)o->choices->first();
+ c;
+ c = (ppdcChoice *)o->choices->next())
+ {
+ // Write this choice...
+ if (!c->text->value || !strcmp(c->name->value, c->text->value))
+ cupsFilePrintf(fp, "*%s %s: \"%s\"%s", o->name->value, c->name->value,
+ c->code->value, lf);
+ else
+ cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
+ c->name->value, catalog->find_message(c->text->value),
+ c->code->value, lf);
+
+ // Multi-line commands need a *End line to terminate them.
+ if (strchr(c->code->value, '\n') ||
+ strchr(c->code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ snprintf(query, sizeof(query), "?%s", o->name->value);
+
+ if ((a = find_attr(query, NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*%s: \"%s\"\n", query, a->value->value);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
+ }
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf);
+ }
+
+ if (locales)
+ {
+ // Add localizations for additional languages...
+ ppdcString *locale; // Locale name
+ ppdcCatalog *locatalog; // Message catalog for locale
+
+
+ // Write the translation strings for each language...
+ for (locale = (ppdcString *)locales->first();
+ locale;
+ locale = (ppdcString *)locales->next())
+ {
+ // Skip (US) English...
+ if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
+ continue;
+
+ // Skip missing languages...
+ if ((locatalog = src->find_po(locale->value)) == NULL)
+ continue;
+
+ // Do the core stuff first...
+ cupsFilePrintf(fp, "*%s.Translation Manufacturer/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value), lf);
+
+ if ((a = find_attr("ModelName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("ShortNickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("NickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value),
+ version->value, lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s, %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value),
+ version->value, lf);
+
+ // Then the page sizes...
+ cupsFilePrintf(fp, "*%s.Translation PageSize/%s: \"\"%s", locale->value,
+ locatalog->find_message("Media Size"), lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ {
+ cupsFilePrintf(fp, "*%s.PageSize %s/%s: \"\"%s", locale->value,
+ m->name->value, locatalog->find_message(m->text->value),
+ lf);
+ }
+
+ // Next the groups and options...
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ {
+ if (!g->options->count)
+ continue;
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
+ g->name->value,
+ locatalog->find_message(g->text->value), lf);
+
+ for (o = (ppdcOption *)g->options->first();
+ o;
+ o = (ppdcOption *)g->options->next())
+ {
+ if (!o->choices->count)
+ continue;
+
+ cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
+ o->name->value,
+ locatalog->find_message(o->text->value ?
+ o->text->value :
+ o->name->value), lf);
+
+ for (c = (ppdcChoice *)o->choices->first();
+ c;
+ c = (ppdcChoice *)o->choices->next())
+ {
+ // Write this choice...
+ cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"%s", locale->value,
+ o->name->value, c->name->value,
+ locatalog->find_message(c->text->value ?
+ c->text->value :
+ c->name->value), lf);
+ }
+ }
+ }
+
+ // Finally the localizable attributes...
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ {
+ if ((!a->text || !a->text->value || !a->text->value[0]) &&
+ strncmp(a->name->value, "Custom", 6) &&
+ strncmp(a->name->value, "ParamCustom", 11))
+ continue;
+
+ if (strcmp(a->name->value, "APCustomColorMatchingName") &&
+ strcmp(a->name->value, "APPrinterPreset") &&
+ strcmp(a->name->value, "cupsICCProfile") &&
+ strcmp(a->name->value, "cupsIPPReason") &&
+ strncmp(a->name->value, "Custom", 6) &&
+ strncmp(a->name->value, "ParamCustom", 11))
+ continue;
+
+ cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value,
+ a->name->value, a->selector->value,
+ locatalog->find_message(a->text && a->text->value ?
+ a->text->value : a->name->value),
+ !strcmp(a->name->value, "cupsIPPReason") ?
+ locatalog->find_message(a->value->value) : "",
+ lf);
+ }
+ }
+ }
+
+ if (default_font && default_font->value)
+ cupsFilePrintf(fp, "*DefaultFont: %s%s", default_font->value, lf);
+ else
+ cupsFilePrintf(fp, "*DefaultFont: Courier%s", lf);
+
+ for (fn = (ppdcFont *)fonts->first(); fn; fn = (ppdcFont *)fonts->next())
+ if (!strcmp(fn->name->value, "*"))
+ {
+ for (bfn = (ppdcFont *)src->base_fonts->first();
+ bfn;
+ bfn = (ppdcFont *)src->base_fonts->next())
+ cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
+ bfn->name->value, bfn->encoding->value,
+ bfn->version->value, bfn->charset->value,
+ bfn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
+ }
+ else
+ cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
+ fn->name->value, fn->encoding->value, fn->version->value,
+ fn->charset->value,
+ fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
+
+ cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value,
+ (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
+ lf);
+
+ if (delete_cat)
+ delete catalog;
+
+ return (0);
+}
+
+
+//
+// End of "$Id$".
+//