# hp4laser:
#	lp model interface for HP LaserJet Series IIIsi and IV.
#
#	With the Adobe Postscript SIMM installed, this script will auto-detect
#	postscript files (by looking for %! as the first characters in the file,
#	and switch the printer mode as needed.
#
#	This script probably works fine with LJ II's and III's without
#	postscript support.  Set ps_simm=no in the CONFIGURATION SECTION.
#
#	See the CONFIGURATION SECTION below to adjust for your site.
#
#	Copyright 1993 Digi International.  All Rights Reserved.
#
#	Permission granted for non-commercial use without fee
#
# command arguments are:
#	request-id user-name title copies printer-options file1 [file2 ...]
#	$1         $2        $3    $4     $5
#
# options (lp -oXXX) are:
#	-otroff		#No cr/lf mapping (for JetRoff, etc.)
#	-oraw		#Same
#	-og		#Same (SCO's naming convention)
#	-oland		#Landscape orientation for unformatted text
#	-oport		#Portrait orientation for unformatted text
#	-o2on1		#Two pages on one page for unformatted text
#	-oi		#Indent 8 characters for unformatted text
#	-o17cpi		#17 CPI for unformatted text
#	-opcl		#Force use of PCL mode
#	-ops		#Force use of PS mode
#
#	-onobanner	Force no banner
#	-onofilebreak	Force no file break
# TODO:
#	-ocpi=pica	10 CPI
#	-ocpi=elite	12 CPI
#	-ocpi=		Other CPI
#	-olpi=		LPI
#	-olength=
#	-owidth=
#	-oindent=	Offset page by N characters
#
# Testing:
#	After configuring the stuff below, you can test this script without
#	actually installing it into the "lp" system with this typical command:
#
#		./hp4laser 9999 rick title 1 "" FILE > DEVICE
#
#	Where FILE is a file to print, and DEVICE is the device you use, e.g.
#	/dev/ttyi1A, /dev/lp0, or /dev/dfax0lp.  You have to be root.
#
# Installation:
#	To install this model as the interface script, do these commands:
#		/usr/lib/lpshut
#		/usr/lib/lpadmin -p ${name} -v ${dev} -m ${model}
#		/usr/lib/lpsched
#		lpstat -r
#		/usr/lib/accept ${name}
#		enable ${name}
#		/usr/lib/lpadmin -d${name}
#	Where ${name} is the name you want for your printer, ${dev} is the
#	device name, and ${model} is the name of this file.
#

#
# BEGIN CONFIGURATION SECTION (adjust these as needed)
#
speed=parallel	#Serial interface speed (e.g. 38400), or "parallel"
banner=no	#Enable printing of banner page ("yes" or "no")
ps_simm="yes"	#Have Adobe Postscript SIMM installed ("yes" or "no")
idlemode="pcl"	#Idle printer in "pcl" mode or "ps" mode (when ps_simm=yes)
#
# END CONFIGURATION SECTION
#

#
#	Word perfect uses its own spooling system
#
for option in $5
do
	if [ $option = WP50 ]
	then
		/usr/wp/bin/wpp50 <$6
		exit 0
	fi
done

#
#	Give names to the command line arguments
#
printer=`basename $0`
request_id=$1
user_name=$2
title="$3"
copies=$4
options=$5
shift 5
files="$*"
nfiles=$#

#
#	If serial interface, set speed
#
if [ "$speed" != "parallel" ]
then
	stty $speed clocal cs8 ixon ixoff -ixany -parenb onlcr -tabs -opost <&1
fi

#
#	Define some shorthand for PCL sequences
#
NORAW="\033&k2G"		#Translate LF to CR+LF and FF to CR+FF
RAW="\033&k0G"			#Do not translate CR, LF, or FF

RESETJOB="\033E\033&l2A"	#Reset printer, eject if any printing on page,
				#Select letter paper by default
RESETPAGE="\033E"		#Reset printer, eject if any printing on page
PSMODE="\033%-12345X@PJL enter language=postscript\n"	# Switch to PS
PCLMODE="\033%-12345X@PJL enter language=pcl\n"		# Switch to PCL

#
#	getarg <arg>:	given an <arg> of the form "x=y", return the "y"
#
getarg () {
	echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
}

#
#	postscript <file>: if <file> is a Postscript file, return true
#
postscript () {
	if [ $ps_simm = no ]; then return 1; fi
	if [ $force = "pcl" ]; then return 1; fi
	if [ $force = "ps" ]; then return 0; fi
	#case "`sed -n '1s/\(..\).*/\1/p' $1`" in
	#%!)	return 0;;
	#?%)	return 0;;
	#*)	return 1;;
	#esac
	ctrl_d=`echo "\004\c"`
	read a <$1
	case "$a" in
	%!*)		return 0;;
	"$ctrl_d"%!*)	return 0;;
	*)		return 1;;
	esac
}

#
#	Definition of the banner page for an HP printer
#
pcl_banner () {
	PCOURIER=	# "\033&l66p2e7.6c66F"
	GRAY="\033*c2400a150b30g2P"
	TLOC="\033*p0x0Y"
	echo "$RESETJOB$NORAW$PCOURIER$TLOC$GRAY\n\n\n\n"
	banner "  $user_name"
	echo "\n"
	full_name=`grep "^$user_name:" /etc/passwd | line | cut -d: -f5`
	if [ -n "$full_name" ]
	then
		echo "                User: $full_name\n"
	else
		echo "\n"
	fi
	echo "                Request id: $request_id    Printer: $printer\n"
	echo "                Options: $options\n"
	echo "                `date`"
	echo "\n"
	if [ -n "$title" ]
	then
		banner $title
	fi
	echo "$RESETJOB\c"
}

#
#	Postscript banner page
#
ps_banner () {
	:
}

#
#	Switch to PS mode
#
ps_mode () {
	echo "$PSMODE"
	echo "\r\004\c"
	echo "letter"	# Force inital paper selection to be letter
}

#
#	Switch to HP mode
#
pcl_mode () {
	echo "$PCLMODE\c"
	echo "$RESETJOB\c"
}

#
#	Process user options
#
raw=0
orient=port
cpi=10
lpi=6
indent=0
length=0
width=0
filebreak=1
two_on_one=0
force=no
for o in $options
do
	case $o in
	raw|troff|g)	raw=1;;
	land)		orient=land;;
	port)		orient=port;;
	17cpi)		cpi=16.66;;
	i)		indent=8;;
	2on1)		two_on_one=1;;
	cpi=pica)	cpi=10;;
	cpi=elite)	cpi=12;;
	cpi=*)		cpi=`getarg ${o}`;;
	indent=*)	indent=`getarg ${o}`;;
	length=*)	length=`getarg ${o}`;;
	width=*)	width=`getarg ${o}`;;
	lpi=*)		lpi=`getarg ${o}`;;
	nobanner)	banner=no;;
	nofilebreak)	filebreak=0;;
	ps)		force="ps";;
	pcl)		force="pcl";;
	esac
done

#
#	Init the printer, set exit traps
#
if [ $ps_simm = no ]; then
	# force PCL only operation
	PCLMODE=
	idlemode=pcl
fi
case $idlemode in
pcl)	cur_mode=pcl; pcl_mode; echo "$RESETJOB\c"
	trap 'pcl_mode; exit' 0 2 3 15
	;;
ps)	cur_mode=ps; ps_mode;
	trap 'ps_mode; exit' 0 2 3 15
	;;
esac

#
#	Get printer banner page out in portrait, courier
#
if [ $banner = yes ]
then
	case $idlemode in
	pcl)	pcl_banner;;
	ps)	ps_banner;;
	esac
fi

#
#	Set variables to use when file is printed in PCL mode
#
SET=
SET="$SET\033(s${cpi}H"
SET="$SET\033&a${indent}L"
if [ $raw = 1 ]; then CRMODE=$RAW; else CRMODE=$NORAW; fi
if [ $orient = "land" ]; then
	SET="$SET\033&l1O\033(s16.66H\033&l5.4C\033&l6E\033&a0R\033&l66F"
fi
if [ $two_on_one = 1 ]; then
	SET="$SET\033&l1O\033(s16.66H\033&l5.4C\033&l6E\033&a0R\033&l66F"
fi

#
#	Loop for each copy, and then for each file
#
copy=1
while [ $copy -le $copies ]
do
	for file in $files
	do
		if postscript $file
		then
			ps_mode
			cat $file
		else
			pcl_mode
			echo "$SET$CRMODE\c"
			if [ $two_on_one = 1 ]
			then
				cat "$file" | newform -i | \
					sed "s/^/| /" | pr -2 -w175 -t
			else
				cat "$file"
			fi
			if [ $filebreak = 1 ]; then echo "$RESETPAGE\c"; fi
		fi
	done
	copy=`expr $copy + 1`
done
exit 0
