Date: Mon, 24 Nov 86 17:25:49 est
From: David Krowitz <mit-erl!mit-kermit!tigger!krowitz@EDDIE.MIT.EDU>
Here are the source files for a print-server for an Apple Imagewriter dot matrix
printer running on an Apollo workstation with an RS232 interface. See the
file PRF.IMAGEWRITER.HLP for the particular capabilities of this print-server
(including multiple fonts, bitmap graphics, etc). Documentation and
compiling instructions are in the normal .DOC and .BLD files. The
bundled files start below the dashed line.
-- David Krowitz
-----------------------------------------------------------------------
# To unbundle, sh this file
echo imagewriter.config 1>&2
cat >imagewriter.config <<'End of imagewriter.config'
PAGE_WIDTH 80
PAGE_LENGTH 66
PAGENO_COLUMN 72
FILE_BANNERS OFF
DEVICE user1
SIO_LINE 2
SPEED 9600
TOP_MARGIN 0
BOTTOM_MARGIN 6
FORM_FEEDS 0
PLOT_MODE ON
RESOLUTION 72
End of imagewriter.config
echo prf.imagewriter.hlp 1>&2
cat >prf.imagewriter.hlp <<'End of prf.imagewriter.hlp'
9.04;prf (print_file), revision 9.04, 85/05/30
PRF (PRINT_FILE) -- Queue a file for printing.
usage: PRF pathname... [-INTER] [-COP n] [-PR name] [-SITE entry_dir]
[-USER name] [-SIG ALARM|OFF]
[-BAN [ON|OFF]]
[-CONFIG [pathname]|-NDB]
[-TEXT|-PLOT|-TRANSPARENT] [-NPAG]
[-MARGINS [ON|OFF]] [-TOP n] [-BOT n]
[-RIGHT n] [-LEFT n] [-HEADERS [ON|OFF]]
[-HEAD l-string/c-string/r-string]
[-FOOT l-string/c-string/r-string]
[-FTN [ON|OFF]] [-WRAP [ON|OFF]]
[-PITCH n] [-POINT n] [-WEIGHT value]
[-LQ [ON|OFF]] [-RES n] [-WHITE n]
[-BW [ON|OFF]] [-MAGN {-1..16}] {CL}
FORMAT
PRF [pathname...] [options]
PRF queues a file for printing. The file must be an ASCII stream (i.e., text)
file, a graphics metafile (GMF), or a GPR bitmap object. After successfully
queueing a file, PRF displays a message containing the full pathname of the
file that you queued.
You can execute PRF once for each file that you want to print (specifying all
the necessary options every time), or you can enter PRF's interactive mode and
hand files to the program continuously. See the examples below.
Files queued by PRF are physically printed using PRSVR (PRINT_SERVER).
When you invoke PRF, it first sets all options to their default states (as
described below). Next, it looks for a PRF configuration file called
~USER_DATA/PRF.DB unless you have invoked PRF with the -NDB option (described
below). If PRF locates a configuration file, it executes the options
contained in the file to configure the current session. Finally, it proceeds
to process any options on the command line or in the interactive session.
A menu-based version of the PRF command is also available. Type HELP PRFD for
more information.
ARGUMENTS
pathname
(optional) Specify the file to be printed. Multiple pathnames and
pathname wildcarding are permitted.
Default if omitted: read standard input.
OPTIONS
The following options may appear on the Shell command line or in PRF
interactive mode as noted below. In addition, you may place one or more
options in a configuration file (see -CONFIG). In that case, create the file
with one option per line without the prepended hyphens (-). See Example 3
below.
If no options are specified, the file(s) are printed using ASCII carriage
control, with pagination enabled, on the default printer (as established by
PRSVR).
___ _________ _______ _____ __ ___ ____ _____
The following options apply to all file types.
-INTER[ACTIVE]
Enter interactive mode.
-COP[IES] n Print multiple copies of the file, where 'n' is the
requested number of copies. If -COP[IES] is specified, 'n'
is required. If this option is omitted, one copy is
printed by default.
-PR[INTER] name
Specify the printer 'name' for printing the file. This
option is useful only if more than one printer is in use on
the network, or if a printer has been assigned a
nonstandard name with the "PRINTER_NAME" configuration
directive in the PRSVR command. If you omit this option,
PRF uses the default printer name, "P". Note that "P" is
also the default printer name used by the PRINT_SERVER.
-S[ITE] entry_dir
Specify print queue (/SYS/PRINT) on alternate node by
giving that node's entry directory name. This option allows
you to maintain more than one printer queue directory. You
may want to maintain separate queues for different
organizations, or you may want two queues to provide
redundancy in case of node failure.
-USER[_NAME] name
Specify user name that will appear on the banner page of
the printed file. The alarm facility of PRF also uses this
name to determine who should be notified when printing is
complete (see -SIG below). This means that this name must
be a valid login name (unless you don't care about sending
an alarm). If this option is omitted, the current login
name is used.
-SIG[NAL] ALARM|OFF
Request an alarm server signal when the file has finished
printing. The default is OFF.
-BAN[NER] [ON|OFF]
Enable/disable banner page. The default is specified in
the PRSVR configuration file. If neither ON nor OFF is
specified, ON is assumed.
-CONFIG[_FILE] [pathname]
Specify a file containing further PRF options, one per
line. Do not use prepended hyphens (-) with the option
names in the configuration file. If 'pathname' is omitted,
PRF will execute the configuration file ~USER_DATA/PRF.DB.
-NDB Suppress processing of the configuration file.
-TEXT Specify text mode for printing ASCII files. This is the
default print mode.
-PLOT Specify plot mode. Include this option to print bitmap
files created by a graphics metafile (GMF) manager or GPR
or the CPSCR (COPY_SCREEN) command.
-TRANSPARENT Specify that when the file is printed, the records of the
file are to be passed directly to the printer driver
routine with no processing by the PRINT_SERVER.
___ _________ _______ _____ __ ____ _____ ____
The following options apply to text files only.
-NPAG Disable the headers and margins generated by PRF.
-MARGINS [ON|OFF]
Enable/disable margins generated by PRF. The default is
'ON'. If neither ON nor OFF is specified, ON is assumed.
-TOP n Specify page top margin, in inches. The default is a value
specified in the PRSVR configuration file.
-BOT[TOM] n Specify page bottom margin, in inches. The default is a
value specified in the PRSVR configuration file.
-RIGHT n Specify page right margin, in inches. The default is 0
inches.
-LEFT n Specify page left margin, in inches. The default is 0
inches.
-HEADERS [ON|OFF]
Enable/disable page headers and footers generated by PRF.
The default is specified in the PRSVR configuration file.
If neither ON nor OFF is specified, ON is assumed.
-HEAD[_STRING] l-string/c-string/r-string
Specify contents of left, center, and right components of
the page header generated by PRF. Components may be empty
strings. The following special characters return the
values indicated when they appear in the header strings.
@ = escape character
# = current page number with 1 leading and
1 trailing space
% = current date
! = filename
& = filename's last time,date modified
* = insert a space in text string (literal spaces
are not allowed)
Example: -HEAD !/Page#/% will produce a header with the
filename in the left component, the string "Page" followed
by the current page number in the center component, and the
current date in the right component. The default header is
a string specified in the PRSVR configuration file.
-FOOT[_STRING] l-string/c-string/r-string
Specify contents of page footers. The format is the same
as for -HEAD above. There is no default footer.
-FTN [ON|OFF]
Force use of FORTRAN carriage control. The -FTN option
causes the PRINT_SERVER to use FORTRAN forms control even
if the file does not have the FORTRAN carriage control
flag. Use of this option will cause PRF to interpret the
first character of each line as a FORTRAN carriage control
character (and not print it). This can be unfortunate if
the file has ASCII carriage control, so be careful. If
neither ON nor OFF is specified, ON is assumed. The
default state is OFF.
-WRAP [ON|OFF]
Enable/disable automatic line wrapping. When enabled, PRF
will wrap any lines that exceed the right margin onto the
next line. When disabled, PRF truncates lines that exceed
the right margin. If neither ON nor OFF is specified, ON
is assumed.
___ _________ _______ ___ ___ ___ ____ ________ __________ ________ ____ ___
The following options are for use with printers supporting variable font and
_____ _____
pitch sizes.
-PITCH n Set the pitch (characters/inch) at which you wish the
document to be printed. The following pitch settings are
available on the printers indicated.
Printronix 10
Spinwriter 12
Imagen 8.5, 10, 12, 15, 17.1
GE 10, 12, 13.1, 16.7
Versatec 12
Imagewriter 5, 6, 7.5, 8.5, 9, 10, 12, 13.4, 15, 17
-POINT n Set the point size for the font to be used. This is a real
number in units of a point which is 1/72 inch.
-WEIGHT value
Set the weight of the font to be used. This option is only
valid for the GE printer type. Possible values are
'light', 'medium', and 'bold'. The default is 'medium'.
If this option is used with the Imagewriter printer, the
'light' and 'medium' values result in a normal typeface and
the 'bold' value causes the printer to print in its bold
typeface.
-LQ [ON|OFF] Specify that the document is to be printed in 'letter
quality' (ON) as opposed to 'draft' (OFF) mode. This
option is only valid for the GE printer type. If neither
ON nor OFF is specified, ON is assumed. The default state
is OFF.
If this option is given with the Imagewriter printer, the
printer will use its proportionally space pica font when
10 char/inch is specified and it will use its proportionally
spaced elite font when 12 char/inch is specified.
___ _________ _______ _____ __ ____ _____
The following options apply to plot files.
-RES[OLUTION] n
Specify resolution of output plot in dots per inch. If you
specify a resolution not available on the particular
printer, the file is printed at the closest available
resolution. The default resolution is specified in the
PRSVR configuration file.
-WHITE[_SPACE] n
Specify amount of white space (in inches) to appear between
multiple plots in one file. The default is three inches.
-BW[_REV] [ON|OFF]
Enable/disable black and white reversal for bitmaps. If
neither ON nor OFF is specified, ON is assumed. The
default state is OFF.
-MAGN[IFICATION] n
Specify bitmap magnification value. 'n' is an integer in
the range -1 to 16.
-1 selects auto-scaling to magnify the bitmap
to fill the available page space.
0 selects 'one-to-one' scaling between the
display and the printer for GMF bitmaps.
(For GPR bitmaps, this translates to
magnification 1.)
1-16 selects magnification by that amount.
Portions of the magnified bitmap that
exceed the printer page boundaries are
clipped.
The default is 0.
For the Imagewriter printer, the default magnification (0)
results in a one-to-one scaling between each pixel of the
display and the printer for GMF bitmaps (same result as
using a magnification value of 1). This will make the
picture on the printer roughly the same size as the picture
on the display.
This command uses the command line parser, and so also accepts the standard
command options listed in HELP CL.
COMMANDS
COMMANDS
COMMANDS
-INTER
-INTER
Once PRF has been invoked in interactive mode (see -INTER above), it accepts
the following interactive commands at the "PRF> " prompt (in addition to the
options already discussed).
P[RINT] pathname
P[RINT] pathname
P[RINT] pathname Queue the specified file for printing.
Q[UIT]
Q[UIT]
Q[UIT] Quit interactive mode and return to the Shell.
SH[ELL]
SH[ELL]
SH[ELL] Create a shell command line. This command allows you to
issue Shell commands without leaving PRF interactive mode.
When you have finished entering Shell commands, type
CTRL/Z. This will return you to PRF interactive mode.
Your previous PRF option settings remain undisturbed by
the intervening Shell commands.
INIT[IALIZE]
INIT[IALIZE]
INIT[IALIZE] Reset PRF parameters to their default values.
R[EAD] [printer]
R[EAD] [printer]
R[EAD] [printer] List entries in the queue for the specified printer at the
current site (as specified by -S). If 'printer' is
omitted, then the contents of the queue (determined by the
current setting of -PR) are listed.
WD [pathname]
WD [pathname]
WD [pathname] Execute the Shell command WD (WORKING_DIRECTORY) to set or
display the working directory.
GET option
GET option
GET option Display the value of the PRF option specified. Use this
command to show the settings of the various PRF
parameters.
CAN[CEL] [queued_filename]
CAN[CEL] [queued_filename]
CAN[CEL] [queued_filename]
Cancel printing of the specified file at the current site
(as specified by -S). Note that you must specify the
pathname which PRF assigns when the file is queued (which
may differ from the name of your original file). Use the
READ command to display the names of currently queued
files. If the filename is omitted, the last file to be
queued by this process is cancelled. This command is only
effective for files which have not yet physically begun to
print.
EXAMPLES
1. $ prf mary -npag -ftn Queue "mary"; suppress
"//NODE1/MY_DIR/MARY" queued for printing. pagination; force
$ FORTRAN carriage
2. $ prf filex -s //tape
"//NODE1/MY_DIR/TEST_FILE.PAS" queued for printing at site //TAPE.
$ Queue "filex" to the
printer queue on the
node called //tape.
3. Configuration File: the following commands might appear in the default
PRF configuration file ~USER_DATA/PRF.DB.
PR ge
SITE //rye
FOOT %/my_file/&
4. Sample interactive session:
$ PRF -INTER
PRF> get pr
pr = p
PRF> -pr cx
PRF> get pr
pr = cx
PRF> -pitch 20
PRF> print test_file.pas
"//NODE1/MY_DIR/TEST_FILE.PAS" queued for printing.
PRF> q
$
5. Running PRF from an icon:
If you would like to run PRF interactively in a process devoted to it,
you might place the following command in your ~USER_DATA/STARTUP_DM
file:
cp -i -c 'P' /com/prf -inter -n print_file
This will create a PRF process and turn its window into an icon using the
print icon character in (/SYS/DM/FONTS/ICONS). Issue the DM command ICON
to change the icon window into its full-size format.
RELATED TOPICS
More information is available. Type:
- HELP PRFD
for information on the menu-based version of this command.
- HELP PRINTER
for general information about printers supported in a DOMAIN network.
- HELP PRSVR
for details about the Print Server.
End of prf.imagewriter.hlp
echo user1.imagewriter.bld 1>&2
cat >user1.imagewriter.bld <<'End of user1.imagewriter.bld'
#########################################################################################
### ###
### Command file for Compiling and Binding the Apple Imagewriter Print Server ###
### ###
#########################################################################################
von
pas user1.imagewriter.pas -cpu any -optall -opt
bind -b prsvr.user1.imagewriter /com/prsvr user1.imagewriter.bin
voff
End of user1.imagewriter.bld
echo user1.imagewriter.doc 1>&2
cat >user1.imagewriter.doc <<'End of user1.imagewriter.doc'
*******************************************************************************
***** *****
***** USER1.IMAGEWRITER.DOC *****
***** Version 8 *****
***** *****
***** Programming Notes for the Apple Imagewriter Print Server *****
***** *****
***** Copyright (c) 1986 *****
***** David M. Krowitz *****
***** Massachusetts Institute of Technology *****
***** Department of Earth, Atmosheric, and Planetary Sciences *****
*******************************************************************************
The Apple Imagewriter printer
-----------------------------
The Apple Imagewriter printer is a low cost dot-matrix printer sold
by Apple for use with their Apple II and Macintosh personal computers.
We are currently sharing one of these printers between an Apple II c and
an Apollo DN320. The printer has the capability to print full bitmap
graphics printing at a density of 72 by 72 dots per inch - a little less
than the resolution of the Apollo's display. The Imagewriter prints 8
lines of up to 576 columns on each pass of the print-head across the
paper, and it will print text with the print-head moving in either
direction - which speeds the printing process.
Interfacing the Printer with the Apollo
---------------------------------------
We have interfaced our Imagewriter printer to an Apollo DN320 using
a 3-wire RS232-C null modem cable. The wiring of the cable is: pin 2 -
pin 3, pin 3 - pin 2, and pin 7 - pin 7 (ie. cross the data receive and
data transmit wires, and connect the signal ground wire). We are using
the X-ON/X-OFF protocal to control the flow of data between the Apollo
and the printer rather than using the DTR and CTS signals in the RS232-C
cable. The SIO line characteristics necessary to run the printer using
X-ON/X-OFF are set up in the routine USER1_INIT. It is also necessary to
change some of the internal jumpers in the Apple printer in order to use
the 3-wire cable. The jumpers that we change are located on a dip switch
underneath the printer's front cover on the right hand side of the
printer. See the Apple Imagewriter manual for a diagram of the location
of the dip switch. The switches should be set to the X-ON/X-OFF position
(see the manual for the correct position of the switches). Apple
normally ship's the printer with the switches in the position for using
DTR/CTS to control the flow of data between the printer and the
computer. If you wish to share the printer between and Apple computer
and the Apollo you will have to use the DTR/CTS flow control. To do this
you will also have to connect the DTR and CTS lines in the printer
cable, and you will have to edit the USER1_INIT routine to set up the
SIO line to use the CTS_ENABLE option and not use the HOST_SYNCH and
INPUT_SYNC option.
Description of the Print Server Routines
----------------------------------------
The Imagewriter print server program consists of six main
subroutines (procedures) which are compiled and then bound to the
standard print server program (/COM/PRSVR) supplied by Apollo. The
subroutines are: USER1_INIT, USER1_WRITE, USER1_FLUSH, USER1_CLOSE,
USER1_SET_MODE, and USER1_RETURN_INFO. Section 6.5 of The DOMAIN System
Administrator's Guide gives a general description of the standard print
server supplied by Apollo and the steps needed to generate a print
server for a printer other than those supported by Apollo. The arguments
to the user-supplied subroutines and the format of the data passed to
the subroutines are defined in the Apollo supplied insert files
/SYS/INS/PRSVR.INS.PAS or /SYS/INS/PRSVR.INS.C which, while defining the
options and data types doesn't really tell you what these various
options are supposed to do. To get that information, you either have to
call Apollo or you just have to play with the print server for awhile
and see how it responds to your poking and prying. Unfortunately for
those of you who program in Fortran, there is no insert file for that
language - you just have to learn Pascal.
The USER1_INIT subroutine is called once by the print server when it
starts up. The subroutine is given the line number of the SIO line to
which the printer is connected and the baud rate of that SIO line. Both
of these numbers are read from the printer configuration file
(IMAGEWRITER.CONFIG) by the print server at startup time. The
USER1_INIT subroutine opens the specified SIO line for stream output and
then sets the necessary SIO line characteristics. These include the use
of X-ON/X-OFF by both the Apollo node and the printer (input_sync and
host_sync), turning off the echoing of characters which the printer may
send to the host (something which is never really done except for X-ON
and X-OFF), disabling the quit character on the SIO line (so if the
printer accidentally glitches it can't kill the print server process),
and the parity, number of bits per character, and number of stop bits of
the characters being transmitted. After defining the SIO line for the
printer, USER1_INIT also initializes several strings of control
characters for the printer, resets various page, line, and graphics
buffer counters. Finally, USER1_INIT sends the printer-init command to
the Imagewriter to make sure the printer is correctly initialized. Note
that the printer-init command also sets the top-of-page to the current
position of the paper, so the paper should be correctly position in the
printer before starting the print server.
The USER1_WRITE subroutine does most of the work of the print
server. This subroutine is called from the print server to perform the
actual output of the data to the Imagewriter printer. The subroutine is
given a buffer of up to 2048 characters and a buffer length. In
practice, I have never seen the buffer length exceed 256 bytes. The
USER1_WRITE subroutine checks the current printer output mode and then
outputs the contents of the buffer according to the mode. The mode is
set by the print server calling the USER1_SET_MODE subroutine prior to
the first call to USER1_WRITE for the current output file. There are
three possible output modes: 'text', 'transparent', and 'plot'.
If the current output mode is 'text' (ie. a PRF command with no
switches), the print server keeps track of the current page and line
counts and prints a page header and and page number at the top of each
page. The print server calls USER1_WRITE one time for each line printed
and simply inserts an extra call to USER1_WRITE at the top of each page
to print the page header and page number. All that USER1_WRITE has to
do in text mode is to dump the buffer to the printer, but we also check
each buffer for form-feed characters and keep a page count and a line
count so that we could do our own (possibly fancier) page headings if we
wanted to do so.
If the current output mode is 'transparent' (ie. a PRF -TRANSPARENT
command), the print server sends the contents of the output file to the
printer with no modifications. USER1_WRITE is called once for each line
in the file (same as with 'text' mode), but no page headers are inserted
into the output stream. In this output mode USER1_WRITE does nothing
except to dump the buffer to the Imagewriter's output stream.
If the current output mode is 'plot' (ie. a PRF -PLOT command), the print
server checks that the output file is a GMF bitmap file, calls USER1_SET_MODE
to set the size of the bitmap, and then calls USER1_WRITE once for each
horizontal scan line in the bitmap. The print server will not attempt to
print bitmap files unless the PLOT_MODE switch in the printer's
configuration file (ie. IMAGEWRITER.CONFIG -- which is specified on the
command line which started the print server) is set to ON. The print
server will try to automatically scale the bitmap so that it is roughly
the same size on the printed page as it is on the display screen of the
Apollo. (I am assuming that the bitmap was created from a dump from the
screen. Actually, the print server checks the bits-per-inch at which the
bitmap was created and compares that against the bit-per-inch of the
printer and then tries to scale the bitmap to the closest integer
factor. The bits-per-inch of the printer is defined in the
USER1_RETURN_INFO subroutine. I believe that you can define the
bit-per-inch at which the bitmap is created through one of the GPR or
GMR calls. I know that you can create bitmaps without displaying them on
the screen.) Since the Imagewriter printer's resolution (72 bpi) is
roughly the same as the Apollo's display screen, the print server will
not do any scaling of the bitmap. The -MAGNIFICATION option of the PRF
command can be used to control the scaling of the bitmap by the print
server. The default value (0) will cause the print server to try to
scale the bitmap to the same size that it was on the screen (this
results in a two to one scaling on the printer). In this case, the print
server will simply tell the USER1_SET_MODE routine that the bitmap is
twice the size of the bitmap on the screen and it will scale the bitmap
before passing the data to the USER1_WRITE routine for printing.
Since the Imagewriter prints 8 horizontal scan line on each pass,
the USER1_WRITE subroutine buffers up 8 complete scan lines, padding
short lines with zeros, before dumping the buffer to the printer. Lines
which are longer than the maximum printable by the Imagewriter (576 dots
across the page) are truncated to the maximum length which can be
printed. If the user has requested the bitmap to be inverted (ie. black
and white reversed), then each byte of the scan line is inverted as it
is buffered. The bits in each of the horizontal scan lines sent to
USER1_WRITE by the print server are packed 8 to each byte, the high
order bit of the byte being the leftmost bit on the scan line. Since the
Imagewriter printer (along with most other dot matrix printers) wants to
print one complete vertical column of bits at a time, it is necessary to
repack the bits in the scan lines which have been buffered before they
can be sent to the printer. USER1_WRITE calls the WRITE_PLOT_BUFFER
routine to repack the bits and output the repacked buffer to the
printer. The WRITE_PLOT_BUFFER subroutine also attempts to speed up the
output process by stripping zero bytes off of the end of the buffer to
avoid the expense of having to repack and transmit these bytes.
The USER1_SET_MODE subroutine is called by the printer server prior
to the output of each file being printed to set the proper printer
output mode and to such things as the bitmap size (for plot mode files).
The print server may also call USER1_SET_MODE after the end of an output
file to reset the printer mode or to change the printer mode to 'text'
so it can output a top-of-page command (ie. a form feed) after finishing
the printing of a bitmap. Note that we can not use the Imagewriter's
printer-init command to reset the printer's mode to the default text
mode. This is because the printer-init command resets the printer's
top-of-page to the current paper position, and the print server may call
USER1_SET_MODE at any point on the page.
The USER1_FLUSH subroutine is called once at the end of each file
output by the print server and also in between changing printer output
modes. This routine checks if the printer is 'plot' and also checks if
there is a partially full buffer of bitmap data. If this is the case,
USER1_FLUSH will call USER1_WRITE with a dummy output buffer to force
the output of the final buffer of bitmap data. USER1_FLUSH then resets
all of the page, line, and buffer counters used during the output of the
file.
The USER1_CLOSE subroutine is only called when the print server is
stopping permanently (as opposed to waiting between files). All that it
does is to close the printer's output stream.
Changes Since Version 6
-----------------------
Version 6 of the Imagewriter USER1 routines is compatible with the
AEGIS SR9.0 version of PRSVR. It should also be backwards compatible
with the SR8.0 version of the print server.
The buffer repacking algorithm for printing GMF bitmap files has
been improved. The new algorithm is faster and it also correctly handles
bitmaps which are wider than the page (the bitmap is truncated to the
width of the page).
The printing of GMF bitmap files is now done with unidirectional
printing (left to right on all lines) in order to get vertical line
segments to line up better.
If the -LQ option of the PRF command (letter quality printing) is
used the printer will now switch to printing with the proportionally
spaced pica font (if the character pitch is 10 char/in) or the
proportionally spaced elite font (if the character pitch is 12 char/in).
If the -WEIGHT option of the PRF command is used with the 'bold'
value, the file will be printed with the printer's boldface option in
order to make the output darker. If the 'light' or 'medium' values are
used with the -WEIGHT option then the file is printed with the normal
typeface. The default value of the weight option is 'medium'.
The -PITCH option of the PRF command can now be used to select
printing in 5.0, 6.0, 7.5, 8.5, 9, 10, 12, 13.4, 15, or 17 characters
per inch. The default character pitch is 10 characters per inch.
The -MAGNIFICATION option of the PRF command can now be used to
control the scaling of bitmaps printed on the Imagewriter. The default
magnification value (0) causes the print server to try to make the
bitmap the same size on the printer as it was on the screen of the
Apollo. Since the Imagewriter's 72 dot per inch resolution is
approximately the same as the Apollo's screen the print server will
print the bitmap with a 1 to 1 scaling. Giving the PRF command a
magnification value of 1 will cause the bitmap to be printed without any
scaling on the printer, a value of 2 will cause the bitmap to be doubled
in size, a value of 3 will cause the bitmap to be tripled in size, etc.
The USER1_INIT routine now reports any errors which it encounters
while attempting to set up the SIO line for the printer. Seperate error
messages are generated for each SIO line parameter to aid in locating
any problems with the SIO line.
Changes Since Version 7
-----------------------
The -BW_REV option of the PRF command can now be used to invert a
GMF bitmap before it is printed. Areas of the bitmap which are normally
white will be printed as black and vice versa.
The problem which caused 'glitches' in the printing of certain
bitmap files has been fixed. On previous versions of the software,
certain bitmap files would have lines which would be shifted over by
a couple of dots in the middle of the line. This was caused by the
SIO system inserting a extra character in the output after a
line feed character was sent to the printer. This has been fixed by
using the new SR9.0 SIO_$NO_NL option when setting up the SIO line
characteristics.
Files Needed to Build the Print Server
--------------------------------------
The files which are provided for the Apple Imagewriter print server are:
USER1.IMAGEWRITER.DOC - This file.
USER1.IMAGEWRITER.DOC.INSTALL - Notes on how to install the print server.
PRF.IMAGEWRITER.HLP - An edited version of the standard Apollo
help file for the PRF command (/SYS/HELP/PRF.HLP)
with notes included for the Imagewriter printer.
USER1.IMAGEWRITER.PAS - The Pascal sources for the print server.
USER1.INS.PAS - An edited version of the standard Apollo
insert file, /SYS/INS/PRSVR.INS.PAS, which is
used by USER1.IMAGEWRITER.PAS to define the data
types and structures used by the print server.
USER1.IMAGEWRITER.BLD - A shell script file for compiling the USER1
routines (and their subroutines) and binding
them with the Apollo supplied print server.
IMAGEWRITER.CONFIG - The configuration file for the Imagewriter printer
to be given as an argument to the print server
when it is started.
PRSVR.USER1.IMAGEWRITER - A ready to run Imagewriter print server. Just in
case you don't have a Pascal compiler. This is
the file which is produced by USER1.BLD.
You will also need the following standard Apollo-supplied files:
/SYS/INS/BASE.INS.PAS - These are all standard insert files which
/SYS/INS/SIO.INS.PAS are used by USER1.IMAGEWRITER.PAS.
/SYS/INS/STREAMS.INS.PAS
/SYS/INS/PGM.INS.PAS
/COM/PRSVR - The standard Apollo print server which must
be bound with the Imagewriter routines to produce
a working print server. Used in USER1.BLD to
produce PRSVR.USER1.IMAGEWRITER.
Bugs, Questions, and Improvements
---------------------------------
If you find a bugs in the print server, have questions on how to
install or use it, or have a good idea for improving the program please
feel free to contact me at the address below.
David M. Krowitz
MIT dept. of Earth, Atmospheric, and Planetary Sciences
Room 54-527
Cambridge, MA 02139
(617) 253-6180
ARPA net mailing adress: DAVID@MIT-MC.ARPA
or
KROWITZ%MIT-MARIE@MIT-MC.ARPA
End of user1.imagewriter.doc
echo user1.imagewriter.doc.install 1>&2
cat >user1.imagewriter.doc.install <<'End of user1.imagewriter.doc.install'
*******************************************************************************
***** *****
***** USER1.IMAGEWRITER.DOC.INSTALL *****
***** Version 7 *****
***** Installing the Apple Imagewriter Print Server *****
***** *****
***** Copyright (c) 1986 *****
***** David M. Krowitz *****
***** Massachusetts Institute of Technology *****
***** Department of Earth, Atmosheric, and Planetary Sciences *****
*******************************************************************************
Read the general installation and documentation notes in USER1.IMAGEWRITER.DOC
if you have not already done so. Then use the shell script file
USER1.IMAGEWRITER.BLD to compile the Apple Imagewriter device-driver routines
and to bind them to the standard Apollo printer server located in /COM/PRSVR.
This will create the Apple Imagewriter version of the print server
(PRSVR.USER1.IMAGEWRITER) in your working directory. Then edit the print server
configuration file (IMAGEWRITER.CONFIG) and make sure it contains the proper
SIO line number and baud rate for your installation. Next copy the new print
server (PRSVR.USER1.IMAGEWRITER) and the print server configuration file
(IMAGEWRITER.CONFIG) to the system directory from which you normally run the
print server on your system. /COM or /SYS/NODE_DATA are two common directories
which we use. You can then run the print server using the command:
/COM/PRSVR.USER1.IMAGEWRITER /COM/IMAGEWRITER.CONFIG
(assuming the files are stored in /COM). This will run the server in the current
window. The server will be stopped when you log out. If you want to run the print
server automatically when the system is brought up, add the following command line
to your installation's startup file in /SYS/NODE_DATA:
###
### To startup user-defined print server for the Apple Imagewriter printer
###
CPS /COM/PRSVR.USER1.IMAGEWRITER -N PRINT_SERVER /COM/IMAGEWRITER.CONFIG
(again, assuming the files are kept in /COM). This will run the print server
automatically when the node is brought up and will give it the process a server
status so that you can logout and leave the print server running for other users
on the network. Apollo's standard print server (and the Imagewriter version) looks
for files to be printed in the /SYS/PRINT directory of the node on which the print
server is running. If you want files from other nodes on the network to be
automatically printed on the Toshiba you should delete the /SYS/PRINT directories
on those nodes and replace them with links to the /SYS/PRINT directory on the
node running the print server. Otherwise, users can use the command:
PRF -S //NODE_NAME
to have the PRF command send the file to the node which has the printer attached
to it.
More information on the installation and use of print servers can be found in
The Domain System Administrator's Guide, section 6.5 (Peripheral Servers).
End of user1.imagewriter.doc.install
echo user1.imagewriter.pas 1>&2
cat >user1.imagewriter.pas <<'End of user1.imagewriter.pas'
{*********************************************************************************
***** *****
***** USER1.IMAGEWRITER.PAS *****
***** *****
***** Serial Printer Driver for the Apple Imagewriter dot-matrix printer *****
***** Version 8 *****
***** David M. Krowitz February 10, 1986. *****
***** *****
***** Copyright (c) 1986 *****
***** David M. Krowitz *****
***** Massachusetts Institute of Technology *****
***** Department of Earth, Atmosheric, and Planetary Sciences *****
*********************************************************************************
}
MODULE USER1_IMAGEWRITER;
%NOLIST;
%INSERT '/sys/ins/base.ins.pas';
%INSERT '/sys/ins/sio.ins.pas';
%INSERT '/sys/ins/streams.ins.pas';
%INSERT '/sys/ins/pgm.ins.pas';
%INSERT 'user1.ins.pas';
%LIST;
CONST
{Definitions of standard ascii control characters}
nul = chr(0); {null character}
bs = chr(8); {backspace (control-H)}
tab = chr(9); {tab (control-I)}
lf = chr(10); {line feed (control-J)}
vt = chr(11); {vertical tab (control-K)}
ff = chr(12); {form feed (control-L)}
cr = chr(13); {carriage return (control-M)}
ctrl_n = chr(14); {control-N}
ctrl_o = chr(15); {control-O}
sub = chr(26); {sub (control-Z)}
esc = chr(27); {escape}
rs = chr(30); {rs}
{Define maximum bitmap size which can be printed}
max_bitmap_size = 576; {maximum number of pixels across the page}
max_buffer_size = 72; {maximum buffer size to hold bitmap (576/8)}
TYPE
str1_t = packed array[1..1] of char;
str2_t = packed array[1..2] of char;
str3_t = packed array[1..3] of char;
str4_t = packed array[1..4] of char;
str5_t = packed array[1..5] of char;
str6_t = packed array[1..6] of char;
str7_t = packed array[1..7] of char;
str8_t = packed array[1..8] of char;
str9_t = packed array[1..9] of char;
bitmap_buffer_t = packed array[1..8,1..max_buffer_size] of char;
print_buffer_t = packed array[1..max_bitmap_size] of char;
VAR
{Definitions of control sequences for the Apple Imagewriter printer}
init_printer: str2_t; {initialize printer characteristics}
image_data: str6_t; {start 8 pin by nnnn column bit map image transfer}
text_vert_spacing: str2_t; {set vertical spacing to 1/6" for default text size}
plot_vert_spacing: str4_t; {set vertical spacing to 16/144" for bitmap graphics}
text_horiz_spacing: str2_t; {set horizontal spacing to 1/10" for default text size}
plot_horiz_spacing: str2_t; {set horizontal spacing to 1/9" for 72 bpi bitmap graphics}
uni_directional: str2_t; {set uni-directional printing mode for bitmap graphics}
bi_directional: str2_t; {set bi-directional printing mode for text}
start_boldface: str2_t; {start printing in boldface}
stop_boldface: str2_t; {stop printing in boldface}
start_double: str1_t; {start printing double width characters}
stop_double: str1_t; {stop printing double width characters}
font_extended: str2_t; {Use extended font (9 chars/in)}
font_pica: str2_t; {Use pica font (10 chars/in)}
font_elite: str2_t; {Use elite font (12 chars/in)}
font_pica_p: str2_t; {Use pica proportional font (??? chars/in)}
font_elite_p: str2_t; {Use elite proportional font (??? chars/in)}
font_semicond: str2_t; {Use semi-condensed font (13.4 chars/in)}
font_cond: str2_t; {Use condensed font (15 chars/in)}
font_ultracond: str2_t; {Use ultra-condensed font (17 chars/in)}
crlf: str2_t; {carriage-return, line-feed sequence}
{Defintions of global variables}
x_bitmap_size: pinteger; {x dimension of GMR bit map being printed}
y_bitmap_size: pinteger; {y dimension of GMR bit map being printed}
scale_factor: pinteger; {factor by which bitmap has been scaled
up by top-level routines}
bitmap_buffer: bitmap_buffer_t; {buffer of 8 lines of 576 bits to hold
data for one pass of the Apple printer's
print-head}
bcount: pinteger; {count of number of buffers of GMR data}
invert_image: boolean; {TRUE if user requested black/white reversed for bitmap}
plot_flag: boolean; {TRUE if we have been printing a bitmap}
trans_flag: boolean; {TRUE if we have been printing in transparent mode}
printer_mode: pr_$data_format_t; {printer mode: text, transparent, or plot}
server_ptr: server_db_ptr_t; {pointer to database set up by server}
driver_ptr: driver_db_ptr_t; {pointer to database of Toshiba's abilities}
stream_id: stream_$id_t; {stream id returned by STREAM_$OPEN}
status: status_$t; {status returned by SIO and STREAM calls}
seek_key: stream_$SK_t; {seek_key returned by STREAM calls}
testmask: array[1..8] of integer; {Constants for testing bits in a byte}
setmask: array[1..8] of integer; {Constants for setting bits in a byte}
PROCEDURE USER1_INIT (
IN sio_line: integer;
IN sio_speed: UNIV sio_$value_t
);
VAR
sioname: array[1..3] of str9_t; {names of SIO lines for STREAM_$OPEN call}
i,j: pinteger; {counters}
BEGIN
{Open I/O stream and set SIO line characteristics}
sioname[1] := '/dev/sio1';
sioname[2] := '/dev/sio2';
sioname[3] := '/dev/sio3';
stream_$open (sioname[sio_line],9,stream_$append,stream_$no_conc_write,
stream_id,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not open output stream: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$speed,sio_speed,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$SPEED: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$no_nl,true,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$NO_NL on: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$nlc_delay,0,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$NLC_DELAY to 0: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$input_sync,true,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$INPUT_SYNC on: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$host_sync,true,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$HOST_SYNC on: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$no_echo,true,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$NO_ECHO on: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$cts_enable,false,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$CTS_ENABLE off: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$quit_enable,false,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$QUIT_ENABLE off: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$parity,sio_$no_parity,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$PARITY to none: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$bits_per_char,sio_$8bpc,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$BPC to 8 bits/char: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
sio_$control (stream_id,sio_$stop_bits,sio_$stop_1,status);
IF (status.fail = TRUE) THEN BEGIN
WRITELN ('**** USER1_INIT: Error - could not set SIO_$STOP to 1 stop bit: ',
sioname[sio_line],' ****');
PGM_$EXIT;
END;
{Initialize strings of control characters for printer}
init_printer[1] := esc;
init_printer[2] := 'c';
image_data[1] := esc;
image_data[2] := 'S';
image_data[3] := '0';
image_data[4] := '0';
image_data[5] := '0';
image_data[6] := '0';
plot_vert_spacing[1] := esc;
plot_vert_spacing[2] := 'T';
plot_vert_spacing[3] := '1';
plot_vert_spacing[4] := '6';
text_vert_spacing[1] := esc;
text_vert_spacing[2] := 'A';
plot_horiz_spacing[1] := esc;
plot_horiz_spacing[2] := 'n';
text_horiz_spacing[1] := esc;
text_horiz_spacing[2] := 'N';
uni_directional[1] := esc;
uni_directional[2] := '>';
bi_directional[1] := esc;
bi_directional[2] := '<';
start_boldface[1] := esc;
start_boldface[2] := '!';
stop_boldface[1] := esc;
stop_boldface[2] := '"';
start_double[1] := ctrl_n;
stop_double[1] := ctrl_o;
font_extended[1] := esc;
font_extended[2] := 'n';
font_pica[1] := esc;
font_pica[2] := 'N';
font_elite[1] := esc;
font_elite[2] := 'E';
font_pica_p[1] := esc;
font_pica_p[2] := 'p';
font_elite_p[1] := esc;
font_elite_p[2] := 'P';
font_semicond[1] := esc;
font_semicond[2] := 'e';
font_cond[1] := esc;
font_cond[2] := 'q';
font_ultracond[1] := esc;
font_ultracond[2] := 'Q';
crlf[1] := cr;
crlf[2] := lf;
{Initialize the graphics output variables}
bcount := 0; {No scan lines of graphics output waiting to be printed}
scale_factor := 1; {Doesn't seem to be used in SR9.0 so must init ourselves for SR8 compatibility}
invert_image := FALSE; {Do normal bitmap printing (not b/w reversed)}
plot_flag := FALSE; {Not printing a bitmap right now}
trans_flag := FALSE; {Not printing in transparent mode, either}
{Initialize bit testing and bit setting masks}
testmask[1] := 16#80;
testmask[2] := 16#40;
testmask[3] := 16#20;
testmask[4] := 16#10;
testmask[5] := 16#08;
testmask[6] := 16#04;
testmask[7] := 16#02;
testmask[8] := 16#01;
setmask[1] := 16#01;
setmask[2] := 16#02;
setmask[3] := 16#04;
setmask[4] := 16#08;
setmask[5] := 16#10;
setmask[6] := 16#20;
setmask[7] := 16#40;
setmask[8] := 16#80;
{Initialize the printer settings}
stream_$put_chr (stream_id,addr(init_printer),2,seek_key,status);
printer_mode := pr_$text;
END; {End of USER1_INIT}
PROCEDURE USER1_WRITE (
IN buffer: UNIV pr_$buf_t;
IN buffer_length: pinteger
);
PROCEDURE USER1_WRITE_TEXT (
IN buffer: UNIV pr_$buf_t;
IN buffer_length: pinteger
);
BEGIN
stream_$put_chr (stream_id,addr(buffer),buffer_length,
seek_key,status);
END; {End of USER1_WRITE_TEXT}
PROCEDURE USER1_WRITE_TRANSPARENT (
IN buffer: UNIV pr_$buf_t;
IN buffer_length: pinteger
);
BEGIN
stream_$put_chr (stream_id,addr(buffer),buffer_length,
seek_key,status);
END; {End of USER1_WRITE_TRANSPARENT}
PROCEDURE WRITE_PLOT_BUFFER (
IN buffer: bitmap_buffer_t;
IN bitmap_length: pinteger
);
VAR
print_buffer: print_buffer_t; {Toshiba output buffer}
print_buffer2: print_buffer_t; {Toshiba output buffer}
buffer_length: pinteger; {length of non-zero data in input buffer}
data_length: pinteger; {length of non-zero data in print_buffer}
i,j,k: pinteger; {index counters}
ii,jj,iii,jjj: pinteger; {buffer subscript variables}
bit_value: pinteger; {value of bit being swapped}
temp1: pinteger; {holds bits being repacked}
temp2: pinteger; {tests bytes to see if repacking needed}
BEGIN
{Find end of the non-zero data in the input buffer.
Don't want to waste time by having to repack a lot of zero
bytes at the end of a line.}
buffer_length := (((bitmap_length-1) div 8) +1);
k := 0;
REPEAT
FOR j := 1 TO 8 DO BEGIN
IF buffer[j,buffer_length] <> chr(0) THEN k := 1;
END;
IF k = 0 THEN buffer_length := buffer_length-1;
UNTIL (k <> 0) OR (buffer_length = 0);
{If the print buffer is all zeroes, then just output a carriage-return
line-feed sequence. Otherwise, repack and print the non-zero portion
of the printer buffer.}
IF buffer_length = 0 THEN BEGIN
stream_$put_chr (stream_id,addr(crlf),2,
seek_key,status);
END
ELSE BEGIN
{Repack the bitmap from 8 horizontal rows of BUFFER_LENGTH*8
bits (8 bits per byte) into BUFFER_LENGTH*8 columns of 1 byte
each (8 bits per byte).}
FOR i := 1 TO buffer_length DO BEGIN
ii := (i-1)*8;
{Check if 6 byte high by 8 bit wide section of bitmap
is all zeros. If so, then we don't need to repack the
bits in this section, we just set the output buffer
to the correct constants. If the area is all ones, we
also do not have to repack the bitmap, we just set
the output buffer to a different constant.}
temp2 := 0;
FOR k := 1 TO 8 DO BEGIN
temp2 := temp2+ord(buffer[k,i]);
END;
IF (temp2 = 0) THEN BEGIN
FOR iii := 1 TO 8 DO BEGIN {Section is all zeros - don't need to repack}
print_buffer[ii+iii] := chr(0);
END;
END
ELSE IF (temp2 <> 8*16#FF) THEN BEGIN
FOR iii := 1 TO 8 DO BEGIN
temp1 := 0; {Init the byte}
FOR k := 1 TO 8 DO BEGIN {Repack eight bits into byte}
bit_value := (ord(buffer[k,i])&testmask[iii]);
IF bit_value <> 0 THEN BEGIN
temp1 := temp1!setmask[k];
END;
END;
print_buffer[ii+iii] := chr(temp1); {Put byte in output buffer}
END;
END
ELSE BEGIN
FOR iii := 1 TO 8 DO BEGIN {Section is all ones - don't need to repack}
print_buffer[ii+iii] := chr(16#FF);
END;
END;
END;
{Find end of the non-zero data in the printer buffer.
Don't want to waste time by having to transmit a lot of zeroes
at the end of a line.}
IF buffer_length*8 < bitmap_length THEN BEGIN
data_length := buffer_length*8;
END
ELSE BEGIN
data_length := bitmap_length;
END;
k := 0;
REPEAT
IF print_buffer[data_length] <> chr(0) THEN k := 1;
IF k = 0 THEN data_length := data_length-1;
UNTIL (k <> 0) OR (data_length = 0);
{Set up the bitmap image data transfer header and print the buffer.}
image_data[3] := chr(ord('0')+((data_length mod 10000) div 1000));
image_data[4] := chr(ord('0')+((data_length mod 1000) div 100));
image_data[5] := chr(ord('0')+((data_length mod 100) div 10));
image_data[6] := chr(ord('0')+((data_length mod 10) div 1));
stream_$put_chr (stream_id,addr(image_data),6,
seek_key,status);
stream_$put_chr (stream_id,addr(print_buffer),data_length,
seek_key,status);
stream_$put_chr (stream_id,addr(crlf),2,seek_key,status);
END;
END; {End of WRITE_PLOT_BUFFER}
PROCEDURE USER1_WRITE_PLOT (
IN buffer: UNIV pr_$buf_t;
IN buffer_length: pinteger
);
VAR
i: integer; {counter}
j: integer; {size of bitmap buffer in bytes}
k: integer; {size of bitmap in pixels across the page}
BEGIN
{Check that BUFFER_LENGTH does not exceed the maximum buffer size
and that X_BITMAP_SIZE*SCALE_FACTOR does not exceed the maximum
printable bitmap size.}
IF buffer_length <= max_buffer_size THEN
j := buffer_length
ELSE
j := max_buffer_size;
IF x_bitmap_size*scale_factor <= max_bitmap_size THEN
k := x_bitmap_size*scale_factor
ELSE
k := max_bitmap_size;
{Buffer up 8 lines by X_BITMAP_SIZE*SCALE_FACTOR columns of the
bitmap and then dump them out to the printer. Pad short lines with
zeros. Invert the buffer if the user requested black/white reversal
for printing bitmap.}
bcount := bcount+1;
i:= 0;
IF (invert_image = FALSE) THEN BEGIN
WHILE i < j DO BEGIN
i := i+1;
bitmap_buffer[bcount,i] := buffer[i];
END;
WHILE i < (((k-1) div 8)+1) DO BEGIN
i := i+1;
bitmap_buffer[bcount,i] := chr(0);
END;
END
ELSE BEGIN
WHILE i < j DO BEGIN
i := i+1;
bitmap_buffer[bcount,i] := chr(~ord(buffer[i]));
END;
WHILE i < (((k-1) div 8)+1) DO BEGIN
i := i+1;
bitmap_buffer[bcount,i] := chr(16#FF);
END;
END;
IF bcount = 8 THEN BEGIN
write_plot_buffer (bitmap_buffer,k);
bcount := 0;
END;
END; {End of USER1_WRITE_PLOT}
BEGIN {Beginning of actual USER1_WRITE code}
{Determine printer mode and dispatch for output of buffer}
CASE printer_mode OF
pr_$text: user1_write_text (buffer,buffer_length);
pr_$transparent: user1_write_transparent (buffer,buffer_length);
pr_$plot: user1_write_plot (buffer,buffer_length);
END;
END; {End of USER1_WRITE}
PROCEDURE USER1_SET_MODE (
IN mode: pr_$set_op_t;
IN data: pr_$data_rec_t
);
BEGIN
CASE mode OF
pr_$font_weight: IF (data.font_weight = pr_$bold) THEN
stream_$put_chr (stream_id,addr(start_boldface),2,seek_key,status)
ELSE
stream_$put_chr (stream_id,addr(stop_boldface),2,seek_key,status);
pr_$font_size: ;
pr_$text_precision: ;
pr_$data_format: BEGIN
printer_mode := data.data_format;
CASE printer_mode OF
pr_$text: BEGIN
stream_$put_chr (stream_id,addr(stop_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(text_vert_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(text_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(bi_directional),2,seek_key,status);
END;
pr_$transparent: BEGIN
stream_$put_chr (stream_id,addr(stop_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(text_vert_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(text_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(bi_directional),2,seek_key,status);
trans_flag := TRUE;
END;
pr_$plot: BEGIN
stream_$put_chr (stream_id,addr(stop_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(plot_vert_spacing),4,seek_key,status);
stream_$put_chr (stream_id,addr(plot_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(uni_directional),2,seek_key,status);
plot_flag := TRUE;
END;
END;
END;
pr_$pitch: CASE ROUND(data.pitch*10.0) OF
50: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_pica),2,seek_key,status);
END;
60: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_elite),2,seek_key,status);
END;
75: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_cond),2,seek_key,status);
END;
85: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_ultracond),2,seek_key,status);
END;
90: stream_$put_chr (stream_id,addr(font_extended),2,seek_key,status);
100: stream_$put_chr (stream_id,addr(font_pica),2,seek_key,status);
120: stream_$put_chr (stream_id,addr(font_elite),2,seek_key,status);
134: stream_$put_chr (stream_id,addr(font_semicond),2,seek_key,status);
150: stream_$put_chr (stream_id,addr(font_cond),2,seek_key,status);
170: stream_$put_chr (stream_id,addr(font_ultracond),2,seek_key,status);
END;
pr_$x_dimension: x_bitmap_size := data.x_dimension;
pr_$y_dimension: y_bitmap_size := data.y_dimension;
pr_$rep_factor: scale_factor := data.rep_factor;
pr_$config: ;
pr_$copies: ;
pr_$server_db: BEGIN
server_ptr := data.server_db_ptr;
printer_mode := server_ptr^.print_mode;
IF (server_ptr^.weight = pr_$bold) THEN
stream_$put_chr (stream_id,addr(start_boldface),2,seek_key,status)
ELSE
stream_$put_chr (stream_id,addr(stop_boldface),2,seek_key,status);
IF server_ptr^.bw_rev = TRUE THEN
invert_image := TRUE
ELSE
invert_image := FALSE;
CASE printer_mode OF
pr_$text: BEGIN
stream_$put_chr (stream_id,addr(text_vert_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(text_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(bi_directional),2,seek_key,status);
CASE ROUND(server_ptr^.cpi*10.0) OF
50: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_pica),2,seek_key,status);
END;
60: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_elite),2,seek_key,status);
END;
75: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_cond),2,seek_key,status);
END;
85: BEGIN
stream_$put_chr (stream_id,addr(start_double),1,seek_key,status);
stream_$put_chr (stream_id,addr(font_ultracond),2,seek_key,status);
END;
90: stream_$put_chr (stream_id,addr(font_extended),2,seek_key,status);
100: IF (server_ptr^.lq = FALSE) THEN
stream_$put_chr (stream_id,addr(font_pica),2,seek_key,status)
ELSE
stream_$put_chr (stream_id,addr(font_pica_p),2,seek_key,status);
120: IF (server_ptr^.lq = FALSE) THEN
stream_$put_chr (stream_id,addr(font_elite),2,seek_key,status)
ELSE
stream_$put_chr (stream_id,addr(font_elite_p),2,seek_key,status);
134: stream_$put_chr (stream_id,addr(font_semicond),2,seek_key,status);
150: stream_$put_chr (stream_id,addr(font_cond),2,seek_key,status);
170: stream_$put_chr (stream_id,addr(font_ultracond),2,seek_key,status);
END;
END;
pr_$transparent: BEGIN
stream_$put_chr (stream_id,addr(text_vert_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(text_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(bi_directional),2,seek_key,status);
trans_flag := TRUE;
END;
pr_$plot: BEGIN
x_bitmap_size := server_ptr^.bitmap_size.x;
y_bitmap_size := server_ptr^.bitmap_size.y;
stream_$put_chr (stream_id,addr(plot_vert_spacing),4,seek_key,status);
stream_$put_chr (stream_id,addr(plot_horiz_spacing),2,seek_key,status);
stream_$put_chr (stream_id,addr(uni_directional),2,seek_key,status);
plot_flag := TRUE;
END;
END;
END;
END;
END; {End of USER1_SET_MODE}
PROCEDURE USER1_RETURN_INFO (
IN query: pr_$inq_op_t;
OUT data: pr_$data_rec_t
);
BEGIN
CASE query OF
pr_$bpi: BEGIN
data.bpi.x := 72;
data.bpi.y := 72;
END;
pr_$rep_ability: data.rep_ability := false;
pr_$driver_db: BEGIN
driver_ptr := data.driver_db_ptr;
WITH driver_ptr^ DO BEGIN
valid := TRUE;
copies := FALSE;
cpi[1] := 10.0; {Put pica font first so it will be default}
cpi[2] := 5.0; {Put the double-width fonts next}
cpi[3] := 6.0;
cpi[4] := 7.5;
cpi[5] := 8.5;
cpi[5] := 9.0; {Put the normal width fonts next}
cpi[7] := 12.0;
cpi[8] := 13.4; {Put the compressed fonts next}
cpi[9] := 15.0;
cpi[10] := 17.0;
lpi[1] := 6;
resolution[1] := 72;
res_min := 72;
res_max := 72;
color_format := none;
bw_rev := TRUE;
END;
END;
END;
END; {End of USER1_RETURN_INFO}
PROCEDURE USER1_FLUSH;
VAR
temp: pr_$data_format_t; {printer mode: text, transparent, or plot}
dummy: pr_$buf_t; {dummy buffer}
BEGIN
{If printer is in plot mode then make sure that the last buffer
of bitmap data is filled out to 8 lines and printed. Then reset
all of the counters.}
{If the printer mode is TRANSPARENT or PLOT, then we need to eject
the page from the printer. Under SR8, the PRSVR would change the
printer mode to TEXT and issue a form feed after the end of a
PLOT or TRANSPARENT mode output. Under SR9, we have to do the
page ejection ourselves.}
IF (bcount <> 0) THEN BEGIN
temp := printer_mode;
printer_mode := pr_$plot;
REPEAT
user1_write(dummy,0);
UNTIL bcount = 0;
printer_mode := temp;
END;
IF (plot_flag = TRUE) OR (trans_flag = TRUE) THEN BEGIN
stream_$put_chr (stream_id,addr(ff),1,seek_key,status);
END;
plot_flag := FALSE;
trans_flag := FALSE;
END; {End of USER1_FLUSH}
PROCEDURE USER1_CLOSE;
BEGIN
stream_$close (stream_id,status);
END; {End of USER1_CLOSE}
{***** End of module USER1_IMAGEWRITER *****}
End of user1.imagewriter.pas
echo user1.ins.pas 1>&2
cat >user1.ins.pas <<'End of user1.ins.pas'
{ PRSVR.INS.PAS, us/com/print, gtr, 05/09/83
Print server routines and associated data types which
are exported for user supplied device drivers.
Changes:
03/30/85 jjm updated for sr9 release
04/09/84 jjm update to sr8
05/09/83 gtr original coding
--------------------------------------------------------------------------
| THE FOLLOWING PROGRAMS ARE THE SOLE PROPERTY OF APOLLO COMPUTER INC. |
| AND CONTAIN ITS PROPRIETARY AND CONFIDENTIAL INFORMATION. |
--------------------------------------------------------------------------
}
CONST pr_$bufsize = 2048 ;
TYPE pr_$buf_t = ARRAY [1..pr_$bufsize] OF char ;
pr_$t = (pr_$user1, pr_$user2, pr_$user3, pr_$user4) ;
pr_$set_op_t = (
pr_$font_weight,
pr_$font_size,
pr_$text_precision,
pr_$data_format,
pr_$pitch,
pr_$y_dimension,
pr_$x_dimension,
pr_$rep_factor,
pr_$config,
pr_$copies,
pr_$server_db
);
pr_$inq_op_t = (
pr_$bpi,
pr_$rep_ability,
pr_$driver_db
);
pr_$font_weight_t = (
pr_$light,
pr_$medium,
pr_$bold
);
pr_$text_precision_t = (
pr_$draft,
pr_$letter_quality
);
pr_$data_format_t = (
pr_$text,
pr_$plot,
pr_$transparent
);
prsvr_color_format_t = (none, {not a color printer}
pixel, {color map format}
scan_line_rgb,{3 plane formats}
scan_line_ymc,
plane_rgb,
plane_ymc
); {this tells the server how to send bitmap data}
pr_$interface_t = ( pr_$serial,
pr_$parallel,
pr_$external,
pr_$versatec,
pr_$multibus);
{This data base is set up by PRSVR based on PRF options specified by
the user and information the driver passes to PRSVR via the
driver database (driver_db_t). To use this database, set up a record
in your driver of type server_db_t. The setmode call will pass a pointer
to this database as it exists in PRSVR.}
server_db_t = RECORD
copies : binteger;
print_mode : pr_$data_format_t;
cpi : real; {characters per inch}
lpi : real; {lines per inch}
weight : pr_$font_weight_t;
lq : boolean;
resolution : pinteger; {set the printer to print at this resolution}
magnification : integer; {set the printer to magnify a bitmap by this amount}
bitmap_size : RECORD
x : integer; {the number of bits PRSVR will send}
y : integer;
planes : integer; {bits per pixel}
END;
color : boolean; {this file should be printed in color}
bw_rev : boolean; {set if user requests it and the printer can do it }
END;
server_db_ptr_t = ^server_db_t; {this points you to the PRSVR server_db}
{Use this database to pass PRSVR information about the driver and
printers capabilities. PRSVR will issue a return_info call at
startup, requesting this information. When the operation type of
this call = pr_$driver_db , pass the PRSVR program the pointer to
your driver database}
driver_db_t = RECORD {information about the printer that the driver supplies}
valid : boolean; { set this to true }
copies : boolean; {does the printer do multiple copies}
cpi : ARRAY [1..10] OF real; {an array of character spacings}
lpi : ARRAY [1..10] OF real;
resolution : ARRAY [1..4] OF pinteger;
{ the printer plots at these resolutions}
res_min : pinteger; {a range of resolutions from minimum ...}
res_max : pinteger; {... to maximum}
magnification : ARRAY [1..16] OF binteger;
color_format : prsvr_color_format_t; {tell prsvr how to send
color images}
bw_rev : boolean; {set if the printer can bw reverse image}
END;
driver_db_ptr_t = ^driver_db_t; {this tells PRSVR where to find
your driver database}
pr_$data_rec_t = packed RECORD
font_weight : pr_$font_weight_t ;
font_size : real ;
text_precision : pr_$text_precision_t ;
bpi : RECORD
x : integer ;
y : integer ;
END;
data_format: pr_$data_format_t;
pitch : real ;
x_dimension : pinteger ;
y_dimension : pinteger ;
rep_factor : pinteger;
rep_ability : boolean;
copies : pinteger;
interface: pr_$interface_t;
server_db_ptr : server_db_ptr_t;
driver_db_ptr : driver_db_ptr_t;
END ;
%eject ;
End of user1.ins.pas
.