]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Merge CUPS 1.4svn-r7319.
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Sat, 16 Feb 2008 00:27:39 +0000 (00:27 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Sat, 16 Feb 2008 00:27:39 +0000 (00:27 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@624 a1ca3aef-8c08-0410-bb20-df032aa958be

155 files changed:
CHANGES-1.3.txt
Makedefs.in
Makefile
backend/pap.c
backend/snmp.c
backend/usb-darwin.c
cgi-bin/admin.c
cgi-bin/classes.c
cgi-bin/printers.c
config-scripts/cups-common.m4
config-scripts/cups-compiler.m4
config-scripts/cups-defaults.m4
config.h.in
cups/Makefile
cups/api-filter.header
cups/api-filter.shtml
cups/backend.c
cups/globals.h
cups/http-support.c
cups/libcups.exp
cups/raster.h [moved from filter/raster.h with 99% similarity]
cups/snmp.c
cups/snmp.h
cups/testsnmp.c
data/Makefile
data/epson.h [new file with mode: 0644]
data/escp.h [new file with mode: 0644]
data/font.defs [new file with mode: 0644]
data/hp.h [new file with mode: 0644]
data/label.h [new file with mode: 0644]
data/media.defs [new file with mode: 0644]
data/pcl.h [new file with mode: 0644]
data/raster.defs [new file with mode: 0644]
doc/cups-printable.css
doc/cups.css
doc/help/api-array.html
doc/help/api-cups.html
doc/help/api-filedir.html
doc/help/api-filter.html
doc/help/api-httpipp.html
doc/help/api-overview.html
doc/help/api-ppd.html
doc/help/api-raster.html
driver/Dependencies [new file with mode: 0644]
driver/Makefile [new file with mode: 0644]
driver/attr.c [new file with mode: 0644]
driver/check.c [new file with mode: 0644]
driver/cmyk.c [new file with mode: 0644]
driver/commandtoescpx.c [new file with mode: 0644]
driver/commandtopclx.c [new file with mode: 0644]
driver/dither.c [new file with mode: 0644]
driver/driver.h [new file with mode: 0644]
driver/lut.c [new file with mode: 0644]
driver/pack.c [new file with mode: 0644]
driver/pcl-common.c [new file with mode: 0644]
driver/pcl-common.h [new file with mode: 0644]
driver/rastertoescpx.c [new file with mode: 0644]
driver/rastertopclx.c [new file with mode: 0644]
driver/rgb.c [new file with mode: 0644]
driver/srgb.c [new file with mode: 0644]
driver/testcmyk.c [new file with mode: 0644]
driver/testdither.c [new file with mode: 0644]
driver/testdriver.c
driver/testrgb.c [new file with mode: 0644]
filter/Dependencies
filter/Makefile
filter/image-private.h
filter/image.h
filter/imagetoraster.c
filter/rasterbench.c
filter/rastertoepson.c
filter/rastertohp.c
filter/rastertolabel.c
locale/Makefile
locale/ppdc.pot [new file with mode: 0644]
locale/ppdc_da.po [new file with mode: 0644]
locale/ppdc_de.po [new file with mode: 0644]
locale/ppdc_es.po [new file with mode: 0644]
locale/ppdc_et.po [new file with mode: 0644]
locale/ppdc_fi.po [new file with mode: 0644]
locale/ppdc_fr.po [new file with mode: 0644]
locale/ppdc_he.po [new file with mode: 0644]
locale/ppdc_it.po [new file with mode: 0644]
locale/ppdc_ja.po [new file with mode: 0644]
locale/ppdc_ko.po [new file with mode: 0644]
locale/ppdc_nl.po [new file with mode: 0644]
locale/ppdc_no.po [new file with mode: 0644]
locale/ppdc_pl.po [new file with mode: 0644]
locale/ppdc_pt.po [new file with mode: 0644]
locale/ppdc_pt_BR.po [new file with mode: 0644]
locale/ppdc_ru.po [new file with mode: 0644]
locale/ppdc_sv.po [new file with mode: 0644]
locale/ppdc_zh.po [new file with mode: 0644]
locale/ppdc_zh_TW.po [new file with mode: 0644]
man/Makefile
man/commandtoescpx.man [new file with mode: 0644]
man/commandtopclx.man [new file with mode: 0644]
man/ppdc.man [new file with mode: 0644]
man/ppdcfile.man [new file with mode: 0644]
man/ppdhtml.man [new file with mode: 0644]
man/ppdi.man [new file with mode: 0644]
man/ppdmerge.man [new file with mode: 0644]
man/ppdpo.man [new file with mode: 0644]
man/rastertoescpx.man [new file with mode: 0644]
man/rastertopclx.man [new file with mode: 0644]
packaging/cups.list.in
packaging/cups.spec.in
ppdc/Dependencies [new file with mode: 0644]
ppdc/Makefile [new file with mode: 0644]
ppdc/drv.cxx [new file with mode: 0644]
ppdc/foo-fr.po [new file with mode: 0644]
ppdc/foo.drv [new file with mode: 0644]
ppdc/ppdc-array.cxx [new file with mode: 0644]
ppdc/ppdc-attr.cxx [new file with mode: 0644]
ppdc/ppdc-catalog.cxx [new file with mode: 0644]
ppdc/ppdc-choice.cxx [new file with mode: 0644]
ppdc/ppdc-constraint.cxx [new file with mode: 0644]
ppdc/ppdc-driver.cxx [new file with mode: 0644]
ppdc/ppdc-file.cxx [new file with mode: 0644]
ppdc/ppdc-filter.cxx [new file with mode: 0644]
ppdc/ppdc-font.cxx [new file with mode: 0644]
ppdc/ppdc-group.cxx [new file with mode: 0644]
ppdc/ppdc-import.cxx [new file with mode: 0644]
ppdc/ppdc-mediasize.cxx [new file with mode: 0644]
ppdc/ppdc-message.cxx [new file with mode: 0644]
ppdc/ppdc-option.cxx [new file with mode: 0644]
ppdc/ppdc-profile.cxx [new file with mode: 0644]
ppdc/ppdc-shared.cxx [new file with mode: 0644]
ppdc/ppdc-source.cxx [new file with mode: 0644]
ppdc/ppdc-string.cxx [new file with mode: 0644]
ppdc/ppdc-variable.cxx [new file with mode: 0644]
ppdc/ppdc.cxx [new file with mode: 0644]
ppdc/ppdc.h [new file with mode: 0644]
ppdc/ppdhtml.cxx [new file with mode: 0644]
ppdc/ppdi.cxx [new file with mode: 0644]
ppdc/ppdmerge.cxx [new file with mode: 0644]
ppdc/ppdpo.cxx [new file with mode: 0644]
scheduler/auth.c
scheduler/auth.h
scheduler/cert.h
scheduler/client.c
scheduler/conf.c
scheduler/conf.h
scheduler/cups-driverd.c
scheduler/cupsd.h
scheduler/ipp.c
scheduler/job.c
scheduler/log.c
scheduler/main.c
systemv/Dependencies
systemv/cupstestppd.c
templates/Makefile
templates/classes.tmpl
templates/header.tmpl.in
templates/printers.tmpl

index 3e05bf7dce7cbfe92bb6f0b4592b9963afe39208..2117b7a8fea44dac3ad87e55f4df8d7cedec1ff7 100644 (file)
@@ -4,6 +4,19 @@ CHANGES-1.3.txt
 CHANGES IN CUPS V1.3.6
 
        - Documentation updates (STR #2646, STR #2647, STR #2649)
+       - Fixed a problem with the web interface "Use Kerberos
+         Authentication" check box (STR #2703)
+       - The scheduler unconditionally overwrote the printer-state-
+         message with "process-name failed" when a filter or backend
+         failed, preventing a useful error message from being shown
+         to the user.
+       - Policies on CUPS-Move-Job didn't work as expected (STR
+         #2699)
+       - The configure script only supported D-BUS on Linux
+         (STR #2702)
+       - The scheduler did not support </LimitExcept> (STR #2701)
+       - The scheduler did not reset the job-hold-until attribute
+         after a job's hold time was reached.
        - The scheduler did not support printer supply attributes
          (STR #1307)
        - The Kerberos credentials provided by some Windows KDCs
index ad73a3108e6143b5a304e4540e7252a2d6996f63..1868ee86169b2903d616d39500dbcf0b6d34362c 100644 (file)
@@ -20,6 +20,7 @@
 AR             =       @AR@
 AWK            =       @AWK@
 CC             =       @LIBTOOL@ @CC@
+CXX            =       @LIBTOOL@ @CXX@
 DSO            =       @DSO@
 HTMLDOC                =       @HTMLDOC@
 INSTALL                =       @INSTALL@
@@ -109,12 +110,16 @@ INSTALLSTATIC     =       @INSTALLSTATIC@
 
 ALL_CFLAGS     =       -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \
                        @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
+ALL_CXXFLAGS   =       -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \
+                       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
 ARCHFLAGS      =       @ARCHFLAGS@
 ARFLAGS                =       @ARFLAGS@
 BACKLIBS       =       @BACKLIBS@
 CFLAGS         =       @CPPFLAGS@ @CFLAGS@
 COMMONLIBS     =       @LIBS@
 CUPSDLIBS      =       @CUPSDLIBS@
+CXXFLAGS       =       @CPPFLAGS@ @CXXFLAGS@
+CXXLIBS                =       @CXXLIBS@
 DSOFLAGS       =       @DSOFLAGS@
 DSOLIBS                =       @DSOLIBS@ $(COMMONLIBS)
 DNSSDLIBS      =       @DNSSDLIBS@
@@ -237,7 +242,7 @@ DBUSDIR             =       @DBUSDIR@
 #
 
 .SILENT:
-.SUFFIXES:     .1 .1.gz .1m .1m.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .h .man .o .32.o .64.o .gz
+.SUFFIXES:     .1 .1.gz .1m .1m.gz .3 .3.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .cxx .h .man .o .32.o .64.o .gz
 
 .c.o:
        echo Compiling $<...
@@ -251,12 +256,16 @@ DBUSDIR           =       @DBUSDIR@
        echo Compiling 64-bit $<...
        $(CC) $(ARCH64FLAGS) $(OPTIM) $(ALL_CFLAGS) -c -o $@ $<
 
-.man.1 .man.1m .man.5 .man.7 .man.8:
+.cxx.o:
+       echo Compiling $<...
+       $(CXX) $(ARCHFLAGS) $(OPTIM) $(ALL_CXXFLAGS) -c $<
+
+.man.1 .man.1m .man.3 .man.5 .man.7 .man.8:
        echo Linking $<...
        $(RM) $@
        $(LN) $< $@
 
-.man.1.gz .man.1m.gz .man.5.gz .man.7.gz .man.8.gz .man.gz:
+.man.1.gz .man.1m.gz .man.3.gz .man.5.gz .man.7.gz .man.8.gz .man.gz:
        echo -n Compressing $<...
        $(RM) $@
        gzip -v9 <$< >$@
index 52408267373ba2ded92327320a69d7669ebf1378..18b871f58f24009b4a72af1893d93f83662bc25c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,8 +19,8 @@ include Makedefs
 # Directories to make...
 #
 
-DIRS   =       cups backend berkeley cgi-bin filter locale man monitor \
-               notifier scheduler systemv test \
+DIRS   =       cups filter backend berkeley cgi-bin driver locale man monitor \
+               notifier ppdc scheduler systemv test \
                $(PHPDIR) \
                conf data doc $(FONTS) ppd templates
 
@@ -31,6 +31,10 @@ DIRS =       cups backend berkeley cgi-bin filter locale man monitor \
 
 all:
        chmod +x cups-config
+       echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
+       echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
+       echo Using LDFLAGS="$(LDFLAGS)"
+       echo Using LIBS="$(LIBS)"
        for dir in $(DIRS); do\
                echo Making all in $$dir... ;\
                (cd $$dir ; $(MAKE) $(MFLAGS)) || exit 1;\
index 461c91fee42cc4256fc2fa6e9a9bae0ffaf36ffd..f89047e1d6926aadc2ccae1f0e2135995a248c94 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * "$Id: pap.c 7010 2007-10-10 21:08:51Z mike $"
 *
-* © Copyright 2004-2008 Apple Computer, Inc. All rights reserved.
+* Copyright 2004-2008 Apple Inc. All rights reserved.
 * 
 * IMPORTANT:  This Apple software is supplied to you by Apple Computer,
 * Inc. ("Apple") in consideration of your agreement to the following
index a001ff8642b760aaa763dc886bf60f9fad85c2fc..9b4532948fef7af78bd6b3367c501b5e72cad26b 100644 (file)
@@ -175,9 +175,9 @@ static cups_array_t *Addresses = NULL;
 static cups_array_t    *Communities = NULL;
 static cups_array_t    *Devices = NULL;
 static int             DebugLevel = 0;
-static int             DeviceDescOID[] = { CUPS_OID_hrDeviceDescr, 1, 0 };
+static int             DeviceDescOID[] = { CUPS_OID_hrDeviceDescr, 1, -1 };
 static unsigned                DeviceDescRequest;
-static int             DeviceTypeOID[] = { CUPS_OID_hrDeviceType, 1, 0 };
+static int             DeviceTypeOID[] = { CUPS_OID_hrDeviceType, 1, -1 };
 static unsigned                DeviceTypeRequest;
 static cups_array_t    *DeviceURIs = NULL;
 static int             HostNameLookups = 0;
@@ -236,7 +236,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
   * Open the SNMP socket...
   */
 
-  if ((fd = cupsSNMPOpen()) < 0)
+  if ((fd = cupsSNMPOpen(AF_INET)) < 0)
     return (1);
 
  /*
@@ -719,7 +719,8 @@ probe_device(snmp_cache_t *device)  /* I - Device */
   for (device_uri = (device_uri_t *)cupsArrayFirst(DeviceURIs);
        device_uri;
        device_uri = (device_uri_t *)cupsArrayNext(DeviceURIs))
-    if (!regexec(&(device_uri->re), device->make_and_model, 0, NULL, 0))
+    if (device->make_and_model &&
+        !regexec(&(device_uri->re), device->make_and_model, 0, NULL, 0))
     {
      /*
       * Found a match, add the URIs...
index 88a7a40766e71302578013945ec6e5593ef426dc..4e9826db55742c03ed7d7643772a633fa0dbf291 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * "$Id: usb-darwin.c 6993 2007-09-28 18:05:28Z mike $"
 *
-* Copyright � 2005-2008 Apple Inc. All rights reserved.
+* Copyright 2005-2008 Apple Inc. All rights reserved.
 *
 * IMPORTANT:  This Apple software is supplied to you by Apple Computer,
 * Inc. ("Apple") in consideration of your agreement to the following
@@ -83,6 +83,7 @@
 #include <fcntl.h>
 #include <termios.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <libgen.h>
 #include <mach/mach.h>
@@ -314,7 +315,8 @@ print_device(const char *uri,               /* I - Device URI */
   OSStatus       status;               /* Function results */
   pthread_t      read_thread_id,       /* Read thread */
                  sidechannel_thread_id;/* Side-channel thread */
-  int            sidechannel_started = 0;/* Was the side-channel thread started? */
+  int            have_sidechannel = 0; /* Was the side-channel thread started? */
+  struct stat     sidechannel_info;    /* Side-channel file descriptor info */
   char           print_buffer[8192],   /* Print data buffer */
                  *print_ptr;           /* Pointer into print data buffer */
   UInt32         location;             /* Unique location in bus topology */
@@ -329,6 +331,17 @@ print_device(const char *uri,              /* I - Device URI */
   struct timespec cond_timeout;                /* pthread condition timeout */
 
 
+ /*
+  * See if the side-channel descriptor is valid...
+  */
+
+  have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) &&
+                     S_ISSOCK(sidechannel_info.st_mode);
+
+ /*
+  * Localize using CoreFoundation...
+  */
+
   setup_cfLanguage();
 
   parse_options(options, serial, sizeof(serial), &location, &g.wait_eof);
@@ -442,21 +455,14 @@ print_device(const char *uri,             /* I - Device URI */
   }
 
  /*
-  * Start the side channel thread only if the descriptor is valid
-  * (i.e. it's not when the backend is used for auto-setup)...
+  * Start the side channel thread if the descriptor is valid...
   */
 
   pthread_mutex_init(&g.readwrite_lock_mutex, NULL);
   pthread_cond_init(&g.readwrite_lock_cond, NULL);
   g.readwrite_lock = 1;
 
-  FD_ZERO(&input_set);
-  FD_SET(CUPS_SC_FD, &input_set);
-
-  stimeout.tv_sec  = 0;
-  stimeout.tv_usec = 0;
-
-  if ((select(CUPS_SC_FD+1, &input_set, NULL, NULL, &stimeout)) >= 0)
+  if (have_sidechannel)
   {
     g.sidechannel_thread_stop = 0;
     g.sidechannel_thread_done = 0;
@@ -469,8 +475,6 @@ print_device(const char *uri,               /* I - Device URI */
       _cupsLangPuts(stderr, _("WARNING: Couldn't create side channel\n"));
       return CUPS_BACKEND_STOP;
     }
-
-    sidechannel_started = 1;
   }
 
  /*
@@ -669,7 +673,7 @@ print_device(const char *uri,               /* I - Device URI */
   * Wait for the side channel thread to exit...
   */
 
-  if (sidechannel_started)
+  if (have_sidechannel)
   {
     close(CUPS_SC_FD);
     pthread_mutex_lock(&g.readwrite_lock_mutex);
@@ -1679,7 +1683,7 @@ static void parse_options(char *options,
 
 /*!
  * @function   setup_cfLanguage
- * @abstract   Convert the contents of the CUPS 'LANG' environment
+ * @abstract   Convert the contents of the CUPS 'APPLE_LANGUAGE' environment
  *             variable into a one element CF array of languages.
  *
  * @discussion Each submitted job comes with a natural language. CUPS passes
@@ -1695,7 +1699,9 @@ static void setup_cfLanguage(void)
   CFArrayRef   langArray = NULL;
   const char   *requestedLang = NULL;
 
-  requestedLang = getenv("LANG");
+  if ((requestedLang = getenv("APPLE_LANGUAGE")) == NULL)
+    requestedLang = getenv("LANG");
+
   if (requestedLang != NULL)
   {
     lang[0] = CFStringCreateWithCString(kCFAllocatorDefault, requestedLang, kCFStringEncodingUTF8);
@@ -1708,7 +1714,7 @@ static void setup_cfLanguage(void)
     CFRelease(langArray);
   }
   else
-    fputs("DEBUG: usb: LANG environment variable missing.\n", stderr);
+    fputs("DEBUG: usb: LANG and APPLE_LANGUAGE environment variables missing.\n", stderr);
 }
 
 #pragma mark -
index 0a981d231841b671a155c0784ed66e4d24753618..6fa500d71c83b8f15b464b0fc9fb3aee40a60e5b 100644 (file)
@@ -1370,12 +1370,12 @@ do_config_server(http_t *http)          /* I - HTTP connection */
                        *remote_printers,
                                        /* REMOTE_PRINTERS value */
                        *share_printers,/* SHARE_PRINTERS value */
+                       *user_cancel_any;
+                                       /* USER_CANCEL_ANY value */
 #ifdef HAVE_GSSAPI
-                       *default_auth_type,
+    char               default_auth_type[255];
                                        /* DefaultAuthType value */
 #endif /* HAVE_GSSAPI */
-                       *user_cancel_any;
-                                       /* USER_CANCEL_ANY value */
 
 
    /*
@@ -1410,13 +1410,16 @@ do_config_server(http_t *http)          /* I - HTTP connection */
     */
 
     if (cgiGetVariable("KERBEROS"))
-      default_auth_type = "Negotiate";
+      strlcpy(default_auth_type, "Negotiate", sizeof(default_auth_type));
     else
     {
-      default_auth_type = cupsGetOption("DefaultAuthType", num_settings,
-                                        settings);
-      if (!strcasecmp(default_auth_type, "Negotiate"))
-        default_auth_type = "Basic";
+      const char *val = cupsGetOption("DefaultAuthType", num_settings,
+                                      settings);
+
+      if (val && !strcasecmp(val, "Negotiate"))
+        strlcpy(default_auth_type, "Basic", sizeof(default_auth_type));
+      else
+        strlcpy(default_auth_type, val, sizeof(default_auth_type));
     }
 
     fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type);
index dbf561c3856bc541b56f729ddbad576c817695d4..39e2d156207079959e4496494a72391a7c061c08 100644 (file)
@@ -407,6 +407,7 @@ show_class(http_t     *http,                /* I - Connection to server */
     * Show the class status...
     */
 
+    cgiSetVariable("_SINGLE_DEST", "1");
     cgiCopyTemplateLang("classes.tmpl");
 
    /*
index 0d817f75e9bbd168dc77a86122dd150e49a47370..de4d769f57f962a4aef1727b63b8c7f0c1d95e91 100644 (file)
@@ -587,6 +587,7 @@ show_printer(http_t     *http,              /* I - Connection to server */
     * Show the printer status...
     */
 
+    cgiSetVariable("_SINGLE_DEST", "1");
     cgiCopyTemplateLang("printers.tmpl");
 
    /*
index dcd126655fec2198edae692fad9f171f4ac84c10..8f51586bca0662fcfbdfa60b277b92325aeaa8ca 100644 (file)
@@ -19,7 +19,7 @@ AC_PREREQ(2.60)
 dnl Set the name of the config header file...
 AC_CONFIG_HEADER(config.h)
 
-dnl Versio number information...
+dnl Version number information...
 CUPS_VERSION="1.4svn"
 CUPS_REVISION=""
 if test -z "$CUPS_REVISION" -a -d .svn; then
@@ -34,12 +34,14 @@ AC_DEFINE_UNQUOTED(CUPS_MINIMAL, "CUPS/$CUPS_VERSION$CUPS_REVISION")
 dnl Default compiler flags...
 CFLAGS="${CFLAGS:=}"
 CPPFLAGS="${CPPFLAGS:=}"
+CXXFLAGS="${CXXFLAGS:=}"
 LDFLAGS="${LDFLAGS:=}"
 
 dnl Checks for programs...
 AC_PROG_AWK
 AC_PROG_CC
 AC_PROG_CPP
+AC_PROG_CXX
 AC_PROG_INSTALL
 if test "$INSTALL" = "$ac_install_sh"; then
        # Use full path to install-sh script...
@@ -130,6 +132,9 @@ else
        AC_CHECK_FUNCS(snprintf vsnprintf)
 fi
 
+dnl Check for random number functions...
+AC_CHECK_FUNCS(random mrand48 lrand48)
+
 dnl Checks for mkstemp and mkstemps functions.
 AC_CHECK_FUNCS(mkstemp mkstemps)
 
@@ -178,26 +183,62 @@ esac
 
 AC_SUBST(ARFLAGS)
 
-dnl Extra platform-specific libraries...
+dnl Prep libraries specifically for cupsd and backends...
 BACKLIBS=""
 CUPSDLIBS=""
-DBUSDIR=""
-CUPS_DEFAULT_PRINTADMIN_AUTH="@SYSTEM"
-CUPS_SYSTEM_AUTHKEY=""
+AC_SUBST(BACKLIBS)
+AC_SUBST(CUPSDLIBS)
+
+dnl See if we have POSIX ACL support...
+SAVELIBS="$LIBS"
+LIBS=""
+AC_SEARCH_LIBS(acl_init, acl, AC_DEFINE(HAVE_ACL_INIT))
+CUPSDLIBS="$CUPSDLIBS $LIBS"
+LIBS="$SAVELIBS"
+
+dnl Check for DBUS support
+if test -d /etc/dbus-1; then
+       DBUSDIR="/etc/dbus-1"
+else
+       DBUSDIR=""
+fi
 
 AC_ARG_ENABLE(dbus, [  --enable-dbus           enable DBUS support, default=auto])
+AC_ARG_WITH(dbusdir, [  --with-dbusdir          set DBUS configuration directory ],
+       DBUSDIR="$withval")
+
+if test "x$enable_dbus" != xno; then
+       AC_PATH_PROG(PKGCONFIG, pkg-config)
+       if test "x$PKGCONFIG" != x; then
+               AC_MSG_CHECKING(for DBUS)
+               if $PKGCONFIG --exists dbus-1; then
+                       AC_MSG_RESULT(yes)
+                       AC_DEFINE(HAVE_DBUS)
+                       CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1` -DDBUS_API_SUBJECT_TO_CHANGE"
+                       CUPSDLIBS="$CUPSDLIBS `$PKGCONFIG --libs dbus-1`"
+                       AC_CHECK_LIB(dbus-1,
+                           dbus_message_iter_init_append,
+                           AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_INIT_APPEND))
+               else
+                       AC_MSG_RESULT(no)
+               fi
+       fi
+fi
 
+AC_SUBST(DBUSDIR)
+
+dnl Extra platform-specific libraries...
+CUPS_DEFAULT_PRINTADMIN_AUTH="@SYSTEM"
+CUPS_SYSTEM_AUTHKEY=""
 FONTS="fonts"
-AC_SUBST(FONTS)
 LEGACY_BACKENDS="parallel scsi"
-AC_SUBST(LEGACY_BACKENDS)
 
 case $uname in
         Darwin*)
                FONTS=""
                LEGACY_BACKENDS=""
-                BACKLIBS="-framework IOKit"
-                CUPSDLIBS="-sectorder __TEXT __text cupsd.order -e start -framework IOKit -framework SystemConfiguration"
+                BACKLIBS="$BACKLIBS -framework IOKit"
+                CUPSDLIBS="$CUPSDLIBS -sectorder __TEXT __text cupsd.order -e start -framework IOKit -framework SystemConfiguration"
                 LIBS="-framework SystemConfiguration -framework CoreFoundation $LIBS"
 
                dnl Check for framework headers...
@@ -227,53 +268,13 @@ case $uname in
                dnl Check for sandbox/Seatbelt support
                AC_CHECK_HEADER(sandbox.h,AC_DEFINE(HAVE_SANDBOX_H))
                 ;;
-
-       Linux*)
-               dnl Check for DBUS support
-               if test "x$enable_dbus" != xno; then
-                       AC_PATH_PROG(PKGCONFIG, pkg-config)
-                       if test "x$PKGCONFIG" != x; then
-                               AC_MSG_CHECKING(for DBUS)
-                               if $PKGCONFIG --exists dbus-1; then
-                                       AC_MSG_RESULT(yes)
-                                       AC_DEFINE(HAVE_DBUS)
-                                       CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1` -DDBUS_API_SUBJECT_TO_CHANGE"
-                                       CUPSDLIBS="`$PKGCONFIG --libs dbus-1`"
-                                       AC_ARG_WITH(dbusdir, [  --with-dbusdir          set DBUS configuration directory ], dbusdir="$withval", dbusdir="/etc/dbus-1")
-                                       DBUSDIR="$dbusdir"
-                                       AC_CHECK_LIB(dbus-1,
-                                           dbus_message_iter_init_append,
-                                           AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_INIT_APPEND))
-                               else
-                                       AC_MSG_RESULT(no)
-                               fi
-                       fi
-               fi
-               ;;
 esac
 
 AC_SUBST(CUPS_DEFAULT_PRINTADMIN_AUTH)
 AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTADMIN_AUTH, "$CUPS_DEFAULT_PRINTADMIN_AUTH")
 AC_SUBST(CUPS_SYSTEM_AUTHKEY)
-
-dnl See if we have POSIX ACL support...
-SAVELIBS="$LIBS"
-LIBS=""
-AC_SEARCH_LIBS(acl_init, acl, AC_DEFINE(HAVE_ACL_INIT))
-CUPSDLIBS="$CUPSDLIBS $LIBS"
-LIBS="$SAVELIBS"
-
-AC_SUBST(BACKLIBS)
-AC_SUBST(CUPSDLIBS)
-AC_SUBST(DBUSDIR)
-
-dnl New default port definition for IPP...
-AC_ARG_WITH(ipp-port, [  --with-ipp-port         set default port number for IPP ],
-       DEFAULT_IPP_PORT="$withval",
-       DEFAULT_IPP_PORT="631")
-
-AC_SUBST(DEFAULT_IPP_PORT)
-AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT)
+AC_SUBST(FONTS)
+AC_SUBST(LEGACY_BACKENDS)
 
 dnl
 dnl End of "$Id: cups-common.m4 6964 2007-09-17 21:33:57Z mike $".
index 3a9f6908be90c90452409eabb0b3f6b3b4a38615..fc1c821eae97ccb2161ed9324fdf47049aab2936 100644 (file)
@@ -60,6 +60,9 @@ dnl Read-only data/program support on Linux...
 AC_ARG_ENABLE(relro, [  --enable-relro          use GCC relro option, default=no])
 
 dnl Update compiler options...
+CXXLIBS="${CXXLIBS:=}"
+AC_SUBST(CXXLIBS)
+
 PIEFLAGS=""
 AC_SUBST(PIEFLAGS)
 
index 6d6f5b64463c1a0efa35020eb22f9b6cf0f6526c..e9d6038e42bda9d91a32f39cc4f18f091d4e1975 100644 (file)
@@ -4,7 +4,7 @@ dnl
 dnl   Default cupsd configuration settings for the Common UNIX Printing System
 dnl   (CUPS).
 dnl
-dnl   Copyright 2007 by Apple Inc.
+dnl   Copyright 2007-2008 by Apple Inc.
 dnl   Copyright 2006-2007 by Easy Software Products, all rights reserved.
 dnl
 dnl   These coded instructions, statements, and computer programs are the
@@ -337,6 +337,14 @@ AC_ARG_WITH(snmp-community, [  --with-snmp-community   set SNMP community, defau
 AC_SUBST(CUPS_SNMP_ADDRESS)
 AC_SUBST(CUPS_SNMP_COMMUNITY)
 
+dnl New default port definition for IPP...
+AC_ARG_WITH(ipp-port, [  --with-ipp-port         set default port number for IPP ],
+       DEFAULT_IPP_PORT="$withval",
+       DEFAULT_IPP_PORT="631")
+
+AC_SUBST(DEFAULT_IPP_PORT)
+AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT)
+
 dnl
 dnl End of "$Id: cups-defaults.m4 6754 2007-08-01 19:00:07Z mike $".
 dnl
index 9bcf7181f2942302f2ac2585c6dc7761837d71a9..fc9013137363fb9c394f76c831e68362bf516462 100644 (file)
 #undef HAVE_SANDBOX_H
 
 
+/*
+ * Which random number generator function to use...
+ */
+
+#undef HAVE_RANDOM
+#undef HAVE_MRAND48
+#undef HAVE_LRAND48
+
+
 #endif /* !_CUPS_CONFIG_H_ */
 
 /*
index 4ea63e200b40a93d246562bdaa563a3411aaa3ab..eb94eac136cb64da9bb843b903bf8d13ab5a470f 100644 (file)
@@ -97,6 +97,7 @@ HEADERS       =       \
                ipp.h \
                language.h \
                ppd.h \
+               raster.h \
                sidechannel.h \
                snmp.h \
                transcode.h \
@@ -478,8 +479,8 @@ apihelp:
                --title "Filter and Backend Programming" \
                --css ../doc/cups-printable.css \
                --header api-filter.header --intro api-filter.shtml \
-               backchannel.c backend.h sidechannel.c sidechannel.h \
-               >../doc/help/api-filter.html
+               backchannel.c backend.h backend.c sidechannel.c sidechannel.h \
+               snmp.c snmp.h >../doc/help/api-filter.html
 
 framedhelp:
        echo Generating CUPS API help files...
@@ -499,31 +500,32 @@ framedhelp:
                --header api-cups.header --intro api-cups.shtml \
                cups.h dest.c getputfile.c language.c notify.c \
                options.c tempfile.c usersys.c \
-               util.c >../doc/help/api-cups.html
+               util.c
        mxmldoc --framed api-filedir \
                --section "Programming" --title "File and Directory APIs" \
                --css ../doc/cups-printable.css \
                --header api-filedir.header --intro api-filedir.shtml \
-               file.h file.c dir.h dir.c >../doc/help/api-filedir.html
+               file.h file.c dir.h dir.c
        mxmldoc --framed api-ppd \
                --section "Programming" --title "PPD API" \
                --css ../doc/cups-printable.css \
                --header api-ppd.header --intro api-ppd.shtml \
                ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
-               ppd.c >../doc/help/api-ppd.html
+               ppd.c
        mxmldoc --framed api-httpipp \
                --section "Programming" --title "HTTP and IPP APIs" \
                --css ../doc/cups-printable.css \
                --header api-httpipp.header --intro api-httpipp.shtml \
                http.h ipp.h auth.c encode.c http.c http-addr.c \
                http-support.c ipp.c ipp-support.c md5passwd.c \
-               request.c >../doc/help/api-httpipp.html
+               request.c
        mxmldoc --framed api-filter \
                --section "Programming" \
                --title "Filter and Backend Programming" \
                --css ../doc/cups-printable.css \
                --header api-filter.header --intro api-filter.shtml \
-               backchannel.c backend.h sidechannel.c sidechannel.h
+               backchannel.c backend.h backend.c sidechannel.c sidechannel.h \
+               snmp.c snmp.h
 
 
 #
index f7ae6a3685c4e5bbfd064ececfe77c0999084ea5..4b41c439b1a4e29aae086bdd0e205ce97f18e62a 100644 (file)
 <div class='summary'><table summary='General Information'>
 <thead>
 <tr>
-       <th>Header</th>
+       <th>Headers</th>
        <th>cups/backend.h<br>
-       cups/sidechannel.h</th>
+       cups/sidechannel.h<br>
+       cups/snmp.h</th>
 </tr>
 </thead>
 <tbody>
index 4f72dfe7193fc9632f969f7d587b8fcdf25db776..f5b6b8cf2c622ebbfa5450b3363e6f7d39204229 100644 (file)
@@ -47,6 +47,52 @@ the remaining filters read from the standard input and write to the standard
 output. The backend is the last filter in the chain and writes to the
 device.</p>
 
+<h3><a name="SECURITY">Security Considerations</a></h3>
+
+<p>It is always important to use security programming practices. Filters and
+most backends are run as a non-priviledged user, so the major security
+consideration is resource utilization - filters should not depend on unlimited
+amounts of CPU, memory, or disk space, and should protect against conditions
+that could lead to excess usage of any resource like infinite loops and
+unbounded recursion. In addition, filters must <em>never</em> allow the user to
+specify an arbitrary file path to a separator page, template, or other file
+used by the filter since that can lead to an unauthorized disclosure of
+information. <em>Always</em> treat input as suspect and validate it!</p>
+
+<p>If you are developing a backend that runs as root, make sure to check for
+potential buffer overflows, integer under/overflow conditions, and file
+accesses since these can lead to privilege escalations. When writing files,
+always validate the file path and <em>never</em> allow a user to determine
+where to store a file.</p>
+
+<blockquote><b>Note:</b>
+
+<p><em>Never</em> write files to a user's home directory. Aside from the
+security implications, CUPS is a network print service and as such the network
+user may not be the same as the local user and/or there may not be a local home
+directory to write to.</p>
+
+<p>In addition, some operating systems provide additional security mechanisms
+that further limit file system access, even for backends running as root.  On
+Mac OS X, for example, no backend may write to a user's home directory.</p>
+</blockquote>
+
+<h3><a name="TEMPFILES">Temporary Files</a></h3>
+
+<p>Temporary files should be created in the directory specified by the
+"TMPDIR" environment variable. The
+<a href="#cupsTempFile2"><code>cupsTempFile2</code></a> function can be
+used to safely create temporary files in this directory.</p>
+
+<h3><a name="COPIES">Copy Generation</a></h3>
+
+<p>The <code>argv[4]</code> argument specifies the number of copies to produce
+of the input file. In general, you should only generate copies if the
+<em>filename</em> argument is supplied. The only exception to this are
+filters that produce device-independent PostScript output, since the PostScript
+filter <var>pstops</var> is responsible for generating copies of PostScript
+files.</p>
+
 <h3><a name="EXITCODES">Exit Codes</a></h3>
 
 <p>Filters must exit with status 0 when they successfully generate print data
@@ -294,3 +340,78 @@ if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;s
   <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
 }
 </pre>
+
+<h3><a name="SNMP">Doing SNMP Queries with Network Printers</a></h3>
+
+<p>The Simple Network Management Protocol (SNMP) allows you to get the current
+status, page counter, and supply levels from most network printers. Every
+piece of information is associated with an Object Identifier (OID), and
+every printer has a <em>community</em> name associated with it. OIDs can be
+queried directly or by "walking" over a range of OIDs with a common prefix.</p>
+
+<p>The CUPS SNMP functions provide a simple API for querying network printers.
+Queries are made using a datagram socket that is created using
+<a href="#cupsSNMPOpen"><code>cupsSNMPOpen</code></a> and destroyed using
+<a href="#cupsSNMPClose"><code>cupsSNMPClose</code></a>:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(AF_INET);
+
+/* do some queries */
+
+<a href="#cupsSNMPClose">cupsSNMPClose</a>(snmp);
+</pre>
+
+<p>OIDs are simple C arrays of integers, terminated by a value of -1. For
+example, the page counter OID .1.3.6.1.2.1.43.10.2.1.4.1.1 would be:</p>
+
+<pre class="example">
+int page_counter_oid[] = { 1, 3, 6, 1, 2, 1, 43, 10, 2, 1, 4, 1, 1, -1 };
+</pre>
+
+<p>You send a query using
+<a href="#cupsSNMPWrite"><code>cupsSNMPWrite</code></a> and read the value back
+using <a href="#cupsSNMPRead"><code>cupsSNMPRead</code></a>. The value is read
+into a structure called <a href="#cups_snmp_t"><code>cups_snmp_t</code></a>:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+int page_counter_oid[] = { 1, 3, 6, 1, 2, 1, 43, 10, 2, 1, 4, 1, 1, -1 };
+http_addrlist_t *host = httpAddrGetList("myprinter", AF_UNSPEC, "161");
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(host->addr.addr.sa_family);
+<a href="#cups_snmp_t">cups_snmp_t</a> packet;
+
+<a href="#cupsSNMPWrite">cupsSNMPWrite</a>(snmp, &amp;(host->addr), CUPS_SNMP_VERSION_1,
+                <a href="#cupsSNMPDefaultCommunity">cupsSNMPDefaultCommunity</a>(), CUPS_ASN1_GET_REQUEST, 1,
+                page_counter_oid);
+if (<a href="#cupsSNMPRead">cupsSNMPRead</a>(snmp, &amp;packet, 5000))
+{
+  /* Do something with the value */
+  printf("Page counter is: %d\n", packet.object_value.integer);
+}
+</pre>
+
+<p>The <a href="#cupsSNMPWalk"><code>cupsSNMPWalk</code></a> function allows you
+to query a whole group of OIDs, calling a function of your choice for each OID
+that is found:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+void
+my_callback(<a href="#cups_snmp_t">cups_snmp_t</a> *packet, void *data)
+{
+  /* Do something with the value */
+}
+
+int printer_mib_oid[] = { 1, 3, 6, 1, 2, 1, 43, -1 };
+http_addrlist_t *host = httpAddrGetList("myprinter", AF_UNSPEC, "161");
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(host->addr.addr.sa_family);
+void *my_data;
+
+<a href="#cupsSNMPWalk">cupsSNMPWalk</a>(snmp, &amp;(host->addr), CUPS_SNMP_VERSION_1,
+               <a href="#cupsSNMPDefaultCommunity">cupsSNMPDefaultCommunity</a>(), printer_mib_oid, my_callback, my_data);
+</pre>
index 992bc5d03eb18c6af53ec7320f807ea5be8cc85b..e30aa9bbf36f6989a6887a9ee757a25255619633 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Backend functions for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -37,7 +37,7 @@
  * first.
  */
 
-const char *                           /* O - Device URI or NULL */
+const char *                           /* O - Device URI or @code NULL@ */
 cupsBackendDeviceURI(char **argv)      /* I - Command-line arguments */
 {
   const char   *device_uri;            /* Device URI */
index faed129510ef6516da6500b1578d3f053ff58394..0aacc0cc8f0248752a7733350253ff036eab197a 100644 (file)
@@ -98,6 +98,8 @@ typedef struct _cups_globals_s                /**** CUPS global state data ****/
   ppd_conform_t                ppd_conform;    /* Level of conformance required */
 
   /* snmp.c */
+  char                 snmp_community[255];
+                                       /* Default SNMP community name */
   int                  snmp_debug;     /* Log SNMP IO to stderr? */
 
   /* tempfile.c */
index a05e528a3976df015e3fc515cb6dccd5e7bd8025..be6cfbe844f3539c523b45c23f83445937ff1d1b 100644 (file)
@@ -1283,7 +1283,7 @@ http_copy_encode(char       *dst, /* O - Destination buffer */
                 const char *term,      /* I - Terminating characters */
                 int        encode)     /* I - %-encode reserved chars? */
 {
-  static const char *hex = "0123456789ABCDEF";
+  static const char hex[] = "0123456789ABCDEF";
 
 
   while (*src && dst < dstend)
index 930c0d5d22c9b6f662cb3b2caa00ab8c8b746cdc..c90f5c9d54fded5f4c2c9453b76940428c0c1953 100644 (file)
@@ -148,11 +148,13 @@ _cupsRemoveDest
 _cupsRemoveOption
 _cupsSNMPClose
 _cupsSNMPCopyOID
+_cupsSNMPDefaultCommunity
 _cupsSNMPIsOID
 _cupsSNMPIsOIDPrefixed
 _cupsSNMPOpen
 _cupsSNMPRead
 _cupsSNMPSetDebug
+_cupsSNMPWalk
 _cupsSNMPWrite
 _cupsSendRequest
 _cupsServer
similarity index 99%
rename from filter/raster.h
rename to cups/raster.h
index 2155ea5166cdda39718731eb4e76fe1c54264205..947b1afcb13379399e72f0ed26e52c19828c875b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: raster.h 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id$"
  *
  *   Raster file definitions for the Common UNIX Printing System (CUPS).
  *
@@ -342,5 +342,5 @@ extern const char   *cupsRasterErrorString(void) _CUPS_API_1_3;
 #endif /* !_CUPS_RASTER_H_ */
 
 /*
- * End of "$Id: raster.h 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id$".
  */
index 123f96538f838dfe4a3238f7cb94378e1626b910..1441b7f18d588d9568fecb5e338d18cda2856537 100644 (file)
  *
  * Contents:
  *
- *   cupsSNMPClose()         - Close a SNMP socket.
- *   cupsSNMPCopyOID()       - Copy an OID.
- *   cupsSNMPIsOID()         - Test whether a SNMP response contains the
- *                             specified OID.
- *   cupsSNMPIsOIDPrefixed() - Test whether a SNMP response uses the specified
- *                             OID prefix.
- *   cupsSNMPOpen()          - Open a SNMP socket.
- *   cupsSNMPRead()          - Read and parse a SNMP response...
- *   cupsSNMPSetDebug()      - Enable/disable debug logging to stderr.
- *   cupsSNMPWrite()         - Send an SNMP query packet.
- *   asn1_decode_snmp()      - Decode a SNMP packet.
- *   asn1_debug()            - Decode an ASN1-encoded message.
- *   asn1_encode_snmp()      - Encode a SNMP packet.
- *   asn1_get_integer()      - Get an integer value.
- *   asn1_get_length()       - Get a value length.
- *   asn1_get_oid()          - Get an OID value.
- *   asn1_get_packed()       - Get a packed integer value.
- *   asn1_get_string()       - Get a string value.
- *   asn1_get_type()         - Get a value type.
- *   asn1_set_integer()      - Set an integer value.
- *   asn1_set_length()       - Set a value length.
- *   asn1_set_oid()          - Set an OID value.
- *   asn1_set_packed()       - Set a packed integer value.
- *   asn1_size_integer()     - Figure out the number of bytes needed for an
- *                             integer value.
- *   asn1_size_length()      - Figure out the number of bytes needed for a
- *                             length value.
- *   asn1_size_oid()         - Figure out the numebr of bytes needed for an OID
- *                             value.
- *   asn1_size_packed()      - Figure out the number of bytes needed for a
- *                             packed integer value.
- *   snmp_set_error()        - Set the localized error for a packet.
+ *   cupsSNMPClose()            - Close a SNMP socket.
+ *   cupsSNMPCopyOID()          - Copy an OID.
+ *   cupsSNMPDefaultCommunity() - Get the default SNMP community name.
+ *   cupsSNMPIsOID()            - Test whether a SNMP response contains the
+ *                                specified OID.
+ *   cupsSNMPIsOIDPrefixed()    - Test whether a SNMP response uses the
+ *                                specified OID prefix.
+ *   cupsSNMPOpen()             - Open a SNMP socket.
+ *   cupsSNMPRead()             - Read and parse a SNMP response.
+ *   cupsSNMPSetDebug()         - Enable/disable debug logging to stderr.
+ *   cupsSNMPWalk()             - Enumerate a group of OIDs.
+ *   cupsSNMPWrite()            - Send an SNMP query packet.
+ *   asn1_debug()               - Decode an ASN1-encoded message.
+ *   asn1_decode_snmp()         - Decode a SNMP packet.
+ *   asn1_encode_snmp()         - Encode a SNMP packet.
+ *   asn1_get_integer()         - Get an integer value.
+ *   asn1_get_length()          - Get a value length.
+ *   asn1_get_oid()             - Get an OID value.
+ *   asn1_get_packed()          - Get a packed integer value.
+ *   asn1_get_string()          - Get a string value.
+ *   asn1_get_type()            - Get a value type.
+ *   asn1_set_integer()         - Set an integer value.
+ *   asn1_set_length()          - Set a value length.
+ *   asn1_set_oid()             - Set an OID value.
+ *   asn1_set_packed()          - Set a packed integer value.
+ *   asn1_size_integer()        - Figure out the number of bytes needed for an
+ *                                integer value.
+ *   asn1_size_length()         - Figure out the number of bytes needed for a
+ *                                length value.
+ *   asn1_size_oid()            - Figure out the numebr of bytes needed for an
+ *                                OID value.
+ *   asn1_size_packed()         - Figure out the number of bytes needed for a
+ *                                packed integer value.
+ *   snmp_set_error()           - Set the localized error for a packet.
  */
 
 /*
  * Local functions...
  */
 
-static int             asn1_decode_snmp(unsigned char *buffer, size_t len,
-                                        cups_snmp_t *packet);
 static void            asn1_debug(const char *prefix, unsigned char *buffer,
                                   size_t len, int indent);
+static int             asn1_decode_snmp(unsigned char *buffer, size_t len,
+                                        cups_snmp_t *packet);
 static int             asn1_encode_snmp(unsigned char *buffer, size_t len,
                                         cups_snmp_t *packet);
 static int             asn1_get_integer(unsigned char **buffer,
@@ -123,6 +125,10 @@ cupsSNMPClose(int fd)                      /* I - SNMP socket file descriptor */
 
 /*
  * 'cupsSNMPCopyOID()' - Copy an OID.
+ *
+ * The array pointed to by "src" is terminated by the value -1.
+ *
+ * @since CUPS 1.4@
  */
 
 int *                                  /* O - New OID */
@@ -133,19 +139,61 @@ cupsSNMPCopyOID(int       *dst,           /* I - Destination OID */
   int  i;                              /* Looping var */
 
 
-  for (i = 0, dstsize --; src[i] && i < dstsize; i ++)
+  for (i = 0, dstsize --; src[i] >= 0 && i < dstsize; i ++)
     dst[i] = src[i];
 
-  dst[i] = 0;
+  dst[i] = -1;
 
   return (dst);
 }
 
 
+/*
+ * 'cupsSNMPDefaultCommunity()' - Get the default SNMP community name.
+ *
+ * The default community name is the first community name found in the
+ * snmp.conf file. If no community name is defined there, "public" is used.
+ *
+ * @since CUPS 1.4@
+ */
+
+const char *                           /* O - Default community name */
+cupsSNMPDefaultCommunity(void)
+{
+  cups_file_t  *fp;                    /* snmp.conf file */
+  char         line[1024],             /* Line from file */
+               *value;                 /* Value from file */
+  int          linenum;                /* Line number in file */
+  _cups_globals_t *cg = _cupsGlobals();        /* Global data */
+
+
+  if (!cg->snmp_community[0])
+  {
+    strlcpy(cg->snmp_community, "public", sizeof(cg->snmp_community));
+
+    snprintf(line, sizeof(line), "%s/snmp.conf", cg->cups_serverroot);
+    if ((fp = cupsFileOpen(line, "r")) != NULL)
+    {
+      linenum = 0;
+      while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+       if (!strcasecmp(line, "Community") && value)
+       {
+         strlcpy(cg->snmp_community, value, sizeof(cg->snmp_community));
+         break;
+       }
+
+      cupsFileClose(fp);
+    }
+  }
+
+  return (cg->snmp_community);
+}
+
+
 /*
  * 'cupsSNMPIsOID()' - Test whether a SNMP response contains the specified OID.
  *
- * The array pointed to by "oid" is 0-terminated.
+ * The array pointed to by "oid" is terminated by the value -1.
  *
  * @since CUPS 1.4@
  */
@@ -168,7 +216,9 @@ cupsSNMPIsOID(cups_snmp_t *packet,  /* I - Response packet */
   * Compare OIDs...
   */
 
-  for (i = 0; i < CUPS_SNMP_MAX_OID && oid[i] && packet->object_name[i]; i ++)
+  for (i = 0;
+       i < CUPS_SNMP_MAX_OID && oid[i] >= 0 && packet->object_name[i] >= 0;
+       i ++)
     if (oid[i] != packet->object_name[i])
       return (0);
 
@@ -180,7 +230,7 @@ cupsSNMPIsOID(cups_snmp_t *packet,  /* I - Response packet */
  * 'cupsSNMPIsOIDPrefixed()' - Test whether a SNMP response uses the specified
  *                             OID prefix.
  *
- * The array pointed to by "prefix" is 0-terminated.
+ * The array pointed to by "prefix" is terminated by the value -1.
  *
  * @since CUPS 1.4@
  */
@@ -205,7 +255,7 @@ cupsSNMPIsOIDPrefixed(
   */
 
   for (i = 0;
-       i < CUPS_SNMP_MAX_OID && prefix[i] && packet->object_name[i];
+       i < CUPS_SNMP_MAX_OID && prefix[i] >= 0 && packet->object_name[i] >= 0;
        i ++)
     if (prefix[i] != packet->object_name[i])
       return (0);
@@ -221,7 +271,7 @@ cupsSNMPIsOIDPrefixed(
  */
 
 int                                    /* O - SNMP socket file descriptor */
-cupsSNMPOpen(void)
+cupsSNMPOpen(int family)               /* I - Address family - @code AF_INET@ or @code AF_INET6@ */
 {
   int          fd;                     /* SNMP socket file descriptor */
   int          val;                    /* Socket option value */
@@ -231,7 +281,7 @@ cupsSNMPOpen(void)
   * Create the SNMP socket...
   */
 
-  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+  if ((fd = socket(family, SOCK_DGRAM, 0)) < 0)
     return (-1);
 
  /*
@@ -252,15 +302,15 @@ cupsSNMPOpen(void)
 
 
 /*
- * 'cupsSNMPRead()' - Read and parse a SNMP response...
+ * 'cupsSNMPRead()' - Read and parse a SNMP response.
  *
- * If "timeout" is negative, cupsSNMPRead() will wait for a response
+ * If "timeout" is negative, @code cupsSNMPRead@ will wait for a response
  * indefinitely.
  *
  * @since CUPS 1.4@
  */
 
-cups_snmp_t *                          /* O - SNMP packet or NULL if none */
+cups_snmp_t *                          /* O - SNMP packet or @code NULL@ if none */
 cupsSNMPRead(int         fd,           /* I - SNMP socket file descriptor */
              cups_snmp_t *packet,      /* I - SNMP packet buffer */
             int         msec)          /* I - Timeout in milliseconds */
@@ -269,6 +319,7 @@ cupsSNMPRead(int         fd,                /* I - SNMP socket file descriptor */
                                        /* Data packet */
   int          bytes;                  /* Number of bytes received */
   socklen_t    addrlen;                /* Source address length */
+  http_addr_t  address;                /* Source address */
 
 
  /*
@@ -326,10 +377,10 @@ cupsSNMPRead(int         fd,              /* I - SNMP socket file descriptor */
   * Read the response data...
   */
 
-  addrlen = sizeof(packet->address);
+  addrlen = sizeof(address);
 
-  if ((bytes = recvfrom(fd, buffer, sizeof(buffer), 0,
-                        (void *)&(packet->address), &addrlen)) < 0)
+  if ((bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (void *)&address,
+                        &addrlen)) < 0)
     return (NULL);
 
  /*
@@ -340,6 +391,8 @@ cupsSNMPRead(int         fd,                /* I - SNMP socket file descriptor */
 
   asn1_decode_snmp(buffer, bytes, packet);
 
+  memcpy(&(packet->address), &address, sizeof(packet->address));
+
  /*
   * Return decoded data packet...
   */
@@ -364,10 +417,75 @@ cupsSNMPSetDebug(int level)               /* I - 1 to enable debug output, 0 otherwise */
 }
 
 
+/*
+ * 'cupsSNMPWalk()' - Enumerate a group of OIDs.
+ *
+ * This function queries all of the OIDs with the specified OID prefix,
+ * calling the "cb" function for every response that is received.
+ *
+ * The array pointed to by "prefix" is terminated by the value -1.
+ *
+ * @since CUPS 1.4@
+ */
+
+int                                    /* O - Number of OIDs found or -1 on error */
+cupsSNMPWalk(int            fd,                /* I - SNMP socket */
+             http_addr_t    *address,  /* I - Address to query */
+            int            version,    /* I - SNMP version */
+            const char     *community, /* I - Community name */
+             const int      *prefix,   /* I - OID prefix */
+            int            msec,       /* I - Timeout for each response in milliseconds */
+            cups_snmp_cb_t cb,         /* I - Function to call for each response */
+            void           *data)      /* I - User data pointer that is passed to the callback function */
+{
+  int          count = 0;              /* Number of OIDs found */
+  int          request_id = 0;         /* Current request ID */
+  cups_snmp_t  packet;                 /* Current response packet */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (fd < 0 || !address || version != CUPS_SNMP_VERSION_1 || !community ||
+      !prefix || !cb)
+    return (-1);
+
+ /*
+  * Copy the OID prefix and then loop until we have no more OIDs...
+  */
+
+  cupsSNMPCopyOID(packet.object_name, prefix, CUPS_SNMP_MAX_OID);
+
+  for (;;)
+  {
+    request_id ++;
+
+    if (!cupsSNMPWrite(fd, address, version, community,
+                       CUPS_ASN1_GET_NEXT_REQUEST, request_id,
+                      packet.object_name))
+      return (-1);
+
+    if (!cupsSNMPRead(fd, &packet, msec))
+      return (-1);
+
+    if (!cupsSNMPIsOIDPrefixed(&packet, prefix))
+      return (count);
+
+    if (packet.error || packet.error_status)
+      return (count > 0 ? count : -1);
+
+    count ++;
+
+    (*cb)(&packet, data);
+  }
+}
+
+
 /*
  * 'cupsSNMPWrite()' - Send an SNMP query packet.
  *
- * The array pointed to by "oid" is 0-terminated.
+ * The array pointed to by "oid" is terminated by the value -1.
  *
  * @since CUPS 1.4@
  */
@@ -389,6 +507,15 @@ cupsSNMPWrite(
   int          bytes;                  /* Size of message */
 
 
+ /*
+  * Range check input...
+  */
+
+  if (fd < 0 || !address || version != CUPS_SNMP_VERSION_1 || !community ||
+      (request_type != CUPS_ASN1_GET_REQUEST &&
+       request_type != CUPS_ASN1_GET_NEXT_REQUEST) || request_id < 1 || !oid)
+    return (0);
+
  /*
   * Create the SNMP message...
   */
@@ -402,15 +529,21 @@ cupsSNMPWrite(
   
   strlcpy(packet.community, community, sizeof(packet.community));
 
-  for (i = 0; oid[i]; i ++)
+  for (i = 0; oid[i] >= 0 && i < (CUPS_SNMP_MAX_OID - 1); i ++)
     packet.object_name[i] = oid[i];
+  packet.object_name[i] = -1;
+
+  if (oid[i] >= 0)
+  {
+    errno = E2BIG;
+    return (0);
+  }
 
   bytes = asn1_encode_snmp(buffer, sizeof(buffer), &packet);
 
   if (bytes < 0)
   {
     errno = E2BIG;
-
     return (0);
   }
 
@@ -432,6 +565,203 @@ cupsSNMPWrite(
 }
 
 
+/*
+ * 'asn1_debug()' - Decode an ASN1-encoded message.
+ */
+
+static void
+asn1_debug(const char    *prefix,      /* I - Prefix string */
+           unsigned char *buffer,      /* I - Buffer */
+           size_t        len,          /* I - Length of buffer */
+           int           indent)       /* I - Indentation */
+{
+  int          i;                      /* Looping var */
+  unsigned char        *bufend;                /* End of buffer */
+  int          integer;                /* Number value */
+  int          oid[CUPS_SNMP_MAX_OID]; /* OID value */
+  char         string[CUPS_SNMP_MAX_STRING];
+                                       /* String value */
+  unsigned char        value_type;             /* Type of value */
+  int          value_length;           /* Length of value */
+  _cups_globals_t *cg = _cupsGlobals();        /* Global data */
+
+
+  if (cg->snmp_debug <= 0)
+    return;
+
+  if (cg->snmp_debug > 1 && indent == 0)
+  {
+   /*
+    * Do a hex dump of the packet...
+    */
+
+    int j;
+
+    fprintf(stderr, "%sHex Dump (%d bytes):\n", prefix, (int)len);
+
+    for (i = 0; i < len; i += 16)
+    {
+      fprintf(stderr, "%s%04x:", prefix, i);
+
+      for (j = 0; j < 16 && (i + j) < len; j ++)
+      {
+        if (j && !(j & 3))
+         fprintf(stderr, "  %02x", buffer[i + j]);
+        else
+         fprintf(stderr, " %02x", buffer[i + j]);
+      }
+
+      while (j < 16)
+      {
+        if (j && !(j & 3))
+         fputs("    ", stderr);
+       else
+         fputs("   ", stderr);
+
+        j ++;
+      }
+
+      fputs("    ", stderr);
+
+      for (j = 0; j < 16 && (i + j) < len; j ++)
+        if (buffer[i + j] < ' ' || buffer[i + j] >= 0x7f)
+         putc('.', stderr);
+       else
+         putc(buffer[i + j], stderr);
+
+      putc('\n', stderr);
+    }
+  }
+
+  if (indent == 0)
+    fprintf(stderr, "%sMessage:\n", prefix);
+
+  bufend = buffer + len;
+
+  while (buffer < bufend)
+  {
+   /*
+    * Get value type...
+    */
+
+    value_type   = asn1_get_type(&buffer, bufend);
+    value_length = asn1_get_length(&buffer, bufend);
+
+    switch (value_type)
+    {
+      case CUPS_ASN1_BOOLEAN :
+          integer = asn1_get_integer(&buffer, bufend, value_length);
+
+          fprintf(stderr, "%s%*sBOOLEAN %d bytes %d\n", prefix, indent, "",
+                 value_length, integer);
+          break;
+
+      case CUPS_ASN1_INTEGER :
+          integer = asn1_get_integer(&buffer, bufend, value_length);
+
+          fprintf(stderr, "%s%*sINTEGER %d bytes %d\n", prefix, indent, "",
+                 value_length, integer);
+          break;
+
+      case CUPS_ASN1_COUNTER :
+          integer = asn1_get_integer(&buffer, bufend, value_length);
+
+          fprintf(stderr, "%s%*sCOUNTER %d bytes %u\n", prefix, indent, "",
+                 value_length, (unsigned)integer);
+          break;
+
+      case CUPS_ASN1_GAUGE :
+          integer = asn1_get_integer(&buffer, bufend, value_length);
+
+          fprintf(stderr, "%s%*sGAUGE %d bytes %u\n", prefix, indent, "",
+                 value_length, (unsigned)integer);
+          break;
+
+      case CUPS_ASN1_TIMETICKS :
+          integer = asn1_get_integer(&buffer, bufend, value_length);
+
+          fprintf(stderr, "%s%*sTIMETICKS %d bytes %u\n", prefix, indent, "",
+                 value_length, (unsigned)integer);
+          break;
+
+      case CUPS_ASN1_OCTET_STRING :
+          fprintf(stderr, "%s%*sOCTET STRING %d bytes \"%s\"\n", prefix,
+                 indent, "", value_length,
+                 asn1_get_string(&buffer, bufend, value_length, string,
+                                 sizeof(string)));
+          break;
+
+      case CUPS_ASN1_HEX_STRING :
+         asn1_get_string(&buffer, bufend, value_length, string,
+                         sizeof(string));
+          fprintf(stderr, "%s%*sHex-STRING %d bytes", prefix,
+                 indent, "", value_length);
+          for (i = 0; i < value_length; i ++)
+           fprintf(stderr, " %02X", string[i] & 255);
+         putc('\n', stderr);
+          break;
+
+      case CUPS_ASN1_NULL_VALUE :
+          fprintf(stderr, "%s%*sNULL VALUE %d bytes\n", prefix, indent, "",
+                 value_length);
+
+         buffer += value_length;
+          break;
+
+      case CUPS_ASN1_OID :
+          integer = asn1_get_oid(&buffer, bufend, value_length, oid,
+                                CUPS_SNMP_MAX_OID);
+
+          fprintf(stderr, "%s%*sOID %d bytes ", prefix, indent, "",
+                 value_length);
+         for (i = 0; i < integer; i ++)
+           fprintf(stderr, ".%d", oid[i]);
+         putc('\n', stderr);
+          break;
+
+      case CUPS_ASN1_SEQUENCE :
+          fprintf(stderr, "%s%*sSEQUENCE %d bytes\n", prefix, indent, "",
+                 value_length);
+          asn1_debug(prefix, buffer, value_length, indent + 4);
+
+         buffer += value_length;
+          break;
+
+      case CUPS_ASN1_GET_NEXT_REQUEST :
+          fprintf(stderr, "%s%*sGet-Next-Request-PDU %d bytes\n", prefix,
+                 indent, "", value_length);
+          asn1_debug(prefix, buffer, value_length, indent + 4);
+
+         buffer += value_length;
+          break;
+
+      case CUPS_ASN1_GET_REQUEST :
+          fprintf(stderr, "%s%*sGet-Request-PDU %d bytes\n", prefix, indent, "",
+                 value_length);
+          asn1_debug(prefix, buffer, value_length, indent + 4);
+
+         buffer += value_length;
+          break;
+
+      case CUPS_ASN1_GET_RESPONSE :
+          fprintf(stderr, "%s%*sGet-Response-PDU %d bytes\n", prefix, indent,
+                 "", value_length);
+          asn1_debug(prefix, buffer, value_length, indent + 4);
+
+         buffer += value_length;
+          break;
+
+      default :
+          fprintf(stderr, "%s%*sUNKNOWN(%x) %d bytes\n", prefix, indent, "",
+                 value_type, value_length);
+
+         buffer += value_length;
+          break;
+    }
+  }
+}
+          
+
 /*
  * 'asn1_decode_snmp()' - Decode a SNMP packet.
  */
@@ -451,6 +781,7 @@ asn1_decode_snmp(unsigned char *buffer,     /* I - Buffer */
   */
 
   memset(packet, 0, sizeof(cups_snmp_t));
+  packet->object_name[0] = -1;
 
   bufptr = buffer;
   bufend = buffer + len;
@@ -556,6 +887,14 @@ asn1_decode_snmp(unsigned char *buffer,    /* I - Buffer */
                                 packet->object_value.oid, CUPS_SNMP_MAX_OID);
                    break;
 
+               case CUPS_ASN1_HEX_STRING :
+                   packet->object_value.hex_string.num_bytes = length;
+
+                   asn1_get_string(&bufptr, bufend, length,
+                                   (char *)packet->object_value.hex_string.bytes,
+                                   CUPS_SNMP_MAX_STRING);
+                   break;
+
                case CUPS_ASN1_COUNTER :
                    packet->object_value.counter =
                        asn1_get_integer(&bufptr, bufend, length);
@@ -566,6 +905,11 @@ asn1_decode_snmp(unsigned char *buffer,    /* I - Buffer */
                        asn1_get_integer(&bufptr, bufend, length);
                    break;
 
+               case CUPS_ASN1_TIMETICKS :
+                   packet->object_value.timeticks =
+                       asn1_get_integer(&bufptr, bufend, length);
+                   break;
+
                 default :
                    snmp_set_error(packet, _("Unsupported value type"));
                    break;
@@ -581,116 +925,6 @@ asn1_decode_snmp(unsigned char *buffer,   /* I - Buffer */
 }
 
 
-/*
- * 'asn1_debug()' - Decode an ASN1-encoded message.
- */
-
-static void
-asn1_debug(const char    *prefix,      /* I - Prefix string */
-           unsigned char *buffer,      /* I - Buffer */
-           size_t        len,          /* I - Length of buffer */
-           int           indent)       /* I - Indentation */
-{
-  int          i;                      /* Looping var */
-  unsigned char        *bufend;                /* End of buffer */
-  int          integer;                /* Number value */
-  int          oid[CUPS_SNMP_MAX_OID]; /* OID value */
-  char         string[CUPS_SNMP_MAX_STRING];
-                                       /* String value */
-  unsigned char        value_type;             /* Type of value */
-  int          value_length;           /* Length of value */
-  _cups_globals_t *cg = _cupsGlobals();        /* Global data */
-
-
-  if (cg->snmp_debug <= 0)
-    return;
-
-  bufend = buffer + len;
-
-  while (buffer < bufend)
-  {
-   /*
-    * Get value type...
-    */
-
-    value_type   = asn1_get_type(&buffer, bufend);
-    value_length = asn1_get_length(&buffer, bufend);
-
-    switch (value_type)
-    {
-      case CUPS_ASN1_BOOLEAN :
-          integer = asn1_get_integer(&buffer, bufend, value_length);
-
-          fprintf(stderr, "%s%*sBOOLEAN %d bytes %d\n", prefix, indent, "",
-                 value_length, integer);
-          break;
-
-      case CUPS_ASN1_INTEGER :
-          integer = asn1_get_integer(&buffer, bufend, value_length);
-
-          fprintf(stderr, "%s%*sINTEGER %d bytes %d\n", prefix, indent, "",
-                 value_length, integer);
-          break;
-
-      case CUPS_ASN1_OCTET_STRING :
-          fprintf(stderr, "%s%*sOCTET STRING %d bytes \"%s\"\n", prefix,
-                 indent, "", value_length,
-                 asn1_get_string(&buffer, bufend, value_length, string,
-                                 sizeof(string)));
-          break;
-
-      case CUPS_ASN1_NULL_VALUE :
-          fprintf(stderr, "%s%*sNULL VALUE %d bytes\n", prefix, indent, "",
-                 value_length);
-
-         buffer += value_length;
-          break;
-
-      case CUPS_ASN1_OID :
-          asn1_get_oid(&buffer, bufend, value_length, oid, CUPS_SNMP_MAX_OID);
-
-          fprintf(stderr, "%s%*sOID %d bytes ", prefix, indent, "",
-                 value_length);
-         for (i = 0; oid[i]; i ++)
-           fprintf(stderr, ".%d", oid[i]);
-         putc('\n', stderr);
-          break;
-
-      case CUPS_ASN1_SEQUENCE :
-          fprintf(stderr, "%s%*sSEQUENCE %d bytes\n", prefix, indent, "",
-                 value_length);
-          asn1_debug(prefix, buffer, value_length, indent + 4);
-
-         buffer += value_length;
-          break;
-
-      case CUPS_ASN1_GET_REQUEST :
-          fprintf(stderr, "%s%*sGet-Request-PDU %d bytes\n", prefix, indent, "",
-                 value_length);
-          asn1_debug(prefix, buffer, value_length, indent + 4);
-
-         buffer += value_length;
-          break;
-
-      case CUPS_ASN1_GET_RESPONSE :
-          fprintf(stderr, "%s%*sGet-Response-PDU %d bytes\n", prefix, indent,
-                 "", value_length);
-          asn1_debug(prefix, buffer, value_length, indent + 4);
-
-         buffer += value_length;
-          break;
-
-      default :
-          fprintf(stderr, "%s%*sUNKNOWN(%x) %d bytes\n", prefix, indent, "",
-                 value_type, value_length);
-
-         buffer += value_length;
-          break;
-    }
-  }
-}
-          
-
 /*
  * 'asn1_encode_snmp()' - Encode a SNMP packet.
  */
@@ -715,6 +949,7 @@ asn1_encode_snmp(unsigned char *buffer,     /* I - Buffer */
   * Get the lengths of the community string, OID, and message...
   */
 
+
   namelen = asn1_size_oid(packet->object_name);
 
   switch (packet->object_type)
@@ -780,7 +1015,7 @@ asn1_encode_snmp(unsigned char *buffer,    /* I - Buffer */
   memcpy(bufptr, packet->community, commlen);
   bufptr += commlen;
 
-  *bufptr++ = packet->request_type;    /* Get-Request-PDU */
+  *bufptr++ = packet->request_type;    /* Get-Request-PDU/Get-Next-Request-PDU */
   asn1_set_length(&bufptr, reqlen);
 
   asn1_set_integer(&bufptr, packet->request_id);
@@ -880,7 +1115,7 @@ asn1_get_length(unsigned char **buffer,    /* IO - Pointer in buffer */
  * 'asn1_get_oid()' - Get an OID value.
  */
 
-static int                             /* O  - Last OID number */
+static int                             /* O  - Number of OIDs */
 asn1_get_oid(
     unsigned char **buffer,            /* IO - Pointer in buffer */
     unsigned char *bufend,             /* I  - End of buffer */
@@ -889,11 +1124,13 @@ asn1_get_oid(
     int           oidsize)             /* I  - Size of OID buffer */
 {
   unsigned char        *valend;                /* End of value */
-  int          *oidend;                /* End of OID buffer */
+  int          *oidptr,                /* Current OID */
+               *oidend;                /* End of OID buffer */
   int          number;                 /* OID number */
 
 
   valend = *buffer + length;
+  oidptr = oid;
   oidend = oid + oidsize - 1;
 
   if (valend > bufend)
@@ -903,28 +1140,28 @@ asn1_get_oid(
 
   if (number < 80)
   {
-    *oid++ = number / 40;
-    number = number % 40;
-    *oid++ = number;
+    *oidptr++ = number / 40;
+    number    = number % 40;
+    *oidptr++ = number;
   }
   else
   {
-    *oid++ = 2;
-    number -= 80;
-    *oid++ = number;
+    *oidptr++ = 2;
+    number    -= 80;
+    *oidptr++ = number;
   }
 
   while (*buffer < valend)
   {
     number = asn1_get_packed(buffer, bufend);
 
-    if (oid < oidend)
-      *oid++ = number;
+    if (oidptr < oidend)
+      *oidptr++ = number;
   }
 
-  *oid = 0;
+  *oidptr = -1;
 
-  return (number);
+  return (oidptr - oid);
 }
 
 
@@ -1126,9 +1363,15 @@ asn1_set_oid(unsigned char **buffer,     /* IO - Pointer in buffer */
 
   asn1_set_length(buffer, asn1_size_oid(oid));
 
+  if (oid[1] < 0)
+  {
+    asn1_set_packed(buffer, oid[0] * 40);
+    return;
+  }
+
   asn1_set_packed(buffer, oid[0] * 40 + oid[1]);
 
-  for (oid += 2; *oid; oid ++)
+  for (oid += 2; *oid >= 0; oid ++)
     asn1_set_packed(buffer, *oid);
 }
 
@@ -1143,25 +1386,25 @@ asn1_set_packed(unsigned char **buffer, /* IO - Pointer in buffer */
 {
   if (integer > 0xfffffff)
   {
-    **buffer = (integer >> 28) & 0x7f;
+    **buffer = ((integer >> 28) & 0x7f) | 0x80;
     (*buffer) ++;
   }
 
   if (integer > 0x1fffff)
   {
-    **buffer = (integer >> 21) & 0x7f;
+    **buffer = ((integer >> 21) & 0x7f) | 0x80;
     (*buffer) ++;
   }
 
   if (integer > 0x3fff)
   {
-    **buffer = (integer >> 14) & 0x7f;
+    **buffer = ((integer >> 14) & 0x7f) | 0x80;
     (*buffer) ++;
   }
 
   if (integer > 0x7f)
   {
-    **buffer = (integer >> 7) & 0x7f;
+    **buffer = ((integer >> 7) & 0x7f) | 0x80;
     (*buffer) ++;
   }
 
@@ -1217,7 +1460,12 @@ asn1_size_oid(const int *oid)            /* I - OID value */
   int  length;                         /* Length of value */
 
 
-  for (length = asn1_size_packed(oid[0] * 40 + oid[1]), oid += 2; *oid; oid ++)
+  if (oid[1] < 0)
+    return (asn1_size_packed(oid[0] * 40));
+
+  for (length = asn1_size_packed(oid[0] * 40 + oid[1]), oid += 2;
+       *oid >= 0;
+       oid ++)
     length += asn1_size_packed(*oid);
 
   return (length);
index b0a9703be69ec5daf71b1650eb0a111fc995bd5b..9f1d8dc1976bca859d70862475dec8f66c3cae56 100644 (file)
@@ -41,7 +41,7 @@
  * Types...
  */
 
-typedef enum cups_asn1_e               /**** ASN1 request/object types ****/
+enum cups_asn1_e                       /**** ASN1 request/object types ****/
 {
   CUPS_ASN1_END_OF_CONTENTS = 0x00,    /* End-of-contents */
   CUPS_ASN1_BOOLEAN = 0x01,            /* BOOLEAN */
@@ -51,13 +51,36 @@ typedef enum cups_asn1_e            /**** ASN1 request/object types ****/
   CUPS_ASN1_NULL_VALUE = 0x05,         /* NULL VALUE */
   CUPS_ASN1_OID = 0x06,                        /* OBJECT IDENTIFIER */
   CUPS_ASN1_SEQUENCE = 0x30,           /* SEQUENCE */
-  CUPS_ASN1_APPLICATION = 0x40,                /* Application-specific bit */
+  CUPS_ASN1_HEX_STRING = 0x40,         /* Binary string aka Hex-STRING */
   CUPS_ASN1_COUNTER = 0x41,            /* 32-bit unsigned aka Counter32 */
   CUPS_ASN1_GAUGE = 0x42,              /* 32-bit unsigned aka Gauge32 */
+  CUPS_ASN1_TIMETICKS = 0x43,          /* 32-bit unsigned aka Timeticks32 */
   CUPS_ASN1_GET_REQUEST = 0xa0,                /* GetRequest-PDU */
   CUPS_ASN1_GET_NEXT_REQUEST = 0xa1,   /* GetNextRequest-PDU */
   CUPS_ASN1_GET_RESPONSE = 0xa2                /* GetResponse-PDU */
-} cups_asn1_t;
+};
+typedef enum cups_asn1_e cups_asn1_t;  /**** ASN1 request/object types ****/
+
+struct cups_snmp_hexstring_s           /**** Hex-STRING value ****/
+{
+  unsigned char        bytes[CUPS_SNMP_MAX_STRING];
+                                       /* Bytes in string */
+  int          num_bytes;              /* Number of bytes */
+};
+
+union cups_snmp_value_u                        /**** Object value ****/
+{
+  int          boolean;                /* Boolean value */
+  int          integer;                /* Integer value */
+  unsigned     counter;                /* Counter value */
+  unsigned     gauge;                  /* Gauge value */
+  unsigned     timeticks;              /* Timeticks  value */
+  int          oid[CUPS_SNMP_MAX_OID]; /* OID value */
+  char         string[CUPS_SNMP_MAX_STRING];
+                                       /* String value */
+  struct cups_snmp_hexstring_s hex_string;
+                                       /* Hex string value */
+};
 
 typedef struct cups_snmp_s             /**** SNMP data packet ****/
 {
@@ -73,17 +96,11 @@ typedef struct cups_snmp_s          /**** SNMP data packet ****/
   int          object_name[CUPS_SNMP_MAX_OID];
                                        /* object-name value */
   cups_asn1_t  object_type;            /* object-value type */
-  union
-  {
-    int                boolean;                /* Boolean value */
-    int                integer;                /* Integer value */
-    unsigned   counter;                /* Counter value */
-    unsigned   gauge;                  /* Gauge value */
-    int                oid[CUPS_SNMP_MAX_OID]; /* OID value */
-    char       string[CUPS_SNMP_MAX_STRING];/* String value */
-  }            object_value;           /* object-value value */
+  union cups_snmp_value_u
+               object_value;           /* object-value value */
 } cups_snmp_t;
 
+typedef void (*cups_snmp_cb_t)(cups_snmp_t *packet, void *data);
 
 /*
  * Prototypes...
@@ -96,15 +113,20 @@ extern "C" {
 extern void            cupsSNMPClose(int fd) _CUPS_API_1_4;
 extern int             *cupsSNMPCopyOID(int *dst, const int *src, int dstsize)
                            _CUPS_API_1_4;
+extern const char      *cupsSNMPDefaultCommunity(void) _CUPS_API_1_4;
 extern int             cupsSNMPIsOID(cups_snmp_t *packet, const int *oid)
                            _CUPS_API_1_4;
 extern int             cupsSNMPIsOIDPrefixed(cups_snmp_t *packet,
                                              const int *prefix) _CUPS_API_1_4;
-extern int             cupsSNMPOpen(void) _CUPS_API_1_4;
+extern int             cupsSNMPOpen(int family) _CUPS_API_1_4;
 extern cups_snmp_t     *cupsSNMPRead(int fd, cups_snmp_t *packet, int msec)
                            _CUPS_API_1_4;
 extern void            cupsSNMPSetDebug(int level) _CUPS_API_1_4;
-extern int             cupsSNMPWrite(int fd, http_addr_t *addr, int version,
+extern int             cupsSNMPWalk(int fd, http_addr_t *address, int version,
+                                    const char *community, const int *prefix,
+                                    int msec, cups_snmp_cb_t cb, void *data)
+                           _CUPS_API_1_4;
+extern int             cupsSNMPWrite(int fd, http_addr_t *address, int version,
                                      const char *community,
                                      cups_asn1_t request_type,
                                      const unsigned request_id,
index 7a3ccfc77b9215f466af2a3a8ddb32127f424f10..e13b238470e0b7d1f3db6bd4a589b50f7105c5c3 100644 (file)
  *
  * Contents:
  *
- *   main() - Main entry.
+ *   main()     - Main entry.
+ *   scan_oid() - Scan an OID value.
+ *   show_oid() - Show the specified OID.
+ *   usage()    - Show program usage and exit.
  */
 
 /*
  * Local functions...
  */
 
-static int     *scan_oid(char *s, int *oid, int oidsize);
-static int     show_oid(int fd, char *s, http_addr_t *addr);
+static void    print_packet(cups_snmp_t *packet, void *data);
+static int     *scan_oid(const char *s, int *oid, int oidsize);
+static int     show_oid(int fd, const char *community,
+                        http_addr_t *addr, const char *s, int walk);
+static void    usage(void);
 
 
 /*
@@ -46,46 +52,158 @@ main(int  argc,                            /* I - Number of command-line args */
      char *argv[])                     /* I - Command-line arguments */
 {
   int                  i;              /* Looping var */
-  int                  fd;             /* SNMP socket */
-  http_addrlist_t      *host;          /* Address of host */
+  int                  fd = -1;        /* SNMP socket */
+  http_addrlist_t      *host = NULL;   /* Address of host */
+  int                  walk = 0;       /* Walk OIDs? */
+  char                 *oid = NULL;    /* Last OID shown */
+  const char           *community;     /* Community name */
 
 
-  if (argc < 2)
+  fputs("cupsSNMPDefaultCommunity: ", stdout);
+
+  if ((community = cupsSNMPDefaultCommunity()) == NULL)
   {
-    puts("Usage: ./testsnmp host-or-ip");
+    puts("FAIL (NULL community name)");
     return (1);
   }
 
-  if ((host = httpAddrGetList(argv[1], AF_UNSPEC, "161")) == NULL)
+  printf("PASS (%s)\n", community);
+
+ /*
+  * Query OIDs from the command-line...
+  */
+
+  for (i = 1; i < argc; i ++)
+    if (!strcmp(argv[i], "-c"))
+    {
+      i ++;
+
+      if (i >= argc)
+        usage();
+      else
+        community = argv[i];
+    }
+    else if (!strcmp(argv[i], "-d"))
+      cupsSNMPSetDebug(10);
+    else if (!strcmp(argv[i], "-w"))
+      walk = 1;
+    else if (!host)
+    {
+      if ((host = httpAddrGetList(argv[i], AF_UNSPEC, "161")) == NULL)
+      {
+       printf("testsnmp: Unable to find \"%s\"!\n", argv[1]);
+       return (1);
+      }
+
+      if (fd < 0)
+      {
+       fputs("cupsSNMPOpen: ", stdout);
+
+       if ((fd = cupsSNMPOpen(host->addr.addr.sa_family)) < 0)
+       {
+         printf("FAIL (%s)\n", strerror(errno));
+         return (1);
+       }
+
+       puts("PASS");
+      }
+    }
+    else if (!show_oid(fd, community, &(host->addr), argv[i], walk))
+      return (1);
+    else
+      oid = argv[i];
+
+  if (!host)
+    usage();
+
+  if (!oid)
   {
-    printf("Unable to find \"%s\"!\n", argv[1]);
-    return (1);
+    if (!show_oid(fd, community,  &(host->addr),
+                  walk ? "1.3.6.1.2.1.43" :
+                        "1.3.6.1.2.1.43.10.2.1.4.1.1", walk))
+      return (1);
   }
+  
+  return (0);
+}
 
-  fputs("cupsSNMPOpen: ", stdout);
 
-  if ((fd = cupsSNMPOpen()) < 0)
-  {
-    printf("FAIL (%s)\n", strerror(errno));
-    return (1);
-  }
+/*
+ * 'print_packet()' - Print the contents of the response packet.
+ */
 
-  puts("PASS");
+static void
+print_packet(cups_snmp_t *packet,      /* I - SNMP response packet */
+             void        *data)                /* I - User data pointer (not used) */
+{
+  int  i;                              /* Looping var */
 
-  if (argc > 2)
+
+  (void)data;
+
+  printf("%d", packet->object_name[0]);
+  for (i = 1; packet->object_name[i] >= 0; i ++)
+    printf(".%d", packet->object_name[i]);
+  fputs(" = ", stdout);
+
+  switch (packet->object_type)
   {
-   /*
-    * Query OIDs from the command-line...
-    */
+    case CUPS_ASN1_BOOLEAN :
+       printf("BOOLEAN %s\n",
+              packet->object_value.boolean ? "TRUE" : "FALSE");
+       break;
 
-    for (i = 2; i < argc; i ++)
-      if (!show_oid(fd, argv[i], &(host->addr)))
-        return (1);
+    case CUPS_ASN1_INTEGER :
+       printf("INTEGER %d\n", packet->object_value.integer);
+       break;
+
+    case CUPS_ASN1_BIT_STRING :
+       printf("BIT-STRING \"%s\"\n", packet->object_value.string);
+       break;
+
+    case CUPS_ASN1_OCTET_STRING :
+       printf("OCTET-STRING \"%s\"\n", packet->object_value.string);
+       break;
+
+    case CUPS_ASN1_NULL_VALUE :
+       puts("NULL-VALUE");
+       break;
+
+    case CUPS_ASN1_OID :
+       printf("OID %d", packet->object_value.oid[0]);
+       for (i = 1; packet->object_value.oid[i] >= 0; i ++)
+         printf(".%d", packet->object_value.oid[i]);
+       putchar('\n');
+       break;
+
+    case CUPS_ASN1_HEX_STRING :
+       fputs("Hex-STRING", stdout);
+       for (i = 0; i < packet->object_value.hex_string.num_bytes; i ++)
+         printf(" %02X", packet->object_value.hex_string.bytes[i]);
+       putchar('\n');
+       break;
+
+    case CUPS_ASN1_COUNTER :
+       printf("Counter %d\n", packet->object_value.counter);
+       break;
+
+    case CUPS_ASN1_GAUGE :
+       printf("Gauge %u\n", packet->object_value.gauge);
+       break;
+
+    case CUPS_ASN1_TIMETICKS :
+       printf("Timeticks %u days, %u:%02u:%02u.%02u\n",
+              packet->object_value.timeticks / 8640000,
+              (packet->object_value.timeticks / 360000) % 24,
+              (packet->object_value.timeticks / 6000) % 60,
+              (packet->object_value.timeticks / 100) % 60,
+              packet->object_value.timeticks % 100);
+       break;
+
+    default :
+       printf("Unknown-%X\n", packet->object_type);
+       break;
   }
-  else if (!show_oid(fd, (char *)"1.3.6.1.2.1.43.10.2.1.4.1.1", &(host->addr)))
-    return (1);
-  
-  return (0);
 }
 
 
@@ -94,28 +212,28 @@ main(int  argc,                            /* I - Number of command-line args */
  */
 
 static int *                           /* O - OID or NULL on error */
-scan_oid(char *s,                      /* I - OID string */
-         int  *oid,                    /* I - OID array */
-        int  oidsize)                  /* I - Size of OID array in integers */
+scan_oid(const char *s,                        /* I - OID string */
+         int        *oid,              /* I - OID array */
+        int        oidsize)            /* I - Size of OID array in integers */
 {
   int  i;                              /* Index into OID array */
   char *ptr;                           /* Pointer into string */
 
 
-  for (ptr = s, i = 0, oidsize --; ptr && *ptr && i < oidsize; i ++)
+  for (ptr = (char *)s, i = 0, oidsize --; ptr && *ptr && i < oidsize; i ++)
   {
     if (!isdigit(*ptr & 255))
       return (NULL);
 
     oid[i] = strtol(ptr, &ptr, 10);
-    if (*ptr == '.')
+    if (ptr && *ptr == '.')
       ptr ++;
   }
 
   if (i >= oidsize)
     return (NULL);
 
-  oid[i] = 0;
+  oid[i] = -1;
 
   return (oid);
 }
@@ -127,95 +245,100 @@ scan_oid(char *s,                        /* I - OID string */
 
 static int                             /* O - 1 on success, 0 on error */
 show_oid(int         fd,               /* I - SNMP socket */
-         char        *s,               /* I - OID to query */
-        http_addr_t *addr)             /* I - Address to query */
+         const char  *community,       /* I - Community name */
+        http_addr_t *addr,             /* I - Address to query */
+         const char  *s,               /* I - OID to query */
+        int         walk)              /* I - Walk OIDs? */
 {
   int          i;                      /* Looping var */
-  int          oid[255];               /* OID */
+  int          oid[CUPS_SNMP_MAX_OID]; /* OID */
   cups_snmp_t  packet;                 /* SNMP packet */
 
 
-  printf("cupsSNMPWrite(%s): ", s);
-
   if (!scan_oid(s, oid, sizeof(oid) / sizeof(oid[0])))
   {
-    puts("FAIL (bad OID)");
+    puts("testsnmp: Bad OID");
     return (0);
   }
 
-  if (!cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, "public",
-                     CUPS_ASN1_GET_REQUEST, 1, oid))
+  if (walk)
   {
-    puts("FAIL");
-    return (0);
+    printf("cupsSNMPWalk(%d", oid[0]);
+    for (i = 1; oid[i] >= 0; i ++)
+      printf(".%d", oid[i]);
+    puts("):");
+
+    if (cupsSNMPWalk(fd, addr, CUPS_SNMP_VERSION_1, community, oid, 5000,
+                     print_packet, NULL) < 0)
+    {
+      printf("FAIL (%s)\n", strerror(errno));
+      return (0);
+    }
   }
-
-  puts("PASS");
-
-  fputs("cupsSNMPRead(5000): ", stdout);
-
-  if (!cupsSNMPRead(fd, &packet, 5000))
+  else
   {
-    puts("FAIL (timeout)");
-    return (0);
+    printf("cupsSNMPWrite(%d", oid[0]);
+    for (i = 1; oid[i] >= 0; i ++)
+      printf(".%d", oid[i]);
+    fputs("): ", stdout);
+
+    if (!cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, community,
+                      CUPS_ASN1_GET_REQUEST, 1, oid))
+    {
+      printf("FAIL (%s)\n", strerror(errno));
+      return (0);
+    }
+
+    puts("PASS");
+
+    fputs("cupsSNMPRead(5000): ", stdout);
+
+    if (!cupsSNMPRead(fd, &packet, 5000))
+    {
+      puts("FAIL (timeout)");
+      return (0);
+    }
+
+    if (!cupsSNMPIsOID(&packet, oid))
+    {
+      printf("FAIL (bad OID %d", packet.object_name[0]);
+      for (i = 1; packet.object_name[i] >= 0; i ++)
+       printf(".%d", packet.object_name[i]);
+      puts(")");
+      return (0);
+    }
+
+    if (packet.error)
+    {
+      printf("FAIL (%s)\n", packet.error);
+      return (0);
+    }
+
+    puts("PASS");
+
+    print_packet(&packet, NULL);
   }
 
-  if (!cupsSNMPIsOID(&packet, oid))
-  {
-    puts("FAIL (bad OID)");
-    return (0);
-  }
-
-  if (packet.error)
-  {
-    printf("FAIL (%s)\n", packet.error);
-    return (0);
-  }
-
-  switch (packet.object_type)
-  {
-    case CUPS_ASN1_BOOLEAN :
-        printf("PASS (BOOLEAN %s)\n",
-              packet.object_value.boolean ? "TRUE" : "FALSE");
-        break;
-
-    case CUPS_ASN1_INTEGER :
-        printf("PASS (INTEGER %d)\n", packet.object_value.integer);
-        break;
-
-    case CUPS_ASN1_BIT_STRING :
-        printf("PASS (BIT-STRING \"%s\")\n", packet.object_value.string);
-        break;
-
-    case CUPS_ASN1_OCTET_STRING :
-        printf("PASS (OCTET-STRING \"%s\")\n", packet.object_value.string);
-        break;
-
-    case CUPS_ASN1_NULL_VALUE :
-        puts("PASS (NULL-VALUE)");
-        break;
-
-    case CUPS_ASN1_OID :
-        printf("PASS (OID %d", packet.object_value.oid[0]);
-       for (i = 1; packet.object_value.oid[i]; i ++)
-         printf(".%d", packet.object_value.oid[i]);
-       puts(")");
-        break;
-
-    case CUPS_ASN1_COUNTER :
-        printf("PASS (Counter %d)\n", packet.object_value.counter);
-        break;
+  return (1);
+}
 
-    case CUPS_ASN1_GAUGE:
-        printf("PASS (Gauge %u)\n", packet.object_value.gauge);
-        break;
 
-    default :
-        printf("PASS (Unknown-%X)\n", packet.object_type);
-       break;
-  }
+/*
+ * 'usage()' - Show program usage and exit.
+ */
 
-  return (1);
+static void
+usage(void)
+{
+  puts("Usage: testsnmp [options] host-or-ip [oid ...]");
+  puts("");
+  puts("Options:");
+  puts("");
+  puts("  -c community    Set community name");
+  puts("  -d              Enable debugging");
+  puts("  -w              Walk all OIDs under the specified one");
+
+  exit (1);
 }
 
 
index f060e382dd719196ca8b36b30767602d45efaee5..85fb590afe76ea5f12b89c904f4abc91fdb5d9c3 100644 (file)
@@ -3,7 +3,7 @@
 #
 #   Datafile makefile for the Common UNIX Printing System (CUPS).
 #
-#   Copyright 2007 by Apple Inc.
+#   Copyright 2007-2008 by Apple Inc.
 #   Copyright 1993-2006 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -74,6 +74,16 @@ DATAFILES =  \
                psglyphs \
                testprint.ps
 
+PPDCFILES =    \
+               epson.h \
+               escp.h \
+               font.defs \
+               hp.h \
+               label.h \
+               media.defs \
+               pcl.h \
+               raster.defs
+
 
 #
 # Make everything...
@@ -117,6 +127,10 @@ install:   all
        for file in $(DATAFILES); do \
                $(INSTALL_DATA) $$file $(DATADIR)/data; \
        done
+       $(INSTALL_DIR) -m 755 $(DATADIR)/ppdc
+       for file in $(PPDCFILES); do \
+               $(INSTALL_DATA) $$file $(DATADIR)/ppdc; \
+       done
        $(INSTALL_DIR) -m 755 $(DATADIR)/profiles
 
 
@@ -137,7 +151,11 @@ uninstall:
        for file in $(DATAFILES); do \
                $(RM) $(DATADIR)/data/$$file; \
        done
+       for file in $(PPDCFILES); do \
+               $(RM) $(DATADIR)/ppdc/$$file; \
+       done
        -$(RMDIR) $(DATADIR)/profiles
+       -$(RMDIR) $(DATADIR)/ppdc
        -$(RMDIR) $(DATADIR)/data
        -$(RMDIR) $(DATADIR)/charsets
        -$(RMDIR) $(DATADIR)/charmaps
diff --git a/data/epson.h b/data/epson.h
new file mode 100644 (file)
index 0000000..13cb1a3
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * "$Id$"
+ *
+ *   This file contains model number definitions for the CUPS sample
+ *   ESC/P driver.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+#define EPSON_9PIN     0               /* 9-pin dot matrix */
+#define EPSON_24PIN    1               /* 24-pin dot matrix */
+#define EPSON_COLOR    2               /* Epson Stylus Color with ESC . */
+#define EPSON_PHOTO    3               /* Epson Stylus Photo with ESC . */
+#define EPSON_ICOLOR   4               /* Epson Stylus Color with ESC i */
+#define EPSON_IPHOTO   5               /* Epson Stylus Photo with ESC i */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/escp.h b/data/escp.h
new file mode 100644 (file)
index 0000000..94389f3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * "$Id$"
+ *
+ *   This file contains model number definitions for the CUPS unified
+ *   ESC/P driver.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+/* General ESC/P Support */
+#define ESCP_DOTMATRIX         0x1             /* Dot matrix printer? */
+#define ESCP_MICROWEAVE                0x2             /* Use microweave command? */
+#define ESCP_STAGGER           0x4             /* Are color jets staggered? */
+#define ESCP_ESCK              0x8             /* Use print mode command?*/
+#define ESCP_EXT_UNITS         0x10            /* Use extended unit commands? */
+#define ESCP_EXT_MARGINS       0x20            /* Use extended margin command */
+#define ESCP_USB               0x40            /* Send USB packet mode escape? */
+#define ESCP_PAGE_SIZE         0x80            /* Use page size command */
+#define ESCP_RASTER_ESCI       0x100           /* Use ESC i graphics command */
+
+/* Remote mode support */
+#define ESCP_REMOTE            0x1000          /* Use remote mode commands? */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/font.defs b/data/font.defs
new file mode 100644 (file)
index 0000000..ee4559e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * "$Id: font.defs 343 2007-07-13 19:52:48Z mike $"
+ *
+ *   Standard ESP Ghostscript font definitions for the CUPS PPD file
+ *   compiler.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+#font AvantGarde-Book Standard "(1.05)" Standard ROM
+#font AvantGarde-BookOblique Standard "(1.05)" Standard ROM
+#font AvantGarde-Demi Standard "(1.05)" Standard ROM
+#font AvantGarde-DemiOblique Standard "(1.05)" Standard ROM
+#font Bookman-Demi Standard "(1.05)" Standard ROM
+#font Bookman-DemiItalic Standard "(1.05)" Standard ROM
+#font Bookman-Light Standard "(1.05)" Standard ROM
+#font Bookman-LightItalic Standard "(1.05)" Standard ROM
+#font Courier Standard "(1.05)" Standard ROM
+#font Courier-Bold Standard "(1.05)" Standard ROM
+#font Courier-BoldOblique Standard "(1.05)" Standard ROM
+#font Courier-Oblique Standard "(1.05)" Standard ROM
+#font Helvetica Standard "(1.05)" Standard ROM
+#font Helvetica-Bold Standard "(1.05)" Standard ROM
+#font Helvetica-BoldOblique Standard "(1.05)" Standard ROM
+#font Helvetica-Narrow Standard "(1.05)" Standard ROM
+#font Helvetica-Narrow-Bold Standard "(1.05)" Standard ROM
+#font Helvetica-Narrow-BoldOblique Standard "(1.05)" Standard ROM
+#font Helvetica-Narrow-Oblique Standard "(1.05)" Standard ROM
+#font Helvetica-Oblique Standard "(1.05)" Standard ROM
+#font NewCenturySchlbk-Bold Standard "(1.05)" Standard ROM
+#font NewCenturySchlbk-BoldItalic Standard "(1.05)" Standard ROM
+#font NewCenturySchlbk-Italic Standard "(1.05)" Standard ROM
+#font NewCenturySchlbk-Roman Standard "(1.05)" Standard ROM
+#font Palatino-Bold Standard "(1.05)" Standard ROM
+#font Palatino-BoldItalic Standard "(1.05)" Standard ROM
+#font Palatino-Italic Standard "(1.05)" Standard ROM
+#font Palatino-Roman Standard "(1.05)" Standard ROM
+#font Symbol Special "(001.005)" Special ROM
+#font Times-Bold Standard "(1.05)" Standard ROM
+#font Times-BoldItalic Standard "(1.05)" Standard ROM
+#font Times-Italic Standard "(1.05)" Standard ROM
+#font Times-Roman Standard "(1.05)" Standard ROM
+#font ZapfChancery-MediumItalic Standard "(1.05)" Standard ROM
+#font ZapfDingbats Special "(001.005)" Special ROM
+
+/*
+ * End of "$Id: font.defs 343 2007-07-13 19:52:48Z mike $".
+ */
diff --git a/data/hp.h b/data/hp.h
new file mode 100644 (file)
index 0000000..c700343
--- /dev/null
+++ b/data/hp.h
@@ -0,0 +1,24 @@
+/*
+ * "$Id$"
+ *
+ *   This file contains model number definitions for the CUPS sample
+ *   HP driver.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+#define HP_LASERJET    0               /* HP LaserJet */
+#define HP_DESKJET     1               /* HP DeskJet with simple color */
+#define HP_DESKJET2    2               /* HP DeskJet with CRet color */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/label.h b/data/label.h
new file mode 100644 (file)
index 0000000..4b6fba6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * "$Id$"
+ *
+ *   This file contains model number definitions for the CUPS sample
+ *   label printer driver.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+#define DYMO_3x0       0               /* Dymo Labelwriter 300/330/330 Turbo */
+
+#define ZEBRA_EPL_LINE  0x10            /* Zebra EPL line mode printers */
+#define ZEBRA_EPL_PAGE  0x11            /* Zebra EPL page mode printers */
+#define ZEBRA_ZPL       0x12            /* Zebra ZPL-based printers */
+#define ZEBRA_CPCL      0x13            /* Zebra CPCL-based printers */
+
+#define INTELLITECH_PCL        0x20            /* Intellitech PCL-based printers */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/media.defs b/data/media.defs
new file mode 100644 (file)
index 0000000..07a4911
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * "$Id: media.defs 343 2007-07-13 19:52:48Z mike $"
+ *
+ *   Adobe standard media size definitions for the CUPS PPD file compiler.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 by Easy Software Products.
+ *
+ *   These codedinstructions, statements, and computer programs are the
+ *   property of Apple Inc. and are protected by Federal copyright
+ *   copyright law.  Distribution and use rights are outlinedin the file
+ *   "LICENSE.txt" which should have beenincluded with this file.  If this
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
+#media "10x11/10x11 - 10x11in" 720 792
+#media "10x13/10x13 - 10x13in" 720 936
+#media "10x14/10x14 - 10x14in" 720 1008
+#media "12x11/12x11 - 12x11in" 864 792
+#media "15x11/15x11 - 15x11in" 1080 792
+#media "7x9/7x9 - 7x9in" 504 648
+#media "8x10/8x10 - 8x10in" 576 720
+#media "9x11/9x11 - 9x11in" 648 792
+#media "9x12/9x12 - 9x12in" 648 864
+#media "A0/A0 - 841x1189mm" 2384 3370
+#media "A0.Transverse/A0 - 1189x841mm" 3370 2384
+#media "A10/A10 - 26x37mm" 73 105
+#media "A1/A1 - 594x841mm" 1684 2384
+#media "A1.Transverse/A1 - 841x594mm" 2384 1684
+#media "A2/A2 - 420x594mm" 1191 1684
+#media "A2.Transverse/A2 - 594x420mm" 1684 1191
+#media "A3/A3 - 297x420mm" 842 1191
+#media "A3Extra/A3 Extra - 322x445mm" 913 1262
+#media "A3Extra.Transverse/A3 Extra.Transverse - 322x445mm" 913 1262
+#media "A3Rotated/A3 Rotated - 420x297mm" 1191 842
+#media "A3.Transverse/A3 - 420x297mm" 1191 842
+#media "A4/A4 - 210x297mm" 595 842
+#media "A4Extra/A4 Extra - 9.270x12.690in" 667 914
+#media "A4Plus/A4 Plus - 210x330mm" 595 936
+#media "A4Rotated/A4 Rotated - 297x210mm" 842 595
+#media "A4Small/A4 Small - 210x297mm" 595 842
+#media "A4.Transverse/A4 - 297x210mm" 842 595
+#media "A5/A5 - 148x210mm" 420 595
+#media "A5/A5 - 149x210mm" 420 595
+#media "A5Extra/A5 Extra - 174x235mm" 492 668
+#media "A5Rotated/A5 Rotated - 210x148mm" 595 420
+#media "A5.Transverse/A5 - 210x149mm" 595 420
+#media "A6/A6 - 105x148mm" 297 420
+#media "A6Rotated/A6 Rotated - 148x105mm" 420 297
+#media "A7/A7 - 74x105mm" 210 297
+#media "A8/A8 - 52x74mm" 148 210
+#media "A9/A9 - 37x52mm" 105 148
+#media "AnsiA/ANSI A - 8.5x11in" 612 792
+#media "AnsiB/ANSI B - 11x17in" 792 1224
+#media "AnsiC/ANSI C - 17x22in" 1224 1584
+#media "AnsiD/ANSI D - 22x34in" 1584 2448
+#media "AnsiE/ANSI E - 34x44in" 2448 3168
+#media "ARCHA/Arch. A - 9x12in" 648 864
+#media "ARCHA.Transverse/Arch. A - 12x9in" 864 648
+#media "ARCHB/Arch. B - 12x18in" 864 1296
+#media "ARCHB.Transverse/Arch. B - 18x12in" 1296 864
+#media "ARCHC/Arch. C - 18x24in" 1296 1728
+#media "ARCHC.Transverse/Arch. C - 24x18in" 1728 1296
+#media "ARCHD/Arch. D - 24x36in" 1728 2592
+#media "ARCHD.Transverse/Arch. D - 36x24in" 2592 1728
+#media "ARCHE/Arch. E - 36x48in" 2592 3456
+#media "ARCHE.Transverse/Arch. E - 48x36in" 3456 2592
+#media "B0/B0 - 1030x1456mm" 2920 4127
+#media "B10/B10 - 32x45mm" 91 127
+#media "B1/B1 - 728x1028mm" 2064 2918
+#media "B1/B1 - 728x1030mm" 2064 2920
+#media "B2/B2 - 515x728mm" 1460 2064
+#media "B3/B3 - 364x515mm" 1032 1460
+#media "B4/B4 - 257x364mm" 729 1032
+#media "B4Rotated/B4 Rotated - 364x257mm" 1032 729
+#media "B5/B5 - 182x257mm" 516 729
+#media "B5Rotated/B5 Rotated - 257x182mm" 729 516
+#media "B5.Transverse/B5.Transverse - 182x257mm" 516 729
+#media "B6/B6 - 128x182mm" 363 516
+#media "B6Rotated/B6 Rotated - 182x128mm" 516 363
+#media "B7/B7 - 91x128mm" 258 363
+#media "B8/B8 - 64x91mm" 181 258
+#media "B9/B9 - 45x64mm" 127 181
+#media "C4/C4 - 229x324mm" 649 918
+#media "C5/C5 - 162x229mm" 459 649
+#media "C6/C6 - 114x162mm" 323 459
+#media "DL/DL - 110x220mm" 312 624
+#media "DoublePostcard/DoublePostcard - 200x148mm" 567 420
+#media "DoublePostcardRotated/DoublePostcardRotated - 148x200mm" 420 567
+#media "Env10/#10 Envelope - 4.13x9.5in" 297 684
+#media "Env11/#11 Envelope - 4.5x10.375in" 324 747
+#media "Env12/#12 Envelope - 4.75x11in" 342 792
+#media "Env14/#14 Envelope - 127x292mm" 360 828
+#media "Env9/#9 Envelope - 3.875x8.875in" 279 639
+#media "EnvC0/C0 Envelope - 917x1297mm" 2599 3676
+#media "EnvC1/C1 Envelope - 648x917mm" 1837 2599
+#media "EnvC2/C2 Envelope - 458x648mm" 1298 1837
+#media "EnvC3/C3 Envelope - 324x458mm" 918 1296
+#media "EnvC4/C4 Envelope - 229x324mm" 649 918
+#media "EnvC5/C5 Envelope - 162x229mm" 459 649
+#media "EnvC65/C65 Envelope - 114x229mm" 324 648
+#media "EnvC6/C6 Envelope - 114x162mm" 323 459
+#media "EnvC7/C7 Envelope - 81x114mm" 230 323
+#media "EnvChou3/Chou3 Envelope - 120x235mm" 340 666
+#media "EnvChou3Rotated/Chou3 Envelope Rotated - 235x120mm" 666 340
+#media "EnvChou4/Chou4 Envelope - 90x205mm" 255 581
+#media "EnvChou4Rotated/Chou4 Envelope Rotated - 205x90mm" 581 255
+#media "EnvDL/DL Envelope - 110x220mm" 312 624
+#media "EnvInvite/Invite Envelope - 220x220mm" 624 624
+#media "EnvISOB4/ISOB4 Envelope - 250x353mm" 708 1001
+#media "EnvISOB5/ISOB5 Envelope - 176x250mm" 499 709
+#media "EnvISOB6/ISOB6 Envelope - 176x125mm" 499 354
+#media "EnvItalian/Italian Envelope - 110x230mm" 312 652
+#media "EnvKaku2/Kaku2 Envelope - 240x332mm" 680 941
+#media "EnvKaku2Rotated/Kaku2 Envelope Rotated - 332x240mm" 941 680
+#media "EnvKaku3/Kaku3 Envelope - 216x277mm" 612 785
+#media "EnvKaku3Rotated/Kaku3 Envelope Rotated - 277x216mm" 785 612
+#media "EnvMonarch/Monarch Envelope - 3.875x7.5in" 279 540
+#media "EnvPersonal/Personal Envelope - 3.625x6.5in" 261 468
+#media "EnvPRC10/PRC10 Envelope - 324x458mm" 918 1298
+#media "EnvPRC10Rotated/PRC10 Envelope Rotated - 458x324mm" 1298 918
+#media "EnvPRC1/PRC1 Envelope - 102x165mm" 289 468
+#media "EnvPRC1Rotated/PRC1 Envelope Rotated - 165x102mm" 468 289
+#media "EnvPRC2/PRC2 Envelope - 102x176mm" 289 499
+#media "EnvPRC2Rotated/PRC2 Envelope Rotated - 176x102mm" 499 289
+#media "EnvPRC3/PRC3 Envelope - 125x176mm" 354 499
+#media "EnvPRC3Rotated/PRC3 Envelope Rotated - 176x125mm" 499 354
+#media "EnvPRC4/PRC4 Envelope - 110x208mm" 312 590
+#media "EnvPRC4Rotated/PRC4 Envelope Rotated - 208x110mm" 590 312
+#media "EnvPRC5/PRC5 Envelope - 110x220mm" 312 624
+#media "EnvPRC5Rotated/PRC5 Envelope Rotated - 220x110mm" 624 312
+#media "EnvPRC6/PRC6 Envelope - 120x230mm" 340 652
+#media "EnvPRC6Rotated/PRC6 Envelope Rotated - 230x120mm" 652 340
+#media "EnvPRC7/PRC7 Envelope - 160x230mm" 454 652
+#media "EnvPRC7Rotated/PRC7 Envelope Rotated - 230x160mm" 652 454
+#media "EnvPRC8/PRC8 Envelope - 120x309mm" 340 876
+#media "EnvPRC8Rotated/PRC8 Envelope Rotated - 309x120mm" 876 340
+#media "EnvPRC9/PRC9 Envelope - 229x324mm" 649 918
+#media "EnvPRC9Rotated/PRC9 Envelope Rotated - 324x229mm" 918 649
+#media "EnvYou4/You4 Envelope - 105x235mm" 298 666
+#media "EnvYou4Rotated/You4 Envelope Rotated - 235x105mm" 666 298
+#media "Executive/Executive - 7.25x10.5in" 522 756
+#media "FanFoldGerman/FanFold German - 8.5x12in" 612 864
+#media "FanFoldGermanLegal/FanFold German Legal - 216x330mm" 612 936
+#media "FanFoldUS/Fanfold - 14.875x11in" 1071 792
+#media "Folio/Folio - 210x330mm" 595 935
+#media "ISOB0/ISOB0 - 1000x1414mm" 2835 4008
+#media "ISOB10/ISOB10 - 31x44mm" 88 125
+#media "ISOB1/ISOB1 - 707x1000mm" 2004 2835
+#media "ISOB2/ISOB2 - 500x707mm" 1417 2004
+#media "ISOB3/ISOB3 - 353x500mm" 1001 1417
+#media "ISOB4/ISOB4 - 250x353mm" 709 1001
+#media "ISOB5Extra/ISOB5 Extra - 201x276mm" 570 782
+#media "ISOB5/ISOB5 - 176x250mm" 499 709
+#media "ISOB6/ISOB6 - 125x176mm" 354 499
+#media "ISOB7/ISOB7 - 88x125mm" 249 354
+#media "ISOB8/ISOB8 - 62x88mm" 176 249
+#media "ISOB9/ISOB9 - 44x62mm" 125 176
+#media "Ledger/Ledger - 17x11in" 1224 792
+#media "LegalExtra/Legal Extra - 9.5x15in" 684 1080
+#media "Legal/Legal - 8.5x14in" 612 1008
+#media "LetterExtra/Letter Extra - 9.5x12in" 684 864
+#media "LetterExtra.Transverse/Letter Extra - 12x9.5in" 864 684
+#media "Letter/Letter - 8.5x11in" 612 792
+#media "LetterPlus/Letter Plus - 8.5x12.690in" 612 914
+#media "LetterRotated/Letter Rotated - 11x8.5in" 792 612
+#media "LetterSmall/Letter Small - 8.5x11in" 612 792
+#media "Letter.Transverse/Letter - 11x8.5in" 792 612
+#media "Monarch/Monarch - 3.875x7.5in" 279 540
+#media "Note/Note - 8.5x11in" 612 792
+#media "Postcard/Postcard - 100x148mm" 284 419
+#media "PostcardRotated/PostcardRotated - 148x100mm" 419 284
+#media "PRC16K/PRC16K - 146x215mm" 414 610
+#media "PRC16KRotated/PRC16KRotated - 215x146mm" 610 414
+#media "PRC32KBig/PRC32KBig - 97x151mm" 275 428
+#media "PRC32KBigRotated/PRC32KBigRotated - 151x97mm" 428 275
+#media "PRC32K/PRC32K - 97x151mm" 275 428
+#media "PRC32KRotated/PRC32KRotated - 151x97mm" 428 275
+#media "Quarto/Quarto - 8.5x10.830in" 610 780
+#media "Statement/Statement - 5.5x8.5in" 396 612
+#media "SuperA/SuperA - 227x356mm" 643 1009
+#media "SuperB/SuperB - 305x487mm" 864 1380
+#media "TabloidExtra/Tabloid Extra - 12x18in" 864 1296
+#media "Tabloid/Tabloid - 11x17in" 792 1224
+
+/*
+ * Non-standard sizes...
+ */
+
+#media "Photo4x6/Photo - 4x6in" 288 432
+#media "PhotoLabel/Photo Labels - 4x6.5in" 288 468
+#media "w288h418/Photo - 4x5.8in" 288 418
+#media "w936h1368/Super B/A3 - 13x19in" 936 1368
+#media "w81h252/Address - 1 1/8x3 1/2in" 81 252
+#media "w101h252/Large Address - 1 4/10x3 1/2in" 101 252
+#media "w54h144/Return Address - 3/4x2in" 54 144
+#media "w167h288/Shipping Address - 2 5/16x4in" 167 288
+#media "w162h540/Internet Postage 2-Part - 2 1/4x7 1/2in" 162 540
+#media "w162h504/Internet Postage 3-Part - 2 1/4x7in" 162 504
+#media "w41h248/File Folder - 9/16x3 7/16in" 41 248
+#media "w41h144/Hanging Folder - 9/16x2in" 41 144
+#media "w153h198/3.5\" Disk - 2 1/8x2 3/4in" 153 198
+
+
+/*
+ * End of "$Id: media.defs 343 2007-07-13 19:52:48Z mike $".
+ */
diff --git a/data/pcl.h b/data/pcl.h
new file mode 100644 (file)
index 0000000..0cb1eff
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * "$Id$"
+ *
+ *   This file contains model number definitions for the CUPS unified
+ *   PCL driver.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+/* General PCL Support */
+#define PCL_PAPER_SIZE         0x1             /* Use ESC&l#A */
+#define PCL_INKJET             0x2             /* Use inkjet commands */
+
+/* Raster Support */
+#define PCL_RASTER_END_COLOR   0x100           /* Use ESC*rC */
+#define PCL_RASTER_CID         0x200           /* Use ESC*v#W */
+#define PCL_RASTER_CRD         0x400           /* Use ESC*g#W */
+#define PCL_RASTER_SIMPLE      0x800           /* Use ESC*r#U */
+#define PCL_RASTER_RGB24       0x1000          /* Use 24-bit RGB mode */
+
+/* PJL Support */
+#define PCL_PJL                        0x10000         /* Use PJL Commands */
+#define PCL_PJL_PAPERWIDTH     0x20000         /* Use PJL PAPERWIDTH/LENGTH */
+#define PCL_PJL_HPGL2          0x40000         /* Enter HPGL2 */
+#define PCL_PJL_PCL3GUI                0x80000         /* Enter PCL3GUI */
+#define PCL_PJL_RESOLUTION     0x100000        /* Use PJL SET RESOLUTION */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/raster.defs b/data/raster.defs
new file mode 100644 (file)
index 0000000..486165f
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * "$Id: raster.defs 343 2007-07-13 19:52:48Z mike $"
+ *
+ *   This file contains the standard definitions for enumerated attributes
+ *   in the CUPS raster page device dictionary.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1997-2005 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/".
+ */
+
+/* Jog values */
+#define CUPS_JOG_NONE          0       /* Never move pages */
+#define CUPS_JOG_FILE          1       /* Move pages after this file */
+#define CUPS_JOG_JOB           2       /* Move pages after this job */
+#define CUPS_JOG_SET           3       /* Move pages after this set */
+
+/* Orientation values */
+#define CUPS_ORIENT_0          0       /* Don't rotate the page */
+#define CUPS_ORIENT_90         1       /* Rotate the page counter-clockwise */
+#define CUPS_ORIENT_180                2       /* Turn the page upside down */
+#define CUPS_ORIENT_270                3       /* Rotate the page clockwise */
+
+/* CutMedia values */
+#define CUPS_CUT_NONE          0       /* Never cut the roll */
+#define CUPS_CUT_FILE          1       /* Cut the roll after this file */
+#define CUPS_CUT_JOB           2       /* Cut the roll after this job */
+#define CUPS_CUT_SET           3       /* Cut the roll after this set */
+#define CUPS_CUT_PAGE          4       /* Cut the roll after this page */
+
+/* AdvanceMedia values */
+#define CUPS_ADVANCE_NONE      0       /* Never advance the roll */
+#define CUPS_ADVANCE_FILE      1       /* Advance the roll after this file */
+#define CUPS_ADVANCE_JOB       2       /* Advance the roll after this job */
+#define CUPS_ADVANCE_SET       3       /* Advance the roll after this set */
+#define CUPS_ADVANCE_PAGE      4       /* Advance the roll after this page */
+
+/* LeadingEdge values */
+#define CUPS_EDGE_TOP          0       /* Leading edge is the top of the page */
+#define CUPS_EDGE_RIGHT                1       /* Leading edge is the right of the page */
+#define CUPS_EDGE_BOTTOM       2       /* Leading edge is the bottom of the page */
+#define CUPS_EDGE_LEFT         3       /* Leading edge is the left of the page */
+
+/* cupsColorOrder values */
+#define CUPS_ORDER_CHUNKED     0       /* CMYK CMYK CMYK ... */
+#define CUPS_ORDER_BANDED      1       /* CCC MMM YYY KKK ... */
+#define CUPS_ORDER_PLANAR      2       /* CCC ... MMM ... YYY ... KKK ... */
+
+/* cupsColorSpace values */
+#define CUPS_CSPACE_W          0       /* Luminance */
+#define CUPS_CSPACE_RGB                1       /* Red, green, blue */
+#define CUPS_CSPACE_RGBA       2       /* Red, green, blue, alpha */
+#define CUPS_CSPACE_K          3       /* Black */
+#define CUPS_CSPACE_CMY                4       /* Cyan, magenta, yellow */
+#define CUPS_CSPACE_YMC                5       /* Yellow, magenta, cyan */
+#define CUPS_CSPACE_CMYK       6       /* Cyan, magenta, yellow, black */
+#define CUPS_CSPACE_YMCK       7       /* Yellow, magenta, cyan, black */
+#define CUPS_CSPACE_KCMY       8       /* Black, cyan, magenta, yellow */
+#define CUPS_CSPACE_KCMYcm     9       /* Black, cyan, magenta, yellow, *
+                                        * light-cyan, light-magenta     */
+#define CUPS_CSPACE_GMCK       10      /* Gold, magenta, yellow, black */
+#define CUPS_CSPACE_GMCS       11      /* Gold, magenta, yellow, silver */
+#define CUPS_CSPACE_WHITE      12      /* White ink (as black) */
+#define CUPS_CSPACE_GOLD       13      /* Gold foil */
+#define CUPS_CSPACE_SILVER     14      /* Silver foil */
+
+#define CUPS_CSPACE_CIEXYZ     15      /* CIE XYZ */
+#define CUPS_CSPACE_CIELab     16      /* CIE Lab */
+
+#define CUPS_CSPACE_ICC1       32      /* ICC-based, 1 color */
+#define CUPS_CSPACE_ICC2       33      /* ICC-based, 2 colors */
+#define CUPS_CSPACE_ICC3       34      /* ICC-based, 3 colors */
+#define CUPS_CSPACE_ICC4       35      /* ICC-based, 4 colors */
+#define CUPS_CSPACE_ICC5       36      /* ICC-based, 5 colors */
+#define CUPS_CSPACE_ICC6       37      /* ICC-based, 6 colors */
+#define CUPS_CSPACE_ICC7       38      /* ICC-based, 7 colors */
+#define CUPS_CSPACE_ICC8       39      /* ICC-based, 8 colors */
+#define CUPS_CSPACE_ICC9       40      /* ICC-based, 9 colors */
+#define CUPS_CSPACE_ICCA       41      /* ICC-based, 10 colors */
+#define CUPS_CSPACE_ICCB       42      /* ICC-based, 11 colors */
+#define CUPS_CSPACE_ICCC       43      /* ICC-based, 12 colors */
+#define CUPS_CSPACE_ICCD       44      /* ICC-based, 13 colors */
+#define CUPS_CSPACE_ICCE       45      /* ICC-based, 14 colors */
+#define CUPS_CSPACE_ICCF       46      /* ICC-based, 15 colors */
+
+
+/*
+ * End of "$Id: raster.defs 343 2007-07-13 19:52:48Z mike $".
+ */
index 12e7e7dbee1711a6fd5c5df2df9b08c3092916ea..83693894d5f5020d7bbee75260f4a2b3f9d34204 100644 (file)
@@ -237,3 +237,7 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
index 935c428214fd516e8c1fe8b9c350c23648942f5d..8c522609e3eab440896e35247225be8fc8d89c01 100644 (file)
@@ -317,11 +317,6 @@ P.summary {
   font-family: monaco, courier, monospace;
 }
 
-SPAN.message {
-  font-style: italic;
-  font-size: smaller;
-}
-
 DIV.summary TABLE {
   border: solid thin #999999;
   border-collapse: collapse;
index 175f6fecdb5d3c130e9c200e7d85f94a03b4761e..e902ed3fcd3ac7b272a53f27574f08d5a0feccb9 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index e2ff9ad283ad5d0dc278566f09f1a1e2a19ca6f4..36f731675a2c80d7d001e2e49db41530afd75580 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index 8c35624ce613d1d245aa25322fa83eed26bb9296..df491db653e8773ac7467e381c3e7b39df31446e 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index 62ae4ac3a963f8a0381d1bf0a8aa37f40ed023c3..2b3975259b9455b7b3f9a3507ac20c18b9bfdcc5 100644 (file)
@@ -245,12 +245,16 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
 <div class='body'>
 <!--
-  "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+  "$Id: api-filter.header 7285 2008-02-01 23:57:39Z mike $"
 
   Filter and backend programming header for the Common UNIX Printing System
   (CUPS).
@@ -269,9 +273,10 @@ div.contents ul.contents {
 <div class='summary'><table summary='General Information'>
 <thead>
 <tr>
-       <th>Header</th>
+       <th>Headers</th>
        <th>cups/backend.h<br>
-       cups/sidechannel.h</th>
+       cups/sidechannel.h<br>
+       cups/snmp.h</th>
 </tr>
 </thead>
 <tbody>
@@ -292,26 +297,53 @@ div.contents ul.contents {
 <ul class="contents">
 </li>
 <li><a href="#OVERVIEW">Overview</a><ul class="subcontents">
+<li><a href="#SECURITY">Security Considerations</a></li>
+<li><a href="#TEMPFILES">Temporary Files</a></li>
+<li><a href="#COPIES">Copy Generation</a></li>
 <li><a href="#EXITCODES">Exit Codes</a></li>
 <li><a href="#ENVIRONMENT">Environment Variables</a></li>
 <li><a href="#MESSAGES">Communicating with the Scheduler</a></li>
 <li><a href="#COMMUNICATING">Communicating with the Backend</a></li>
+<li><a href="#SNMP">Doing SNMP Queries with Network Printers</a></li>
 </ul></li>
 <li><a href="#FUNCTIONS">Functions</a><ul class="code">
 <li><a href="#cupsBackChannelRead" title="Read data from the backchannel.">cupsBackChannelRead</a></li>
 <li><a href="#cupsBackChannelWrite" title="Write data to the backchannel.">cupsBackChannelWrite</a></li>
+<li><a href="#cupsBackendDeviceURI" title="Get the device URI for a backend.">cupsBackendDeviceURI</a></li>
+<li><a href="#cupsSNMPClose" title="Close a SNMP socket.">cupsSNMPClose</a></li>
+<li><a href="#cupsSNMPCopyOID" title="Copy an OID.">cupsSNMPCopyOID</a></li>
+<li><a href="#cupsSNMPDefaultCommunity" title="Get the default SNMP community name.">cupsSNMPDefaultCommunity</a></li>
+<li><a href="#cupsSNMPIsOID" title="Test whether a SNMP response contains the specified OID.">cupsSNMPIsOID</a></li>
+<li><a href="#cupsSNMPIsOIDPrefixed" title="Test whether a SNMP response uses the specified
+OID prefix.">cupsSNMPIsOIDPrefixed</a></li>
+<li><a href="#cupsSNMPOpen" title="Open a SNMP socket.">cupsSNMPOpen</a></li>
+<li><a href="#cupsSNMPRead" title="Read and parse a SNMP response.">cupsSNMPRead</a></li>
+<li><a href="#cupsSNMPSetDebug" title="Enable/disable debug logging to stderr.">cupsSNMPSetDebug</a></li>
+<li><a href="#cupsSNMPWalk" title="Enumerate a group of OIDs.">cupsSNMPWalk</a></li>
+<li><a href="#cupsSNMPWrite" title="Send an SNMP query packet.">cupsSNMPWrite</a></li>
 <li><a href="#cupsSideChannelDoRequest" title="Send a side-channel command to a backend and wait for a response.">cupsSideChannelDoRequest</a></li>
 <li><a href="#cupsSideChannelRead" title="Read a side-channel message.">cupsSideChannelRead</a></li>
 <li><a href="#cupsSideChannelWrite" title="Write a side-channel message.">cupsSideChannelWrite</a></li>
 </ul>
 <li><a href="#TYPES">Data Types</a><ul class="code">
+       <li><a href="#cups_asn1_t" title="ASN1 request/object types">cups_asn1_t</a></li>
        <li><a href="#cups_backend_t" title="Backend exit codes">cups_backend_t</a></li>
        <li><a href="#cups_sc_bidi_t" title="Bidirectional capabilities">cups_sc_bidi_t</a></li>
        <li><a href="#cups_sc_command_t" title="Request command codes">cups_sc_command_t</a></li>
        <li><a href="#cups_sc_state_t" title="Printer state bits">cups_sc_state_t</a></li>
        <li><a href="#cups_sc_status_t" title="Response status codes">cups_sc_status_t</a></li>
+       <li><a href="#cups_snmp_cb_t" title="Prototypes...">cups_snmp_cb_t</a></li>
+       <li><a href="#cups_snmp_t" title="SNMP data packet">cups_snmp_t</a></li>
+</ul></li>
+<li><a href="#STRUCTURES">Structures</a><ul class="code">
+       <li><a href="#cups_snmp_hexstring_s" title="Hex-STRING value">cups_snmp_hexstring_s</a></li>
+       <li><a href="#cups_snmp_s" title="SNMP data packet">cups_snmp_s</a></li>
+</ul></li>
+<li><a href="#UNIONS">Unions</a><ul class="code">
+       <li><a href="#cups_snmp_value_u" title="Object value">cups_snmp_value_u</a></li>
 </ul></li>
 <li><a href="#ENUMERATIONS">Constants</a><ul class="code">
+       <li><a href="#cups_asn1_e" title="ASN1 request/object types">cups_asn1_e</a></li>
        <li><a href="#cups_backend_e" title="Backend exit codes">cups_backend_e</a></li>
        <li><a href="#cups_sc_bidi_e" title="Bidirectional capabilities">cups_sc_bidi_e</a></li>
        <li><a href="#cups_sc_command_e" title="Request command codes">cups_sc_command_e</a></li>
@@ -320,7 +352,7 @@ div.contents ul.contents {
 </ul></li>
 </ul>
 <!--
-  "$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
+  "$Id: api-filter.shtml 7288 2008-02-06 01:39:05Z mike $"
 
   Filter and backend programming introduction for the Common UNIX Printing
   System (CUPS).
@@ -368,6 +400,52 @@ the remaining filters read from the standard input and write to the standard
 output. The backend is the last filter in the chain and writes to the
 device.</p>
 
+<h3><a name="SECURITY">Security Considerations</a></h3>
+
+<p>It is always important to use security programming practices. Filters and
+most backends are run as a non-priviledged user, so the major security
+consideration is resource utilization - filters should not depend on unlimited
+amounts of CPU, memory, or disk space, and should protect against conditions
+that could lead to excess usage of any resource like infinite loops and
+unbounded recursion. In addition, filters must <em>never</em> allow the user to
+specify an arbitrary file path to a separator page, template, or other file
+used by the filter since that can lead to an unauthorized disclosure of
+information. <em>Always</em> treat input as suspect and validate it!</p>
+
+<p>If you are developing a backend that runs as root, make sure to check for
+potential buffer overflows, integer under/overflow conditions, and file
+accesses since these can lead to privilege escalations. When writing files,
+always validate the file path and <em>never</em> allow a user to determine
+where to store a file.</p>
+
+<blockquote><b>Note:</b>
+
+<p><em>Never</em> write files to a user's home directory. Aside from the
+security implications, CUPS is a network print service and as such the network
+user may not be the same as the local user and/or there may not be a local home
+directory to write to.</p>
+
+<p>In addition, some operating systems provide additional security mechanisms
+that further limit file system access, even for backends running as root.  On
+Mac OS X, for example, no backend may write to a user's home directory.</p>
+</blockquote>
+
+<h3><a name="TEMPFILES">Temporary Files</a></h3>
+
+<p>Temporary files should be created in the directory specified by the
+"TMPDIR" environment variable. The
+<a href="#cupsTempFile2"><code>cupsTempFile2</code></a> function can be
+used to safely create temporary files in this directory.</p>
+
+<h3><a name="COPIES">Copy Generation</a></h3>
+
+<p>The <code>argv[4]</code> argument specifies the number of copies to produce
+of the input file. In general, you should only generate copies if the
+<em>filename</em> argument is supplied. The only exception to this are
+filters that produce device-independent PostScript output, since the PostScript
+filter <var>pstops</var> is responsible for generating copies of PostScript
+files.</p>
+
 <h3><a name="EXITCODES">Exit Codes</a></h3>
 
 <p>Filters must exit with status 0 when they successfully generate print data
@@ -615,6 +693,81 @@ if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;s
   <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
 }
 </pre>
+
+<h3><a name="SNMP">Doing SNMP Queries with Network Printers</a></h3>
+
+<p>The Simple Network Management Protocol (SNMP) allows you to get the current
+status, page counter, and supply levels from most network printers. Every
+piece of information is associated with an Object Identifier (OID), and
+every printer has a <em>community</em> name associated with it. OIDs can be
+queried directly or by "walking" over a range of OIDs with a common prefix.</p>
+
+<p>The CUPS SNMP functions provide a simple API for querying network printers.
+Queries are made using a datagram socket that is created using
+<a href="#cupsSNMPOpen"><code>cupsSNMPOpen</code></a> and destroyed using
+<a href="#cupsSNMPClose"><code>cupsSNMPClose</code></a>:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(AF_INET);
+
+/* do some queries */
+
+<a href="#cupsSNMPClose">cupsSNMPClose</a>(snmp);
+</pre>
+
+<p>OIDs are simple C arrays of integers, terminated by a value of -1. For
+example, the page counter OID .1.3.6.1.2.1.43.10.2.1.4.1.1 would be:</p>
+
+<pre class="example">
+int page_counter_oid[] = { 1, 3, 6, 1, 2, 1, 43, 10, 2, 1, 4, 1, 1, -1 };
+</pre>
+
+<p>You send a query using
+<a href="#cupsSNMPWrite"><code>cupsSNMPWrite</code></a> and read the value back
+using <a href="#cupsSNMPRead"><code>cupsSNMPRead</code></a>. The value is read
+into a structure called <a href="#cups_snmp_t"><code>cups_snmp_t</code></a>:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+int page_counter_oid[] = { 1, 3, 6, 1, 2, 1, 43, 10, 2, 1, 4, 1, 1, -1 };
+http_addrlist_t *host = httpAddrGetList("myprinter", AF_UNSPEC, "161");
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(host->addr.addr.sa_family);
+<a href="#cups_snmp_t">cups_snmp_t</a> packet;
+
+<a href="#cupsSNMPWrite">cupsSNMPWrite</a>(snmp, &amp;(host->addr), CUPS_SNMP_VERSION_1,
+                <a href="#cupsSNMPDefaultCommunity">cupsSNMPDefaultCommunity</a>(), CUPS_ASN1_GET_REQUEST, 1,
+                page_counter_oid);
+if (<a href="#cupsSNMPRead">cupsSNMPRead</a>(snmp, &amp;packet, 5000))
+{
+  /* Do something with the value */
+  printf("Page counter is: %d\n", packet.object_value.integer);
+}
+</pre>
+
+<p>The <a href="#cupsSNMPWalk"><code>cupsSNMPWalk</code></a> function allows you
+to query a whole group of OIDs, calling a function of your choice for each OID
+that is found:</p>
+
+<pre class="example">
+#include &lt;cups/snmp.h&gt;
+
+void
+my_callback(<a href="#cups_snmp_t">cups_snmp_t</a> *packet, void *data)
+{
+  /* Do something with the value */
+}
+
+int printer_mib_oid[] = { 1, 3, 6, 1, 2, 1, 43, -1 };
+http_addrlist_t *host = httpAddrGetList("myprinter", AF_UNSPEC, "161");
+int snmp = <a href="#cupsSNMPOpen">cupsSNMPOpen</a>(host->addr.addr.sa_family);
+void *my_data;
+
+<a href="#cupsSNMPWalk">cupsSNMPWalk</a>(snmp, &amp;(host->addr), CUPS_SNMP_VERSION_1,
+               <a href="#cupsSNMPDefaultCommunity">cupsSNMPDefaultCommunity</a>(), printer_mib_oid, my_callback, my_data);
+</pre>
 <h2 class="title"><a name="FUNCTIONS">Functions</a></h2>
 <h3 class="function"><span class="info">&nbsp;CUPS 1.2&nbsp;</span><a name="cupsBackChannelRead">cupsBackChannelRead</a></h3>
 <p class="description">Read data from the backchannel.</p>
@@ -667,6 +820,234 @@ controls how many seconds to wait for the data to be written - use
 0.0 to return immediately if the data cannot be written, -1.0 to wait
 indefinitely.
 
+</p>
+<h3 class="function"><a name="cupsBackendDeviceURI">cupsBackendDeviceURI</a></h3>
+<p class="description">Get the device URI for a backend.</p>
+<p class="code">
+const char *cupsBackendDeviceURI (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char **argv<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>argv</dt>
+<dd class="description">Command-line arguments</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Device URI or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The &quot;argv&quot; argument is the argv argument passed to main(). This
+function returns the device URI passed in the DEVICE_URI environment
+variable or the device URI passed in argv[0], whichever is found
+first.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPClose">cupsSNMPClose</a></h3>
+<p class="description">Close a SNMP socket.</p>
+<p class="code">
+void cupsSNMPClose (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">SNMP socket file descriptor</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPCopyOID">cupsSNMPCopyOID</a></h3>
+<p class="description">Copy an OID.</p>
+<p class="code">
+int *cupsSNMPCopyOID (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *dst,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *src,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int dstsize<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dst</dt>
+<dd class="description">Destination OID</dd>
+<dt>src</dt>
+<dd class="description">Source OID</dd>
+<dt>dstsize</dt>
+<dd class="description">Number of integers in dst</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">New OID</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The array pointed to by &quot;src&quot; is terminated by the value -1.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPDefaultCommunity">cupsSNMPDefaultCommunity</a></h3>
+<p class="description">Get the default SNMP community name.</p>
+<p class="code">
+const char *cupsSNMPDefaultCommunity (void);</p>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Default community name</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The default community name is the first community name found in the
+snmp.conf file. If no community name is defined there, &quot;public&quot; is used.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPIsOID">cupsSNMPIsOID</a></h3>
+<p class="description">Test whether a SNMP response contains the specified OID.</p>
+<p class="code">
+int cupsSNMPIsOID (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_snmp_t">cups_snmp_t</a> *packet,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *oid<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>packet</dt>
+<dd class="description">Response packet</dd>
+<dt>oid</dt>
+<dd class="description">OID</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if equal, 0 if not equal</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The array pointed to by &quot;oid&quot; is terminated by the value -1.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPIsOIDPrefixed">cupsSNMPIsOIDPrefixed</a></h3>
+<p class="description">Test whether a SNMP response uses the specified
+OID prefix.</p>
+<p class="code">
+int cupsSNMPIsOIDPrefixed (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_snmp_t">cups_snmp_t</a> *packet,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *prefix<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>packet</dt>
+<dd class="description">Response packet</dd>
+<dt>prefix</dt>
+<dd class="description">OID prefix</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 if prefixed, 0 if not prefixed</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The array pointed to by &quot;prefix&quot; is terminated by the value -1.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPOpen">cupsSNMPOpen</a></h3>
+<p class="description">Open a SNMP socket.</p>
+<p class="code">
+int cupsSNMPOpen (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int family<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>family</dt>
+<dd class="description">Address family - <code>AF_INET</code> or <code>AF_INET6</code></dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">SNMP socket file descriptor</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPRead">cupsSNMPRead</a></h3>
+<p class="description">Read and parse a SNMP response.</p>
+<p class="code">
+<a href="#cups_snmp_t">cups_snmp_t</a> *cupsSNMPRead (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_snmp_t">cups_snmp_t</a> *packet,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">SNMP socket file descriptor</dd>
+<dt>packet</dt>
+<dd class="description">SNMP packet buffer</dd>
+<dt>msec</dt>
+<dd class="description">Timeout in milliseconds</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">SNMP packet or <code>NULL</code> if none</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">If &quot;timeout&quot; is negative, <code>cupsSNMPRead</code> will wait for a response
+indefinitely.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPSetDebug">cupsSNMPSetDebug</a></h3>
+<p class="description">Enable/disable debug logging to stderr.</p>
+<p class="code">
+void cupsSNMPSetDebug (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int level<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>level</dt>
+<dd class="description">1 to enable debug output, 0 otherwise</dd>
+</dl>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPWalk">cupsSNMPWalk</a></h3>
+<p class="description">Enumerate a group of OIDs.</p>
+<p class="code">
+int cupsSNMPWalk (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_addr_t *address,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int version,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *community,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *prefix,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_snmp_cb_t">cups_snmp_cb_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *data<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">SNMP socket</dd>
+<dt>address</dt>
+<dd class="description">Address to query</dd>
+<dt>version</dt>
+<dd class="description">SNMP version</dd>
+<dt>community</dt>
+<dd class="description">Community name</dd>
+<dt>prefix</dt>
+<dd class="description">OID prefix</dd>
+<dt>msec</dt>
+<dd class="description">Timeout for each response in milliseconds</dd>
+<dt>cb</dt>
+<dd class="description">Function to call for each response</dd>
+<dt>data</dt>
+<dd class="description">User data pointer that is passed to the callback function</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Number of OIDs found or -1 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">This function queries all of the OIDs with the specified OID prefix,
+calling the &quot;cb&quot; function for every response that is received.<br>
+<br>
+The array pointed to by &quot;prefix&quot; is terminated by the value -1.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.4&nbsp;</span><a name="cupsSNMPWrite">cupsSNMPWrite</a></h3>
+<p class="description">Send an SNMP query packet.</p>
+<p class="code">
+int cupsSNMPWrite (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int fd,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_addr_t *address,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int version,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *community,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_asn1_t">cups_asn1_t</a> request_type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const unsigned request_id,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const int *oid<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>fd</dt>
+<dd class="description">SNMP socket</dd>
+<dt>address</dt>
+<dd class="description">Address to send to</dd>
+<dt>version</dt>
+<dd class="description">SNMP version</dd>
+<dt>community</dt>
+<dd class="description">Community name</dd>
+<dt>request_type</dt>
+<dd class="description">Request type</dd>
+<dt>request_id</dt>
+<dd class="description">Request ID</dd>
+<dt>oid</dt>
+<dd class="description">OID</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on error</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The array pointed to by &quot;oid&quot; is terminated by the value -1.
+
 </p>
 <h3 class="function"><span class="info">&nbsp;CUPS 1.3&nbsp;</span><a name="cupsSideChannelDoRequest">cupsSideChannelDoRequest</a></h3>
 <p class="description">Send a side-channel command to a backend and wait for a response.</p>
@@ -769,6 +1150,11 @@ responses to a filter, driver, or port monitor program.
 
 </p>
 <h2 class="title"><a name="TYPES">Data Types</a></h2>
+<h3 class="typedef"><a name="cups_asn1_t">cups_asn1_t</a></h3>
+<p class="description">ASN1 request/object types</p>
+<p class="code">
+typedef enum <a href="#cups_asn1_e">cups_asn1_e</a> cups_asn1_t;
+</p>
 <h3 class="typedef"><a name="cups_backend_t">cups_backend_t</a></h3>
 <p class="description">Backend exit codes</p>
 <p class="code">
@@ -794,7 +1180,138 @@ typedef enum <a href="#cups_sc_state_e">cups_sc_state_e</a> cups_sc_state_t;
 <p class="code">
 typedef enum <a href="#cups_sc_status_e">cups_sc_status_e</a> cups_sc_status_t;
 </p>
+<h3 class="typedef"><a name="cups_snmp_cb_t">cups_snmp_cb_t</a></h3>
+<p class="description">Prototypes...</p>
+<p class="code">
+typedef void (*cups_snmp_cb_t)(<a href="#cups_snmp_t">cups_snmp_t</a> *packet, void *data);
+</p>
+<h3 class="typedef"><a name="cups_snmp_t">cups_snmp_t</a></h3>
+<p class="description">SNMP data packet</p>
+<p class="code">
+typedef struct <a href="#cups_snmp_s">cups_snmp_s</a> cups_snmp_t;
+</p>
+<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
+<h3 class="struct"><a name="cups_snmp_hexstring_s">cups_snmp_hexstring_s</a></h3>
+<p class="description">Hex-STRING value</p>
+<p class="code">struct cups_snmp_hexstring_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned char bytes[CUPS_SNMP_MAX_STRING];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_bytes;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>bytes[CUPS_SNMP_MAX_STRING] </dt>
+<dd class="description">Bytes in string</dd>
+<dt>num_bytes </dt>
+<dd class="description">Number of bytes</dd>
+</dl>
+<h3 class="struct"><a name="cups_snmp_s">cups_snmp_s</a></h3>
+<p class="description">SNMP data packet</p>
+<p class="code">struct cups_snmp_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;http_addr_t address;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char community[CUPS_SNMP_MAX_STRING];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const char *error;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int error_index;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int error_status;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int object_name[CUPS_SNMP_MAX_OID];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_asn1_t">cups_asn1_t</a> object_type;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;union <a href="#cups_snmp_value_u">cups_snmp_value_u</a> object_value;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int request_id;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_asn1_t">cups_asn1_t</a> request_type;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int version;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>address </dt>
+<dd class="description">Source address</dd>
+<dt>community[CUPS_SNMP_MAX_STRING] </dt>
+<dd class="description">Community name</dd>
+<dt>error </dt>
+<dd class="description">Encode/decode error</dd>
+<dt>error_index </dt>
+<dd class="description">error-index value</dd>
+<dt>error_status </dt>
+<dd class="description">error-status value</dd>
+<dt>object_name[CUPS_SNMP_MAX_OID] </dt>
+<dd class="description">object-name value</dd>
+<dt>object_type </dt>
+<dd class="description">object-value type</dd>
+<dt>object_value </dt>
+<dd class="description">object-value value</dd>
+<dt>request_id </dt>
+<dd class="description">request-id value</dd>
+<dt>request_type </dt>
+<dd class="description">Request type</dd>
+<dt>version </dt>
+<dd class="description">Version number</dd>
+</dl>
+<h2 class="title"><a name="UNIONS">Unions</a></h2>
+<h3 class="union"><a name="cups_snmp_value_u">cups_snmp_value_u</a></h3>
+<p class="description">Object value</p>
+<p class="code">union cups_snmp_value_u {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int boolean;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned counter;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned gauge;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;struct <a href="#cups_snmp_hexstring_s">cups_snmp_hexstring_s</a> hex_string;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int integer;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int oid[CUPS_SNMP_MAX_OID];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char string[CUPS_SNMP_MAX_STRING];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned timeticks;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>boolean </dt>
+<dd class="description">Boolean value</dd>
+<dt>counter </dt>
+<dd class="description">Counter value</dd>
+<dt>gauge </dt>
+<dd class="description">Gauge value</dd>
+<dt>hex_string </dt>
+<dd class="description">Hex string value</dd>
+<dt>integer </dt>
+<dd class="description">Integer value</dd>
+<dt>oid[CUPS_SNMP_MAX_OID] </dt>
+<dd class="description">OID value</dd>
+<dt>string[CUPS_SNMP_MAX_STRING] </dt>
+<dd class="description">String value</dd>
+<dt>timeticks </dt>
+<dd class="description">Timeticks  value</dd>
+</dl>
 <h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
+<h3 class="enumeration"><a name="cups_asn1_e">cups_asn1_e</a></h3>
+<p class="description">ASN1 request/object types</p>
+<h4 class="constants">Constants</h4>
+<dl>
+<dt>CUPS_ASN1_BIT_STRING </dt>
+<dd class="description">BIT STRING</dd>
+<dt>CUPS_ASN1_BOOLEAN </dt>
+<dd class="description">BOOLEAN</dd>
+<dt>CUPS_ASN1_COUNTER </dt>
+<dd class="description">32-bit unsigned aka Counter32</dd>
+<dt>CUPS_ASN1_END_OF_CONTENTS </dt>
+<dd class="description">End-of-contents</dd>
+<dt>CUPS_ASN1_GAUGE </dt>
+<dd class="description">32-bit unsigned aka Gauge32</dd>
+<dt>CUPS_ASN1_GET_NEXT_REQUEST </dt>
+<dd class="description">GetNextRequest-PDU</dd>
+<dt>CUPS_ASN1_GET_REQUEST </dt>
+<dd class="description">GetRequest-PDU</dd>
+<dt>CUPS_ASN1_GET_RESPONSE </dt>
+<dd class="description">GetResponse-PDU</dd>
+<dt>CUPS_ASN1_HEX_STRING </dt>
+<dd class="description">Binary string aka Hex-STRING</dd>
+<dt>CUPS_ASN1_INTEGER </dt>
+<dd class="description">INTEGER or ENUMERATION</dd>
+<dt>CUPS_ASN1_NULL_VALUE </dt>
+<dd class="description">NULL VALUE</dd>
+<dt>CUPS_ASN1_OCTET_STRING </dt>
+<dd class="description">OCTET STRING</dd>
+<dt>CUPS_ASN1_OID </dt>
+<dd class="description">OBJECT IDENTIFIER</dd>
+<dt>CUPS_ASN1_SEQUENCE </dt>
+<dd class="description">SEQUENCE</dd>
+<dt>CUPS_ASN1_TIMETICKS </dt>
+<dd class="description">32-bit unsigned aka Timeticks32</dd>
+</dl>
 <h3 class="enumeration"><a name="cups_backend_e">cups_backend_e</a></h3>
 <p class="description">Backend exit codes</p>
 <h4 class="constants">Constants</h4>
index e8c09e286e8a22cd6105e496029e986f43c0d5a7..6939384cecc6924869a0199d4e0734337b350fc5 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index 151f3c90b4d6540ef739c32c437c6cb3964b829f..246db7993871223dac6c9d80ea0edffc4476c19e 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index d8aa110a73c579ccc23eb7f5871b257e789b8eb6..d332ca6f5088c0a4f923d62f4d05804f32902155 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
index f9010c93365976c43afb20d3f9439f37ff914db3..f2d4c3a7cb520dffcf8157beeb10267c869d5a64 100644 (file)
@@ -245,6 +245,10 @@ div.contents h2 {
 div.contents ul.contents {
   font-size: 80%;
 }
+div.contents ul.subcontents li {
+  margin-left: 1em;
+  text-indent: -1em;
+}
 --></style>
 </head>
 <body>
diff --git a/driver/Dependencies b/driver/Dependencies
new file mode 100644 (file)
index 0000000..70eb28e
--- /dev/null
@@ -0,0 +1,57 @@
+# DO NOT DELETE
+
+commandtoescpx.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h
+commandtoescpx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+commandtoescpx.o: ../cups/file.h ../cups/language.h driver.h ../cups/raster.h
+commandtoescpx.o: ../cups/string.h ../config.h ../data/escp.h
+commandtopclx.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h
+commandtopclx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+commandtopclx.o: ../cups/file.h ../cups/language.h driver.h ../cups/raster.h
+commandtopclx.o: ../cups/string.h ../config.h ../data/pcl.h
+rastertoescpx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertoescpx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertoescpx.o: ../cups/file.h ../cups/language.h ../cups/raster.h
+rastertoescpx.o: ../cups/string.h ../config.h ../data/escp.h
+rastertopclx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertopclx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertopclx.o: ../cups/file.h ../cups/language.h ../cups/raster.h
+rastertopclx.o: pcl-common.h ../data/pcl.h
+pcl-common.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+pcl-common.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+pcl-common.o: ../cups/file.h ../cups/language.h ../cups/raster.h pcl-common.h
+pcl-common.o: ../data/pcl.h
+testcmyk.o: ../cups/string.h ../config.h driver.h ../cups/cups.h
+testcmyk.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testcmyk.o: ../cups/array.h ../cups/file.h ../cups/language.h
+testcmyk.o: ../cups/raster.h
+testdither.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+testdither.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+testdither.o: ../cups/file.h ../cups/language.h ../cups/raster.h
+testdither.o: ../cups/string.h ../config.h
+testrgb.o: ../cups/string.h ../config.h driver.h ../cups/cups.h ../cups/ipp.h
+testrgb.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+testrgb.o: ../cups/file.h ../cups/language.h ../cups/raster.h
+attr.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+attr.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+attr.o: ../cups/language.h ../cups/raster.h ../cups/string.h ../config.h
+check.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+check.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+check.o: ../cups/language.h ../cups/raster.h
+cmyk.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+cmyk.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+cmyk.o: ../cups/language.h ../cups/raster.h ../cups/string.h ../config.h
+dither.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+dither.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+dither.o: ../cups/language.h ../cups/raster.h
+lut.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+lut.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+lut.o: ../cups/language.h ../cups/raster.h
+pack.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+pack.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+pack.o: ../cups/language.h ../cups/raster.h
+rgb.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rgb.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+rgb.o: ../cups/language.h ../cups/raster.h
+srgb.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+srgb.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+srgb.o: ../cups/language.h ../cups/raster.h
diff --git a/driver/Makefile b/driver/Makefile
new file mode 100644 (file)
index 0000000..11796fe
--- /dev/null
@@ -0,0 +1,237 @@
+#
+# "$Id$"
+#
+#   Makefile for the CUPS base drivers.
+#
+#   Copyright 2007-2008 by Apple Inc.
+#   Copyright 2002-2005 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/".
+#
+
+#
+# Include standard definitions...
+#
+
+include ../Makedefs
+
+
+#
+# Object files...
+#
+
+LIBOBJS        = \
+               attr.o \
+               check.o \
+               cmyk.o \
+               dither.o \
+               lut.o \
+               pack.o \
+               rgb.o \
+               srgb.o
+
+OBJS           = \
+               commandtoescpx.o \
+               commandtopclx.o \
+               rastertoescpx.o \
+               rastertopclx.o \
+               pcl-common.o \
+               testcmyk.o \
+               testdither.o \
+               testrgb.o \
+               $(LIBOBJS)
+
+TARGETS                = \
+               libcupsdriver.a \
+               commandtoescpx \
+               commandtopclx \
+               rastertoescpx \
+               rastertopclx \
+               testcmyk \
+               testdither \
+               testrgb
+
+
+#
+# Make everything...
+#
+
+all:           $(TARGETS)
+
+
+#
+# Clean everything...
+#
+
+clean:
+       $(RM) $(OBJS) core
+       $(RM) *.bck core.*
+       $(RM) $(TARGETS)
+       $(RM) -r images
+
+
+#
+# Update dependencies...
+#
+
+depend:
+       makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install...
+#
+
+install:
+       $(INSTALL_DIR) $(SERVERBIN)/filter
+       for file in commandtoescpx commandtopclx rastertoescpx rastertopclx; do \
+               $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \
+       done
+       $(INSTALL_DIR) $(INCLUDEDIR)/cups
+       $(INSTALL_DATA) driver.h $(INCLUDEDIR)/cups
+
+
+#
+# Uninstall...
+#
+
+uninstall:
+       for file in commandtoescpx commandtopclx rastertoescpx rastertopclx; do \
+               $(RM) $(SERVERBIN)/filter/$$file; \
+       done
+       $(RM) $(INCLUDEDIR)/cups/driver.h
+
+
+#
+# Automatic API help files...
+#
+
+apihelp:
+       mxmldoc --section "Programming" \
+               --title "Printer Driver API" \
+               --css ../doc/cups-printable.css \
+               --header api-driver.header --intro api-driver.shtml \
+               driver.h $(LIBOBJS:.o=.c) >../doc/help/api-driver.html
+
+framedhelp:
+       mxmldoc --framed api-driver \
+               --section "Programming" \
+               --title "Printer Driver API" \
+               --css ../doc/cups-printable.css \
+               --header api-driver.header --intro api-driver.shtml \
+               driver.h $(LIBOBJS:.o=.c)
+
+
+#
+# commandtopclx, the PCL command printer driver.
+#
+
+commandtopclx:         commandtopclx.o libcupsdriver.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ commandtopclx.o libcupsdriver.a $(LIBS)
+
+
+#
+# commandtoescpx, the ESC/P command printer driver.
+#
+
+commandtoescpx:                commandtoescpx.o libcupsdriver.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ commandtoescpx.o libcupsdriver.a $(LIBS)
+
+
+#
+# rastertoescpx, the ESC/P raster printer driver.
+#
+
+rastertoescpx:         rastertoescpx.o libcupsdriver.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ rastertoescpx.o libcupsdriver.a \
+               $(LINKCUPSIMAGE) $(LIBS)
+
+
+#
+# rastertopclx, the ESC/P raster printer driver.
+#
+
+rastertopclx:          rastertopclx.o pcl-common.o libcupsdriver.a \
+                       ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ rastertopclx.o pcl-common.o libcupsdriver.a \
+               $(LINKCUPSIMAGE) $(LIBS)
+
+
+#
+# testcmyk, test cmyk separation functions.
+#
+
+testcmyk:              testcmyk.o libcupsdriver.a ../cups/libcups.a
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ testcmyk.o libcupsdriver.a ../cups/libcups.a \
+               $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+       if test ! -d test; then \
+               mkdir test; \
+       fi
+       ./testcmyk > test/testcmyk.log 2>&1
+
+
+#
+# testdither, test dithering functions.
+#
+
+testdither:            testdither.o libcupsdriver.a ../cups/libcups.a
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ testdither.o libcupsdriver.a ../cups/libcups.a \
+               $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+       if test ! -d test; then \
+               mkdir test; \
+       fi
+       ./testdither > test/0-255.pgm 2>test/0-255.log
+       ./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log
+       ./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log
+       ./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log
+       ./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log
+       ./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log
+       ./testdither 0 510 > test/0-510.pgm 2>test/0-510.log
+       ./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log
+
+
+#
+# testrgb, test RGB separation functions.
+#
+
+testrgb:               testrgb.o libcupsdriver.a ../cups/libcups.a
+       echo Linking $@...
+       $(CC) $(LDFLAGS) -o $@ testrgb.o libcupsdriver.a ../cups/libcups.a \
+               $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+       if test ! -d test; then \
+               mkdir test; \
+       fi
+       ./testrgb > test/testrgb.log 2>&1
+
+
+#
+# libcupsdriver.a, the CUPS driver library...
+#
+
+libcupsdriver.a:       $(LIBOBJS)
+       echo Archiving $@...
+       $(RM) $@
+       $(AR) $(ARFLAGS) $@ $(LIBOBJS)
+       $(RANLIB) $@
+
+
+#
+# Include dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/driver/attr.c b/driver/attr.c
new file mode 100644 (file)
index 0000000..320e1c7
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * "$Id$"
+ *
+ *   PPD attribute lookup routine for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsFindAttr() - Find a PPD attribute based on the colormodel,
+ *                    media, and resolution.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <cups/string.h>
+
+
+/*
+ * 'cupsFindAttr()' - Find a PPD attribute based on the colormodel,
+ *                    media, and resolution.
+ */
+
+ppd_attr_t *                           /* O - Matching attribute or NULL */
+cupsFindAttr(ppd_file_t *ppd,          /* I - PPD file */
+             const char *name,         /* I - Attribute name */
+             const char *colormodel,   /* I - Color model */
+             const char *media,                /* I - Media type */
+             const char *resolution,   /* I - Resolution */
+            char       *spec,          /* O - Final selection string */
+            int        specsize)       /* I - Size of string buffer */
+{
+  ppd_attr_t   *attr;                  /* Attribute */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!ppd || !name || !colormodel || !media || !resolution || !spec ||
+      specsize < PPD_MAX_NAME)
+    return (NULL);
+
+ /*
+  * Look for the attribute with the following keywords:
+  *
+  *     ColorModel.MediaType.Resolution
+  *     ColorModel.Resolution
+  *     ColorModel
+  *     MediaType.Resolution
+  *     MediaType
+  *     Resolution
+  *     ""
+  */
+
+  snprintf(spec, specsize, "%s.%s.%s", colormodel, media, resolution);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  snprintf(spec, specsize, "%s.%s", colormodel, resolution);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  strlcpy(spec, colormodel, specsize);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  snprintf(spec, specsize, "%s.%s", media, resolution);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  strlcpy(spec, media, specsize);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  strlcpy(spec, resolution, specsize);
+  fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  spec[0] = '\0';
+  fprintf(stderr, "DEBUG2: Looking for \"*%s\"...\n", name);
+  if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL)
+    return (attr);
+
+  fprintf(stderr, "DEBUG2: No instance of \"*%s\" found...\n", name);
+
+  return (NULL);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/check.c b/driver/check.c
new file mode 100644 (file)
index 0000000..d7ceb3d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * "$Id$"
+ *
+ *   Byte checking routines for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsCheckBytes() - Check to see if all bytes are zero.
+ *   cupsCheckValue() - Check to see if all bytes match the given value.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsCheckBytes()' - Check to see if all bytes are zero.
+ */
+
+int                                            /* O - 1 if they match */
+cupsCheckBytes(const unsigned char *bytes,     /* I - Bytes to check */
+               int                 length)     /* I - Number of bytes to check */
+{
+  while (length > 7)
+  {
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+    if (*bytes++)
+      return (0);
+
+    length -= 8;
+  }
+
+  while (length > 0)
+    if (*bytes++)
+      return (0);
+    else
+      length --;
+
+  return (1);
+}
+
+
+/*
+ * 'cupsCheckValue()' - Check to see if all bytes match the given value.
+ */
+
+int                                            /* O - 1 if they match */
+cupsCheckValue(const unsigned char *bytes,     /* I - Bytes to check */
+               int                 length,     /* I - Number of bytes to check */
+              const unsigned char value)       /* I - Value to check */
+{
+  while (length > 7)
+  {
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+    if (*bytes++ != value)
+      return (0);
+
+    length -= 8;
+  }
+
+  while (length > 0)
+    if (*bytes++ != value)
+      return (0);
+    else
+      length --;
+
+  return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/cmyk.c b/driver/cmyk.c
new file mode 100644 (file)
index 0000000..01b8771
--- /dev/null
@@ -0,0 +1,1971 @@
+/*
+ * "$Id$"
+ *
+ *   CMYK color separation code for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsCMYKDelete()      - Delete a color separation.
+ *   cupsCMYKDoBlack()     - Do a black separation...
+ *   cupsCMYKDoCMYK()      - Do a CMYK separation...
+ *   cupsCMYKDoGray()      - Do a grayscale separation...
+ *   cupsCMYKDoRGB()       - Do an sRGB separation...
+ *   cupsCMYKLoad()        - Load a CMYK color profile from PPD attributes.
+ *   cupsCMYKNew()         - Create a new CMYK color separation.
+ *   cupsCMYKSetBlack()    - Set the transition range for CMY to black.
+ *   cupsCMYKSetCurve()    - Set a color transform curve using points.
+ *   cupsCMYKSetGamma()    - Set a color transform curve using gamma and
+ *                           density.
+ *   cupsCMYKSetInkLimit() - Set the limit on the amount of ink.
+ *   cupsCMYKSetLtDk()     - Set light/dark ink transforms.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <cups/string.h>
+
+
+/*
+ * 'cupsCMYKDelete()' - Delete a color separation.
+ */
+
+void
+cupsCMYKDelete(cups_cmyk_t *cmyk)      /* I - Color separation */
+{
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL)
+    return;
+
+ /*
+  * Free memory used...
+  */
+
+  free(cmyk->channels[0]);
+  free(cmyk);
+}
+
+
+/*
+ * 'cupsCMYKDoBlack()' - Do a black separation...
+ */
+
+void
+cupsCMYKDoBlack(const cups_cmyk_t   *cmyk,
+                                       /* I - Color separation */
+               const unsigned char *input,
+                                       /* I - Input grayscale pixels */
+               short               *output,
+                                       /* O - Output Device-N pixels */
+               int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  k;              /* Current black value */
+  const short          **channels;     /* Copy of channel LUTs */
+  const unsigned char  *black_lut,     /* Black LUT */
+                       *color_lut;     /* Color LUT */
+  int                  ink,            /* Amount of ink */
+                       ink_limit;      /* Ink limit from separation */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+    return;
+
+ /*
+  * Loop through it all...
+  */
+
+  channels  = (const short **)cmyk->channels;
+  black_lut = cmyk->black_lut;
+  color_lut = cmyk->color_lut;
+  ink_limit = cmyk->ink_limit;
+
+  switch (cmyk->num_channels)
+  {
+    case 1 : /* Black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         *output++ = channels[0][k];
+
+          num_pixels --;
+        }
+       break;
+
+    case 2 : /* Black, light black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         output[0] = channels[0][k];
+         output[1] = channels[1][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+           }
+         }
+
+          output += 2;
+          num_pixels --;
+        }
+       break;
+
+    case 3 : /* CMY */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         output[0] = channels[0][k];
+         output[1] = channels[1][k];
+         output[2] = channels[2][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+           }
+         }
+
+          output += 3;
+          num_pixels --;
+        }
+       break;
+
+    case 4 : /* CMYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = channels[3][k];
+
+          num_pixels --;
+        }
+       break;
+
+    case 6 : /* CcMmYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = 0;
+         *output++ = channels[5][k];
+
+          num_pixels --;
+        }
+       break;
+
+    case 7 : /* CcMmYKk */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = *input++;
+         output[0] = 0;
+         output[1] = 0;
+         output[2] = 0;
+         output[3] = 0;
+         output[4] = 0;
+         output[5] = channels[5][k];
+         output[6] = channels[6][k];
+
+          if (ink_limit)
+         {
+           ink = output[5] + output[6];
+
+           if (ink > ink_limit)
+           {
+             output[5] = ink_limit * output[5] / ink;
+             output[6] = ink_limit * output[6] / ink;
+           }
+         }
+
+          output += 7;
+          num_pixels --;
+        }
+       break;
+  }
+}
+
+
+/*
+ * 'cupsCMYKDoCMYK()' - Do a CMYK separation...
+ */
+
+void
+cupsCMYKDoCMYK(const cups_cmyk_t   *cmyk,
+                                       /* I - Color separation */
+              const unsigned char *input,
+                                       /* I - Input grayscale pixels */
+              short               *output,
+                                       /* O - Output Device-N pixels */
+              int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  c,              /* Current cyan value */
+                       m,              /* Current magenta value */
+                       y,              /* Current yellow value */
+                       k;              /* Current black value */
+  const short          **channels;     /* Copy of channel LUTs */
+  const unsigned char  *black_lut,     /* Black LUT */
+                       *color_lut;     /* Color LUT */
+  int                  ink,            /* Amount of ink */
+                       ink_limit;      /* Ink limit from separation */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+    return;
+
+ /*
+  * Loop through it all...
+  */
+
+  channels  = (const short **)cmyk->channels;
+  black_lut = cmyk->black_lut;
+  color_lut = cmyk->color_lut;
+  ink_limit = cmyk->ink_limit;
+
+  switch (cmyk->num_channels)
+  {
+    case 1 : /* Black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = *input++;
+         m = *input++;
+         y = *input++;
+         k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
+
+         if (k < 255)
+           *output++ = channels[0][k];
+         else
+           *output++ = channels[0][255];
+
+          num_pixels --;
+        }
+       break;
+
+    case 2 : /* Black, light black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = *input++;
+         m = *input++;
+         y = *input++;
+         k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
+
+         if (k < 255)
+         {
+           output[0] = channels[0][k];
+           output[1] = channels[1][k];
+         }
+         else
+         {
+           output[0] = channels[0][255];
+           output[1] = channels[1][255];
+         }
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+           }
+         }
+
+          output += 2;
+          num_pixels --;
+        }
+       break;
+
+    case 3 : /* CMY */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = *input++;
+         m = *input++;
+         y = *input++;
+         k = *input++;
+         c += k;
+         m += k;
+         y += k;
+
+         if (c < 255)
+           output[0] = channels[0][c];
+         else
+           output[0] = channels[0][255];
+
+         if (m < 255)
+           output[1] = channels[1][m];
+         else
+           output[1] = channels[1][255];
+
+         if (y < 255)
+           output[2] = channels[2][y];
+         else
+           output[2] = channels[2][255];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+           }
+         }
+
+          output += 3;
+          num_pixels --;
+        }
+       break;
+
+    case 4 : /* CMYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c         = *input++;
+         m         = *input++;
+         y         = *input++;
+         k         = *input++;
+
+         output[0] = channels[0][c];
+         output[1] = channels[1][m];
+         output[2] = channels[2][y];
+         output[3] = channels[3][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+           }
+         }
+
+          output += 4;
+          num_pixels --;
+        }
+       break;
+
+    case 6 : /* CcMmYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c         = *input++;
+         m         = *input++;
+         y         = *input++;
+         k         = *input++;
+
+         output[0] = channels[0][c];
+         output[1] = channels[1][c];
+         output[2] = channels[2][m];
+         output[3] = channels[3][m];
+         output[4] = channels[4][y];
+         output[5] = channels[5][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+           }
+         }
+
+          output += 6;
+          num_pixels --;
+        }
+       break;
+
+    case 7 : /* CcMmYKk */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c         = *input++;
+         m         = *input++;
+         y         = *input++;
+         k         = *input++;
+
+         output[0] = channels[0][c];
+         output[1] = channels[1][c];
+         output[2] = channels[2][m];
+         output[3] = channels[3][m];
+         output[4] = channels[4][y];
+         output[5] = channels[5][k];
+         output[6] = channels[6][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5] + output[6];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+             output[6] = ink_limit * output[6] / ink;
+           }
+         }
+
+          output += 7;
+          num_pixels --;
+        }
+       break;
+  }
+}
+
+
+/*
+ * 'cupsCMYKDoGray()' - Do a grayscale separation...
+ */
+
+void
+cupsCMYKDoGray(const cups_cmyk_t   *cmyk,
+                                       /* I - Color separation */
+              const unsigned char *input,
+                                       /* I - Input grayscale pixels */
+              short               *output,
+                                       /* O - Output Device-N pixels */
+              int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  k,              /* Current black value */
+                       kc;             /* Current black color value */
+  const short          **channels;     /* Copy of channel LUTs */
+  const unsigned char  *black_lut,     /* Black LUT */
+                       *color_lut;     /* Color LUT */
+  int                  ink,            /* Amount of ink */
+                       ink_limit;      /* Ink limit from separation */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+    return;
+
+ /*
+  * Loop through it all...
+  */
+
+  channels  = (const short **)cmyk->channels;
+  black_lut = cmyk->black_lut;
+  color_lut = cmyk->color_lut;
+  ink_limit = cmyk->ink_limit;
+
+  switch (cmyk->num_channels)
+  {
+    case 1 : /* Black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         *output++ = channels[0][k];
+
+          num_pixels --;
+        }
+       break;
+
+    case 2 : /* Black, light black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         output[0] = channels[0][k];
+         output[1] = channels[1][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+           }
+         }
+
+          output += 2;
+          num_pixels --;
+        }
+       break;
+
+    case 3 : /* CMY */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         output[0] = channels[0][k];
+         output[1] = channels[1][k];
+         output[2] = channels[2][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+           }
+         }
+
+          output += 3;
+          num_pixels --;
+        }
+       break;
+
+    case 4 : /* CMYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         kc        = cmyk->color_lut[k];
+         k         = cmyk->black_lut[k];
+         output[0] = channels[0][kc];
+         output[1] = channels[1][kc];
+         output[2] = channels[2][kc];
+         output[3] = channels[3][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+           }
+         }
+
+          output += 4;
+          num_pixels --;
+        }
+       break;
+
+    case 6 : /* CcMmYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         kc        = cmyk->color_lut[k];
+         k         = cmyk->black_lut[k];
+         output[0] = channels[0][kc];
+         output[1] = channels[1][kc];
+         output[2] = channels[2][kc];
+         output[3] = channels[3][kc];
+         output[4] = channels[4][kc];
+         output[5] = channels[5][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+           }
+         }
+
+          output += 6;
+          num_pixels --;
+        }
+       break;
+
+    case 7 : /* CcMmYKk */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         k         = cups_scmy_lut[*input++];
+         kc        = cmyk->color_lut[k];
+         k         = cmyk->black_lut[k];
+         output[0] = channels[0][kc];
+         output[1] = channels[1][kc];
+         output[2] = channels[2][kc];
+         output[3] = channels[3][kc];
+         output[4] = channels[4][kc];
+         output[5] = channels[5][k];
+         output[6] = channels[6][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5] + output[6];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+             output[6] = ink_limit * output[6] / ink;
+           }
+         }
+
+          output += 7;
+          num_pixels --;
+        }
+       break;
+  }
+}
+
+
+/*
+ * 'cupsCMYKDoRGB()' - Do an sRGB separation...
+ */
+
+void
+cupsCMYKDoRGB(const cups_cmyk_t   *cmyk,
+                                       /* I - Color separation */
+             const unsigned char *input,
+                                       /* I - Input grayscale pixels */
+             short               *output,
+                                       /* O - Output Device-N pixels */
+             int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  c,              /* Current cyan value */
+                       m,              /* Current magenta value */
+                       y,              /* Current yellow value */
+                       k,              /* Current black value */
+                       kc,             /* Current black color value */
+                       km;             /* Maximum black value */
+  const short          **channels;     /* Copy of channel LUTs */
+  const unsigned char  *black_lut,     /* Black LUT */
+                       *color_lut;     /* Color LUT */
+  int                  ink,            /* Amount of ink */
+                       ink_limit;      /* Ink limit from separation */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
+    return;
+
+ /*
+  * Loop through it all...
+  */
+
+  channels  = (const short **)cmyk->channels;
+  black_lut = cmyk->black_lut;
+  color_lut = cmyk->color_lut;
+  ink_limit = cmyk->ink_limit;
+
+  switch (cmyk->num_channels)
+  {
+    case 1 : /* Black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = cups_scmy_lut[*input++];
+         m = cups_scmy_lut[*input++];
+         y = cups_scmy_lut[*input++];
+         k = (c * 31 + m * 61 + y * 8) / 100;
+
+          *output++ = channels[0][k];
+
+          num_pixels --;
+        }
+       break;
+
+    case 2 : /* Black, light black */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = cups_scmy_lut[*input++];
+         m = cups_scmy_lut[*input++];
+         y = cups_scmy_lut[*input++];
+         k = (c * 31 + m * 61 + y * 8) / 100;
+
+          output[0] = channels[0][k];
+          output[1] = channels[1][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+           }
+         }
+
+          output += 2;
+          num_pixels --;
+        }
+       break;
+
+    case 3 : /* CMY */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c = cups_scmy_lut[*input++];
+         m = cups_scmy_lut[*input++];
+         y = cups_scmy_lut[*input++];
+
+         output[0] = channels[0][c];
+          output[1] = channels[1][m];
+         output[2] = channels[2][y];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+           }
+         }
+
+          output += 3;
+          num_pixels --;
+        }
+       break;
+
+    case 4 : /* CMYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c  = cups_scmy_lut[*input++];
+         m  = cups_scmy_lut[*input++];
+         y  = cups_scmy_lut[*input++];
+         k  = min(c, min(m, y));
+
+         if ((km = max(c, max(m, y))) > k)
+            k = k * k * k / (km * km);
+
+         kc = cmyk->color_lut[k] - k;
+         k  = cmyk->black_lut[k];
+         c  += kc;
+         m  += kc;
+         y  += kc;
+
+         output[0] = channels[0][c];
+          output[1] = channels[1][m];
+         output[2] = channels[2][y];
+         output[3] = channels[3][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+           }
+         }
+
+          output += 4;
+          num_pixels --;
+        }
+       break;
+
+    case 6 : /* CcMmYK */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c  = cups_scmy_lut[*input++];
+         m  = cups_scmy_lut[*input++];
+         y  = cups_scmy_lut[*input++];
+         k  = min(c, min(m, y));
+
+         if ((km = max(c, max(m, y))) > k)
+            k = k * k * k / (km * km);
+
+         kc = cmyk->color_lut[k] - k;
+         k  = cmyk->black_lut[k];
+         c  += kc;
+         m  += kc;
+         y  += kc;
+
+         output[0] = channels[0][c];
+         output[1] = channels[1][c];
+         output[2] = channels[2][m];
+         output[3] = channels[3][m];
+         output[4] = channels[4][y];
+         output[5] = channels[5][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+           }
+         }
+
+          output += 6;
+          num_pixels --;
+        }
+       break;
+
+    case 7 : /* CcMmYKk */
+        while (num_pixels > 0)
+        {
+        /*
+         * Get the input black value and then set the corresponding color
+         * channel values...
+         */
+
+         c  = cups_scmy_lut[*input++];
+         m  = cups_scmy_lut[*input++];
+         y  = cups_scmy_lut[*input++];
+         k  = min(c, min(m, y));
+
+         if ((km = max(c, max(m, y))) > k)
+            k = k * k * k / (km * km);
+
+         kc = cmyk->color_lut[k] - k;
+         k  = cmyk->black_lut[k];
+         c  += kc;
+         m  += kc;
+         y  += kc;
+
+         output[0] = channels[0][c];
+         output[1] = channels[1][c];
+         output[2] = channels[2][m];
+         output[3] = channels[3][m];
+         output[4] = channels[4][y];
+         output[5] = channels[5][k];
+         output[6] = channels[6][k];
+
+          if (ink_limit)
+         {
+           ink = output[0] + output[1] + output[2] + output[3] +
+                 output[4] + output[5] + output[6];
+
+           if (ink > ink_limit)
+           {
+             output[0] = ink_limit * output[0] / ink;
+             output[1] = ink_limit * output[1] / ink;
+             output[2] = ink_limit * output[2] / ink;
+             output[3] = ink_limit * output[3] / ink;
+             output[4] = ink_limit * output[4] / ink;
+             output[5] = ink_limit * output[5] / ink;
+             output[6] = ink_limit * output[6] / ink;
+           }
+         }
+
+          output += 7;
+          num_pixels --;
+        }
+       break;
+  }
+}
+
+
+/*
+ * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes.
+ */
+
+cups_cmyk_t *                          /* O - CMYK color separation */
+cupsCMYKLoad(ppd_file_t *ppd,          /* I - PPD file */
+            const char *colormodel,    /* I - ColorModel value */
+            const char *media,         /* I - MediaType value */
+            const char *resolution)    /* I - Resolution value */
+{
+  cups_cmyk_t  *cmyk;                  /* CMYK color separation */
+  char         spec[PPD_MAX_NAME];     /* Profile name */
+  ppd_attr_t   *attr;                  /* Attribute from PPD file */
+  int          num_channels;           /* Number of color components */
+  float                gamval,                 /* Gamma correction value */
+               density,                /* Density value */
+               light,                  /* Light ink limit */
+               dark,                   /* Light ink cut-off */
+               lower,                  /* Start of black ink */
+               upper;                  /* End of color ink */
+  int          num_xypoints;           /* Number of X,Y points */
+  float                xypoints[100 * 2],      /* X,Y points */
+               *xyptr;                 /* Current X,Y point */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (ppd == NULL || colormodel == NULL || resolution == NULL || media == NULL)
+    return (NULL);
+
+ /*
+  * Find the following attributes:
+  *
+  *     cupsAllGamma          - Set default curve using gamma + density
+  *     cupsAllXY             - Set default curve using XY points
+  *     cupsBlackGamma        - Set black curve using gamma + density
+  *     cupsBlackGeneration   - Set black generation
+  *     cupsBlackLightDark    - Set black light/dark transition
+  *     cupsBlackXY           - Set black curve using XY points
+  *     cupsCyanGamma         - Set cyan curve using gamma + density
+  *     cupsCyanLightDark     - Set cyan light/dark transition
+  *     cupsCyanXY            - Set cyan curve using XY points
+  *     cupsInkChannels       - Set number of color channels
+  *     cupsInkLimit          - Set total ink limit
+  *     cupsLightBlackGamma   - Set light black curve using gamma + density
+  *     cupsLightBlackXY      - Set light black curve using XY points
+  *     cupsLightCyanGamma    - Set light cyan curve using gamma + density
+  *     cupsLightCyanXY       - Set light cyan curve using XY points
+  *     cupsLightMagentaGamma - Set light magenta curve using gamma + density
+  *     cupsLightMagentaXY    - Set light magenta curve using XY points
+  *     cupsMagentaGamma      - Set magenta curve using gamma + density
+  *     cupsMagentaLightDark  - Set magenta light/dark transition
+  *     cupsMagentaXY         - Set magenta curve using XY points
+  *     cupsYellowGamma       - Set yellow curve using gamma + density
+  *     cupsYellowXY          - Set yellow curve using XY points
+  *
+  * The only required attribute is cupsInkChannels.
+  *
+  * The *XY attributes have precedence over the *Gamma attributes, and
+  * the *Light* attributes have precedence over the corresponding
+  * *LightDark* attributes.
+  */
+
+ /*
+  * Get the required cupsInkChannels attribute...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsInkChannels", colormodel, media,
+                           resolution, spec, sizeof(spec))) == NULL)
+    return (NULL);
+
+  num_channels = atoi(attr->value);
+
+  if (num_channels < 1 || num_channels > 7 || num_channels == 5)
+    return (NULL);
+
+  if ((cmyk = cupsCMYKNew(num_channels)) == NULL)
+    return (NULL);
+
+ /*
+  * Get the optional cupsInkLimit attribute...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsInkLimit", colormodel, media,
+                           resolution, spec, sizeof(spec))) != NULL)
+    cupsCMYKSetInkLimit(cmyk, atof(attr->value));
+
+ /*
+  * Get the optional cupsBlackGeneration attribute...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsBlackGeneration", colormodel, media,
+                           resolution, spec, sizeof(spec))) != NULL)
+  {
+    if (sscanf(attr->value, "%f%f", &lower, &upper) == 2)
+      cupsCMYKSetBlack(cmyk, lower, upper);
+  }
+
+ /*
+  * Get the optional cupsBlackXY or cupsBlackGamma attributes...
+  */
+
+  if (num_channels != 3)
+  {
+    if ((attr = cupsFindAttr(ppd, "cupsBlackXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsBlackXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 1 :
+       case 2 :
+            cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+           break;
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsBlackGamma", colormodel,
+                                  media, resolution, spec,
+                                 sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 1 :
+         case 2 :
+              cupsCMYKSetGamma(cmyk, 0, gamval, density);
+             break;
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 3, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 5, gamval, density);
+             break;
+       }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 1 :
+       case 2 :
+            cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+           break;
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel,
+                                  media, resolution, spec,
+                                 sizeof(spec))) != NULL &&
+             num_channels != 3)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 1 :
+         case 2 :
+              cupsCMYKSetGamma(cmyk, 0, gamval, density);
+             break;
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 3, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 5, gamval, density);
+             break;
+       }
+    }
+  }
+
+  if (num_channels > 2)
+  {
+   /*
+    * Get the optional cupsCyanXY or cupsCyanGamma attributes...
+    */
+
+    if ((attr = cupsFindAttr(ppd, "cupsCyanXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsCyanXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsCyanGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       cupsCMYKSetGamma(cmyk, 0, gamval, density);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       cupsCMYKSetGamma(cmyk, 0, gamval, density);
+    }
+
+   /*
+    * Get the optional cupsMagentaXY or cupsMagentaGamma attributes...
+    */
+
+    if ((attr = cupsFindAttr(ppd, "cupsMagentaXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsMagentaXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 3 :
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsMagentaGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 3 :
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 1, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 2, gamval, density);
+             break;
+       }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 3 :
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 3 :
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 1, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 2, gamval, density);
+             break;
+       }
+    }
+
+   /*
+    * Get the optional cupsYellowXY or cupsYellowGamma attributes...
+    */
+
+    if ((attr = cupsFindAttr(ppd, "cupsYellowXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsYellowXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 3 :
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsYellowGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 3 :
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 2, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 4, gamval, density);
+             break;
+       }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 3 :
+       case 4 :
+            cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
+           break;
+       case 6 :
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 3 :
+         case 4 :
+              cupsCMYKSetGamma(cmyk, 2, gamval, density);
+             break;
+         case 6 :
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 4, gamval, density);
+             break;
+       }
+    }
+  }
+
+ /*
+  * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or
+  * cupsBlackLtDk attributes...
+  */
+
+  if (num_channels == 2 || num_channels == 7)
+  {
+    if ((attr = cupsFindAttr(ppd, "cupsLightBlackXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsLightBlackXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      switch (num_channels)
+      {
+       case 2 :
+            cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+           break;
+       case 7 :
+            cupsCMYKSetCurve(cmyk, 6, num_xypoints, xypoints);
+           break;
+      }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsLightBlackGamma", colormodel,
+                                  media, resolution, spec,
+                                 sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       switch (num_channels)
+       {
+         case 2 :
+              cupsCMYKSetGamma(cmyk, 1, gamval, density);
+             break;
+         case 7 :
+              cupsCMYKSetGamma(cmyk, 6, gamval, density);
+             break;
+       }
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsBlackLtDk", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+       switch (num_channels)
+       {
+         case 2 :
+              cupsCMYKSetLtDk(cmyk, 0, light, dark);
+             break;
+         case 7 :
+              cupsCMYKSetLtDk(cmyk, 5, light, dark);
+             break;
+       }
+      else
+       fprintf(stderr, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n",
+               attr->value);
+    }
+    else
+      fprintf(stderr, "WARNING: No light black attribute found for %s!\n",
+              spec);
+  }
+
+  if (num_channels >= 6)
+  {
+   /*
+    * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or
+    * cupsCyanLtDk attributes...
+    */
+
+    if ((attr = cupsFindAttr(ppd, "cupsLightCyanXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsLightCyanXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsLightCyanGamma", colormodel,
+                                  media, resolution, spec,
+                                 sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       cupsCMYKSetGamma(cmyk, 1, gamval, density);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsCyanLtDk", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+       cupsCMYKSetLtDk(cmyk, 0, light, dark);
+      else
+       fprintf(stderr, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n",
+               attr->value);
+    }
+    else
+      fprintf(stderr, "WARNING: No light cyan attribute found for %s!\n",
+              spec);
+
+   /*
+    * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or
+    * cupsMagentaLtDk attributes...
+    */
+
+    if ((attr = cupsFindAttr(ppd, "cupsLightMagentaXY", colormodel, media,
+                             resolution, spec, sizeof(spec))) != NULL)
+    {
+      for (num_xypoints = 0, xyptr = xypoints;
+           attr != NULL && attr->value != NULL && num_xypoints < 100;
+          attr = ppdFindNextAttr(ppd, "cupsLightMagentaXY", spec))
+       if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
+       {
+          num_xypoints ++;
+         xyptr += 2;
+       }
+
+      cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsLightMagentaGamma", colormodel,
+                                  media, resolution, spec,
+                                 sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
+       cupsCMYKSetGamma(cmyk, 3, gamval, density);
+    }
+    else if ((attr = cupsFindAttr(ppd, "cupsMagentaLtDk", colormodel, media,
+                                  resolution, spec, sizeof(spec))) != NULL)
+    {
+      if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
+       cupsCMYKSetLtDk(cmyk, 2, light, dark);
+      else
+       fprintf(stderr, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n",
+               attr->value);
+    }
+    else
+      fprintf(stderr, "WARNING: No light magenta attribute found for %s!\n",
+              spec);
+  }
+
+ /*
+  * Return the new profile...
+  */
+
+  return (cmyk);
+}
+
+
+/*
+ * 'cupsCMYKNew()' - Create a new CMYK color separation.
+ */
+
+cups_cmyk_t *                          /* O - New CMYK separation or NULL */
+cupsCMYKNew(int num_channels)          /* I - Number of color components */
+{
+  cups_cmyk_t  *cmyk;                  /* New color separation */
+  int          i;                      /* Looping var */
+
+
+ /*
+  * Range-check the input...
+  */
+
+  if (num_channels < 1)
+    return (NULL);
+
+ /*
+  * Allocate memory for the separation...
+  */
+
+  if ((cmyk = calloc(1, sizeof(cups_cmyk_t))) == NULL)
+    return (NULL);
+
+ /*
+  * Allocate memory for the LUTs...
+  */
+
+  cmyk->num_channels = num_channels;
+
+  if ((cmyk->channels[0] = calloc(num_channels * 256, sizeof(short))) == NULL)
+  {
+    free(cmyk);
+    return (NULL);
+  }
+
+  for (i = 1; i < num_channels; i ++)
+    cmyk->channels[i] = cmyk->channels[0] + i * 256;
+
+ /*
+  * Fill in the LUTs with unity transitions...
+  */
+
+  for (i = 0; i < 256; i ++)
+    cmyk->black_lut[i] = i;
+
+  switch (num_channels)
+  {
+    case 1 : /* K */
+    case 2 : /* Kk */
+       for (i = 0; i < 256; i ++)
+       {
+         cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+       }
+       break;
+    case 3 : /* CMY */
+       for (i = 0; i < 256; i ++)
+       {
+         cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+       }
+       break;
+    case 4 : /* CMYK */
+       for (i = 0; i < 256; i ++)
+       {
+         cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[3][i] = CUPS_MAX_LUT * i / 255;
+       }
+       break;
+    case 6 : /* CcMmYK */
+    case 7 : /* CcMmYKk */
+       for (i = 0; i < 256; i ++)
+       {
+         cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[4][i] = CUPS_MAX_LUT * i / 255;
+         cmyk->channels[5][i] = CUPS_MAX_LUT * i / 255;
+       }
+       break;
+  }
+
+ /*
+  * Return the separation...
+  */
+
+  return (cmyk);
+}
+
+
+/*
+ * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black.
+ */
+
+void
+cupsCMYKSetBlack(cups_cmyk_t *cmyk,    /* I - CMYK color separation */
+                float       lower,     /* I - No black ink */
+                float       upper)     /* I - Only black ink */
+{
+  int  i,                              /* Looping var */
+       delta,                          /* Difference between lower and upper */
+       ilower,                         /* Lower level from 0 to 255 */
+       iupper;                         /* Upper level from 0 to 255 */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || lower < 0.0 || lower > 1.0 || upper < 0.0 || upper > 1.0 ||
+      lower > upper)
+    return;
+
+ /*
+  * Convert lower and upper to integers from 0 to 255...
+  */
+
+  ilower  = (int)(255.0 * lower + 0.5);
+  iupper  = (int)(255.0 * upper + 0.5);
+  delta   = iupper - ilower;
+
+ /*
+  * Generate the CMY-only data...
+  */
+
+  for (i = 0; i < ilower; i ++)
+  {
+    cmyk->black_lut[i] = 0;
+    cmyk->color_lut[i] = i;
+  }
+
+ /*
+  * Then the transition data...
+  */
+
+  for (; i < iupper; i ++)
+  {
+    cmyk->black_lut[i] = iupper * (i - ilower) / delta;
+    cmyk->color_lut[i] = ilower - ilower * (i - ilower) / delta;
+  }
+
+ /*
+  * Then the K-only data...
+  */
+
+  for (; i < 256; i ++)
+  {
+    cmyk->black_lut[i] = i;
+    cmyk->color_lut[i] = 0;
+  }
+
+  fprintf(stderr, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower, upper);
+
+  for (i = 0; i < 256; i += 17)
+    fprintf(stderr, "DEBUG:    %3d = %3dk + %3dc\n", i,
+            cmyk->black_lut[i], cmyk->color_lut[i]);
+}
+
+
+/*
+ * 'cupsCMYKSetCurve()' - Set a color transform curve using points.
+ */
+
+void
+cupsCMYKSetCurve(cups_cmyk_t *cmyk,    /* I - CMYK color separation */
+                 int         channel,  /* I - Color channel */
+                int         num_xypoints,
+                                       /* I - Number of X,Y points */
+                const float *xypoints) /* I - X,Y points */
+{
+  int  i;                              /* Looping var */
+  int  xstart;                         /* Start position */
+  int  xend;                           /* End position */
+  int  xdelta;                         /* Difference in position */
+  int  ystart;                         /* Start value */
+  int  yend;                           /* End value */
+  int  ydelta;                         /* Difference in value */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
+      num_xypoints < 1 || xypoints == NULL)
+    return;
+
+ /*
+  * Initialize the lookup table for the specified channel...
+  */
+
+  for (xstart = xend = 0, ystart = yend = 0;
+       num_xypoints > 0;
+       num_xypoints --, xypoints += 2, xstart = xend, ystart = yend)
+  {
+    xend   = (int)(255.0 * xypoints[1] + 0.5);
+    yend   = (int)(CUPS_MAX_LUT * xypoints[0] + 0.5);
+    xdelta = xend - xstart;
+    ydelta = yend - ystart;
+
+    for (i = xstart; i < xend; i ++)
+      cmyk->channels[channel][i] = ystart + ydelta * (i - xstart) / xdelta;
+  }
+
+ /*
+  * Initialize any trailing values to the maximum of the last data point...
+  */
+
+  for (i = xend; i < 256; i ++)
+    cmyk->channels[channel][i] = yend;
+
+  fprintf(stderr, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, "
+                  "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel,
+          num_xypoints, xypoints[0], xypoints[1], xypoints[2], xypoints[3]);
+
+  for (i = 0; i < 256; i += 17)
+    fprintf(stderr, "DEBUG:     %3d = %4d\n", i,
+            cmyk->channels[channel + 0][i]);
+}
+
+
+/*
+ * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density.
+ */
+
+void
+cupsCMYKSetGamma(cups_cmyk_t *cmyk,    /* I - CMYK color separation */
+                 int         channel,  /* I - Ink channel */
+                 float       gamval,   /* I - Gamma correction */
+                float       density)   /* I - Maximum density */
+{
+  int  i;                              /* Looping var */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
+      gamval <= 0.0 || density <= 0.0 || density > 1.0)
+    return;
+
+ /*
+  * Initialize the lookup table for the specified channel...
+  */
+
+  for (i = 0; i < 256; i ++)
+    cmyk->channels[channel][i] = (int)(density * CUPS_MAX_LUT *
+                                       pow((float)i / 255.0, gamval) + 0.5);
+
+  fprintf(stderr, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, "
+                  "density=%.3f)\n", channel, gamval, density);
+
+  for (i = 0; i < 256; i += 17)
+    fprintf(stderr, "DEBUG:     %3d = %4d\n", i,
+            cmyk->channels[channel + 0][i]);
+}
+
+
+/*
+ * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink.
+ */
+
+void
+cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, /* I - CMYK color separation */
+                    float       limit) /* I - Limit of ink */
+{
+  if (!cmyk || limit < 0.0)
+    return;
+
+  cmyk->ink_limit = limit * CUPS_MAX_LUT;
+}
+
+
+/*
+ * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms.
+ */
+
+void
+cupsCMYKSetLtDk(cups_cmyk_t *cmyk,     /* I - CMYK color separation */
+                int         channel,   /* I - Dark ink channel (+1 for light) */
+               float       light,      /* I - Light ink only level */
+               float       dark)       /* I - Dark ink only level */
+{
+  int  i,                              /* Looping var */
+       delta,                          /* Difference between lower and upper */
+       ilight,                         /* Light level from 0 to 255 */
+       idark;                          /* Dark level from 0 to 255 */
+  short        lut[256];                       /* Original LUT data */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (cmyk == NULL || light < 0.0 || light > 1.0 || dark < 0.0 || dark > 1.0 ||
+      light > dark || channel < 0 || channel > (cmyk->num_channels - 2))
+    return;
+
+ /*
+  * Convert lower and upper to integers from 0 to 255...
+  */
+
+  ilight = (int)(255.0 * light + 0.5);
+  idark  = (int)(255.0 * dark + 0.5);
+  delta  = idark - ilight;
+
+ /*
+  * Copy the dark ink LUT...
+  */
+
+  memcpy(lut, cmyk->channels[channel], sizeof(lut));
+
+ /*
+  * Generate the light-only data...
+  */
+
+  for (i = 0; i < ilight; i ++)
+  {
+    cmyk->channels[channel + 0][i] = 0;
+    cmyk->channels[channel + 1][i] = CUPS_MAX_LUT * i / ilight;
+  }
+
+ /*
+  * Then the transition data...
+  */
+
+  for (; i < idark; i ++)
+  {
+    cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * idark * (i - ilight) /
+                                     delta / 255;
+    cmyk->channels[channel + 1][i] = CUPS_MAX_LUT - CUPS_MAX_LUT *
+                                     (i - ilight) / delta;
+  }
+
+ /*
+  * Then the K-only data...
+  */
+
+  for (; i < 256; i ++)
+  {
+    cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * i / 255;
+    cmyk->channels[channel + 1][i] = 0;
+  }
+
+  fprintf(stderr, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, "
+                  "dark=%.3f)\n", channel, light, dark);
+
+  for (i = 0; i < 256; i += 17)
+    fprintf(stderr, "DEBUG:     %3d = %4dlt + %4ddk\n", i,
+            cmyk->channels[channel + 0][i], cmyk->channels[channel + 1][i]);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/commandtoescpx.c b/driver/commandtoescpx.c
new file mode 100644 (file)
index 0000000..ce09ebc
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * "$Id$"
+ *
+ *   Advanced EPSON ESC/P command filter for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   main() - Main entry and command processing.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include "driver.h"
+#include <cups/string.h>
+#include "data/escp.h"
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int                                            /* O - Exit status */
+main(int  argc,                                        /* I - Number of command-line arguments */
+     char *argv[])                             /* I - Command-line arguments */
+{
+  FILE         *fp;                            /* Command file */
+  char         line[1024],                     /* Line from file */
+               *lineptr;                       /* Pointer into line */
+  int          feedpage;                       /* Feed the page */
+  ppd_file_t   *ppd;                           /* PPD file */
+
+
+ /*
+  * Check for valid arguments...
+  */
+
+  if (argc < 6 || argc > 7)
+  {
+   /*
+    * We don't have the correct number of arguments; write an error message
+    * and return.
+    */
+
+    fputs("ERROR: commandtoescpx job-id user title copies options [file]\n", stderr);
+    return (1);
+  }
+
+ /*
+  * Open the PPD file...
+  */
+
+  if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL)
+  {
+    fputs("ERROR: Unable to open PPD file!\n", stderr);
+    return (1);
+  }
+
+ /*
+  * Open the command file as needed...
+  */
+
+  if (argc == 7)
+  {
+    if ((fp = fopen(argv[6], "r")) == NULL)
+    {
+      perror("ERROR: Unable to open command file - ");
+      return (1);
+    }
+  }
+  else
+    fp = stdin;
+
+ /*
+  * Some EPSON printers need an additional command issued at the
+  * beginning of each job to exit from USB "packet" mode...
+  */
+
+  if (ppd->model_number & ESCP_USB)
+    cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL     \n\033@", 29);
+
+ /*
+  * Reset the printer...
+  */
+
+  cupsWritePrintData("\033@", 2);
+
+ /*
+  * Enter remote mode...
+  */
+
+  cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+  feedpage = 0;
+
+ /*
+  * Read the commands from the file and send the appropriate commands...
+  */
+
+  while (fgets(line, sizeof(line), fp) != NULL)
+  {
+   /*
+    * Drop trailing newline...
+    */
+
+    lineptr = line + strlen(line) - 1;
+    if (*lineptr == '\n')
+      *lineptr = '\0';
+
+   /*
+    * Skip leading whitespace...
+    */
+
+    for (lineptr = line; isspace(*lineptr); lineptr ++);
+
+   /*
+    * Skip comments and blank lines...
+    */
+
+    if (*lineptr == '#' || !*lineptr)
+      continue;
+
+   /*
+    * Parse the command...
+    */
+
+    if (strncasecmp(lineptr, "Clean", 5) == 0)
+    {
+     /*
+      * Clean heads...
+      */
+
+      cupsWritePrintData("CH\002\000\000\000", 6);
+    }
+    else if (strncasecmp(lineptr, "PrintAlignmentPage", 18) == 0)
+    {
+     /*
+      * Print alignment page...
+      */
+
+      int phase;
+
+      phase = atoi(lineptr + 18);
+
+      cupsWritePrintData("DT\003\000\000", 5);
+      putchar(phase & 255);
+      putchar(phase >> 8);
+      feedpage = 1;
+    }
+    else if (strncasecmp(lineptr, "PrintSelfTestPage", 17) == 0)
+    {
+     /*
+      * Print version info and nozzle check...
+      */
+
+      cupsWritePrintData("VI\002\000\000\000", 6);
+      cupsWritePrintData("NC\002\000\000\000", 6);
+      feedpage = 1;
+    }
+    else if (strncasecmp(lineptr, "ReportLevels", 12) == 0)
+    {
+     /*
+      * Report ink levels...
+      */
+
+      cupsWritePrintData("IQ\001\000\001", 5);
+    }
+    else if (strncasecmp(lineptr, "SetAlignment", 12) == 0)
+    {
+     /*
+      * Set head alignment...
+      */
+
+      int phase, x;
+
+      if (sscanf(lineptr + 12, "%d%d", &phase, &x) != 2)
+      {
+        fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+        continue;
+      }
+
+      cupsWritePrintData("DA\004\000", 4);
+      putchar(0);
+      putchar(phase);
+      putchar(0);
+      putchar(x);
+      cupsWritePrintData("SV\000\000", 4);
+    }
+    else
+      fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+  }
+
+ /*
+  * Exit remote mode...
+  */
+
+  cupsWritePrintData("\033\000\000\000", 4);
+
+ /*
+  * Eject the page as needed...
+  */
+
+  if (feedpage)
+  {
+    fputs("PAGE: 1 1\n", stderr);
+
+    putchar(13);
+    putchar(10);
+    putchar(12);
+  }
+
+ /*
+  * Reset the printer...
+  */
+
+  cupsWritePrintData("\033@", 2);
+
+ /*
+  * Close the command file and return...
+  */
+
+  ppdClose(ppd);
+
+  if (fp != stdin)
+    fclose(fp);
+
+  return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/commandtopclx.c b/driver/commandtopclx.c
new file mode 100644 (file)
index 0000000..1c5c10d
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * "$Id$"
+ *
+ *   Advanced PCL command filter for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   main() - Main entry and command processing.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include "driver.h"
+#include <cups/string.h>
+#include "data/pcl.h"
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int                                            /* O - Exit status */
+main(int  argc,                                        /* I - Number of command-line arguments */
+     char *argv[])                             /* I - Command-line arguments */
+{
+  FILE         *fp;                            /* Command file */
+  char         line[1024],                     /* Line from file */
+               *lineptr;                       /* Pointer into line */
+  int          feedpage;                       /* Feed the page */
+  ppd_file_t   *ppd;                           /* PPD file */
+
+
+ /*
+  * Check for valid arguments...
+  */
+
+  if (argc < 6 || argc > 7)
+  {
+   /*
+    * We don't have the correct number of arguments; write an error message
+    * and return.
+    */
+
+    fputs("ERROR: commandtopclx job-id user title copies options [file]\n", stderr);
+    return (1);
+  }
+
+ /*
+  * Open the PPD file...
+  */
+
+  if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL)
+  {
+    fputs("ERROR: Unable to open PPD file!\n", stderr);
+    return (1);
+  }
+
+ /*
+  * Open the command file as needed...
+  */
+
+  if (argc == 7)
+  {
+    if ((fp = fopen(argv[6], "r")) == NULL)
+    {
+      perror("ERROR: Unable to open command file - ");
+      return (1);
+    }
+  }
+  else
+    fp = stdin;
+
+ /*
+  * Reset the printer...
+  */
+
+  cupsWritePrintData("\033E", 2);
+
+ /*
+  * Read the commands from the file and send the appropriate commands...
+  */
+
+  feedpage = 0;
+
+  while (fgets(line, sizeof(line), fp) != NULL)
+  {
+   /*
+    * Drop trailing newline...
+    */
+
+    lineptr = line + strlen(line) - 1;
+    if (*lineptr == '\n')
+      *lineptr = '\0';
+
+   /*
+    * Skip leading whitespace...
+    */
+
+    for (lineptr = line; isspace(*lineptr); lineptr ++);
+
+   /*
+    * Skip comments and blank lines...
+    */
+
+    if (*lineptr == '#' || !*lineptr)
+      continue;
+
+   /*
+    * Parse the command...
+    */
+
+    if (strncasecmp(lineptr, "Clean", 5) == 0 &&
+        (ppd->model_number & PCL_INKJET))
+    {
+     /*
+      * Clean heads...
+      */
+
+      cupsWritePrintData("\033&b16WPML \004\000\006\001\004\001\005\001"
+                         "\001\004\001\144", 22);
+    }
+    else
+      fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr);
+  }
+
+ /*
+  * Eject the page as needed...
+  */
+
+  if (feedpage)
+  {
+    fputs("PAGE: 1 1\n", stderr);
+
+    putchar(12);
+  }
+
+ /*
+  * Reset the printer...
+  */
+
+  cupsWritePrintData("\033E", 2);
+
+ /*
+  * Close the command file and return...
+  */
+
+  ppdClose(ppd);
+
+  if (fp != stdin)
+    fclose(fp);
+
+  return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/dither.c b/driver/dither.c
new file mode 100644 (file)
index 0000000..2391734
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * "$Id$"
+ *
+ *   Dithering routines for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsDitherDelete() - Free a dithering buffer.
+ *   cupsDitherLine()   - Dither a line of pixels...
+ *   cupsDitherNew()    - Create a dithering buffer.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * Random number function to use, in order of preference...
+ */
+
+#ifdef HAVE_RANDOM
+#  define RANDOM_FUNCTION      random
+#elif defined(HAVE_MRAND48)
+#  define RANDOM_FUNCTION      mrand48
+#elif defined(HAVE_LRAND48)
+#  define RANDOM_FUNCTION      lrand48
+#else
+#  define RANDOM_FUNCTION      rand
+#endif /* HAVE_RANDOM */
+
+
+/*
+ * 'cupsDitherDelete()' - Free a dithering buffer.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+
+void
+cupsDitherDelete(cups_dither_t *d)     /* I - Dithering buffer */
+{
+  if (d != NULL)
+    free(d);
+}
+
+
+/*
+ * 'cupsDitherLine()' - Dither a line of pixels...
+ */
+
+void
+cupsDitherLine(cups_dither_t    *d,    /* I - Dither data */
+               const cups_lut_t *lut,  /* I - Lookup table */
+              const short      *data,  /* I - Separation data */
+              int              num_channels,
+                                       /* I - Number of components */
+              unsigned char    *p)     /* O - Pixels */
+{
+  register int x,                      /* Horizontal position in line... */
+               pixel,                  /* Current adjusted pixel... */
+               e,                      /* Current error */
+               e0,e1,e2;               /* Error values */
+  register int errval0,                /* First half of error value */
+               errval1,                /* Second half of error value */
+               errbase,                /* Base multiplier */
+               errbase0,               /* Base multiplier for large values */
+               errbase1,               /* Base multiplier for small values */
+               errrange;               /* Range of random multiplier */
+  register int *p0,                    /* Error buffer pointers... */
+               *p1;
+  static char  logtable[16384];        /* Error magnitude for randomness */
+  static char  loginit = 0;            /* Has the table been initialized? */
+
+
+  if (!loginit)
+  {
+   /*
+    * Initialize a logarithmic table for the magnitude of randomness
+    * that is introduced.
+    */
+
+    loginit = 1;
+
+    logtable[0] = 0;
+    for (x = 1; x < 2049; x ++)
+      logtable[x] = (int)(log(x / 16.0) / log(2.0) + 1.0);
+    for (; x < 16384; x ++)
+      logtable[x] = logtable[2049];
+  }
+
+  if (d->row == 0)
+  {
+   /*
+    * Dither from left to right:
+    *
+    *       e0   ==        p0[0]
+    *    e1 e2   == p1[-1] p1[0]
+    */
+
+    p0 = d->errors + 2;
+    p1 = d->errors + 2 + d->width + 4;
+    e0 = p0[0];
+    e1 = 0;
+    e2 = 0;
+
+   /*
+    * Error diffuse each output pixel...
+    */
+
+    for (x = d->width;
+        x > 0;
+        x --, p0 ++, p1 ++, p ++, data += num_channels)
+    {
+     /*
+      * Skip blank pixels...
+      */
+
+      if (*data == 0)
+      {
+        *p     = 0;
+       e0     = p0[1];
+       p1[-1] = e1;
+       e1     = e2;
+       e2     = 0;
+       continue;
+      }
+
+     /*
+      * Compute the net pixel brightness and brightness error.  Set a dot
+      * if necessary...
+      */
+
+      pixel = lut[*data].intensity + e0 / 128;
+
+      if (pixel > CUPS_MAX_LUT)
+       pixel = CUPS_MAX_LUT;
+      else if (pixel < 0)
+       pixel = 0;
+
+      *p = lut[pixel].pixel;
+      e  = lut[pixel].error;
+
+     /*
+      * Set the randomness factor...
+      */
+
+      if (e > 0)
+        errrange = logtable[e];
+      else
+        errrange = logtable[-e];
+
+      errbase  = 8 - errrange;
+      errrange = errrange * 2 + 1;
+
+     /*
+      * Randomize the error value.
+      */
+
+      if (errrange > 1)
+      {
+        errbase0 = errbase + (RANDOM_FUNCTION() % errrange);
+        errbase1 = errbase + (RANDOM_FUNCTION() % errrange);
+      }
+      else
+        errbase0 = errbase1 = errbase;
+
+     /*
+      *       X   7/16 =    X  e0
+      * 3/16 5/16 1/16 =    e1 e2
+      */
+
+      errval0 = errbase0 * e;
+      errval1 = (16 - errbase0) * e;
+      e0      = p0[1] + 7 * errval0;
+      e1      = e2 + 5 * errval1;
+
+      errval0 = errbase1 * e;
+      errval1 = (16 - errbase1) * e;
+      e2      = errval0;
+      p1[-1]  = e1 + 3 * errval1;
+    }
+  }
+  else
+  {
+   /*
+    * Dither from right to left:
+    *
+    *    e0      == p0[0]
+    *    e2 e1   == p1[0] p1[1]
+    */
+
+    p0   = d->errors + d->width + 1 + d->width + 4;
+    p1   = d->errors + d->width + 1;
+    p    += d->width - 1;
+    data += num_channels * (d->width - 1);
+    e0   = p0[0];
+    e1   = 0;
+    e2   = 0;
+
+   /*
+    * Error diffuse each output pixel...
+    */
+
+    for (x = d->width;
+        x > 0;
+        x --, p0 --, p1 --, p --, data -= num_channels)
+    {
+     /*
+      * Skip blank pixels...
+      */
+
+      if (*data == 0)
+      {
+        *p    = 0;
+       e0    = p0[-1];
+       p1[1] = e1;
+       e1    = e2;
+       e2    = 0;
+       continue;
+      }
+
+     /*
+      * Compute the net pixel brightness and brightness error.  Set a dot
+      * if necessary...
+      */
+
+      pixel = lut[*data].intensity + e0 / 128;
+
+      if (pixel > CUPS_MAX_LUT)
+       pixel = CUPS_MAX_LUT;
+      else if (pixel < 0)
+       pixel = 0;
+
+      *p = lut[pixel].pixel;
+      e  = lut[pixel].error;
+
+     /*
+      * Set the randomness factor...
+      */
+
+      if (e > 0)
+        errrange = logtable[e];
+      else
+        errrange = logtable[-e];
+
+      errbase  = 8 - errrange;
+      errrange = errrange * 2 + 1;
+
+     /*
+      * Randomize the error value.
+      */
+
+      if (errrange > 1)
+      {
+        errbase0 = errbase + (RANDOM_FUNCTION() % errrange);
+        errbase1 = errbase + (RANDOM_FUNCTION() % errrange);
+      }
+      else
+        errbase0 = errbase1 = errbase;
+
+     /*
+      *       X   7/16 =    X  e0
+      * 3/16 5/16 1/16 =    e1 e2
+      */
+
+      errval0 = errbase0 * e;
+      errval1 = (16 - errbase0) * e;
+      e0      = p0[-1] + 7 * errval0;
+      e1      = e2 + 5 * errval1;
+
+      errval0 = errbase1 * e;
+      errval1 = (16 - errbase1) * e;
+      e2      = errval0;
+      p1[1]   = e1 + 3 * errval1;
+    }
+  }
+
+ /*
+  * Update to the next row...
+  */
+
+  d->row = 1 - d->row;
+}
+
+
+/*
+ * 'cupsDitherNew()' - Create an error-diffusion dithering buffer.
+ */
+
+cups_dither_t *                        /* O - New state array */
+cupsDitherNew(int width)       /* I - Width of output in pixels */
+{
+  cups_dither_t        *d;             /* New dithering buffer */
+
+
+  if ((d = (cups_dither_t *)calloc(1, sizeof(cups_dither_t) +
+                                   2 * (width + 4) *
+                                      sizeof(int))) == NULL)
+    return (NULL);
+
+  d->width = width;
+
+  return (d);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/driver.h b/driver/driver.h
new file mode 100644 (file)
index 0000000..ed4eab9
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * "$Id$"
+ *
+ *   Printer driver utilities header file for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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/".
+ */
+
+#ifndef _CUPS_DRIVER_H_
+#  define _CUPS_DRIVER_H_
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+/*
+ * Include necessary headers...
+ */
+
+#  include <stdio.h>
+#  include <stdlib.h>
+#  include <time.h>
+#  include <math.h>
+
+#  if defined(WIN32) || defined(__EMX__)
+#    include <io.h>
+#  else
+#    include <unistd.h>
+#    include <fcntl.h>
+#  endif /* WIN32 || __EMX__ */
+
+#  include <cups/cups.h>
+#  include <cups/raster.h>
+
+
+/*
+ * Common macros...
+ */
+
+#  ifndef min
+#    define min(a,b)   ((a) < (b) ? (a) : (b))
+#    define max(a,b)   ((a) > (b) ? (a) : (b))
+#  endif /* !min */
+
+
+/*
+ * Constants...
+ */
+
+#define CUPS_MAX_CHAN  15              /* Maximum number of color components */
+#define CUPS_MAX_LUT   4095            /* Maximum LUT value */
+#define CUPS_MAX_RGB   4               /* Maximum number of sRGB components */
+
+
+/*
+ * Types/structures for the various routines.
+ */
+
+typedef struct cups_lut_s              /**** Lookup Table for Dithering ****/
+{
+  short                intensity;              /* Adjusted intensity */
+  short                pixel;                  /* Output pixel value */
+  int          error;                  /* Error from desired value */
+} cups_lut_t;
+
+typedef struct cups_dither_s           /**** Dithering State ****/
+{
+  int          width;                  /* Width of buffer */
+  int          row;                    /* Current row */
+  int          errors[96];             /* Error values */
+} cups_dither_t;
+
+typedef struct cups_sample_s           /**** Color sample point ****/
+{
+  unsigned char        rgb[3];                 /* sRGB values */
+  unsigned char        colors[CUPS_MAX_RGB];   /* Color values */
+} cups_sample_t;
+
+typedef struct cups_rgb_s              /**** Color separation lookup table ****/
+{
+  int          cube_size;              /* Size of color cube (2-N) on a side */
+  int          num_channels;           /* Number of colors per sample */
+  unsigned char        ****colors;             /* 4-D array of sample values */
+  int          cube_index[256];        /* Index into cube for a given sRGB value */
+  int          cube_mult[256];         /* Multiplier value for a given sRGB value */
+  int          cache_init;             /* Are cached values initialized? */
+  unsigned char        black[CUPS_MAX_RGB];    /* Cached black (sRGB = 0,0,0) */
+  unsigned char        white[CUPS_MAX_RGB];    /* Cached white (sRGB = 255,255,255) */
+} cups_rgb_t;
+
+typedef struct cups_cmyk_s             /**** Simple CMYK lookup table ****/
+{
+  unsigned char        black_lut[256];         /* Black generation LUT */
+  unsigned char        color_lut[256];         /* Color removal LUT */
+  int          ink_limit;              /* Ink limit */
+  int          num_channels;           /* Number of components */
+  short                *channels[CUPS_MAX_CHAN];
+                                       /* Lookup tables */
+} cups_cmyk_t;
+
+
+/*
+ * Globals...
+ */
+
+extern const unsigned char
+                       cups_srgb_lut[256];
+                                       /* sRGB gamma lookup table */
+extern const unsigned char
+                       cups_scmy_lut[256];
+                                       /* sRGB gamma lookup table (inverted) */
+
+
+/*
+ * Prototypes...
+ */
+
+/*
+ * Attribute function...
+ */
+
+extern ppd_attr_t      *cupsFindAttr(ppd_file_t *ppd, const char *name,
+                                     const char *colormodel,
+                                     const char *media,
+                                     const char *resolution,
+                                     char *spec, int specsize);
+                              
+/*
+ * Byte checking functions...
+ */
+
+extern int             cupsCheckBytes(const unsigned char *, int);
+extern int             cupsCheckValue(const unsigned char *, int,
+                                      const unsigned char);
+
+/*
+ * Dithering functions...
+ */
+
+extern void            cupsDitherLine(cups_dither_t *d, const cups_lut_t *lut,
+                                      const short *data, int num_channels,
+                                      unsigned char *p);
+extern cups_dither_t   *cupsDitherNew(int width);
+extern void            cupsDitherDelete(cups_dither_t *);
+
+/*
+ * Lookup table functions for dithering...
+ */
+
+extern cups_lut_t      *cupsLutNew(int num_vals, const float *vals);
+extern void            cupsLutDelete(cups_lut_t *lut);
+extern cups_lut_t      *cupsLutLoad(ppd_file_t *ppd,
+                                    const char *colormodel,
+                                    const char *media,
+                                    const char *resolution,
+                                    const char *ink);
+
+
+/*
+ * Bit packing functions...
+ */
+
+extern void            cupsPackHorizontal(const unsigned char *,
+                                          unsigned char *, int,
+                                          const unsigned char, const int);
+extern void            cupsPackHorizontal2(const unsigned char *,
+                                           unsigned char *, int, const int);
+extern void            cupsPackHorizontalBit(const unsigned char *,
+                                             unsigned char *, int,
+                                             const unsigned char,
+                                             const unsigned char);
+extern void            cupsPackVertical(const unsigned char *, unsigned char *,
+                                        int, const unsigned char, const int);
+
+/*
+ * Color separation functions...
+ */
+
+extern void            cupsRGBDelete(cups_rgb_t *rgb);
+extern void            cupsRGBDoGray(cups_rgb_t *rgb,
+                                     const unsigned char *input,
+                                     unsigned char *output, int num_pixels);
+extern void            cupsRGBDoRGB(cups_rgb_t *rgb,
+                                    const unsigned char *input,
+                                    unsigned char *output, int num_pixels);
+extern cups_rgb_t      *cupsRGBLoad(ppd_file_t *ppd,
+                                    const char *colormodel,
+                                    const char *media,
+                                    const char *resolution);
+extern cups_rgb_t      *cupsRGBNew(int num_samples, cups_sample_t *samples,
+                                   int cube_size, int num_channels);
+
+/*
+ * CMYK separation functions...
+ */
+
+extern cups_cmyk_t     *cupsCMYKNew(int num_channels);
+extern void            cupsCMYKDelete(cups_cmyk_t *cmyk);
+extern void            cupsCMYKDoBlack(const cups_cmyk_t *cmyk,
+                                       const unsigned char *input,
+                                       short *output, int num_pixels);
+extern void            cupsCMYKDoCMYK(const cups_cmyk_t *cmyk,
+                                      const unsigned char *input,
+                                      short *output, int num_pixels);
+extern void            cupsCMYKDoGray(const cups_cmyk_t *cmyk,
+                                      const unsigned char *input,
+                                      short *output, int num_pixels);
+extern void            cupsCMYKDoRGB(const cups_cmyk_t *cmyk,
+                                     const unsigned char *input,
+                                     short *output, int num_pixels);
+extern cups_cmyk_t     *cupsCMYKLoad(ppd_file_t *ppd,
+                                     const char *colormodel,
+                                     const char *media,
+                                     const char *resolution);
+extern void            cupsCMYKSetBlack(cups_cmyk_t *cmyk,
+                                        float lower, float upper);
+extern void            cupsCMYKSetCurve(cups_cmyk_t *cmyk, int channel,
+                                        int num_xypoints,
+                                        const float *xypoints);
+extern void            cupsCMYKSetGamma(cups_cmyk_t *cmyk, int channel,
+                                        float gamval, float density);
+extern void            cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, float limit);
+extern void            cupsCMYKSetLtDk(cups_cmyk_t *cmyk, int channel,
+                                       float light, float dark);
+
+
+/*
+ * Convenience macro for writing print data...
+ */
+
+#  define cupsWritePrintData(s,n) fwrite((s), 1, (n), stdout)
+
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+
+#endif /* !_CUPS_DRIVER_H_ */
+
+/*
+ * End of "$Id$".
+ */
+
diff --git a/driver/lut.c b/driver/lut.c
new file mode 100644 (file)
index 0000000..7ca7e43
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * "$Id$"
+ *
+ *   Lookup table routines for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsLutDelete() - Free the memory used by a lookup table.
+ *   cupsLutLoad()   - Load a LUT from a PPD file.
+ *   cupsLutNew()    - Make a lookup table from a list of pixel values.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <math.h>
+
+
+/*
+ * 'cupsLutDelete()' - Free the memory used by a lookup table.
+ */
+
+void
+cupsLutDelete(cups_lut_t *lut)         /* I - Lookup table to free */
+{
+  if (lut != NULL)
+    free(lut);
+}
+
+
+/*
+ * 'cupsLutLoad()' - Load a LUT from a PPD file.
+ */
+
+cups_lut_t *                           /* O - New lookup table */
+cupsLutLoad(ppd_file_t *ppd,           /* I - PPD file */
+            const char *colormodel,    /* I - Color model */
+            const char *media,         /* I - Media type */
+            const char *resolution,    /* I - Resolution */
+           const char *ink)            /* I - Ink name */
+{
+  char         name[PPD_MAX_NAME],     /* Attribute name */
+               spec[PPD_MAX_NAME];     /* Attribute spec */
+  ppd_attr_t   *attr;                  /* Attribute */
+  int          nvals;                  /* Number of values */
+  float                vals[4];                /* Values */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!ppd || !colormodel || !media || !resolution || !ink)
+    return (NULL);
+
+ /*
+  * Try to find the LUT values...
+  */
+
+  snprintf(name, sizeof(name), "cups%sDither", ink);
+
+  if ((attr = cupsFindAttr(ppd, name, colormodel, media, resolution, spec,
+                           sizeof(spec))) == NULL)
+    attr = cupsFindAttr(ppd, "cupsAllDither", colormodel, media,
+                        resolution, spec, sizeof(spec));
+
+  if (!attr)
+    return (NULL);
+
+  vals[0] = 0.0;
+  vals[1] = 0.0;
+  vals[2] = 0.0;
+  vals[3] = 0.0;
+  nvals   = sscanf(attr->value, "%f%f%f", vals + 1, vals + 2, vals + 3) + 1;
+
+  fprintf(stderr, "DEBUG: Loaded LUT %s from PPD with values [%.3f %.3f %.3f %.3f]\n",
+          name, vals[0], vals[1], vals[2], vals[3]);
+
+  return (cupsLutNew(nvals, vals));
+}
+
+
+/*
+ * 'cupsLutNew()' - Make a lookup table from a list of pixel values.
+ *
+ * Returns a pointer to the lookup table on success, NULL on failure.
+ */
+
+cups_lut_t *                           /* O - New lookup table */
+cupsLutNew(int         num_values,     /* I - Number of values */
+          const float *values)         /* I - Lookup table values */
+{
+  int          pixel;                  /* Pixel value */
+  cups_lut_t   *lut;                   /* Lookup table */
+  int          start,                  /* Start value */
+               end,                    /* End value */
+               maxval;                 /* Maximum value */
+
+
+ /*
+  * Range check...
+  */
+
+  if (!num_values || !values)
+    return (NULL);
+
+ /*
+  * Allocate memory for the lookup table...
+  */
+
+  if ((lut = (cups_lut_t *)calloc((CUPS_MAX_LUT + 1),
+                                  sizeof(cups_lut_t))) == NULL)
+    return (NULL);
+
+ /*
+  * Generate the dither lookup table.  The pixel values are roughly
+  * defined by a piecewise linear curve that has an intensity value
+  * at each output pixel.  This isn't perfectly accurate, but it's
+  * close enough for jazz.
+  */
+
+  maxval = CUPS_MAX_LUT / values[num_values - 1];
+
+  for (start = 0; start <= CUPS_MAX_LUT; start ++)
+    lut[start].intensity = start * maxval / CUPS_MAX_LUT;
+
+  for (pixel = 0; pixel < num_values; pixel ++)
+  {
+   /*
+    * Select start and end values for this pixel...
+    */
+
+    if (pixel == 0)
+      start = 0;
+    else
+      start = (int)(0.5 * maxval * (values[pixel - 1] +
+                                    values[pixel])) + 1;
+
+    if (start < 0)
+      start = 0;
+    else if (start > CUPS_MAX_LUT)
+      start = CUPS_MAX_LUT;
+
+    if (pixel == (num_values - 1))
+      end = CUPS_MAX_LUT;
+    else
+      end = (int)(0.5 * maxval * (values[pixel] + values[pixel + 1]));
+
+    if (end < 0)
+      end = 0;
+    else if (end > CUPS_MAX_LUT)
+      end = CUPS_MAX_LUT;
+
+    if (start == end)
+      break;
+
+   /*
+    * Generate lookup values and errors for each pixel.
+    */
+
+    while (start <= end)
+    {
+      lut[start].pixel = pixel;
+      if (start == 0)
+        lut[0].error = 0;
+      else
+        lut[start].error = start - maxval * values[pixel];
+
+      start ++;
+    }
+  }
+
+ /*
+  * Show the lookup table...
+  */
+
+  for (start = 0; start <= CUPS_MAX_LUT; start += CUPS_MAX_LUT / 15)
+    fprintf(stderr, "DEBUG: %d = %d/%d/%d\n", start, lut[start].intensity,
+            lut[start].pixel, lut[start].error);
+
+ /*
+  * Return the lookup table...
+  */
+
+  return (lut);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/pack.c b/driver/pack.c
new file mode 100644 (file)
index 0000000..d9d01d1
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * "$Id$"
+ *
+ *   Bit packing routines for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsPackHorizontal()    - Pack pixels horizontally...
+ *   cupsPackHorizontal2()   - Pack 2-bit pixels horizontally...
+ *   cupsPackHorizontalBit() - Pack pixels horizontally by bit...
+ *   cupsPackVertical()      - Pack pixels vertically...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsPackHorizontal()' - Pack pixels horizontally...
+ */
+
+void
+cupsPackHorizontal(const unsigned char *ipixels,/* I - Input pixels */
+                  unsigned char       *obytes, /* O - Output bytes */
+                  int                 width,   /* I - Number of pixels */
+                  const unsigned char clearto, /* I - Initial value of bytes */
+                  const int           step)    /* I - Step value between pixels */
+{
+  register unsigned char       b;              /* Current byte */
+
+
+ /*
+  * Do whole bytes first...
+  */
+
+  while (width > 7)
+  {
+    b = clearto;
+
+    if (*ipixels)
+      b ^= 0x80;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x40;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x20;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x10;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x08;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x04;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x02;
+    ipixels += step;
+    if (*ipixels)
+      b ^= 0x01;
+    ipixels += step;
+
+    *obytes++ = b;
+
+    width -= 8;
+  }
+
+ /*
+  * Then do the last N bytes (N < 8)...
+  */
+
+  b = clearto;
+
+  switch (width)
+  {
+    case 7 :
+       if (ipixels[6 * step])
+         b ^= 0x02;
+    case 6 :
+       if (ipixels[5 * step])
+         b ^= 0x04;
+    case 5 :
+       if (ipixels[4 * step])
+         b ^= 0x08;
+    case 4 :
+       if (ipixels[3 * step])
+         b ^= 0x10;
+    case 3 :
+       if (ipixels[2 * step])
+         b ^= 0x20;
+    case 2 :
+       if (ipixels[1 * step])
+         b ^= 0x40;
+    case 1 :
+       if (ipixels[0])
+         b ^= 0x80;
+        *obytes = b;
+        break;
+  }
+}
+
+
+/*
+ * 'cupsPackHorizontal2()' - Pack 2-bit pixels horizontally...
+ */
+
+void
+cupsPackHorizontal2(const unsigned char *ipixels,      /* I - Input pixels */
+                   unsigned char       *obytes,        /* O - Output bytes */
+                   int                 width,          /* I - Number of pixels */
+                   const int           step)           /* I - Stepping value */
+{
+  register unsigned char       b;                      /* Current byte */
+
+
+ /*
+  * Do whole bytes first...
+  */
+
+  while (width > 3)
+  {
+    b = *ipixels;
+    ipixels += step;
+    b = (b << 2) | *ipixels;
+    ipixels += step;
+    b = (b << 2) | *ipixels;
+    ipixels += step;
+    b = (b << 2) | *ipixels;
+    ipixels += step;
+
+    *obytes++ = b;
+
+    width -= 4;
+  }
+
+ /*
+  * Then do the last N bytes (N < 4)...
+  */
+
+  b = 0;
+
+  switch (width)
+  {
+    case 3 :
+       b = ipixels[2 * step];
+    case 2 :
+       b = (b << 2) | ipixels[step];
+    case 1 :
+       b = (b << 2) | ipixels[0];
+        *obytes = b << (8 - 2 * width);
+        break;
+  }
+}
+
+
+/*
+ * 'cupsPackHorizontalBit()' - Pack pixels horizontally by bit...
+ */
+
+void
+cupsPackHorizontalBit(const unsigned char *ipixels,    /* I - Input pixels */
+                      unsigned char       *obytes,     /* O - Output bytes */
+                      int                 width,       /* I - Number of pixels */
+                      const unsigned char clearto,     /* I - Initial value of bytes */
+                     const unsigned char bit)          /* I - Bit to check */
+{
+  register unsigned char       b;                      /* Current byte */
+
+
+ /*
+  * Do whole bytes first...
+  */
+
+  while (width > 7)
+  {
+    b = clearto;
+
+    if (*ipixels++ & bit)
+      b ^= 0x80;
+    if (*ipixels++ & bit)
+      b ^= 0x40;
+    if (*ipixels++ & bit)
+      b ^= 0x20;
+    if (*ipixels++ & bit)
+      b ^= 0x10;
+    if (*ipixels++ & bit)
+      b ^= 0x08;
+    if (*ipixels++ & bit)
+      b ^= 0x04;
+    if (*ipixels++ & bit)
+      b ^= 0x02;
+    if (*ipixels++ & bit)
+      b ^= 0x01;
+
+    *obytes++ = b;
+
+    width -= 8;
+  }
+
+ /*
+  * Then do the last N bytes (N < 8)...
+  */
+
+  b = clearto;
+
+  switch (width)
+  {
+    case 7 :
+       if (ipixels[6] & bit)
+         b ^= 0x02;
+    case 6 :
+       if (ipixels[5] & bit)
+         b ^= 0x04;
+    case 5 :
+       if (ipixels[4] & bit)
+         b ^= 0x08;
+    case 4 :
+       if (ipixels[3] & bit)
+         b ^= 0x10;
+    case 3 :
+       if (ipixels[2] & bit)
+         b ^= 0x20;
+    case 2 :
+       if (ipixels[1] & bit)
+         b ^= 0x40;
+    case 1 :
+       if (ipixels[0] & bit)
+         b ^= 0x80;
+        *obytes = b;
+        break;
+  }
+}
+
+
+/*
+ * 'cupsPackVertical()' - Pack pixels vertically...
+ */
+
+void
+cupsPackVertical(const unsigned char *ipixels, /* I - Input pixels */
+                 unsigned char       *obytes,  /* O - Output bytes */
+                 int                 width,    /* I - Number of input pixels */
+                 const unsigned char bit,      /* I - Output bit */
+                 const int           step)     /* I - Number of bytes between columns */
+{
+ /*
+  * Loop through the entire array...
+  */
+
+  while (width > 7)
+  {
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+    if (*ipixels++)
+      *obytes ^= bit;
+    obytes += step;
+
+    width -= 8;
+  }
+
+  while (width > 0)
+  {
+    if (*ipixels++)
+      *obytes ^= bit;
+
+    obytes += step;
+    width --;
+  }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/pcl-common.c b/driver/pcl-common.c
new file mode 100644 (file)
index 0000000..4278793
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * "$Id$"
+ *
+ *   Common PCL functions for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   pcl_set_media_size() - Set media size using the page size command.
+ *   pjl_write()          - Write a PJL command string, performing
+ *                          substitutions as needed.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "driver.h"
+#include "pcl-common.h"
+#include <math.h>
+
+
+/*
+ * 'pcl_set_media_size()' - Set media size using the page size command.
+ */
+
+void
+pcl_set_media_size(ppd_file_t *ppd,    /* I - PPD file */
+                   float      width,   /* I - Width of page */
+                   float      length)  /* I - Length of page */
+{
+  (void)width;
+
+  printf("\033&l0O");                  /* Set portrait orientation */
+
+  if (ppd->model_number & PCL_PAPER_SIZE)
+    switch ((int)(length + 0.5f))
+    {
+      case 419 : /* Postcard */
+          printf("\033&l71A");         /* Set page size */
+         break;
+
+      case 540 : /* Monarch Envelope */
+          printf("\033&l80A");         /* Set page size */
+         break;
+
+      case 567 : /* Double Postcard */
+          printf("\033&l72A");         /* Set page size */
+         break;
+
+      case 595 : /* A5 */
+          printf("\033&l25A");         /* Set page size */
+         break;
+
+      case 612 : /* Statement */
+          printf("\033&l5A");          /* Set page size */
+         break;
+
+      case 624 : /* DL Envelope */
+          printf("\033&l90A");         /* Set page size */
+         break;
+
+      case 649 : /* C5 Envelope */
+          printf("\033&l91A");         /* Set page size */
+         break;
+
+      case 684 : /* COM-10 Envelope */
+          printf("\033&l81A");         /* Set page size */
+         break;
+
+      case 709 : /* B5 Envelope */
+          printf("\033&l100A");                /* Set page size */
+         break;
+
+      case 729 : /* B5 */
+          printf("\033&l45A");         /* Set page size */
+         break;
+
+      case 756 : /* Executive */
+          printf("\033&l1A");          /* Set page size */
+         break;
+
+      case 792 : /* Letter */
+          printf("\033&l2A");          /* Set page size */
+         break;
+
+      case 842 : /* A4 */
+          printf("\033&l26A");         /* Set page size */
+         break;
+
+      case 936 : /* Foolscap */
+          printf("\033&l23A");         /* Set page size */
+         break;
+
+      case 1008 : /* Legal */
+          printf("\033&l3A");          /* Set page size */
+         break;
+
+      case 1032 : /* B4 */
+          printf("\033&l46A");         /* Set page size */
+         break;
+
+      case 1191 : /* A3 */
+          printf("\033&l27A");         /* Set page size */
+         break;
+
+      case 1224 : /* Tabloid */
+          printf("\033&l6A");          /* Set page size */
+         break;
+
+      default :
+          printf("\033&l101A");                /* Set page size */
+         printf("\033&l6D\033&k12H");  /* Set 6 LPI, 10 CPI */
+         printf("\033&l%.2fP", length / 12.0);
+                                       /* Set page length */
+         printf("\033&l%.0fF", length / 12.0);
+                                       /* Set text length to page */
+         break;
+    }
+  else
+  {
+    printf("\033&l6D\033&k12H");       /* Set 6 LPI, 10 CPI */
+    printf("\033&l%.2fP", length / 12.0);
+                                       /* Set page length */
+    printf("\033&l%.0fF", length / 12.0);
+                                       /* Set text length to page */
+  }
+
+  printf("\033&l0L");                  /* Turn off perforation skip */
+  printf("\033&l0E");                  /* Reset top margin to 0 */
+}
+
+
+/*
+ * 'pjl_write()' - Write a PJL command string, performing substitutions as needed.
+ */
+
+void
+pjl_write(ppd_file_t    *ppd,          /* I - PPD file */
+          const char    *format,       /* I - Format string */
+          const char    *value,                /* I - Value for %s */
+         int           job_id,         /* I - Job ID */
+          const char    *user,         /* I - Username */
+         const char    *title,         /* I - Title */
+         int           num_options,    /* I - Number of options */
+          cups_option_t *options)      /* I - Options */
+{
+  const char   *optval;                /* Option value */
+  char         match[255],             /* Match string */
+               *mptr;                  /* Pointer into match string */
+
+
+  if (!format)
+    return;
+
+  while (*format)
+  {
+    if (*format == '%')
+    {
+     /*
+      * Perform substitution...
+      */
+
+      format ++;
+      switch (*format)
+      {
+        case 'b' :                     /* job-billing */
+           if ((optval = cupsGetOption("job-billing", num_options,
+                                       options)) != NULL)
+             fputs(optval, stdout);
+           break;
+
+       case 'h' :                      /* job-originating-host-name */
+           if ((optval = cupsGetOption("job-originating-host-name",
+                                       num_options, options)) != NULL)
+             fputs(optval, stdout);
+           break;
+
+       case 'j' :                      /* job-id */
+           printf("%d", job_id);
+           break;
+
+       case 'n' :                      /* CR + LF */
+           putchar('\r');
+           putchar('\n');
+           break;
+
+       case 'q' :                      /* double quote (") */
+           putchar('\"');
+           break;
+
+       case 's' :                      /* "value" */
+           if (value)
+             fputs(value, stdout);
+           break;
+
+       case 't' :                      /* job-name */
+            fputs(title, stdout);
+           break;
+
+       case 'u' :                      /* job-originating-user-name */
+            fputs(user, stdout);
+           break;
+
+        case '?' :                     /* ?value:string; */
+           /*
+           * Get the match value...
+           */
+
+           for (format ++, mptr = match; *format && *format != ':'; format ++)
+             if (mptr < (match + sizeof(match) - 1))
+               *mptr++ = *format;
+
+            if (!*format)
+             return;
+
+           /*
+           * See if we have a match...
+           */
+
+            format ++;
+            *mptr = '\0';
+
+           if (!value || strcmp(match, value))
+           {
+            /*
+             * Value doesn't match; skip the string that follows...
+             */
+
+              while (*format && *format != ';')
+               format ++;
+           }
+           else
+           {
+            /*
+             * Value matches; copy the string that follows...
+             */
+
+              while (*format && *format != ';')
+               putchar(*format++);
+           }
+
+           if (!*format)
+             return;
+           break;
+
+       default :                       /* Anything else */
+           putchar('%');
+       case '%' :                      /* %% = single % */
+           putchar(*format);
+           break;
+      }
+    }
+    else
+      putchar(*format);
+
+    format ++;
+  }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/pcl-common.h b/driver/pcl-common.h
new file mode 100644 (file)
index 0000000..78cf701
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * "$Id$"
+ *
+ *   Common HP-PCL definitions for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 by Easy Software Products, All Rights Reserved.
+ *
+ *   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/".
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "string.h"
+#include "data/pcl.h"
+
+
+/*
+ * Functions/macros...
+ */
+
+#define pcl_reset()\
+       printf("\033E")
+#define pcl_set_copies(copies)\
+       printf("\033&l%dX", (copies))
+#define pcl_set_pcl_mode(m)\
+       printf("\033%%%dA", (m))
+#define pcl_set_hpgl_mode(m)\
+       printf("\033%%%dB", (m))
+#define pcl_set_negative_motion()\
+        printf("\033&a1N")
+#define pcl_set_media_source(source)\
+       printf("\033&l%dH", source)
+#define pcl_set_media_type(type)\
+       printf("\033&l%dM", type)
+#define pcl_set_duplex(duplex,landscape)\
+       if (duplex) printf("\033&l%dS", (duplex) + (landscape))
+#define pcl_set_simple_black()\
+       printf("\033*r-1U")
+#define pcl_set_simple_color()\
+       printf("\033*r3U")
+#define pcl_set_simple_cmy()\
+       printf("\033*r-3U")
+#define pcl_set_simple_kcmy()\
+       printf("\033*r-4U")
+#define pcl_set_simple_resolution(r)\
+       printf("\033*t%dR", (r))
+
+#define pjl_escape()\
+       printf("\033%%-12345X@PJL\r\n")
+#define pjl_set_job(job_id,user,title)\
+       printf("@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\r\n", \
+              (title), (job_id), (user), (title))
+#define pjl_enter_language(lang)\
+       printf("@PJL ENTER LANGUAGE=%s\r\n", (lang))
+
+extern void    pcl_set_media_size(ppd_file_t *ppd, float width, float length);
+extern void    pjl_write(ppd_file_t *ppd, const char *format,
+                         const char *value, int job_id,
+                         const char *user, const char *title,
+                         int num_options, cups_option_t *options);
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/rastertoescpx.c b/driver/rastertoescpx.c
new file mode 100644 (file)
index 0000000..f9cf22a
--- /dev/null
@@ -0,0 +1,1845 @@
+/*
+ * "$Id$"
+ *
+ *   Advanced EPSON ESC/P raster driver for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   Setup()           - Prepare the printer for graphics output.
+ *   StartPage()       - Start a page of graphics.
+ *   EndPage()         - Finish a page of graphics.
+ *   Shutdown()        - Shutdown a printer.
+ *   CompressData()    - Compress a line of graphics.
+ *   OutputBand()      - Output a band of graphics.
+ *   ProcessLine()     - Read graphics from the page stream and output
+ *                       as needed.
+ *   main()            - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "driver.h"
+#include <cups/string.h>
+#include "data/escp.h"
+
+
+/*
+ * Softweave data...
+ */
+
+typedef struct cups_weave_str
+{
+  struct cups_weave_str        *prev,                  /* Previous band */
+                       *next;                  /* Next band */
+  int                  x, y,                   /* Column/Line on the page */
+                       plane,                  /* Color plane */
+                       dirty,                  /* Is this buffer dirty? */
+                       row,                    /* Row in the buffer */
+                       count;                  /* Max rows this pass */
+  unsigned char                *buffer;                /* Data buffer */
+} cups_weave_t;
+
+
+/*
+ * Globals...
+ */
+
+cups_rgb_t     *RGB;                   /* RGB color separation data */
+cups_cmyk_t    *CMYK;                  /* CMYK color separation data */
+unsigned char  *PixelBuffer,           /* Pixel buffer */
+               *CMYKBuffer,            /* CMYK buffer */
+               *OutputBuffers[7],      /* Output buffers */
+               *DotBuffers[7],         /* Dot buffers */
+               *CompBuffer;            /* Compression buffer */
+short          *InputBuffer;           /* Color separation buffer */
+cups_weave_t   *DotAvailList,          /* Available buffers */
+               *DotUsedList,           /* Used buffers */
+               *DotBands[128][7];      /* Buffers in use */
+int            DotBufferSize,          /* Size of dot buffers */
+               DotRowMax,              /* Maximum row number in buffer */
+               DotColStep,             /* Step for each output column */
+               DotRowStep,             /* Step for each output line */
+               DotRowFeed,             /* Amount to feed for interleave */
+               DotRowCount,            /* Number of rows to output */
+               DotRowOffset[7],        /* Offset for each color on print head */
+               DotRowCurrent,          /* Current row */
+               DotSize;                /* Dot size (Pro 5000 only) */
+int            PrinterPlanes,          /* # of color planes */
+               BitPlanes,              /* # of bit planes per color */
+               PrinterTop,             /* Top of page */
+               PrinterLength;          /* Length of page */
+cups_lut_t     *DitherLuts[7];         /* Lookup tables for dithering */
+cups_dither_t  *DitherStates[7];       /* Dither state tables */
+int            OutputFeed;             /* Number of lines to skip */
+
+
+/*
+ * Prototypes...
+ */
+
+void   Setup(ppd_file_t *);
+void   StartPage(ppd_file_t *, cups_page_header_t *);
+void   EndPage(ppd_file_t *, cups_page_header_t *);
+void   Shutdown(ppd_file_t *);
+
+void   AddBand(cups_weave_t *band);
+void   CompressData(ppd_file_t *, const unsigned char *, const int,
+                    int, int, const int, const int, const int,
+                    const int);
+void   OutputBand(ppd_file_t *, cups_page_header_t *,
+                  cups_weave_t *band);
+void   ProcessLine(ppd_file_t *, cups_raster_t *,
+                   cups_page_header_t *, const int y);
+
+
+/*
+ * 'Setup()' - Prepare a printer for graphics output.
+ */
+
+void
+Setup(ppd_file_t *ppd)         /* I - PPD file */
+{
+ /*
+  * Some EPSON printers need an additional command issued at the
+  * beginning of each job to exit from USB "packet" mode...
+  */
+
+  if (ppd->model_number & ESCP_USB)
+    cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL     \n\033@", 29);
+}
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(ppd_file_t         *ppd,     /* I - PPD file */
+          cups_page_header_t *header)  /* I - Page header */
+{
+  int          i, y;                   /* Looping vars */
+  int          subrow,                 /* Current subrow */
+               modrow,                 /* Subrow modulus */
+               plane;                  /* Current color plane */
+  unsigned char        *ptr;                   /* Pointer into dot buffer */
+  int          bands;                  /* Number of bands to allocate */
+  int          units;                  /* Units for resolution */
+  cups_weave_t *band;                  /* Current band */
+  const char   *colormodel;            /* Color model string */
+  char         resolution[PPD_MAX_NAME],
+                                       /* Resolution string */
+               spec[PPD_MAX_NAME];     /* PPD attribute name */
+  ppd_attr_t   *attr;                  /* Attribute from PPD file */
+  const float  default_lut[2] =        /* Default dithering lookup table */
+               {
+                 0.0,
+                 1.0
+               };
+
+
+  fprintf(stderr, "DEBUG: StartPage...\n");
+  fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
+  fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
+  fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
+  fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
+
+  fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
+  fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
+  fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
+  fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
+  fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
+  fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
+          header->HWResolution[1]);
+  fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
+          header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
+          header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
+  fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
+  fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
+  fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
+  fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
+          header->Margins[1]);
+  fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
+  fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
+  fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
+  fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
+  fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
+  fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
+  fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
+  fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
+  fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
+          header->PageSize[1]);
+  fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
+  fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
+  fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
+  fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
+  fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
+  fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
+  fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
+  fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
+  fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
+  fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
+  fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
+  fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
+  fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount);
+  fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
+  fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
+
+ /*
+  * Figure out the color model and spec strings...
+  */
+
+  switch (header->cupsColorSpace)
+  {
+    case CUPS_CSPACE_K :
+        colormodel = "Black";
+       break;
+    case CUPS_CSPACE_W :
+        colormodel = "Gray";
+       break;
+    default :
+    case CUPS_CSPACE_RGB :
+        colormodel = "RGB";
+       break;
+    case CUPS_CSPACE_CMYK :
+        colormodel = "CMYK";
+       break;
+  }
+
+  if (header->HWResolution[0] != header->HWResolution[1])
+    snprintf(resolution, sizeof(resolution), "%dx%ddpi",
+             header->HWResolution[0], header->HWResolution[1]);
+  else
+    snprintf(resolution, sizeof(resolution), "%ddpi",
+             header->HWResolution[0]);
+
+  if (!header->MediaType[0])
+    strcpy(header->MediaType, "Plain");
+
+ /*
+  * Load the appropriate color profiles...
+  */
+
+  RGB  = NULL;
+  CMYK = NULL;
+
+  fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr);
+  fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel);
+  fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType);
+  fprintf(stderr, "DEBUG: Resolution = %s\n", resolution);
+
+  if (header->cupsColorSpace == CUPS_CSPACE_RGB ||
+      header->cupsColorSpace == CUPS_CSPACE_W)
+    RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution);
+  else
+    RGB = NULL;
+
+  CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution);
+
+  if (RGB)
+    fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr);
+
+  if (CMYK)
+    fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr);
+  else
+  {
+    fputs("DEBUG: Loading default CMYK separation.\n", stderr);
+    CMYK = cupsCMYKNew(4);
+  }
+
+  PrinterPlanes = CMYK->num_channels;
+
+  fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes);
+
+ /*
+  * Get the dithering parameters...
+  */
+
+  switch (PrinterPlanes)
+  {
+    case 1 : /* K */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Black");
+        break;
+
+    case 2 : /* Kk */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Black");
+        DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightBlack");
+        break;
+
+    case 3 : /* CMY */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Cyan");
+        DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Magenta");
+        DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Yellow");
+        break;
+
+    case 4 : /* CMYK */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Cyan");
+        DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Magenta");
+        DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Yellow");
+        DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Black");
+        break;
+
+    case 6 : /* CcMmYK */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Cyan");
+        DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightCyan");
+        DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Magenta");
+        DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightMagenta");
+        DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Yellow");
+        DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Black");
+        break;
+
+    case 7 : /* CcMmYKk */
+        DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Cyan");
+        DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightCyan");
+        DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Magenta");
+        DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightMagenta");
+        DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Yellow");
+        DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "Black");
+        DitherLuts[6] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                   resolution, "LightBlack");
+        break;
+  }
+
+  for (plane = 0; plane < PrinterPlanes; plane ++)
+  {
+    DitherStates[plane] = cupsDitherNew(header->cupsWidth);
+
+    if (!DitherLuts[plane])
+      DitherLuts[plane] = cupsLutNew(2, default_lut);
+  }
+
+  if (DitherLuts[0][4095].pixel > 1)
+    BitPlanes = 2;
+  else
+    BitPlanes = 1;
+
+ /*
+  * Initialize the printer...
+  */
+
+  printf("\033@");
+
+  if (ppd->model_number & ESCP_REMOTE)
+  {
+   /*
+    * Go into remote mode...
+    */
+
+    cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+
+   /*
+    * Disable status reporting...
+    */
+
+    cupsWritePrintData("ST\002\000\000\000", 6);
+
+   /*
+    * Enable borderless printing...
+    */
+
+    if ((attr = ppdFindAttr(ppd, "cupsESCPFP", NULL)) != NULL && attr->value)
+    {
+     /*
+      * Set horizontal offset...
+      */
+
+      i = atoi(attr->value);
+
+      cupsWritePrintData("FP\003\000\000", 5);
+      putchar(i & 255);
+      putchar(i >> 8);
+    }
+
+   /*
+    * Set media type...
+    */
+
+    if (header->cupsMediaType)
+    {
+      sprintf(spec, "%d", header->cupsMediaType);
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN0", spec)) != NULL && attr->value)
+      {
+       /*
+        * Set feed sequence...
+       */
+
+       cupsWritePrintData("SN\003\000\000\000", 6);
+       putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN1", spec)) != NULL && attr->value)
+      {
+       /*
+        * Set platten gap...
+       */
+
+       cupsWritePrintData("SN\003\000\000\001", 6);
+       putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN2", spec)) != NULL && attr->value)
+      {
+       /*
+        * Paper feeding/ejecting sequence...
+       */
+
+       cupsWritePrintData("SN\003\000\000\002", 6);
+       putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN6", spec)) != NULL && attr->value)
+      {
+       /*
+        * Eject delay...
+       */
+
+        cupsWritePrintData("SN\003\000\000\006", 6);
+        putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPMT", spec)) != NULL && attr->value)
+      {
+       /*
+        * Set media type.
+       */
+
+       cupsWritePrintData("MT\003\000\000\000", 6);
+        putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPPH", spec)) != NULL && attr->value)
+      {
+       /*
+        * Set paper thickness.
+        */
+
+       cupsWritePrintData("PH\002\000\000", 5);
+        putchar(atoi(attr->value));
+      }
+    }
+
+    sprintf(spec, "%d", header->MediaPosition);
+
+    if (header->MediaPosition)
+    {
+      if ((attr = ppdFindAttr(ppd, "cupsESCPPC", spec)) != NULL && attr->value)
+      {
+       /*
+       * Paper check.
+       */
+
+       cupsWritePrintData("PC\002\000\000", 5);
+        putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPPP", spec)) != NULL && attr->value)
+      {
+       /*
+       * Paper path.
+       */
+
+        int a, b;
+
+        a = b = 0;
+        sscanf(attr->value, "%d%d", &a, &b);
+
+       cupsWritePrintData("PP\003\000\000", 5);
+        putchar(a);
+        putchar(b);
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPEX", spec)) != NULL && attr->value)
+      {
+       /*
+       * Set media position.
+       */
+
+       cupsWritePrintData("EX\006\000\000\000\000\000\005", 9);
+        putchar(atoi(attr->value));
+      }
+    }
+
+    if ((attr = ppdFindAttr(ppd, "cupsESCPMS", spec)) != NULL && attr->value)
+    {
+     /*
+      * Set media size...
+      */
+
+      cupsWritePrintData("MS\010\000\000", 5);
+      putchar(atoi(attr->value));
+
+      switch (header->PageSize[1])
+      {
+        case 1191 :    /* A3 */
+           putchar(0x01);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 1032 :     /* B4 */
+           putchar(0x02);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 842 :      /* A4 */
+           putchar(0x03);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 595 :      /* A4.Transverse */
+           putchar(0x03);
+           putchar(0x01);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 729 :      /* B5 */
+           putchar(0x04);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 516 :      /* B5.Transverse */
+           putchar(0x04);
+           putchar(0x01);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 1369 :     /* Super A3/B */
+           putchar(0x20);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 792 :      /* Letter */
+           putchar(0x08);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 612 :      /* Letter.Transverse */
+           putchar(0x08);
+           putchar(0x01);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 1004 :     /* Legal */
+           putchar(0x0a);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       case 1224 :     /* Tabloid */
+           putchar(0x2d);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           putchar(0x00);
+           break;
+       default :       /* Custom size */
+           putchar(0xff);
+           putchar(0xff);
+           i = 360 * header->PageSize[0] / 72;
+           putchar(i);
+           putchar(i >> 8);
+           i = 360 * header->PageSize[1] / 72;
+           putchar(i);
+           putchar(i >> 8);
+           break;
+      }
+    }
+
+    sprintf(spec, "%d", header->CutMedia);
+
+    if ((attr = ppdFindAttr(ppd, "cupsESCPAC", spec)) != NULL && attr->value)
+    {
+     /*
+      * Enable/disable cutter.
+      */
+
+      cupsWritePrintData("AC\002\000\000", 5);
+      putchar(atoi(attr->value));
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN80", header->MediaType)) != NULL && attr->value)
+      {
+       /*
+       * Cutting method...
+       */
+
+       cupsWritePrintData("SN\003\000\000\200", 6);
+       putchar(atoi(attr->value));
+      }
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPSN81", header->MediaType)) != NULL && attr->value)
+      {
+       /*
+       * Cutting pressure...
+       */
+
+       cupsWritePrintData("SN\003\000\000\201", 6);
+       putchar(atoi(attr->value));
+      }
+    }
+
+    if ((attr = ppdFindAttr(ppd, "cupsESCPCO", spec)) != NULL && attr->value)
+    {
+     /*
+      * Enable/disable cutter.
+      */
+
+      cupsWritePrintData("CO\010\000\000\000", 6);
+      putchar(atoi(attr->value));
+      cupsWritePrintData("\000\000\000\000\000", 5);
+    }
+
+   /*
+    * Exit remote mode...
+    */
+
+    cupsWritePrintData("\033\000\000\000", 4);
+  }
+
+ /*
+  * Enter graphics mode...
+  */
+
+  cupsWritePrintData("\033(G\001\000\001", 6);
+
+ /*
+  * Set the line feed increment...
+  */
+
+  /* TODO: get this from the PPD file... */
+  for (units = 1440; units < header->HWResolution[0]; units *= 2);
+
+  if (ppd->model_number & ESCP_EXT_UNITS)
+  {
+    cupsWritePrintData("\033(U\005\000", 5);
+    putchar(units / header->HWResolution[1]);
+    putchar(units / header->HWResolution[1]);
+    putchar(units / header->HWResolution[0]);
+    putchar(units);
+    putchar(units >> 8);
+  }
+  else
+  {
+    cupsWritePrintData("\033(U\001\000", 5);
+    putchar(3600 / header->HWResolution[1]);
+  }
+
+ /*
+  * Set the page length...
+  */
+
+  PrinterLength = header->PageSize[1] * header->HWResolution[1] / 72;
+
+  if (ppd->model_number & ESCP_PAGE_SIZE)
+  {
+   /*
+    * Set page size (expands bottom margin)...
+    */
+
+    cupsWritePrintData("\033(S\010\000", 5);
+
+    i = header->PageSize[0] * header->HWResolution[1] / 72;
+    putchar(i);
+    putchar(i >> 8);
+    putchar(i >> 16);
+    putchar(i >> 24);
+
+    i = header->PageSize[1] * header->HWResolution[1] / 72;
+    putchar(i);
+    putchar(i >> 8);
+    putchar(i >> 16);
+    putchar(i >> 24);
+  }
+  else
+  {
+    cupsWritePrintData("\033(C\002\000", 5);
+    putchar(PrinterLength & 255);
+    putchar(PrinterLength >> 8);
+  }
+
+ /*
+  * Set the top and bottom margins...
+  */
+
+  PrinterTop = (int)((ppd->sizes[1].length - ppd->sizes[1].top) *
+                     header->HWResolution[1] / 72.0);
+
+  if (ppd->model_number & ESCP_EXT_MARGINS)
+  {
+    cupsWritePrintData("\033(c\010\000", 5);
+
+    putchar(PrinterTop);
+    putchar(PrinterTop >> 8);
+    putchar(PrinterTop >> 16);
+    putchar(PrinterTop >> 24);
+
+    putchar(PrinterLength);
+    putchar(PrinterLength >> 8);
+    putchar(PrinterLength >> 16);
+    putchar(PrinterLength >> 24);
+  }
+  else
+  {
+    cupsWritePrintData("\033(c\004\000", 5);
+
+    putchar(PrinterTop & 255);
+    putchar(PrinterTop >> 8);
+
+    putchar(PrinterLength & 255);
+    putchar(PrinterLength >> 8);
+  }
+
+ /*
+  * Set the top position...
+  */
+
+  cupsWritePrintData("\033(V\002\000\000\000", 7);
+
+ /*
+  * Enable unidirectional printing depending on the mode...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsESCPDirection", colormodel,
+                           header->MediaType, resolution, spec,
+                          sizeof(spec))) != NULL)
+    printf("\033U%c", atoi(attr->value));
+
+ /*
+  * Enable/disable microweaving as needed...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsESCPMicroWeave", colormodel,
+                           header->MediaType, resolution, spec,
+                          sizeof(spec))) != NULL)
+    printf("\033(i\001%c%c", 0, atoi(attr->value));
+
+ /*
+  * Set the dot size and print speed as needed...
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsESCPDotSize", colormodel,
+                           header->MediaType, resolution, spec,
+                          sizeof(spec))) != NULL)
+    printf("\033(e\002%c%c%c", 0, 0, atoi(attr->value));
+
+  if (ppd->model_number & ESCP_ESCK)
+  {
+   /*
+    * Set the print mode...
+    */
+
+    if (PrinterPlanes == 1)
+    {
+     /*
+      * Fast black printing.
+      */
+
+      cupsWritePrintData("\033(K\002\000\000\001", 7);
+    }
+    else
+    {
+     /*
+      * Color printing.
+      */
+
+      cupsWritePrintData("\033(K\002\000\000\002", 7);
+    }
+  }
+
+ /*
+  * Get softweave settings from header...
+  */
+
+  if (header->cupsRowCount <= 1)
+  {
+    DotRowCount = 1;
+    DotColStep  = 1;
+    DotRowStep  = 1;
+    DotRowFeed  = 1;
+  }
+  else
+  {
+    DotRowCount = header->cupsRowCount;
+    DotRowFeed  = header->cupsRowFeed;
+    DotRowStep  = header->cupsRowStep % 100;
+    DotColStep  = header->cupsRowStep / 100;
+
+    if (DotColStep == 0)
+      DotColStep ++;
+  }
+
+ /*
+  * Setup softweave parameters...
+  */
+
+  DotRowCurrent = 0;
+  DotRowMax     = DotRowCount * DotRowStep;
+  DotBufferSize = (header->cupsWidth / DotColStep * BitPlanes + 7) / 8;
+
+  fprintf(stderr, "DEBUG: DotBufferSize = %d\n", DotBufferSize);
+  fprintf(stderr, "DEBUG: DotColStep = %d\n", DotColStep);
+  fprintf(stderr, "DEBUG: DotRowMax = %d\n", DotRowMax);
+  fprintf(stderr, "DEBUG: DotRowStep = %d\n", DotRowStep);
+  fprintf(stderr, "DEBUG: DotRowFeed = %d\n", DotRowFeed);
+  fprintf(stderr, "DEBUG: DotRowCount = %d\n", DotRowCount);
+
+  DotAvailList  = NULL;
+  DotUsedList   = NULL;
+  DotBuffers[0] = NULL;
+
+  fprintf(stderr, "DEBUG: model_number = %x\n", ppd->model_number);
+
+  if (DotRowMax > 1)
+  {
+   /*
+    * Compute offsets for the color jets on the print head...
+    */
+
+    bands = DotRowStep * DotColStep * PrinterPlanes * 4;
+
+    memset(DotRowOffset, 0, sizeof(DotRowOffset));
+
+    if (PrinterPlanes == 1)
+    {
+     /*
+      * Use full height of print head...
+      */
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPBlack", resolution)) != NULL &&
+          attr->value)
+      {
+       /*
+        * Use custom black head data...
+       */
+
+        sscanf(attr->value, "%d%d", &DotRowCount, &DotRowStep);
+      }
+    }
+    else if (ppd->model_number & ESCP_STAGGER)
+    {
+     /*
+      * Use staggered print head...
+      */
+
+      fputs("DEBUG: Offset head detected...\n", stderr);
+
+      if ((attr = ppdFindAttr(ppd, "cupsESCPOffsets", resolution)) != NULL &&
+          attr->value)
+      {
+       /*
+        * Use only 1/3 of the print head when printing color...
+       */
+
+        sscanf(attr->value, "%d%d%d%d", DotRowOffset + 0,
+              DotRowOffset + 1, DotRowOffset + 2, DotRowOffset + 3);
+      }
+    }
+
+    for (i = 0; i < PrinterPlanes; i ++)
+      fprintf(stderr, "DEBUG: DotRowOffset[%d] = %d\n", i, DotRowOffset[i]);
+
+   /*
+    * Allocate bands...
+    */
+
+    for (i = 0; i < bands; i ++)
+    {
+      band         = (cups_weave_t *)calloc(1, sizeof(cups_weave_t));
+      band->next   = DotAvailList;
+      DotAvailList = band;
+
+      band->buffer = calloc(DotRowCount, DotBufferSize);
+    }
+
+    fputs("DEBUG: Pointer list at start of page...\n", stderr);
+
+    for (band = DotAvailList; band != NULL; band = band->next)
+      fprintf(stderr, "DEBUG: %p\n", band);
+
+    fputs("DEBUG: ----END----\n", stderr);
+
+   /*
+    * Fill the initial bands...
+    */
+
+    modrow = DotColStep * DotRowStep;
+
+    if (DotRowFeed == 0)
+    {
+     /*
+      * Automatically compute the optimal feed value...
+      */
+
+      DotRowFeed = DotRowCount / DotColStep - DotRowStep;
+
+      while ((((DotRowFeed % 2) == 0) == ((DotRowCount % 2) == 0) ||
+              ((DotRowFeed % 3) == 0) == ((DotRowCount % 3) == 0) ||
+              ((DotRowFeed % 5) == 0) == ((DotRowCount % 5) == 0)) &&
+            DotRowFeed > 1)
+       DotRowFeed --;
+
+      if (DotRowFeed < 1)
+       DotRowFeed = 1;
+
+      fprintf(stderr, "DEBUG: Auto DotRowFeed = %d, modrow=%d...\n",
+              DotRowFeed, modrow);
+    }
+
+    memset(DotBands, 0, sizeof(DotBands));
+
+    for (i = modrow, subrow = modrow - 1, y = DotRowFeed;
+        i > 0;
+        i --, y += DotRowFeed)
+    {
+      while (DotBands[subrow][0])
+      {
+       /*
+        * This subrow is already used, move to another one...
+       */
+
+       subrow = (subrow + 1) % modrow;
+      }
+
+      for (plane = 0; plane < PrinterPlanes; plane ++)
+      {
+       /*
+        * Pull the next available band from the list...
+       */
+
+        band                    = DotAvailList;
+       DotAvailList            = DotAvailList->next;
+       DotBands[subrow][plane] = band;
+
+       /*
+        * Start the band in the first few passes, with the number of rows
+       * varying to allow for a nice interleaved pattern...
+       */
+
+        band->x     = subrow / DotRowStep;
+        band->y     = (subrow % DotRowStep) + DotRowOffset[plane];
+       band->plane = plane;
+       band->row   = 0;
+       band->count = DotRowCount - y / DotRowStep;
+
+        if (band->count < 1)
+         band->count = 1;
+       else if (band->count > DotRowCount)
+         band->count = DotRowCount;
+
+       fprintf(stderr, "DEBUG: DotBands[%d][%d] = %p, x = %d, y = %d, plane = %d, count = %d\n",
+               subrow, plane, band, band->x, band->y, band->plane, band->count);
+      }
+
+      subrow = (subrow + DotRowFeed) % modrow;
+    }
+  }
+  else
+  {
+   /*
+    * Allocate memory for a single line of graphics...
+    */
+
+    ptr = calloc(PrinterPlanes, DotBufferSize);
+
+    for (plane = 0; plane < PrinterPlanes; plane ++, ptr += DotBufferSize)
+      DotBuffers[plane] = ptr;
+  }
+
+ /*
+  * Set the output resolution...
+  */
+
+  cupsWritePrintData("\033(D\004\000", 5);
+  putchar(units);
+  putchar(units >> 8);
+  putchar(units * DotRowStep / header->HWResolution[1]);
+  putchar(units * DotColStep / header->HWResolution[0]);
+
+ /*
+  * Set the top of form...
+  */
+
+  OutputFeed = 0;
+
+ /*
+  * Allocate buffers as needed...
+  */
+
+  PixelBuffer      = malloc(header->cupsBytesPerLine);
+  InputBuffer      = malloc(header->cupsWidth * PrinterPlanes * 2);
+  OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth);
+
+  for (i = 1; i < PrinterPlanes; i ++)
+    OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth;
+
+  if (RGB)
+    CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes);
+
+  CompBuffer = malloc(10 * DotBufferSize * DotRowMax);
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(ppd_file_t         *ppd,       /* I - PPD file */
+        cups_page_header_t *header)    /* I - Page header */
+{
+  int          i;                      /* Looping var */
+  cups_weave_t *band,                  /* Current band */
+               *next;                  /* Next band in list */
+  int          plane;                  /* Current plane */
+  int          subrow;                 /* Current subrow */
+  int          subrows;                /* Number of subrows */
+
+
+ /*
+  * Output the last bands of print data as necessary...
+  */
+
+  if (DotRowMax > 1)
+  {
+   /*
+    * Move the remaining bands to the used or avail lists...
+    */
+
+    subrows = DotRowStep * DotColStep;
+
+    for (subrow = 0; subrow < subrows; subrow ++)
+      for (plane = 0; plane < PrinterPlanes; plane ++)
+      {
+        if (DotBands[subrow][plane]->dirty)
+       {
+        /*
+         * Insert into the used list...
+         */
+
+          DotBands[subrow][plane]->count = DotBands[subrow][plane]->row;
+
+          AddBand(DotBands[subrow][plane]);
+       }
+       else
+       {
+        /*
+         * Nothing here, so move it to the available list...
+         */
+
+         DotBands[subrow][plane]->next = DotAvailList;
+         DotAvailList                  = DotBands[subrow][plane];
+       }
+
+       DotBands[subrow][plane] = NULL;
+      }
+
+   /*
+    * Loop until all bands are written...
+    */
+
+    fputs("DEBUG: Pointer list at end of page...\n", stderr);
+
+    for (band = DotUsedList; band != NULL; band = band->next)
+      fprintf(stderr, "DEBUG: %p (used)\n", band);
+    for (band = DotAvailList; band != NULL; band = band->next)
+      fprintf(stderr, "DEBUG: %p (avail)\n", band);
+
+    fputs("DEBUG: ----END----\n", stderr);
+
+    for (band = DotUsedList; band != NULL; band = next)
+    {
+      next = band->next;
+
+      OutputBand(ppd, header, band);
+
+      fprintf(stderr, "DEBUG: freeing used band %p, prev = %p, next = %p\n",
+              band, band->prev, band->next);
+
+      free(band->buffer);
+      free(band);
+    }
+
+   /*
+    * Free memory for the available bands, if any...
+    */
+
+    for (band = DotAvailList; band != NULL; band = next)
+    {
+      next = band->next;
+
+      fprintf(stderr, "DEBUG: freeing avail band %p, prev = %p,  next = %p\n",
+              band, band->prev, band->next);
+
+      free(band->buffer);
+      free(band);
+    }
+  }
+  else
+    free(DotBuffers[0]);
+
+ /*
+  * Output a page eject sequence...
+  */
+
+  putchar(12);
+
+ /*
+  * Free memory for the page...
+  */
+
+  for (i = 0; i < PrinterPlanes; i ++)
+  {
+    cupsDitherDelete(DitherStates[i]);
+    cupsLutDelete(DitherLuts[i]);
+  }
+
+  free(OutputBuffers[0]);
+
+  free(PixelBuffer);
+  free(InputBuffer);
+  free(CompBuffer);
+
+  cupsCMYKDelete(CMYK);
+
+  if (RGB)
+  {
+    cupsRGBDelete(RGB);
+    free(CMYKBuffer);
+  }
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown a printer.
+ */
+
+void
+Shutdown(ppd_file_t *ppd)              /* I - PPD file */
+{
+ /*
+  * Reset the printer...
+  */
+
+  printf("\033@");
+
+  if (ppd->model_number & ESCP_REMOTE)
+  {
+   /*
+    * Go into remote mode...
+    */
+
+    cupsWritePrintData("\033(R\010\000\000REMOTE1", 13);
+
+   /*
+    * Load defaults...
+    */
+
+    cupsWritePrintData("LD\000\000", 4);
+
+   /*
+    * Exit remote mode...
+    */
+
+    cupsWritePrintData("\033\000\000\000", 4);
+  }
+}
+
+
+/*
+ * 'AddBand()' - Add a band of data to the used list.
+ */
+
+void
+AddBand(cups_weave_t *band)                    /* I - Band to add */
+{
+  cups_weave_t *current,                       /* Current band */
+               *prev;                          /* Previous band */
+
+
+  if (band->count < 1)
+    return;
+
+  for (current = DotUsedList, prev = NULL;
+       current != NULL;
+       prev = current, current = current->next)
+    if (band->y < current->y ||
+        (band->y == current->y && band->x < current->x) ||
+       (band->y == current->y && band->x == current->x &&
+        band->plane < current->plane))
+      break;
+
+  if (current != NULL)
+  {
+   /*
+    * Insert the band...
+    */
+
+    band->next    = current;
+    band->prev    = prev;
+    current->prev = band;
+
+    if (prev != NULL)
+      prev->next = band;
+    else
+      DotUsedList = band;
+  }
+  else if (prev != NULL)
+  {
+   /*
+    * Append the band to the end...
+    */
+
+    band->prev = prev;
+    prev->next = band;
+    band->next = NULL;
+  }
+  else
+  {
+   /*
+    * First band in list...
+    */
+
+    DotUsedList = band;
+    band->prev  = NULL;
+    band->next  = NULL;
+  }
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(ppd_file_t          *ppd, /* I - PPD file information */
+             const unsigned char *line,        /* I - Data to compress */
+             const int           length,/* I - Number of bytes */
+            int                 plane, /* I - Color plane */
+            int                 type,  /* I - Type of compression */
+            const int           rows,  /* I - Number of lines to write */
+            const int           xstep, /* I - Spacing between columns */
+            const int           ystep, /* I - Spacing between lines */
+            const int           offset)/* I - Head offset */
+{
+  register const unsigned char *line_ptr,
+                                       /* Current byte pointer */
+               *line_end,              /* End-of-line byte pointer */
+               *start;                 /* Start of compression sequence */
+  register unsigned char *comp_ptr;    /* Pointer into compression buffer */
+  register int  count;                 /* Count of bytes for output */
+  register int bytes;                  /* Number of bytes per row */
+  static int   ctable[7][7] =          /* Colors */
+               {
+                 {  0,  0,  0,  0,  0,  0,  0 },       /* K */
+                 {  0, 16,  0,  0,  0,  0,  0 },       /* Kk */
+                 {  2,  1,  4,  0,  0,  0,  0 },       /* CMY */
+                 {  2,  1,  4,  0,  0,  0,  0 },       /* CMYK */
+                 {  0,  0,  0,  0,  0,  0,  0 },
+                 {  2, 18,  1, 17,  4,  0,  0 },       /* CcMmYK */
+                 {  2, 18,  1, 17,  4,  0, 16 },       /* CcMmYKk */
+               };
+
+
+  switch (type)
+  {
+    case 0 :
+       /*
+       * Do no compression...
+       */
+
+       line_ptr = (const unsigned char *)line;
+       line_end = (const unsigned char *)line + length;
+       break;
+
+    default :
+       /*
+        * Do TIFF pack-bits encoding...
+        */
+
+       line_ptr = (const unsigned char *)line;
+       line_end = (const unsigned char *)line + length;
+       comp_ptr = CompBuffer;
+
+       while (line_ptr < line_end && (comp_ptr - CompBuffer) < length)
+       {
+         if ((line_ptr + 1) >= line_end)
+         {
+          /*
+           * Single byte on the end...
+           */
+
+           *comp_ptr++ = 0x00;
+           *comp_ptr++ = *line_ptr++;
+         }
+         else if (line_ptr[0] == line_ptr[1])
+         {
+          /*
+           * Repeated sequence...
+           */
+
+           line_ptr ++;
+           count = 2;
+
+           while (line_ptr < (line_end - 1) &&
+                  line_ptr[0] == line_ptr[1] &&
+                  count < 127)
+           {
+              line_ptr ++;
+              count ++;
+           }
+
+           *comp_ptr++ = 257 - count;
+           *comp_ptr++ = *line_ptr++;
+         }
+         else
+         {
+          /*
+           * Non-repeated sequence...
+           */
+
+           start    = line_ptr;
+           line_ptr ++;
+           count    = 1;
+
+           while (line_ptr < (line_end - 1) &&
+                  line_ptr[0] != line_ptr[1] &&
+                  count < 127)
+           {
+              line_ptr ++;
+              count ++;
+           }
+
+           *comp_ptr++ = count - 1;
+
+           memcpy(comp_ptr, start, count);
+           comp_ptr += count;
+         }
+       }
+
+        if ((comp_ptr - CompBuffer) < length)
+       {
+          line_ptr = (const unsigned char *)CompBuffer;
+          line_end = (const unsigned char *)comp_ptr;
+       }
+       else
+       {
+         type     = 0;
+         line_ptr = (const unsigned char *)line;
+         line_end = (const unsigned char *)line + length;
+       }
+       break;
+  }
+
+ /*
+  * Position the print head...
+  */
+
+  putchar(0x0d);
+
+  if (offset)
+  {
+    if (BitPlanes == 1)
+      cupsWritePrintData("\033(\\\004\000\240\005", 7);
+    else
+      printf("\033\\");
+
+    putchar(offset);
+    putchar(offset >> 8);
+  }
+
+ /*
+  * Send the graphics...
+  */
+
+  bytes = length / rows;
+
+  if (ppd->model_number & ESCP_RASTER_ESCI)
+  {
+   /*
+    * Send graphics with ESC i command.
+    */
+
+    printf("\033i");
+    putchar(ctable[PrinterPlanes - 1][plane]);
+    putchar(type != 0);
+    putchar(BitPlanes);
+    putchar(bytes & 255);
+    putchar(bytes >> 8);
+    putchar(rows & 255);
+    putchar(rows >> 8);
+  }
+  else
+  {
+   /*
+    * Set the color if necessary...
+    */
+
+    if (PrinterPlanes > 1)
+    {
+      plane = ctable[PrinterPlanes - 1][plane];
+
+      if (plane & 0x10)
+       printf("\033(r%c%c%c%c", 2, 0, 1, plane & 0x0f);
+      else
+       printf("\033r%c", plane);
+    }
+
+   /*
+    * Send graphics with ESC . command.
+    */
+
+    bytes *= 8;
+
+    printf("\033.");
+    putchar(type != 0);
+    putchar(ystep);
+    putchar(xstep);
+    putchar(rows);
+    putchar(bytes & 255);
+    putchar(bytes >> 8);
+  }
+
+  cupsWritePrintData(line_ptr, line_end - line_ptr);
+}
+
+
+/*
+ * 'OutputBand()' - Output a band of graphics.
+ */
+
+void
+OutputBand(ppd_file_t         *ppd,    /* I - PPD file */
+           cups_page_header_t *header, /* I - Page header */
+           cups_weave_t       *band)   /* I - Current band */
+{
+  int  xstep,                          /* Spacing between columns */
+       ystep;                          /* Spacing between rows */
+
+
+ /*
+  * Interleaved ESC/P2 graphics...
+  */
+
+  OutputFeed    = band->y - DotRowCurrent;
+  DotRowCurrent = band->y;
+
+  fprintf(stderr, "DEBUG: Printing band %p, x = %d, y = %d, plane = %d, count = %d, OutputFeed = %d\n",
+          band, band->x, band->y, band->plane, band->count, OutputFeed);
+
+ /*
+  * Compute step values...
+  */
+
+  xstep = 3600 * DotColStep / header->HWResolution[0];
+  ystep = 3600 * DotRowStep / header->HWResolution[1];
+
+ /*
+  * Output the band...
+  */
+
+  if (OutputFeed > 0)
+  {
+    cupsWritePrintData("\033(v\002\000", 5);
+    putchar(OutputFeed & 255);
+    putchar(OutputFeed >> 8);
+
+    OutputFeed = 0;
+  }
+
+  CompressData(ppd, band->buffer, band->count * DotBufferSize, band->plane,
+              header->cupsCompression, band->count, xstep, ystep, band->x);
+
+ /*
+  * Clear the band...
+  */
+
+  memset(band->buffer, 0, band->count * DotBufferSize);
+  band->dirty = 0;
+
+ /*
+  * Flush the output buffers...
+  */
+
+  fflush(stdout);
+}
+
+
+/*
+ * 'ProcessLine()' - Read graphics from the page stream and output as needed.
+ */
+
+void
+ProcessLine(ppd_file_t         *ppd,   /* I - PPD file */
+            cups_raster_t      *ras,   /* I - Raster stream */
+            cups_page_header_t *header,        /* I - Page header */
+            const int          y)      /* I - Current scanline */
+{
+  int          plane,                  /* Current color plane */
+               width,                  /* Width of line */
+               subwidth,               /* Width of interleaved row */
+               subrow,                 /* Subrow for interleaved output */
+               offset,                 /* Offset to current line */
+               pass,                   /* Pass number */
+               xstep,                  /* X step value */
+               ystep;                  /* Y step value */
+  cups_weave_t *band;                  /* Current band */
+
+
+ /*
+  * Read a row of graphics...
+  */
+
+  if (!cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine))
+    return;
+
+ /*
+  * Perform the color separation...
+  */
+
+  offset   = 0;
+  width    = header->cupsWidth;
+  subwidth = header->cupsWidth / DotColStep;
+  xstep    = 3600 / header->HWResolution[0];
+  ystep    = 3600 / header->HWResolution[1];
+
+  switch (header->cupsColorSpace)
+  {
+    case CUPS_CSPACE_W :
+        if (RGB)
+       {
+         cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width);
+         cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+       }
+       else
+          cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    case CUPS_CSPACE_K :
+        cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    default :
+    case CUPS_CSPACE_RGB :
+        if (RGB)
+       {
+         cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width);
+         cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+       }
+       else
+          cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    case CUPS_CSPACE_CMYK :
+        cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+  }
+
+ /*
+  * Dither the pixels...
+  */
+
+  for (plane = 0; plane < PrinterPlanes; plane ++)
+  {
+    cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane,
+                   PrinterPlanes, OutputBuffers[plane]);
+
+    if (DotRowMax == 1)
+    {
+     /*
+      * Handle microweaved output...
+      */
+
+      if (cupsCheckBytes(OutputBuffers[plane], width))
+       continue;
+
+      if (BitPlanes == 1)
+       cupsPackHorizontal(OutputBuffers[plane], DotBuffers[plane],
+                          width, 0, 1);
+      else
+       cupsPackHorizontal2(OutputBuffers[plane], DotBuffers[plane],
+                           width, 1);
+
+      if (OutputFeed > 0)
+      {
+       cupsWritePrintData("\033(v\002\000", 5);
+       putchar(OutputFeed & 255);
+       putchar(OutputFeed >> 8);
+       OutputFeed = 0;
+      }
+
+      CompressData(ppd, DotBuffers[plane], DotBufferSize, plane, 1, 1,
+                   xstep, ystep, 0);
+      fflush(stdout);
+    }
+    else
+    {
+     /*
+      * Handle softweaved output...
+      */
+
+      for (pass = 0, subrow = y % DotRowStep;
+           pass < DotColStep;
+          pass ++, subrow += DotRowStep)
+      {
+       /*
+       * See if we need to output the band...
+       */
+
+        band   = DotBands[subrow][plane];
+       offset = band->row * DotBufferSize;
+
+        if (BitPlanes == 1)
+         cupsPackHorizontal(OutputBuffers[plane] + pass,
+                            band->buffer + offset, subwidth, 0, DotColStep);
+        else
+         cupsPackHorizontal2(OutputBuffers[plane] + pass,
+                             band->buffer + offset, subwidth, DotColStep);
+
+        band->row ++;
+       band->dirty |= !cupsCheckBytes(band->buffer + offset, DotBufferSize);
+       if (band->row >= band->count)
+       {
+         if (band->dirty)
+         {
+          /*
+           * Dirty band needs to be added to the used list...
+           */
+
+           AddBand(band);
+
+           /*
+           * Then find a new band...
+           */
+
+           if (DotAvailList == NULL)
+           {
+             OutputBand(ppd, header, DotUsedList);
+
+             DotBands[subrow][plane] = DotUsedList;
+             DotUsedList->x          = band->x;
+             DotUsedList->y          = band->y + band->count * DotRowStep;
+             DotUsedList->plane      = band->plane;
+             DotUsedList->row        = 0;
+             DotUsedList->count      = DotRowCount;
+             DotUsedList             = DotUsedList->next;
+           }
+           else
+           {
+             DotBands[subrow][plane] = DotAvailList;
+             DotAvailList->x         = band->x;
+             DotAvailList->y         = band->y + band->count * DotRowStep;
+             DotAvailList->plane     = band->plane;
+             DotAvailList->row       = 0;
+             DotAvailList->count     = DotRowCount;
+             DotAvailList            = DotAvailList->next;
+           }
+         }
+         else
+         {
+          /*
+           * This band isn't dirty, so reuse it...
+           */
+
+            fprintf(stderr, "DEBUG: Blank band %p, x = %d, y = %d, plane = %d, count = %d\n",
+                   band, band->x, band->y, band->plane, band->count);
+
+           band->y     += band->count * DotRowStep;
+           band->row   = 0;
+           band->count = DotRowCount;
+         }
+        }
+      }
+    }
+  }
+
+  if (DotRowMax == 1)
+    OutputFeed ++;
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int                                    /* O - Exit status */
+main(int  argc,                                /* I - Number of command-line arguments */
+     char *argv[])                     /* I - Command-line arguments */
+{
+  int                  fd;             /* File descriptor */
+  cups_raster_t                *ras;           /* Raster stream for printing */
+  cups_page_header_t   header;         /* Page header from file */
+  int                  page;           /* Current page */
+  int                  y;              /* Current line */
+  ppd_file_t           *ppd;           /* PPD file */
+  int                  num_options;    /* Number of options */
+  cups_option_t                *options;       /* Options */
+
+
+ /*
+  * Make sure status messages are not buffered...
+  */
+
+  setbuf(stderr, NULL);
+
+ /*
+  * Check command-line...
+  */
+
+  if (argc < 6 || argc > 7)
+  {
+    fputs("ERROR: rastertoescpx job-id user title copies options [file]\n", stderr);
+    return (1);
+  }
+
+  num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+  * Open the PPD file...
+  */
+
+  ppd = ppdOpenFile(getenv("PPD"));
+
+  if (!ppd)
+  {
+    fputs("ERROR: Unable to open PPD file!\n", stderr);
+    return (1);
+  }
+
+  ppdMarkDefaults(ppd);
+  cupsMarkOptions(ppd, num_options, options);
+
+ /*
+  * Open the page stream...
+  */
+
+  if (argc == 7)
+  {
+    if ((fd = open(argv[6], O_RDONLY)) == -1)
+    {
+      perror("ERROR: Unable to open raster file - ");
+      return (1);
+    }
+  }
+  else
+    fd = 0;
+
+  ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+  * Initialize the print device...
+  */
+
+  Setup(ppd);
+
+ /*
+  * Process pages as needed...
+  */
+
+  page = 0;
+
+  while (cupsRasterReadHeader(ras, &header))
+  {
+    page ++;
+
+    fprintf(stderr, "PAGE: %d 1\n", page);
+    fprintf(stderr, "INFO: Starting page %d...\n", page);
+
+    StartPage(ppd, &header);
+
+    for (y = 0; y < header.cupsHeight; y ++)
+    {
+      if ((y & 127) == 0)
+        fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page,
+               100 * y / header.cupsHeight);
+
+      ProcessLine(ppd, ras, &header, y);
+    }
+
+    fprintf(stderr, "INFO: Finished page %d...\n", page);
+
+    EndPage(ppd, &header);
+  }
+
+  Shutdown(ppd);
+
+  cupsFreeOptions(num_options, options);
+
+  cupsRasterClose(ras);
+
+  if (fd != 0)
+    close(fd);
+
+  if (page == 0)
+  {
+    fputs("ERROR: No pages found!\n", stderr);
+    return (1);
+  }
+  else
+  {
+    fputs("INFO: Ready to print.\n", stderr);
+    return (0);
+  }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/rastertopclx.c b/driver/rastertopclx.c
new file mode 100644 (file)
index 0000000..9c50974
--- /dev/null
@@ -0,0 +1,1875 @@
+/*
+ * "$Id$"
+ *
+ *   Advanced HP Page Control Language and Raster Transfer Language
+ *   filter for CUPS.
+ *
+ *   Copyright 2007-2008 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   Setup()        - Prepare a printer for graphics output.
+ *   StartPage()    - Start a page of graphics.
+ *   EndPage()      - Finish a page of graphics.
+ *   Shutdown()     - Shutdown a printer.
+ *   CompressData() - Compress a line of graphics.
+ *   OutputLine()   - Output the specified number of lines of graphics.
+ *   ReadLine()     - Read graphics from the page stream.
+ *   main()         - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "driver.h"
+#include "pcl-common.h"
+
+
+/*
+ * Output modes...
+ */
+
+typedef enum
+{
+  OUTPUT_BITMAP,                       /* Output bitmap data from RIP */
+  OUTPUT_INVERBIT,                     /* Output inverted bitmap data */
+  OUTPUT_RGB,                          /* Output 24-bit RGB data from RIP */
+  OUTPUT_DITHERED                      /* Output dithered data */
+} pcl_output_t;
+
+
+/*
+ * Globals...
+ */
+
+cups_rgb_t     *RGB;                   /* RGB color separation data */
+cups_cmyk_t    *CMYK;                  /* CMYK color separation data */
+unsigned char  *PixelBuffer,           /* Pixel buffer */
+               *CMYKBuffer,            /* CMYK buffer */
+               *OutputBuffers[6],      /* Output buffers */
+               *DotBuffers[6],         /* Bit buffers */
+               *CompBuffer,            /* Compression buffer */
+               *SeedBuffer,            /* Mode 3 seed buffers */
+               BlankValue;             /* The blank value */
+short          *InputBuffer;           /* Color separation buffer */
+cups_lut_t     *DitherLuts[6];         /* Lookup tables for dithering */
+cups_dither_t  *DitherStates[6];       /* Dither state tables */
+int            PrinterPlanes,          /* Number of color planes */
+               SeedInvalid,            /* Contents of seed buffer invalid? */
+               DotBits[6],             /* Number of bits per color */
+               DotBufferSizes[6],      /* Size of one row of color dots */
+               DotBufferSize,          /* Size of complete line */
+               OutputFeed,             /* Number of lines to skip */
+               Page;                   /* Current page number */
+pcl_output_t   OutputMode;             /* Output mode - see OUTPUT_ consts */
+const int      ColorOrders[7][7] =     /* Order of color planes */
+               {
+                 { 0, 0, 0, 0, 0, 0, 0 },      /* Black */
+                 { 0, 0, 0, 0, 0, 0, 0 },
+                 { 0, 1, 2, 0, 0, 0, 0 },      /* CMY */
+                 { 3, 0, 1, 2, 0, 0, 0 },      /* KCMY */
+                 { 0, 0, 0, 0, 0, 0, 0 },
+                 { 5, 0, 1, 2, 3, 4, 0 },      /* KCMYcm */
+                 { 5, 0, 1, 2, 3, 4, 6 }       /* KCMYcmk */
+               };
+
+
+/*
+ * Prototypes...
+ */
+
+void   StartPage(ppd_file_t *ppd, cups_page_header_t *header, int job_id,
+                 const char *user, const char *title, int num_options,
+                 cups_option_t *options);
+void   EndPage(ppd_file_t *ppd, cups_page_header_t *header);
+void   Shutdown(ppd_file_t *ppd, int job_id, const char *user,
+                const char *title, int num_options, cups_option_t *options);
+
+void   CompressData(unsigned char *line, int length, int plane, int pend,
+                    int type);
+void   OutputLine(ppd_file_t *ppd, cups_page_header_t *header);
+int    ReadLine(cups_raster_t *ras, cups_page_header_t *header);
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(ppd_file_t         *ppd,     /* I - PPD file */
+          cups_page_header_t *header,  /* I - Page header */
+         int                job_id,    /* I - Job ID */
+         const char         *user,     /* I - User printing job */
+         const char         *title,    /* I - Title of job */
+         int                num_options,
+                                       /* I - Number of command-line options */
+         cups_option_t      *options)  /* I - Command-line options */
+{
+  int          i;                      /* Temporary/looping var */
+  int          plane;                  /* Current plane */
+  char         s[255];                 /* Temporary value */
+  const char   *colormodel;            /* Color model string */
+  char         resolution[PPD_MAX_NAME],
+                                       /* Resolution string */
+               spec[PPD_MAX_NAME];     /* PPD attribute name */
+  ppd_attr_t   *attr;                  /* Attribute from PPD file */
+  ppd_choice_t *choice;                /* Selected option */
+  const int    *order;                 /* Order to use */
+  int          xorigin,                /* X origin of page */
+               yorigin;                /* Y origin of page */
+  static const float default_lut[2] =  /* Default dithering lookup table */
+               {
+                 0.0,
+                 1.0
+               };
+
+
+ /*
+  * Debug info...
+  */
+
+  fprintf(stderr, "DEBUG: StartPage...\n");
+  fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass);
+  fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor);
+  fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType);
+  fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType);
+
+  fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance);
+  fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia);
+  fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate);
+  fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia);
+  fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex);
+  fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0],
+          header->HWResolution[1]);
+  fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n",
+          header->ImagingBoundingBox[0], header->ImagingBoundingBox[1],
+          header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]);
+  fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet);
+  fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog);
+  fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge);
+  fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0],
+          header->Margins[1]);
+  fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed);
+  fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition);
+  fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight);
+  fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint);
+  fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint);
+  fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies);
+  fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation);
+  fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp);
+  fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0],
+          header->PageSize[1]);
+  fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations);
+  fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch);
+  fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble);
+  fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth);
+  fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight);
+  fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType);
+  fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header->cupsBitsPerColor);
+  fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header->cupsBitsPerPixel);
+  fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header->cupsBytesPerLine);
+  fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder);
+  fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace);
+  fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression);
+
+#ifdef __APPLE__
+ /*
+  * MacOS X 10.2.x doesn't set most of the page device attributes, so check
+  * the options and set them accordingly...
+  */
+
+  if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble"))
+  {
+    header->Duplex = CUPS_TRUE;
+    header->Tumble = CUPS_FALSE;
+  }
+  else if (ppdIsMarked(ppd, "Duplex", "DuplexTumble"))
+  {
+    header->Duplex = CUPS_TRUE;
+    header->Tumble = CUPS_TRUE;
+  }
+
+  fprintf(stderr, "DEBUG: num_options=%d\n", num_options);
+
+  for (i = 0; i < num_options; i ++)
+    fprintf(stderr, "DEBUG: options[%d]=[\"%s\" \"%s\"]\n", i,
+            options[i].name, options[i].value);
+#endif /* __APPLE__ */
+
+ /*
+  * Figure out the color model and spec strings...
+  */
+
+  switch (header->cupsColorSpace)
+  {
+    case CUPS_CSPACE_K :
+        colormodel = "Black";
+       break;
+    case CUPS_CSPACE_W :
+        colormodel = "Gray";
+       break;
+    default :
+    case CUPS_CSPACE_RGB :
+        colormodel = "RGB";
+       break;
+    case CUPS_CSPACE_CMY :
+        colormodel = "CMY";
+       break;
+    case CUPS_CSPACE_CMYK :
+        colormodel = "CMYK";
+       break;
+  }
+
+  if (header->HWResolution[0] != header->HWResolution[1])
+    snprintf(resolution, sizeof(resolution), "%dx%ddpi",
+             header->HWResolution[0], header->HWResolution[1]);
+  else
+    snprintf(resolution, sizeof(resolution), "%ddpi",
+             header->HWResolution[0]);
+
+  if (!header->MediaType[0])
+    strcpy(header->MediaType, "PLAIN");
+
+ /*
+  * Get the dithering parameters...
+  */
+
+  BlankValue = 0x00;
+
+  if (header->cupsBitsPerColor == 1)
+  {
+   /*
+    * Use raw bitmap mode...
+    */
+
+    switch (header->cupsColorSpace)
+    {
+      case CUPS_CSPACE_K :
+          OutputMode    = OUTPUT_BITMAP;
+         PrinterPlanes = 1;
+         break;
+      case CUPS_CSPACE_W :
+          OutputMode    = OUTPUT_INVERBIT;
+         PrinterPlanes = 1;
+         break;
+      default :
+      case CUPS_CSPACE_RGB :
+          OutputMode    = OUTPUT_INVERBIT;
+         PrinterPlanes = 3;
+         break;
+      case CUPS_CSPACE_CMY :
+          OutputMode    = OUTPUT_BITMAP;
+         PrinterPlanes = 3;
+         break;
+      case CUPS_CSPACE_CMYK :
+          OutputMode    = OUTPUT_BITMAP;
+         PrinterPlanes = 4;
+         break;
+    }
+
+    if (OutputMode == OUTPUT_INVERBIT)
+      BlankValue = 0xff;
+
+    DotBufferSize = header->cupsBytesPerLine;
+
+    memset(DitherLuts, 0, sizeof(DitherLuts));
+    memset(DitherStates, 0, sizeof(DitherStates));
+  }
+  else if (header->cupsColorSpace == CUPS_CSPACE_RGB &&
+           (ppd->model_number & PCL_RASTER_RGB24))
+  {
+   /*
+    * Use 24-bit RGB output mode...
+    */
+
+    OutputMode    = OUTPUT_RGB;
+    PrinterPlanes = 3;
+    DotBufferSize = header->cupsBytesPerLine;
+
+    if (header->cupsCompression == 10)
+      BlankValue = 0xff;
+
+    memset(DitherLuts, 0, sizeof(DitherLuts));
+    memset(DitherStates, 0, sizeof(DitherStates));
+  }
+  else if ((header->cupsColorSpace == CUPS_CSPACE_K ||
+            header->cupsColorSpace == CUPS_CSPACE_W) &&
+           (ppd->model_number & PCL_RASTER_RGB24) &&
+          header->cupsCompression == 10)
+  {
+   /*
+    * Use 24-bit RGB output mode for grayscale/black output...
+    */
+
+    OutputMode    = OUTPUT_RGB;
+    PrinterPlanes = 1;
+    DotBufferSize = header->cupsBytesPerLine;
+
+    if (header->cupsColorSpace == CUPS_CSPACE_W)
+      BlankValue = 0xff;
+
+    memset(DitherLuts, 0, sizeof(DitherLuts));
+    memset(DitherStates, 0, sizeof(DitherStates));
+  }
+  else
+  {
+   /*
+    * Use dithered output mode...
+    */
+
+    OutputMode = OUTPUT_DITHERED;
+
+   /*
+    * Load the appropriate color profiles...
+    */
+
+    RGB  = NULL;
+    CMYK = NULL;
+
+    fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr);
+    fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel);
+    fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType);
+    fprintf(stderr, "DEBUG: Resolution = %s\n", resolution);
+
+    if (header->cupsColorSpace == CUPS_CSPACE_RGB ||
+       header->cupsColorSpace == CUPS_CSPACE_W)
+      RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution);
+
+    CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution);
+
+    if (RGB)
+      fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr);
+
+    if (CMYK)
+      fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr);
+    else
+    {
+      fputs("DEBUG: Loading default K separation.\n", stderr);
+      CMYK = cupsCMYKNew(1);
+    }
+
+    PrinterPlanes = CMYK->num_channels;
+
+   /*
+    * Use dithered mode...
+    */
+
+    switch (PrinterPlanes)
+    {
+      case 1 : /* K */
+          DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Black");
+          break;
+
+      case 3 : /* CMY */
+          DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Cyan");
+          DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Magenta");
+          DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Yellow");
+          break;
+
+      case 4 : /* CMYK */
+          DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Cyan");
+          DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Magenta");
+          DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Yellow");
+          DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Black");
+          break;
+
+      case 6 : /* CcMmYK */
+          DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Cyan");
+          DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "LightCyan");
+          DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Magenta");
+          DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "LightMagenta");
+          DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Yellow");
+          DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType,
+                                     resolution, "Black");
+          break;
+    }
+
+    for (plane = 0; plane < PrinterPlanes; plane ++)
+    {
+      if (!DitherLuts[plane])
+        DitherLuts[plane] = cupsLutNew(2, default_lut);
+
+      if (DitherLuts[plane][4095].pixel > 1)
+       DotBits[plane] = 2;
+      else
+       DotBits[plane] = 1;
+
+      DitherStates[plane] = cupsDitherNew(header->cupsWidth);
+
+      if (!DitherLuts[plane])
+       DitherLuts[plane] = cupsLutNew(2, default_lut);
+    }
+  }
+
+  fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes);
+
+ /*
+  * Initialize the printer...
+  */
+
+  if ((attr = ppdFindAttr(ppd, "cupsInitialNulls", NULL)) != NULL)
+    for (i = atoi(attr->value); i > 0; i --)
+      putchar(0);
+
+  if (Page == 1 && (ppd->model_number & PCL_PJL))
+  {
+    pjl_escape();
+
+   /*
+    * PJL job setup...
+    */
+
+    pjl_set_job(job_id, user, title);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "StartJob")) != NULL)
+      pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options,
+                options);
+
+    snprintf(spec, sizeof(spec), "RENDERMODE.%s", colormodel);
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL)
+      printf("@PJL SET RENDERMODE=%s\r\n", attr->value);
+
+    snprintf(spec, sizeof(spec), "COLORSPACE.%s", colormodel);
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL)
+      printf("@PJL SET COLORSPACE=%s\r\n", attr->value);
+
+    snprintf(spec, sizeof(spec), "RENDERINTENT.%s", colormodel);
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL)
+      printf("@PJL SET RENDERINTENT=%s\r\n", attr->value);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "Duplex")) != NULL)
+    {
+      sprintf(s, "%d", header->Duplex);
+      pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options);
+    }
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "Tumble")) != NULL)
+    {
+      sprintf(s, "%d", header->Tumble);
+      pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options);
+    }
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaClass")) != NULL)
+      pjl_write(ppd, attr->value, header->MediaClass, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaColor")) != NULL)
+      pjl_write(ppd, attr->value, header->MediaColor, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaType")) != NULL)
+      pjl_write(ppd, attr->value, header->MediaType, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "OutputType")) != NULL)
+      pjl_write(ppd, attr->value, header->OutputType, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsBooklet")) != NULL &&
+        (choice = ppdFindMarkedChoice(ppd, "cupsBooklet")) != NULL)
+      pjl_write(ppd, attr->value, choice->choice, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "Jog")) != NULL)
+    {
+      sprintf(s, "%d", header->Jog);
+      pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options);
+    }
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsPunch")) != NULL &&
+        (choice = ppdFindMarkedChoice(ppd, "cupsPunch")) != NULL)
+      pjl_write(ppd, attr->value, choice->choice, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsStaple")) != NULL &&
+        (choice = ppdFindMarkedChoice(ppd, "cupsStaple")) != NULL)
+      pjl_write(ppd, attr->value, choice->choice, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsRET")) != NULL &&
+        (choice = ppdFindMarkedChoice(ppd, "cupsRET")) != NULL)
+      pjl_write(ppd, attr->value, choice->choice, job_id, user, title,
+                num_options, options);
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsTonerSave")) != NULL &&
+        (choice = ppdFindMarkedChoice(ppd, "cupsTonerSave")) != NULL)
+      pjl_write(ppd, attr->value, choice->choice, job_id, user, title,
+                num_options, options);
+
+    if (ppd->model_number & PCL_PJL_PAPERWIDTH)
+    {
+      printf("@PJL SET PAPERLENGTH=%d\r\n", header->PageSize[1] * 10);
+      printf("@PJL SET PAPERWIDTH=%d\r\n", header->PageSize[0] * 10);
+    }
+
+    if (ppd->model_number & PCL_PJL_RESOLUTION)
+      printf("@PJL SET RESOLUTION=%d\r\n", header->HWResolution[0]);
+
+    if (ppd->model_number & PCL_PJL_HPGL2)
+      pjl_enter_language("HPGL2");
+    else if (ppd->model_number & PCL_PJL_PCL3GUI)
+      pjl_enter_language("PCL3GUI");
+    else
+      pjl_enter_language("PCL");
+  }
+
+  if (Page == 1)
+  {
+    pcl_reset();
+  }
+
+  if (ppd->model_number & PCL_PJL_HPGL2)
+  {
+    if (Page == 1)
+    {
+     /*
+      * HP-GL/2 initialization...
+      */
+
+      printf("IN;");
+      printf("MG\"%d %s %s\";", job_id, user, title);
+    }
+
+   /*
+    * Set media size, position, type, etc...
+    */
+
+    printf("BP5,0;");
+    printf("PS%.0f,%.0f;",
+          header->cupsHeight * 1016.0 / header->HWResolution[1],
+          header->cupsWidth * 1016.0 / header->HWResolution[0]);
+    printf("PU;");
+    printf("PA0,0");
+
+    printf("MT%d;", header->cupsMediaType);
+
+    if (header->CutMedia == CUPS_CUT_PAGE)
+      printf("EC;");
+    else
+      printf("EC0;");
+
+   /*
+    * Set graphics mode...
+    */
+
+    pcl_set_pcl_mode(0);
+    pcl_set_negative_motion();
+  }
+  else
+  {
+   /*
+    * Set media size, position, type, etc...
+    */
+
+    if (!header->Duplex || (Page & 1))
+    {
+      pcl_set_media_size(ppd, header->PageSize[0], header->PageSize[1]);
+
+      if (header->MediaPosition)
+        pcl_set_media_source(header->MediaPosition);
+
+      pcl_set_media_type(header->cupsMediaType);
+
+      if (ppdFindAttr(ppd, "cupsPJL", "Duplex") == NULL)
+        pcl_set_duplex(header->Duplex, header->Tumble);
+
+     /*
+      * Set the number of copies...
+      */
+
+      if (!ppd->manual_copies)
+       pcl_set_copies(header->NumCopies);
+
+     /*
+      * Set the output order/bin...
+      */
+
+      if (ppdFindAttr(ppd, "cupsPJL", "Jog") == NULL && header->Jog)
+        printf("\033&l%dG", header->Jog);
+    }
+    else
+    {
+     /*
+      * Print on the back side...
+      */
+
+      printf("\033&a2G");
+    }
+
+    if (header->Duplex && (ppd->model_number & PCL_RASTER_CRD))
+    {
+     /*
+      * Reload the media...
+      */
+
+      pcl_set_media_source(-2);
+    }
+
+   /*
+    * Set the units for cursor positioning and go to the top of the form.
+    */
+
+    printf("\033&u%dD", header->HWResolution[0]);
+    printf("\033*p0Y\033*p0X");
+  }
+
+  if ((attr = cupsFindAttr(ppd, "cupsPCLQuality", colormodel,
+                           header->MediaType, resolution, spec,
+                          sizeof(spec))) != NULL)
+  {
+   /*
+    * Set the print quality...
+    */
+
+    if (ppd->model_number & PCL_PJL_HPGL2)
+      printf("QM%d", atoi(attr->value));
+    else
+      printf("\033*o%dM", atoi(attr->value));
+  }
+
+ /*
+  * Enter graphics mode...
+  */
+
+  if (ppd->model_number & PCL_RASTER_CRD)
+  {
+   /*
+    * Use configure raster data command...
+    */
+
+    if (OutputMode == OUTPUT_RGB)
+    {
+     /*
+      * Send 12-byte configure raster data command with horizontal and
+      * vertical resolutions as well as a color count...
+      */
+
+      if ((attr = cupsFindAttr(ppd, "cupsPCLCRDMode", colormodel,
+                               header->MediaType, resolution, spec,
+                              sizeof(spec))) != NULL)
+        i = atoi(attr->value);
+      else
+        i = 31;
+
+      printf("\033*g12W");
+      putchar(6);                      /* Format 6 */
+      putchar(i);                      /* Set pen mode */
+      putchar(0x00);                   /* Number components */
+      putchar(0x01);                   /* (1 for RGB) */
+
+      putchar(header->HWResolution[0] >> 8);
+      putchar(header->HWResolution[0]);
+      putchar(header->HWResolution[1] >> 8);
+      putchar(header->HWResolution[1]);
+
+      putchar(header->cupsCompression);        /* Compression mode 3 or 10 */
+      putchar(0x01);                   /* Portrait orientation */
+      putchar(0x20);                   /* Bits per pixel (32 = RGB) */
+      putchar(0x01);                   /* Planes per pixel (1 = chunky RGB) */
+    }
+    else
+    {
+     /*
+      * Send the configure raster data command with horizontal and
+      * vertical resolutions as well as a color count...
+      */
+
+      printf("\033*g%dW", PrinterPlanes * 6 + 2);
+      putchar(2);                      /* Format 2 */
+      putchar(PrinterPlanes);          /* Output planes */
+
+      order = ColorOrders[PrinterPlanes - 1];
+
+      for (i = 0; i < PrinterPlanes; i ++)
+      {
+        plane = order[i];
+
+       putchar(header->HWResolution[0] >> 8);
+       putchar(header->HWResolution[0]);
+       putchar(header->HWResolution[1] >> 8);
+       putchar(header->HWResolution[1]);
+       putchar(0);
+       putchar(1 << DotBits[plane]);
+      }
+    }
+  }
+  else if ((ppd->model_number & PCL_RASTER_CID) && OutputMode == OUTPUT_RGB)
+  {
+   /*
+    * Use configure image data command...
+    */
+
+    pcl_set_simple_resolution(header->HWResolution[0]);
+                                       /* Set output resolution */
+
+    cupsWritePrintData("\033*v6W\0\3\0\10\10\10", 11);
+                                       /* 24-bit RGB */
+  }
+  else
+  {
+   /*
+    * Use simple raster commands...
+    */
+
+    pcl_set_simple_resolution(header->HWResolution[0]);
+                                       /* Set output resolution */
+
+    if (PrinterPlanes == 3)
+      pcl_set_simple_cmy();
+    else if (PrinterPlanes == 4)
+      pcl_set_simple_kcmy();
+  }
+
+  if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "X")) != NULL)
+    xorigin = atoi(attr->value);
+  else
+    xorigin = 0;
+
+  if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "Y")) != NULL)
+    yorigin = atoi(attr->value);
+  else
+    yorigin = 120;
+
+  printf("\033&a%dH\033&a%dV", xorigin, yorigin);
+  printf("\033*r%dS", header->cupsWidth);
+  printf("\033*r%dT", header->cupsHeight);
+  printf("\033*r1A");
+
+  if (header->cupsCompression && header->cupsCompression != 10)
+    printf("\033*b%dM", header->cupsCompression);
+
+  OutputFeed = 0;
+
+ /*
+  * Allocate memory for the page...
+  */
+
+  PixelBuffer = malloc(header->cupsBytesPerLine);
+
+  if (OutputMode == OUTPUT_DITHERED)
+  {
+    InputBuffer      = malloc(header->cupsWidth * PrinterPlanes * 2);
+    OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth);
+
+    for (i = 1; i < PrinterPlanes; i ++)
+      OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth;
+
+    if (RGB)
+      CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes);
+
+    for (plane = 0, DotBufferSize = 0; plane < PrinterPlanes; plane ++)
+    {
+      DotBufferSizes[plane] = (header->cupsWidth + 7) / 8 * DotBits[plane];
+      DotBufferSize         += DotBufferSizes[plane];
+    }
+
+    DotBuffers[0] = malloc(DotBufferSize);
+    for (plane = 1; plane < PrinterPlanes; plane ++)
+      DotBuffers[plane] = DotBuffers[plane - 1] + DotBufferSizes[plane - 1];
+  }
+
+  if (header->cupsCompression)
+    CompBuffer = malloc(DotBufferSize * 4);
+
+  if (header->cupsCompression >= 3)
+    SeedBuffer = malloc(DotBufferSize);
+
+  SeedInvalid = 1;
+
+  fprintf(stderr, "BlankValue=%d\n", BlankValue);
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(ppd_file_t         *ppd,       /* I - PPD file */
+        cups_page_header_t *header)    /* I - Page header */
+{
+  int  plane;                          /* Current plane */
+
+
+ /*
+  * End graphics mode...
+  */
+
+  if (ppd->model_number & PCL_RASTER_END_COLOR)
+    printf("\033*rC");                 /* End color GFX */
+  else
+    printf("\033*r0B");                        /* End B&W GFX */
+
+ /*
+  * Output a page eject sequence...
+  */
+
+  if (ppd->model_number & PCL_PJL_HPGL2)
+  {
+     pcl_set_hpgl_mode(0);             /* Back to HP-GL/2 mode */
+     printf("PG;");                    /* Eject the current page */
+  }
+  else if (!(header->Duplex && (Page & 1)))
+    printf("\014");                    /* Eject current page */
+
+ /*
+  * Free memory for the page...
+  */
+
+  free(PixelBuffer);
+
+  if (OutputMode == OUTPUT_DITHERED)
+  {
+    for (plane = 0; plane < PrinterPlanes; plane ++)
+    {
+      cupsDitherDelete(DitherStates[plane]);
+      cupsLutDelete(DitherLuts[plane]);
+    }
+
+    free(DotBuffers[0]);
+    free(InputBuffer);
+    free(OutputBuffers[0]);
+
+    cupsCMYKDelete(CMYK);
+
+    if (RGB)
+    {
+      cupsRGBDelete(RGB);
+      free(CMYKBuffer);
+    }
+  }
+
+  if (header->cupsCompression)
+    free(CompBuffer);
+
+  if (header->cupsCompression >= 3)
+    free(SeedBuffer);
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown a printer.
+ */
+
+void
+Shutdown(ppd_file_t         *ppd,      /* I - PPD file */
+        int                job_id,     /* I - Job ID */
+        const char         *user,      /* I - User printing job */
+        const char         *title,     /* I - Title of job */
+        int                num_options,/* I - Number of command-line options */
+        cups_option_t      *options)   /* I - Command-line options */
+{
+  ppd_attr_t   *attr;                  /* Attribute from PPD file */
+
+
+  if ((attr = ppdFindAttr(ppd, "cupsPCL", "EndJob")) != NULL)
+  {
+   /*
+    * Tell the printer how many pages were in the job...
+    */
+
+    putchar(0x1b);
+    printf(attr->value, Page);
+  }
+  else
+  {
+   /*
+    * Return the printer to the default state...
+    */
+
+    pcl_reset();
+  }
+
+  if (ppd->model_number & PCL_PJL)
+  {
+    pjl_escape();
+
+    if ((attr = ppdFindAttr(ppd, "cupsPJL", "EndJob")) != NULL)
+      pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options,
+                options);
+    else
+      printf("@PJL EOJ\r\n");
+
+    pjl_escape();
+  }
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(unsigned char *line,      /* I - Data to compress */
+             int           length,     /* I - Number of bytes */
+            int           plane,       /* I - Color plane */
+            int           pend,        /* I - End character for data */
+            int           type)        /* I - Type of compression */
+{
+  unsigned char        *line_ptr,              /* Current byte pointer */
+               *line_end,              /* End-of-line byte pointer */
+               *comp_ptr,              /* Pointer into compression buffer */
+               *start,                 /* Start of compression sequence */
+               *seed;                  /* Seed buffer pointer */
+  int           count,                 /* Count of bytes for output */
+               offset,                 /* Offset of bytes for output */
+               temp;                   /* Temporary count */
+  int          r, g, b;                /* RGB deltas for mode 10 compression */
+
+
+  switch (type)
+  {
+    default :
+       /*
+       * Do no compression; with a mode-0 only printer, we can compress blank
+       * lines...
+       */
+
+       line_ptr = line;
+
+        if (cupsCheckBytes(line, length))
+          line_end = line;             /* Blank line */
+        else
+         line_end = line + length;     /* Non-blank line */
+       break;
+
+    case 1 :
+       /*
+        * Do run-length encoding...
+        */
+
+       line_end = line + length;
+       for (line_ptr = line, comp_ptr = CompBuffer;
+            line_ptr < line_end;
+            comp_ptr += 2, line_ptr += count)
+       {
+         for (count = 1;
+               (line_ptr + count) < line_end &&
+                  line_ptr[0] == line_ptr[count] &&
+                  count < 256;
+               count ++);
+
+         comp_ptr[0] = count - 1;
+         comp_ptr[1] = line_ptr[0];
+       }
+
+        line_ptr = CompBuffer;
+        line_end = comp_ptr;
+       break;
+
+    case 2 :
+       /*
+        * Do TIFF pack-bits encoding...
+        */
+
+       line_ptr = line;
+       line_end = line + length;
+       comp_ptr = CompBuffer;
+
+       while (line_ptr < line_end)
+       {
+         if ((line_ptr + 1) >= line_end)
+         {
+          /*
+           * Single byte on the end...
+           */
+
+           *comp_ptr++ = 0x00;
+           *comp_ptr++ = *line_ptr++;
+         }
+         else if (line_ptr[0] == line_ptr[1])
+         {
+          /*
+           * Repeated sequence...
+           */
+
+           line_ptr ++;
+           count = 2;
+
+           while (line_ptr < (line_end - 1) &&
+                  line_ptr[0] == line_ptr[1] &&
+                  count < 127)
+           {
+              line_ptr ++;
+              count ++;
+           }
+
+           *comp_ptr++ = 257 - count;
+           *comp_ptr++ = *line_ptr++;
+         }
+         else
+         {
+          /*
+           * Non-repeated sequence...
+           */
+
+           start    = line_ptr;
+           line_ptr ++;
+           count    = 1;
+
+           while (line_ptr < (line_end - 1) &&
+                  line_ptr[0] != line_ptr[1] &&
+                  count < 127)
+           {
+              line_ptr ++;
+              count ++;
+           }
+
+           *comp_ptr++ = count - 1;
+
+           memcpy(comp_ptr, start, count);
+           comp_ptr += count;
+         }
+       }
+
+        line_ptr = CompBuffer;
+        line_end = comp_ptr;
+       break;
+
+    case 3 :
+       /*
+       * Do delta-row compression...
+       */
+
+       line_ptr = line;
+       line_end = line + length;
+
+       comp_ptr = CompBuffer;
+       seed     = SeedBuffer + plane * length;
+
+       while (line_ptr < line_end)
+        {
+         /*
+          * Find the next non-matching sequence...
+          */
+
+          start = line_ptr;
+
+         if (SeedInvalid)
+         {
+          /*
+           * The seed buffer is invalid, so do the next 8 bytes, max...
+           */
+
+           offset = 0;
+
+           if ((count = line_end - line_ptr) > 8)
+             count = 8;
+
+           line_ptr += count;
+         }
+         else
+         {
+          /*
+           * The seed buffer is valid, so compare against it...
+           */
+
+            while (*line_ptr == *seed &&
+                   line_ptr < line_end)
+            {
+              line_ptr ++;
+              seed ++;
+            }
+
+            if (line_ptr == line_end)
+              break;
+
+            offset = line_ptr - start;
+
+           /*
+            * Find up to 8 non-matching bytes...
+            */
+
+            start = line_ptr;
+            count = 0;
+            while (*line_ptr != *seed &&
+                   line_ptr < line_end &&
+                   count < 8)
+            {
+              line_ptr ++;
+              seed ++;
+              count ++;
+            }
+         }
+
+         /*
+          * Place mode 3 compression data in the buffer; see HP manuals
+          * for details...
+          */
+
+          if (offset >= 31)
+          {
+           /*
+            * Output multi-byte offset...
+            */
+
+            *comp_ptr++ = ((count - 1) << 5) | 31;
+
+            offset -= 31;
+            while (offset >= 255)
+            {
+              *comp_ptr++ = 255;
+              offset    -= 255;
+            }
+
+            *comp_ptr++ = offset;
+          }
+          else
+          {
+           /*
+            * Output single-byte offset...
+            */
+
+            *comp_ptr++ = ((count - 1) << 5) | offset;
+          }
+
+          memcpy(comp_ptr, start, count);
+          comp_ptr += count;
+        }
+
+       line_ptr = CompBuffer;
+       line_end = comp_ptr;
+
+        memcpy(SeedBuffer + plane * length, line, length);
+       break;
+
+    case 10 :
+       /*
+        * Mode 10 "near lossless" RGB compression...
+       */
+
+       line_ptr = line;
+       line_end = line + length;
+
+       comp_ptr = CompBuffer;
+       seed     = SeedBuffer;
+
+        if (PrinterPlanes == 1)
+       {
+        /*
+         * Do grayscale compression to RGB...
+         */
+
+         while (line_ptr < line_end)
+          {
+           /*
+            * Find the next non-matching sequence...
+            */
+
+            start = line_ptr;
+            while (line_ptr < line_end &&
+                  *line_ptr == *seed)
+            {
+              line_ptr ++;
+              seed ++;
+            }
+
+            if (line_ptr == line_end)
+              break;
+
+            offset = line_ptr - start;
+
+           /*
+            * Find non-matching grayscale pixels...
+            */
+
+            start = line_ptr;
+            while (line_ptr < line_end &&
+                  *line_ptr != *seed)
+            {
+              line_ptr ++;
+              seed ++;
+            }
+
+            count = line_ptr - start;
+
+#if 0
+            fprintf(stderr, "DEBUG: offset=%d, count=%d, comp_ptr=%p(%d of %d)...\n",
+                   offset, count, comp_ptr, comp_ptr - CompBuffer,
+                   BytesPerLine * 5);
+#endif /* 0 */
+
+           /*
+            * Place mode 10 compression data in the buffer; each sequence
+           * starts with a command byte that looks like:
+           *
+           *     CMD SRC SRC OFF OFF CNT CNT CNT
+           *
+           * For the purpose of this driver, CMD and SRC are always 0.
+           *
+           * If the offset >= 3 then additional offset bytes follow the
+           * first command byte, each byte == 255 until the last one.
+           *
+           * If the count >= 7, then additional count bytes follow each
+           * group of pixels, each byte == 255 until the last one.
+           *
+           * The offset and count are in RGB tuples (not bytes, as for
+           * Mode 3 and 9)...
+            */
+
+            if (offset >= 3)
+            {
+             /*
+              * Output multi-byte offset...
+              */
+
+              if (count > 7)
+               *comp_ptr++ = 0x1f;
+             else
+               *comp_ptr++ = 0x18 | (count - 1);
+
+              offset -= 3;
+              while (offset >= 255)
+              {
+               *comp_ptr++ = 255;
+               offset      -= 255;
+              }
+
+              *comp_ptr++ = offset;
+            }
+            else
+            {
+             /*
+              * Output single-byte offset...
+              */
+
+              if (count > 7)
+               *comp_ptr++ = (offset << 3) | 0x07;
+             else
+               *comp_ptr++ = (offset << 3) | (count - 1);
+            }
+
+           temp = count - 8;
+           seed -= count;
+
+            while (count > 0)
+           {
+             if (count <= temp)
+             {
+              /*
+               * This is exceedingly lame...  The replacement counts
+               * are intermingled with the data...
+               */
+
+               if (temp >= 255)
+                 *comp_ptr++ = 255;
+               else
+                 *comp_ptr++ = temp;
+
+               temp -= 255;
+             }
+
+             /*
+             * Get difference between current and see pixels...
+             */
+
+              r = *start - *seed;
+             g = r;
+             b = ((*start & 0xfe) - (*seed & 0xfe)) / 2;
+
+              if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15)
+             {
+              /*
+               * Pack 24-bit RGB into 23 bits...  Lame...
+               */
+
+                g = *start;
+
+               *comp_ptr++ = g >> 1;
+
+               if (g & 1)
+                 *comp_ptr++ = 0x80 | (g >> 1);
+               else
+                 *comp_ptr++ = g >> 1;
+
+               if (g & 1)
+                 *comp_ptr++ = 0x80 | (g >> 1);
+               else
+                 *comp_ptr++ = g >> 1;
+              }
+             else
+             {
+              /*
+               * Pack 15-bit RGB difference...
+               */
+
+               *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03);
+               *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f);
+             }
+
+              count --;
+             start ++;
+             seed ++;
+            }
+
+           /*
+           * Make sure we have the ending count if the replacement count
+           * was exactly 8 + 255n...
+           */
+
+           if (temp == 0)
+             *comp_ptr++ = 0;
+          }
+       }
+       else
+       {
+        /*
+         * Do RGB compression...
+         */
+
+         while (line_ptr < line_end)
+          {
+           /*
+            * Find the next non-matching sequence...
+            */
+
+            start = line_ptr;
+            while (line_ptr[0] == seed[0] &&
+                   line_ptr[1] == seed[1] &&
+                   line_ptr[2] == seed[2] &&
+                   (line_ptr + 2) < line_end)
+            {
+              line_ptr += 3;
+              seed += 3;
+            }
+
+            if (line_ptr == line_end)
+              break;
+
+            offset = (line_ptr - start) / 3;
+
+           /*
+            * Find non-matching RGB tuples...
+            */
+
+            start = line_ptr;
+            while ((line_ptr[0] != seed[0] ||
+                    line_ptr[1] != seed[1] ||
+                    line_ptr[2] != seed[2]) &&
+                   (line_ptr + 2) < line_end)
+            {
+              line_ptr += 3;
+              seed += 3;
+            }
+
+            count = (line_ptr - start) / 3;
+
+           /*
+            * Place mode 10 compression data in the buffer; each sequence
+           * starts with a command byte that looks like:
+           *
+           *     CMD SRC SRC OFF OFF CNT CNT CNT
+           *
+           * For the purpose of this driver, CMD and SRC are always 0.
+           *
+           * If the offset >= 3 then additional offset bytes follow the
+           * first command byte, each byte == 255 until the last one.
+           *
+           * If the count >= 7, then additional count bytes follow each
+           * group of pixels, each byte == 255 until the last one.
+           *
+           * The offset and count are in RGB tuples (not bytes, as for
+           * Mode 3 and 9)...
+            */
+
+            if (offset >= 3)
+            {
+             /*
+              * Output multi-byte offset...
+              */
+
+              if (count > 7)
+               *comp_ptr++ = 0x1f;
+             else
+               *comp_ptr++ = 0x18 | (count - 1);
+
+              offset -= 3;
+              while (offset >= 255)
+              {
+               *comp_ptr++ = 255;
+               offset      -= 255;
+              }
+
+              *comp_ptr++ = offset;
+            }
+            else
+            {
+             /*
+              * Output single-byte offset...
+              */
+
+              if (count > 7)
+               *comp_ptr++ = (offset << 3) | 0x07;
+             else
+               *comp_ptr++ = (offset << 3) | (count - 1);
+            }
+
+           temp = count - 8;
+           seed -= count * 3;
+
+            while (count > 0)
+           {
+             if (count <= temp)
+             {
+              /*
+               * This is exceedingly lame...  The replacement counts
+               * are intermingled with the data...
+               */
+
+               if (temp >= 255)
+                 *comp_ptr++ = 255;
+               else
+                 *comp_ptr++ = temp;
+
+               temp -= 255;
+             }
+
+             /*
+             * Get difference between current and see pixels...
+             */
+
+              r = start[0] - seed[0];
+             g = start[1] - seed[1];
+             b = ((start[2] & 0xfe) - (seed[2] & 0xfe)) / 2;
+
+              if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15)
+             {
+              /*
+               * Pack 24-bit RGB into 23 bits...  Lame...
+               */
+
+               *comp_ptr++ = start[0] >> 1;
+
+               if (start[0] & 1)
+                 *comp_ptr++ = 0x80 | (start[1] >> 1);
+               else
+                 *comp_ptr++ = start[1] >> 1;
+
+               if (start[1] & 1)
+                 *comp_ptr++ = 0x80 | (start[2] >> 1);
+               else
+                 *comp_ptr++ = start[2] >> 1;
+              }
+             else
+             {
+              /*
+               * Pack 15-bit RGB difference...
+               */
+
+               *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03);
+               *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f);
+             }
+
+              count --;
+             start += 3;
+             seed += 3;
+            }
+
+           /*
+           * Make sure we have the ending count if the replacement count
+           * was exactly 8 + 255n...
+           */
+
+           if (temp == 0)
+             *comp_ptr++ = 0;
+          }
+        }
+
+       line_ptr = CompBuffer;
+       line_end = comp_ptr;
+
+        memcpy(SeedBuffer, line, length);
+       break;
+  }
+
+ /*
+  * Set the length of the data and write a raster plane...
+  */
+
+  printf("\033*b%d%c", (int)(line_end - line_ptr), pend);
+  cupsWritePrintData(line_ptr, line_end - line_ptr);
+}
+
+
+/*
+ * 'OutputLine()' - Output the specified number of lines of graphics.
+ */
+
+void
+OutputLine(ppd_file_t         *ppd,    /* I - PPD file */
+           cups_page_header_t *header) /* I - Page header */
+{
+  int                  i, j;           /* Looping vars */
+  int                  plane;          /* Current plane */
+  unsigned char                bit;            /* Current bit */
+  int                  bytes;          /* Number of bytes/plane */
+  int                  width;          /* Width of line in pixels */
+  const int            *order;         /* Order to use */
+  unsigned char                *ptr;           /* Pointer into buffer */
+
+
+ /*
+  * Output whitespace as needed...
+  */
+
+  if (OutputFeed > 0)
+  {
+    if (header->cupsCompression < 3)
+    {
+     /*
+      * Send blank raster lines...
+      */
+
+      while (OutputFeed > 0)
+      {
+       printf("\033*b0W");
+       OutputFeed --;
+      }
+    }
+    else
+    {
+     /*
+      * Send Y offset command and invalidate the seed buffer...
+      */
+
+      printf("\033*b%dY", OutputFeed);
+      OutputFeed  = 0;
+      SeedInvalid = 1;
+    }
+  }
+
+ /*
+  * Write bitmap data as needed...
+  */
+
+  switch (OutputMode)
+  {
+    case OUTPUT_BITMAP :               /* Send 1-bit bitmap data... */
+       order = ColorOrders[PrinterPlanes - 1];
+       bytes = header->cupsBytesPerLine / PrinterPlanes;
+
+       for (i = 0; i < PrinterPlanes; i ++)
+       {
+         plane = order[i];
+
+         CompressData(PixelBuffer + i * bytes, bytes, plane,
+                      (i < (PrinterPlanes - 1)) ? 'V' : 'W',
+                      header->cupsCompression);
+        }
+        break;
+
+    case OUTPUT_INVERBIT :             /* Send inverted 1-bit bitmap data... */
+       order = ColorOrders[PrinterPlanes - 1];
+       bytes = header->cupsBytesPerLine / PrinterPlanes;
+
+        for (i = header->cupsBytesPerLine, ptr = PixelBuffer;
+            i > 0;
+            i --, ptr ++)
+         *ptr = ~*ptr;
+
+       for (i = 0; i < PrinterPlanes; i ++)
+       {
+         plane = order[i];
+
+         CompressData(PixelBuffer + i * bytes, bytes, plane,
+                      (i < (PrinterPlanes - 1)) ? 'V' : 'W',
+                      header->cupsCompression);
+        }
+        break;
+
+    case OUTPUT_RGB :                  /* Send 24-bit RGB data... */
+        if (PrinterPlanes == 1 && !BlankValue)
+       {
+        /*
+         * Invert black to grayscale...
+         */
+
+          for (i = header->cupsBytesPerLine, ptr = PixelBuffer;
+              i > 0;
+              i --, ptr ++)
+           *ptr = ~*ptr;
+       }
+
+       /*
+       * Compress the output...
+       */
+
+       CompressData(PixelBuffer, header->cupsBytesPerLine, 0, 'W',
+                    header->cupsCompression);
+        break;
+
+    default :
+       order = ColorOrders[PrinterPlanes - 1];
+       width = header->cupsWidth;
+
+       for (i = 0, j = 0; i < PrinterPlanes; i ++)
+       {
+         plane = order[i];
+         bytes = DotBufferSizes[plane] / DotBits[plane];
+
+         for (bit = 1, ptr = DotBuffers[plane];
+              bit <= DotBits[plane];
+              bit <<= 1, ptr += bytes, j ++)
+         {
+           cupsPackHorizontalBit(OutputBuffers[plane], DotBuffers[plane],
+                                 width, 0, bit);
+            CompressData(ptr, bytes, j,
+                        i == (PrinterPlanes - 1) &&
+                            bit == DotBits[plane] ? 'W' : 'V',
+                        header->cupsCompression);
+          }
+       }
+       break;
+  }
+
+ /*
+  * The seed buffer, if any, now should contain valid data...
+  */
+
+  SeedInvalid = 0;
+}
+
+
+/*
+ * 'ReadLine()' - Read graphics from the page stream.
+ */
+
+int                                    /* O - Number of lines (0 if blank) */
+ReadLine(cups_raster_t      *ras,      /* I - Raster stream */
+         cups_page_header_t *header)   /* I - Page header */
+{
+  int  plane,                          /* Current color plane */
+       width;                          /* Width of line */
+
+
+ /*
+  * Read raster data...
+  */
+
+  cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine);
+
+ /*
+  * See if it is blank; if so, return right away...
+  */
+
+  if (cupsCheckValue(PixelBuffer, header->cupsBytesPerLine, BlankValue))
+    return (0);
+
+ /*
+  * If we aren't dithering, return immediately...
+  */
+
+  if (OutputMode != OUTPUT_DITHERED)
+    return (1);
+
+ /*
+  * Perform the color separation...
+  */
+
+  width = header->cupsWidth;
+
+  switch (header->cupsColorSpace)
+  {
+    case CUPS_CSPACE_W :
+        if (RGB)
+       {
+         cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width);
+
+         if (RGB->num_channels == 1)
+           cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width);
+         else
+           cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+       }
+       else
+          cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    case CUPS_CSPACE_K :
+        cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    default :
+    case CUPS_CSPACE_RGB :
+        if (RGB)
+       {
+         cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width);
+
+         if (RGB->num_channels == 1)
+           cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width);
+         else
+           cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width);
+       }
+       else
+          cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+
+    case CUPS_CSPACE_CMYK :
+        cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width);
+       break;
+  }
+
+ /*
+  * Dither the pixels...
+  */
+
+  for (plane = 0; plane < PrinterPlanes; plane ++)
+    cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane,
+                   PrinterPlanes, OutputBuffers[plane]);
+
+ /*
+  * Return 1 to indicate that we have non-blank output...
+  */
+
+  return (1);
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int                                    /* O - Exit status */
+main(int  argc,                                /* I - Number of command-line arguments */
+     char *argv[])                     /* I - Command-line arguments */
+{
+  int                  fd;             /* File descriptor */
+  cups_raster_t                *ras;           /* Raster stream for printing */
+  cups_page_header_t   header;         /* Page header from file */
+  int                  y;              /* Current line */
+  ppd_file_t           *ppd;           /* PPD file */
+  int                  job_id;         /* Job ID */
+  int                  num_options;    /* Number of options */
+  cups_option_t                *options;       /* Options */
+
+
+ /*
+  * Make sure status messages are not buffered...
+  */
+
+  setbuf(stderr, NULL);
+
+ /*
+  * Check command-line...
+  */
+
+  if (argc < 6 || argc > 7)
+  {
+    fputs("ERROR: rastertopclx job-id user title copies options [file]\n", stderr);
+    return (1);
+  }
+
+  num_options = cupsParseOptions(argv[5], 0, &options);
+
+ /*
+  * Open the PPD file...
+  */
+
+  ppd = ppdOpenFile(getenv("PPD"));
+
+  if (!ppd)
+  {
+    fputs("ERROR: Unable to open PPD file!\n", stderr);
+    return (1);
+  }
+
+  ppdMarkDefaults(ppd);
+  cupsMarkOptions(ppd, num_options, options);
+
+ /*
+  * Open the page stream...
+  */
+
+  if (argc == 7)
+  {
+    if ((fd = open(argv[6], O_RDONLY)) == -1)
+    {
+      perror("ERROR: Unable to open raster file - ");
+      return (1);
+    }
+  }
+  else
+    fd = 0;
+
+  ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+  * Process pages as needed...
+  */
+
+  job_id = atoi(argv[1]);
+
+  Page = 0;
+
+  while (cupsRasterReadHeader(ras, &header))
+  {
+    Page ++;
+
+    fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
+    fprintf(stderr, "INFO: Starting page %d...\n", Page);
+
+    StartPage(ppd, &header, atoi(argv[1]), argv[2], argv[3],
+              num_options, options);
+
+    for (y = 0; y < (int)header.cupsHeight; y ++)
+    {
+      if ((y & 127) == 0)
+        fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", Page,
+               100 * y / header.cupsHeight);
+
+      if (ReadLine(ras, &header))
+        OutputLine(ppd, &header);
+      else
+        OutputFeed ++;
+    }
+
+    fprintf(stderr, "INFO: Finished page %d...\n", Page);
+
+    EndPage(ppd, &header);
+  }
+
+  Shutdown(ppd, job_id, argv[2], argv[3], num_options, options);
+
+  cupsFreeOptions(num_options, options);
+
+  cupsRasterClose(ras);
+
+  if (fd != 0)
+    close(fd);
+
+  if (Page == 0)
+  {
+    fputs("ERROR: No pages found!\n", stderr);
+    return (1);
+  }
+  else
+  {
+    fputs("INFO: Ready to print.\n", stderr);
+    return (0);
+  }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/rgb.c b/driver/rgb.c
new file mode 100644 (file)
index 0000000..fd0b117
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * "$Id$"
+ *
+ *   RGB color separation code for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   cupsRGBDelete() - Delete a color separation.
+ *   cupsRGBDoGray() - Do a grayscale separation...
+ *   cupsRGBDoRGB()  - Do a RGB separation...
+ *   cupsRGBLoad()   - Load a RGB color profile from a PPD file.
+ *   cupsRGBNew()    - Create a new RGB color separation.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * 'cupsRGBDelete()' - Delete a color separation.
+ */
+
+void
+cupsRGBDelete(cups_rgb_t *rgbptr)      /* I - Color separation */
+{
+  if (rgbptr == NULL)
+    return;
+
+  free(rgbptr->colors[0][0][0]);
+  free(rgbptr->colors[0][0]);
+  free(rgbptr->colors[0]);
+  free(rgbptr->colors);
+  free(rgbptr);
+}
+
+
+/*
+ * 'cupsRGBDoGray()' - Do a grayscale separation...
+ */
+
+void
+cupsRGBDoGray(cups_rgb_t          *rgbptr,
+                                       /* I - Color separation */
+             const unsigned char *input,
+                                       /* I - Input grayscale pixels */
+             unsigned char       *output,
+                                       /* O - Output Device-N pixels */
+             int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  i;              /* Looping var */
+  int                  lastgray;       /* Previous grayscale */
+  int                  xs, ys, zs,     /* Current RGB row offsets */
+                       g, gi, gm0, gm1;/* Current gray index and multipliers ... */
+  const unsigned char  *color;         /* Current color data */
+  int                  tempg;          /* Current separation color */
+  int                  rgbsize;        /* Separation data size */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!rgbptr || !input || !output || num_pixels <= 0)
+    return;
+
+ /*
+  * Initialize variables used for the duration of the separation...
+  */
+
+  lastgray = -1;
+  rgbsize  = rgbptr->num_channels;
+  xs       = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels;
+  ys       = rgbptr->cube_size * rgbptr->num_channels;
+  zs       = rgbptr->num_channels;
+
+ /*
+  * Loop through it all...
+  */
+
+  while (num_pixels > 0)
+  {
+   /*
+    * See if the next pixel is a cached value...
+    */
+
+    num_pixels --;
+
+    g = cups_srgb_lut[*input++];
+
+    if (g == lastgray)
+    {
+     /*
+      * Copy previous color and continue...
+      */
+
+      memcpy(output, output - rgbptr->num_channels, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+    else if (g == 0x00 && rgbptr->cache_init)
+    {
+     /*
+      * Copy black color and continue...
+      */
+
+      memcpy(output, rgbptr->black, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+    else if (g == 0xff && rgbptr->cache_init)
+    {
+     /*
+      * Copy white color and continue...
+      */
+
+      memcpy(output, rgbptr->white, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+
+   /*
+    * Nope, figure this one out on our own...
+    */
+
+    gi  = rgbptr->cube_index[g];
+    gm0 = rgbptr->cube_mult[g];
+    gm1 = 256 - gm0;
+
+    color = rgbptr->colors[gi][gi][gi];
+
+    for (i = 0; i < rgbptr->num_channels; i ++, color ++)
+    {
+      tempg = (color[0] * gm0 + color[xs + ys + zs] * gm1) / 256;
+
+      if (tempg > 255)
+        *output++ = 255;
+      else if (tempg < 0)
+        *output++ = 0;
+      else
+        *output++ = tempg;
+    }
+  }
+}
+
+
+/*
+ * 'cupsRGBDoRGB()' - Do a RGB separation...
+ */
+
+void
+cupsRGBDoRGB(cups_rgb_t          *rgbptr,
+                                       /* I - Color separation */
+            const unsigned char *input,
+                                       /* I - Input RGB pixels */
+            unsigned char       *output,
+                                       /* O - Output Device-N pixels */
+            int                 num_pixels)
+                                       /* I - Number of pixels */
+{
+  int                  i;              /* Looping var */
+  int                  rgb,            /* Current RGB color */
+                       lastrgb;        /* Previous RGB color */
+  int                  r, ri, rm0, rm1, rs,
+                                       /* Current red index, multipliexs, and row offset */
+                       g, gi, gm0, gm1, gs,
+                                       /* Current green ... */
+                       b, bi, bm0, bm1, bs;
+                                       /* Current blue ... */
+  const unsigned char  *color;         /* Current color data */
+  int                  tempr,          /* Current separation colors */
+                       tempg,          /* ... */
+                       tempb ;         /* ... */
+  int                  rgbsize;        /* Separation data size */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!rgbptr || !input || !output || num_pixels <= 0)
+    return;
+
+ /*
+  * Initialize variables used for the duration of the separation...
+  */
+
+  lastrgb = -1;
+  rgbsize = rgbptr->num_channels;
+  rs      = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels;
+  gs      = rgbptr->cube_size * rgbptr->num_channels;
+  bs      = rgbptr->num_channels;
+
+ /*
+  * Loop through it all...
+  */
+
+  while (num_pixels > 0)
+  {
+   /*
+    * See if the next pixel is a cached value...
+    */
+
+    num_pixels --;
+
+    r   = cups_srgb_lut[*input++];
+    g   = cups_srgb_lut[*input++];
+    b   = cups_srgb_lut[*input++];
+    rgb = (((r << 8) | g) << 8) | b;
+
+    if (rgb == lastrgb)
+    {
+     /*
+      * Copy previous color and continue...
+      */
+
+      memcpy(output, output - rgbptr->num_channels, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+    else if (rgb == 0x000000 && rgbptr->cache_init)
+    {
+     /*
+      * Copy black color and continue...
+      */
+
+      memcpy(output, rgbptr->black, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+    else if (rgb == 0xffffff && rgbptr->cache_init)
+    {
+     /*
+      * Copy white color and continue...
+      */
+
+      memcpy(output, rgbptr->white, rgbsize);
+
+      output += rgbptr->num_channels;
+      continue;
+    }
+
+   /*
+    * Nope, figure this one out on our own...
+    */
+
+    ri  = rgbptr->cube_index[r];
+    rm0 = rgbptr->cube_mult[r];
+    rm1 = 256 - rm0;
+
+    gi  = rgbptr->cube_index[g];
+    gm0 = rgbptr->cube_mult[g];
+    gm1 = 256 - gm0;
+
+    bi  = rgbptr->cube_index[b];
+    bm0 = rgbptr->cube_mult[b];
+    bm1 = 256 - bm0;
+
+    color = rgbptr->colors[ri][gi][bi];
+
+    for (i = rgbptr->num_channels; i > 0; i --, color ++)
+    {
+      tempb = (color[0] * bm0 + color[bs] * bm1) / 256;
+      tempg = tempb  * gm0;
+      tempb = (color[gs] * gm0 + color[gs + bs] * bm1) / 256;
+      tempg = (tempg + tempb  * gm1) / 256;
+
+      tempr = tempg * rm0;
+
+      tempb = (color[rs] * bm0 + color[rs + bs] * bm1) / 256;
+      tempg = tempb  * gm0;
+      tempb = (color[rs + gs] * bm0 + color[rs + gs + bs] * bm1) / 256;
+      tempg = (tempg + tempb  * gm1) / 256;
+
+      tempr = (tempr + tempg * rm1) / 256;
+
+      if (tempr > 255)
+        *output++ = 255;
+      else if (tempr < 0)
+        *output++ = 0;
+      else
+        *output++ = tempr;
+    }
+  }
+}
+
+
+/*
+ * 'cupsRGBLoad()' - Load a RGB color profile from a PPD file.
+ */
+
+cups_rgb_t *                           /* O - New color profile */
+cupsRGBLoad(ppd_file_t *ppd,           /* I - PPD file */
+            const char *colormodel,    /* I - Color model */
+            const char *media,         /* I - Media type */
+            const char *resolution)    /* I - Resolution */
+{
+  int          i,                      /* Looping var */
+               cube_size,              /* Size of color lookup cube */
+               num_channels,           /* Number of color channels */
+               num_samples;            /* Number of color samples */
+  cups_sample_t        *samples;               /* Color samples */
+  float                values[7];              /* Color sample values */
+  char         spec[PPD_MAX_NAME];     /* Profile name */
+  ppd_attr_t   *attr;                  /* Attribute from PPD file */
+  cups_rgb_t   *rgbptr;                /* RGB color profile */
+
+
+ /*
+  * Find the following attributes:
+  *
+  *    cupsRGBProfile  - Specifies the cube size, number of channels, and
+  *                      number of samples
+  *    cupsRGBSample   - Specifies an RGB to CMYK color sample
+  */
+
+  if ((attr = cupsFindAttr(ppd, "cupsRGBProfile", colormodel, media,
+                           resolution, spec, sizeof(spec))) == NULL)
+  {
+    fputs("DEBUG2: No cupsRGBProfile attribute found for the current settings!\n", stderr);
+    return (NULL);
+  }
+
+  if (!attr->value || sscanf(attr->value, "%d%d%d", &cube_size, &num_channels,
+                             &num_samples) != 3)
+  {
+    fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n",
+            attr->value ? attr->value : "(null)");
+    return (NULL);
+  }
+
+  if (cube_size < 2 || cube_size > 16 ||
+      num_channels < 1 || num_channels > CUPS_MAX_RGB ||
+      num_samples != (cube_size * cube_size * cube_size))
+  {
+    fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n",
+            attr->value);
+    return (NULL);
+  }
+
+ /*
+  * Allocate memory for the samples and read them...
+  */
+
+  if ((samples = calloc(num_samples, sizeof(cups_sample_t))) == NULL)
+  {
+    fputs("ERROR: Unable to allocate memory for RGB profile!\n", stderr);
+    return (NULL);
+  }
+
+ /*
+  * Read all of the samples...
+  */
+
+  for (i = 0; i < num_samples; i ++)
+    if ((attr = ppdFindNextAttr(ppd, "cupsRGBSample", spec)) == NULL)
+      break;
+    else if (!attr->value)
+    {
+      fputs("ERROR: Bad cupsRGBSample value!\n", stderr);
+      break;
+    }
+    else if (sscanf(attr->value, "%f%f%f%f%f%f%f", values + 0,
+                    values + 1, values + 2, values + 3, values + 4, values + 5,
+                    values + 6) != (3 + num_channels))
+    {
+      fputs("ERROR: Bad cupsRGBSample value!\n", stderr);
+      break;
+    }
+    else
+    {
+      samples[i].rgb[0]    = (int)(255.0 * values[0] + 0.5);
+      samples[i].rgb[1]    = (int)(255.0 * values[1] + 0.5);
+      samples[i].rgb[2]    = (int)(255.0 * values[2] + 0.5);
+      samples[i].colors[0] = (int)(255.0 * values[3] + 0.5);
+      if (num_channels > 1)
+       samples[i].colors[1] = (int)(255.0 * values[4] + 0.5);
+      if (num_channels > 2)
+       samples[i].colors[2] = (int)(255.0 * values[5] + 0.5);
+      if (num_channels > 3)
+       samples[i].colors[3] = (int)(255.0 * values[6] + 0.5);
+    }
+
+ /*
+  * If everything went OK, create the color profile...
+  */
+
+  if (i == num_samples)
+    rgbptr = cupsRGBNew(num_samples, samples, cube_size, num_channels);
+  else
+    rgbptr = NULL;
+
+ /*
+  * Free the temporary sample array and return...
+  */
+
+  free(samples);
+
+  return (rgbptr);
+}
+
+
+/*
+ * 'cupsRGBNew()' - Create a new RGB color separation.
+ */
+
+cups_rgb_t *                           /* O - New color separation or NULL */
+cupsRGBNew(int           num_samples,  /* I - Number of samples */
+          cups_sample_t *samples,      /* I - Samples */
+          int           cube_size,     /* I - Size of LUT cube */
+           int           num_channels) /* I - Number of color components */
+{
+  cups_rgb_t           *rgbptr;        /* New color separation */
+  int                  i;              /* Looping var */
+  int                  r, g, b;        /* Current RGB */
+  int                  tempsize;       /* Sibe of main arrays */
+  unsigned char                *tempc;         /* Pointer for C arrays */
+  unsigned char                **tempb ;       /* Pointer for Z arrays */
+  unsigned char                ***tempg;       /* Pointer for Y arrays */
+  unsigned char                ****tempr;      /* Pointer for X array */
+  unsigned char                rgb[3];         /* Temporary RGB value */
+
+
+ /*
+  * Range-check the input...
+  */
+
+  if (!samples || num_samples != (cube_size * cube_size * cube_size) ||
+      num_channels <= 0 || num_channels > CUPS_MAX_RGB)
+    return (NULL);
+
+ /*
+  * Allocate memory for the separation...
+  */
+
+  if ((rgbptr = calloc(1, sizeof(cups_rgb_t))) == NULL)
+    return (NULL);
+
+ /*
+  * Allocate memory for the samples and the LUT cube...
+  */
+
+  tempsize = cube_size * cube_size * cube_size;        /* FUTURE: num_samples < cs^3 */
+
+  tempc = calloc(tempsize, num_channels);
+  tempb = calloc(tempsize, sizeof(unsigned char *));
+  tempg = calloc(cube_size * cube_size, sizeof(unsigned char **));
+  tempr = calloc(cube_size, sizeof(unsigned char ***));
+
+  if (tempc == NULL || tempb  == NULL || tempg == NULL || tempr == NULL)
+  {
+    free(rgbptr);
+
+    if (tempc)
+      free(tempc);
+
+    if (tempb)
+      free(tempb);
+
+    if (tempg)
+      free(tempg);
+
+    if (tempr)
+      free(tempr);
+
+    return (NULL);
+  }
+
+ /*
+  * Fill in the arrays...
+  */
+
+  for (i = 0, r = 0; r < cube_size; r ++)
+  {
+    tempr[r] = tempg + r * cube_size;
+
+    for (g = 0; g < cube_size; g ++)
+    {
+      tempr[r][g] = tempb + i;
+
+      for (b = 0; b < cube_size; b ++, i ++)
+        tempr[r][g][b] = tempc + i * num_channels;
+    }
+  }
+
+  for (i = 0; i < num_samples; i ++)
+  {
+    r = samples[i].rgb[0] * (cube_size - 1) / 255;
+    g = samples[i].rgb[1] * (cube_size - 1) / 255;
+    b = samples[i].rgb[2] * (cube_size - 1) / 255;
+
+    memcpy(tempr[r][g][b], samples[i].colors, num_channels);
+  }
+
+  rgbptr->cube_size    = cube_size;
+  rgbptr->num_channels = num_channels;
+  rgbptr->colors       = tempr;
+
+ /*
+  * Generate the lookup tables for the cube indices and multipliers...
+  */
+
+  for (i = 0; i < 256; i ++)
+  {
+    rgbptr->cube_index[i] = i * (cube_size - 1) / 256;
+
+    if (i == 0)
+      rgbptr->cube_mult[i] = 256;
+    else
+      rgbptr->cube_mult[i] = 255 - ((i * (cube_size - 1)) & 255);
+  }
+
+ /*
+  * Generate the black and white cache values for the separation...
+  */
+
+  rgb[0] = 0;
+  rgb[1] = 0;
+  rgb[2] = 0;
+
+  cupsRGBDoRGB(rgbptr, rgb, rgbptr->black, 1);
+
+  rgb[0] = 255;
+  rgb[1] = 255;
+  rgb[2] = 255;
+
+  cupsRGBDoRGB(rgbptr, rgb, rgbptr->white, 1);
+
+  rgbptr->cache_init = 1;
+
+ /*
+  * Return the separation...
+  */
+
+  return (rgbptr);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/srgb.c b/driver/srgb.c
new file mode 100644 (file)
index 0000000..0354f23
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * "$Id$"
+ *
+ *   sRGB lookup tables for CUPS.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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/".
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+
+
+/*
+ * sRGB gamma lookup table.
+ */
+
+const unsigned char cups_srgb_lut[256] =
+{
+    0,  20,  28,  33,  38,  42,  46,  49,  52,  55,  58,  61,  63,  65,  68,
+   70,  72,  74,  76,  78,  80,  81,  83,  85,  87,  88,  90,  91,  93,  94,
+   96,  97,  99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 114,
+  115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131,
+  132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+  146, 147, 147, 148, 149, 150, 151, 152, 153, 153, 154, 155, 156, 157, 158,
+  158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169,
+  170, 171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180,
+  181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190,
+  190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, 198, 199, 199,
+  200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, 208, 208,
+  209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217,
+  217, 218, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 224, 224, 225,
+  225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232,
+  233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 240,
+  240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247,
+  248, 248, 249, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254,
+  255
+};
+
+
+/*
+ * sRGB gamma lookup table (inverted output to map to CMYK...)
+ */
+
+const unsigned char cups_scmy_lut[256] =
+{
+  255, 235, 227, 222, 217, 213, 209, 206, 203, 200, 197, 194, 192, 190, 187,
+  185, 183, 181, 179, 177, 175, 174, 172, 170, 168, 167, 165, 164, 162, 161,
+  159, 158, 156, 155, 153, 152, 151, 149, 148, 147, 146, 144, 143, 142, 141,
+  140, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 127, 126, 125, 124,
+  123, 122, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110,
+  109, 108, 108, 107, 106, 105, 104, 103, 102, 102, 101, 100,  99,  98,  97,
+   97,  96,  95,  94,  93,  93,  92,  91,  90,  90,  89,  88,  87,  87,  86,
+   85,  84,  84,  83,  82,  81,  81,  80,  79,  79,  78,  77,  77,  76,  75,
+   74,  74,  73,  72,  72,  71,  70,  70,  69,  68,  68,  67,  66,  66,  65,
+   65,  64,  63,  63,  62,  61,  61,  60,  59,  59,  58,  58,  57,  56,  56,
+   55,  55,  54,  53,  53,  52,  52,  51,  50,  50,  49,  49,  48,  47,  47,
+   46,  46,  45,  45,  44,  43,  43,  42,  42,  41,  41,  40,  39,  39,  38,
+   38,  37,  37,  36,  36,  35,  35,  34,  33,  33,  32,  32,  31,  31,  30,
+   30,  29,  29,  28,  28,  27,  27,  26,  26,  25,  25,  24,  24,  23,  23,
+   22,  22,  21,  21,  20,  20,  19,  19,  18,  18,  17,  17,  16,  16,  15,
+   15,  14,  14,  13,  13,  12,  12,  11,  11,  10,  10,   9,   9,   8,   8,
+    7,   7,   6,   6,   6,   5,   5,   4,   4,   3,   3,   2,   2,   1,   1,
+    0
+};
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/testcmyk.c b/driver/testcmyk.c
new file mode 100644 (file)
index 0000000..a89353c
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * "$Id$"
+ *
+ *   Test the CMYK color separation code for ESP Print Pro.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2006 by Easy Software Products, All Rights Reserved.
+ *
+ *   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:
+ *
+ *   test_gray() - Test grayscale separations...
+ *   test_rgb()  - Test color separations...
+ *   main()      - Do color separation tests.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/string.h>
+#include "driver.h"
+#include <sys/stat.h>
+
+
+void   test_gray(int num_comps, const char *basename);
+void   test_rgb(int num_comps, const char *basename);
+
+
+/*
+ * 'main()' - Do color separation tests.
+ */
+
+int                                            /* O - Exit status */
+main(int  argc,                                        /* I - Number of command-line arguments */
+     char *argv[])                             /* I - Command-line arguments */
+{
+ /*
+  * Make the test directory...
+  */
+
+  mkdir("test", 0755);
+
+ /*
+  * Run tests for K, Kk, CMY, CMYK, CcMmYK, and CcMmYKk separations...
+  */
+
+  test_rgb(1, "test/K-rgb");
+  test_rgb(2, "test/Kk-rgb");
+  test_rgb(3, "test/CMY-rgb");
+  test_rgb(4, "test/CMYK-rgb");
+  test_rgb(6, "test/CcMmYK-rgb");
+  test_rgb(7, "test/CcMmYKk-rgb");
+
+  test_gray(1, "test/K-gray");
+  test_gray(2, "test/Kk-gray");
+  test_gray(3, "test/CMY-gray");
+  test_gray(4, "test/CMYK-gray");
+  test_gray(6, "test/CcMmYK-gray");
+  test_gray(7, "test/CcMmYKk-gray");
+
+ /*
+  * Return with no errors...
+  */
+
+  return (0);
+}
+
+
+/*
+ * 'test_gray()' - Test grayscale separations...
+ */
+
+void
+test_gray(int        num_comps,                /* I - Number of components */
+         const char *basename)         /* I - Base filename of output */
+{
+  int                  i;              /* Looping var */
+  char                 filename[255];  /* Output filename */
+  char                 line[255];      /* Line from PGM file */
+  int                  width, height;  /* Width and height of test image */
+  int                  x, y;           /* Current coordinate in image */
+  int                  r, g, b;        /* Current RGB color */
+  unsigned char                input[7000];    /* Line to separate */
+  short                        output[48000],  /* Output separation data */
+                       *outptr;        /* Pointer in output */
+  FILE                 *in;            /* Input PPM file */
+  FILE                 *out[CUPS_MAX_CHAN];
+                                       /* Output PGM files */
+  FILE                 *comp;          /* Composite output */
+  cups_cmyk_t          *cmyk;          /* Color separation */
+
+
+ /*
+  * Open the test image...
+  */
+
+  in = fopen("image.pgm", "rb");
+  while (fgets(line, sizeof(line), in) != NULL)
+    if (isdigit(line[0]))
+      break;
+
+  sscanf(line, "%d%d", &width, &height);
+
+  fgets(line, sizeof(line), in);
+
+ /*
+  * Create the color separation...
+  */
+
+  cmyk = cupsCMYKNew(num_comps);
+
+  switch (num_comps)
+  {
+    case 2 : /* Kk */
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+       break;
+
+    case 4 :
+       cupsCMYKSetGamma(cmyk, 2, 1.0, 0.9);
+        cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+       break;
+
+    case 6 : /* CcMmYK */
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+        cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+       cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
+        cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+       break;
+
+    case 7 : /* CcMmYKk */
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+        cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+       cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
+        cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
+       break;
+  }
+
+ /*
+  * Open the color separation files...
+  */
+
+  for (i = 0; i < num_comps; i ++)
+  {
+    sprintf(filename, "%s%d.pgm", basename, i);
+    out[i] = fopen(filename, "wb");
+
+    fprintf(out[i], "P5\n%d %d 255\n", width, height);
+  }
+
+  sprintf(filename, "%s.ppm", basename);
+  comp = fopen(filename, "wb");
+
+  fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+  * Read the image and do the separations...
+  */
+
+  for (y = 0; y < height; y ++)
+  {
+    fread(input, width, 1, in);
+
+    cupsCMYKDoGray(cmyk, input, output, width);
+
+    for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+    {
+      for (i = 0; i < num_comps; i ++)
+        putc(255 - 255 * outptr[i] / 4095, out[i]);
+
+      r = 4095;
+      g = 4095;
+      b = 4095;
+
+      switch (num_comps)
+      {
+        case 1 :
+           r -= outptr[0];
+           g -= outptr[0];
+           b -= outptr[0];
+           break;
+       case 2 :
+           r -= outptr[0];
+           g -= outptr[0];
+           b -= outptr[0];
+
+           r -= outptr[1] / 2;
+           g -= outptr[1] / 2;
+           b -= outptr[1] / 2;
+           break;
+       case 3 :
+           r -= outptr[0];
+           g -= outptr[1];
+           b -= outptr[2];
+           break;
+       case 4 :
+           r -= outptr[0];
+           g -= outptr[1];
+           b -= outptr[2];
+
+           r -= outptr[3];
+           g -= outptr[3];
+           b -= outptr[3];
+           break;
+       case 6 :
+           r -= outptr[0] + outptr[1] / 2;
+           g -= outptr[2] + outptr[3] / 3;
+           b -= outptr[4];
+
+           r -= outptr[5];
+           g -= outptr[5];
+           b -= outptr[5];
+           break;
+       case 7 :
+           r -= outptr[0] + outptr[1] / 2;
+           g -= outptr[2] + outptr[3] / 3;
+           b -= outptr[4];
+
+           r -= outptr[5] + outptr[6] / 2;
+           g -= outptr[5] + outptr[6] / 2;
+           b -= outptr[5] + outptr[6] / 2;
+           break;
+      }
+
+      if (r < 0)
+        putc(0, comp);
+      else
+        putc(255 * r / 4095, comp);
+
+      if (g < 0)
+        putc(0, comp);
+      else
+        putc(255 * g / 4095, comp);
+
+      if (b < 0)
+        putc(0, comp);
+      else
+        putc(255 * b / 4095, comp);
+    }
+  }
+
+  for (i = 0; i < num_comps; i ++)
+    fclose(out[i]);
+
+  fclose(comp);
+  fclose(in);
+
+  cupsCMYKDelete(cmyk);
+}
+
+
+/*
+ * 'test_rgb()' - Test color separations...
+ */
+
+void
+test_rgb(int        num_comps,         /* I - Number of components */
+        const char *basename)          /* I - Base filename of output */
+{
+  int                  i;              /* Looping var */
+  char                 filename[255];  /* Output filename */
+  char                 line[255];      /* Line from PPM file */
+  int                  width, height;  /* Width and height of test image */
+  int                  x, y;           /* Current coordinate in image */
+  int                  r, g, b;        /* Current RGB color */
+  unsigned char                input[7000];    /* Line to separate */
+  short                        output[48000],  /* Output separation data */
+                       *outptr;        /* Pointer in output */
+  FILE                 *in;            /* Input PPM file */
+  FILE                 *out[CUPS_MAX_CHAN];
+                                       /* Output PGM files */
+  FILE                 *comp;          /* Composite output */
+  cups_cmyk_t          *cmyk;          /* Color separation */
+
+
+ /*
+  * Open the test image...
+  */
+
+  in = fopen("image.ppm", "rb");
+  while (fgets(line, sizeof(line), in) != NULL)
+    if (isdigit(line[0]))
+      break;
+
+  sscanf(line, "%d%d", &width, &height);
+
+  fgets(line, sizeof(line), in);
+
+ /*
+  * Create the color separation...
+  */
+
+  cmyk = cupsCMYKNew(num_comps);
+
+  cupsCMYKSetBlack(cmyk, 0.5, 1.0);
+
+  switch (num_comps)
+  {
+    case 2 : /* Kk */
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+       break;
+    case 6 : /* CcMmYK */
+       cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+       cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
+        cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+       break;
+    case 7 : /* CcMmYKk */
+       cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
+        cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
+       cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
+        cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
+        cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
+       break;
+  }
+
+ /*
+  * Open the color separation files...
+  */
+
+  for (i = 0; i < num_comps; i ++)
+  {
+    sprintf(filename, "%s%d.pgm", basename, i);
+    out[i] = fopen(filename, "wb");
+
+    fprintf(out[i], "P5\n%d %d 255\n", width, height);
+  }
+
+  sprintf(filename, "%s.ppm", basename);
+  comp = fopen(filename, "wb");
+
+  fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+  * Read the image and do the separations...
+  */
+
+  for (y = 0; y < height; y ++)
+  {
+    fread(input, width, 3, in);
+
+    cupsCMYKDoRGB(cmyk, input, output, width);
+
+    for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+    {
+      for (i = 0; i < num_comps; i ++)
+        putc(255 - 255 * outptr[i] / 4095, out[i]);
+
+      r = 4095;
+      g = 4095;
+      b = 4095;
+
+      switch (num_comps)
+      {
+        case 1 :
+           r -= outptr[0];
+           g -= outptr[0];
+           b -= outptr[0];
+           break;
+       case 2 :
+           r -= outptr[0];
+           g -= outptr[0];
+           b -= outptr[0];
+
+           r -= outptr[1] / 2;
+           g -= outptr[1] / 2;
+           b -= outptr[1] / 2;
+           break;
+       case 3 :
+           r -= outptr[0];
+           g -= outptr[1];
+           b -= outptr[2];
+           break;
+       case 4 :
+           r -= outptr[0];
+           g -= outptr[1];
+           b -= outptr[2];
+
+           r -= outptr[3];
+           g -= outptr[3];
+           b -= outptr[3];
+           break;
+       case 6 :
+           r -= outptr[0] + outptr[1] / 2;
+           g -= outptr[2] + outptr[3] / 3;
+           b -= outptr[4];
+
+           r -= outptr[5];
+           g -= outptr[5];
+           b -= outptr[5];
+           break;
+       case 7 :
+           r -= outptr[0] + outptr[1] / 2;
+           g -= outptr[2] + outptr[3] / 3;
+           b -= outptr[4];
+
+           r -= outptr[5] + outptr[6] / 2;
+           g -= outptr[5] + outptr[6] / 2;
+           b -= outptr[5] + outptr[6] / 2;
+           break;
+      }
+
+      if (r < 0)
+        putc(0, comp);
+      else
+        putc(255 * r / 4095, comp);
+
+      if (g < 0)
+        putc(0, comp);
+      else
+        putc(255 * g / 4095, comp);
+
+      if (b < 0)
+        putc(0, comp);
+      else
+        putc(255 * b / 4095, comp);
+    }
+  }
+
+  for (i = 0; i < num_comps; i ++)
+    fclose(out[i]);
+
+  fclose(comp);
+  fclose(in);
+
+  cupsCMYKDelete(cmyk);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/driver/testdither.c b/driver/testdither.c
new file mode 100644 (file)
index 0000000..29f5e33
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * "$Id$"
+ *
+ *   Dither test program for ESP Print Pro.
+ *
+ *   Try the following:
+ *
+ *       testdither 0 255 > filename.ppm
+ *       testdither 0 127 255 > filename.ppm
+ *       testdither 0 85 170 255 > filename.ppm
+ *       testdither 0 63 127 170 198 227 255 > filename.ppm
+ *       testdither 0 210 383 > filename.ppm
+ *       testdither 0 82 255 > filename.ppm
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2005 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:
+ *
+ *   main()  - Test dithering and output a PPM file.
+ *   usage() - Show program usage...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "driver.h"
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+void   usage(void);
+
+
+/*
+ * 'main()' - Test dithering and output a PPM file.
+ */
+
+int                            /* O - Exit status */
+main(int  argc,                        /* I - Number of command-line arguments */
+     char *argv[])             /* I - Command-line arguments */
+{
+  int          x, y;           /* Current coordinate in image */
+  short                line[512];      /* Line to dither */
+  unsigned char        pixels[512],    /* Dither pixels */
+               *pixptr;        /* Pointer in line */
+  int          output;         /* Output pixel */
+  cups_lut_t   *lut;           /* Dither lookup table */
+  cups_dither_t        *dither;        /* Dither state */
+  int          nlutvals;       /* Number of lookup values */
+  float                lutvals[16];    /* Lookup values */
+  int          pixvals[16];    /* Pixel values */
+
+
+ /*
+  * See if we have lookup table values on the command-line...
+  */
+
+  if (argc > 1)
+  {
+   /*
+    * Yes, collect them...
+    */
+
+    nlutvals = 0;
+
+    for (x = 1; x < argc; x ++)
+      if (isdigit(argv[x][0]) && nlutvals < 16)
+      {
+        pixvals[nlutvals] = atoi(argv[x]);
+        lutvals[nlutvals] = atof(argv[x]) / 255.0;
+       nlutvals ++;
+      }
+      else
+        usage();
+
+   /*
+    * See if we have at least 2 values...
+    */
+
+    if (nlutvals < 2)
+      usage();
+  }
+  else
+  {
+   /*
+    * Otherwise use the default 2-entry LUT with values of 0 and 255...
+    */
+
+    nlutvals   = 2;
+    lutvals[0] = 0.0;
+    lutvals[1] = 1.0;
+    pixvals[0] = 0;
+    pixvals[1] = 255;
+  }
+
+ /*
+  * Create the lookup table and dither state...
+  */
+
+  lut    = cupsLutNew(nlutvals, lutvals);
+  dither = cupsDitherNew(512);
+
+ /*
+  * Put out the PGM header for a raw 256x256x8-bit grayscale file...
+  */
+
+  puts("P5\n512\n512\n255");
+
+ /*
+  * Dither 512 lines, which are written out in 256 image lines...
+  */
+
+  for (y = 0; y < 512; y ++)
+  {
+   /*
+    * Create the grayscale data for the current line...
+    */
+
+    for (x = 0; x < 512; x ++)
+      line[x] = 4095 * ((y / 32) * 16 + x / 32) / 255;
+
+   /*
+    * Dither the line...
+    */
+
+    cupsDitherLine(dither, lut, line, 1, pixels);
+
+    if (y == 0)
+    {
+      fputs("DEBUG: pixels =", stderr);
+      for (x = 0; x < 512; x ++)
+        fprintf(stderr, " %d", pixels[x]);
+      fputs("\n", stderr);
+    }
+
+   /*
+    * Add or set the output pixel values...
+    */
+
+    for (x = 0, pixptr = pixels; x < 512; x ++, pixptr ++)
+    {
+      output = 255 - pixvals[*pixptr];
+
+      if (output < 0)
+       putchar(0);
+      else
+       putchar(output);
+    }
+  }
+
+ /*
+  * Free the dither state and lookup table...
+  */
+
+  cupsDitherDelete(dither);
+  cupsLutDelete(lut);
+
+ /*
+  * Return with no errors...
+  */
+
+  return (0);
+}
+
+
+/*
+ * 'usage()' - Show program usage...
+ */
+
+void
+usage(void)
+{
+  puts("Usage: testdither [val1 val2 [... val16]] >filename.ppm");
+  exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
index 47a5eacdc14bd42a10b90696991801d1c7dad857..0d1f299ebb964bc7a5f7eb17ea0b6b8abcfbcf71 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 #include <stdio.h>
-#include <string.h>
+#include <cups/string.h>
 #include <cups/cups.h>
 
 
diff --git a/driver/testrgb.c b/driver/testrgb.c
new file mode 100644 (file)
index 0000000..3fb0ae4
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * "$Id$"
+ *
+ *   Test the new RGB color separation code for ESP Print Pro.
+ *
+ *   Copyright 2007 by Apple Inc.
+ *   Copyright 1993-2006 by Easy Software Products, All Rights Reserved.
+ *
+ *   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:
+ *
+ *   main()       - Do color rgb tests.
+ *   test_gray()  - Test grayscale rgbs...
+ *   test_rgb()   - Test color rgbs...
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/string.h>
+#include "driver.h"
+#include <sys/stat.h>
+
+#ifdef HAVE_LIBLCMS
+#  include <lcms/lcms.h>
+#endif /* HAVE_LIBLCMS */
+
+
+void   test_gray(cups_sample_t *samples, int num_samples,
+                 int cube_size, int num_comps, const char *basename);
+void   test_rgb(cups_sample_t *samples, int num_samples,
+                int cube_size, int num_comps,
+                const char *basename);
+
+
+/*
+ * 'main()' - Do color rgb tests.
+ */
+
+int                                            /* O - Exit status */
+main(int  argc,                                        /* I - Number of command-line arguments */
+     char *argv[])                             /* I - Command-line arguments */
+{
+  static cups_sample_t CMYK[] =                /* Basic 4-color sep */
+                       {
+                         /*{ r,   g,   b   }, { C,   M,   Y,   K   }*/
+                         { { 0,   0,   0   }, { 0,   0,   0,   255 } },
+                         { { 255, 0,   0   }, { 0,   255, 240, 0   } },
+                         { { 0,   255, 0   }, { 200, 0,   200, 0   } },
+                         { { 255, 255, 0   }, { 0,   0,   240, 0   } },
+                         { { 0,   0,   255 }, { 200, 200, 0,   0   } },
+                         { { 255, 0,   255 }, { 0,   200, 0,   0   } },
+                         { { 0,   255, 255 }, { 200, 0,   0,   0   } },
+                         { { 255, 255, 255 }, { 0,   0,   0,   0   } }
+                       };
+
+
+ /*
+  * Make the test directory...
+  */
+
+  mkdir("test", 0755);
+
+ /*
+  * Run tests for CMYK and CMYK separations...
+  */
+
+  test_rgb(CMYK, 8, 2, 4, "test/rgb-cmyk");
+
+  test_gray(CMYK, 8, 2, 4, "test/gray-cmyk");
+
+ /*
+  * Return with no errors...
+  */
+
+  return (0);
+}
+
+
+/*
+ * 'test_gray()' - Test grayscale rgbs...
+ */
+
+void
+test_gray(cups_sample_t *samples,      /* I - Sample values */
+          int           num_samples,   /* I - Number of samples */
+         int           cube_size,      /* I - Cube size */
+          int           num_comps,     /* I - Number of components */
+         const char    *basename)      /* I - Base filename of output */
+{
+  int                  i;              /* Looping var */
+  char                 filename[255];  /* Output filename */
+  char                 line[255];      /* Line from PPM file */
+  int                  width, height;  /* Width and height of test image */
+  int                  x, y;           /* Current coordinate in image */
+  int                  r, g, b;        /* Current RGB color */
+  unsigned char                input[7000];    /* Line to rgbarate */
+  unsigned char                output[48000],  /* Output rgb data */
+                       *outptr;        /* Pointer in output */
+  FILE                 *in;            /* Input PPM file */
+  FILE                 *out[CUPS_MAX_CHAN];
+                                       /* Output PGM files */
+  FILE                 *comp;          /* Composite output */
+  cups_rgb_t           *rgb;           /* Color separation */
+
+
+ /*
+  * Open the test image...
+  */
+
+  in = fopen("image.pgm", "rb");
+  while (fgets(line, sizeof(line), in) != NULL)
+    if (isdigit(line[0]))
+      break;
+
+  sscanf(line, "%d%d", &width, &height);
+
+  fgets(line, sizeof(line), in);
+
+ /*
+  * Create the color rgb...
+  */
+
+  rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps);
+
+ /*
+  * Open the color rgb files...
+  */
+
+  for (i = 0; i < num_comps; i ++)
+  {
+    sprintf(filename, "%s%d.pgm", basename, i);
+    out[i] = fopen(filename, "wb");
+
+    fprintf(out[i], "P5\n%d %d 255\n", width, height);
+  }
+
+  sprintf(filename, "%s.ppm", basename);
+  comp = fopen(filename, "wb");
+
+  fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+  * Read the image and do the rgbs...
+  */
+
+  for (y = 0; y < height; y ++)
+  {
+    fread(input, width, 1, in);
+
+    cupsRGBDoGray(rgb, input, output, width);
+
+    for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+    {
+      for (i = 0; i < num_comps; i ++)
+        putc(255 - outptr[i], out[i]);
+
+      r = 255;
+      g = 255;
+      b = 255;
+
+      r -= outptr[0];
+      g -= outptr[1];
+      b -= outptr[2];
+
+      r -= outptr[3];
+      g -= outptr[3];
+      b -= outptr[3];
+
+      if (num_comps > 4)
+      {
+        r -= outptr[4] / 2;
+       g -= outptr[5] / 2;
+      }
+
+      if (num_comps > 6)
+      {
+        r -= outptr[6] / 2;
+       g -= outptr[6] / 2;
+       b -= outptr[6] / 2;
+      }
+
+      if (r < 0)
+        putc(0, comp);
+      else
+        putc(r, comp);
+
+      if (g < 0)
+        putc(0, comp);
+      else
+        putc(g, comp);
+
+      if (b < 0)
+        putc(0, comp);
+      else
+        putc(b, comp);
+    }
+  }
+
+  for (i = 0; i < num_comps; i ++)
+    fclose(out[i]);
+
+  fclose(comp);
+  fclose(in);
+
+  cupsRGBDelete(rgb);
+}
+
+
+/*
+ * 'test_rgb()' - Test color rgbs...
+ */
+
+void
+test_rgb(cups_sample_t *samples,       /* I - Sample values */
+         int           num_samples,    /* I - Number of samples */
+        int           cube_size,       /* I - Cube size */
+         int           num_comps,      /* I - Number of components */
+        const char    *basename)       /* I - Base filename of output */
+{
+  int                  i;              /* Looping var */
+  char                 filename[255];  /* Output filename */
+  char                 line[255];      /* Line from PPM file */
+  int                  width, height;  /* Width and height of test image */
+  int                  x, y;           /* Current coordinate in image */
+  int                  r, g, b;        /* Current RGB color */
+  unsigned char                input[7000];    /* Line to rgbarate */
+  unsigned char                output[48000],  /* Output rgb data */
+                       *outptr;        /* Pointer in output */
+  FILE                 *in;            /* Input PPM file */
+  FILE                 *out[CUPS_MAX_CHAN];
+                                       /* Output PGM files */
+  FILE                 *comp;          /* Composite output */
+  cups_rgb_t           *rgb;           /* Color separation */
+
+
+ /*
+  * Open the test image...
+  */
+
+  in = fopen("image.ppm", "rb");
+  while (fgets(line, sizeof(line), in) != NULL)
+    if (isdigit(line[0]))
+      break;
+
+  sscanf(line, "%d%d", &width, &height);
+
+  fgets(line, sizeof(line), in);
+
+ /*
+  * Create the color rgb...
+  */
+
+  rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps);
+
+ /*
+  * Open the color rgb files...
+  */
+
+  for (i = 0; i < num_comps; i ++)
+  {
+    sprintf(filename, "%s%d.pgm", basename, i);
+    out[i] = fopen(filename, "wb");
+
+    fprintf(out[i], "P5\n%d %d 255\n", width, height);
+  }
+
+  sprintf(filename, "%s.ppm", basename);
+  comp = fopen(filename, "wb");
+
+  fprintf(comp, "P6\n%d %d 255\n", width, height);
+
+ /*
+  * Read the image and do the rgbs...
+  */
+
+  for (y = 0; y < height; y ++)
+  {
+    fread(input, width, 3, in);
+
+    cupsRGBDoRGB(rgb, input, output, width);
+
+    for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
+    {
+      for (i = 0; i < num_comps; i ++)
+        putc(255 - outptr[i], out[i]);
+
+      r = 255;
+      g = 255;
+      b = 255;
+
+      r -= outptr[0];
+      g -= outptr[1];
+      b -= outptr[2];
+
+      r -= outptr[3];
+      g -= outptr[3];
+      b -= outptr[3];
+
+      if (num_comps > 4)
+      {
+        r -= outptr[4] / 2;
+       g -= outptr[5] / 2;
+      }
+
+      if (num_comps > 6)
+      {
+        r -= outptr[6] / 2;
+       g -= outptr[6] / 2;
+       b -= outptr[6] / 2;
+      }
+
+      if (r < 0)
+        putc(0, comp);
+      else
+        putc(r, comp);
+
+      if (g < 0)
+        putc(0, comp);
+      else
+        putc(g, comp);
+
+      if (b < 0)
+        putc(0, comp);
+      else
+        putc(b, comp);
+    }
+  }
+
+  for (i = 0; i < num_comps; i ++)
+    fclose(out[i]);
+
+  fclose(comp);
+  fclose(in);
+
+  cupsRGBDelete(rgb);
+}
+
+
+/*
+ * End of "$Id$".
+ */
index c1e89fd2806ca25a0745ea07d3525759af7de55d..dee74c3c36aa249755fcee31cef10d4ba11ba0c5 100644 (file)
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-hpgl-attr.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-config.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-main.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
-hpgl-prolog.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-char.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-input.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-hpgl-polygon.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-vector.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-image-bmp.o: image-bmp.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-colorspace.o: image-colorspace.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-gif.o: image-gif.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-jpeg.o: image-jpeg.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-photocd.o: image-photocd.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-pix.o: image-pix.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-png.o: image-png.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-pnm.o: image-pnm.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-sgi.o: image-sgi.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h image-sgi.h
-image-sgilib.o: image-sgilib.c image-sgi.h
-image-sun.o: image-sun.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-tiff.o: image-tiff.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-zoom.o: image-zoom.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image.o: image.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-error.o: error.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-interpret.o: interpret.c ../cups/string.h ../config.h image-private.h \
-  image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/debug.h
-raster.o: raster.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-form-main.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-ps.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-tree.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-gziptoany.o: gziptoany.c ../cups/file.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h ../cups/language.h ../cups/array.h
-imagetops.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image.h raster.h ../cups/i18n.h ../cups/transcode.h
-imagetoraster.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image-private.h image.h raster.h ../cups/debug.h ../cups/i18n.h \
-  ../cups/transcode.h
-common.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h
-pstops.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/file.h \
-  ../cups/array.h ../cups/i18n.h ../cups/transcode.h
-rasterbench.o: rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-rastertoepson.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/ppd.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h raster.h
-rastertohp.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h \
-  raster.h
-rastertolabel.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h \
-  ../cups/transcode.h raster.h
-testimage.o: testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-testraster.o: testraster.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-textcommon.o: textcommon.c textcommon.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-texttops.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-hpgl-attr.32.o: hpgl-attr.c  hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-config.32.o: hpgl-config.c  hpgl-config.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-main.32.o: hpgl-main.c  hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
-hpgl-prolog.32.o: hpgl-prolog.c  hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-char.32.o: hpgl-char.c  hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-input.32.o: hpgl-input.c  hpgl-input.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-hpgl-polygon.32.o: hpgl-polygon.c  hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-vector.32.o: hpgl-vector.c  hpgl-vector.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-image-bmp.32.o: image-bmp.c  image-bmp.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-colorspace.32.o: image-colorspace.c  image-colorspace.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-gif.32.o: image-gif.c  image-gif.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-jpeg.32.o: image-jpeg.c  image-jpeg.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-photocd.32.o: image-photocd.c  image-photocd.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-pix.32.o: image-pix.c  image-pix.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-png.32.o: image-png.c  image-png.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-pnm.32.o: image-pnm.c  image-pnm.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-sgi.32.o: image-sgi.c  image-sgi.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h image-sgi.h
-image-sgilib.32.o: image-sgilib.c  image-sgilib.c image-sgi.h
-image-sun.32.o: image-sun.c  image-sun.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-tiff.32.o: image-tiff.c  image-tiff.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-zoom.32.o: image-zoom.c  image-zoom.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image.32.o: image.c  image.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-error.32.o: error.c  error.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-interpret.32.o: interpret.c  interpret.c ../cups/string.h ../config.h image-private.h \
-  image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/debug.h
-raster.32.o: raster.c  raster.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-form-main.32.o: form-main.c  form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-ps.32.o: form-ps.c  form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-tree.32.o: form-tree.c  form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-gziptoany.32.o: gziptoany.c  gziptoany.c ../cups/file.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h ../cups/language.h ../cups/array.h
-imagetops.32.o: imagetops.c  imagetops.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image.h raster.h ../cups/i18n.h ../cups/transcode.h
-imagetoraster.32.o: imagetoraster.c  imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image-private.h image.h raster.h ../cups/debug.h ../cups/i18n.h \
-  ../cups/transcode.h
-common.32.o: common.c  common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h
-pstops.32.o: pstops.c  pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/file.h \
-  ../cups/array.h ../cups/i18n.h ../cups/transcode.h
-rasterbench.32.o: rasterbench.c  rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-rastertoepson.32.o: rastertoepson.c  rastertoepson.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/ppd.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h raster.h
-rastertohp.32.o: rastertohp.c  rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h \
-  raster.h
-rastertolabel.32.o: rastertolabel.c  rastertolabel.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h \
-  ../cups/transcode.h raster.h
-testimage.32.o: testimage.c  testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-testraster.32.o: testraster.c  testraster.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-textcommon.32.o: textcommon.c  textcommon.c textcommon.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-texttops.32.o: texttops.c  texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-hpgl-attr.64.o: hpgl-attr.c  hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-config.64.o: hpgl-config.c  hpgl-config.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-main.64.o: hpgl-main.c  hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
-hpgl-prolog.64.o: hpgl-prolog.c  hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-char.64.o: hpgl-char.c  hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-hpgl-input.64.o: hpgl-input.c  hpgl-input.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-hpgl-polygon.64.o: hpgl-polygon.c  hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-hpgl-vector.64.o: hpgl-vector.c  hpgl-vector.c hpgltops.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h
-image-bmp.64.o: image-bmp.c  image-bmp.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-colorspace.64.o: image-colorspace.c  image-colorspace.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-gif.64.o: image-gif.c  image-gif.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-jpeg.64.o: image-jpeg.c  image-jpeg.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-photocd.64.o: image-photocd.c  image-photocd.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-pix.64.o: image-pix.c  image-pix.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-png.64.o: image-png.c  image-png.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-pnm.64.o: image-pnm.c  image-pnm.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-sgi.64.o: image-sgi.c  image-sgi.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h image-sgi.h
-image-sgilib.64.o: image-sgilib.c  image-sgilib.c image-sgi.h
-image-sun.64.o: image-sun.c  image-sun.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-image-tiff.64.o: image-tiff.c  image-tiff.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image-zoom.64.o: image-zoom.c  image-zoom.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-image.64.o: image.c  image.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-error.64.o: error.c  error.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-interpret.64.o: interpret.c  interpret.c ../cups/string.h ../config.h image-private.h \
-  image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/debug.h
-raster.64.o: raster.c  raster.c image-private.h image.h raster.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h \
-  ../config.h
-form-main.64.o: form-main.c  form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-ps.64.o: form-ps.c  form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-form-tree.64.o: form-tree.c  form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
-gziptoany.64.o: gziptoany.c  gziptoany.c ../cups/file.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h ../cups/language.h ../cups/array.h
-imagetops.64.o: imagetops.c  imagetops.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image.h raster.h ../cups/i18n.h ../cups/transcode.h
-imagetoraster.64.o: imagetoraster.c  imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  image-private.h image.h raster.h ../cups/debug.h ../cups/i18n.h \
-  ../cups/transcode.h
-common.64.o: common.c  common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h
-pstops.64.o: pstops.c  pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/file.h \
-  ../cups/array.h ../cups/i18n.h ../cups/transcode.h
-rasterbench.64.o: rasterbench.c  rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-rastertoepson.64.o: rastertoepson.c  rastertoepson.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/ppd.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h raster.h
-rastertohp.64.o: rastertohp.c  rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h \
-  raster.h
-rastertolabel.64.o: rastertolabel.c  rastertolabel.c ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h \
-  ../cups/transcode.h raster.h
-testimage.64.o: testimage.c  testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h
-testraster.64.o: testraster.c  testraster.c image-private.h image.h raster.h \
-  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h \
-  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \
-  ../cups/string.h ../config.h
-textcommon.64.o: textcommon.c  textcommon.c textcommon.h common.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \
-  ../config.h ../cups/i18n.h ../cups/transcode.h
-texttops.64.o: texttops.c  texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \
-  ../cups/i18n.h ../cups/transcode.h
+# DO NOT DELETE
+
+hpgl-attr.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-attr.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-attr.o: ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-attr.o: ../cups/string.h ../config.h
+hpgl-config.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-config.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-config.o: ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-config.o: ../cups/language.h ../cups/string.h ../config.h
+hpgl-main.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-main.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-main.o: ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-main.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-prolog.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-prolog.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-prolog.o: ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-prolog.o: ../cups/language.h ../cups/string.h ../config.h
+hpgl-char.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-char.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-char.o: ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-char.o: ../cups/string.h ../config.h
+hpgl-input.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-input.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-input.o: ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-input.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-polygon.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-polygon.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-polygon.o: ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-polygon.o: ../cups/language.h ../cups/string.h ../config.h
+hpgl-vector.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-vector.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-vector.o: ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-vector.o: ../cups/language.h ../cups/string.h ../config.h
+image-bmp.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-bmp.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-bmp.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-bmp.o: ../cups/debug.h ../cups/string.h ../config.h
+image-colorspace.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-colorspace.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-colorspace.o: ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-colorspace.o: ../cups/language.h ../cups/debug.h ../cups/string.h
+image-colorspace.o: ../config.h
+image-gif.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-gif.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-gif.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-gif.o: ../cups/debug.h ../cups/string.h ../config.h
+image-jpeg.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-jpeg.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-jpeg.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-jpeg.o: ../cups/debug.h ../cups/string.h ../config.h
+image-photocd.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-photocd.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-photocd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-photocd.o: ../cups/language.h ../cups/debug.h ../cups/string.h
+image-photocd.o: ../config.h
+image-pix.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pix.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pix.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-pix.o: ../cups/debug.h ../cups/string.h ../config.h
+image-png.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-png.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-png.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-png.o: ../cups/debug.h ../cups/string.h ../config.h
+image-pnm.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pnm.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pnm.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-pnm.o: ../cups/debug.h ../cups/string.h ../config.h
+image-sgi.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sgi.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sgi.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-sgi.o: ../cups/debug.h ../cups/string.h ../config.h image-sgi.h
+image-sgilib.o: image-sgi.h
+image-sun.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sun.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sun.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-sun.o: ../cups/debug.h ../cups/string.h ../config.h
+image-tiff.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-tiff.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-tiff.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-tiff.o: ../cups/debug.h ../cups/string.h ../config.h
+image-zoom.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-zoom.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-zoom.o: ../cups/array.h ../cups/file.h ../cups/language.h
+image-zoom.o: ../cups/debug.h ../cups/string.h ../config.h
+image.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+image.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+image.o: ../cups/string.h ../config.h
+error.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+error.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+error.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+error.o: ../cups/string.h ../config.h
+interpret.o: ../cups/string.h ../config.h image-private.h image.h
+interpret.o: ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+interpret.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+interpret.o: ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+raster.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+raster.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.o: ../cups/string.h ../config.h
+form-main.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-main.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-main.o: ../cups/file.h ../cups/language.h ../cups/language.h
+form-main.o: ../cups/string.h ../config.h
+form-ps.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-ps.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+form-ps.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+form-tree.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-tree.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-tree.o: ../cups/file.h ../cups/language.h ../cups/language.h
+form-tree.o: ../cups/string.h ../config.h
+gziptoany.o: ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h
+gziptoany.o: ../cups/i18n.h ../cups/transcode.h ../cups/language.h
+gziptoany.o: ../cups/array.h
+imagetops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetops.o: ../cups/file.h ../cups/language.h ../cups/language.h
+imagetops.o: ../cups/string.h ../config.h image.h ../cups/raster.h
+imagetops.o: ../cups/i18n.h ../cups/transcode.h
+imagetoraster.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetoraster.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetoraster.o: ../cups/file.h ../cups/language.h ../cups/language.h
+imagetoraster.o: ../cups/string.h ../config.h image-private.h image.h
+imagetoraster.o: ../cups/raster.h ../cups/debug.h ../cups/i18n.h
+imagetoraster.o: ../cups/transcode.h
+common.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+common.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+common.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pdftops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+pdftops.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+pdftops.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+pstops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+pstops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+pstops.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pstops.o: ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h
+rasterbench.o: ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rasterbench.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rasterbench.o: ../cups/file.h ../cups/language.h
+rastertoepson.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertoepson.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertoepson.o: ../cups/file.h ../cups/language.h ../cups/ppd.h
+rastertoepson.o: ../cups/string.h ../config.h ../cups/i18n.h
+rastertoepson.o: ../cups/transcode.h ../cups/raster.h
+rastertohp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertohp.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertohp.o: ../cups/file.h ../cups/language.h ../cups/string.h ../config.h
+rastertohp.o: ../cups/i18n.h ../cups/transcode.h ../cups/raster.h
+rastertolabel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertolabel.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertolabel.o: ../cups/file.h ../cups/language.h ../cups/string.h
+rastertolabel.o: ../config.h ../cups/i18n.h ../cups/transcode.h
+rastertolabel.o: ../cups/raster.h
+testimage.o: image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h
+testimage.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testimage.o: ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h
+testraster.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testraster.o: ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.o: ../cups/debug.h ../cups/string.h ../config.h
+textcommon.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h
+textcommon.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+textcommon.o: ../cups/array.h ../cups/file.h ../cups/language.h
+textcommon.o: ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h
+textcommon.o: ../cups/transcode.h
+texttops.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+texttops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+texttops.o: ../cups/language.h ../cups/language.h ../cups/string.h
+texttops.o: ../config.h ../cups/i18n.h ../cups/transcode.h
+# DO NOT DELETE
+
+hpgl-attr.32.o: hpgl-attr.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-attr.32.o: hpgl-attr.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-attr.32.o: hpgl-attr.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-attr.32.o: hpgl-attr.c  ../cups/string.h ../config.h
+hpgl-config.32.o: hpgl-config.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-config.32.o: hpgl-config.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-config.32.o: hpgl-config.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-config.32.o: hpgl-config.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-main.32.o: hpgl-main.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-main.32.o: hpgl-main.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-main.32.o: hpgl-main.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-main.32.o: hpgl-main.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-prolog.32.o: hpgl-prolog.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-prolog.32.o: hpgl-prolog.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-prolog.32.o: hpgl-prolog.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-prolog.32.o: hpgl-prolog.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-char.32.o: hpgl-char.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-char.32.o: hpgl-char.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-char.32.o: hpgl-char.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-char.32.o: hpgl-char.c  ../cups/string.h ../config.h
+hpgl-input.32.o: hpgl-input.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-input.32.o: hpgl-input.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-input.32.o: hpgl-input.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-input.32.o: hpgl-input.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-polygon.32.o: hpgl-polygon.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-polygon.32.o: hpgl-polygon.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-polygon.32.o: hpgl-polygon.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-polygon.32.o: hpgl-polygon.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-vector.32.o: hpgl-vector.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-vector.32.o: hpgl-vector.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-vector.32.o: hpgl-vector.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-vector.32.o: hpgl-vector.c  ../cups/language.h ../cups/string.h ../config.h
+image-bmp.32.o: image-bmp.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-bmp.32.o: image-bmp.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-bmp.32.o: image-bmp.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-bmp.32.o: image-bmp.c  ../cups/debug.h ../cups/string.h ../config.h
+image-colorspace.32.o: image-colorspace.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-colorspace.32.o: image-colorspace.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-colorspace.32.o: image-colorspace.c  ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-colorspace.32.o: image-colorspace.c  ../cups/language.h ../cups/debug.h ../cups/string.h
+image-colorspace.32.o: image-colorspace.c  ../config.h
+image-gif.32.o: image-gif.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-gif.32.o: image-gif.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-gif.32.o: image-gif.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-gif.32.o: image-gif.c  ../cups/debug.h ../cups/string.h ../config.h
+image-jpeg.32.o: image-jpeg.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-jpeg.32.o: image-jpeg.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-jpeg.32.o: image-jpeg.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-jpeg.32.o: image-jpeg.c  ../cups/debug.h ../cups/string.h ../config.h
+image-photocd.32.o: image-photocd.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-photocd.32.o: image-photocd.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-photocd.32.o: image-photocd.c  ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-photocd.32.o: image-photocd.c  ../cups/language.h ../cups/debug.h ../cups/string.h
+image-photocd.32.o: image-photocd.c  ../config.h
+image-pix.32.o: image-pix.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pix.32.o: image-pix.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pix.32.o: image-pix.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-pix.32.o: image-pix.c  ../cups/debug.h ../cups/string.h ../config.h
+image-png.32.o: image-png.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-png.32.o: image-png.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-png.32.o: image-png.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-png.32.o: image-png.c  ../cups/debug.h ../cups/string.h ../config.h
+image-pnm.32.o: image-pnm.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pnm.32.o: image-pnm.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pnm.32.o: image-pnm.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-pnm.32.o: image-pnm.c  ../cups/debug.h ../cups/string.h ../config.h
+image-sgi.32.o: image-sgi.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sgi.32.o: image-sgi.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sgi.32.o: image-sgi.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-sgi.32.o: image-sgi.c  ../cups/debug.h ../cups/string.h ../config.h image-sgi.h
+image-sgilib.32.o: image-sgilib.c  image-sgi.h
+image-sun.32.o: image-sun.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sun.32.o: image-sun.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sun.32.o: image-sun.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-sun.32.o: image-sun.c  ../cups/debug.h ../cups/string.h ../config.h
+image-tiff.32.o: image-tiff.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-tiff.32.o: image-tiff.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-tiff.32.o: image-tiff.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-tiff.32.o: image-tiff.c  ../cups/debug.h ../cups/string.h ../config.h
+image-zoom.32.o: image-zoom.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-zoom.32.o: image-zoom.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-zoom.32.o: image-zoom.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-zoom.32.o: image-zoom.c  ../cups/debug.h ../cups/string.h ../config.h
+image.32.o: image.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image.32.o: image.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image.32.o: image.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+image.32.o: image.c  ../cups/string.h ../config.h
+error.32.o: error.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+error.32.o: error.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+error.32.o: error.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+error.32.o: error.c  ../cups/string.h ../config.h
+interpret.32.o: interpret.c  ../cups/string.h ../config.h image-private.h image.h
+interpret.32.o: interpret.c  ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+interpret.32.o: interpret.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+interpret.32.o: interpret.c  ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.32.o: raster.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+raster.32.o: raster.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+raster.32.o: raster.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.32.o: raster.c  ../cups/string.h ../config.h
+form-main.32.o: form-main.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-main.32.o: form-main.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-main.32.o: form-main.c  ../cups/file.h ../cups/language.h ../cups/language.h
+form-main.32.o: form-main.c  ../cups/string.h ../config.h
+form-ps.32.o: form-ps.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-ps.32.o: form-ps.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+form-ps.32.o: form-ps.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+form-tree.32.o: form-tree.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-tree.32.o: form-tree.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-tree.32.o: form-tree.c  ../cups/file.h ../cups/language.h ../cups/language.h
+form-tree.32.o: form-tree.c  ../cups/string.h ../config.h
+gziptoany.32.o: gziptoany.c  ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h
+gziptoany.32.o: gziptoany.c  ../cups/i18n.h ../cups/transcode.h ../cups/language.h
+gziptoany.32.o: gziptoany.c  ../cups/array.h
+imagetops.32.o: imagetops.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetops.32.o: imagetops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetops.32.o: imagetops.c  ../cups/file.h ../cups/language.h ../cups/language.h
+imagetops.32.o: imagetops.c  ../cups/string.h ../config.h image.h ../cups/raster.h
+imagetops.32.o: imagetops.c  ../cups/i18n.h ../cups/transcode.h
+imagetoraster.32.o: imagetoraster.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetoraster.32.o: imagetoraster.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetoraster.32.o: imagetoraster.c  ../cups/file.h ../cups/language.h ../cups/language.h
+imagetoraster.32.o: imagetoraster.c  ../cups/string.h ../config.h image-private.h image.h
+imagetoraster.32.o: imagetoraster.c  ../cups/raster.h ../cups/debug.h ../cups/i18n.h
+imagetoraster.32.o: imagetoraster.c  ../cups/transcode.h
+common.32.o: common.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+common.32.o: common.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+common.32.o: common.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pdftops.32.o: pdftops.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+pdftops.32.o: pdftops.c  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+pdftops.32.o: pdftops.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+pstops.32.o: pstops.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+pstops.32.o: pstops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+pstops.32.o: pstops.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pstops.32.o: pstops.c  ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h
+rasterbench.32.o: rasterbench.c  ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rasterbench.32.o: rasterbench.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rasterbench.32.o: rasterbench.c  ../cups/file.h ../cups/language.h
+rastertoepson.32.o: rastertoepson.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertoepson.32.o: rastertoepson.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertoepson.32.o: rastertoepson.c  ../cups/file.h ../cups/language.h ../cups/ppd.h
+rastertoepson.32.o: rastertoepson.c  ../cups/string.h ../config.h ../cups/i18n.h
+rastertoepson.32.o: rastertoepson.c  ../cups/transcode.h ../cups/raster.h
+rastertohp.32.o: rastertohp.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertohp.32.o: rastertohp.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertohp.32.o: rastertohp.c  ../cups/file.h ../cups/language.h ../cups/string.h ../config.h
+rastertohp.32.o: rastertohp.c  ../cups/i18n.h ../cups/transcode.h ../cups/raster.h
+rastertolabel.32.o: rastertolabel.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertolabel.32.o: rastertolabel.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertolabel.32.o: rastertolabel.c  ../cups/file.h ../cups/language.h ../cups/string.h
+rastertolabel.32.o: rastertolabel.c  ../config.h ../cups/i18n.h ../cups/transcode.h
+rastertolabel.32.o: rastertolabel.c  ../cups/raster.h
+testimage.32.o: testimage.c  image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h
+testimage.32.o: testimage.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testimage.32.o: testimage.c  ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.32.o: testraster.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+testraster.32.o: testraster.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testraster.32.o: testraster.c  ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.32.o: testraster.c  ../cups/debug.h ../cups/string.h ../config.h
+textcommon.32.o: textcommon.c  textcommon.h common.h ../cups/cups.h ../cups/ipp.h
+textcommon.32.o: textcommon.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+textcommon.32.o: textcommon.c  ../cups/array.h ../cups/file.h ../cups/language.h
+textcommon.32.o: textcommon.c  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h
+textcommon.32.o: textcommon.c  ../cups/transcode.h
+texttops.32.o: texttops.c  textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+texttops.32.o: texttops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+texttops.32.o: texttops.c  ../cups/language.h ../cups/language.h ../cups/string.h
+texttops.32.o: texttops.c  ../config.h ../cups/i18n.h ../cups/transcode.h
+# DO NOT DELETE
+
+hpgl-attr.64.o: hpgl-attr.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-attr.64.o: hpgl-attr.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-attr.64.o: hpgl-attr.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-attr.64.o: hpgl-attr.c  ../cups/string.h ../config.h
+hpgl-config.64.o: hpgl-config.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-config.64.o: hpgl-config.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-config.64.o: hpgl-config.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-config.64.o: hpgl-config.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-main.64.o: hpgl-main.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-main.64.o: hpgl-main.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-main.64.o: hpgl-main.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-main.64.o: hpgl-main.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-prolog.64.o: hpgl-prolog.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-prolog.64.o: hpgl-prolog.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-prolog.64.o: hpgl-prolog.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-prolog.64.o: hpgl-prolog.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-char.64.o: hpgl-char.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-char.64.o: hpgl-char.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-char.64.o: hpgl-char.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-char.64.o: hpgl-char.c  ../cups/string.h ../config.h
+hpgl-input.64.o: hpgl-input.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-input.64.o: hpgl-input.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+hpgl-input.64.o: hpgl-input.c  ../cups/file.h ../cups/language.h ../cups/language.h
+hpgl-input.64.o: hpgl-input.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+hpgl-polygon.64.o: hpgl-polygon.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-polygon.64.o: hpgl-polygon.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-polygon.64.o: hpgl-polygon.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-polygon.64.o: hpgl-polygon.c  ../cups/language.h ../cups/string.h ../config.h
+hpgl-vector.64.o: hpgl-vector.c  hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-vector.64.o: hpgl-vector.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+hpgl-vector.64.o: hpgl-vector.c  ../cups/array.h ../cups/file.h ../cups/language.h
+hpgl-vector.64.o: hpgl-vector.c  ../cups/language.h ../cups/string.h ../config.h
+image-bmp.64.o: image-bmp.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-bmp.64.o: image-bmp.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-bmp.64.o: image-bmp.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-bmp.64.o: image-bmp.c  ../cups/debug.h ../cups/string.h ../config.h
+image-colorspace.64.o: image-colorspace.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-colorspace.64.o: image-colorspace.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-colorspace.64.o: image-colorspace.c  ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-colorspace.64.o: image-colorspace.c  ../cups/language.h ../cups/debug.h ../cups/string.h
+image-colorspace.64.o: image-colorspace.c  ../config.h
+image-gif.64.o: image-gif.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-gif.64.o: image-gif.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-gif.64.o: image-gif.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-gif.64.o: image-gif.c  ../cups/debug.h ../cups/string.h ../config.h
+image-jpeg.64.o: image-jpeg.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-jpeg.64.o: image-jpeg.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-jpeg.64.o: image-jpeg.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-jpeg.64.o: image-jpeg.c  ../cups/debug.h ../cups/string.h ../config.h
+image-photocd.64.o: image-photocd.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-photocd.64.o: image-photocd.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+image-photocd.64.o: image-photocd.c  ../cups/ppd.h ../cups/array.h ../cups/file.h
+image-photocd.64.o: image-photocd.c  ../cups/language.h ../cups/debug.h ../cups/string.h
+image-photocd.64.o: image-photocd.c  ../config.h
+image-pix.64.o: image-pix.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pix.64.o: image-pix.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pix.64.o: image-pix.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-pix.64.o: image-pix.c  ../cups/debug.h ../cups/string.h ../config.h
+image-png.64.o: image-png.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-png.64.o: image-png.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-png.64.o: image-png.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-png.64.o: image-png.c  ../cups/debug.h ../cups/string.h ../config.h
+image-pnm.64.o: image-pnm.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-pnm.64.o: image-pnm.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-pnm.64.o: image-pnm.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-pnm.64.o: image-pnm.c  ../cups/debug.h ../cups/string.h ../config.h
+image-sgi.64.o: image-sgi.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sgi.64.o: image-sgi.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sgi.64.o: image-sgi.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-sgi.64.o: image-sgi.c  ../cups/debug.h ../cups/string.h ../config.h image-sgi.h
+image-sgilib.64.o: image-sgilib.c  image-sgi.h
+image-sun.64.o: image-sun.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-sun.64.o: image-sun.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-sun.64.o: image-sun.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-sun.64.o: image-sun.c  ../cups/debug.h ../cups/string.h ../config.h
+image-tiff.64.o: image-tiff.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-tiff.64.o: image-tiff.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-tiff.64.o: image-tiff.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-tiff.64.o: image-tiff.c  ../cups/debug.h ../cups/string.h ../config.h
+image-zoom.64.o: image-zoom.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image-zoom.64.o: image-zoom.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image-zoom.64.o: image-zoom.c  ../cups/array.h ../cups/file.h ../cups/language.h
+image-zoom.64.o: image-zoom.c  ../cups/debug.h ../cups/string.h ../config.h
+image.64.o: image.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+image.64.o: image.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+image.64.o: image.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+image.64.o: image.c  ../cups/string.h ../config.h
+error.64.o: error.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+error.64.o: error.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+error.64.o: error.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+error.64.o: error.c  ../cups/string.h ../config.h
+interpret.64.o: interpret.c  ../cups/string.h ../config.h image-private.h image.h
+interpret.64.o: interpret.c  ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+interpret.64.o: interpret.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+interpret.64.o: interpret.c  ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.64.o: raster.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+raster.64.o: raster.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+raster.64.o: raster.c  ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h
+raster.64.o: raster.c  ../cups/string.h ../config.h
+form-main.64.o: form-main.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-main.64.o: form-main.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-main.64.o: form-main.c  ../cups/file.h ../cups/language.h ../cups/language.h
+form-main.64.o: form-main.c  ../cups/string.h ../config.h
+form-ps.64.o: form-ps.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-ps.64.o: form-ps.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+form-ps.64.o: form-ps.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+form-tree.64.o: form-tree.c  form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-tree.64.o: form-tree.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+form-tree.64.o: form-tree.c  ../cups/file.h ../cups/language.h ../cups/language.h
+form-tree.64.o: form-tree.c  ../cups/string.h ../config.h
+gziptoany.64.o: gziptoany.c  ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h
+gziptoany.64.o: gziptoany.c  ../cups/i18n.h ../cups/transcode.h ../cups/language.h
+gziptoany.64.o: gziptoany.c  ../cups/array.h
+imagetops.64.o: imagetops.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetops.64.o: imagetops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetops.64.o: imagetops.c  ../cups/file.h ../cups/language.h ../cups/language.h
+imagetops.64.o: imagetops.c  ../cups/string.h ../config.h image.h ../cups/raster.h
+imagetops.64.o: imagetops.c  ../cups/i18n.h ../cups/transcode.h
+imagetoraster.64.o: imagetoraster.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetoraster.64.o: imagetoraster.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+imagetoraster.64.o: imagetoraster.c  ../cups/file.h ../cups/language.h ../cups/language.h
+imagetoraster.64.o: imagetoraster.c  ../cups/string.h ../config.h image-private.h image.h
+imagetoraster.64.o: imagetoraster.c  ../cups/raster.h ../cups/debug.h ../cups/i18n.h
+imagetoraster.64.o: imagetoraster.c  ../cups/transcode.h
+common.64.o: common.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+common.64.o: common.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+common.64.o: common.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pdftops.64.o: pdftops.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+pdftops.64.o: pdftops.c  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+pdftops.64.o: pdftops.c  ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h
+pstops.64.o: pstops.c  common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+pstops.64.o: pstops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+pstops.64.o: pstops.c  ../cups/language.h ../cups/language.h ../cups/string.h ../config.h
+pstops.64.o: pstops.c  ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h
+rasterbench.64.o: rasterbench.c  ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rasterbench.64.o: rasterbench.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rasterbench.64.o: rasterbench.c  ../cups/file.h ../cups/language.h
+rastertoepson.64.o: rastertoepson.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertoepson.64.o: rastertoepson.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertoepson.64.o: rastertoepson.c  ../cups/file.h ../cups/language.h ../cups/ppd.h
+rastertoepson.64.o: rastertoepson.c  ../cups/string.h ../config.h ../cups/i18n.h
+rastertoepson.64.o: rastertoepson.c  ../cups/transcode.h ../cups/raster.h
+rastertohp.64.o: rastertohp.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertohp.64.o: rastertohp.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertohp.64.o: rastertohp.c  ../cups/file.h ../cups/language.h ../cups/string.h ../config.h
+rastertohp.64.o: rastertohp.c  ../cups/i18n.h ../cups/transcode.h ../cups/raster.h
+rastertolabel.64.o: rastertolabel.c  ../cups/cups.h ../cups/ipp.h ../cups/http.h
+rastertolabel.64.o: rastertolabel.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+rastertolabel.64.o: rastertolabel.c  ../cups/file.h ../cups/language.h ../cups/string.h
+rastertolabel.64.o: rastertolabel.c  ../config.h ../cups/i18n.h ../cups/transcode.h
+rastertolabel.64.o: rastertolabel.c  ../cups/raster.h
+testimage.64.o: testimage.c  image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h
+testimage.64.o: testimage.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testimage.64.o: testimage.c  ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.64.o: testraster.c  image-private.h image.h ../cups/raster.h ../cups/cups.h
+testraster.64.o: testraster.c  ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+testraster.64.o: testraster.c  ../cups/array.h ../cups/file.h ../cups/language.h
+testraster.64.o: testraster.c  ../cups/debug.h ../cups/string.h ../config.h
+textcommon.64.o: textcommon.c  textcommon.h common.h ../cups/cups.h ../cups/ipp.h
+textcommon.64.o: textcommon.c  ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+textcommon.64.o: textcommon.c  ../cups/array.h ../cups/file.h ../cups/language.h
+textcommon.64.o: textcommon.c  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h
+textcommon.64.o: textcommon.c  ../cups/transcode.h
+texttops.64.o: texttops.c  textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+texttops.64.o: texttops.c  ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+texttops.64.o: texttops.c  ../cups/language.h ../cups/language.h ../cups/string.h
+texttops.64.o: texttops.c  ../config.h ../cups/i18n.h ../cups/transcode.h
index 5f6a4aca52793b783b4e320c5c36c11f09b93d06..068fb776002551da41466009d7f73590ec98de25 100644 (file)
@@ -71,8 +71,8 @@ depend:
        makedepend -Y -I.. -fDependencies.tmp $(OBJS:.o=.c) >/dev/null 2>&1
        $(RM) Dependencies
        cp Dependencies.tmp Dependencies
-       sed -r -e '1,$$s/^([^.]+)\.o:/\1\.32.o: \1\.c /' Dependencies.tmp >>Dependencies
-       sed -r -e '1,$$s/^([^.]+)\.o:/\1\.64.o: \1\.c /' Dependencies.tmp >>Dependencies
+       sed -E -e '1,$$s/^([^.]+)\.o:/\1\.32.o: \1\.c /' Dependencies.tmp >>Dependencies
+       sed -E -e '1,$$s/^([^.]+)\.o:/\1\.64.o: \1\.c /' Dependencies.tmp >>Dependencies
        $(RM) Dependencies.tmp
 
 
@@ -113,7 +113,6 @@ installstatic:
 installhdrs:
        $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups
        $(INSTALL_DATA) image.h $(INCLUDEDIR)/cups
-       $(INSTALL_DATA) raster.h $(INCLUDEDIR)/cups
 
 install32bit:
        $(INSTALL_DIR) -m 755 $(LIB32DIR)
@@ -147,7 +146,6 @@ uninstall: $(UNINSTALL32) $(UNINSTALL64)
        $(RM) $(LIBDIR)/libcupsimage.so.2
        -$(RMDIR) $(LIBDIR)
        $(RM) $(INCLUDEDIR)/cups/image.h
-       $(RM) $(INCLUDEDIR)/cups/raster.h
        -$(RMDIR) $(INCLUDEDIR)/cups
 
 uninstall32bit:
@@ -170,7 +168,8 @@ apihelp:
        mxmldoc --section "Programming" --title "Raster API" \
                --css ../doc/cups-printable.css \
                --header api-raster.header --intro api-raster.shtml \
-               raster.h interpret.c raster.c >../doc/help/api-raster.html
+               ../cups/raster.h interpret.c raster.c \
+               >../doc/help/api-raster.html
 
 framedhelp:
        echo Generating CUPS API help files...
@@ -178,7 +177,7 @@ framedhelp:
                --framed ../cups/api-raster \
                --css ../doc/cups-printable.css \
                --header api-raster.header --intro api-raster.shtml \
-               raster.h interpret.c raster.c
+               ../cups/raster.h interpret.c raster.c
 
 
 #
index 9921bce4d8245951ae0419ff23e67973f4a42185..dcf03a7e6235bc16cba7fdf59541af26624ed73d 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #  include "image.h"
-#  include "raster.h"
 #  include <cups/cups.h>
 #  include <cups/debug.h>
 #  include <cups/string.h>
index 6dcba98388e666760a7d3d8098cd66bca7dc9985..b2de9ad99999a5750f3c35bc68418f2e937aab56 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #  include <stdio.h>
-#  include "raster.h"
+#  include <cups/raster.h>
 
 #  ifdef __cplusplus
 extern "C" {
index 1a6a27babeb13adea306a1f636275314e9582023..bc4a806ecdba4015ae546800770b0b26bf280761 100644 (file)
@@ -37,7 +37,6 @@
 
 #include "common.h"
 #include "image-private.h"
-#include "raster.h"
 #include <unistd.h>
 #include <math.h>
 #include <cups/i18n.h>
index a165bed7a7741a0cd705f4aaab1da46563440b09..acfb8be76a8f2dfa66e3abb24601f24c0e9b4e30 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Raster benchmark program for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -26,7 +26,7 @@
  * Include necessary headers...
  */
 
-#include "raster.h"
+#include <cups/raster.h>
 #include <stdlib.h>
 #include <sys/time.h>
 #include <signal.h>
index a50d977c738368c7845d985929052063e3fd4e10..f1ad6547cf87b1a9364972c25228f29d97a3819b 100644 (file)
@@ -34,7 +34,7 @@
 #include <cups/ppd.h>
 #include <cups/string.h>
 #include <cups/i18n.h>
-#include "raster.h"
+#include <cups/raster.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
index f35b58ca7639e8a586681a422a16efa1a6d35f4c..04ac4017a57a2ae63a23068b472387d4ec28aa9d 100644 (file)
@@ -34,7 +34,7 @@
 #include <cups/cups.h>
 #include <cups/string.h>
 #include <cups/i18n.h>
-#include "raster.h"
+#include <cups/raster.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
index 26a254f9a5e89111a565d949969d7c2ed4e2cb3b..05adc03977ef4b15c5ea9d05a408ef6436c173b0 100644 (file)
@@ -33,7 +33,7 @@
 #include <cups/cups.h>
 #include <cups/string.h>
 #include <cups/i18n.h>
-#include "raster.h"
+#include <cups/raster.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
index f7cbc8913dbf54613e152e15505067956db1289b..b6d9fe8cb41f9b433886eff46c4c9cd121e88ee2 100644 (file)
@@ -3,7 +3,7 @@
 #
 #   Locale file makefile for the Common UNIX Printing System (CUPS).
 #
-#   Copyright 2007 by Apple Inc.
+#   Copyright 2007-2008 by Apple Inc.
 #   Copyright 1993-2007 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -55,6 +55,7 @@ install-languages:
                if test -f cups_$$loc.po; then \
                        $(INSTALL_DIR) -m 755 $(LOCALEDIR)/$$loc ; \
                        $(INSTALL_DATA) cups_$$loc.po $(LOCALEDIR)/$$loc/cups_$$loc.po ; \
+                       $(INSTALL_DATA) ppdc_$$loc.po $(LOCALEDIR)/$$loc/ppdc_$$loc.po ; \
                fi ; \
        done
 
@@ -68,6 +69,7 @@ uninstall: $(UNINSTALL_LANGUAGES)
 uninstall-languages:
        -for loc in $(LANGUAGES) ; do \
                $(RM) $(LOCALEDIR)/$$loc/cups_$$loc.po ; \
+               $(RM) $(LOCALEDIR)/$$loc/ppdc_$$loc.po ; \
        done
 
 
diff --git a/locale/ppdc.pot b/locale/ppdc.pot
new file mode 100644 (file)
index 0000000..96b4644
--- /dev/null
@@ -0,0 +1,592 @@
+# Template message catalog for the CUPS PPD compiler.
+msgid "Color Mode"
+msgstr "Color Mode"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options Installed"
+
+msgid "Paper Type"
+msgstr "Paper Type"
+
+msgid "Duplex Unit"
+msgstr "Duplex Unit"
+
+msgid "Optional Input Tray"
+msgstr "Optional Input Tray"
+
+msgid "Optional Hard Disk"
+msgstr "Optional Hard Disk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Closed Booklet Envelope"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A3 Oversize Tray"
+msgstr "A3 Oversize Tray"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "A6 Card"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Auto Select"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Black"
+
+msgid "Bond Paper"
+msgstr "Bond Paper"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 10"
+msgstr "Bin 10"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Bin 9"
+msgstr "Bin 9"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Bypass Tray"
+msgstr "Bypass Tray"
+
+msgid "9 Envelope"
+msgstr "9 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Card Stock"
+
+msgid "Paper Cassette"
+msgstr "Paper Cassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Heavy Weight Matte"
+
+msgid "Colored Paper"
+msgstr "Colored Paper"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Long Edge"
+msgstr "Long Edge"
+
+msgid "Short Edge"
+msgstr "Short Edge"
+
+msgid "#10 Envelope"
+msgstr "#10 Envelope"
+
+msgid "C4 Envelope"
+msgstr "C4 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL Envelope"
+
+msgid "B4 Envelope"
+msgstr "B4 Envelope"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelope"
+
+msgid "Monarch Envelope"
+msgstr "Monarch Envelope"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 Envelope"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Finisher Tray"
+msgstr "Finisher Tray"
+
+msgid "Glossy Paper"
+msgstr "Glossy Paper"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "Black and White"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet Paper"
+
+msgid "Installed"
+msgstr "Installed"
+
+msgid "Iron-On Transfer"
+msgstr "Iron-On Transfer"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Hagaki"
+msgstr "Hagaki"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Lower Tray"
+
+msgid "Mailbox"
+msgstr "Mailbox"
+
+msgid "Manual Feed"
+msgstr "Manual Feed"
+
+msgid "Manual Envelope"
+msgstr "Manual Envelope"
+
+msgid "Middle Tray"
+msgstr "Middle Tray"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Not Installed"
+msgstr "Not Installed"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Tray 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Tray 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Tray 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Tray 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Tray 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Tray 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Tray 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Tray 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Tray 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Tray 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Photo Paper"
+
+msgid "Plain Paper"
+msgstr "Plain Paper"
+
+msgid "Letterhead"
+msgstr "Letterhead"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Recycled Paper"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Thick Paper"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6"
+
+msgid "Upper Tray"
+msgstr "Upper Tray"
+
diff --git a/locale/ppdc_da.po b/locale/ppdc_da.po
new file mode 100644 (file)
index 0000000..0ec32c5
--- /dev/null
@@ -0,0 +1,345 @@
+msgid "Color Mode"
+msgstr "Farveindstilling"
+
+msgid "2-Sided Printing"
+msgstr "Dupleks"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Installeret tilbehør"
+
+msgid "Paper Type"
+msgstr "Papirtype"
+
+msgid "Duplex Unit"
+msgstr "Duplexenhed"
+
+msgid "Optional Input Tray"
+msgstr "Magasiner, der fås som tilbehør"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 "
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Overstørrrelse)"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (lille)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "Auto Select"
+msgstr "Vælg automatisk"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Sort"
+
+msgid "Bond Paper"
+msgstr "Kontraktpapir"
+
+msgid "Bin 1"
+msgstr "Indvendig bakke 2"
+
+msgid "Bin 2"
+msgstr "Postkasse 2"
+
+msgid "Bin 3"
+msgstr "Postkasse 3"
+
+msgid "Bin 4"
+msgstr "Postkasse 4"
+
+msgid "Bin 5"
+msgstr "Postkasse 5"
+
+msgid "Bin 6"
+msgstr "Postkasse 6"
+
+msgid "Bin 7"
+msgstr "Postkasse 7"
+
+msgid "Bin 8"
+msgstr "Postkasse 8"
+
+msgid "Black Only"
+msgstr "Sort"
+
+msgid "Bypass Tray"
+msgstr "Magasin 1 (MPT)"
+
+msgid "C5 Envelope"
+msgstr "C5-konvolutter"
+
+msgid "Envelope C6"
+msgstr "C6-konvolut"
+
+msgid "Color"
+msgstr "Farve"
+
+msgid "Card Stock"
+msgstr "Indekskort"
+
+msgid "Paper Cassette"
+msgstr "Papirkassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Bestrøget"
+
+msgid "Colored Paper"
+msgstr "Farve"
+
+msgid "Env Comm10"
+msgstr "Comm10-konvolutter"
+
+msgid "Printer Default"
+msgstr "Printerstandard"
+
+msgid "Long Edge"
+msgstr "Lang kant"
+
+msgid "Short Edge"
+msgstr "Kort kant"
+
+msgid "#10 Envelope"
+msgstr "#10-kuvert"
+
+msgid "C4 Envelope"
+msgstr "Konvolut C4 (324 x 229)"
+
+msgid "C5 Envelope"
+msgstr "C5-kuvert"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL-kuvert"
+
+msgid "Env ISO B5"
+msgstr "Konv ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Monarch Envelope"
+msgstr "Monarch-kuvert"
+
+msgid "#6 3/4 Envelope"
+msgstr "Nr. 6 3/4-konvolut"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Konvolut"
+
+msgid "7.25 x 10.5\""
+msgstr "7,25 x 10,5\""
+
+msgid "Off"
+msgstr "Fra"
+
+msgid "Glossy Paper"
+msgstr "Glittet papir"
+
+msgid "Black and White"
+msgstr "Grå"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Faneblade"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet papir"
+
+msgid "Iron-On Transfer"
+msgstr "Stryg-på-ark"
+
+msgid "Labels"
+msgstr "Etiketter"
+
+msgid "Tray 4"
+msgstr "Bakke 4"
+
+msgid "US Legal"
+msgstr "8.5 x 14\""
+
+msgid "Legal (Small)"
+msgstr "Legal (lille)"
+
+msgid "US Letter"
+msgstr "8.5 x 11\"(falset)"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (lille)"
+
+msgid "Lower Tray"
+msgstr "Bakke 3"
+
+msgid "Manual Feed"
+msgstr "Manuel"
+
+msgid "Middle Tray"
+msgstr "Bakke 2"
+
+msgid "Off"
+msgstr "Ingen"
+
+msgid "Not Installed"
+msgstr "Ikke installeret"
+
+msgid "On"
+msgstr "Til"
+
+msgid "None"
+msgstr "Fra"
+
+msgid "Bin 1"
+msgstr "Bakke 1"
+
+msgid "Bin 2"
+msgstr "Bakke 2"
+
+msgid "Bin 3"
+msgstr "Bakke 3"
+
+msgid "Bin 4"
+msgstr "Bakke 4"
+
+msgid "Bin 5"
+msgstr "Bakke 5"
+
+msgid "Bin 6"
+msgstr "Bakke 6"
+
+msgid "Bin 7"
+msgstr "Bakke 7"
+
+msgid "Bin 8"
+msgstr "Bakke 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Sorteringsbakke 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Sorteringsbakke 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Sorteringsbakke 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Sorteringsbakke 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Sorteringsbakke 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Sorteringsbakke 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Sorteringsbakke 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Sorteringsbakke 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Sorteringsbakke 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Sorteringsbakke 9"
+
+msgid "Plain Paper"
+msgstr "Almindeligt papir"
+
+msgid "Letterhead"
+msgstr "Fortrykt"
+
+msgid "Printer Default"
+msgstr "Printerens aktuelle indstilling"
+
+msgid "Recycled Paper"
+msgstr "Genbrugspapir"
+
+msgid "Tab Stock"
+msgstr "Faneblade"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Overstørrrelse)"
+
+msgid "12x18"
+msgstr "12 x 18\""
+
+msgid "Thick Paper"
+msgstr "Tykt papir"
+
+msgid "Top Output Tray"
+msgstr "Topbakke"
+
+msgid "Tray 1"
+msgstr "Bakke 1"
+
+msgid "Tray 2"
+msgstr "Magasin 2"
+
+msgid "Tray 3"
+msgstr "Magasin 3"
+
+msgid "Tray 4"
+msgstr "Magasin 4"
+
+msgid "Tray 5"
+msgstr "Magasin 5"
+
+msgid "Tray 6"
+msgstr "Magasin 6 (Det store magasin)"
+
+msgid "Upper Tray"
+msgstr "Bakke 1"
+
diff --git a/locale/ppdc_de.po b/locale/ppdc_de.po
new file mode 100644 (file)
index 0000000..4adf2cd
--- /dev/null
@@ -0,0 +1,579 @@
+msgid "Color Mode"
+msgstr "Farbmodus"
+
+msgid "2-Sided Printing"
+msgstr "Duplexdruck"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Installierte Optionen"
+
+msgid "Paper Type"
+msgstr "Papiertyp"
+
+msgid "Duplex Unit"
+msgstr "Duplexer"
+
+msgid "Optional Input Tray"
+msgstr "Optionale Behälter"
+
+msgid "Optional Hard Disk"
+msgstr "Optionale Festplatte"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10 Zoll"
+
+msgid "9 x 11\""
+msgstr "9 x 11 Zoll"
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Umschlag Klappe Längsseite geschlossen"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "DIN A3"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Überformat)"
+
+msgid "Full Bleed A3"
+msgstr "A3, randlos"
+
+msgid "A3 Oversize Tray"
+msgstr "Fach A3 Übergröße   "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "DIN A4"
+
+msgid "Full Bleed A4"
+msgstr "A4, randlos"
+
+msgid "A4 (Small)"
+msgstr "A4 (Klein)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "DIN A5"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "DIN A6"
+
+msgid "A6 Card"
+msgstr "Karte A6"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Papier selbstklebend"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Automatische Zufuhr"
+
+msgid "JB0"
+msgstr "jis-B0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Schwarz"
+
+msgid "Bond Paper"
+msgstr "Briefpapier"
+
+msgid "Bin 1"
+msgstr "Papierablage 1"
+
+msgid "Bin 10"
+msgstr "Papierablage 10"
+
+msgid "Bin 2"
+msgstr "Papierablage 2"
+
+msgid "Bin 3"
+msgstr "Papierablage 3"
+
+msgid "Bin 4"
+msgstr "Papierablage 4"
+
+msgid "Bin 5"
+msgstr "Papierablage 5"
+
+msgid "Bin 6"
+msgstr "Papierablage 6"
+
+msgid "Bin 7"
+msgstr "Papierablage 7"
+
+msgid "Bin 8"
+msgstr "Papierablage 8"
+
+msgid "Bin 9"
+msgstr "Papierablage 9"
+
+msgid "Black Only"
+msgstr "Schwarz"
+
+msgid "Bypass Tray"
+msgstr "Fach 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "C9 Briefumschlag"
+
+msgid "C5 Envelope"
+msgstr "C5 Briefumschlag"
+
+msgid "Envelope C6"
+msgstr "Kuvert C6"
+
+msgid "Color"
+msgstr "Farbe"
+
+msgid "Card Stock"
+msgstr "Registerkarten"
+
+msgid "Paper Cassette"
+msgstr "Papierfach"
+
+msgid "Heavy Weight Matte"
+msgstr "Beschichtet"
+
+msgid "Colored Paper"
+msgstr "Farbe"
+
+msgid "Env Comm10"
+msgstr "Umschlag Comm10"
+
+msgid "Printer Default"
+msgstr "Druckerstandard"
+
+msgid "Long Edge"
+msgstr "Lange Kante"
+
+msgid "Short Edge"
+msgstr "Kurze Kante"
+
+msgid "#10 Envelope"
+msgstr "US #10 Umschlag"
+
+msgid "C4 Envelope"
+msgstr "Umschlag C4"
+
+msgid "C5 Envelope"
+msgstr "Umschlag C5"
+
+msgid "C6 Env."
+msgstr "C6 Umschlag"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 GOU"
+
+msgid "DL Envelope"
+msgstr "Umschlag DL"
+
+msgid "B4 Envelope"
+msgstr "Umschlag B4"
+
+msgid "Env ISO B5"
+msgstr "Umschlag ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku-Umschlag Nr. 2"
+
+msgid "Monarch Envelope"
+msgstr "Umschlag Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Umschlag #6 3/4"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Umschlag"
+
+msgid "7.25 x 10.5\""
+msgstr "7,25 x 10,5 Zoll"
+
+msgid "Off"
+msgstr "Aus"
+
+msgid "Glossy Paper"
+msgstr "Glanzpapier"
+
+msgid "Glossy Film"
+msgstr "Hochglanzfolie"
+
+msgid "Black and White"
+msgstr "Schwarzweiß"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "DIN B5"
+
+msgid "B6"
+msgstr "DIN B6"
+
+msgid "Tab Stock"
+msgstr "Registerblätter"
+
+msgid "Installed"
+msgstr "Eingebaut"
+
+msgid "Iron-On Transfer"
+msgstr "Transferpapier"
+
+msgid "JB0"
+msgstr "jis-B0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Oufuku-Hagaki"
+
+msgid "Labels"
+msgstr "Aufkleber"
+
+msgid "Tray 4"
+msgstr "Zufuhrfach 4"
+
+msgid "US Legal"
+msgstr "US Lang"
+
+msgid "Legal (Small)"
+msgstr "Legal (Klein)"
+
+msgid "US Letter"
+msgstr "US Brief"
+
+msgid "Full Bleed US Letter"
+msgstr "US Brief, randlos"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Klein)"
+
+msgid "Lower Tray"
+msgstr "Unteres Papierfach"
+
+msgid "Manual Feed"
+msgstr "Manuell"
+
+msgid "Manual Envelope"
+msgstr "Briefumschlag manuell"
+
+msgid "Middle Tray"
+msgstr "Mittleres Papierfach"
+
+msgid "Off"
+msgstr "Aus"
+
+msgid "Not Installed"
+msgstr "Nicht Eingebaut"
+
+msgid "On"
+msgstr "Ein"
+
+msgid "Oversize A0"
+msgstr "Übergröße A0"
+
+msgid "Oversize A1"
+msgstr "Übergröße A1"
+
+msgid "Oversize A2"
+msgstr "Übergröße A2"
+
+msgid "None"
+msgstr "Aus"
+
+msgid "Bin 1"
+msgstr "Ausgabefach 1"
+
+msgid "Bin 2"
+msgstr "Ausgabefach 2"
+
+msgid "Bin 3"
+msgstr "Ausgabefach 3"
+
+msgid "Bin 4"
+msgstr "Ausgabefach 4"
+
+msgid "Bin 5"
+msgstr "Ausgabefach 5"
+
+msgid "Bin 6"
+msgstr "Ausgabefach 6"
+
+msgid "Bin 7"
+msgstr "Ausgabefach 7"
+
+msgid "Bin 8"
+msgstr "Ausgabefach 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Ausgabefach 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Ausgabefach 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Ausgabefach 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Ausgabefach 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Ausgabefach 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Ausgabefach 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Ausgabefach 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Ausgabefach 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Ausgabefach 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Ausgabefach 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24 x 48 Zoll"
+
+msgid "24\" x 60\""
+msgstr "24 x 60 Zoll"
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36 x 60 Zoll"
+
+msgid "36\" x 72\""
+msgstr "36 x 72 Zoll"
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42 x 60 Zoll"
+
+msgid "42\" x 72\""
+msgstr "42 x 72 Zoll"
+
+msgid "42\" x 84\""
+msgstr "42 x 84 Zoll"
+
+msgid "54\" x 72\""
+msgstr "54 x 72 Zoll"
+
+msgid "54\" x 84\""
+msgstr "54 x 84 Zoll"
+
+msgid "54\" x 96\""
+msgstr "54 x 96 Zoll"
+
+msgid "60\" x 72\""
+msgstr "60 x 72 Zoll"
+
+msgid "60\" x 84\""
+msgstr "60 x 84 Zoll"
+
+msgid "60\" x 96\""
+msgstr "60 x 96 Zoll"
+
+msgid "Photo Paper"
+msgstr "Fotopapier"
+
+msgid "Plain Paper"
+msgstr "Normalpapier"
+
+msgid "Letterhead"
+msgstr "Bedruckt"
+
+msgid "Printer Default"
+msgstr "Druckereinstellung"
+
+msgid "Color"
+msgstr "Farbpapier"
+
+msgid "Recycled Paper"
+msgstr "Recycling"
+
+msgid "Roll Feed"
+msgstr "Rollenzufuhr"
+
+msgid "Roll 1"
+msgstr "Rolle 1"
+
+msgid "Roll 2"
+msgstr "Rolle 2"
+
+msgid "Cut Sheet"
+msgstr "Blattmedien"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Registerblattmaterial"
+
+msgid "11x17"
+msgstr "11x17 Zoll"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Überformat)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Tabloid, randlos"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Dickes Papier"
+
+msgid "Top Output Tray"
+msgstr "Oberes Ausgabefach"
+
+msgid "Top Output Tray"
+msgstr "Oberes Ausgabefach"
+
+msgid "Transparency"
+msgstr "Transparentfolie"
+
+msgid "Tray 1"
+msgstr "Fach 1"
+
+msgid "Tray 2"
+msgstr "Fach 2"
+
+msgid "Tray 3"
+msgstr "Fach 3"
+
+msgid "Tray 4"
+msgstr "Fach 4"
+
+msgid "Tray 5"
+msgstr "Fach 5"
+
+msgid "Tray 6"
+msgstr "Fach 6"
+
+msgid "Upper Tray"
+msgstr "Oberes Papierfach"
+
diff --git a/locale/ppdc_es.po b/locale/ppdc_es.po
new file mode 100644 (file)
index 0000000..9a01310
--- /dev/null
@@ -0,0 +1,585 @@
+msgid "Color Mode"
+msgstr "Modo de color"
+
+msgid "2-Sided Printing"
+msgstr "Dúplex"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Opciones instaladas"
+
+msgid "Paper Type"
+msgstr "Tipo de papel"
+
+msgid "Duplex Unit"
+msgstr "Unidad de impresión dúplex"
+
+msgid "Optional Input Tray"
+msgstr "Bandeja opcional de alimentación"
+
+msgid "Optional Hard Disk"
+msgstr "Disco Duro Opcional"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10 pulg."
+
+msgid "9 x 11\""
+msgstr "9x11 pulg."
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "Sobre de 9x12 pulg., cerrado, solapa larga"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (extragrande)"
+
+msgid "Full Bleed A3"
+msgstr "A3 sin margen"
+
+msgid "A3 Oversize Tray"
+msgstr "Bandeja para A3 extendido "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "A4 sin margen"
+
+msgid "A4 (Small)"
+msgstr "A4 (pequeño)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "Tarjeta A6"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesivo"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Selección automática"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Negro"
+
+msgid "Bond Paper"
+msgstr "Papel de cartas"
+
+msgid "Bin 1"
+msgstr "Bandeja de Salida 1"
+
+msgid "Bin 10"
+msgstr "Bandeja de Salida 10"
+
+msgid "Bin 2"
+msgstr "Bandeja de Salida 2"
+
+msgid "Bin 3"
+msgstr "Bandeja de Salida 3"
+
+msgid "Bin 4"
+msgstr "Bandeja de Salida 4"
+
+msgid "Bin 5"
+msgstr "Bandeja de Salida 5"
+
+msgid "Bin 6"
+msgstr "Bandeja de Salida 6"
+
+msgid "Bin 7"
+msgstr "Bandeja de Salida 7"
+
+msgid "Bin 8"
+msgstr "Bandeja de Salida 8"
+
+msgid "Bin 9"
+msgstr "Bandeja de Salida 9"
+
+msgid "Black Only"
+msgstr "Negro"
+
+msgid "Bypass Tray"
+msgstr "Bandeja 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "Sobres 9"
+
+msgid "C5 Envelope"
+msgstr "Sobres C5"
+
+msgid "Envelope C6"
+msgstr "Sobre C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Tarjetas"
+
+msgid "Paper Cassette"
+msgstr "Casete para papel"
+
+msgid "Heavy Weight Matte"
+msgstr "Couché"
+
+msgid "Colored Paper"
+msgstr "Colores"
+
+msgid "Env Comm10"
+msgstr "Sobre Comm10"
+
+msgid "Printer Default"
+msgstr "Impresora por defecto"
+
+msgid "Long Edge"
+msgstr "Borde largo"
+
+msgid "Short Edge"
+msgstr "Borde corto"
+
+msgid "#10 Envelope"
+msgstr "Sobre n゜10"
+
+msgid "C4 Envelope"
+msgstr "Sobre C4"
+
+msgid "C5 Envelope"
+msgstr "Sobre C5"
+
+msgid "C6 Env."
+msgstr "Sobre C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Couche 4 Gou"
+
+msgid "DL Envelope"
+msgstr "Sobre DL"
+
+msgid "B4 Envelope"
+msgstr "Sobres B4"
+
+msgid "Env ISO B5"
+msgstr "Sobre ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Sobre kaku nº 2"
+
+msgid "Monarch Envelope"
+msgstr "Sobre Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Sobre de tamaño 6 3/4"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Sobre"
+
+msgid "7.25 x 10.5\""
+msgstr "Ejecutivo"
+
+msgid "Off"
+msgstr "Desactivado"
+
+msgid "Finisher Tray"
+msgstr "Finalizador"
+
+msgid "Glossy Paper"
+msgstr "Satinado"
+
+msgid "Glossy Film"
+msgstr "Transp. Satinada"
+
+msgid "Black and White"
+msgstr "Blanco y negro"
+
+msgid "Statement"
+msgstr "Declaración"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Hojas tabuladoras"
+
+msgid "Inkjet Paper"
+msgstr "Papel inyección de tinta"
+
+msgid "Installed"
+msgstr "Instalada"
+
+msgid "Iron-On Transfer"
+msgstr "Transferencia térmica"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki 200 x 148 mm"
+
+msgid "Labels"
+msgstr "Etiquetas"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "US Legal"
+msgstr "Oficio"
+
+msgid "Legal (Small)"
+msgstr "Legal (pequeño)"
+
+msgid "US Letter"
+msgstr "Carta"
+
+msgid "Full Bleed US Letter"
+msgstr "Carta EE.UU. sin margen"
+
+msgid "Letter Plus"
+msgstr "Carta Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (pequeño)"
+
+msgid "Lower Tray"
+msgstr "Bandeja 3"
+
+msgid "Manual Feed"
+msgstr "Alimentación manual"
+
+msgid "Manual Envelope"
+msgstr "Sobre manual"
+
+msgid "Middle Tray"
+msgstr "Bandeja 2"
+
+msgid "Off"
+msgstr "Ninguno"
+
+msgid "Not Installed"
+msgstr "No Instalado"
+
+msgid "On"
+msgstr "Activado"
+
+msgid "Oversize A0"
+msgstr "Mayor A0"
+
+msgid "Oversize A1"
+msgstr "Mayor A1"
+
+msgid "Oversize A2"
+msgstr "Mayor A2"
+
+msgid "None"
+msgstr "Desactivado"
+
+msgid "Bin 1"
+msgstr "Bandeja 1"
+
+msgid "Bin 2"
+msgstr "Bandeja 2"
+
+msgid "Bin 3"
+msgstr "Bandeja 3"
+
+msgid "Bin 4"
+msgstr "Bandeja 4"
+
+msgid "Bin 5"
+msgstr "Bandeja 5"
+
+msgid "Bin 6"
+msgstr "Bandeja 6"
+
+msgid "Bin 7"
+msgstr "Bandeja 7"
+
+msgid "Bin 8"
+msgstr "Bandeja 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Bandeja MX1 (buzón)"
+
+msgid "Mailbox Tray 10"
+msgstr "Bandeja MX10 (buzón)"
+
+msgid "Mailbox Tray 2"
+msgstr "Bandeja MX2 (buzón)"
+
+msgid "Mailbox Tray 3"
+msgstr "Bandeja MX3 (buzón)"
+
+msgid "Mailbox Tray 4"
+msgstr "Bandeja MX4 (buzón)"
+
+msgid "Mailbox Tray 5"
+msgstr "Bandeja MX5 (buzón)"
+
+msgid "Mailbox Tray 6"
+msgstr "Bandeja MX6 (buzón)"
+
+msgid "Mailbox Tray 7"
+msgstr "Bandeja MX7 (buzón)"
+
+msgid "Mailbox Tray 8"
+msgstr "Bandeja MX8 (buzón)"
+
+msgid "Mailbox Tray 9"
+msgstr "Bandeja MX9 (buzón)"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54 x 72"
+
+msgid "54\" x 84\""
+msgstr "54 x 84"
+
+msgid "54\" x 96\""
+msgstr "54 x 96"
+
+msgid "60\" x 72\""
+msgstr "60 x 72"
+
+msgid "60\" x 84\""
+msgstr "60 x 84"
+
+msgid "60\" x 96\""
+msgstr "60 x 96"
+
+msgid "Photo Paper"
+msgstr "Papel de fotografía"
+
+msgid "Plain Paper"
+msgstr "Papel normal"
+
+msgid "Letterhead"
+msgstr "Preimpreso"
+
+msgid "Printer Default"
+msgstr "Valor prefijado de la impresora"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Reciclado"
+
+msgid "Roll Feed"
+msgstr "Rollo"
+
+msgid "Roll 1"
+msgstr "Rollo 1"
+
+msgid "Roll 2"
+msgstr "Rollo 2"
+
+msgid "Cut Sheet"
+msgstr "Hoja"
+
+msgid "Super B"
+msgstr "Super B (13 x 19  pulg.)"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Separadores"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (extragrande)"
+
+msgid "12x18"
+msgstr "12x18 pulg."
+
+msgid "Full Bleed Tabloid"
+msgstr "Tabloide sin margen"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Grueso"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de salida superior"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de salida superior"
+
+msgid "Transparency"
+msgstr "Transparencias"
+
+msgid "Tray 1"
+msgstr "Bandeja 1"
+
+msgid "Tray 2"
+msgstr "Bandeja 2"
+
+msgid "Tray 3"
+msgstr "Bandeja 3"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "Tray 5"
+msgstr "Bandeja 5"
+
+msgid "Tray 6"
+msgstr "Bandeja 6"
+
+msgid "Upper Tray"
+msgstr "Bandeja 1"
+
diff --git a/locale/ppdc_et.po b/locale/ppdc_et.po
new file mode 100644 (file)
index 0000000..96b4644
--- /dev/null
@@ -0,0 +1,592 @@
+# Template message catalog for the CUPS PPD compiler.
+msgid "Color Mode"
+msgstr "Color Mode"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options Installed"
+
+msgid "Paper Type"
+msgstr "Paper Type"
+
+msgid "Duplex Unit"
+msgstr "Duplex Unit"
+
+msgid "Optional Input Tray"
+msgstr "Optional Input Tray"
+
+msgid "Optional Hard Disk"
+msgstr "Optional Hard Disk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Closed Booklet Envelope"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A3 Oversize Tray"
+msgstr "A3 Oversize Tray"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "A6 Card"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Auto Select"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Black"
+
+msgid "Bond Paper"
+msgstr "Bond Paper"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 10"
+msgstr "Bin 10"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Bin 9"
+msgstr "Bin 9"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Bypass Tray"
+msgstr "Bypass Tray"
+
+msgid "9 Envelope"
+msgstr "9 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Card Stock"
+
+msgid "Paper Cassette"
+msgstr "Paper Cassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Heavy Weight Matte"
+
+msgid "Colored Paper"
+msgstr "Colored Paper"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Long Edge"
+msgstr "Long Edge"
+
+msgid "Short Edge"
+msgstr "Short Edge"
+
+msgid "#10 Envelope"
+msgstr "#10 Envelope"
+
+msgid "C4 Envelope"
+msgstr "C4 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL Envelope"
+
+msgid "B4 Envelope"
+msgstr "B4 Envelope"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelope"
+
+msgid "Monarch Envelope"
+msgstr "Monarch Envelope"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 Envelope"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Finisher Tray"
+msgstr "Finisher Tray"
+
+msgid "Glossy Paper"
+msgstr "Glossy Paper"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "Black and White"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet Paper"
+
+msgid "Installed"
+msgstr "Installed"
+
+msgid "Iron-On Transfer"
+msgstr "Iron-On Transfer"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Hagaki"
+msgstr "Hagaki"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Lower Tray"
+
+msgid "Mailbox"
+msgstr "Mailbox"
+
+msgid "Manual Feed"
+msgstr "Manual Feed"
+
+msgid "Manual Envelope"
+msgstr "Manual Envelope"
+
+msgid "Middle Tray"
+msgstr "Middle Tray"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Not Installed"
+msgstr "Not Installed"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Tray 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Tray 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Tray 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Tray 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Tray 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Tray 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Tray 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Tray 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Tray 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Tray 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Photo Paper"
+
+msgid "Plain Paper"
+msgstr "Plain Paper"
+
+msgid "Letterhead"
+msgstr "Letterhead"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Recycled Paper"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Thick Paper"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6"
+
+msgid "Upper Tray"
+msgstr "Upper Tray"
+
diff --git a/locale/ppdc_fi.po b/locale/ppdc_fi.po
new file mode 100644 (file)
index 0000000..239c405
--- /dev/null
@@ -0,0 +1,273 @@
+msgid "Color Mode"
+msgstr "Tulosta värit harmaasävyinä"
+
+msgid "2-Sided Printing"
+msgstr "Kaksipuolinen tulostus"
+
+msgid "Media Source"
+msgstr "Paperilähde"
+
+msgid "Options Installed"
+msgstr "Asennetut lisävarusteet"
+
+msgid "Paper Type"
+msgstr "Tulostusmateriaali"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (pieni)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "Auto Select"
+msgstr "Autom. valinta"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "JIS B6"
+
+msgid "Bond Paper"
+msgstr "Hienopaperi"
+
+msgid "Bin 1"
+msgstr "Lokero 1"
+
+msgid "Bin 2"
+msgstr "Lokero 2"
+
+msgid "Bin 3"
+msgstr "Lokero 3"
+
+msgid "Bin 4"
+msgstr "Lokero 4"
+
+msgid "Bin 5"
+msgstr "Lokero 5"
+
+msgid "Bin 6"
+msgstr "Lokero 6"
+
+msgid "Bin 7"
+msgstr "Lokero 7"
+
+msgid "Bin 8"
+msgstr "Lokero 8"
+
+msgid "Black Only"
+msgstr "Vain musta"
+
+msgid "C5 Envelope"
+msgstr "C5 kirjekuori"
+
+msgid "Color"
+msgstr "Pois"
+
+msgid "Card Stock"
+msgstr "Korttipaperi"
+
+msgid "Paper Cassette"
+msgstr "Paperikasetti"
+
+msgid "Colored Paper"
+msgstr "Väri"
+
+msgid "Env Comm10"
+msgstr "Comm10 kirjekuori"
+
+msgid "Printer Default"
+msgstr "Nopea"
+
+msgid "Long Edge"
+msgstr "Pitkän reunan sidonta"
+
+msgid "Short Edge"
+msgstr "Lyhyen reunan sidonta"
+
+msgid "#10 Envelope"
+msgstr "#10 kirjekuori"
+
+msgid "C4 Envelope"
+msgstr "Kirjekuori, C4 (324 x 229)"
+
+msgid "C5 Envelope"
+msgstr "C5 kirjekuori"
+
+msgid "C6 Env."
+msgstr "C6-kirjekuori"
+
+msgid "Envelope MAX"
+msgstr "Kirjekuori MAX"
+
+msgid "DL Envelope"
+msgstr "DL kirjekuori"
+
+msgid "Env ISO B5"
+msgstr "Kirjekuori ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Monarch Envelope"
+msgstr "Monarch kirjekuori"
+
+msgid "Envelope #4"
+msgstr "Kirjekuori nro 4"
+
+msgid "Envelope Feeder"
+msgstr "Kirjekuori"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Ei käytössä"
+
+msgid "Glossy Paper"
+msgstr "Muu valokuvapaperi"
+
+msgid "Black and White"
+msgstr "Harmaa"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Inkjet Paper"
+msgstr "Mustesuihkupaperi"
+
+msgid "Tray 4"
+msgstr "Lokero 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (pieni)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Letter (Small)"
+msgstr "Letter (pieni)"
+
+msgid "Lower Tray"
+msgstr "Lokero 3"
+
+msgid "Manual Feed"
+msgstr "Käsinsyöttö"
+
+msgid "Middle Tray"
+msgstr "Lokero 2"
+
+msgid "Off"
+msgstr "Ei"
+
+msgid "None"
+msgstr "Ei"
+
+msgid "Bin 1"
+msgstr "Lokero 1"
+
+msgid "Bin 2"
+msgstr "Lokero 2"
+
+msgid "Bin 3"
+msgstr "Lokero 3"
+
+msgid "Bin 4"
+msgstr "Lokero 4"
+
+msgid "Bin 5"
+msgstr "Lokero 5"
+
+msgid "Bin 6"
+msgstr "Lokero 6"
+
+msgid "Bin 7"
+msgstr "Lokero 7"
+
+msgid "Bin 8"
+msgstr "Lokero 8"
+
+msgid "Plain Paper"
+msgstr "Tavallinen paperi"
+
+msgid "Letterhead"
+msgstr "Esipainettu"
+
+msgid "Printer Default"
+msgstr "Kirjoittimen nykyinen asetus"
+
+msgid "Recycled Paper"
+msgstr "Uusiopaperi"
+
+msgid "Tab Stock"
+msgstr "Hakulehdet"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12 x 18\""
+
+msgid "Thick Paper"
+msgstr "Paksu paperi"
+
+msgid "Top Output Tray"
+msgstr "Yläluovutusalusta"
+
+msgid "Tray 1"
+msgstr "Kasetti1"
+
+msgid "Tray 2"
+msgstr "Kasetti2"
+
+msgid "Tray 3"
+msgstr "Alusta 3"
+
+msgid "Tray 4"
+msgstr "Alusta 4"
+
+msgid "Tray 5"
+msgstr "Lokero 5"
+
+msgid "Tray 6"
+msgstr "Alusta 6 (iso)"
+
+msgid "Upper Tray"
+msgstr "Lokero 1"
+
diff --git a/locale/ppdc_fr.po b/locale/ppdc_fr.po
new file mode 100644 (file)
index 0000000..58cc529
--- /dev/null
@@ -0,0 +1,582 @@
+msgid "Color Mode"
+msgstr "Mode couleur"
+
+msgid "2-Sided Printing"
+msgstr "Impression recto-verso"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options installées"
+
+msgid "Paper Type"
+msgstr "Type de support"
+
+msgid "Duplex Unit"
+msgstr "Unité d'impression recto-verso"
+
+msgid "Optional Input Tray"
+msgstr "Bac d'entrée optionnel"
+
+msgid "Optional Hard Disk"
+msgstr "Disque dur en Option"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10"
+
+msgid "9 x 11\""
+msgstr "9 x 11"
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "Enveloppe 9 x 12 rabat grand côté fermé"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Grand Format)"
+
+msgid "Full Bleed A3"
+msgstr "A3 Extra"
+
+msgid "A3 Oversize Tray"
+msgstr "Bac A3+ "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "A4 Extra"
+
+msgid "A4 (Small)"
+msgstr "A4 (petit)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (100 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "Carte A6"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Papier autocollant"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Sélection automatique"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Noir"
+
+msgid "Bond Paper"
+msgstr "Papier fort"
+
+msgid "Bin 1"
+msgstr "Réceptacle 1"
+
+msgid "Bin 10"
+msgstr "Réceptacle 10"
+
+msgid "Bin 2"
+msgstr "Réceptacle 2"
+
+msgid "Bin 3"
+msgstr "Réceptacle 3"
+
+msgid "Bin 4"
+msgstr "Réceptacle 4"
+
+msgid "Bin 5"
+msgstr "Réceptacle 5"
+
+msgid "Bin 6"
+msgstr "Réceptacle 6"
+
+msgid "Bin 7"
+msgstr "Réceptacle 7"
+
+msgid "Bin 8"
+msgstr "Réceptacle 8"
+
+msgid "Bin 9"
+msgstr "Réceptacle 9"
+
+msgid "Black Only"
+msgstr "Noir"
+
+msgid "Bypass Tray"
+msgstr "Bac 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "Enveloppe C9"
+
+msgid "C5 Envelope"
+msgstr "Enveloppe C5"
+
+msgid "Envelope C6"
+msgstr "Enveloppe C6"
+
+msgid "Color"
+msgstr "Couleur"
+
+msgid "Card Stock"
+msgstr "Papier cartonné"
+
+msgid "Paper Cassette"
+msgstr "Cassette à papier"
+
+msgid "Heavy Weight Matte"
+msgstr "Couché"
+
+msgid "Colored Paper"
+msgstr "Couleur"
+
+msgid "Env Comm10"
+msgstr "Env. Comm10"
+
+msgid "Printer Default"
+msgstr "Imprimante par défaut"
+
+msgid "Long Edge"
+msgstr "Bord Long"
+
+msgid "Short Edge"
+msgstr "Bord Court"
+
+msgid "#10 Envelope"
+msgstr "Enveloppe n゜10"
+
+msgid "C4 Envelope"
+msgstr "Enveloppe C4"
+
+msgid "C5 Envelope"
+msgstr "Enveloppe C5"
+
+msgid "C6 Env."
+msgstr "Env. C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "Enveloppe DL"
+
+msgid "B4 Envelope"
+msgstr "Enveloppe B4"
+
+msgid "Env ISO B5"
+msgstr "Enveloppe B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Enveloppe Kaku n° 2"
+
+msgid "Monarch Envelope"
+msgstr "Enveloppe Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Enveloppe 6 3/4"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Enveloppe"
+
+msgid "7.25 x 10.5\""
+msgstr "Exécutif"
+
+msgid "Off"
+msgstr "Désactivé"
+
+msgid "Finisher Tray"
+msgstr "Finisseuse"
+
+msgid "Glossy Paper"
+msgstr "Papier glacé"
+
+msgid "Glossy Film"
+msgstr "Film polyester glacé"
+
+msgid "Black and White"
+msgstr "Noir et Blanc"
+
+msgid "Statement"
+msgstr "Relevé"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Onglets"
+
+msgid "Inkjet Paper"
+msgstr "Papier jet d'encre"
+
+msgid "Installed"
+msgstr "Installée"
+
+msgid "Iron-On Transfer"
+msgstr "Transfert sur tissu"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Etiquettes"
+
+msgid "Tray 4"
+msgstr "Bac 4"
+
+msgid "US Legal"
+msgstr "Légal US"
+
+msgid "Legal (Small)"
+msgstr "Légal (petit)"
+
+msgid "US Letter"
+msgstr "Lettre"
+
+msgid "Full Bleed US Letter"
+msgstr "Lettre US Extra"
+
+msgid "Letter Plus"
+msgstr "Folio Special"
+
+msgid "Letter (Small)"
+msgstr "Letter (petit)"
+
+msgid "Lower Tray"
+msgstr "Bac inférieur"
+
+msgid "Manual Feed"
+msgstr "Manuel"
+
+msgid "Manual Envelope"
+msgstr "Enveloppe Manuel"
+
+msgid "Middle Tray"
+msgstr "Bac central"
+
+msgid "Off"
+msgstr "Aucun"
+
+msgid "Not Installed"
+msgstr "Non Installée"
+
+msgid "On"
+msgstr "Oui"
+
+msgid "Oversize A0"
+msgstr "A0 surdimensioné"
+
+msgid "Oversize A1"
+msgstr "A1 surdimensioné"
+
+msgid "Oversize A2"
+msgstr "A2 surdimensioné"
+
+msgid "None"
+msgstr "Désactivé"
+
+msgid "Bin 1"
+msgstr "Bac 1"
+
+msgid "Bin 2"
+msgstr "Bac 2"
+
+msgid "Bin 3"
+msgstr "Bac 3"
+
+msgid "Bin 4"
+msgstr "Bac 4"
+
+msgid "Bin 5"
+msgstr "Bac 5"
+
+msgid "Bin 6"
+msgstr "Bac 6"
+
+msgid "Bin 7"
+msgstr "Bac 7"
+
+msgid "Bin 8"
+msgstr "Bac 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Boîtes aux lettres Bac 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Boîtes aux lettres Bac 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Boîtes aux lettres Bac 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Boîtes aux lettres Bac 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Boîtes aux lettres Bac 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Boîtes aux lettres Bac 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Boîtes aux lettres Bac 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Boîtes aux lettres Bac 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Boîtes aux lettres Bac 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Boîtes aux lettres Bac 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Papier photo"
+
+msgid "Plain Paper"
+msgstr "Papier ordinaire"
+
+msgid "Letterhead"
+msgstr "Préimprimé"
+
+msgid "Printer Default"
+msgstr "Valeur par défaut imprimante "
+
+msgid "Color"
+msgstr "Couleur "
+
+msgid "Recycled Paper"
+msgstr "Recyclé"
+
+msgid "Roll Feed"
+msgstr "Alimentation en rouleau"
+
+msgid "Roll 1"
+msgstr "Rouleau 1"
+
+msgid "Roll 2"
+msgstr "Rouleau 2"
+
+msgid "Cut Sheet"
+msgstr "Feuille coupée"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Intercalaire"
+
+msgid "11x17"
+msgstr "11 x 17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Grand Format)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Tabloid Extra"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Papier épais"
+
+msgid "Top Output Tray"
+msgstr "Bac récepteur supérieur"
+
+msgid "Top Output Tray"
+msgstr "Bac de sortie supérieur"
+
+msgid "Tray 1"
+msgstr "Bac 1"
+
+msgid "Tray 2"
+msgstr "Bac 2"
+
+msgid "Tray 3"
+msgstr "Bac 3"
+
+msgid "Tray 4"
+msgstr "Bac 4"
+
+msgid "Tray 5"
+msgstr "Bac 5"
+
+msgid "Tray 6"
+msgstr "Bac 6"
+
+msgid "Upper Tray"
+msgstr "Bac supérieur"
+
diff --git a/locale/ppdc_he.po b/locale/ppdc_he.po
new file mode 100644 (file)
index 0000000..96b4644
--- /dev/null
@@ -0,0 +1,592 @@
+# Template message catalog for the CUPS PPD compiler.
+msgid "Color Mode"
+msgstr "Color Mode"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options Installed"
+
+msgid "Paper Type"
+msgstr "Paper Type"
+
+msgid "Duplex Unit"
+msgstr "Duplex Unit"
+
+msgid "Optional Input Tray"
+msgstr "Optional Input Tray"
+
+msgid "Optional Hard Disk"
+msgstr "Optional Hard Disk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Closed Booklet Envelope"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A3 Oversize Tray"
+msgstr "A3 Oversize Tray"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "A6 Card"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Auto Select"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Black"
+
+msgid "Bond Paper"
+msgstr "Bond Paper"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 10"
+msgstr "Bin 10"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Bin 9"
+msgstr "Bin 9"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Bypass Tray"
+msgstr "Bypass Tray"
+
+msgid "9 Envelope"
+msgstr "9 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Card Stock"
+
+msgid "Paper Cassette"
+msgstr "Paper Cassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Heavy Weight Matte"
+
+msgid "Colored Paper"
+msgstr "Colored Paper"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Long Edge"
+msgstr "Long Edge"
+
+msgid "Short Edge"
+msgstr "Short Edge"
+
+msgid "#10 Envelope"
+msgstr "#10 Envelope"
+
+msgid "C4 Envelope"
+msgstr "C4 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL Envelope"
+
+msgid "B4 Envelope"
+msgstr "B4 Envelope"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelope"
+
+msgid "Monarch Envelope"
+msgstr "Monarch Envelope"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 Envelope"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Finisher Tray"
+msgstr "Finisher Tray"
+
+msgid "Glossy Paper"
+msgstr "Glossy Paper"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "Black and White"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet Paper"
+
+msgid "Installed"
+msgstr "Installed"
+
+msgid "Iron-On Transfer"
+msgstr "Iron-On Transfer"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Hagaki"
+msgstr "Hagaki"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Lower Tray"
+
+msgid "Mailbox"
+msgstr "Mailbox"
+
+msgid "Manual Feed"
+msgstr "Manual Feed"
+
+msgid "Manual Envelope"
+msgstr "Manual Envelope"
+
+msgid "Middle Tray"
+msgstr "Middle Tray"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Not Installed"
+msgstr "Not Installed"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Tray 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Tray 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Tray 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Tray 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Tray 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Tray 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Tray 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Tray 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Tray 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Tray 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Photo Paper"
+
+msgid "Plain Paper"
+msgstr "Plain Paper"
+
+msgid "Letterhead"
+msgstr "Letterhead"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Recycled Paper"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Thick Paper"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6"
+
+msgid "Upper Tray"
+msgstr "Upper Tray"
+
diff --git a/locale/ppdc_it.po b/locale/ppdc_it.po
new file mode 100644 (file)
index 0000000..4ac2157
--- /dev/null
@@ -0,0 +1,585 @@
+msgid "Color Mode"
+msgstr "Modo Colore"
+
+msgid "2-Sided Printing"
+msgstr "Fronte-retro"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Opzioni installate"
+
+msgid "Paper Type"
+msgstr "Tipo di carta"
+
+msgid "Duplex Unit"
+msgstr "Unità duplex"
+
+msgid "Optional Input Tray"
+msgstr "Cassetti opzionali"
+
+msgid "Optional Hard Disk"
+msgstr "Hard Disk Opzionale"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "203 x 254 mm"
+
+msgid "9 x 11\""
+msgstr "299 x 279 mm"
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Busta linguetta lato lungo chiusa"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Allungato)"
+
+msgid "Full Bleed A3"
+msgstr "A3 al vivo"
+
+msgid "A3 Oversize Tray"
+msgstr "Cassetto A3 grande "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "A4 al vivo"
+
+msgid "A4 (Small)"
+msgstr "A4 (ridotta)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "Scheda A6"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Carta autoadesiva"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Selezione automatica"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Nero"
+
+msgid "Bond Paper"
+msgstr "Cartoncino"
+
+msgid "Bin 1"
+msgstr "Racc. di uscita 1"
+
+msgid "Bin 10"
+msgstr "Racc. di uscita 10"
+
+msgid "Bin 2"
+msgstr "Racc. di uscita 2"
+
+msgid "Bin 3"
+msgstr "Racc. di uscita 3"
+
+msgid "Bin 4"
+msgstr "Racc. di uscita 4"
+
+msgid "Bin 5"
+msgstr "Racc. di uscita 5"
+
+msgid "Bin 6"
+msgstr "Racc. di uscita 6"
+
+msgid "Bin 7"
+msgstr "Racc. di uscita 7"
+
+msgid "Bin 8"
+msgstr "Racc. di uscita 8"
+
+msgid "Bin 9"
+msgstr "Racc. di uscita 9"
+
+msgid "Black Only"
+msgstr "Nero"
+
+msgid "Bypass Tray"
+msgstr "Cassetto 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "Busta 9"
+
+msgid "C5 Envelope"
+msgstr "Busta C5"
+
+msgid "Envelope C6"
+msgstr "Busta C6"
+
+msgid "Color"
+msgstr "Colore"
+
+msgid "Card Stock"
+msgstr "Cartoncino"
+
+msgid "Paper Cassette"
+msgstr "Cassetto della carta"
+
+msgid "Heavy Weight Matte"
+msgstr "Patinata"
+
+msgid "Colored Paper"
+msgstr "Colore"
+
+msgid "Env Comm10"
+msgstr "Busta Comm10"
+
+msgid "Printer Default"
+msgstr "Impostazioni predefinite stampante"
+
+msgid "Long Edge"
+msgstr "Rilegatura lato lungo"
+
+msgid "Short Edge"
+msgstr "Rilegatura lato corto"
+
+msgid "#10 Envelope"
+msgstr "Busta #10"
+
+msgid "C4 Envelope"
+msgstr "Busta C4"
+
+msgid "C5 Envelope"
+msgstr "Busta C5"
+
+msgid "C6 Env."
+msgstr "Busta C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "Busta DL"
+
+msgid "B4 Envelope"
+msgstr "Busta B4"
+
+msgid "Env ISO B5"
+msgstr "Busta B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Busta Kaku n. 2"
+
+msgid "Monarch Envelope"
+msgstr "Busta Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Busta n. 6"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Busta"
+
+msgid "7.25 x 10.5\""
+msgstr "184 x 267 mm"
+
+msgid "Off"
+msgstr "Non installato"
+
+msgid "Finisher Tray"
+msgstr "Rifinitore"
+
+msgid "Glossy Paper"
+msgstr "Carta lucida"
+
+msgid "Glossy Film"
+msgstr "Pellicola lucida"
+
+msgid "Black and White"
+msgstr "Grigio"
+
+msgid "Statement"
+msgstr "Dichiarazione"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Schede indicizzate"
+
+msgid "Inkjet Paper"
+msgstr "Carta Inkjet"
+
+msgid "Installed"
+msgstr "Installata"
+
+msgid "Iron-On Transfer"
+msgstr "Trasferibile a caldo"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Etichette"
+
+msgid "Tray 4"
+msgstr "Vassoio 4"
+
+msgid "US Legal"
+msgstr "Legale USA"
+
+msgid "Legal (Small)"
+msgstr "Legal (ridotto)"
+
+msgid "US Letter"
+msgstr "Lettera USA"
+
+msgid "Full Bleed US Letter"
+msgstr "Lettera USA al vivo"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (ridotta)"
+
+msgid "Lower Tray"
+msgstr "Cassetto inferiore"
+
+msgid "Manual Feed"
+msgstr "Manuale"
+
+msgid "Manual Envelope"
+msgstr "Busta Manuale"
+
+msgid "Middle Tray"
+msgstr "Cassetto mediano"
+
+msgid "Off"
+msgstr "Nessuno"
+
+msgid "Not Installed"
+msgstr "Non Installato"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Over A0"
+
+msgid "Oversize A1"
+msgstr "Over A1"
+
+msgid "Oversize A2"
+msgstr "Over A2"
+
+msgid "None"
+msgstr "Disattivo"
+
+msgid "Bin 1"
+msgstr "Scomparto 1"
+
+msgid "Bin 2"
+msgstr "Scomparto 2"
+
+msgid "Bin 3"
+msgstr "Scomparto 3"
+
+msgid "Bin 4"
+msgstr "Scomparto 4"
+
+msgid "Bin 5"
+msgstr "Scomparto 5"
+
+msgid "Bin 6"
+msgstr "Scomparto 6"
+
+msgid "Bin 7"
+msgstr "Scomparto 7"
+
+msgid "Bin 8"
+msgstr "Scomparto 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Vass. MX1 (Mailbox)"
+
+msgid "Mailbox Tray 10"
+msgstr "Vass. MX10 (Mailbox)"
+
+msgid "Mailbox Tray 2"
+msgstr "Vass. MX2 (Mailbox)"
+
+msgid "Mailbox Tray 3"
+msgstr "Vass. MX3 (Mailbox)"
+
+msgid "Mailbox Tray 4"
+msgstr "Vass. MX4 (Mailbox)"
+
+msgid "Mailbox Tray 5"
+msgstr "Vass. MX5 (Mailbox)"
+
+msgid "Mailbox Tray 6"
+msgstr "Vass. MX6 (Mailbox)"
+
+msgid "Mailbox Tray 7"
+msgstr "Vass. MX7 (Mailbox)"
+
+msgid "Mailbox Tray 8"
+msgstr "Vass. MX8 (Mailbox)"
+
+msgid "Mailbox Tray 9"
+msgstr "Vass. MX9 (Mailbox)"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54 x 72"
+
+msgid "54\" x 84\""
+msgstr "54 x 84"
+
+msgid "54\" x 96\""
+msgstr "54 x 96"
+
+msgid "60\" x 72\""
+msgstr "60 x 72"
+
+msgid "60\" x 84\""
+msgstr "60 x 84"
+
+msgid "60\" x 96\""
+msgstr "60 x 96"
+
+msgid "Photo Paper"
+msgstr "Carta fotografica"
+
+msgid "Plain Paper"
+msgstr "Carta normale"
+
+msgid "Letterhead"
+msgstr "Prestampata"
+
+msgid "Printer Default"
+msgstr "Default stampante"
+
+msgid "Color"
+msgstr "Colorata"
+
+msgid "Recycled Paper"
+msgstr "Riciclata"
+
+msgid "Roll Feed"
+msgstr "Rotoli"
+
+msgid "Roll 1"
+msgstr "Rullo 1"
+
+msgid "Roll 2"
+msgstr "Rullo 2"
+
+msgid "Cut Sheet"
+msgstr "Fogli"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Divisori a rubrica"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Allungato)"
+
+msgid "12x18"
+msgstr "12x18 (305 x 457 mm)"
+
+msgid "Full Bleed Tabloid"
+msgstr "Tabloid al vivo"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Carta spessa"
+
+msgid "Top Output Tray"
+msgstr "Vassoio di ricezione superiore"
+
+msgid "Top Output Tray"
+msgstr "Cassetto di uscita superiore"
+
+msgid "Transparency"
+msgstr "Trasparenza"
+
+msgid "Tray 1"
+msgstr "Vassoio 1"
+
+msgid "Tray 2"
+msgstr "Cassetto 2"
+
+msgid "Tray 3"
+msgstr "Cassetto 3"
+
+msgid "Tray 4"
+msgstr "Cassetto 4"
+
+msgid "Tray 5"
+msgstr "Cassetto 5"
+
+msgid "Tray 6"
+msgstr "Cassetto 6"
+
+msgid "Upper Tray"
+msgstr "Cassetto superiore"
+
diff --git a/locale/ppdc_ja.po b/locale/ppdc_ja.po
new file mode 100644 (file)
index 0000000..d67bf71
--- /dev/null
@@ -0,0 +1,471 @@
+msgid "Color Mode"
+msgstr "カラー モデル"
+
+msgid "2-Sided Printing"
+msgstr "両面印刷"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "装着済みオプション"
+
+msgid "Paper Type"
+msgstr "用紙の種類"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (大)"
+
+msgid "Full Bleed A3"
+msgstr "A3 ノビ"
+
+msgid "Full Bleed A4"
+msgstr "A4 ノビ"
+
+msgid "A4 (Small)"
+msgstr "A4 (小)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "C"
+msgstr "ANSI C"
+
+msgid "D"
+msgstr "ANSI D"
+
+msgid "E"
+msgstr "ANSI E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "粘着紙"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "自動給紙"
+
+msgid "JB0"
+msgstr "B0 (JIS)"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "B5 (JIS)"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Bond Paper"
+msgstr "ボンド紙"
+
+msgid "Bin 1"
+msgstr "排紙トレイ 1"
+
+msgid "Bin 10"
+msgstr "排紙トレイ 10"
+
+msgid "Bin 2"
+msgstr "排紙トレイ 2"
+
+msgid "Bin 3"
+msgstr "排紙トレイ 3"
+
+msgid "Bin 4"
+msgstr "排紙トレイ 4"
+
+msgid "Bin 5"
+msgstr "排紙トレイ 5"
+
+msgid "Bin 6"
+msgstr "排紙トレイ 6"
+
+msgid "Bin 7"
+msgstr "排紙トレイ 7"
+
+msgid "Bin 8"
+msgstr "排紙トレイ 8"
+
+msgid "Bin 9"
+msgstr "排紙トレイ 9"
+
+msgid "Black Only"
+msgstr "黒のみ"
+
+msgid "9 Envelope"
+msgstr "封筒(C9号)"
+
+msgid "C5 Envelope"
+msgstr "封筒(C5号)"
+
+msgid "Color"
+msgstr "カラー"
+
+msgid "Card Stock"
+msgstr "カード ストック"
+
+msgid "Heavy Weight Matte"
+msgstr "マット紙"
+
+msgid "Colored Paper"
+msgstr "カラー"
+
+msgid "Printer Default"
+msgstr "システムデフォルト"
+
+msgid "Long Edge"
+msgstr "長辺とじ"
+
+msgid "Short Edge"
+msgstr "短辺とじ"
+
+msgid "#10 Envelope"
+msgstr "Com-10"
+
+msgid "C5 Envelope"
+msgstr "C5"
+
+msgid "C6 Env."
+msgstr "C6 封筒"
+
+msgid "Envelope MAX"
+msgstr "洋形定形最大封筒"
+
+msgid "DL Envelope"
+msgstr "DL"
+
+msgid "Env ISO B5"
+msgstr "封筒 ISO B5"
+
+msgid "B6 "
+msgstr "B6"
+
+msgid "Kaku #2 envelope"
+msgstr "封筒 角 2 号"
+
+msgid "Monarch Envelope"
+msgstr "Monarch"
+
+msgid "Envelope #4"
+msgstr "洋形4号封筒"
+
+msgid "Envelope Feeder"
+msgstr "封筒"
+
+msgid "7.25 x 10.5\""
+msgstr "エグゼクティブ"
+
+msgid "Off"
+msgstr "オフ"
+
+msgid "Finisher Tray"
+msgstr "フィニッシャー"
+
+msgid "Glossy Paper"
+msgstr "光沢紙"
+
+msgid "Glossy Film"
+msgstr "光沢フィルム"
+
+msgid "Black and White"
+msgstr "モノクロ"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "B5"
+msgstr "ISO B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "インデックス紙"
+
+msgid "Inkjet Paper"
+msgstr "インクジェット紙"
+
+msgid "Installed"
+msgstr "インストール済み"
+
+msgid "Iron-On Transfer"
+msgstr "アイロンプリント紙"
+
+msgid "JB0"
+msgstr "B0(JIS)"
+
+msgid "JB1"
+msgstr "B1(JIS)"
+
+msgid "JB2"
+msgstr "B2(JIS)"
+
+msgid "JB3"
+msgstr "B3(JIS)"
+
+msgid "JB4"
+msgstr "B4(JIS)"
+
+msgid "Hagaki"
+msgstr "ハガキ"
+
+msgid "Ofuku Hagaki"
+msgstr "往復ハガキ"
+
+msgid "Tray 4"
+msgstr "トレイ 4"
+
+msgid "US Legal"
+msgstr "リーガル"
+
+msgid "Legal (Small)"
+msgstr "リーガル (小)"
+
+msgid "US Letter"
+msgstr "レター"
+
+msgid "Full Bleed US Letter"
+msgstr "US レター ノビ"
+
+msgid "Letter (Small)"
+msgstr "レター (小)"
+
+msgid "Lower Tray"
+msgstr "下"
+
+msgid "Mailbox"
+msgstr "プリントポスト"
+
+msgid "Manual Feed"
+msgstr "手差し"
+
+msgid "Manual Envelope"
+msgstr "手差し封筒"
+
+msgid "Middle Tray"
+msgstr "トレイ 2"
+
+msgid "Off"
+msgstr "なし"
+
+msgid "Not Installed"
+msgstr "インストールされていません"
+
+msgid "On"
+msgstr "オン"
+
+msgid "Oversize A0"
+msgstr "オーバーサイズ A0"
+
+msgid "Oversize A1"
+msgstr "オーバーサイズ A1"
+
+msgid "Oversize A2"
+msgstr "オーバーサイズ A2"
+
+msgid "None"
+msgstr "オフ"
+
+msgid "Bin 1"
+msgstr "ビン 1"
+
+msgid "Bin 2"
+msgstr "ビン 2"
+
+msgid "Bin 3"
+msgstr "ビン 3"
+
+msgid "Bin 4"
+msgstr "ビン 4"
+
+msgid "Bin 5"
+msgstr "ビン 5"
+
+msgid "Bin 6"
+msgstr "ビン 6"
+
+msgid "Bin 7"
+msgstr "ビン 7"
+
+msgid "Bin 8"
+msgstr "ビン 8"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Plain Paper"
+msgstr "普通紙"
+
+msgid "Letterhead"
+msgstr "印刷フォーム"
+
+msgid "Printer Default"
+msgstr "プリンタの現在の設定"
+
+msgid "Color"
+msgstr "カラー"
+
+msgid "Recycled Paper"
+msgstr "再生紙"
+
+msgid "Roll Feed"
+msgstr "カット紙"
+
+msgid "Roll 1"
+msgstr "ロール紙 1"
+
+msgid "Roll 2"
+msgstr "ロール紙 2"
+
+msgid "Cut Sheet"
+msgstr "ロール紙"
+
+msgid "Super B"
+msgstr "スーパー B/A3"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (大)"
+
+msgid "Full Bleed Tabloid"
+msgstr "タブロイド ノビ"
+
+msgid "Thick Paper"
+msgstr "厚紙"
+
+msgid "Transparency"
+msgstr "OHPフィルム"
+
+msgid "Tray 1"
+msgstr "カセット 1"
+
+msgid "Tray 2"
+msgstr "カセット 2"
+
+msgid "Tray 3"
+msgstr "カセット 3"
+
+msgid "Tray 4"
+msgstr "カセット 4"
+
+msgid "Tray 5"
+msgstr "カセット 5"
+
+msgid "Tray 6"
+msgstr "トレイ 6"
+
+msgid "Upper Tray"
+msgstr "上"
+
diff --git a/locale/ppdc_ko.po b/locale/ppdc_ko.po
new file mode 100644 (file)
index 0000000..947727b
--- /dev/null
@@ -0,0 +1,468 @@
+msgid "Color Mode"
+msgstr "컬러 모델"
+
+msgid "2-Sided Printing"
+msgstr "양면인쇄"
+
+msgid "Media Source"
+msgstr "용지함"
+
+msgid "Options Installed"
+msgstr "설치된 옵션"
+
+msgid "Paper Type"
+msgstr "용지 종류"
+
+msgid "Media Size"
+msgstr "Page Size"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (특대)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (소)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "접착 용지 "
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "자동 선택"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "JIS B6"
+
+msgid "Black"
+msgstr "검정색"
+
+msgid "Bin 1"
+msgstr "빈 1"
+
+msgid "Bin 10"
+msgstr "빈 10"
+
+msgid "Bin 2"
+msgstr "빈 2"
+
+msgid "Bin 3"
+msgstr "빈 3"
+
+msgid "Bin 4"
+msgstr "빈 4"
+
+msgid "Bin 5"
+msgstr "빈 5"
+
+msgid "Bin 6"
+msgstr "빈 6"
+
+msgid "Bin 7"
+msgstr "빈 7"
+
+msgid "Bin 8"
+msgstr "빈 8"
+
+msgid "Bin 9"
+msgstr "빈 9"
+
+msgid "Black Only"
+msgstr "흑색 전용"
+
+msgid "Bypass Tray"
+msgstr "수동트레이"
+
+msgid "9 Envelope"
+msgstr "C9 봉투"
+
+msgid "C5 Envelope"
+msgstr "C5 봉투"
+
+msgid "Color"
+msgstr "꺼짐"
+
+msgid "Card Stock"
+msgstr "카드 용지"
+
+msgid "Colored Paper"
+msgstr "색"
+
+msgid "Printer Default"
+msgstr "빠르게"
+
+msgid "Long Edge"
+msgstr "긴 가장자리로 뒤집기(표준)"
+
+msgid "Short Edge"
+msgstr "짧은 가장자리로 뒤집기"
+
+msgid "#10 Envelope"
+msgstr "Comm10 봉투"
+
+msgid "C4 Envelope"
+msgstr "C4 봉투"
+
+msgid "C5 Envelope"
+msgstr "C5 봉투"
+
+msgid "C6 Env."
+msgstr "C6 봉투"
+
+msgid "Envelope MAX"
+msgstr "Choukei 3 Gou"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL 봉투"
+
+msgid "Env ISO B5"
+msgstr "ISO B5 봉투"
+
+msgid "Kaku #2 envelope"
+msgstr "#2 카쿠 봉투"
+
+msgid "Monarch Envelope"
+msgstr "Monarch 봉투"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 ºÀÅõ"
+
+msgid "Envelope Feeder"
+msgstr "봉투"
+
+msgid "7.25 x 10.5\""
+msgstr "ÇàÁ¤ÀϹݿëÁö"
+
+msgid "Off"
+msgstr "꺼짐"
+
+msgid "Glossy Paper"
+msgstr "광택지"
+
+msgid "Glossy Film"
+msgstr "광택필름"
+
+msgid "Black and White"
+msgstr "켜짐"
+
+msgid "Statement"
+msgstr "2절 레터"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "B5"
+msgstr "B5 봉투"
+
+msgid "B6"
+msgstr "B6 (ISO)"
+
+msgid "Installed"
+msgstr "설치됨"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "오푸쿠 엽서"
+
+msgid "Labels"
+msgstr "레이블 용지"
+
+msgid "Tray 4"
+msgstr "용지함 4"
+
+msgid "US Legal"
+msgstr "리갈"
+
+msgid "Legal (Small)"
+msgstr "리갈 (소)"
+
+msgid "US Letter"
+msgstr "레터"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter (Small)"
+msgstr "레터 (소)"
+
+msgid "Lower Tray"
+msgstr "ÇÏ´Ü ¿ëÁöÇÔ"
+
+msgid "Manual Feed"
+msgstr "수동"
+
+msgid "Manual Envelope"
+msgstr "수동 봉투"
+
+msgid "Middle Tray"
+msgstr "Áß°£ ¿ëÁöÇÔ"
+
+msgid "Off"
+msgstr "없음"
+
+msgid "Not Installed"
+msgstr "설치 안됨"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "꺼짐"
+
+msgid "Bin 1"
+msgstr "칸 1"
+
+msgid "Bin 2"
+msgstr "칸 2"
+
+msgid "Bin 3"
+msgstr "칸 3"
+
+msgid "Bin 4"
+msgstr "칸 4"
+
+msgid "Bin 5"
+msgstr "칸 5"
+
+msgid "Bin 6"
+msgstr "칸 6"
+
+msgid "Bin 7"
+msgstr "칸 7"
+
+msgid "Bin 8"
+msgstr "칸 8"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54 x 72"
+
+msgid "54\" x 84\""
+msgstr "54 x 84"
+
+msgid "54\" x 96\""
+msgstr "54 x 96"
+
+msgid "60\" x 72\""
+msgstr "60 x 72"
+
+msgid "60\" x 84\""
+msgstr "60 x 84"
+
+msgid "60\" x 96\""
+msgstr "60 x 96"
+
+msgid "Photo Paper"
+msgstr "»çÁø ¿ëÁö"
+
+msgid "Plain Paper"
+msgstr "일반 용지"
+
+msgid "Letterhead"
+msgstr "미리 인쇄"
+
+msgid "Printer Default"
+msgstr "프린터의 현재 설정"
+
+msgid "Color"
+msgstr "컬러"
+
+msgid "Recycled Paper"
+msgstr "재활용지"
+
+msgid "Roll Feed"
+msgstr "롤 용지"
+
+msgid "Roll 1"
+msgstr "롤 용지 1"
+
+msgid "Roll 2"
+msgstr "롤 용지 2"
+
+msgid "Cut Sheet"
+msgstr "낱장 용지"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (특대)"
+
+msgid "12x18"
+msgstr "Tabloid Extra"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "Thick Paper"
+msgstr "두꺼운 외곽선"
+
+msgid "Top Output Tray"
+msgstr "상단 출력 용지함"
+
+msgid "Transparency"
+msgstr "투명 용지"
+
+msgid "Tray 1"
+msgstr "트레이 1"
+
+msgid "Tray 2"
+msgstr "용지함 2"
+
+msgid "Tray 3"
+msgstr "용지함 3"
+
+msgid "Tray 4"
+msgstr "용지함 4"
+
+msgid "Tray 5"
+msgstr "용지함 5"
+
+msgid "Tray 6"
+msgstr "용지함 6"
+
+msgid "Upper Tray"
+msgstr "»ó´Ü ¿ëÁöÇÔ"
+
diff --git a/locale/ppdc_nl.po b/locale/ppdc_nl.po
new file mode 100644 (file)
index 0000000..db97082
--- /dev/null
@@ -0,0 +1,381 @@
+msgid "Color Mode"
+msgstr "Kleurenmodus"
+
+msgid "2-Sided Printing"
+msgstr "Dubbelzijdig afdrukken"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Geïnstalleerde opties"
+
+msgid "Paper Type"
+msgstr "Papiersoort"
+
+msgid "Duplex Unit"
+msgstr "Duplex-eenheid"
+
+msgid "Optional Input Tray"
+msgstr "Optionele laden"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10 inch"
+
+msgid "9 x 11\""
+msgstr "9 x 11 inch"
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Gesloten boekenvelop"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (buitenmodel)"
+
+msgid "A3 Oversize Tray"
+msgstr "Lade A3 groot"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (klein)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "Auto Select"
+msgstr "Automatisch"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Zwart"
+
+msgid "Bond Paper"
+msgstr "Briefpapier"
+
+msgid "Bin 1"
+msgstr "Interne uitvoer 2"
+
+msgid "Bin 2"
+msgstr "Bak 2"
+
+msgid "Bin 3"
+msgstr "Bak 3"
+
+msgid "Bin 4"
+msgstr "Bak 4"
+
+msgid "Bin 5"
+msgstr "Bak 5"
+
+msgid "Bin 6"
+msgstr "Bak 6"
+
+msgid "Bin 7"
+msgstr "Bak 7"
+
+msgid "Bin 8"
+msgstr "Bak 8"
+
+msgid "Black Only"
+msgstr "Zwart"
+
+msgid "Bypass Tray"
+msgstr "Lade 1 (MPT)"
+
+msgid "C5 Envelope"
+msgstr "Env C5"
+
+msgid "Envelope C6"
+msgstr "Envelop C6"
+
+msgid "Color"
+msgstr "Kleur"
+
+msgid "Card Stock"
+msgstr "Karton"
+
+msgid "Paper Cassette"
+msgstr "Papierlade"
+
+msgid "Heavy Weight Matte"
+msgstr "Gecoat"
+
+msgid "Colored Paper"
+msgstr "Kleur"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printerstandaard"
+
+msgid "Long Edge"
+msgstr "Lange kant"
+
+msgid "Short Edge"
+msgstr "Korte kant"
+
+msgid "#10 Envelope"
+msgstr "#10-Envelop"
+
+msgid "C4 Envelope"
+msgstr "C4-envelop"
+
+msgid "C5 Envelope"
+msgstr "C5-envelop"
+
+msgid "C6 Env."
+msgstr "Env. C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL-envelop"
+
+msgid "B4 Envelope"
+msgstr "B4-envelop"
+
+msgid "Env ISO B5"
+msgstr "B5-envelop"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelop"
+
+msgid "Monarch Envelope"
+msgstr "Monarch-envelop"
+
+msgid "#6 3/4 Envelope"
+msgstr "Nr.6 3/4-envelop"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelop"
+
+msgid "7.25 x 10.5\""
+msgstr "7,25 x 10,5 inch"
+
+msgid "Off"
+msgstr "Uit"
+
+msgid "Glossy Paper"
+msgstr "Glanzend papier"
+
+msgid "Black and White"
+msgstr "Zwart-wit"
+
+msgid "Statement"
+msgstr "1/2 Letter "
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tabblad"
+
+msgid "Inkjet Paper"
+msgstr "Inkjetpapier"
+
+msgid "Iron-On Transfer"
+msgstr "Opstrijk-transfer"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Lade 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (klein)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (klein)"
+
+msgid "Lower Tray"
+msgstr "Lade 3"
+
+msgid "Manual Feed"
+msgstr "Handmatig"
+
+msgid "Middle Tray"
+msgstr "Lade 2"
+
+msgid "Off"
+msgstr "Geen"
+
+msgid "Not Installed"
+msgstr "Niet geïnstalleerd"
+
+msgid "On"
+msgstr "Aan"
+
+msgid "None"
+msgstr "Uit"
+
+msgid "Bin 1"
+msgstr "Bak 1"
+
+msgid "Bin 2"
+msgstr "Bak 2"
+
+msgid "Bin 3"
+msgstr "Bak 3"
+
+msgid "Bin 4"
+msgstr "Bak 4"
+
+msgid "Bin 5"
+msgstr "Bak 5"
+
+msgid "Bin 6"
+msgstr "Bak 6"
+
+msgid "Bin 7"
+msgstr "Bak 7"
+
+msgid "Bin 8"
+msgstr "Bak 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox lade 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox lade 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox lade 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox lade 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox lade 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox lade 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox lade 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox lade 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox lade 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox lade 9"
+
+msgid "Photo Paper"
+msgstr "Fotopapier"
+
+msgid "Plain Paper"
+msgstr "Normaal papier"
+
+msgid "Letterhead"
+msgstr "Voorgedrukt"
+
+msgid "Printer Default"
+msgstr "Standaardinstelling printer"
+
+msgid "Color"
+msgstr "Kleur"
+
+msgid "Recycled Paper"
+msgstr "Gerecycled"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tabbladen"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (buitenmodel)"
+
+msgid "12x18"
+msgstr "12 x 18 inch"
+
+msgid "Thick Paper"
+msgstr "Dik"
+
+msgid "Top Output Tray"
+msgstr "Bovenste opvangbak"
+
+msgid "Top Output Tray"
+msgstr "Bovenste uitvoerlade"
+
+msgid "Tray 1"
+msgstr "Lade 1"
+
+msgid "Tray 2"
+msgstr "Lade 2"
+
+msgid "Tray 3"
+msgstr "Lade 3"
+
+msgid "Tray 4"
+msgstr "Lade 4"
+
+msgid "Tray 5"
+msgstr "Lade 5"
+
+msgid "Tray 6"
+msgstr "Lade 6"
+
+msgid "Upper Tray"
+msgstr "Lade 1"
+
diff --git a/locale/ppdc_no.po b/locale/ppdc_no.po
new file mode 100644 (file)
index 0000000..a7efadd
--- /dev/null
@@ -0,0 +1,276 @@
+msgid "Color Mode"
+msgstr "Fargemodus"
+
+msgid "2-Sided Printing"
+msgstr "Tosidig"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Installerbart ekstrautstyr"
+
+msgid "Paper Type"
+msgstr "Papirtype"
+
+msgid "Optional Input Tray"
+msgstr "Optionele invoerlade"
+
+msgid "Optional Hard Disk"
+msgstr "Optionele vaste schijf"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10 t."
+
+msgid "9 x 11\""
+msgstr "9 x 11 t."
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (ekstra stort)"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (lite)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Svart"
+
+msgid "Bin 1"
+msgstr "Internt brett 2"
+
+msgid "Bin 2"
+msgstr "Utskuff 2"
+
+msgid "Bin 3"
+msgstr "Utskuff 3"
+
+msgid "Bin 4"
+msgstr "Utskuff 4"
+
+msgid "Bin 5"
+msgstr "Utskuff 5"
+
+msgid "Bin 6"
+msgstr "Utskuff 6"
+
+msgid "Bin 7"
+msgstr "Utskuff 7"
+
+msgid "Bin 8"
+msgstr "Utskuff 8"
+
+msgid "Black Only"
+msgstr "Svart"
+
+msgid "C5 Envelope"
+msgstr "C5-konvolutt"
+
+msgid "Color"
+msgstr "Farge"
+
+msgid "Card Stock"
+msgstr "Indekskort"
+
+msgid "Paper Cassette"
+msgstr "Papirkassett"
+
+msgid "Heavy Weight Matte"
+msgstr "Bestrøket"
+
+msgid "Colored Paper"
+msgstr "Farge"
+
+msgid "Env Comm10"
+msgstr "Comm10-konvolutt"
+
+msgid "Printer Default"
+msgstr "Skriverstandard"
+
+msgid "Long Edge"
+msgstr "Langsiden"
+
+msgid "Short Edge"
+msgstr "Kortsiden"
+
+msgid "#10 Envelope"
+msgstr "Comm10-konvolutt"
+
+msgid "C4 Envelope"
+msgstr "Konvolutt, C4 (324 x 229 mm)"
+
+msgid "C5 Envelope"
+msgstr "C5-konvolutt"
+
+msgid "C6 Env."
+msgstr "C6-konv."
+
+msgid "DL Envelope"
+msgstr "DL-konvolutt"
+
+msgid "Env ISO B5"
+msgstr "B5-konvolutt"
+
+msgid "Monarch Envelope"
+msgstr "Monarch-konvolutt"
+
+msgid "Envelope Feeder"
+msgstr "Konvolutt"
+
+msgid "7.25 x 10.5\""
+msgstr "7,25 x 10,5 t."
+
+msgid "Off"
+msgstr "Av"
+
+msgid "Glossy Paper"
+msgstr "Glanset"
+
+msgid "Black and White"
+msgstr "Svart-hvitt"
+
+msgid "Statement"
+msgstr "1/2 Letter"
+
+msgid "B5"
+msgstr "B5 (ISO)"
+
+msgid "B6"
+msgstr "B6 (ISO)"
+
+msgid "Tab Stock"
+msgstr "Faneark"
+
+msgid "Iron-On Transfer"
+msgstr "Påstrykningspapir"
+
+msgid "Tray 4"
+msgstr "Skuff 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (lite)"
+
+msgid "US Letter"
+msgstr "Tekst"
+
+msgid "Letter Plus"
+msgstr "SP Folio"
+
+msgid "Letter (Small)"
+msgstr "Letter (lite)"
+
+msgid "Lower Tray"
+msgstr "Skuff 3"
+
+msgid "Manual Feed"
+msgstr "Handmatig"
+
+msgid "Middle Tray"
+msgstr "Skuff 2"
+
+msgid "Off"
+msgstr "Ingen"
+
+msgid "None"
+msgstr "Av"
+
+msgid "Bin 1"
+msgstr "Skuff 1"
+
+msgid "Bin 2"
+msgstr "Skuff 2"
+
+msgid "Bin 3"
+msgstr "Skuff 3"
+
+msgid "Bin 4"
+msgstr "Skuff 4"
+
+msgid "Bin 5"
+msgstr "Skuff 5"
+
+msgid "Bin 6"
+msgstr "Skuff 6"
+
+msgid "Bin 7"
+msgstr "Skuff 7"
+
+msgid "Bin 8"
+msgstr "Skuff 8"
+
+msgid "Plain Paper"
+msgstr "Vanlig"
+
+msgid "Letterhead"
+msgstr "Fortrykt"
+
+msgid "Printer Default"
+msgstr "Skriverens gjeldende innstilling"
+
+msgid "Recycled Paper"
+msgstr "Resirkulert"
+
+msgid "Tab Stock"
+msgstr "Skillekort med fane"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (ekstra stort)"
+
+msgid "12x18"
+msgstr "12 x 18 tommer"
+
+msgid "Thick Paper"
+msgstr "Tykt"
+
+msgid "Top Output Tray"
+msgstr "Øvre mottaker"
+
+msgid "Tray 1"
+msgstr "Skuff 1"
+
+msgid "Tray 2"
+msgstr "Skuff 2"
+
+msgid "Tray 3"
+msgstr "Magasin 3"
+
+msgid "Tray 4"
+msgstr "Magasin 4"
+
+msgid "Tray 5"
+msgstr "Skuff 5"
+
+msgid "Tray 6"
+msgstr "Magasin 6 (stormagasin)"
+
+msgid "Upper Tray"
+msgstr "Skuff 1"
+
diff --git a/locale/ppdc_pl.po b/locale/ppdc_pl.po
new file mode 100644 (file)
index 0000000..96b4644
--- /dev/null
@@ -0,0 +1,592 @@
+# Template message catalog for the CUPS PPD compiler.
+msgid "Color Mode"
+msgstr "Color Mode"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options Installed"
+
+msgid "Paper Type"
+msgstr "Paper Type"
+
+msgid "Duplex Unit"
+msgstr "Duplex Unit"
+
+msgid "Optional Input Tray"
+msgstr "Optional Input Tray"
+
+msgid "Optional Hard Disk"
+msgstr "Optional Hard Disk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Closed Booklet Envelope"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A3 Oversize Tray"
+msgstr "A3 Oversize Tray"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "A6 Card"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Auto Select"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Black"
+
+msgid "Bond Paper"
+msgstr "Bond Paper"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 10"
+msgstr "Bin 10"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Bin 9"
+msgstr "Bin 9"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Bypass Tray"
+msgstr "Bypass Tray"
+
+msgid "9 Envelope"
+msgstr "9 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Card Stock"
+
+msgid "Paper Cassette"
+msgstr "Paper Cassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Heavy Weight Matte"
+
+msgid "Colored Paper"
+msgstr "Colored Paper"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Long Edge"
+msgstr "Long Edge"
+
+msgid "Short Edge"
+msgstr "Short Edge"
+
+msgid "#10 Envelope"
+msgstr "#10 Envelope"
+
+msgid "C4 Envelope"
+msgstr "C4 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL Envelope"
+
+msgid "B4 Envelope"
+msgstr "B4 Envelope"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelope"
+
+msgid "Monarch Envelope"
+msgstr "Monarch Envelope"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 Envelope"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Finisher Tray"
+msgstr "Finisher Tray"
+
+msgid "Glossy Paper"
+msgstr "Glossy Paper"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "Black and White"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet Paper"
+
+msgid "Installed"
+msgstr "Installed"
+
+msgid "Iron-On Transfer"
+msgstr "Iron-On Transfer"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Hagaki"
+msgstr "Hagaki"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Lower Tray"
+
+msgid "Mailbox"
+msgstr "Mailbox"
+
+msgid "Manual Feed"
+msgstr "Manual Feed"
+
+msgid "Manual Envelope"
+msgstr "Manual Envelope"
+
+msgid "Middle Tray"
+msgstr "Middle Tray"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Not Installed"
+msgstr "Not Installed"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Tray 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Tray 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Tray 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Tray 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Tray 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Tray 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Tray 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Tray 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Tray 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Tray 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Photo Paper"
+
+msgid "Plain Paper"
+msgstr "Plain Paper"
+
+msgid "Letterhead"
+msgstr "Letterhead"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Recycled Paper"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Thick Paper"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6"
+
+msgid "Upper Tray"
+msgstr "Upper Tray"
+
diff --git a/locale/ppdc_pt.po b/locale/ppdc_pt.po
new file mode 100644 (file)
index 0000000..c86176f
--- /dev/null
@@ -0,0 +1,483 @@
+msgid "Color Mode"
+msgstr "Modo Cor"
+
+msgid "2-Sided Printing"
+msgstr "Impressão em Frente e Verso"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Opções instaladas"
+
+msgid "Paper Type"
+msgstr "Tipo de Papel"
+
+msgid "Duplex Unit"
+msgstr "Unidade dúplex"
+
+msgid "Optional Input Tray"
+msgstr "Bandeja de Entrada Opcional"
+
+msgid "Optional Hard Disk"
+msgstr "Disco Rígido Opcional"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "Envelope livreto fechado 9x12"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (extragrande)"
+
+msgid "A3 Oversize Tray"
+msgstr "Bandeja para A3 estendido      "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (pequeno)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "Arch A"
+
+msgid "ARCH B"
+msgstr "Arch B"
+
+msgid "ARCH C"
+msgstr "Arch C"
+
+msgid "ARCH D"
+msgstr "Arch D"
+
+msgid "ARCH E"
+msgstr "Arch E"
+
+msgid "Adhesive Paper"
+msgstr "Papel adesivo"
+
+msgid "ANSI C"
+msgstr "C"
+
+msgid "ANSI D"
+msgstr "D"
+
+msgid "ANSI E"
+msgstr "E"
+
+msgid "Auto Select"
+msgstr "Seleção automática"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 JIS"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 JIS"
+
+msgid "Bond Paper"
+msgstr "Papel bond"
+
+msgid "Bin 1"
+msgstr "Bandeja de Saída 1"
+
+msgid "Bin 10"
+msgstr "Bandeja de Saída 10"
+
+msgid "Bin 2"
+msgstr "Bandeja de Saída 2"
+
+msgid "Bin 3"
+msgstr "Bandeja de Saída 3"
+
+msgid "Bin 4"
+msgstr "Bandeja de Saída 4"
+
+msgid "Bin 5"
+msgstr "Bandeja de Saída 5"
+
+msgid "Bin 6"
+msgstr "Bandeja de Saída 6"
+
+msgid "Bin 7"
+msgstr "Bandeja de Saída 7"
+
+msgid "Bin 8"
+msgstr "Bandeja de Saída 8"
+
+msgid "Bin 9"
+msgstr "Bandeja de Saída 9"
+
+msgid "Black Only"
+msgstr "Somente em preto"
+
+msgid "Bypass Tray"
+msgstr "Bandeja 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "Envelope C9"
+
+msgid "C5 Envelope"
+msgstr "Envelope C5"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Inativo"
+
+msgid "Card Stock"
+msgstr "Cartolina"
+
+msgid "Paper Cassette"
+msgstr "Cassete para Papel"
+
+msgid "Colored Paper"
+msgstr "Cor"
+
+msgid "Env Comm10"
+msgstr "Env. Comm10"
+
+msgid "Printer Default"
+msgstr "Rápido"
+
+msgid "Long Edge"
+msgstr "Encadernação em borda longa"
+
+msgid "Short Edge"
+msgstr "Encadernação em borda curta"
+
+msgid "#10 Envelope"
+msgstr "Envelope n°10"
+
+msgid "C4 Envelope"
+msgstr "Envelope C4"
+
+msgid "C5 Envelope"
+msgstr "Envelope C5"
+
+msgid "C6 Env."
+msgstr "Envelope C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "Envelope DL"
+
+msgid "B4 Envelope"
+msgstr "Envelope B4"
+
+msgid "Env ISO B5"
+msgstr "Envelope B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Envelope Kaku nº2"
+
+msgid "Monarch Envelope"
+msgstr "Envelope Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Envelope nº 6 3/4"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelopes"
+
+msgid "7.25 x 10.5\""
+msgstr "Executivo"
+
+msgid "Off"
+msgstr "Desligado"
+
+msgid "Glossy Paper"
+msgstr "Papel acetinado"
+
+msgid "Glossy Film"
+msgstr "Filme brilhante"
+
+msgid "Black and White"
+msgstr "Cinza"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "Envelope B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Inkjet Paper"
+msgstr "Papel impressora de tinta"
+
+msgid "Installed"
+msgstr "Instalada"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Etiquetas"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "US Legal"
+msgstr "Ofício"
+
+msgid "Legal (Small)"
+msgstr "Legal (pequeno)"
+
+msgid "US Letter"
+msgstr "Carta"
+
+msgid "Letter Plus"
+msgstr "Carta Plus"
+
+msgid "Letter (Small)"
+msgstr "Carta (pequeno)"
+
+msgid "Lower Tray"
+msgstr "Bandeja 3"
+
+msgid "Manual Feed"
+msgstr "Alimentação Manual"
+
+msgid "Manual Envelope"
+msgstr "Envelope Manual"
+
+msgid "Middle Tray"
+msgstr "Bandeja 2"
+
+msgid "Off"
+msgstr "Nenhum"
+
+msgid "Not Installed"
+msgstr "Não instalado"
+
+msgid "On"
+msgstr "Ativado"
+
+msgid "None"
+msgstr "Desactivar"
+
+msgid "Bin 1"
+msgstr "Compartimento 1"
+
+msgid "Bin 2"
+msgstr "Compartimento 2"
+
+msgid "Bin 3"
+msgstr "Compartimento 3"
+
+msgid "Bin 4"
+msgstr "Compartimento 4"
+
+msgid "Bin 5"
+msgstr "Compartimento 5"
+
+msgid "Bin 6"
+msgstr "Compartimento 6"
+
+msgid "Bin 7"
+msgstr "Compartimento 7"
+
+msgid "Bin 8"
+msgstr "Compartimento 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Bandeja MX1 (Caixa de Correio)"
+
+msgid "Mailbox Tray 10"
+msgstr "Bandeja MX10 (Caixa de Correio)"
+
+msgid "Mailbox Tray 2"
+msgstr "Bandeja MX2 (Caixa de Correio)"
+
+msgid "Mailbox Tray 3"
+msgstr "Bandeja MX3 (Caixa de Correio)"
+
+msgid "Mailbox Tray 4"
+msgstr "Bandeja MX4 (Caixa de Correio)"
+
+msgid "Mailbox Tray 5"
+msgstr "Bandeja MX5 (Caixa de Correio)"
+
+msgid "Mailbox Tray 6"
+msgstr "Bandeja MX6 (Caixa de Correio)"
+
+msgid "Mailbox Tray 7"
+msgstr "Bandeja MX7 (Caixa de Correio)"
+
+msgid "Mailbox Tray 8"
+msgstr "Bandeja MX8 (Caixa de Correio)"
+
+msgid "Mailbox Tray 9"
+msgstr "Bandeja MX9 (Caixa de Correio)"
+
+msgid "Photo Paper"
+msgstr "Papel fotográfico"
+
+msgid "Plain Paper"
+msgstr "Papel normal"
+
+msgid "Letterhead"
+msgstr "Pré-impresso"
+
+msgid "Printer Default"
+msgstr "Padrão da impressora"
+
+msgid "Color"
+msgstr "Colorido"
+
+msgid "Recycled Paper"
+msgstr "Reciclado"
+
+msgid "Roll Feed"
+msgstr "Rolo"
+
+msgid "Roll 1"
+msgstr "Rolo 1"
+
+msgid "Roll 2"
+msgstr "Rolo 2"
+
+msgid "Cut Sheet"
+msgstr "Folha"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Divisórias"
+
+msgid "11x17"
+msgstr "Tablóide"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (extragrande)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Thick Paper"
+msgstr "Papel grosso"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de Saída Superior"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de saída superior"
+
+msgid "Transparency"
+msgstr "Transparência"
+
+msgid "Tray 1"
+msgstr "Bandeja 1"
+
+msgid "Tray 2"
+msgstr "Bandeja 2"
+
+msgid "Tray 3"
+msgstr "Bandeja 3"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "Tray 5"
+msgstr "Bandeja 5"
+
+msgid "Tray 6"
+msgstr "Bandeja 6"
+
+msgid "Upper Tray"
+msgstr "Bandeja 1"
+
diff --git a/locale/ppdc_pt_BR.po b/locale/ppdc_pt_BR.po
new file mode 100644 (file)
index 0000000..c86176f
--- /dev/null
@@ -0,0 +1,483 @@
+msgid "Color Mode"
+msgstr "Modo Cor"
+
+msgid "2-Sided Printing"
+msgstr "Impressão em Frente e Verso"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Opções instaladas"
+
+msgid "Paper Type"
+msgstr "Tipo de Papel"
+
+msgid "Duplex Unit"
+msgstr "Unidade dúplex"
+
+msgid "Optional Input Tray"
+msgstr "Bandeja de Entrada Opcional"
+
+msgid "Optional Hard Disk"
+msgstr "Disco Rígido Opcional"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "Envelope livreto fechado 9x12"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (extragrande)"
+
+msgid "A3 Oversize Tray"
+msgstr "Bandeja para A3 estendido      "
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (pequeno)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "Arch A"
+
+msgid "ARCH B"
+msgstr "Arch B"
+
+msgid "ARCH C"
+msgstr "Arch C"
+
+msgid "ARCH D"
+msgstr "Arch D"
+
+msgid "ARCH E"
+msgstr "Arch E"
+
+msgid "Adhesive Paper"
+msgstr "Papel adesivo"
+
+msgid "ANSI C"
+msgstr "C"
+
+msgid "ANSI D"
+msgstr "D"
+
+msgid "ANSI E"
+msgstr "E"
+
+msgid "Auto Select"
+msgstr "Seleção automática"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 JIS"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 JIS"
+
+msgid "Bond Paper"
+msgstr "Papel bond"
+
+msgid "Bin 1"
+msgstr "Bandeja de Saída 1"
+
+msgid "Bin 10"
+msgstr "Bandeja de Saída 10"
+
+msgid "Bin 2"
+msgstr "Bandeja de Saída 2"
+
+msgid "Bin 3"
+msgstr "Bandeja de Saída 3"
+
+msgid "Bin 4"
+msgstr "Bandeja de Saída 4"
+
+msgid "Bin 5"
+msgstr "Bandeja de Saída 5"
+
+msgid "Bin 6"
+msgstr "Bandeja de Saída 6"
+
+msgid "Bin 7"
+msgstr "Bandeja de Saída 7"
+
+msgid "Bin 8"
+msgstr "Bandeja de Saída 8"
+
+msgid "Bin 9"
+msgstr "Bandeja de Saída 9"
+
+msgid "Black Only"
+msgstr "Somente em preto"
+
+msgid "Bypass Tray"
+msgstr "Bandeja 1 (MPT)"
+
+msgid "9 Envelope"
+msgstr "Envelope C9"
+
+msgid "C5 Envelope"
+msgstr "Envelope C5"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Inativo"
+
+msgid "Card Stock"
+msgstr "Cartolina"
+
+msgid "Paper Cassette"
+msgstr "Cassete para Papel"
+
+msgid "Colored Paper"
+msgstr "Cor"
+
+msgid "Env Comm10"
+msgstr "Env. Comm10"
+
+msgid "Printer Default"
+msgstr "Rápido"
+
+msgid "Long Edge"
+msgstr "Encadernação em borda longa"
+
+msgid "Short Edge"
+msgstr "Encadernação em borda curta"
+
+msgid "#10 Envelope"
+msgstr "Envelope n°10"
+
+msgid "C4 Envelope"
+msgstr "Envelope C4"
+
+msgid "C5 Envelope"
+msgstr "Envelope C5"
+
+msgid "C6 Env."
+msgstr "Envelope C6"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "Envelope DL"
+
+msgid "B4 Envelope"
+msgstr "Envelope B4"
+
+msgid "Env ISO B5"
+msgstr "Envelope B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Envelope Kaku nº2"
+
+msgid "Monarch Envelope"
+msgstr "Envelope Monarch"
+
+msgid "#6 3/4 Envelope"
+msgstr "Envelope nº 6 3/4"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelopes"
+
+msgid "7.25 x 10.5\""
+msgstr "Executivo"
+
+msgid "Off"
+msgstr "Desligado"
+
+msgid "Glossy Paper"
+msgstr "Papel acetinado"
+
+msgid "Glossy Film"
+msgstr "Filme brilhante"
+
+msgid "Black and White"
+msgstr "Cinza"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "Envelope B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Inkjet Paper"
+msgstr "Papel impressora de tinta"
+
+msgid "Installed"
+msgstr "Instalada"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Etiquetas"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "US Legal"
+msgstr "Ofício"
+
+msgid "Legal (Small)"
+msgstr "Legal (pequeno)"
+
+msgid "US Letter"
+msgstr "Carta"
+
+msgid "Letter Plus"
+msgstr "Carta Plus"
+
+msgid "Letter (Small)"
+msgstr "Carta (pequeno)"
+
+msgid "Lower Tray"
+msgstr "Bandeja 3"
+
+msgid "Manual Feed"
+msgstr "Alimentação Manual"
+
+msgid "Manual Envelope"
+msgstr "Envelope Manual"
+
+msgid "Middle Tray"
+msgstr "Bandeja 2"
+
+msgid "Off"
+msgstr "Nenhum"
+
+msgid "Not Installed"
+msgstr "Não instalado"
+
+msgid "On"
+msgstr "Ativado"
+
+msgid "None"
+msgstr "Desactivar"
+
+msgid "Bin 1"
+msgstr "Compartimento 1"
+
+msgid "Bin 2"
+msgstr "Compartimento 2"
+
+msgid "Bin 3"
+msgstr "Compartimento 3"
+
+msgid "Bin 4"
+msgstr "Compartimento 4"
+
+msgid "Bin 5"
+msgstr "Compartimento 5"
+
+msgid "Bin 6"
+msgstr "Compartimento 6"
+
+msgid "Bin 7"
+msgstr "Compartimento 7"
+
+msgid "Bin 8"
+msgstr "Compartimento 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Bandeja MX1 (Caixa de Correio)"
+
+msgid "Mailbox Tray 10"
+msgstr "Bandeja MX10 (Caixa de Correio)"
+
+msgid "Mailbox Tray 2"
+msgstr "Bandeja MX2 (Caixa de Correio)"
+
+msgid "Mailbox Tray 3"
+msgstr "Bandeja MX3 (Caixa de Correio)"
+
+msgid "Mailbox Tray 4"
+msgstr "Bandeja MX4 (Caixa de Correio)"
+
+msgid "Mailbox Tray 5"
+msgstr "Bandeja MX5 (Caixa de Correio)"
+
+msgid "Mailbox Tray 6"
+msgstr "Bandeja MX6 (Caixa de Correio)"
+
+msgid "Mailbox Tray 7"
+msgstr "Bandeja MX7 (Caixa de Correio)"
+
+msgid "Mailbox Tray 8"
+msgstr "Bandeja MX8 (Caixa de Correio)"
+
+msgid "Mailbox Tray 9"
+msgstr "Bandeja MX9 (Caixa de Correio)"
+
+msgid "Photo Paper"
+msgstr "Papel fotográfico"
+
+msgid "Plain Paper"
+msgstr "Papel normal"
+
+msgid "Letterhead"
+msgstr "Pré-impresso"
+
+msgid "Printer Default"
+msgstr "Padrão da impressora"
+
+msgid "Color"
+msgstr "Colorido"
+
+msgid "Recycled Paper"
+msgstr "Reciclado"
+
+msgid "Roll Feed"
+msgstr "Rolo"
+
+msgid "Roll 1"
+msgstr "Rolo 1"
+
+msgid "Roll 2"
+msgstr "Rolo 2"
+
+msgid "Cut Sheet"
+msgstr "Folha"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Divisórias"
+
+msgid "11x17"
+msgstr "Tablóide"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (extragrande)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Thick Paper"
+msgstr "Papel grosso"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de Saída Superior"
+
+msgid "Top Output Tray"
+msgstr "Bandeja de saída superior"
+
+msgid "Transparency"
+msgstr "Transparência"
+
+msgid "Tray 1"
+msgstr "Bandeja 1"
+
+msgid "Tray 2"
+msgstr "Bandeja 2"
+
+msgid "Tray 3"
+msgstr "Bandeja 3"
+
+msgid "Tray 4"
+msgstr "Bandeja 4"
+
+msgid "Tray 5"
+msgstr "Bandeja 5"
+
+msgid "Tray 6"
+msgstr "Bandeja 6"
+
+msgid "Upper Tray"
+msgstr "Bandeja 1"
+
diff --git a/locale/ppdc_ru.po b/locale/ppdc_ru.po
new file mode 100644 (file)
index 0000000..96b4644
--- /dev/null
@@ -0,0 +1,592 @@
+# Template message catalog for the CUPS PPD compiler.
+msgid "Color Mode"
+msgstr "Color Mode"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Options Installed"
+
+msgid "Paper Type"
+msgstr "Paper Type"
+
+msgid "Duplex Unit"
+msgstr "Duplex Unit"
+
+msgid "Optional Input Tray"
+msgstr "Optional Input Tray"
+
+msgid "Optional Hard Disk"
+msgstr "Optional Hard Disk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10\""
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9x12 Closed Booklet Envelope"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "A3 Oversize Tray"
+msgstr "A3 Oversize Tray"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (105 x 148 mm)"
+
+msgid "A6 Card"
+msgstr "A6 Card"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "Auto Select"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Black"
+
+msgid "Bond Paper"
+msgstr "Bond Paper"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 10"
+msgstr "Bin 10"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Bin 9"
+msgstr "Bin 9"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Bypass Tray"
+msgstr "Bypass Tray"
+
+msgid "9 Envelope"
+msgstr "9 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "Envelope C6"
+msgstr "Envelope C6"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Card Stock"
+msgstr "Card Stock"
+
+msgid "Paper Cassette"
+msgstr "Paper Cassette"
+
+msgid "Heavy Weight Matte"
+msgstr "Heavy Weight Matte"
+
+msgid "Colored Paper"
+msgstr "Colored Paper"
+
+msgid "Env Comm10"
+msgstr "Env Comm10"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Long Edge"
+msgstr "Long Edge"
+
+msgid "Short Edge"
+msgstr "Short Edge"
+
+msgid "#10 Envelope"
+msgstr "#10 Envelope"
+
+msgid "C4 Envelope"
+msgstr "C4 Envelope"
+
+msgid "C5 Envelope"
+msgstr "C5 Envelope"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL Envelope"
+
+msgid "B4 Envelope"
+msgstr "B4 Envelope"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 envelope"
+
+msgid "Monarch Envelope"
+msgstr "Monarch Envelope"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4 Envelope"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "7.25 x 10.5\""
+msgstr "7.25 x 10.5\""
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Finisher Tray"
+msgstr "Finisher Tray"
+
+msgid "Glossy Paper"
+msgstr "Glossy Paper"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "Black and White"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "ISO B3"
+msgstr "ISO B3"
+
+msgid "ISO B4"
+msgstr "ISO B4"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "Inkjet Paper"
+msgstr "Inkjet Paper"
+
+msgid "Installed"
+msgstr "Installed"
+
+msgid "Iron-On Transfer"
+msgstr "Iron-On Transfer"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Hagaki"
+msgstr "Hagaki"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Labels"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Lower Tray"
+
+msgid "Mailbox"
+msgstr "Mailbox"
+
+msgid "Manual Feed"
+msgstr "Manual Feed"
+
+msgid "Manual Envelope"
+msgstr "Manual Envelope"
+
+msgid "Middle Tray"
+msgstr "Middle Tray"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "Not Installed"
+msgstr "Not Installed"
+
+msgid "On"
+msgstr "On"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Bin 1"
+
+msgid "Bin 2"
+msgstr "Bin 2"
+
+msgid "Bin 3"
+msgstr "Bin 3"
+
+msgid "Bin 4"
+msgstr "Bin 4"
+
+msgid "Bin 5"
+msgstr "Bin 5"
+
+msgid "Bin 6"
+msgstr "Bin 6"
+
+msgid "Bin 7"
+msgstr "Bin 7"
+
+msgid "Bin 8"
+msgstr "Bin 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Mailbox Tray 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Mailbox Tray 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Mailbox Tray 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Mailbox Tray 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Mailbox Tray 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Mailbox Tray 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Mailbox Tray 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Mailbox Tray 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Mailbox Tray 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Mailbox Tray 9"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Photo Paper"
+msgstr "Photo Paper"
+
+msgid "Plain Paper"
+msgstr "Plain Paper"
+
+msgid "Letterhead"
+msgstr "Letterhead"
+
+msgid "Printer Default"
+msgstr "Printer Default"
+
+msgid "Color"
+msgstr "Color"
+
+msgid "Recycled Paper"
+msgstr "Recycled Paper"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Tab Stock"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "12x18"
+msgstr "12x18"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "Thick Paper"
+msgstr "Thick Paper"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Top Output Tray"
+msgstr "Top Output Tray"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6"
+
+msgid "Upper Tray"
+msgstr "Upper Tray"
+
diff --git a/locale/ppdc_sv.po b/locale/ppdc_sv.po
new file mode 100644 (file)
index 0000000..1ef252d
--- /dev/null
@@ -0,0 +1,378 @@
+msgid "Color Mode"
+msgstr "Färginställningar"
+
+msgid "2-Sided Printing"
+msgstr "Dubbelsidig utskrift"
+
+msgid "Media Source"
+msgstr "Media Source"
+
+msgid "Options Installed"
+msgstr "Installerade alternativ"
+
+msgid "Paper Type"
+msgstr "Papperstyp"
+
+msgid "Duplex Unit"
+msgstr "Enhet för dubbelsidig utskrift"
+
+msgid "Optional Input Tray"
+msgstr "Inmatningsfack (tillval)"
+
+msgid "Optional Hard Disk"
+msgstr "Valfri hårddisk"
+
+msgid "Media Size"
+msgstr "Media Size"
+
+msgid "8 x 10\""
+msgstr "8 x 10 tum"
+
+msgid "9 x 11\""
+msgstr "9 x 11\""
+
+msgid "9x12 Closed Booklet Envelope"
+msgstr "9 x 12\" Kuvert"
+
+msgid "A3 (297 x 420 mm)"
+msgstr "A3 (297 x 420 mm)"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (extra stor)"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297 mm)"
+
+msgid "A4 (Small)"
+msgstr "A4 (litet)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 (100 x 148 mm)"
+
+msgid "Auto Select"
+msgstr "Välj automatiskt"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Black"
+msgstr "Svart"
+
+msgid "Bond Paper"
+msgstr "Strukturpapper"
+
+msgid "Bin 1"
+msgstr "Internt utmatningsfack 2"
+
+msgid "Bin 2"
+msgstr "Fack 2"
+
+msgid "Bin 3"
+msgstr "Fack 3"
+
+msgid "Bin 4"
+msgstr "Fack 4"
+
+msgid "Bin 5"
+msgstr "Fack 5"
+
+msgid "Bin 6"
+msgstr "Fack 6"
+
+msgid "Bin 7"
+msgstr "Fack 7"
+
+msgid "Bin 8"
+msgstr "Fack 8"
+
+msgid "Black Only"
+msgstr "Svart"
+
+msgid "Bypass Tray"
+msgstr "Fack 1 (MPT)"
+
+msgid "C5 Envelope"
+msgstr "Kuv C5"
+
+msgid "Envelope C6"
+msgstr "Kuvert C6"
+
+msgid "Color"
+msgstr "Färgat"
+
+msgid "Card Stock"
+msgstr "Vykort"
+
+msgid "Paper Cassette"
+msgstr "Pappersmagasin"
+
+msgid "Heavy Weight Matte"
+msgstr "Bestruket"
+
+msgid "Colored Paper"
+msgstr "Färgat"
+
+msgid "Env Comm10"
+msgstr "Kuv Comm10"
+
+msgid "Printer Default"
+msgstr "Skrivarstandard"
+
+msgid "Long Edge"
+msgstr "Bindning längs långsidan"
+
+msgid "Short Edge"
+msgstr "Bindning längs kortsidan"
+
+msgid "#10 Envelope"
+msgstr "Kuvert #10"
+
+msgid "C4 Envelope"
+msgstr "C4-kuvert"
+
+msgid "C5 Envelope"
+msgstr "C5-kuvert"
+
+msgid "C6 Env."
+msgstr "C6 Kuvert"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "Choukei 4 Gou"
+msgstr "Choukei 4 Gou"
+
+msgid "DL Envelope"
+msgstr "DL-kuvert"
+
+msgid "B4 Envelope"
+msgstr "B4-kuvert"
+
+msgid "Env ISO B5"
+msgstr "ISO B5-kuvert"
+
+msgid "B6 "
+msgstr "B6 "
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2, kuvert"
+
+msgid "Monarch Envelope"
+msgstr "Monarch-kuvert"
+
+msgid "#6 3/4 Envelope"
+msgstr "#6 3/4-kuvert"
+
+msgid "Envelope #4"
+msgstr "Envelope #4"
+
+msgid "Envelope Feeder"
+msgstr "Kuvert"
+
+msgid "7.25 x 10.5\""
+msgstr "7,25 x 10,5\""
+
+msgid "Off"
+msgstr "Av"
+
+msgid "Finisher Tray"
+msgstr "Efterbehandlare"
+
+msgid "Glossy Paper"
+msgstr "Glättat papper"
+
+msgid "Black and White"
+msgstr "Svartvit"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "B5"
+msgstr "B5"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Tab Stock"
+msgstr "Registerflikar"
+
+msgid "Inkjet Paper"
+msgstr "Bläckpapper"
+
+msgid "Iron-On Transfer"
+msgstr "Transferpapper"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Labels"
+msgstr "Etiketter"
+
+msgid "Tray 4"
+msgstr "Fack 4"
+
+msgid "US Legal"
+msgstr "US Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (litet)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Letter Plus"
+msgstr "Letter Plus"
+
+msgid "Letter (Small)"
+msgstr "Letter (litet)"
+
+msgid "Lower Tray"
+msgstr "Fack 3"
+
+msgid "Manual Feed"
+msgstr "Manuell"
+
+msgid "Middle Tray"
+msgstr "Fack 2"
+
+msgid "Off"
+msgstr "Av"
+
+msgid "Not Installed"
+msgstr "Ej installerad"
+
+msgid "On"
+msgstr "På"
+
+msgid "None"
+msgstr "Av"
+
+msgid "Bin 1"
+msgstr "Fack 1"
+
+msgid "Bin 2"
+msgstr "Fack 2"
+
+msgid "Bin 3"
+msgstr "Fack 3"
+
+msgid "Bin 4"
+msgstr "Fack 4"
+
+msgid "Bin 5"
+msgstr "Fack 5"
+
+msgid "Bin 6"
+msgstr "Fack 6"
+
+msgid "Bin 7"
+msgstr "Fack 7"
+
+msgid "Bin 8"
+msgstr "Fack 8"
+
+msgid "Mailbox Tray 1"
+msgstr "Sort fack 1"
+
+msgid "Mailbox Tray 10"
+msgstr "Sort fack 10"
+
+msgid "Mailbox Tray 2"
+msgstr "Sort fack 2"
+
+msgid "Mailbox Tray 3"
+msgstr "Sort fack 3"
+
+msgid "Mailbox Tray 4"
+msgstr "Sort fack 4"
+
+msgid "Mailbox Tray 5"
+msgstr "Sort fack 5"
+
+msgid "Mailbox Tray 6"
+msgstr "Sort fack 6"
+
+msgid "Mailbox Tray 7"
+msgstr "Sort fack 7"
+
+msgid "Mailbox Tray 8"
+msgstr "Sort fack 8"
+
+msgid "Mailbox Tray 9"
+msgstr "Sort fack 9"
+
+msgid "Photo Paper"
+msgstr "Fotopapper"
+
+msgid "Plain Paper"
+msgstr "Vanligt papper"
+
+msgid "Letterhead"
+msgstr "Förtryckt"
+
+msgid "Printer Default"
+msgstr "Skrivarens inställning"
+
+msgid "Color"
+msgstr "Färg"
+
+msgid "Recycled Paper"
+msgstr "Återvunnet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "Tab Stock"
+msgstr "Flikar"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (extra stor)"
+
+msgid "12x18"
+msgstr "Tabloid Extra"
+
+msgid "Thick Paper"
+msgstr "Tjockt"
+
+msgid "Top Output Tray"
+msgstr "Övre utmatningsfack"
+
+msgid "Top Output Tray"
+msgstr "Övre utmatningsfack"
+
+msgid "Tray 1"
+msgstr "Fack 1"
+
+msgid "Tray 2"
+msgstr "Fack 2"
+
+msgid "Tray 3"
+msgstr "Fack 3"
+
+msgid "Tray 4"
+msgstr "Fack 4"
+
+msgid "Tray 5"
+msgstr "Fack 5"
+
+msgid "Tray 6"
+msgstr "Fack 6"
+
+msgid "Upper Tray"
+msgstr "Fack 1"
+
diff --git a/locale/ppdc_zh.po b/locale/ppdc_zh.po
new file mode 100644 (file)
index 0000000..2f9faae
--- /dev/null
@@ -0,0 +1,417 @@
+msgid "Color Mode"
+msgstr "色彩模式"
+
+msgid "2-Sided Printing"
+msgstr "2-Sided Printing"
+
+msgid "Media Source"
+msgstr "Paper Source"
+
+msgid "Options Installed"
+msgstr "Installed Options"
+
+msgid "Paper Type"
+msgstr "Media Type"
+
+msgid "Media Size"
+msgstr "Page Size"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (Oversize)"
+
+msgid "Full Bleed A3"
+msgstr "Full Bleed A3"
+
+msgid "Full Bleed A4"
+msgstr "Full Bleed A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (Small)"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "Adhesive Paper"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "Auto Select"
+msgstr "自动选择"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "B4 (JIS)"
+
+msgid "JIS B5"
+msgstr "B5 (JIS)"
+
+msgid "B6 (JIS)"
+msgstr "B6 (JIS)"
+
+msgid "Bond Paper"
+msgstr "铜板纸"
+
+msgid "Bin 1"
+msgstr "Output Bin 1"
+
+msgid "Bin 2"
+msgstr "Output Bin 2"
+
+msgid "Bin 3"
+msgstr "Output Bin 3"
+
+msgid "Bin 4"
+msgstr "Output Bin 4"
+
+msgid "Bin 5"
+msgstr "Output Bin 5"
+
+msgid "Bin 6"
+msgstr "Output Bin 6"
+
+msgid "Bin 7"
+msgstr "Output Bin 7"
+
+msgid "Bin 8"
+msgstr "Output Bin 8"
+
+msgid "Black Only"
+msgstr "Black Only"
+
+msgid "Color"
+msgstr "Off"
+
+msgid "Card Stock"
+msgstr "Card Stock 164-200 g"
+
+msgid "Colored Paper"
+msgstr "彩色"
+
+msgid "Long Edge"
+msgstr "Long-Edge Binding"
+
+msgid "Short Edge"
+msgstr "Short-Edge Binding"
+
+msgid "#10 Envelope"
+msgstr "Com-10"
+
+msgid "C5 Envelope"
+msgstr "Env C5"
+
+msgid "C6 Env."
+msgstr "C6 信封"
+
+msgid "Envelope MAX"
+msgstr "Envelope MAX"
+
+msgid "DL Envelope"
+msgstr "DL 信封"
+
+msgid "Env ISO B5"
+msgstr "Env ISO B5"
+
+msgid "Kaku #2 envelope"
+msgstr "Kaku #2 信封"
+
+msgid "Monarch Envelope"
+msgstr "Monarch"
+
+msgid "Envelope #4"
+msgstr "JE4 信封"
+
+msgid "Envelope Feeder"
+msgstr "Envelope Feeder"
+
+msgid "Off"
+msgstr "No"
+
+msgid "Glossy Paper"
+msgstr "光面纸"
+
+msgid "Glossy Film"
+msgstr "Glossy Film"
+
+msgid "Black and White"
+msgstr "On"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "B5"
+msgstr "B5 (ISO)"
+
+msgid "B6"
+msgstr "B6"
+
+msgid "Inkjet Paper"
+msgstr "喷墨专用纸"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "US Legal"
+msgstr "美国法定用纸"
+
+msgid "Legal (Small)"
+msgstr "Legal (Small)"
+
+msgid "US Letter"
+msgstr "美国信纸"
+
+msgid "Full Bleed US Letter"
+msgstr "Full Bleed US Letter"
+
+msgid "Letter (Small)"
+msgstr "Letter (Small)"
+
+msgid "Lower Tray"
+msgstr "Tray 3"
+
+msgid "Manual Feed"
+msgstr "手动"
+
+msgid "Middle Tray"
+msgstr "Tray 2"
+
+msgid "Off"
+msgstr "Off"
+
+msgid "On"
+msgstr "开"
+
+msgid "Oversize A0"
+msgstr "Oversize A0"
+
+msgid "Oversize A1"
+msgstr "Oversize A1"
+
+msgid "Oversize A2"
+msgstr "Oversize A2"
+
+msgid "None"
+msgstr "None"
+
+msgid "Bin 1"
+msgstr "Mailbox 1 (Face Down)"
+
+msgid "Bin 2"
+msgstr "Mailbox 2 (Face Down)"
+
+msgid "Bin 3"
+msgstr "Mailbox 3 (Face Down)"
+
+msgid "Bin 4"
+msgstr "Mailbox 4 (Face Down)"
+
+msgid "Bin 5"
+msgstr "Mailbox 5 (Face Down)"
+
+msgid "Bin 6"
+msgstr "Mailbox 6 (Face Down)"
+
+msgid "Bin 7"
+msgstr "Mailbox 7 (Face Down)"
+
+msgid "Bin 8"
+msgstr "Mailbox 8 (Face Down)"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54\" x 72\""
+
+msgid "54\" x 84\""
+msgstr "54\" x 84\""
+
+msgid "54\" x 96\""
+msgstr "54\" x 96\""
+
+msgid "60\" x 72\""
+msgstr "60\" x 72\""
+
+msgid "60\" x 84\""
+msgstr "60\" x 84\""
+
+msgid "60\" x 96\""
+msgstr "60\" x 96\""
+
+msgid "Plain Paper"
+msgstr "普通纸"
+
+msgid "Printer Default"
+msgstr "Printer's Current Setting"
+
+msgid "Color"
+msgstr "颜色"
+
+msgid "Recycled Paper"
+msgstr "再生纸"
+
+msgid "Roll Feed"
+msgstr "Roll Feed"
+
+msgid "Roll 1"
+msgstr "Roll 1"
+
+msgid "Roll 2"
+msgstr "Roll 2"
+
+msgid "Cut Sheet"
+msgstr "Cut Sheet"
+
+msgid "Super B"
+msgstr "Super B"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "11x17"
+msgstr "11x17"
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (Oversize)"
+
+msgid "Full Bleed Tabloid"
+msgstr "Full Bleed Tabloid"
+
+msgid "Thick Paper"
+msgstr "厚"
+
+msgid "Transparency"
+msgstr "Transparency"
+
+msgid "Tray 1"
+msgstr "Tray 1"
+
+msgid "Tray 2"
+msgstr "Tray 2"
+
+msgid "Tray 3"
+msgstr "Tray 3"
+
+msgid "Tray 4"
+msgstr "Tray 4"
+
+msgid "Tray 5"
+msgstr "Tray 5"
+
+msgid "Tray 6"
+msgstr "Tray 6 "
+
+msgid "Upper Tray"
+msgstr "Tray 1"
+
diff --git a/locale/ppdc_zh_TW.po b/locale/ppdc_zh_TW.po
new file mode 100644 (file)
index 0000000..34288d5
--- /dev/null
@@ -0,0 +1,435 @@
+msgid "Color Mode"
+msgstr "用灰色列印彩色"
+
+msgid "2-Sided Printing"
+msgstr "雙面列印"
+
+msgid "Media Source"
+msgstr "紙張來源"
+
+msgid "Options Installed"
+msgstr "已安裝選購品"
+
+msgid "Paper Type"
+msgstr "媒體類型"
+
+msgid "Media Size"
+msgstr "Page Size"
+
+msgid "A3 (Oversize)"
+msgstr "A3 (超大)"
+
+msgid "Full Bleed A3"
+msgstr "全吸墨 A3"
+
+msgid "A4 (210 x 297 mm)"
+msgstr "A4 (210 x 297mm)"
+
+msgid "Full Bleed A4"
+msgstr "全吸墨 A4"
+
+msgid "A4 (Small)"
+msgstr "A4 (小)"
+
+msgid "A5 (148 x 210 mm)"
+msgstr "A5 (148 x 210 mm)"
+
+msgid "A6 (105 x 148 mm)"
+msgstr "A6 紙張"
+
+msgid "C"
+msgstr "C"
+
+msgid "D"
+msgstr "D"
+
+msgid "E"
+msgstr "E"
+
+msgid "ARCH A"
+msgstr "ARCH A"
+
+msgid "ARCH B"
+msgstr "ARCH B"
+
+msgid "ARCH C"
+msgstr "ARCH C"
+
+msgid "ARCH D"
+msgstr "ARCH D"
+
+msgid "ARCH E"
+msgstr "ARCH E"
+
+msgid "Adhesive Paper"
+msgstr "自黏紙"
+
+msgid "ANSI C"
+msgstr "ANSI C"
+
+msgid "ANSI D"
+msgstr "ANSI D"
+
+msgid "ANSI E"
+msgstr "ANSI E"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "B4 (JIS)"
+msgstr "JIS B4"
+
+msgid "JIS B5"
+msgstr "JIS B5"
+
+msgid "B6 (JIS)"
+msgstr "JIS B6"
+
+msgid "Black"
+msgstr "黑色"
+
+msgid "Bin 1"
+msgstr "1 號送紙匣"
+
+msgid "Bin 10"
+msgstr "10 號送紙匣"
+
+msgid "Bin 2"
+msgstr "2 號送紙匣"
+
+msgid "Bin 3"
+msgstr "3 號送紙匣"
+
+msgid "Bin 4"
+msgstr "4 號送紙匣"
+
+msgid "Bin 5"
+msgstr "5 號送紙匣"
+
+msgid "Bin 6"
+msgstr "6 號送紙匣"
+
+msgid "Bin 7"
+msgstr "7 號送紙匣"
+
+msgid "Bin 8"
+msgstr "8 號送紙匣"
+
+msgid "Bin 9"
+msgstr "9 號送紙匣"
+
+msgid "Black Only"
+msgstr "純黑色"
+
+msgid "Bypass Tray"
+msgstr "手送紙盤"
+
+msgid "9 Envelope"
+msgstr "C9 號信封"
+
+msgid "C5 Envelope"
+msgstr "C5 信封"
+
+msgid "Color"
+msgstr "關"
+
+msgid "Card Stock"
+msgstr "卡片紙"
+
+msgid "Colored Paper"
+msgstr "顏色"
+
+msgid "Printer Default"
+msgstr "快速"
+
+msgid "Long Edge"
+msgstr "在長邊緣倒轉( 標準)"
+
+msgid "Short Edge"
+msgstr "在短邊緣倒轉"
+
+msgid "#10 Envelope"
+msgstr "Comm10 信封"
+
+msgid "C5 Envelope"
+msgstr "C5 信封"
+
+msgid "C6 Env."
+msgstr "C6 Env."
+
+msgid "DL Envelope"
+msgstr "DL 信封"
+
+msgid "Env ISO B5"
+msgstr "ISO B5 信封"
+
+msgid "Monarch Envelope"
+msgstr "Monarch 信封"
+
+msgid "Envelope Feeder"
+msgstr "信封"
+
+msgid "7.25 x 10.5\""
+msgstr "Executive (7.25 x 10.5\")"
+
+msgid "Off"
+msgstr "關閉"
+
+msgid "Glossy Paper"
+msgstr "光面紙"
+
+msgid "Glossy Film"
+msgstr "光面膠片"
+
+msgid "Black and White"
+msgstr "開"
+
+msgid "Statement"
+msgstr "Statement"
+
+msgid "A0"
+msgstr "A0"
+
+msgid "A1"
+msgstr "A1"
+
+msgid "A2"
+msgstr "A2"
+
+msgid "A3"
+msgstr "A3"
+
+msgid "A4"
+msgstr "A4"
+
+msgid "B5"
+msgstr "B5 信封"
+
+msgid "B6"
+msgstr "B6 (ISO)"
+
+msgid "Installed"
+msgstr "已安裝"
+
+msgid "JB0"
+msgstr "JB0"
+
+msgid "JB1"
+msgstr "JB1"
+
+msgid "JB2"
+msgstr "JB2"
+
+msgid "JB3"
+msgstr "JB3"
+
+msgid "JB4"
+msgstr "JB4"
+
+msgid "Ofuku Hagaki"
+msgstr "Ofuku Hagaki"
+
+msgid "Tray 4"
+msgstr "紙匣4"
+
+msgid "US Legal"
+msgstr "美國 Legal"
+
+msgid "Legal (Small)"
+msgstr "Legal (小)"
+
+msgid "US Letter"
+msgstr "US Letter"
+
+msgid "Full Bleed US Letter"
+msgstr "全吸墨US Letter"
+
+msgid "Letter (Small)"
+msgstr "Letter (小)"
+
+msgid "Lower Tray"
+msgstr "紙匣3"
+
+msgid "Manual Feed"
+msgstr "手動"
+
+msgid "Manual Envelope"
+msgstr "手動信封"
+
+msgid "Middle Tray"
+msgstr "紙匣2"
+
+msgid "Off"
+msgstr "無"
+
+msgid "Not Installed"
+msgstr "未安裝"
+
+msgid "Oversize A0"
+msgstr "大於 A0 尺寸"
+
+msgid "Oversize A1"
+msgstr "大於 A1 尺寸"
+
+msgid "Oversize A2"
+msgstr "大於 A2 尺寸"
+
+msgid "None"
+msgstr "關閉"
+
+msgid "Bin 1"
+msgstr "紙槽 1"
+
+msgid "Bin 2"
+msgstr "紙槽 2"
+
+msgid "Bin 3"
+msgstr "紙槽 3"
+
+msgid "Bin 4"
+msgstr "紙槽 4"
+
+msgid "Bin 5"
+msgstr "紙槽 5"
+
+msgid "Bin 6"
+msgstr "紙槽 6"
+
+msgid "Bin 7"
+msgstr "紙槽 7"
+
+msgid "Bin 8"
+msgstr "紙槽 8"
+
+msgid "24\" x 108\""
+msgstr "24\" x 108\""
+
+msgid "24\" x 48\""
+msgstr "24\" x 48\""
+
+msgid "24\" x 60\""
+msgstr "24\" x 60\""
+
+msgid "24\" x 72\""
+msgstr "24\" x 72\""
+
+msgid "24\" x 84\""
+msgstr "24\" x 84\""
+
+msgid "24\" x 96\""
+msgstr "24\" x 96\""
+
+msgid "36\" x 108\""
+msgstr "36\" x 108\""
+
+msgid "36\" x 60\""
+msgstr "36\" x 60\""
+
+msgid "36\" x 72\""
+msgstr "36\" x 72\""
+
+msgid "36\" x 84\""
+msgstr "36\" x 84\""
+
+msgid "36\" x 96\""
+msgstr "36\" x 96\""
+
+msgid "42\" x 60\""
+msgstr "42\" x 60\""
+
+msgid "42\" x 72\""
+msgstr "42\" x 72\""
+
+msgid "42\" x 84\""
+msgstr "42\" x 84\""
+
+msgid "54\" x 72\""
+msgstr "54 x 72"
+
+msgid "54\" x 84\""
+msgstr "54 x 84"
+
+msgid "54\" x 96\""
+msgstr "54 x 96"
+
+msgid "60\" x 72\""
+msgstr "60 x 72"
+
+msgid "60\" x 84\""
+msgstr "60 x 84"
+
+msgid "60\" x 96\""
+msgstr "60 x 96"
+
+msgid "Plain Paper"
+msgstr "普通紙"
+
+msgid "Letterhead"
+msgstr "預印的"
+
+msgid "Printer Default"
+msgstr "印表機目前的設定值"
+
+msgid "Recycled Paper"
+msgstr "再生紙"
+
+msgid "Roll Feed"
+msgstr "捲筒進紙"
+
+msgid "Roll 1"
+msgstr "捲筒紙 1"
+
+msgid "Roll 2"
+msgstr "捲筒紙 2"
+
+msgid "Cut Sheet"
+msgstr "裁切單張"
+
+msgid "Toyo"
+msgstr "Toyo"
+
+msgid "11x17"
+msgstr "11x17 "
+
+msgid "11x17 (Oversize)"
+msgstr "11x17 (超大)"
+
+msgid "Full Bleed Tabloid"
+msgstr "全吸墨小報"
+
+msgid "Thick Paper"
+msgstr "粗框"
+
+msgid "Transparency"
+msgstr "投影片"
+
+msgid "Tray 1"
+msgstr "裝紙匣 1"
+
+msgid "Tray 2"
+msgstr "裝紙匣 2"
+
+msgid "Tray 3"
+msgstr "裝紙匣 3"
+
+msgid "Tray 4"
+msgstr "裝紙匣 4"
+
+msgid "Tray 5"
+msgstr "裝紙匣 5"
+
+msgid "Tray 6"
+msgstr "6 號紙匣"
+
+msgid "Upper Tray"
+msgstr "紙匣1"
+
index 9f23b90c7fdd8391c101077e36a6c61ef1dc3618..de0870cd9a5953b4d2617bca7863cb3d38c0080b 100644 (file)
@@ -3,7 +3,7 @@
 #
 #   Man page makefile for the Common UNIX Printing System (CUPS).
 #
-#   Copyright 2007 by Apple Inc.
+#   Copyright 2007-2008 by Apple Inc.
 #   Copyright 1993-2006 by Easy Software Products.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -30,7 +30,12 @@ MAN1 =       cancel.$(MAN1EXT) \
                lpq.$(MAN1EXT) \
                lprm.$(MAN1EXT) \
                lpr.$(MAN1EXT) \
-               lpstat.$(MAN1EXT)
+               lpstat.$(MAN1EXT) \
+               ppdc.$(MAN1EXT) \
+               ppdhtml.$(MAN1EXT) \
+               ppdi.$(MAN1EXT) \
+               ppdmerge.$(MAN1EXT) \
+               ppdpo.$(MAN1EXT)
 MAN5   =       classes.conf.$(MAN5EXT) \
                client.conf.$(MAN5EXT) \
                cups-snmp.conf.$(MAN5EXT) \
@@ -38,10 +43,15 @@ MAN5        =       classes.conf.$(MAN5EXT) \
                mailto.conf.$(MAN5EXT) \
                mime.convs.$(MAN5EXT) \
                mime.types.$(MAN5EXT) \
+               ppdcfile.$(MAN5EXT) \
                printers.conf.$(MAN5EXT) \
                subscriptions.conf.$(MAN5EXT)
 MAN7   =       backend.$(MAN7EXT) \
-               filter.$(MAN7EXT)
+               commandtoescpx.$(MAN7EXT) \
+               commandtopclx.$(MAN7EXT) \
+               filter.$(MAN7EXT) \
+               rastertoescpx.$(MAN7EXT) \
+               rastertopclx.$(MAN7EXT)
 MAN8   =       accept.$(MAN8EXT) \
                cupsaddsmb.$(MAN8EXT) \
                cupsctl.$(MAN8EXT) \
diff --git a/man/commandtoescpx.man b/man/commandtoescpx.man
new file mode 100644 (file)
index 0000000..683edea
--- /dev/null
@@ -0,0 +1,33 @@
+.\"
+.\" "$Id$"
+.\"
+.\"   rastertoescpx man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH rastertoescpx 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+rastertoescpx \- enhanced esc/p raster driver for cups
+.SH SYNOPSIS
+.B rastertoescpx
+jobid user title copies options [
+.I filename.ras
+]
+.SH DESCRIPTION
+\fIrastertoescpx\fR converts a CUPS raster stream to ESC/P or
+ESC/P2. It is used to support printing to a variety of EPSON and
+EPSON-compatible printers and plotters.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id$".
+.\"
diff --git a/man/commandtopclx.man b/man/commandtopclx.man
new file mode 100644 (file)
index 0000000..dec7add
--- /dev/null
@@ -0,0 +1,33 @@
+.\"
+.\" "$Id$"
+.\"
+.\"   rastertopclx man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH rastertopclx 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+rastertopclx \- enhanced pcl raster driver for cups
+.SH SYNOPSIS
+.B rastertopclx
+jobid user title copies options [
+.I filename.ras
+]
+.SH DESCRIPTION
+\fIrastertopclx\fR converts a CUPS raster stream to HP-PCL. It is
+used to support printing to a variety of HP and HP-compatible
+printers and plotters.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id$".
+.\"
diff --git a/man/ppdc.man b/man/ppdc.man
new file mode 100644 (file)
index 0000000..ecf6181
--- /dev/null
@@ -0,0 +1,73 @@
+.\"
+.\" "$Id: ppdc.man 343 2007-07-13 19:52:48Z mike $"
+.\"
+.\"   ppdc man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdc 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdc \- cups ppd compiler
+.SH SYNOPSIS
+.B ppdc
+[ -D
+.I name=value
+] [ -I
+.I include-directory
+] [ -c
+.I message-catalog
+] [ -d
+.I output-directory
+] [ -l
+.I language(s)
+] [ -v ] [ -z ] [ --cr ] [ --crlf ] [ --lf ]
+.I source-file
+.SH DESCRIPTION
+\fIppdc\fR compiles PPDC source files into one or more PPD
+files.
+.PP
+The \fI-D\fR option sets the named variable for use in the
+source file. It is equivalent to using the #define directive
+in the source file.
+.PP
+The \fI-I\fR option specifies an alternate include directory;
+multiple \fI-I\fR options can be supplied to add additional
+directories.
+.PP
+The \fI-c\fR option specifies a single message catalog file in GNU
+gettext source format (filename.po) to be used for localization.
+.PP
+The \fI-d\fR option specifies the output directory for PPD
+files. The default output directory is "ppd".
+.PP
+The \fI-l\fR option specifies one or more languages to use when
+localizing the PPD file(s). The default language is "en"
+(English). Separate multiple languages with commas, for example
+"de_DE,en_UK,es_ES,es_MX,es_US,fr_CA,fr_FR,it_IT" will create PPD
+files with German, UK English, Spanish (Spain, Mexico, and US),
+French (France and Canada), and Italian languages in each file.
+.PP
+The \fI-v\fR option provides more verbose output, basically a
+running status of which files are being loaded or written.
+.PP
+The \fI-z\fR option generates compressed PPD files (filename.ppd.gz).
+The default is to generate uncompressed PPD files.
+.PP
+The \fI--cr\fR, \fI--crlf\fR, and \fI--lf\fR options specify the
+line ending to use - carriage return, carriage return and line feed,
+or line feed. The default is to use the line feed character alone.
+.SH SEE ALSO
+cupsprofile(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5),
+CUPS Driver Developer Kit Manual
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id: ppdc.man 343 2007-07-13 19:52:48Z mike $".
+.\"
diff --git a/man/ppdcfile.man b/man/ppdcfile.man
new file mode 100644 (file)
index 0000000..f2b052f
--- /dev/null
@@ -0,0 +1,162 @@
+.\"
+.\" "$Id: ppdcfile.man 343 2007-07-13 19:52:48Z mike $"
+.\"
+.\"   ppdcfile man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdcfile 5 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdcfile \- cups ppd compiler source file format
+.SH DESCRIPTION
+The CUPS PPD compiler reads meta files that contain descriptions
+of one or more PPD files to be generated by \fIppdc\fR. This man
+page provides a quick reference to the supported keywords and
+should be used in conjuction with the CUPS Driver Development Kit
+Developers Manual.
+.PP
+The source file format is plain ASCII text that can be edited
+using your favorite text editor. Comments are supported using
+the C (/* ... */) and C++ (// ...) comment mechanisms.
+.PP
+Printer driver information can be grouped and shared using
+curley braces ({ ... }); PPD files are written when a close
+brace or end-of-file is seen and a PCFileName directive has been
+defined.
+.PP
+Directives may be placed anywhere on a line and are followed by
+one or more values. The following is a list of the available
+directives and the values they accept:
+.TP 5
+\fB#define\fR name value
+.TP 5
+\fB#font\fR name encoding "version" charset status
+.TP 5
+\fB#include\fR <filename>
+.TP 5
+\fB#include\fR "filename"
+.TP 5
+\fB#media\fR name width length
+.TP 5
+\fB#media\fR "name/text" width length
+.TP 5
+\fB#po\fR locale "filename.po"
+.TP 5
+\fBAttribute\fR name "" value
+.TP 5
+\fBAttribute\fR name keyword value
+.TP 5
+\fBAttribute\fR name "keyword/text" value
+.TP 5
+\fBChoice\fR name "code"
+.TP 5
+\fBChoice\fR "name/text" "code"
+.TP 5
+\fBColorDevice\fR boolean-value
+.TP 5
+\fBColorModel\fR name colorspace colororder compression
+.TP 5
+\fBColorModel\fR "name/text" colorspace colororder compression
+.TP 5
+\fBColorProfile\fR resolution/mediatype gamma density matrix
+.TP 5
+\fBCopyright\fR "text"
+.TP 5
+\fBCustomMedia\fR name width length left bottom right top "size-code" "region-code"
+.TP 5
+\fBCustomMedia\fR "name/text" width length left bottom right top "size-code" "region-code"
+.TP 5
+\fBCutter\fR boolean-value
+.TP 5
+\fBDarkness\fR temperature name
+.TP 5
+\fBDarkness\fR temperature "name/text"
+.TP 5
+\fBDriverType\fR type
+.TP 5
+\fBDuplex\fR type
+.TP 5
+\fBFilter\fR mime-type cost program
+.TP 5
+\fBFinishing\fR name
+.TP 5
+\fBFinishing\fR "name/text"
+.TP 5
+\fBFont\fR *
+.TP 5
+\fBFont\fR name encoding "version" charset status
+.TP 5
+\fBGroup\fR name
+.TP 5
+\fBGroup\fR "name/text"
+.TP 5
+\fBHWMargins\fR left bottom right top
+.TP 5
+\fBInputSlot\fR position name
+.TP 5
+\fBInputSlot\fR position "name/text"
+.TP 5
+\fBInstallable\fR name
+.TP 5
+\fBInstallable\fR "name/text"
+.TP 5
+\fBManualCopies\fR boolean-value
+.TP 5
+\fBManufacturer\fR "name"
+.TP 5
+\fBMaxSize\fR width length
+.TP 5
+\fBMediaSize\fR name
+.TP 5
+\fBMediaType\fR type name
+.TP 5
+\fBMediaType\fR type "name/text"
+.TP 5
+\fBMinSize\fR width length
+.TP 5
+\fBModelName\fR "name"
+.TP 5
+\fBModelNumber\fR number
+.TP 5
+\fBOption\fR name type section order
+.TP 5
+\fBOption\fR "name/text" type section order
+.TP 5
+\fBPCFileName\fR "filename.ppd"
+.TP 5
+\fBResolution\fR colorspace bits-per-color row-count row-feed row-step name
+.TP 5
+\fBResolution\fR colorspace bits-per-color row-count row-feed row-step "name/text"
+.TP 5
+\fBSimpleColorProfile\fR resolution/mediatype density yellow-density red-density gamma red-adjust green-adjust blue-adjust
+.TP 5
+\fBThroughput\fR pages-per-minute
+.TP 5
+\fBUIConstraints\fR "*Option1 *Option2"
+.TP 5
+\fBUIConstraints\fR "*Option1 Choice1 *Option2"
+.TP 5
+\fBUIConstraints\fR "*Option1 *Option2 Choice2"
+.TP 5
+\fBUIConstraints\fR "*Option1 Choice1 *Option2 Choice2"
+.TP 5
+\fBVariablePaperSize\fR boolean-value
+.TP 5
+\fBVersion\fR number
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1),
+CUPS Driver Developer Kit Manual,
+.br
+http://localhost:631/help/ref-ppdc.html
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id: ppdcfile.man 343 2007-07-13 19:52:48Z mike $".
+.\"
diff --git a/man/ppdhtml.man b/man/ppdhtml.man
new file mode 100644 (file)
index 0000000..3bdcd1a
--- /dev/null
@@ -0,0 +1,38 @@
+.\"
+.\" "$Id: ppdhtml.man 343 2007-07-13 19:52:48Z mike $"
+.\"
+.\"   ppdhtml man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdhtml 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdhtml \- cups html summary generator
+.SH SYNOPSIS
+.B ppdhtml
+[ \-I
+.I include-directory
+]
+.I source-file
+.SH DESCRIPTION
+\fIppdhtml\fR reads a driver information file and produces a
+HTML summary page that lists all of the drivers in a file and
+the supported options.
+.PP
+The \fI-I\fR option specifies an alternate include directory;
+multiple \fI-I\fR options can be supplied to add additional
+directories.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdcfile(5), ppdi(1), ppdmerge(1), ppdpo(1), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id: ppdhtml.man 343 2007-07-13 19:52:48Z mike $".
+.\"
diff --git a/man/ppdi.man b/man/ppdi.man
new file mode 100644 (file)
index 0000000..39b4cc5
--- /dev/null
@@ -0,0 +1,44 @@
+.\"
+.\" "$Id: ppdi.man 343 2007-07-13 19:52:48Z mike $"
+.\"
+.\"   ppdi man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdi 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdi \- import ppd files
+.SH SYNOPSIS
+.B ppdi
+[ \-I
+.I include-directory
+] [ \-o
+.I source-file
+]
+.I ppd-file
+[
+.I ppd-file2 ... ppd-fileN
+]
+.SH DESCRIPTION
+\fIppdi\fR imports one or more PPD files into a PPD compiler source file.
+Multiple languages of the same PPD file are merged into a single printer
+definition to facilitate accurate changes for all localizations.
+.PP
+The \fI-o\fR option specifies the PPD source file to update. If the source
+file does not exist, a new source file is created. Otherwise the existing
+file is merged with the new PPD file(s) on the command-line. If no source
+file is specified, the filename "ppdi.drv" is used.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdmerge(1), ppdpo(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id: ppdi.man 343 2007-07-13 19:52:48Z mike $".
+.\"
diff --git a/man/ppdmerge.man b/man/ppdmerge.man
new file mode 100644 (file)
index 0000000..12473b8
--- /dev/null
@@ -0,0 +1,47 @@
+.\"
+.\" "$Id$"
+.\"
+.\"   ppdmerge man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdmerge 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdmerge \- merge ppd files
+.SH SYNOPSIS
+.B ppdmerge
+[ \-o
+.I output-ppd-file
+]
+.I ppd-file
+.I ppd-file2
+[
+.I ... ppd-fileN
+]
+.SH DESCRIPTION
+\fIppdmerge\fR merges two or more PPD files into a single, multi-language
+PPD file.
+.PP
+The \fI-o\fR option specifies the PPD file to create. If not specified,
+the merged PPD file is written to the standard output. If the output file
+already exists, the new 
+.SH NOTES
+\fIppdmerge\fR does not check whether the merged PPD files are for the
+same device. Merging of different device PPDs will yield unpredictable
+results.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdpo(1), ppdcfile(5),
+.br
+CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id$".
+.\"
diff --git a/man/ppdpo.man b/man/ppdpo.man
new file mode 100644 (file)
index 0000000..b5b43eb
--- /dev/null
@@ -0,0 +1,41 @@
+.\"
+.\" "$Id: ppdpo.man 343 2007-07-13 19:52:48Z mike $"
+.\"
+.\"   ppdpo man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH ppdpo 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+ppdpo \- cups message catalog generator
+.SH SYNOPSIS
+.B ppdpo
+[ \-I
+.I include-directory
+] [ \-o
+.I output-file
+]
+.I source-file
+.SH DESCRIPTION
+\fIppdpo\fR extracts UI strings from PPDC source files and writes them in
+a GNU gettext format message catalog source file for translation.
+.PP
+The \fI-I\fR option specifies an alternate include directory;
+multiple \fI-I\fR options can be supplied to add additional
+directories.
+.PP
+The \fI-o\fR option specifies the output file.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id: ppdpo.man 343 2007-07-13 19:52:48Z mike $".
+.\"
diff --git a/man/rastertoescpx.man b/man/rastertoescpx.man
new file mode 100644 (file)
index 0000000..683edea
--- /dev/null
@@ -0,0 +1,33 @@
+.\"
+.\" "$Id$"
+.\"
+.\"   rastertoescpx man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH rastertoescpx 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+rastertoescpx \- enhanced esc/p raster driver for cups
+.SH SYNOPSIS
+.B rastertoescpx
+jobid user title copies options [
+.I filename.ras
+]
+.SH DESCRIPTION
+\fIrastertoescpx\fR converts a CUPS raster stream to ESC/P or
+ESC/P2. It is used to support printing to a variety of EPSON and
+EPSON-compatible printers and plotters.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id$".
+.\"
diff --git a/man/rastertopclx.man b/man/rastertopclx.man
new file mode 100644 (file)
index 0000000..dec7add
--- /dev/null
@@ -0,0 +1,33 @@
+.\"
+.\" "$Id$"
+.\"
+.\"   rastertopclx man page for the CUPS Driver Development Kit.
+.\"
+.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 1997-2007 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/".
+.\"
+.TH rastertopclx 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.SH NAME
+rastertopclx \- enhanced pcl raster driver for cups
+.SH SYNOPSIS
+.B rastertopclx
+jobid user title copies options [
+.I filename.ras
+]
+.SH DESCRIPTION
+\fIrastertopclx\fR converts a CUPS raster stream to HP-PCL. It is
+used to support printing to a variety of HP and HP-compatible
+printers and plotters.
+.SH SEE ALSO
+cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+.SH COPYRIGHT
+Copyright 2007 by Apple Inc.
+.\"
+.\" End of "$Id$".
+.\"
index ba8a2b1b5457e7bad3b2dd4d4cc5fa4d011c37d0..705885d318576164ae1664287ad7b1729a58b22f 100644 (file)
@@ -4,7 +4,7 @@
 #   ESP Package Manager (EPM) file list for the Common UNIX Printing
 #   System (CUPS).
 #
-#   Copyright 2007 by Apple Inc.
+#   Copyright 2007-2008 by Apple Inc.
 #   Copyright 1997-2007 by Easy Software Products, all rights reserved.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -16,7 +16,7 @@
 
 # Product information
 %product Common UNIX Printing System
-%copyright 2007 by Apple Inc.
+%copyright 2007-2008 by Apple Inc.
 %vendor Apple Inc.
 #%license LICENSE.txt
 %readme LICENSE.txt
@@ -209,6 +209,7 @@ $CUPS_PERM=0@CUPS_CONFIG_FILE_PERM@
 $INSTALLSTATIC=@INSTALLSTATIC@
 
 $MAN1EXT=@MAN1EXT@
+$MAN3EXT=@MAN3EXT@
 $MAN5EXT=@MAN5EXT@
 $MAN7EXT=@MAN7EXT@
 $MAN8EXT=@MAN8EXT@
@@ -257,7 +258,10 @@ f 0755 root sys $SERVERBIN/daemon/cups-deviced scheduler/cups-deviced
 f 0755 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd
 f 0755 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld
 d 0755 root sys $SERVERBIN/driver -
+f 0755 root sys $SERVERBIN/driver/drv ppdc/drv
 d 0755 root sys $SERVERBIN/filter -
+f 0755 root sys $SERVERBIN/filter/commandtoespcx driver/commandtoescpx
+f 0755 root sys $SERVERBIN/filter/commandtopclx driver/commandtopclx
 f 0755 root sys $SERVERBIN/filter/gziptoany filter/gziptoany
 f 0755 root sys $SERVERBIN/filter/hpgltops filter/hpgltops
 %if IMGFILTERS
@@ -268,10 +272,12 @@ f 0755 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster
 f 0755 root sys $SERVERBIN/filter/pdftops pdftops/pdftops
 %endif
 f 0755 root sys $SERVERBIN/filter/pstops filter/pstops
+f 0755 root sys $SERVERBIN/filter/rastertoespcx driver/rastertoescpx
 f 0755 root sys $SERVERBIN/filter/rastertolabel filter/rastertolabel
 l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel
 f 0755 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson
 f 0755 root sys $SERVERBIN/filter/rastertohp filter/rastertohp
+f 0755 root sys $SERVERBIN/filter/rastertopclx driver/rastertopclx
 f 0755 root sys $SERVERBIN/filter/texttops filter/texttops
 d 0755 root sys $SERVERBIN/notifier -
 f 0755 root sys $SERVERBIN/notifier/mailto notifier/mailto
@@ -382,40 +388,59 @@ d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs -
 # Data files
 %subpackage da
 f 0644 root sys $LOCALEDIR/da/cups_da.po locale/cups_da.po
+f 0644 root sys $LOCALEDIR/da/ppdc_da.po locale/ppdc_da.po
 %subpackage de
 f 0644 root sys $LOCALEDIR/de/cups_de.po locale/cups_de.po
+f 0644 root sys $LOCALEDIR/de/ppdc_de.po locale/ppdc_de.po
 %subpackage es
 f 0644 root sys $LOCALEDIR/es/cups_es.po locale/cups_es.po
+f 0644 root sys $LOCALEDIR/es/ppdc_es.po locale/ppdc_es.po
 %subpackage et
 f 0644 root sys $LOCALEDIR/et/cups_et.po locale/cups_et.po
+f 0644 root sys $LOCALEDIR/et/ppdc_et.po locale/ppdc_et.po
 %subpackage fi
 f 0644 root sys $LOCALEDIR/fi/cups_fi.po locale/cups_fi.po
+f 0644 root sys $LOCALEDIR/fi/ppdc_fi.po locale/ppdc_fi.po
 %subpackage fr
 f 0644 root sys $LOCALEDIR/fr/cups_fr.po locale/cups_fr.po
+f 0644 root sys $LOCALEDIR/fr/ppdc_fr.po locale/ppdc_fr.po
 %subpackage he
 f 0644 root sys $LOCALEDIR/he/cups_he.po locale/cups_he.po
+f 0644 root sys $LOCALEDIR/he/ppdc_he.po locale/ppdc_he.po
 %subpackage it
 f 0644 root sys $LOCALEDIR/it/cups_it.po locale/cups_it.po
+f 0644 root sys $LOCALEDIR/it/ppdc_it.po locale/ppdc_it.po
 %subpackage ja
 f 0644 root sys $LOCALEDIR/ja/cups_ja.po locale/cups_ja.po
+f 0644 root sys $LOCALEDIR/ja/ppdc_ja.po locale/ppdc_ja.po
 %subpackage ko
 f 0644 root sys $LOCALEDIR/ko/cups_ko.po locale/cups_ko.po
+f 0644 root sys $LOCALEDIR/ko/ppdc_ko.po locale/ppdc_ko.po
 %subpackage nl
 f 0644 root sys $LOCALEDIR/nl/cups_nl.po locale/cups_nl.po
+f 0644 root sys $LOCALEDIR/nl/ppdc_nl.po locale/ppdc_nl.po
 %subpackage no
 f 0644 root sys $LOCALEDIR/no/cups_no.po locale/cups_no.po
+f 0644 root sys $LOCALEDIR/no/ppdc_no.po locale/ppdc_no.po
 %subpackage pl
 f 0644 root sys $LOCALEDIR/pl/cups_pl.po locale/cups_pl.po
+f 0644 root sys $LOCALEDIR/pl/ppdc_pl.po locale/ppdc_pl.po
 %subpackage pt
 f 0644 root sys $LOCALEDIR/pt/cups_pt.po locale/cups_pt.po
+f 0644 root sys $LOCALEDIR/pt/ppdc_pt.po locale/ppdc_pt.po
 f 0644 root sys $LOCALEDIR/pt_BR/cups_pt_BR.po locale/cups_pt_BR.po
+f 0644 root sys $LOCALEDIR/pt_BR/ppdc_pt_BR.po locale/ppdc_pt_BR.po
 %subpackage ru
 f 0644 root sys $LOCALEDIR/ru/cups_ru.po locale/cups_ru.po
+f 0644 root sys $LOCALEDIR/ru/ppdc_ru.po locale/ppdc_ru.po
 %subpackage sv
 f 0644 root sys $LOCALEDIR/sv/cups_sv.po locale/cups_sv.po
+f 0644 root sys $LOCALEDIR/sv/ppdc_sv.po locale/ppdc_sv.po
 %subpackage zh
 f 0644 root sys $LOCALEDIR/zh/cups_zh.po locale/cups_zh.po
+f 0644 root sys $LOCALEDIR/zh/ppdc_zh.po locale/ppdc_zh.po
 f 0644 root sys $LOCALEDIR/zh_TW/cups_zh_TW.po locale/cups_zh_TW.po
+f 0644 root sys $LOCALEDIR/zh_TW/ppdc_zh_TW.po locale/ppdc_zh_TW.po
 %subpackage
 
 d 0755 root sys $DATADIR -
@@ -446,6 +471,10 @@ f 0644 root sys $DATADIR/fonts/Symbol fonts/Symbol
 d 0755 root sys $DATADIR/model -
 f 0644 root sys $DATADIR/model ppd/*.ppd
 
+d 0755 root sys $DATADIR/ppdc -
+f 0644 root sys $DATADIR/ppdc data/*.defs
+f 0644 root sys $DATADIR/ppdc data/*.h
+
 d 0755 root sys $DATADIR/templates -
 f 0644 root sys $DATADIR/templates templates/*.tmpl
 
@@ -506,13 +535,14 @@ f 0644 root sys $INCLUDEDIR/cups/array.h cups/array.h
 f 0644 root sys $INCLUDEDIR/cups/backend.h cups/backend.h
 f 0644 root sys $INCLUDEDIR/cups/cups.h cups/cups.h
 f 0644 root sys $INCLUDEDIR/cups/dir.h cups/dir.h
+f 0644 root sys $INCLUDEDIR/cups/driver.h driver/driver.h
 f 0644 root sys $INCLUDEDIR/cups/file.h cups/file.h
 f 0644 root sys $INCLUDEDIR/cups/http.h cups/http.h
 f 0644 root sys $INCLUDEDIR/cups/image.h filter/image.h
 f 0644 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h
 f 0644 root sys $INCLUDEDIR/cups/language.h cups/language.h
 f 0644 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h
-f 0644 root sys $INCLUDEDIR/cups/raster.h filter/raster.h
+f 0644 root sys $INCLUDEDIR/cups/raster.h cups/raster.h
 f 0644 root sys $INCLUDEDIR/cups/transcode.h cups/transcode.h
 
 %if INSTALLSTATIC
@@ -520,6 +550,8 @@ f 0644 root sys $LIBDIR/libcups.a cups/libcups.a
 f 0644 root sys $LIBDIR/libcupsimage.a filter/libcupsimage.a
 %endif
 
+f 0644 root sys $LIBDIR/libcupsdriver.a driver/libcupsdriver.a
+
 d 0755 root sys $DOCDIR/help -
 f 0644 root sys $DOCDIR/help doc/help/api*.html
 f 0644 root sys $DOCDIR/help doc/help/spec*.html
@@ -612,7 +644,11 @@ f 0644 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.$MAN5EXT
 f 0644 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.$MAN5EXT
 
 f 0644 root sys $MANDIR/man7/backend.$MAN7EXT man/backend.$MAN7EXT
+f 0644 root sys $MANDIR/man7/commandtoescpx.$MAN7EXT man/commandtoescpx.$MAN7EXT
+f 0644 root sys $MANDIR/man7/commandtopclx.$MAN7EXT man/commandtopclx.$MAN7EXT
 f 0644 root sys $MANDIR/man7/filter.$MAN7EXT man/filter.$MAN7EXT
+f 0644 root sys $MANDIR/man7/rastertoescpx.$MAN7EXT man/rastertoescpx.$MAN7EXT
+f 0644 root sys $MANDIR/man7/rastertopclx.$MAN7EXT man/rastertopclx.$MAN7EXT
 
 f 0644 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT man/accept.$MAN8EXT
 l 0644 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT
@@ -630,6 +666,8 @@ f 0644 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.$MAN8EXT
 
 %subpackage devel
 f 0644 root sys $MANDIR/man1/cups-config.$MAN1EXT man/cups-config.$MAN1EXT
+f 0644 root sys $MANDIR/man1/ man/ppd*.$MAN1EXT
+f 0644 root sys $MANDIR/man5/ppdcfile.$MAN5EXT man/ppdcfile.$MAN5EXT
 
 %subpackage lpd
 d 0755 root sys $AMANDIR/man$MAN8DIR -
index 3a967cf06345545007b62252ba72b0bf47862f31..d64d3b9f7b3573204a21380594039f9bc65fdad9 100644 (file)
@@ -5,7 +5,7 @@
 #
 #   Original version by Jason McMullan <jmcc@ontv.com>.
 #
-#   Copyright 2007 by Apple Inc.
+#   Copyright 2007-2008 by Apple Inc.
 #   Copyright 1999-2007 by Easy Software Products, all rights reserved.
 #
 #   These coded instructions, statements, and computer programs are the
@@ -368,6 +368,7 @@ rm -rf $RPM_BUILD_ROOT
 /usr/lib/cups/daemon/cups-driverd
 /usr/lib/cups/daemon/cups-polld
 %dir /usr/lib/cups/driver
+/usr/lib/cups/driver/drv
 %dir /usr/lib/cups/filter
 /usr/lib/cups/filter/*
 %dir /usr/lib/cups/monitor
@@ -389,6 +390,8 @@ rm -rf $RPM_BUILD_ROOT
 /usr/share/cups/fonts/*
 %dir /usr/share/cups/model
 /usr/share/cups/model/*
+%dir /usr/share/cups/ppdc
+/usr/share/cups/ppdc/*
 %dir /usr/share/cups/templates
 /usr/share/cups/templates/*.tmpl
 %dir /usr/share/doc/cups
@@ -424,7 +427,11 @@ rm -rf $RPM_BUILD_ROOT
 /usr/share/man/man1/lprm.1.gz
 /usr/share/man/man1/lpstat.1.gz
 %dir /usr/share/man/man5
-/usr/share/man/man5/*
+/usr/share/man/man5/*.conf.5.gz
+/usr/share/man/man5/mime.*.5.gz
+%dir /usr/share/man/man7
+/usr/share/man/man7/commandto*
+/usr/share/man/man7/rasterto*
 %dir /usr/share/man/man8
 /usr/share/man/man8/accept.8.gz
 /usr/share/man/man8/cupsaddsmb.8.gz
@@ -458,10 +465,14 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root)
 %dir /usr/share/man/man1
 /usr/share/man/man1/cups-config.1.gz
-%dir /usr/share/man/man7
-/usr/share/man/man7/*
+/usr/share/man/man1/ppd*.1.gz
+%dir /usr/share/man/man5
+/usr/share/man/man5/ppdcfile.5.gz
+/usr/share/man/man7/backend.7.gz
+/usr/share/man/man7/filter.7.gz
 
 /usr/bin/cups-config
+/usr/bin/ppd*
 %dir /usr/include/cups
 /usr/include/cups/*
 /usr/lib*/*.so
@@ -489,7 +500,7 @@ rm -rf $RPM_BUILD_ROOT
 
 %files da
 %defattr(-,root,root)
-/usr/share/locale/da/cups_da.po
+/usr/share/locale/da/*
 
 %files de
 %defattr(-,root,root)
@@ -497,7 +508,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/de/index.html
 #%dir /usr/share/cups/templates/de
 #/usr/share/cups/templates/de/*
-/usr/share/locale/de/cups_de.po
+/usr/share/locale/de/*
 
 %files es
 %defattr(-,root,root)
@@ -505,7 +516,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/es/index.html
 #%dir /usr/share/cups/templates/es
 #/usr/share/cups/templates/es/*
-/usr/share/locale/es/cups_es.po
+/usr/share/locale/es/*
 
 %files et
 %defattr(-,root,root)
@@ -513,11 +524,11 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/et/index.html
 #%dir /usr/share/cups/templates/et
 #/usr/share/cups/templates/et/*
-/usr/share/locale/et/cups_et.po
+/usr/share/locale/et/*
 
 %files fi
 %defattr(-,root,root)
-/usr/share/locale/fi/cups_fi.po
+/usr/share/locale/fi/*
 
 %files fr
 %defattr(-,root,root)
@@ -525,7 +536,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/fr/index.html
 #%dir /usr/share/cups/templates/fr
 #/usr/share/cups/templates/fr/*
-/usr/share/locale/fr/cups_fr.po
+/usr/share/locale/fr/*
 
 %files he
 %defattr(-,root,root)
@@ -534,7 +545,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/he/cups.css
 #%dir /usr/share/cups/templates/he
 #/usr/share/cups/templates/he/*
-/usr/share/locale/he/cups_he.po
+/usr/share/locale/he/*
 
 %files it
 %defattr(-,root,root)
@@ -542,7 +553,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/it/index.html
 #%dir /usr/share/cups/templates/it
 #/usr/share/cups/templates/it/*
-/usr/share/locale/it/cups_it.po
+/usr/share/locale/it/*
 
 %files ja
 %defattr(-,root,root)
@@ -550,19 +561,19 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/ja/index.html
 #%dir /usr/share/cups/templates/ja
 #/usr/share/cups/templates/ja/*
-/usr/share/locale/ja/cups_ja.po
+/usr/share/locale/ja/*
 
 %files ko
 %defattr(-,root,root)
-/usr/share/locale/ko/cups_ko.po
+/usr/share/locale/ko/*
 
 %files nl
 %defattr(-,root,root)
-/usr/share/locale/nl/cups_nl.po
+/usr/share/locale/nl/*
 
 %files no
 %defattr(-,root,root)
-/usr/share/locale/no/cups_no.po
+/usr/share/locale/no/*
 
 %files pl
 %defattr(-,root,root)
@@ -570,17 +581,16 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/pl/index.html
 #%dir /usr/share/cups/templates/pl
 #/usr/share/cups/templates/pl/*
-/usr/share/locale/pl/cups_pl.po
+/usr/share/locale/pl/*
 
 %files pt
 %defattr(-,root,root)
-/usr/share/locale/pt/cups_pt.po
-/usr/share/locale/pt_BR/cups_pt_BR.po
-/usr/share/locale/pt_PT/cups_pt_PT.po
+/usr/share/locale/pt/*
+/usr/share/locale/pt_BR/*
 
 %files ru
 %defattr(-,root,root)
-/usr/share/locale/ru/cups_ru.po
+/usr/share/locale/ru/*
 
 %files sv
 %defattr(-,root,root)
@@ -588,7 +598,7 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/sv/index.html
 #%dir /usr/share/cups/templates/sv
 #/usr/share/cups/templates/sv/*
-/usr/share/locale/sv/cups_sv.po
+/usr/share/locale/sv/*
 
 %files zh
 %defattr(-,root,root)
@@ -596,8 +606,8 @@ rm -rf $RPM_BUILD_ROOT
 #/usr/share/doc/cups/zh_TW/index.html
 #%dir /usr/share/cups/templates/zh_TW
 #/usr/share/cups/templates/zh_TW/*
-/usr/share/locale/zh/cups_zh.po
-/usr/share/locale/zh_TW/cups_zh_TW.po
+/usr/share/locale/zh/*
+/usr/share/locale/zh_TW/*
 
 %if %{?_with_php:1}%{!?_with_php:0}
 %files php
diff --git a/ppdc/Dependencies b/ppdc/Dependencies
new file mode 100644 (file)
index 0000000..3cd35de
--- /dev/null
@@ -0,0 +1,68 @@
+# DO NOT DELETE
+
+drv.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+drv.o: ../cups/versioning.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+drv.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+drv.o: ../cups/dir.h
+ppdc-array.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-array.o: ../cups/versioning.h
+ppdc-attr.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-attr.o: ../cups/versioning.h
+ppdc-catalog.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-catalog.o: ../cups/versioning.h ../cups/globals.h ../cups/string.h
+ppdc-catalog.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h
+ppdc-catalog.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h
+ppdc-catalog.o: ../cups/ppd.h ../cups/array.h ../cups/file.h
+ppdc-catalog.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h
+ppdc-choice.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-choice.o: ../cups/versioning.h
+ppdc-constraint.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-constraint.o: ../cups/versioning.h
+ppdc-driver.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-driver.o: ../cups/versioning.h ../cups/cups.h ../cups/ipp.h
+ppdc-driver.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+ppdc-driver.o: ../cups/language.h
+ppdc-file.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-file.o: ../cups/versioning.h
+ppdc-filter.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-filter.o: ../cups/versioning.h
+ppdc-font.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-font.o: ../cups/versioning.h
+ppdc-group.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-group.o: ../cups/versioning.h
+ppdc-import.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-import.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+ppdc-import.o: ../cups/file.h
+ppdc-mediasize.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-mediasize.o: ../cups/versioning.h
+ppdc-message.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-message.o: ../cups/versioning.h
+ppdc-option.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-option.o: ../cups/versioning.h
+ppdc-profile.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-profile.o: ../cups/versioning.h
+ppdc-shared.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-shared.o: ../cups/versioning.h
+ppdc-source.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-source.o: ../cups/versioning.h ../cups/globals.h ../cups/string.h
+ppdc-source.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h
+ppdc-source.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h
+ppdc-source.o: ../cups/ppd.h ../cups/array.h ../cups/file.h
+ppdc-source.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h
+ppdc-source.o: ../data/epson.h ../data/escp.h ../data/hp.h ../data/label.h
+ppdc-source.o: ../data/pcl.h
+ppdc-string.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-string.o: ../cups/versioning.h
+ppdc-variable.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc-variable.o: ../cups/versioning.h
+ppdc.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdc.o: ../cups/versioning.h
+ppdhtml.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdhtml.o: ../cups/versioning.h
+ppdi.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdi.o: ../cups/versioning.h
+ppdmerge.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h
+ppdmerge.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h
+ppdmerge.o: ../cups/array.h ../cups/string.h ../config.h
+ppdpo.o: ppdc.h ../cups/string.h ../config.h ../cups/file.h
+ppdpo.o: ../cups/versioning.h
diff --git a/ppdc/Makefile b/ppdc/Makefile
new file mode 100644 (file)
index 0000000..1e69747
--- /dev/null
@@ -0,0 +1,210 @@
+#
+# "$Id$"
+#
+#   Makefile for the CUPS PPD Compiler.
+#
+#   Copyright 2007-2008 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/".
+#
+
+#
+# Include standard definitions...
+#
+
+include ../Makedefs
+
+
+#
+# Object files...
+#
+
+PPDCOBJS       = \
+               ppdc-array.o \
+               ppdc-attr.o \
+               ppdc-catalog.o \
+               ppdc-choice.o \
+               ppdc-constraint.o \
+               ppdc-driver.o \
+               ppdc-file.o \
+               ppdc-filter.o \
+               ppdc-font.o \
+               ppdc-group.o \
+               ppdc-import.o \
+               ppdc-mediasize.o \
+               ppdc-message.o \
+               ppdc-option.o \
+               ppdc-profile.o \
+               ppdc-shared.o \
+               ppdc-source.o \
+               ppdc-string.o \
+               ppdc-variable.o
+
+OBJS           = \
+               drv.o \
+               ppdc.o \
+               ppdhtml.o \
+               ppdi.o \
+               ppdmerge.o \
+               ppdpo.o \
+               $(PPDCOBJS)
+
+TARGETS                = \
+               libppdc.a \
+               drv \
+               ppdc-static \
+               ppdc \
+               ppdhtml \
+               ppdi \
+               ppdmerge \
+               ppdpo
+
+
+#
+# Make everything...
+#
+
+all:           $(TARGETS)
+
+
+#
+# Clean everything...
+#
+
+clean:
+       $(RM) $(OBJS) core
+       $(RM) *.bak *.bck core.*
+       $(RM) $(TARGETS)
+       $(RM) -r ppd
+       $(RM) test.drv
+
+
+#
+# Update dependencies...
+#
+
+depend:
+       makedepend -Y -I.. -fDependencies $(OBJS:.o=.cxx) >/dev/null 2>&1
+
+
+#
+# Install...
+#
+
+install:
+       echo Installing PPD compiler programs...
+       $(INSTALL_DIR) $(BINDIR)
+       $(INSTALL_BIN) ppdc $(BINDIR)
+       $(INSTALL_BIN) ppdhtml $(BINDIR)
+       $(INSTALL_BIN) ppdi $(BINDIR)
+       $(INSTALL_BIN) ppdmerge $(BINDIR)
+       $(INSTALL_BIN) ppdpo $(BINDIR)
+       $(INSTALL_DIR) $(SERVERBIN)/driver
+       $(INSTALL_BIN) drv $(SERVERBIN)/driver
+       $(INSTALL_DIR) $(DATADIR)/drv
+
+
+#
+# Uninstall...
+#
+
+uninstall:
+       $(RM) $(BINDIR)/ppdc
+       $(RM) $(BINDIR)/ppdhtml
+       $(RM) $(BINDIR)/ppdi
+       $(RM) $(BINDIR)/ppdmerge
+       $(RM) $(BINDIR)/ppdpo
+       $(RM) $(SERVERBIN)/driver/drv
+       $(RMDIR) $(SERVERBIN)/driver
+       $(RMDIR) $(DATADIR)/drv
+
+
+#
+# drv, the CUPS driver interface program to the PPD compiler.
+#
+
+drv:                   drv.o libppdc.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ drv.o libppdc.a $(LIBS)
+
+
+#
+# ppdc, the PPD compiler.
+#
+
+ppdc:                  ppdc.o libppdc.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ ppdc.o libppdc.a $(LIBS)
+
+
+ppdc-static:           ppdc.o libppdc.a  ../cups/libcups.a foo.drv foo-fr.po
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o ppdc-static ppdc.o libppdc.a ../cups/libcups.a \
+               $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+       echo Testing PPD compiler...
+       ./ppdc-static -l en,fr -I ../data foo.drv
+       ./ppdc-static -l en,fr -z -I ../data foo.drv
+
+
+#
+# ppdhtml, the PPD to HTML utility.
+#
+
+ppdhtml:                       ppdhtml.o libppdc.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ ppdhtml.o libppdc.a $(LIBS)
+
+
+#
+# ppdi, import PPD files.
+#
+
+ppdi:                  ppdi.o libppdc.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ ppdi.o libppdc.a $(LIBS)
+
+
+#
+# ppdmerge, merge PPD files.
+#
+
+ppdmerge:                      ppdmerge.o ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ ppdmerge.o $(LIBS)
+
+
+#
+# ppdpo, create message catalog files.
+#
+
+ppdpo:                 ppdpo.o libppdc.a ../cups/$(LIBCUPS)
+       echo Linking $@...
+       $(CXX) $(LDFLAGS) -o $@ ppdpo.o libppdc.a $(LIBS)
+
+
+#
+# libppdc.a, the PPD compiler library...
+#
+
+libppdc.a:             $(PPDCOBJS)
+       echo Creating $@...
+       $(RM) $@
+       $(AR) $(ARFLAGS) $@ $(PPDCOBJS)
+       $(RANLIB) $@
+
+
+#
+# Include dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/ppdc/drv.cxx b/ppdc/drv.cxx
new file mode 100644 (file)
index 0000000..23b9ece
--- /dev/null
@@ -0,0 +1,427 @@
+//
+// "$Id$"
+//
+//   DDK driver interface main entry 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:
+//
+//   main()      - Enumerate or display PPD files.
+//   cat_ppd()   - Display a PPD file.
+//   list_ppds() - List PPDs.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/cups.h>
+#include <cups/dir.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+//
+// Local functions...
+//
+
+static int     cat_ppd(ppdcSource *src, const char *name);
+static int     list_drvs(const char *pathname, const char *prefix);
+static int     list_ppds(ppdcSource *src, const char *name);
+
+
+//
+// 'main()' - Enumerate or display PPD files.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  const char   *datadir;               // CUPS_DATADIR
+  ppdcSource   *src;                   // PPD source file data
+  char         filename[1024],         // Full path to .drv file(s)
+               scheme[32],             // URI scheme ("drv")
+               userpass[256],          // User/password info (unused)
+               host[2],                // Hostname (unused)
+               resource[1024],         // Resource path (/dir/to/filename.drv)
+               *pc_file_name;          // Filename portion of URI
+  int          port,                   // Port number (unused)
+               status;                 // Exit status
+
+
+  // Determine where CUPS has installed the data files...
+  if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+    datadir = CUPS_DATADIR;
+
+  // List all available PPDs or cat a single PPD...
+  if (argc == 2 && !strcmp(argv[1], "list"))
+  {
+    snprintf(filename, sizeof(filename), "%s/drv", datadir);
+    return (list_drvs(filename, "/"));
+  }
+  else if (argc == 3 && !strcmp(argv[1], "cat"))
+  {
+    httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme, sizeof(scheme),
+                    userpass, sizeof(userpass), host, sizeof(host), &port,
+                   resource, sizeof(resource));
+
+    if (strstr(resource, "../") ||
+        (pc_file_name = strrchr(resource, '/')) == NULL ||
+       pc_file_name == resource)
+    {
+      fprintf(stderr, "ERROR: Bad driver info URI \"%s\"!\n", argv[2]);
+      return (1);
+    }
+
+    *pc_file_name++ = '\0';
+
+    snprintf(filename, sizeof(filename), "%s/drv%s", datadir, resource);
+
+    src = new ppdcSource(filename);
+
+    status = cat_ppd(src, pc_file_name);
+
+    delete src;
+
+    return (status);
+  }
+  
+  fprintf(stderr, "ERROR: Usage: %s cat URI\n", argv[0]);
+  fprintf(stderr, "ERROR: Usage: %s list\n", argv[0]);
+
+  return (1);
+}
+
+
+//
+// 'cat_ppd()' - Display a PPD file.
+//
+
+static int                             // O - Exit status
+cat_ppd(ppdcSource *src,               // I - Driver info file
+        const char *name)              // I - PC filename
+{
+  ppdcDriver   *d;                     // Current driver
+  cups_file_t  *out;                   // Stdout via CUPS file API 
+  
+  for (d = (ppdcDriver *)src->drivers->first();
+       d;
+       d = (ppdcDriver *)src->drivers->next())
+    if (!strcmp(name, d->pc_file_name->value))
+    {
+      out = cupsFileStdout();
+
+      d->write_ppd_file(out, NULL, NULL, src, PPDC_LFONLY);
+      cupsFileClose(out);
+      return (0);
+    }
+  
+  return (1);
+}
+
+
+//
+// 'list_drvs()' - List all drv files in the given path...
+//
+
+static int                             // O - Exit status
+list_drvs(const char *pathname,                // I - Full path to directory
+          const char *prefix)          // I - Prefix for directory
+{
+  char         *ext,                   // Extension on file
+               filename[1024],         // Full path to .drv file(s)
+               newprefix[1024];        // New prefix for directory
+  cups_dir_t   *dir;                   // Current directory
+  cups_dentry_t        *dent;                  // Current directory entry
+
+
+  if ((dir = cupsDirOpen(pathname)) == NULL)
+    return (1);
+
+  while ((dent = cupsDirRead(dir)) != NULL)
+  {
+    // Skip "dot" files...
+    if (dent->filename[0] == '.')
+      continue;
+
+    // See if this is a file or directory...
+    snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename);
+
+    if (S_ISDIR(dent->fileinfo.st_mode))
+    {
+      // Descend into the subdirectory...
+      snprintf(newprefix, sizeof(newprefix), "%s%s/", prefix, dent->filename);
+
+      if (list_drvs(filename, newprefix))
+      {
+       cupsDirClose(dir);
+       return (1);
+      }
+    }
+    else if ((ext = strrchr(dent->filename, '.')) != NULL &&
+             (!strcmp(ext, ".drv") || !strcmp(ext, ".drv.gz")))
+    {
+      // List the PPDs in this driver info file...
+      ppdcSource *src = new ppdcSource(filename);
+                                       // Driver info file
+
+      snprintf(newprefix, sizeof(newprefix), "%s%s", prefix, dent->filename);
+      list_ppds(src, newprefix);
+      delete src;
+    }
+  }
+
+  cupsDirClose(dir);
+
+  return (0);
+}
+
+
+//
+// 'list_ppds()' - List PPDs in a driver info file.
+//
+
+static int                             // O - Exit status
+list_ppds(ppdcSource *src,             // I - Driver info file
+          const char *name)            // I - Name of driver info file
+{
+  ppdcDriver   *d;                     // Current driver
+  ppdcAttr     *attr;                  // 1284DeviceID attribute
+  char         uri[1024];              // Driver URI
+
+
+  for (d = (ppdcDriver *)src->drivers->first();
+       d;
+       d = (ppdcDriver *)src->drivers->next())
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0,
+                     "%s/%s", name, d->pc_file_name->value);
+
+    attr = d->find_attr("1284DeviceID", NULL);
+
+    printf("\"%s\" en \"%s\" \"%s\" \"%s\"\n", uri, d->manufacturer->value,
+           d->model_name->value, attr ? attr->value->value : "");
+  }
+
+  return (0);
+}
+
+
+
+
+#if 0
+
+
+
+  // Scan the command-line...
+  catalog = NULL;
+  outdir  = "ppd";
+  src     = 0;
+  verbose = 0;
+  locales = NULL;
+  comp    = PPDC_NO_COMPRESSION;
+  le      = PPDC_LFONLY;
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+         case 'c' :                    // Message catalog...
+             i ++;
+              if (i >= argc)
+                usage();
+
+              if (verbose > 1)
+               printf("ppdc: Loading messages from \"%s\"...\n", argv[i]);
+
+              if (!catalog)
+               catalog = new ppdcCatalog("en");
+
+              if (catalog->load_messages(argv[i]))
+             {
+               fprintf(stderr,
+                       "ppdc: Unable to load localization file \"%s\" - %s\n",
+                       argv[i], strerror(errno));
+                return (1);
+             }
+             break;
+
+          case 'd' :                   // Output directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (verbose > 1)
+               printf("ppdc: Writing PPD files to directory \"%s\"...\n",
+                      argv[i]);
+
+             outdir = argv[i];
+             break;
+
+          case 'l' :                   // Language(s)...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (strchr(argv[i], ','))
+             {
+               // Comma-delimited list of languages...
+               char    temp[1024],     // Copy of language list
+                       *start,         // Start of current locale name
+                       *end;           // End of current locale name
+
+
+               locales = new ppdcArray();
+
+               strlcpy(temp, argv[i], sizeof(temp));
+               for (start = temp; *start; start = end)
+               {
+                 if ((end = strchr(start, ',')) != NULL)
+                   *end++ = '\0';
+                 else
+                   end = start + strlen(start);
+
+                  if (end > start)
+                   locales->add(new ppdcString(start));
+               }
+             }
+             else
+             {
+               if (verbose > 1)
+                 printf("ppdc: Loading messages for locale \"%s\"...\n",
+                        argv[i]);
+
+               if (catalog)
+                 delete catalog;
+
+               catalog = new ppdcCatalog(argv[i]);
+
+               if (catalog->messages->count == 0)
+               {
+                 fprintf(stderr,
+                         "ppdc: Unable to find localization for \"%s\" - %s\n",
+                         argv[i], strerror(errno));
+                  return (1);
+               }
+             }
+             break;
+
+          case 'I' :                   // Include directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (verbose > 1)
+               printf("ppdc: Adding include directory \"%s\"...\n", argv[i]);
+
+             ppdcSource::add_include(argv[i]);
+             break;
+
+          case 'v' :                   // Be verbose...
+             verbose ++;
+             break;
+           
+          case 'z' :                   // Compress files...
+             comp = PPDC_GZIP_COMPRESSION;
+             break;
+
+         case '-' :                    // --option
+             if (!strcmp(opt, "-lf"))
+             {
+               le  = PPDC_LFONLY;
+               opt += strlen(opt) - 1;
+               break;
+             }
+             else if (!strcmp(opt, "-cr"))
+             {
+               le  = PPDC_CRONLY;
+               opt += strlen(opt) - 1;
+               break;
+             }
+             else if (!strcmp(opt, "-crlf"))
+             {
+               le  = PPDC_CRLF;
+               opt += strlen(opt) - 1;
+               break;
+             }
+           
+         default :                     // Unknown
+             usage();
+             break;
+       }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      if (verbose > 1)
+        printf("ppdc: Loading driver information file \"%s\"...\n", argv[i]);
+
+      src = new ppdcSource(argv[i]);
+
+      // Create the output directory...
+      if (mkdir(outdir, 0777))
+      {
+        if (errno != EEXIST)
+       {
+         fprintf(stderr, "ppdc: Unable to create output directory %s: %s\n",
+                 outdir, strerror(errno));
+          return (1);
+       }
+      }
+
+      // Write PPD files...
+      for (d = (ppdcDriver *)src->drivers->first();
+           d;
+          d = (ppdcDriver *)src->drivers->next())
+      {
+        // Write the PPD file for this driver...
+       for (j = 0; d->pc_file_name->value[j]; j ++)
+         pcfilename[j] = tolower(d->pc_file_name->value[j]);
+
+       pcfilename[j] = '\0';
+
+       if (comp == PPDC_GZIP_COMPRESSION)
+         snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
+       else
+         snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
+
+       if (verbose)
+         printf("ppdc: Writing %s...\n", filename);
+
+       if (d->write_ppd_file(filename, catalog, locales, src, le, comp))
+         return (1);
+      }
+
+      // Delete the printer driver information...
+      delete src;
+    }
+
+  if (catalog)
+    delete catalog;
+
+  // If no drivers have been loaded, display the program usage message.
+  if (!src)
+    usage();
+
+  // Return with no errors.
+  return (0);
+}
+#endif // 0
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/foo-fr.po b/ppdc/foo-fr.po
new file mode 100644 (file)
index 0000000..1b1561b
--- /dev/null
@@ -0,0 +1,11 @@
+msgid "A Serious Error"
+msgstr "La Error Serious"
+
+msgid "http://foo.com/serious.html"
+msgstr "http://foo.com/fr/serious.html"
+
+msgid "Foo Letter"
+msgstr "La Foo Letter"
+
+msgid "Foo Photo"
+msgstr "La Foo Photo"
diff --git a/ppdc/foo.drv b/ppdc/foo.drv
new file mode 100644 (file)
index 0000000..fa84f3d
--- /dev/null
@@ -0,0 +1,548 @@
+//
+// "$Id$"
+//
+//   PPD file compiler test data file for the Common UNIX Printing
+//   System (CUPS).
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 1997-2003 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/".
+//
+
+/*
+ * C-style comments are supported.
+ */
+
+//
+// C++-style comments are supported.
+//
+
+//
+// Include the common media size definitions...
+//
+// #include directives support both <name> to include a standard file
+// and "name" or just name without the quotes for a local file.  Local
+// files resolve relative to the current file's path.  Unlike C/C++,
+// #include <name> does not look in multiple directories, and
+// #include "name" does not look in the standard directory.
+//
+
+#include <media.defs>
+
+
+//
+// Include the CUPS raster definitions...
+//
+
+#include <raster.defs>
+
+
+//
+// Include the standard CUPS fonts...
+//
+
+#include <font.defs>
+
+
+//
+// Define variables using the #define directive.  In this case we
+// are defining constants for the model number, which is used by
+// our imaginary rastertofoo filter to determine which model-specific
+// features to use/support.
+//
+
+#define MODEL_BW       0
+#define MODEL_COLOR    1
+
+#define MODEL_LASER    0
+#define MODEL_PHOTO    2
+
+
+//
+// Media sizes are defined using the #media directive.  The order of
+// values is: size name/text, width, length.
+//
+// "Size name" is an alphanumeric string of up to 40 characters as
+// defined by the Adobe PPD specification.
+//
+// "Size text" is a text string of up to 80 characters as defined by
+// the Adobe PPD specification.
+//
+// "Width" and "length" are the width and length of the media size.
+// Numbers by themselves represent points (72 points = 1 inch).  The
+// suffixes "cm", "ft", "in", "m", "mm", and "pt" are recognized to
+// specify centimeters, feet, inches, meters, millimeters, and points,
+// respectively.
+//
+
+#media "FooLetter/Foo Letter" 8in 10in
+#media "FooPhoto/Foo Photo" 200mm 300mm
+
+
+//
+// Message catalogs can be included using #po...
+//
+
+#po fr foo-fr.po
+
+
+//
+// Specify that the drivers use all of the standard base fonts...
+//
+
+Font *
+
+
+//
+// All copyright lines are put at the top of the PPD file in order
+// of their appearance.  Copyright text can span multiple lines and
+// will be properly included in the PPD file with comment prefixes
+// on each line.
+//
+// First an MIT-style copyright/license notice...
+//
+
+Copyright "Copyright 2007 by Foo Industries."
+Copyright "
+Permission is granted for redistribution of this file as long as
+this copyright notice is intact and the contents of the file are
+not altered in any way from their original form.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the \"Software\"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"
+
+//
+// Then a GPL notice...
+//
+
+Copyright "Copyright 2007 by Foo Industries."
+Copyright "
+This software is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of
+the License, or (at your option) any later version.
+
+This software is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this software; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111 USA
+"
+
+
+//
+// All printer drivers must define the manufacturer, model, PC
+// filename, and version strings; since this test file contains
+// drivers for an imaginary manufacturer "Foo", all of the drivers
+// listed in this file share common manufacturer and version
+// strings.
+//
+
+Manufacturer "Foo"
+Version 1.0
+
+
+//
+// Printer drivers can access driver-specific attributes in a PPD
+// file; these attributes are specified using lines of the form:
+//
+//     Attribute name selector value
+//
+// "Name" is the name of the attribute and should start with either
+// the "cups" prefix or the name of the vendor, e.g. "hpFoo",
+// "epsonBar", etc.  The name can be any alphanumeric character (a-z,
+// A-Z, and 0-9) and cannot be a common prefix of another attribute,
+// e.g. "fooLines" and "fooLinesPerInch" cannot be in the same file.
+//
+// "Selector" is a selector string containing any characters except
+// colon (:).  Typically this will be one or more keywords separated
+// by the forward slash (/), however the empty string ("") can be used
+// to omit the selector.
+//
+// "Value" is a quoted value string that can contain any printable
+// characters except the double quote (").  Hexadecimal numbers
+// inside angle brackets (<xx>) can be used to substitute escape
+// codes and other special characters.
+//
+
+Attribute fooOutputFormat "" "PCL"
+Attribute fooPJL Begin "<1B>%-12345X@PJL<0D0A>"
+Attribute fooPJL Enter/PCL "@PJL ENTER LANGUAGE=PCL<0D0A>"
+Attribute fooPJL End "<1B>%-12345X@PJL END JOB<0D0A>"
+
+//
+// Most printer drivers use filters; exceptions include PostScript
+// printers and PPD files for software RIPs.
+//
+// The format is:
+//
+//     Filter mime-type cost program
+//
+// The "mime-type" field defines the MIME type that the filter program
+// accepts; for CUPS raster printer drivers, this will be
+// "application/vnd.cups-raster".
+//
+// The "cost" field defines the relative cost of the filter in terms of
+// both CPU and memory usage, and is used to limit the number of
+// simultaneous jobs in some configurations.  Most raster filters should
+// have a cost of 100, unless the filter does no dithering - then a cost
+// of 33 is more appropriate.
+//
+// The "program" field defined the filter program to run; use the null
+// filter "-" to define a MIME type that the printer accepts directly.
+// If no path information is provided, then the program will be run
+// from the standard CUPS filter directory, usually
+// /usr/lib/cups/filter.
+//
+// When compiling PPD files for PostScript capable devices that use
+// additional filters, add a null filter for the MIME type
+// "application/vnd.cups-postscript" so that printer commands, user
+// job filters, and page markings can be added to the PostScript
+// output that is sent to the printer.
+//
+
+Filter application/vnd.cups-raster 100 rastertofoo
+
+
+//
+// Attributes are included thusly...
+//
+
+Attribute cupsIPPReason "com.foo-serious-error/A Serious Error" "http://foo.com/serious.html"
+
+
+//
+// Curley braces are used for grouping common data and for isolating
+// individual printer models.  All data values are inherited *except*
+// for the PCFilename and ModelName strings.
+//
+
+{
+  //
+  // Define two printer drivers that support only the FooLetter and
+  // FooPhoto media size.  One is color, the other is black-and-white.
+  //
+  // Both printers share two MediaSize definitions; the name listed
+  // after the MediaSize keyword must be one of the Adobe standard
+  // names listed in the PPD specification or any named size defined
+  // using the #media directive.
+  //
+  // Default options are indicated by placing an asterisk (*) before
+  // the keyword.
+  //
+  // For custom size and margin specification, see the next group of
+  // printer drivers.
+  //
+
+  MediaSize FooLetter
+  *MediaSize FooPhoto
+
+
+  //
+  // These imaginary printers support printing at 300, 600x300,
+  // and 600 DPI.  We'll use the old-style Resolution convenience
+  // keyword which accepts the following parameters: colorspace/
+  // order, bits-per-color, row count, row feed, row step, and
+  // name/text.
+  //
+  // The name must be of the form NNNsuffix or NNNxMMMsuffix,
+  // where NNN and MMM represent the X and Y resolution in dots
+  // per inch.
+  //
+
+  Resolution - 8 0 0 0 "300dpi/300 DPI"
+  Resolution - 8 0 0 0 "600x300dpi/600 x 300 DPI"
+  *Resolution - 8 0 0 0 "600dpi/600 DPI"
+
+
+  //
+  // One printer is grayscale only, and the other does grayscale
+  // and color.  Define the grayscale color model for both printers
+  // using the old-style ColorModel convenience keyword which
+  // accepts the name/text, colorspace, color order, and compression
+  // parameters.
+  //
+
+  ColorModel   Gray/Grayscale w chunked 0
+
+
+  {
+    //
+    // The first sub-group contains the grayscale printer, which
+    // only needs the model name, PC filename, and model number
+    // values set...
+    //
+    // The ModelName keyword defines the string that is shown to
+    // the user.
+    //
+
+    ModelName "Mono Photo Printer"
+
+
+    //
+    // The ModelNumber keyword defines the cupsModelNumber
+    // attribute value.  We use the "(name name)" notation
+    // to perform a bitwise OR of the #define'd constants.
+    //
+
+    ModelNumber ($MODEL_BW $MODEL_PHOTO)
+
+
+    //
+    // The PCFileName keyword defines the filename of the PPD
+    // file and should be 8 characters or less + the .ppd
+    // extension.
+    //
+
+    PCFileName "foogphot.ppd"
+  }
+
+
+  {
+    //
+    // The second sub-group contains the color printer, which
+    // needs another ColorModel definition along with the model
+    // name, PC filename, and model number values.  For fun, we'll
+    // add some input slots (paper trays) as well.
+    //
+    // The ModelName keyword defines the string that is shown to
+    // the user.
+    //
+
+    ModelName "Color Photo Printer"
+
+
+    //
+    // The ModelNumber keyword defines the cupsModelNumber
+    // attribute value.  We use the "(name name)" notation
+    // to perform a bitwise OR of the #define'd constants.
+    //
+
+    ModelNumber ($MODEL_COLOR $MODEL_PHOTO)
+
+
+    //
+    // The PCFileName keyword defines the filename of the PPD
+    // file and should be 8 characters or less + the .ppd
+    // extension.
+    //
+
+    PCFileName "foocphot.ppd"
+
+
+    //
+    // This printer does color printing, too, so add it and make
+    // RGB the default...
+    //
+
+    ColorDevice Yes
+
+    *ColorModel        RGB/Color rgb chunked 0
+
+
+    //
+    // The old-style InputSlot keyword accepts tray definitions
+    // of the form:
+    //
+    //    InputSlot position name/text
+    //
+
+    InputSlot 0 "Upper/Main Paper Tray"
+    InputSlot 1 "LargeCapacity/Large Paper Tray"
+  }
+}
+
+
+{
+  //
+  // Define two printer drivers that support two typical laser
+  // printers with custom page sizes.  One is color, the other is
+  // black-and-white.
+  //
+  // Both printers share several MediaSize definitions and support
+  // custom page sizes from 3x5 to 13x19 inches.
+  //
+  // All US media sizes use hardware margins of 0.25 inches on the sides
+  // and 12 points (1/6th inch) at the top and bottom.  European sizes
+  // and custom sizes use margins of 12 points all around.
+  //
+  // The order of the HWMargins numbers are left, bottom, right, and top.
+  // The current HWMargins values are used when defining each media size.
+  // The last HWMargins values are used for custom page size margins.
+  //
+
+  HWMargins 0.25in 12pt 0.25in 12pt
+
+  *MediaSize Letter
+  MediaSize Legal
+  MediaSize Tabloid
+  MediaSize TabloidExtra
+
+  HWMargins 12pt 12pt 12pt 12pt
+  MediaSize A4
+  MediaSize A3
+
+  //
+  // Specify that custom/variable paper sizes are supported, and the
+  // range of sizes that are supported...
+  //
+
+  VariablePaperSize Yes
+  MinSize 3in 5in
+  MaxSize 13in 19in
+
+
+  //
+  // These imaginary printers support printing at 600 and 1200 DPI.
+  // We'll use the new Option and Choice keywords to define the
+  // Resolution options...
+  //
+  // Option option-name option-text option-type
+  // Choice choice-name choice-text code
+  //
+  // "Option-type" is the type of option: boolean, pickone, or pickmany.
+  //
+
+  Option Resolution PickOne AnySetup 10
+  Choice "600dpi/600 DPI" "<</HWResolution[600 600]/cupsBitsPerColor 8>>setpagedevice"
+  Choice "1200dpi/1200 DPI" "<</HWResolution[1200 1200]/cupsBitsPerColor 8>>setpagedevice"
+  
+
+  //
+  // One printer is grayscale only, and the other does grayscale
+  // and color.  Define the grayscale color model for both printers
+  // using the new Option and Choice keywords.
+  //
+
+  Option "ColorModel/Color Mode" PickOne AnySetup 10
+  Choice Gray/Grayscale "<</cupsColorSpace $CUPS_CSPACE_W>>setpagedevice"
+
+
+  //
+  // Both printers provide two paper trays, which we'll define using
+  // the new Option and Choice keywords...
+  //
+
+  Option "InputSlot/Input Slot" PickOne AnySetup 10
+  Choice "Upper/Main Paper Tray" "<</MediaPosition 0>>setpagedevice"
+  Choice "LargeCapacity/Large Paper Tray" "<</MediaPosition 1>>setpagedevice"
+
+
+  //
+  // Both printers support duplexing...
+  //
+  // The Duplex keyword accepts values of "none" (no duplexing capability),
+  // "normal" (standard duplexing capability), and "flip" (auto-duplex that
+  // requires the back side to be flipped by the RIP...)
+  //
+
+  Duplex normal
+
+
+  {
+    //
+    // The first sub-group contains the grayscale printer, which
+    // only needs the model name, PC filename, and model number
+    // values set...
+    //
+    // The ModelName keyword defines the string that is shown to
+    // the user.
+    //
+
+    ModelName "Mono Laser Printer"
+
+
+    //
+    // The ModelNumber keyword defines the cupsModelNumber
+    // attribute value.  We use the "(name name)" notation
+    // to perform a bitwise OR of the #define'd constants.
+    //
+
+    ModelNumber ($MODEL_BW $MODEL_LASER)
+
+
+    //
+    // The PCFileName keyword defines the filename of the PPD
+    // file and should be 8 characters or less + the .ppd
+    // extension.
+    //
+
+    PCFileName "fooglasr.ppd"
+  }
+
+
+  {
+    //
+    // The second sub-group contains the color printer, which
+    // needs another ColorModel definition along with the model
+    // name, PC filename, and model number values.
+    //
+    // The ModelName keyword defines the string that is shown to
+    // the user.
+    //
+
+    ModelName "Color Laser Printer"
+
+
+    //
+    // The ModelNumber keyword defines the cupsModelNumber
+    // attribute value.  We use the "(name name)" notation
+    // to perform a bitwise OR of the #define'd constants.
+    //
+
+    ModelNumber ($MODEL_COLOR $MODEL_LASER)
+
+
+    //
+    // The PCFileName keyword defines the filename of the PPD
+    // file and should be 8 characters or less + the .ppd
+    // extension.
+    //
+
+    PCFileName "fooclasr.ppd"
+
+
+    //
+    // This printer does color printing, too, so add it and make
+    // RGB the default...
+    //
+
+    ColorDevice Yes
+
+    Option "ColorModel/Color Mode" PickOne AnySetup 10
+    *Choice RGB/Color "<</cupsColorSpace $CUPS_CSPACE_RGB>>setpagedevice"
+  }
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-array.cxx b/ppdc/ppdc-array.cxx
new file mode 100644 (file)
index 0000000..3cccad3
--- /dev/null
@@ -0,0 +1,163 @@
+//
+// "$Id$"
+//
+//   Array class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcArray::ppdcArray()  - Create a new array.
+//   ppdcArray::~ppdcArray() - Destroy an array.
+//   ppdcArray::add()        - Add an element to an array.
+//   ppdcArray::first()      - Return the first element in the array.
+//   ppdcArray::next()       - Return the next element in the array.
+//   ppdcArray::remove()     - Remove an element from the array.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcArray::ppdcArray()' - Create a new array.
+//
+
+ppdcArray::ppdcArray(ppdcArray *a)
+{
+  if (a)
+  {
+    count = a->count;
+    alloc = count;
+
+    if (count)
+    {
+      // Make a copy of the array...
+      data = new ppdcShared *[count];
+
+      memcpy(data, a->data, count * sizeof(ppdcShared *));
+
+      for (int i = 0; i < count; i ++)
+        data[i]->get();
+    }
+    else
+      data = 0;
+  }
+  else
+  {
+    count = 0;
+    alloc = 0;
+    data  = 0;
+  }
+
+  current = 0;
+}
+
+
+//
+// 'ppdcArray::~ppdcArray()' - Destroy an array.
+//
+
+ppdcArray::~ppdcArray()
+{
+  for (int i = 0; i < count; i ++)
+    data[i]->release();
+
+  if (alloc)
+    delete[] data;
+}
+
+
+//
+// 'ppdcArray::add()' - Add an element to an array.
+//
+
+void
+ppdcArray::add(ppdcShared *d)
+{
+  ppdcShared   **temp;
+
+
+  if (count >= alloc)
+  {
+    alloc += 10;
+    temp  = new ppdcShared *[alloc];
+
+    memcpy(temp, data, count * sizeof(ppdcShared *));
+
+    delete[] data;
+    data = temp;
+  }
+
+  data[count++] = d;
+}
+
+
+//
+// 'ppdcArray::first()' - Return the first element in the array.
+//
+
+ppdcShared *
+ppdcArray::first()
+{
+  current = 0;
+
+  if (current >= count)
+    return (0);
+  else
+    return (data[current ++]);
+}
+
+
+//
+// 'ppdcArray::next()' - Return the next element in the array.
+//
+
+ppdcShared *
+ppdcArray::next()
+{
+  if (current >= count)
+    return (0);
+  else
+    return (data[current ++]);
+}
+
+
+//
+// 'ppdcArray::remove()' - Remove an element from the array.
+//
+
+void
+ppdcArray::remove(ppdcShared *d)               // I - Data element
+{
+  int  i;                                      // Looping var
+
+
+  for (i = 0; i < count; i ++)
+    if (d == data[i])
+      break;
+
+  if (i >= count)
+    return;
+
+  count --;
+  d->release();
+
+  if (i < count)
+    memmove(data + i, data + i + 1, (count - i) * sizeof(ppdcShared *));
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-attr.cxx b/ppdc/ppdc-attr.cxx
new file mode 100644 (file)
index 0000000..094e387
--- /dev/null
@@ -0,0 +1,60 @@
+//
+// "$Id$"
+//
+//   Attribute class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcAttr::ppdcAttr()  - Create an attribute.
+//   ppdcAttr::~ppdcAttr() - Destroy an attribute.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcAttr::ppdcAttr()' - Create an attribute.
+//
+
+ppdcAttr::ppdcAttr(const char *n,      // I - Name
+                   const char *s,      // I - Spec string
+                  const char *t,       // I - Human-readable text
+                  const char *v)       // I - Value
+  : ppdcShared()
+{
+  name     = new ppdcString(n);
+  selector = new ppdcString(s);
+  text     = new ppdcString(t);
+  value    = new ppdcString(v);
+}
+
+
+//
+// 'ppdcAttr::~ppdcAttr()' - Destroy an attribute.
+//
+
+ppdcAttr::~ppdcAttr()
+{
+  name->release();
+  selector->release();
+  text->release();
+  value->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-catalog.cxx b/ppdc/ppdc-catalog.cxx
new file mode 100644 (file)
index 0000000..96cd6e3
--- /dev/null
@@ -0,0 +1,370 @@
+//
+// "$Id$"
+//
+//   Shared message catalog class for the CUPS PPD Compiler.
+//
+//   Copyright 2007-2008 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:
+//
+//   ppdcCatalog::ppdcCatalog()   - Create a shared message catalog.
+//   ppdcCatalog::~ppdcCatalog()  - Destroy a shared message catalog.
+//   ppdcCatalog::add_message()   - Add a new message.
+//   ppdcCatalog::find_message()  - Find a message in a catalog...
+//   ppdcCatalog::load_messages() - Load messages from a .po file.
+//   ppdcCatalog::save_messages() - Save the messages to a .po file.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/globals.h>
+
+
+//
+// 'ppdcCatalog::ppdcCatalog()' - Create a shared message catalog.
+//
+
+ppdcCatalog::ppdcCatalog(const char *l,        // I - Locale
+                         const char *f)        // I - Message catalog file
+  : ppdcShared()
+{
+  _cups_globals_t      *cg = _cupsGlobals();
+                                       // Global information
+
+
+  locale   = new ppdcString(l);
+  filename = new ppdcString(f);
+  messages = new ppdcArray();
+
+  if (l)
+  {
+    // Try loading the base messages for this locale...
+    char       pofile[1024];           // Message catalog file
+
+
+    snprintf(pofile, sizeof(pofile), "%s/%s/ppdc_%s.po", cg->localedir, l, l);
+
+    if (load_messages(pofile) && strchr(l, '_'))
+    {
+      // Try the base locale...
+      char     baseloc[3];             // Base locale...
+
+
+      strlcpy(baseloc, l, sizeof(baseloc));
+      snprintf(pofile, sizeof(pofile), "%s/%s/ppdc_%s.po", cg->localedir,
+               baseloc, baseloc);
+
+      load_messages(pofile);
+    }
+  }
+
+  if (f)
+    load_messages(f);
+}
+
+
+//
+// 'ppdcCatalog::~ppdcCatalog()' - Destroy a shared message catalog.
+//
+
+ppdcCatalog::~ppdcCatalog()
+{
+  delete locale;
+  delete filename;
+  delete messages;
+}
+
+
+//
+// 'ppdcCatalog::add_message()' - Add a new message.
+//
+
+void
+ppdcCatalog::add_message(const char *id)// I - Message ID to add
+{
+  ppdcMessage  *m;                     // Current message
+  char         text[1024];             // Text to translate
+
+
+  // Range check input...
+  if (!id || !*id)
+    return;
+
+  // Verify that we don't already have the message ID...
+  for (m = (ppdcMessage *)messages->first();
+       m;
+       m = (ppdcMessage *)messages->next())
+    if (!strcmp(m->id->value, id))
+      return;
+
+  // Add the message...
+  snprintf(text, sizeof(text), "TRANSLATE %s", id);
+  messages->add(new ppdcMessage(id, text));
+}
+
+
+//
+// 'ppdcCatalog::find_message()' - Find a message in a catalog...
+//
+
+const char *                           // O - Message text
+ppdcCatalog::find_message(
+    const char *id)                    // I - Message ID
+{
+  ppdcMessage  *m;                     // Current message
+
+
+  for (m = (ppdcMessage *)messages->first();
+       m;
+       m = (ppdcMessage *)messages->next())
+    if (!strcmp(m->id->value, id))
+      return (m->string->value);
+
+  return (id);
+}
+
+
+//
+// 'ppdcCatalog::load_messages()' - Load messages from a .po file.
+//
+
+int                                    // O - 0 on success, -1 on failure
+ppdcCatalog::load_messages(
+    const char *f)                     // I - Message catalog file
+{
+  cups_file_t  *fp;                    // Message file
+  ppdcMessage  *temp;                  // Current message
+  char         line[4096],             // Line buffer
+               *ptr,                   // Pointer into buffer
+               id[4096],               // Translation ID
+               str[4096];              // Translation string
+  int          linenum;                // Line number
+
+
+  // Open the message catalog file...
+  if ((fp = cupsFileOpen(f, "r")) == NULL)
+    return (-1);
+
+ /*
+  * Read messages from the catalog file until EOF...
+  *
+  * The format is the GNU gettext .po format, which is fairly simple:
+  *
+  *     msgid "some text"
+  *     msgstr "localized text"
+  *
+  * The ID and localized text can span multiple lines using the form:
+  *
+  *     msgid ""
+  *     "some long text"
+  *     msgstr ""
+  *     "localized text spanning "
+  *     "multiple lines"
+  */
+
+  linenum = 0;
+  id[0]   = '\0';
+  str[0]  = '\0';
+
+  while (cupsFileGets(fp, line, sizeof(line)))
+  {
+    linenum ++;
+
+    // Skip blank and comment lines...
+    if (line[0] == '#' || !line[0])
+      continue;
+
+    // Strip the trailing quote...
+    if ((ptr = strrchr(line, '\"')) == NULL)
+    {
+      fprintf(stderr, "load_messages: Expected quoted string on line %d of %s!\n",
+              linenum, f);
+      cupsFileClose(fp);
+      return (-1);
+    }
+
+    *ptr = '\0';
+
+    // Find start of value...
+    if ((ptr = strchr(line, '\"')) == NULL)
+    {
+      fprintf(stderr, "load_messages: Expected quoted string on line %d of %s!\n",
+              linenum, f);
+      cupsFileClose(fp);
+      return (-1);
+    }
+
+    ptr ++;
+
+    // Unquote the text...
+    char *sptr, *dptr;                 // Source/destination pointers
+
+    for (sptr = ptr, dptr = ptr; *sptr;)
+    {
+      if (*sptr == '\\')
+      {
+       sptr ++;
+       if (isdigit(*sptr))
+       {
+         *dptr = 0;
+
+         while (isdigit(*sptr))
+         {
+           *dptr = *dptr * 8 + *sptr - '0';
+           sptr ++;
+         }
+
+         dptr ++;
+       }
+       else
+       {
+         if (*sptr == 'n')
+           *dptr++ = '\n';
+         else if (*sptr == 'r')
+           *dptr++ = '\r';
+         else if (*sptr == 't')
+           *dptr++ = '\t';
+         else
+           *dptr++ = *sptr;
+
+         sptr ++;
+       }
+      }
+      else
+       *dptr++ = *sptr++;
+    }
+
+    *dptr = '\0';
+
+    // Create or add to a message...
+    if (!strncmp(line, "msgid", 5))
+    {
+      if (id[0] && str[0])
+      {
+       temp = new ppdcMessage(id, str);
+
+       messages->add(temp);
+      }
+
+      strlcpy(id, ptr, sizeof(id));
+      str[0] = '\0';
+    }
+    else if (!strncmp(line, "msgstr", 6))
+    {
+      if (!id[0])
+      {
+       fprintf(stderr, "load_messages: Need a msgid line before any "
+                       "translation strings on line %d of %s!\n",
+               linenum, f);
+       cupsFileClose(fp);
+       return (-1);
+      }
+
+      strlcpy(str, ptr, sizeof(str));
+    }
+    else if (line[0] == '\"' && str[0])
+      strlcat(str, ptr, sizeof(str));
+    else if (line[0] == '\"' && id[0])
+      strlcat(id, ptr, sizeof(id));
+    else
+    {
+      fprintf(stderr, "load_messages: Unexpected text on line %d of %s!\n",
+              linenum, f);
+      cupsFileClose(fp);
+      return (-1);
+    }
+  }
+
+  if (id[0] && str[0])
+  {
+    temp = new ppdcMessage(id, str);
+
+    messages->add(temp);
+  }
+
+  cupsFileClose(fp);
+
+  return (0);
+}
+
+
+//
+// 'ppdcCatalog::save_messages()' - Save the messages to a .po file.
+//
+
+int                                    // O - 0 on success, -1 on error
+ppdcCatalog::save_messages(
+    const char *f)                     // I - File to save to
+{
+  cups_file_t  *fp;                    // Message file
+  ppdcMessage  *m;                     // Current message
+  const char   *ptr;                   // Pointer into string
+
+
+  if ((fp = cupsFileOpen(f, "w")) == NULL)
+    return (-1);
+
+  for (m = (ppdcMessage *)messages->first();
+       m;
+       m = (ppdcMessage *)messages->next())
+  {
+    cupsFilePuts(fp, "msgid \"");
+    for (ptr = m->id->value; *ptr; ptr ++)
+      switch (*ptr)
+      {
+        case '\n' :
+           cupsFilePuts(fp, "\\n");
+           break;
+        case '\\' :
+           cupsFilePuts(fp, "\\\\");
+           break;
+        case '\"' :
+           cupsFilePuts(fp, "\\\"");
+           break;
+        default :
+           cupsFilePutChar(fp, *ptr);
+           break;
+      }
+    cupsFilePuts(fp, "\"\n");
+
+    cupsFilePuts(fp, "msgstr \"");
+    for (ptr = m->string->value; *ptr; ptr ++)
+      switch (*ptr)
+      {
+        case '\n' :
+           cupsFilePuts(fp, "\\n");
+           break;
+        case '\\' :
+           cupsFilePuts(fp, "\\\\");
+           break;
+        case '\"' :
+           cupsFilePuts(fp, "\\\"");
+           break;
+        default :
+           cupsFilePutChar(fp, *ptr);
+           break;
+      }
+    cupsFilePuts(fp, "\"\n");
+
+    cupsFilePutChar(fp, '\n');
+  }
+
+  cupsFileClose(fp);
+
+  return (0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-choice.cxx b/ppdc/ppdc-choice.cxx
new file mode 100644 (file)
index 0000000..22ae055
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// "$Id$"
+//
+//   Option choice class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcChoice::ppdcChoice()  - Create a new option choice.
+//   ppdcChoice::~ppdcChoice() - Destroy an option choice.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcChoice::ppdcChoice()' - Create a new option choice.
+//
+
+ppdcChoice::ppdcChoice(const char *n,  // I - Name of choice
+                       const char *t,  // I - Text of choice
+                      const char *c)   // I - Code of choice
+  : ppdcShared()
+{
+  name = new ppdcString(n);
+  text = new ppdcString(t);
+  code = new ppdcString(c);
+}
+
+
+//
+// 'ppdcChoice::~ppdcChoice()' - Destroy an option choice.
+//
+
+ppdcChoice::~ppdcChoice()
+{
+  name->release();
+  text->release();
+  code->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-constraint.cxx b/ppdc/ppdc-constraint.cxx
new file mode 100644 (file)
index 0000000..2a651b9
--- /dev/null
@@ -0,0 +1,60 @@
+//
+// "$Id$"
+//
+//   Contraint class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcConstraint::ppdcConstraint()  - Create a constraint.
+//   ppdcConstraint::~ppdcConstraint() - Destroy a constraint.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcConstraint::ppdcConstraint()' - Create a constraint.
+//
+
+ppdcConstraint::ppdcConstraint(const char *o1, // I - First option
+                               const char *c1, // I - First choice
+                              const char *o2,  // I - Second option
+                              const char *c2)  // I - Second choice
+  : ppdcShared()
+{
+  option1 = new ppdcString(o1);
+  choice1 = new ppdcString(c1);
+  option2 = new ppdcString(o2);
+  choice2 = new ppdcString(c2);
+}
+
+
+//
+// 'ppdcConstraint::~ppdcConstraint()' - Destroy a constraint.
+//
+
+ppdcConstraint::~ppdcConstraint()
+{
+  option1->release();
+  choice1->release();
+  option2->release();
+  choice2->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-driver.cxx b/ppdc/ppdc-driver.cxx
new file mode 100644 (file)
index 0000000..d59b275
--- /dev/null
@@ -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$".
+//
diff --git a/ppdc/ppdc-file.cxx b/ppdc/ppdc-file.cxx
new file mode 100644 (file)
index 0000000..3af0e49
--- /dev/null
@@ -0,0 +1,100 @@
+//
+// "$Id$"
+//
+//   File class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcFile::ppdcFile()  - Create (open) a file.
+//   ppdcFile::~ppdcFile() - Delete (close) a file.
+//   ppdcFile::get()       - Get a character from a file.
+//   ppdcFile::peek()      - Look at the next character from a file.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcFile::ppdcFile()' - Create (open) a file.
+//
+
+ppdcFile::ppdcFile(const char *f)              // I - File to open
+{
+  fp       = cupsFileOpen(f, "r");
+  filename = f;
+  line     = 1;
+
+  if (!fp)
+    fprintf(stderr, "ppdc: Unable to open %s: %s\n", f, strerror(errno));
+}
+
+
+//
+// 'ppdcFile::~ppdcFile()' - Delete (close) a file.
+//
+
+ppdcFile::~ppdcFile()
+{
+  if (fp)
+    cupsFileClose(fp);
+}
+
+
+//
+// 'ppdcFile::get()' - Get a character from a file.
+//
+
+int
+ppdcFile::get()
+{
+  int  ch;                                     // Character from file
+
+
+  // Return EOF if there is no open file...
+  if (!fp)
+    return (EOF);
+
+  // Get the character...
+  ch = cupsFileGetChar(fp);
+
+  // Update the line number as needed...
+  if (ch == '\n')
+    line ++;
+
+  // Return the character...
+  return (ch);
+}
+
+
+//
+// 'ppdcFile::peek()' - Look at the next character from a file.
+//
+
+int                                    // O - Next character in file
+ppdcFile::peek()
+{
+  // Return immediaely if there is no open file...
+  if (!fp)
+    return (EOF);
+
+  // Otherwise return the next character without advancing...
+  return (cupsFilePeekChar(fp));
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-filter.cxx b/ppdc/ppdc-filter.cxx
new file mode 100644 (file)
index 0000000..bc33add
--- /dev/null
@@ -0,0 +1,55 @@
+//
+// "$Id$"
+//
+//   Filter class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcFilter::ppdcFilter()  - Create a filter.
+//   ppdcFilter::~ppdcFilter() - Destroy a filter.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcFilter::ppdcFilter()' - Create a filter.
+//
+
+ppdcFilter::ppdcFilter(const char *t,  // I - MIME type
+                      const char *p,   // I - Filter program
+                      int        c)    // I - Relative cost
+{
+  mime_type = new ppdcString(t);
+  program   = new ppdcString(p);
+  cost      = c;
+}
+
+
+//
+// 'ppdcFilter::~ppdcFilter()' - Destroy a filter.
+//
+
+ppdcFilter::~ppdcFilter()
+{
+  mime_type->release();
+  program->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-font.cxx b/ppdc/ppdc-font.cxx
new file mode 100644 (file)
index 0000000..85a719d
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// "$Id$"
+//
+//   Shared font class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcFont::ppdcFont()  - Create a shared font.
+//   ppdcFont::~ppdcFont() - Destroy a shared font.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcFont::ppdcFont()' - Create a shared font.
+//
+
+ppdcFont::ppdcFont(const char     *n,          // I - Name of font
+                   const char     *e,          // I - Font encoding
+                  const char     *v,           // I - Font version
+                  const char     *c,           // I - Font charset
+                  ppdcFontStatus s)            // I - Font status
+  : ppdcShared()
+{
+  name     = new ppdcString(n);
+  encoding = new ppdcString(e);
+  version  = new ppdcString(v);
+  charset  = new ppdcString(c);
+  status   = s;
+}
+
+
+//
+// 'ppdcFont::~ppdcFont()' - Destroy a shared font.
+//
+
+ppdcFont::~ppdcFont()
+{
+  name->release();
+  encoding->release();
+  version->release();
+  charset->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-group.cxx b/ppdc/ppdc-group.cxx
new file mode 100644 (file)
index 0000000..c93fc20
--- /dev/null
@@ -0,0 +1,96 @@
+//
+// "$Id$"
+//
+//   Group class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcGroup::ppdcGroup()   - Create a new group.
+//   ppdcGroup::ppdcGroup()   - Copy a new group.
+//   ppdcGroup::~ppdcGroup()  - Destroy a group.
+//   ppdcGroup::find_option() - Find an option in a group.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcGroup::ppdcGroup()' - Create a new group.
+//
+
+ppdcGroup::ppdcGroup(const char *n,    // I - Name of group
+                     const char *t)    // I - Text of group
+{
+  name    = new ppdcString(n);
+  text    = new ppdcString(t);
+  options = new ppdcArray();
+}
+
+
+//
+// 'ppdcGroup::ppdcGroup()' - Copy a new group.
+//
+
+ppdcGroup::ppdcGroup(ppdcGroup *g)     // I - Group template
+{
+  ppdcOption   *o;                     // Current option
+
+
+  g->name->get();
+  g->text->get();
+
+  name = g->name;
+  text = g->text;
+
+  options = new ppdcArray();
+  for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
+    options->add(new ppdcOption(o));
+}
+
+
+//
+// 'ppdcGroup::~ppdcGroup()' - Destroy a group.
+//
+
+ppdcGroup::~ppdcGroup()
+{
+  name->release();
+  text->release();
+  delete options;
+}
+
+
+//
+// 'ppdcGroup::find_option()' - Find an option in a group.
+//
+
+ppdcOption *
+ppdcGroup::find_option(const char *n)  // I - Name of option
+{
+  ppdcOption   *o;                     // Current option
+
+
+  for (o = (ppdcOption *)options->first(); o; o = (ppdcOption *)options->next())
+    if (!strcasecmp(n, o->name->value))
+      return (o);
+
+  return (0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-import.cxx b/ppdc/ppdc-import.cxx
new file mode 100644 (file)
index 0000000..486f9b7
--- /dev/null
@@ -0,0 +1,283 @@
+//
+// "$Id$"
+//
+//   PPD file import methods 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:
+//
+//   ppdcSource::import_ppd() - Import a PPD file.
+//   ppd_gets()               - Get a line from a PPD file.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/ppd.h>
+
+
+//
+// 'ppdcSource::import_ppd()' - Import a PPD file.
+//
+
+int                                    // O - 1 on success, 0 on failure
+ppdcSource::import_ppd(const char *f)  // I - Filename
+{
+  int          i, j, k;                // Looping vars
+  cups_file_t  *fp;                    // File
+  char         line[256],              // Comment line
+               *ptr;                   // Pointer into line
+  ppd_file_t   *ppd;                   // PPD file data
+  ppd_group_t  *group;                 // PPD group
+  ppd_option_t *option;                // PPD option
+  ppd_choice_t *choice;                // PPD choice
+  ppd_attr_t   *attr;                  // PPD attribute
+  ppd_const_t  *constraint;            // PPD UI constraint
+  ppd_const_t  *constraint2;           // Temp PPD UI constraint
+  ppd_size_t   *size;                  // PPD page size
+  ppdcDriver   *driver;                // Driver
+  ppdcFont     *font;                  // Font
+  ppdcGroup    *cgroup;                // UI group
+  ppdcOption   *coption;               // UI option
+  ppdcChoice   *cchoice;               // UI choice
+  ppdcConstraint *cconstraint;         // UI constraint
+  ppdcMediaSize        *csize;                 // Media size
+
+
+  // Try opening the PPD file...
+  if ((ppd = ppdOpenFile(f)) == NULL)
+    return (0);
+
+  // All PPD files need a PCFileName attribute...
+  if (!ppd->pcfilename)
+  {
+    ppdClose(ppd);
+    return (0);
+  }
+
+  // See if the driver has already been imported...
+  if ((driver = find_driver(ppd->pcfilename)) == NULL)
+  {
+    // Create a new PPD file...
+    if ((fp = cupsFileOpen(f, "r")) == NULL)
+    {
+      ppdClose(ppd);
+      return (0);
+    }
+
+    driver       = new ppdcDriver();
+    driver->type = PPDC_DRIVER_PS;
+
+    drivers->add(driver);
+
+    // Read the initial comments from the PPD file and use them as the
+    // copyright/license text...
+    cupsFileGets(fp, line, sizeof(line));
+                                       // Skip *PPD-Adobe-M.m
+
+    while (cupsFileGets(fp, line, sizeof(line)))
+      if (strncmp(line, "*%", 2))
+        break;
+      else
+      {
+        for (ptr = line + 2; isspace(*ptr); ptr ++);
+
+        driver->add_copyright(ptr);
+      }
+
+    cupsFileClose(fp);
+
+    // Then add the stuff from the PPD file...
+    if (ppd->modelname && ppd->manufacturer &&
+        !strncasecmp(ppd->modelname, ppd->manufacturer,
+                     strlen(ppd->manufacturer)))
+    {
+      ptr = ppd->modelname + strlen(ppd->manufacturer);
+
+      while (isspace(*ptr))
+        ptr ++;
+    }
+    else
+      ptr = ppd->modelname;
+
+    driver->manufacturer  = new ppdcString(ppd->manufacturer);
+    driver->model_name    = new ppdcString(ptr);
+    driver->pc_file_name  = new ppdcString(ppd->pcfilename);
+    attr = ppdFindAttr(ppd, "FileVersion", NULL);
+    driver->version       = new ppdcString(attr ? attr->value : NULL);
+    driver->model_number  = ppd->model_number;
+    driver->manual_copies = ppd->manual_copies;
+    driver->color_device  = ppd->color_device;
+    driver->throughput    = ppd->throughput;
+
+    attr = ppdFindAttr(ppd, "DefaultFont", NULL);
+    driver->default_font  = new ppdcString(attr ? attr->value : NULL);
+
+    // Collect media sizes...
+    ppd_option_t       *region_option,         // PageRegion option
+                       *size_option;           // PageSize option
+    ppd_choice_t       *region_choice,         // PageRegion choice
+                       *size_choice;           // PageSize choice
+
+    region_option = ppdFindOption(ppd, "PageRegion");
+    size_option   = ppdFindOption(ppd, "PageSize");
+
+    for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
+    {
+      // Don't do custom size here...
+      if (!strcasecmp(size->name, "Custom"))
+        continue;
+
+      // Get the code for the PageSize and PageRegion options...
+      region_choice = ppdFindChoice(region_option, size->name);
+      size_choice   = ppdFindChoice(size_option, size->name);
+
+      // Create a new media size record and add it to the driver...
+      csize = new ppdcMediaSize(size->name, size_choice->text, size->width,
+                                size->length, size->left, size->bottom,
+                               size->width - size->right,
+                               size->length - size->top,
+                               size_choice->code, region_choice->code);
+
+       driver->add_size(csize);
+
+       if (!strcasecmp(size_option->defchoice, size->name))
+         driver->set_default_size(csize);
+    }
+
+    // Now all of the options...
+    for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+    {
+      cgroup = new ppdcGroup(group->name, group->text);
+      driver->add_group(cgroup);
+
+      for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+      {
+        if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion"))
+          continue;
+            
+        coption = new ppdcOption((ppdcOptType)option->ui, option->keyword,
+                                option->text, (ppdcOptSection)option->section,
+                                option->order);
+        cgroup->add_option(coption);
+
+        for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++)
+        {
+          cchoice = new ppdcChoice(choice->choice, choice->text, choice->code);
+          coption->add_choice(cchoice);
+
+          if (!strcasecmp(option->defchoice, choice->choice))
+            coption->set_defchoice(cchoice);
+        }
+      }
+    }
+
+    // Now the constraints...
+    for (i = ppd->num_consts, constraint = ppd->consts;
+         i > 0;
+        i --, constraint ++)
+    {
+      for (j = i - 1, constraint2 = constraint;
+           j > 0;
+          j --, constraint2 ++)
+       if (constraint != constraint2 &&
+           !strcmp(constraint->option1, constraint2->option2) &&
+           (constraint->choice1 == constraint2->choice2 ||
+            (constraint->choice1 && constraint2->choice2 &&
+             !strcmp(constraint->choice1, constraint2->choice2))) &&
+           !strcmp(constraint->option2, constraint2->option1) &&
+           (constraint->choice2 == constraint2->choice1 ||
+            (constraint->choice2 && constraint2->choice1 &&
+             !strcmp(constraint->choice2, constraint2->choice1))))
+          break;
+
+      if (j)
+        continue;
+
+      cconstraint = new ppdcConstraint(constraint->option1, constraint->choice1,
+                                       constraint->option2, constraint->choice2);
+      driver->add_constraint(cconstraint);
+    }
+
+    for (i = 0; i < ppd->num_attrs; i ++)
+    {
+      attr = ppd->attrs[i];
+
+      if (!strcmp(attr->name, "Font"))
+      {
+        // Font...
+       char            encoding[256],  // Encoding string
+                       version[256],   // Version string
+                       charset[256],   // Charset string
+                       status[256];    // Status string
+       ppdcFontStatus  fstatus;        // Status enumeration
+
+
+        if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version,
+                  charset, status) != 4)
+       {
+         fprintf(stderr, "Bad font attribute: %s\n", attr->value);
+         continue;
+       }
+
+        if (!strcmp(status, "ROM"))
+         fstatus = PPDC_FONT_ROM;
+       else
+         fstatus = PPDC_FONT_DISK;
+
+        font = new ppdcFont(attr->spec, encoding, version, charset, fstatus);
+
+       driver->add_font(font);
+      }
+      else if ((strncmp(attr->name, "Default", 7) ||
+               !strcmp(attr->name, "DefaultColorSpace")) &&
+              strcmp(attr->name, "ColorDevice") &&
+              strcmp(attr->name, "Manufacturer") &&
+              strcmp(attr->name, "ModelName") &&
+              strcmp(attr->name, "MaxMediaHeight") &&
+              strcmp(attr->name, "MaxMediaWidth") &&
+              strcmp(attr->name, "NickName") &&
+              strcmp(attr->name, "ShortNickName") &&
+              strcmp(attr->name, "Throughput") &&
+              strcmp(attr->name, "PCFileName") &&
+              strcmp(attr->name, "FileVersion") &&
+              strcmp(attr->name, "FormatVersion") &&
+              strcmp(attr->name, "VariablePaperSize") &&
+              strcmp(attr->name, "LanguageEncoding") &&
+              strcmp(attr->name, "LanguageVersion"))
+      {
+        // Attribute...
+        driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
+                                     attr->value));
+      }
+      else if (!strncmp(attr->name, "Default", 7) &&
+               !ppdFindOption(ppd, attr->name + 7) &&
+              strcmp(attr->name, "DefaultFont") &&
+              strcmp(attr->name, "DefaultImageableArea") &&
+              strcmp(attr->name, "DefaultPaperDimension") &&
+              strcmp(attr->name, "DefaultFont"))
+      {
+        // Default attribute...
+        driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
+                                     attr->value));
+      }
+    }
+  }
+
+  return (1);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-mediasize.cxx b/ppdc/ppdc-mediasize.cxx
new file mode 100644 (file)
index 0000000..eb1f697
--- /dev/null
@@ -0,0 +1,81 @@
+//
+// "$Id$"
+//
+//   Shared media size class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcMediaSize::ppdcMediaSize()  - Create a new media size.
+//   ppdcMediaSize::~ppdcMediaSize() - Destroy a media size.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcMediaSize::ppdcMediaSize()' - Create a new media size.
+//
+
+ppdcMediaSize::ppdcMediaSize(const char *n,    // I - Name of media size
+                             const char *t,    // I - Text of media size
+                            float      w,      // I - Width in points
+                            float      l,      // I - Length in points
+                             float      lm,    // I - Left margin in points
+                            float      bm,     // I - Bottom margin in points
+                            float      rm,     // I - Right margin in points
+                            float      tm,     // I - Top margin in points
+                            const char *sc,    // I - PageSize code, if any
+                            const char *rc)    // I - PageRegion code, if any
+  : ppdcShared()
+{
+  name        = new ppdcString(n);
+  text        = new ppdcString(t);
+  width       = w;
+  length      = l;
+  left        = lm;
+  bottom      = bm;
+  right       = rm;
+  top         = tm;
+  size_code   = new ppdcString(sc);
+  region_code = new ppdcString(rc);
+
+  if (left < 0.0f)
+    left = 0.0f;
+  if (bottom < 0.0f)
+    bottom = 0.0f;
+  if (right < 0.0f)
+    right = 0.0f;
+  if (top < 0.0f)
+    top = 0.0f;
+}
+
+
+//
+// 'ppdcMediaSize::~ppdcMediaSize()' - Destroy a media size.
+//
+
+ppdcMediaSize::~ppdcMediaSize()
+{
+  name->release();
+  text->release();
+  size_code->release();
+  region_code->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-message.cxx b/ppdc/ppdc-message.cxx
new file mode 100644 (file)
index 0000000..e0285d2
--- /dev/null
@@ -0,0 +1,54 @@
+//
+// "$Id$"
+//
+//   Shared message class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcMessage::ppdcMessage()  - Create a shared message.
+//   ppdcMessage::~ppdcMessage() - Destroy a shared message.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcMessage::ppdcMessage()' - Create a shared message.
+//
+
+ppdcMessage::ppdcMessage(const char *i,        // I - ID
+                         const char *s)        // I - Text
+  : ppdcShared()
+{
+  id     = new ppdcString(i);
+  string = new ppdcString(s);
+}
+
+
+//
+// 'ppdcMessage::~ppdcMessage()' - Destroy a shared message.
+//
+
+ppdcMessage::~ppdcMessage()
+{
+  delete id;
+  delete string;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-option.cxx b/ppdc/ppdc-option.cxx
new file mode 100644 (file)
index 0000000..3eb46aa
--- /dev/null
@@ -0,0 +1,126 @@
+//
+// "$Id$"
+//
+//   Option class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcOption::ppdcOption()    - Create a new option.
+//   ppdcOption::ppdcOption()    - Copy a new option.
+//   ppdcOption::~ppdcOption()   - Destroy an option.
+//   ppdcOption::find_choice()   - Find an option choice.
+//   ppdcOption::set_defchoice() - Set the default choice.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcOption::ppdcOption()' - Create a new option.
+//
+
+ppdcOption::ppdcOption(ppdcOptType    ot,      // I - Option type
+                       const char     *n,      // I - Option name
+                      const char     *t,       // I - Option text
+                      ppdcOptSection s,        // I - Section
+                       float          o)       // I - Ordering number
+{
+//  printf("ppdcOption(ot=%d, n=\"%s\", t=\"%s\"), this=%p\n",
+//         ot, n, t, this);
+
+  type      = ot;
+  name      = new ppdcString(n);
+  text      = new ppdcString(t);
+  section   = s;
+  order     = o;
+  choices   = new ppdcArray();
+  defchoice = 0;
+}
+
+
+//
+// 'ppdcOption::ppdcOption()' - Copy a new option.
+//
+
+ppdcOption::ppdcOption(ppdcOption *o)          // I - Template option
+{
+  o->name->get();
+  o->text->get();
+  if (o->defchoice)
+    o->defchoice->get();
+
+  type      = o->type;
+  name      = o->name;
+  text      = o->text;
+  section   = o->section;
+  order     = o->order;
+  choices   = new ppdcArray(o->choices);
+  defchoice = o->defchoice;
+}
+
+
+//
+// 'ppdcOption::~ppdcOption()' - Destroy an option.
+//
+
+ppdcOption::~ppdcOption()
+{
+  name->release();
+  text->release();
+  if (defchoice)
+    defchoice->release();
+  delete choices;
+}
+
+
+//
+// 'ppdcOption::find_choice()' - Find an option choice.
+//
+
+ppdcChoice *                                   // O - Choice or NULL
+ppdcOption::find_choice(const char *n)         // I - Name of choice
+{
+  ppdcChoice   *c;                             // Current choice
+
+
+  for (c = (ppdcChoice *)choices->first(); c; c = (ppdcChoice *)choices->next())
+    if (!strcasecmp(n, c->name->value))
+      return (c);
+
+  return (0);
+}
+
+
+//
+// 'ppdcOption::set_defchoice()' - Set the default choice.
+//
+
+void
+ppdcOption::set_defchoice(ppdcChoice *c)       // I - Choice
+{
+  if (defchoice)
+    defchoice->release();
+
+  if (c->name)
+    c->name->get();
+
+  defchoice = c->name;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-profile.cxx b/ppdc/ppdc-profile.cxx
new file mode 100644 (file)
index 0000000..813339e
--- /dev/null
@@ -0,0 +1,60 @@
+//
+// "$Id$"
+//
+//   Color profile class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcProfile::ppdcProfile()  - Create a color profile.
+//   ppdcProfile::~ppdcProfile() - Destroy a color profile.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcProfile::ppdcProfile()' - Create a color profile.
+//
+
+ppdcProfile::ppdcProfile(const char  *r,       // I - Resolution name
+                         const char  *m,       // I - Media type name
+                        float       d,         // I - Density
+                        float       g,         // I - Gamma
+                        const float *p)        // I - 3x3 transform matrix
+{
+  resolution = new ppdcString(r);
+  media_type = new ppdcString(m);
+  density    = d;
+  gamma      = g;
+
+  memcpy(profile, p, sizeof(profile));
+}
+
+
+//
+// 'ppdcProfile::~ppdcProfile()' - Destroy a color profile.
+//
+
+ppdcProfile::~ppdcProfile()
+{
+  resolution->release();
+  media_type->release();
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-shared.cxx b/ppdc/ppdc-shared.cxx
new file mode 100644 (file)
index 0000000..28874dd
--- /dev/null
@@ -0,0 +1,75 @@
+//
+// "$Id$"
+//
+//   Shared data class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcShared::ppdcShared()  - Create shared data.
+//   ppdcShared::~ppdcShared() - Destroy shared data.
+//   ppdcShared::get()         - Increment the use count for this data.
+//   ppdcShared::release()     - Decrement the use count and delete as needed.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcShared::ppdcShared()' - Create shared data.
+//
+
+ppdcShared::ppdcShared()
+{
+  use = 1;
+}
+
+
+//
+// 'ppdcShared::~ppdcShared()' - Destroy shared data.
+//
+
+ppdcShared::~ppdcShared()
+{
+}
+
+
+//
+// 'ppdcShared::get()' - Increment the use count for this data.
+//
+
+void
+ppdcShared::get(void)
+{
+  use ++;
+}
+
+
+//
+// 'ppdcShared::release()' - Decrement the use count and delete as needed.
+//
+
+void
+ppdcShared::release(void)
+{
+  use --;
+  if (!use)
+    delete this;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx
new file mode 100644 (file)
index 0000000..c85dd6c
--- /dev/null
@@ -0,0 +1,3241 @@
+//
+// "$Id$"
+//
+//   Source class for the CUPS PPD Compiler.
+//
+//   Copyright 2007-2008 by Apple Inc.
+//   Copyright 2002-2007 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:
+//
+//   ppdcSource::ppdcSource()         - Load a driver source file.
+//   ppdcSource::~ppdcSource()        - Free a driver source file.
+//   ppdcSource::add_include()        - Add an include directory.
+//   ppdcSource::find_driver()        - Find a driver.
+//   ppdcSource::find_include()       - Find an include file.
+//   ppdcSource::find_size()          - Find a media size.
+//   ppdcSource::find_variable()      - Find a variable.
+//   ppdcSource::get_attr()           - Get an attribute.
+//   ppdcSource::get_boolean()        - Get a boolean value.
+//   ppdcSource::get_choice()         - Get a choice.
+//   ppdcSource::get_color_model()    - Get an old-style color model option.
+//   ppdcSource::get_color_order()    - Get an old-style color order value.
+//   ppdcSource::get_color_profile()  - Get a color profile definition.
+//   ppdcSource::get_color_space()    - Get an old-style colorspace value.
+//   ppdcSource::get_constraint()     - Get a constraint.
+//   ppdcSource::get_custom_size()    - Get a custom media size definition
+//                                      from a file.
+//   ppdcSource::get_filter()         - Get a filter.
+//   ppdcSource::get_float()          - Get a single floating-point number.
+//   ppdcSource::get_font()           - Get a font definition.
+//   ppdcSource::get_generic()        - Get a generic old-style option.
+//   ppdcSource::get_group()          - Get an option group.
+//   ppdcSource::get_installable()    - Get an installable option.
+//   ppdcSource::get_integer()        - Get an integer value from a string.
+//   ppdcSource::get_integer()        - Get an integer value from a file.
+//   ppdcSource::get_measurement()    - Get a measurement value.
+//   ppdcSource::get_option()         - Get an option definition.
+//   ppdcSource::get_resolution()     - Get an old-style resolution option.
+//   ppdcSource::get_simple_profile() - Get a simple color profile definition.
+//   ppdcSource::get_size()           - Get a media size definition from a file.
+//   ppdcSource::get_token()          - Get a token from a file.
+//   ppdcSource::get_variable()       - Get a variable definition.
+//   ppdcSource::quotef()             - Write a formatted, quoted string...
+//   ppdcSource::read_file()          - Read a driver source file.
+//   ppdcSource::scan_file()          - Scan a driver source file.
+//   ppdcSource::set_variable()       - Set a variable.
+//   ppdcSource::write_file()         - Write the current source data to a file.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/globals.h>
+#include <limits.h>
+#include <math.h>
+#include <unistd.h>
+#include <cups/raster.h>
+#include "data/epson.h"
+#include "data/escp.h"
+#include "data/hp.h"
+#include "data/label.h"
+#include "data/pcl.h"
+
+
+//
+// Class globals...
+//
+
+ppdcArray      *ppdcSource::includes = 0;
+const char     *ppdcSource::driver_types[] =
+               {
+                 "custom",
+                 "ps",
+                 "escp",
+                 "pcl",
+                 "label",
+                 "epson",
+                 "hp"
+               };
+
+
+//
+// 'ppdcSource::ppdcSource()' - Load a driver source file.
+//
+
+ppdcSource::ppdcSource(const char *f)  // I - File to read
+{
+  filename   = new ppdcString(f);
+  base_fonts = new ppdcArray();
+  drivers    = new ppdcArray();
+  po_files   = new ppdcArray();
+  sizes      = new ppdcArray();
+  vars       = new ppdcArray();
+
+  if (f)
+    read_file(f);
+}
+
+
+//
+// 'ppdcSource::~ppdcSource()' - Free a driver source file.
+//
+
+ppdcSource::~ppdcSource()
+{
+  delete filename;
+  delete base_fonts;
+  delete drivers;
+  delete po_files;
+  delete sizes;
+  delete vars;
+}
+
+
+//
+// 'ppdcSource::add_include()' - Add an include directory.
+//
+
+void
+ppdcSource::add_include(const char *d) // I - Include directory
+{
+  if (!d)
+    return;
+
+  if (!includes)
+    includes = new ppdcArray();
+
+  includes->add(new ppdcString(d));
+}
+
+
+//
+// 'ppdcSource::find_driver()' - Find a driver.
+//
+
+ppdcDriver *                           // O - Driver
+ppdcSource::find_driver(const char *f) // I - Driver file name
+{
+  ppdcDriver   *d;                     // Current driver
+
+
+  for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next())
+    if (!strcasecmp(f, d->pc_file_name->value))
+      return (d);
+
+  return (NULL);
+}
+
+
+//
+// 'ppdcSource::find_include()' - Find an include file.
+//
+
+char *                                 // O - Found path or NULL
+ppdcSource::find_include(
+    const char *f,                     // I - Include filename
+    const char *base,                  // I - Current directory
+    char       *n,                     // I - Path buffer
+    int        nlen)                   // I - Path buffer length
+{
+  ppdcString   *dir;                   // Include directory
+  char         temp[1024],             // Temporary path
+               *ptr;                   // Pointer to end of path
+
+
+  // Range check input...
+  if (!f || !*f || !n || nlen < 2)
+    return (0);
+
+  // Check the first character to see if we have <name> or "name"...
+  if (*f == '<')
+  {
+    // Remove the surrounding <> from the name...
+    strlcpy(temp, f + 1, sizeof(temp));
+    ptr = temp + strlen(temp) - 1;
+
+    if (*ptr != '>')
+    {
+      fprintf(stderr, "ppdc: Invalid #include/#po filename \"%s\"!\n", n);
+      return (0);
+    }
+
+    *ptr = '\0';
+    f    = temp;
+  }
+  else
+  {
+    // Check for the local file relative to the current directory...
+    if (base && *base && f[0] != '/')
+      snprintf(n, nlen, "%s/%s", base, f);
+    else
+      strlcpy(n, f, nlen);
+
+    if (!access(n, 0))
+      return (n);
+    else if (*f == '/')
+    {
+      // Absolute path that doesn't exist...
+      return (0);
+    }
+  }
+
+  // Search the include directories, if any...
+  if (includes)
+  {
+    for (dir = (ppdcString *)includes->first(); dir; dir = (ppdcString *)includes->next())
+    {
+      snprintf(n, nlen, "%s/%s", dir->value, f);
+      if (!access(n, 0))
+        return (n);
+    }
+  }
+
+  // Search the standard include directories...
+  _cups_globals_t *cg = _cupsGlobals();        // Global data
+
+  snprintf(n, nlen, "%s/ppdc/%s", cg->cups_datadir, f);
+  if (!access(n, 0))
+    return (n);
+
+  snprintf(n, nlen, "%s/po/%s", cg->cups_datadir, f);
+  if (!access(n, 0))
+    return (n);
+  else
+    return (0);
+}
+
+
+//
+// 'ppdcSource::find_po()' - Find a message catalog for the given locale...
+//
+
+ppdcCatalog *                          // O - Message catalog or NULL
+ppdcSource::find_po(const char *l)     // I - Locale name
+{
+  ppdcCatalog  *cat;                   // Current message catalog
+
+
+  for (cat = (ppdcCatalog *)po_files->first();
+       cat;
+       cat = (ppdcCatalog *)po_files->next())
+    if (!strcasecmp(l, cat->locale->value))
+      return (cat);
+
+  return (NULL);
+}
+
+
+//
+// 'ppdcSource::find_size()' - Find a media size.
+//
+
+ppdcMediaSize *                                // O - Size
+ppdcSource::find_size(const char *s)   // I - Size name
+{
+  ppdcMediaSize        *m;                     // Current media size
+
+
+  for (m = (ppdcMediaSize *)sizes->first(); m; m = (ppdcMediaSize *)sizes->next())
+    if (!strcasecmp(s, m->name->value))
+      return (m);
+
+  return (NULL);
+}
+
+
+//
+// 'ppdcSource::find_variable()' - Find a variable.
+//
+
+ppdcVariable *                         // O - Variable
+ppdcSource::find_variable(const char *n)// I - Variable name
+{
+  ppdcVariable *v;                     // Current variable
+
+
+  for (v = (ppdcVariable *)vars->first(); v; v = (ppdcVariable *)vars->next())
+    if (!strcasecmp(n, v->name->value))
+      return (v);
+
+  return (NULL);
+}
+
+
+//
+// 'ppdcSource::get_attr()' - Get an attribute.
+//
+
+ppdcAttr *                             // O - Attribute
+ppdcSource::get_attr(ppdcFile *fp)     // I - File to read
+{
+  char name[1024],                     // Name string
+       selector[1024],                 // Selector string
+       *text,                          // Text string
+       value[1024];                    // Value string
+
+
+  // Get the attribute parameters:
+  //
+  // Attribute name selector value
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected name after Attribute on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (0);
+  }
+
+  if (!get_token(fp, selector, sizeof(selector)))
+  {
+    fprintf(stderr, "ppdc: Expected selector after Attribute on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (0);
+  }
+
+  if ((text = strchr(selector, '/')) != NULL)
+    *text++ = '\0';
+
+  if (!get_token(fp, value, sizeof(value)))
+  {
+    fprintf(stderr, "ppdc: Expected value after Attribute on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (0);
+  }
+
+//  printf("name=\"%s\", selector=\"%s\", value=\"%s\"\n", name, selector, value);
+
+  return (new ppdcAttr(name, selector, text, value));
+}
+
+
+//
+// 'ppdcSource::get_boolean()' - Get a boolean value.
+//
+
+int                                    // O - Boolean value
+ppdcSource::get_boolean(ppdcFile *fp)  // I - File to read
+{
+  char buffer[256];                    // String buffer
+
+
+  if (!get_token(fp, buffer, sizeof(buffer)))
+  {
+    fprintf(stderr, "ppdc: Expected boolean value on line %d of %s.\n",
+            fp->line, fp->filename);
+    return (-1);
+  }
+
+  if (!strcasecmp(buffer, "on") ||
+      !strcasecmp(buffer, "yes") ||
+      !strcasecmp(buffer, "true"))
+    return (1);
+  else if (!strcasecmp(buffer, "off") ||
+          !strcasecmp(buffer, "no") ||
+          !strcasecmp(buffer, "false"))
+    return (0);
+  else
+  {
+    fprintf(stderr, "ppdc: Bad boolean value (%s) on line %d of %s.\n",
+            buffer, fp->line, fp->filename);
+    return (-1);
+  }
+}
+
+
+//
+// 'ppdcSource::get_choice()' - Get a choice.
+//
+
+ppdcChoice *                           // O - Choice data
+ppdcSource::get_choice(ppdcFile *fp)   // I - File to read
+{
+  char name[1024],                     // Name
+       *text,                          // Text
+       code[10240];                    // Code
+
+
+  // Read a choice from the file:
+  //
+  // Choice name/text code
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected choice name/text on line %d of %s.\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if (!get_token(fp, code, sizeof(code)))
+  {
+    fprintf(stderr, "ppdc: Expected choice code on line %d of %s.\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  // Return the new choice
+  return (new ppdcChoice(name, text, code));
+}
+
+
+//
+// 'ppdcSource::get_color_model()' - Get an old-style color model option.
+//
+
+ppdcChoice *                           // O - Choice data
+ppdcSource::get_color_model(ppdcFile *fp)
+                                       // I - File to read
+{
+  char         name[1024],             // Option name
+               *text,                  // Text option
+               temp[256];              // Temporary string
+  int          color_space,            // Colorspace
+               color_order,            // Color order
+               compression;            // Compression mode
+
+
+  // Get the ColorModel parameters:
+  //
+  // ColorModel name/text colorspace colororder compression
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr,
+            "ppdc: Expected name/text combination for ColorModel on line "
+           "%d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr,
+            "ppdc: Expected colorspace for ColorModel on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((color_space = get_color_space(temp)) < 0)
+    color_space = get_integer(temp);
+
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr,
+            "ppdc: Expected color order for ColorModel on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((color_order = get_color_order(temp)) < 0)
+    color_order = get_integer(temp);
+
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr,
+            "ppdc: Expected compression for ColorModel on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  compression = get_integer(temp);
+
+  snprintf(temp, sizeof(temp),
+           "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
+          "setpagedevice",
+           color_space, color_order, compression);
+
+  return (new ppdcChoice(name, text, temp));
+}
+
+
+//
+// 'ppdcSource::get_color_order()' - Get an old-style color order value.
+//
+
+int                                    // O - Color order value
+ppdcSource::get_color_order(
+    const char *co)                    // I - Color order string
+{
+  if (!strcasecmp(co, "chunked") ||
+      !strcasecmp(co, "chunky"))
+    return (CUPS_ORDER_CHUNKED);
+  else if (!strcasecmp(co, "banded"))
+    return (CUPS_ORDER_BANDED);
+  else if (!strcasecmp(co, "planar"))
+    return (CUPS_ORDER_PLANAR);
+  else
+    return (-1);
+}
+
+
+//
+// 'ppdcSource::get_color_profile()' - Get a color profile definition.
+//
+
+ppdcProfile *                          // O - Color profile
+ppdcSource::get_color_profile(
+    ppdcFile *fp)                      // I - File to read
+{
+  char         resolution[1024],       // Resolution/media type
+               *media_type;            // Media type
+  int          i;                      // Looping var
+  float                g,                      // Gamma value
+               d,                      // Density value
+               m[9];                   // Transform matrix
+
+
+  // Get the ColorProfile parameters:
+  //
+  // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
+  if (!get_token(fp, resolution, sizeof(resolution)))
+  {
+    fprintf(stderr, "ppdc: Expected resolution/mediatype following ColorProfile on line %d of %s!\n",
+           fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((media_type = strchr(resolution, '/')) != NULL)
+    *media_type++ = '\0';
+  else
+    media_type = resolution;
+
+  g = get_float(fp);
+  d = get_float(fp);
+  for (i = 0; i < 9; i ++)
+    m[i] = get_float(fp);
+
+  return (new ppdcProfile(resolution, media_type, g, d, m));
+}
+
+
+//
+// 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
+//
+
+int                                    // O - Colorspace value
+ppdcSource::get_color_space(
+    const char *cs)                    // I - Colorspace string
+{
+  if (!strcasecmp(cs, "w"))
+    return (CUPS_CSPACE_W);
+  else if (!strcasecmp(cs, "rgb"))
+    return (CUPS_CSPACE_RGB);
+  else if (!strcasecmp(cs, "rgba"))
+    return (CUPS_CSPACE_RGBA);
+  else if (!strcasecmp(cs, "k"))
+    return (CUPS_CSPACE_K);
+  else if (!strcasecmp(cs, "cmy"))
+    return (CUPS_CSPACE_CMY);
+  else if (!strcasecmp(cs, "ymc"))
+    return (CUPS_CSPACE_YMC);
+  else if (!strcasecmp(cs, "cmyk"))
+    return (CUPS_CSPACE_CMYK);
+  else if (!strcasecmp(cs, "ymck"))
+    return (CUPS_CSPACE_YMCK);
+  else if (!strcasecmp(cs, "kcmy"))
+    return (CUPS_CSPACE_KCMY);
+  else if (!strcasecmp(cs, "kcmycm"))
+    return (CUPS_CSPACE_KCMYcm);
+  else if (!strcasecmp(cs, "gmck"))
+    return (CUPS_CSPACE_GMCK);
+  else if (!strcasecmp(cs, "gmcs"))
+    return (CUPS_CSPACE_GMCS);
+  else if (!strcasecmp(cs, "white"))
+    return (CUPS_CSPACE_WHITE);
+  else if (!strcasecmp(cs, "gold"))
+    return (CUPS_CSPACE_GOLD);
+  else if (!strcasecmp(cs, "silver"))
+    return (CUPS_CSPACE_SILVER);
+  else if (!strcasecmp(cs, "CIEXYZ"))
+    return (CUPS_CSPACE_CIEXYZ);
+  else if (!strcasecmp(cs, "CIELab"))
+    return (CUPS_CSPACE_CIELab);
+  else if (!strcasecmp(cs, "RGBW"))
+    return (CUPS_CSPACE_RGBW);
+  else if (!strcasecmp(cs, "ICC1"))
+    return (CUPS_CSPACE_ICC1);
+  else if (!strcasecmp(cs, "ICC2"))
+    return (CUPS_CSPACE_ICC2);
+  else if (!strcasecmp(cs, "ICC3"))
+    return (CUPS_CSPACE_ICC3);
+  else if (!strcasecmp(cs, "ICC4"))
+    return (CUPS_CSPACE_ICC4);
+  else if (!strcasecmp(cs, "ICC5"))
+    return (CUPS_CSPACE_ICC5);
+  else if (!strcasecmp(cs, "ICC6"))
+    return (CUPS_CSPACE_ICC6);
+  else if (!strcasecmp(cs, "ICC7"))
+    return (CUPS_CSPACE_ICC7);
+  else if (!strcasecmp(cs, "ICC8"))
+    return (CUPS_CSPACE_ICC8);
+  else if (!strcasecmp(cs, "ICC9"))
+    return (CUPS_CSPACE_ICC9);
+  else if (!strcasecmp(cs, "ICCA"))
+    return (CUPS_CSPACE_ICCA);
+  else if (!strcasecmp(cs, "ICCB"))
+    return (CUPS_CSPACE_ICCB);
+  else if (!strcasecmp(cs, "ICCC"))
+    return (CUPS_CSPACE_ICCC);
+  else if (!strcasecmp(cs, "ICCD"))
+    return (CUPS_CSPACE_ICCD);
+  else if (!strcasecmp(cs, "ICCE"))
+    return (CUPS_CSPACE_ICCE);
+  else if (!strcasecmp(cs, "ICCF"))
+    return (CUPS_CSPACE_ICCF);
+  else
+    return (-1);
+}
+
+
+//
+// 'ppdcSource::get_constraint()' - Get a constraint.
+//
+
+ppdcConstraint *                       // O - Constraint
+ppdcSource::get_constraint(ppdcFile *fp)// I - File to read
+{
+  char         temp[1024],             // One string to rule them all
+               *ptr,                   // Pointer into string
+               *option1,               // Constraint option 1
+               *choice1,               // Constraint choice 1
+               *option2,               // Constraint option 2
+               *choice2;               // Constraint choice 2
+
+
+  // Read the UIConstaints parameter in one of the following forms:
+  //
+  // UIConstraints "*Option1 *Option2"
+  // UIConstraints "*Option1 Choice1 *Option2"
+  // UIConstraints "*Option1 *Option2 Choice2"
+  // UIConstraints "*Option1 Choice1 *Option2 Choice2"
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr, "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  for (ptr = temp; isspace(*ptr); ptr ++);
+
+  if (*ptr != '*')
+  {
+    fprintf(stderr, "ppdc: Option constraint must *name on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  option1 = ptr;
+
+  for (; *ptr && !isspace(*ptr); ptr ++);
+  for (; isspace(*ptr); *ptr++ = '\0');
+
+  if (*ptr != '*')
+  {
+    choice1 = ptr;
+
+    for (; *ptr && !isspace(*ptr); ptr ++);
+    for (; isspace(*ptr); *ptr++ = '\0');
+  }
+  else
+    choice1 = NULL;
+
+  if (*ptr != '*')
+  {
+    fprintf(stderr, "ppdc: Expected two option names on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  option2 = ptr;
+
+  for (; *ptr && !isspace(*ptr); ptr ++);
+  for (; isspace(*ptr); *ptr++ = '\0');
+
+  if (*ptr)
+    choice2 = ptr;
+  else
+    choice2 = NULL;
+
+  return (new ppdcConstraint(option1, choice1, option2, choice2));
+}
+
+
+//
+// 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
+//
+
+ppdcMediaSize *                                // O - Media size
+ppdcSource::get_custom_size(ppdcFile *fp)
+                                       // I - File to read
+{
+  char         name[1024],             // Name
+               *text,                  // Text
+               size_code[10240],       // PageSize code
+               region_code[10240];     // PageRegion
+  float                width,                  // Width
+               length,                 // Length
+               left,                   // Left margin
+               bottom,                 // Bottom margin
+               right,                  // Right margin
+               top;                    // Top margin
+
+
+  // Get the name, text, width, length, margins, and code:
+  //
+  // CustomMedia name/text width length left bottom right top size-code region-code
+  if (!get_token(fp, name, sizeof(name)))
+    return (NULL);
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if ((width = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((length = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((left = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((bottom = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((right = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((top = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if (!get_token(fp, size_code, sizeof(size_code)))
+    return (NULL);
+
+  if (!get_token(fp, region_code, sizeof(region_code)))
+    return (NULL);
+
+  // Return the new media size...
+  return (new ppdcMediaSize(name, text, width, length, left, bottom,
+                            right, top, size_code, region_code));
+}
+
+
+//
+// 'ppdcSource::get_duplex()' - Get a duplex option.
+//
+
+void
+ppdcSource::get_duplex(ppdcFile   *fp, // I - File to read from
+                       ppdcDriver *d)  // I - Current driver
+{
+  char         temp[256];              // Duplex keyword
+  ppdcAttr     *attr;                  // cupsFlipDuplex attribute
+  ppdcGroup    *g;                     // Current group
+  ppdcOption   *o;                     // Duplex option
+
+
+  // Duplex {boolean|none|normal|flip}
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr, "ppdc: Expected duplex type after Duplex on line %d of %s!\n",
+           fp->line, fp->filename);
+    return;
+  }
+
+  if (!strcasecmp(temp, "none") || !strcasecmp(temp, "false") ||
+      !strcasecmp(temp, "no") || !strcasecmp(temp, "off"))
+  {
+    g = d->find_group("General");
+    if ((o = g->find_option("Duplex")) != NULL)
+      g->options->remove(o);
+
+    for (attr = (ppdcAttr *)d->attrs->first();
+         attr;
+        attr = (ppdcAttr *)d->attrs->next())
+      if (!strcmp(attr->name->value, "cupsFlipDuplex"))
+      {
+        d->attrs->remove(attr);
+       break;
+      }
+  }
+  else if (!strcasecmp(temp, "normal") || !strcasecmp(temp, "true") ||
+          !strcasecmp(temp, "yes") || !strcasecmp(temp, "on") ||
+          !strcasecmp(temp, "flip"))
+  {
+    g = d->find_group("General");
+    o = g->find_option("Duplex");
+
+    if (!o)
+    {
+      o = new ppdcOption(PPDC_PICKONE, "Duplex", "2-Sided Printing",
+                        !strcasecmp(temp, "flip") ? PPDC_SECTION_PAGE :
+                                                    PPDC_SECTION_ANY, 10.0f);
+      o->add_choice(new ppdcChoice("None", "Off (1-Sided)",
+                                  "<</Duplex false>>setpagedevice"));
+      o->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
+                                   "<</Duplex true/Tumble false>>setpagedevice"));
+      o->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
+                                   "<</Duplex true/Tumble true>>setpagedevice"));
+
+      g->add_option(o);
+    }
+
+    for (attr = (ppdcAttr *)d->attrs->first();
+         attr;
+        attr = (ppdcAttr *)d->attrs->next())
+      if (!strcmp(attr->name->value, "cupsFlipDuplex"))
+      {
+        if (strcasecmp(temp, "flip"))
+          d->attrs->remove(attr);
+       break;
+      }
+
+    if (!strcasecmp(temp, "flip") && !attr)
+      d->add_attr(new ppdcAttr("cupsFlipDuplex", NULL, NULL, "true"));
+  }
+  else
+    fprintf(stderr, "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n",
+           temp, fp->line, fp->filename);
+}
+
+
+//
+// 'ppdcSource::get_filter()' - Get a filter.
+//
+
+ppdcFilter *                           // O - Filter
+ppdcSource::get_filter(ppdcFile *fp)   // I - File to read
+{
+  char type[1024],                     // MIME type
+       program[1024],                  // Filter program
+       *ptr;                           // Pointer into MIME type
+  int  cost;                           // Relative cost
+
+
+  // Read filter parameters in one of the following formats:
+  //
+  // Filter "type cost program"
+  // Filter type cost program
+
+  if (!get_token(fp, type, sizeof(type)))
+  {
+    fprintf(stderr, "ppdc: Expected a filter definition on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((ptr = strchr(type, ' ')) != NULL)
+  {
+    // Old-style filter definition in one string...
+    *ptr++ = '\0';
+    cost = strtol(ptr, &ptr, 10);
+
+    while (isspace(*ptr))
+      ptr ++;
+
+    strcpy(program, ptr);
+  }
+  else
+  {
+    cost = get_integer(fp);
+
+    if (!get_token(fp, program, sizeof(program)))
+    {
+      fprintf(stderr, "ppdc: Expected a program name on line %d of %s!\n",
+              fp->line, fp->filename);
+      return (NULL);
+    }
+  }
+
+  if (!type[0])
+  {
+    fprintf(stderr, "ppdc: Invalid empty MIME type for filter on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (cost < 0 || cost > 200)
+  {
+    fprintf(stderr, "ppdc: Invalid cost for filter on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (!program[0])
+  {
+    fprintf(stderr, "ppdc: Invalid empty program name for filter on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  return (new ppdcFilter(type, program, cost));
+}
+
+
+//
+// 'ppdcSource::get_float()' - Get a single floating-point number.
+//
+
+float                                  // O - Number
+ppdcSource::get_float(ppdcFile *fp)    // I - File to read
+{
+  char temp[256],                      // String buffer
+       *ptr;                           // Pointer into buffer
+  float        val;                            // Floating point value
+
+
+  // Get the number from the file and range-check...
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr, "ppdc: Expected real number on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (-1.0f);
+  }
+
+  val = (float)strtod(temp, &ptr);
+
+  if (*ptr)
+  {
+    fprintf(stderr, "ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n",
+            temp, fp->line, fp->filename);
+    return (-1.0f);
+  }
+  else
+    return (val);
+}
+
+
+//
+// 'ppdcSource::get_font()' - Get a font definition.
+//
+
+ppdcFont *                             // O - Font data
+ppdcSource::get_font(ppdcFile *fp)     // I - File to read
+{
+  char                 name[256],      // Font name
+                       encoding[256],  // Font encoding
+                       version[256],   // Font version
+                       charset[256],   // Font charset
+                       temp[256];      // Font status string
+  ppdcFontStatus       status;         // Font status enumeration
+
+
+  // Read font parameters as follows:
+  //
+  // Font *
+  // Font name encoding version charset status
+  // %font name encoding version charset status
+  //
+  // "Name" is the PostScript font name.
+  //
+  // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
+  // Special, Expert, ExpertSubset, etc.
+  //
+  // "Version" is the version number string.
+  //
+  // "Charset" specifies the characters that are included in the font:
+  // Standard, Special, Expert, Adobe-Identity, etc.
+  //
+  // "Status" is the keyword ROM or Disk.
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected name after Font on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (0);
+  }
+
+  if (!strcmp(name, "*"))
+  {
+    // Include all base fonts...
+    encoding[0] = '\0';
+    version[0]  = '\0';
+    charset[0]  = '\0';
+    status      = PPDC_FONT_ROM;
+  }
+  else
+  {
+    // Load a full font definition...
+    if (!get_token(fp, encoding, sizeof(encoding)))
+    {
+      fprintf(stderr, "ppdc: Expected encoding after Font on line %d of %s!\n",
+              fp->line, fp->filename);
+      return (0);
+    }
+
+    if (!get_token(fp, version, sizeof(version)))
+    {
+      fprintf(stderr, "ppdc: Expected version after Font on line %d of %s!\n",
+              fp->line, fp->filename);
+      return (0);
+    }
+
+    if (!get_token(fp, charset, sizeof(charset)))
+    {
+      fprintf(stderr, "ppdc: Expected charset after Font on line %d of %s!\n",
+              fp->line, fp->filename);
+      return (0);
+    }
+
+    if (!get_token(fp, temp, sizeof(temp)))
+    {
+      fprintf(stderr, "ppdc: Expected status after Font on line %d of %s!\n",
+              fp->line, fp->filename);
+      return (0);
+    }
+
+    if (!strcasecmp(temp, "ROM"))
+      status = PPDC_FONT_ROM;
+    else if (!strcasecmp(temp, "Disk"))
+      status = PPDC_FONT_DISK;
+    else
+    {
+      fprintf(stderr, "ppdc: Bad status keyword %s on line %d of %s!\n",
+              temp, fp->line, fp->filename);
+      return (0);
+    }
+  }
+
+//  printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
+
+  return (new ppdcFont(name, encoding, version, charset, status));
+}
+
+
+//
+// 'ppdcSource::get_generic()' - Get a generic old-style option.
+//
+
+ppdcChoice *                           // O - Choice data
+ppdcSource::get_generic(ppdcFile   *fp,        // I - File to read
+                        const char *keyword,
+                                       // I - Keyword name
+                        const char *tattr,
+                                       // I - Text attribute
+                       const char *nattr)
+                                       // I - Numeric attribute
+{
+  char         name[1024],             // Name
+               *text,                  // Text
+               command[256];           // Command string
+  int          val;                    // Numeric value
+
+
+  // Read one of the following parameters:
+  //
+  // Foo name/text
+  // Foo integer name/text
+  if (nattr)
+    val = get_integer(fp);
+  else
+    val = 0;
+
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected name/text after %s on line %d of %s!\n",
+            keyword, fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if (nattr)
+  {
+    if (tattr)
+      snprintf(command, sizeof(command),
+               "<</%s(%s)/%s %d>>setpagedevice",
+               tattr, name, nattr, val);
+    else
+      snprintf(command, sizeof(command),
+               "<</%s %d>>setpagedevice",
+               nattr, val);
+  }
+  else
+    snprintf(command, sizeof(command),
+             "<</%s(%s)>>setpagedevice",
+             tattr, name);
+
+  return (new ppdcChoice(name, text, command));
+}
+
+
+//
+// 'ppdcSource::get_group()' - Get an option group.
+//
+
+ppdcGroup *                            // O - Group
+ppdcSource::get_group(ppdcFile   *fp,  // I - File to read
+                      ppdcDriver *d)   // I - Printer driver
+{
+  char         name[1024],             // UI name
+               *text;                  // UI text
+  ppdcGroup    *g;                     // Group
+
+
+  // Read the Group parameters:
+  //
+  // Group name/text
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected group name/text on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  // See if the group already exists...
+  if ((g = d->find_group(name)) == NULL)
+  {
+    // Nope, add a new one...
+    g = new ppdcGroup(name, text);
+    d->add_group(g);
+  }
+
+  return (g);
+}
+
+
+//
+// 'ppdcSource::get_installable()' - Get an installable option.
+//
+
+ppdcOption *                           // O - Option
+ppdcSource::get_installable(ppdcFile *fp)
+                                       // I - File to read
+{
+  char         name[1024],             // Name for installable option
+               *text;                  // Text for installable option
+  ppdcOption   *o;                     // Option
+
+
+  // Read the parameter for an installable option:
+  //
+  // Installable name/text
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected name/text after Installable on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  // Create the option...
+  o = new ppdcOption(PPDC_BOOLEAN, name, text, PPDC_SECTION_ANY, 10.0f);
+
+  // Add the false and true choices...
+  o->add_choice(new ppdcChoice("False", "Not Installed", ""));
+  o->add_choice(new ppdcChoice("True", "Installed", ""));
+
+  return (o);
+}
+
+
+//
+// 'ppdcSource::get_integer()' - Get an integer value from a string.
+//
+
+int                                    // O - Integer value
+ppdcSource::get_integer(const char *v) // I - Value string
+{
+  int  val;                            // Value
+  int  temp;                           // Temporary value
+  char *newv;                          // New value string pointer
+
+
+  // Parse the value string...
+  if (!v)
+    return (-1);
+
+  if (isdigit(*v) || *v == '-' || *v == '+')
+  {
+    // Return a simple integer value
+    val = strtol(v, (char **)&v, 0);
+    if (*v || val == LONG_MIN)
+      return (-1);
+    else
+      return (val);
+  }
+  else if (*v == '(')
+  {
+    // Return the bitwise OR of each integer in parenthesis...
+    v ++;
+    val = 0;
+
+    while (*v && *v != ')')
+    {
+      temp = strtol(v, &newv, 0);
+
+      if (!*newv || newv == v || !(isspace(*newv) || *newv == ')') ||
+          temp == LONG_MIN)
+        return (-1);
+
+      val |= temp;
+      v   = newv;
+    }
+
+    if (*v == ')')
+      return (val);
+    else
+      return (-1);
+  }
+  else
+    return (-1);
+}
+
+
+//
+// 'ppdcSource::get_integer()' - Get an integer value from a file.
+//
+
+int                                    // O - Integer value
+ppdcSource::get_integer(ppdcFile *fp)  // I - File to read
+{
+  char temp[1024];                     // String buffer
+
+
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr, "ppdc: Expected integer on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (-1);
+  }
+  else
+    return (get_integer(temp));
+}
+
+
+//
+// 'ppdcSource::get_measurement()' - Get a measurement value.
+//
+
+float                                  // O - Measurement value in points
+ppdcSource::get_measurement(ppdcFile *fp)
+                                       // I - File to read
+{
+  char buffer[256],                    // Number buffer
+       *ptr;                           // Pointer into buffer
+  float        val;                            // Measurement value
+
+
+  // Grab a token from the file...
+  if (!get_token(fp, buffer, sizeof(buffer)))
+    return (-1.0f);
+
+  // Get the floating point value of "s" and skip all digits and decimal points.
+  val = (float)strtod(buffer, &ptr);
+
+  // Check for a trailing unit specifier...
+  if (!strcasecmp(ptr, "mm"))
+    val *= 72.0f / 25.4f;
+  else if (!strcasecmp(ptr, "cm"))
+    val *= 72.0f / 2.54f;
+  else if (!strcasecmp(ptr, "m"))
+    val *= 72.0f / 0.0254f;
+  else if (!strcasecmp(ptr, "in"))
+    val *= 72.0f;
+  else if (!strcasecmp(ptr, "ft"))
+    val *= 72.0f * 12.0f;
+  else if (strcasecmp(ptr, "pt") && *ptr)
+    return (-1.0f);
+
+  return (val);
+}
+
+
+//
+// 'ppdcSource::get_option()' - Get an option definition.
+//
+
+ppdcOption *                           // O - Option
+ppdcSource::get_option(ppdcFile   *fp, // I - File to read
+                       ppdcDriver *d,  // I - Printer driver
+                      ppdcGroup  *g)   // I - Current group
+{
+  char         name[1024],             // UI name
+               *text,                  // UI text
+               type[256];              // UI type string
+  ppdcOptType  ot;                     // Option type value
+  ppdcOptSection section;              // Option section
+  float                order;                  // Option order
+  ppdcOption   *o;                     // Option
+
+
+  // Read the Option parameters:
+  //
+  // Option name/text type section order
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected option name/text on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if (!get_token(fp, type, sizeof(type)))
+  {
+    fprintf(stderr, "ppdc: Expected option type on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (!strcasecmp(type, "boolean"))
+    ot = PPDC_BOOLEAN;
+  else if (!strcasecmp(type, "pickone"))
+    ot = PPDC_PICKONE;
+  else if (!strcasecmp(type, "pickmany"))
+    ot = PPDC_PICKMANY;
+  else
+  {
+    fprintf(stderr, "ppdc: Invalid option type \"%s\" on line %d of %s!\n",
+            type, fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (!get_token(fp, type, sizeof(type)))
+  {
+    fprintf(stderr, "ppdc: Expected option section on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (!strcasecmp(type, "AnySetup"))
+    section = PPDC_SECTION_ANY;
+  else if (!strcasecmp(type, "DocumentSetup"))
+    section = PPDC_SECTION_DOCUMENT;
+  else if (!strcasecmp(type, "ExitServer"))
+    section = PPDC_SECTION_EXIT;
+  else if (!strcasecmp(type, "JCLSetup"))
+    section = PPDC_SECTION_JCL;
+  else if (!strcasecmp(type, "PageSetup"))
+    section = PPDC_SECTION_PAGE;
+  else if (!strcasecmp(type, "Prolog"))
+    section = PPDC_SECTION_PROLOG;
+  else
+  {
+    fprintf(stderr, "ppdc: Invalid option section \"%s\" on line %d of %s!\n",
+            type, fp->line, fp->filename);
+    return (NULL);
+  }
+
+  order = get_float(fp);
+
+  // See if the option already exists...
+  if ((o = d->find_option(name)) == NULL)
+  {
+    // Nope, add a new one...
+    o = new ppdcOption(ot, name, text, section, order);
+    g->add_option(o);
+  }
+  else if (o->type != ot)
+  {
+//    printf("o=%p, o->type=%d, o->name=%s, ot=%d, name=%s\n",
+//           o, o->type, o->name->value, ot, name);
+    fprintf(stderr, "ppdc: Option already defined with a different type on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  return (o);
+}
+
+
+//
+// 'ppdcSource::get_po()' - Get a message catalog.
+//
+
+ppdcCatalog *                          // O - Message catalog
+ppdcSource::get_po(ppdcFile *fp)       // I - File to read
+{
+  char         locale[32],             // Locale name
+               poname[1024],           // Message catalog filename
+               basedir[1024],          // Base directory
+               *baseptr,               // Pointer into directory
+               pofilename[1024];       // Full filename of message catalog
+  ppdcCatalog  *cat;                   // Message catalog
+
+
+  // Read the #po parameters:
+  //
+  // #po locale "filename.po"
+  if (!get_token(fp, locale, sizeof(locale)))
+  {
+    fprintf(stderr, "ppdc: Expected locale after #po on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if (!get_token(fp, poname, sizeof(poname)))
+  {
+    fprintf(stderr, "ppdc: Expected filename after #po %s on line %d of %s!\n",
+            locale, fp->line, fp->filename);
+    return (NULL);
+  }
+
+  // See if the locale is already loaded...
+  if (find_po(locale))
+  {
+    fprintf(stderr, "ppdc: Duplicate #po for locale %s on line %d of %s!\n",
+            locale, fp->line, fp->filename);
+    return (NULL);
+  }
+
+  // Figure out the current directory...
+  strlcpy(basedir, fp->filename, sizeof(basedir));
+
+  if ((baseptr = strrchr(basedir, '/')) != NULL)
+    *baseptr = '\0';
+  else
+    strcpy(basedir, ".");
+
+  // Find the po file...
+  if (find_include(poname, basedir, pofilename, sizeof(pofilename)))
+  {
+    // Found it, so load it...
+    cat = new ppdcCatalog(locale, pofilename);
+
+    // Reset the filename to the name supplied by the user...
+    delete cat->filename;
+    cat->filename = new ppdcString(poname);
+
+    // Return the catalog...
+    return (cat);
+  }
+  else
+  {
+    fprintf(stderr, "ppdc: Unable to find #po file %s on line %d of %s!\n",
+            poname, fp->line, fp->filename);
+    return (NULL);
+  }
+}
+
+
+//
+// 'ppdcSource::get_resolution()' - Get an old-style resolution option.
+//
+
+ppdcChoice *                           // O - Choice data
+ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
+{
+  char         name[1024],             // Name
+               *text,                  // Text
+               temp[256],              // Temporary string
+               command[256],           // Command string
+               *commptr;               // Pointer into command
+  int          xdpi, ydpi,             // X + Y resolution
+               color_order,            // Color order
+               color_space,            // Colorspace
+               compression,            // Compression mode
+               depth,                  // Bits per color
+               row_count,              // Row count
+               row_feed,               // Row feed
+               row_step;               // Row step/interval
+
+
+  // Read the resolution parameters:
+  //
+  // Resolution colorspace bits row-count row-feed row-step name/text
+  if (!get_token(fp, temp, sizeof(temp)))
+  {
+    fprintf(stderr, "ppdc: Expected override field after Resolution on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  color_order = get_color_order(temp);
+  color_space = get_color_space(temp);
+  compression = get_integer(temp);
+
+  depth       = get_integer(fp);
+  row_count   = get_integer(fp);
+  row_feed    = get_integer(fp);
+  row_step    = get_integer(fp);
+
+  if (!get_token(fp, name, sizeof(name)))
+  {
+    fprintf(stderr, "ppdc: Expected name/text after Resolution on line %d of %s!\n",
+            fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  switch (sscanf(name, "%dx%d", &xdpi, &ydpi))
+  {
+    case 0 :
+        fprintf(stderr, "ppdc: Bad resolution name \"%s\" on line %d of %s!\n",
+               name, fp->line, fp->filename);
+        break;
+    case 1 :
+        ydpi = xdpi;
+       break;
+  }
+
+  // Create the necessary PS commands...
+  snprintf(command, sizeof(command),
+           "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
+           "/cupsRowFeed %d/cupsRowStep %d",
+          xdpi, ydpi, depth, row_count, row_feed, row_step);
+  commptr = command + strlen(command);
+
+  if (color_order >= 0)
+  {
+    snprintf(commptr, sizeof(command) - (commptr - command),
+             "/cupsColorOrder %d", color_order);
+    commptr += strlen(commptr);
+  }
+
+  if (color_space >= 0)
+  {
+    snprintf(commptr, sizeof(command) - (commptr - command),
+             "/cupsColorSpace %d", color_space);
+    commptr += strlen(commptr);
+  }
+
+  if (compression >= 0)
+  {
+    snprintf(commptr, sizeof(command) - (commptr - command),
+             "/cupsCompression %d", compression);
+    commptr += strlen(commptr);
+  }
+
+  snprintf(commptr, sizeof(command) - (commptr - command), ">>setpagedevice");
+
+  // Return the new choice...
+  return (new ppdcChoice(name, text, command));
+}
+
+
+//
+// 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
+//
+
+ppdcProfile *                          // O - Color profile
+ppdcSource::get_simple_profile(ppdcFile *fp)
+                                       // I - File to read
+{
+  char         resolution[1024],       // Resolution/media type
+               *media_type;            // Media type
+  float                m[9];                   // Transform matrix
+  float                kd, rd, g;              // Densities and gamma
+  float                red, green, blue;       // RGB adjustments
+  float                yellow;                 // Yellow density
+  float                color;                  // Color density values
+
+
+  // Get the SimpleColorProfile parameters:
+  //
+  // SimpleColorProfile resolution/mediatype black-density yellow-density
+  //     red-density gamma red-adjust green-adjust blue-adjust
+  if (!get_token(fp, resolution, sizeof(resolution)))
+  {
+    fprintf(stderr, "ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d of %s!\n",
+           fp->line, fp->filename);
+    return (NULL);
+  }
+
+  if ((media_type = strchr(resolution, '/')) != NULL)
+    *media_type++ = '\0';
+  else
+    media_type = resolution;
+
+  // Collect the profile parameters...
+  kd     = get_float(fp);
+  yellow = get_float(fp);
+  rd     = get_float(fp);
+  g      = get_float(fp);
+  red    = get_float(fp);
+  green  = get_float(fp);
+  blue   = get_float(fp);
+
+  // Build the color profile...
+  color = 0.5f * rd / kd - kd;
+  m[0]  = 1.0f;                                // C
+  m[1]  = color + blue;                        // C + M (blue)
+  m[2]  = color - green;               // C + Y (green)
+  m[3]  = color - blue;                        // M + C (blue)
+  m[4]  = 1.0f;                                // M
+  m[5]  = color + red;                 // M + Y (red)
+  m[6]  = yellow * (color + green);    // Y + C (green)
+  m[7]  = yellow * (color - red);      // Y + M (red)
+  m[8]  = yellow;                      // Y
+
+  if (m[1] > 0.0f)
+  {
+    m[3] -= m[1];
+    m[1] = 0.0f;
+  }
+  else if (m[3] > 0.0f)
+  {
+    m[1] -= m[3];
+    m[3] = 0.0f;
+  }
+
+  if (m[2] > 0.0f)
+  {
+    m[6] -= m[2];
+    m[2] = 0.0f;
+  }
+  else if (m[6] > 0.0f)
+  {
+    m[2] -= m[6];
+    m[6] = 0.0f;
+  }
+
+  if (m[5] > 0.0f)
+  {
+    m[7] -= m[5];
+    m[5] = 0.0f;
+  }
+  else if (m[7] > 0.0f)
+  {
+    m[5] -= m[7];
+    m[7] = 0.0f;
+  }
+
+  // Return the new profile...
+  return (new ppdcProfile(resolution, media_type, g, kd, m));
+}
+
+
+//
+// 'ppdcSource::get_size()' - Get a media size definition from a file.
+//
+
+ppdcMediaSize *                                // O - Media size
+ppdcSource::get_size(ppdcFile *fp)     // I - File to read
+{
+  char         name[1024],             // Name
+               *text;                  // Text
+  float                width,                  // Width
+               length;                 // Length
+
+
+  // Get the name, text, width, and length:
+  //
+  // #media name/text width length
+  if (!get_token(fp, name, sizeof(name)))
+    return (NULL);
+
+  if ((text = strchr(name, '/')) != NULL)
+    *text++ = '\0';
+  else
+    text = name;
+
+  if ((width = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  if ((length = get_measurement(fp)) < 0.0f)
+    return (NULL);
+
+  // Return the new media size...
+  return (new ppdcMediaSize(name, text, width, length, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+
+//
+// 'ppdcSource::get_token()' - Get a token from a file.
+//
+
+char *                                 // O - Token string or NULL
+ppdcSource::get_token(ppdcFile *fp,    // I - File to read
+                      char     *buffer,        // I - Buffer
+                     int      buflen)  // I - Length of buffer
+{
+  char         *bufptr,                // Pointer into string buffer
+               *bufend;                // End of string buffer
+  int          ch,                     // Character from file
+               nextch,                 // Next char in file
+               quote,                  // Quote character used...
+               empty,                  // Empty input?
+               startline;              // Start line for quote
+  char         name[256],              // Name string
+               *nameptr;               // Name pointer
+  ppdcVariable *var;                   // Variable pointer
+
+
+  // Mark the beginning and end of the buffer...
+  bufptr = buffer;
+  bufend = buffer + buflen - 1;
+
+  // Loop intil we've read a token...
+  quote     = 0;
+  startline = 0;
+  empty     = 1;
+
+  while ((ch = fp->get()) != EOF)
+  {
+    if (isspace(ch) && !quote)
+    {
+      if (empty)
+        continue;
+      else
+        break;
+    }
+    else if (ch == '$')
+    {
+      // Variable substitution
+      empty = 0;
+
+      for (nameptr = name; (ch = fp->peek()) != EOF;)
+      {
+        if (!isalnum(ch) && ch != '_')
+         break;
+       else if (nameptr < (name + sizeof(name) - 1))
+         *nameptr++ = fp->get();
+      }
+
+      if (nameptr == name)
+      {
+        // Just substitute this character...
+       if (ch == '$')
+       {
+         // $$ = $
+         if (bufptr < bufend)
+           *bufptr++ = fp->get();
+       }
+       else
+       {
+         // $ch = $ch
+          fprintf(stderr, "ppdc: Bad variable substitution ($%c) on line %d of %s.\n",
+                  ch, fp->line, fp->filename);
+
+         if (bufptr < bufend)
+           *bufptr++ = '$';
+       }
+      }
+      else
+      {
+        // Substitute the variable value...
+       *nameptr = '\0';
+       var = find_variable(name);
+       if (var)
+       {
+         strncpy(bufptr, var->value->value, bufend - bufptr);
+         bufptr += strlen(var->value->value);
+       }
+       else
+       {
+         fprintf(stderr, "ppdc: Undefined variable (%s) on line %d of %s.\n",
+                 name, fp->line, fp->filename);
+         snprintf(bufptr, bufend - bufptr + 1, "$%s", name);
+         bufptr += strlen(name) + 1;
+       }
+      }
+    }
+    else if (ch == '/' && !quote)
+    {
+      // Possibly a comment...
+      nextch = fp->peek();
+
+      if (nextch == '*')
+      {
+        // C comment...
+       fp->get();
+       ch = fp->get();
+       while ((nextch = fp->get()) != EOF)
+       {
+         if (ch == '*' && nextch == '/')
+           break;
+
+         ch = nextch;
+       }
+
+        if (nextch == EOF)
+          break;
+      }
+      else if (nextch == '/')
+      {
+        // C++ comment...
+        while ((nextch = fp->get()) != EOF)
+          if (nextch == '\n')
+           break;
+
+        if (nextch == EOF)
+          break;
+      }
+      else
+      {
+        // Not a comment...
+        empty = 0;
+
+       if (bufptr < bufend)
+         *bufptr++ = ch;
+      }
+    }
+    else if (ch == '\'' || ch == '\"')
+    {
+      empty = 0;
+
+      if (quote == ch)
+      {
+        // Ending the current quoted string...
+        quote = 0;
+      }
+      else if (quote)
+      {
+        // Insert the opposing quote char...
+       if (bufptr < bufend)
+          *bufptr++ = ch;
+      }
+      else
+      {
+        // Start a new quoted string...
+        startline = fp->line;
+        quote     = ch;
+      }
+    }
+    else if ((ch == '(' || ch == '<') && !quote)
+    {
+      empty     = 0;
+      quote     = ch;
+      startline = fp->line;
+
+      if (bufptr < bufend)
+       *bufptr++ = ch;
+    }
+    else if ((ch == ')' && quote == '(') || (ch == '>' && quote == '<'))
+    {
+      quote = 0;
+
+      if (bufptr < bufend)
+       *bufptr++ = ch;
+    }
+    else if (ch == '\\')
+    {
+      empty = 0;
+
+      if ((ch = fp->get()) == EOF)
+        break;
+
+      if (bufptr < bufend)
+        *bufptr++ = ch;
+    }
+    else if (bufptr < bufend)
+    {
+      empty = 0;
+
+      *bufptr++ = ch;
+
+      if ((ch == '{' || ch == '}') && !quote)
+        break;
+    }
+  }
+
+  if (quote)
+  {
+    fprintf(stderr, "ppdc: Unterminated string starting with %c on line %d of %s!\n",
+            quote, startline, fp->filename);
+    return (NULL);
+  }
+
+  if (empty)
+    return (NULL);
+  else
+  {
+    *bufptr = '\0';
+//    puts(buffer);
+    return (buffer);
+  }
+}
+
+
+//
+// 'ppdcSource::get_variable()' - Get a variable definition.
+//
+
+ppdcVariable *                         // O - Variable
+ppdcSource::get_variable(ppdcFile *fp) // I - File to read
+{
+  char         name[1024],             // Name
+               value[1024];            // Value
+
+
+  // Get the name and value:
+  //
+  // #define name value
+  if (!get_token(fp, name, sizeof(name)))
+    return (NULL);
+
+  if (!get_token(fp, value, sizeof(value)))
+    return (NULL);
+
+  // Set the variable...
+  return (set_variable(name, value));
+}
+
+
+//
+// 'ppdcSource::quotef()' - Write a formatted, quoted string...
+//
+
+int                                    // O - Number bytes on success, -1 on failure
+ppdcSource::quotef(cups_file_t *fp,    // I - File to write to
+                   const char  *format,        // I - Printf-style format string
+                  ...)                 // I - Additional args as needed
+{
+  va_list      ap;                     // Pointer to additional arguments
+  int          bytes;                  // Bytes written
+  char         sign,                   // Sign of format width
+               size,                   // Size character (h, l, L)
+               type;                   // Format type character
+  const char   *bufformat;             // Start of format
+  int          width,                  // Width of field
+               prec;                   // Number of characters of precision
+  char         tformat[100];           // Temporary format string for fprintf()
+  char         *s;                     // Pointer to string
+  int          slen;                   // Length of string
+  int          i;                      // Looping var
+
+
+  // Range check input...
+  if (!fp || !format)
+    return (-1);
+
+  // Loop through the format string, formatting as needed...
+  va_start(ap, format);
+
+  bytes = 0;
+
+  while (*format)
+  {
+    if (*format == '%')
+    {
+      bufformat = format;
+      format ++;
+
+      if (*format == '%')
+      {
+        cupsFilePutChar(fp, *format++);
+       bytes ++;
+       continue;
+      }
+      else if (strchr(" -+#\'", *format))
+        sign = *format++;
+      else
+        sign = 0;
+
+      width = 0;
+      while (isdigit(*format))
+        width = width * 10 + *format++ - '0';
+
+      if (*format == '.')
+      {
+        format ++;
+       prec = 0;
+
+       while (isdigit(*format))
+          prec = prec * 10 + *format++ - '0';
+      }
+      else
+        prec = -1;
+
+      if (*format == 'l' && format[1] == 'l')
+      {
+        size = 'L';
+       format += 2;
+      }
+      else if (*format == 'h' || *format == 'l' || *format == 'L')
+        size = *format++;
+
+      if (!*format)
+        break;
+
+      type = *format++;
+
+      switch (type)
+      {
+       case 'E' : // Floating point formats
+       case 'G' :
+       case 'e' :
+       case 'f' :
+       case 'g' :
+           if ((format - bufformat + 1) > (int)sizeof(tformat))
+             break;
+
+           strncpy(tformat, bufformat, format - bufformat);
+           tformat[format - bufformat] = '\0';
+
+           bytes += cupsFilePrintf(fp, tformat, va_arg(ap, double));
+           break;
+
+        case 'B' : // Integer formats
+       case 'X' :
+       case 'b' :
+        case 'd' :
+       case 'i' :
+       case 'o' :
+       case 'u' :
+       case 'x' :
+           if ((format - bufformat + 1) > (int)sizeof(tformat))
+             break;
+
+           strncpy(tformat, bufformat, format - bufformat);
+           tformat[format - bufformat] = '\0';
+
+           bytes += cupsFilePrintf(fp, tformat, va_arg(ap, int));
+           break;
+           
+       case 'p' : // Pointer value
+           if ((format - bufformat + 1) > (int)sizeof(tformat))
+             break;
+
+           strncpy(tformat, bufformat, format - bufformat);
+           tformat[format - bufformat] = '\0';
+
+           bytes += cupsFilePrintf(fp, tformat, va_arg(ap, void *));
+           break;
+
+        case 'c' : // Character or character array
+           if (width <= 1)
+           {
+             bytes ++;
+             cupsFilePutChar(fp, va_arg(ap, int));
+           }
+           else
+           {
+             cupsFileWrite(fp, va_arg(ap, char *), width);
+             bytes += width;
+           }
+           break;
+
+       case 's' : // String
+           if ((s = va_arg(ap, char *)) == NULL)
+             s = (char *)"(nil)";
+
+           slen = strlen(s);
+           if (slen > width && prec != width)
+             width = slen;
+
+            if (slen > width)
+             slen = width;
+
+            if (sign != '-')
+           {
+             for (i = width - slen; i > 0; i --, bytes ++)
+               cupsFilePutChar(fp, ' ');
+           }
+
+            for (i = slen; i > 0; i --, s ++, bytes ++)
+           {
+             if (*s == '\\' || *s == '\"')
+             {
+               cupsFilePutChar(fp, '\\');
+               bytes ++;
+             }
+
+             cupsFilePutChar(fp, *s);
+           }
+
+            if (sign == '-')
+           {
+             for (i = width - slen; i > 0; i --, bytes ++)
+               cupsFilePutChar(fp, ' ');
+           }
+           break;
+      }
+    }
+    else
+    {
+      cupsFilePutChar(fp, *format++);
+      bytes ++;
+    }
+  }
+
+  va_end(ap);
+
+  // Return the number of characters written.
+  return (bytes);
+}
+
+
+//
+// 'ppdcSource::read_file()' - Read a driver source file.
+//
+
+void
+ppdcSource::read_file(const char *f)   // I - File to read
+{
+  ppdcFile *fp = new ppdcFile(f);
+  scan_file(fp);
+  delete fp;
+}
+
+
+//
+// 'ppdcSource::scan_file()' - Scan a driver source file.
+//
+
+void
+ppdcSource::scan_file(ppdcFile   *fp,  // I - File to read
+                      ppdcDriver *td,  // I - Driver template
+                     bool       inc)   // I - Including?
+{
+  ppdcDriver   *d;                     // Current driver
+  ppdcGroup    *g,                     // Current group
+               *general,               // General options group
+               *install;               // Installable options group
+  ppdcOption   *o;                     // Current option
+  ppdcChoice   *c;                     // Current choice
+  char         temp[256],              // Token from file...
+               *ptr;                   // Pointer into token
+  int          isdefault;              // Default option?
+
+
+  // Initialize things as needed...
+  if (inc && td)
+    d = td;
+  else
+    d = new ppdcDriver(td);
+
+  if ((general = d->find_group("General")) == NULL)
+  {
+    general = new ppdcGroup("General", NULL);
+    d->add_group(general);
+  }
+
+  if ((install = d->find_group("InstallableOptions")) == NULL)
+  {
+    install = new ppdcGroup("InstallableOptions", "Installable Options");
+    d->add_group(install);
+  }
+
+  // Loop until EOF or }
+  o = 0;
+  g = general;
+  while (get_token(fp, temp, sizeof(temp)))
+  {
+    if (temp[0] == '*')
+    {
+      // Mark the next choice as the default
+      isdefault = 1;
+
+      for (ptr = temp; ptr[1]; ptr ++)
+        *ptr = ptr[1];
+
+      *ptr = '\0';
+    }
+    else
+    {
+      // Don't mark the next choice as the default
+      isdefault = 0;
+    }
+
+    if (!strcasecmp(temp, "}"))
+    {
+      // Close this one out...
+      break;
+    }
+    else if (!strcasecmp(temp, "{"))
+    {
+      // Open a new child...
+      scan_file(fp, d);
+    }
+    else if (!strcasecmp(temp, "#define"))
+    {
+      // Get the variable...
+      get_variable(fp);
+    }
+    else if (!strcasecmp(temp, "#include"))
+    {
+      // #include filename
+      char     basedir[1024],          // Base directory
+               *baseptr,               // Pointer into directory
+               inctemp[1024],          // Initial filename
+               incname[1024];          // Include filename
+      ppdcFile *incfile;               // Include file
+
+
+      // Get the include name...
+      if (!get_token(fp, inctemp, sizeof(inctemp)))
+      {
+        fprintf(stderr, "ppdc: Expected include filename on line %d of %s!\n",
+               fp->line, fp->filename);
+        break;
+      }
+
+      // Figure out the current directory...
+      strlcpy(basedir, fp->filename, sizeof(basedir));
+
+      if ((baseptr = strrchr(basedir, '/')) != NULL)
+        *baseptr = '\0';
+      else
+        strcpy(basedir, ".");
+
+      // Find the include file...
+      if (find_include(inctemp, basedir, incname, sizeof(incname)))
+      {
+       // Open the include file, scan it, and then close it...
+       incfile = new ppdcFile(incname);
+       scan_file(incfile, d, true);
+       delete incfile;
+      }
+      else
+      {
+        // Can't find it!
+       fprintf(stderr,
+               "ppdc: Unable to find include file \"%s\" on line %d of %s!\n",
+               inctemp, fp->line, fp->filename);
+       break;
+      }
+    }
+    else if (!strcasecmp(temp, "#media"))
+    {
+      ppdcMediaSize    *m;             // Media size
+
+
+      // Get a media size...
+      m = get_size(fp);
+      if (m)
+        sizes->add(m);
+    }
+    else if (!strcasecmp(temp, "#po"))
+    {
+      ppdcCatalog      *cat;           // Message catalog
+
+
+      // Get a message catalog...
+      cat = get_po(fp);
+      if (cat)
+        po_files->add(cat);
+    }
+    else if (!strcasecmp(temp, "Attribute"))
+    {
+      ppdcAttr *a;                     // Attribute
+
+
+      // Get an attribute...
+      a = get_attr(fp);
+      if (a)
+        d->add_attr(a);
+    }
+    else if (!strcasecmp(temp, "Choice"))
+    {
+      // Get a choice...
+      if (!o)
+      {
+        fprintf(stderr, "ppdc: Choice found on line %d of %s with no Option!\n",
+               fp->line, fp->filename);
+        break;
+      }
+
+      c = get_choice(fp);
+      if (!c)
+        break;
+
+      // Add it to the current option...
+      o->add_choice(c);
+
+      if (isdefault)
+        o->set_defchoice(c);
+    }
+    else if (!strcasecmp(temp, "ColorDevice"))
+    {
+      // ColorDevice boolean
+      d->color_device = get_boolean(fp);
+    }
+    else if (!strcasecmp(temp, "ColorModel"))
+    {
+      // Get the color model
+      c = get_color_model(fp);
+      if (!c)
+        continue;
+
+      // Add the choice to the ColorModel option...
+      if ((o = d->find_option("ColorModel")) == NULL)
+      {
+       // Create the ColorModel option...
+       o = new ppdcOption(PPDC_PICKONE, "ColorModel", "Color Mode", PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "ColorProfile"))
+    {
+      ppdcProfile      *p;             // Color profile
+
+
+      // Get the color profile...
+      p = get_color_profile(fp);
+
+      if (p)
+        d->profiles->add(p);
+    }
+    else if (!strcasecmp(temp, "Copyright"))
+    {
+      // Copyright string
+      char     copytemp[8192],         // Copyright string
+               *copyptr,               // Pointer into string
+               *copyend;               // Pointer to end of string
+
+
+      // Get the copyright string...
+      if (!get_token(fp, copytemp, sizeof(temp)))
+      {
+        fprintf(stderr,
+               "ppdc: Expected string after Copyright on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      // Break it up into individual lines...
+      for (copyptr = copytemp; copyptr; copyptr = copyend)
+      {
+        if ((copyend = strchr(copyptr, '\n')) != NULL)
+         *copyend++ = '\0';
+
+        d->copyright->add(new ppdcString(copyptr));
+      }
+    }
+    else if (!strcasecmp(temp, "CustomMedia"))
+    {
+      ppdcMediaSize    *m;             // Media size
+
+
+      // Get a custom media size...
+      m = get_custom_size(fp);
+      if (m)
+        d->sizes->add(m);
+
+      if (isdefault)
+        d->set_default_size(m);
+    }
+    else if (!strcasecmp(temp, "Cutter"))
+    {
+      // Cutter boolean
+      int      have_cutter;            // Have a paper cutter?
+
+
+      have_cutter = get_boolean(fp);
+      if (have_cutter <= 0)
+        continue;
+
+      if ((o = d->find_option("CutMedia")) == NULL)
+      {
+        o = new ppdcOption(PPDC_BOOLEAN, "CutMedia", "Cut Media", PPDC_SECTION_ANY, 10.0f);
+
+       g = general;
+       g->add_option(o);
+
+       c = new ppdcChoice("False", NULL, "<</CutMedia 0>>setpagedevice");
+       o->add_choice(c);
+       o->set_defchoice(c);
+
+       c = new ppdcChoice("True", NULL, "<</CutMedia 4>>setpagedevice");
+       o->add_choice(c);
+      }
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "Darkness"))
+    {
+      // Get the darkness choice...
+      c = get_generic(fp, "Darkness", NULL, "cupsCompression");
+      if (!c)
+        continue;
+
+      // Add the choice to the cupsDarkness option...
+      if ((o = d->find_option("cupsDarkness")) == NULL)
+      {
+       // Create the cupsDarkness option...
+       o = new ppdcOption(PPDC_PICKONE, "cupsDarkness", "Darkness", PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "DriverType"))
+    {
+      int      i;                      // Looping var
+
+
+      // DriverType keyword
+      if (!get_token(fp, temp, sizeof(temp)))
+      {
+        fprintf(stderr, "ppdc: Expected driver type keyword following DriverType on line %d of %s!\n",
+               fp->line, fp->filename);
+        continue;
+      }
+
+      for (i = 0; i < (int)(sizeof(driver_types) / sizeof(driver_types[0])); i ++)
+        if (!strcasecmp(temp, driver_types[i]))
+         break;
+
+      if (i < (int)(sizeof(driver_types) / sizeof(driver_types[0])))
+        d->type = (ppdcDrvType)i;
+      else if (!strcasecmp(temp, "dymo"))
+        d->type = PPDC_DRIVER_LABEL;
+      else
+        fprintf(stderr, "ppdc: Unknown driver type %s on line %d of %s!\n",
+               temp, fp->line, fp->filename);
+    }
+    else if (!strcasecmp(temp, "Duplex"))
+      get_duplex(fp, d);
+    else if (!strcasecmp(temp, "Filter"))
+    {
+      ppdcFilter       *f;             // Filter
+
+
+      // Get the filter value...
+      f = get_filter(fp);
+      if (f)
+        d->filters->add(f);
+    }
+    else if (!strcasecmp(temp, "Finishing"))
+    {
+      // Get the finishing choice...
+      c = get_generic(fp, "Finishing", "OutputType", NULL);
+      if (!c)
+        continue;
+
+      // Add the choice to the cupsFinishing option...
+      if ((o = d->find_option("cupsFinishing")) == NULL)
+      {
+       // Create the cupsFinishing option...
+       o = new ppdcOption(PPDC_PICKONE, "cupsFinishing", "Finishing", PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "Font") ||
+             !strcasecmp(temp, "#font"))
+    {
+      ppdcFont *f;                     // Font
+
+
+      // Get a font...
+      f = get_font(fp);
+      if (f)
+      {
+       if (!strcasecmp(temp, "#font"))
+         base_fonts->add(f);
+        else
+         d->add_font(f);
+
+        if (isdefault)
+          d->set_default_font(f);
+      }
+    }
+    else if (!strcasecmp(temp, "Group"))
+    {
+      // Get a group...
+      g = get_group(fp, d);
+      if (!g)
+        break;
+    }
+    else if (!strcasecmp(temp, "HWMargins"))
+    {
+      // HWMargins left bottom right top
+      d->left_margin   = get_measurement(fp);
+      d->bottom_margin = get_measurement(fp);
+      d->right_margin  = get_measurement(fp);
+      d->top_margin    = get_measurement(fp);
+    }
+    else if (!strcasecmp(temp, "InputSlot"))
+    {
+      // Get the input slot choice...
+      c = get_generic(fp, "InputSlot", NULL, "MediaPosition");
+      if (!c)
+        continue;
+
+      // Add the choice to the InputSlot option...
+      if ((o = d->find_option("InputSlot")) == NULL)
+      {
+       // Create the InputSlot option...
+       o = new ppdcOption(PPDC_PICKONE, "InputSlot", "Media Source",
+                          PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "Installable"))
+    {
+      // Get the installable option...
+      o = get_installable(fp);
+
+      // Add it as needed...
+      if (o)
+      {
+        install->add_option(o);
+        o = NULL;
+      }
+    }
+    else if (!strcasecmp(temp, "ManualCopies"))
+    {
+      // ManualCopies boolean
+      d->manual_copies = get_boolean(fp);
+    }
+    else if (!strcasecmp(temp, "Manufacturer"))
+    {
+      // Manufacturer name
+      char     name[256];              // Model name string
+
+
+      if (!get_token(fp, name, sizeof(name)))
+      {
+        fprintf(stderr, "ppdc: Expected name after Manufacturer on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      d->set_manufacturer(name);
+    }
+    else if (!strcasecmp(temp, "MaxSize"))
+    {
+      // MaxSize width length
+      d->max_width  = get_measurement(fp);
+      d->max_length = get_measurement(fp);
+    }
+    else if (!strcasecmp(temp, "MediaSize"))
+    {
+      // MediaSize keyword
+      char             name[41];       // Media size name
+      ppdcMediaSize    *m,             // Matching media size...
+                       *dm;            // Driver media size...
+
+
+      if (get_token(fp, name, sizeof(name)) == NULL)
+      {
+        fprintf(stderr, "ppdc: Expected name after MediaSize on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      m = find_size(name);
+
+      if (!m)
+      {
+        fprintf(stderr, "ppdc: Unknown media size \"%s\" on line %d of %s!\n",
+               name, fp->line, fp->filename);
+       break;
+      }
+
+      // Add this size to the driver...
+      dm = new ppdcMediaSize(m->name->value, m->text->value,
+                             m->width, m->length, d->left_margin,
+                            d->bottom_margin, d->right_margin,
+                            d->top_margin);
+      d->sizes->add(dm);
+
+      if (isdefault)
+        d->set_default_size(dm);
+    }
+    else if (!strcasecmp(temp, "MediaType"))
+    {
+      // Get the media type choice...
+      c = get_generic(fp, "MediaType", "MediaType", "cupsMediaType");
+      if (!c)
+        continue;
+
+      // Add the choice to the MediaType option...
+      if ((o = d->find_option("MediaType")) == NULL)
+      {
+       // Create the MediaType option...
+       o = new ppdcOption(PPDC_PICKONE, "MediaType", "Media Type",
+                          PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "MinSize"))
+    {
+      // MinSize width length
+      d->min_width  = get_measurement(fp);
+      d->min_length = get_measurement(fp);
+    }
+    else if (!strcasecmp(temp, "ModelName"))
+    {
+      // ModelName name
+      char     name[256];              // Model name string
+
+
+      if (!get_token(fp, name, sizeof(name)))
+      {
+        fprintf(stderr, "ppdc: Expected name after ModelName on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      d->set_model_name(name);
+    }
+    else if (!strcasecmp(temp, "ModelNumber"))
+    {
+      // ModelNumber number
+      d->model_number = get_integer(fp);
+    }
+    else if (!strcasecmp(temp, "Option"))
+    {
+      // Get an option...
+      o = get_option(fp, d, g);
+      if (!o)
+        break;
+    }
+    else if (!strcasecmp(temp, "PCFileName"))
+    {
+      // PCFileName name
+      char     name[256];              // Model name string
+
+
+      if (!get_token(fp, name, sizeof(name)))
+      {
+        fprintf(stderr, "ppdc: Expected name after PCFileName on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      d->set_pc_file_name(name);
+    }
+    else if (!strcasecmp(temp, "Resolution"))
+    {
+      // Get the resolution choice...
+      c = get_resolution(fp);
+      if (!c)
+        continue;
+
+      // Add the choice to the Resolution option...
+      if ((o = d->find_option("Resolution")) == NULL)
+      {
+       // Create the Resolution option...
+       o = new ppdcOption(PPDC_PICKONE, "Resolution", NULL, PPDC_SECTION_ANY, 10.0f);
+       g = general;
+       g->add_option(o);
+      }
+
+      o->add_choice(c);
+
+      if (isdefault)
+       o->set_defchoice(c);
+
+      o = NULL;
+    }
+    else if (!strcasecmp(temp, "SimpleColorProfile"))
+    {
+      ppdcProfile      *p;             // Color profile
+
+
+      // Get the color profile...
+      p = get_simple_profile(fp);
+
+      if (p)
+        d->profiles->add(p);
+    }
+    else if (!strcasecmp(temp, "Throughput"))
+    {
+      // Throughput number
+      d->throughput = get_integer(fp);
+    }
+    else if (!strcasecmp(temp, "UIConstraints"))
+    {
+      ppdcConstraint   *con;           // Constraint
+
+
+      con = get_constraint(fp);
+
+      if (con)
+        d->constraints->add(con);
+    }
+    else if (!strcasecmp(temp, "VariablePaperSize"))
+    {
+      // VariablePaperSize boolean
+      d->variable_paper_size = get_boolean(fp);
+    }
+    else if (!strcasecmp(temp, "Version"))
+    {
+      // Version string
+      char     name[256];              // Model name string
+
+
+      if (!get_token(fp, name, sizeof(name)))
+      {
+        fprintf(stderr, "ppdc: Expected string after Version on line %d of %s!\n",
+               fp->line, fp->filename);
+       break;
+      }
+
+      d->set_version(name);
+    }
+    else
+    {
+      fprintf(stderr, "ppdc: Unknown token \"%s\" seen on line %d of %s!\n",
+              temp, fp->line, fp->filename);
+      break;
+    }
+  }
+
+  // Done processing this block, is there anything to save?
+  if (!inc)
+  {
+    if (!d->pc_file_name || !d->model_name || !d->manufacturer || !d->version ||
+       !d->sizes->count)
+    {
+      // Nothing to save...
+      d->release();
+    }
+    else
+    {
+      // Got a driver, save it...
+      drivers->add(d);
+    }
+  }
+}
+
+
+//
+// 'ppdcSource::set_variable()' - Set a variable.
+//
+
+ppdcVariable *                         // O - Variable
+ppdcSource::set_variable(
+    const char *name,                  // I - Name
+    const char *value)                 // I - Value
+{
+  ppdcVariable *v;                     // Variable
+
+
+  // See if the variable exists already...
+  v = find_variable(name);
+  if (v)
+  {
+    // Change the variable value...
+    v->set_value(value);
+  }
+  else
+  {
+    // Create a new variable and add it...
+    v = new ppdcVariable(name, value);
+    vars->add(v);
+  }
+
+  return (v);
+}
+
+
+//
+// 'ppdcSource::write_file()' - Write the current source data to a file.
+//
+
+int                                    // O - 0 on success, -1 on error
+ppdcSource::write_file(const char *f)  // I - File to write
+{
+  cups_file_t  *fp;                    // Output file
+  char         bckname[1024];          // Backup file
+  ppdcDriver   *d;                     // Current driver
+  ppdcString   *st;                    // Current string
+  ppdcAttr     *a;                     // Current attribute
+  ppdcConstraint *co;                  // Current constraint
+  ppdcFilter   *fi;                    // Current filter
+  ppdcFont     *fo;                    // Current font
+  ppdcGroup    *g;                     // Current group
+  ppdcOption   *o;                     // Current option
+  ppdcChoice   *ch;                    // Current choice
+  ppdcProfile  *p;                     // Current color profile
+  ppdcMediaSize        *si;                    // Current media size
+  float                left,                   // Current left margin
+               bottom,                 // Current bottom margin
+               right,                  // Current right margin
+               top;                    // Current top margin
+  int          dtused[PPDC_DRIVER_MAX];// Driver type usage...
+
+
+  // Rename the current file, if any, to .bck...
+  snprintf(bckname, sizeof(bckname), "%s.bck", f);
+  rename(f, bckname);
+
+  // Open the output file...
+  fp = cupsFileOpen(f, "w");
+
+  if (!fp)
+  {
+    // Can't create file; restore backup and return...
+    rename(bckname, f);
+    return (-1);
+  }
+
+  cupsFilePuts(fp, "// CUPS PPD Compiler " CUPS_SVERSION "\n\n");
+
+  // Include standard files...
+  cupsFilePuts(fp, "// Include necessary files...\n");
+  cupsFilePuts(fp, "#include <font.defs>\n");
+  cupsFilePuts(fp, "#include <media.defs>\n");
+
+  memset(dtused, 0, sizeof(dtused));
+
+  for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next())
+    if (d->type > PPDC_DRIVER_PS && !dtused[d->type])
+    {
+      cupsFilePrintf(fp, "#include <%s.h>\n", driver_types[d->type]);
+      dtused[d->type] = 1;
+    }
+
+  // Output each driver...
+  for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next())
+  {
+    // Start the driver...
+    cupsFilePrintf(fp, "\n// %s %s\n", d->manufacturer->value, d->model_name->value);
+    cupsFilePuts(fp, "{\n");
+
+    // Write the copyright stings...
+    for (st = (ppdcString *)d->copyright->first();
+         st;
+        st = (ppdcString *)d->copyright->next())
+      quotef(fp, "  Copyright \"%s\"\n", st->value);
+
+    // Write other strings and values...
+    if (d->manufacturer->value)
+      quotef(fp, "  Manufacturer \"%s\"\n", d->manufacturer->value);
+    if (d->model_name->value)
+      quotef(fp, "  ModelName \"%s\"\n", d->model_name->value);
+    if (d->pc_file_name->value)
+      quotef(fp, "  PCFileName \"%s\"\n", d->pc_file_name->value);
+    if (d->version->value)
+      quotef(fp, "  Version \"%s\"\n", d->version->value);
+
+    cupsFilePrintf(fp, "  DriverType %s\n", driver_types[d->type]);
+
+    if (d->model_number)
+    {
+      switch (d->type)
+      {
+        case PPDC_DRIVER_ESCP :
+           cupsFilePuts(fp, "  ModelNumber (");
+
+           if (d->model_number & ESCP_DOTMATRIX)
+             cupsFilePuts(fp, " $ESCP_DOTMATRIX");
+           if (d->model_number & ESCP_MICROWEAVE)
+             cupsFilePuts(fp, " $ESCP_MICROWEAVE");
+           if (d->model_number & ESCP_STAGGER)
+             cupsFilePuts(fp, " $ESCP_STAGGER");
+           if (d->model_number & ESCP_ESCK)
+             cupsFilePuts(fp, " $ESCP_ESCK");
+           if (d->model_number & ESCP_EXT_UNITS)
+             cupsFilePuts(fp, " $ESCP_EXT_UNITS");
+           if (d->model_number & ESCP_EXT_MARGINS)
+             cupsFilePuts(fp, " $ESCP_EXT_MARGINS");
+           if (d->model_number & ESCP_USB)
+             cupsFilePuts(fp, " $ESCP_USB");
+           if (d->model_number & ESCP_PAGE_SIZE)
+             cupsFilePuts(fp, " $ESCP_PAGE_SIZE");
+           if (d->model_number & ESCP_RASTER_ESCI)
+             cupsFilePuts(fp, " $ESCP_RASTER_ESCI");
+           if (d->model_number & ESCP_REMOTE)
+             cupsFilePuts(fp, " $ESCP_REMOTE");
+
+           cupsFilePuts(fp, ")\n");
+           break;
+
+       case PPDC_DRIVER_PCL :
+           cupsFilePuts(fp, "  ModelNumber (");
+
+           if (d->model_number & PCL_PAPER_SIZE)
+             cupsFilePuts(fp, " $PCL_PAPER_SIZE");
+           if (d->model_number & PCL_INKJET)
+             cupsFilePuts(fp, " $PCL_INKJET");
+           if (d->model_number & PCL_RASTER_END_COLOR)
+             cupsFilePuts(fp, " $PCL_RASTER_END_COLOR");
+           if (d->model_number & PCL_RASTER_CID)
+             cupsFilePuts(fp, " $PCL_RASTER_CID");
+           if (d->model_number & PCL_RASTER_CRD)
+             cupsFilePuts(fp, " $PCL_RASTER_CRD");
+           if (d->model_number & PCL_RASTER_SIMPLE)
+             cupsFilePuts(fp, " $PCL_RASTER_SIMPLE");
+           if (d->model_number & PCL_RASTER_RGB24)
+             cupsFilePuts(fp, " $PCL_RASTER_RGB24");
+           if (d->model_number & PCL_PJL)
+             cupsFilePuts(fp, " $PCL_PJL");
+           if (d->model_number & PCL_PJL_PAPERWIDTH)
+             cupsFilePuts(fp, " $PCL_PJL_PAPERWIDTH");
+           if (d->model_number & PCL_PJL_HPGL2)
+             cupsFilePuts(fp, " $PCL_PJL_HPGL2");
+           if (d->model_number & PCL_PJL_PCL3GUI)
+             cupsFilePuts(fp, " $PCL_PJL_PCL3GUI");
+           if (d->model_number & PCL_PJL_RESOLUTION)
+             cupsFilePuts(fp, " $PCL_PJL_RESOLUTION");
+
+           cupsFilePuts(fp, ")\n");
+           break;
+
+       case PPDC_DRIVER_LABEL :
+           cupsFilePuts(fp, "  ModelNumber ");
+
+           switch (d->model_number)
+           {
+             case DYMO_3x0 :
+                 cupsFilePuts(fp, "$DYMO_3x0\n");
+                 break;
+
+             case ZEBRA_EPL_LINE :
+                 cupsFilePuts(fp, "$ZEBRA_EPL_LINE\n");
+                 break;
+
+             case ZEBRA_EPL_PAGE :
+                 cupsFilePuts(fp, "$ZEBRA_EPL_PAGE\n");
+                 break;
+
+             case ZEBRA_ZPL :
+                 cupsFilePuts(fp, "$ZEBRA_ZPL\n");
+                 break;
+
+             case ZEBRA_CPCL :
+                 cupsFilePuts(fp, "$ZEBRA_CPCL\n");
+                 break;
+
+             case INTELLITECH_PCL :
+                 cupsFilePuts(fp, "$INTELLITECH_PCL\n");
+                 break;
+
+             default :
+                 cupsFilePrintf(fp, "%d\n", d->model_number);
+                 break;
+           }
+           break;
+
+       case PPDC_DRIVER_EPSON :
+           cupsFilePuts(fp, "  ModelNumber ");
+
+           switch (d->model_number)
+           {
+             case EPSON_9PIN :
+                 cupsFilePuts(fp, "$EPSON_9PIN\n");
+                 break;
+
+             case EPSON_24PIN :
+                 cupsFilePuts(fp, "$EPSON_24PIN\n");
+                 break;
+
+             case EPSON_COLOR :
+                 cupsFilePuts(fp, "$EPSON_COLOR\n");
+                 break;
+
+             case EPSON_PHOTO :
+                 cupsFilePuts(fp, "$EPSON_PHOTO\n");
+                 break;
+
+             case EPSON_ICOLOR :
+                 cupsFilePuts(fp, "$EPSON_ICOLOR\n");
+                 break;
+
+             case EPSON_IPHOTO :
+                 cupsFilePuts(fp, "$EPSON_IPHOTO\n");
+                 break;
+
+             default :
+                 cupsFilePrintf(fp, "%d\n", d->model_number);
+                 break;
+           }
+           break;
+
+       case PPDC_DRIVER_HP :
+           cupsFilePuts(fp, "  ModelNumber ");
+           switch (d->model_number)
+           {
+             case HP_LASERJET :
+                 cupsFilePuts(fp, "$HP_LASERJET\n");
+                 break;
+
+             case HP_DESKJET :
+                 cupsFilePuts(fp, "$HP_DESKJET\n");
+                 break;
+
+             case HP_DESKJET2 :
+                 cupsFilePuts(fp, "$HP_DESKJET2\n");
+                 break;
+
+             default :
+                 cupsFilePrintf(fp, "%d\n", d->model_number);
+                 break;
+           }
+
+           cupsFilePuts(fp, ")\n");
+           break;
+
+        default :
+            cupsFilePrintf(fp, "  ModelNumber %d\n", d->model_number);
+           break;
+      }
+    }
+
+    if (d->manual_copies)
+      cupsFilePuts(fp, "  ManualCopies Yes\n");
+
+    if (d->color_device)
+      cupsFilePuts(fp, "  ColorDevice Yes\n");
+
+    if (d->throughput)
+      cupsFilePrintf(fp, "  Throughput %d\n", d->throughput);
+
+    // Output all of the attributes...
+    for (a = (ppdcAttr *)d->attrs->first();
+         a;
+        a = (ppdcAttr *)d->attrs->next())
+      if (a->text->value && a->text->value[0])
+       quotef(fp, "  Attribute \"%s\" \"%s/%s\" \"%s\"\n",
+               a->name->value, a->selector->value ? a->selector->value : "",
+              a->text->value, a->value->value ? a->value->value : "");
+      else
+       quotef(fp, "  Attribute \"%s\" \"%s\" \"%s\"\n",
+               a->name->value, a->selector->value ? a->selector->value : "",
+              a->value->value ? a->value->value : "");
+
+    // Output all of the constraints...
+    for (co = (ppdcConstraint *)d->constraints->first();
+         co;
+        co = (ppdcConstraint *)d->constraints->next())
+    {
+      if (co->option1->value[0] == '*')
+       cupsFilePrintf(fp, "  UIConstraints \"%s %s", co->option1->value,
+                      co->choice1->value ? co->choice1->value : "");
+      else
+       cupsFilePrintf(fp, "  UIConstraints \"*%s %s", co->option1->value,
+                      co->choice1->value ? co->choice1->value : "");
+
+      if (co->option2->value[0] == '*')
+       cupsFilePrintf(fp, " %s %s\"\n", co->option2->value,
+                      co->choice2->value ? co->choice2->value : "");
+      else
+       cupsFilePrintf(fp, " *%s %s\"\n", co->option2->value,
+                      co->choice2->value ? co->choice2->value : "");
+    }
+
+    // Output all of the filters...
+    for (fi = (ppdcFilter *)d->filters->first();
+         fi;
+        fi = (ppdcFilter *)d->filters->next())
+      cupsFilePrintf(fp, "  Filter \"%s %d %s\"\n",
+                     fi->mime_type->value, fi->cost, fi->program->value);
+
+    // Output all of the fonts...
+    for (fo = (ppdcFont *)d->fonts->first();
+         fo;
+        fo = (ppdcFont *)d->fonts->next())
+      if (!strcmp(fo->name->value, "*"))
+        cupsFilePuts(fp, "  Font *\n");
+      else
+       cupsFilePrintf(fp, "  Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
+                      fo->name->value, fo->encoding->value,
+                      fo->version->value, fo->charset->value,
+                      fo->status == PPDC_FONT_ROM ? "ROM" : "Disk");
+
+    // Output all options...
+    for (g = (ppdcGroup *)d->groups->first();
+         g;
+        g = (ppdcGroup *)d->groups->next())
+    {
+      if (g->options->count == 0)
+        continue;
+
+      if (g->text->value && g->text->value[0])
+        quotef(fp, "  Group \"%s/%s\"\n", g->name->value, g->text->value);
+      else
+        cupsFilePrintf(fp, "  Group \"%s\"\n", g->name->value);
+
+      for (o = (ppdcOption *)g->options->first();
+           o;
+          o = (ppdcOption *)g->options->next())
+      {
+        if (o->choices->count == 0)
+         continue;
+
+       if (o->text->value && o->text->value[0])
+          quotef(fp, "    Option \"%s/%s\"", o->name->value, o->text->value);
+       else
+          cupsFilePrintf(fp, "    Option \"%s\"", o->name->value);
+
+        cupsFilePrintf(fp, " %s %s %.1f\n",
+                      o->type == PPDC_BOOLEAN ? "Boolean" :
+                          o->type == PPDC_PICKONE ? "PickOne" : "PickMany",
+                      o->section == PPDC_SECTION_ANY ? "AnySetup" :
+                          o->section == PPDC_SECTION_DOCUMENT ? "DocumentSetup" :
+                          o->section == PPDC_SECTION_EXIT ? "ExitServer" :
+                          o->section == PPDC_SECTION_JCL ? "JCLSetup" :
+                          o->section == PPDC_SECTION_PAGE ? "PageSetup" :
+                          "Prolog",
+                      o->order);
+
+        for (ch = (ppdcChoice *)o->choices->first();
+            ch;
+            ch = (ppdcChoice *)o->choices->next())
+       {
+         if (ch->text->value && ch->text->value[0])
+            quotef(fp, "      %sChoice \"%s/%s\" \"%s\"\n",
+                  o->defchoice == ch->name ? "*" : "",
+                   ch->name->value, ch->text->value,
+                  ch->code->value ? ch->code->value : "");
+         else
+            quotef(fp, "      %sChoice \"%s\" \"%s\"\n",
+                  o->defchoice == ch->name ? "*" : "",
+                  ch->name->value,
+                  ch->code->value ? ch->code->value : "");
+       }
+      }
+    }
+
+    // Output all of the color profiles...
+    for (p = (ppdcProfile *)d->profiles->first();
+         p;
+        p = (ppdcProfile *)d->profiles->next())
+      cupsFilePrintf(fp, "  ColorProfile \"%s/%s\" %.3f %.3f "
+                        "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
+                    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]);
+
+    // Output all of the media sizes...
+    left   = 0.0;
+    bottom = 0.0;
+    right  = 0.0;
+    top    = 0.0;
+
+    for (si = (ppdcMediaSize *)d->sizes->first();
+         si;
+        si = (ppdcMediaSize *)d->sizes->next())
+      if (si->size_code->value && si->region_code->value)
+      {
+        // Output a custom media size...
+       quotef(fp, "  %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
+              si->name == d->default_size ? "*" : "", si->name->value,
+              si->text->value, si->width, si->length, si->left, si->bottom,
+              si->right, si->top, si->size_code->value,
+              si->region_code->value);
+      }
+      else
+      {
+        // Output a standard media size...
+       if (fabs(left - si->left) > 0.1 ||
+            fabs(bottom - si->bottom) > 0.1 ||
+            fabs(right - si->right) > 0.1 ||
+            fabs(top - si->top) > 0.1)
+       {
+          cupsFilePrintf(fp, "  HWMargins %.2f %.2f %.2f %.2f\n",
+                        si->left, si->bottom, si->right, si->top);
+
+          left   = si->left;
+         bottom = si->bottom;
+         right  = si->right;
+         top    = si->top;
+       }
+
+       cupsFilePrintf(fp, "  %sMediaSize %s\n",
+                      si->name == d->default_size ? "*" : "",
+                      si->name->value);
+      }
+
+    if (d->variable_paper_size)
+    {
+      cupsFilePuts(fp, "  VariablePaperSize Yes\n");
+
+      if (fabs(left - d->left_margin) > 0.1 ||
+          fabs(bottom - d->bottom_margin) > 0.1 ||
+          fabs(right - d->right_margin) > 0.1 ||
+          fabs(top - d->top_margin) > 0.1)
+      {
+        cupsFilePrintf(fp, "  HWMargins %.2f %.2f %.2f %.2f\n",
+                      d->left_margin, d->bottom_margin, d->right_margin,
+                      d->top_margin);
+      }
+
+      cupsFilePrintf(fp, "  MinSize %.2f %.2f\n", d->min_width, d->min_length);
+      cupsFilePrintf(fp, "  MaxSize %.2f %.2f\n", d->max_width, d->max_length);
+    }
+
+    // End the driver...
+    cupsFilePuts(fp, "}\n");
+  }
+
+  // Close the file and return...
+  cupsFileClose(fp);
+
+  return (0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-string.cxx b/ppdc/ppdc-string.cxx
new file mode 100644 (file)
index 0000000..9b55d58
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// "$Id$"
+//
+//   Shared string class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcString::ppdcString()  - Create a shared string.
+//   ppdcString::~ppdcString() - Destroy a shared string.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcString::ppdcString()' - Create a shared string.
+//
+
+ppdcString::ppdcString(const char *v)  // I - String
+  : ppdcShared()
+{
+  if (v)
+  {
+    value = new char[strlen(v) + 1];
+    strcpy(value, v);
+  }
+  else
+    value = 0;
+}
+
+
+//
+// 'ppdcString::~ppdcString()' - Destroy a shared string.
+//
+
+ppdcString::~ppdcString()
+{
+  if (value)
+    delete[] value;
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-variable.cxx b/ppdc/ppdc-variable.cxx
new file mode 100644 (file)
index 0000000..6cea762
--- /dev/null
@@ -0,0 +1,66 @@
+//
+// "$Id$"
+//
+//   Variable class for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   ppdcVariable::ppdcVariable()  - Create a variable.
+//   ppdcVariable::~ppdcVariable() - Destroy a variable.
+//   ppdcVariable::set_value()     - Set the value of a variable.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+
+
+//
+// 'ppdcVariable::ppdcVariable()' - Create a variable.
+//
+
+ppdcVariable::ppdcVariable(const char *n,      // I - Name of variable
+                           const char *v)      // I - Value of variable
+{
+  name  = new ppdcString(n);
+  value = new ppdcString(v);
+}
+
+
+//
+// 'ppdcVariable::~ppdcVariable()' - Destroy a variable.
+//
+
+ppdcVariable::~ppdcVariable()
+{
+  name->release();
+  value->release();
+}
+
+
+//
+// 'ppdcVariable::set_value()' - Set the value of a variable.
+//
+
+void
+ppdcVariable::set_value(const char *v)
+{
+  value->release();
+  value = new ppdcString(v);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc.cxx b/ppdc/ppdc.cxx
new file mode 100644 (file)
index 0000000..02852ca
--- /dev/null
@@ -0,0 +1,328 @@
+//
+// "$Id$"
+//
+//   PPD file compiler main entry for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2007 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:
+//
+//   main()  - Main entry for the PPD compiler.
+//   usage() - Show usage and exit.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+//
+// Local functions...
+//
+
+static void    usage(void);
+
+
+//
+// 'main()' - Main entry for the PPD compiler.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  int                  i, j;           // Looping vars
+  ppdcCatalog          *catalog;       // Message catalog
+  const char           *outdir;        // Output directory
+  ppdcSource           *src;           // PPD source file data
+  ppdcDriver           *d;             // Current driver
+  cups_file_t          *fp;            // PPD file
+  char                 *opt,           // Current option
+                       *value,         // Value in option
+                       pcfilename[1024],
+                                       // Lowercase pcfilename
+                       filename[1024]; // PPD filename
+  int                  verbose;        // Verbosity
+  ppdcArray            *locales;       // List of locales
+  int                  comp;           // Compress
+  ppdcLineEnding       le;             // Line ending to use
+
+
+  // Scan the command-line...
+  catalog = NULL;
+  outdir  = "ppd";
+  src     = new ppdcSource();
+  verbose = 0;
+  locales = NULL;
+  comp    = 0;
+  le      = PPDC_LFONLY;
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+         case 'c' :                    // Message catalog...
+             i ++;
+              if (i >= argc)
+                usage();
+
+              if (verbose > 1)
+               printf("ppdc: Loading messages from \"%s\"...\n", argv[i]);
+
+              if (!catalog)
+               catalog = new ppdcCatalog("en");
+
+              if (catalog->load_messages(argv[i]))
+             {
+               fprintf(stderr,
+                       "ppdc: Unable to load localization file \"%s\" - %s\n",
+                       argv[i], strerror(errno));
+                return (1);
+             }
+             break;
+
+          case 'd' :                   // Output directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (verbose > 1)
+               printf("ppdc: Writing PPD files to directory \"%s\"...\n",
+                      argv[i]);
+
+             outdir = argv[i];
+             break;
+
+          case 'l' :                   // Language(s)...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (strchr(argv[i], ','))
+             {
+               // Comma-delimited list of languages...
+               char    temp[1024],     // Copy of language list
+                       *start,         // Start of current locale name
+                       *end;           // End of current locale name
+
+
+               locales = new ppdcArray();
+
+               strlcpy(temp, argv[i], sizeof(temp));
+               for (start = temp; *start; start = end)
+               {
+                 if ((end = strchr(start, ',')) != NULL)
+                   *end++ = '\0';
+                 else
+                   end = start + strlen(start);
+
+                  if (end > start)
+                   locales->add(new ppdcString(start));
+               }
+             }
+             else
+             {
+               if (verbose > 1)
+                 printf("ppdc: Loading messages for locale \"%s\"...\n",
+                        argv[i]);
+
+               if (catalog)
+                 delete catalog;
+
+               catalog = new ppdcCatalog(argv[i]);
+
+               if (catalog->messages->count == 0)
+               {
+                 fprintf(stderr,
+                         "ppdc: Unable to find localization for \"%s\" - %s\n",
+                         argv[i], strerror(errno));
+                  return (1);
+               }
+             }
+             break;
+
+          case 'D' :                   // Define variable
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if ((value = strchr(argv[i], '=')) != NULL)
+             {
+               *value++ = '\0';
+
+               src->set_variable(argv[i], value);
+             }
+             else
+               src->set_variable(argv[i], "1");
+              break;
+
+          case 'I' :                   // Include directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (verbose > 1)
+               printf("ppdc: Adding include directory \"%s\"...\n", argv[i]);
+
+             ppdcSource::add_include(argv[i]);
+             break;
+
+          case 'v' :                   // Be verbose...
+             verbose ++;
+             break;
+           
+          case 'z' :                   // Compress files...
+             comp = 1;
+             break;
+
+         case '-' :                    // --option
+             if (!strcmp(opt, "-lf"))
+             {
+               le  = PPDC_LFONLY;
+               opt += strlen(opt) - 1;
+               break;
+             }
+             else if (!strcmp(opt, "-cr"))
+             {
+               le  = PPDC_CRONLY;
+               opt += strlen(opt) - 1;
+               break;
+             }
+             else if (!strcmp(opt, "-crlf"))
+             {
+               le  = PPDC_CRLF;
+               opt += strlen(opt) - 1;
+               break;
+             }
+           
+         default :                     // Unknown
+             usage();
+             break;
+       }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      if (verbose > 1)
+        printf("ppdc: Loading driver information file \"%s\"...\n", argv[i]);
+
+      src->read_file(argv[i]);
+    }
+
+
+  if (src->drivers->count > 0)
+  {
+    // Create the output directory...
+    if (mkdir(outdir, 0777))
+    {
+      if (errno != EEXIST)
+      {
+       fprintf(stderr, "ppdc: Unable to create output directory %s: %s\n",
+               outdir, strerror(errno));
+        return (1);
+      }
+    }
+
+    // Write PPD files...
+    for (d = (ppdcDriver *)src->drivers->first();
+         d;
+        d = (ppdcDriver *)src->drivers->next())
+    {
+      // Write the PPD file for this driver...
+      if (strstr(d->pc_file_name->value, ".PPD"))
+      {
+       // Convert PCFileName to lowercase...
+       for (j = 0;
+            d->pc_file_name->value[j] && j < (int)(sizeof(pcfilename) - 1);
+            j ++)
+         pcfilename[j] = tolower(d->pc_file_name->value[j]);
+
+       pcfilename[j] = '\0';
+      }
+      else
+      {
+       // Leave PCFileName as-is...
+       strlcpy(pcfilename, d->pc_file_name->value, sizeof(pcfilename));
+      }
+
+      // Open the PPD file for writing...
+      if (comp)
+       snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
+      else
+       snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
+
+      fp = cupsFileOpen(filename, comp ? "w9" : "w");
+      if (!fp)
+      {
+       fprintf(stderr, "ppdc: Unable to create PPD file \"%s\" - %s.\n",
+               filename, strerror(errno));
+       return (1);
+      }
+
+      if (verbose)
+       printf("ppdc: Writing %s...\n", filename);
+
+      if (d->write_ppd_file(fp, catalog, locales, src, le))
+      {
+       cupsFileClose(fp);
+       return (1);
+      }
+
+      cupsFileClose(fp);
+    }
+  }
+  else
+    usage();
+
+  // Delete the printer driver information...
+  delete src;
+
+  // Message catalog...
+  if (catalog)
+    delete catalog;
+
+  // Return with no errors.
+  return (0);
+}
+
+
+//
+// 'usage()' - Show usage and exit.
+//
+
+static void
+usage(void)
+{
+  puts("Usage: ppdc [options] filename.drv [ ... filenameN.drv ]");
+  puts("Options:");
+  puts("  -D name=value        Set named variable to value.");
+  puts("  -I include-dir       Add include directory to search path.");
+  puts("  -c catalog.po        Load the specified message catalog.");
+  puts("  -d output-dir        Specify the output directory.");
+  puts("  -l lang[,lang,...]   Specify the output language(s) (locale).");
+  puts("  -v                   Be verbose (more v's for more verbosity).");
+  puts("  -z                   Compress PPD files using GNU zip.");
+  puts("  --cr                 End lines with CR (Mac OS 9).");
+  puts("  --crlf               End lines with CR + LF (Windows).");
+  puts("  --lf                 End lines with LF (UNIX/Linux/Mac OS X).");
+
+  exit(1);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc.h b/ppdc/ppdc.h
new file mode 100644 (file)
index 0000000..ab67a36
--- /dev/null
@@ -0,0 +1,477 @@
+//
+// "$Id$"
+//
+//   Definitions for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2007 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/".
+//
+
+#ifndef _PPDC_H_
+#  define _PPDC_H_
+
+//
+// Include necessary headers...
+//
+
+#  include <cups/string.h>
+
+#  include <cups/file.h>
+#  include <stdlib.h>
+#  include <errno.h>
+
+
+//
+// Enumerations...
+//
+
+enum ppdcDrvType                       //// Driver type
+{
+  PPDC_DRIVER_CUSTOM,                  // Custom driver
+  PPDC_DRIVER_PS,                      // PostScript driver
+  PPDC_DRIVER_ESCP,                    // rastertoescpx driver
+  PPDC_DRIVER_PCL,                     // rastertopclx driver
+  PPDC_DRIVER_LABEL,                   // rastertolabel/rastertodymo driver
+  PPDC_DRIVER_EPSON,                   // rastertoepson driver
+  PPDC_DRIVER_HP,                      // rastertohp driver
+  PPDC_DRIVER_MAX                      // Number of driver types defined
+};
+
+enum ppdcFontStatus                    //// Load status of font
+{
+  PPDC_FONT_ROM,                       // Font is in ROM
+  PPDC_FONT_DISK                       // Font is on disk
+};
+
+enum ppdcOptSection                    //// Option section
+{
+  PPDC_SECTION_ANY,                    // AnySetup
+  PPDC_SECTION_DOCUMENT,               // DocumentSetup
+  PPDC_SECTION_EXIT,                   // ExitServer
+  PPDC_SECTION_JCL,                    // JCLSetup
+  PPDC_SECTION_PAGE,                   // PageSetup
+  PPDC_SECTION_PROLOG                  // Prolog
+};
+
+enum ppdcOptType                       //// Option type
+{
+  PPDC_BOOLEAN,                                // True/false option
+  PPDC_PICKONE,                                // Single choice from list
+  PPDC_PICKMANY                                // Multiple choices from list
+};
+
+enum ppdcLineEnding                    //// Line endings
+{
+  PPDC_LFONLY,                         // LF only
+  PPDC_CRONLY,                         // CR only
+  PPDC_CRLF                            // CR + LF
+};
+
+
+//
+// Printer description data...
+//
+
+class ppdcShared                       //// Shared Data Value
+{
+  private:
+
+  int          use;                    // Use count (delete when 0)
+
+  public:
+
+  ppdcShared();
+  virtual ~ppdcShared();
+
+  void         get(void);
+  void         release(void);
+};
+
+class ppdcArray                                //// Shared Array
+  : public ppdcShared
+{
+  public:
+
+  int          count,                  // Number of elements
+               alloc,                  // Allocated elements
+               current;                // Current element
+  ppdcShared   **data;                 // Elements
+
+  ppdcArray(ppdcArray *a = 0);
+  ~ppdcArray();
+
+  void         add(ppdcShared *d);
+  ppdcShared   *first();
+  ppdcShared   *next();
+  void         remove(ppdcShared *d);
+};
+
+class ppdcString                       //// Shared String
+  : public ppdcShared
+{
+  public:
+
+  char         *value;                 // String value
+
+  ppdcString(const char *v);
+  ~ppdcString();
+};
+
+class ppdcInteger                      //// Shared integer
+  : public ppdcShared
+{
+  public:
+
+  int          *value;                 // Integer value
+
+  ppdcInteger(int *v) { value = v; }
+};
+
+class ppdcMessage                      //// Translation message
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *id,                    // Translation ID
+               *string;                // Translation string
+
+  ppdcMessage(const char *i, const char *s);
+  ~ppdcMessage();
+};
+
+class ppdcCatalog                      //// Translation catalog
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *locale;                // Name of locale
+  ppdcString   *filename;              // Name of translation file
+  ppdcArray    *messages;              // Array of translation messages
+
+  ppdcCatalog(const char *l, const char *f = 0);
+  ~ppdcCatalog();
+
+  void         add_message(ppdcMessage *m) { messages->add(m); }
+  void         add_message(const char *id);
+  const char   *find_message(const char *id);
+  int          load_messages(const char *f);
+  int          save_messages(const char *f);
+};
+
+class ppdcAttr                         //// Attribute
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Name of attribute
+               *selector,              // Selector string
+               *text,                  // Text string
+               *value;                 // Value string
+
+  ppdcAttr(const char *n, const char *s, const char *t, const char *v);
+  ~ppdcAttr();
+};
+
+class ppdcFont                         //// Shared Font
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Font name
+               *encoding,              // Font base encoding
+               *version,               // Font version
+               *charset;               // Font charset
+  ppdcFontStatus status;               // Font status (ROM or Disk)
+
+  ppdcFont(const char *n, const char *e, const char *v, const char *c,
+           ppdcFontStatus s);
+  ~ppdcFont();
+};
+
+class ppdcChoice                       //// Option Choice
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Name of choice
+               *text,                  // Human-readable text of choice
+               *code;                  // PS code of choice
+
+  ppdcChoice(const char *n, const char *t, const char *c);
+  ~ppdcChoice();
+};
+
+class ppdcOption                       //// Option
+  : public ppdcShared
+{
+  public:
+
+  ppdcOptType  type;                   // Type of option
+  ppdcString   *name,                  // Name of option
+               *text;                  // Human-readable text of option
+  ppdcOptSection section;              // Section for option code
+  float                order;                  // Order number
+  ppdcArray    *choices;               // Choices
+  ppdcString   *defchoice;             // Default choice
+
+  ppdcOption(ppdcOptType ot, const char *n, const char *t, ppdcOptSection s,
+             float o);
+  ppdcOption(ppdcOption *o);
+  ~ppdcOption();
+
+  void         add_choice(ppdcChoice *c) { choices->add(c); }
+  ppdcChoice   *find_choice(const char *n);
+  void         set_defchoice(ppdcChoice *c);
+};
+
+class ppdcGroup                        //// Group of Options
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Name of option
+               *text;                  // Human-readable text of option
+  ppdcArray    *options;               // Options
+
+  ppdcGroup(const char *n, const char *t);
+  ppdcGroup(ppdcGroup *g);
+  ~ppdcGroup();
+
+  void         add_option(ppdcOption *o) { options->add(o); }
+  ppdcOption   *find_option(const char *n);
+};
+
+class ppdcConstraint                   //// Constraint
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *option1,               // First option
+               *choice1,               // First choice
+               *option2,               // Second option
+               *choice2;               // Second choice
+
+  ppdcConstraint(const char *o1, const char *c1, const char *o2,
+                const char *c2);
+  ~ppdcConstraint();
+};
+
+class ppdcFilter                       //// Filter Program
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *mime_type,             // MIME type
+               *program;               // Filter program
+  int          cost;                   // Relative cost of filter
+
+  ppdcFilter(const char *t, const char *p, int c);
+  ~ppdcFilter();
+};
+
+class ppdcMediaSize                    //// Media Size
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Name of size
+               *text;                  // Human-readable text
+  float                width,                  // Width in points
+               length,                 // Length in points
+               left,                   // Left limit in points
+               bottom,                 // Bottom limit in points
+               right,                  // Right limit in points
+               top;                    // Top limit in points
+  ppdcString   *size_code,             // PageSize code, if any
+               *region_code;           // PageRegion code, if any
+
+  ppdcMediaSize(const char *n, const char *t, float w, float l,
+                float lm, float bm, float rm, float tm,
+               const char *sc = 0, const char *rc = 0);
+  ~ppdcMediaSize();
+};
+
+class ppdcProfile                      //// Color Profile
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *resolution,            // Resolution name
+               *media_type;            // Media type name
+  float                density,                // Color profile density
+               gamma,                  // Color profile gamma
+               profile[9];             // Color profile matrix
+
+  ppdcProfile(const char *r, const char *m, float d, float g, const float *p);
+  ~ppdcProfile();
+};
+
+class ppdcSource;
+
+class ppdcDriver                       //// Printer Driver Data
+  : public ppdcShared
+{
+  public:
+
+  ppdcDrvType  type;                   // Driver type
+  ppdcArray    *copyright;             // Copyright strings
+  ppdcString   *manufacturer,          // Manufacturer
+               *model_name,            // Name of printer model
+               *pc_file_name,          // 8 character PC filename for PPD
+               *version;               // Version number
+  int          model_number,           // Model number for driver
+               manual_copies,          // Do manual copies?
+               color_device,           // Support color?
+               throughput;             // Throughput in pages per minute
+  ppdcArray    *attrs,                 // Attributes
+               *constraints,           // Constraints
+               *filters,               // Filters
+               *fonts,                 // Fonts
+               *groups,                // Option groups
+               *profiles,              // Color profiles
+               *sizes;                 // Fixed sizes
+  ppdcString   *default_font,          // Default font
+               *default_size;          // Default size option
+  int          variable_paper_size;    // Support variable sizes?
+  ppdcString   *custom_size_code;      // Custom page size code, if any
+  float                left_margin,            // Margins for device in points
+               bottom_margin,
+               right_margin,
+               top_margin,
+               max_width,              // Maximum width (points)
+               max_length,             // Maximum length (points)
+               min_width,              // Minimum width (points)
+               min_length;             // Minimum length (points)
+
+  ppdcDriver(ppdcDriver *d = 0);
+  ~ppdcDriver();
+
+  void         add_attr(ppdcAttr *a) { attrs->add(a); }
+  void         add_constraint(ppdcConstraint *c) { constraints->add(c); }
+  void         add_copyright(const char *c) {
+                 copyright->add(new ppdcString(c));
+               }
+  void         add_filter(ppdcFilter *f) { filters->add(f); }
+  void         add_font(ppdcFont *f) { fonts->add(f); }
+  void         add_group(ppdcGroup *g) { groups->add(g); }
+  void         add_profile(ppdcProfile *p) { profiles->add(p); }
+  void         add_size(ppdcMediaSize *m) { sizes->add(m); }
+
+  ppdcAttr     *find_attr(const char *k, const char *s);
+  ppdcGroup    *find_group(const char *n);
+  ppdcOption   *find_option(const char *n);
+
+  void         set_custom_size_code(const char *c);
+  void         set_default_font(ppdcFont *f);
+  void         set_default_size(ppdcMediaSize *m);
+  void         set_manufacturer(const char *m);
+  void         set_model_name(const char *m);
+  void         set_pc_file_name(const char *f);
+  void         set_version(const char *v);
+
+  int          write_ppd_file(cups_file_t *fp, ppdcCatalog *catalog,
+                              ppdcArray *locales, ppdcSource *src,
+                              ppdcLineEnding le);
+};
+
+class ppdcVariable                     //// Variable Definition
+  : public ppdcShared
+{
+  public:
+
+  ppdcString   *name,                  // Name of variable
+               *value;                 // Value of variable
+
+  ppdcVariable(const char *n, const char *v);
+  ~ppdcVariable();
+
+  void         set_value(const char *v);
+};
+
+class ppdcFile                         //// File
+{
+  public:
+
+  cups_file_t  *fp;                    // File pointer
+  const char   *filename;              // Filename
+  int          line;                   // Line in file
+
+  ppdcFile(const char *f);
+  ~ppdcFile();
+
+  int          get();
+  int          peek();
+};
+
+class ppdcSource                       //// Source File
+  : public ppdcShared
+{
+  public:
+
+  static ppdcArray *includes;          // Include directories
+  static const char *driver_types[];   // Driver types
+
+  ppdcString   *filename;              // Filename
+  ppdcArray    *base_fonts,            // Base fonts
+               *drivers,               // Printer drivers
+               *po_files,              // Message catalogs
+               *sizes,                 // Predefined media sizes
+               *vars;                  // Defined variables
+
+  ppdcSource(const char *f = 0);
+  ~ppdcSource();
+
+  static void  add_include(const char *d);
+  ppdcDriver   *find_driver(const char *f);
+  static char  *find_include(const char *f, const char *base, char *n,
+                             int nlen);
+  ppdcCatalog  *find_po(const char *l);
+  ppdcMediaSize        *find_size(const char *s);
+  ppdcVariable *find_variable(const char *n);
+  ppdcAttr     *get_attr(ppdcFile *fp);
+  int          get_boolean(ppdcFile *fp);
+  ppdcChoice   *get_choice(ppdcFile *fp);
+  ppdcChoice   *get_color_model(ppdcFile *fp);
+  int          get_color_order(const char *co);
+  ppdcProfile  *get_color_profile(ppdcFile *fp);
+  int          get_color_space(const char *cs);
+  ppdcConstraint *get_constraint(ppdcFile *fp);
+  ppdcMediaSize        *get_custom_size(ppdcFile *fp);
+  void         get_duplex(ppdcFile *fp, ppdcDriver *d);
+  ppdcFilter   *get_filter(ppdcFile *fp);
+  float                get_float(ppdcFile *fp);
+  ppdcFont     *get_font(ppdcFile *fp);
+  ppdcChoice   *get_generic(ppdcFile *fp, const char *keyword,
+                            const char *tattr, const char *nattr);
+  ppdcGroup    *get_group(ppdcFile *fp, ppdcDriver *d);
+  ppdcOption   *get_installable(ppdcFile *fp);
+  int          get_integer(const char *v);
+  int          get_integer(ppdcFile *fp);
+  float                get_measurement(ppdcFile *fp);
+  ppdcOption   *get_option(ppdcFile *fp, ppdcDriver *d, ppdcGroup *g);
+  ppdcCatalog  *get_po(ppdcFile *fp);
+  ppdcChoice   *get_resolution(ppdcFile *fp);
+  ppdcProfile  *get_simple_profile(ppdcFile *fp);
+  ppdcMediaSize        *get_size(ppdcFile *fp);
+  char         *get_token(ppdcFile *fp, char *buffer, int buflen);
+  ppdcVariable *get_variable(ppdcFile *fp);
+  int          import_ppd(const char *f);
+  int          quotef(cups_file_t *fp, const char *format, ...);
+  void         read_file(const char *f);
+  void         scan_file(ppdcFile *fp, ppdcDriver *td = 0, bool inc = false);
+  ppdcVariable *set_variable(const char *name, const char *value);
+  int          write_file(const char *f);
+};
+
+
+#endif // !_PPDC_H_
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdhtml.cxx b/ppdc/ppdhtml.cxx
new file mode 100644 (file)
index 0000000..dd85129
--- /dev/null
@@ -0,0 +1,164 @@
+//
+// "$Id$"
+//
+//   PPD to HTML utility for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   main()  - Main entry for the PPD to HTML utility.
+//   usage() - Show usage and exit.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+//
+// Local functions...
+//
+
+static void    usage(void);
+
+
+//
+// 'main()' - Main entry for the PPD compiler.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  int          i;                      // Looping var
+  ppdcSource   *src;                   // PPD source file data
+  ppdcDriver   *d;                     // Current driver
+  ppdcGroup    *g,                     // Current group
+               *composite;             // Composite of all drivers
+  ppdcOption   *o,                     // Current option
+               *compo;                 // Composite option
+  ppdcChoice   *c;                     // Current choice
+  char         *opt;                   // Current option char
+  ppdcMediaSize        *size;                  // Current media size
+
+
+  // Scan the command-line...
+  src = 0;
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+          case 'I' :                   // Include directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+             ppdcSource::add_include(argv[i]);
+             break;
+
+         default :                     // Unknown
+             usage();
+             break;
+       }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      src = new ppdcSource(argv[i]);
+
+      // Create a composite group with all of the features from the
+      // drivers in the info file...
+      composite = new ppdcGroup("", "");
+
+      for (d = (ppdcDriver *)src->drivers->first(); d; d = (ppdcDriver *)src->drivers->next())
+        for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next())
+         for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
+         {
+           if ((compo = composite->find_option(o->name->value)) == NULL)
+             composite->add_option(new ppdcOption(o));
+         }
+
+      puts("<html>");
+      printf("<head><title>Driver Summary for %s</title></head>\n", argv[i]);
+      printf("<body><h1>Driver Summary for %s</h1>\n", argv[i]);
+      printf("<p><table border='1'><thead><tr><th>Printer</th><th>Media Size</th>");
+      for (compo = (ppdcOption *)composite->options->first(); compo; compo = (ppdcOption *)composite->options->next())
+        printf("<th>%s</th>", compo->text->value);
+      puts("</tr></thead><tbody>");
+
+      // Write HTML summary...
+      for (d = (ppdcDriver *)src->drivers->first(); d; d = (ppdcDriver *)src->drivers->next())
+      {
+        // Write the summary for this driver...
+       printf("<tr valign='top'><td nowrap>%s</td><td nowrap>", d->model_name->value);
+       for (size = (ppdcMediaSize *)d->sizes->first(); size;
+            size = (ppdcMediaSize *)d->sizes->next())
+          printf("%s<br>", size->text->value);
+        printf("</td>");
+
+        for (compo = (ppdcOption *)composite->options->first(); compo;
+            compo = (ppdcOption *)composite->options->next())
+         if ((o = d->find_option(compo->name->value)) != NULL)
+         {
+           printf("<td nowrap>");
+           for (c = (ppdcChoice *)o->choices->first(); c;
+                c = (ppdcChoice *)o->choices->next())
+             printf("%s<br>", c->text->value);
+           printf("</td>");
+         }
+         else
+           printf("<td>N/A</td>");
+
+        puts("</tr>");
+      }
+
+      puts("</tbody></table></p>");
+      puts("</body>");
+      puts("</html>");
+      // Delete the printer driver information...
+      delete composite;
+      delete src;
+    }
+
+  // If no drivers have been loaded, display the program usage message.
+  if (!src)
+    usage();
+
+  // Return with no errors.
+  return (0);
+}
+
+
+//
+// 'usage()' - Show usage and exit.
+//
+
+static void
+usage(void)
+{
+  puts("Usage: ppdhtml [options] filename.drv >filename.html");
+  puts("Options:");
+  puts("  -I include-dir    Add include directory to search path.");
+
+  exit(1);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdi.cxx b/ppdc/ppdi.cxx
new file mode 100644 (file)
index 0000000..2fe4a5f
--- /dev/null
@@ -0,0 +1,137 @@
+//
+// "$Id$"
+//
+//   PPD file import utility for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   main()  - Main entry for the PPD import utility.
+//   usage() - Show usage and exit.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+//
+// Local functions...
+//
+
+static void    usage(void);
+
+
+//
+// 'main()' - Main entry for the PPD import utility.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  int          i;                      // Looping var
+  char         *opt;                   // Current option
+  const char   *srcfile;               // Output file
+  ppdcSource   *src;                   // PPD source file data
+
+
+  // Scan the command-line...
+  srcfile = NULL;
+  src     = NULL;
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+         case 'o' :                    // Output file
+              if (srcfile || src)
+               usage();
+
+             i ++;
+             if (i >= argc)
+               usage();
+
+             srcfile = argv[i];
+             break;
+
+         case 'I' :                    // Include dir
+             i ++;
+             if (i >= argc)
+               usage();
+
+             ppdcSource::add_include(argv[i]);
+             break;
+
+         default :                     // Unknown
+             usage();
+             break;
+        }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      if (!srcfile)
+        srcfile = "ppdi.drv";
+
+      if (!src)
+      {
+        if (access(srcfile, 0))
+         src = new ppdcSource();
+       else
+          src = new ppdcSource(srcfile);
+      }
+
+      // Import the PPD file...
+      src->import_ppd(argv[i]);
+    }
+
+  // If no drivers have been loaded, display the program usage message.
+  if (!src)
+    usage();
+
+  // Write the driver info file back to disk...
+  src->write_file(srcfile);
+
+  // Delete the printer driver information...
+  delete src;
+
+  // Return with no errors.
+  return (0);
+}
+
+
+//
+// 'usage()' - Show usage and exit.
+//
+
+static void
+usage(void)
+{
+  puts("Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]");
+  puts("Options:");
+  puts("  -I include-dir");
+  puts("  -o filename.drv");
+
+  exit(1);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdmerge.cxx b/ppdc/ppdmerge.cxx
new file mode 100644 (file)
index 0000000..598b4b8
--- /dev/null
@@ -0,0 +1,358 @@
+//
+// "$Id$"
+//
+//   PPD file merge utility for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2007 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:
+//
+//   main()       - Main entry for the PPD merge utility.
+//   ppd_locale() - Return the locale associated with a PPD file.
+//   usage()      - Show usage and exit.
+//
+
+//
+// Include necessary headers...
+//
+
+#include <cups/cups.h>
+#include <cups/array.h>
+#include <cups/string.h>
+#include <errno.h>
+
+
+//
+// Local functions...
+//
+
+static const char      *ppd_locale(ppd_file_t *ppd);
+static void            usage(void);
+
+
+//
+// 'main()' - Main entry for the PPD merge utility.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  int          i;                      // Looping var
+  char         *opt;                   // Current option
+  ppd_file_t   *ppd;                   // PPD file
+  cups_array_t *ppds;                  // Array of PPD files
+  const char   *inname,                // First input filename
+               *outname;               // Output filename (if any)
+  cups_file_t  *infile,                // Input file
+               *outfile;               // Output file
+  char         languages[1024];        // Languages in file
+
+
+  // Scan the command-line...
+  inname       = NULL;
+  outname      = NULL;
+  outfile      = NULL;
+  languages[0] = '\0';
+  ppds         = cupsArrayNew(NULL, NULL);
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+         case 'o' :                    // Output file
+              if (outname)
+               usage();
+
+             i ++;
+             if (i >= argc)
+               usage();
+
+             outname = argv[i];
+             break;
+
+         default :                     // Unknown
+             usage();
+             break;
+        }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      if ((infile = cupsFileOpen(argv[i], "r")) == NULL)
+      {
+        fprintf(stderr, "ppdmerge: Unable to open %s - %s\n", argv[i],
+               strerror(errno));
+       goto error;
+      }
+
+      // Open the PPD file...
+      if ((ppd = ppdOpen2(infile)) == NULL)
+      {
+        ppd_status_t   status;         // PPD open status
+       int             linenum;        // Line number
+        char           line[1024];     // First line from file
+       
+       
+        status = ppdLastError(&linenum);
+       
+       fprintf(stderr, "ppdmerge: Unable to open %s - %s on line %d.\n",
+               argv[i], ppdErrorString(status), linenum);
+       
+        fprintf(stderr, "%d: ", linenum);
+        cupsFileRewind(infile);
+       
+        line[0] = '\0';
+       
+        while (cupsFileGets(infile, line, sizeof(line)))
+       {
+         linenum --;
+         if (!linenum)
+           break;
+       }
+       
+       fprintf(stderr, "%s\n", line);
+       
+        cupsFileClose(infile);
+
+        goto error;
+      }
+      
+      // Figure out the locale...
+      const char *locale = ppd_locale(ppd);
+
+      if (!locale)
+      {
+        fprintf(stderr, "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n",
+               ppd->lang_version, argv[i]);
+        cupsFileClose(infile);
+       ppdClose(ppd);
+
+       goto error;
+      }
+      
+      if (!strcmp(locale, "en") && !inname && !outfile)
+      {
+        // Set the English PPD's filename...
+        inname = argv[i];
+       
+        if (outname && !strcmp(inname, outname))
+       {       
+         // Rename input filename so that we don't overwrite it...
+         char bckname[1024];           // Backup filename
+         
+         
+         snprintf(bckname, sizeof(bckname), "%s.bck", inname);
+         
+         if (rename(inname, bckname))
+         {
+           fprintf(stderr, "ppdmerge: Unable to backup %s to %s- %s\n",
+                   inname, bckname, strerror(errno));
+           return (1);
+         }
+       }
+
+        // Open the output stream...
+       if (outname)
+       {
+         const char *ext = strrchr(outname, '.');
+         if (ext && !strcmp(ext, ".ppd.gz"))
+           outfile = cupsFileOpen(outname, "w9");
+         else
+           outfile = cupsFileOpen(outname, "w");
+       }
+       else
+         outfile = cupsFileStdout();
+
+        // Copy the PPD file to the output stream...
+       char line[1024];                // Line from file
+       
+       cupsFileRewind(infile);
+
+       while (cupsFileGets(infile, line, sizeof(line)))
+       {
+         if (!strncmp(line, "*cupsLanguages:", 15))
+         {
+           if (sscanf(line, "*cupsLanguages:%*[ \t]\"%1023[^\"]",
+                      languages) != 1)
+             languages[0] = '\0';
+         }
+         else
+           cupsFilePrintf(outfile, "%s\n", line);
+       }
+      }
+      else if (strcmp(locale, "en") && !strstr(languages, locale))
+      {
+       // Save this PPD for later processing...
+        cupsArrayAdd(ppds, ppd);
+      }
+      else
+      {
+        // Don't need this PPD...
+       fprintf(stderr, "ppdmerge: Ignoring PPD file %s...\n", argv[i]);
+        ppdClose(ppd);
+      }
+      
+      // Close and move on...
+      cupsFileClose(infile);
+    }
+
+  // If no PPDs have been loaded, display the program usage message.
+  if (!inname)
+    usage();
+      
+  // Loop through the PPD files we loaded to provide the translations...
+  for (ppd = (ppd_file_t *)cupsArrayFirst(ppds);
+       ppd;
+       ppd = (ppd_file_t *)cupsArrayNext(ppds))
+  {
+    // Output all of the UI text for this language...
+    int                        j, k, l;        // Looping vars
+    ppd_group_t                *g;             // Option group
+    ppd_option_t       *o;             // Option
+    ppd_choice_t       *c;             // Choice
+    const char         *locale = ppd_locale(ppd);
+                                       // Locale
+
+    
+    cupsFilePrintf(outfile, "*%% %s localization\n", ppd->lang_version);
+    
+    cupsFilePrintf(outfile, "*%s.Translation ModelName/%s: \"\"\n", locale,
+                  ppd->modelname);
+    
+    for (j = ppd->num_groups, g = ppd->groups; j > 0; j --, g ++)
+    {
+      cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale,
+                    g->name, g->text);
+      
+      for (k = g->num_options, o = g->options; k > 0; k --, o ++)
+      {
+       cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale,
+                      o->keyword, o->text);
+       
+       for (l = o->num_choices, c = o->choices; l > 0; l --, c ++)
+         cupsFilePrintf(outfile, "*%s.%s %s/%s: \"\"\n", locale,
+                        o->keyword, c->choice, c->text);
+      }
+    }
+    
+    if (languages[0])
+      strlcat(languages, " ", sizeof(languages));
+    
+    strlcat(languages, locale, sizeof(languages));
+
+    ppdClose(ppd);
+  }
+
+  cupsArrayDelete(ppds);
+
+  if (languages[0])
+    cupsFilePrintf(outfile, "*cupsLanguages: \"%s\"\n", languages);
+
+  cupsFileClose(outfile);
+
+  // Return with no errors.
+  return (0);
+
+  // Error out...
+error:
+
+  for (ppd = (ppd_file_t *)cupsArrayFirst(ppds);
+       ppd;
+       ppd = (ppd_file_t *)cupsArrayNext(ppds))
+    ppdClose(ppd);
+
+  cupsArrayDelete(ppds);
+
+  if (outfile)
+    cupsFileClose(outfile);
+
+  return (1);
+}
+
+
+//
+// 'ppd_locale()' - Return the locale associated with a PPD file.
+//
+
+static const char *                    // O - Locale string
+ppd_locale(ppd_file_t *ppd)            // I - PPD file
+{
+  int          i,                      // Looping var
+               vlen;                   // Length of LanguageVersion string
+  static char  locale[255];            // Locale string
+  static struct                                // LanguageVersion translation table
+  {
+    const char *version,               // LanguageVersion string */
+               *language;              // Language code */
+  }            languages[] =
+  {
+    { "chinese",       "zh" },
+    { "danish",                "da" },
+    { "dutch",         "nl" },
+    { "english",       "en" },
+    { "finnish",       "fi" },
+    { "french",                "fr" },
+    { "german",                "de" },
+    { "greek",         "el" },
+    { "italian",       "it" },
+    { "japanese",      "ja" },
+    { "korean",                "ko" },
+    { "norwegian",     "no" },
+    { "polish",                "pl" },
+    { "portuguese",    "pt" },
+    { "russian",       "ru" },
+    { "slovak",                "sk" },
+    { "spanish",       "es" },
+    { "swedish",       "sv" },
+    { "turkish",       "tr" }
+  };
+
+
+  for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
+  {
+    vlen = strlen(languages[i].version);
+
+    if (!strncasecmp(ppd->lang_version, languages[i].version, vlen))
+    {
+      if (ppd->lang_version[vlen] == '-' ||
+          ppd->lang_version[vlen] == '_')
+        snprintf(locale, sizeof(locale), "%s_%s", languages[i].language,
+                ppd->lang_version + vlen + 1);
+      else
+        strlcpy(locale, languages[i].language, sizeof(locale));
+
+      return (locale);
+    }
+  }
+
+  return (NULL);
+}
+
+//
+// 'usage()' - Show usage and exit.
+//
+
+static void
+usage(void)
+{
+  puts("Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]");
+  puts("Options:");
+  puts("  -o filename.ppd[.gz]");
+
+  exit(1);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdpo.cxx b/ppdc/ppdpo.cxx
new file mode 100644 (file)
index 0000000..0ee273e
--- /dev/null
@@ -0,0 +1,232 @@
+//
+// "$Id$"
+//
+//   PPD file message catalog program for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2005 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:
+//
+//   main()           - Main entry for the PPD compiler.
+//   add_ui_strings() - Add all UI strings from the driver.
+//   usage()          - Show usage and exit.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+//
+// Local functions...
+//
+
+static void    add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog);
+static void    usage(void);
+
+
+//
+// 'main()' - Main entry for the PPD compiler.
+//
+
+int                                    // O - Exit status
+main(int  argc,                                // I - Number of command-line arguments
+     char *argv[])                     // I - Command-line arguments
+{
+  int          i;                      // Looping var
+  ppdcCatalog  *catalog;               // Message catalog
+  ppdcSource   *src;                   // PPD source file data
+  ppdcDriver   *d;                     // Current driver
+  char         *opt;                   // Current option
+  int          verbose;                // Verbosity
+  const char   *outfile;               // Output file
+
+
+  // Scan the command-line...
+  catalog = new ppdcCatalog("en");
+  src     = 0;
+  verbose = 0;
+  outfile = 0;
+
+  for (i = 1; i < argc; i ++)
+    if (argv[i][0] == '-')
+    {
+      for (opt = argv[i] + 1; *opt; opt ++)
+        switch (*opt)
+       {
+          case 'I' :                   // Include directory...
+             i ++;
+             if (i >= argc)
+               usage();
+
+              if (verbose > 1)
+               printf("ppdc: Adding include directory \"%s\"...\n", argv[i]);
+
+             ppdcSource::add_include(argv[i]);
+             break;
+
+          case 'o' :                   // Output file...
+             i ++;
+             if (i >= argc || outfile)
+               usage();
+
+              outfile = argv[i];
+
+             catalog->load_messages(outfile);
+             break;
+
+          case 'v' :                   // Be verbose...
+             verbose ++;
+             break;
+
+         default :                     // Unknown
+             usage();
+             break;
+       }
+    }
+    else
+    {
+      // Open and load the driver info file...
+      if (verbose > 1)
+        printf("ppdc: Loading driver information file \"%s\"...\n", argv[i]);
+
+      src = new ppdcSource(argv[i]);
+
+      // Add UI strings...
+      for (d = (ppdcDriver *)src->drivers->first();
+           d;
+          d = (ppdcDriver *)src->drivers->next())
+      {
+       if (verbose)
+         printf("ppdc: Adding/updating UI text from %s...\n", argv[i]);
+
+        add_ui_strings(d, catalog);
+      }
+
+      // Delete the printer driver information...
+      delete src;
+    }
+
+  // Write the message catalog...
+  if (!outfile)
+    usage();
+  else
+    catalog->save_messages(outfile);
+
+  delete catalog;
+
+  // If no drivers have been loaded, display the program usage message.
+  if (!src)
+    usage();
+
+  // Return with no errors.
+  return (0);
+}
+
+
+//
+// 'add_ui_strings()' - Add all UI strings from the driver.
+//
+
+static void
+add_ui_strings(ppdcDriver  *d,         // I - Driver data
+               ppdcCatalog *catalog)   // I - Message catalog
+{
+  // Add the make/model/language strings...
+  catalog->add_message(d->manufacturer->value);
+  catalog->add_message(d->model_name->value);
+
+  // Add the media size strings...
+  ppdcMediaSize        *m;                     // Current media size
+
+  for (m = (ppdcMediaSize *)d->sizes->first();
+       m;
+       m = (ppdcMediaSize *)d->sizes->next())
+    catalog->add_message(m->text->value);
+
+  // Add the group/option/choice strings...
+  ppdcGroup    *g;                     // Current group
+  ppdcOption   *o;                     // Current option
+  ppdcChoice   *c;                     // Current choice
+
+  for (g = (ppdcGroup *)d->groups->first();
+       g;
+       g = (ppdcGroup *)d->groups->next())
+  {
+    if (!g->options->count)
+      continue;
+
+    if (strcasecmp(g->name->value, "General"))
+      catalog->add_message(g->text->value);
+
+    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))
+        catalog->add_message(o->text->value);
+      else
+        catalog->add_message(o->name->value);
+
+      for (c = (ppdcChoice *)o->choices->first();
+           c;
+          c = (ppdcChoice *)o->choices->next())
+       if (c->text->value && strcmp(c->name->value, c->text->value))
+          catalog->add_message(c->text->value);
+        else
+          catalog->add_message(c->name->value);
+    }
+  }
+
+  // Add profile and preset strings...
+  ppdcAttr *a;                         // Current attribute
+  for (a = (ppdcAttr *)d->attrs->first();
+       a;
+       a = (ppdcAttr *)d->attrs->next())
+    if (a->text->value && a->text->value[0] &&
+        (!strncmp(a->name->value, "Custom", 6) ||
+         !strncmp(a->name->value, "ParamCustom", 11) ||
+         !strcmp(a->name->value, "APCustomColorMatchingName") ||
+         !strcmp(a->name->value, "APPrinterPreset") ||
+         !strcmp(a->name->value, "cupsICCProfile") ||
+         !strcmp(a->name->value, "cupsIPPReason")))
+      catalog->add_message(a->text->value);
+    else if (!strncmp(a->name->value, "Custom", 6) ||
+             !strncmp(a->name->value, "ParamCustom", 11))
+      catalog->add_message(a->name->value);
+}
+
+
+//
+// 'usage()' - Show usage and exit.
+//
+
+static void
+usage(void)
+{
+  puts("Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]");
+  puts("Options:");
+  puts("  -I include-dir    Add include directory to search path.");
+  puts("  -v                Be verbose (more v's for more verbosity).");
+
+  exit(1);
+}
+
+
+//
+// End of "$Id$".
+//
index d6c128293ddb2c71c40aab4578f8609c9395e743..ce62b7154fe9d03f475c49297c2dd43faab964e2 100644 (file)
@@ -308,9 +308,10 @@ cupsdAllowHost(cupsd_location_t *loc,      /* I - Location to add to */
  */
 
 void
-cupsdAllowIP(cupsd_location_t *loc,    /* I - Location to add to */
-             unsigned   address[4],    /* I - IP address to add */
-             unsigned   netmask[4])    /* I - Netmask of address */
+cupsdAllowIP(
+    cupsd_location_t *loc,             /* I - Location to add to */
+    const unsigned   address[4],       /* I - IP address to add */
+    const unsigned   netmask[4])       /* I - Netmask of address */
 {
   cupsd_authmask_t     *temp;          /* New host/domain mask */
 
@@ -1703,8 +1704,8 @@ cupsdDenyHost(cupsd_location_t *loc,      /* I - Location to add to */
 
 void
 cupsdDenyIP(cupsd_location_t *loc,     /* I - Location to add to */
-           unsigned         address[4],/* I - IP address to add */
-           unsigned         netmask[4])/* I - Netmask of address */
+           const unsigned   address[4],/* I - IP address to add */
+           const unsigned   netmask[4])/* I - Netmask of address */
 {
   cupsd_authmask_t     *temp;          /* New host/domain mask */
 
index e1434400b1c3ec002d604369081c2a6dcde0adc1..2679420f0b38edca379c1297d1962f3fbfce13a8 100644 (file)
@@ -131,8 +131,9 @@ VAR http_encryption_t       DefaultEncryption VALUE(HTTP_ENCRYPT_REQUIRED);
 extern cupsd_location_t        *cupsdAddLocation(const char *location);
 extern void            cupsdAddName(cupsd_location_t *loc, char *name);
 extern void            cupsdAllowHost(cupsd_location_t *loc, char *name);
-extern void            cupsdAllowIP(cupsd_location_t *loc, unsigned address[4],
-                                    unsigned netmask[4]);
+extern void            cupsdAllowIP(cupsd_location_t *loc, 
+                                    const unsigned address[4],
+                                    const unsigned netmask[4]);
 extern void            cupsdAuthorize(cupsd_client_t *con);
 extern int             cupsdCheckAccess(unsigned ip[4], char *name,
                                         int namelen, cupsd_location_t *loc);
@@ -145,8 +146,9 @@ extern cupsd_location_t     *cupsdCopyLocation(cupsd_location_t **loc);
 extern void            cupsdDeleteAllLocations(void);
 extern void            cupsdDeleteLocation(cupsd_location_t *loc);
 extern void            cupsdDenyHost(cupsd_location_t *loc, char *name);
-extern void            cupsdDenyIP(cupsd_location_t *loc, unsigned address[4],
-                                   unsigned netmask[4]);
+extern void            cupsdDenyIP(cupsd_location_t *loc, 
+                                   const unsigned address[4],
+                                   const unsigned netmask[4]);
 extern cupsd_location_t        *cupsdFindBest(const char *path, http_state_t state);
 extern cupsd_location_t        *cupsdFindLocation(const char *location);
 extern http_status_t   cupsdIsAuthorized(cupsd_client_t *con, const char *owner);
index bac490ae697f4e5aaf911d5835c5bb25bfbc0f61..a6c24e86a152abf7148da96538bfe4e89de35d4d 100644 (file)
@@ -34,8 +34,10 @@ typedef struct cupsd_cert_s
  * Globals...
  */
 
-VAR cupsd_cert_t       *Certs;         /* List of certificates */
-VAR time_t             RootCertTime;   /* Root certificate update time */
+VAR cupsd_cert_t       *Certs          /* List of certificates */
+                               VALUE(NULL);
+VAR time_t             RootCertTime    /* Root certificate update time */
+                               VALUE(0);
 
 
 /*
index 706c315418ec95c5af46ccb98cafc607b6727a63..ada07dfea981bd6ec75266cfcbf8a50158369223 100644 (file)
@@ -2530,7 +2530,7 @@ cupsdSendHeader(
   {
     cupsdLogMessage(CUPSD_LOG_ERROR,
                     "Kerberos credentials larger than 64k (%d)!",
-                   con->gss_output_token.length);
+                   (int)con->gss_output_token.length);
     return (0);
   }
 #endif /* HAVE_GSSAPI */
index 977ef4352fb24adca6737bfbbed381b141e1ddc4..d9f9b052479cfb8079c3b96f0bef5c4ff55434d2 100644 (file)
@@ -72,7 +72,7 @@ typedef struct
  * Local globals...
  */
 
-static cupsd_var_t     variables[] =
+static const cupsd_var_t       variables[] =
 {
   { "AccessLog",               &AccessLog,             CUPSD_VARTYPE_STRING },
 #ifdef __APPLE__
@@ -175,11 +175,11 @@ static cupsd_var_t        variables[] =
 #define NUM_VARS       (sizeof(variables) / sizeof(variables[0]))
 
 
-static unsigned                ones[4] =
+static const unsigned  ones[4] =
                        {
                          0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
                        };
-static unsigned                zeros[4] =
+static const unsigned  zeros[4] =
                        {
                          0x00000000, 0x00000000, 0x00000000, 0x00000000
                        };
@@ -2073,7 +2073,7 @@ read_configuration(cups_file_t *fp)       /* I - File to read from */
                        *value,         /* Pointer to value */
                        *valueptr;      /* Pointer into value */
   int                  valuelen;       /* Length of value */
-  cupsd_var_t          *var;           /* Current variable */
+  cupsd_var_t const    *var;           /* Current variable */
   http_addrlist_t      *addrlist,      /* Address list */
                        *addr;          /* Current address */
   unsigned             ip[4],          /* Address value */
@@ -3209,7 +3209,8 @@ read_location(cups_file_t *fp,            /* I - Configuration file */
 
       parent->limit &= ~loc->limit;
     }
-    else if (!strcasecmp(line, "</Limit>"))
+    else if (!strcasecmp(line, "</Limit>") ||
+             !strcasecmp(line, "</LimitExcept>"))
       loc = parent;
     else if (!parse_aaa(loc, line, value, linenum))
     {
index 4f1ab36e85cf585150c6df3242fa916abdfaef92..764cc622a5a9626c65e8dedfb4e04d737b7baef8 100644 (file)
@@ -68,9 +68,11 @@ VAR char             *ConfigurationFile      VALUE(NULL),
 VAR int                        ServerNameIsIP          VALUE(0);
 VAR int                        NumSystemGroups         VALUE(0);
                                        /* Number of system group names */
-VAR char               *SystemGroups[MAX_SYSTEM_GROUPS];
+VAR char               *SystemGroups[MAX_SYSTEM_GROUPS]
+                                               VALUE({0});
                                        /* System group names */
-VAR gid_t              SystemGroupIDs[MAX_SYSTEM_GROUPS];
+VAR gid_t              SystemGroupIDs[MAX_SYSTEM_GROUPS]
+                                               VALUE({0});
                                        /* System group IDs */
 VAR char               *AccessLog              VALUE(NULL),
                                        /* Access log filename */
@@ -160,7 +162,8 @@ VAR int                     ClassifyOverride        VALUE(0),
                                        /* Timeout before reload from SIGHUP */
                        RootCertDuration        VALUE(300),
                                        /* Root certificate update interval */
-                       RunUser,        /* User to run as, used for files */
+                       RunUser                 VALUE(0),
+                                       /* User to run as, used for files */
                        PrintcapFormat          VALUE(PRINTCAP_BSD),
                                        /* Format of printcap file? */
                        DefaultShared           VALUE(TRUE);
index 4f29c03d529b5a3712d46ef90b2f39a120133761..517a940a43f8d75a783631e75ad3f97fb35381df 100644 (file)
@@ -60,7 +60,7 @@ extern cups_encoding_t        _ppdGetEncoding(const char *name);
 #define PPD_TYPE_FAX           3       /* Facsimile/MFD PPD */
 #define PPD_TYPE_UNKNOWN       4       /* Other/hybrid PPD */
 
-static const char *ppd_types[] =
+static const char * const ppd_types[] =        /* ppd-type values */
 {
   "postscript",
   "pdf",
index 5e80e55781a50bbfb96c72769495bf0c4ee37134..0b68f781a7f36833c7de29658cfa1e41babe59b5 100644 (file)
@@ -154,7 +154,8 @@ typedef void (*cupsd_selfunc_t)(void *data);
 
 VAR int                        TestConfigFile  VALUE(0);
                                        /* Test the cupsd.conf file? */
-VAR int                        MaxFDs;         /* Maximum number of files */
+VAR int                        MaxFDs          VALUE(0);
+                                       /* Maximum number of files */
 
 VAR time_t             ReloadTime      VALUE(0);
                                        /* Time of reload request... */
@@ -164,7 +165,8 @@ VAR void            *DefaultProfile VALUE(0);
                                        /* Default security profile */
 
 #ifdef HAVE_GSSAPI
-VAR krb5_context       KerberosContext;/* Kerberos context for credentials */
+VAR krb5_context       KerberosContext VALUE(NULL);
+                                       /* Kerberos context for credentials */
 #endif /* HAVE_GSSAPI */
 
 #ifdef HAVE_LAUNCH_H
index 39ba5919b6f76b5dbd387d32738d4bad48245962..6b964d8455b2a203701882bae5892e7f767ab9fc 100644 (file)
@@ -7219,17 +7219,6 @@ move_job(cupsd_client_t  *con,           /* I - Client connection */
     return;
   }
 
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con,
-                                 NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status, dprinter);
-    return;
-  }
-
  /*
   * See if we have a job URI or a printer URI...
   */
@@ -7337,6 +7326,17 @@ move_job(cupsd_client_t  *con,           /* I - Client connection */
     }
   }
 
+ /*
+  * Check the policy of the destination printer...
+  */
+
+  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con,
+                                 job ? job->username : NULL)) != HTTP_OK)
+  {
+    send_http_error(con, status, dprinter);
+    return;
+  }
+
  /*
   * Now move the job or jobs...
   */
index 004ee51485e7f0acf3a0bd6a059b6d8facdd9e89..696d3721a371e1ab46fb190fca9ec2acb49c049d 100644 (file)
@@ -352,6 +352,7 @@ cupsdCheckJobs(void)
   cupsd_job_t          *job;           /* Current job in queue */
   cupsd_printer_t      *printer,       /* Printer destination */
                        *pclass;        /* Printer class destination */
+  ipp_attribute_t      *attr;          /* Job attribute */
 
 
   DEBUG_puts("cupsdCheckJobs()");
@@ -385,6 +386,17 @@ cupsdCheckJobs(void)
 
       job->state->values[0].integer = IPP_JOB_PENDING;
       job->state_value              = IPP_JOB_PENDING;
+
+      if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+                                  IPP_TAG_KEYWORD)) == NULL)
+       attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+      if (attr)
+      {
+       attr->value_tag = IPP_TAG_KEYWORD;
+       cupsdSetString(&(attr->values[0].string.text), "no-hold");
+       cupsdSaveJob(job);
+      }
     }
 
    /*
@@ -444,9 +456,6 @@ cupsdCheckJobs(void)
          * so that we know which printer actually printed the job...
          */
 
-          ipp_attribute_t      *attr;  /* job-actual-printer-uri attribute */
-
-
           if ((attr = ippFindAttribute(job->attrs, "job-actual-printer-uri",
                                       IPP_TAG_URI)) != NULL)
             cupsdSetString(&attr->values[0].string.text, printer->uri);
index bc113c63406fb3cd1b8b03557c847eb341296580..77ab3e5e86f7fa098cb93f92f076e4ac92e920f1 100644 (file)
@@ -365,7 +365,7 @@ cupsdLogPage(cupsd_job_t *job,              /* I - Job being printed */
  /*
   * Print a page log entry of the form:
   *
-  *    printer job-id user [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \
+  *    printer user job-id [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \
   *        billing hostname
   */
 
index 10303b909faa4ff288a22c294dd4c55095a82265..613b593fb276369dc6cbc0269aad89c318931c64 100644 (file)
@@ -1684,8 +1684,11 @@ process_children(void)
            else
              job->status = -status;    /* Backend failed */
 
-            if (job->printer && !(job->printer->type & CUPS_PRINTER_FAX))
+            if (job->printer && !(job->printer->type & CUPS_PRINTER_FAX) &&
+               job->status_level > CUPSD_LOG_ERROR)
            {
+             job->status_level = CUPSD_LOG_ERROR;
+
               snprintf(job->printer->state_message,
                       sizeof(job->printer->state_message), "%s failed", name);
               cupsdAddPrinterHistory(job->printer);
index 08e10c1fd01519f5d36796a3919881494c3cde0a..263d3e753ec3c428c606cb40040aa0ba71cf557e 100644 (file)
@@ -1,49 +1,54 @@
 # DO NOT DELETE THIS LINE -- make depend depends on it.
-accept.o: accept.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h
-cancel.o: cancel.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h
-cupsaddsmb.o: cupsaddsmb.c ../cups/string.h ../config.h \
-  ../cups/adminutil.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \
-  ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h \
-  ../cups/i18n.h ../cups/transcode.h ../cups/debug.h
-cupsctl.o: cupsctl.c ../cups/adminutil.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h \
-  ../cups/transcode.h
-cupstestdsc.o: cupstestdsc.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/file.h ../cups/i18n.h \
-  ../cups/transcode.h
-cupstestppd.o: cupstestppd.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h \
-  ../filter/raster.h
-lp.o: lp.c ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h \
-  ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/i18n.h ../cups/transcode.h
-lpadmin.o: lpadmin.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h \
-  ../cups/debug.h
-lpinfo.o: lpinfo.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h \
-  ../cups/debug.h
-lpmove.o: lpmove.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h \
-  ../cups/debug.h
-lpoptions.o: lpoptions.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h
-lppasswd.o: lppasswd.c ../cups/string.h ../config.h ../cups/cups.h \
-  ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h \
-  ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h \
-  ../cups/md5.h
-lpstat.o: lpstat.c ../cups/http-private.h ../config.h ../cups/http.h \
-  ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h \
-  ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h \
-  ../cups/language.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h
+
+accept.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+accept.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+accept.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+accept.o: ../cups/transcode.h
+cancel.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+cancel.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+cancel.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+cancel.o: ../cups/transcode.h
+cupsaddsmb.o: ../cups/string.h ../config.h ../cups/adminutil.h ../cups/cups.h
+cupsaddsmb.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+cupsaddsmb.o: ../cups/array.h ../cups/file.h ../cups/language.h
+cupsaddsmb.o: ../cups/i18n.h ../cups/transcode.h ../cups/debug.h
+cupsctl.o: ../cups/adminutil.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+cupsctl.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h
+cupsctl.o: ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h
+cupsctl.o: ../cups/transcode.h
+cupstestdsc.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+cupstestdsc.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+cupstestdsc.o: ../cups/array.h ../cups/file.h ../cups/language.h
+cupstestdsc.o: ../cups/file.h ../cups/i18n.h ../cups/transcode.h
+cupstestppd.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+cupstestppd.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+cupstestppd.o: ../cups/array.h ../cups/file.h ../cups/language.h
+cupstestppd.o: ../cups/i18n.h ../cups/transcode.h ../cups/raster.h
+lp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lp.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+lp.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h
+lpadmin.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpadmin.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+lpadmin.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+lpadmin.o: ../cups/transcode.h ../cups/debug.h
+lpinfo.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpinfo.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+lpinfo.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+lpinfo.o: ../cups/transcode.h ../cups/debug.h
+lpmove.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpmove.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+lpmove.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+lpmove.o: ../cups/transcode.h ../cups/debug.h
+lpoptions.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpoptions.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h
+lpoptions.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h
+lpoptions.o: ../cups/transcode.h
+lppasswd.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lppasswd.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h
+lppasswd.o: ../cups/file.h ../cups/language.h ../cups/i18n.h
+lppasswd.o: ../cups/transcode.h ../cups/md5.h
+lpstat.o: ../cups/http-private.h ../config.h ../cups/http.h
+lpstat.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h
+lpstat.o: ../cups/ipp.h ../cups/string.h ../cups/cups.h ../cups/ppd.h
+lpstat.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h
+lpstat.o: ../cups/transcode.h ../cups/debug.h
index 0ab40ffe322212b1ac2aae15d885625b3ecda64f..54b3b4c620e20607519a852d51113ffa7f4df052 100644 (file)
@@ -37,7 +37,7 @@
 #include <cups/string.h>
 #include <cups/cups.h>
 #include <cups/i18n.h>
-#include <filter/raster.h>
+#include <cups/raster.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/stat.h>
index b4fcc3735d200bb75d5057b01da1efd6261f19af..2036534be4ea6c09f26cfe20c21b85fd260c6b66 100644 (file)
@@ -122,12 +122,12 @@ install: all $(INSTALL_LANGUAGES)
 
 install-languages:
        for lang in $(LANGUAGES); do \
-               $(INSTALL_DIR) -m 755 $(DATADIR)/templates/$$lang; \
-               for file in $(FILES); do \
-                       if test -f $$lang/$$file; then \
-                               $(INSTALL_DATA) $$lang/$$file $(DATADIR)/templates/$$lang; \
-                       fi \
-               done \
+               if test -d $$lang; then \
+                       $(INSTALL_DIR) -m 755 $(DATADIR)/templates/$$lang; \
+                       for file in $(FILES); do \
+                               $(INSTALL_DATA) $$lang/$$file $(DATADIR)/templates/$$lang || true; \
+                       done \
+               fi \
        done
 
 
index 08dda008ee02d0180f2b6f577854ca5f5150ecb5..e40103413fe7c43bc709d45533ae84f181afe5b6 100644 (file)
@@ -1,7 +1,6 @@
 {#printer_name=0?:
 {[printer_name]
-{#printer_name=1?:<H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>{default_name={printer_name}? (Default Printer):}}
-{?printer_state_message=?:<SPAN CLASS="message">"{printer_state_message}"</SPAN>}</H2>
+{_SINGLE_DEST?:<H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>{default_name={printer_name}? (Default Printer):}</H2>}
 
 <TABLE WIDTH="100%" CELLSPACING="0" CELLPADDING="0" SUMMARY="{printer_name}">
 <TR>
@@ -9,9 +8,9 @@
 <IMG SRC="/images/classes.png" WIDTH="128" HEIGHT="128" ALT=""></A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
 <TD VALIGN=TOP><B>Description:</B> {printer_info}<BR>
 <B>Location:</B> {printer_location}<BR>
-<B>Class State:</B> {printer_state=3?idle:{printer_state=4?processing:paused}},
+<B>Class State:</B> {printer_state=3?Idle:{printer_state=4?Processing:Paused}}{?printer_state_message=?: ("{printer_state_message}")}},
 {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}, {server_is_sharing_printers=0?not:{printer_is_shared=0?not:}} shared{default_name={printer_name}?, server default:}.
-{?member_uris=?:<BR>Members: {member_uris}}
+{?member_uris=?:<BR><B>Members:</B> {member_uris}}
 
 <P><TABLE CLASS="inset" WIDTH="100%" SUMMARY="Maintenance Commands">
 <CAPTION>Maintenance Commands</CAPTION>
index 00c215e1f9557f896c57c8ea56b9a5f9e4459d71..ea1c47fe50455f13bcbc877e810fb59c97a5a8d8 100644 (file)
@@ -2,7 +2,7 @@
 <HTML>
 <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
-       <TITLE>{title} - CUPS 1.4svn-r6854</TITLE>
+       <TITLE>{title} - CUPS @CUPS_VERSION@@CUPS_REVISION@</TITLE>
        <LINK REL="STYLESHEET" TYPE="text/css" HREF="/cups.css">
        <LINK REL="SHORTCUT ICON" HREF="/favicon.png" TYPE="image/png">
        {refresh_page?<META HTTP-EQUIV="Refresh" CONTENT="{refresh_page}">:}
index bf5427ee343af908440840a381defb6db31413c0..0b05f431881ce4e3ac2ee93831848f28c727487e 100644 (file)
@@ -1,7 +1,6 @@
 {printer_type?:}{#printer_name=0?:
 {[printer_name]
-{#printer_name=1?:<H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>{default_name={printer_name}? (Default Printer):}}
-{?printer_state_message=?:<SPAN CLASS="message">"{printer_state_message}"</SPAN>}</H2>
+{_SINGLE_DEST?:<H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>{default_name={printer_name}? (Default Printer):}</H2>}
 
 <TABLE WIDTH="100%" CELLSPACING="0" CELLPADDING="0" SUMMARY="{printer_name}">
 <TR>
@@ -10,7 +9,7 @@
 <TD VALIGN="TOP"><B>Description:</B> {printer_info}<BR>
 <B>Location:</B> {printer_location}<BR>
 <B>Printer Driver:</B> {printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})<BR>
-<B>Printer State:</B> {printer_state=3?idle:{printer_state=4?processing:paused}},
+<B>Printer State:</B> {printer_state=3?Idle:{printer_state=4?Processing:Paused}{?printer_state_message=?: ("{printer_state_message}")}},
 {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}, {server_is_sharing_printers=0?not:{printer_is_shared=0?not:}} shared{default_name={printer_name}?, server default:}.<BR>
 <B>Default Options:</B> job-sheets={job_sheets_default}
 media={media_default?{media_default}:unknown}