% sysguide.tex - 20:13 GMT +10:00 Tue 3 Aug 1993 - modifier Geoffrey Tobin. % This is the TeX source file for the "dvgt System Guide". % % Details peculiar to our site are indicated by the string "SYSDEP". % Cross references are indicated by the string "XREF". % Feel free to make modifications applicable to your site. % Andrew Trevorrow, July 1986. % % Note: Andrew wrote to me in 1992 to say that he's released DVItoVDU % to the public domain, and that he is no longer maintaining it. % You may also modify dvgt to your heart's content, though it would % be more pleasant for the users if you rename it, first. % Don't forget to change the documentation: userguide.tex, % sysguide.tex, README, CHANGES, TODO, the Makefile-s, and any other % documentary evidence of what you've done to the software. % Geoffrey Tobin, May 1993. \input guidemacs % \centerline{\crest} % SYSDEP: University of Adelaide crest \vfil \centerline{\title \dvgt~~System~~Guide} \bigskip \vskip\parskip \centerline{\bigbf DVItoVDU Version 1.0 for VAX/UNIX in Modula-2 was by Andrew Trevorrow, July 1986} \smallskip \centerline{\bigbf DVItoVDU Version 3.0 ported to C by Ian Dall, Novemebr 1990} \smallskip \centerline{\bigbf \dvgt\ for AIX and Sun/OS unix systems is a modification by Geoffrey Tobin, May 1993} \bigskip \noindent This document explains how to install or modify \dvgt, a \TeX\ page previewer written in C. Details on how to use the program can be found in the {\sl \dvgt~User Guide}. It is assumed you are familiar with \TeX\ under unix\null. Please convey any problems or suggestions to: \medskip % SYSDEP % % \centerline{Andrew Trevorrow} % \centerline{Computing Services, University of Adelaide} % \centerline{GPO Box 498, Adelaide, South Australia, 5001} % \centerline{ACSnet address: |akt@uacomsci.ua.oz|~~Phone: (08) 228 5984} % \centerline{Geoffrey Tobin} \centerline{Electronic Engineering, La Trobe University} \centerline{Bundoora, Victoria, 3083} \centerline{Internet address: |ecsgrt@luxor.latrobe.edu.au|~~Phone: |+ (03) 479 1987|} \bigskip \vskip\parskip \centerline{\bigbf Contents} \bigskip % XREF: make sure page numbers are up-to-date!!! \line{Important files\leaders\hbox to .75em{\hss.\hss}\hfil 1} \line{Installing \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 3} \line{Overview\leaders\hbox to .75em{\hss.\hss}\hfil 4} \line{Module map\leaders\hbox to .75em{\hss.\hss}\hfil 7} \line{Modifying \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 8} \line{Testing \dvgt\leaders\hbox to .75em{\hss.\hss}\hfil 10} \line{Revision history\leaders\hbox to .75em{\hss.\hss}\hfil 11} \vfil % \centerline{\smallrm University of Adelaide Computing Services} % SYSDEP \eject % The above is the title page; let's make a few adjustments to some parameters: \footline={\hss\rm\folio\hss} % turn page numbers back on \pageno=1 % and restart numbering \subhead{Important files.} \noindent Let's suppose you've unpacked the distribution into some directory and are now looking at its contents. The files are: \begindisplay Top-level distribution files\cr \noalign{\medskip} |DVGT.README|& overview of current distribution\cr |Makefile.dvgt|& make a tar, shar or zip distribution\cr |dvgt/|& parent of doc, help, misc and src directories\cr \noalign{\bigskip} Top-level files\cr \noalign{\medskip} |CHANGES|& list of changes since previous version\cr |README|& brief overview of \dvgt\cr |TODO|& wish-list\cr |doc/|& documentation and test files, in TeX\cr |help/|& help files\cr |misc/|& miscellaneous C headers\cr |src/|& sources for \dvgt\ executable\cr \noalign{\bigskip} |TAGS|, in |src| directory\cr \noalign{\medskip} |TAGS|& list of identifiers, with source location\cr & - useful with some editors, such as elvis\cr & - a "tags" or "ctags" program is needed,\cr & if you wish to make a TAGS file\cr \noalign{\bigskip} Program make files, in |src| directory\cr \noalign{\medskip} |Makefile.aix|& make |dvgt| for IBM Risc/6000 under AIX\cr |Makefile.sun|& make |dvgt| for Sparc 1 under Sun/OS\cr \noalign{\bigskip} C sources, in |src| directory\cr \noalign{\medskip} |version.h|& version description string\cr |config.h|& system-dependent C macros, types and variables\cr |dvitovdu.c|& main program's source file\cr |globals.h|& global things, often defined in |dvitovdu.c|\cr |options.c|/|h|& command-line options\cr |defaults.h|& system-dependent defaults for certain values\cr & used and/or set in |dvitovdu.c| and |options.c|\cr |files.h|& unix random access file i/o declarations,\cr & for |dvireader.c| and |fontreader.c|\cr |help.h|& (fall-back) option and interactive help texts\cr |screenio.c|/|h|& low-level terminal i/o routines\cr & (see also |unixio.c|/|h|)\cr |unixio.c|/|h|& unix command line interface routines\cr |lstring.c|/|h|& length specified strings\cr |new.h|& generic memory allocation\cr |dvireader.c|/|h|& DVI file translation routines and data structures\cr |fontreader.c|/|h|& PK and TFM font file access routines\cr |vdu.c|/|vdu.h|& generic VDU parameters and routines\cr |aed512vdu.c|& routines for AED 512\cr |ncsatelvdu.c|& routines for NCSA Telnet's tek4010 emulation\cr |regisvdu.c|/|h|& routines for ReGIS compatible VDUs\cr |tek4010emu.c|/|h|& routines for Tektronix 4010/4014 emulating VDUs\cr |vis240vdu.c|& routines for VISUAL 240\cr |vis500vdu.c|/|h|& routines for VISUAL 500\cr |vis550vdu.c|& routines for VISUAL 550\cr |vis603vdu.c|& routines for VISUAL 603\cr |vis630vdu.c|& routines for VISUAL 630\cr |vt100vdu.c|/|h|& routines for VT100\cr |vt100132vdu.c|& routines for VT100 in 132 column mode\cr |vt220vdu.c|& routines for VT220\cr |vt640vdu.c|& routines for VT100 with Retrographics\cr \noalign{\bigskip} Miscellaneous C headers, in |misc| directory\cr \noalign{\medskip} |stdlib.h|& Ian Dall's sample |"stdlib.h"| file,\cr & for those systems without ||\cr \noalign{\bigskip} Help files, in |help| directory\cr \noalign{\medskip} |cmd.hlp|& text file read by \dvgt's |?| interactive command\cr |immed.hlp|& on-line help file\cr |options.hlp|& detailed description of \dvgt\ options\cr \noalign{\bigskip} Documents, in |doc| directory\cr \noalign{\medskip} |Makefile|& make file for Documentation and Test files\cr |guidemacs.tex|& macros used by the following guides\cr |sysguide.tex|& source for this document, the {\sl \dvgt\ System Guide}\cr |userguide.tex|& source for the {\sl \dvgt\ User Guide}\cr \noalign{\bigskip} Test file, in |doc| directory\cr \noalign{\medskip} |tripvdu.tex|& source for |tripvdu.dvi|, a torture test for \dvgt\cr \enddisplay \vfil\eject \subhead{Installing \dvgt.} \noindent To make {\dvgt}, you need a C compiler, linker, and many of the most usual header and library files. \dvgt\ should compile under ANSI C, and under at least some traditional and pre-ANSI C compilers. Minor modifications may be necessary for some compilers and/or operating systems. \noindent This distribution is designed for IBM Risc/6000 computers under (a no-longer supported version (!) of) AIX, and for Sparc 1 computers under (a locally-modified) Sun/OS 4.0.3, but variants of these systems may possibly compile, link and run \dvgt\ as distributed. \noindent Reports of successful ports, as well as of bugs encountered, and of further items for the wish-list, are welcome. \noindent The executable file is called |dvgt|. Before making |dvgt| available to other users at your site, read the section on command options in the {\sl \dvgt\ User Guide}. If you have a C compiler and libraries, you may want to make a few changes to |defaults.h| to suit your site: \item{$\bullet$} Change |DEF_X_RESOLUTION| and |DEF_Y_RESOLUTION| (the default values of |-rx| and |-ry|) to match the X and Y resolutions of your printer, in dots per inch. \item{$\bullet$} Change |DEF_PAPERWD| and |DEF_PAPERHT| (the default values of |-x| and |-y|) to define the dimensions of the default paper used by your printer. \item{$\bullet$} Change |DEF_PK_DIR| and |DEF_TFM_DIR| (the default values of |-f| and |-t|) to tell \dvgt\ where to look for PK and TFM files. \item{$\bullet$} Change |DEF_DUMMY_PK| (the default value of |-d|) to indicate which PK file to use when a requested one does not exist. \item{$\bullet$} Change |DEF_HELP_FILE| (the default value of |-h|) to indicate the location of |cmd.hlp|. \noindent Individual users can of course override any of these defaults. Any changes you make should be reflected in the user documentation in |userguide.tex|, |immed.hlp|, |CHANGES| and |README|. (the |immed.hlp| file provides a suitable basis for a |man| entry). System-dependent information in these files is flagged by the string ``|SYSDEP|'' so you can quickly locate where changes need to be made. \vfil\eject \subhead{Overview.} \noindent A C program is typically built up from a number of separately compiled |.c| source files. Let's use the term |object| loosely for a type, constant, macro, variable, or function. The source files certainly must share some objects, in order to cooperate as a single program. \noindent Shared objects in C are defined in exactly one file. \noindent To increase the likelihood that the sources use shared objects correctly, common practice is to declare each shared object in exactly one |header| file, mnemonically suffixed |.h|. Any file that must use that shared object should |#include| that header. Headers should not allocate storage; that should be left to |.c| files. \noindent In the case of types, constants and macros, which don't require runtime storage, the declaration constitutes the definition, so if these are shared, then they are defined and declared in the same file, which will be a header. \noindent However, for variables and functions, which do need storage at runtime, a definition not only describes the object, but it also allocates storage for it, whereas a declaration is a mere description. Consequently, shared variables and functions are defined in one |.c| file, and declared in a header typically named after it. That header may also define types, constants and macros needed by those shared variables and functions. \noindent For example, |fontreader.c| defines some shared functions, which are declared in |fontreader.h|, which is |#include|-ed by the C source files (including |fontreader.c| itself) that use those functions. \noindent If this is done wisely, then rapid system regeneration is possible, because the |.c| files only use information provided in the headers; each |.c| file may be modified (e.g., optimized) without the need to recompile the others. This is called |modular| programming, and we may then meaningfully speak of the |.c| and any accompanying |.h| file as a |module|. To carry the terminology further, we can loosely describe the defining file (or module) as |implementing| the shared objects, which it |exports|, through the |interface| provided by its header, to the |client| modules that |import| those shared objects in order to use them. \noindent The module map on page 7 % XREF shows the importation dependencies of all the modules of \dvgt\null. \noindent Not only do modules allow a large program to be broken up into manageable chunks, they also provide a sensible basis for describing a program: \medskip \noindent |DVItoVDU| \nobreak\noindent The main module is primarily concerned with the user interface. It handles all the interactive command processing and contains the high-level logic used to update the dialogue and window regions. Data and procedures are imported from the following modules to help the main module carry out its many tasks. \medskip \noindent |Options| \nobreak\noindent This module provides the interface to the UNIX shell. The command line used to invoke \dvgt\ is parsed and the DVI file name extracted. All the options are also initialized, either to explicit values given in the command line or to site-dependent default values. \medskip \noindent |VDUinterface| \nobreak\noindent \dvgt\ can work efficiently on different types of VDUs by letting C function pointers act as generic VDU routines. These routines, along with the generic VDU parameters, are defined in |VDUinterface|. \noindent The generic VDU routines are: \begindisplay |StartText|& switch to ``text mode''\cr |ClearTextLine|& erase given line\cr |MoveToTextLine|& move cursor to start of given line\cr |ClearScreen|& erase the entire screen\cr |StartGraphics|& switch to ``graphics mode''\cr |LoadFont|& simulate the given font for future |ShowChar| calls\cr |ShowChar|& display a Terse mode character at given screen location\cr |ShowRectangle|& display a given rectangular region of screen pixels\cr |ResetVDU|& reset VDU to its normal state\cr \enddisplay Most of these are quite trivial to implement for a specific VDU. The main module looks after all the tricky graphic operations such as the clipping of characters and rules outside the current window region, and the way in which visible paper pixels are scaled to screen pixels. \noindent From an efficiency point of view, the two most critical routines are |ShowChar| and |ShowRectangle|. |ShowChar| is used by the main module to display a character in Terse mode. The only information given is the \TeX\ character (currently restricted to |\char0..\char255|) and its screen position. Since characters are displayed one font at a time, some VDUs can use scaling information sent by the most recent |LoadFont| routine to select an appropriate hardware ``font''. \noindent |ShowRectangle| is used for all other window graphics. It is used to draw the paper edges, to draw all rules (regardless of display mode), to draw all glyph outlines in a Box display, and to draw the horizontal lines making up all glyphs in a Full display. The majority of rectangles are in fact horizontal or vertical lines just one screen pixel thick. \bigbreak \noindent The generic VDU parameters are: \begindisplay |DVIstatusl|& DVI status line, usually 1\cr |windowstatusl|& window status line, usually 2\cr |messagel|& message line, usually 3\cr |commandl|& command line, usually 4\cr |bottoml|& bottom text line in screen\cr |windowh|& window region's top left h coordinate\cr |windowv|& window region's top left v coordinate\cr |windowwd|& unscaled window width\cr |windowht|& unscaled window height\cr \enddisplay These ``parameters'' are actually integer variables. The main module treats them as constants. \noindent There are two screen coordinate systems used by \dvgt: \item{(1)} When updating the screen in text mode (i.e., when updating the dialogue region or during a |?| or |S| command), \dvgt\ assumes text lines start at 1 and increase downwards. The bottom text line on the screen is given by the parameter |bottoml|. \item{(2)} When updating the screen in graphics mode, \dvgt\ assumes the top left screen pixel is positioned at (0,0). Horizontal coordinates increase to the right and vertical coordinates increase down the screen. The top left pixel in the window region is at (|windowh|,|windowv|). Specific VDU modules may have to do a translation to the actual coordinate scheme used by the VDU\null. The size of the window region in screen pixels is given by |windowwd| and |windowht|. \medskip \noindent |aed512vdu|, |ncsatelvdu|, |regisvdu|, etc. \nobreak\noindent Each specific VDU module exports an initialization routine that will assign appropriate procedures to the generic VDU routines and specific integers to the generic VDU parameters. |VDUinterface| imports all these initialization routines and uses the |-v| value set in |Options| to execute one of them. \medskip \noindent |DVIReader| \nobreak\noindent This module exports the routines and data structures needed to move about randomly in a DVI file and interpret selected pages. Although the main module is currently the only client, it is anticipated that |DVIReader| could just as well form the basis of another DVI translator, such as a non-interactive device driver. \noindent Font, character and rule information is stored in dynamically allocated lists to avoid imposing any limit on their numbers. The length of the font list is determined soon after opening the DVI file by reading all the font definitions in the postamble. Each font node is a record made up of many fields; one of these fields is the head of a character list. The nodes in each character list will store the positions and \TeX\ codes of all characters on a page. Besides the font list, there is also a rule list. The nodes in the rule list will store the positions and dimensions of all rules on a page. (Character and rule positions are stored as pairs of horizontal and vertical paper pixel coordinates. The manner in which |DVIReader| calculates such positions is based firmly on Donald Knuth's |DVItype|.) \noindent Just before interpreting a selected DVI page, the rule list and all the character lists are deallocated if necessary. During interpretation, |DVIReader| adds a new rule or character node to the {\it tail\/} of an appropriate list. When the main module processes such lists, rules and characters will be displayed in somewhat the same sequence as seen in the DVI page; i.e., top-to-bottom and left-to-right. (Since there is a separate rule list, as well as a character list for each font, the precise sequence is not remembered.) After interpretation, the nodes in the font list are sorted so that fonts with the least number of characters ($>$ 0) will be processed first. \noindent The various lists contain most of the information needed to display the page; they are traversed by the main module whenever the window region is updated. If the page isn't empty then |DVIReader| will also determine the edges of the page rectangle. This is the smallest rectangle containing all black pixels in glyphs and rules, as well as all character reference points (needed for Terse displays). The main module uses the page rectangle to decide if the page is off the paper, and to restrict window movement. \medskip \noindent |FontReader| \nobreak\noindent \dvgt\ gets all its character information from standard PK files. |FontReader| exports routines for moving about in such files and grabbing various bytes and words. A PK file contains the crucial TFM widths needed by |DVIReader| to correctly position characters when interpreting a DVI page. These widths, along with other details about each glyph, are kept in the PK file. The PK file is loaded just once for each font (the very first time the font is seen) and \dvgt\ will write `|Loading font data from ...|' to the log file. \noindent A PK file also contains glyph shape information (in the form of bitmaps) for all characters in a \TeX\ font. \dvgt\ uses these bitmaps during a Full display to draw characters a font at a time. \noindent Because |DVIReader| creates a separate character list for each font used on a page, there never needs to be more than one PK file open at any given time. (But there are! - Geoffrey Tobin observes.) \medskip \noindent |ScreenIO| \nobreak\noindent All low-level terminal i/o is handled by the routines defined in this module. It uses some C routines written by Alex Dickinson (see |unixio.c|). \vfil\eject \subhead{Module map.} \font\arrowfont=linew10 at 10truept % MACROS FOR MAP. % \plot is based on \point macro described on page 389 of TeXbook. \newdimen\unit \unit=1in \def\plot % #1 is down, #2 is right, #3 is stuff to plot #1 #2 #3\endplot {\rlap{\kern#2\unit \vbox to 0pt {\parindent=0pt\offinterlineskip\kern#1\unit#3\vss}}} \def\ulap#1{\vbox to 0pt{\vss#1}} % vertical analog of \llap \def\dlap#1{\vbox to 0pt{#1\vss}} % vertical analog of \rlap \def\cvlap#1{\vbox to 0pt{\vss#1\vss}} % centre vertically \def\chlap#1{\hbox to 0pt{\hss#1\hss}} % centre horizontally \def\drawbox ht#1 wd#2 #3\endbox {\vbox{\hsize=#2\unit \hrule height10sp \hbox to \hsize {\vrule width10sp \vbox to #1\unit {\vfil #3\vfil}% \vrule width10sp } \hrule height10sp } } \def\mainmodule {\drawbox ht.7 wd1.2 \centerline{\strut |DVItoVDU|} \centerline{\strut (main module)} \endbox } \def\midmodules {\drawbox ht.4 wd1 \centerline{|DVIReader|} \endbox \kern .3\unit \drawbox ht.4 wd1 \centerline{|FontReader|} \endbox \kern .3\unit \drawbox ht.4 wd1 \centerline{|VDUinterface|} \endbox \kern .3\unit \drawbox ht.4 wd1 \centerline{|Options|} \endbox \kern .5\unit \drawbox ht.4 wd1.5 \centerline{|ScreenIO|} \endbox } \def\vdumodules {\drawbox ht1.2 wd1.3 \centerline{\strut VDU modules:} \centerline{\strut |aed512vdu|} \centerline{\strut |ncsatelvdu|} \centerline{\strut |regisvdu|} \centerline{\strut etc.} \endbox } \def\uline#1 {\ulap{\hrule width 10sp height#1\unit}} \def\dline#1 {\dlap{\hrule width 10sp height#1\unit}} \def\lline#1 {\llap{\vrule height10sp width #1\unit}} \def\rline#1 {\rlap{\vrule height10sp width #1\unit}} \def\uarrow#1 {\ulap{\arrowfont\dlap{\hbox{\char'66 }} \hrule width10sp height#1\unit}} \def\darrow#1 {\dlap{\arrowfont\hrule width10sp height#1\unit \ulap{\hbox{\char'77 }}}} \def\rarrow#1 {\rlap{\vrule height10sp width#1\unit \setbox0=\hbox{\arrowfont\char'55 }\ht0=0pt\dp0=0pt \llap{\box0}}} \def\larrow#1 {\llap{\setbox0=\hbox{\arrowfont\char'33 }\ht0=0pt\dp0=0pt \rlap{\box0}\relax \vrule height10sp width#1\unit}} % START PLOTTING MAP \noindent An arrow from module |A| to module |B| indicates the latter imports data and/or procedures from the former. Module |B| is said to be a {\it client\/} of module |A|\null. \vskip 1in \hbox {\kern-.3\unit % shift 0,0 left % plot all the module boxes: \plot 0.0 0.5 \mainmodule \endplot \plot 1.0 2.5 \midmodules \endplot \plot 2.4 4.4 \vdumodules \endplot % plot all the arrows: \plot 1.2 1.5 \uarrow 0.5 \endplot % DVIReader to main \plot 1.2 1.5 \rline 1.0 \endplot \plot 1.9 1.3 \uarrow 1.2 \endplot % FontReader to main \plot 1.9 1.3 \rline 1.2 \endplot \plot 2.6 1.1 \uarrow 1.9 \endplot % VDUinterface to main \plot 2.6 1.1 \rline 1.4 \endplot \plot 3.3 0.9 \uarrow 2.6 \endplot % Options to main \plot 3.3 0.9 \rline 1.6 \endplot \plot 4.2 0.7 \uarrow 3.5 \endplot % ScreenIO to main \plot 4.2 0.7 \rline 1.8 \endplot \plot 4.0 3.0 \uarrow 0.5 \endplot % ScreenIO to Options \plot 4.0 3.8 \uline 1.3 \endplot % ScreenIO to VDUinterface \plot 2.7 3.8 \larrow 0.3 \endplot \plot 3.9 3.8 \darrow 0.1 \endplot % down arrow at point 6 \plot 3.1 3.0 \uarrow 0.3 \endplot % Options to VDUinterface \plot 2.5 4.4 \larrow 0.9 \endplot % point 5 to VDUinterface \plot 2.5 4.3 \rarrow 0.1 \endplot % right arrow at point 5 \plot 4.2 4.0 \rline 2.3 \endplot % line to right of ScreenIO \plot 4.2 6.3 \uline 3.0 \endplot % ScreenIO to vdus, font, dvi \plot 3.0 6.3 \larrow 0.6 \endplot % ScreenIO to vdus \plot 1.9 6.3 \larrow 2.8 \endplot % ScreenIO to FontReader \plot 1.2 6.3 \larrow 2.8 \endplot % ScreenIO to DVIReader % plot all the numbers: \plot 1.5 2.4 \llap{1} \endplot \plot 2.4 2.4 \llap{2} \endplot \plot 3.1 2.4 \llap{3} \endplot \plot 2.9 3.1 \rlap{4} \endplot \plot 2.3 4.3 \llap{5} \endplot \plot 3.8 3.9 \rlap{6} \endplot } \vfill \noindent Points of interest: \item{1 } |DVIReader| does not depend on |FontReader|. It does know that PK files contain crucial typesetting data, but leaves it up to the main module to specify how and where to get such information. \item{2 } |VDUinterface| exports the generic VDU routines and parameters for use in the main module. \item{3 } |Options| extracts the DVI file name and options from the |dvgt| command line. \item{4 } |VDUinterface| needs the |-v| value to select an appropriate VDU initialization routine. \item{5 } Specific VDU modules import the generic VDU routines and parameters from |VDUinterface|. In return, each VDU module exports an initialization routine. \item{6 } |ScreenIO| needs to use some |VDUinterface| routines to be able to leave the VDU screen in a decent state after abnormal termination. \vfil\eject \subhead{Modifying \dvgt.} \noindent \dvgt\ is descended from Andrew Trevorrow's |DVItoVDU|. \noindent |DVItoVDU| was originally developed under VAX/VMS using the Modula-2 system from Hamburg University. The UNIX version of |DVItoVDU| was developed using the Modula-2 compiler from DEC WRL and can run under ULTRIX or UNIX 4.2 BSD\null. The main module and all the supporting modules of |DVItoVDU| are written in Modula-2, except for the C routines in |unixio.c|. \noindent Ian Dall ported |DVItoVDU| version 3.0 to traditional C in November 1990, working from December 1989, with amendments in January 1991. Geoffrey Tobin (conditionally) ported it to ANSI C in May 1992, renaming it |dvgt| to avoid confusion. Significant modifications have been made to the user interface and code of |dvgt| up to the present date (May 1993), especially in versions 3.4 (first official public release, December 1992) and 3.5. \noindent If you wish to modify \dvgt\ you'll obviously need C, preferably either ANSI C or gcc (Gnu C), because those compilers provide stronger checks than earlier versions of C. Conversion to another C system should, however, be quite easy, particularly since traditional C is still provided for, via a test for the ANSI C macro |__STDC__|. \noindent All the source files avoid non-standard compiler features (IF NOT, PLEASE REPORT!), and system-dependent code is flagged by the string ``|SYSDEP|''\null. Terminal i/o is isolated in the |ScreenIO| module, and most file operations are restricted to |DVIReader| and |FontReader|. \noindent (The VMS-to-UNIX conversion took [Andrew Trevorrow] about two weeks. A working version was up in less than a week; it then took another week to fix some terminal i/o problems and produce a new {\sl User Guide}. [He] was a bit surprised at just how easy the conversion was.) \noindent [ Andrew Trevorrow, re the Modula-2 version of DVItoVDU: \noindent What about conversion to another language? An obvious candidate is Pascal. The similarities in syntax would allow any decent text editor to carry out much of the conversion automatically. The major difficulty in translation to standard Pascal would be the lack of procedure variables; it might be easier to implement just one type of VDU before attempting anything more sophisticated. ] \medskip \noindent IMPLEMENTING A NEW VDU. \noindent Assuming you have a C compiler, the most likely change you'll want to make is to add a new type of VDU to the program's capabilities. The code takes advantage of separate compilation (modularity), so that such a task can be undertaken without having to make any changes to the main module. \noindent The steps required to implement a new VDU (which we'll call brand XXX) are as follows, assuming that each of the other C files has been compiled to a |.o| file. This includes how to compile and link by hand; the changes to the Makefile-s should be evident to anyone who has even a little experience with |make| on either unix or another system. \item{$\bullet$} Read |vdu.h| to see if the task is even possible. \dvgt\ requires XXX to be able to carry out a number of primitive graphic operations such as clearing the screen, addressing individual pixels, etc. As little as possible is assumed about the capabilities of a VDU\null. In particular, the availability of a graphic input device is ignored. \dvgt\ should be able to work on any terminal that can: \itemitem{---} Mix text and graphics on the screen (some VDUs make no distinction). {\parskip=0pt \itemitem{---} Erase all of the screen, or individual text lines. \itemitem{---} Move the cursor to any given screen pixel. \itemitem{---} Display a rectangular region of screen pixels (possibly just one). } % reset \parskip \item{$\bullet$} Look at some of the |*vdu.h| files and use them to help you create |xxxvdu.h|. \item{$\bullet$} Look at some of the |*vdu.c| files and use them to help you create |xxxvdu.c|. Type `|cc -c xxxvdu.c|' to create |xxxvdu.o|. % SYSDEP \item{$\bullet$} Edit |vdu.c| and add appropriate code in the recommended locations (search for occurrences of ``|XXX|''). Type `|cc -c vdu.c|' to create a new |.o| file. % SYSDEP \item{$\bullet$} Relink |dvgt| by typing `|cc -o dvgt *.o|'. % SYSDEP \item{$\bullet$} Test the new version of |dvgt| (see the next section). \noindent It should be pointed out that \dvgt\ is currently targeted towards relatively primitive terminals. Significant changes to both the display logic and page data structures would probably be needed to take full advantage of the latest graphic work\-stations. For instance, a large amount of bit-mapped memory could store an entire rasterized page and allow much more sophisticated updating of the window region. Pan and zoom operations would also be much easier using a mouse or thumbwheel cursor controls. \vfil\eject \subhead{Testing \dvgt.} \noindent The file |tripvdu.dvi| was created to test \dvgt\ using much the same philosophy as Donald Knuth's torture test for \TeX\null. Most pages exercise rarely-used parts of the program: \begindisplay page& contents\cr \noalign{\medskip} 1& empty page (but with |\special| stuff that will be ignored)\cr 2& one black pixel at (0{,}0)\cr 3& entirely blackened A4 sheet of paper\cr 4& like page 3 but one pixel wider\cr 5& like page 3 but one pixel longer\cr 6& has a rulelist with one full ruletable node (300 rules)\cr 7& like page 6 but has one more rule\cr 8& has a charlist with one full chartable node (3000 characters)\cr 9& like page 8 but has one more character\cr 10& multiple \TeX\ page counters\cr 11& negative \TeX\ page counter\cr 12& characters from many fonts\cr 13& characters from many fonts, some of which have no PK file\cr 14& paragraph using most characters from standard roman font\cr 15& page in bottom half of A4 paper\cr 16& page entirely above and to the left of A4 paper\cr 17& page entirely below and to the right of A4 paper\cr 18& page extending beyond all edges of A4 paper\cr \enddisplay Type `|dvgt tripvdu|' and go through all the pages to verify that the program is working correctly. You may need to specify a |-v| value to tell |dvgt| what type of terminal you're using. See the {\sl \dvgt\ User Guide} for details on what |-v| values are available and the special requirements of some VDUs. \noindent If a catastrophe occurs and \dvgt\ actually crashes, please report the problem back to me, Geoffrey Tobin. \noindent If the reason for the crash is not obvious, and you have a C compiler, you might try to rebuild |dvgt| after editing the |.c| files that contain debugging code. \noindent Before all comments of the form |#ifdef |, perhaps at the top of the source file, so you can find them easily, write |#define |. Here || represents an identifier, usually in all capitals, such as |DEBUG|, or |BORING_MESSAGES|. \noindent Alternatively, write code of your own to output |snapshots| (current information) to the |logfile|. Wrap this code in an |#ifdef ... #else ... #endif| test, remembering to |#define| the appropriate macro constant when you're debugging. I like to label the |#else| and |#endif| lines with the name of the macro constant, so that its easy to see matching lines. \noindent Only a few modules have such code; use `|grep #ifdef *.c|' to list them. Note that the occurrences with |__STDC__| in them are not debugging code, but ANSI/non-ANSI detection switches, so you'll need to exclude those from your list; one way is to use the |-v| pattern exclusion option of |grep|, thus: `|grep #ifdef *.c| $\|$ |grep -v __STDC__|'. You might also want to redirect th eoutput to a file, or pipe it to either |more| or |less| (an improvement over |more| that allows backward scrolling, and much besides). \noindent The extra code might provide additional clues as to what is going wrong. \vfil\eject \subhead{Revision history} \medskip \noindent |DVItoVDU 1.0| \nobreak\noindent Version 1.0 of DVItoVDU for VAX/UNIX was based on version 1.5 for VAX/VMS (TUGboat vol.~7 no.~1 has an article describing the VMS version). The UNIX version of DVItoVDU is virtually identical as far as the user is concerned. The command option syntax is a little different of course, and there are a couple of new VDU types, but the interactive commands are exactly the same. \noindent A few improvements have been made to the UNIX version: \item{$\bullet$} Whenever a |\special| command is ignored, the first few bytes are displayed in case some users need to see them. \item{$\bullet$} While updating the window region, the main module uses |BusyRead| from |ScreenIO| to check for user input after drawing each visible rule or character. (The VMS version checked after every 8th rule or character; the overheads for |BusyRead| seem to be much less under UNIX.) \item{$\bullet$} |ScreenIO| required significant changes to be able to handle some of the more useful UNIX interrupts: |^C| can be used to return quickly to the `|Command:|' level, and |^Z| can be used to suspend |DVItoVDU|. (Thanks to Alex Dickinson who wrote the necessary |unixio.c| routines.) These interrupts are only detected during |Read|, |ReadString| and |BusyRead|. \medskip \noindent |DVItoVDU 2.0 to 3.0| \nobreak\noindent Lamentably mysterious. \medskip \noindent |C port| \nobreak\noindent Geoffrey Tobin is not aware of any significant functional changes introduced by Ian Dall. \medskip \noindent |dvgt 3.1 to 3.4| \nobreak\noindent See the README file in the dvgt/ directory. \medskip \noindent |dvgt 3.5| \nobreak\noindent See the CHANGES file in the dvgt/ directory, and/or the README file. \finishline \bye