# hplaser-pac:
#	lp model interface for HP LaserJet Series II, IIP, III
#	optionally, with the Pacific Page Postscript cartridge available
#
#	NOTE: although this interface attempts to switch modes between
#	PCL and PS, the current version of the Pacific Page cartridge
#	(2.58) will not switch properly back to PCL mode without losing
#	output or forgetting to switch to PCL mode if new output comes
#	quickly after the mode change.  A printer buffer will aggravate
#	the situation.  To handle this problem, we have put in delays
#	to account for the time spent during mode switching.  This seems
#	to work.
#
#	See the CONFIGURATION SECTION below to adjust for your site.
#
# Copyright 1991 DigiBoard, Inc. 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 are:
#	-otroff		#No cr/lf mapping (for JetRoff, etc.)
#	-oraw		#Same
#	-og		#Same
#	-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
#	-ohp		#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
#

#
# BEGIN CONFIGURATION SECTION (adjust these as needed)
#
speed=19200		#Serial interface speed (19.2)
speed=			#Parallel interface leave blank
banner=0		#Enable printing of banner page
pacpage=1		#Pacific Page postscript cartridge installed
idlemode="hp"		#Idle printer in "hp" mode or "ps" mode (when pacpage=1)
post_pcl_sleep=60	# Sleep time switching from PCL to PS
post_ps_sleep=120	# Sleep time switching from PS to PCL
#
# END CONFIGURATION SECTION
#

#
#	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" != "" ]
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
RESET="\033E"			#Reset printer, eject if any printing on page
HPMODE="\033&l1057.32259J"	#Switch from PostScript to HP PCL
PSMODE="\033&l5257.1058J"	#Switch from HP PCL to PostScript

#
#	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 [ $pacpage = 0 ]; then return 1; fi
	if [ $force = "hp" ]; then return 1; fi
	if [ $force = "ps" ]; then return 0; fi
	case "`sed -n '1s/\(..\).*/\1/p' $1`" in
	%!)	return 0;;
	*)	return 1;;
	esac
}

#
#	Definition of the banner page for an HP printer
#
hp_banner () {
	PCOURIER=	# "\033&l66p2e7.6c66F"
	GRAY="\033*c2400a150b30g2P"
	TLOC="\033*p0x0Y"
	echo "$RESET$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 "$RESET\c"
}

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

#
#	Switch to PS mode
#
ps_mode () {
	if [ $cur_mode != "ps" ]
	then
		sleep $post_pcl_sleep
		cur_mode="ps"
		echo "$PSMODE\c"
		sleep 40
	else
		echo "\r\004\c"
	fi
}

#
#	Switch to HP mode
#
hp_mode () {
	if [ $cur_mode != "hp" ]
	then
		echo "\r\r\004\c"
		sleep $post_ps_sleep
		cur_mode="hp"
		echo "$HPMODE\c"
		sleep 30
	else
		echo "$RESET\c"
	fi
}

#
#	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
duplex=no
for o in $options
do
	case $o in
	g|raw|troff)	raw=1;;
	land)		orient=land;;
	port)		orient=port;;
	duplex)		duplex=yes;;
	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=0;;
	nofilebreak)	filebreak=0;;
	ps)		force="ps";;
	hp)		force="hp";;
	ps_sleep=*)	post_ps_sleep=`getarg ${o}`;;
	pcl_sleep=*)	post_pcl_sleep=`getarg ${o}`;;
	esac
done

#
#	Init the printer, set exit traps
#
if [ $pacpage = 0 ]
then	# force PCL only operation
	HPMODE=
	idlemode=hp
fi
case $idlemode in
hp)	cur_mode=hp; hp_mode; echo "$RESET\c"
	trap 'hp_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 = 1 ]
then
	case $idlemode in
	hp)	hp_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
if [ $duplex = "yes" ]; then
	SET="$SET\033&l1S"
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
			hp_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 "$RESET\c"; fi
		fi
	done
	copy=`expr $copy + 1`
done
exit 0
