This note is just to outline some ideas that I have had about the
problems of load balance queues, PPD files, client side filters,
PPD extensions, and other related items.   Due to the rather
interrelated mess^H^H^H^H nature of these topics,  the following
is a bit more rambling and disconnected than most of my notes...
ummm... if that is possible,  which many of my critics would doubt.

Enjoy.

Topics:
  a) Load Balance Queues
  b) PPD files and other things needed by Filters To Do Their
     Dirty Deeds
  c) Client Side Filters - 
  d) PPD file extensions, Internationalization, and RTFM
     (Read the Funny Menu)

Load Balance Queues and Destinations for Load Balance Queues

This is a topic that I (and others) have fought with for a long time,
and there appears to be a general concensus (actually,  I stole^H^H^H^H^H
borrowed the best ideas):

a)  You want to allow users to either send jobs to a
  'printer pool'  or a 'load balance' queue,  in which
  case the spooling system will choose the destination.

   lpr -Ploadbalance

b)  You want to allow users to send directly the the
  printers in the 'printer pool' as well.
   lpr -Pdest1

c)  The 'printer pool' has a 'generic' configuration that
  has simply the 'absctract' capabilities of the particular
  set of printers in the printer pool.  For example,  in the
  LPRng environment,  this means there is a set of -Z options
  which are supported by all the printers in the pool.
  Note that individual printers MUST support these,  but may
  also have additional capabilities,  which is why b) is
  desireable as well.

    loadbalance:
      :zopts=landscape,portrait,....

    dest1:
      :tc=loadbalance
      :zopts+=firstleft,color

  (The opts += is in the current LPRng public release,  I think.
  If not, it will get added.  Note that currently the zopts is not
  enforced by LPR.  But I have the code patches to do it.)

d) If you want 'pooling' then you MUST provide a 'generic' format
  of job (can you say PostScript for an Apple II? Yuch! But you
  allow page sizes...),  which the spooler will then forward
  (no modifications) to the selected output printer.
  This printer MUST be able to determine if it has a generic job
  and use the -Z options for the job to convert the job to a format
  compatible with the output printer.

PPD Files, Filter Options, and Getting The Right Infomration

How does a filter determine what it is to do?
  - user options
How does it get information about the output device
  so it can format the data correctly?
  - PPD file (actually, an abused PPD file, with extensions)

It is clear (to me at least) that the '-Z' or '-o' command line
options,  or configuration information,  specifies the user level
options you want to pass to the filter,  and the 'ppd file' contains
the detailed information it needs to carry out the work.

My current thinking is to provide the driver a set of 'hints' that
are specific to the driver,  and then let the administrator fight
it out:

    loadbalance:
      # for checking
      :zopts=landscape,portrait,...
      # ppd file for filter
      :ppd=http\://host.with.ppd/ppd/ppd.file,http\072//host.with.ppd/ppd/ppd.file,

  "What the &((*&^ is that URL doing there?"

  Now I just KNOW that some of you are having kittens on this.
  This is what the driver uses to get the PPD file.  Note that you can
  have alternate locations for the PPD file of course.  Or one loaction.
  Of course you can have:
      :ppd=/pathname
  which  is just shorthand for:
      :ppd=file\://pathname
  OR you can have
      :ppd=|/pathname option option

  This cause the specified program to be run and the program will
  deliver the PPD file.

  This is just an ugly hack to have the 'delivery of ppd information'
  dumped on the filter writer,  rather than the Print spooler writer.
  Besides,  it is now open ended,  and you can adapt any set of conventions
  you want into this.

Client Side Filter Support

LPRng does this right now by allowing an 'lpr_filter' operation to
be specified.  That is,  the 'lpr' program will run a filter on
the job and then forward the filter output to the destination queue.
This job can be marked as 'no further formatting or filtering
required' in which case the spooler simply whacks the printer across
the electronic forehead to wake it up, and then flings the job at
it.  It is assumed that the user has taken responsibility for the
various formatting operations, etc,  which apparently is what the
GIMP and other folks need.

I do not claim that this is an optimal or even good solution to the
problem,  but it appears to be a workable solution.  Right now there
is not a mechanism for users to specify the filter that they want
used on a command line option,  but if there is interest then I will
add the following to LPRng:

lpr -X '/path_to_filter'

The /path_to_filter is the filter that you want to use.
By default,  LPRng will put a slew of options on the filter command
line,  including the printer name, user name, time of day,
phase of moon,...   OK, perhaps not the last,  but you get the idea.
In addition,  the PRINTCAP entry for the printer is put in the
PRINTCAP_ENTRY environment variable.

If you want to specify no further filter operations,  then you would
use the -l 'literal or binary' flag or -Fl (format l):

lpr -X '/path_to_filter' -l  
or lpr -X '/path_to_filter' -Fl  

Abusing the PPD File and other Horrible Acts of Desperation

I spent a day or so looking at the PWG work on the XML based
Universal Print Driver stuff.  With all due respect to the PWG, it
is Not Quite Ready For Prime Time.  Plus there is apparently little
(no?) work or support going into this effort.  On the other hand,
XML looks like the way to go in the future, so whatever is done
should be done with this in mind.

<aside>
First,  I must make a cautionary statement:

I think the PPD file format is a botch of the first order.

   a) no internationalization facility
   b) one file per device
   c) no subclassing
   d) no 'help' facility
   e) Totally intertwined 'option' and 'menu' structure
   f) Enwrangled with "Microsoft/Apple" drivers in a Laocoon
      embrace of the ugliest form. 
   g) It is UGLY UGLY UGLY...  And nobody documents the 'majic
      options' they put into it.

The method for dealing with conflicting option values is, I will
admit,  rather clever.

There.  I feel much better now.
</aside>

Here are some ramblings on what I would like to see in
a 'extended PPD file' format:

a) Sections and Subclassing

[ name ]
... PPD stuff

[ subclass ]
*Subclass: name

This would allow us to put LOTS and LOTS of printer PPDs
in a single file,  and we would be able to use one common
structure for most of the PPD information and then subclass
the particular one.

Note 1:  if a 'name' had the form '.xxx',  then it would
be a 'phony' name, and not be for a real printer.

Note 2:

I would also add entries like:

*Name:  "This is the HP XXX Printer"
*Name:  "This is the Lexmark XXX Printer"

(This is already being done with the UIConstraints stuff).

So that you could build a 'name to PPD entry' index.
The 'Name1' stuff may or may not be necessary.

b) Additional Tags

In the PPD world, each 'option' has a name,  a set of values,
and some junk associated with the values.  Lets look at an example:

*JCLBegin: "<1B>%-12345X@PJL JOB<0A>"
*JCLToPSInterpreter: "@PJL ENTER LANGUAGE = POSTSCRIPT <0A>"
*JCLEnd: "<1B>%-12345X@PJL EOJ<0A><1B>%-12345X"

*JCLOpenUI *JCLEconomode/EconoMode: Boolean
*DefaultJCLEconomode: PrinterDefault
*JCLEconomode PrinterDefault/Printer Default: ""
*OrderDependency: 10 JCLSetup  *JCLEconomode
*JCLEconomode on/ON: "@PJL SET ECONOMODE = ON<0A>"
*JCLEconomode off/OFF: "@PJL SET ECONOMODE = OFF<0A>"
*JCLCloseUI: *JCLEconomode


You thought that PPD files were only for PostScript, didn't you?
Well, it turns out that they have been mangled to support other
formats as well. So we can add 'Capabilities' of other languages easily.

Now if HP or others would care to provide documentation on their
use of these extensions?

The PPD format was developed by folks who wanted 'to make it simple to parse'.
Well, they did.  However,  the semantic content is a bit of a pain.

*% Code in this section both selects a tray and sets up a frame buffer.
*OpenUI *PageSize: PickOne
*OrderDependency: 30 AnySetup *PageSize
*DefaultPageSize: Letter
*PageSize Letter/Letter 8 1/2 x 11 in: "
    2 dict
    dup /Policies 1 dict dup /PageSize 1 put put
    dup /DeferredMediaSelection true put setpagedevice
    2 dict dup /PageSize [612 792] put dup /ImagingBBox null put setpagedevice"
*End
*PageSize Legal/Legal 8 1/2 x 14 in: "
    2 dict
    dup /Policies 1 dict dup /PageSize 1 put put
    dup /DeferredMediaSelection true put setpagedevice
    2 dict dup /PageSize [612 1008] put dup /ImagingBBox null put setpagedevice"
*End



Here is a quick tutorial on this:
*% Comment        - hardly used,  no explanations in most PPD files...

*OpenUI *PageSize: PickOne   -  this means that you have a user selectable
             grommet called 'PageSize',  only one value of which
             can be used

*OrderDependency: 30 AnySetup *PageSize
       This means that the 'priority' in terms of where this is
  put into the PostScript or other file is '30'  (lowest first).
  Then this is for 'AnySetup' - I will not bother you with the
  details,  you REALLY do not want to know.  Finally,  we have the
  option that has this priority if it is set.

*DefaultPageSize: Letter

       This makes sense - the default is letter... ummm... maybe... :-)
  But the idea is unless 'letter' is specifically picked you do not need
  to put this into the output stream... Yeah. Right.

*PageSize Letter/Letter 8 1/2 x 11 in: "
    2 dict
    dup /Policies 1 dict dup /PageSize 1 put put
    dup /DeferredMediaSelection true put setpagedevice
    2 dict dup /PageSize [612 792] put dup /ImagingBBox null put setpagedevice"
*End


The PageSize option has a 'value' called 'Letter'.
This has a 'textual representation' of the form: "Letter 8 1/2 x 11 in"

And now we come to my first extension:

*Tag.Letter "Letter 8 1/2 x 11 in"   <- default tag, overrides
*Tag.Letter.jp.xxxx "...."           <- LOCALIZATION
   For various painful reasons,  I think that this will have to
   be done using URL escaped UNICODE otherwise things might break
   a little.  But perhaps not.

And now we have the second extension:

*Help.PageSize "Set the Page size"
*Help.PageSize.jp.xxx "...."
*Help.Letter   "Set Page Size to Letter. This will select...."
*Help.Letter.jp.xxx   "...."

Note now that the help stuff is actually in the PPD file,  there is
singing and dancing by the users,  and you can tell them to RTFM
(Read The F* Menus)  ...  sigh...  And perhaps we can even get the
manufacturers to do this...

I am still mulling over the way to have PCL conversions get data.
Perhaps some work has already been done here?

Patrick Powell                 Astart Technologies,
[EMAIL PROTECTED]            9475 Chesapeake Drive, Suite D,
Network and System             San Diego, CA 92123
  Consulting                   858-874-6543 FAX 858-279-8424 
LPRng - Print Spooler (http://www.astart.com)

-----------------------------------------------------------------------------
If you need help, send email to [EMAIL PROTECTED] (or lprng-requests
or lprng-digest-requests) with the word 'help' in the body.  For the impatient,
to subscribe to a list with name LIST,  send mail to [EMAIL PROTECTED]
with:                           | example:
subscribe LIST <mailaddr>       |  subscribe lprng-digest [EMAIL PROTECTED]
unsubscribe LIST <mailaddr>     |  unsubscribe lprng [EMAIL PROTECTED]

If you have major problems,  send email to [EMAIL PROTECTED] with the word
LPRNGLIST in the SUBJECT line.
-----------------------------------------------------------------------------

Reply via email to