From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 21-AUG-1990 01:00:41.36
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	New version of modified print symbiont for Postscript printers

Received:  by crdgw1.ge.com (5.57/GE 1.70)
	 id AA00907; Tue, 21 Aug 90 00:53:09 EDT
Message-Id:  <9008210453.AA00907@crdgw1.ge.com>
Received: From SOL1.GPS.CALTECH.EDU by CRVAX.SRI.COM with TCP; Mon, 20 AUG 90 13:29:27 PDT
Date: 20 Aug 1990 12:25:10 EST
From: Carl.J.Lydick@SOL1.GPS.CALTECH.EDU
To: info-vax@sri.com
Subject: New version of modified print symbiont for Postscript printers
X-Vms-Original-To: INET%"info-vax@sri.com"


A while back, I posted the code to use the PSM routines to modify the standard
print symbiont to service a postscript printer.  Since then, I've found a
better way to do it (still using the PSM routines).  In the older posting, I
replaced the FILE_TRAILER routine; I've since realized that replacing the
JOB_COMPLETION routine is a better way to do it.  The code (and three setup
modules to process straight text for the printer) follows:
******************** Code to create modified print symbiont ********************
$ COPY SYS$INPUT: $PSMDEF.H
/* PSMDEF.H -- Print Symbiont Modification definitions */
#define	PSM$K_CANCEL		 1
#define	PSM$K_CLOSE		 2
#define	PSM$K_FORMAT		 3
#define	PSM$K_OPEN		 4
#define	PSM$K_READ		 5
#define	PSM$K_GET_KEY		 6
#define	PSM$K_POSITION_TO_KEY	 7
#define	PSM$K_REWIND		 8
#define	PSM$K_WRITE		 9
#define	PSM$K_WRITE_NOFORMAT	10
#define	PSM$K_WRITE_SUPPRESSED	11
#define	PSM$K_PAUSE_TASK	12
#define	PSM$K_RESET_STREAM	13
#define	PSM$K_RESUME_TASK	14
#define	PSM$K_START_STREAM	15
#define	PSM$K_START_TASK	16
#define	PSM$K_STOP_TASK		17
#define	PSM$K_STOP_STREAM	18
#define	PSM$K_PAGE_SETUP	 1
#define	PSM$K_PAGE_HEADER	 2
#define	PSM$K_LIBRARY_INPUT	 3
#define	PSM$K_INPUT_FILTER	 4
#define	PSM$K_MAIN_FORMAT	 5
#define	PSM$K_OUTPUT_FILTER	 6
#define	PSM$K_OUTPUT		 7
#define	PSM$K_JOB_SETUP		 8
#define	PSM$K_FORM_SETUP	 9
#define	PSM$K_JOB_FLAG		10
#define	PSM$K_JOB_BURST		11
#define	PSM$K_FILE_SETUP	12
#define	PSM$K_FILE_FLAG		13
#define	PSM$K_FILE_BURST	14
#define	PSM$K_FILE_SETUP_2	15
#define	PSM$K_MAIN_INPUT	16
#define	PSM$K_FILE_INFORMATION	17
#define	PSM$K_FILE_ERRORS	18
#define	PSM$K_FILE_TRAILER	19
#define	PSM$K_JOB_RESET		20
#define	PSM$K_JOB_TRAILER	21
#define	PSM$K_JOB_COMPLETION	22
#define	PSM$K_PAGE_FOOTER	23
#define	PSM$k_max		24
#define	PSM$K_CC_INTERNAL	 1
#define	PSM$K_CC_IMPLIED	 2
#define	PSM$K_CC_FORTRAN	 3
#define	PSM$K_CC_PRINT		 4
#define	PSM$K_CC_MAX		 5
$ COPY SYS$INPUT: PS_SMB.C
/* PS_SMB.C -- code to modify print symbiont to deal with PostScript printers */
/* Copyright (C) 1990 Caltech Odd Hack Committee; no rights reserved */
#include descrip
#include psmmsgdef
#include "$psmdef.h"

modify()
{	long code = PSM$K_JOB_COMPLETION, ps_job_completion();
	PSM$REPLACE(&code, ps_job_completion);
	PSM$PRINT(0, 0, 0);
}

/* Send <CTRL/D><FF> instead of <FF> at job completion */
ps_job_completion(long *request_id, long *work_area, long *func, 
	struct dsc$descriptor *funcdesc, long *funcarg)
{	static char eof[] = "\f\4";
	static int sent_eof = 0;

	if(*func == PSM$K_READ)
	{	if(sent_eof == 0)
		{	funcdesc->dsc$b_class = DSC$K_CLASS_S;
			funcdesc->dsc$a_pointer = &eof;
			funcdesc->dsc$w_length = 2;
			sent_eof = 1;
			return 1;
		}
		else
			return PSM$_EOF;
	}
	else if(*func == PSM$K_OPEN || *func == PSM$K_CLOSE)
	{	sent_eof = 0;
		return 1;
	}
	else
		return PSM$_FUNNOTSUP;
}
$ CC PS_SMB
$ LINK PS_SMB
$ COPY PS_SMB.EXE SYS$SYSTEM:
***************** End of Code to create modified print symbiont ****************
Setup modules:
For 10-point portrait:
********************************************************************************
%!PS-Adobe-1.0<CR>
%%Creator: Carl J Lydick<CR>
%%DocumentFonts: Courier<CR>
%%Pages: (atend)<CR>
/Courier findfont 11 scalefont setfont<CR>
/P {showpage /H 750 def} def<CR>
/Q { 36 H moveto dup length 80 gt {0 80 getinterval} if show /H H 12 sub def
   H 30 le {P} if} def<CR>
/R 0 def<CR>
/S 512 string def<CR>
/T {(<FF>) search {R 0 ne {Q pop P} {pop pop /R 1 def} ifelse T} if} def<CR>
/L {/H 750 def {currentfile S readline not {exit} if T Q} loop showpage} def<CR>
L<CR><FF>
********************************************************************************
For 9 point landscape
********************************************************************************
%!PS-Adobe-1.0<CR>
%%Creator: Carl J Lydick<CR>
%%DocumentFonts: Courier<CR>
%%Pages: (atend)<CR>
/Courier findfont 9 scalefont setfont<CR>
/P {showpage 90 rotate 0 -618 translate /H 594 def} def<CR>
/Q {36 H moveto dup length 132 gt {0 132 getinterval} if show /H H 9.5 sub 
    def<CR>
    H 30 le {P} if} def<CR>
/R 0 def<CR>
/S 512 string def<CR>
/T {(<FF>) search {R 0 ne {Q pop P} {pop pop /R 1 def} ifelse T} if} def<CR>
/L {90 rotate 0 -618 translate /H 594 def {currentfile S readline not {exit}
    if<CR>
    T Q} loop showpage} def<CR>
L<CR><FF>
********************************************************************************
For 6 point portrait (132 columns)
********************************************************************************
%!PS-Adobe-1.0<CR>
%%Creator: Carl J Lydick<CR>
%%DocumentFonts: Courier<CR>
%%Pages: (atend)<CR>
/Courier findfont 6 scalefont setfont<CR>
/P {showpage /H 750 def} def<CR>
/Q { 36 H moveto dup length 132 gt {0 132 getinterval} if show /H H 7 sub def
   H 30 le {P} if} def<CR>
/R 0 def<CR>
/S 512 string def<CR>
/T {(<FF>) search {R 0 ne {Q pop P} {pop pop /R 1 def} ifelse T} if} def<CR>
/L {/H 750 def {currentfile S readline not {exit} if T Q} loop showpage} def<CR>
L<CR><FF>
********************************************************************************
In the setup modules, <CR> stands for ASCII 13, and <FF> for ASCII 12.
The only real drawbacks to this implementation are that it doesn't log (or for
that matter, pay attention to) any error messages generated by the printer, so
you have to take special steps to debug any PostScript files you send to it
(but we don't generate invalid PostScript files in the first place, do we? :-)
and that it doesn't query the printer to determine number of pages printed.

