[comp.text] Apple Laser Writer Manual Feed

monson@diablo.amd.com (Steve Monson) (05/18/91)

Here's an easy one, guys:

We have an Apple Laser Writer here at work, and I want to use the manual
single-sheet mode of operation. We use it as a network printer with our
Suns, not just for Macintoshes. The only doc we have is a user's manual,
which tells how to print manually, using menu options on the Mac. But I
want to use manual feed to print a job sent from Unix. So, what escape
sequence do I send ahead of my file, so it draws the paper from the manual
feed instead of the paper tray? Do I need to send some sort of reset sequence
after I'm done, or will the lpr handler reset everything automatically for
the next print job?

Hope to hear from you soon.

Steve
--
Once you give up your integrity, the rest is a piece of cake.
					  J.R. Ewing

graziano@charlie.heurikon.com (John Graziano) (05/31/91)

In article 1914 of comp.text, monson@diablo.amd.com (Steve Monson) writes:

> Here's an easy one, guys:
> 
> We have an Apple Laser Writer here at work, and I want to use the manual
> single-sheet mode of operation. We use it as a network printer with our
> Suns, not just for Macintoshes. The only doc we have is a user's manual,
> which tells how to print manually, using menu options on the Mac. But I
> want to use manual feed to print a job sent from Unix. So, what escape
> sequence do I send ahead of my file, so it draws the paper from the manual
> feed instead of the paper tray? Do I need to send some sort of reset sequence
> after I'm done, or will the lpr handler reset everything automatically for
> the next print job?

How fortunate for you that I just spent a week trying to do the very same
thing :-)!  It can be done, but it certainly isn't easy if, like me, you know 
little or nothing about Postscript or network printing.

The problem is that the Apple LaserWriter (ALW) requires a Postscript command
to set the manual feed option.  This option is reset for each file it receives,
so to set manual feed, you need to alter the code of each file sent to the
printer - ugh.

First, you need a program to add a manual feed directive to a Postscript file.
Here is one:
CUT HERE----------------------manual.l begins---------------------CUT HERE
%{
static int parens; /* parentheses counter */
static int lines;   
%}

MAN	\/manualfeed.false
IP	(\\\()|(\\\))

%%
\%\!.*$	{
	/* set /manualfeed after first line */
	printf("%s", yytext);
	if(!lines){
		printf("\nstatusdict /manualfeed true put");
		printf("\nusertime 5000 add { dup usertime lt { pop exit } if } loop");
	}
	}
\(	{
	printf("(");
	parens++;
	}
\)	{
	printf(")");
	parens--;
	}
{IP}	printf("%s", yytext);	/* ignore escaped parens */
{MAN}	{
	/* if "/manualfeed false" found outside of parens, switch to true */
	if(parens) 
		printf("%s", yytext);
	else 
		printf("/manualfeed true");
	}
\n	{
	lines++;
	putchar('\n');
	}
CUT HERE-----------------------manual.l ends-----------------------CUT HERE

This is written in lex. It takes a Postscript file from stdin, adds the manual
feed directive, and prints it to stdout.  If you don't know about lex, don't
worry - the Makefile is included at the end of the post.

The way it works is by matching the "%!" that starts every Postscript file and
adding the manual feed command directly after line 1.  The manual feed
directive looks like this:
            statusdict /manualfeed true put
	    usertime 5000 add { dup usertime lt { pop exit } if } loop

I got the above 2 lines from the sources to lpscript by Stephen Frede, et all
(file pcom.c, lines 105-110).  The first line sets the appropriate symbol in an
ALW dictionary (hashtable).  The second line described as a fix for an ALW 
manual feed bug, with a reference to p. 29, Appendix D of Inside LaserWriter.  
I couldn't find a copy of Inside LaserWriter so I don't know if the bug still 
exists in the newer models, but I've used the code extensively on an NTX with 
no ill effects (that anyone has noticed!).

The program also scans for the occurrence of "/manualfeed false" outside of 
parentheses (parens delimit Postscript string literals).  It changes each
occurrence to "/manualfeed true".  This should override ANY attempt to turn off
manual feed while leaving actual text references to manualfeed alone.

The next step is to set up this program as a filter for your printer. I did this
on a System V.3 machine, so it won't apply to SunOS.  I'll include the procedure
in case any *real* UNIX users are interested :-).  

Edit the ALW interface script in /usr/spool/lp/interface.  This should be 
something like "lw0" or "lw".  Before the script processes command switches,
initialize a variable MANUAL (or whatever) to "/bin/cat".  Then insert the code 
for another command switch (I used 'M').  When 'M' is passed to the script, set 
MANUAL to the pathname for the manual feed program.  Then, find all the spots in
the script where a file is sent to the printer and make $MANUAL the last filter
the file is piped through before it gets sent.  You should now be able to print 
with manual feed by specifying "-oM" as a switch to lp.

For SunOS, things look a bit harder.  I just glanced at the Sun manual entries 
for lpr and printcap and I don't see a spot to insert a custom filter, let
alone one which can be activated by a command line switch.  One solution may be
to create a separate printcap entry which uses the manual feed program as the
last step for all filters.  Users could then use the -P flag to access the 
manual feed printer. You could, of course, use lp instead of lpr, assuming that
it works like SysV lp.  No one here knows much about SunOS printing - we use 
"rsh <sysVmachine> lp ..." to print from our Suns (seriously).  Let me know 
what you figure out.
	
BTW, my motivation to implement manual feed was to allow employees to make 
double-sided printouts in order to cut down paper usage.  We soon found out 
that the ALW is not set up to make double-sided copies.  The the second time 
through, the heat from printing melts the toner on the other side and gums up 
the machine :-/


Good Luck!

--graz

Oops - almost forgot the Makefile!
CUT HERE------------------------Makefile begins------------------------CUT HERE
CC=cc
LDFLAGS=-ll
PROG=manual
PS=lpscript   #insert your favorite stdin-to-Postscript program here
PSFLAGS=-S
VIEW=view
TXTFILE=foo   #any text file 
PSFILE=$(TXTFILE).`basename $(PS)`
LEXFILE=$(TXTFILE).lex

$(PROG): $(PROG).o
	$(CC) -o $(PROG) $(PROG).o $(LDFLAGS)

test: $(PROG) $(PSFILE)
	cat $(PSFILE) | $(PROG) > $(LEXFILE)
	$(VIEW) $(PSFILE) $(LEXFILE)

$(PSFILE): $(TXTFILE)
	$(PS) $(PSFLAGS) < $(TXTFILE) > $(PSFILE)