Hi all,
I've thought a bit about this question of printer drivers et all.
I'm sorry that this will be a very long email -at the end hereof I have a
specific question for Joachim, so if you don't want to wade thrgough all of
these ramblings, just read the last section.
You will remember that the question of printing reared its head with respect
to ASCII output (mainly I though at the time, from QUILL - but this was mater
widened).
The FILTER
===========
In response to that I made the Proforma Filter (PF) which is on my "website".
It comes on several parts - i'll set them out in a very small way here, just
to show what has been done up to now.
- First,there is the PF itself. It takes the ASCII file, including printer
directives for switching bold on/off etc... and writes this to a Proforma
printer driver, converting everything on the way. Proforma then makes the
actual output to the printer.
- Then there is the PROforma Filter Graphical User Interface (PF GUI). The
PF is a background job, which you start with a commanbd line eg ex
PF;"filename printer_id char_size spooler_file" etc... This is pretty
difficult, so I made a GUI to allow the user to choose several of these
things more interactively. Also, since the filter can preview to the screen,
it MUST be kept separate from the GUI, else it can't use the entire screen
for preview but would be limited to the GUI's screen
- Then I made a printer driver for Xchange. Indeed, the PF expects that
printer directives to switch bold on/off etc are send in a certain way (eg.
<b> switches bold on, </b> switches it off).
I felt that these three components answered the need I perceived: the user
pritns to a file, starts the GUI (perhaps via a hotkey) and sends the file to
PROforma which then does the printing. However, when I announced this on the
list, it was not found satisfactory, mainly, I understand, for two reasons:
One, some programs cannot handle the printer directives as set out above, but
need some kind of ESC/P facility. Two, some programs apparently cannot send
output to a file, but only to a device.
Point one can be answered simply by adapting the PF. Let me point out that
all of the sources are on my "website", so changing the routine that parses
an input line to see whether bold or underline should be switched on or off
is not that difficult (hint, hint).
Point two above cannot be handled so easily. Another device was needed, to
which the program can print. Thus the fourth component the PFF device (PFF)
was born. Marcel has pointed out on this list that the old PRTBUF device
would be suitable, however I feel this is not the case since that can only
send output to ser or par IIRC (?). And it can't start the job we'll come to
later on.
At that time, Rich also drew up some impressive specifications for a fully
fledged printing system, including things, devices with different names and
options, filter etc...
For various reasons, I thought that this system was unnecessarily complex,
(but this is more a question of pholisophy and design) and, notably the thing
seemed to me to be overly ambitious and, perhaps, the answer to a problem (.
independent job) which it didn't really solve.
So I prefer to keep things simple. I did, however, make the PFF device, but
kept this to a much simpler philosophy than that proposed.
PFF.
===
As it stands now, PFF is indeed a very simple device. It accepts input and
sends this to a pipe. For the time being, this pipe is a fixed pipe, named
"pipe_PFFxxxx_10000". The pipe does all the buffering necessary and, since
you can make pipes of a determined length, there is no fear that the job will
not be able to print to the PFF device as that could run out of memory. In
the above name, the pipe is 10000 bytes long.
The disadvantage of this limited buffering is that the program that is doing
the printing (the "printing job") will seem to hang until the pipe is emptied
enough so that all of the data can be printed. This however, is not different
from other systems - and you can (later) always increase the size of the pipe
if you have a larger system.
PFF also allows you to set a usage name, eg. PFF_USE "PAR" will cause all
output directed to PAR to be sent to PFF.
The JOB
========
However, the PFF device itself is not enough. The consensus on this list, and
with which I agree, is that a lot of work will have to be done via some kind
of job, notably that of transporting the data to the filter(s). This
**could** be done in the PFF itself, but you would have to work under such
severe restrictions (as this would be either in the open or i/o calls of a
device driver, or within a scheduler loop ) that this would be not acceptable
- if only for the fact that all other progs in the machine would be halted
since all of this would be done in supervisor mode...
This brings us to the question of how we can start this ,as yet
unspecified,job once the user has initiated the printing.
Remember in my initial scheme (and as it stands now), this was to be done by
the user himself who would have started up the PF GUI (perhaps through a
hotkey).
This however was felt to be too complicated for the poor end user who, some
think, cannot be counted upon to remember to do this. Even though I'd have a
tendancy to think that such an end user should be shot rather then receive an
award for his behaviour, this is probably not a viable solution, so we must
go along with that user inability for the time being. This means that we need
some kind of job to be started when the user has started to print to the PFF
device. This must be done by the PFF device since at that stage nothing else
is involved in the printing itself and the *bleep*ing user can't do this
himself.
The problem is that, due to the nature of QDOS/SMSQE, starting a job from
within the OPEN call to a device in a "legal" way is not a possibility
("legal" means by using the facilities offcially provided by the OS for
starting a job). This includes any other indirect ways, as long as these are
being called as part of the OPEN call. The discussion on this list thus has
allowed us to eliminate various methods to do this (e.g. Things, putting
return values on the user stack of the program that is doing the printing
etc...). I had thought of several other possibilities (e.g. doing a hotkey
from within the open call which would start a program ) but they, also fall
foul of being indirect ways of doing something we are not allowed to do
directly but stil not being legal, .
This means that I can see no way around to having a job that is already
executing (and not being started from nothing) and somehow getting this job
to do its work when printing is initiated. However, having a job that runs in
the background, continuously scanning whether a channel was opended is
wasteful of system resources. It would be better for this job to "sleep" and
only be awoken when needed, thus using as little as possible system resources
whilst being asleep.
On an SMSQ/E system, this would be no problem: Have a job set itself up as a
button (thus being suspended most of the time), send it a wake event (a legal
way) when printing is initiated and voila, problem solved.
Marcel put a hole into that very early by reminding us that events are an OS
facility, and thus not available to QDOS users - and much of this discussion
here is about legacy systems....
Per then made the important and breakthrough contribution by telling us that
we could make a change in the job header of a suspended job which would then
become unsuspended. This is not an entire legal way of doing things, but the
least illegal I can find. I personnally would prefer to change that job's
priority from 0 to 1 (or whatever) which will also cause the job to awaken,
but this is exactly the same principle. We can probably test both - having
implemented one, the other is trivial.
Now the question becomes: what does this job do? Here I have quite a
different philosophy from Joachim and Rich. Apparently for them, this job
does important work. For me it doesn't, it is an "intermediary job" and all
it should do is - start another job.
The reason for this is that I envision that this job should be set up by the
PFF device driver when that is installed (and thus the job to be awoken which
will be part of it) All of this will all be programmed in machine code.
Doing some big print processing job in m/c is not my idea of fun, when we
have a perfectly functioning Basic that is more or less ideal for this.
Moreover, doing it this way, this job can be kept very small, taking up very
little memory during the time it isn't really doing anything useful, and
communciation between the device driver and the job will be easy.
When executing, all that job does is start the real "distributing" job. For
me, this processing job would be the PF GUI - which has the advantage of
already existing...
Finally, the advantage I see in this is that the GUI can also be invoked from
the print object which Jim Hunkins has mentioned and which could be important
for his desktop prog.
and,I understand, also for launchpad (In this respect, the question is: could
the printing objects in both of these programs just dump the file into the
PFF device? - if yes: Problem (nearly) solved...)
Since the intermediary job would be part of the PFF, it would be installed
and started at the same time the PFF is installed. One less thing the user
has to think about. Moreover, the name of the GUI (and where it can be found)
would be configurable. This would also allow for other GUIs to be written.
The GUI
=======
So now we come to the GUI. If you look at other operating systems, when you
initiate printing, you get some kind of printer dialog, which allows you
chose your printer, the number of copies to be printed etc. Why not do the
same thing here? And the program to do that already exists, at least to 90 %.
This is the PF GUI. It already allows you to choose which PROforma printer
driver to use. It could probably be adapted to Ghostscript,but I do confess
to a total ignorance in all maters Ghostscripty... Proforma even allows
landscape printing, and I could adapt the GUI to propose such an options.
In this scheme, the GUI needn't even be loaded all of the time in memory, it
could be executed (from hardisk, floppies, or a hotkey) as and when needed.
It could also disappear as soon as printing is finished.
The GUI and PFF
===============
Moreover, the GUI will allow the user to choose what filter and printer
driver to use. To me that makes more sense than trying to print to, say
PFF1oeyx, where the letters denote some of the printing options (use the
filter, print to this driver etc), for at least two reasons:. remember, we're
talking here about a hypothetical user too ... distracted to start up a
print job. Will he remember these device settings? Choosing from a list of
options will certainly be easier! Also, nothing guarantees that these older
programs which allow you yo print to a file will allow you to print to a
device with a very long name!
However, if need be, the PFF device could be adapted so that it could pass on
to the intermediary job, and then the GUI the device NUMBER to which the suer
printed. 1 could be stright ASCII with printer directives as entioned above,
PFF2 could be ESC P2 etc....
Yet, one identified weakness in this scheme of things is that the user would
have to choose the filter appropriate for what
he is trying to accomplish. Is he trying to print an ASCII file to Proforma?
Is he trying to print an ESC/P2 file to Ghostscript? He alone knows. So the
choice must be his. To keep things more simple, I propose that the names of
the filter files all reflect what the do (for example
win1_filter_ESC/P2_to_Proforma_obj). If all filters are put in the same
directory, the user could choose the filters relatively easily. If the user
always uses the same program to print, he filters could be preconfigured.
In short,my scheme would be as follows
Printing progamm prints to PFF
PFF wakes up the intermediary job
intermediary job wakes the GUI
the user chooses his options in the GUI
The GUI starts the filter
The filter prints to the printer using PROforma
Where does PROforma print?
==========================
FInally a question for Joachim. In all of the above, I have assued that the
printing is being done by PROforma. Nothing stops a filter being developped
for Ghostscript, of course, but I use PROforma because i KNOW it works, and
it is a QL native solution...
However - how does PROforma know WHERE to print? Mine just worked straight
out of the box prnting to PAR. The only thing I have found is that this seems
to be hard coded in the device drivers (pfd). Is this correct?
Anyway, let me all know what you think of the above scheme, knowing that I
could continue developemnt on the PF GUI and the PFF to implement all of what
I have mentioned above.
Have a nice sunday
Wolfgang
----------------------------------------
www.scp-paulet-lenerz.com
_______________________________________________
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm