summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES-1.3.txt13
-rw-r--r--Makedefs.in15
-rw-r--r--Makefile8
-rw-r--r--backend/pap.c2
-rw-r--r--backend/snmp.c9
-rw-r--r--backend/usb-darwin.c40
-rw-r--r--cgi-bin/admin.c19
-rw-r--r--cgi-bin/classes.c1
-rw-r--r--cgi-bin/printers.c1
-rw-r--r--config-scripts/cups-common.m4103
-rw-r--r--config-scripts/cups-compiler.m43
-rw-r--r--config-scripts/cups-defaults.m410
-rw-r--r--config.h.in9
-rw-r--r--cups/Makefile16
-rw-r--r--cups/api-filter.header5
-rw-r--r--cups/api-filter.shtml121
-rw-r--r--cups/backend.c4
-rw-r--r--cups/globals.h2
-rw-r--r--cups/http-support.c2
-rw-r--r--cups/libcups.exp2
-rw-r--r--cups/raster.h (renamed from filter/raster.h)4
-rw-r--r--cups/snmp.c608
-rw-r--r--cups/snmp.h50
-rw-r--r--cups/testsnmp.c333
-rw-r--r--data/Makefile20
-rw-r--r--data/epson.h27
-rw-r--r--data/escp.h34
-rw-r--r--data/font.defs55
-rw-r--r--data/hp.h24
-rw-r--r--data/label.h28
-rw-r--r--data/media.defs207
-rw-r--r--data/pcl.h38
-rw-r--r--data/raster.defs94
-rw-r--r--doc/cups-printable.css4
-rw-r--r--doc/cups.css5
-rw-r--r--doc/help/api-array.html4
-rw-r--r--doc/help/api-cups.html4
-rw-r--r--doc/help/api-filedir.html4
-rw-r--r--doc/help/api-filter.html525
-rw-r--r--doc/help/api-httpipp.html4
-rw-r--r--doc/help/api-overview.html4
-rw-r--r--doc/help/api-ppd.html4
-rw-r--r--doc/help/api-raster.html4
-rw-r--r--driver/Dependencies57
-rw-r--r--driver/Makefile237
-rw-r--r--driver/attr.c109
-rw-r--r--driver/check.c111
-rw-r--r--driver/cmyk.c1971
-rw-r--r--driver/commandtoescpx.c244
-rw-r--r--driver/commandtopclx.c171
-rw-r--r--driver/dither.c320
-rw-r--r--driver/driver.h249
-rw-r--r--driver/lut.c202
-rw-r--r--driver/pack.c307
-rw-r--r--driver/pcl-common.c272
-rw-r--r--driver/pcl-common.h71
-rw-r--r--driver/rastertoescpx.c1845
-rw-r--r--driver/rastertopclx.c1875
-rw-r--r--driver/rgb.c558
-rw-r--r--driver/srgb.c79
-rw-r--r--driver/testcmyk.c437
-rw-r--r--driver/testdither.c191
-rw-r--r--driver/testdriver.c2
-rw-r--r--driver/testrgb.c348
-rw-r--r--filter/Dependencies966
-rw-r--r--filter/Makefile11
-rw-r--r--filter/image-private.h1
-rw-r--r--filter/image.h2
-rw-r--r--filter/imagetoraster.c1
-rw-r--r--filter/rasterbench.c4
-rw-r--r--filter/rastertoepson.c2
-rw-r--r--filter/rastertohp.c2
-rw-r--r--filter/rastertolabel.c2
-rw-r--r--locale/Makefile4
-rw-r--r--locale/ppdc.pot592
-rw-r--r--locale/ppdc_da.po345
-rw-r--r--locale/ppdc_de.po579
-rw-r--r--locale/ppdc_es.po585
-rw-r--r--locale/ppdc_et.po592
-rw-r--r--locale/ppdc_fi.po273
-rw-r--r--locale/ppdc_fr.po582
-rw-r--r--locale/ppdc_he.po592
-rw-r--r--locale/ppdc_it.po585
-rw-r--r--locale/ppdc_ja.po471
-rw-r--r--locale/ppdc_ko.po468
-rw-r--r--locale/ppdc_nl.po381
-rw-r--r--locale/ppdc_no.po276
-rw-r--r--locale/ppdc_pl.po592
-rw-r--r--locale/ppdc_pt.po483
-rw-r--r--locale/ppdc_pt_BR.po483
-rw-r--r--locale/ppdc_ru.po592
-rw-r--r--locale/ppdc_sv.po378
-rw-r--r--locale/ppdc_zh.po417
-rw-r--r--locale/ppdc_zh_TW.po435
-rw-r--r--man/Makefile16
-rw-r--r--man/commandtoescpx.man33
-rw-r--r--man/commandtopclx.man33
-rw-r--r--man/ppdc.man73
-rw-r--r--man/ppdcfile.man162
-rw-r--r--man/ppdhtml.man38
-rw-r--r--man/ppdi.man44
-rw-r--r--man/ppdmerge.man47
-rw-r--r--man/ppdpo.man41
-rw-r--r--man/rastertoescpx.man33
-rw-r--r--man/rastertopclx.man33
-rw-r--r--packaging/cups.list.in44
-rw-r--r--packaging/cups.spec.in58
-rw-r--r--ppdc/Dependencies68
-rw-r--r--ppdc/Makefile210
-rw-r--r--ppdc/drv.cxx427
-rw-r--r--ppdc/foo-fr.po11
-rw-r--r--ppdc/foo.drv548
-rw-r--r--ppdc/ppdc-array.cxx163
-rw-r--r--ppdc/ppdc-attr.cxx60
-rw-r--r--ppdc/ppdc-catalog.cxx370
-rw-r--r--ppdc/ppdc-choice.cxx57
-rw-r--r--ppdc/ppdc-constraint.cxx60
-rw-r--r--ppdc/ppdc-driver.cxx1209
-rw-r--r--ppdc/ppdc-file.cxx100
-rw-r--r--ppdc/ppdc-filter.cxx55
-rw-r--r--ppdc/ppdc-font.cxx62
-rw-r--r--ppdc/ppdc-group.cxx96
-rw-r--r--ppdc/ppdc-import.cxx283
-rw-r--r--ppdc/ppdc-mediasize.cxx81
-rw-r--r--ppdc/ppdc-message.cxx54
-rw-r--r--ppdc/ppdc-option.cxx126
-rw-r--r--ppdc/ppdc-profile.cxx60
-rw-r--r--ppdc/ppdc-shared.cxx75
-rw-r--r--ppdc/ppdc-source.cxx3241
-rw-r--r--ppdc/ppdc-string.cxx58
-rw-r--r--ppdc/ppdc-variable.cxx66
-rw-r--r--ppdc/ppdc.cxx328
-rw-r--r--ppdc/ppdc.h477
-rw-r--r--ppdc/ppdhtml.cxx164
-rw-r--r--ppdc/ppdi.cxx137
-rw-r--r--ppdc/ppdmerge.cxx358
-rw-r--r--ppdc/ppdpo.cxx232
-rw-r--r--scheduler/auth.c11
-rw-r--r--scheduler/auth.h10
-rw-r--r--scheduler/cert.h6
-rw-r--r--scheduler/client.c2
-rw-r--r--scheduler/conf.c11
-rw-r--r--scheduler/conf.h9
-rw-r--r--scheduler/cups-driverd.c2
-rw-r--r--scheduler/cupsd.h6
-rw-r--r--scheduler/ipp.c22
-rw-r--r--scheduler/job.c15
-rw-r--r--scheduler/log.c2
-rw-r--r--scheduler/main.c5
-rw-r--r--systemv/Dependencies101
-rw-r--r--systemv/cupstestppd.c2
-rw-r--r--templates/Makefile12
-rw-r--r--templates/classes.tmpl7
-rw-r--r--templates/header.tmpl.in2
-rw-r--r--templates/printers.tmpl5
155 files changed, 31925 insertions, 1017 deletions
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 3e05bf7dc..2117b7a8f 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -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
diff --git a/Makedefs.in b/Makedefs.in
index ad73a3108..1868ee861 100644
--- a/Makedefs.in
+++ b/Makedefs.in
@@ -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 <$< >$@
diff --git a/Makefile b/Makefile
index 524082673..18b871f58 100644
--- 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;\
diff --git a/backend/pap.c b/backend/pap.c
index 461c91fee..f89047e1d 100644
--- a/backend/pap.c
+++ b/backend/pap.c
@@ -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
diff --git a/backend/snmp.c b/backend/snmp.c
index a001ff864..9b4532948 100644
--- a/backend/snmp.c
+++ b/backend/snmp.c
@@ -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...
diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c
index 88a7a4076..4e9826db5 100644
--- a/backend/usb-darwin.c
+++ b/backend/usb-darwin.c
@@ -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 -
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
index 0a981d231..6fa500d71 100644
--- a/cgi-bin/admin.c
+++ b/cgi-bin/admin.c
@@ -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);
diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c
index dbf561c38..39e2d1562 100644
--- a/cgi-bin/classes.c
+++ b/cgi-bin/classes.c
@@ -407,6 +407,7 @@ show_class(http_t *http, /* I - Connection to server */
* Show the class status...
*/
+ cgiSetVariable("_SINGLE_DEST", "1");
cgiCopyTemplateLang("classes.tmpl");
/*
diff --git a/cgi-bin/printers.c b/cgi-bin/printers.c
index 0d817f75e..de4d769f5 100644
--- a/cgi-bin/printers.c
+++ b/cgi-bin/printers.c
@@ -587,6 +587,7 @@ show_printer(http_t *http, /* I - Connection to server */
* Show the printer status...
*/
+ cgiSetVariable("_SINGLE_DEST", "1");
cgiCopyTemplateLang("printers.tmpl");
/*
diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4
index dcd126655..8f51586bc 100644
--- a/config-scripts/cups-common.m4
+++ b/config-scripts/cups-common.m4
@@ -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 $".
diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4
index 3a9f6908b..fc1c821ea 100644
--- a/config-scripts/cups-compiler.m4
+++ b/config-scripts/cups-compiler.m4
@@ -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)
diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4
index 6d6f5b644..e9d6038e4 100644
--- a/config-scripts/cups-defaults.m4
+++ b/config-scripts/cups-defaults.m4
@@ -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
diff --git a/config.h.in b/config.h.in
index 9bcf7181f..fc9013137 100644
--- a/config.h.in
+++ b/config.h.in
@@ -553,6 +553,15 @@
#undef HAVE_SANDBOX_H
+/*
+ * Which random number generator function to use...
+ */
+
+#undef HAVE_RANDOM
+#undef HAVE_MRAND48
+#undef HAVE_LRAND48
+
+
#endif /* !_CUPS_CONFIG_H_ */
/*
diff --git a/cups/Makefile b/cups/Makefile
index 4ea63e200..eb94eac13 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -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
#
diff --git a/cups/api-filter.header b/cups/api-filter.header
index f7ae6a368..4b41c439b 100644
--- a/cups/api-filter.header
+++ b/cups/api-filter.header
@@ -18,9 +18,10 @@
<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>
diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml
index 4f72dfe71..f5b6b8cf2 100644
--- a/cups/api-filter.shtml
+++ b/cups/api-filter.shtml
@@ -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>
diff --git a/cups/backend.c b/cups/backend.c
index 992bc5d03..e30aa9bbf 100644
--- a/cups/backend.c
+++ b/cups/backend.c
@@ -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 */
diff --git a/cups/globals.h b/cups/globals.h
index faed12951..0aacc0cc8 100644
--- a/cups/globals.h
+++ b/cups/globals.h
@@ -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 */
diff --git a/cups/http-support.c b/cups/http-support.c
index a05e528a3..be6cfbe84 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -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)
diff --git a/cups/libcups.exp b/cups/libcups.exp
index 930c0d5d2..c90f5c9d5 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -148,11 +148,13 @@ _cupsRemoveDest
_cupsRemoveOption
_cupsSNMPClose
_cupsSNMPCopyOID
+_cupsSNMPDefaultCommunity
_cupsSNMPIsOID
_cupsSNMPIsOIDPrefixed
_cupsSNMPOpen
_cupsSNMPRead
_cupsSNMPSetDebug
+_cupsSNMPWalk
_cupsSNMPWrite
_cupsSendRequest
_cupsServer
diff --git a/filter/raster.h b/cups/raster.h
index 2155ea516..947b1afcb 100644
--- a/filter/raster.h
+++ b/cups/raster.h
@@ -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$".
*/
diff --git a/cups/snmp.c b/cups/snmp.c
index 123f96538..1441b7f18 100644
--- a/cups/snmp.c
+++ b/cups/snmp.c
@@ -16,38 +16,40 @@
*
* 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.
*/
/*
@@ -66,10 +68,10 @@
* 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...
*/
@@ -365,9 +418,74 @@ 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@
*/
@@ -390,6 +508,15 @@ cupsSNMPWrite(
/*
+ * 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);
}
@@ -433,6 +566,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;
@@ -582,116 +926,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);
diff --git a/cups/snmp.h b/cups/snmp.h
index b0a9703be..9f1d8dc19 100644
--- a/cups/snmp.h
+++ b/cups/snmp.h
@@ -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,
diff --git a/cups/testsnmp.c b/cups/testsnmp.c
index 7a3ccfc77..e13b23847 100644
--- a/cups/testsnmp.c
+++ b/cups/testsnmp.c
@@ -15,7 +15,10 @@
*
* 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.
*/
/*
@@ -33,8 +36,11 @@
* 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);
}
diff --git a/data/Makefile b/data/Makefile
index f060e382d..85fb590af 100644
--- a/data/Makefile
+++ b/data/Makefile
@@ -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
index 000000000..13cb1a346
--- /dev/null
+++ b/data/epson.h
@@ -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
index 000000000..94389f3b9
--- /dev/null
+++ b/data/escp.h
@@ -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
index 000000000..ee4559e82
--- /dev/null
+++ b/data/font.defs
@@ -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
index 000000000..c70034316
--- /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
index 000000000..4b6fba64f
--- /dev/null
+++ b/data/label.h
@@ -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
index 000000000..07a4911fb
--- /dev/null
+++ b/data/media.defs
@@ -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
index 000000000..0cb1effe5
--- /dev/null
+++ b/data/pcl.h
@@ -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
index 000000000..486165f01
--- /dev/null
+++ b/data/raster.defs
@@ -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 $".
+ */
diff --git a/doc/cups-printable.css b/doc/cups-printable.css
index 12e7e7dbe..83693894d 100644
--- a/doc/cups-printable.css
+++ b/doc/cups-printable.css
@@ -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;
+}
diff --git a/doc/cups.css b/doc/cups.css
index 935c42821..8c522609e 100644
--- a/doc/cups.css
+++ b/doc/cups.css
@@ -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;
diff --git a/doc/help/api-array.html b/doc/help/api-array.html
index 175f6fecd..e902ed3fc 100644
--- a/doc/help/api-array.html
+++ b/doc/help/api-array.html
@@ -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/doc/help/api-cups.html b/doc/help/api-cups.html
index e2ff9ad28..36f731675 100644
--- a/doc/help/api-cups.html
+++ b/doc/help/api-cups.html
@@ -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/doc/help/api-filedir.html b/doc/help/api-filedir.html
index 8c35624ce..df491db65 100644
--- a/doc/help/api-filedir.html
+++ b/doc/help/api-filedir.html
@@ -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/doc/help/api-filter.html b/doc/help/api-filter.html
index 62ae4ac3a..2b3975259 100644
--- a/doc/help/api-filter.html
+++ b/doc/help/api-filter.html
@@ -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>
@@ -668,6 +821,234 @@ controls how many seconds to wait for the data to be written - use
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>
<p class="code">
@@ -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>
diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html
index e8c09e286..6939384ce 100644
--- a/doc/help/api-httpipp.html
+++ b/doc/help/api-httpipp.html
@@ -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/doc/help/api-overview.html b/doc/help/api-overview.html
index 151f3c90b..246db7993 100644
--- a/doc/help/api-overview.html
+++ b/doc/help/api-overview.html
@@ -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/doc/help/api-ppd.html b/doc/help/api-ppd.html
index d8aa110a7..d332ca6f5 100644
--- a/doc/help/api-ppd.html
+++ b/doc/help/api-ppd.html
@@ -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/doc/help/api-raster.html b/doc/help/api-raster.html
index f9010c933..f2d4c3a7c 100644
--- a/doc/help/api-raster.html
+++ b/doc/help/api-raster.html
@@ -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
index 000000000..70eb28e27
--- /dev/null
+++ b/driver/Dependencies
@@ -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
index 000000000..11796fe6f
--- /dev/null
+++ b/driver/Makefile
@@ -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
index 000000000..320e1c7da
--- /dev/null
+++ b/driver/attr.c
@@ -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
index 000000000..d7ceb3d44
--- /dev/null
+++ b/driver/check.c
@@ -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
index 000000000..01b87714d
--- /dev/null
+++ b/driver/cmyk.c
@@ -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
index 000000000..ce09ebcad
--- /dev/null
+++ b/driver/commandtoescpx.c
@@ -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
index 000000000..1c5c10df1
--- /dev/null
+++ b/driver/commandtopclx.c
@@ -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
index 000000000..239173442
--- /dev/null
+++ b/driver/dither.c
@@ -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
index 000000000..ed4eab96d
--- /dev/null
+++ b/driver/driver.h
@@ -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
index 000000000..7ca7e4350
--- /dev/null
+++ b/driver/lut.c
@@ -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
index 000000000..d9d01d16b
--- /dev/null
+++ b/driver/pack.c
@@ -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
index 000000000..427879338
--- /dev/null
+++ b/driver/pcl-common.c
@@ -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
index 000000000..78cf70168
--- /dev/null
+++ b/driver/pcl-common.h
@@ -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
index 000000000..f9cf22a61
--- /dev/null
+++ b/driver/rastertoescpx.c
@@ -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
index 000000000..9c5097448
--- /dev/null
+++ b/driver/rastertopclx.c
@@ -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
index 000000000..fd0b117a5
--- /dev/null
+++ b/driver/rgb.c
@@ -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
index 000000000..0354f23e5
--- /dev/null
+++ b/driver/srgb.c
@@ -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
index 000000000..a89353cd9
--- /dev/null
+++ b/driver/testcmyk.c
@@ -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
index 000000000..29f5e337e
--- /dev/null
+++ b/driver/testdither.c
@@ -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$".
+ */
diff --git a/driver/testdriver.c b/driver/testdriver.c
index 47a5eacdc..0d1f299eb 100644
--- a/driver/testdriver.c
+++ b/driver/testdriver.c
@@ -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
index 000000000..3fb0ae41a
--- /dev/null
+++ b/driver/testrgb.c
@@ -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$".
+ */
diff --git a/filter/Dependencies b/filter/Dependencies
index c1e89fd28..dee74c3c3 100644
--- a/filter/Dependencies
+++ b/filter/Dependencies
@@ -1,459 +1,507 @@
-# 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
diff --git a/filter/Makefile b/filter/Makefile
index 5f6a4aca5..068fb7760 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -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
#
diff --git a/filter/image-private.h b/filter/image-private.h
index 9921bce4d..dcf03a7e6 100644
--- a/filter/image-private.h
+++ b/filter/image-private.h
@@ -24,7 +24,6 @@
*/
# include "image.h"
-# include "raster.h"
# include <cups/cups.h>
# include <cups/debug.h>
# include <cups/string.h>
diff --git a/filter/image.h b/filter/image.h
index 6dcba9838..b2de9ad99 100644
--- a/filter/image.h
+++ b/filter/image.h
@@ -23,7 +23,7 @@
*/
# include <stdio.h>
-# include "raster.h"
+# include <cups/raster.h>
# ifdef __cplusplus
extern "C" {
diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c
index 1a6a27bab..bc4a806ec 100644
--- a/filter/imagetoraster.c
+++ b/filter/imagetoraster.c
@@ -37,7 +37,6 @@
#include "common.h"
#include "image-private.h"
-#include "raster.h"
#include <unistd.h>
#include <math.h>
#include <cups/i18n.h>
diff --git a/filter/rasterbench.c b/filter/rasterbench.c
index a165bed7a..acfb8be76 100644
--- a/filter/rasterbench.c
+++ b/filter/rasterbench.c
@@ -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>
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
index a50d977c7..f1ad6547c 100644
--- a/filter/rastertoepson.c
+++ b/filter/rastertoepson.c
@@ -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>
diff --git a/filter/rastertohp.c b/filter/rastertohp.c
index f35b58ca7..04ac4017a 100644
--- a/filter/rastertohp.c
+++ b/filter/rastertohp.c
@@ -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>
diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c
index 26a254f9a..05adc0397 100644
--- a/filter/rastertolabel.c
+++ b/filter/rastertolabel.c
@@ -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>
diff --git a/locale/Makefile b/locale/Makefile
index f7cbc8913..b6d9fe8cb 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -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
index 000000000..96b46447f
--- /dev/null
+++ b/locale/ppdc.pot
@@ -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
index 000000000..0ec32c588
--- /dev/null
+++ b/locale/ppdc_da.po
@@ -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
index 000000000..4adf2cd96
--- /dev/null
+++ b/locale/ppdc_de.po
@@ -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
index 000000000..9a01310b0
--- /dev/null
+++ b/locale/ppdc_es.po
@@ -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
index 000000000..96b46447f
--- /dev/null
+++ b/locale/ppdc_et.po
@@ -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
index 000000000..239c4057d
--- /dev/null
+++ b/locale/ppdc_fi.po
@@ -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
index 000000000..58cc529af
--- /dev/null
+++ b/locale/ppdc_fr.po
@@ -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
index 000000000..96b46447f
--- /dev/null
+++ b/locale/ppdc_he.po
@@ -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
index 000000000..4ac215780
--- /dev/null
+++ b/locale/ppdc_it.po
@@ -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
index 000000000..d67bf71b5
--- /dev/null
+++ b/locale/ppdc_ja.po
@@ -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
index 000000000..947727bb5
--- /dev/null
+++ b/locale/ppdc_ko.po
@@ -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
index 000000000..db97082ca
--- /dev/null
+++ b/locale/ppdc_nl.po
@@ -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
index 000000000..a7efadd38
--- /dev/null
+++ b/locale/ppdc_no.po
@@ -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
index 000000000..96b46447f
--- /dev/null
+++ b/locale/ppdc_pl.po
@@ -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
index 000000000..c86176fc8
--- /dev/null
+++ b/locale/ppdc_pt.po
@@ -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
index 000000000..c86176fc8
--- /dev/null
+++ b/locale/ppdc_pt_BR.po
@@ -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
index 000000000..96b46447f
--- /dev/null
+++ b/locale/ppdc_ru.po
@@ -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
index 000000000..1ef252d35
--- /dev/null
+++ b/locale/ppdc_sv.po
@@ -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
index 000000000..2f9faae56
--- /dev/null
+++ b/locale/ppdc_zh.po
@@ -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
index 000000000..34288d504
--- /dev/null
+++ b/locale/ppdc_zh_TW.po
@@ -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"
+
diff --git a/man/Makefile b/man/Makefile
index 9f23b90c7..de0870cd9 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -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
index 000000000..683edeaaf
--- /dev/null
+++ b/man/commandtoescpx.man
@@ -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
index 000000000..dec7add2e
--- /dev/null
+++ b/man/commandtopclx.man
@@ -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
index 000000000..ecf6181d7
--- /dev/null
+++ b/man/ppdc.man
@@ -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
index 000000000..f2b052f3b
--- /dev/null
+++ b/man/ppdcfile.man
@@ -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
index 000000000..3bdcd1a45
--- /dev/null
+++ b/man/ppdhtml.man
@@ -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
index 000000000..39b4cc5c7
--- /dev/null
+++ b/man/ppdi.man
@@ -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
index 000000000..12473b833
--- /dev/null
+++ b/man/ppdmerge.man
@@ -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
index 000000000..b5b43ebbe
--- /dev/null
+++ b/man/ppdpo.man
@@ -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
index 000000000..683edeaaf
--- /dev/null
+++ b/man/rastertoescpx.man
@@ -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
index 000000000..dec7add2e
--- /dev/null
+++ b/man/rastertopclx.man
@@ -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/packaging/cups.list.in b/packaging/cups.list.in
index ba8a2b1b5..705885d31 100644
--- a/packaging/cups.list.in
+++ b/packaging/cups.list.in
@@ -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 -
diff --git a/packaging/cups.spec.in b/packaging/cups.spec.in
index 3a967cf06..d64d3b9f7 100644
--- a/packaging/cups.spec.in
+++ b/packaging/cups.spec.in
@@ -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
index 000000000..3cd35def7
--- /dev/null
+++ b/ppdc/Dependencies
@@ -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
index 000000000..1e6974709
--- /dev/null
+++ b/ppdc/Makefile
@@ -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
index 000000000..23b9ecec9
--- /dev/null
+++ b/ppdc/drv.cxx
@@ -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
index 000000000..1b1561b39
--- /dev/null
+++ b/ppdc/foo-fr.po
@@ -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
index 000000000..fa84f3d1f
--- /dev/null
+++ b/ppdc/foo.drv
@@ -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
index 000000000..3cccad392
--- /dev/null
+++ b/ppdc/ppdc-array.cxx
@@ -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
index 000000000..094e38706
--- /dev/null
+++ b/ppdc/ppdc-attr.cxx
@@ -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
index 000000000..96cd6e3aa
--- /dev/null
+++ b/ppdc/ppdc-catalog.cxx
@@ -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
index 000000000..22ae05541
--- /dev/null
+++ b/ppdc/ppdc-choice.cxx
@@ -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
index 000000000..2a651b9fe
--- /dev/null
+++ b/ppdc/ppdc-constraint.cxx
@@ -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
index 000000000..d59b275a1
--- /dev/null
+++ b/ppdc/ppdc-driver.cxx
@@ -0,0 +1,1209 @@
+//
+// "$Id$"
+//
+// PPD file compiler definitions for the CUPS PPD Compiler.
+//
+// Copyright 2007 by Apple Inc.
+// Copyright 2002-2006 by Easy Software Products.
+//
+// These coded instructions, statements, and computer programs are the
+// property of Apple Inc. and are protected by Federal copyright
+// law. Distribution and use rights are outlined in the file "LICENSE.txt"
+// which should have been included with this file. If this file is
+// file is missing or damaged, see the license at "http://www.cups.org/".
+//
+// Contents:
+//
+// ppdcDriver::ppdcDriver() - Create a new printer driver.
+// ppdcDriver::~ppdcDriver() - Destroy a printer driver.
+// ppdcDriver::find_attr() - Find an attribute.
+// ppdcDriver::find_group() - Find a group.
+// ppdcDriver::find_option() - Find an option.
+// ppdcDriver::set_default_size() - Set the default size name.
+// ppdcDriver::set_manufacturer() - Set the manufacturer name.
+// ppdcDriver::set_model_name() - Set the model name.
+// ppdcDriver::set_pc_file_name() - Set the PC filename.
+// ppdcDriver::set_version() - Set the version string.
+// ppdcDriver::write_ppd_file() - Write a PPD file...
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/cups.h>
+
+
+//
+// 'ppdcDriver::ppdcDriver()' - Create a new printer driver.
+//
+
+ppdcDriver::ppdcDriver(ppdcDriver *d) // I - Printer driver template
+{
+ ppdcGroup *g; // Current group
+
+
+ if (d)
+ {
+ // Bump the use count of any strings we inherit...
+ if (d->manufacturer)
+ d->manufacturer->get();
+ if (d->version)
+ d->version->get();
+ if (d->default_font)
+ d->default_font->get();
+ if (d->default_size)
+ d->default_size->get();
+ if (d->custom_size_code)
+ d->custom_size_code->get();
+
+ // Copy all of the data from the driver template...
+ copyright = new ppdcArray(d->copyright);
+ manufacturer = d->manufacturer;
+ model_name = 0;
+ pc_file_name = 0;
+ type = d->type;
+ version = d->version;
+ model_number = d->model_number;
+ manual_copies = d->manual_copies;
+ color_device = d->color_device;
+ throughput = d->throughput;
+ attrs = new ppdcArray(d->attrs);
+ constraints = new ppdcArray(d->constraints);
+ filters = new ppdcArray(d->filters);
+ fonts = new ppdcArray(d->fonts);
+ profiles = new ppdcArray(d->profiles);
+ sizes = new ppdcArray(d->sizes);
+ default_font = d->default_font;
+ default_size = d->default_size;
+ variable_paper_size = d->variable_paper_size;
+ custom_size_code = d->custom_size_code;
+ left_margin = d->left_margin;
+ bottom_margin = d->bottom_margin;
+ right_margin = d->right_margin;
+ top_margin = d->top_margin;
+ max_width = d->max_width;
+ max_length = d->max_length;
+ min_width = d->min_width;
+ min_length = d->min_length;
+
+ // Then copy the groups manually, since we want separate copies
+ // of the groups and options...
+ groups = new ppdcArray();
+
+ for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next())
+ groups->add(new ppdcGroup(g));
+ }
+ else
+ {
+ // Zero all of the data in the driver...
+ copyright = new ppdcArray();
+ manufacturer = 0;
+ model_name = 0;
+ pc_file_name = 0;
+ version = 0;
+ type = PPDC_DRIVER_CUSTOM;
+ model_number = 0;
+ manual_copies = 0;
+ color_device = 0;
+ throughput = 1;
+ attrs = new ppdcArray();
+ constraints = new ppdcArray();
+ fonts = new ppdcArray();
+ filters = new ppdcArray();
+ groups = new ppdcArray();
+ profiles = new ppdcArray();
+ sizes = new ppdcArray();
+ default_font = 0;
+ default_size = 0;
+ variable_paper_size = 0;
+ custom_size_code = 0;
+ left_margin = 0;
+ bottom_margin = 0;
+ right_margin = 0;
+ top_margin = 0;
+ max_width = 0;
+ max_length = 0;
+ min_width = 0;
+ min_length = 0;
+ }
+}
+
+
+//
+// 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver.
+//
+
+ppdcDriver::~ppdcDriver()
+{
+ delete copyright;
+
+ if (manufacturer)
+ manufacturer->release();
+ if (model_name)
+ model_name->release();
+ if (pc_file_name)
+ pc_file_name->release();
+ if (version)
+ version->release();
+ if (default_font)
+ default_font->release();
+ if (default_size)
+ default_size->release();
+ if (custom_size_code)
+ custom_size_code->release();
+
+ delete attrs;
+ delete constraints;
+ delete filters;
+ delete fonts;
+ delete groups;
+ delete profiles;
+ delete sizes;
+}
+
+
+//
+// 'ppdcDriver::find_attr()' - Find an attribute.
+//
+
+ppdcAttr * // O - Attribute or NULL
+ppdcDriver::find_attr(const char *k, // I - Keyword string
+ const char *s) // I - Spec string
+{
+ ppdcAttr *a; // Current attribute
+
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, k) &&
+ ((!s && (!a->selector->value || !a->selector->value[0])) ||
+ (!s && !a->selector->value && !strcmp(a->selector->value, s))))
+ return (a);
+
+ return (NULL);
+}
+
+
+//
+// 'ppdcDriver::find_group()' - Find a group.
+//
+
+ppdcGroup * // O - Matching group or NULL
+ppdcDriver::find_group(const char *n) // I - Group name
+{
+ ppdcGroup *g; // Current group
+
+
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ if (!strcasecmp(n, g->name->value))
+ return (g);
+
+ return (0);
+}
+
+
+//
+// 'ppdcDriver::find_option()' - Find an option.
+//
+
+ppdcOption * // O - Matching option or NULL
+ppdcDriver::find_option(const char *n) // I - Option name
+{
+ ppdcGroup *g; // Current group
+ ppdcOption *o; // Current option
+
+
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
+ if (!strcasecmp(n, o->name->value))
+ return (o);
+
+ return (0);
+}
+
+
+//
+// 'ppdcDriver::set_custom_size_code()' - Set the custom page size code.
+//
+
+void
+ppdcDriver::set_custom_size_code(const char *c)
+ // I - CustomPageSize code
+{
+ if (custom_size_code)
+ custom_size_code->release();
+
+ custom_size_code = new ppdcString(c);
+}
+
+
+//
+// 'ppdcDriver::set_default_font()' - Set the default font name.
+//
+
+void
+ppdcDriver::set_default_font(ppdcFont *f)
+ // I - Font
+{
+ if (default_font)
+ default_font->release();
+
+ if (f)
+ {
+ f->name->get();
+ default_font = f->name;
+ }
+ else
+ default_font = 0;
+}
+
+
+//
+// 'ppdcDriver::set_default_size()' - Set the default size name.
+//
+
+void
+ppdcDriver::set_default_size(ppdcMediaSize *m)
+ // I - Media size
+{
+ if (default_size)
+ default_size->release();
+
+ if (m)
+ {
+ m->name->get();
+ default_size = m->name;
+ }
+ else
+ default_size = 0;
+}
+
+
+//
+// 'ppdcDriver::set_manufacturer()' - Set the manufacturer name.
+//
+
+void
+ppdcDriver::set_manufacturer(const char *m)
+ // I - Model name
+{
+ if (manufacturer)
+ manufacturer->release();
+
+ manufacturer = new ppdcString(m);
+}
+
+
+//
+// 'ppdcDriver::set_model_name()' - Set the model name.
+//
+
+void
+ppdcDriver::set_model_name(const char *m)
+ // I - Model name
+{
+ if (model_name)
+ model_name->release();
+
+ model_name = new ppdcString(m);
+}
+
+
+//
+// 'ppdcDriver::set_pc_file_name()' - Set the PC filename.
+//
+
+void
+ppdcDriver::set_pc_file_name(const char *f)
+ // I - Filename
+{
+ if (pc_file_name)
+ pc_file_name->release();
+
+ pc_file_name = new ppdcString(f);
+}
+
+
+//
+// 'ppdcDriver::set_version()' - Set the version string.
+//
+
+void
+ppdcDriver::set_version(const char *v) // I - Version
+{
+ if (version)
+ version->release();
+
+ version = new ppdcString(v);
+}
+
+
+//
+// 'ppdcDriver::write_ppd_file()' - Write a PPD file...
+//
+
+int // O - 0 on success, -1 on failure
+ppdcDriver::write_ppd_file(
+ cups_file_t *fp, // I - PPD file
+ ppdcCatalog *catalog, // I - Message catalog
+ ppdcArray *locales, // I - Additional languages to add
+ ppdcSource *src, // I - Driver source
+ ppdcLineEnding le) // I - Line endings to use
+{
+ bool delete_cat; // Delete the catalog when we are done?
+ char query[42]; // Query attribute
+ ppdcString *s; // Copyright string
+ ppdcGroup *g; // Current group
+ ppdcOption *o; // Current option
+ ppdcChoice *c; // Current choice
+ ppdcMediaSize *m; // Current media size
+ ppdcProfile *p; // Current color profile
+ ppdcFilter *f; // Current filter
+ ppdcFont *fn, // Current font
+ *bfn; // Current base font
+ ppdcConstraint *cn; // Current constraint
+ ppdcAttr *a; // Current attribute
+ const char *lf; // Linefeed character to use
+
+
+ // If we don't have a message catalog, use an empty (English) one...
+ if (!catalog)
+ {
+ catalog = new ppdcCatalog("en");
+ delete_cat = true;
+ }
+ else
+ delete_cat = false;
+
+ // Figure out the end-of-line string...
+ if (le == PPDC_LFONLY)
+ lf = "\n";
+ else if (le == PPDC_CRONLY)
+ lf = "\r";
+ else
+ lf = "\r\n";
+
+ // Write the standard header stuff...
+ cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
+ cupsFilePrintf(fp, "*%% PPD file for %s with CUPS.%s", model_name->value, lf);
+ cupsFilePrintf(fp,
+ "*%% Created by the CUPS PPD Compiler " CUPS_SVERSION ".%s",
+ lf);
+ for (s = (ppdcString *)copyright->first();
+ s;
+ s = (ppdcString *)copyright->next())
+ cupsFilePrintf(fp, "*%% %s%s", catalog->find_message(s->value), lf);
+ cupsFilePrintf(fp, "*FormatVersion: \"4.3\"%s", lf);
+ cupsFilePrintf(fp, "*FileVersion: \"%s\"%s", version->value, lf);
+
+ a = find_attr("LanguageVersion", NULL);
+ cupsFilePrintf(fp, "*LanguageVersion: %s%s",
+ catalog->find_message(a ? a->value->value : "English"), lf);
+
+ a = find_attr("LanguageEncoding", NULL);
+ cupsFilePrintf(fp, "*LanguageEncoding: %s%s",
+ catalog->find_message(a ? a->value->value : "ISOLatin1"), lf);
+
+ cupsFilePrintf(fp, "*PCFileName: \"%s\"%s", pc_file_name->value, lf);
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "Product"))
+ break;
+
+ if (a)
+ {
+ for (; a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "Product"))
+ cupsFilePrintf(fp, "*Product: \"%s\"%s", a->value->value, lf);
+ }
+ else
+ {
+ cupsFilePrintf(fp, "*Product: \"(ESP Ghostscript)\"%s", lf);
+ cupsFilePrintf(fp, "*Product: \"(GPL Ghostscript)\"%s", lf);
+ cupsFilePrintf(fp, "*Product: \"(GNU Ghostscript)\"%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*Manufacturer: \"%s\"%s",
+ catalog->find_message(manufacturer->value), lf);
+
+ if ((a = find_attr("ModelName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*ModelName: \"%s %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*ModelName: \"%s\"%s",
+ catalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("ShortNickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s",
+ catalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("NickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*NickName: \"%s\"%s",
+ catalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s",
+ catalog->find_message(manufacturer->value),
+ catalog->find_message(model_name->value), version->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*NickName: \"%s, %s\"%s",
+ catalog->find_message(model_name->value), version->value,
+ lf);
+
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "PSVersion"))
+ break;
+
+ if (a)
+ {
+ for (; a; a = (ppdcAttr *)attrs->next())
+ if (!strcmp(a->name->value, "PSVersion"))
+ cupsFilePrintf(fp, "*PSVersion: \"%s\"%s", a->value->value, lf);
+ }
+ else
+ {
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 705\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 707\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 815\"%s", lf);
+ cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 853\"%s", lf);
+ }
+
+ if ((a = find_attr("LanguageLevel", NULL)) != NULL)
+ cupsFilePrintf(fp, "*LanguageLevel: \"%s\"%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*LanguageLevel: \"3\"%s", lf);
+
+ cupsFilePrintf(fp, "*ColorDevice: %s%s", color_device ? "True" : "False", lf);
+
+ if ((a = find_attr("DefaultColorSpace", NULL)) != NULL)
+ cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*DefaultColorSpace: %s%s",
+ color_device ? "RGB" : "Gray", lf);
+
+ if ((a = find_attr("FileSystem", NULL)) != NULL)
+ cupsFilePrintf(fp, "*FileSystem: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*FileSystem: False%s", lf);
+
+ cupsFilePrintf(fp, "*Throughput: \"%d\"%s", throughput, lf);
+
+ if ((a = find_attr("LandscapeOrientation", NULL)) != NULL)
+ cupsFilePrintf(fp, "*LandscapeOrientation: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*LandscapeOrientation: Plus90%s", lf);
+
+ if ((a = find_attr("TTRasterizer", NULL)) != NULL)
+ cupsFilePrintf(fp, "*TTRasterizer: %s%s", a->value->value, lf);
+ else if (type != PPDC_DRIVER_PS)
+ cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
+
+ if (attrs->count)
+ {
+ // Write driver-defined attributes...
+ cupsFilePrintf(fp, "*%% Driver-defined attributes...%s", lf);
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ {
+ if (!strcmp(a->name->value, "Product") ||
+ !strcmp(a->name->value, "PSVersion") ||
+ !strcmp(a->name->value, "LanguageLevel") ||
+ !strcmp(a->name->value, "DefaultColorSpace") ||
+ !strcmp(a->name->value, "FileSystem") ||
+ !strcmp(a->name->value, "LandscapeOrientation") ||
+ !strcmp(a->name->value, "TTRasterizer") ||
+ !strcmp(a->name->value, "LanguageVersion") ||
+ !strcmp(a->name->value, "LanguageEncoding") ||
+ !strcmp(a->name->value, "ModelName") ||
+ !strcmp(a->name->value, "NickName") ||
+ !strcmp(a->name->value, "ShortNickName") ||
+ !strcmp(a->name->value, "cupsVersion") ||
+ a->name->value[0] == '?')
+ continue;
+
+ if (!a->selector->value || !a->selector->value[0])
+ cupsFilePrintf(fp, "*%s", a->name->value);
+ else if (!a->text->value || !a->text->value[0])
+ cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
+ else
+ cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
+ a->text->value);
+
+ if (strcmp(a->value->value, "False") &&
+ strcmp(a->value->value, "True") &&
+ strcmp(a->name->value, "1284Modes") &&
+ strcmp(a->name->value, "InkName") &&
+ strcmp(a->name->value, "PageStackOrder") &&
+ strncmp(a->name->value, "ParamCustom", 11) &&
+ strcmp(a->name->value, "Protocols") &&
+ strcmp(a->name->value, "ReferencePunch") &&
+ strncmp(a->name->value, "Default", 7))
+ {
+ cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
+ }
+ }
+
+ if (type != PPDC_DRIVER_PS || filters->count)
+ {
+ if ((a = find_attr("cupsVersion", NULL)) != NULL)
+ cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR,
+ CUPS_VERSION_MINOR, lf);
+ cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf);
+ cupsFilePrintf(fp, "*cupsManualCopies: %s%s",
+ manual_copies ? "True" : "False", lf);
+
+ if (filters->count)
+ {
+ for (f = (ppdcFilter *)filters->first();
+ f;
+ f = (ppdcFilter *)filters->next())
+ cupsFilePrintf(fp, "*cupsFilter: \"%s %d %s\"%s", f->mime_type->value,
+ f->cost, f->program->value, lf);
+ }
+ else
+ {
+ switch (type)
+ {
+ case PPDC_DRIVER_LABEL :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertolabel\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_EPSON :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertoepson\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_ESCP :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
+ "commandtoescpx\"%s", lf);
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertoescpx\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_HP :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertohp\"%s", lf);
+ break;
+
+ case PPDC_DRIVER_PCL :
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 "
+ "commandtopclx\"%s", lf);
+ cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 "
+ "rastertopclx\"%s", lf);
+ break;
+
+ default :
+ break;
+ }
+ }
+
+ for (p = (ppdcProfile *)profiles->first();
+ p;
+ p = (ppdcProfile *)profiles->next())
+ cupsFilePrintf(fp,
+ "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
+ "%.3f %.3f %.3f %.3f %.3f\"%s",
+ p->resolution->value, p->media_type->value,
+ p->density, p->gamma,
+ p->profile[0], p->profile[1],
+ p->profile[2], p->profile[3],
+ p->profile[4], p->profile[5],
+ p->profile[6], p->profile[7],
+ p->profile[8], lf);
+ }
+
+ if (locales)
+ {
+ // Add localizations for additional languages...
+ ppdcString *locale; // Locale name
+ ppdcCatalog *locatalog; // Message catalog for locale
+
+
+ // Write the list of languages...
+ cupsFilePrintf(fp, "*cupsLanguages: \"en");
+
+ for (locale = (ppdcString *)locales->first();
+ locale;
+ locale = (ppdcString *)locales->next())
+ {
+ // Skip (US) English...
+ if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
+ continue;
+
+ // See if we have a po file for this language...
+ if (!src->find_po(locale->value))
+ {
+ // No, see if we can use the base file?
+ locatalog = new ppdcCatalog(locale->value);
+
+ if (locatalog->messages->count == 0)
+ {
+ // No, skip this one...
+ fprintf(stderr, "ppdc: No message catalog provided for locale %s!\n",
+ locale->value);
+ continue;
+ }
+
+ // Add the base file to the list...
+ src->po_files->add(locatalog);
+ }
+
+ cupsFilePrintf(fp, " %s", locale->value);
+ }
+
+ cupsFilePrintf(fp, "\"%s", lf);
+ }
+
+ for (cn = (ppdcConstraint *)constraints->first();
+ cn;
+ cn = (ppdcConstraint *)constraints->next())
+ {
+ // First constrain 1 against 2...
+ if (!strncmp(cn->option1->value, "*Custom", 7) ||
+ !strncmp(cn->option2->value, "*Custom", 7))
+ cupsFilePrintf(fp, "*NonUIConstraints: ");
+ else
+ cupsFilePrintf(fp, "*UIConstraints: ");
+
+ if (cn->option1->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option1->value);
+
+ if (cn->choice1->value)
+ cupsFilePrintf(fp, " %s", cn->choice1->value);
+
+ cupsFilePutChar(fp, ' ');
+
+ if (cn->option2->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option2->value);
+
+ if (cn->choice2->value)
+ cupsFilePrintf(fp, " %s", cn->choice2->value);
+
+ cupsFilePrintf(fp, "%s", lf);
+
+ // Then constrain 2 against 1...
+ if (!strncmp(cn->option1->value, "*Custom", 7) ||
+ !strncmp(cn->option2->value, "*Custom", 7))
+ cupsFilePrintf(fp, "*NonUIConstraints: ");
+ else
+ cupsFilePrintf(fp, "*UIConstraints: ");
+
+ if (cn->option2->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option2->value);
+
+ if (cn->choice2->value)
+ cupsFilePrintf(fp, " %s", cn->choice2->value);
+
+ cupsFilePutChar(fp, ' ');
+
+ if (cn->option1->value[0] != '*')
+ cupsFilePutChar(fp, '*');
+
+ cupsFilePrintf(fp, cn->option1->value);
+
+ if (cn->choice1->value)
+ cupsFilePrintf(fp, " %s", cn->choice1->value);
+
+ cupsFilePuts(fp, lf);
+ }
+
+ // PageSize option...
+ cupsFilePrintf(fp, "*OpenUI *PageSize/Media Size: PickOne%s", lf);
+ cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageSize%s", lf);
+ cupsFilePrintf(fp, "*DefaultPageSize: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ if (m->size_code->value)
+ {
+ cupsFilePrintf(fp, "*PageSize %s/%s: \"%s\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->size_code->value, lf);
+
+ if (strchr(m->size_code->value, '\n') ||
+ strchr(m->size_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*PageSize %s/%s: \"<</PageSize[%.0f %.0f]"
+ "/ImagingBBox null>>setpagedevice\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PageSize", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PageSize: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *PageSize%s", lf);
+
+ // PageRegion option...
+ cupsFilePrintf(fp, "*OpenUI *PageRegion/Media Size: PickOne%s", lf);
+ cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageRegion%s", lf);
+ cupsFilePrintf(fp, "*DefaultPageRegion: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ if (m->region_code->value)
+ {
+ cupsFilePrintf(fp, "*PageRegion %s/%s: \"%s\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->region_code->value, lf);
+
+ if (strchr(m->region_code->value, '\n') ||
+ strchr(m->region_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*PageRegion %s/%s: \"<</PageSize[%.0f %.0f]"
+ "/ImagingBBox null>>setpagedevice\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PageRegion", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PageRegion: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *PageRegion%s", lf);
+
+ // ImageableArea info...
+ cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->left, m->bottom, m->width - m->right, m->length - m->top,
+ lf);
+
+ if ((a = find_attr("?ImageableArea", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?ImageableArea: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ // PaperDimension info...
+ cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
+ default_size ? default_size->value : "Letter", lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
+ m->name->value, catalog->find_message(m->text->value),
+ m->width, m->length, lf);
+
+ if ((a = find_attr("?PaperDimension", NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*?PaperDimension: \"%s\"%s", a->value->value, lf);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ // Custom size support...
+ if (variable_paper_size)
+ {
+ cupsFilePrintf(fp, "*MaxMediaWidth: \"%.2f\"%s", max_width, lf);
+ cupsFilePrintf(fp, "*MaxMediaHeight: \"%.2f\"%s", max_length, lf);
+ cupsFilePrintf(fp, "*HWMargins: %.2f %.2f %.2f %.2f\n",
+ left_margin, bottom_margin, right_margin, top_margin);
+
+ if (custom_size_code && custom_size_code->value)
+ {
+ cupsFilePrintf(fp, "*CustomPageSize True: \"%s\"%s",
+ custom_size_code->value, lf);
+
+ if (strchr(custom_size_code->value, '\n') ||
+ strchr(custom_size_code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+ else
+ cupsFilePrintf(fp,
+ "*CustomPageSize True: \"pop pop pop <</PageSize[5 -2 roll]"
+ "/ImagingBBox null>>setpagedevice\"%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Width")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
+ min_width, max_width, lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
+ lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
+ min_length, max_length, lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "HeightOffset")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf);
+
+ if ((a = find_attr("ParamCustomPageSize", "Orientation")) != NULL)
+ cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: %s%s",
+ a->value->value, lf);
+ else
+ cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
+ }
+
+ if (type != PPDC_DRIVER_PS && !find_attr("RequiresPageRegion", NULL))
+ cupsFilePrintf(fp, "*RequiresPageRegion All: True%s", lf);
+
+ // All other options...
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ {
+ if (!g->options->count)
+ continue;
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value,
+ catalog->find_message(g->text->value), lf);
+
+ for (o = (ppdcOption *)g->options->first();
+ o;
+ o = (ppdcOption *)g->options->next())
+ {
+ if (!o->choices->count)
+ continue;
+
+ if (!o->text->value || !strcmp(o->name->value, o->text->value))
+ cupsFilePrintf(fp, "*OpenUI *%s: ", o->name->value);
+ else
+ cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value,
+ catalog->find_message(o->text->value));
+
+ switch (o->type)
+ {
+ case PPDC_BOOLEAN :
+ cupsFilePrintf(fp, "Boolean%s", lf);
+ break;
+ default :
+ cupsFilePrintf(fp, "PickOne%s", lf);
+ break;
+ case PPDC_PICKMANY :
+ cupsFilePrintf(fp, "PickMany%s", lf);
+ break;
+ }
+
+ cupsFilePrintf(fp, "*OrderDependency: %.1f ", o->order);
+ switch (o->section)
+ {
+ default :
+ cupsFilePrintf(fp, "AnySetup");
+ break;
+ case PPDC_SECTION_DOCUMENT :
+ cupsFilePrintf(fp, "DocumentSetup");
+ break;
+ case PPDC_SECTION_EXIT :
+ cupsFilePrintf(fp, "ExitServer");
+ break;
+ case PPDC_SECTION_JCL :
+ cupsFilePrintf(fp, "JCLSetup");
+ break;
+ case PPDC_SECTION_PAGE :
+ cupsFilePrintf(fp, "PageSetup");
+ break;
+ case PPDC_SECTION_PROLOG :
+ cupsFilePrintf(fp, "Prolog");
+ break;
+ }
+
+ cupsFilePrintf(fp, " *%s%s", o->name->value, lf);
+
+ if (o->defchoice)
+ {
+ // Use the programmer-supplied default...
+ cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value,
+ o->defchoice->value, lf);
+ }
+ else
+ {
+ // Make the first choice the default...
+ c = (ppdcChoice *)o->choices->first();
+ cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, c->name->value,
+ lf);
+ }
+
+ for (c = (ppdcChoice *)o->choices->first();
+ c;
+ c = (ppdcChoice *)o->choices->next())
+ {
+ // Write this choice...
+ if (!c->text->value || !strcmp(c->name->value, c->text->value))
+ cupsFilePrintf(fp, "*%s %s: \"%s\"%s", o->name->value, c->name->value,
+ c->code->value, lf);
+ else
+ cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value,
+ c->name->value, catalog->find_message(c->text->value),
+ c->code->value, lf);
+
+ // Multi-line commands need a *End line to terminate them.
+ if (strchr(c->code->value, '\n') ||
+ strchr(c->code->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ snprintf(query, sizeof(query), "?%s", o->name->value);
+
+ if ((a = find_attr(query, NULL)) != NULL)
+ {
+ cupsFilePrintf(fp, "*%s: \"%s\"\n", query, a->value->value);
+
+ if (strchr(a->value->value, '\n') ||
+ strchr(a->value->value, '\r'))
+ cupsFilePrintf(fp, "*End%s", lf);
+ }
+
+ cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
+ }
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf);
+ }
+
+ if (locales)
+ {
+ // Add localizations for additional languages...
+ ppdcString *locale; // Locale name
+ ppdcCatalog *locatalog; // Message catalog for locale
+
+
+ // Write the translation strings for each language...
+ for (locale = (ppdcString *)locales->first();
+ locale;
+ locale = (ppdcString *)locales->next())
+ {
+ // Skip (US) English...
+ if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US"))
+ continue;
+
+ // Skip missing languages...
+ if ((locatalog = src->find_po(locale->value)) == NULL)
+ continue;
+
+ // Do the core stuff first...
+ cupsFilePrintf(fp, "*%s.Translation Manufacturer/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value), lf);
+
+ if ((a = find_attr("ModelName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("ShortNickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value), lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value), lf);
+
+ if ((a = find_attr("NickName", NULL)) != NULL)
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s",
+ locale->value,
+ locatalog->find_message(a->value->value), lf);
+ else if (strncasecmp(model_name->value, manufacturer->value,
+ strlen(manufacturer->value)))
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(manufacturer->value),
+ locatalog->find_message(model_name->value),
+ version->value, lf);
+ else
+ cupsFilePrintf(fp, "*%s.Translation NickName/%s, %s: \"\"%s",
+ locale->value,
+ locatalog->find_message(model_name->value),
+ version->value, lf);
+
+ // Then the page sizes...
+ cupsFilePrintf(fp, "*%s.Translation PageSize/%s: \"\"%s", locale->value,
+ locatalog->find_message("Media Size"), lf);
+
+ for (m = (ppdcMediaSize *)sizes->first();
+ m;
+ m = (ppdcMediaSize *)sizes->next())
+ {
+ cupsFilePrintf(fp, "*%s.PageSize %s/%s: \"\"%s", locale->value,
+ m->name->value, locatalog->find_message(m->text->value),
+ lf);
+ }
+
+ // Next the groups and options...
+ for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
+ {
+ if (!g->options->count)
+ continue;
+
+ if (strcasecmp(g->name->value, "General"))
+ cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
+ g->name->value,
+ locatalog->find_message(g->text->value), lf);
+
+ for (o = (ppdcOption *)g->options->first();
+ o;
+ o = (ppdcOption *)g->options->next())
+ {
+ if (!o->choices->count)
+ continue;
+
+ cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value,
+ o->name->value,
+ locatalog->find_message(o->text->value ?
+ o->text->value :
+ o->name->value), lf);
+
+ for (c = (ppdcChoice *)o->choices->first();
+ c;
+ c = (ppdcChoice *)o->choices->next())
+ {
+ // Write this choice...
+ cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"%s", locale->value,
+ o->name->value, c->name->value,
+ locatalog->find_message(c->text->value ?
+ c->text->value :
+ c->name->value), lf);
+ }
+ }
+ }
+
+ // Finally the localizable attributes...
+ for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+ {
+ if ((!a->text || !a->text->value || !a->text->value[0]) &&
+ strncmp(a->name->value, "Custom", 6) &&
+ strncmp(a->name->value, "ParamCustom", 11))
+ continue;
+
+ if (strcmp(a->name->value, "APCustomColorMatchingName") &&
+ strcmp(a->name->value, "APPrinterPreset") &&
+ strcmp(a->name->value, "cupsICCProfile") &&
+ strcmp(a->name->value, "cupsIPPReason") &&
+ strncmp(a->name->value, "Custom", 6) &&
+ strncmp(a->name->value, "ParamCustom", 11))
+ continue;
+
+ cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value,
+ a->name->value, a->selector->value,
+ locatalog->find_message(a->text && a->text->value ?
+ a->text->value : a->name->value),
+ !strcmp(a->name->value, "cupsIPPReason") ?
+ locatalog->find_message(a->value->value) : "",
+ lf);
+ }
+ }
+ }
+
+ if (default_font && default_font->value)
+ cupsFilePrintf(fp, "*DefaultFont: %s%s", default_font->value, lf);
+ else
+ cupsFilePrintf(fp, "*DefaultFont: Courier%s", lf);
+
+ for (fn = (ppdcFont *)fonts->first(); fn; fn = (ppdcFont *)fonts->next())
+ if (!strcmp(fn->name->value, "*"))
+ {
+ for (bfn = (ppdcFont *)src->base_fonts->first();
+ bfn;
+ bfn = (ppdcFont *)src->base_fonts->next())
+ cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
+ bfn->name->value, bfn->encoding->value,
+ bfn->version->value, bfn->charset->value,
+ bfn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
+ }
+ else
+ cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s",
+ fn->name->value, fn->encoding->value, fn->version->value,
+ fn->charset->value,
+ fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf);
+
+ cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value,
+ (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)),
+ lf);
+
+ if (delete_cat)
+ delete catalog;
+
+ return (0);
+}
+
+
+//
+// End of "$Id$".
+//
diff --git a/ppdc/ppdc-file.cxx b/ppdc/ppdc-file.cxx
new file mode 100644
index 000000000..3af0e4975
--- /dev/null
+++ b/ppdc/ppdc-file.cxx
@@ -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
index 000000000..bc33add84
--- /dev/null
+++ b/ppdc/ppdc-filter.cxx
@@ -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
index 000000000..85a719d7e
--- /dev/null
+++ b/ppdc/ppdc-font.cxx
@@ -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
index 000000000..c93fc20b1
--- /dev/null
+++ b/ppdc/ppdc-group.cxx
@@ -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
index 000000000..486f9b72c
--- /dev/null
+++ b/ppdc/ppdc-import.cxx
@@ -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
index 000000000..eb1f697e0
--- /dev/null
+++ b/ppdc/ppdc-mediasize.cxx
@@ -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
index 000000000..e0285d24f
--- /dev/null
+++ b/ppdc/ppdc-message.cxx
@@ -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
index 000000000..3eb46aaa6
--- /dev/null
+++ b/ppdc/ppdc-option.cxx
@@ -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
index 000000000..813339e7d
--- /dev/null
+++ b/ppdc/ppdc-profile.cxx
@@ -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
index 000000000..28874ddd5
--- /dev/null
+++ b/ppdc/ppdc-shared.cxx
@@ -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
index 000000000..c85dd6c60
--- /dev/null
+++ b/ppdc/ppdc-source.cxx
@@ -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
index 000000000..9b55d58eb
--- /dev/null
+++ b/ppdc/ppdc-string.cxx
@@ -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
index 000000000..6cea762ce
--- /dev/null
+++ b/ppdc/ppdc-variable.cxx
@@ -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
index 000000000..02852cabf
--- /dev/null
+++ b/ppdc/ppdc.cxx
@@ -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
index 000000000..ab67a36c3
--- /dev/null
+++ b/ppdc/ppdc.h
@@ -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
index 000000000..dd8512954
--- /dev/null
+++ b/ppdc/ppdhtml.cxx
@@ -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
index 000000000..2fe4a5feb
--- /dev/null
+++ b/ppdc/ppdi.cxx
@@ -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
index 000000000..598b4b8d6
--- /dev/null
+++ b/ppdc/ppdmerge.cxx
@@ -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
index 000000000..0ee273eb9
--- /dev/null
+++ b/ppdc/ppdpo.cxx
@@ -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$".
+//
diff --git a/scheduler/auth.c b/scheduler/auth.c
index d6c128293..ce62b7154 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -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 */
diff --git a/scheduler/auth.h b/scheduler/auth.h
index e1434400b..2679420f0 100644
--- a/scheduler/auth.h
+++ b/scheduler/auth.h
@@ -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);
diff --git a/scheduler/cert.h b/scheduler/cert.h
index bac490ae6..a6c24e86a 100644
--- a/scheduler/cert.h
+++ b/scheduler/cert.h
@@ -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);
/*
diff --git a/scheduler/client.c b/scheduler/client.c
index 706c31541..ada07dfea 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -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 */
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 977ef4352..d9f9b0524 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -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))
{
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 4f1ab36e8..764cc622a 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -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);
diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c
index 4f29c03d5..517a940a4 100644
--- a/scheduler/cups-driverd.c
+++ b/scheduler/cups-driverd.c
@@ -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",
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index 5e80e5578..0b68f781a 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -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
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 39ba5919b..6b964d845 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -7220,17 +7220,6 @@ move_job(cupsd_client_t *con, /* I - Client connection */
}
/*
- * 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...
*/
@@ -7338,6 +7327,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...
*/
diff --git a/scheduler/job.c b/scheduler/job.c
index 004ee5148..696d3721a 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -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);
diff --git a/scheduler/log.c b/scheduler/log.c
index bc113c634..77ab3e5e8 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -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
*/
diff --git a/scheduler/main.c b/scheduler/main.c
index 10303b909..613b593fb 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -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);
diff --git a/systemv/Dependencies b/systemv/Dependencies
index 08e10c1fd..263d3e753 100644
--- a/systemv/Dependencies
+++ b/systemv/Dependencies
@@ -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
diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c
index 0ab40ffe3..54b3b4c62 100644
--- a/systemv/cupstestppd.c
+++ b/systemv/cupstestppd.c
@@ -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>
diff --git a/templates/Makefile b/templates/Makefile
index b4fcc3735..2036534be 100644
--- a/templates/Makefile
+++ b/templates/Makefile
@@ -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
diff --git a/templates/classes.tmpl b/templates/classes.tmpl
index 08dda008e..e40103413 100644
--- a/templates/classes.tmpl
+++ b/templates/classes.tmpl
@@ -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>
diff --git a/templates/header.tmpl.in b/templates/header.tmpl.in
index 00c215e1f..ea1c47fe5 100644
--- a/templates/header.tmpl.in
+++ b/templates/header.tmpl.in
@@ -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}">:}
diff --git a/templates/printers.tmpl b/templates/printers.tmpl
index bf5427ee3..0b05f4318 100644
--- a/templates/printers.tmpl
+++ b/templates/printers.tmpl
@@ -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}