Lexmark Z11 Color Jetprinter Linux Driver

Linux Printing Howto here you might find the right driver for your printer - if it is not a Lexmark 2070 or Z11.

Download

cZ11 source and documentation

Introduction

Unfortunately, Lexmark decided to design the Z11 as a Windows GDI printer. The protocol is proprietary, so there is not any documentation available. Fortunately, as it is a rather simple protocol, it has not been an unsolvable problem to reverse engineer it by printing to a file using the Windows driver, calculating some hex values, loosing some hair and cursing a lot.

The protocol uses a rather long initialization sequence to set up the printer and load a page. With this driver, this prologue is read from a file. After the prologue, print sweeps are sent. The Cartridge has 192 pens, which come in three packets seperated by 26 pixels for the three colors and in two interlaced rows separated by 16 pixels. The native resolution of this cartridge is 600dpi; 1200dpi printing is done in two interlaced sweeps (and only in windows, as this driver cannot do this). The print sweeps consist of a header, which contains the width of the line, the vertical movement which is done after the sweep has been printed and some fancy checksum bytes. There might even be more information in it, which I know nothing about. This header is followed by the compressed matrix for this sweep. Compression is done bytewise for the 24 bytes (= 192 bits). If the byte is empty, it is ommitted; otherwise, a byte in a preceding 4 Byte mask is set to 0 and the byte is copied into the stream.

Color printing is nonetheless a difficult issue. As there are three colors in the color cartridge, there is only a third of the pens available for each color. There is also a gap inbetween two colors. Yet all three colors are printed in one sweep, so there have to be some arithmetics. If you are interested in how this works, feel free to look at the abundantly commented code.

Optimization of white spaces is also handled by this driver by transporting vertically over completely empty lines in just one sequence.

The driver filters GhostScript output to the Lexmark protocol. The input format has changed to bitcmyk, which means you have to change your apsfilter accordingly. The driver simply reads the standard input, converts it and then sends the data to the standard output. This has been successfully tested with GhostScript 6.0, but should also work with 5.x.

Installation

After you have downloaded the tarball with the sourcecode, you have to extract its contents into a directory of your choice by typing

tar -xzf cZ11.tar.gz

Then you have to compile the code to get the binary for your system. This is done simply by typing

make

If you are root (you should be root while installing new software in most cases anyway) you can now copy the binary and the prologue to their destinations, which are /usr/bin/cZ11 and /etc/LexmarkZ11/prolog.prn by typing

make install

On SuSE 6.4, you should now type

make suse64

to install the printer correctly on lp0, using the standard name of "lp". Please note that this overwrites all other entries in /etc/printcap, so you will only want to do this if you have not configured any other printers yet.

SuSE 6.4 users should now be able to print. All others have to do some more work, which is hopefully covered in the following paragraphs.

You should now modify your apsfilter, as this driver is designed to work with the BSD printing system. There might exist other possibilities, but please do not ask me about them. A good basic apsfilter can be found in SuSE Linux 6.4, but I guess that other distibutors use quite similar files.

Warning! Before you change the apsfilter, backup the original file!

You have to modify two sections of the apsfilter in order to make the new driver work with it. These sections might differ slightly in your filter! All modifications are in bold letters. Your apsfilter is linked to several places, probably at least to "/usr/lib/apsfilter/bin/apsfilter".

...
...
...
case $PRINTER in
	PS_*dpi)
	    r="${PRINTER#PS_}" ; r="${r%dpi}" ; setres $r
	    [ `echo $r|grep -cE '^([0-9]+|[0-9]+x[0-9]+)$'` -eq 0 ] && setres 300
	    [ -n "$DPI" ] && setres $DPI
	    ;;
	PS_*)			setres 300        ;;
	cdj*|*desk*|djet*)	setres 300 -r     ;;
	dnj*c)			setres 300 -r     ;;
	hpdj)			setres 300 -r     ;;
	ljet4l)			setres 300        ;;
	ljet4)			setres 600        ;;
	lj4dith)		setres 600        ;;
	laserjet|ljet[23]*)	setres 300        ;;
	paintjet|pj*)		setres 300        ;;
	necp6)			setres 360        ;;
	bj10e|bj200|bjc[68]00)	setres 360 -r     ;;
	stcolor|st800)		setres 360 -r     ;;
	eps9*)			setres 240x216 -r ;;
	epson)			setres 360x180 -r ;;
	epsonc)			setres 360x180 -r ;;
	*\.upp)			setres 300 -r     ;;
	ppa1000|ppa[87]20)	setres 600 -r     ;;
	cZ11)                  setres 600 -r     ;;
	*)			setres 300 -r     ;;
esac
...
...
...
case $PRINTER in
	*\.upp)	# PRINTER = option file (e.g. unified printer driver)
		# Note: A resolution in the option file overwrites
		#       the given resolution. This is a `must be'.
		HAVE_GS="$HAVE_GS ${GS_RESOL} @${PRINTER}"
		;;
	ppa1000|ppa[87]20)
		# PRINTER = pbmraw gs device + post filter pbm2ppa
		#
		HAVE_GS="$HAVE_GS -sDEVICE=pbmraw ${GS_RESOL}"
		#
		findfilter pbm2ppa PBMTOPPA
		OUTPIPE="$HAVE_PBMTOPPA -v ${PRINTER#ppa}|$PRINT_RAW"
		#
		;;
	lex*)	# PRINTER = pbmraw gs device + post filter pbm2l7k
		#
		HAVE_GS="$HAVE_GS -sDEVICE=pbmraw ${GS_RESOL}"
		#
		findfilter pbm2l7k PBMTOLEX
		case $PRINTER in
			*7000)	OUTPIPE="$HAVE_PBMTOLEX -m 0 |$PRINT_RAW" ;;
			*5700)	OUTPIPE="$HAVE_PBMTOLEX -m 1 |$PRINT_RAW" ;;
			*)	OUTPIPE="$HAVE_PBMTOLEX      |$PRINT_RAW" ;;
		esac
		;;
	cZ11)
		# PRINTER = bitcmyk gs device + post filter cZ11
		HAVE_GS="$HAVE_GS -sDEVICE=bitcmyk ${GS_RESOL}"
		#
		findfilter cZ11 CMYKTOZ11
		OUTPIPE="$HAVE_CMYKTOZ11|$PRINT_RAW"
		;;
	*)	# PRINTER = ghostscript device
         	HAVE_GS="$HAVE_GS -sDEVICE=${PRINTER} ${GS_RESOL}"
	        ;;
esac
...
...
...

It is probably a good idea to copy the modifications directly from this document to your apsfilter. You should test the apsfilter by simply executing it and looking for any error messages. You should get some error messages when trying this anyway, but a syntax error indicates that is is your fault. You can monitor the correct execution later by watching the list of active processes after launching a print job.

The -dDITHERPPI parameter of GhostScript controls the graininess of the output. If you want your own Andy Warhol graphic, you might want to set this to 10 ;-). The GhostScript standard setting is 60, which looks really grainy. You should experiment with this parameter to find the best setting.

Finally, you have to create your printer's queues. This can be done more or less easily using /usr/lib/apsfilter/bin/SETUP. You should configure a

"cZ11 a4 color 600" at (in most cases) "/dev/lp0".

Now it should be done. Try to print now, curse and try again ;-).

Copyright and License

This driver and documentation have been written by Christian Kornblum in June 2000. It is protected by the GNU Public License, which you should have received a copy of along with this package.


You are welcome to contact me if you have any questions or ideas! kornblum@studst.fh-muenster.de