.\" $Header: README.nr,v 1.1 88/01/15 12:14:04 simpson Rel $ .\" $Log: README.nr,v $ .\" Revision 1.1 88/01/15 12:14:04 simpson .\" initial release .\" .\" Revision 0.2 88/01/13 14:31:43 simpson .\" removed reference to pre-made PK files .\" .\" Revision 0.1 88/01/07 08:27:30 simpson .\" beta test .\" .\" This document uses the -ms macros .if t .ds Tx T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X .if n .ds Tx TeX .if t .ds LX L\v'-.22m'a\v'.22m'T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X .if n .ds LX LaTeX .TL QMS and Talaris Laser Printer Software for the 4.2 BSD Spooling System .AU Scott Simpson .AI TRW Space & Defense Sector One Space Park, R2/2133 Redondo Beach, CA 90278 (213) 812-5338 {decvax,ucbvax,ihnp4}!trwrb!simpson trwrb!simpson@trwind.trw.com .AB .PP This is the installation guide for the 4.2 BSD QMS and Talaris laser printer software. It is a long document, so before you install anything get a cup of coffee (or a beer), put your feet on the desk, and relax. This will be a fun, hallucinogenic ride through installation land. .AE .SH The Name Of The Game .PP Many of you may not know the difference between a Talaris printer and a QMS printer. Well, the difference is\-nothing. Well, almost nothing. Talaris puts new ROM fonts in their printer when they sell it to you but they just buy the printers from QMS and put their name on them. QMS in turn buys their printer engines from Xerox, Canon and Ricoh and puts their controllers on them. The end result is that consumers like you and I pay through the wazoo for everything. Such is the way of the world. .SH In The Beginning... .PP Around 1985 I had written a QMS \*(Tx and troff driver for our QMS laser printers since at the time there were none available (or none that I knew of). I made this driver compatible with an otroff (the C/A/T troff, not ditroff) driver called ``qcat'' from Mt. Xinu. This driver maintained a state table on disk which stored information about the fonts currently residing in the printer. Some type of state information needed to be stored since it was not possible to query the QMS printer to ask it what fonts it had downloaded or how much memory those fonts consumed. This seemed like a logical solution. .PP I didn't like the code so I rewrote it. Before I rewrote the troff driver, I had given my \*(Tx driver to the University of Washington to distribute on the Unix \*(Tx tape. After I had completed my troff driver, a number of people discovered my TRW telephone number and asked if they could have a copy of it (the driver, not my telephone number). I freely gave away the software to interested parties. .SH Problems In Paradise .PP I immediately ran into some problems. The otroff driver used proprietary fonts so when someone asked for the code, they needed to already have ``qcat'' and the fonts. Freely distributable fonts were needed. .PP I also discovered some annoying problems with the \*(Tx and troff drivers. First, the state table presents a consistency problem. If the printer is powered down or if fonts are downloaded without going through the driver software or the state table is inadvertently trashed, the table and the printer have different ideas about what fonts are loaded and they proceed to print funny documents often with many greek characters. (The character 0 is Gamma in \*(Tx fonts and the QMS printer prints character 0 when it can't find a letter in a certain font.) This is very entertaining unless you are trying to get work done. Users don't have a sense of humor. .PP Another more serious problem reared its ugly head. The \*(Tx driver supported the ``\especial'' command of \*(Tx. So, you could say ``\especial{overlay(/staff1/simpson/barchart)}'' and output the file barchart to the QMS printer at that point. The file ``barchart'' would be a QMS QUIC file possibly generated by a graphics program. Nice graphs and other wonderful pictures could be inserted into \*(Tx documents this way. There is one problem: the driver often ran as root. So, the mischevious user could say ``\especial{overlay(/usr/lib/uucp/L.sys)}'' and merrily print out the contents of the UUCP password file. This is not good. A simple solution would be to change the uid of the driver to the person running the driver. This works, but now you must make the state table writable by everyone so the driver can write it. This is also not good. A last solution would be to run as root, open the state table, leave it open and then change the uid. This works, is secure and was not implemented. Sorry. (The new drivers do this and don't suffer security problems.) .PP During the next couple of years a few nice advances in technology occurred. The very compact pk format font file was designed. This font format stores the bit rasters as run lengths rather than bit maps. It created a 78% reduction in font file disk space over the pxl format (which stores characters as bit maps) on our system. Also, QMS added the ability to query the controller and ask it pertinent information about the status of the printer. Information is provided about available font ram and the currently downloaded fonts. This is very useful. I congratulate QMS on doing something right. Unfortunately, the way they implemented it was brain damaged. There are two ports on the QMS controller. Ours are both serial lines although one used to be a parallel interface. RS232 lines can talk both ways but the QMS dedicates one line for writing to the QMS printer and the other line (known as the debugger port) for reading status information. It works but you have to dedicate two ports to each printer instead of one. Not too painful. Lastly, they added the ability to download font data in binary format instead of as ASCII hex characters. This allows you to send half the amount of data down to the printer when downloading fonts compared to the ASCII hex format. Since much of the printer time is spent downloading fonts, this is actually quite useful. .PP In summary, the old driver is woefully out of date. If you have it, burn it in effigy. .SH My Solution .PP My solution incorporates what I feel is the best solution so far. I decided to write a set of filters to fit snugly in the 4.2BSD spooling system. My new otroff, ditroff and \*(Tx drivers query the QMS printers for font download and ram available information so the information is always correct, even if you re-power up the printer. Also, my driver uses the new compact ``pk'' font format and converts fonts from ``pk'' format to QMS format on the fly. Eight bit download format is used. .PP QMS font numbers are assigned ranges. The font numbers 1-10000 are available for \*(Tx fonts and the range 10001-20000 are for troff fonts (both otroff and ditroff share the same fonts). Consequently, you can not have more than 10000 \*(Tx or 10000 troff fonts. If you run over this limit you are warped. Font numbers are assigned in the following manner: Each time the driver runs, it reads all the names in the font directory and assigns them numbers consecutively in the order they are found in the font directory. This takes surprisingly little time. If you add or delete files from the system font directory you will have to reset the printer since the numbers of the fonts in the printer and the mapping the drivers compute may not mesh. .SH Installation .PP There are a number of steps to follow to install the software. Follow them closely. Don't be scared about the length. I explain things in gory detail. .IP 1. You must have a running METAFONT and \fIgftopk\fR(1) to create the troff fonts. Copy the METAFONT file ``logodesign.mf'' in the directory ``mffiles'' to your METAFONT macro directory. Next, run the ``makefonts'' scripts in the directories ``wwfonts'' and ``wbfonts''. This assumes you have set up the mode ``qms'' for the Xerox and Ricoh engines and the mode ``imagen'' for the Canon engine. Our ``local.mf'' contains the lines .ID .ft CW mode_def imagen = % imagen mode: for the Imagen 8/300 (Canon engine) proofing:=0; % no, we're not making proofs fontmaking:=1; % yes, we are making a font tracingtitles:=0;% no, don't show titles in the log pixels_per_inch:=300; blacker:=0; % Canon engine is black enough fillin:=.2; % and it tends to fill in diagonals o_correction:=.6; enddef; mode_def qms = % qms mode: for the QMS (Xerox engine) proofing:=0; % no, we're not making proofs fontmaking:=1; % yes, we are making a font tracingtitles:=0;% no, don't show titles in the log pixels_per_inch:=300; blacker:=.8; % Values from Charles Karney, TUGboat, April 1987 fillin:=.2; o_correction:=.4; enddef; .DE .ft R ``Local.mf'' is loaded when you create METAFONT. If you don't understand the concept of modes or how ``local.mf'' plays a part in all this, see The METAFONTbook. Running these two scripts will probably take a couple of days. Literally. .IP 2. Decide if you have device-independent troff. This is easy. Did you send a lot of money to AT&T and get a tape in the mail? If you did, you must unfortunately make some changes to the eqn and pic preprocessors that came in the distribution. These two processors take a .B -T option which designates which device to generate output for. We need to add the QMS printer as a valid device. In the directory ``diffs'' are two context diffs suitable for input to Larry Wall's infamous .I patch program. The eqn patch modifies the file ``io.c'' in the distribution. The pic patch modifies the file ``main.c'' in the distribution. Modify your eqn and pic now. .IP 3. If you have multiple printers, let's first set up one printer at a time. You can come back to this step to install more printers when you are done if need be. Select two tty ports to use to talk to your printer. That's right. Each printer needs .I two serial tty lines. If your printer has a parallel port, get it converted. A parallel port will probably work but I have not tested it. You are on your own if you don't convert to serial. Two types of flow control are used\-one type for each port. The daughter board port uses hardware flow control. The printer lowers DTR when the buffer is full and raises it when it is ready to accept data. Since the computer is a DTE and the printer is a DTE, a null modem must be used to connect the computer and the printer. The tty bits for the daughter board port are specified in the ``/etc/printcap'' file and are set by lpr. The tty bits are also read by my software to set the debugger port bits. .IP Hardware flow control (DTR) is used for the daughter board port so ^S/^Q can be sent and not interpreted as flow control. Unfortunately, the debugger port will not work with hardware flow control and ^S/^Q must be used. Simply run a regular RS-232 line through from the debugger port to the computer. .IP All machines don't work as simply as this. In fact, none of the machines I have tested the software on work as simply as this! Here are descriptions of what to do different for different machines. If your machine is not listed here, the software has not been tested on your machine and you need to figure it out. When you do, let me know so I can share your experience with other users of the same equipment. .RS .IP PYRAMID The Pyramid does not use a normal null modem. To create a null modem for the Pyramid, switch pins 2 and 3, 4 and 8, and connect pin 20 on one side to pins 5 and 6 on the other side. Connect lines 1, 7 and 22 straight through. I don't know why this works and even the people at RTOC (Pyramid's Remote Technical Operations Center) could not explain it to me. .IP SUN I hooked the two lines up to the serial ports on the Sun CPU board. These ports are driven by the ``zs0'' driver in the kernel configuration file. The ``flags'' variable to the zs0 driver determines whether a modem can detect a carrier drop. If bit 0 of the flags variable is on, software carrier will be turned on the first port. If bit 1 of the flags variable is on, software carrier will be turned on the second port. We want to use hardware carrier on both ports so set the flags variable to 0x0 and reconfigure and reinstall the kernel if necessary. .IP A Sun null modem can be made by switching lines 2 and 3 and running line 7 straight through. See the excellent Sun documentation. .IP "OTHER COMPUTERS" Here are some hints for other computers. First, check the documentation! This sounds completely obvious but it is amazing how many people don't do it. If the documentation does not describe how to make a null modem for hardware carrier, try using a normal null modem. On normal machines, a NULL modem is made by switching pins 2 and 3, 6 and 20, and looping 4 back to 5. Lines 1, 7, 8 and 22 are connected straight through. .IP Often fast machines have front ends whose tty bits need to be configured. For example, the Pyramid has a couple of ioctl calls specific to it that must be used to really get flow control to work. In the file ``of.c'' in the ``src'' directory you will see a section demarcated ``#ifdef pyr'' that really gets the flow control to work on the Pyramid since the Pyramid has a pseudo front-end called an ITP which has special ioctl calls. You may have to change this to get this to work on your machine\-or maybe not. You can usually check the include file ``/usr/include/sys/ioctl.h'' to see if your computer has such a special call. .RE .IP 4. Each printer has two queues\-one for portrait mode and one for landscape mode. The landscape queue retains the same name as the portrait queue but the landscape queue is suffixed with an `l'. For example, suppose you want to name your printer queue ``grumpy''. You will create two queues: ``grumpy'' and ``grumpyl'' for portrait and landscape mode respectively. If you queue to the two different queues simultaneously, you obviously don't want both jobs printing at the same time! Pyramid has modified their ``lpd'' daemon to check if another job has the printer. Sun hasn't. If your ``lpd'' does not check whether two jobs are using the same printer simultaneously, my software will check for it. In the ``src'' directory in the file ``of.c'' you will see two sections delimited by ``#if defined(sun)'' that lock out other print jobs. Define it in both places if your lpd does not lock out other processes. .IP 5. You'll now have to set up the correct interface options on your printer. The interface options for the printer are the class 1 options and unfortunately cannot be set by software. If you have a QMS 1200, QMS 1500 or QMS 2400, set the interface options 2 and 30 in class 1 using the panel. Do not set any other options within this class. This is eight bit, no parity with hardware flow control. If you have a QMS 800, set bit 2 on SWS 1 on, all others on SWS 1 off. Setting options is described in the User Guide and Daughter Board manuals. The options in the other classes will be set by software and are specified in the configuration file (see step 10). You will also need to set the dip switches on the QMS Daughter Board to the appropriate speed. We use our printers at 9600 baud. I couldn't get 19200 to work. You can try. Set bits 7 and 8 on, all others off, on switch S1 on the daughter board for 9600 baud. See the QMS RS-232 Daughter Board Operating Manual. .IP 6. Set the owner of the two tty lines to root and the group owner to daemon. Set the permissions to 660. Turn off getty on the two tty lines by editing the ``/etc/ttys'' file. If you have a 4.2 BSD ``/etc/ttys'' file, set the first column to 0 to disable getty and the second column to the appropriate baud rate. Do a ``kill -HUP 1'' so init rereads the ``/etc/ttys'' file. .IP 7. There are a set of include files written here at TRW which declare machine specific C preprocessor #defines and macros. Use of these symbolic names within programs makes them more portable, since you need only change the ``standard'' include files and the programs will port. The include files are only currently set up for a small variety of machines. You may have to add the appropriate values for your machine. .IP In the directory ``standard'', look at the files ``standenviron.h'' and ``standconst.h.'' If your machine type is not in there, add it and send me a message telling me what your additions are. Please try to use the pre-defined C preprocessor variables as I did. This makes things more portable. .IP 8. The top level Makefile makes and installs everything. You will need to set up some paths in it. I strongly suggest that you use the paths distributed. Here is what the variables are: .RS .IP INCLUDE This distribution includes a set of libraries that you receive in addition to the printer filters. The printer filters use these libraries so you must install them. The libraries need some header files and the header files are put in this directory. You must .I "leave this variable as is." .IP FILTER This is where all the lpr filters are put. You can change this to anything you want, but ``/usr/local/lib/lpr'' seems the most logical. .IP LIB This is where the bonus libraries are put. The glob and profile library are quite useful. The trw and qmsquery libraries aren't. .IP "WBTEXFONT and WWTEXFONT" This is where the write-black and write-white \*(Tx pk fonts are stored. There are two kinds of laser printers in this great big world of ours: write-black and write-white engines. Write-black printers write the black part with the laser and write-white write everything but the black part with the laser. To get the best looking output, you should use different fonts for each type of printer. The QMS 800 is a write-black printer. The QMS 1200, QMS 1500 and QMS 2400 are write-white printers. At our site, we only have QMS 1200, QMS 1500 and QMS 2400 printers so we don't have any write-black printers. If we did, I would put the \*(Tx fonts in ``/usr/lib/tex/imagenfonts'' since the imagen 240 laser printer is write-black. Also, you specify ``\emode:=imagen;'' to METAFONT when you want to get fonts for a write-black printer. We store our write-white fonts in ``/usr/lib/tex/qmsfonts'' since you say ``\emode:=qms;'' to get write-white fonts from METAFONT. Our \*(Tx tfm files are stored in ``/usr/lib/tex/tfm'' since both write-black and write-white printers can use the same tfm files. \*(Tx doesn't care about what type of printer you have so it only reads the files in the ``tfm'' directory. My driver only cares about the rasters and can get the widths from the pk file so it only reads the files in the ``imagenfonts'' and ``qmsfonts'' directories. Whether you have a write-black/write-white printer or not, set both paths to an appropriate value. .IP OTROFFFONT This is the directory where the width tables for otroff are stored. This is always ``/usr/lib/font'' on every system I have ever seen. The rasters for old troff are discussed under DITROFFFONT. .IP DITROFFFONT This is the location of the ditroff width tables and the grandfather directory of the font raster files. Please leave it as ``/usr/lib/font/devqms''. Ditroff likes to look there. In this directory will be created two more directories: ``wbfonts'' and ``wwfonts.'' You guessed it. These are the write-black and write-white troff font directories. Both otroff and ditroff share the same fonts so they don't have to download fonts very often if they run right after each other. If you have ditroff, most people never use otroff again so this is not usually a problem anyway, but otroff is there if you need it. .IP BINARIES Along with the filters comes a few programs that manipulate fonts and such. This is the location to store those programs. .IP DOCILEUSER The \*(Tx and ditroff drivers can output a file directly to the printer during execution so that graphics can be included into text. This can present a security problem since they run as root. To avoid this, the drivers open the tty lines to the printer and then change uid to the user they are processing the file for. This solves our permission problems. Remote users don't have a uid on this machine so they switch to the uid given here. Games seems docile enough. .RE .IP You must also change the values in a couple of scripts. In the scripts .I glpr and .I glpq in the ``src'' directory change the ``printers'' variable to the name of your QMS printer queues. The landscape versions of the queues need not be given. If you don't have ditroff, you need to change the last line of the ``qtroff.backup'' script from ``otroff'' to ``troff''. .IP 9. If you have ditroff, there is a program called ``makedev'' distributed with it. This program takes a human readable DESC file and creates the ``DESC.out'' binary file that ditroff reads. Put this in your path now if you have it. Some systems have an ``/etc/makedev'' so you will want to put this program in your path before the system makedev. If you are using the C shell, you may have to type ``rehash''. .IP 10. Type ``make configure install'' as root in the home directory. Stand back. This installs everything. (At TRW, we use the ``Makefile.TRW'' makefile, since we have added extensive accounting for badge numbers, cost centers, charge numbers and session ids. We had to modify our kernel to handle all these bizarre elements so you should never have a need to use this Makefile.) .IP 11. A configuration file is used by the software for each printer queue. It is in \fIprofile\fP(5) format and should reside in the spooling directory of the printer (usually /usr/spool/*) in the file ``configuration''. If you have not made two directories for each printer, do so now. Make a portrait and landscape directory with owner root, group daemon and mode 775. You will need a configuration file in each spooling directory. Our configuration file looks like .ID .ft CW { readline /dev/ttyi54 portraitfont 1204 portraitpitch 12 landscapefont 1217 landscapepitch 14 model QMS1200 queuename grumpy class1 2 30 class2 2 11 class3 2 class4 } .DE .ft R The stanza does not need a marker. The ``readline'' value is the tty number of the line the software should read from (the tty line hooked to the debugger port). The ``portraitfont'' and ``landscapefont'' are the ROM fonts to use in portrait and landscape mode when acting as a line printer. The pitch values are the number of characters per inch in these fonts. It can be a real number or an integer. This needs to be set or a backspace-underline sequence won't work. The model is the model of the QMS printer. It should be ``QMS800'', ``QMS1200'', ``QMS1500'', or ``QMS2400''. Since the QMS 800 and QMS 1500 lasers scan the page in a direction perpendicular to the QMS 1200 and QMS 2400, they download fonts differently and the software needs to know which way to download fonts. The ``queuename'' is the name of the queue this configuration file is for. The class values are printer configuration options to turn on. These values are automatically set by software so if they are not correct then they will be changed and you will get messages on your error file when the first job you print runs. As previously mentioned, the class1 options are ignored because they cannot be set with software. Set the class 1 options as in step 4 above. .IP 12. Set up your ``/etc/printcap''. You will need separate queue entries for landscape and portrait mode. Our printcap looks like .ft CW .ID grumpy|lp|QMS laser printer model number 2400:\e :br#9600:fc#0177737:fs#040:xs#0460:xc#040000:\e :mx#0:pl#66:pw#80:px#2550:py#3300:\e :lp=/dev/ttyi62:\e :if=/usr/local/lib/lpr/if:\e :of=/usr/local/lib/lpr/of:\e :gf=/usr/local/lib/lpr/gf:\e :rf=/usr/local/lib/lpr/rf:\e :df=/usr/local/lib/lpr/df:\e :nf=/usr/local/lib/lpr/nf:\e :tf=/usr/local/lib/lpr/tf:\e :sd=/usr/spool/grumpy:\e :af=/usr/adm/grumpyacct: grumpyl|QMS laser printer model number 2400 landscape:\e :pl#66:pw#132:px#3300:py#2550:\e :af=/usr/adm/grumpylacct:\e :sd=/usr/spool/grumpyl:\e :tc=grumpy: .DE .ft R Note the skillful use of the ``tc'' termcap entry. Accounting is fully implemented. Just add an ``af'' entry and accounting files will automatically get written (provided the accounting file is writable by daemon). Make sure the tty bit entries ``fs'', ``fc'', ``xs'' and ``xc'' are set correctly and that the baud rate entry, ``br'', matches the baud rate that you have set on the daughter board. If you also name your printers after the seven dwarfs do not get more than seven printers. .PP You're done. The biggest problem I anticipate you having is that you cannot get flow control to work. There is hope. If you define the flag ``-DASCIILOAD'' to the CFLAGS variable in the top level Makefile and re-install, the drivers will use only ASCII characters when downloading a font. You can then turn on software flow control at a small performance cost. You will also need to change the class 1 option from 2 and 30 to only 6 if you have a QMS 1200, 1500 or 2400, or turn on bit 6 on switch SWS 1 if you have a QMS 800. You will also need to change the ``fc'', ``fs'', ``xs'' and ``xc'' entries in /etc/printcap to #0177776, #001, #040460 and #00, respectively. .PP If you wish to add characters to ditroff, you will need to select an unused font character position and insert the METAFONT source for the new character. You will also need to change the file ``tfm2difont.c'' in the ``src'' directory and add the new character to the table contained within it. You can create a table of character positions using the ``testfont.tex'' file on the \*(TX distribution tape. Don't fill in the space character and don't add characters to octal 000 or 177 in a normal (i.e., not special) font because these positions are occupied by the ditroff \e| and \e^ characters. That is, they won't show up on the table printout because they have width but no bitmap! .PP Some of the additional goodies you get with the code are useful. There is a version of ``eqnchar'' in the ``src'' directory that is suitable for both otroff and ditroff. You will probably want to replace your system ``eqnchar.'' Look at the libraries. You might find some quite useful (especially the profile library). Also, there are five programs in the src directory that are made and installed in the BINARIES directory: ``pktoch'', ``cati'', ``tfm2difont'', ``tfm2ofont'' and ``dumpdesc''. Pktoch prints out a symbolic dump of a PK file just like pxtoch. Tfm2difont converts a METAFONT TFM file to a ditroff width table file. It is used in the Makefile in the font directories. Tfm2ofont converts a METAFONT TFM file to a C file which can be compiled and used as a width table for old troff. Dumpdesc symbolically prints out a dump of the ``DESC.out'' file. It's pretty worthless except for debugging. Cati symbolically prints out the output of old troff, just like ``dvitype'' does for DVI files. It's pretty worthless too. .PP Any error messages output by the programs are pretty self-explanatory. Some of you may have trouble installing this software. Since it has not been tested on a lot of systems, I expect this. If you have trouble, please mail a message to the UUCP or ARPA address at the beginning of this file. You can call me, but \fBI PREFER MAIL\fP. Also, my phone number is subject to change at whim so you may have to do some hunting. If you find any bugs or things you really don't like, please tell me about them. Good luck.