<?xml version="1.0"?>
<article id="index"><artheader><title>The Linux Printing HOWTO</title><author><firstname>Grant</firstname><surname>Taylor</surname><affiliation><address format="linespecific">     <email>gtaylor+pht@picante.com</email>
    </address></affiliation></author><pubdate>Version $Revision: 1.2 $, $Date: 2000/09/19 20:36:53 $</pubdate><abstract><para>     This is the Linux Printing HOWTO, a collection of information on
     how to generate, preview, print and fax anything under Linux (and
     other Unices in general).
   </para></abstract></artheader><sect1 id="howto-intro"><title>Introduction</title><para>    The Printing HOWTO should contain everything you need to know to
    help you set up printing services on your Linux box(en).  As life
    would have it, it's a bit more complicated than in the
    point-and-click world of Microsoft and Apple, but it's also a bit
    more flexible and certainly easier to administer for large LANs.
  </para><para>    This document is structured so that most people will only need to
    read the first half or so.  Most of the more obscure and
    situation-dependent information in here is in the last half, and
    can be easily located in the Table of Contents, whereas most of
    the information through section 8 or 9 is probably needed by most
    people.
  </para><para>    If you find this document or the <ulink url="http://www.linuxprinting.org/">LinuxPrinting.org</ulink>
    website useful, consider buying something through my referral
    association with buy.com or outpost.com; please use the links on
    the <ulink url="http://www.linuxprinting.org/suggested.html">suggested
    printers page</ulink> so that your purchase can be credited to
    LinuxPrinting.org.
  </para><para>    Since version 3.x is a complete rewrite, some information from
    previous editions has been lost.  This is by design, as the
    previous HOWTOs were so large as to be 60 typeset pages, and had
    the narrative flow of a dead turtle.  If you do not find your
    answers here, you are encouraged to a) look on the <ulink url="http://www.linuxprinting.org/">LinuxPrinting.org website</ulink>
    and b) drop me a note saying what ought to be here but isn't.
  </para><para>    The <ulink url="http://www.linuxprinting.org/">LinuxPrinting.org
    website</ulink> is a good place to find the latest version; it is
    also, of course, distributed from Metalab (<literal moreinfo="none" remap="tt">metalab.unc.edu</literal>) and your friendly local LDP
    mirror.
  </para><sect2 id="howto-hist"><title>History</title><para>    This is the fourth generation of the Printing HOWTO.  The history
    of the PHT may be chronicled thusly:

    <orderedlist inheritnum="ignore" continuation="restarts"><listitem><para>        I wrote the printing-howto in 1992 in response to too many
        printing questions in comp.os.linux, and posted it.  This
        predated the HOWTO project by a few months and was the first
        FAQlet called a `howto'.  This edition was in plain ascii.
      </para></listitem><listitem><para>       After joining the HOWTO project, the Printing-HOWTO was merged
       with an Lpd FAQ by Brian McCauley <literal moreinfo="none" remap="tt">B.A.McCauley@bham.ac.uk</literal>; we
       continued to co-author the PHT for two years or so.  At some
       point we incorporated the work of Karl Auer <literal moreinfo="none" remap="tt">Karl.Auer@anu.edu.au</literal>.  This
       generation of the PHT was in TeXinfo, and available in PS,
       HTML, Ascii, and Info.
      </para></listitem><listitem><para>       After letting the PHT rot and decay for over a year, and an
       unsuccessful attempt at getting someone else to maintain it,
       this rewrite happened.  This generation of the PHT is written
       in SGML using the LinuxDoc DTD and the SGML-Tools-1 package.
       Beginning with version 3.27, it incorporates a summary of a
       companion printer support database; before 3.27 there was never
       a printer compatibility list in this HOWTO (!).
      </para></listitem><listitem><para>       In mid-January, 2000, I found out about the PDQ print
       "spooler".  PDQ provides a printing mechanism so much better
       than lpd ever did that I spent several hours playing with it,
       rewrote parts of this HOWTO, and bumped the version number of
       the document to 4.
      </para></listitem><listitem><para>       In mid-2000, I moved my printing website to <literal moreinfo="none" remap="tt">www.linuxprinting.org</literal>, and began offering
       more powerful configuration tools there.  I also converted the
       HOWTO to DocBook, and initiated coverage of CUPS, LPRng, and
       GPR/libppd.
      </para></listitem></orderedlist>
   </para></sect2><sect2 id="howto-copy"><title>Copyright</title><para>    This document is Copyright (c) 1992-2000 by Grant Taylor.  Feel
    free to copy and redistribute this document according to the terms
    of the GNU General Public License, revision 2 or later.
   </para></sect2></sect1><sect1 id="quickstart"><title>Quick Start</title><para>   The quickest way to get started is simply to use the setup tools
   provided by your vendor.  Assuming that this includes support for
   your driver, and assuming that your vendor shipped the driver for
   your printer, then it should be easy to get a basic setup going
   this way.  For information on vendor-provided setup tools, see
   <xref linkend="vendors"></xref>.
  </para><para>   If your vendor's tool doesn't work out, you should
   figure out if your printer is supposed to work at all.  Consult the
   printer compatibility listings in <xref linkend="printer-compat-list"></xref> as well as the online version
   described there.
  </para><para>   If your printer is known to work with a driver, check that you have
   that driver, and install if it not.  Typically you will be able to
   find a contributed Ghostscript package including newer Ghostscript
   code and assorted third-party drivers.  If not, you can compile it
   yourself; the process is not trivial, but it is well documented.
   See <xref linkend="ghostscript"></xref> for more information on
   Ghostscript.
  </para><para>   After installing the proper driver, attempt again to configure your
   printer with your vendor's tools.  If that fails, select a
   suitable third party tool from those described in <xref linkend="setup"></xref>.  If that also fails, you'll need to construct
   your own setup; again see <xref linkend="setup"></xref>.
  </para><para>   If you're still stuck, you've got a little troubleshooting to do.
   It's probably best to read most of this document first to get a
   feel for how things are supposed to work; then you'll be in a
   better position to debug.
  </para></sect1><sect1 id="how"><title>How to print</title><para>   You actually use a different command to print depending on which
   spooling software you use. 
  </para><sect2 id="pdqintro"><indexterm significance="normal"><primary>PDQ</primary><secondary>usage</secondary></indexterm><title>With PDQ</title><para>    Most systems today ship with lpd, so this section won't apply.
    That said, I now recommend that people install and use PDQ in most
    cases instead of (or in addition to) lpd.  PDQ just has much
    better support for printer options and such.
   </para><para>    With PDQ, instead of the lpr command, you use the command <ulink url="http://feynman.tam.uiuc.edu/pdq/man/pdq.1.html">pdq</ulink>
    or <ulink url="http://feynman.tam.uiuc.edu/pdq/man/xpdq.1.html">xpdq</ulink>.  Both work much like the traditional lpr in that
    they will print the files you specify, or stdin if no files are
    given.
   </para><sect3 id="xpdq-intro"><indexterm significance="normal"><primary>xpdq</primary><secondary>usage</secondary></indexterm><indexterm significance="normal"><primary>xpdq</primary><seealso>PDQ</seealso></indexterm><title>Xpdq</title><para>     Xpdq is an X Windows application that shows a list of available
     printers and a summary of the print queue (including current and
     historical jobs).  There are two options under the File menu, one
     to print specific files, and one to print stdin.  You can set
     whatever options are defined in your printer driver from the
     Driver Options dialog; typically there will be duplex,
     resolution, paper type and size settings, and so forth.
    </para></sect3><sect3 id="pdq-intro"><title>Pdq</title><para>     The PDQ system's command-line printing command is simply called
     <command moreinfo="none">pdq</command>.  It can be used in place of the lpr
     command in most situations; it accepts the <literal moreinfo="none" remap="tt">-P</literal> printer specification argument.  Like
     lpr, it prints either the listed file(s) or stdin.
    </para><para>     Printer options can be controlled with the <literal moreinfo="none" remap="tt">-o</literal> and <literal moreinfo="none" remap="tt">-a</literal>
     options.
    </para></sect3></sect2><sect2 id="with-lpd-and-lpr"><indexterm significance="normal"><primary>lpr</primary><secondary>usage</secondary></indexterm><title>With LPD and the lpr command</title><para>    If you've already got lpd setup to print to your printer, or your
    system administrator already did so, or your vendor did so for
    you, then all you need to do is learn how to use the lpr command.
    The <ulink url="http://metalab.unc.edu/LDP/HOWTO/Printing-Usage-HOWTO.html">Printing Usage HOWTO</ulink> covers this, and a few other queue
    manipulation commands you should probably know.  Or just read the
    lpr(1) man page.
   </para><para>    In a nutshell, you specify the queue name with <literal moreinfo="none" remap="tt">-P</literal>, and specify a filename to print a file,
    or nothing to print from stdin.  Driver options are traditionally
    not controllable from lpr, but various systems accept certain
    options with <literal moreinfo="none" remap="tt">-o</literal>, <literal moreinfo="none" remap="tt">-Z</literal>, or <literal moreinfo="none" remap="tt">-J</literal>.
   </para><para>    If, however, you have a new system or new printer, then you'll
    have to set up printing services one way or another before you can
    print.  Read on!
   </para></sect2><sect2 id="how-with-gui-tools"><title>GUI Printing Tools</title><para>    Most spooling systems alone offer only a rather basic command-line
    interface.  Rather than use <command moreinfo="none">lpr</command> directly, you
    may wish to obtain and use a front-end interface.  These generally
    let you fiddle with various printing options (the printer, paper
    types, collation, n-up, etc) in an easy-to-use graphical way.
    Some may have other features, as well.
   </para><simplesect id="gpr-intro"><title>GPR</title><para>     <ulink url="http://www.compumetric.com/linux.html">GPR</ulink>,
     by Thomas Hubbell, uses code from CUPS to filter Postscript jobs
     and offer easy user control over job options.  Some options (like
     n-way printing, page selection, etc) are implemented directly by
     GPR, while most others are implemented by the printer or by the
     spooler's filter system.  
    </para><para>     GPR works with LPD or LPRng; or can be compiled specifically for
     use with VA Linux's modified LPD.  When compiled normally, it
     uses VA's libppd directly to produce printer-specific
     PostScript which it will then submit to the lpr command.  When
     compiled for VA's LPD, it will submit your unmodified job
     PostScript to the lpr command, along with the set of job options
     you specify.  This is arguably the better route, since it allows
     the Postscript to be redirected to a different printer by the
     spooler when appropriate; unfortunately it required VA's special
     LPD, which is not in wide circulation yet (although it is of
     course trivial to install).
    </para><para>     To use GPR, first select a
     printer (by LPD queue name) and check that GPR has loaded the
     proper PPD file.  If it hasn't, you'll need to specify the PPD
     filename, and specify your printer's options in the Printer
     Configuration dialog (you get this dialog by pressing the Printer
     Configuration button; it contains assorted printer setup options
     defined by the PPD).
    </para><para>     Once you've configured your printer in GPR, you can print jobs by
     specifying the filename and selecting the proper options from the
     `Common' and `Advanced' tabbed panels.  The `Common' options are
     implemented directly by GPR for all printers, while the
     `Advanced' options are defined by the PPD file for your printer.
     You can see these option panels in <xref linkend="snapshot-gpr-common"></xref> and <xref linkend="snapshot-gpr-printer"></xref>.
    </para><figure float="0" id="snapshot-gpr-main"><title>GPR Main Options</title><graphic fileref="snapshot-gpr-main" scale="60"></graphic></figure><figure float="0" id="snapshot-gpr-common"><title>GPR Common Options</title><graphic fileref="snapshot-gpr-common" scale="60"></graphic></figure><figure float="0" id="snapshot-gpr-printer"><title>GPR Printer Options</title><graphic fileref="snapshot-gpr-printer" scale="60"></graphic></figure></simplesect><simplesect id="xpp-sect"><title>XPP</title><indexterm significance="normal"><primary>XPP</primary></indexterm><para>     If you use CUPS as your spooler, you can use the program
     <command moreinfo="none"><ulink url="http://www.phy.uni-bayreuth.de/till/xpp/">XPP</ulink></command> (see <xref linkend="snapshot-xpp-main"></xref>).
    </para><para>     To print with XPP, simply run the xpp program, and specify a file
     (or nothing, if you're using xpp in place of lpr to print from
     stdin).  Then select a printer from the list of configured
     printers, and select any options you'd like to apply from the
     various tabbed panels.  See <xref linkend="snapshot-xpp-options"></xref>
     for an example options panel highlighting the standard CUPS
     options.
    </para><para>     You can save your selected printer and all the options with the
     `Save Settings' button.
    </para><figure float="0" id="snapshot-xpp-main"><title>XPP Main Window</title><graphic fileref="snapshot-xpp-main" scale="60"></graphic></figure><figure float="0" id="snapshot-xpp-options"><title>CUPS/XPP Options Window</title><graphic fileref="snapshot-xpp-options" scale="60"></graphic></figure></simplesect><simplesect><title>XPDQ</title><para>     PDQ can be easily configured to print to queues controlled by
     most spooling systems, and PDQ's configuration syntax offers a
     very easy way to define arbitrary filtering and user options for
     print jobs.  So you can thus use <command moreinfo="none">xpdq</command> as a
     front-end to LPD printing with great success.
    </para><para>     For more information, see <xref linkend="pdq-which-spooler"></xref>.
    </para></simplesect></sect2></sect1><sect1 id="kernel"><indexterm significance="normal"><primary>ports</primary></indexterm><title>Kernel printer devices</title><indexterm significance="normal"><primary>drivers</primary><secondary>port</secondary><seealso>ports</seealso></indexterm><para>   There are two completely different device drivers for the parallel
   port; which one you are using depends on your kernel version (which
   you can find out with the command <literal moreinfo="none" remap="tt">uname
   -a</literal>).  The driver changed in Linux 2.1.33; essentially all
   current systems will be running kernel 2.2 or later, so you'll
   probably want to skip ahead to the parport driver section.
  </para><para>   A few details are the same for both styles of driver.  Most
   notably, many people have found that Linux will not detect their
   parallel port unless they disable "Plug and Play" in their PC BIOS.
   (This is no surprise; the track record for PnP of non-PCI devices
   with Windows and elsewhere has been something of a disaster).
  </para><sect2 id="old-lp-device"><indexterm significance="normal"><primary>ports</primary><secondary>parallel</secondary></indexterm><title>The lp device (kernels =2.1.32)</title><para>    The Linux kernel (=2.1.32), assuming you have compiled in or
    loaded the lp device (the output of <literal moreinfo="none" remap="tt">cat
    /proc/devices</literal> should include the device lp if it is
    loaded), provides one or more of <emphasis>/dev/lp0</emphasis>,
    <emphasis>/dev/lp1</emphasis>, and <emphasis>/dev/lp2</emphasis>.
    These are NOT assigned dynamically, rather, each corresponds to a
    specific hardware I/O address.  This means that your first printer
    may be <emphasis>lp0</emphasis> or <emphasis>lp1</emphasis>
    depending on your hardware.  Just try both.
   </para><para>    A few users have reported that their bidirectional lp ports aren't
    detected if they use an older unidirectional printer cable.  Check
    that you've got a decent cable.
   </para><para>    One cannot run the plip and lp drivers at the same time on any
    given port (under 2.0, anyway).  You can, however, have one or the
    other driver loaded at any given time either manually, or by
    kerneld with version 2.x (and later 1.3.x) kernels.  By carefully
    setting the interrupts and such, you can supposedly run plip on
    one port and lp on the other.  One person did so by editing the
    drivers; I eagerly await a success report of someone doing so with
    only a clever command line.
   </para><para>    There is a little utility called <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/tunelp.8.html">tunelp</ulink></literal> floating about with which you, as root, can tune the
    Linux 2.0 lp device's interrupt usage, polling rate, and other
    options.
   </para><para>    When the lp driver is built into the kernel, the kernel will
    accept an <literal moreinfo="none" remap="tt">lp=</literal> option to set
    interrupts and io addresses:

<screen format="linespecific">When the lp driver is built in to the kernel, you may use the
LILO/LOADLIN command line to set the port addresses and interrupts
that the driver will use.

Syntax:      lp=port0[,irq0[,port1[,irq1[,port2[,irq2]]]]]

For example:   lp=0x378,0   or   lp=0x278,5,0x378,7 **

Note that if this feature is used, you must specify *all* the ports
you want considered, there are no defaults.  You can disable a
built-in driver with lp=0.</screen>

   </para><para>    When loaded as a module, it is possible to specify io addresses
    and interrupt lines on the insmod command line (or in
    <emphasis>/etc/conf.modules</emphasis> so as to affect kerneld)
    using the usual module argument syntax.  The parameters are
    <literal moreinfo="none" remap="tt">io=port0,port1,port2</literal> and <literal moreinfo="none" remap="tt">irq=irq0,irq1,irq2</literal>.  Read ye the man page for
    <emphasis><ulink url="http://www.linuxprinting.org/man/insmod.1.html">insmod</ulink></emphasis> for more information on this.
   </para><para>    **For those of you who (like me) can never find the standard port
    numbers when you need them, they are as in the second example
    above.  The other port (<emphasis>lp0</emphasis>) is at 0x3bc.
    I've no idea what interrupt it usually uses.
   </para><para>    The source code for the Linux 2.0 parallel port driver is in
    /usr/src/linux/drivers/char/lp.c.
   </para></sect2><sect2 id="new-parport-device"><indexterm significance="normal"><primary>ports</primary><secondary>parallel</secondary></indexterm><title>The parport device (kernels = 2.1.33)</title><para>    Beginning with kernel 2.1.33 (and available as a patch for kernel
    2.0.30), the lp device is merely a client of the new parport
    device.  The addition of the parport device corrects a number of
    the problems that plague the old lp device driver - it can share
    the port with other drivers, it dynamically assigns available
    parallel ports to device numbers rather than enforcing a fixed
    correspondence between I/O addresses and port numbers, and so
    forth.
   </para><para>    The advent of the parport device has enabled a whole flock of new
    parallel-port drivers for things like Zip drives, Backpack CD-ROMs
    and disks, and so forth.  Some of these are also available in
    versions for 2.0 kernels; look around on the web.
   </para><para>    The main difference that you will notice, so far as printing goes,
    is that parport-based kernels dynamically assign lp devices to
    parallel ports.  So what was lp1 under Linux 2.0 may well be lp0
    under Linux 2.2.  Be sure to check this if you upgrade from an
    lp-driver kernel to a parport-driver kernel.
   </para><para>    The most popular problems with this device seems to stem from
    misconfiguration:
    <variablelist><varlistentry><term>The Distribution</term><listitem><para>Some Linux distributions don't ship with a properly setup
        /etc/modules.conf (or /etc/conf.modules), so the driver isn't
        loaded properly when you need it to be.  With a recent
        modutils, the proper magical lines from modules.conf seem to
        be:

<screen format="linespecific">  alias /dev/printers lp             # only for devfs?
  alias /dev/lp*      lp             # only for devfs?
  alias parport_lowlevel parport_pc  # missing in Red Hat 6.0-6.1</screen>

       </para></listitem></varlistentry><varlistentry><term>The BIOS</term><listitem><para>Many PC BIOSes will make the parallel port into a
        Plug-and-Play device.  This just adds needless complexity to a
        perfectly simple device that is nearly always present; turn
        off the PnP setting for your parallel prot ("LPT1" in many
        BIOSes) if your parallel port isn't detected by the Linux
        driver.  The correct setting is often called "legacy", "ISA",
        or "0x378", but probably not "disabled".
       </para></listitem></varlistentry></variablelist>
   </para><para>    You can also read the  <ulink url="http://people.redhat.com/twaugh/parport/html/parportguide.html">parport documentation</ulink> in your kernel sources, or
    look at the <ulink url="http://people.redhat.com/twaugh/parport/">parport web
    site</ulink>.
   </para></sect2><sect2 id="serial-devices"><indexterm significance="normal"><primary>ports</primary><secondary>serial</secondary></indexterm><title>Serial devices</title><para>    Serial devices are usually called something like
    <emphasis>/dev/ttyS1</emphasis> under Linux.  The utility <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/stty.1.html">stty</ulink></literal> will allow you to interactively view or
    set the settings for a serial port; <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/setserial.8.html">setserial</ulink></literal> will allow you to control a few
    extended attributes and configure IRQs and I/O addresses for
    non-standard ports.  Further discussion of serial ports under
    Linux may be found in the <ulink url="http://metalab.unc.edu/mdw/HOWTO/Serial-HOWTO.html">Serial-HOWTO</ulink>.
   </para><para>    When using a slow serial printer with flow control, you may find
    that some of your print jobs get truncated.  This may be due to
    the serial port, whose default behavior is to purge any
    untransmitted characters from its buffer 30 seconds after the port
    device is closed.  The buffer can hold up to 4096 characters, and
    if your printer uses flow control and is slow enough that it can't
    accept all the data from the buffer within 30 seconds after
    printing software has closed the serial port, the tail end of the
    buffer's contents will be lost.  If the command <literal moreinfo="none" remap="tt">cat file  /dev/ttyS2</literal> produces complete
    printouts for short files but truncated ones for longer files, you
    may have this condition.
   </para><para>    The 30 second interval can be adjusted through the
    "closingwait" commandline option of setserial (version
    2.12 and later).  A machine's serial ports are usually initialized
    by a call to setserial in the rc.serial boot file.  The call for
    the printing serial port can be modified to set the
    closingwait at the same time as it sets that port's other
    parameters.
   </para></sect2><sect2 id="usb-devices"><indexterm significance="normal"><primary>ports</primary><secondary>USB</secondary></indexterm><title>USB Devices</title><para>    I don't have any USB devices to play with, so all I can offer are
    pointers.  Once set up, you end up with the device file
    <filename moreinfo="none">/dev/usb/lp0</filename>, much as you do with parallel
    ports, which will work fine in printcap or as a PDQ local-port
    device.
   </para><para>    USB is documented at the <ulink url="http://www.linux-usb.org/">Linux USB Website</ulink>.
   </para></sect2></sect1><sect1 id="printers"><title>Supported Printers</title><para>   The Linux kernel will let you speak with any printer that you can
   plug into a serial, parallel, or usb port, plus any printer on the
   network, but this alone is insufficient; you must also be able to
   generate data that the printer will understand.  Primary among the
   incompatible printers are those referred to as "Windows" or "GDI"
   printers.  They are called this because all or part of the printer
   control language and the design details of the printing mechanism
   are not documented.  Typically the vendor will provide a Windows
   driver and happily sell only to Windows users; this is why they are
   called Winprinters.  In some cases the vendor also provides drivers
   for NT, OS/2, or other operating systems.
  </para><indexterm significance="normal"><primary>winprinters</primary></indexterm><para>   Many of these printers <emphasis>do not work</emphasis> with Linux.
   A few of them do, and some of them only work a little bit (usually
   because someone has reverse engineered the details needed to write
   a driver).  See the printer support list below for details on
   specific printers.
  </para><para>   A few printers are in-between.  Some of NEC's models, for example,
   implement a simple form of the standard printer language PCL that
   allows PCL-speaking software to print at up to 300dpi, but only NEC
   knows how to get the full 600dpi out of these printers.
  </para><para>   Note that if you already have one of these Winprinters, there are
   roundabout ways to get Linux to print to one, but they're rather
   awkward.  See <xref linkend="winprinters"></xref> in this
   document for more discussion of Windows-only printers.
  </para><sect2 id="supported-printers-postscript"><indexterm significance="normal"><primary>Postscript</primary></indexterm><indexterm significance="normal"><primary>Postscript</primary><secondary>printers</secondary></indexterm><title>Postscript</title><para>    As for what printers <emphasis>do</emphasis> work with Linux, the
    best choice is to buy a printer with native PostScript support
    <emphasis>in firmware</emphasis>.  Nearly all Unix software that
    produces printable output produces it in PostScript, so obviously
    it'd be nice to get a printer that supports PostScript directly.
    Unfortunately, PostScript support is scarce outside the laser
    printer domain, and is sometimes a costly add-on.
   </para><para>    Unix software, and the publishing industry in general, have
    standardized upon Postscript as the printer control language of
    choice.  This happened for several reasons:
    <variablelist><varlistentry><term>Timing</term><listitem><para>Postscript arrived as part of the Apple Laserwriter, a
        perfect companion to the Macintosh, the system largely
        responsible for the desktop publishing revolution of the 80s.
       </para></listitem></varlistentry><varlistentry id="pdf-description"><indexterm significance="normal"><primary>PDF</primary></indexterm><term>It's device-independent</term><listitem><para>Postscript programs can be run to generate output on a
        pixel screen, a vector screen, a fax machine, or almost any
        sort of printer mechanism, without the original program
        needing to be changed.  Postscript output will look the same
        on any Postscript device, at least within the limits of the
        device's capabilities.  Before the creation of PDF, people
        exchanged complex documents online as Postscript files.  The
        only reason this standard didn't "stick" was because Windows
        machines didn't usually include a Postscript previewer, so
        Adobe specified hyperlinks and compression for Postscript,
        called the result PDF, distributed previewers for it, and
        invented a market for their "distiller" tools (the
        functionality of which is also provided by ghostscript's
        ps2pdf and pdf2ps programs).
       </para></listitem></varlistentry><varlistentry><term>It's a real programming language</term><listitem><para>Postscript is a complete programming language; you can
        write software to do most anything in it.  This is mostly
        useful for defining subroutines at the start of your program
        to reproduce complex things over and over throughout your
        document, like a logo or a big "DRAFT" in the background.  But
        there's no reason you couldn't compute in a Postscript
        program.
       </para></listitem></varlistentry><varlistentry><term>It's open</term><listitem><para>Postscript is fully specified in a publically available
        series of books (which you can find at any good bookstore).
        Although Adobe invented it and provides the dominant
        commercial implementation, other vendors like Aladdin produce
        independently coded implementations as well.
       </para></listitem></varlistentry></variablelist>
   </para></sect2><sect2 id="non-ps-printers"><title>Non-Postscript</title><para>    Failing the (larger) budget necessary to buy a Postscript printer,
    you can use any printer supported by Ghostscript, the free
    Postscript interpreter used in lieu of actual printer Postscript
    support.  Note that most Linux distributions can only ship a
    somewhat outdated version of Ghostscript due to the license.
    Fortunately, there is usually a prepackaged up to date Ghostscript
    made available in each distribution's contrib area.  
   </para><para>    Adobe now has a new printer language called "PrintGear".  I think
    it's a greatly simplified binary format language with some
    Postscript heritage but no Postscript compatibility.  And I
    haven't heard of Ghostscript supporting it.  But some PrintGear
    printers seem to support another language like PCL, and these
    printers will work with Linux (iff the PCL is implemented in the
    printer and not in a Windows driver).
   </para><para>    Similarly, Adobe offers a host-based Postscript implementation
    called <productname class="trade">PressReady</productname>.  This works much
    like Ghostscript does to provide Postscript support for a
    non-Postscript printer, but has the disadvantage that it runs only
    on Windows.
  </para></sect2><sect2 id="what-printers-work"><indexterm significance="normal"><primary>printers</primary><secondary>buying</secondary></indexterm><title>What printers work?</title><para>    If you want to buy a printer, you can look in several places to
    see if it will work.  The cooperatively maintained Printing HOWTO
    printer <ulink url="http://www.linuxprinting.org/database.html">database</ulink> aims to be a comprehensive listing of the state
    of Linux printer support.  A summary of it is below; be sure to
    check online for more details and information on what driver(s) to
    use.
   </para><para>    Ghostscript's <ulink url="http://www.cs.wisc.edu/~ghost/printer.html">printer
    compatibility page</ulink> has a list of some working printers,
    as well as links to other pages.
   </para><para>    <ulink url="http://www.deja.com/usenet/">Dejanews</ulink>
    contains hundreds of "it works" and "it doesn't work"
    testimonials.  Try all three, and when you're done, check that
    your printer is present and correct in the <ulink url="http://www.linuxprinting.org/database.html">database</ulink>, so that it will be listed properly in this document in the
    future.
   </para><para>    If you're lazy, I keep a short list of <ulink url="http://www.linuxprinting.org/suggested.html">suggested
    printers</ulink> on my website.  These center around color inkjets and
    low-cost laser devices; fully compatible mid-range and high-end
    devices are much easier to find.  You can even help support this
    document and the website by buying from buy.com or outpost.com
    through me.
   </para><sect3 id="printer-compat-list"><indexterm significance="normal"><primary>drivers</primary><secondary>printer</secondary></indexterm><title>Printer compatibility list</title><para>     This section is a summary of the <ulink url="http://www.linuxprinting.org/database.html">online
     database</ulink>.  The online version includes device
     specifications, notes, driver information, user-maintained
     documentation, manufacturer web pages, and interface scripts for
     using drivers with several print spooling systems (including LPR,
     LPRng, PDQ, and CUPS).  The online version of this list is also
     interactive; people can and do add printers all the time, so be
     sure to check it as well.  Finally, if your printer isn't listed,
     add it!
    </para><para>     Note that this listing is not gospel; people sometimes add
     incorrect information, which I eventually weed out.  Entries I
     have not sanity-checked are marked with an asterisk (*).  Verify
     from Dejanews that a printer works for someone before buying it
     based on this list.  If you can find no information in Dejanews,
     mail me and I'll put you in contact with the person who added the
     printer.
    </para><para>     Printers here are categorized into three types:
     <variablelist><varlistentry><term>Perfectly</term><listitem><para>Perfect printers work perfectly - you can print to the full
         ability of the printer, including color, full resolution, etc.
         In a few cases printers with undocumented "resolution
         enhancement" modes that don't work are listed as perfect;
         generally the difference in print quality is small enough that
         it isn't worth worrying about.
        </para></listitem></varlistentry><varlistentry><term>Mostly</term><listitem><para>You can print fine, but there may be minor limitations of one
         sort or another in either printing or other features.
        </para></listitem></varlistentry><varlistentry><term>Partially</term><listitem><para>You can print, but maybe not in color, or only at a poor
         resolution.  See the online listing for information on the
         limitation.
        </para></listitem></varlistentry><varlistentry><term>Paperweight</term><listitem><para>You can't print a darned thing; typically this will be due to
         lack of a driver and/or documentation on how to write one.
         Paperweights occasionally get "promoted", either when someone
         discovers that an existing driver works, or when someone
         creates a new driver, but you shouldn't count on this
         happening.
        </para></listitem></varlistentry></variablelist>

     In all cases, since this information is provided by dozens of
     people, none of it is guaranteed to be correct; entries with an
     asterisk (*) are particularly suspect.  The facts, however, should
     be easy to corroborate from the driver web pages and manufacturer
     web sites.
    </para><para>     And without further ado, here is the printer compatibility list:
<table><title>Linux Printer Support</title><tgroup cols="5"><thead><row><entry><simpara>Manufacturer</simpara></entry><entry><simpara>Perfectly</simpara></entry><entry><simpara>Mostly</simpara></entry><entry><simpara>Partially</simpara></entry><entry><simpara>Paperweight</simpara></entry></row></thead><tbody><row><entry><simpara>Alps</simpara></entry><entry></entry><entry></entry><entry><simplelist type="vert"><member>MD-1000</member><member>MD-1300</member><member>MD-2000</member><member>MD-4000</member><member>MD-5000</member></simplelist></entry><entry></entry></row><row><entry><simpara>Apollo</simpara></entry><entry></entry><entry><simplelist type="vert"><member>P-1200</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Apple</simpara></entry><entry><simplelist type="vert"><member>12/640ps</member><member>Dot Matrix</member><member>ImageWriter</member><member>ImageWriter LQ</member><member>LaserWriter 16/600*</member><member>LaserWriter IINTX*</member><member>LaserWriter IIg</member><member>LaserWriter Select 360</member></simplelist></entry><entry><simplelist type="vert"><member>Color StyleWriter 1500</member><member>Color StyleWriter 2200</member><member>Color StyleWriter 2400</member><member>Color StyleWriter 2500</member><member>LaserWriter NT</member><member>StyleWriter 1200</member><member>StyleWriter I</member><member>StyleWriter II</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Avery</simpara></entry><entry><simplelist type="vert"><member>Personal Label Printer+</member></simplelist></entry><entry><simplelist type="vert"><member>Personal Label Printer</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Brother</simpara></entry><entry><simplelist type="vert"><member>HL-4Ve</member><member>HL-8</member><member>HL-10V</member><member>HL-10h</member><member>HL-630</member><member>HL-660</member><member>HL-720</member><member>HL-730</member><member>HL-760</member><member>HL-820</member><member>HL-1020</member><member>HL-1040</member><member>HL-1070*</member><member>HL-1250</member><member>HL-1260</member><member>HL-1270N</member><member>HL-1660e</member><member>HL-2060</member></simplelist></entry><entry><simplelist type="vert"><member>HJ-400</member><member>HL-1050</member><member>HL-1060</member><member>HL-1240</member></simplelist></entry><entry><simplelist type="vert"><member>DCP-1200</member><member>HL-1030*</member><member>MC-3000</member><member>MFC 7150C</member><member>MFC-4350</member><member>MFC-6550MC</member><member>MFC-8300</member><member>MFC-9100c</member><member>MFC-9500</member><member>MFC-9600</member></simplelist></entry><entry><simplelist type="vert"><member>4550*</member><member>MP-21C</member></simplelist></entry></row><row><entry><simpara>C.Itoh</simpara></entry><entry><simplelist type="vert"><member>M8510</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>CalComp</simpara></entry><entry><simplelist type="vert"><member>Artisan 1023 penplotter*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Canon</simpara></entry><entry><simplelist type="vert"><member>BJ-5</member><member>BJ-10e</member><member>BJ-20</member><member>BJ-200</member><member>BJ-330</member><member>BJC-70</member><member>BJC-210</member><member>BJC-250</member><member>BJC-600</member><member>BJC-610</member><member>BJC-620</member><member>BJC-800</member><member>BJC-4000</member><member>BJC-4100</member><member>BJC-4200</member><member>BJC-4300*</member><member>BJC-4400*</member><member>GP 335</member><member>GP 405</member><member>LBP-4+</member><member>LBP-4U</member><member>LBP-8A1</member><member>LBP-430</member><member>LBP-1260</member><member>LBP-1760</member><member>LIPS-III</member></simplelist></entry><entry><simplelist type="vert"><member>BJC-80</member><member>BJC-240</member><member>BJC-1000*</member><member>BJC-2000*</member><member>BJC-2100</member><member>BJC-3000</member><member>BJC-4310SP</member><member>BJC-7004*</member><member>LBP-4sx</member></simplelist></entry><entry><simplelist type="vert"><member>BJ-300</member><member>BJC-210SP</member><member>BJC-4550</member><member>BJC-6000*</member><member>BJC-6100</member><member>BJC-7000*</member><member>BJC-7100*</member><member>BJC-8200</member><member>MultiPASS C2500*</member><member>MultiPASS C3000</member><member>MultiPASS C3500*</member><member>MultiPASS C5000*</member><member>MultiPASS C5500</member></simplelist></entry><entry><simplelist type="vert"><member>BJC-5000</member><member>BJC-5100</member><member>BJC-6500</member><member>BJC-8000</member><member>LBP-460*</member><member>LBP-600</member><member>LBP-660*</member><member>Multipass L6000*</member></simplelist></entry></row><row><entry><simpara>Citizen</simpara></entry><entry><simplelist type="vert"><member>ProJet II*</member><member>ProJet IIc</member></simplelist></entry><entry><simplelist type="vert"><member>printiva600C</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Compaq</simpara></entry><entry></entry><entry></entry><entry><simplelist type="vert"><member>IJ300</member><member>IJ750</member><member>IJ900</member></simplelist></entry><entry></entry></row><row><entry><simpara>DEC</simpara></entry><entry><simplelist type="vert"><member>DECWriter 500i*</member><member>DECwriter 110i*</member><member>DECwriter 520ic*</member><member>LA50*</member><member>LA75*</member><member>LA75 Plus*</member><member>LN03*</member><member>LN07*</member></simplelist></entry><entry><simplelist type="vert"><member>LJ250*</member><member>LN17</member></simplelist></entry><entry><simplelist type="vert"><member>1800*</member></simplelist></entry><entry></entry></row><row><entry><simpara>Dymo-CoStar</simpara></entry><entry><simplelist type="vert"><member>ASCII 250*</member><member>ASCII+*</member><member>EL40*</member><member>EL60*</member><member>LabelWriter II*</member><member>LabelWriter XL*</member><member>LabelWriter XL+*</member><member>SE250*</member><member>SE250+*</member><member>Turbo*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Epson</simpara></entry><entry><simplelist type="vert"><member>Action Laser II</member><member>ActionLaser 1100*</member><member>ActionPrinter 3250</member><member>Dot Matrix</member><member>L-1000*</member><member>LP 8000</member><member>LQ-24</member><member>LQ-500</member><member>LQ-570+</member><member>LQ-850</member><member>LQ-2550</member><member>LX-1050</member><member>SQ 1170</member><member>Stylus Color</member><member>Stylus Color 400</member><member>Stylus Color 440</member><member>Stylus Color 460</member><member>Stylus Color 480</member><member>Stylus Color 500</member><member>Stylus Color 600</member><member>Stylus Color 640</member><member>Stylus Color 660</member><member>Stylus Color 740</member><member>Stylus Color 760</member><member>Stylus Color 800</member><member>Stylus Color 860</member><member>Stylus Color 880</member><member>Stylus Color 900</member><member>Stylus Color 980</member><member>Stylus Color 1160</member><member>Stylus Color 1500</member><member>Stylus Color 1520</member><member>Stylus Color 3000</member><member>Stylus Color I</member><member>Stylus Color PRO</member><member>Stylus Photo</member><member>Stylus Photo 700</member><member>Stylus Photo 720</member><member>Stylus Photo 750</member><member>Stylus Photo 870</member><member>Stylus Photo 1200</member><member>Stylus Photo 1270</member><member>Stylus Photo EX</member></simplelist></entry><entry><simplelist type="vert"><member>EPL-5700</member><member>Stylus Color 300</member><member>Stylus Color 670*</member><member>Stylus Color 850</member><member>Stylus Color II</member><member>Stylus Color IIs</member><member>Stylus Pro XL</member></simplelist></entry><entry><simplelist type="vert"><member>Stylus Photo 2000P</member></simplelist></entry><entry><simplelist type="vert"><member>EPL-5700L</member></simplelist></entry></row><row><entry><simpara>Fujitsu</simpara></entry><entry><simplelist type="vert"><member>1200*</member><member>2400*</member><member>3400*</member><member>PrintPartner 10V*</member><member>PrintPartner 16DV*</member><member>PrintPartner 20W*</member><member>PrintPartner 8000*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>HP</simpara></entry><entry><simplelist type="vert"><member>2000C</member><member>2500C</member><member>Color LaserJet 4500</member><member>DesignJet 3500CP</member><member>DeskJet</member><member>DeskJet 400</member><member>DeskJet 420C</member><member>DeskJet 500</member><member>DeskJet 500C</member><member>DeskJet 510</member><member>DeskJet 520</member><member>DeskJet 540</member><member>DeskJet 550C</member><member>DeskJet 560C</member><member>DeskJet 600</member><member>DeskJet 1200C</member><member>DeskJet 1600C</member><member>DeskJet 1600CM</member><member>LaserJet</member><member>LaserJet 2 w/PS*</member><member>LaserJet 2D</member><member>LaserJet 2P</member><member>LaserJet 2P Plus</member><member>LaserJet 3</member><member>LaserJet 3D</member><member>LaserJet 3P w/PS</member><member>LaserJet 4 Plus</member><member>LaserJet 4L</member><member>LaserJet 4M</member><member>LaserJet 4ML*</member><member>LaserJet 4P</member><member>LaserJet 5</member><member>LaserJet 5L*</member><member>LaserJet 5M*</member><member>LaserJet 5MP*</member><member>LaserJet 5P*</member><member>LaserJet 6</member><member>LaserJet 6L*</member><member>LaserJet 6MP*</member><member>LaserJet 1100</member><member>LaserJet 2100</member><member>LaserJet 2100M</member><member>LaserJet 4050N</member><member>LaserJet 5000</member><member>LaserJet 8000</member><member>LaserJet 8100</member><member>LaserJet Plus*</member><member>LaserJet Series II*</member><member>Mopier 240*</member><member>Mopier 320*</member><member>PaintJet*</member><member>PaintJet XL*</member><member>PaintJet XL300*</member><member>ThinkJet*</member></simplelist></entry><entry><simplelist type="vert"><member>Color LaserJet 5</member><member>DesignJet 230*</member><member>DesignJet 350C</member><member>DesignJet 650C*</member><member>Designjet 750 C Plus*</member><member>DeskJet 310</member><member>DeskJet 610C</member><member>DeskJet 610CL</member><member>DeskJet 612C</member><member>DeskJet 660C</member><member>DeskJet 670C</member><member>DeskJet 672C</member><member>DeskJet 682C</member><member>DeskJet 690C</member><member>DeskJet 692C</member><member>DeskJet 694C</member><member>DeskJet 697C</member><member>DeskJet 710C*</member><member>DeskJet 712C</member><member>DeskJet 720C*</member><member>DeskJet 722C*</member><member>DeskJet 810C</member><member>DeskJet 812C</member><member>DeskJet 815C*</member><member>DeskJet 820C</member><member>DeskJet 832C</member><member>DeskJet 840C</member><member>DeskJet 842C*</member><member>DeskJet 850C</member><member>DeskJet 855C</member><member>DeskJet 870C</member><member>DeskJet 870Cse*</member><member>DeskJet 870Cxi</member><member>DeskJet 880C</member><member>DeskJet 882C</member><member>DeskJet 895C</member><member>DeskJet 895Cxi*</member><member>DeskJet 932C</member><member>DeskJet 950C*</member><member>DeskJet 970C</member><member>DeskJet 970Cse</member><member>DeskJet 1100C</member><member>DeskJet 1120C</member><member>DeskJet 1220C</member><member>LaserJet 2</member><member>LaserJet 6P</member><member>LaserJet 4000</member><member>PSC 500*</member></simplelist></entry><entry><simplelist type="vert"><member>Color LaserJet 5000</member><member>DeskJet 320</member><member>DeskJet 340C</member><member>DeskJet 890C</member><member>DeskJet 930C</member><member>DeskJet 1000C</member><member>LaserJet 1100A</member><member>OfficeJet 500*</member><member>OfficeJet 600*</member><member>OfficeJet 625*</member><member>OfficeJet 635*</member><member>OfficeJet 710*</member><member>OfficeJet Pro 1170C*</member><member>OfficeJet Pro 1175C*</member><member>OfficeJet R45*</member><member>OfficeJet R60</member><member>PhotoSmart P1000</member><member>PhotoSmart P1100*</member></simplelist></entry><entry><simplelist type="vert"><member>LaserJet 3100*</member><member>LaserJet 3150</member></simplelist></entry></row><row><entry><simpara>Heidelberg</simpara></entry><entry><simplelist type="vert"><member>Digimaster 9110*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Hitachi</simpara></entry><entry><simplelist type="vert"><member>DDP 70 (with MicroPress)*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>IBM</simpara></entry><entry><simplelist type="vert"><member>3853 JetPrinter*</member><member>4019*</member><member>4029 10P*</member><member>4303 Network Color Printer*</member><member>Execjet 4072*</member><member>Page Printer 3112*</member><member>ProPrinterII*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Imagen</simpara></entry><entry><simplelist type="vert"><member>ImPress*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Infotec</simpara></entry><entry><simplelist type="vert"><member>infotec 4651 MF*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Kodak</simpara></entry><entry><simplelist type="vert"><member>DigiSource 9110*</member><member>IS 70 CPII*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Kyocera</simpara></entry><entry><simplelist type="vert"><member>F-3300</member><member>FS-600*</member><member>FS-600 (KPDL-2)*</member><member>FS-680*</member><member>FS-800*</member><member>FS-1200*</member><member>FS-1700+*</member><member>FS-1750*</member><member>FS-3750*</member><member>FS-5900C*</member><member>P-2000*</member></simplelist></entry><entry><simplelist type="vert"><member>F-800T*</member><member>FS-3500*</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Lexmark</simpara></entry><entry><simplelist type="vert"><member>4039 10plus</member><member>Optra Color 40</member><member>Optra Color 45</member><member>Optra Color 1200</member><member>Optra Color 1275</member><member>Optra E*</member><member>Optra E+*</member><member>Optra E310</member><member>Optra E312</member><member>Optra Ep*</member><member>Optra K 1220*</member><member>Optra R+*</member><member>Optra S 1250*</member><member>Optra S 1855*</member><member>Optra Se 3455*</member><member>Optra W810</member><member>Valuewriter 300*</member><member>Z32</member></simplelist></entry><entry><simplelist type="vert"><member>1020 Business</member><member>3000</member></simplelist></entry><entry><simplelist type="vert"><member>1000</member><member>1100</member><member>2030</member><member>2070</member><member>3200</member><member>5000</member><member>5700</member><member>7000</member><member>7200</member><member>Winwriter 400*</member><member>Z11*</member><member>Z51</member></simplelist></entry><entry><simplelist type="vert"><member>1020</member><member>2050</member><member>Winwriter 100*</member><member>Winwriter 150c*</member><member>Winwriter 200*</member><member>Z22</member><member>Z52*</member></simplelist></entry></row><row><entry><simpara>Minolta</simpara></entry><entry><simplelist type="vert"><member>PagePro 6*</member><member>PagePro 6e*</member><member>PagePro 6ex*</member><member>PagePro 8*</member></simplelist></entry><entry></entry><entry><simplelist type="vert"><member>PagePro 8L*</member></simplelist></entry><entry><simplelist type="vert"><member>PagePro 6L</member></simplelist></entry></row><row><entry><simpara>Mitsubishi</simpara></entry><entry><simplelist type="vert"><member>CP50 Color Printer*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>NEC</simpara></entry><entry><simplelist type="vert"><member>P2X*</member><member>PinWriter P6*</member><member>PinWriter P6 plus*</member><member>PinWriter P7*</member><member>PinWriter P7 plus*</member><member>PinWriter P60*</member><member>PinWriter P70*</member><member>SilentWriter LC 890*</member><member>Silentwriter2 S60P*</member><member>Silentwriter2 model 290*</member><member>SuperScript 660i*</member><member>SuperScript 1800</member></simplelist></entry><entry><simplelist type="vert"><member>Silentwriter 95f*</member></simplelist></entry><entry><simplelist type="vert"><member>SuperScript 100C*</member><member>SuperScript 150C*</member><member>SuperScript 650C*</member><member>SuperScript 750C*</member><member>SuperScript 860*</member><member>SuperScript 870*</member><member>SuperScript 1260*</member></simplelist></entry><entry><simplelist type="vert"><member>SuperScript 610plus*</member><member>SuperScript 660*</member><member>SuperScript 660plus*</member></simplelist></entry></row><row><entry><simpara>Oce</simpara></entry><entry><simplelist type="vert"><member>3165*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Okidata</simpara></entry><entry><simplelist type="vert"><member>ML 380*</member><member>OL 410e</member><member>OL 600e*</member><member>OL 610e/PS</member><member>OL 800</member><member>OL 810e/PS</member><member>OL400ex</member><member>OL810ex</member><member>OL820*</member><member>OL830Plus</member><member>Okipage 6e</member><member>Okipage 6ex*</member><member>Okipage 8c</member><member>Okipage 8p</member><member>Okipage 10e</member><member>Okipage 12i</member><member>Okipage 20DXn</member></simplelist></entry><entry><simplelist type="vert"><member>Microline 182</member><member>OL 400w*</member><member>OL 610e/S</member><member>OkiPage 4w+*</member><member>OkiPage 8w Lite*</member><member>OkiPage 8z*</member><member>Okijet 2500*</member><member>Okipage 4w*</member><member>Okipage 8w*</member><member>Super 6e</member></simplelist></entry><entry><simplelist type="vert"><member>Microline 192+</member><member>Okipage 6w*</member></simplelist></entry><entry><simplelist type="vert"><member>Okijet 2010</member></simplelist></entry></row><row><entry><simpara>Olivetti</simpara></entry><entry><simplelist type="vert"><member>JP350S*</member><member>JP450*</member><member>JP470*</member><member>PG 306*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>PCPI</simpara></entry><entry><simplelist type="vert"><member>1030*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Panasonic</simpara></entry><entry><simplelist type="vert"><member>KX-P1123*</member><member>KX-P1124*</member><member>KX-P1150*</member><member>KX-P1180i*</member><member>KX-P2023*</member><member>KX-P2135*</member><member>KX-P2150*</member><member>KX-P4410*</member><member>KX-P4450*</member><member>KX-P5400*</member><member>KX-P8420*</member><member>KX-P8475*</member><member>KX-PS600*</member><member>kx-p1624*</member></simplelist></entry><entry><simplelist type="vert"><member>KX-P2123*</member><member>KX-P6150*</member></simplelist></entry><entry><simplelist type="vert"><member>KX-P6500*</member></simplelist></entry><entry><simplelist type="vert"><member>KX-P6100*</member><member>KX-P6300 GDI*</member><member>KX-P8410*</member></simplelist></entry></row><row><entry><simpara>Printrex</simpara></entry><entry></entry><entry></entry><entry><simplelist type="vert"><member>820 DL*</member></simplelist></entry><entry></entry></row><row><entry><simpara>QMS</simpara></entry><entry><simplelist type="vert"><member>2425 Turbo EX*</member><member>LPK-100*</member></simplelist></entry><entry><simplelist type="vert"><member>magicolor 2+*</member><member>ps-810*</member></simplelist></entry><entry></entry><entry><simplelist type="vert"><member>magicolor 2</member></simplelist></entry></row><row><entry><simpara>Raven</simpara></entry><entry></entry><entry><simplelist type="vert"><member>LP-410</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Ricoh</simpara></entry><entry><simplelist type="vert"><member>4081*</member><member>4801*</member><member>6000*</member><member>Aficio 220*</member><member>Aficio AP2000</member></simplelist></entry><entry><simplelist type="vert"><member>Aficio 401*</member></simplelist></entry><entry></entry><entry><simplelist type="vert"><member>Aficio Color 2206*</member><member>Afico FX10*</member></simplelist></entry></row><row><entry><simpara>Samsung</simpara></entry><entry><simplelist type="vert"><member>ML-85*</member><member>ML-4600*</member><member>ML-5000a*</member><member>ML-6000/6100*</member><member>ML-7000/7000P/7000N*</member><member>ML-7050*</member><member>QL-5100A*</member><member>QL-6050*</member><member>SI-630A*</member></simplelist></entry><entry><simplelist type="vert"><member>ML-85G</member><member>QL-85G</member></simplelist></entry><entry></entry><entry><simplelist type="vert"><member>ML-5050G*</member><member>SF/MSYS/MJ-4700/4800/4500C*</member></simplelist></entry></row><row><entry><simpara>Seiko</simpara></entry><entry><simplelist type="vert"><member>SpeedJET 200*</member></simplelist></entry><entry><simplelist type="vert"><member>SLP*</member><member>SLP 120*</member><member>SLP 220*</member><member>SLP EZ30*</member><member>SLP Plus*</member><member>SLP Pro*</member></simplelist></entry><entry></entry><entry></entry></row><row><entry><simpara>Sharp</simpara></entry><entry><simplelist type="vert"><member>AR-161*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Star</simpara></entry><entry><simplelist type="vert"><member>LC24-100*</member><member>LS-04</member><member>NL-10*</member></simplelist></entry><entry><simplelist type="vert"><member>LC 90*</member><member>LC24-200*</member><member>StarJet 48*</member></simplelist></entry><entry></entry><entry><simplelist type="vert"><member>WinType 4000*</member></simplelist></entry></row><row><entry><simpara>Tally</simpara></entry><entry><simplelist type="vert"><member>MT908*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Tektronix</simpara></entry><entry><simplelist type="vert"><member>3693d color printer, 8-bit mode*</member><member>4693d color printer, 2-bit mode*</member><member>4693d color printer, 4-bit mode*</member><member>4695*</member><member>4696*</member><member>4697*</member><member>Phaser 780</member><member>Phaser 850*</member><member>Phaser IISX*</member><member>Phaser PX*</member></simplelist></entry><entry></entry><entry></entry><entry></entry></row><row><entry><simpara>Xerox</simpara></entry><entry><simplelist type="vert"><member>2700 XES</member><member>3700 XES</member><member>4045 XES*</member><member>DocuPrint 4508</member><member>DocuPrint C20</member><member>DocuPrint C55*</member><member>DocuPrint N17</member><member>DocuPrint N32*</member><member>Document Centre 400*</member></simplelist></entry><entry><simplelist type="vert"><member>DocuPrint C6*</member><member>DocuPrint P8e</member><member>DocuPrint P12*</member><member>Docuprint C6*</member><member>Docuprint C8*</member><member>XJ6C*</member></simplelist></entry><entry><simplelist type="vert"><member>Document Homecentre</member><member>WorkCentre 450cp*</member><member>WorkCentre 470cx*</member><member>XJ8C*</member></simplelist></entry><entry><simplelist type="vert"><member>DocuPrint P8*</member><member>Work Centre XK35c</member><member>WorkCenter XE90fx*</member><member>WorkCentre XD120f*</member><member>WorkCentre XE80</member><member>workcentre 385*</member></simplelist></entry></row></tbody></tgroup></table>
     * This entry has not been sanity-checked by me.
    </para></sect3></sect2><sect2 id="shopping"><indexterm significance="normal"><primary>printers</primary><secondary>buying</secondary></indexterm><title>How to buy a printer</title><para>    It's a bit difficult to select a printer these days; there are many
    models to choose from.  Here are some shopping tips:
    <variablelist><varlistentry><term>Cost</term><listitem><para>You get what you pay for.  Most printers under $200-300
        will print reasonably well, but printing costs a lot per page.
        For some printers, it only takes one or two cartridges to add
        up to the cost of a new printer!  Similarly, the cheapest
        printers won't last very long.  The least expensive printers,
        for example, have a MTBF of about three
        <emphasis>months</emphasis>; obviously these are poorly suited
        for heavy use.
       </para></listitem></varlistentry><varlistentry><term>Inkjets</term><listitem><para>Inkjet printheads will clog irreparably over time, so the
        ability to replace the head somehow is a feature.  Inkjet
        printheads are expensive, with integrated head/ink cartridges
        costing ten times (!) what ink-only cartridges go for, so the
        ability to replace the head only when needed is a feature.
        Epson Styluses tend to have fixed heads, and HP DeskJets tend
        to have heads integrated into the cartridges.  Canons have
        three-part cartridges with independently replaceable ink
        tanks; I like this design.  OTOH, the HP cartridges aren't
        enormously more expensive, and HP makes a better overall line;
        Canon is often the third choice from the print quality
        standpoint; and Epson Styluses are the best supported under
        Linux at the moment.  You just can't win.
       </para></listitem></varlistentry><varlistentry><term>Lasers</term><listitem><para>Laser printers consume a drum and toner, plus a little
        toner wiping bar.  The cheapest designs include toner and drum
        together in a big cartridge; these designs cost the most to
        run.  The best designs for large volume take plain toner
        powder or at least separate toner cartridges and drums.
       </para></listitem></varlistentry><varlistentry id="photo-printers-shopping"><indexterm significance="normal"><primary>photograph</primary><secondary>printers</secondary></indexterm><indexterm significance="normal"><primary>printers</primary><secondary>photograph</secondary></indexterm><term>Photography</term><listitem><para>The best color photograph output is from continuous tone
        printers which use a silver halide plus lasers approach to
        producesurprise!actual photographs.  Since these
        printers cost tens of thousands to buy, <ulink url="http://www.ofoto.com">Ofoto.com</ulink> offers
        inexpensive print-by-print jobs.  The results are stunning;
        even the best inkjets don't compare.
       </para><para>        The best affordable photo prints come from the dye-sublimation
        devices like some members of the Alps series (thermal transfer
        of dry ink or dye sublimation).  Unfortunately they have poor
        Linux support (the one report I have speaks of banding and
        grainy pictures), and even then it's unclear if the dye-sub
        option is supported.  
       </para><para>        The more common photo-specialized inkjets usually feature 6
        color CMYKcm printing or even a 7 color CMYKcmy process.  All
        photo-specialized printers are expensive to run; either you
        always run out of blue and have to replace the whole
        cartridge, or the individual color refills for your high-end
        photo printer cost an arm and a leg.  Special papers cost a
        bundle, too; you can expect top-quality photo inkjet output to
        run over a US dollar per page.  See also the section on
        printing photographs later in this document, and the sections
        on color tuning (such as it is) in Ghostscript.
       </para></listitem></varlistentry><varlistentry><term>Speed</term><listitem><para>Speed is proportional to processing power, bandwidth, and
        generally printer cost.  The fastest printers will be networked
        Postscript printers with powerful internal processors.
        Consumer-grade printers will depend partly on Ghostscript's
        rendering speed, which you can affect by having a reasonably
        well-powered machine; full pages of color, in particular, can
        consume large amounts of host memory.  As long as you actually
        <emphasis>have</emphasis> that memory, things should work out
        fine. 
       </para></listitem></varlistentry><varlistentry><term>Forms</term><listitem><para>If you want to print on multicopy forms, then you need an
        impact printer; many companies still make dot matrix printers,
        most of which emulate traditional Epson models and thus work
        fine.
       </para></listitem></varlistentry><varlistentry><term>Labels</term><listitem><para>There are two supported lines of label printer; look for
        the Dymo-Costar and the Seiko SLP models.  Other models may or
        may not work.  Avery also makes various sizes of stick-on
        labels in 8.5x11 format that you can run through a regular
        printer.
       </para></listitem></varlistentry><varlistentry><term>Plotting</term><listitem><para>Big drafting formats are usually supported these days by
        monster inkjets; HP is a popular choice.  Mid-sized (11x17)
        inkjets are also commonly used for smaller prints.  Much
        plotting of this sort is done with the languages RTL, HP-GL,
        and HP-GL/2, all of which are simple HP proprietary vector
        languages usually generated directly by application software.
       </para></listitem></varlistentry></variablelist>
   </para><sect3 id="my-printers"><title>What do I have?</title><para>     I own an HP Deskjet 500, a Lexmark Optra 40, and a Canon
     BJC-4100.  All work perfectly: the HP and Canon are older models,
     well supported by Ghostscript; and the Optra is a more modern
     color inkjet with full Postscript and PCL 5 support (!).
    </para><para>     I also own a Hawking Technology 10/100 Ethernet print server
     (model 7117, actually made by Zero One Technologies in Taiwan);
     this makes it possible to put the printer anywhere with power and
     a network jack, instead of just near a computer.  It's a little
     dongle that attaches to the printer's parallel port and has an
     Ethernet jack on the other side.  The only flaw with this is that
     it doesn't allow bidirectional communication, so I can't arrange
     to be sent email when the ink is low.
    </para></sect3></sect2></sect1><sect1 id="spoolers"><title>Spooling software</title><para>   Until recently, the choice for Linux users was simple - everyone
   ran the same old lpd lifted mostly verbatim out of BSD's Net-2
   code.  Even today, most vendors ship this software.  But this is
   beginning to change.  SVR4-like systems including Sun's Solaris
   come with a completely different print spooling package, centered
   around lpsched.
  </para><para>   Today, there are a number of good systems to chose from.  I
   describe them all below; read the descriptions and make your own
   choice.  PDQ is the simplest modern system with a GUI; it is
   suitable for both basic home users and (in a hybrid pdq/lprng
   setup) people in many larger environments.  For business
   environments with mainly networked Postscript printers, a front-end
   program like GPR with LPRng is a good alternative; it handles
   PPD options directly and has a slightly nicer interface.  In other
   cases CUPS is a good option; it too has excellent Postscript
   printer support, and offers IPP support, a web interface, and a
   number of other features.
  </para><sect2 id="lpd-which-spooler"><indexterm significance="normal"><primary>LPD</primary><secondary>VA Linux's version</secondary></indexterm><indexterm significance="normal"><primary>VA Linux</primary><secondary>LPD</secondary></indexterm><title>LPD</title><para>    LPD, the original BSD Unix Line Printer Daemon, has been the
    standard on Unix for years.  It is available for every style of
    Unix, and offers a rather minimal feature set derived from the
    needs of timesharing-era computing.  Despite this somewhat
    peculiar history, it is still useful today as a basic print
    spooler.  To be really useful with modern printer, a good deal of
    extra work is needed in the form of companion filter scripts and
    front-end programs.  But these exist, and it does all work.
   </para><para>    LPD is also the name given to the network printing protocol by
    <ulink url="http://www.ietf.org/rfc/rfc1179.txt">RFC
    1179</ulink>.  This network protocol is spoken not only by
    the LPD daemon itself, but by essentially every networked print
    server, networked printer, and every other print spooler out
    there; LPD is the least common denominator of standards-based
    network printing.
   </para><para>    LPRng (see <xref linkend="lprng-which-spooler"></xref>) is a far better
    implementation of the basic LPD design than the regular one; if
    you must use LPD, consider using LPRng instead.  There is far less
    voodoo involved in making it do what you want, and what voodoo
    there is is well documented.
   </para><para>    There are a large number of LPD sources floating around in the
    world.  Arguably, some strain of BSD Unix is probably the official
    owner, but everyone implements changes willy-nilly, and they all
    cross-pollinate in unknown ways, such that it is difficult to say
    with certainty exactly which LPD you might have.  Of the readily
    available LPDs, VA Linux offers one with a few minor modifications
    that make the user interface much more flexible.  The <ulink url="http://sourceforge.net/project/?group_id=3800">SourceForge
    LPD</ulink> supports command-line option specification with a
    <option>-o</option> flag; options are then passed through to
    filters.  This is similar to the features offered by a number of
    traditional Unix vendors, and similar to (although incompatible
    with) LPRng's <option>-z</option> option mechanism.
   </para><simplesect id="lpd-front-ends"><title>LPD front-ends</title><para>     If you go with LPD, the best way to use it is via a front-end.
     There are several to chose from; GPR (see <xref linkend="how-with-gui-tools"></xref>) and XPDQ (see <xref linkend="pdq-which-spooler"></xref>) are perhaps the two best.  Others
     exist; tell me about them.
    </para></simplesect></sect2><sect2 id="pdq-which-spooler"><indexterm significance="normal"><primary>PDQ</primary></indexterm><indexterm significance="normal"><primary>spoolers</primary><secondary>PDQ</secondary></indexterm><indexterm significance="normal"><primary>xpdq</primary></indexterm><title>PDQ</title><para>    <ulink url="http://feynman.tam.uiuc.edu/pdq/">PDQ</ulink> is a
    non-daemon-centric print system which has a built-in, and
    sensible, driver configuration syntax.  This includes the ability
    to declare printing options, and a GUI or command line tool for
    users to specify these options with; users get a nice dialog box
    in which to specify resolution, duplexing, paper type, etc (see
    <xref linkend="snapshot-xpdq-options"></xref>).
   </para><figure float="0"><title>XPDQ Main Window</title><graphic fileref="snapshot-xpdq-main" scale="60"></graphic></figure><para>    Running all of the filters as the user has a number of advantages:
    the security problems possible from Postscript are mostly gone,
    multi-file LaTeX jobs can be printed effectively as dvi files, and
    so forth.
   </para><para>    This is what I now use; I've written driver spec files for my
    printers, and there are several included with the distribution, so
    there are plenty of examples to base yours on.  I've also written
    a few tools to automate driver spec generation to help the rest of
    you.
   </para><para>    PDQ is not without flaws: most notably it processes the entire job
    before sending it to the printer.  This means that, for large
    jobs, PDQ may simply be impractical you can end up with
    hundreds of megs being copied back and forth on your disk.  Even
    worse, for slow drivers like the better quality inkjet drivers,
    the job will not start printing until Ghostscript and the driver
    have finished processing.  This may be many minutes after submission.
   </para><para>    If you have many users, many printers, or anything else complex
    going on, I recommend using PDQ as a front-end to LPD-protocol
    based network printing (you can print via the lpd protocol to the
    local machine).  In most such situations, rather than using the
    traditional BSD lpd as the back-end, I recommend LPRng:
   </para><figure float="0" id="snapshot-xpdq-options"><title>XPDQ Driver Options Window</title><graphic fileref="snapshot-xpdq-options" scale="60"></graphic></figure></sect2><sect2 id="lprng-which-spooler"><indexterm significance="normal"><primary>LPRng</primary></indexterm><indexterm significance="normal"><primary>spoolers</primary><secondary>LPRng</secondary></indexterm><title>LPRng</title><para>    Some Linux vendors (including Caldera) provide LPRng, a far less
    ancient LPD print spooling implementation.  LPRng is far easier to
    administer for large installations (read: more than one printer,
    any serial printers, or any peculiar non-lpd network printers) and
    has a less frightfully haphazard codebase than does stock lpd.  It
    can even honestly claim to be secure - there are no SUID binaries,
    and it supports authentication via PGP or Kerberos.
   </para><para>    LPRng also includes some example setups for common network
    printers - HP LaserJets, mainly, that include some accounting
    abilities.  If you'd like more information on LPRng, check out the
    <ulink url="http://www.astart.com/lprng/LPRng.html">LPRng Web
    Page</ulink>.  LPRng uses more or less the same basic filter model
    as does BSD lpd, so the <ulink url="http://www.linuxprinting.org/lpd-doc.html">LPD
    support</ulink> offered by my website applies to LPRng as well.
    This can help you effectively use free software drivers for many
    printers.
   </para><para>    LPRng is distributed under either the GPL or an Artistic license.
   </para></sect2><sect2 id="ppr-which-spooler"><indexterm significance="normal"><primary>PPR</primary></indexterm><indexterm significance="normal"><primary>spoolers</primary><secondary>PPR</secondary></indexterm><title>PPR</title><para>    <ulink url="http://ppr.trincoll.edu/">PPR</ulink> is a
    Postscript-centric spooler which includes a rudimentary Postscript
    parsing ability from which it derives several nice features.  It
    includes good accounting capabilities, good support for Appletalk,
    SMB, and LPD clients, and much better error handling than lpd.
    PPR, like every other spooler here, can call Ghostscript to handle
    non-Postscript printers.
   </para><para>    I only recently found out about PPR; I don't know of anyone who
    has tried it.  It was written by, and is in use at, Trinity
    College.  The license is BSD-style; free for all use but credit is
    due.
   </para><para>    According to the documentation, it's somewhat experimental.
    Malformed Postscript jobs won't print; instead they bounce, and
    it's up to the user to fix the Postscript.  This may make it
    unsuitable for some environments, although most users generate
    Postscript with a small handful of well-characterized Postscript
    generators, so it probably wouldn't be that big an issue.
   </para></sect2><sect2 id="cups-which-spooler"><indexterm significance="normal"><primary>CUPS</primary></indexterm><indexterm significance="normal"><primary>CUPS</primary><secondary>XPP</secondary><see>XPP</see></indexterm><indexterm significance="normal"><primary>spoolers</primary><secondary>CUPS</secondary></indexterm><indexterm significance="normal"><primary>XPP</primary></indexterm><title>CUPS</title><para>    <indexterm significance="normal"><primary>IPP</primary></indexterm>
    <indexterm significance="normal"><primary>Internet Printing Protocol</primary><see>IPP</see></indexterm>
    One interesting newcomer on the scene is <ulink url="http://www.cups.org/">CUPS</ulink>, an implementation of the
    Internet Printing Protocol (IPP), an HTTP-like RFC standard
    replacement protocol for the venerable (and klunky) LPD protocol.
    The implementation of CUPS has been driven by Michael Sweet of
    Easy Software Products; CUPS is distributed under the GPL.
   </para><para id="cups-home-environ">   <indexterm significance="normal"><primary>environment</primary><secondary>home</secondary></indexterm>
    I've finally done some work with CUPS, and it does 
    work as advertised.  There are a number of very good features in
    it, including sensible option handling; web, gui, and command-line
    interfaces; and a mime-based filtering system with strong support
    for Postscript.  Since it is so new, however, it does have a
    number of quirks, and it is hard to recommend for large or secure
    installations at this time (as of version 1.1).  It is a fine
    solution, however, for smaller installations or especially larger
    installatons with trusted users.
   </para><para>    Like other systems, CUPS can be used with most existing drivers.
    Unfortunately, it's a bit tricky to configure an arbitrary driver
    for use with CUPS at least if you want all the options to
    work so it's best to find a preexisting PPD file and filter
    script to make your driver go.  There are at least four sets of
    drivers which you can use with CUPS:
    <variablelist><varlistentry><term><ulink url="http://www.linuxprinting.org/cups-doc.html">CUPS-O-Matic</ulink></term><listitem><para>My web-based CUPS-O-Matic system can generate a suitable
	PPD for use with any printer driver that has full details
	entered in the Linux Printing Database.  The PPD gets used
	together with a backend script named
	<command moreinfo="none">cupsomatic</command>.  CUPS-O-Matic uses free
	software drivers.  At the moment I am concentrating on
	correctness rather than completeness, so rather few drivers
	are in fact supported.  This will change over time.
       </para></listitem></varlistentry><varlistentry><term><ulink url="http://cups.sourceforge.net/">CUPS Drivers
                 and KUPS</ulink></term><listitem><para>The CUPS Drivers project is accumulating PPD files
	useable with either Postscript printers or the backend filter
	<command moreinfo="none">ps2gs2raw</command>.  These PPD files use free
	software drivers.  KUPS is a companion setup program.
       </para></listitem></varlistentry><varlistentry><term>Postscript PPDs</term><listitem><para>CUPS can use vendor-supplied PPD files for Postscript
	printers directly.  Often these come with the Windows drivers
	for a printer, or can be found on the printer vendor's
	website.  <ulink url="http://www.adobe.com/products/printerdrivers/winppd.html">Adobe</ulink> also distributes PPD files for many Postscript
	printers.
       </para></listitem></varlistentry><varlistentry><term>ESP Print Pro</term><listitem><para><ulink url="http://www.easysw.com/">Easy Software Products,
	Inc.</ulink> sells CUPS bundled with a collection of
	proprietary drivers.  Although they are not free software,
	they do drive many common printers.  The bundle is somewhat
	expensive measured against the price of a single supported
	printer, but it certainly has a place.  These drivers are
	reputedly not terribly good, but they are somewhat
	comprehensive, and even mediocre quality is preferable to a
	paperweight. 
       </para></listitem></varlistentry></variablelist>
   </para><para>    The third-party program <command moreinfo="none"><ulink url="http://www.phy.uni-bayreuth.de/till/xpp/">XPP</ulink></command> (see <xref linkend="snapshot-xpp-main"></xref>) offers a
    very nice graphical interface to the user functionality of CUPS,
    including an marvelous interface to print-time options (shown in
    <xref linkend="snapshot-xpp-options"></xref>).  For information on using
    XPP, see <xref linkend="xpp-sect"></xref>.
   </para></sect2></sect1><sect1 id="background"><indexterm significance="normal"><primary>spoolers</primary></indexterm><title>How it all works</title><para>   In order to get printing working well, you need to understand how your 
   spooling software works.  All systems work in essentially the same
   way, although the exact order might vary a bit, and some systems
   skip a step or two:

   <figure float="0" id="spool-illustration"><title>Spooling Illustration</title><graphic fileref="spool-illustration" scale="80"></graphic></figure>

   <orderedlist inheritnum="ignore" continuation="restarts"><listitem><simpara>The user submits a job along with his selection of options.  The
      job data is usually, but not always, Postscript.
     </simpara></listitem><listitem><simpara>The spooling system copies the job and the options over the
      network in the general direction of the printer.
     </simpara></listitem><listitem><simpara>The spooling system waits for the printer to be available.
     </simpara></listitem><indexterm significance="normal"><primary>filtering</primary></indexterm><listitem id="background-filtering"><simpara>The spooling system applies the user's selected options to the
      job, and translates the job data into the printer's native
      language, which is usually not Postscript.  This step is called
      <emphasis>filtering</emphasis>; most of the work in setting
      things up lies in getting the proper filtering to happen.
     </simpara></listitem><listitem><simpara>The job is done.  The spooling system will usually do assorted
      cleanup things at this point.  If there was an error along the
      way, the spooler will usually notify the user somehow (for
      example, by email).
     </simpara></listitem></orderedlist>
  </para><sect2 id="pdq-overview"><indexterm significance="normal"><primary>PDQ</primary><secondary>overview</secondary></indexterm><title>PDQ</title><para>    Pdq stands for "Print, Don't Queue", and the way it works reflects
    this design.  The following sequence of events happens when you
    use PDQ to print:
    <itemizedlist><listitem><para>You run pdq or xpdq, specifying a file.
      </para></listitem><listitem><para>You specify a printer.
      </para></listitem><listitem><para>You specify the settings for the various options and arguments
       defined in the printer's PDQ driver file (duplex, copies, print
       quality, and so forth).
      </para></listitem><listitem><para>PDQ analyzes the contents of what you printed, and follows the
       instructions in the PDQ driver file which tell it how to
       process your data for this printer with your options.
      </para></listitem><listitem><para>PDQ sends the processed data to the printer according to the
       interface defined for that printer (straight to
       <filename moreinfo="none">/dev/lp0</filename>, or to an LPD daemon on the
       network, over the network to an Apple or Microsoft system, or
       even to a fax machine).
      </para></listitem><listitem><para>If PDQ can't send the data to the printer right away, it spawns
       a background process to wait and try again until it succeeds or
       hits a time limit.
      </para></listitem></itemizedlist>
    At all times during this process, and afterwards, the state of each
    print job can be seen and inspected using xpdq.  Jobs that failed are
    shown in red and can be resent.
   </para></sect2><sect2 id="lpd-overview"><title>LPD</title><indexterm significance="normal"><primary>LPD</primary></indexterm><para>    Lpd stands for Line Printer Daemon, and refers in different
    contexts to both the daemon and the whole collection of programs
    which run print spooling.  These are:
    <variablelist><varlistentry><term>       <command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/lpd.8.html">lpd</ulink></command>
      </term><listitem><para>The spooling daemon.  One of these runs to control everything
        on a machine, AND one is run per printer while the printer is
        printing.
       </para></listitem></varlistentry><varlistentry id="lpr-in-lpd-overview"><indexterm significance="normal"><primary>lpr</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>lpr</secondary></indexterm><term><command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/lpr.1.html">lpr</ulink></command>
      </term><listitem><para>The user spooling command.  Lpr contacts lpd
        and injects a new print job into the spool.
       </para></listitem></varlistentry><varlistentry id="lpq-in-lpd"><indexterm significance="normal"><primary>lpq</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>lpq</secondary></indexterm><term>       <command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/lpq.1.html">lpq</ulink></command>
      </term><listitem><para>Lists the jobs in a print queue.
       </para></listitem></varlistentry><varlistentry id="lpc-in-lpd"><indexterm significance="normal"><primary>lpc</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>lpc</secondary></indexterm><term><command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/lpc.8.html">lpc</ulink></command>
      </term><listitem><para>The Lpd system control command.  With lpc you can stop, start,
        reorder, etc, the print queues.
       </para></listitem></varlistentry><varlistentry id="lprm-in-lpd"><indexterm significance="normal"><primary>lprm</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>lprm</secondary></indexterm><term><command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/lprm.1.html">lprm</ulink></command>
      </term><listitem><para><command moreinfo="none">lprm</command> removes a job from the print spool.
       </para></listitem></varlistentry></variablelist>
   </para><para>    So how does it fit together?  The following things happen:

    <orderedlist inheritnum="ignore" continuation="restarts"><listitem><simpara>At boot time, <command moreinfo="none">lpd</command> is run.  It waits for
       connections and manages printer queues.
      </simpara><simpara>     </simpara></listitem><listitem><simpara>A user submits a job with the <command moreinfo="none">lpr</command> command
       or, alternatively, with an lpr front-end like GPR, PDQ, etc.
       <command moreinfo="none">Lpr</command> contacts <command moreinfo="none">lpd</command> over the
       network and submits both the user's data file (containing the
       print data) and a control file (containing user options).
      </simpara><simpara>     </simpara></listitem><listitem><simpara>When the printer becomes available, the main
       <command moreinfo="none">lpd</command> spawns a child <command moreinfo="none">lpd</command> to
       handle the print job.
      </simpara></listitem><listitem><simpara>The child <command moreinfo="none">lpd</command> executes the appropriate
       filter(s) (as specified in the <option>if</option> attribute in
       <filename moreinfo="none">/etc/printcap</filename>) for this job and sends the
       resulting data on to the printer.
      </simpara></listitem></orderedlist>
   </para><para>    The lp system was originally designed when most printers were line
    printers - that is, people mostly printed plain ascii.  By placing
    all sorts of magic in the <option>if</option> filter, modern
    printing needs can be met with <command moreinfo="none">lpd</command> (well, more
    or less; many other systems do a better job).
   </para><para>    There are many programs useful for writing LPD filters.  Among
    them are:
    <variablelist><varlistentry><term><command moreinfo="none">gs</command></term><listitem><para>Ghostscript is a host-based Postscript interpreter (aka a
        Raster Image Processor or RIP).  It accepts Postscript and
        produces output in various printer languages or a number of
        graphics formats.  Ghostscript is covered in <xref linkend="ghostscript"></xref>.
       </para></listitem></varlistentry><varlistentry><term><command moreinfo="none">ppdfilt</command></term><listitem><para><command moreinfo="none"><ulink url="http://sourceforge.net/project/?group_id=1658">ppdfilt</ulink></command> is a standalone version of a CUPS
        component.  It filters Postscript, executing a few basic
        transformations on it (n-up printing, multiple copies, etc)
        and adding in user option statements according to a Postscript
        Printer Definition (PPD) file usually included with Postscript
        printers.
       </para><para>        <command moreinfo="none">ppdfilt</command> is best used together with an
        option-accepting LPD system (like the VA Linux LPD, or LPRng)
        and a filter script which parses user-provided options into
        the equivalent <command moreinfo="none">ppdfilt</command> command.  VA Linux
        and HP provide a modified rhs-printfilters package which does
        exactly this; it produces nice results if you have a
        Postscript printer.  See <xref linkend="lpd-for-postscript-printers"></xref> for information on
        this system.
       </para></listitem></varlistentry><varlistentry><term><command moreinfo="none">ps2ps</command></term><listitem><para><command moreinfo="none">ps2ps</command> is a utility script included
        with Ghostscript.  It filters Postscript into more streamlined
        Postscript, possibly at a lower Language Level.  This is
        useful if you have an older Postscript printer; most modern
        software produces modern Postscript.
       </para></listitem></varlistentry><varlistentry><term><command moreinfo="none">mpage</command></term><listitem><para><command moreinfo="none">mpage</command> is a utility which accepts
        text or Postscript, and generates n-up outputthat is,
        output with several page images on each piece of paper.  There
        are actually several programs which do this, including
        <command moreinfo="none">enscript</command>, <command moreinfo="none">nenscript</command>, and
        <command moreinfo="none">a2ps</command>.
       </para></listitem></varlistentry><varlistentry><term><command moreinfo="none">a2ps</command></term><listitem><para><command moreinfo="none">a2ps</command>, aka any-to-ps, is a program which
        accepts a variety of file types and converts them to
        Postscript for printing.
       </para></listitem></varlistentry></variablelist>   
   </para></sect2></sect1><sect1 id="setup"><title>How to set things up</title><para>   For common configurations, you can probably ignore this section
   entirely - instead, you should jump straight to <xref linkend="vendors"></xref> below, or better yet, your vendor's
   documentation.  Most Linux distributions supply one or more
   "idiot-proof" tools to do everything described here for common
   printers.
  </para><para>   If your vendor's tool doesn't work out for you, or you'd like the
   ability to interactively control printing options when you print,
   then you should use some other system.  PDQ is a good choice; it
   provides very good functionality and is easy to setup.  APS Filter
   is another good system; it configures LPD queues and filters very
   easily on most any sort of Unix system.
  </para><para>   You can also use the printing system interfaces from the <ulink url="http://www.linuxprinting.org/">Linux Printing Website</ulink>
   to connect many free drivers into several spooling systems.  Once
   this project is complete, these interfaces will offer the best
   functionality: all styles of free software drivers are supported,
   user-settable options are available, and most common spooling
   systems are supported.
  </para><sect2 id="pdq-config"><indexterm significance="normal"><primary>PDQ</primary><secondary>configuration</secondary></indexterm><indexterm significance="normal"><primary>configuration</primary><secondary>PDQ</secondary></indexterm><title>Configuring PDQ</title><para>    PDQ can be configured by either the superuser or by a joeuser.
    Root's changes are made to <filename moreinfo="none">/etc/printrc</filename>, and
    affect everyone, while joeuser can only modify his personal
    <filename moreinfo="none">.printrc</filename>.  Everything applies to both types
    of configuration.
   </para><para>    If PDQ is not available prepackaged for your distribution, you
    should obtain the source distribution from the <ulink url="http://feynman.tam.uiuc.edu/pdq/">PDQ web page</ulink> and
    compile it yourself.  It is an easy compile, but you must first be
    sure to have installed the various GTK development library
    packages, the C library development package, the gcc compiler,
    make, and possibly a few other development things.
   </para><sect3 id="pdq-drivers-interfaces"><title>Drivers and Interfaces</title><para>     PDQ lets users select a printer to print to.  A printer is
     defined in PDQ as the combination of a "driver" and an
     "interface".  Both drivers and interfaces are, in fact, merely
     snippets of text in the PDQ configuration file.
    </para><para>     A PDQ interface says everything about how to ship data out to a
     printer.  The most common interfaces, which are predefined in the
     PDQ distribution's example printrc file, are:
     <variablelist><varlistentry><term>local-port</term><listitem><para>A local port interface speaks to a parallel or serial
         port on the machine PDQ is running on.  Using this interface,
         PDQ can print directly to your parallel port.  Note that if
         you have a multiuser system this can cause confusion, and if
         you have a network the local-port interface will only apply
         to one system.  In those cases, you can define a raw
         unfiltered lpd queue for the port and print to the system's
         lpd daemon exactly the same way from all systems and accounts
         without any troubles.  This interface has a device name
         argument; the typical value would be
         <filename moreinfo="none">/dev/lp0</filename>.
        </para></listitem></varlistentry><varlistentry><term>bsd-lpd</term><listitem><para>A bsd lpd interface speaks over the network to an LPD
         daemon or LPD-speaking networked printer.  PDQ supports job
         submission, cancellation, and queries to LPD interfaces.
         This interface has hostname and queuename arguments.
        </para></listitem></varlistentry><varlistentry id="pdq-config-apple"><indexterm significance="normal"><primary>PDQ</primary><secondary>appletalk</secondary></indexterm><term>appletalk</term><listitem><para>The appletalk interface allows you to print to printers
         over the Appletalk network; if you have a printer plugged
         into your Mac this is the way to go.  This interface needs to
         have the Netatalk package installed to work.
        </para></listitem></varlistentry></variablelist>
    </para><para>     A PDQ driver says everything about how to massage print data into
     a format that a particular printer can handle.  For Postscript
     printers, this will include conversion from ascii into
     Postscript; for non-Postscript printers this will include
     conversion from Postscript into the printer's language with
     Ghostscript.
    </para><para>     If one of PDQ's included driver specifications doesn't fit your
     printer, then read the section below on how to write your own.
    </para></sect3><sect3 id="defining-printers-in-pdq"><title>Defining Printers</title><para>     To define a printer in PDQ:
     <itemizedlist><listitem><para>First check that you've got suitable driver and interface
        declarations in the system or your personal printrc.
       </para></listitem><listitem><para>If you want to define the printer in
        <filename moreinfo="none">/etc/printrc</filename> (for all users), then su to
        root.
       </para></listitem><listitem><para>Run <command moreinfo="none">xpdq</command>, and select Printer-Add
        printer.  This "wizard" will walk you through the selection of
        a driver and interface.
       </para></listitem></itemizedlist>
     That's really all there is to it; most of the work lies in
     finding or creating a suitable driver specification if you can't
     find one premade.
    </para></sect3><sect3 id="pdq-drivers-tutorial"><indexterm significance="normal"><primary>PDQ</primary><secondary>creating drivers</secondary></indexterm><indexterm significance="normal"><primary>PDQ</primary><secondary>finding drivers</secondary></indexterm><title>Creating a PDQ Driver Declaration</title><para>     Here I'll walk through an example of how to make a PDQ driver
     declaration.  Before you try that, though, there are several
     places to look for existing driver specs:
     <itemizedlist><listitem><para>PDQ itself comes with a collection of prewritten driver
        files.
       </para></listitem><listitem><para>The Linux Printing Website's <ulink url="http://www.linuxprinting.org/database.html">database</ulink> includes a program called "<ulink url="http://www.linuxprinting.org/pdq-doc.html">PDQ-O-Matic</ulink>"
        which will generate a PDQ specification from the information
        in the database.  Assuming that the database contains the
        proper information for your printer and driver, this is the
        best path if you have a non-Postscript printer.
       </para></listitem><listitem><para>I've written a tool called <command moreinfo="none"><ulink url="http://www.picante.com/~gtaylor/download/printing/">ppdtopdq</ulink></command> which takes a Postscript Printer
        Definition file and converts it into a PDQ driver
        specification, with about 75% success.  This is an option if
        you have a Postscript printer.
       </para></listitem></itemizedlist>
    </para><para>     There are several places to look for the information needed to
     write your own PDQ driver:
     <itemizedlist><listitem><para>The PDQ driver specification syntax is quite rich, and is
        fully documented in the <ulink url="http://feynman.tam.uiuc.edu/pdq/man/printrc.5.html">printrc(5)</ulink> man page.
       </para></listitem><listitem><para>        The PDQ distribution includes a few example files.  Look in
        particular at the Epson Stylus file, which demonstrates the
        structure of the definition for a Ghostscript-driven printer.
       </para></listitem><listitem><para>The <ulink url="http://www.linuxprinting.org/database.html">Printing HOWTO Database</ulink> includes raw Linux driver
        information for over 600 printers.  This will tell you what
        options to give Ghostscript, or what extra program to
        run on the Ghostscript output.
       </para></listitem></itemizedlist>
    </para><para>     If you have to create your own driver specification, or if you
     enhance one from the PDQ distribution or one of the PDQ driver
     generator programs mentioned above, please share your creation
     with the world!  Send it to me (<literal moreinfo="none" remap="tt">gtaylor+pht@picante.com</literal>), and I'll make sure
     that it gets found by future PDQ users with your type of printer.
    </para><para>     Now, let's walk through the writing of a driver specification for
     a printer listed in the Printing HOWTO's database as working, but
     for which you can't find a PDQ driver spec.  I'll use the Canon
     BJC-210 as the example printer.
    </para><para>     First, we look at the <ulink url="http://www.linuxprinting.org/show_printer.cgi?recnum=58752">database entry</ulink> for this printer.  Note that it is
     supported "perfectly", so we can expect to get comparable results
     (or better) to Windows users.  The important information is in
     two places in the entry:
     <variablelist><varlistentry><term>Notes</term><listitem><para>The human-readable notes will often contain useful
         information.  For some printers, there is a More Info link,
         which usually refers to a web page run by a user with this
         printer, or to the driver's home page.
        </para></listitem></varlistentry><varlistentry><term>Driver List</term><listitem><para>Most printers have a list of drivers that are known to work.
         This is the most important part.  You can follow the driver
         links to a driver-specific page, which will often have more
         information about how to execute the driver, as well as a
         link to the driver's web page, if it has one.
        </para></listitem></varlistentry></variablelist>
     A PDQ driver spec has two logical functions: user interaction,
     and print job processing. These are represented in the file in
     three places:
     <variablelist><varlistentry><term>Option Declarations</term><listitem><para>These define what options the user can set, and declare PDQ
         variables for later parts of the driver to use.
        </para></listitem></varlistentry><varlistentry><term>Language Filters</term><listitem><para>These process the print job from whatever format it arrived
         in (typically Postscript or ASCII) into a language the
         printer can understand (for example, PCL).  Option values are
         available here, as well as in the output filter.
        </para></listitem></varlistentry><varlistentry><term>Output Filter</term><listitem><para>This final filter bundles up the printer data regardless of
         input type; often printer options are set here.
        </para></listitem></varlistentry></variablelist>
     Let's work on each of these for a Canon BJC-210:
    </para><sect4 id="pdq-driver-options"><title>Options</title><para>      The driver list for this printer includes the bj200 and bjc600
      drivers, both of which are Ghostscript style drivers.  The notes
      suggest that we use the bj200 for black-and-white printing.
     </para><para>      So, as far as the user is concerned, the BJC-210 supports one
      useful option: the user should pick color or black-and-white.
      Let's declare that as choice option called "MODE":
<screen format="linespecific">option {
  var = "MODE"
  desc = "Print Mode"
  # default_choice "Color"    # uncomment to default to color
  choice "BW" {
    # The value part assigns to the variable MODE whatever you 
    # want. Here we'll assign the text that varies between the 
    # two Ghostscript option sets for the two modes.
    value = "bj200"
    help = "Fast black printing with the black cartridge."
    desc = "Black-only"
  }
  choice "Color" {
    value = "bjc600"
    help = "Full-color printing."
    desc = "Color"
  }
}</screen>

      With the above choice declarations, the user will see a Color or
      BW choice in the driver options dialog when he prints from xpdq.
      In the command-line pdq tool, he may specify
      <option>-oBW</option> or <option>-oColor</option>.  The default
      can be set from xpdq, or declared above with the
      <option>defaultchoice</option> keyword.
     </para></sect4><sect4 id="pdq-filter-tutorial"><indexterm significance="normal"><primary>filtering</primary><secondary>PDQ</secondary></indexterm><indexterm significance="normal"><primary>PDQ</primary><secondary>filtering</secondary></indexterm><title>Language Filtering</title><para>      PDQ normally identifies its input with the
      <command moreinfo="none">file(1)</command> command.  For each type returned by
      <command moreinfo="none">file</command> that you want to handle, you provide a
      <function moreinfo="none">languagedriver</function> clause.  The clause
      consists mostly of a script to process the printjob language, in
      any (!) scripting language you wish (the default is the usual
      Bourne shell).
     </para><para>      In our case, we want to print Postscript and ASCII on our
      BJC-210.  This needs two language drivers: one to run
      Ghostscript for Postscript jobs, and one to add carriage returns
      to ASCII jobs:

<programlisting format="linespecific"># The first language_driver in the file that matches what file(1) 
# says is what gets used.
language_driver ps {
  # file(1) returns "PostScript document text conforming at..."
  filetype_regx = "postscript"
  convert_exec = { 
    gs -sDEVICE=$MODE -r360x360 \     # gs options from the database
       -q -dNOPAUSE -dBATCH -dSAFER \ # the "usual" Ghostscript options
       -sOutputFile=$OUTPUT $INPUT    # process INPUT into file OUTPUT

    # Those last two lines will often be the same for gs-supported
    # printers.  The gs... line, however, will be different for each
    # printer.      
  }
}

# We declare text after postscript, because the command "file" will
# often describe a postscript file as text (which it is).
language_driver text {
  # No filetype_regx; we match the driver's name: "text"
  convert_exec = {#!/usr/bin/perl
     # a Perl program, just because we can!
     my ($in, $out) = ($ENV{'INPUT'}, $ENV{'OUTPUT'});
     open INPUT, "$in";
     open OUTPUT, "$out";
     while(INPUT) {
        chomp;
        print OUTPUT, "$_\r\n";
     }
  }
}</programlisting>

     </para><para>      That's it!  While other printers may need output filtering (as
      described in the next section), the above clauses are it for the
      BJC-210.  We just wrap them all up in a named
      <function moreinfo="none">driver</function> clause:
<programlisting format="linespecific">driver canon-bjc210-0.1 {
  option {
    var = "MODE"
    desc = "Print Mode"
    # default_choice "Color"    # uncomment to default to color
    choice "BW" {
      # The value part assigns to the variable MODE whatever you 
      # want. Here we'll assign the text that varies between the 
      # two Ghostscript option sets for the two modes.
      value = "bj200"
      help = "Fast black printing with the black cartridge."
      desc = "Black-only"
    }
    choice "Color" {
      value = "bjc600"
      help = "Full-color printing."
      desc = "Color"
    }
  }

  # The first language_driver in the file that matches what file(1) 
  # says is what gets used.
  language_driver ps {
    # file(1) returns "PostScript document text conforming at..."
    filetype_regx = "postscript"
    convert_exec = { 
      gs -sDEVICE=$MODE -r360x360 \     # gs options from the database
         -q -dNOPAUSE -dBATCH -dSAFER \ # the "usual" Ghostscript options
         -sOutputFile=$OUTPUT $INPUT    # process INPUT into file OUTPUT

      # Those last two lines will often be the same for gs-supported
      # printers.  The gs... line, however, will be different for each
      # printer.      
    }
  }

  # We declare text after postscript, because the command "file" will
  # often describe a postscript file as text (which it is).
  language_driver text {
    # No filetype_regx; we match the driver's name: "text"
    convert_exec = {#!/usr/bin/perl
       # a Perl program, just because we can!
       my ($in, $out) = ($ENV{'INPUT'}, $ENV{'OUTPUT'});
       open INPUT, "$in";
       open OUTPUT, "$out";
       while(INPUT) {
          chomp;
          print OUTPUT, "$_\r\n";
       }
    }
  }
}</programlisting>

     </para></sect4><sect4 id="pdq-output-filter"><title>Output Filtering</title><para>      If you want to prepend or append something to all printjobs, or
      do some sort of transformation on all the data of all types,
      then it belongs in the <function moreinfo="none">filterexec</function>
      clause.  Our little Canon doesn't require such a clause, but
      just to have an example, here's a simple illustration showing
      how to support duplexing and resolution choice on a Laserjet or
      clone that speaks PJL:
<programlisting format="linespecific">driver generic-ljet4-with-duplex-0.1 {
  # First, two option clauses for the user-selectable things:
  option {
    var = "DUPLEX_MODE"
    desc = "Duplex Mode"
    default_choice = "SIMPLEX"
    choice "SIMPLEX" {
      value = "OFF"
      desc = "One-sided prints"
    }
    choice "DUPLEX" {
      value = "ON"
      desc = "Two-sided prints"
    }
  }

  option { 
    var = "GS_RES"
    desc = "Resolution"
    default_choice = "DPI600"
    choice "DPI300" {
      value = "-r300x300"
      desc = "300 dpi" 
    }
    choice "DPI600" {
      value = "-r600x600"
      desc = "600 dpi" 
    }
  }

  # Now, we handle Postscript input with Ghostscript's ljet4 driver:
  language_driver ps {
    filetype_regx = "postscript"
    convert_exec = { 
       gs -sDEVICE=ljet4 $GS_RES \
          -q -dNOPAUSE -dBATCH -dSAFER \
          -sOutputFile=$OUTPUT $INPUT
    }
  }

  # Finally, we wrap the job in PJL commands:
  filter_exec {
    # requires echo with escape code ability...
    echo -ne '\33%-12345X'  $OUTPUT

    echo "@PJL SET DUPLEX=$DUPLEX_MODE"     $OUTPUT
    # You can add additional @PJL commands like the above line here.
    # Be sure to always append () to the output file!

    cat $INPUT  $OUTPUT
    echo -ne '\33%-12345X'  $OUTPUT
  }
}</programlisting>

     </para></sect4></sect3></sect2><sect2 id="lpd-config-tutorial"><indexterm significance="normal"><primary>LPD</primary><secondary>configuration</secondary></indexterm><indexterm significance="normal"><primary>configuration</primary><secondary>LPD</secondary></indexterm><title>Configuring LPD</title><para>    Most Linux systems ship with LPD.  This section describes a very
    basic setup for LPD; further sections detail the creation of
    complex filters and network configuration.
   </para><sect3 id="basic-lpd-configuration"><title>Basic LPD configuration</title><para>     The minimal setup for lpd results in a system that can queue
     files and print them.  It will not pay any attention to wether or
     not your printer will understand them, and will probably not let
     you produce attractive output.  But we have to start somewhere.
    </para><para>     To add a print queue to lpd, you must add an entry in
     <filename moreinfo="none">/etc/printcap</filename>, and make the new spool
     directory under <filename moreinfo="none">/var/spool/lpd</filename>.
    </para><para>     An entry in <filename moreinfo="none">/etc/printcap</filename> looks like:
<programlisting format="linespecific"># LOCAL djet500
lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :mx#0:\
        :lp=/dev/lp0:\
        :sh:</programlisting>
     This defines a spool called <emphasis>lp</emphasis>,
     <emphasis>dj</emphasis>, or <emphasis>deskjet</emphasis>, spooled
     in the directory <filename moreinfo="none">/var/spool/lpd/dj</filename>, with no
     per-job maximum size limit, which prints to the device
     <filename moreinfo="none">/dev/lp0</filename>, and which does not have a banner
     page (with the name of the person who printed, etc) added to the
     front of the print job.
    </para><para>     Go now and read the man page for <filename moreinfo="none"><ulink url="http://www.linuxprinting.org/man/printcap.5.html">printcap</ulink></filename>.
    </para><para>     The above looks very simple, but there a catch - unless I send in
     files a DeskJet 500 can understand, this DeskJet will print
     strange things.  For example, sending an ordinary Unix text file
     to a deskjet results in literally interpreted newlines, and gets
     me:
<screen format="linespecific">This is line one.
                 This is line two.
                                  This is line three.</screen>
     ad nauseam.  Printing a PostScript file to this spool would get a
     beautiful listing of the PostScript commands, printed out with
     this "staircase effect", but no useful output.
    </para><para id="lpd-filtering-example">     <indexterm significance="normal"><primary><option>if</option></primary></indexterm>
     <indexterm significance="normal"><primary>LPD</primary><secondary><option>if</option></secondary></indexterm>
     Clearly more is needed, and this is the purpose of filtering.
     The more observant of you who read the printcap man page might
     have noticed the spool attributes <option>if</option> and
     <option>of</option>.  Well, <option>if</option>, or the
     input filter, is just what we need here.
    </para><para>     If we write a small shell script called <command moreinfo="none">filter</command>
     that adds carriage returns before newlines, the staircasing can
     be eliminated.  So we have to add in an <option>if</option>
     line to our printcap entry above:
<programlisting format="linespecific">lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :mx#0:\
        :lp=/dev/lp0:\
        :if=/var/spool/lpd/dj/filter:\
        :sh:</programlisting>
A simple filter script might be:
<programlisting format="linespecific">#!perl
# The above line should really have the whole path to perl
# This script must be executable: chmod 755 filter
while(STDIN){chomp $_; print "$_\r\n";};
# You might also want to end with a form feed: print "\f";</programlisting>
     If we were to do the above, we'd have a spool to which we could
     print regular Unix text files and get meaningful results.  (Yes,
     there are four million better ways to write this filter, but few
     so illustrative.  You are encouraged to do this more
     efficiently.)
    </para><para>     The only remaining problem is that printing plain text is really
     not too hot - surely it would be better to be able to print
     PostScript and other formatted or graphic types of output.  Well,
     yes, it would, and it's easy to do.  The method is simply an
     extention of the above linefeed-fixing filter. 
    </para><para>     Such a filter is called a <emphasis>magic</emphasis> filter.  It
     plays the same role as the language filters of PDQ.  Don't bother
     writing one yourself unless you print strange things - there are
     a good many written for you already, and most have easy-to-use
     interactive configuration tools.  You should simply select a
     suitable pre-written filter:
     <variablelist id="lpd-filters-available-now"><indexterm significance="normal"><primary>LPD</primary><secondary>filters</secondary></indexterm><indexterm significance="normal"><primary>filtering</primary><secondary>LPD</secondary></indexterm><varlistentry id="lpdomatic-filter-available"><indexterm significance="normal"><primary>filters</primary><secondary>lpdomatic</secondary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>lpdomatic</secondary></indexterm><indexterm significance="normal"><primary>lpdomatic</primary></indexterm><term>LPD-O-Matic</term><listitem><para><ulink url="http://www.linuxprinting.org/lpd-doc.html">Lpdomatic</ulink> is a filter designed to use data from the Linux

         Printing printer database.  It will soon support essentially
         all free software printer drivers, including regular
         Ghostscript drivers, Uniprint drivers, and the assorted
         filter programs floating around out there.  It works with
         various strains of LPD, including stock BSD, LPRng, and the
         new VA Linux LPD, to allow option selection.
        </para></listitem></varlistentry><varlistentry id="apsfilter-available-now"><indexterm significance="normal"><primary>filters</primary><secondary>APS Filter</secondary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>APS Filter</secondary></indexterm><indexterm significance="normal"><primary>APS Filter</primary></indexterm><term>APS Filter</term><listitem><para><ulink url="http://people.FreeBSD.org/~andreas/apsfilter/">apsfilter</ulink> is a filter designed for use on a wide
                  variety of Unices.  It supports essentially all
                  Ghostscript drivers.  It, too, works with
                  various strains of LPD, including stock BSD and
                  LPRng.  At the moment, this is probably the best
                  third-party system around for non-PostScript
		  printers.
        </para></listitem></varlistentry><varlistentry id="rhs-printfilters-available"><indexterm significance="normal"><primary>filters</primary><secondary>rhs-printfilters</secondary></indexterm><indexterm significance="normal"><primary>rhs-printfilters</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>rhs-printfilters</secondary></indexterm><term>RHS-Printfilters</term><listitem><para>RHS-Printfilters is a filter system constructed by Red Hat.
         It shipped beginning, I think, in version 4 of Red Hat Linux,
         as the backend to the easy-to-use
         <command moreinfo="none">printtool</command> GUI printer configuration tool.
         Other distributions, including Debian, now ship the
         rhs-printfilters/printool combo as a printing option.  Thus
         this filter system is arguably the most widely deployed one.
        </para><para>         The rhs filter system is built on an ascii database listing
         distributed with it.  This listing supports many Ghostscript
         and Uniprint drivers, but not filter-style drivers.  The
         filters constructed also do not support much in the way of
         user-controllable options at print time.
        </para><para>         The <command moreinfo="none">printtool</command> places a configuration file
         named <filename moreinfo="none">postscript.cfg</filename> in the spool
         directory.  Inside this Bourne shell-style file, each setting
         is a variable.  In unusual cases, you can make useful changes
         directly to the config file which the printtool won't allow;
         typically this would be the specification of an unusual
         Ghostscript driver, or a PPD filename for the VA
         rhs-printfilters version.
        </para><para>         VA Linux has made some enhancements to the rhs-printfilters
         system under contract from HP.  With the proper versions, it
         is now possible to select options for Postscript printers
         under control of Adobe PPD files.  I cover this system in
         <xref linkend="lpd-for-postscript-printers"></xref>.
        </para></listitem></varlistentry></variablelist>
    </para><para>     There's one catch to such filters: older version of lpd don't run
     the <emphasis>if</emphasis> filter for remote printers, while
     most newer ones do (although often with no arguments).  The
     version of LPD shipped with modern Linux and FreeBSD
     distributions does; most commercial unices that still ship LPD
     have a version that does not.  See the section on network
     printing later in this document for more information on this.  If
     you only have locally-connected printers, then this won't affect
     you.
    </para></sect3><sect3 id="lpd-for-postscript-printers"><indexterm significance="normal"><primary>PostScript</primary><secondary>printers</secondary></indexterm><indexterm significance="normal"><primary>PostScript</primary><secondary>LPD</secondary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>PostScript</secondary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>VA Linux's version</secondary></indexterm><indexterm significance="normal"><primary>VA Linux</primary><secondary>LPD</secondary></indexterm><title>LPD for PostScript Printers</title><para>     While most versions of LPD don't gracefully handle PostScript
     (nevermind user options), VA Linux recently modified LPD and Red
     Hat's filtering software to support PostScript printers fairly
     well.  For the moment, this system works only with Red Hat 6.2,
     although the packages could be easily adapted for other
     distributions.
    </para><simplesect><title>How it works</title><para>      VA's new system uses Postscript Printer Definition, or PPD,
      files.  PPD files are provided by printer manufacturers and
      declare the available options on a printer, along with the
      Postscript code needed to activate them.  With the VA system,
      the normal LPD scheme works a little differently:
      <orderedlist inheritnum="ignore" continuation="restarts"><listitem><para>The user can specify options with the <option>-o</option>
         flag.  For example, you might specify <option>-o
         MediaType:Transparency</option> if you were about to print on
         overhead film.  Alternatively, the front-end <ulink url="http://www.compumetric.com/linux.html">GPR</ulink> can
         be used to specify options in a dialog box; you can see
         screenshots of GPR in <xref linkend="gpr-intro"></xref>.
        </para></listitem><listitem><para>LPR passes the options to LPD as an extended attribute in the
         LPD control file.
        </para></listitem><listitem><para>A modified version of the rhs-printfilters package is given
         the extended options data in an environment variable, and
         uses ppdfilt to add these options to the print data.
        </para></listitem></orderedlist>
     </para></simplesect><simplesect><title>Obtaining and Installing</title><para>      You can obtain RPM packages, or source tarballs, from the
      project's <ulink url="http://printing.sourceforge.net/">website
      on SourceForge</ulink>.  For installation details, consult the
      project's <ulink url="http://printing.sourceforge.net/gpr-libppd-uhowto.html">installation
      micro-HOWTO</ulink>.   In essence, you need to uninstall the Red
      Hat version of printtool, lpd, and rhs-printfilters entirely,
      and then install the VA versions, plus ppdfilt, gpr, and a few
      other utilities.
     </para><para>      You will also need PPD files for your Postscript printers.
      PPD files are usually fairly easy to find.  VA Linux and HP
      distribute PPD files for many Laserjet models.  Other vendors
      provide PPDs for their own printers, and Adobe distributes
      <ulink url="http://www.adobe.com/products/printerdrivers/winppd.html">PPD files</ulink> for many printers.
     </para><para>      At the moment, much of this is a bit difficult to install.  But
      future installation tools will build upon the printer
      configuration library <command moreinfo="none">libprinterconf</command>, which
      enables both the autodetection and rhs-printfilter configuration
      of both networked and local printers.
     </para><note><para>It is possible to use GPR alone, without the modified LPD
            or even rhs-printfilters.  GPR can be compiled with
            all the logic needed to massage Postscript jobs directly.
            This may be an easier-to-install option suitable for
            people who never really need to print using lpr
            directly.</para></note></simplesect><simplesect><title>Controlling Postscript Options</title><para>      Once you've setup VA's Postscript-capable LPD system, you can
      control your printer's options in two ways:

      <variablelist><varlistentry><term>With the GUI</term><listitem><para>To use GPR, you first make sure that you've specified the
	  proper PPD file.  Then the printer's options will be
	  available on the `Advanced' panel.  Basic
	  <command moreinfo="none">ppdfilt</command> options will be available on the
	  `Common' panel.
         </para></listitem></varlistentry><varlistentry><term>With the command line</term><listitem><para>This <command moreinfo="none">lpr</command> supports the <option>-o</option>
	  option.  You may specify any option/value pair from your
	  printer's PPD file with <option>-o</option>.  For example,
	  consider this PPD file option clause:
<programlisting format="linespecific">*OpenUI *PrintQuality/Print Quality: PickOne
*DefaultPrintQuality: None
*OrderDependency: 150 AnySetup *PrintQuality
*PrintQuality None/Printer Setting: ""
*PrintQuality Quick/QuickPrint:  " /DeviceRenderingInfo ...
*PrintQuality Normal/Normal: " /DeviceRenderingInfo  /...
*PrintQuality Pres/Presentation: " /DeviceRenderingInfo ...
*PrintQuality Image/1200 Image Quality: " /DeviceRenderi...
*CloseUI: *PrintQuality</programlisting>
	  For the option <option>PrintQuality</option>, the possible
	  values are <option>Quick</option>, <option>Normal</option>,
	  <option>Pres</option>, or <option>Image</option>.  You might
	  give a command like:
        <screen format="linespecific"><prompt moreinfo="none">%</prompt> <command moreinfo="none">lpr</command> <option>-o PrintQuality:Image</option> <option>file.ps</option></screen>
         </para><para>          There are a number of options common to all printers which
          will work in addition to the ones from your PPD.  These
          include:

          <variablelist><varlistentry><term><option>page-ranges</option></term><listitem><para>You can specify a range of pages to print.  For example,
              <option>page-ranges:2-3</option>.
             </para></listitem></varlistentry><varlistentry><term><option>page-set</option></term><listitem><para>You can print only odd or even pages.  For example,
              <option>page-set:odd</option>.
             </para></listitem></varlistentry><varlistentry><term><option>number-up</option></term><listitem><para>You can print multiple pages on each piece of paper.
              For example, <option>number-up:2</option>.
             </para></listitem></varlistentry></variablelist>

          Other options are detailed in the <command moreinfo="none">ppdfilt</command>
          man page.

         </para></listitem></varlistentry></variablelist>

     </para></simplesect></sect3><sect3 id="lpd-permissions"><indexterm significance="normal"><primary>LPD</primary><secondary>permissions</secondary></indexterm><title>File Permissions</title><para>     By popular demand, I include below a listing of the permissions
     on interesting files on my system.  There are a number of better
     ways to do this, ideally using only SGID binaries and not making
     everything SUID root, but this is how my system came out of the
     box, and it works for me.  (Quite frankly, if your vendor can't
     even ship a working lpd you're in for a rough ride).
<screen format="linespecific">-r-sr-sr-x   1 root     lp    /usr/bin/lpr*
-r-sr-sr-x   1 root     lp    /usr/bin/lprm*
-rwxr--r--   1 root     root  /usr/sbin/lpd*
-r-xr-sr-x   1 root     lp    /usr/sbin/lpc*
drwxrwxr-x   4 root     lp    /var/spool/lpd/
drwxr-xr-x   2 root     lp    /var/spool/lpd/lp/</screen>

    </para><para>     Lpd must currently be run as root so that it can bind to the
     low-numbered lp service port.  It should probably become UID
     lp.lp or something after binding, but I don't think it does.
     This is simply one more reason to avoid the stock BSD LPD.
    </para><para>     PDQ uses a different, non-daemon-centric scheme, so it has
     different programs.  The only SUID root programs are the lpd
     interface programs <command moreinfo="none">lpdcancel</command>,
     <command moreinfo="none">lpdprint</command>, and
     <command moreinfo="none">lpdstatus</command>; these are SUID because
     actual Unix print servers require print requests to originate
     from a priviledged port.  If the only printers for which you use
     PDQ's bsd-lpd interface are networked print servers (like the HP
     JetDirect or Lexmark's MarkNet adapters) then you do not need the
     SUID bit on these programs.
    </para></sect3></sect2><sect2 id="large-installations"><indexterm significance="normal"><primary>networks</primary><secondary>large</secondary></indexterm><indexterm significance="normal"><primary>environment</primary><secondary>enterprise</secondary></indexterm><title>Large Installations</title><para>    Large installations, by which I mean networks including more than
    two printers or hosts, have special needs.  Below are some tips.
    For really large environments, merely distributing printcap/filter
    information becomes a difficult problem; the <ulink url="http://ceps.sourceforge.net/">Cisco Enterprise Print
    System</ulink> addresses this and is probably either a good starting
    point or a nearly complete solution, depending on your needs.
    Medium to large environments can be well supported by native LPRng
    features.
    <itemizedlist><listitem><para>Each printer should have a single point of control, where an
       administrator can pause, reorder, or redirect the queue.  To
       implement this, have everyone printing to a local server,
       which will then queue jobs and direct them to the proper
       printer.  For large campuses or distributed networks, have one
       server per building or other suitable network subset.
      </para></listitem><listitem><para>Use LPRng, at least on servers; the BSD LPD is too buggy for
       "real" use.  So is CUPS, at least right now in mid-2000.
       But don't take my word for ityou should test a number of
       spoolers and see which suits you best.
      </para></listitem><listitem><para>Client systems should not have unique printing configurations.
       To implement this, use LPRng's extended printcap syntax so
       that you have one printcap to use everywhere.  CEPS provides
       for this by building atop a lightweight distributed database
       instead of traditional printcap files.
      </para></listitem><listitem><para>Print queues should not be named for make or model; name print
       queues for something sensible like location (floor2nw)
       or capability (colortransparency).  Three years from
       now, when a printer breaks, you will be able to replace it
       with a different make or model without causing confusion.
      </para></listitem><listitem><para>Operate a web page which shows detailed information on each
       printer, including location, capabilities, etc.  Consider
       having it show the queue and include a button to remove jobs
       from the queue.  Complex networked environments are
       unmanagable for users without proper documentation.
      </para></listitem><listitem><para>On Unix systems, use PDQ or the like to allow selection of
       print job attributes such as duplex or paper size, and to force
       users to run all Ghostscript processing under the proper user
       ID.  If you have all Postscript printers (as is best), you can
       also select from the GPR or XPP front-ends; both are prettier.
      </para></listitem><listitem><para>On Windows and Apple systems, use either the platform-specific
       drivers <emphasis>everywhere</emphasis> (Samba supports the
       Windows automagical driver-download mechanism) or, better, use
       generic Postscript drivers <emphasis>everywhere</emphasis>.  Do
       not mix and match; primitive word processors often produce
       different output when the installed printer driver changes;
       users cannot deal with output that vaires depending on the
       particular client/printer pair.
      </para></listitem><listitem><para>If at all possible, buy a large-volume printer for
       large-volume printing.  If on a budget, use LPRng's multiple
       printers/one queue facility and assign a babysitter; printers
       are complex mechanical devices that will often jam and run out
       of paper in such configurations.
      </para></listitem><listitem id="network-print-servers-in-large"><indexterm significance="normal"><primary>networks</primary><secondary>print servers</secondary></indexterm><para>Do not feel that printers must be plugged into workstations;
       Ethernet "print servers" now cost under $100.  The ability to
       locate printers anywhere you can network is a big improvement
       over forced location near a host; locate printers in sensible,
       central locations.
      </para></listitem><indexterm significance="normal"><primary>npadmin</primary><secondary>uses</secondary></indexterm><listitem><para>Use any SNMP trap or other monitoring/alert facility available
       to you - someone should be tasked with running around and
       fixing printers with no ink or paper.  Npadmin (see <xref linkend="npadmin"></xref>) can be used to do some management
       operations with SNMP printers. 
      </para></listitem></itemizedlist>
   </para></sect2><sect2 id="accounting"><indexterm significance="normal"><primary>accounting</primary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>accounting</secondary></indexterm><title>Accounting</title><para>    Regular LPD provides very little to help you with accounting.  You
    can specify the name of an accounting file in the
    <option>af</option> printcap attribute, but this is merely passed
    as an argument to your <option>if</option> filter.  It's up to you
    to make your <option>if</option> filter write entries to the
    accounting file, and up to you to process the accounting file
    later (the traditional format is mainly useful for line printers,
    and is nontrivial to parse in Perl, so there's no reason to
    preserve it).  Also, if you're using my
    <command moreinfo="none">lpdomatic</command> program as your filter, you'll need
    to make changes, since it depends on being given a configuration
    file as the ``accounting'' file name.
   </para><para id="gs-accounting">    <indexterm significance="normal"><primary>Ghostscript</primary><secondary>accounting</secondary></indexterm>
    Ghostscript provides a PageCount operator that you can use to
    count the number of pages in each job; basically you just tack a
    few lines of postscript onto the end of the job to write an
    accounting file entry; for the best example of this see the file
    <filename moreinfo="none">unix-lpr.sh</filename> in the Ghostscript source
    distribution.
   </para><para>    Note that the <command moreinfo="none">unix-lpr</command> implementation of
    accounting writes to a file from the Ghostscript interpreter, and
    is thus incompatible with the recommended -dSAFER option.  A
    better solution might be to query the printer with a PJL command
    after each job, or to write a postscript snippet that prints the
    pagecount on stdout, where it can be captured without having to
    write to a file.
   </para><para id="lprng-accounting">    <indexterm significance="normal"><primary>LPRng</primary><secondary>accounting</secondary></indexterm>
    The LPRng print spooler includes an HP-specific sample
    implementation of accounting; I assume that it queries the
    printer with PJL.  This technique should work for most PJL,
    Postscript, or SNMP printers with which you have two-way
    communications.
   </para><indexterm significance="normal"><primary>npadmin</primary><secondary>uses</secondary></indexterm><para>    If you have a networked printer that supports SNMP, you can use
    the npadmin program to query a pagecount after each job.  This
    should work properly for all print jobs.  See <xref linkend="npadmin"></xref> for more information on npadmin.
   </para></sect2></sect1><sect1 id="vendors"><title>Vendor Solutions</title><para>   This section is, by definition, incomplete.  Feel free to send in
   details of your favourite distribution.  At the moment, I am aware
   of no distribution that supports, or even provides, the software I
   recommend: PDQ.
  </para><para>   There are a number of third-party packages out there designed to
   make printer configuration under Unix easy.  These are covered in
   <xref linkend="setup"></xref>; see the subsection there for your
   particular spooling software for pointers.
  </para><sect2 id="rhs-filters-come-with-redhat"><indexterm significance="normal"><primary>Red Hat</primary></indexterm><indexterm significance="normal"><primary>filters</primary><secondary>rhs-printfilters</secondary></indexterm><title>Red Hat</title><para>    Red Hat has a GUI printer administration tool called printtool
    which can add remote printers and printers on local devices.  It
    lets you choose a ghostscript-supported printer type and Unix
    device file to print to, then installs a print queue in
    <filename moreinfo="none">/etc/printcap</filename> and uses a filter program from
    the rhs-printfilters package to support postscript and other
    common input types.  This solution works fairly well, and is
    trivial to setup for common cases.
   </para><para>    Where Red Hat fails is when you have a printer which isn't
    supported by their standard Ghostscript (which is GNU rather than
    Aladdin Ghostscript, and which supports fewer printers).  Check in
    the printer compatibility list above (or <ulink url="http://www.linuxprinting.org/printer_list.cgi">online</ulink>) if you find that you can't print properly with the stock Red
    Hat software.  If your printer isn't supported by Red Hat's tools,
    you may need to install a contributed verison of Aladdin
    Ghostscript, and will probably also be better off if you use the
    lpdomatic or apsfilter packages, which know all about the printers
    supported by late-model Ghostscripts, and others besides.
   </para><para>    In future versions of Red Hat the printtool will be reimplemented
    to support a larger list of printers and with the intent to
    support an eventual rhs-printfilters replacement (the current
    filter has difficulty with many common printers like some non-PCL
    DeskJets and most Lexmarks).  Some VA Linux-developed PPD features
    may be incorporated, as well.
   </para></sect2><sect2 id="debian-what-comes-with"><indexterm significance="normal"><primary>Debian</primary></indexterm><title>Debian</title><para>    Debian offers a choice between plain LPD, LPRng, or CUPS; LPRng or
    CUPS are probably the better choices.  I believe Debian also
    offers a choice of printer configuration tools; apsfilter version
    5 or later is probably your best bet, since that verison adds
    support for LPRng and Ghostscript's uniprint driver scheme.  Red
    Hat's printtool is also supported, for those who like GUI
    administration tools.
   </para></sect2><sect2 id="suse-what-comes-with"><indexterm significance="normal"><primary>SuSE</primary></indexterm><indexterm significance="normal"><primary>APS Filter</primary><secondary>SuSE</secondary></indexterm><indexterm significance="normal"><primary>filters</primary><secondary>APS Filter</secondary></indexterm><title>SuSE</title><para>    The printing system on SuSE Linux is based on apsfilter, with some
    enhancements; SuSE's apsfilter will recognize all common file
    formats (including HTML, if html2ps is installed).  There are two
    ways to setup printers on SuSE systems:
    <itemizedlist><listitem><para>YaST will let you configure "PostScript", "DeskJet" and "Other
       printers", supported by Ghostscript drivers; it's also possible
       to setup HP's GDI printers (DeskJet 710/720, 820, 1000, via the
       "ppa" package).  YaST will provide
       <filename moreinfo="none">/etc/printcap</filename> entries for every printer
       ("raw", "ascii", "auto" and "color", if the printer to
       configure is a color printer).  YaST will create spool
       directories and it will arrange apsfilterrc files, where you're
       able to fine tune some settings (Ghostscript preloads, paper
       size, paper orientation, resolution, printer escape sequences,
       etc.).  With YaST it's also possible to setup network printers
       (TCP/IP, Samba, or Novell Netware Printer).
      </para></listitem><listitem><para>In addition SuSE includes the regular SETUP program from the
       original apsfilter package (with some enhancements); run
       <command moreinfo="none">lprsetup</command> to invoke this configuration
       script.  Once you get accustomed to its GUI, you'll be able to
       configure local and network printers.
      </para></listitem></itemizedlist>
   </para><para>    The SuSE installation manual explains both of these setup
    procedures.
   </para><para>    Wolf Rogner reported some difficulties with SuSE.  Apparently the
    following bugs may bite:
    <itemizedlist><listitem><para>Apsfilter's regular SETUP script is a bit broken, as are the
       KDE setup tools.  Use YaST.  [ Ed: does this still apply?  It's
       been some time sice Wolf's report. ]
      </para></listitem><listitem><para>For networked printers that need to be fed from Ghostscript,
       you'll need to first uncomment the line
       REMOTEPRINTER="remote" in
       <filename moreinfo="none">/etc/apsfilterrc</filename>.  Then run YaST to
       configure the printer and, under Network configurations, set up
       a remote printer queue.
      </para></listitem><listitem><para>YaST's setup doesn't allow color laser printers, so configure a
       mono printer and then change mono to color everwhere in the
       printcap entry.  You may have to rename the spool directory,
       too.
      </para></listitem></itemizedlist>
   </para></sect2><sect2 id="caldera-what-comes-with"><indexterm significance="normal"><primary>Caldera</primary></indexterm><indexterm significance="normal"><primary>LPRng</primary><secondary>Caldera</secondary></indexterm><title>Caldera</title><para>Caldera ships LPRng.  I have no idea what sort of setup tools they
    offer.
   </para></sect2><sect2 id="corel-what-comes-with"><indexterm significance="normal"><primary>Corel</primary></indexterm><indexterm significance="normal"><primary>Debian</primary><secondary>Corel</secondary></indexterm><title>Corel</title><para>Corel is Debian-based, so all the Debian facts above should still
    apply.  In addition, they've written their own setup
    tool, based on the sysAPS library which in turn uses my database.
    They've certainly done so as part of WordPerfect. 
   </para><para>    Corel operates a printing support newsgroup named <ulink url="news://cnews.corel.com/corelsupport.linux.printing">corelsupport.linux.printing</ulink>.  The bulk of the traffic
    appears to be WordPerfect and Corel Linux related.
   </para></sect2><sect2 id="mandrake-what-comes-with"><indexterm significance="normal"><primary>Mandrake</primary></indexterm><title>Mandrake</title><para>    As of version 7.2b1, Mandrake ships with CUPS standard.  The
    program QtCUPS is used to provide a clean GUI administration
    interface.  Till went to some trouble to include as many drivers
    as possible, and they ship CUPS PPD files build with my own
    <ulink url="http://www.linuxprinting.org/foomatic.html">foomatic</ulink>
    interface code. 
   </para><para>I think Earlier Mandrake versions shipped with the Red Hat
   printtool.</para></sect2><sect2 id="other-dists"><title>Other Distributions</title><para>Please send me info on what other distributions do!
   </para></sect2></sect1><sect1 id="ghostscript"><indexterm significance="normal"><primary>Ghostscript</primary></indexterm><indexterm significance="normal"><primary>Postscript</primary><seealso>Ghostscript</seealso></indexterm><title>Ghostscript.</title><para>   <ulink url="http://www.cs.wisc.edu/~ghost/">Ghostscript</ulink> is
   an incredibly significant program for Linux printing.  Most
   printing software under Unix generates PostScript, which is
   typically a 100 option on a printer.  Ghostscript, however,
   is free, and will generate the language of your printer from
   PostScript.  When tied in with your PDQ printer driver declaration
   or <command moreinfo="none">lpd</command> input filter, it gives you a virtual
   PostScript printer and simplifies life immensely.
  </para><para>   Ghostscript is available in two forms.  The commercial version of
   Ghostscript, called Aladdin Ghostscript, may be used freely for
   personal use but may not be distributed by commercial entities.  It
   is generally a year or so ahead of the free Ghostscript; at the
   moment, for example, it supports many color inkjets that the older
   Ghostscripts do not and has rather better PDF support.
  </para><para>   The free version of Ghostscript is GNU Ghostscript, and is simply
   an aged version of Aladdin ghostscript.  This somewhat awkward
   arrangement has allowed Aladdin to be a totally self-funded free
   software project; the leading edge versions are done by L Peter and
   a few employees, and are licensed to hardware and software vendors
   for use in commercial products.  Unfortunately, while this scheme
   has provided for L Peter's continued work on Ghostscript for
   years, it has also inhibited the participation of the wider free
   software community.  Driver authors, in particular, find the
   arrangement poor.  L Peter's retirement plans mandate a larger
   community involvement in the project, so he is considering license
   changes, and has established a SourceForge project.
  </para><para>   Whatever you do with <command moreinfo="none"><ulink url="http://www.linuxprinting.org/man/gs.1.html">gs</ulink></command>, be very sure to run it with the option for disabling
   file access (<option>-dSAFER</option>).  PostScript is a fully
   functional language, and a bad PostScript program could give you
   quite a headache.
  </para><para>   Speaking of PDF, Adobe's Portable Document Format (at least through
   1.3) is actually little more than organized PostScript in a
   compressed file.  Ghostscript can handle PDF input just as it does
   PostScript.  So you can be the first on your block with a
   PDF-capable printer.
  </para><sect2 id="invoking-gs"><title>Invoking Ghostscript</title><para>    Typically, Ghostscript will be run by whatever filter you settle
    upon (I recommend <command moreinfo="none">apsfilter</command> or my own
    <command moreinfo="none">lpdomatic</command> if your vendor didn't supply anything
    that suits you), but for debugging purposes it is often handy to
    run it directly.
   </para><para>    <command moreinfo="none">gs -help</command> will give a brief listing of options
    and available drivers (note that this list is the list of drivers
    compiled in, not the master list of all available drivers).
   </para><para>    You might run gs for testing purposes like: `<command moreinfo="none">gs
	  options -q -dSAFER -sOutputFile=/dev/lp1
	  test.ps</command>'. 
   </para></sect2><sect2 id="gs-tuning-stuff"><indexterm significance="normal"><primary>Ghostscript</primary><secondary>tuning</secondary></indexterm><title>Ghostscript output tuning</title><para>    There are a number of things one can do if Ghostscript's output is
    not satisfactory (actually, you can do anything you darn well
    please, since you have the source).
   </para><para>    Some of these options, and others are described in the Ghostscript
    User Guide (the file <filename moreinfo="none"><ulink url="http://www.cs.wisc.edu/~ghost/aladdin/doc/Use.htm">Use.htm</ulink></filename> in the Ghostscript distribution;
    possibly installed under <filename moreinfo="none">/usr/doc</filename> or
    <filename moreinfo="none">/usr/share/doc</filename> on your system) are all
    excellent candidates for driver options in your filter system or
    PDQ driver declaration.
   </para><sect3 id="gs-output-loc-size"><title>Output location and size</title><para>     The location, size, and aspect ratio of the image on a page is
     controlled by the printer-specific driver in ghostscript.  If you
     find that your pages are coming out scrunched too short, or too
     long, or too big by a factor of two, you might want to look in
     your driver's source module and adjust whatever parameters jump
     out at you.  Unfortunately, each driver is different, so I can't
     really tell you what to adjust, but most of them are reasonably
     well commented.
    </para></sect3><sect3 id="gsgamma"><indexterm significance="normal"><primary>photograph</primary><secondary>gamma</secondary></indexterm><title>Gamma, dotsizes, etc.</title><para>     Most non-laser printers suffer from the fact that their dots are
     rather large. This results in pictures coming out too dark. If
     you experience this problem with an otherwise untunable driver,
     you could use your own transfer function.  Simply create the
     following file in the ghostscript lib-dir and add its name to the
     gs call just before the actual file. You may need to tweak the
     actual values to fit your printer. Lower values result in a
     brighter print.  Especially if your driver uses a Floyd-Steinberg
     algorithm to rasterize colors, lower values ( 0.2 - 0.15 ) are
     probably a good choice.
    </para><para><programlisting format="linespecific">%!
%transfer functions for cyan magenta yellow black
{0.3 exp} {0.3 exp} {0.3 exp} {0.3 exp} setcolortransfer</programlisting>
    </para><para>     It is also possible to mend printers that have some kind of
     color fault by tweaking these values. If you do that kind of
     thing, I recommend using the file
     <filename moreinfo="none">colorcir.ps</filename>, that comes with ghostscript (in
     the <filename moreinfo="none">examples/</filename> subdirectory), as a test page.
    </para><para>     For many of the newer color inkjet drivers, there are
     command-line options, or different upp driver files, which
     implement gamma and other changes to adapt the printer to
     different paper types.  You sould look into this before playing
     with Postscript to fix things.
    </para></sect3><sect3 id="gscolor"><title>Color Printing in Ghostscript</title><indexterm significance="normal"><primary>photograph</primary><secondary>color</secondary></indexterm><para>     Ghostscript's default color dithering is optimized for
     low-resolution devices.  It will dither rather coarsely in an
     attempt to produce 60ppi output (not dpi, ppi - the "apparent"
     color pixels per inch you get after dithering).  This produces
     rather poor output on modern color printers; inkjets with photo
     paper, in particular, are capable of mich finer ppi settings.
    </para><para>     To adjust this, use the Ghostscript option
     <option>-dDITHERPPI=x</option>, where <option>x</option> is the
     value to use.  This may or may not have an effect with all
     drivers; many newer drivers (the Epson Stylus
     <command moreinfo="none">stp</command> driver, for example) implement their own
     dithering and pay no attention to this setting.  Some drivers can
     use either the regular Ghostscript or driver-specific dithering
     (the Canon Bubblejet <command moreinfo="none">bjc600</command> driver, for
     example).
    </para><para>     Ghostscript's dithering is in fact rather rudimentary.  Many
     things needed for good output on modern printers are simply not
     available in the Ghostscript core.  Various projects to fix this
     situationand the free software world does have the
     software to do so ready and waitingare hampered by
     Ghostscript's licensing situation and the resulting "cathedral"
     development style.  Beginning at the <ulink url="http://www.linuxprinting.org/summit.html">Open Source
     Printing Summit 2000</ulink>, however, all the necessary people are
     talking, so you can expect this situation to improve shortly.
    </para></sect3></sect2></sect1><sect1 id="network"><indexterm significance="normal"><primary>networks</primary></indexterm><title>Networks</title><para>   One of the features of most spoolers is that they support printing
   over the network to printers physically connected to a different
   machine, or to the network directly.  With the careful combination
   of filter scripts and assorted utilities, you can print
   transparently to printers on all sorts of networks.
  </para><sect2 id="network-to-unix"><indexterm significance="normal"><primary>networks</primary><secondary>Unix</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>LPD</secondary></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary>Unix networks</secondary></indexterm><title>Printing to a Unix/lpd host</title><para>    To allow remote machines to print to your printer using the LPD
    protocol, you must list the machines in
    <emphasis>/etc/hosts.equiv</emphasis> or
    <emphasis>/etc/hosts.lpd</emphasis>.  (Note that
    <emphasis>hosts.equiv</emphasis> has a host of other effects; be
    sure you know what you are doing if you list any machine there).
    You can allow only certain users on the other machines to print to
    your printer by usign the <emphasis>rs</emphasis> attribute; read
    the <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/lpd.8.html">lpd</ulink></literal> man page for information on this.
   </para><sect3 id="network-to-unix-with-pdq"><indexterm significance="normal"><primary>networks</primary><secondary>PDQ</secondary></indexterm><indexterm significance="normal"><primary>PDQ</primary><secondary>Unix networks</secondary></indexterm><title>With <literal moreinfo="none" remap="tt">pdq</literal></title><para>     With PDQ, you define a printer with the interface type "bsd-lpd".
     This interface takes arguments for the remote hostname and queue
     name; the printer definition wizard will prompt you for these.
    </para></sect3><sect3 id="network-to-unix-with-lpd"><title>With <literal moreinfo="none" remap="tt">lpd</literal></title><para>     To print to another machine, you make an
     <emphasis>/etc/printcap</emphasis> entry like this:
<screen format="linespecific"># REMOTE djet500
lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :rm=machine.out.there.com:\
        :rp=printername:\
        :sh:</screen>
     Note that there is still a spool directory on the local machine
     managed by <literal moreinfo="none" remap="tt">lpd</literal>.  If the remote
     machine is busy or offline, print jobs from the local machine
     wait in the spool area until they can be sent.
    </para></sect3><sect3 id="network-to-unix-with-rlpr"><indexterm significance="normal"><primary>rlpr</primary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>rlpr</secondary></indexterm><title>With <literal moreinfo="none" remap="tt">rlpr</literal></title><para>     You can also use <emphasis>rlpr</emphasis> to send a print job
     directly to a queue on a remote machine without going through the
     hassle of configuring lpd to handle it.  This is mostly useful in
     situations where you print to a variety of printers only
     occasionally.  From the announcement for
     <emphasis>rlpr</emphasis>:
    </para><para>     Rlpr uses TCP/IP to send print jobs to lpd servers anywhere on a
     network.
    </para><para>     Unlike lpr, it *does not* require that the remote printers be
     explicitly known to the machine you wish to print from,
     (e.g. through <emphasis>/etc/printcap</emphasis>) and thus is
     considerably more flexible and requires less administration.
    </para><para>     rlpr can be used anywhere a traditional lpr might be used, and is
     backwards compatible with traditional BSD lpr.
    </para><para>     The main power gained by rlpr is the power to print remotely
     *from anywhere to anywhere* without regard for how the system you
     wish to print from was configured.  Rlpr can work as a filter
     just like traditional lpr so that clients executing on a remote
     machine like netscape, xemacs, etc, etc can print to your local
     machine with little effort.
    </para><para>     Rlpr is available from <literal moreinfo="none" remap="tt"><ulink url="ftp://metalab.unc.edu/pub/Linux/system/printing/">Metalab</ulink></literal>.
    </para></sect3></sect2><sect2 id="network-to-windows"><indexterm significance="normal"><primary>networks</primary><secondary>Windows</secondary></indexterm><indexterm significance="normal"><primary>Windows</primary><secondary>printing to</secondary></indexterm><title>Printing to a Windows or Samba printer</title><para>    There is a Printing to Windows mini-HOWTO out there which has more
    info than there is here.
   </para><sect3 id="network-to-windows-with-pdq"><indexterm significance="normal"><primary>PDQ</primary><secondary>Windows networks</secondary></indexterm><title>From PDQ</title><para>     There is not a prebuilt smb interface that I am aware of, but it
     would be fairly easy to create using the model set by the
     Netatalk-based appletalk interface.  Someone please create one
     and submit it for inclusion!
    </para><para>     Read the Windows/LPD section below for more tips on how to do it.
    </para></sect3><sect3 id="network-to-windows-with-lpd"><indexterm significance="normal"><primary>LPD</primary><secondary>Windows networks</secondary></indexterm><title>From LPD</title><para>     It is possible to direct a print queue through the <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/smbclient.1.html">smbclient</ulink></literal> program (part of the samba suite)
     to a TCP/IP based SMB print service.  Samba includes a script to
     do this called <literal moreinfo="none" remap="tt">smbprint</literal>.  In short,
     you put a configuration file for the specific printer in question
     in the spool directory, and install the <literal moreinfo="none" remap="tt">smbprint</literal> script as the
     <emphasis>if</emphasis>.
    </para><para>     The <emphasis>/etc/printcap</emphasis> entry goes like this:
<screen format="linespecific">lp|remote-smbprinter:\
    :sh:\
    :lp=/dev/null:\
    :sd=/var/spool/lpd/lp:\
    :if=/usr/local/sbin/smbprint:</screen>
    </para><para>     You should read the documentation inside the <literal moreinfo="none" remap="tt">smbprint</literal> script for more information on how
     to set this up.
    </para><para>     You can also use <literal moreinfo="none" remap="tt">smbclient</literal> to
     submit a file directly to an SMB printing service without
     involving <literal moreinfo="none" remap="tt">lpd</literal>.  See the man page.
    </para></sect3></sect2><sect2 id="network-to-netware"><title>Printing to a NetWare Printer</title><indexterm significance="normal"><primary>networks</primary><secondary>Netware</secondary></indexterm><indexterm significance="normal"><primary>PDQ</primary><secondary>Netware networks</secondary></indexterm><indexterm significance="normal"><primary>Netware</primary><secondary>printing to</secondary></indexterm><para>    The ncpfs suite includes a utility called <literal moreinfo="none" remap="tt">nprint</literal> which provides the same functionality
    as <literal moreinfo="none" remap="tt">smbprint</literal> but for NetWare.  You
    can get ncpfs from <ulink url="ftp://metalab.unc.edu/pub/Linux/system/filesystems/ncpfs/">Metalab</ulink>.  From the LSM entry for version 0.16:
   </para><para>    <quote>     With ncpfs you can mount volumes of your netware server under
     Linux. You can also print to netware print queues and spool
     netware print queues to the Linux printing system. You need
     kernel 1.2.x or 1.3.54 and above. ncpfs does NOT work with any
     1.3.x kernel below 1.3.54.
    </quote>
   </para><sect3 id="network-to-netware-with-lpd"><indexterm significance="normal"><primary>LPD</primary><secondary>Netware networks</secondary></indexterm><title>From LPD</title><para>     To make <literal moreinfo="none" remap="tt">nprint</literal> work via lpd, you
     write a little shell script to print stdin on the NetWare
     printer, and install that as the <emphasis>if</emphasis> for an
     lpd print queue.  You'll get something like:
<screen format="linespecific">sub2|remote-NWprinter:\
        :sh:\
        :lp=/dev/null:\
        :sd=/var/spool/lpd/sub2:\
        :if=/var/spool/lpd/nprint-script:</screen>

     The <literal moreinfo="none" remap="tt">nprint-script</literal> might look
     approximately like:
<screen format="linespecific">#! /bin/sh
# You should try the guest account with no password first!
/usr/local/bin/nprint -S net -U name -P passwd -q printq-name -</screen>

    </para></sect3></sect2><sect2 id="network-to-apple"><indexterm significance="normal"><primary>networks</primary><secondary>Apple</secondary></indexterm><indexterm significance="normal"><primary>Apple</primary><secondary>printing to</secondary></indexterm><title>Printing to an EtherTalk (Apple) printer</title><para>    The netatalk package includes something like <literal moreinfo="none" remap="tt">nprint</literal> and <literal moreinfo="none" remap="tt">smbclient</literal>.  Others have documented the
    procedure for printing to and from an Apple network far better
    than I ever will; see the <ulink url="http://thehamptons.com/anders/netatalk/">Linux
    Netatalk-HOWTO</ulink>.
   </para><sect3 id="network-to-apple-from-pdq"><title>From PDQ</title><indexterm significance="normal"><primary>PDQ</primary><secondary>Apple networks</secondary></indexterm><para>     PDQ includes an interface declaration called "appletalk".  This
     uses the Netatalk package to print to a networked Apple printer.
     Just select this interface in xpdq's "Add printer" wizard.
    </para></sect3></sect2><sect2 id="networked-printers"><indexterm significance="normal"><primary>networks</primary><secondary>network printers</secondary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>print servers</secondary></indexterm><title>Printing to a networked printer</title><indexterm significance="normal"><primary>LPD</primary><secondary>network printers</secondary></indexterm><indexterm significance="normal"><primary>PDQ</primary><secondary>network printers</secondary></indexterm><para>    Many printers come with an ethernet interface which you can print
    to directly, typically using the LPD protocol.  You should
    follow the instructions that came with your printer or its network
    adaptor, but in general, such printers are "running" lpd, and
    provide one or more queues which you can print to.  An HP, for
    example, might work with a printcap like:
<screen format="linespecific">lj-5|remote-hplj:\
        :sh:\
        :sd=/var/spool/lpd/lj-5:\
        :rm=printer.name.com:\
        :rp=raw:</screen>
    or, using the PDQ bsd-lpd interface arguments of
    REMOTEHOST=printer.name.com and QUEUE=raw.
   </para><para>    HP Laserjet printers with JetDirect interfaces generally support
    two built in lpd queues - "raw" which accepts PCL (and possibly
    Postscript) and "text" which accepts straight ascii (and copes
    automatically with the staircase effect).  If you've got a
    JetDirect Plus3 three-port box, the queues are named "raw1",
    "text2", and so forth.
   </para><para>    Note that the ISS company has identified an assortment of denial
    of service attacks which hang HP Jetdirect interfaces.  Most of
    these have been addressed beginning in Fall 98.  These sorts of
    problems are common in embedded code; few appliance-style devices
    should be exposed to general Internet traffic.
   </para><indexterm significance="normal"><primary>environment</primary><secondary>enterprise</secondary></indexterm><para>    In a large scale environment, especially a large environment where
    some printers do not support PostScript, it may be useful to
    establish a dedicated print server to which all machines print and
    on which all ghostscript jobs are run.  This will allow the queue
    to be paused or reordered using the topq and lprm commands.
   </para><para>    This also allows your Linux box to act as a spool server for the
    printer so that your network users can complete their print jobs
    quickly and get on with things without waiting for the printer to
    print any other job that someone else has sent.  This is suggested
    too if you have unfixable older HP Jetdirects; it reduces the
    likelihood of the printers wedging.
   </para><para>    To do this, set up a queue on your linux box that points at the
    ethernet equipped HP LJ (as above). Now set up all the clients on
    your LAN to point at the Linux queue (eg lj-5 in the example
    above).
   </para><para>    Some HP network printers apparently don't heed the banner page
    setting sent by clients; you can turn off their internally
    generated banner page by telnetting to the printer, hitting return
    twice, typing "banner: 0" followed by "quit".  There are other
    settings you can change this way, as well; type "?" to see a list.
   </para><para>    The full range of settings can be controlled with HP's <ulink url="http://www.hp.com/go/webjetadmin">webJetAdmin</ulink>
    software.  This package runs as a daemon, and accepts http
    requests on a designated port.  It serves up forms and Java
    applets which can control HP printers on the network.  In theory,
    it can also control Unix print queues, but it does so using the
    rexec service, which is completely unsecure.  I don't advise using
    that feature.
   </para><sect3 id="networked-printers-appsocket"><indexterm significance="normal"><primary>AppSocket protocol</primary></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>AppSocket protocol</secondary></indexterm><indexterm significance="normal"><primary>HP</primary><secondary>JetDirect</secondary></indexterm><title>To AppSocket Devices</title><indexterm significance="normal"><primary>LPRng</primary><secondary>AppSocket protocol</secondary></indexterm><para>     Some printers (and printer networking "black boxes") support only
     a cheesy little non-protocol involving plain TCP connections;
     this is sometimes called the "AppSocket" protocol.  Notable in
     this category are early-model JetDirect (including some
     JetDirectEx) cards.  Basically, to print to the printer, you must
     open a TCP connection to the printer on a specified port
     (typically 9100, or 9100, 9101 and 9102 for three-port boxes) and
     stuff your print job into it.  LPRng has built-in support for
     stuffing print jobs into random TCP ports, but with BSD lpd it's
     not so easy.  The best thing is probably to obtain and use the
     little utility called netcat.
    </para><para id="networked-printers-from-spoolers">    <indexterm significance="normal"><primary>PDQ</primary><secondary>AppSocket protocol</secondary></indexterm>
    <indexterm significance="normal"><primary>LPD</primary><secondary>AppSocket protocol</secondary></indexterm>

     A netcat-using PDQ interface would look something like this:
<programlisting format="linespecific">interface tcp-port-0.1 {

   help "This is one of the first interfaces supported by standalone
         network printers and print servers.  The device simply
         listens for a TCP connection on a certain port, and sends
         data from any connection to the printer.\nThis interface
         requires the netcat program (\"nc\")."

   required_args "REMOTE_HOST"

   argument { 
      var = "REMOTE_HOST"
      desc = "Remote host"
      help = "This is IP name or number of the print server."
   }

   argument { 
      var = "REMOTE_PORT"
      def_value = "9100"
      desc = "Remote port"
      help = "This is the TCP port number on the print server that the
              print job should be sent to.  Most JetDirect cards, and
              clones, accept jobs on port 9100 (or 9101 for port 2,
              etc)."
   }

   requires "nc"

   send_exec { cat $OUTPUT | nc $REMOTE_HOST $REMOTE_PORT }
 
}</programlisting>

    </para><para>     Failing that, it can be implemented, among other ways, in Perl
     using the program below.  For better performance, use the
     program netcat ("nc"), which does much the same thing in a
     general purpose way.  Most distributions should have netcat
     available in prepackaged form.
    </para><para><programlisting format="linespecific">#!/usr/bin/perl
# Thanks to Dan McLaughlin for writing the original version of this
# script (And to Jim W. Jones for sitting next to Dan when writing me
# for help ;)

$fileName = @ARGV[0];

open(IN,"$fileName") || die "Can't open file $fileName";

$dpi300     = "\x1B*t300R";
$dosCr      = "\x1Bk3G";
$ends = "\x0A";

$port =  9100 unless $port;
$them = "bach.sr.hp.com" unless $them;

$AF_INET = 2;
$SOCK_STREAM = 1;
$SIG{'INT'} = 'dokill';
$sockaddr = 'S n a4 x8';

chop($hostname = `hostname`);
($name,$aliases,$proto) = getprotobyname('tcp');
($name,$aliases,$port) = getservbyname($port,'tcp')
    unless $port =~ /^\d+$/;;
($name,$aliases,$type,$len,$thisaddr) =
        gethostbyname($hostname);
($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);
$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
$that = pack($sockaddr, $AF_INET, $port, $thataddr);

if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
#    print "socket ok\n";
}
else {
    die $!;
}
# Give the socket an address.
if (bind(S, $this)) {
#    print "bind ok\n";
}
else {
    die $!;
}

# Call up the server.

if (connect(S,$that)) {
#    print "connect ok\n";
}
else {
    die $!;
}

# Set socket to be command buffered.

select(S); $| = 1; select(STDOUT);

#    print S "@PJL ECHO Hi $hostname! $ends";
#    print S "@PJL OPMSG DISPLAY=\"Job $whoami\" $ends";
#    print S $dpi300;

# Avoid deadlock by forking.

if($child = fork) {
    print S $dosCr;
    print S $TimesNewR;

    while (IN) {
        print S;
    }
    sleep 3;
    do dokill();
} else {
    while(S) {
        print;
    }
}

sub dokill {
    kill 9,$child if $child;
}</programlisting>

    </para></sect3></sect2><sect2 id="if-for-remote-printers"><indexterm significance="normal"><primary><option>if</option></primary><seealso>LPD</seealso></indexterm><indexterm significance="normal"><primary>LPD</primary><secondary><option>if</option></secondary></indexterm><title>Running an <option>if</option> for remote printers with old
          LPDs</title><para>    One oddity of older versions of lpd is that the <option>if</option>
    is not run for remote printers.  (Versions after 0.43 or so have
    the change originated on FreeBSD such that the <option>if</option>
    is always run).  If you find that you need to run an
    <option>if</option> for a remote printer, and it isn't working
    with your lpr, you can do so by setting up a double queue and
    requeueing the job.  As an example, consider this
    <filename moreinfo="none">printcap</filename>:
   </para><para><programlisting format="linespecific">lj-5:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/lj-5:\
        :if=/usr/lib/lpd/filter-lj-5:
lj-5-remote:sh:rm=printer.name.com:\
        :rp=raw:sd=/var/spool/lpd/lj-5-raw:</programlisting>

    in light of this <command moreinfo="none">filter-lj-5</command> script:
<programlisting format="linespecific">#!/bin/sh
gs options -q -dSAFER -sOutputFile=- - | \
        lpr -Plj-5-remote -U$5</programlisting>

   </para><para>    The <option>-U</option> option to lpr only works if lpr is run
    as daemon, and it sets the submitter's name for the job in the
    resubmitted queue correctly.  You should probably use a more
    robust method of getting the username, since in some cases it is
    not argument 5.  See the man page for <filename moreinfo="none"><ulink url="http://www.linuxprinting.org/man/printcap.5.html">printcap</ulink></filename>.
   </para></sect2><sect2 id="network-from-windows"><indexterm significance="normal"><primary>Windows</primary><secondary>printing from</secondary></indexterm><indexterm significance="normal"><primary>Windows</primary><secondary>samba</secondary><see>samba</see></indexterm><indexterm significance="normal"><primary>networks</primary><secondary>Windows</secondary></indexterm><title>From Windows.</title><indexterm significance="normal"><primary>samba</primary></indexterm><para>     Printing from a Windows (or presumably, OS/2) client to a Linux
     server is directly supported over SMB through the use of the
     SAMBA package, which also supports file sharing of your Linux
     filesystem to Windows clients.
    </para><para>     Samba includes fairly complete documentation, and there is a good
     Samba FAQ which covers it, too.  You can either configure a magic
     filter on the Linux box and print PostScript to it, or run around
     installing printer-specific drivers on all the Windows machines
     and having a queue for them with no filters at all.  Relying on
     the Windows drivers may in some cases produce better output, but
     is a bit more of an administrative hassle if there are many
     Windows boxen.  So try Postscript first.  Modern versions of
     Samba should support the automagical driver download mechanism
     offered by Windows NT servers to deal with this problem.
    </para><indexterm significance="normal"><primary>PDQ</primary><secondary>from Windows</secondary></indexterm><para>     With PDQ, you should configure Samba to run the pdq command with
     appropriate arguments instead of the lpr command that it defaults
     to running.  I believe that Samba will run pdq as the proper
     user, so it should work well this way.  There are several Samba
     options that you should adjust to do this:
     <variablelist><varlistentry><term>printcap</term><listitem><para>This should point to a "fake" printcap you whip up listing
         available printers.  All you need is a short and long name
         for each printer, one per line:
<screen format="linespecific">lp1|Printer One
lp2|Printer Two
lp3|Printer Three</screen>
         The short name will be used as the printer name for the print
         command:
        </para></listitem></varlistentry><varlistentry><term>print command</term><listitem><para>This will need to be set to something like <literal moreinfo="none" remap="tt">pdq -P p s ; rm
         s</literal>.
        </para></listitem></varlistentry><varlistentry><term>lprm command</term><listitem><para>There doesn't seem to be a good value for this setting at the
        moment.  PDQ's queued jobs will expire after a time, so if the
        printer is totally gone there's no problem.  If you just
        change your mind, you can use <command moreinfo="none">xpdq</command> to
        cancel jobs, but this is inconvenient from Windows.  Just put
        a do-nothing command like <command moreinfo="none">true</command> for now.  If
        you use <command moreinfo="none">lpd</command> or LPRng as the back-end, then
        a suitable <command moreinfo="none">lprm</command> command should work.  I'm
        not sure how Samba would identify the lpr queue entry number
        for a pdq-submitted job.
       </para></listitem></varlistentry><varlistentry><term>lpq command</term><listitem><para>Again, PDQ doesn't offer a good value to put here.
        Distributed systems don't offer a sensible way to see the
        queue, but samba-centric centralized server systems want to
        have a queue worth examining.  Just put a do-nothing command
        like <command moreinfo="none">true</command> for now.  If you use LPD or LPRng
        as the back-end, then a suitable <command moreinfo="none">lpq</command>
        command should work; you just won't see jobs until they're
        done being filtered by PDQ.
       </para></listitem></varlistentry></variablelist>
   </para></sect2><sect2 id="networks-from-apple"><indexterm significance="normal"><primary>networks</primary><secondary>Apple</secondary></indexterm><indexterm significance="normal"><primary>Apple</primary><secondary>printing from</secondary></indexterm><indexterm significance="normal"><primary>netatalk</primary></indexterm><indexterm significance="normal"><primary>Apple</primary><secondary>netatalk</secondary><see>netatalk</see></indexterm><title>From an Apple.</title><para>    Netatalk supports printing from Apple clients over EtherTalk.  See
    the <ulink url="http://thehamptons.com/anders/netatalk/">Netatalk
    HOWTO Page</ulink> for more information.
   </para></sect2><sect2 id="networks-from-netware"><indexterm significance="normal"><primary>networks</primary><secondary>Netware</secondary></indexterm><indexterm significance="normal"><primary>Netware</primary><secondary>printing from</secondary></indexterm><indexterm significance="normal"><primary>ncpfs</primary></indexterm><indexterm significance="normal"><primary>Netware</primary><secondary>ncpfs</secondary><see>ncpfs</see></indexterm><title>From Netware.</title><para>    The ncpfs package includes a daemon named pserver which can be
    used to privide service to a NetWare print queue.  From what I
    understand, this system requires a Bindery-based NetWare, ie 2.x,
    3.x, or 4.x with bindery access enabled.
   </para><para>    For more information on ncpfs and it's pserver program, see <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/">the ncpfs FTP
    site</ulink>.
   </para></sect2><sect2><indexterm significance="normal"><primary>networks</primary><secondary>administration</secondary></indexterm><indexterm significance="normal"><primary>npadmin</primary></indexterm><title>Networked Printer Administration</title><para>    Most networked printers support some method of remote
    administration.  Often there are easy-to-use web pages for
    configuration.  More usefully, there is often support for SNMP
    management.  Typically you can find out interesting information on
    printer status like ink and paper levels, print volumes, and so
    forth, and you can usually change certain settings.  SNMP printer
    control, and a number of other printing-related things, are being
    standardized by the IEEE's <ulink url="http://www.pwg.org/">Printer Working Group</ulink>
   </para><sect3 id="npadmin"><title><command moreinfo="none">npadmin</command></title><para>     <ulink url="http://npadmin.sourceforge.net/">Npadmin</ulink> is a
     command-line program which offers an interface to the common SNMP
     functionality of networked printers.  It implements the standard
     <ulink url="http://www.ietf.org/rfc/rfc1759.txt">Printer
     MIB</ulink>, as well as a few vendor-proprietary schemes used
     mainly for older devices.  Both printer-discovery style actions
     and various printer status queries are supported.
    </para><para>     npadmin has an excellent <ulink url="http://npadmin.sourceforge.net/man/">man page</ulink>, and
     precompiled packages are distributed for a number of RPM and dpkg
     based distributions.
    </para></sect3><sect3><title>Other SNMP tools</title><para>     Besides npadmin, there are a number of SNMP tools that will be
     useful.  <command moreinfo="none">snmptraplogd</command> can log SNMP trap
     events.  This is useful for observing printer jams, out of paper
     events, etc; it would be straightforward to retransmit certain
     events to a pager, or to send an email.
    </para><para>     While npadmin provides simplified support for many network
     printers' SNMP interfaces, some printers may have vendor
     extensions which npadmin doesn't know about.  In this case, you
     can use the CMU SNMP tools, which support arbitrary SNMP GET and
     SET operations, as well as walks and the like.  With these, and a
     bit of work, you can make use of any SNMP feature offered by your
     printer's MIB.  You may need to obtain a MIB from your vendor to
     figure out what all the variables are; sometimes vendors think
     that people actually use the proprietary tools they ship.
    </para><para>     VA Linux's <command moreinfo="none"><ulink url="http://sourceforge.net/project/?group_id=3648">libprinterconf</ulink></command> includes code to perform
     network printer discovery.  Printers are identified against a
     compiled-in library of printer signatures; at the moment the
     library is not large, but does cover many common networked
     printer models.
    </para></sect3></sect2></sect1><sect1 id="winprinters"><indexterm significance="normal"><primary>winprinters</primary><secondary>workarounds</secondary></indexterm><title>Windows-only printers</title><para>   As I discussed earlier, some printers are inherently unsupported
   because they don't speak a normal printer language, instead using
   the computer's CPU to render a bitmap which is then piped to the
   printer at a fixed speed.  In a few cases, these printers also
   speak something normal like PCL, but often they do not.  In some
   (really low-end) cases, the printer doesn't even use a normal
   parallel connection but relies on the vendor's driver to emulate
   what should be hardware behaviour (most importantly flow control).
  </para><para>   In any case, there are a few possible workarounds if you find
   yourself stuck with such a lemon.
  </para><sect2 id="gs-win-redirector"><title>The Ghostscript Windows redirector</title><para>    There is now a Windows printer driver available (called
    <command moreinfo="none">mswinpr2</command>) that will run a print job through
    Ghostscript before finally printing it.  (Rather like an
    <option>if</option> filter in Unix's LPD).  There is also a new
    Ghostscript driver which will print using Windows GDI calls.
    Taken all together, this allows a Windows machine to print
    PostScript to a Windows-only printer through the vendor's driver.
   </para><para>    If you get that working, you can then follow the instructions
    above for printing to a Windows printer over the network from
    Linux to let Unix (and other Windows, Mac, etc) hosts print to
    your lemon printer.
   </para></sect2><sect2 id="hp-winprinters"><title>HP Winprinters</title><para>    Some HP printers use "Printing Performance Architecture"
    (marketingspeak for "we were too cheap to implement PCL").  This
    is supported in a roundabout way via the pbm2ppa translator
    written by Tim Norman.  Basically, you use ghostscript to render
    PostScript into a bitmapped image in pbm format and then use
    pbm2ppa to translate this into a printer-specific ppa format
    bitmap ready to be dumped to the printer.  This program may also
    come in ghostscript driver format by now.
   </para><para>    The ppa software can be had from <ulink url="http://www.rpi.edu/~normat/technical/ppa/">the ppa home
    page</ulink>; pbm2ppa supports some models of the HP 720, 820,
    and 1000; read the documentation that comes with the package for
    more details on ppa printer support.
   </para></sect2><sect2 id="lex-winprinters"><title>Lexmark Winprinters</title><para>    Most of the cheap Lexmark inkjets use a proprietary language and
    are therefore Winprinters.  However, Henryk Paluch has written a
    program which can print on a Lexmark 7000.  Hopefully he'll be
    able to figure out color and expand support to other Lexmark
    inkjets.  See <ulink url="http://bimbo.fjfi.cvut.cz/~paluch/l7kdriver/">here</ulink>
    for more info.
   </para><para>    Similarly, there are now drivers for the 5700, 1000, 1100, 2070,
    3200, and others.  See the supported printers listing above, and
    my web site, for more information on obtaining these drivers.
   </para></sect2></sect1><sect1 id="faxing"><title>How to print to a fax machine.</title><para>   You can print to a fax machine with, or without, a modem.
  </para><sect2 id="using-a-faxmodem"><title>Using a faxmodem</title><para>    There are a number of fax programs out there that will let you fax
    and receive documents.  One of the most powerful is Sam Leffler's
    <productname class="trade"><ulink url="http://www.hylafax.org/">HylaFAX</ulink></productname>.  It supports all sorts of things
    from multiple modems to broadcasting.
   </para><para>    SuSE ships a Java HylaFax client which allegedly works on any Java
    platform (including Windows and Linux).  There are also non-Java
    fax clients for most platforms; Linux can almost certainly handle
    your network faxing needs.
   </para><para id="efax">    <indexterm significance="normal"><primary>environment</primary><secondary>home</secondary></indexterm>
    Also available, and a better choice for smaller installations, is
    <command moreinfo="none"><ulink url="http://casas.ee.ubc.ca/efax/">efax</ulink></command>, a simple program which sends and receives faxes.  The
    getty program <command moreinfo="none">mgetty</command> can receive faxes using
    <command moreinfo="none">efax</command> (and do voicemail or interactive logins).
   </para><sect3 id="fax-from-pdq"><title>Faxing from PDQ</title><para>     PDQ doesn't ship with a fax interface declaration, but here's a
     simple one (which is only partly tested):
<programlisting format="linespecific">interface efax-0.1 {
   help "This interface uses the efax package's fax program to send a
         fax.  You should first get efax's \"fax send\" working by
         itself by editing the file /etc/efax.rc and testing.  Connect
         this interface to a generic postscript driver to define a
         fax machine \"printer\"". 

   requires { "efax" "fax" }

   # Making phone number required means that the add printer wizard
   # will demand a phone number at add printer time.  This is
   # undesirable, so it isn't explicitly required, even though it is
   # logically required.  The send_exec script checks for the number.
   # You could skip the wizard by adding this printer by hand to
   # .printrc, mark this as required, and it might then prompt?
   argument {
      var = "PHONE_NUMBER"
      desc = "Phone Number"
      help = "The phone number to dial.  Prefixes like 9 ought to be
              defined in your /etc/efax.rc file."
   }

   option {
      var = "RESOLUTION"
      desc = "Fax resolution"
      default_choice = "high"
      choice "low" {
         value = "-l"
         desc = "Low"
         help = "Low resolution on a fax is 96lpi."         
      }
      choice "high" {
         value = ""
         desc = "High"
         help = "High resolution on a fax is 192lpi."         
      }
   }

   # If you don't specify a phone number the job just fails, and 
   # the only way to figure this out is to look at the error message
   # at the bottom of the job details.  Hmm.
   send_exec { 
     if [ "x$PHONE_NUMBER" != "x" ] 
     then
          fax send $RESOLUTION $PHONE_NUMBER $INPUT
     else 
          echo 'You must specify a phone number!'
          false
     fi
   }
}</programlisting>

    </para></sect3></sect2><sect2 id="fax-via-email"><title>Using the Remote Printing Service</title><para>    There is an experimental service offered that lets you send an
    email message containing something you'd like printed such that it
    will appear on a fax machine elsewhere.  Nice formats like
    postscript are supported, so even though global coverage is
    spotty, this can still be a very useful service.  For more
    information on printing via the remote printing service, see the
    <ulink url="http://www.tpc.int/">Remote Printing WWW Site</ulink>.
   </para></sect2><sect2 id="fax-via-web"><title>Commercial Faxing Services</title><para>    A number of companies operate web-based faxing services.  <ulink url="http://www.efax.com/">EFax</ulink>, in particular, offers
    free inbound faxes (to your own dedicated fax number, no less) via
    email, and fax transmission for a fee.  Other companies offer
    similar services.
   </para></sect2></sect1><sect1 id="authoring"><title>How to generate something worth printing.</title><para>   Here we get into a real rat's-nest of software.  Basically, Linux
   can run many types of binaries with varying degrees of success:
   Linux/x86, Linux/Alpha, Linux/Sparc, Linux/foo, iBCS, Win16/Win32s
   (with dosemu and, someday, with Wine), Mac/68k (with Executor), and
   Java.  I'll just discuss native Linux and common Unix software.
  </para><sect2 id="markup-languages"><title>Markup languages</title><para>    Most markup languages are more suitable for large or repetitive
    projects, where you want the computer to control the layout of the
    text to make things uniform.
    <variablelist><varlistentry><term><command moreinfo="none">nroff</command></term><listitem><para>This was one of the first Unix markup languages.  Man pages
        are the most common examples of things formatted in *roff
        macros; many people swear by them, but nroff has, to me at
        least, a more arcane syntax than needed (see <xref linkend="roff-example"></xref>), and probably makes a poor choice for
        new works.  It is worth knowing, though, that you can typeset
        a man page directly into postscript with groff.  Most man
        commands will do this for you with <command moreinfo="none">man -t foo
         lpr</command>.
       </para><figure float="0" id="roff-example"><title>Example of <command moreinfo="none">roff</command> Input</title><programlisting format="linespecific">.B man
is the system's manual pager. Each
.I page
argument given to 
.B man
is normally the name of a program, utility or function. 
The 
.I manual page 
associated with each of these arguments is then found and
displayed. A 
.IR section ,
if provided, will direct
.B man
to look 
only in that
.I section
of the manual.</programlisting></figure></listitem></varlistentry><varlistentry><term>TeX</term><listitem><para>TeX, and the macro package LaTeX, are one of the most widely
        used markup languages on Unix.  Technical works are frequently
        written in LaTeX because it greatly simplifies the layout
        issues and is <emphasis>still</emphasis> one of the few text
        processing systems to support mathematics both completely and
        well.  TeX's output format is <filename moreinfo="none">dvi</filename>, and is
        converted to PostScript or Hewlett Packard's PCL with
        <command moreinfo="none">dvips</command> or <command moreinfo="none">dvilj</command>.  If you
        wish to install TeX or LaTeX, install the whole teTeX group of
        packages; it contains everything.  Recent TeX installations
        include pdfTeX and pdfLaTeX, which produce Adobe PDF files
        directly.  Commands are available do create hyperlinks and
        navigation features in the PDF file.
       </para><figure float="0" id="latex-example"><title>Example of LaTeX Input</title><programlisting format="linespecific">\subsubsection{NAT}

  Each real server is assigned a different IP address, and the NA
  implements address translation for all inbound and outbound
  packets.

  \begin{description}
  \item[Advantage] Implementation simplicity, especially if we
        already implement other NAT capabilities.

  \item[Disadvantage] Return traffic from the server goes through
        address translation, which may incur a speed penalty.  This
        probably isn't too bad if we design for it from the
        beginning.

  \item[Disadvantage] NAT breaks the end-to-end semantics of normal
        internet traffic.  Protocols like ftp, H.323, etc would
        require special support involving snooping and in-stream
        rewriting, or complete protocol proxying; neither is likely
        to be practical.
  \end{description}</programlisting></figure></listitem></varlistentry><varlistentry><term>SGML</term><listitem><para>There is at least one free SGML parser available for Unix and
        Linux; it forms the basis of Linuxdoc-SGML's homegrown
        document system.  It can support other DTD's, as well, most
        notably DocBook.  This document is written in DocBook-DTD
        SGML; see <xref linkend="sgml-example"></xref> for an example.
       </para><figure float="0" id="sgml-example"><title>Example of DocBook SGML</title><programlisting format="linespecific">VarListEntry
 TermSGML/Term
 ListItem
  Para
   There is at least one free SGML parser available for Unix 
   and Linux; it forms the basis of Linuxdoc-SGML's homegrown 
   document system.  It can support other DTD's, as well, most
   notably DocBook.  This document is written in DocBook-DTD 
   SGML.
  /Para
 /ListItem
/VarListEntry</programlisting></figure></listitem></varlistentry></variablelist>
   </para></sect2><sect2 id="wysiwyg-processors"><title>WYSIWYG Word Processors</title><para>    There is no shortage of WYSIWYG word processing software.  Several
    complete office suites are available, including one that's free
    for personal use (StarOffice).
    <variablelist><varlistentry><term>StarOffice</term><listitem><para>Sun Microsystems is distributing StarOffice on the net free
        for Linux.  This full-blown office suite has all the features
        you'd expect, including both import and export of Microsoft
        Office file formats (including Word documents).  There's a
        mini-HOWTO out there which describes how to obtain and install
        it.  It generates PostScript, so should work with most any
        printer that works otherwise on Linux.
       </para></listitem></varlistentry><varlistentry><term>WordPerfect</term><listitem><para>Corel distributes a basic version of WordPerfect 8 free for
        Linux, and sells various packages of Word Perfect Office 2000
        (which includes WordPerfect, Corel Draw and Quattro Pro
        Versions 9).  The <ulink url="http://www.rodsbooks.com/wpfonts/"> Linux WordPerfect
        Fonts and Printers</ulink> page has information about
        configuring WordPerfect for use with either Ghostscript or its
        built-in printer drivers (which are apparently identical the
        DOS WordPerfect drivers, if your printer's driver isn't
        included in the distribution).
       </para></listitem></varlistentry><varlistentry><term>Applix</term><listitem><para>Applix is a cross-platform (ie, various Unices, Windows, and
        others) office suite sold by the Applix company.  Red Hat and
        SuSE sold it themselves when it was the only game in town;
        now sales have reverted to Applix.  This is the only native
        Unix-style application suite; it probably fits in better with
        the Unix way of doign things.
       </para></listitem></varlistentry><varlistentry><term>AbiWord</term><listitem><para><ulink url="http://www.abisource.com/">AbiWord</ulink> is one
        of several GPL WYSIWYG word processor projects; this one has
        produced a very nice word processor based on an XML format.
        It is capable of Word file import.  AbiWord is still a work in
        progress, although it is useful for small things now.
       </para><figure float="0"><title>AbiWord</title><graphic fileref="snapshot-abiword" scale="60"></graphic></figure></listitem></varlistentry><varlistentry><term>LyX</term><listitem><para>LyX is a front-end to LaTeX which looks very promising.  See
        the <ulink url="http://www.lyx.org/">LyX Homepage</ulink>
        for more information.  There is a KDE-styled version of LyX,
        called Klyx; the author of LyX and the instigator of KDE are
        the same person.
       </para><figure float="0"><title>LyX</title><graphic fileref="snapshot-lyx" scale="60"></graphic></figure></listitem></varlistentry><varlistentry><term>Maxwell</term><listitem><para>Maxwell is a simple MS RTF-format based word processor which
        started as a commercial product but is now distributed under
        the GPL.
       </para></listitem></varlistentry></variablelist>
   </para><para>    Other vendors should feel free to drop me a line with your offerings.
   </para></sect2></sect1><sect1 id="photos"><title>Printing Photographs</title><indexterm significance="normal"><primary>photograph</primary><secondary>tips</secondary></indexterm><para>   There are many details to getting decent photo output from common
   printers.  If you haven't bought a photo printer yet, see the
   photo-related tips in <xref linkend="shopping"></xref>.
  </para><sect2 id="gs-photos-tips-and-tricks"><indexterm significance="normal"><primary>Ghostscript</primary><secondary>photographs</secondary></indexterm><indexterm significance="normal"><primary>photograph</primary><secondary>Ghostscript</secondary></indexterm><title>Ghostscript and Photos</title><para>    Ghostscript has some difficulties rendering color photographs
    through most drivers.  The problems are several:
    <itemizedlist><listitem><para>Many drivers have poorly tuned color support.  Often the
       colors don't match the Windows driver output or the screen.
       OTOH, all drivers, and Ghostscript as a whole, have readily
       adjustable color support; the "Gamma" settings (see
       <xref linkend="gsgamma"></xref>) are one thing
       to play with, and there are others documented in Ghostscript's
       <filename moreinfo="none">Use.htm</filename> documentation file.
      </para></listitem><listitem><para>I'm only aware of one Ghostscript driver with support for 6
       and 7 color printing; it's in beta at the moment and supports
       most Epson Stylus Photo models.  It is rumoured to produce
       better color than the Windows driver (!).  The Ghostscript
       driver core itself provides no support for non CMYK or RGB
       colors; arguably, some work to put that there is needed.
      </para></listitem><listitem><para>Ghostscript often ends up dithering coarsely, or generating
       printouts with artifacts like banding.  The dithering can
       usually be corrected; see <xref linkend="gscolor"></xref>, and read
       the documentation for your driver.
      </para></listitem></itemizedlist>
    You should be able to correct some of these problems by tuning
    Ghostscript; see <xref linkend="ghostscript"></xref> for more
    information on how to do this.  Fiddling with Ghostscript options
    is much easier if you declare them as options in your spooling system.
   </para><para>    That said, the obvious solution for now is to use non-Ghostscript
    software for printing photos, and indeed, such things do exist.
    The main contender is the print plugin in the Gimp, which supports
    pixel-for-pixel printing on Epson Styluses and Postscript printers
    (with basic PPD support).  That Epson Stylus portion of that
    driver is available for Ghostcript, as well, as the
    <command moreinfo="none">stp</command> driver.  Also possible to use for this
    purpose are the assorted external pnm-to-foo programs used to
    print on printers like the cheap Lexmarks; these print attempt to
    print pixmaps pixel-for-pixel.
   </para><para>    The best solution, of course, is to buy a Postscript printer;
    such printers can usually be completely controlled from available
    free software, and will print to the full capability of the
    printer.
   </para></sect2><sect2 id="paper-for-inkjets"><indexterm significance="normal"><primary>paper</primary><secondary>quality</secondary></indexterm><title>Paper</title><para>    Color inkjets are extremely dependent on the paper for good
    output.  The expensive glossy coated inkjet papers will allow you
    to produce near-photographic output, while plain uncoated paper
    will often produce muddy colors and fuzzy details.  Nonglossy
    coated inkjet papers will produce results in between, and are
    probably best for final prints of text, as well.  Stiffer glossy
    coated "photo" papers will produce similar output to
    lighter-weight glossy papers, but will feel like a regular photo.
   </para></sect2><sect2 id="photo-printer-settings"><title>Printer Settings</title><para>    For photo output on most color inkjets, you should use the most
    highly interlaced (and slowest) print mode; otherwise solid
    regions may have banding or weak colors.  Generally with
    Ghostscript this is what will happen when you pick the highest
    resolution.  With Postscript printers, you may need to add a
    snippet to the prologue based on the settings available in the PPD
    file.  The Gimp's PPD support doesn't include (printer-specific)
    print quality settings, but I added one in an ugly way for my own
    use; contact me if you'd like that.  If you use PDQ or CUPS, you
    can easily control all the printer settings you need.  VA Linux's
    <command moreinfo="none">libppd</command> and the GPR front-end can also add these
    options for Postscript printers.
   </para></sect2><sect2 id="inkjet-archiving"><indexterm significance="normal"><primary>archiving</primary><secondary>print durability</secondary></indexterm><title>Print Durability</title><para>    Color inkjet printouts usually fade after a few years, especially
    if exposed to lots of light and air; this is a function of the
    ink.  Printers with ink-only consumables like the Epsons and
    Canons can buy archival inks, which are less prone to this
    problem.  Newer printers often use pigment-based inks, which
    don't fade as much as the older dye-based ink did.  No inkjet
    output is really particularly good for long-term archival use.
    Write the bits to a CD-R and store that instead.
   </para></sect2><sect2 id="commercial-photo-printing-software"><indexterm significance="normal"><primary>photograph</primary><secondary>commercial software</secondary></indexterm><title>Shareware and Commercial Software</title><para>    There's a program called <ulink url="http://home.t-online.de/home/jj.sarton/startE.htm">xwtools</ulink> which supports photo printing with all the
    bells and whistles on an assortment of Epson, HP, and Canon
    printers.  Unfortunately, it was written under NDA, so comes
    without source.  Unless you use it for the Epson Stylus Color 300
    on Linux x86, it costs E15 for personal use; commercial pricing
    is unknown.
   </para><para>    The ESP Print Pro package from Easy Software supports some
    printers which might otherwise be unsupported.  These drivers are
    not reported to be very well-tuned for photos, but they do work.
   </para></sect2></sect1><sect1 id="previewing"><indexterm significance="normal"><primary>previewing</primary></indexterm><title>On-screen previewing of printable things.</title><para>   Nearly anything you can print can be viewed on the screen, too.
  </para><sect2 id="previewing-with-ghostscript"><indexterm significance="normal"><primary>Ghostscript</primary><secondary>previewing</secondary></indexterm><indexterm significance="normal"><primary>previewing</primary><secondary>Postscript</secondary></indexterm><indexterm significance="normal"><primary>Postscript</primary><secondary>previewing</secondary></indexterm><title>PostScript</title><para>    Ghostscript has an X11 driver best used under the management of
    the PostScript previewer <ulink url="http://wwwthep.physik.uni-mainz.de/~plass/gv/">gv</ulink>.
    The latest versions of these programs should be able to view PDF
    files, as well.  Note that gv has replaced the older previewer
    "Ghostview"; the new user interface is mch prettier and featureful
    that ghostview's plain old Athena GUI.
   </para><figure float="0"><title>Gv</title><graphic fileref="snapshot-gv" scale="60"></graphic></figure></sect2><sect2 id="previewing-tex-dvi"><title>TeX dvi</title><para>    TeX DeVice Independent files may be previewed under X11 with
    <ulink url="http://www.linuxprinting.org/man/xdvi.1.html">xdvi</ulink>.  Modern versions of xdvi call ghostscript to
    render PostScript specials.
   </para><para>    A VT100 driver exists as well.  It's called <literal moreinfo="none" remap="tt">dgvt</literal>.  <literal moreinfo="none" remap="tt">Tmview</literal>
    works with Linux and svgalib, if that's all you can do.
   </para></sect2><sect2 id="pdf-previewing"><indexterm significance="normal"><primary>Ghostscript</primary><secondary>previewing</secondary></indexterm><indexterm significance="normal"><primary>previewing</primary><secondary>PDF</secondary></indexterm><indexterm significance="normal"><primary>PDF</primary><secondary>previewing</secondary></indexterm><title>Adobe PDF</title><para>    Adobe's Acrobat Reader is available for Linux; just download it
    from the <ulink url="http://www.adobe.com/">Adobe web site</ulink>.
   </para><para>    You can also use xpdf, which is free software, and I believe
    <command moreinfo="none">gv</command> supports viewing PDF files with gs under X11.
   </para></sect2></sect1><sect1 id="serial"><indexterm significance="normal"><primary>ports</primary><secondary>serial</secondary></indexterm><title>Serial printers under lpd</title><para>   Serial printers are rather tricky under lpd.
  </para><sect2 id="serial-printcap"><title>Setting up in printcap</title><para>    Lpd provides five attributes which you can set in
    <emphasis>/etc/printcap</emphasis> to control all the settings of
    the serial port a printer is on.  Read the <emphasis><ulink url="http://www.linuxprinting.org/man/printcap.5.html">printcap</ulink></emphasis> man page and note the meanings of
    <emphasis>br</emphasis>, <emphasis>fc</emphasis>,
    <emphasis>xc</emphasis>, <emphasis>fs</emphasis> and
    <emphasis>xs</emphasis>.  The last four of these attributes
    are bitmaps indicating the settings for use the port.  The
    <emphasis>br</emphasis> atrribute is simply the baud rate, ie
    `<literal moreinfo="none" remap="tt">br9600</literal>'.
   </para><para>    It is very easy to translate from <ulink url="http://www.linuxprinting.org/man/stty.1.html">stty</ulink> settings to printcap flag settings. If you need to,
    see the man page for stty now.
   </para><para>    Use stty to set up the printer port so that you can cat a file to
    it and have it print correctly. Here's what `<emphasis>stty
    -a</emphasis>' looks like for my printer port:

<screen format="linespecific">dina:/usr/users/andy/work/lpd/lpd# stty -a  /dev/ttyS2
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = undef;
eol2 = undef; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr 
-igncr -icrnl ixon -ixoff -iuclc -ixany -imaxbel
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 
bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop -echoprt -echoctl -echoke</screen>

    The only changes between this and the way the port is initialized
    at bootup are <literal moreinfo="none" remap="tt">-clocal</literal>, <literal moreinfo="none" remap="tt">-crtscts</literal>, and <literal moreinfo="none" remap="tt">ixon</literal>. Your port may well be different
    depending on how your printer does flow control.
   </para><para>    You actually use stty in a somewhat odd way.  Since stty operates
    on the terminal connected to it's standard input, you use it to
    manipulate a given serial port by using the `<literal moreinfo="none" remap="tt"></literal>' character as above.
   </para><para>    Once you have your stty settings right, so that `<emphasis>cat
    file  /dev/ttyS2</emphasis>' (in my case) sends the file to
    the printer, look at the file
    /usr/src/linux/include/asm-i386/termbits.h. This contains a lot of
    defines and a few structs (You may wish to cat this file to
    the printer (you do have that working, right?) and use it as
    scratch paper).  Go to the section that starts out
   </para><para><screen format="linespecific">/* c_cflag bit meaning */
#define CBAUD   0000017</screen>

    This section lists the meaning of the <emphasis>fc</emphasis>
    and <emphasis>fs</emphasis> bits. You will notice that the
    names there (after the baud rates) match up with one of the lines
    of stty output. Didn't I say this was going to be easy?
   </para><para>    Note which of those settings are preceded with a - in your stty
    output. Sum up all those numbers (they are octal). This represents
    the bits you want to clear, so the result is your
    <emphasis>fc</emphasis> capability.  Of course, remember that
    you will be setting bits directly after you clear, so you can just
    use `<literal moreinfo="none" remap="tt">fc0177777</literal>' (I do).
   </para><para>    Now do the same for those settings (listed in this section) which
    do not have a - before them in your stty output. In my example the
    important ones are CS8 (0000060), HUPCL (0002000), and CREAD
    (0000200). Also note the flags for your baud rate (mine is
    0000015). Add those all up, and in my example you get
    0002275. This goes in your <emphasis>fs</emphasis> capability
    (`<literal moreinfo="none" remap="tt">fs02275</literal>' works fine in my
    example).
   </para><para>    Do the same with set and clear for the next section of the include
    file, "clflag bits". In my case I didn't have to set
    anything, so I just use `<literal moreinfo="none" remap="tt">xc0157777</literal>' and `<literal moreinfo="none" remap="tt">xs0</literal>'.
   </para></sect2><sect2><title>Older serial printers that drop characters</title><para>    Jon Luckey points out that some older serial printers with
    ten-cent serial interfaces and small buffers
    <emphasis>really</emphasis> mean stop when they say so with flow
    control.  He found that disabling the FIFO in his Linux box's
    16550 serial port with <literal moreinfo="none" remap="tt"><ulink url="http://www.linuxprinting.org/man/setserial.8.html">setserial</ulink></literal> corrected the problem of dropped
    characters (you apparently just specify the uart type as an 8250
    to do this).
   </para></sect2></sect1><sect1 id="development"><title>What's missing?</title><para>   Many of the parts for a complete printing system do not exist yet.
   Projects are underway to address most of these, although most have
   not yet produced running useful code, and efforts to standardize
   the necessary protocols and APIs are in their infancy.
  </para><simplesect><title>Plumbing</title><para>    There's a general problem with getting all the parts to talk to
    one another; especially in a spooler-independent way.  This
    problem manifests itself most noticably in the pathetic
    application support for control over all the "usual" printing
    features.  There is simply no way for an application writer to get
    information about printers, jobs, etc; no standardized way to
    submit jobs; no good way to get job status back; nor even really a
    standardized way to generate print data (although most of the new
    desktop systems offer desktop-specific facilities for doing this).
   </para><para>    Work to define a sensible API for applications to use for printing
    will undoubtedly center around Corel's sysAPS library, which
    provides a rudimentary implementation of several queueing and
    printer information features.
   </para></simplesect><simplesect><title>Fonts</title><para>    Font handling on free systems is rather awkward.  The display, the
    printer, the application, and the data files should ideally all
    have access to the same fonts.  Unfortunately this is simply not
    the case.  Plans are afoot to remove font handling from the X
    server, simplifying part of the problem, but good printer font to
    application font mapping is still a problem.  No project really
    seems to be underway to address this; currently application
    writers simply embed their own fonts into printed data.
   </para></simplesect><simplesect><title>Metadata</title><para>    Applications or spoolers need to learn about printer and driver
    properties somehow.  The current standardized scheme, implemented
    on Windows, the Mac, and in CUPS, is to use Postscript Printer
    Description files to drive a programatic interface and user
    interface.  This had trouble for non-Postscript printers, for
    obvious reasons, so the IEEE's Printer Working Group has a project
    to specify "Universal Printer Driver Format", or UPDF, files.
    Thus far they have constructed a sample file in an XML format.
    The sample file strongly resembles a PPD file, and is missing all
    sorts of driver and platform specific information; so much so that
    UPDF is currently not useful.  IBM has a fully parameterized
    driver architecture for OS/2 which is available as free software;
    once this is released it is bound to be a useful source of ideas
    or code, and possibly a good enough system to just use outright.
    Even this system, however, provides no defined mechanism for
    communicating interesting properties from the driver space up to
    the application.  Some XML format, and/or an API for fetching
    assorted properties, is bound to appear at some point.
   </para></simplesect><simplesect><title>Drivers</title><para>    The state of free software drivers is rather poor.  Fortunately,
    several projects are underway to correct this, and impressive
    results can now be had on printers using that code.  The eventual
    goal seems to be to provide both good drivers and a good framework
    for the frequently duplicated (and hard!) parts of driver
    codedithering, for exampleto be shared.  
   </para><para>    Printer vendor cooperation will be an important part of achieving
    this goal.  Vendors currently do not provide the minimum
    documentation necessary to operate their devices well.  At the
    Printing Summit 2000, many vendors were present, and some small
    headway was made on this point.  Vendors are mainly concerned with
    keeping the dithering and related algorithms secret; these
    software components are what produces such remarkable inkjet
    output, and the vendors are of course competing.  Those vendors
    present at the summit should now have a clearer picture of how
    free software works and what we want from them.  This isn't much;
    bt it sets the stage for future progress.
   </para></simplesect></sect1><sect1 id="credits"><title>Credits</title><para>   Special thanks to Jacob Langford, author of <literal moreinfo="none" remap="tt">pdq</literal>, who finally gave us something better than
   the smattering of scripts globbed onto a 20 year old overgrown
   line-printer control program.
  </para><para>   The <literal moreinfo="none" remap="tt">smbprint</literal> information is from an
   article by Marcel Roelofs <literal moreinfo="none" remap="tt">marcel@paragon.nl</literal>.
  </para><para>   The <literal moreinfo="none" remap="tt">nprint</literal> information for using
   Netware printers was provided by Michael Smith <literal moreinfo="none" remap="tt">mikes@bioch.ox.ac.uk</literal>.
  </para><para>   The serial printers under lpd section is from Andrew Tefft <literal moreinfo="none" remap="tt">teffta@engr.dnet.ge.com</literal>.
  </para><para>   The blurb about gammas and such for gs was sent in by Andreas
   <literal moreinfo="none" remap="tt">quasi@hub-fue.franken.de</literal>.
  </para><para>   The two paragraphs about the 30 second closingwait of the
   serial driver was contributed by Chris Johnson <literal moreinfo="none" remap="tt">cdj@netcom.com</literal>.
  </para><para>   Robert Hart sent a few excellent paragraphs about setting up a print
   server to networked HPs which I used verbatim.
  </para><para>   And special thanks to the dozens upon dozens of you who've pointed
   out typos, bad urls, and errors in the document over the years.
  </para></sect1><index id="doc-index"><title>Index</title><indexdiv><title>A</title><indexentry><primaryie>accounting,
    <ulink url="setup.html#ACCOUNTING" role="AEN1996">Accounting</ulink>
  </primaryie></indexentry><indexentry><primaryie>Apple
  </primaryie><secondaryie>netatalk
  </secondaryie><seeie>netatalk</seeie><secondaryie>printing from,
    <ulink url="network.html#NETWORKS-FROM-APPLE" role="AEN2431">From an Apple.</ulink>
  </secondaryie><secondaryie>printing to,
    <ulink url="network.html#NETWORK-TO-APPLE" role="AEN2292">Printing to an EtherTalk (Apple) printer</ulink>
  </secondaryie></indexentry><indexentry><primaryie>AppSocket protocol,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2334">To AppSocket Devices</ulink>
  </primaryie></indexentry><indexentry><primaryie>APS Filter,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1825">Basic LPD configuration</ulink>
  </primaryie><secondaryie>SuSE,
    <ulink url="vendors.html#SUSE-WHAT-COMES-WITH" role="AEN2048">SuSE</ulink>
  </secondaryie></indexentry><indexentry><primaryie>archiving
  </primaryie><secondaryie>print durability,
    <ulink url="photos.html#INKJET-ARCHIVING" role="AEN2653">Print Durability</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>C</title><indexentry><primaryie>Caldera,
    <ulink url="vendors.html#CALDERA-WHAT-COMES-WITH" role="AEN2074">Caldera</ulink>
  </primaryie></indexentry><indexentry><primaryie>configuration
  </primaryie><secondaryie>LPD,
    <ulink url="setup.html#LPD-CONFIG-TUTORIAL" role="AEN1755">Configuring LPD</ulink>
  </secondaryie><secondaryie>PDQ,
    <ulink url="setup.html#PDQ-CONFIG" role="AEN1620">Configuring PDQ</ulink>
  </secondaryie></indexentry><indexentry><primaryie>Corel,
    <ulink url="vendors.html#COREL-WHAT-COMES-WITH" role="AEN2082">Corel</ulink>
  </primaryie></indexentry><indexentry><primaryie>CUPS,
    <ulink url="spoolers.html#CUPS-WHICH-SPOOLER" role="AEN1393">CUPS</ulink>
  </primaryie><secondaryie>XPP
  </secondaryie><seeie>XPP</seeie></indexentry></indexdiv><indexdiv><title>D</title><indexentry><primaryie>Debian,
    <ulink url="vendors.html#DEBIAN-WHAT-COMES-WITH" role="AEN2041">Debian</ulink>
  </primaryie><secondaryie>Corel,
    <ulink url="vendors.html#COREL-WHAT-COMES-WITH" role="AEN2084">Corel</ulink>
  </secondaryie></indexentry><indexentry><primaryie>drivers
  </primaryie><secondaryie>port
  </secondaryie><seealsoie>ports</seealsoie><secondaryie>printer,
    <ulink url="printers.html#PRINTER-COMPAT-LIST" role="AEN291">Printer compatibility list</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>E</title><indexentry><primaryie>environment
  </primaryie><secondaryie>enterprise,
    <ulink url="setup.html#LARGE-INSTALLATIONS" role="AEN1959">Large Installations</ulink>,
    <ulink url="network.html#NETWORKED-PRINTERS" role="AEN2324">Printing to a networked printer</ulink>
  </secondaryie><secondaryie>home,
    <ulink url="spoolers.html#CUPS-WHICH-SPOOLER" role="AEN1413">CUPS</ulink>,
    <ulink url="faxing.html#USING-A-FAXMODEM" role="AEN2518">Using a faxmodem</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>F</title><indexentry><primaryie>filtering,
    <ulink url="background.html" role="AEN1461">How it all works</ulink>
  </primaryie><secondaryie>LPD,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1802">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>PDQ,
    <ulink url="setup.html#PDQ-FILTER-TUTORIAL" role="AEN1730">Language Filtering</ulink>
  </secondaryie></indexentry><indexentry><primaryie>filters
  </primaryie><secondaryie>APS Filter,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1819">Basic LPD configuration</ulink>,
    <ulink url="vendors.html#SUSE-WHAT-COMES-WITH" role="AEN2051">SuSE</ulink>
  </secondaryie><secondaryie>lpdomatic,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1806">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>rhs-printfilters,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1832">Basic LPD configuration</ulink>,
    <ulink url="vendors.html#RHS-FILTERS-COME-WITH-REDHAT" role="AEN2031">Red Hat</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>G</title><indexentry><primaryie>Ghostscript,
    <ulink url="ghostscript.html" role="AEN2102">Ghostscript.</ulink>
  </primaryie><secondaryie>accounting,
    <ulink url="setup.html#ACCOUNTING" role="AEN2008">Accounting</ulink>
  </secondaryie><secondaryie>photographs,
    <ulink url="photos.html#GS-PHOTOS-TIPS-AND-TRICKS" role="AEN2620">Ghostscript and Photos</ulink>
  </secondaryie><secondaryie>previewing,
    <ulink url="previewing.html#PREVIEWING-WITH-GHOSTSCRIPT" role="AEN2672">PostScript</ulink>,
    <ulink url="previewing.html#PDF-PREVIEWING" role="AEN2695">Adobe PDF</ulink>
  </secondaryie><secondaryie>tuning,
    <ulink url="ghostscript.html#GS-TUNING-STUFF" role="AEN2128">Ghostscript output tuning</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>H</title><indexentry><primaryie>HP
  </primaryie><secondaryie>JetDirect,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2339">To AppSocket Devices</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>I</title><indexentry><primaryie>if,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1780">Basic LPD configuration</ulink>
  </primaryie><seealsoie>LPD</seealsoie></indexentry><indexentry><primaryie>Internet Printing Protocol
  </primaryie><seeie>IPP</seeie></indexentry><indexentry><primaryie>IPP,
    <ulink url="spoolers.html#CUPS-WHICH-SPOOLER" role="AEN1406">CUPS</ulink>
  </primaryie></indexentry></indexdiv><indexdiv><title>L</title><indexentry><primaryie>lpc,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1523">LPD</ulink>
  </primaryie></indexentry><indexentry><primaryie>LPD,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1490">LPD</ulink>
  </primaryie><secondaryie>accounting,
    <ulink url="setup.html#ACCOUNTING" role="AEN1998">Accounting</ulink>
  </secondaryie><secondaryie>AppSocket protocol,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2351">To AppSocket Devices</ulink>
  </secondaryie><secondaryie>APS Filter,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1822">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>configuration,
    <ulink url="setup.html#LPD-CONFIG-TUTORIAL" role="AEN1752">Configuring LPD</ulink>
  </secondaryie><secondaryie>filters,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1799">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>if,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1783">Basic LPD configuration</ulink>,
    <ulink url="network.html#IF-FOR-REMOTE-PRINTERS" role="AEN2363">Running an if for remote printers with old           LPDs</ulink>
  </secondaryie><secondaryie>lpc,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1525">LPD</ulink>
  </secondaryie><secondaryie>lpdomatic,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1809">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>lpq,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1514">LPD</ulink>
  </secondaryie><secondaryie>lpr,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1503">LPD</ulink>
  </secondaryie><secondaryie>lprm,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1536">LPD</ulink>
  </secondaryie><secondaryie>Netware networks,
    <ulink url="network.html#NETWORK-TO-NETWARE-WITH-LPD" role="AEN2278">From LPD</ulink>
  </secondaryie><secondaryie>network printers,
    <ulink url="network.html#NETWORKED-PRINTERS" role="AEN2314">Printing to a networked printer</ulink>
  </secondaryie><secondaryie>permissions,
    <ulink url="setup.html#LPD-PERMISSIONS" role="AEN1944">File Permissions</ulink>
  </secondaryie><secondaryie>PostScript,
    <ulink url="setup.html#LPD-FOR-POSTSCRIPT-PRINTERS" role="AEN1859">LPD for PostScript Printers</ulink>
  </secondaryie><secondaryie>rhs-printfilters,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1837">Basic LPD configuration</ulink>
  </secondaryie><secondaryie>Unix networks,
    <ulink url="network.html#NETWORK-TO-UNIX" role="AEN2178">Printing to a Unix/lpd host</ulink>
  </secondaryie><secondaryie>VA Linux's version,
    <ulink url="spoolers.html#LPD-WHICH-SPOOLER" role="AEN1326">LPD</ulink>,
    <ulink url="setup.html#LPD-FOR-POSTSCRIPT-PRINTERS" role="AEN1862">LPD for PostScript Printers</ulink>
  </secondaryie><secondaryie>Windows networks,
    <ulink url="network.html#NETWORK-TO-WINDOWS-WITH-LPD" role="AEN2242">From LPD</ulink>
  </secondaryie></indexentry><indexentry><primaryie>lpdomatic,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1812">Basic LPD configuration</ulink>
  </primaryie></indexentry><indexentry><primaryie>lpq,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1512">LPD</ulink>
  </primaryie></indexentry><indexentry><primaryie>lpr,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1501">LPD</ulink>
  </primaryie><secondaryie>usage,
    <ulink url="how.html#WITH-LPD-AND-LPR" role="AEN87">With LPD and the lpr command</ulink>
  </secondaryie></indexentry><indexentry><primaryie>lprm,
    <ulink url="background.html#LPD-OVERVIEW" role="AEN1534">LPD</ulink>
  </primaryie></indexentry><indexentry><primaryie>LPRng,
    <ulink url="spoolers.html#LPRNG-WHICH-SPOOLER" role="AEN1370">LPRng</ulink>
  </primaryie><secondaryie>accounting,
    <ulink url="setup.html#ACCOUNTING" role="AEN2015">Accounting</ulink>
  </secondaryie><secondaryie>AppSocket protocol,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2343">To AppSocket Devices</ulink>
  </secondaryie><secondaryie>Caldera,
    <ulink url="vendors.html#CALDERA-WHAT-COMES-WITH" role="AEN2076">Caldera</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>M</title><indexentry><primaryie>Mandrake,
    <ulink url="vendors.html#MANDRAKE-WHAT-COMES-WITH" role="AEN2092">Mandrake</ulink>
  </primaryie></indexentry></indexdiv><indexdiv><title>N</title><indexentry><primaryie>ncpfs,
    <ulink url="network.html#NETWORKS-FROM-NETWARE" role="AEN2450">From Netware.</ulink>
  </primaryie></indexentry><indexentry><primaryie>netatalk,
    <ulink url="network.html#NETWORKS-FROM-APPLE" role="AEN2434">From an Apple.</ulink>
  </primaryie></indexentry><indexentry><primaryie>Netware
  </primaryie><secondaryie>ncpfs
  </secondaryie><seeie>ncpfs</seeie><secondaryie>printing from,
    <ulink url="network.html#NETWORKS-FROM-NETWARE" role="AEN2447">From Netware.</ulink>
  </secondaryie><secondaryie>printing to,
    <ulink url="network.html#NETWORK-TO-NETWARE" role="AEN2268">Printing to a NetWare Printer</ulink>
  </secondaryie></indexentry><indexentry><primaryie>networks,
    <ulink url="network.html" role="AEN2167">Networks</ulink>
  </primaryie><secondaryie>administration,
    <ulink url="network.html#AEN2460" role="AEN2461">Networked Printer Administration</ulink>
  </secondaryie><secondaryie>Apple,
    <ulink url="network.html#NETWORK-TO-APPLE" role="AEN2289">Printing to an EtherTalk (Apple) printer</ulink>,
    <ulink url="network.html#NETWORKS-FROM-APPLE" role="AEN2428">From an Apple.</ulink>
  </secondaryie><secondaryie>AppSocket protocol,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2336">To AppSocket Devices</ulink>
  </secondaryie><secondaryie>large,
    <ulink url="setup.html#LARGE-INSTALLATIONS" role="AEN1956">Large Installations</ulink>
  </secondaryie><secondaryie>LPD,
    <ulink url="network.html#NETWORK-TO-UNIX" role="AEN2175">Printing to a Unix/lpd host</ulink>
  </secondaryie><secondaryie>Netware,
    <ulink url="network.html#NETWORK-TO-NETWARE" role="AEN2262">Printing to a NetWare Printer</ulink>,
    <ulink url="network.html#NETWORKS-FROM-NETWARE" role="AEN2444">From Netware.</ulink>
  </secondaryie><secondaryie>network printers,
    <ulink url="network.html#NETWORKED-PRINTERS" role="AEN2307">Printing to a networked printer</ulink>
  </secondaryie><secondaryie>PDQ,
    <ulink url="network.html#NETWORK-TO-UNIX-WITH-PDQ" role="AEN2190">With pdq</ulink>
  </secondaryie><secondaryie>print servers,
    <ulink url="setup.html#LARGE-INSTALLATIONS" role="AEN1985">Large Installations</ulink>,
    <ulink url="network.html#NETWORKED-PRINTERS" role="AEN2310">Printing to a networked printer</ulink>
  </secondaryie><secondaryie>rlpr,
    <ulink url="network.html#NETWORK-TO-UNIX-WITH-RLPR" role="AEN2209">With rlpr</ulink>
  </secondaryie><secondaryie>Unix,
    <ulink url="network.html#NETWORK-TO-UNIX" role="AEN2172">Printing to a Unix/lpd host</ulink>
  </secondaryie><secondaryie>Windows,
    <ulink url="network.html#NETWORK-TO-WINDOWS" role="AEN2226">Printing to a Windows or Samba printer</ulink>,
    <ulink url="network.html#NETWORK-FROM-WINDOWS" role="AEN2390">From Windows.</ulink>
  </secondaryie></indexentry><indexentry><primaryie>npadmin,
    <ulink url="network.html#AEN2460" role="AEN2464">Networked Printer Administration</ulink>
  </primaryie><secondaryie>uses,
    <ulink url="setup.html#LARGE-INSTALLATIONS" role="AEN1989">Large Installations</ulink>,
    <ulink url="setup.html#ACCOUNTING" role="AEN2018">Accounting</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>P</title><indexentry><primaryie>paper
  </primaryie><secondaryie>quality,
    <ulink url="photos.html#PAPER-FOR-INKJETS" role="AEN2643">Paper</ulink>
  </secondaryie></indexentry><indexentry><primaryie>PDF,
    <ulink url="printers.html#SUPPORTED-PRINTERS-POSTSCRIPT" role="AEN257">Postscript</ulink>
  </primaryie><secondaryie>previewing,
    <ulink url="previewing.html#PDF-PREVIEWING" role="AEN2701">Adobe PDF</ulink>
  </secondaryie></indexentry><indexentry><primaryie>PDQ,
    <ulink url="spoolers.html#PDQ-WHICH-SPOOLER" role="AEN1348">PDQ</ulink>
  </primaryie><secondaryie>Apple networks,
    <ulink url="network.html#NETWORK-TO-APPLE-FROM-PDQ" role="AEN2302">From PDQ</ulink>
  </secondaryie><secondaryie>appletalk,
    <ulink url="setup.html#PDQ-DRIVERS-INTERFACES" role="AEN1644">Drivers and Interfaces</ulink>
  </secondaryie><secondaryie>AppSocket protocol,
    <ulink url="network.html#NETWORKED-PRINTERS-APPSOCKET" role="AEN2348">To AppSocket Devices</ulink>
  </secondaryie><secondaryie>configuration,
    <ulink url="setup.html#PDQ-CONFIG" role="AEN1617">Configuring PDQ</ulink>
  </secondaryie><secondaryie>creating drivers,
    <ulink url="setup.html#PDQ-DRIVERS-TUTORIAL" role="AEN1665">Creating a PDQ Driver Declaration</ulink>
  </secondaryie><secondaryie>filtering,
    <ulink url="setup.html#PDQ-FILTER-TUTORIAL" role="AEN1733">Language Filtering</ulink>
  </secondaryie><secondaryie>finding drivers,
    <ulink url="setup.html#PDQ-DRIVERS-TUTORIAL" role="AEN1668">Creating a PDQ Driver Declaration</ulink>
  </secondaryie><secondaryie>from Windows,
    <ulink url="network.html#NETWORK-FROM-WINDOWS" role="AEN2398">From Windows.</ulink>
  </secondaryie><secondaryie>Netware networks,
    <ulink url="network.html#NETWORK-TO-NETWARE" role="AEN2265">Printing to a NetWare Printer</ulink>
  </secondaryie><secondaryie>network printers,
    <ulink url="network.html#NETWORKED-PRINTERS" role="AEN2317">Printing to a networked printer</ulink>
  </secondaryie><secondaryie>overview,
    <ulink url="background.html#PDQ-OVERVIEW" role="AEN1469">PDQ</ulink>
  </secondaryie><secondaryie>Unix networks,
    <ulink url="network.html#NETWORK-TO-UNIX-WITH-PDQ" role="AEN2193">With pdq</ulink>
  </secondaryie><secondaryie>usage,
    <ulink url="how.html#PDQINTRO" role="AEN61">With PDQ</ulink>
  </secondaryie><secondaryie>Windows networks,
    <ulink url="network.html#NETWORK-TO-WINDOWS-WITH-PDQ" role="AEN2235">From PDQ</ulink>
  </secondaryie></indexentry><indexentry><primaryie>photograph
  </primaryie><secondaryie>color,
    <ulink url="ghostscript.html#GSCOLOR" role="AEN2155">Color Printing in Ghostscript</ulink>
  </secondaryie><secondaryie>commercial software,
    <ulink url="photos.html#COMMERCIAL-PHOTO-PRINTING-SOFTWARE" role="AEN2659">Shareware and Commercial Software</ulink>
  </secondaryie><secondaryie>gamma,
    <ulink url="ghostscript.html#GSGAMMA" role="AEN2142">Gamma, dotsizes, etc.</ulink>
  </secondaryie><secondaryie>Ghostscript,
    <ulink url="photos.html#GS-PHOTOS-TIPS-AND-TRICKS" role="AEN2623">Ghostscript and Photos</ulink>
  </secondaryie><secondaryie>printers,
    <ulink url="printers.html#SHOPPING" role="AEN1288">How to buy a printer</ulink>
  </secondaryie><secondaryie>tips,
    <ulink url="photos.html" role="AEN2614">Printing Photographs</ulink>
  </secondaryie></indexentry><indexentry><primaryie>ports,
    <ulink url="kernel.html" role="AEN145">Kernel printer devices</ulink>
  </primaryie><secondaryie>parallel,
    <ulink url="kernel.html#OLD-LP-DEVICE" role="AEN156">The lp device (kernels =2.1.32)</ulink>,
    <ulink url="kernel.html#NEW-PARPORT-DEVICE" role="AEN185">The parport device (kernels = 2.1.33)</ulink>
  </secondaryie><secondaryie>serial,
    <ulink url="kernel.html#SERIAL-DEVICES" role="AEN207">Serial devices</ulink>,
    <ulink url="serial.html" role="AEN2710">Serial printers under lpd</ulink>
  </secondaryie><secondaryie>USB,
    <ulink url="kernel.html#USB-DEVICES" role="AEN222">USB Devices</ulink>
  </secondaryie></indexentry><indexentry><primaryie>Postscript,
    <ulink url="printers.html#SUPPORTED-PRINTERS-POSTSCRIPT" role="AEN241">Postscript</ulink>
  </primaryie><seealsoie>Ghostscript</seealsoie><secondaryie>LPD,
    <ulink url="setup.html#LPD-FOR-POSTSCRIPT-PRINTERS" role="AEN1856">LPD for PostScript Printers</ulink>
  </secondaryie><secondaryie>previewing,
    <ulink url="previewing.html#PREVIEWING-WITH-GHOSTSCRIPT" role="AEN2678">PostScript</ulink>
  </secondaryie><secondaryie>printers,
    <ulink url="printers.html#SUPPORTED-PRINTERS-POSTSCRIPT" role="AEN243">Postscript</ulink>,
    <ulink url="setup.html#LPD-FOR-POSTSCRIPT-PRINTERS" role="AEN1853">LPD for PostScript Printers</ulink>
  </secondaryie></indexentry><indexentry><primaryie>PPR,
    <ulink url="spoolers.html#PPR-WHICH-SPOOLER" role="AEN1382">PPR</ulink>
  </primaryie></indexentry><indexentry><primaryie>previewing,
    <ulink url="previewing.html" role="AEN2667">On-screen previewing of printable things.</ulink>
  </primaryie><secondaryie>PDF,
    <ulink url="previewing.html#PDF-PREVIEWING" role="AEN2698">Adobe PDF</ulink>
  </secondaryie><secondaryie>Postscript,
    <ulink url="previewing.html#PREVIEWING-WITH-GHOSTSCRIPT" role="AEN2675">PostScript</ulink>
  </secondaryie></indexentry><indexentry><primaryie>printers
  </primaryie><secondaryie>buying,
    <ulink url="printers.html#WHAT-PRINTERS-WORK" role="AEN277">What printers work?</ulink>,
    <ulink url="printers.html#SHOPPING" role="AEN1268">How to buy a printer</ulink>
  </secondaryie><secondaryie>photograph,
    <ulink url="printers.html#SHOPPING" role="AEN1291">How to buy a printer</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>R</title><indexentry><primaryie>Red Hat,
    <ulink url="vendors.html#RHS-FILTERS-COME-WITH-REDHAT" role="AEN2029">Red Hat</ulink>
  </primaryie></indexentry><indexentry><primaryie>rhs-printfilters,
    <ulink url="setup.html#BASIC-LPD-CONFIGURATION" role="AEN1835">Basic LPD configuration</ulink>
  </primaryie></indexentry><indexentry><primaryie>rlpr,
    <ulink url="network.html#NETWORK-TO-UNIX-WITH-RLPR" role="AEN2207">With rlpr</ulink>
  </primaryie></indexentry></indexdiv><indexdiv><title>S</title><indexentry><primaryie>samba,
    <ulink url="network.html#NETWORK-FROM-WINDOWS" role="AEN2394">From Windows.</ulink>
  </primaryie></indexentry><indexentry><primaryie>spoolers,
    <ulink url="background.html" role="AEN1447">How it all works</ulink>
  </primaryie><secondaryie>CUPS,
    <ulink url="spoolers.html#CUPS-WHICH-SPOOLER" role="AEN1399">CUPS</ulink>
  </secondaryie><secondaryie>LPRng,
    <ulink url="spoolers.html#LPRNG-WHICH-SPOOLER" role="AEN1372">LPRng</ulink>
  </secondaryie><secondaryie>PDQ,
    <ulink url="spoolers.html#PDQ-WHICH-SPOOLER" role="AEN1350">PDQ</ulink>
  </secondaryie><secondaryie>PPR,
    <ulink url="spoolers.html#PPR-WHICH-SPOOLER" role="AEN1384">PPR</ulink>
  </secondaryie></indexentry><indexentry><primaryie>SuSE,
    <ulink url="vendors.html#SUSE-WHAT-COMES-WITH" role="AEN2046">SuSE</ulink>
  </primaryie></indexentry></indexdiv><indexdiv><title>V</title><indexentry><primaryie>VA Linux
  </primaryie><secondaryie>LPD,
    <ulink url="spoolers.html#LPD-WHICH-SPOOLER" role="AEN1329">LPD</ulink>,
    <ulink url="setup.html#LPD-FOR-POSTSCRIPT-PRINTERS" role="AEN1865">LPD for PostScript Printers</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>W</title><indexentry><primaryie>Windows
  </primaryie><secondaryie>printing from,
    <ulink url="network.html#NETWORK-FROM-WINDOWS" role="AEN2383">From Windows.</ulink>
  </secondaryie><secondaryie>printing to,
    <ulink url="network.html#NETWORK-TO-WINDOWS" role="AEN2229">Printing to a Windows or Samba printer</ulink>
  </secondaryie><secondaryie>samba
  </secondaryie><seeie>samba</seeie></indexentry><indexentry><primaryie>winprinters,
    <ulink url="printers.html" role="AEN233">Supported Printers</ulink>
  </primaryie><secondaryie>workarounds,
    <ulink url="winprinters.html" role="AEN2486">Windows-only printers</ulink>
  </secondaryie></indexentry></indexdiv><indexdiv><title>X</title><indexentry><primaryie>xpdq,
    <ulink url="spoolers.html#PDQ-WHICH-SPOOLER" role="AEN1353">PDQ</ulink>
  </primaryie><seealsoie>PDQ</seealsoie><secondaryie>usage,
    <ulink url="how.html#XPDQ-INTRO" role="AEN70">Xpdq</ulink>
  </secondaryie></indexentry><indexentry><primaryie>XPP,
    <ulink url="how.html#XPP-SECT" role="AEN123">XPP</ulink>,
    <ulink url="spoolers.html#CUPS-WHICH-SPOOLER" role="AEN1402">CUPS</ulink>
  </primaryie></indexentry></indexdiv></index></article>

