Home Page ] [ Eiffel Archive ] [ Eiffel Classes and Clusters ]

Arc de Triomphe clipart (2486 bytes)HPMODESET v2.0

Written by Glenn Maughan.

hpmodeset.tar.zip (436,199 bytes)

Quick Links:


Many of the newer model Hewlett-Packard printers do not have a control panel to change printer settings. In a Windows/DOS environment you are typically given drivers that allow you to change the printer settings. However, in a Unix environment such as Linux you usually do not get such nice drivers! I purchased a new LaserJet printer and found I could not control it completely under Linux. To reduce my frustrations I developed this utility.

Hpmodeset provides a simple interface to encapsulate print files within printer control statements. The control statements can take any reasonable form and are configurable via a config file. The utility is distributed with a config file for HP LaserJet 5MP printers. With a little modification it will work with most HP printers. (The current config file will work with all HP printers without modification as the PJL language ignores statements that it doesn't understand).

The utility currently supports all PJL commands through a configuration file.



hpmodeset [-help | -config]
hpmodeset [<config switches>] [<printer switches>] file ...

General switches

-help display the help message and current printer switches
-config display the printer configuration information

Configuration switches

-configfile=<file> use <file> as the configuration file and store
in <file>.store

Printer switches (default values shown in braces)

-formlines=[5-128 {60}]
-economode=[ON | {OFF} | on | off]
-pageprotect=[ON | {AUTO} | on | auto]
-resolution=[300 | {600}]
-orientation=[{PORTRAIT} | LANDSCAPE | portrait | landscape]
-mptray=[{CASSETTE} | MANUAL | FIRST | cassette | manual | first]
-copies=[1-999 {1}]
-manualfeed=[ON | {OFF} | on | off]
-personality=[{AUTO} | PCL | POSTSCRIPT | auto | pcl | postscript]
-ret=[OFF | LIGHT | {MEDIUM} | DARK | off | light |
medium | dark]
-paper=[LETTER | LEGAL | {A4} | EXECUTIVE | COM10 | MONACH |
C5 | CL | B5 | CUSTOM | letter | legal |
a4 | executive | com10 | monarch | c5 | cl |
b5 | custom]
-timeout=[5-300 {15}]

All printer switches are fully configurable. The configuration above is for a LaserJet 5MP printer. The user can specify the switch, the valid options and the default option. This ability can be used to configure hpmodeset for different printers. The utility has been designed to handle PJL. However this is also configurable, and therefore it may be possible to configure for a non PJL printer.

Following any printer control options should be a list of files to encapsulate. For example, to print the files `test.ps' and `test.pcl' in economode with manual paper feeds, the following hpmodeset command would perform the task:

$ hpmodeset -economode=ON test.ps test.pcl | lpr

Hpmodeset can also read from stdin using `-' as the file marker. The following command would be the ultimate in paper and toner saving print commands:

$ psnup -2 test.ps | hpmodeset -economode=ON - | lpr

(psnup is available in the excellent psutils package by Angus Duggan found on many Unix utility ftp sites. Sorry I can't remember the site I found it on, try archie!)


The distribution includes both a statically and dynamically linked binary. Try the dynamic binary first. If you get no problems with linking libraries then use it. Otherwise use the static linked version. I currently do not have an ELF Linux installation therefore I cannot create a binary in ELF format. Possibly in the near future.

Installation therefore is very simple. Copy the binary to a destination of your choice, such as /usr/local/bin:

For the dynamic version:

# cp hpmodeset-dynamic /usr/local/bin/hpmodeset

or for the static version

# cp hpmodeset-static /usr/local/bin/hpmodeset

and copy the man file to its relevant home, such as /usr/local/man/man1:

# cp hpmodeset.man /usr/local/man/man1/hpmodeset.1

You should also keep this README for reference. /usr/doc may be a good place for it.

Make sure the binary is executable:

# chown root.bin /usr/local/bin/hpmodeset
# chmod 755 /usr/local/bin/hpmodeset

You must then set an environment variable to let hpmodeset know where to read and store its configuration information (and other bits and pieces). Set the variable with:

In bash:

$ export HPMODESETHOME="$HOME/.Hpmodeset"

or in csh/tcsh:

$ setenv HPMODESETHOME "$HOME/.Hpmodeset

You may change the path to another existing directory. The only consideration is that hpmodeset must be able to write to the directory.

Once the directory is created copy the configuration file to it:

$ mkdir $HOME/.Hpmodeset
$ cp config/config $HOME/.Hpmodeset
$ chmod 644 $HOME/.Hpmodeset/config

You are ready to go. Hpmodeset will create to additional files in that directory: the persistent store for the configuration and a lexical analyser for reading configuration files. (There may be other files in the future also). This form of configuration is not optimal as each user needs to create the configuration directory and have a local copy of the config file (See TODO below).


The full source of hpmodeset is now distributed. It is dependant on a number of libraries distributed with the Interactive Software Engineering (ISE) Eiffel compiler v3.3.7. However, it should not matter which vendor's compiler is used to compile it. Specifically, the source relies heavily on the EiffelParse, EiffelLex and EiffelBase
(some parts that are not in the Kernel Specification) libraries.

You need to apply the EiffelParse.patch to the current ISE EiffelParse libraries. The best way to do this is to create a copy of the parse libraries into src/extended_parse:

$ cd src
$ cp $EIFFEL3/library/parse/* extended_parse
$ patch < EiffelParse.patch
$ mv aggregate_one.e* extended_parse

Check for any rejects (*.rej). If you have any you will have to apply the patches by hand. You may clean up the directory if you want:

$ rm extended_parse/*.orig

Then apply the supplied patch with:

$ patch < eiffelparse.patch

Set up the environment variable to point to the source directory. In bash:

$ cd src
$ export HPMODESET=`pwd`

Compilation is easy. If you are using ISE Eiffel change to the source directory and perform a finalize:

$ cd src
$ es3 -finalize
$ cd EIFGEN/F_code
$ finish_freezing

If you are using another compiler you will have to follow the procedures for that compiler. You may have to modify the source to fit the libraries you are using. With the new Eiffel Kernel Library Standard this will hopefully not be necessary either!

The executable resides in the file "src/EIFGEN/F_code/hpmodeset" after compilation.


I use GNU emacs and the Tower Eiffel eiffel-mode (available at http://www.cm.cf.ac.uk/Tower/). Indentation is at 8 spaces per tab. Set eiffel-mode with the following code in your .emacs file:

; Set Eiffel modes
(setq auto-mode-alist (cons '("\\.e$" . eiffel-mode)
(autoload 'eiffel-mode "eiffel3" "Mode for Eiffel programs" t)
(defun eiffel-minor-modes ()
    "Enables several minor modes for Eiffel"
    (interactive "")
    (setq eif-indent-increment 8))
(add-hook 'eiffel-mode-hook 'eiffel-minor-modes)

If you modify the code, please use this mode and indentation settings.

To Do

Terms and Conditions

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


Make sure your printer filter supports PJL source. ie. it should send any PJL code directly to the printer without any modification.

Depending on the printer you are using you may not notice any difference between the `economode' and `draftquality' settings. On some printers the effect will be identical.

Hpmodeset currently only modifies the current print environment for each print job. Therefore global printer settings are not changed. You can configure hpsetmode to use the `DEFAULT' command instead of `SET' to modify the default print environment however, you should be careful doing this as the settings will remain after hpmodeset has completed.


Please send all bugs, suggestions and support to:

Glenn Maughan (glennm@insect.sd.monash.edu.au)

The home site for Hpmodeset is:


Also if you create a new config file for a different printer, please send it to me. I will create a catalog of printer configurations to distribute with the package.

Home Page ] [ Eiffel Archive ] [ Eiffel Classes and Clusters ]