[Desktop_printing] PPD settings vs IPP options

Kurt Pfeifle k1pfeifle at gmx.net
Thu Feb 9 09:07:40 PST 2006

On Thursday 09 February 2006 13:00, Alexander Larsson wrote:

> I'm starting to look at the Gtk+ print dialog, and I have some questions
> about how things are supposed to work.
> When the user pops up the print dialog, with some printer selected the
> UI is modified to the capabilities of that printer (set of input trays,
> paper sizes, etc), and the defaults are set up according to some
> defaults set for the printer. We then let the user select their options,
> create a postscript file and send it to the printer.
> Now, there seems to be two ways of doing this. Either using PPDs, or
> using IPP options:
> 1) Get the PPD file for the printer, use the PPD file to set up the UI
> and defaults. 


> When printing, embed the postscript snippets from the PPD 
> file based on the settings the user made.

Not correct. (Unless you are OOo).

> Send this to the cups/ipp 
> server.


CUPS itself will do (most of) the embedding.

*If* an application wants to produce printer-specific PostScript
(f.e. in order to have full control about what is sent to the marking 
engine), then it needs to tell CUPS to not try and filter it (there
is a "-o raw" option for that), or it has to use a "raw" CUPS queue
(that is one that has no PPD assigned to it).

Basic rules:
  1. The application creates "device independent" PostScript.
  2. CUPS inserts printer-specific stuff into the file before
     sending it off to the destination device.

The UI only has to display available options for the user to *select*
from. The UI (or rather the underlying program driven by the UI) does
not have to fiddle with the PostScript snippets at all!

Based on the user's print option selections, the "UI" needs only to 
generate a  commandline for CUPS to act on, specifying the PPD options 
(as well as other, generic, not-printer-specific options!) in the same 
format as you would on a CUPS "lp" or "lpr" commandline (some options' 
values may be boolean boolean):

 -o optionname1=value1 -o optionname2=value2 .... 


 -o "optionname1=value1 optionname2=value2 .... "

It is then the job of the various CUPS filters (who are automatically 
chained as needed, based on directives in /etc/cups/mime.{types,convs}) 
to send the PPD options to the printer (inside the finalized PostScript 
file, or in whatever format the device wants its data) to use the 
PostScript snippet representing "optionnameX=valueX".

Specifically, for a PPD representing a PostScript printer, the filter
used by CUPS that inserts the PostScript snippets into the data stream
send to the device is "pstops" and resides in /usr/lib/cups/filter/.

Be aware that CUPS uses "PPDs" even for non-PostScript devices. The "UI"
does not have to care. Just parse the PPD, present available options to
the user, let her pick, send the options on the commandline to CUPS (and
CUPS will have to care).

Now, how do you quickly look at the PPD options? Let's take an example,
one that queries a remote CUPS server:

kurt at soprano:~> CUPS_SERVER= IPP_PORT=631 lpstat -r
  scheduler is running
## Let's see if the cupsd is up and running. Since 631 is default,
## we can as well leave it out...

## Instead of using the CUPS_SERVER env var, you can also
## use "-h <cupshost>". So let's continue with "-h"

kurt at soprano:~> CUPS_SERVER= lpstat -p
  printer 2075merge1 disabled since Jan 01 00:00 -
          reason unknown
  printer ir85wm is idle.  enabled since Jan 01 00:00
  printer mop320 is idle.  enabled since Jan 01 00:00
          Data file sent successfully
## See which printers are there, and what their "state" is.

kurt at soprano:~> CUPS_SERVER= lpstat -v
  device for 2075merge1: ipp://cupssrv2:631/printers/digimaster1
  device for ir85wm: socket://
  device for mop320: lpd://
## See how the various printers are connected to the CUPS server.
## - one is connected via IPP
## - one is connected via LPR/LPD
## - one is connected via "AppSocket" (a.k.a. "HP JetDirect")

kurt at soprano:~> lpoptions -h -p mop320 -l
  REt/REt Setting: Dark Light *Medium Off
  TonerDensity/Toner Density: 1 2 *3 4 5
  Duplex/Double-Sided Printing: *DuplexNoTumble DuplexTumble None
  InputSlot/Media Source: Default Tray1 *Tray2 Tray3 Manual Auto
  PageSize/Page Size: A4 Letter 11x17 A3 *A5 B5 [....] Legal
  PageRegion/PageRegion: A4 Letter 11x17 A3 A5 B5 [....] Legal
  Resolution/Resolution: default *300x300dpi 600x600dpi 1200x1200dpi
  Economode/Toner Saving: *Off On
## See which PPD options are there for printer "mop320", attached
## to remote CUPS server "":
## The important things to note here are:
## - before the "/" there is the name of the PPD option to be used
##   on commandlines passed to CUPS
## - after the "/", before the ":" is a (supposedly userfriendly) 
##   translation to be displayed in the UI
## - after the ":" an enumeration of values for the PPD option is
##   listed
## - the value tagged with "*" is the one currently used as the 
##   default by this CUPS server for that printer (that means, it
##   will "-o Duplex=DuplexNoTumble -o InputSlot=Tray2
##   -o PageSize=A5 -o Resolution=300x300dpi" for any printout that
##   doesnt specify options otherwise. It also means your GUI needs
##   to display these options as pre-selected if called.
## It is even a bit more complex: a user may have saved his own 
## personal settings for that queue (eg. printing by default on
## A3 paper, non-duplex). These personal settings are read from
## ~/.lpoptions and merged with what CUPS returns as PPD default
## values. Above "lpoptions" commandline returns took that into 
## account already...


Of course, for writing a GUI frontend to CUPS printing clients (what 
is equivalent to lp & lpr commands), you'd use the appropriate parts 
of the CUPS API.

The above "commandline" usage of CUPS is just listed illustrate the 
general idea...

CUPS can also process the above options if they are sent "embedded"
inside the PostScript file. IIRC the syntax is s.th. like:

%cupsJobTicket: Duplex=DuplexNoTumble InputSlot=Tray2 
%cupsJobTicket: option3=value3 option4=valueXYZ foo=bar

(this is true *not* only for PPD options, but any other device 
independent print option. CUPS will recognize the keyword 
"cupsJobTicket" -- other applications will see the "%" leading in the
line, and conclude "I don't bother, this is only a comment".

You may find some other interesting tidbids about printing in general,
and CUPS/Linux specifically in this document:

  http://docs.kde.org/development/en/   # search "kdeprint" 
                                        # (above URLs may change soon)


it is really a pity that (as you wrote previously) no-one from the 
Gtk+/Gnome camp will be able to attend the printing summit. It looks
that we could all benefit from an intensive exchange!

> 2) Get IPP attributes for the cups printer (media-supported,
> media-default, orientation-requested-supported,
> orientation-requested-default, etc). 

PPD options can *also* be passed in as IPP job attributes to CUPS...

> Use this info to set up the UI, and 
> defaults. When printing create a "plain" postscript file, and pass this
> to cups/ipp together with a set of ipp options based on what the user
> selected in the UI.
> Is one way preferable over the other in any way?

If you have CUPS, of course the *first* is preferable. 

Uhmm... *strictly* speaking it is neither "1)", nor "2)" but a third
option. Details are outlined above  ;-P

> Does it ever make sense 
> to mix these different methods?

CUPS is an IPP server, and you can send the IPP options to CUPS too.
But as you notice, IPP job options are only a subset of what CUPS can
> It seems to me that using the PPD file allows higher fidelity in the UI
> (with UIConstraints and things like that) and allows printer-specific
> features. So, IMHO it looks like a better choice, but I don't know all
> the details here.

Isn't it possible that you can attend the summit? A lot of info 
exchange (and also basic training in CUPS and other printing matters) 
could be short-circuited there.  It is very time consuming to write 
down all these details in mails...  :-)

I think it is great that Gnome and Gtk+ will now start to fill the 
huge gaps it suffers from when it comes to printing. After all, this 
will make the overall Linux desktop offering more compelling, 
especially if ISVs and enterprises are looking for what we all have 
to offer on our platform.

> The PPD method only seems to work if you use postscript files though.


CUPS can handle lots of formats, and several print formats sent to the 
devices. *All* of them have PPDs (with CUPS); even the non-PostScript

> How would this work if we used e.g. PDF as the spool format?

The details of this will still have to be decided. But for the immediate
user interface of current applications nothing will change next month:
Linux apps will still generate PostScript, the printing GUI will still
have to parse the PPD for available print options of the target printer,
the currently used devices will still not understand PDF and expect their
data to come in whatever they can grok.

Whatever will be changed re. PDF will first have to be implemented in
CUPS: a new CUPS filter (placed in the chain after or in parallel to 
"pstops" is a detail) that converts into PDF (if PDF is expected or 
preferred by the receiving end [which could be another CUPS server]).

We are still a good timespan away from the day we will expect the 
application to generate dirctly a PDF that has all print option 
information encapsulated in an embedded JobTicket... ;-)

> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>  Alexander Larsson                                      Red Hat, Inc 
>                    alexl at redhat.com    alla at lysator.liu.se 


More information about the Printing-summit mailing list