[CONTACT]

[ABOUT]

[POLICY]

[ADVERTISE]

Mon,Nov estDavid Krowitz

Found at: ftp.icm.edu.pl:70/packages/netlib/apollo/image

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

		

		
.

NEW PAGES:

[ODDNUGGET]

[GOPHER]