summaryrefslogtreecommitdiff
path: root/dviware/dvgtk
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvgtk
Initial commit
Diffstat (limited to 'dviware/dvgtk')
-rw-r--r--dviware/dvgtk/AUTHORS14
-rw-r--r--dviware/dvgtk/ChangeLog19
-rw-r--r--dviware/dvgtk/INSTALL18
-rw-r--r--dviware/dvgtk/MACHINES10
-rw-r--r--dviware/dvgtk/Makefile.in181
-rw-r--r--dviware/dvgtk/NEWS18
-rw-r--r--dviware/dvgtk/README32
-rw-r--r--dviware/dvgtk/ansi2knr.ac78
-rw-r--r--dviware/dvgtk/ansi2knr.c481
-rw-r--r--dviware/dvgtk/c-auto.h.in126
-rw-r--r--dviware/dvgtk/configure2544
-rw-r--r--dviware/dvgtk/configure.in30
-rw-r--r--dviware/dvgtk/defaults.h32
-rw-r--r--dviware/dvgtk/doc/CHANGES448
-rw-r--r--dviware/dvgtk/doc/Makefile24
-rw-r--r--dviware/dvgtk/doc/README426
-rw-r--r--dviware/dvgtk/doc/TODO36
-rw-r--r--dviware/dvgtk/doc/ansi2knr.119
-rw-r--r--dviware/dvgtk/doc/example.tex232
-rw-r--r--dviware/dvgtk/doc/guidemacs.tex105
-rw-r--r--dviware/dvgtk/doc/options.txt139
-rw-r--r--dviware/dvgtk/doc/sysguide.tex914
-rw-r--r--dviware/dvgtk/doc/tripvdu.tex279
-rw-r--r--dviware/dvgtk/doc/userguide.tex1286
-rw-r--r--dviware/dvgtk/dvgt.c3595
-rw-r--r--dviware/dvgtk/dvgt.h110
-rw-r--r--dviware/dvgtk/dvgt.man82
-rw-r--r--dviware/dvgtk/dvireader.c1885
-rw-r--r--dviware/dvgtk/dvireader.h171
-rw-r--r--dviware/dvgtk/etc/dv-env25
-rw-r--r--dviware/dvgtk/etc/sane9
-rw-r--r--dviware/dvgtk/fontreader.c1079
-rw-r--r--dviware/dvgtk/fontreader.h21
-rw-r--r--dviware/dvgtk/options.c534
-rw-r--r--dviware/dvgtk/options.h45
-rw-r--r--dviware/dvgtk/screenio.c483
-rw-r--r--dviware/dvgtk/screenio.h73
-rw-r--r--dviware/dvgtk/stamp-auto1
-rw-r--r--dviware/dvgtk/stamp-auto.in1
-rw-r--r--dviware/dvgtk/unixio.c357
-rw-r--r--dviware/dvgtk/unixio.h44
-rw-r--r--dviware/dvgtk/vdu.c547
-rw-r--r--dviware/dvgtk/vdu.h87
-rw-r--r--dviware/dvgtk/web2c-dvgtk.patch55
44 files changed, 16695 insertions, 0 deletions
diff --git a/dviware/dvgtk/AUTHORS b/dviware/dvgtk/AUTHORS
new file mode 100644
index 0000000000..cec62e794f
--- /dev/null
+++ b/dviware/dvgtk/AUTHORS
@@ -0,0 +1,14 @@
+This program, dvgtk, was modified by Tomasz J. Cholewo from Geoffrey Tobin's
+dvgt distribution. Send bug reports to t.cholewo@ieee.org.
+
+Andrew Trevorrow wrote the original DVItoVDU in Modula-2.
+
+The initial C code for this version of DVItoVDU was copied from Ian
+Dall's site, ftp://augean.oz.au/pub/misc/dv.tar.Z. Ian had, as his
+source code seems to indicate, automatically translated it from Modula.
+
+Geoffrey Tobin added a lot of new functionality: font searching and
+substitution, option handling, bitmap allocation, help files, and much
+more.
+
+Tomasz J. Cholewo modified dvgt to use kpathsea library.
diff --git a/dviware/dvgtk/ChangeLog b/dviware/dvgtk/ChangeLog
new file mode 100644
index 0000000000..9e3cc1c82a
--- /dev/null
+++ b/dviware/dvgtk/ChangeLog
@@ -0,0 +1,19 @@
+Thu Mar 28 23:36:41 1997 Tomasz J. Cholewo <t.cholewo@ieee.org>
+
+ * First public beta release: version 0.2.
+
+Fri Mar 28 03:29:28 1997 Tomasz J. Cholewo <t.cholewo@ieee.org>
+
+ * Makefile.in: Using ansi2knr.
+
+Fri Mar 28 03:20:55 1997 Tomasz J. Cholewo <t.cholewo@ieee.org>
+
+ * dvireader.c: Removed extern references.
+ * dvgt.h: Renamed from config.h.
+
+Mon Mar 24 01:48:49 1997 Tomasz J. Cholewo <t.cholewo@ieee.org>
+
+ * dvgt.h, dvgt.c, options.c, vdu.h, options.h, vdu.c, unixio.h,
+ unixio.c, screenio.h, screenio.c, fontreader.h,
+ fontreader.c, dvireader.h, dvireader.c, defaults.h,
+ Makefile.in: Checked in as revision 0.1.
diff --git a/dviware/dvgtk/INSTALL b/dviware/dvgtk/INSTALL
new file mode 100644
index 0000000000..1860a306d2
--- /dev/null
+++ b/dviware/dvgtk/INSTALL
@@ -0,0 +1,18 @@
+1. Unpack, compile and install web2c by following its installation
+ instructions.
+
+2. Untar dvgtk-0.2.tar.gz in the top-level web2c source directory which
+ should create a dvgtk subdirectory.
+
+3. Set the default values in dvgtk/defaults.h.
+
+4. Run configure in dvgtk directory with the same parameters as for web2c.
+
+5. make
+
+6. make install
+
+If you prefer to compile web2c and dvgtk in the same session you will
+need to apply the supplied web2c-dvgtk.patch in the top-level web2c
+directory and then run configure, make and make install.
+
diff --git a/dviware/dvgtk/MACHINES b/dviware/dvgtk/MACHINES
new file mode 100644
index 0000000000..5ab3eda277
--- /dev/null
+++ b/dviware/dvgtk/MACHINES
@@ -0,0 +1,10 @@
+dvgtk-0.2 was verified to compile and work on the following architectures:
+
+mips-sgi-irix6.2
+ gcc-2.7.2.1 with -fbounds-checking
+ cc
+
+hppa1.1-hp-hpux10.10
+ gcc-2.7.2
+ cc with and without -Aa option
+
diff --git a/dviware/dvgtk/Makefile.in b/dviware/dvgtk/Makefile.in
new file mode 100644
index 0000000000..5c7bc9a234
--- /dev/null
+++ b/dviware/dvgtk/Makefile.in
@@ -0,0 +1,181 @@
+# Makefile for dvgtk -- t.cholewo@ieee.org. Public domain.
+# $Id: Makefile.in,v 0.2 1997/03/28 03:29:28 tjchol01 Exp $
+version = 0.2
+
+ac_include ../make/paths.make
+ac_include ../make/common.make
+ac_include ../make/programs.make
+
+ANSI2KNR = @ANSI2KNR@
+o = .@U@o
+
+#BOUNDS = -fbounds-checking
+#XCFLAGS = $(BOUNDS) -O -Wall -Wformat
+#XLDFLAGS = $(BOUNDS)
+
+program = dvgt
+objects = dvgt$o dvireader$o fontreader$o options$o screenio$o unixio$o vdu$o
+
+programs = $(program)
+
+default all: $(programs)
+
+$(program): $(objects) $(kpathsea)
+ $(kpathsea_link) $(objects) $(LOADLIBES)
+
+ac_include ../make/tkpathsea.make
+
+install: install-exec install-data
+uninstall: uninstall-exec uninstall-data
+
+install-exec:
+ $(SHELL) $(top_srcdir)/../mkdirchain $(bindir)
+ test ! -f $(program) \
+ || $(INSTALL_LIBTOOL_PROG) $(bindir) $(program)
+uninstall-exec:
+ cd $(bindir); rm -f $(program)
+
+install-data:
+ $(SHELL) $(top_srcdir)/../mkdirchain $(mandir)
+ $(INSTALL_DATA) $(srcdir)/dvgt.man $(mandir)/dvgt.$(manext)
+uninstall-data:
+ rm -f $(mandir)/dvgt.$(manext)
+
+clean::
+ rm -f $(ANSI2KNR) *._o *._c *.vlg doc/*.dvi doc/*.vlg doc/*.log depend.make
+
+xclean: clean configclean
+ rm -f stamp-auto stamp-auto.in
+
+distname = dvgtk
+program_files = dvgt.man web2c-dvgtk.patch ansi2knr.ac MACHINES
+version_files = dvgt.c
+
+pre-dist-$(distname):
+post-dist-$(distname):
+ ln -s `pwd`/doc `pwd`/etc $(distdir)
+
+# modified dist.make -- making distribution tar files.
+distdir = $(distname)
+ln_files = AUTHORS ChangeLog INSTALL NEWS README *.in *.h *.c \
+ configure .gdbinit stamp-auto
+
+dist_rm_predicate = -name depend.make -o -name Makefile
+dist: all pre-dist-$(distname)
+ rm -rf $(distdir)
+ mkdir -p $(distdir)
+ -ln $(ln_files) $(distdir)
+ ln $(program_files) $(distdir)
+# Remove the extra files our patterns got us.
+ cd $(distdir); rm -f c-auto.h
+ find $(distdir) \( $(dist_rm_predicate) \) -exec rm '{}' \;
+ find $(distdir) -name \.*texi -exec egrep -ni ' | ::|xx[^}]' \;
+ $(MAKE) post-dist-$(distname)
+ chmod -R a+rwX $(distdir)
+ GZIP=-9 tar chzf $(distdir)-$(version).tar.gz $(distdir)
+ rm -rf $(distdir)
+
+# End of modified dist.make.
+
+.SUFFIXES: .c .o ._c ._o
+
+.c._c: $(ANSI2KNR)
+ $(ANSI2KNR) $< > $*.tmp && mv $*.tmp $@
+
+._c._o:
+ @echo $(compile) -c $<
+ @rm -f _$*.c
+ @ln $< _$*.c && $(compile) _$*.c && mv _$*.o $@ && rm _$*.c
+
+.c._o: $(ANSI2KNR)
+ $(ANSI2KNR) $< > $*.tmp && mv $*.tmp $*._c
+ @echo $(compile) $*._c
+ @rm -f _$*.c
+ @ln $*._c _$*.c && $(compile) _$*.c && mv _$*.o $@ && rm _$*.c
+
+ansi2knr: ansi2knr.o c-auto.h
+ $(CC) -o ansi2knr ansi2knr.o $(LIBS)
+
+ac_include ../make/config.make
+
+info dvi check:
+
+ac_include ../make/clean.make
+ac_include ../make/rdepend.make
+
+# dependencies
+
+# configure:: ansi2knr.ac
+
+$(objects): $(ANSI2KNR)
+
+# depend.make
+
+dvgt$o: dvgt.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h ../kpathsea/proginit.h ../kpathsea/tex-file.h \
+ defaults.h screenio.h options.h unixio.h vdu.h dvireader.h \
+ fontreader.h
+dvireader$o: dvireader.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h dvireader.h screenio.h fontreader.h options.h
+fontreader$o: fontreader.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h ../kpathsea/tex-file.h ../kpathsea/tex-glyph.h \
+ screenio.h vdu.h options.h dvireader.h fontreader.h
+options$o: options.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h screenio.h options.h defaults.h
+screenio$o: screenio.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h screenio.h unixio.h vdu.h
+unixio$o: unixio.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h unixio.h screenio.h \
+
+vdu$o: vdu.c dvgt.h c-auto.h \
+ ../kpathsea/debug.h \
+ ../kpathsea/c-proto.h ../kpathsea/c-std.h ../kpathsea/c-unistd.h \
+ ../kpathsea/systypes.h ../kpathsea/c-memstr.h ../kpathsea/c-errno.h \
+ ../kpathsea/c-minmax.h \
+ ../kpathsea/c-limits.h \
+ ../kpathsea/types.h \
+ ../kpathsea/progname.h ../kpathsea/c-pathch.h ../kpathsea/c-ctype.h \
+ ../kpathsea/lib.h vdu.h options.h screenio.h
+
diff --git a/dviware/dvgtk/NEWS b/dviware/dvgtk/NEWS
new file mode 100644
index 0000000000..488db9b8e1
--- /dev/null
+++ b/dviware/dvgtk/NEWS
@@ -0,0 +1,18 @@
+1. Uses kpathsea library: finds fonts according to the texmf.cnf
+ settings, MakeTeXPK/gsftopk is called as needed.
+
+2. Installation integrated with web2c-7.0 source tree structure.
+
+3. Uses configure to simplify installation process.
+
+4. Now works with dvicopy output what enables previewing documents with
+ virtual fonts.
+
+5. Shows bounding boxes of included Postscript figures.
+
+6. Uses getopt library for option processing what allows for greater
+ flexibility in command line syntax.
+
+7. General code cleanup.
+
+8. Supports only Tektronix 4010 emulations.
diff --git a/dviware/dvgtk/README b/dviware/dvgtk/README
new file mode 100644
index 0000000000..5946b734e5
--- /dev/null
+++ b/dviware/dvgtk/README
@@ -0,0 +1,32 @@
+dvgtk-0.2 is a beta release of a DVI file previewer for Tektronix 4010
+terminal emulators.
+
+dvgtk is derived from the dvgt-3.51 package. The original authors were
+Andrew Trevorrow, Ian Dall, and Geoffrey Tobin.
+
+Installation requires access to web2c-7.0 source tree. An attempt was
+made to integrate dvgtk as a subpackage of the web2c but dvgt is still
+in a very rough shape and does not stand to web2c standards yet. Actually
+it should be rewritten from scratch :-).
+
+Installation instructions are in file INSTALL and description of recent
+modifications is in file NEWS. For a list of architectures on which
+dvgtk was verified to compile see file MACHINES. For original
+instructions and acknowledgments please refer to doc/README.
+
+dvgtk was verified to work with Kermit 3.14, X11R6 xterm and CONEX 7.2.
+The maintainer currently uses CONEX by Erhard Hilbig with a modem
+connection and this package was tested most extensively for this
+configuration. CONEX works well even on low-end PCs and can be found
+for example at:
+
+ ftp://ftp.cdrom.com/simtelnet/msdos/commprog/conex71.zip
+
+The latest version of dvgtk can be found at
+
+ http://mecca.spd.louisville.edu/~tjchol01/software/dvgtk/
+
+Please direct all suggestions and bug reports to Tomasz J. Cholewo
+<t.cholewo@ieee.org>. I will be very grateful for all build reports
+containing the host type and possibly invalid output from the
+compilation process.
diff --git a/dviware/dvgtk/ansi2knr.ac b/dviware/dvgtk/ansi2knr.ac
new file mode 100644
index 0000000000..6381c3b3fc
--- /dev/null
+++ b/dviware/dvgtk/ansi2knr.ac
@@ -0,0 +1,78 @@
+# -*- m4 -*-
+# Based on aclocal.m4 from wget-1.4.4 by Hrvoje Niksic
+AC_DEFUN(AM_C_PROTOTYPES,
+[AC_REQUIRE([AM_PROG_CC_STDC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_MSG_CHECKING([for function prototypes])
+if test "$am_cv_prog_cc_stdc" != no; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(PROTOTYPES)
+ U= ANSI2KNR=
+else
+ AC_MSG_RESULT(no)
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS(string.h)
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# HP-UX -Aa -D_HPUX_SOURCE
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" "-Aa -D_HPUX_SOURCE" -qlanglvl=ansi -std1 "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+], [
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+AC_MSG_RESULT($am_cv_prog_cc_stdc)
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
diff --git a/dviware/dvgtk/ansi2knr.c b/dviware/dvgtk/ansi2knr.c
new file mode 100644
index 0000000000..4c1c165af1
--- /dev/null
+++ b/dviware/dvgtk/ansi2knr.c
@@ -0,0 +1,481 @@
+/* Copyright (C) 1989, 1991, 1993, 1994, 1995 Aladdin Enterprises. All rights reserved. */
+
+/* ansi2knr.c */
+/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
+
+/*
+ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY. No author or distributor accepts responsibility to anyone for the
+consequences of using it or for whether it serves any particular purpose or
+works at all, unless he says so in writing. Refer to the GNU General Public
+License (the "GPL") for full details.
+
+Everyone is granted permission to copy, modify and redistribute ansi2knr,
+but only under the conditions described in the GPL. A copy of this license
+is supposed to have been given to you along with ansi2knr so you can know
+your rights and responsibilities. It should be in a file named COPYLEFT.
+Among other things, the copyright notice and this notice must be preserved
+on all copies.
+
+We explicitly state here what we believe is already implied by the GPL: if
+the ansi2knr program is distributed as a separate set of sources and a
+separate executable file which are aggregated on a storage medium together
+with another program, this in itself does not bring the other program under
+the GPL, nor does the mere fact that such a program or the procedures for
+constructing it invoke the ansi2knr executable bring any other part of the
+program under the GPL.
+*/
+
+/*
+ * Usage:
+ ansi2knr input_file [output_file]
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes function definitions by seeing a non-keyword
+ * identifier at the left margin, followed by a left parenthesis,
+ * with a right parenthesis as the last character on the line.
+ * It will recognize a multi-line header provided that the last character
+ * of the last line of the header is a right parenthesis,
+ * and no intervening line ends with a left or right brace or a semicolon.
+ * These algorithms ignore whitespace and comments, except that
+ * the function name must be the first thing on the line.
+ * The following constructs will confuse it:
+ * - Any other construct that starts at the left margin and
+ * follows the above syntax (such as a macro or function call).
+ * - Macros that tinker with the syntax of the function header.
+ */
+
+/*
+ * The original and principal author of ansi2knr is L. Peter Deutsch
+ * <ghost@aladdin.com>. Other authors are noted in the change history
+ * that follows (in reverse chronological order):
+ lpd 95-06-22 removed #ifndefs whose sole purpose was to define
+ undefined preprocessor symbols as 0; changed all #ifdefs
+ for configuration symbols to #ifs
+ lpd 95-04-05 changed copyright notice to make it clear that
+ including ansi2knr in a program does not bring the entire
+ program under the GPL
+ lpd 94-12-18 added conditionals for systems where ctype macros
+ don't handle 8-bit characters properly, suggested by
+ Francois Pinard <pinard@iro.umontreal.ca>;
+ removed --varargs switch (this is now the default)
+ lpd 94-10-10 removed CONFIG_BROKETS conditional
+ lpd 94-07-16 added some conditionals to help GNU `configure',
+ suggested by Francois Pinard <pinard@iro.umontreal.ca>;
+ properly erase prototype args in function parameters,
+ contributed by Jim Avera <jima@netcom.com>;
+ correct error in writeblanks (it shouldn't erase EOLs)
+ lpd 89-xx-xx original version
+ */
+
+/* Most of the conditionals here are to make ansi2knr work with */
+/* the GNU configure machinery. */
+
+#if HAVE_CONFIG_H
+# include <c-auto.h> /* tjc change!!! */
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if HAVE_CONFIG_H
+
+/*
+ For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
+ This will define HAVE_CONFIG_H and so, activate the following lines.
+ */
+
+# if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+#else /* not HAVE_CONFIG_H */
+
+/*
+ Without AC_CONFIG_HEADER, merely use <string.h> as in the original
+ Ghostscript distribution. This loses on older BSD systems.
+ */
+
+# include <string.h>
+
+#endif /* not HAVE_CONFIG_H */
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+/*
+ malloc and free should be declared in stdlib.h,
+ but if you've got a K&R compiler, they probably aren't.
+ */
+char *malloc();
+void free();
+#endif
+
+/*
+ * The ctype macros don't always handle 8-bit characters correctly.
+ * Compensate for this here.
+ */
+#ifdef isascii
+# undef HAVE_ISASCII /* just in case */
+# define HAVE_ISASCII 1
+#else
+#endif
+#if STDC_HEADERS || !HAVE_ISASCII
+# define is_ascii(c) 1
+#else
+# define is_ascii(c) isascii(c)
+#endif
+
+#define is_space(c) (is_ascii(c) && isspace(c))
+#define is_alpha(c) (is_ascii(c) && isalpha(c))
+#define is_alnum(c) (is_ascii(c) && isalnum(c))
+
+/* Scanning macros */
+#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
+
+/* Forward references */
+char *skipspace();
+void writeblanks();
+int test1();
+int convert1();
+
+/* The main program */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{ FILE *in, *out;
+#define bufsize 5000 /* arbitrary size */
+ char *buf;
+ char *line;
+ /*
+ * In previous versions, ansi2knr recognized a --varargs switch.
+ * If this switch was supplied, ansi2knr would attempt to convert
+ * a ... argument to va_alist and va_dcl; if this switch was not
+ * supplied, ansi2knr would simply drop any such arguments.
+ * Now, ansi2knr always does this conversion, and we only
+ * check for this switch for backward compatibility.
+ */
+ int convert_varargs = 1;
+
+ if ( argc > 1 && argv[1][0] == '-' )
+ { if ( !strcmp(argv[1], "--varargs") )
+ { convert_varargs = 1;
+ argc--;
+ argv++;
+ }
+ else
+ { fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
+ exit(1);
+ }
+ }
+ switch ( argc )
+ {
+ default:
+ printf("Usage: ansi2knr input_file [output_file]\n");
+ exit(0);
+ case 2:
+ out = stdout;
+ break;
+ case 3:
+ out = fopen(argv[2], "w");
+ if ( out == NULL )
+ { fprintf(stderr, "Cannot open output file %s\n", argv[2]);
+ exit(1);
+ }
+ }
+ in = fopen(argv[1], "r");
+ if ( in == NULL )
+ { fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+ exit(1);
+ }
+ fprintf(out, "#line 1 \"%s\"\n", argv[1]);
+ buf = malloc(bufsize);
+ line = buf;
+ while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+ { switch ( test1(buf) )
+ {
+ case 2: /* a function header */
+ convert1(buf, out, 1, convert_varargs);
+ break;
+ case 1: /* a function */
+ convert1(buf, out, 0, convert_varargs);
+ break;
+ case -1: /* maybe the start of a function */
+ line = buf + strlen(buf);
+ if ( line != buf + (bufsize - 1) ) /* overflow check */
+ continue;
+ /* falls through */
+ default: /* not a function */
+ fputs(buf, out);
+ break;
+ }
+ line = buf;
+ }
+ if ( line != buf ) fputs(buf, out);
+ free(buf);
+ fclose(out);
+ fclose(in);
+ return 0;
+}
+
+/* Skip over space and comments, in either direction. */
+char *
+skipspace(p, dir)
+ register char *p;
+ register int dir; /* 1 for forward, -1 for backward */
+{ for ( ; ; )
+ { while ( is_space(*p) ) p += dir;
+ if ( !(*p == '/' && p[dir] == '*') ) break;
+ p += dir; p += dir;
+ while ( !(*p == '*' && p[dir] == '/') )
+ { if ( *p == 0 ) return p; /* multi-line comment?? */
+ p += dir;
+ }
+ p += dir; p += dir;
+ }
+ return p;
+}
+
+/*
+ * Write blanks over part of a string.
+ * Don't overwrite end-of-line characters.
+ */
+void
+writeblanks(start, end)
+ char *start;
+ char *end;
+{ char *p;
+ for ( p = start; p < end; p++ )
+ if ( *p != '\r' && *p != '\n' ) *p = ' ';
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ * 0 - definitely not a function definition;
+ * 1 - definitely a function definition;
+ * 2 - definitely a function prototype (NOT USED);
+ * -1 - may be the beginning of a function definition,
+ * append another line and look again.
+ * The reason we don't attempt to convert function prototypes is that
+ * Ghostscript's declaration-generating macros look too much like
+ * prototypes, and confuse the algorithms.
+ */
+int
+test1(buf)
+ char *buf;
+{ register char *p = buf;
+ char *bend;
+ char *endfn;
+ int contin;
+ if ( !isidfirstchar(*p) )
+ return 0; /* no name at left margin */
+ bend = skipspace(buf + strlen(buf) - 1, -1);
+ switch ( *bend )
+ {
+ case ';': contin = 0 /*2*/; break;
+ case ')': contin = 1; break;
+ case '{': return 0; /* not a function */
+ case '}': return 0; /* not a function */
+ default: contin = -1;
+ }
+ while ( isidchar(*p) ) p++;
+ endfn = p;
+ p = skipspace(p, 1);
+ if ( *p++ != '(' )
+ return 0; /* not a function */
+ p = skipspace(p, 1);
+ if ( *p == ')' )
+ return 0; /* no parameters */
+ /* Check that the apparent function name isn't a keyword. */
+ /* We only need to check for keywords that could be followed */
+ /* by a left parenthesis (which, unfortunately, is most of them). */
+ { static char *words[] =
+ { "asm", "auto", "case", "char", "const", "double",
+ "extern", "float", "for", "if", "int", "long",
+ "register", "return", "short", "signed", "sizeof",
+ "static", "switch", "typedef", "unsigned",
+ "void", "volatile", "while", 0
+ };
+ char **key = words;
+ char *kp;
+ int len = endfn - buf;
+ while ( (kp = *key) != 0 )
+ { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+ return 0; /* name is a keyword */
+ key++;
+ }
+ }
+ return contin;
+}
+
+/* Convert a recognized function definition or header to K&R syntax. */
+int
+convert1(buf, out, header, convert_varargs)
+ char *buf;
+ FILE *out;
+ int header; /* Boolean */
+ int convert_varargs; /* Boolean */
+{ char *endfn;
+ register char *p;
+ char **breaks;
+ unsigned num_breaks = 2; /* for testing */
+ char **btop;
+ char **bp;
+ char **ap;
+ char *vararg = 0;
+ /* Pre-ANSI implementations don't agree on whether strchr */
+ /* is called strchr or index, so we open-code it here. */
+ for ( endfn = buf; *(endfn++) != '('; ) ;
+top: p = endfn;
+ breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+ if ( breaks == 0 )
+ { /* Couldn't allocate break table, give up */
+ fprintf(stderr, "Unable to allocate break table!\n");
+ fputs(buf, out);
+ return -1;
+ }
+ btop = breaks + num_breaks * 2 - 2;
+ bp = breaks;
+ /* Parse the argument list */
+ do
+ { int level = 0;
+ char *lp = NULL;
+ char *rp;
+ char *end = NULL;
+ if ( bp >= btop )
+ { /* Filled up break table. */
+ /* Allocate a bigger one and start over. */
+ free((char *)breaks);
+ num_breaks <<= 1;
+ goto top;
+ }
+ *bp++ = p;
+ /* Find the end of the argument */
+ for ( ; end == NULL; p++ )
+ { switch(*p)
+ {
+ case ',':
+ if ( !level ) end = p;
+ break;
+ case '(':
+ if ( !level ) lp = p;
+ level++;
+ break;
+ case ')':
+ if ( --level < 0 ) end = p;
+ else rp = p;
+ break;
+ case '/':
+ p = skipspace(p, 1) - 1;
+ break;
+ default:
+ ;
+ }
+ }
+ /* Erase any embedded prototype parameters. */
+ if ( lp )
+ writeblanks(lp + 1, rp);
+ p--; /* back up over terminator */
+ /* Find the name being declared. */
+ /* This is complicated because of procedure and */
+ /* array modifiers. */
+ for ( ; ; )
+ { p = skipspace(p - 1, -1);
+ switch ( *p )
+ {
+ case ']': /* skip array dimension(s) */
+ case ')': /* skip procedure args OR name */
+ { int level = 1;
+ while ( level )
+ switch ( *--p )
+ {
+ case ']': case ')': level++; break;
+ case '[': case '(': level--; break;
+ case '/': p = skipspace(p, -1) + 1; break;
+ default: ;
+ }
+ }
+ if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+ { /* We found the name being declared */
+ while ( !isidfirstchar(*p) )
+ p = skipspace(p, 1) + 1;
+ goto found;
+ }
+ break;
+ default: goto found;
+ }
+ }
+found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+ { if ( convert_varargs )
+ { *bp++ = "va_alist";
+ vararg = p-2;
+ }
+ else
+ { p++;
+ if ( bp == breaks + 1 ) /* sole argument */
+ writeblanks(breaks[0], p);
+ else
+ writeblanks(bp[-1] - 1, p);
+ bp--;
+ }
+ }
+ else
+ { while ( isidchar(*p) ) p--;
+ *bp++ = p+1;
+ }
+ p = end;
+ }
+ while ( *p++ == ',' );
+ *bp = p;
+ /* Make a special check for 'void' arglist */
+ if ( bp == breaks+2 )
+ { p = skipspace(breaks[0], 1);
+ if ( !strncmp(p, "void", 4) )
+ { p = skipspace(p+4, 1);
+ if ( p == breaks[2] - 1 )
+ { bp = breaks; /* yup, pretend arglist is empty */
+ writeblanks(breaks[0], p + 1);
+ }
+ }
+ }
+ /* Put out the function name and left parenthesis. */
+ p = buf;
+ while ( p != endfn ) putc(*p, out), p++;
+ /* Put out the declaration. */
+ if ( header )
+ { fputs(");", out);
+ for ( p = breaks[0]; *p; p++ )
+ if ( *p == '\r' || *p == '\n' )
+ putc(*p, out);
+ }
+ else
+ { for ( ap = breaks+1; ap < bp; ap += 2 )
+ { p = *ap;
+ while ( isidchar(*p) )
+ putc(*p, out), p++;
+ if ( ap < bp - 1 )
+ fputs(", ", out);
+ }
+ fputs(") ", out);
+ /* Put out the argument declarations */
+ for ( ap = breaks+2; ap <= bp; ap += 2 )
+ (*ap)[-1] = ';';
+ if ( vararg != 0 )
+ { *vararg = 0;
+ fputs(breaks[0], out); /* any prior args */
+ fputs("va_dcl", out); /* the final arg */
+ fputs(bp[0], out);
+ }
+ else
+ fputs(breaks[0], out);
+ }
+ free((char *)breaks);
+ return 0;
+}
diff --git a/dviware/dvgtk/c-auto.h.in b/dviware/dvgtk/c-auto.h.in
new file mode 100644
index 0000000000..56c2025d1b
--- /dev/null
+++ b/dviware/dvgtk/c-auto.h.in
@@ -0,0 +1,126 @@
+/* c-auto.h.in. Generated automatically from configure.in by autoheader. */
+/* acconfig.h -- used by autoheader when generating c-auto.h.in.
+
+ If you're thinking of editing acconfig.h to fix a configuration
+ problem, don't. Edit the c-auto.h file created by configure,
+ instead. Even better, fix configure to give the right answer. */
+
+/* kpathsea/configure.in tests for these functions with
+ kb_AC_KLIBTOOL_REPLACE_FUNCS, and naturally Autoheader doesn't know
+ about that macro. Since the shared library stuff is all preliminary
+ anyway, I decided not to change Autoheader, but rather to hack them
+ in here. */
+#undef HAVE_BASENAME
+#undef HAVE_PUTENV
+#undef HAVE_STRCASECMP
+#undef HAVE_STRTOL
+#undef HAVE_STRSTR
+
+
+/* Define if the closedir function returns void instead of int. */
+#undef CLOSEDIR_VOID
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define if the setvbuf function takes the buffering type as its second
+ argument and the buffer pointer as the third, as on System V
+ before release 3. */
+#undef SETVBUF_REVERSED
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define if your putenv doesn't waste space when the same environment
+ variable is assigned more than once, with different (malloced)
+ values. This is true only on NetBSD/FreeBSD, as far as I know. See
+ xputenv.c. */
+#undef SMART_PUTENV
+
+/* Define if you are using GNU libc or otherwise have global variables
+ `program_invocation_name' and `program_invocation_short_name'. */
+#undef HAVE_PROGRAM_INVOCATION_NAME
+
+/* all: Define to enable running scripts when missing input files. */
+#define MAKE_TEX_MF_BY_DEFAULT 0
+#define MAKE_TEX_PK_BY_DEFAULT 0
+#define MAKE_TEX_TEX_BY_DEFAULT 0
+#define MAKE_TEX_TFM_BY_DEFAULT 0
+#define MAKE_OMEGA_OFM_BY_DEFAULT 0
+#define MAKE_OMEGA_OCP_BY_DEFAULT 0
+
+/* dvgtk: Defined if compiler supports prototypes */
+#undef PROTOTYPES
+
+/* Define if you have the basename function. */
+#undef HAVE_BASENAME
+
+/* Define if you have the bcopy function. */
+#undef HAVE_BCOPY
+
+/* Define if you have the getwd function. */
+#undef HAVE_GETWD
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtol function. */
+#undef HAVE_STRTOL
+
+/* Define if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/dviware/dvgtk/configure b/dviware/dvgtk/configure
new file mode 100644
index 0000000000..045ca979e7
--- /dev/null
+++ b/dviware/dvgtk/configure
@@ -0,0 +1,2544 @@
+#! /bin/sh
+
+# From configure.in Revision: 0.2
+
+
+
+
+
+
+
+
+
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared build shared libraries [default=no]"
+ac_help="$ac_help
+ --enable-static build shared libraries [default=yes]"
+ac_help="$ac_help
+ --without-maketexmf-default do not run MakeTeXMF if MF source missing"
+ac_help="$ac_help
+ --without-maketexpk-default do not run MakeTeXPK if PK font missing"
+ac_help="$ac_help
+ --without-maketextfm-default do not run MakeTeXTFM if TFM file missing"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=dvgt.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 && (ls -l conftest | grep x) >/dev/null 2>&1'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:550: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:579: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:627: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 && (ls -l conftest | grep x) >/dev/null 2>&1'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 637 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:661: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:666: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:675: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:690: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=`pwd`/$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=`pwd`/$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:747: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall installbsd scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:797: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:829: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 834 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:842: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:867: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 875 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:908: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 916 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:950: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 965 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:971: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 982 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1011: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1016 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1041 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1059 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1080 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
+echo "configure:1115: checking whether closedir returns void" >&5
+if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_closedir_void=yes
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1123 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_header_dirent>
+int closedir(); main() { exit(closedir(opendir(".")) != 0); }
+EOF
+if { (eval echo configure:1129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_closedir_void=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_closedir_void=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_closedir_void" 1>&6
+if test $ac_cv_func_closedir_void = yes; then
+ cat >> confdefs.h <<\EOF
+#define CLOSEDIR_VOID 1
+EOF
+
+fi
+
+for ac_hdr in assert.h float.h limits.h memory.h pwd.h stdlib.h \
+ string.h sys/param.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1156: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1161 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1198: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1231: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`$ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+
+#
+echo $ac_n "checking for libtool object types""... $ac_c" 1>&6
+echo "configure:1255: checking for libtool object types" >&5
+#
+## Check that the klibtool script is in ac_aux_dir. Don't bother to
+# scan PATH. For one thing, if we found it somewhere there, we couldn't
+# use that directory to put the config file ... and that's what we need
+# to do, to avoid having to configure in every subdirectory.
+LIBTOOL=$ac_aux_dir/klibtool
+
+if test ! -r $LIBTOOL; then
+ { echo "configure: error: klibtool not in $ac_aux_dir, goodbye" 1>&2; exit 1; }
+ exit 1
+fi
+#
+## Argument parsing: we support --enable-shared and --enable-static.
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ :
+else
+ enable_shared=no
+fi
+
+#
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ :
+else
+ enable_static=yes
+fi
+
+#
+# If they explicitly --enable-static, make that the link type.
+# More commonly, they will just --enable-shared; make that the link type.
+# In either case, prepend to any existing LIBTOOL_OBJTYPES.
+# If they really want to build both and link statically,
+# then they set LIBTOOL_OBJTYPES to SHARED and --enable-static.
+test "$enable_static" = yes && LIBTOOL_OBJTYPES=STATIC:$LIBTOOL_OBJTYPES
+test "$enable_shared" = yes && LIBTOOL_OBJTYPES=SHARED:$LIBTOOL_OBJTYPES
+# Don't bother to remove the trailing :, it'll be ignored.
+#
+## Finally: Run the klibtool configure command.
+LIBTOOL_OBJTYPES=$LIBTOOL_OBJTYPES RANLIB=$RANLIB \
+ $LIBTOOL --config-dir $ac_aux_dir configure "$host"
+echo "$ac_t""$LIBTOOL_OBJTYPES" 1>&6
+
+ for ac_func in basename putenv strcasecmp strtol strstr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1304: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1309 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LTLIBOBJS="$LTLIBOBJS $ac_func.lo"
+fi
+done
+
+
+
+for ac_func in bcopy getwd
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1362: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1367 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1416: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1421 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1470: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+
+# This is a GNU libc invention.
+echo $ac_n "checking whether program_invocation_name is predefined""... $ac_c" 1>&6
+echo "configure:1493: checking whether program_invocation_name is predefined" >&5
+if eval "test \"`echo '$''{'kb_cv_var_program_inv_name'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1498 "configure"
+#include "confdefs.h"
+
+int main() {
+main() { program_invocation_name = "love"; }
+; return 0; }
+EOF
+if { (eval echo configure:1505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ kb_cv_var_program_inv_name=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ kb_cv_var_program_inv_name=no
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$kb_cv_var_program_inv_name" 1>&6
+if test "$kb_cv_var_program_inv_name" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PROGRAM_INVOCATION_NAME 1
+EOF
+
+fi
+
+# Some BSD putenv's, e.g., FreeBSD, do malloc/free's on the environment.
+# This test program is due to Mike Hibler <mike@cs.utah.edu>.
+# We don't actually need to run this if we don't have putenv, but it
+# doesn't hurt.
+echo $ac_n "checking whether putenv uses malloc""... $ac_c" 1>&6
+echo "configure:1529: checking whether putenv uses malloc" >&5
+if eval "test \"`echo '$''{'kb_cv_func_putenv_malloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ kb_cv_func_putenv_malloc=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1537 "configure"
+#include "confdefs.h"
+
+#define VAR "YOW_VAR"
+#define STRING1 "GabbaGabbaHey"
+#define STRING2 "Yow!!" /* should be shorter than STRING1 */
+extern char *getenv (); /* in case char* and int don't mix gracefully */
+main ()
+{
+ char *str1, *rstr1, *str2, *rstr2;
+ str1 = getenv (VAR);
+ if (str1)
+ exit (1);
+ str1 = malloc (strlen (VAR) + 1 + strlen (STRING1) + 1);
+ if (str1 == 0)
+ exit (2);
+ strcpy (str1, VAR);
+ strcat (str1, "=");
+ strcat (str1, STRING1);
+ if (putenv (str1) < 0)
+ exit (3);
+ rstr1 = getenv (VAR);
+ if (rstr1 == 0)
+ exit (4);
+ rstr1 -= strlen (VAR) + 1;
+ if (strncmp (rstr1, VAR, strlen (VAR)))
+ exit (5);
+ str2 = malloc (strlen (VAR) + 1 + strlen (STRING2) + 1);
+ if (str2 == 0 || str1 == str2)
+ exit (6);
+ strcpy (str2, VAR);
+ strcat (str2, "=");
+ strcat (str2, STRING2);
+ if (putenv (str2) < 0)
+ exit (7);
+ rstr2 = getenv (VAR);
+ if (rstr2 == 0)
+ exit (8);
+ rstr2 -= strlen (VAR) + 1;
+#if 0
+ printf ("rstr1=0x%x, rstr2=0x%x\n", rstr1, rstr2);
+ /*
+ * If string from first call was reused for the second call,
+ * you had better not do a free on the first string!
+ */
+ if (rstr1 == rstr2)
+ printf ("#define SMART_PUTENV\n");
+ else
+ printf ("#undef SMART_PUTENV\n");
+#endif
+ exit (rstr1 == rstr2 ? 0 : 1);
+}
+EOF
+if { (eval echo configure:1590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ kb_cv_func_putenv_malloc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ kb_cv_func_putenv_malloc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$kb_cv_func_putenv_malloc" 1>&6
+if test $kb_cv_func_putenv_malloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define SMART_PUTENV 1
+EOF
+
+fi
+
+# Common --with and --enable options.
+
+# Check whether --with-maketexmf-default or --without-maketexmf-default was given.
+if test "${with_maketexmf_default+set}" = set; then
+ withval="$with_maketexmf_default"
+ :
+else
+ enableval=yes
+fi
+
+if test $enableval = yes; then
+ cat >> confdefs.h <<\EOF
+#define MAKE_TEX_MF_BY_DEFAULT 1
+EOF
+
+fi
+# Check whether --with-maketexpk-default or --without-maketexpk-default was given.
+if test "${with_maketexpk_default+set}" = set; then
+ withval="$with_maketexpk_default"
+ :
+else
+ enableval=yes
+fi
+
+if test $enableval = yes; then
+ cat >> confdefs.h <<\EOF
+#define MAKE_TEX_PK_BY_DEFAULT 1
+EOF
+
+fi
+# Check whether --with-maketextfm-default or --without-maketextfm-default was given.
+if test "${with_maketextfm_default+set}" = set; then
+ withval="$with_maketextfm_default"
+ :
+else
+ enableval=yes
+fi
+
+if test $enableval = yes; then
+ cat >> confdefs.h <<\EOF
+#define MAKE_TEX_TFM_BY_DEFAULT 1
+EOF
+
+fi
+
+
+# -*- m4 -*-
+# Based on aclocal.m4 from wget-1.4.4 by Hrvoje Niksic
+
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:1685: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# HP-UX -Aa -D_HPUX_SOURCE
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" "-Aa -D_HPUX_SOURCE" -qlanglvl=ansi -std1 "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 1701 "configure"
+#include "confdefs.h"
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+int main() {
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+; return 0; }
+EOF
+if { (eval echo configure:1719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_prog_cc_stdc="$ac_arg"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+
+
+echo $ac_n "checking for function prototypes""... $ac_c" 1>&6
+echo "configure:1741: checking for function prototypes" >&5
+if test "$am_cv_prog_cc_stdc" != no; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define PROTOTYPES 1
+EOF
+
+ U= ANSI2KNR=
+else
+ echo "$ac_t""no" 1>&6
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1754: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1759 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1767: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1784 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1802 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1823 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+ for ac_hdr in string.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1861: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1866 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1871: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+
+for ac_hdr in termio.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1904: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1909 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1942: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 1949 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 1964 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1975: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1995 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:2008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2032: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2037 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6
+echo "configure:2066: checking whether setvbuf arguments are reversed" >&5
+if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2074 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+/* If setvbuf has the reversed format, exit 0. */
+main () {
+ /* This call has the arguments reversed.
+ A reversed system may check and see that the address of main
+ is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */
+ if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0)
+ exit(1);
+ putc('\r', stdout);
+ exit(0); /* Non-reversed systems segv here. */
+}
+EOF
+if { (eval echo configure:2088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_setvbuf_reversed=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_setvbuf_reversed=no
+fi
+rm -fr conftest*
+fi
+
+rm -f core core.* *.core
+fi
+
+echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6
+if test $ac_cv_func_setvbuf_reversed = yes; then
+ cat >> confdefs.h <<\EOF
+#define SETVBUF_REVERSED 1
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2112: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2117 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:2134: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile c-auto.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CPP@%$CPP%g
+s%@RANLIB@%$RANLIB%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LTLIBOBJS@%$LTLIBOBJS%g
+s%@U@%$U%g
+s%@ANSI2KNR@%$ANSI2KNR%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ # Replace lines of the form ac_include foo with the contents of foo:
+ # first, from the ac_include lines construct a list of sed
+ # commands to remove them, and include the files; then run sed.
+ # Have to use sed because old (Ultrix, SunOS) awk does not support
+ # getline or system. (Anyway, configure scripts aren't supposed to use awk.)
+ # Use \@...@<cmd> form of sed address because the filename may contain /.
+ # Can't use only one -e and commands {dr foo} because foo has to be last.
+ # Use @e initially instead of -e because GNU echo has a -e option.
+ # Use `X' to mean a bunch of backslashes; this is for FreeBSD.
+ #
+ # No support for the multiple-output file :-separated stuff.
+ #
+ file_substs=`sed -n \
+"/^ac_include/s%ac_include[ ]*\(.*\)%@e 'X@^&@r \1' -e 'X@^&@d'%p" \
+ $ac_given_srcdir/$ac_file_in`
+ if test -n "$file_substs"; then
+ # Change @e back to -e and X@^ to \@^.
+ file_subst_cmd="sed `echo $file_substs \
+ | sed -e 's/@e/-e/g' -e 's/X@^/\\\@^/g'`"
+ else
+ # If no substitutions and hence no sed commands, don't choke.
+ file_subst_cmd=cat
+ fi
+ # cd into the srcdir because the files being included more or less
+ # must be part of the distribution. I can't find any way to do
+ # variable substitution in the sed commands (so the user could have,
+ # e.g., $top_srcdir in their ac_include line).
+ (cd $ac_given_srcdir && eval $file_subst_cmd $ac_file_in) \
+ | sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="c-auto.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/dviware/dvgtk/configure.in b/dviware/dvgtk/configure.in
new file mode 100644
index 0000000000..118ae24886
--- /dev/null
+++ b/dviware/dvgtk/configure.in
@@ -0,0 +1,30 @@
+dnl -*- m4 -*-
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl dvgtk - Tomasz J. Cholewo <t.cholewo@ieee.org>
+dnl $Id: configure.in,v 0.2 1997/03/28 03:20:02 tjchol01 Exp $
+dnl
+AC_REVISION($Revision: 0.2 $)dnl
+AC_INIT(dvgt.c)
+
+sinclude(../kpathsea/common.ac)
+sinclude(./ansi2knr.ac)
+
+dnl Check if we can handle prototypes. It is a bit tricky to
+dnl change compiler flags after most of detection stuff happened in common.ac.
+dnl It should be done somewhere in its middle.
+AM_C_PROTOTYPES
+
+dnl Checks for header files.
+AC_CHECK_HEADERS(termio.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_BIGENDIAN
+AC_TYPE_SIZE_T
+
+dnl Checks for library functions.
+AC_FUNC_SETVBUF_REVERSED
+AC_TYPE_SIGNAL
+
+dnl Create output
+AC_OUTPUT(Makefile)
diff --git a/dviware/dvgtk/defaults.h b/dviware/dvgtk/defaults.h
new file mode 100644
index 0000000000..d9aae39780
--- /dev/null
+++ b/dviware/dvgtk/defaults.h
@@ -0,0 +1,32 @@
+/* defaults.h - site configuration file for dvgtk
+ $Id: defaults.h,v 0.1 1997/03/24 01:46:56 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __DEFAULTS_H__
+#define __DEFAULTS_H__
+
+/* Initial default values for various dvgtk quantities */
+
+/* MetaFont mode used for MakeTeXPK */
+#define DEF_MFMODE "cx"
+
+/* Resolution */
+#define DEF_XRES 300.0 /* Horizontal resolution in dpi */
+#define DEF_YRES 300.0 /* Vertical resolution in dpi */
+
+/* PK and TFM of last resort */
+#define DEF_DUMMY_PK "cmr10.300pk"
+#define DEF_DUMMY_TFM "cmr10.tfm"
+#define DEF_DUMMY "cmr10"
+
+/* Paper size: change 1 to 0 to use A4 paper */
+#if 1
+#define DEF_PAPERWD "8.5in" /* letter paper width */
+#define DEF_PAPERHT "11in" /* letter paper height */
+#else
+#define DEF_PAPERWD "210mm" /* A4 paper width */
+#define DEF_PAPERHT "297mm" /* A4 paper height */
+#endif
+
+#endif /* __DEFAULTS_H__ */
diff --git a/dviware/dvgtk/doc/CHANGES b/dviware/dvgtk/doc/CHANGES
new file mode 100644
index 0000000000..3f5acd5c0b
--- /dev/null
+++ b/dviware/dvgtk/doc/CHANGES
@@ -0,0 +1,448 @@
+CHANGES - dvgt up to 3.51 - 18:30 GMT +10:00 Wed 25 August 1993.
+
+----------------------------------------------------------------------
+dvgt 3.4 (3 mod 4) : changes not recorded here.
+----------------------------------------------------------------------
+
+1. - 18:17 GMT +10:00 Thu 18 Mar 1993 -
+options.c :
+ Added DV_TERM environment variable, to override TERM.
+
+2. - Sun 2 May 1993 -
+fontreader.c, lstring.c, lstring.h :
+ Length specified strings introduced to make the TFM and PK font
+ file specification string formation more controlled.
+
+3. - Sun 2 May 1993 -
+ Using strncpy widely in place of strcpy, to keep string memory
+ accesses within bounds.
+
+4. - 17:48 GMT +10:00 Mon 3 May 1993 -
+ncsatelvdu.c, vduinterface.c :
+ Added Vijay's (vijay@ncst.ernet.in) NCSA Telnet driver.
+ Now my picture is clear.
+
+5. - About or before Sun 9 May 1993 -
+defaults.h :
+ Added constant "DEF_DUMMY_TFM", in case I implement such a thing.
+
+6. - 21:22 GMT +10:00 Sun 9 May 1993 -
+All drivers and other files that referred to "tek4010vdu" :
+ Renamed: tek4010vdu.c -> tek4010emu.c
+ tek4010vdu.h -> tek4010emu.h
+ This was because some users have been misled by the name to think
+ that these files were for a true TEK4010 terminal. But they are
+ not: they are only for the use of the TEK4010 emulating drivers.
+
+7. - 21:20 GMT +10:00 Mon 10 May 1993 -
+In all *.c files that use exit() :
+ All deliberate exits produce a message.
+
+ (I don't account for outside interruptions, such as power failures.)
+
+8. - 21:24 GMT +10:00 Mon 10 May 1993 -
+ All message text is logged in a file named `<dvistem>.vlg',
+ where the DVI file is named `<dvistem>.dvi'.
+ If that log file cannot be opened, then `dvgt.log' is opened.
+ If then `dvgt.log' cannot be opened, dvgt exits with a message.
+
+9. - Tue 11 May 1993 -
+fontreader.c :
+ TFM and PK font paths may now contain multiple directories.
+ For example, "setenv PKFONTS .:/usr/local/lib/tex/fonts/tmp"
+ allows searching in current directory, then in the other location.
+
+10. - Tue 11 May 1993 -
+fontreader.c :
+ Dummy font's file specification is now formed in the same way
+ as other PK fonts.
+
+11. - 20:02 GMT +10:00 Wed 12 May 1993 -
+dvitovdu.c :
+ Inability to write a log file no longer exits dvgt.
+ Instead, logfile is set NULL, and subsequently ignored.
+ Some other exits deleted as due to non-fatal conditions.
+
+12. - 20:02 GMT +10:00 Wed 12 May 1993 -
+config.h, globals.h, dvitovdu.c, fontreader.c :
+ "bitmap_rec" replaced by "Word" which I typedef as int.
+ Bitmaps are dynamicaly allocated, so they can be much smaller
+ or much larger, as the case requires.
+
+13. - 22:06 GMT +10:00 Wed 12 May 1993 -
+fontreader.c :
+ Fatal message "Couldn't open dummy font!" is now written to the
+ terminal, after resetting VDU, and appears cleanly - at least
+ after use of the "ncsatel" vdu mode.
+
+14. - 22:06 GMT +10:00 Wed 12 May 1993 -
+dvitovdu.c :
+ The following signals are caught so that the screen may be reset
+ before exit: SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM.
+ Any other signal is also caught!
+
+15. - Fri 14 May 1993 -
+tek4010emu.c :
+ In Terse mode, i.e. in TEK4010ShowChar(), the unrepresented font
+ characters, previously shown as '?', are now displayed as
+ hexadecimal escape sequences. E.g., code 1 appears as '\01'.
+
+16. - Fri 14 May 1993 -
+dvitovdu.c :
+ 'N' and 'P' commands now page forward and back, to the next and
+ previous page, respectively.
+ So, the '<' and '>' commands are deleted.
+
+17. - Fri 14 May 1993 -
+dvitovdu.c :
+ Added control-L command to refresh screen.
+
+18. - Fri 14 May 1993 -
+dvitovdu.c :
+ Units are now changed by a 'C' command. The 'C' may be followed by
+ zero or more spaces, and then the unit name. (The actual unit names
+ are as before: IN, CM, MM, PT, BP, PC, BP, SP and PX.)
+
+19. - Fri 14 May 1993 -
+dvitovdu.c, help.h :
+ The '?' interactive command help is now integrated into the source
+ code, in "help.h", using a ShowText() function.
+
+20. - Sun 16 May 1993 -
+dvitovdu.c, tek4010emu.c :
+ The "F" (Full), "B" (Box) and "T" (Terse) commands are now toggles.
+ Any combination of these display modes is now accepted.
+ Change necessary to tek4010emu.c, to correct a faulty assumption at
+ the beginning of TEK4010ShowChar().
+
+21. - Sun 16 May 1993 -
+dvitovdu.c :
+ The "A" Auto window command is now a toggle.
+
+22. - Mon 17 May 1993 -
+dvitovdu.c :
+ BoxChar() is now used in place of FullCharPS in Full mode when a TFM
+ gives the Bounding Box information, because I prefer outlines to
+ solid rectangles.
+
+23. - Fri 21 May 1993 -
+fontreader.c, dvitovdu.c :
+ BuildFontSpec() and PixelTableRoutine() have been altered, so that
+ dvgt seeks a PK font first, then a TFM, then the dummy PK font.
+ Consequently, the PostScript prefix code and option are eliminated.
+
+24. - Fri 21 May 1993 -
+vdu.h, vduinterface.c, dvitovdu.c :
+ For each VDU, the value "vdu_clears_lines" is set true if the VDU
+ can clear a single line. The "ncsatel" driver cannot, due to a
+ property of the Tek4010 terminal and (I suppose) its emulators.
+ So, for the "ncsatel" vdu, when the Status lines should be updated,
+ the whole display is now updated.
+
+25. - Sun 23 May 1993 -
+userguide.tex, sysguide.tex, guidemacs.tex :
+ Updated Andrew Trevorrow's documentation to reflect Ian Dall's port
+ of DVItoVDU to C and features of dvgt 3.5.
+
+26. - Mon 24 May 1993 -
+In all files that used "__((void))" :
+ In "config.h", VOID is defined as "void" for ANSI C, empty otherwise.
+ All function and function pointer declarations and definitions
+ that used "__((void))" now use "(VOID)" instead.
+ This helps "tags" and "ctags" programs to identify functions
+ correctly. (It also marginally reduces source code size.)
+
+27. - Tue 25 May 1993 -
+options.c :
+ Fixed "-r" option to interpret "-r x,y" to set the X and Y resolutions
+ to x and y respectively. Retained "-r x" to set the X and Y resolutions
+ to the common value x, and "-r" to display the default resolutions.
+
+28. - Tue 25 May 1993 -
+defaults.h, options.c:
+ Renamed the constant DEF_HELP_FILE to DEF_CMD_HELP,
+ and renamed the environment variable DV_HELP to DV_CMD_HELP.
+
+29. - Tue 25 May 1993 -
+defaults.h, options.c, fontreader.c :
+ Fall back to dummy TFM, in case dummy PK not found.
+ Added env. var. DV_DUMMY_TFM.
+ Renamed DV_DUMMYFONT to DV_DUMMY_PK.
+
+30. - Wed 26 May 1993 -
+options.c, defaults.h :
+ Added DV_PAPERWD and DV_PAPERHT env. vars.
+ These and DEF_PAPERWD and DEF_PAPERHT now accept dimensions,
+ else they default to inches.
+
+31. - Wed 26 May 1993 -
+defaults.h, options.c :
+ Renamed DEF_IMMEDIATE_HELP to DEF_IMMED_HELP.
+
+32. - Wed 26 May 1993 -
+dvgt/help directory:
+ Renamed "help" file to "cmd.help".
+
+33. - Sun 30 May 1993 -
+defaults.h, options.c :
+ Renamed DEF_XRESOLUTION to DEF_XRES and DEF_YRESOLUTION to DEF_YRES.
+ Renamed DEF_PSPREFIX to DEF_PS_PREFIX.
+
+34. - Sun 30 May 1993 -
+options.c :
+ Resolution option "-r" now allows one or two ("xres,yres") arguments.
+ Added DV_RES environment variable for both X and Y resolutions.
+ Renamed env. var. DV_PSPREFIX to DV_PS_PREFIX.
+
+35. - Mon 31 May 1993 -
+dvireader.h, fontreader.c, dvitovdu.c :
+ Added "honest" field to "fontinfo" structure. This records whether
+ the true font (for the given fontname) is specified in the fontspec.
+ Now have "psfont", "pkfont" and "honest" fields to guide treatment
+ of fonts and their description by ShowStatistics.
+
+36. - Mon 31 May 1993 -
+dvitovdu.c :
+ ShowStatistics shows either "H" or "S", and either "P" or "K" or "T",
+ to indicate whether the font used is Honest or a Substitute, and
+ whether it is a PostScript font TFM, a PK font bitmap, or a
+ non-PostScript TFM, respectively.
+ ShowStatistics also shows fontsize (in pt), and the font description
+ is more compact, to allow for the extra info. Attempted to align
+ lines of info. for different fonts.
+
+37. - Mon 31 May 1993 -
+fontreader.c :
+ Font search order is now:
+ PK -> PS -> TFM -> dummy PK -> dummy TFM -> fail.
+
+38. - Mon 31 May 1993 -
+dvitovdu.c :
+ Added time info (ANSI C only), to logfile.
+
+39. - Tue 1 June 1993 -
+dvgt/src and dvgt directories:
+ Moved CHANGES and TODO files from dvgt/src to dvgt directory.
+
+40. - Tue 1 June 1993 -
+dvitovdu.c :
+ Default Left, Right, Up and Down movements are by _half_ the window
+ dimension (instead of by the full dimension).
+
+41. - Tue 1 June 1993 -
+dvitovdu.c :
+ Zoom In/Out to/from Centre of window (instead of Top Left corner).
+
+42. - Wed 2 June 1993 -
+fontreader.c :
+ Multiple PS font prefixes, separated by same characters (in DIRSEP)
+ as (PK and TFM) directories. In dvgt 3.5, which is for unix,
+ DIRSEP = ":", a colon.
+
+43. - Thu 3 June 1993 -
+fontreader.c, dvitovdu.c :
+ Font search is now:
+ PK -> PS -> dummy PK -> TFM -> dummy TFM -> DVI Terse.
+ So, if no other representation can be found, then a missing font
+ is guesstimated using the design size in the DVI file, and displayed
+ as in Terse mode. Other fonts are unaffected.
+ Currently, I estimate character size in design size units as 1 unit
+ high and 0.5 unit wide. This seems not too far off-mark for normal
+ text; preview of "example.dvi" is too wide by about one part in
+ eight.
+ (Another possibility, allowed by the DVI Standard, Level 0, is to
+ ignore such fonts entirely, but that would give the user less
+ information.)
+
+44. - Fri 25 June 1993 -
+options.h, options.c, fontreader.c, dvitovdu.c :
+ C variable "fontdir" renamed to "pkdir".
+
+45. - Mon 19 Jul 1993 -
+help and src directories:
+ Updated cmd.hlp, immed.hlp, options.hlp, and help.h, for dvgt 3.5's
+commands, options, and VDU types.
+
+46. - Wed 21 Jul 1993 -
+doc directory:
+ Updated sysguide.tex, userguide.tex to reflect dvgt 3.5's options
+and commands.
+
+47. - Wed 21 Jul 1993 -
+version.h, dvitovdu.h, help.h :
+ Renamed C quantity "version" to "dvgt_version", because of clash
+with an enumerated type of the same name in System V's <math.h>.
+
+48. - Wed 21 Jul 1993 -
+dvitovdu.c :
+ Renamed C static variable "signals" to "common_signals", in case of
+a clash, and eliminated the "extern int signals" line.
+
+49. - Wed 21 Jul 1993 -
+Makefile.dvgt :
+ Added "regisvdu.h" to list of files to distribute. (Bad oversight!)
+
+50. - Wed 21 Jul 1993 -
+fontreader.c :
+ Changed test of the boolean function OpenFontFile from the
+erroneous "< 0" to the correct test for true.
+
+51. - Wed 21 Jul 1993 -
+Makefile.sun :
+ Removed references to site specific include directories.
+
+52. - Mon 2 Aug 1993 -
+unixio.c :
+ In non-BSD OS's, used TCGETA, TCSETAW with ioctl.
+ (Suggested by Guy Harris.)
+
+53. - Mon 2 Aug 1993 -
+unixio.c, Makefile.aix, Makefile.sun :
+ Used "string" in unixio.c; so add dependency on "globals.h".
+
+54. - Mon 2 Aug 1993 -
+src/dvitovdu.c, doc/userguide.tex :
+ Reverted to ZI, ZO holding window's top left;
+introduced ZCI, ZCO to hold window's centre.
+
+55. - Tue 3 Aug 1993 -
+screenio.c :
+ MesgLine now unsets raw mode, if it's on (so that NL -> CR+NL),
+and finally restores it, if it was.
+
+56. - Tue 3 Aug 1993 -
+doc directory :
+sysguide.tex, userguide.tex updated.
+
+57. - Tue 3 Aug 1993 -
+dvitovdu.c :
+ Defer call to InitScreenIO, so that "fprintf (stderr, ...);" will
+have the normal line discipline.
+
+58. - Wed 4 Aug 1993 -
+dvitovdu.c, dvireader.c, options.c, vdu.c :
+ Delete old DEBUG code that wrtes to stderr.
+
+59. - Wed 4 Aug 1993 -
+unixio.c, unixio.h, screenio.c :
+ Separate initial and temporary tty state.
+
+60. - Wed 4 Aug 1993 -
+dvitovdu.c, dvireader.c, (fontreader.c), (options.c), vdu.c :
+ Ensure that RestoreTerminal is called immediately before each exit.
+
+61. - Wed 4 Aug 1993 -
+options.c :
+ In DimenPixels, account for unimplemented unit, in the newer code.
+
+62. - Wed 4 Aug 1993 -
+dvitovdu.c :
+ In main, save initial terminal settings, early, using save_init_tty.
+
+----------------------------------------------------------------------
+RELEASE of dvgt 3.5 to SHSU (hence to CTAN).
+----------------------------------------------------------------------
+
+63. - Mon 16 Aug 1993 -
+new.h :
+ Deleted #ifndef Malloc ... #endif around #include "config.h" .
+ Replaced #ifdef __STDC__ by #ifdef HAS_STDLIB .
+
+64. - Mon 16 Aug 1993 -
+config.h :
+ Big rearrangement and recoding, to allow for an ANSI compiler (eg,
+gcc) with a non-ANSI library (eg, Sun/OS 4.0 's BSD-like cc library).
+ Added #include <sys/file.h> and #include <sys/types.h> for when
+BSD is true.
+ Also for when BSD is true, added twelve further (non-ANSI style)
+function declarations.
+ Added <sys/types.h> also for non-BSD library with non-ANSI
+compiler.
+ Now #define GNUC_LIB if and only if ANSI compiler with non-BSD
+library.
+
+65. - Tue 17 Aug 1993 -
+options.c :
+ Moved #define NEW_DIMEN_PIXELS to top of file.
+ Deleted <stddef.h> inclusion and getenv() declaration, as config.h
+already handles those.
+ Added code to protect (eg, ANSI C compilers') use of constant
+storage for strings from Sun/OS 4.0 's library's sscanf function's
+use of ungetc.
+ Added ToLower debugging code.
+ Changed definition of ToLower to always check for isupper.
+ Deleted block from around ToLower and Luname.
+
+66. - Tue 17 Aug 1993 -
+Makefile.cc-sun :
+ New Makefile for Sun/OS 4.0 's non-ANSI compiler, "cc".
+ Mentions dependency on <sys/file.h> and <sys/types.h> .
+
+67. - Wed 18 Aug 1993 -
+dvitovdu.c, dvireader.c :
+ SetConversionFactor's magnification argument now has the
+interpretation that 1 corresponds to the document's normal size.
+Non-ANSI compilers don't convert int mag to double magnification,
+so dvitovdu.c now calls SetConversionFactor with its magnification
+argument = mag/1000.0, to coerce it to be double.
+
+68. - Wed 18 Aug 1993 -
+options.c :
+ Deleted ToLower debugging code.
+
+69. - Wed 18 Aug 1993 -
+config.h :
+ Deleted "#include <string.h>" from STDC, non-BSD case, because it
+duplicated that in the general non-BSD case.
+
+70. - Wed 18 Aug 1993 -
+version.h :
+ Version upped to "3.51".
+
+71. - Wed 18 Aug 1993 -
+Makefile.gcc :
+ New. (Based on gcc code in old "Makefile.sun".)
+
+72. - Wed 18 Aug 1993 -
+Makefile.sun :
+ Now refers only to Sun's "cc" compiler.
+ Deleted comments referring to <stddef.h>, <stdlib.h> and <unistd.h>.
+
+73. - Fri 20 Aug 1993 -
+options.c :
+ PK search now = TEXPKS || PKFONTS || TEXFONTS || DEF_PK_DIR.
+
+74. - Fri 20 Aug 1993 -
+new.h :
+ Deleted <malloc.h> code, because "config.h" already handles that.
+
+75. - Fri 20 Aug 1993 -
+TODO :
+ Added wish to "Make TFM, PK path and file spec. strings dynamic."
+
+76. - Fri 20 Aug 1993 -
+Makedist.dvgt :
+ Added line for "dvgt/src/Makefile.gcc".
+
+77. - Fri 20 Aug 1993 -
+README :
+ Refer to Makefile.gcc; change description of Makefile.sun.
+
+78. - Fri 20 Aug 1993 -
+Makedist.dvgt :
+ Added "sane" Bourne shell script for resetting terminal, in case
+dvgt leaves it seriously messed up.
+
+79. - Fri 20 Aug 1993 -
+misc/stdlib.h :
+ Emended non-ANSI function declarations.
+ Added headlines with date.
+
+80. - Wed 25 Aug 1993 -
+README, userguide.tex :
+ Updated for dvgt 3.51, specifically the use of TEXPKS.
+
+----------------------------------------------------------------------
+dvgt 3.51 : 3 mod 5 revision 1.
+----------------------------------------------------------------------
+
diff --git a/dviware/dvgtk/doc/Makefile b/dviware/dvgtk/doc/Makefile
new file mode 100644
index 0000000000..58e0c10bbe
--- /dev/null
+++ b/dviware/dvgtk/doc/Makefile
@@ -0,0 +1,24 @@
+# Makefile for DVItoVDU documents. 18:56 Tue 11 May 1993. Geoffrey Tobin.
+
+.tex.dvi:
+ tex $<
+
+dvi: guidemacs.tex example.dvi sysguide.dvi tripvdu.dvi userguide.dvi
+
+# AIX make is not very smart: it cannot follow the .tex.dvi line.
+# Sun/OS make has no trouble.
+
+example.dvi: example.tex
+ tex example
+
+sysguide.dvi: guidemacs.tex sysguide.tex
+ tex sysguide
+
+tripvdu.dvi: tripvdu.tex
+ tex tripvdu
+
+userguide.dvi: guidemacs.tex userguide.tex
+ tex userguide
+
+clean:
+ rm *.dvi *.log
diff --git a/dviware/dvgtk/doc/README b/dviware/dvgtk/doc/README
new file mode 100644
index 0000000000..3d7c29fbf5
--- /dev/null
+++ b/dviware/dvgtk/doc/README
@@ -0,0 +1,426 @@
+README - 18:22 GMT +10:00 Wed 25 August 1993 - Geoffrey Tobin.
+- for "dvgt 3.51",
+ alias: "DVItoVDU version 3.0, gt modification 5 revision 1".
+
+Addresses: ecsgrt@luxor.latrobe.edu.au
+ gt@ee.latrobe.edu.au
+
+
+DVItoVDU, also known as "dvitovdu", "dvi2vdu", and "dv", is a public
+domain screen previewer for TeX DVI files using PK fonts. It was
+invented long ago by Andrew Trevorrow (author also of OzTeX, a TeX
+for Macintoshes), and has passed through several hands since.
+
+"dvgt" is a modification of Ian Dall's "dv" (a C translation of a
+Pascal (or Modula-2 ?) version of DVItoVDU 3.0). Some bug fixes have
+been applied, and the source has been ported to the IBM Risc/6000
+under AIX using the "xlc" compiler. It is also compilable on Sparc 1
+workstations under Sun/OS using the Gnu C compiler, "gcc", and may
+- perhaps with minor changes - also compile under some traditional
+(Kernighan and Ritchie, _The C Programming Language_, first edition)
+C compilers.
+
+This previewer is neither sophisticated nor pretty, but it can drive
+a number of common visual display terminals, such as VT series, Gigi,
+Regis, VK100, VIS series, and terminals that emulate Tek4010. (Not a
+real Tek4010, sadly.) A full list of supported terminals is contained
+in the immediate help file, "immed.hlp", and in the "options.hlp"
+document.
+
+** Currently, those who wish to use a Tek4010 emulation are advised
+to try the terminal types kermit, ncsatel, tek4010, vis500, vis550,
+vis630 or vt640. **
+
+I first used dvgt on a Sun Sparc 1 to preview DVI files in Terse mode
+(like ascii) on a remote vt220 terminal. Now I use its "ncsatel"
+driver (coutesy of Vijay, vijay@ncst.ernet.in, in India) to view in
+Full (graphics) mode on a PC connected over NCSA Telnet to the dvgt
+host machine, using Tek4010 emulation. The Tek4010 emulation drivers
+kermit, ncsatel and tek4010 also work with MS-Kermit 3.12.
+
+
+NOTE WELL:
+
+1. Current directory (and upper-level file) structure is:
+
+ Makefile.dvgt dvgt/
+ CHANGES README TODO doc/ help/ misc/ src/
+
+The documents in doc/ are based on Andrew Trevorrow's Modula-2 version,
+but they now have been updated for dvgt 3.5. Not every version
+of DVItoVDU has the full collection of documents. Hopefully, they're
+all gathered here. If not, please lead me to any omitted files.
+
+The single file in the misc/ subdirectory, "stdlib.h", is inherited
+from Ian Dall's version. It's there in case someone wishes to port to
+a system that lacks a suitable header for the C standard library.
+However, it's not needed for either the AIX or the Sun/OS port.
+
+2. The "src" source directory's Makefile must be correct for your
+machine, operating system and compiler.
+
+Three Makefiles are provided:
+
+ Makefile.aix for IBM machines (such as the Risc/6000) running AIX.
+ Makefile.gcc for gcc (tested on Suns and Sparcs running Sun/OS 4 and 5).
+ Makefile.sun for Suns and Sparcs running Sun/OS, with Sun's non-ANSI cc.
+
+These can serve as templates for other Makefiles. (I made the AIX and
+gcc ones from the Sun Makefile.)
+
+Copy the appropriate one to "Makefile", then edit it to suit your
+site.
+
+3. The source header "defaults.h" needs to be customised for each site,
+as it contains absolute directory information. (Even though these
+paths may be overridden by environment variables, it's more convenient
+if they point to where the system manager puts the appropriate files.)
+
+(The files "dvitovdu.c" and "options.c" include "defaults.h".)
+
+4. The source header "config.h" also needs attention.
+
+Especially be sure that either LITTLE_ENDIAN or BIG_ENDIAN is defined
+correctly for your machine, and remember that if you define both, then
+LITTLE_ENDIAN will prevail.
+
+(The C source files use "config.h". Also, "unixio.h" assumes that
+"config.h" has been read before it.)
+
+5. In setting the environment variables on the system, or on your own
+account, be careful to set them sensibly. I once set DV_IMMED_HELP to
+point to a directory by mistake, and when I typed just "dvgt", instead
+of getting immediate help, I saw a line consisting of leading spaces
+and a dot.
+
+The C shell script, "dv-env", in the src directory, is a sample for
+setting dvgt's environment variables.
+
+6. Note that page drawing can (as in the original dvitovdu) be
+interrupted by a carriage return, but only _between_ characters and
+rules. A very large character or rule won't be interrupted, even
+though this means waiting for some time.
+
+7. To get the best appearance for dvgt's output when using it over
+MS-Kermit 3.12, set the following in your MSCUSTOM.INI :
+
+ set terminal flow-control none
+ set terminal graphics character-writing opaque
+ set terminal graphics cursor off
+
+The first line gets rid of most of the ^S and ^Q characters that may
+otherwise appear on the dvgt command line. The second causes message
+lines to overwrite opaquely, which makes the messages in certain
+drivers much more readable. The third renders the graphics cursor
+invisible.
+
+Because one ^S^Q pair still remains on my command line when I use
+MS-Kermit 3.12, despite the above precaution, I've made the ^Q and ^S
+characters into no-op commands in dvgt.
+
+
+BRIEF HISTORY.
+
+The initial C code for this version of DVItoVDU was copied from Ian
+Dall's site, augean.oz.au : pub/misc/dv.tar.Z. Ian had, as his source
+code seems to indicate, automatically translated it from Pascal.
+(Andrew Trevorrow wrote the original DVItoVDU in Modula-2.)
+
+A thorough history of the various versions of "dvitovdu", "dvi2vdu",
+and "dv" in the world is beyond the scope of this README file, and
+exceeds my competence.
+
+Version 3.4 was the first public release of dvgt. It was uploaded to
+
+ Niord.SHSU.edu
+
+and subsequently propagated to the CTAN sites:
+
+ ftp.shsu.edu
+ ftp.tex.ac.uk
+ ftp.uni-stuttgart.de
+
+
+SUMMARY of CHANGES to dvitovdu 3.0 in the "gt" MODS up to "mod 5".
+
+1. Commands.
+
+U (Up), D (Down), L (Left) and R (Right) now move by half a screen
+(instead of a full screen), to retain more context.
+
+The zoom commands, ZI and ZO, now take an optional argument, the zoom
+factor. The initial default zoom is 2. When a new zoom factor is
+specified, that becomes the new default value. This value is
+displayed at the far right in the top line of the screen.
+
+Whereas ZI and ZO maintain the top left of the window stationary,
+ZCI and ZCO zoom in and out relative to the window's centre.
+These have very nearly the same effects as DR ZI UL and DR ZO UL,
+respectively.
+
+Two new units commands, BP for big point, and SP for scaled point,
+have been added, because TeX has these, and because big point
+(1/72 inch) is the American standard point, used by PostScript.
+
+Units are now set by the C command, which allows zero or more
+spaces between it and the following unit. For example:
+
+ C IN
+ CMM
+ C PX
+
+The < and > commands have been deleted, in favor of N always paging
+forwards, and P paging back.
+
+The T (Terse), B (Box), F (Full) are now toggles, and any combination
+of these can be applied simultaneously. If all are off, then font
+characters will not show, but rules will.
+
+The A (Auto window scaling) command has been made a toggle.
+A+ and A- no longer exist.
+
+Control-L (^L, ascii character 12 decimal, 14 octal, C hexadecimal)
+is a new command to refresh the page. The usual command line parsing
+still applies, so the page is not refreshed until after a carriage
+return is typed.
+
+Control-Q (^Q) and Control-S (^S) do nothing.
+
+2. Help.
+
+There are now three help files, "cmd.hlp", "immed.hlp" and "options.hlp".
+
+If dvgt can find "immed.hlp" - ie, if the environment variable
+DV_IMMED_HELP points to it - then a novice user, who types simply "dvgt"
+on the command line, will see "immed.hlp" displayed. Otherwise, the
+file listed in "defaults.h" as "IMMEDIATE_HELP", is displayed. If
+even that cannot be opened, then the precompiled message from "help.h"
+is shown - this is intended to be very similar to "immed.hlp".
+
+Also, if a command line option is typed without an argument, as, eg,
+"dvgt -f", then dvgt will describe the option. Another example is
+"dvgt -i", which has no valid argument, and prints out the current
+pathname of the immediate help file.
+
+Once in the program, the command "?" as before, will display the
+"cmd.hlp" file, which has been updated because of the changes to the
+commands. If that file cannot be found, then the precompiled command
+help text is displayed.
+
+The file "options.hlp" is an expanded version of "immed.hlp", to
+describe the options more fully. dvgt does not read "options.hlp":
+the user is directed to do that for her/himself.
+
+3. Environment Variables and Command Line Options.
+
+There are now a variety of environment variables that the installer of
+the program is supposed to set before dropping "dvgt" on the poor users.
+Otherwise, the user must specify options to "dvgt" to override defaults.
+Here is a table (not in TeX, as this is a README file).
+
+
+Option Program Environment Constant in Purpose
+ Variable Variable "defaults.h"
+
+ -H hoffset --- --- Horizontal page offset,
+ in given units.
+
+ -V voffset --- --- Vertical page offset,
+ in given units.
+
+ -d dummy_pk DV_DUMMY_PK DEF_DUMMY_PK Dummy PK font, used when
+ correct font's absent.
+
+ -e dummy_tfm DV_DUMMY_TFM DEF_DUMMY_TFM Dummy TFM, used when
+ correct TFM's absent.
+
+ -f pkdir TEXPKS DEF_PK_DIR PK fonts' directory.
+ else
+ PKFONTS
+ else
+ TEXFONTS
+
+ -h cmd_help DV_HELP DEF_CMD_HELP Help file for "?" command.
+
+ -i immed_help DV_IMMED_HELP DEF_IMMED_HELP Give help at startup.
+
+ -l landscape --- --- Landscape page dimensions.
+
+ -m mag --- --- Magnification.
+
+ -p psprefix DV_PSPREFIX DEF_PS_PREFIX Prefix in PS font names.
+
+ -r xres, DV_RES DEF_XRES, X and Y resolutions,
+ yres DEF_YRES in dots per inch (dpi).
+
+ -t tfmdir TEXFONTS DEF_TFM_DIR TFM metric files' directory.
+
+ -v vdu DV_TERM --- Terminal type.
+ else
+ TERM
+
+ -x paperwd DV_PAPERWD DEF_PAPERWD Paper width,
+ in given units.
+
+ -y paperht DV_PAPERHT DEF_PAPERHT Paper height,
+ in given units.
+
+
+Command line options override environment variables, which override
+the constants in "defaults.h".
+
+TEXPKS (as used by Rokicki's dvips) is used for the PK fonts
+directory, but if it is absent, then PKFONTS is used; if that is
+also absent, then TEXFONTS is used.
+
+Since TERM is usually set in every users' account, there is no
+hard-wired value for the terminal in "defaults.h". Often, however,
+for example when using NCSA Telnet for viewing, it is necessary to
+have a different terminal type for dvgt than for the regular screen
+mode; to avoid confusion, dvgt will use the terminal type given in the
+environment variable DV_TERM (if it exists) in preference to that in
+TERM.
+
+4. Terminal names.
+
+The vdu names `kermit', `ncsatel' and `tek4010' are synonyms for the
+NCSA Telnet driver.
+
+5. Bitmaps.
+
+Dynamic memory allocation of bitmaps replaces the old static
+allocation. Small glyphs now require little memory, and huge glyphs
+(such as those in mfpic(*) picture fonts) can be viewed.
+
+(*) Mfpic is a macro package by Thomas Leathrum (moth@dartmouth.edu)
+to enable TeX to draw graphics using MetaFont. Such graphics are
+viewable by almost any TeX DVI previewer.
+
+6. PK and TFM multiple path searching.
+
+Multiple paths have been implemented for TFM and PK file directories
+under unix. For instance,
+
+ .:/usr/local/lib/tex/fonts
+
+will seek the TFM files in the current directory, and then in the
+directory /usr/local/lib/tex/fonts (where they are found on a
+significant number of systems). This enables the regular TEXFONTS
+environment variable (if used for TeX) to be employed for dvgt.
+
+Similarly for PK fonts (env. vars. TEXPKS, PKFONTS), though less
+flexibly as subdirectory searching is not implemented in dvgt 3.5 and
+TeX installations can differ markedly in how they place PK fonts.
+
+7. Font substitution strategy.
+
+When a font is missing, dvgt 3.5 tries each of several replacements
+in turn. Briefly:
+
+ PK -> PS -> dummy PK -> TFM -> dummy TFM -> DVI Terse.
+
+In words, if the correct PK bitmap (plus or minus one dot per inch in
+its resolution) is found, then that is used.
+
+Otherwise, if the font is identified as a PostScript font (using the
+list of PostScript prefixes) and the correct TFM is found, then
+display the TFM bounding boxes (in outline - previous versions used
+solid blocks).
+
+If that fails, then display the dummy PK font, provided that it can
+be found.
+
+Otherwise, try the correct TFM metric file.
+
+If that is missing, then seek the dummy TFM metric file.
+
+If nothing else succeeds, then use the font's scaled size from the
+DVI file, assuming heights equal to the scaled size and widths of half
+the scaled size. Display the characters of such a font in Terse mode.
+(Other fonts are unaffected.)
+
+
+FILE TIMES and DATES.
+
+The times and dates in the various files of this distribution are the
+modification times of those files. "GMT" signifies Greenwich Mean
+Time, and "GMT +10:00" means ten hours in advance of GMT. In the
+absence of "GMT", the time is local to Melbourne, Victoria, Australia.
+
+
+ACKNOWLEDGMENTS.
+
+Andrew Trevorrow, for developing DVItoVDU, which has stood the test of
+time.
+
+Masahiro Kitagawa (kitagawa@will.ntt.jp), for inventing the Japanese
+versions 1.0J and 1.1J, for encouraging me in this work, and for much
+advice, including the original recommendation of Ian Dall's port, of
+which I was hitherto oblivious. Also for reporting user-hostile
+deficiencies in dvgt's error handling.
+
+Ian Dall, for porting version 3.0 to C.
+
+The many others who have enhanced, ported and otherwise improved
+one branch or another of DVItoVDU's family tree over the years.
+
+Guy Harris and Dave Curry for each pointing out a bug in the System
+Vr4 and Solaris code of `unixio.c'.
+
+The patient testers, many of whom are still waiting for code that will
+drive a true Tek4010 graphics terminal or a VGA monitor, and one or
+two other things. I wish I could have delivered these features, but
+my Winnie-the-Pooh brain was sorely taxed by trying to make sense of
+AIX's C compilers (cc, c89, xlc), not to mention the differing header
+files and object libraries on BSD and System Vr4 and hybrids thereof.
+
+If it's any consolation to those who're missing a desired feature,
+Masahiro wrote to me that "dvgt" (since version 3.4) works fine with
+Japanese text.
+
+La Trobe University Computer Services and the Department of Electronic
+Engineering, for providing the resources by which DVItoVDU became
+dvgt, and dvgt has been maintained.
+
+The archivers, who kindly donated machine resources and their own
+time and effort, to provide a place for this software to rest.
+Without their generosity, many of you would not be reading this.
+
+IBM, for inventing the Risc/6000. AIX? Well, it's a long story ...
+
+
+PLEAS.
+
+Suggestions for improvements of "dvgt" are welcome.
+So is practical advice. Here is a brief wish list for enhancements
+which are beyond my current reach.
+
+1. If you know how to drive a true Tek4010 terminal (copy from
+Gnuplot?), and would can implement this in dvgt, you may make at least
+one other user happy.
+
+2. An EGA/VGA driver that functions over MS-Kermit or Telnet would be
+very helpful! I was told that (part of) the driver must reside on the
+PC, but TSRs and such are out of my league.
+
+3. Someone with a strong stomach might attempt to make the data
+structures more "object-oriented", I mean "easy to modify correctly".
+Tread _very_ carefully!
+
+4. Make dvgt fully conformant with the TUG DVI Driver Standard,
+wherever appropriate.
+
+5. Also see the "TODO" file.
+
+
+DISCLAIMER.
+
+dvgt is _not_ conformant with the TUG DVI Driver Standards Committee's
+_DVI Driver Standard, Level 0_, for ``minimally functional'' DVI
+processors, although I have a copy of draft 0.5 of that document
+(from CTAN). [See if you can spot the differences: some of them are
+flagged in the source code.]
+
+
+All the Best!
+Geoffrey Tobin
diff --git a/dviware/dvgtk/doc/TODO b/dviware/dvgtk/doc/TODO
new file mode 100644
index 0000000000..5b15511436
--- /dev/null
+++ b/dviware/dvgtk/doc/TODO
@@ -0,0 +1,36 @@
+TODO - for dvgt 3.5 - 21:22 GMT +10:00 Fri 20 August 1993 - Geoffrey Tobin.
+
+1. Subdirectory searching?
+
+2. Scale substitute PK and TFM files (like zoom, but restricted to
+ one font), to match the scaled size of the missing font.
+
+3. More VDU drivers.
+
+4. Allow an output character recoding file?
+ That might be useful where the glyph encoding differs from ascii,
+ or, more generally, from the encoding of the display.
+ One way would be pairs of (hexadecimal?) integers.
+ Might allow "D" for decimal, "C" for ascii character,
+ "X" for hexadecimal, and "O" for octal, as in Knuth's TFM files.
+ Default would be which `number system'?
+
+ To Terse mode, add a user-definable glyph encoding?
+ (Currently uses an encoding based on cmr10.)
+ Employ a character recoding file, which the user could alter?
+
+ Virtual Fonts?
+ A fanciful dream, that one.
+
+5. Macros?
+
+6. String Search in the DVI file.
+
+7. Conform dvgt to TUG's DVI Driver Standard, Level 0, at least more
+ nearly.
+
+8. Choose different DVI files interactively?
+
+9. Make TFM, PK path and file spec. strings dynamic.
+
+Geoffrey Tobin
diff --git a/dviware/dvgtk/doc/ansi2knr.1 b/dviware/dvgtk/doc/ansi2knr.1
new file mode 100644
index 0000000000..434ce8f042
--- /dev/null
+++ b/dviware/dvgtk/doc/ansi2knr.1
@@ -0,0 +1,19 @@
+.TH ANSI2KNR 1 "31 December 1990"
+.SH NAME
+ansi2knr \- convert ANSI C to Kernighan & Ritchie C
+.SH SYNOPSIS
+.I ansi2knr
+input_file output_file
+.SH DESCRIPTION
+If no output_file is supplied, output goes to stdout.
+.br
+There are no error messages.
+.sp
+.I ansi2knr
+recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line.
+.sp
+The following constructs will confuse it:
+.br
+ - Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call).
+.br
+ - Macros that tinker with the syntax of the function header.
diff --git a/dviware/dvgtk/doc/example.tex b/dviware/dvgtk/doc/example.tex
new file mode 100644
index 0000000000..858ad3b9bb
--- /dev/null
+++ b/dviware/dvgtk/doc/example.tex
@@ -0,0 +1,232 @@
+% This is the TeX source file for the "TeXnical Typesetting" document.
+% Notice how you can put in comments? If TeX sees a % it simply ignores
+% the rest of the line.
+
+% A4 paper is 8.3in wide and 11.7in high; we set the page dimensions so that
+% there are 1in margins all around:
+\hsize 6.3in % page width
+\vsize 9.7in % page height
+
+\parskip 8pt plus 2pt minus 1pt % glue before a paragraph
+
+% Define a few extra fonts for later use:
+\font\bigrm=cmr10 scaled\magstep4 % big version of the standard roman font
+\font\ninerm=cmr9 % 9pt roman
+\font\fiverm=cmr5 % 5pt roman
+\font\sm=cmcsc10 % caps and small caps
+\font\ss=cmss10 % sans serif
+
+% Here's a macro that we'll use to produce all subheadings:
+\def\subhead#1{\bigskip % extra glue before subheading
+ \noindent{\bf #1}\par % unindented boldface subheading
+ \nobreak} % prevent a page break after subheading
+
+\centerline{\bigrm \TeX nical Typesetting}
+
+\vskip 2.5cm % dimensions can be metric
+
+\subhead{What is \TeX?}
+
+\TeX\ (pronounced ``teck'') is a computerized typesetting system developed by
+Donald Knuth and others at Stanford University. It is used to create
+high-quality documents, particularly those containing mathematics.
+The name \TeX\ is an uppercase form of the Greek letters $\tau\epsilon\chi$,
+the first three letters of a Greek word meaning {\sl art} as well as
+{\sl technology}.
+The lowering of the ``E'' is a reminder that \TeX\ is about typesetting,
+which can be thought of as the next stage beyond word processing.
+On devices where such lowering is difficult or impossible you may see \TeX\
+written as {\tt TeX}.
+
+% the above blank line ends the first paragraph
+
+Most word processors allow you to
+create and modify a document interactively --- what
+you see on the screen is usually what your output will look like.
+\TeX\ does {\it not} work in this way.
+Like other typesetting systems (such as SCRIBE and
+{\sl troff\/}), \TeX\ is known as a ``document compiler''. Using your
+favourite text editor you need to create a file containing the
+text of your manuscript along with the \TeX\ typesetting commands.
+\TeX\ gives you the ability to produce printed matter with a quality
+matching that found in books, depending on the output device.
+Adelaide University has an {\sm imagen} laser printer
+with a resolution of 240 dots per inch.
+This publication shows both the capabilities of \TeX\ and
+the output quality of the laser printer.
+
+\subhead{Fonts}
+
+One of the more obvious advantages of \TeX\ is the large range of fonts from
+which you can choose. A font is a collection of characters each having a
+similar size and style. Some of the fonts currently available include:
+$$ % enter display math mode just to get space above and below \line
+\line
+ {\hfil % infinitely stretchable glue
+ \rm roman\hfil \sl slanted\hfil \it italic\hfil \bf boldface\hfil
+ \tt typewriter\hfil \ss sans serif\hfil \sm small caps\hfil
+ } % take care to ensure each { has a matching }
+$$
+Many of these also come in a variety of sizes:
+$$
+\centerline{{\bigrm from the very big},~ % extra space after comma
+ {\ninerm to the very small},~
+ {\fiverm to the ridiculous}.}
+$$
+Apart from a large selection of mathematical symbols,
+many special characters and accents are available:
+$$
+\vbox
+ {\tabskip 10pt plus 1fil % glue before and after all columns
+ \halign to\hsize
+ {& \hfil#\hfil\cr % specify a variable number of centred columns
+ \copyright& \it\$& \S& \P& \dag& \ddag&
+ $\circ$& $\bigcirc$& % some symbols must be accessed from math mode
+ $\leftarrow$& $\rightarrow$& $\triangle$& $\clubsuit$&
+ \`a& \'e& \c c& \^o& \"u\cr
+ }
+ }
+$$
+\TeX\ does a few subtle things automatically.
+Certain sequences of characters in your text will
+be replaced by {\sl ligatures} in the printed output (consider the ``{\tt ffi}''
+in ``difficult''), while other pairs of characters need to be {\sl kerned}
+(e.g., the ``o'' and ``x'' in ``box'' look better if they are moved closer
+together). The range and quality of fonts available will continue to improve.
+
+\subhead{Mathematics}
+
+A major design goal of \TeX\ was to simplify the task of typesetting
+mathematics --- and to do it properly. Mathematicians will be pleasantly
+surprised at the ease with which formulae and expressions can be created;
+from simple in-line equations
+such as $e^{i\pi}=-1$ and $f_{n+2}=f_{n+1}+f_n$, to more extravagant displays:
+$$
+\sum_{k\ge1} \sqrt{x_k-\ln k}\quad\ne\quad
+\int_{0}^\infty {e^{-x^3}+\sqrt{x} \over \left(123-x\right)^3} \,dx
+$$
+\TeX\ looks after most of the nitty gritty details, such as spacing things
+correctly and choosing the right sizes for superscripts, parentheses,
+square root signs etc. (The discoverer of the above relation wishes to
+remain anonymous.)
+
+\subhead{Alignment}
+
+The preparation of tabular material such as in lists and matrices can be a
+tedious job for a person armed only with a typewriter and a bottle of
+correction fluid. With a little help from \TeX, computers can make it so
+much easier:
+$$
+\vcenter % a vertically centred \vbox
+ {\tabskip 0pt % no space before column 1
+ \halign to 3.5in % width of table
+ {\strut#& % col 1 is a strut
+ \vrule#\tabskip .5em plus2em& % col 2 is a vrule; also set col spacing
+ #\hfil& % col 3 is left justified
+ \vrule#& % col 4 is a vrule
+ \hfil#\hfil& % col 5 is centred
+ \vrule#& % col 6 is a vrule
+ \hfil#& % col 7 is right justified
+ \vrule#\tabskip 0pt % col 8 is a vrule; no space after it
+ \cr % end of the preamble
+ \noalign{\hrule}
+ & & \multispan5 \hfil Oldest players to represent\hfil& \cr
+ & & \multispan5 \hfil England in a Test Match\hfil& \cr
+ \noalign{\hrule}
+ & & \omit\hfil Name\hfil& & % \omit ignores template in preamble
+ \omit\hfil Age\hfil& &
+ \omit\hfil Versus\hfil& \cr
+ \noalign{\hrule}
+ & & W.Rhodes& & 52y 165d& & West Indies, 1930& \cr
+ \noalign{\hrule}
+ & & W.G.Grace& & 50y 320d& & Australia, 1899& \cr
+ \noalign{\hrule}
+ & & G.Gunn& & 50y 303d& & West Indies, 1929& \cr
+ \noalign{\hrule}
+ & & J.Southerton{\ninerm*}& & 49y 139d& & Australia, 1877& \cr
+ \noalign{\hrule\smallskip}
+ & \multispan7\ninerm* (This was actually his Test debut.)\hfil \cr
+ }
+ }
+\hskip .5in % space between table and matrix
+A=\pmatrix % parenthesized matrix
+ {a_{11}& a_{12}& \ldots& a_{1n}\cr
+ a_{21}& a_{22}& \ldots& a_{2n}\cr
+ \vdots& \vdots& \ddots& \vdots\cr
+ a_{m1}& a_{m2}& \ldots& a_{mn}\cr
+ }
+$$
+
+\vskip -\the\belowdisplayskip % avoid too much space below display
+
+\subhead{Other features}
+
+Space does not permit examples of all the things \TeX\ can do. Here are some
+more features you might like to know about:
+
+\item{$\bullet$}
+Multi-column output can be generated.
+
+{\parskip=0pt % temporarily turn off the skipping between paragraphs
+\item{$\bullet$}
+\TeX\ has a very sophisticated paragraph building algorithm and rarely needs
+to resort to hyphenation. Paragraphs can be indented and shaped in many
+different ways.
+
+\item{$\bullet$}
+Automatic insertion of footnotes,\footnote{\dag}{\ninerm Here is
+a footnote.} running heads, page numbers etc.
+
+\item{$\bullet$}
+\TeX\ makes provision for generating a table of contents, a bibliography, even
+an index. Automatic section numbering and cross referencing are also possible.
+
+\item{$\bullet$}
+A powerful macro facility is built into \TeX. This lets you do some very
+useful things, like creating an abbreviation for a commonly used phrase, or
+defining a new command that will have varying effects depending on the
+parameters it is given. A macro package can enhance \TeX\ by making it much
+easier to generate a document in a predefined format.
+\par % end the last paragraph BEFORE ending the group
+} % \parskip will now revert to its previous value
+
+\subhead{What CAN'T \TeX\ do?}
+
+Complex graphics such as diagrams and illustrations pose
+a major problem --- at the moment you have to leave an appropriate amount of
+blank space and paste them in later.
+Graphic facilities are the subject of current research.
+
+\subhead{\TeX\ and VAX/VMS}
+
+The \TeX\ source file used to generate this document is available for
+inspection on any VAX node that has \TeX ---
+just type `{\tt scroll tex\char'137 inputs:example.tex}'.
+A few steps are needed to print such a file:
+
+\item{(1)}
+Type `{\tt tex example}' to ``compile'' the file.
+(\TeX\ looks for a {\tt .tex} file by default. If it can't find the given
+file in your current directory it will look in {\tt tex\char'137 inputs}.)
+Two new files will be created in your current directory:
+{\tt example.dvi} and {\tt example.lis}.
+The former is a device independent description of the document;
+the latter is simply a log of the \TeX\ run.
+
+{\parskip=0pt % temporarily turn off \parskip
+\item{(2)}
+Type `{\tt dvitovdu example}' to preview the document on a terminal screen.
+This program can be used to detect a variety of formatting problems,
+saving both time and paper.
+
+\item{(3)}
+Type `{\tt imprint example}' to print the document.
+(Note that the DVIto\kern-.15em VDU and IMPRINT commands
+accept a {\tt .dvi} file by default).
+
+} % restore \parskip
+
+Detailed help on all these commands is available on-line --- try typing
+`{\tt help tex}' to get started.
+
+\bye
diff --git a/dviware/dvgtk/doc/guidemacs.tex b/dviware/dvgtk/doc/guidemacs.tex
new file mode 100644
index 0000000000..11f556ae9f
--- /dev/null
+++ b/dviware/dvgtk/doc/guidemacs.tex
@@ -0,0 +1,105 @@
+% guidemacs.tex - 14:31 GMT +10:00 Sun 23 May 1993 - modifier Geoffrey Tobin.
+% I don't have the original Andrew Trevorrow guidemacs.
+% This will have to do. -- Ian Dall
+
+\def \dvgt {{dvgt 3.5}}
+\font\bigbf=cmbx12
+\font\Bigbf=cmbx12 scaled \magstep1
+\font\title=cmbx10 scaled \magstep5
+\font\smallrm=cmr8
+\def \subhead #1{\bigskip\leftline{\Bigbf #1}\medskip}
+\let \;=\unskip
+\def \finishline{}
+\parskip=10pt
+
+
+% Macros for verbatim TeX (from MANMAC.TEX):
+% After \inputing this file you can use the following macros:
+%
+% 1. |<verbatim horizontal mode text in \tt>|
+%
+% 2. \begintt <optional stuff here>
+% <boxed lines of verbatim text in \tt; | is temporary escape character>
+% \endtt
+%
+% 3. \begindisplay
+% <off-centred display of aligned columns; typical row follows:>
+% |text in \tt|& |text in \tt|& text in current font\cr
+% \enddisplay
+%
+% 4. \listing{foo}
+% foo.tex will be \input and set verbatim in \tt; \parskip must be non-zero
+% if you want to see any empty lines
+
+\catcode`@=11 % borrow some PLAIN macros which use @ as a letter
+
+\newskip\ttglue
+\ttglue=0.5em plus.25em minus.15em
+
+\chardef\other=12
+\def\ttverbatim{\begingroup
+ \catcode`\\=\other
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\$=\other
+ \catcode`\&=\other
+ \catcode`\#=\other
+ \catcode`\%=\other
+ \catcode`\~=\other
+ \catcode`\_=\other
+ \catcode`\^=\other
+ \obeyspaces \obeylines \tt}
+{\obeyspaces\gdef {\ }} % active space = \ , not \space
+
+\outer\def\begintt{$$\let\par=\endgraf \ttverbatim \parskip=\z@
+ \catcode`\|=\other
+ \rightskip-5pc \ttfinish}
+{\catcode`\|=0 |catcode`|\=\other % | is temporary escape character
+ |obeylines % end of line is active
+ |gdef|ttfinish#1^^M#2\endtt{#1|dimen0=|hsize|advance|dimen0 by -|hangindent%
+ |hsize=|dimen0|vbox{#2}|endgroup$$}}
+% \begintt ... \endtt will now work in a paragraph with \hangindent, such
+% as an \item
+
+\catcode`\|=\active
+{\obeylines \gdef|{\ttverbatim \spaceskip\ttglue \let^^M=\ \let|=\endgroup}}
+
+\catcode`@=12 % return @ its normal category of "other"
+
+% Macros for non-centered displays:
+% Note that we turn \ttglue off so |stuff| spaces will all be equal.
+\outer\def\begindisplay{\obeylines\startdisplay}
+{\obeylines\gdef\startdisplay#1
+ {\catcode`\^^M=5$$\ttglue=0em#1\halign to\hsize%
+\bgroup\indent##\hfil\tabskip 0pt plus 1000pt&&\qquad##\hfil\cr}}
+\outer\def\enddisplay{\crcr\egroup$$}
+
+% MACROS FOR VERBATIM LISTINGS (ADAPTED FROM TEXBOOK APPENDIX D, P380)
+
+\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
+
+
+\def\setupverbatim{\tt % \lineno=0
+ \def\par{\leavevmode\egroup\box0\endgraf}
+ \obeylines \uncatcodespecials \obeyspaces
+ \catcode`\`=\active \catcode`\^^I=\active
+ \everypar{ % \advance \lineno by1 \llap{\sevenrm\the\lineno\ \ }
+ \startbox}}
+\newdimen\w \setbox0=\hbox{\tt\space} \w=8\wd0 % tab amount
+% \newcount\lineno
+\def\startbox{\setbox0=\hbox\bgroup}
+{\catcode`\^^I=\active
+ \gdef^^I{\leavevmode\egroup
+ \dimen0=\wd0 % the width so far, or since the previous tab
+ \divide\dimen0 by\w
+ \multiply\dimen0 by\w % compute previous multiple of \w
+ \advance\dimen0 by\w % advance to next multiple of \w
+ \wd0=\dimen0 \box0 \startbox}}
+
+\def\listing#1{\par\begingroup\parindent0pt \parskip0pt
+ \vskip\baselineskip
+ \setupverbatim
+ \catcode`\|=\other % allow | in listing file
+ \input#1
+ \vskip\baselineskip\endgroup}
+
diff --git a/dviware/dvgtk/doc/options.txt b/dviware/dvgtk/doc/options.txt
new file mode 100644
index 0000000000..b913ebb1f9
--- /dev/null
+++ b/dviware/dvgtk/doc/options.txt
@@ -0,0 +1,139 @@
+dvgt is a version of the DVItoVDU interactive TeX page previewer.
+The program allows you to look at TeX-generated DVI files on a variety
+of commonly available VDUs.
+
+The "DVItoVDU User Guide", "userguide.tex", explains how to use the program.
+
+USAGE: dvgt filename[.dvi]
+ [-H x_offset] [-V y_offset] [-d dummy_pk] [-e dummy_tfm]
+ [-f pk_directory] [-h helpfile] [-i] [-l]
+ [-m magnification] [-p postscript_font_prefix]
+ [-r xres yres] [-t tfm_directory]
+ [-v vdu] [-x paperwd] [-y paperht]
+
+NOTE ON OPTIONS' DEFAULTS:
+
+All options have default values.
+System dependent initial defaults are set at compile-time.
+(Compilation note: these constants are set in the source file "defaults.h".)
+Some defaults can be set by environment variables.
+The command line options override the environment variables, which in
+turn override the compiled initial defaults.
+
+BRIEF SUMMARY OF OPTIONS:
+
+-H horizontal_offset (default = 0.0 in)
+-V vertical_offset (default = 0.0 in)
+-l (set landscape mode, instead of the default portrait mode)
+-m magnification (default = DVI file's intrinsic magnification)
+-v vdu (default = value of the environment variable TERM)
+
+ vdu may be one of:
+
+ aed512 gigi kermit ncsatel regis tek4010 vis240 vis241 vis500 vis550
+ vis603 vis630 vk100 vt100 vt100132 vt102 vt125 vt200 vt220 vt240
+ vt640
+
+The other options' default values are system dependent.
+Try "dvgt -f", for example, to find the current default PK font directory.
+
+COMMAND OPTIONS:
+
+-H horizontal_offset (default = 0.0in)
+
+-V vertical_offset (default = 0.0in)
+
+ TeX, by default, considers the top left corner of the printed page as
+ one inch below and one inch to the right of the physical page. So
+ does dvgt. The two offsets move this corner. Positive dimensions
+ move it downwards and rightwards; negative offsets are allowed.
+
+-d file (default is system dependent; environment: DV_DUMMY_PK)
+
+ dvgt will warn you if your document uses a font at a non-existent size.
+ Rather than abort, it will load the PK font specified after -d and continue
+ so you can look for more errors. Paragraphs using this dummy information
+ are likely to have ragged right margins.
+
+-e file (default is system dependent; environment: DV_DUMMY_TFM)
+
+ Default TFM file, similar to -d option.
+
+-f file (default is system dependent; environment: PKFONTS or TEXFONTS)
+
+ dvgt gets all its font information from PK files. These files are
+ kept within the directory specified by this option.
+
+-h file (default is system dependent; environment: DV_HELP)
+
+ The ? command reads the help text file specified by this option.
+
+-i (default is system dependent; environment: DV_IMMED_HELP)
+
+ Display the path name of the immediate help file.
+ Typing "dv" by itself displays the immediate help file.
+
+-l
+
+ Set landscape mode: exchange x and y dimensions.
+ (This does NOT rotate the page, sorry.)
+ The default is portrait mode.
+
+-m i (default = DVI magnification)
+
+ This option allows you to replace the magnification used in the
+ DVI file with some other value; i is a positive *integer*, 1000 times
+ the desired magnification. The given value should be chosen carefully
+ so that the new font sizes still correspond to existing PK files.
+ Unless you know exactly what you are doing you should avoid using -m,
+ especially if your TeX source file uses \magnification AND true dimensions.
+
+-r x,y (default is system dependent)
+-r x
+
+ dvgt treats the imaginary sheet of paper on which a DVI page will
+ appear as a two dimensional array of tiny dots known as paper pixels.
+ x and y are positive floating point numbers that define the numbers of
+ pixels per inch in the horizonatl and vertical directions, respectively.
+ Their values should match the respective resolutions of the device that
+ will be used to print your document.
+ If only one value is given, then it is used as the resolution both
+ horizontally and vertically.
+
+-t tfm_directory (default is system dependent; environment: TEXFONTS)
+
+ This sets the directory where dvgt will look for TFM (TeX Font
+ Metric) files, such as "cmr10.tfm".
+
+-v string (default = value of TERM)
+
+ This option is used to tell dvgt what type of VDU you are using.
+ If TERM does not describe your VDU, you need to override the default value.
+ Typing `dvgt -v vis550 foo' will tell dvgt you're using a VISUAL 550.
+ The current version will accept the following strings
+ (in upper or lower case):
+
+ aed512 (AED 512 with 512 by 512 screen)
+ kermit (same as ncsatel)
+ ncsatel (NCSA Telnet's Tektronix 4010 emulation)
+ regis (any ReGIS compatible VDU; synonyms = GIGI, VK100, VT125, VT240)
+ tek4010 (same as ncsatel)
+ vis240 (VISUAL 240; synonym = VIS241)
+ vis500 (VISUAL 500)
+ vis550 (VISUAL 550)
+ vis603 (VISUAL 603)
+ vis630 (VISUAL 630)
+ vt100 (any VT100 compatible VDU in 80 column mode; synonym = VT102)
+ vt100132 (any VT100 compatible VDU in 132 column mode)
+ vt220 (VT220 using down-loaded chunky graphics; synonym = VT200)
+ vt640 (VT100 with Retro-Graphics)
+
+-x dimen (default is system dependent)
+-y dimen (default is system dependent)
+
+ These two options define the width and height of the paper upon which your
+ document will be printed. Both values are specified as dimensions like
+ those used in TeX, but the units are restricted to BP, CM, IN, MM, PC, PT,
+ PX, or SP. PX is specific to dvgt, and represents one paper pixel.
+ Every time you select a page, dvgt will use these paper dimensions
+ to check that all printed material falls within the paper edges.
diff --git a/dviware/dvgtk/doc/sysguide.tex b/dviware/dvgtk/doc/sysguide.tex
new file mode 100644
index 0000000000..438f14cefa
--- /dev/null
+++ b/dviware/dvgtk/doc/sysguide.tex
@@ -0,0 +1,914 @@
+% 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 |<stdlib.h>|\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 <MACRO>|, perhaps at the top
+of the source file, so you can find them easily, write |#define <MACRO>|.
+Here |<MACRO>| 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
diff --git a/dviware/dvgtk/doc/tripvdu.tex b/dviware/dvgtk/doc/tripvdu.tex
new file mode 100644
index 0000000000..d8c3d25729
--- /dev/null
+++ b/dviware/dvgtk/doc/tripvdu.tex
@@ -0,0 +1,279 @@
+% TeX source file for creating TRIPVDU.DVI, a torture file for DVItoVDU
+% (using the same philosophy as Donald Knuth's torture test for TeX).
+
+\nopagenumbers
+\topskip 0pt
+\parindent 0pt
+\parskip 0pt
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 1
+% This page is completely empty but has some \special stuff.
+
+\message{Empty page.}
+\null
+\special{DVItoVDU should warn user that it is ignoring this stuff.}
+\special{And this.}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 2
+% This page has 1 black pixel at (0,0).
+
+\message{1 black pixel at (0,0).}
+\hrule height 1sp width 1sp depth 0sp
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 3
+% This page will fill an A4 sheet with black pixels, assuming A4 paper is
+% 8.3in by 11.7in and (0,0) is 1in from the top and left edges.
+
+\message{A4 sheet full of black pixels.}
+{% change page size and location temporarily
+\hsize 10in
+\vsize 12in
+\hoffset -1in
+\voffset -1in
+% Because ref pts of rules are at BOTTOM left corner we first need to output
+% a rule that will guarantee Minv = -1in, then output the large rule with
+% slightly less than A4 height.
+\hrule height 1sp width 8.299in depth 0sp
+\hrule height 11.695in width 8.299in depth 0sp
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 4
+% This page is 1 pixel wider than page 3.
+% DVItoVDU should detect that page is too wide for A4 paper.
+
+\message{As above but 1 pixel too wide.}
+\hrule height 1sp width 8.301in depth 0sp
+\hrule height 11.695in width 8.301in depth 0sp
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 5
+% This page is 1 pixel longer than page 3.
+% DVItoVDU should detect that page is too low for A4 paper.
+
+\message{As above but 1 pixel too low.}
+\hrule height 11.701in width 8.299in depth 0sp
+\vfil\eject
+
+}% reset page size and location
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 6
+% This page has a rulelist with a full ruletable (= 300 rules).
+% Note that DVItoVDU does not impose any limits
+% on the number of rules or characters in a page. Pages 6 to 9
+% test the list manipulating code in DVIReader and DVItoVDU.
+
+\message{Page with ruletablesize rules.}
+\newcount\temp
+\temp=300
+\loop\ifnum\temp>0
+ \hrule height 1sp width \hsize % 1 pixel high
+ \vfil
+ \advance\temp by -1
+\repeat
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 7
+% This page has ruletablesize+1 rules (so rulelist has 2 nodes).
+
+\message{Page with ruletablesize+1 rules.}
+\temp=301
+\loop\ifnum\temp>0
+ \hrule height 1sp width \hsize % 1 pixel high
+ \vfil
+ \advance\temp by -1
+\repeat
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 8
+% This page has a charlist with a full chartable (= 3000 characters).
+
+\message{Page with chartablesize characters from one font.}
+\font\small=cmr5
+{\small \offinterlineskip
+ \temp=30
+ \loop\ifnum\temp>0
+ \leftline{iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii} % 100 chars
+ \advance\temp by -1
+ \repeat
+}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 9
+% This page has chartablesize+1 characters (so charlist has 2 nodes).
+
+\message{Page with chartablesize+1 characters from one font.}
+{\small \offinterlineskip
+ \temp=30
+ \loop\ifnum\temp>0
+ \leftline{iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii} % 100 chars
+ \advance\temp by -1
+ \repeat
+ \leftline{i} % the extra character
+}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 10
+
+\message{Multiple TeX page counters.}
+\footline={\hss\tenrm\folio\hss} % turn on page numbers
+\pageno=0
+\count1=1 \count2=2 \count3=3 \count4=4 \count9=9
+\noindent
+This is \TeX\ page [0.1.2.3.4.....9].
+\vfil\eject
+
+\count1=0 \count2=0 \count3=0 \count4=0 \count9=0 % reset TeX counters
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 11
+
+\message{Negative TeX page.}
+\pageno=-11
+\noindent
+This is \TeX\ page [-11].
+\vfil\eject
+
+\pageno=12 % DVI page = TeX page again
+\nopagenumbers % turn off page numbers again
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 12
+% This page has characters from many fonts.
+% Note that the page is off the right edge of A4 paper.
+
+\message{Page with characters from many fonts.}
+% avoid redefining plain TeX's \i, \j etc.
+\font\Fb=cmr5
+\font\Fc=cmr5 scaled\magstep5
+\font\Fe=cmr10 scaled\magstep5
+\font\Fg=cmbx10
+\font\Fh=cmbx10 scaled\magstep5
+\font\Fj=cmsl10
+\font\Fk=cmsl10 scaled\magstep5
+\font\Fm=cmtt10
+\font\Fn=cmtt10 scaled\magstep5
+\font\Fo=cmss10
+\font\Fp=cmcsc10
+\font\Fq=cmdunh10
+
+\leftline{\Fb These characters are from CMR5 at mag 1000.}
+\leftline{\Fc These characters are from CMR5 at mag 2488.}
+\leftline{\tenrm These characters are from CMR10 at mag 1000.}
+\leftline{\Fe These characters are from CMR10 at mag 2488.}
+\leftline{\Fg These characters are from CMBX10 at mag 1000.}
+\leftline{\Fh These characters are from CMBX10 at mag 2488.}
+\leftline{\Fj These characters are from CMSL10 at mag 1000.}
+\leftline{\Fk These characters are from CMSL10 at mag 2488.}
+\leftline{\Fm These characters are from CMTT10 at mag 1000.}
+\leftline{\Fn These characters are from CMTT10 at mag 2488.}
+\leftline{\Fo These characters are from CMSS10 at mag 1000.}
+\leftline{\Fp These characters are from CMCSC10 at mag 1000.}
+\leftline{\Fq These characters are from CMDUNH10 at mag 1000.}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 13
+% This page has characters from many fonts, some of which have no corresponding
+% PXL file. DVItoVDU should warn user about non-existent font files and
+% continue as best it can by loading dummy font info.
+% Note that the page is off the right edge of A4 paper.
+
+\message{Page with characters from fonts at unknown magnifications.}
+% PXL files do not exist at the requested magnifications:
+\font\Fr=cmr5 scaled 500
+\font\Fs=cmr5 scaled 3000
+\font\Ft=cmr10 scaled 200
+\font\Fu=cmr10 scaled 5000
+\font\Fv=cmsl10 scaled 200
+\font\Fw=cmsl10 scaled 10000
+
+\leftline{\Fr CMR5 at mag 500 does not exist.}
+\leftline{\Fb These characters are from CMR5 at mag 1000.}
+\leftline{\Fs CMR5 at mag 3000 does not exist.}
+\leftline{\Ft CMR10 at mag 200 does not exist.}
+\leftline{\tenrm These characters are from CMR10 at mag 1000.}
+\leftline{\Fu CMR10 at mag 5000 does not exist.}
+\leftline{\Fv CMSL10 at mag 200 does not exist.}
+\leftline{\Fj These characters are from CMSL10 at mag 1000.}
+\leftline{\Fw CMSL10 at mag 10000 does not exist.}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 14
+% This page has a paragraph illustrating most of the characters from the
+% standard roman TeX text font.
+
+\message{Standard paragraph.}
+\rm
+Our task is to create a paragraph illustrating what a typical piece of text
+looks like in the standard \TeX\ font. It should be stressed that not all
+\TeX\ fonts can be used for typesetting text. We need to show most of the
+characters in this font---for instance, something like ``the quick brown fox
+jumps over a lazy dog'' would use all the lower-case letters. Hmmm \dots\
+how about ``THE QUICK BROWN FOX JUMPS OVER 9876543210 LAZY DOGS'' to make
+sure we show all the upper-case letters and digits? Such a paragraph would
+hardly be typical! Then there's ligatures (try and fit in words like
+fluffy, waffle, firefly, difficult) and examples of kerning (boxer, cooked,
+vowel). Not to mention the various accents and other special letters:
+prot\'eg\'e, r\^ole, na\"\i ve, \AE sop's \OE vres en fran\c cais.
+But how do we put all this stuff into a paragraph that makes sense!?
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 15
+
+\message{Page in bottom half of A4 paper.}
+\null\vfil
+\centerline{Page in bottom half of A4 paper.}
+\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 16
+
+\message{Page completely above left of A4 paper.}
+\voffset -3in
+\hoffset -9in
+\leftline{Page completely above left of A4 paper.}
+\vfil\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 17
+
+\message{Page completely below right of A4 paper.}
+\voffset 3in
+\hoffset 9in
+\null\vfil
+\rightline{Page completely below right of A4 paper.}
+\eject
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DVI page 18
+
+\message{Page beyond all edges of A4 paper.}
+\voffset -3in
+\hoffset -3in
+\vsize 15in
+\hsize 15in
+\line{Page beyond all edges of A4 paper.\hfil
+ Page beyond all edges of A4 paper.}
+\vfil
+\line{Page beyond all edges of A4 paper.\hfil
+ Page beyond all edges of A4 paper.}
+\eject
+\voffset 0in \hoffset 0in % offsets back to normal
+
+\bye
diff --git a/dviware/dvgtk/doc/userguide.tex b/dviware/dvgtk/doc/userguide.tex
new file mode 100644
index 0000000000..f70df582d9
--- /dev/null
+++ b/dviware/dvgtk/doc/userguide.tex
@@ -0,0 +1,1286 @@
+% userguide.tex - 18:29 GMT +10:00 Wed 25 Aug 1993 - modifier Geoffrey Tobin.
+%**start of header
+% This is the TeX source file for the "dvgt 3.51 User 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.
+
+\input guidemacs
+%**end of header
+
+\null
+\vfil
+\centerline{\title \dvgt\ User Guide}
+\bigskip
+\vskip\parskip
+\centerline{\bigbf DVItoVDU 3.0, in Modula-2: Andrew Trevorrow, October 1988}
+\smallskip
+\centerline{\bigbf DVItoVDU 3.0, C conversion: Ian Dall, November 1990}
+\smallskip
+\centerline{\bigbf dvgt 3.51: Geoffrey Tobin
+ ({\tt ecsgrt@luxor.latrobe.edu.au}),
+ Aug 1993}
+\bigskip
+
+\noindent
+This document explains how to use {\dvgt}, a \TeX\ page previewer.
+The program allows you to look at \TeX-generated DVI pages on a variety
+of commonly available VDUs.
+It is assumed you are already familiar with \TeX.
+
+\bigskip
+\vskip\parskip
+\centerline{\bigbf Contents}
+\bigskip
+
+\def\aligneddots{\leaders\hbox to .75em{\hss.\hss}\hfil}
+
+% XREF: make sure titles and page numbers are up-to-date!!!
+
+\line{Introduction \aligneddots\ 1}
+\line{Program Options \aligneddots\ 2}
+\line{\hskip1cm Options in Detail \aligneddots\ 3}
+\line{Screen Regions \aligneddots\ 7}
+\line{\hskip1cm Dialog region \aligneddots\ 7}
+\line{\hskip1cm Window region \aligneddots\ 8}
+\line{The Commands \aligneddots\ 10}
+\line{\hskip1cm Miscellaneous \aligneddots\ 10}
+\line{\hskip1cm Selecting a Page \aligneddots\ 10}
+\line{\hskip1cm Changing How a Page is Displayed \aligneddots\ 11}
+\line{\hskip1cm Changing Units \aligneddots\ 11}
+\line{\hskip1cm Moving the Window \aligneddots\ 12}
+\line{\hskip1cm Changing Window Size \aligneddots\ 12}
+\line{The Coordinate Scheme \aligneddots\ 14}
+\line{Some Examples \aligneddots\ 15}
+
+\vfil\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{Introduction.}
+
+Let's assume you've just run \TeX\ and created a file called |foo.dvi|.
+Even if \TeX\ did not find any errors, you cannot be sure that
+the document is formatted correctly. There might be bad line breaks, bad
+page breaks, alignment problems, pages too big for your printer's paper,
+missing fonts---not to mention spelling mistakes.
+
+The lack of visual feedback is one of the major disadvantages of
+using a document compiler like \TeX\null.
+Without a previewing program, the only way to check |foo.dvi| is to
+continue through the \TeX\ cycle and look for errors in the printed output.
+This can be time consuming and is a waste of paper.
+Instead, you can use {\dvgt} to look at |foo.dvi| on a variety of commonly
+available terminals.
+
+\dvgt\ is an interactive program; you can enter commands to
+select a particular page for display, look at the overall format of the
+entire page and then request a smaller region for closer examination.
+The manner in which the page is displayed can be varied from a full,
+accurate representation to a terse, fast display for when fine details
+are unimportant.
+All the commands are described in detail in a later section. % XREF
+
+Some environment variables and/or command options are needed for {\dvgt}
+to work properly. In particular, set the |DV_TERM| environment variable
+to describe the type of VDU you are using; or else use the |-v| option.
+
+Then to look at |foo.dvi|, just type `|dvgt foo|'.
+
+\vfil\eject
+
+\subhead{Program Options.}
+
+The |dvgt| program has a number of options, each of which must be
+followed by a value.
+If the same option appears more than once, then the last value will be used.
+If a particular option does not appear, then a default value will be used,
+which might be taken from an environment variable. If no appropriate
+environment variable is set, the default value used is that specified
+in the source code --- either in `options.c', or as one of the constants
+in `defaults.h'. The constants in `defaults.h' all begin with the prefix
+`|DEF_|'. All the environment variables that are specific to {\dvgt} begin
+with `|DV_|'. All options begin with `|-|'.
+
+\begindisplay
+Option& Program& Environment& Default value& Meaning\cr
+ & Variable& Variable&&\cr
+\noalign{\medskip}
+|-H|& |hoffset|& ---& |0mm|& Horizontal page offset,\cr
+&&&& in given units.\cr
+\noalign{\medskip}
+|-V|& |voffset|& ---& |0mm|& Vertical page offset,\cr
+&&&& in given units.\cr
+\noalign{\medskip}
+|-d|& |dummy_pk|& |DV_DUMMY_PK|& |DEF_DUMMY_PK|& Dummy PK font, used when\cr
+&&&& correct font's absent.\cr
+\noalign{\medskip}
+|-e|& |dummy_tfm|& |DV_DUMMY_TFM|& |DEF_DUMMY_TFM|& Dummy TFM, used when\cr
+&&&& correct TFM's absent.\cr
+\noalign{\medskip}
+|-f|& |pkdir|& |TEXPKS|& |DEF_PK_DIR|& PK fonts' directory.\cr
+&& else&&\cr
+&& |PKFONTS|&&\cr
+&& else&&\cr
+&& |TEXFONTS|&&\cr
+\noalign{\medskip}
+|-h|& |cmd_help|& |DV_HELP|& |DEF_CMD_HELP|& Command help file read\cr
+&&&& by `?' command.\cr
+\noalign{\medskip}
+|-i|& |immed_help|& |DV_IMMED_HELP|& |DEF_IMMED_HELP|& Help file displayed\cr
+&&&& at startup.\cr
+\noalign{\medskip}
+|-l|& |landscape|& ---& (portrait)& Landscape page\cr
+&&&& (swaps |-x| and |-y|).\cr
+\noalign{\medskip}
+|-m|& mag& ---& (DVI mag)& Magnification.\cr
+\noalign{\medskip}
+|-p|& |psprefix|& |DV_PSPREFIX|& |DEF_PS_PREFIX|& PS font name prefix.\cr
+\noalign{\medskip}
+|-r|& |xres|,& |DV_RES|& |DEF_XRES|,& X and Y resolutions,\cr
+& |yres|&& |DEF_YRES|& in dots per inch (dpi).\cr
+\noalign{\medskip}
+|-t|& |tfmdir|& |TEXFONTS|& |DEF_TFM_DIR|& TFM files' directory.\cr
+\noalign{\medskip}
+|-v|& |vdu|& |DV_TERM|& ---& Type of VDU.\cr
+&& else&&\cr
+&& |TERM|&&\cr
+\noalign{\medskip}
+|-x|& |paperwd|& |DV_PAPERWD|& |DEF_PAPERWD|& Paper width,\cr
+&&&& in given units.\cr
+\noalign{\medskip}
+|-y|& |paperht|& |DV_PAPERHT|& |DEF_PAPERHT|& Paper height,\cr
+&&&& in given units.\cr
+\noalign{\medskip}
+\enddisplay
+
+Options -d -e -f -h -i -p -r -t are really for system wizards;
+their default values have been set up so that most users need never worry
+about changing them.
+% SYSDEP: take note system wizards!
+
+\noindent Example: A4 paper using a 180 by 360 dpi printer:
+\begindisplay
+|dvgt -r 180,360 -x 210mm -y 297mm|
+\enddisplay
+
+\bigskip
+\noindent Default values in the supplied `defaults.h'.
+
+The default TFM and PK directories are:
+\begindisplay
+|.:/usr/local/lib/tex/fonts|\cr
+|.:/usr/local/lib/tex/fonts/tmp|\cr
+\enddisplay
+These cause {\dvgt} to look first in the current directory, then in the
+directories that are standard for Karl Berry's TeX distribution.
+
+The default dummy TFM metric and PK font files are:
+\begindisplay
+|cmr10.tfm|\cr
+|cmr10.300pk|\cr
+\enddisplay
+since cmr10 is the most commonly used font on most TeX systems,
+and 300 dpi seems the most common resolution among medium quality
+printers at present.
+
+Consequently, the default resolution is 300,300 (dots per inch).
+
+In Karl Berry's font naming convention, PostScript fonts' TFM files
+are prefixed with the letter `p'. By default, {\dvgt} follows this
+convention.
+Several PS font prefixes can be separated by the `:' character,
+as with the PK and TFM directories. The `:' character was chosen
+because it seems easy to remember.
+If no PS font prefixes are specified, as when the list of prefixes is
+an empty string, `', then {\it no\/} fonts are considered PS fonts.
+
+The command and immediate help files default to:
+\begindisplay
+|/usr/local/lib/tex/dvgt/cmd.hlp|\cr
+|/usr/local/lib/tex/dvgt/immed.hlp|\cr
+\enddisplay
+
+Since most of the industrial world uses metric paper, the default
+paper size is A4 (approximately 210 mm wide by 297 mm high).
+
+\medskip
+\bigskip
+\leftline{OPTIONS in DETAIL.}
+\bigskip
+
+\noindent
+Each option is followed by a value of a certain type:
+{\it string\/} is a string of alphanumeric characters,
+{\it i, x, y\/} are positive integers,
+{\it file\/} is a file,
+{\it dir\/} is a directory, and
+{\it dimen\/} is an integer or real number followed by a
+two-letter unit: |bp|, |cm|, |in|, |mm|, |pc|, |pt|, |px| or |sp|.
+(Most of these should be familiar from \TeX\null. {\dvgt} provides
+an additional unit, |px|, which stands for ``paper pixels''.
+These two-letter sequences can be arguments to the `|C|' interactive
+command to change the unit of dimensions---see page 11 for details.) % XREF
+
+\bigskip
+\noindent |-H| {\it dimen\/}~~and~~|-V| {\it dimen\/}
+
+These two qualifiers allow you to shift the location of each page within
+the paper. Negative dimensions are allowed;
+for example, |-H -.5in| shifts each page half an inch to the left.
+
+\bigskip
+\noindent |-d| {\it file\/}
+
+\dvgt\ will warn you if your document uses a font at a non-existent size.
+Rather than abort, it will load the dummy PK file specified by |-d|, and
+following the PK paths, then continue so you can look for more errors.
+Paragraphs using this dummy information are likely to have ragged right
+margins, and tables are likely to be horizontally distorted.
+
+The quickest way to check your DVI file for missing fonts is to type
+the |S| (Statistics) command. The resulting display will indicate
+any PK files that do not exist, and list TFM files that are used
+for Bounding Boxes.
+
+\bigskip
+\noindent |-e| {\it file\/}
+
+If a TFM file is missing, then a dummy TFM is sought in the TFM paths.
+The dummy TFM filename may be set using the |-e| option.
+
+\bigskip
+\noindent |-f| {\it dir\/}
+
+{\dvgt} gets all its bit-mapped font information from PK files stored
+in the specified directory (which can, but need not, end with |/|).
+
+\TeX\ gets all its font information from TFM files. A particular TFM file
+usually has a number of corresponding bit-mapped font files, each one
+corresponding to the same set of ideal character shapes, but at a
+different size.
+Although \TeX\ allows you to scale a font to virtually any size,
+it is obviously impossible to provide an infinite number of bit-mapped fonts.
+That is why it is best to stick to the pre-defined |\magstep| values when
+scaling such fonts---you're much more likely to stay within the range of
+existing PK files.
+
+The above warning does not apply to TFM files for resident
+PostScript or other scalable fonts. Such fonts can be used at any
+desired size.
+However, since no bit-map information is available, \dvgt\ cannot
+show characters from such fonts in a Full display.
+Instead, it shows those characters as outline rectangles, using the
+TFM files to determine their bounding boxes, just as in Box mode.
+
+\bigskip
+\noindent |-h| {\it file\/}
+
+The |?| command reads the help file specified by this option.
+The default help file contains a brief summary of all the commands.
+If no help file can be found, then a pre-compiled help text is shown.
+
+\bigskip
+\noindent |-i|
+
+This `option' only displays the current immediate help file's pathname
+and the name of the corresponding environment variable (|DV_IMMED_HELP|).
+The immediate help file is displayed when {\tt dvgt} is typed alone
+on the command line.
+
+\bigskip
+\noindent |-m| {\it i\/}
+
+This option allows you to replace the magnification used
+in the DVI file with some other value;
+{\it i\/} is a positive integer 1000 $\times$ the desired magnification.
+The given value should be chosen carefully so that the new font sizes
+still correspond to existing PK files.
+
+Unless you know exactly what you are doing, you should avoid changing
+the DVI magnification,
+especially if your \TeX\ source file uses |\magnification| {\it and\/} |true|
+dimensions.
+You should only supply a replacement magnification if you intend to
+print the DVI file with the same override.
+
+\bigskip
+\noindent |-r| {\it x,y\/}
+\noindent |-r| {\it x\/}
+
+{\dvgt} treats the imaginary sheet of paper on which a DVI page will appear
+as a two-dimensional array of tiny dots called {\it paper pixels\/}.
+{\it x\/} and {\it y\/} are positive integers that define the number
+of paper pixels per inch ({\it horizontally} and {\it vertically},
+respectively). When only {x\/} is given, y is assigned the same value.
+
+The |-r| values should match the respective resolutions of the device
+that will be used to print your document.
+The Apple LaserWriter, for instance, has a resolution of 300 dots per
+inch, so {\tt dvgt -r 300} suits it.
+
+\bigskip
+\noindent |-t| {\it dir\/}
+
+If a font name does not include an explicit directory, and requires
+a TFM file, then \dvgt\ will use the |-t| value to locate the file.
+The given value can, but need not, end with |/|.
+
+\bigskip
+\noindent |-v| {\it string\/}
+
+This option explicitly tells {\dvgt} what type of VDU you are using.
+If |-v| is not given, the value of the |DV_TERM| environment variable is used;
+if that is not defined, the value of the |TERM| environment variable is used.
+For example, if you're using a VISUAL 603 terminal and |DV_TERM| and |TERM|
+do not equal |vis603|, then you'll need to type `|dvgt -v vis603 foo|'.
+The purpose of |DV_TERM| is to allow {\dvgt} to use a graphics mode
+distinct from the usual text display mode. This can be useful across
+a network or in X11 windows.
+
+\noindent
+The current version of {\dvgt} will accept the following {\it string\/}
+values in upper or lower case:
+\begindisplay
+|aed512|& (AED 512 with 512 by 512 screen)\cr
+|kermit|& (MS-Kermit, in Tek4010 emulation: same as ncsatel below)\cr
+|ncsatel|& (NCSA Telnet, in Tek4010 emulation)\cr
+|regis|& (any ReGIS compatible VDU;
+ synonyms = |gigi|, |vk100|, |vt125|, |vt240|)\cr
+|tek4010|& (Tek4010 emulation: same as ncsatel above)\cr
+|vis240|& (VISUAL 240; synonym = |vis241|)\cr
+|vis500|& (VISUAL 500)\cr
+|vis550|& (VISUAL 550)\cr
+|vis603|& (VISUAL 603)\cr
+|vis630|& (VISUAL 630)\cr
+|vt100|& (any VT100 compatible VDU)\cr
+|vt100132|& (any VT100 compatible VDU in 132 column mode)\cr
+|vt220|& (VT220 using down-loaded chunky graphics)\cr
+|vt640|& (VT100 with Retro-Graphics)\cr
+\enddisplay
+
+\noindent
+It is assumed your terminal has been set up to obey XON/XOFF flow control.
+
+\noindent
+Some VDUs require special settings for {\dvgt} to work properly:
+
+\item{$\bullet$}
+When using MS-Kermit (eg, version 3.12) over TCP/IP (eg, TELNET), for
+best appearances you may wish to add the following to MSCUSTOM.INI:
+\begindisplay
+set flow-control none\cr
+set terminal graphics character-writing opaque\cr
+set terminal graphics cursor off\cr
+\enddisplay
+
+\item{$\bullet$}
+When writing to a PC monitor over NCSA Telnet, the |ncsatel| terminal
+may sometimes leave you in the wrong screen mode. If that happens,
+type NCSA Telnet's |Alt-R| command to reset the screen to VT102 mode.
+Typing NCSA Telnet's `help' command, |Alt-H|, gives a (VT102 mode) screen
+containing more information.
+
+\item{$\bullet$}
+The |vis630| terminal needs to be in interlace mode.
+Simply hit |Shift-PF3|.
+
+\item{$\bullet$}
+The |vis500| and |vis550| terminals have function keys which control how
+information on the screen is to be displayed. {\dvgt}
+assumes graphic images and alphanumeric text can be seen at the
+same time. To ensure that this is possible, you may need to:
+
+{\parskip=0pt
+\smallskip
+\itemitem{---} hit the |SET-UP| key
+\itemitem{---} hit the |F6| function key until |F6=BOTH| appears
+\itemitem{---} hit the |SET-UP| key to return to normal operating mode.
+\smallskip
+\item{}
+You can do these steps while {\dvgt} is running.
+Both terminal types should also have the Scale Factor set at 3\;:\;4.
+\par
+} % \parskip back to normal
+
+\item{$\bullet$}
+The |regis| VDUs use VT100 escape sequences to update the dialog region,
+and the |vis550| VDU is assumed to be emulating a VT100.
+Change the appropriate |SET-UP| value if your screen becomes full of junk.
+
+\item{$\bullet$}
+The |vt100132|, |vt220|, |vis603| and |vis630| VDUs are automatically
+switched to 132 columns when \dvgt\ starts up
+(and then to 80 columns when you quit).
+MS-Kermit may not approve of 132 columns.
+
+\bigskip
+\noindent |-x| {\it dimen\/}~~and~~|-y| {\it dimen\/}
+
+These two options define the width and height of the paper upon which your
+document will eventually be printed.
+% SYSDEP
+Note that their default values specify A4 paper
+(|210mm| wide and |297mm| high).
+Every time you select a page, {\dvgt} uses the paper dimensions
+to check that all the printed material will fit on the paper.
+
+\vfil\eject
+
+\subhead{Screen Regions.}
+
+\medskip
+\bigskip
+\leftline{DIALOG REGION.}
+\bigskip
+
+If your command line is correct and if the |-v| value matches the type of
+terminal you're actually using, then {\dvgt} will clear the screen
+and display
+\begindisplay
+||$n$| pages DVI page=0 TeX page=[0] Auto=+ F Zoom=2.00|\cr
+|Window at (|$h$|,|$v$|) |$wwd$| by |$wht
+ $| Page at (|$minh$|,|$minv$|) |$pwd$| by |$pht$| IN|\cr
+|This is dvgt 3.51 (DVItoVDU, v. 3.0, gt mod 5 rev. 1) - Wed 25 Aug 93|\cr
+|Command: |\cr
+\enddisplay
+These lines represent the ``dialog region''; the rest of the screen is
+called the ``window region'' and should be blank at this stage.
+
+\noindent
+The top two lines show status information. The first status line shows:
+
+\item{$\bullet$} $n$, the total number of pages in the DVI file.
+
+\item{$\bullet$} The current DVI page and its corresponding \TeX\ page counters.
+ Particular pages can be selected by their position in the DVI
+ file (1 to $n$) or by the value of their \TeX\ counters.
+
+\item{$\bullet$} The |A| command allows you to toggle
+ (alternately enable or disable)
+ the automatic calculation of window position and size upon page
+ selection; initially enabled (|+|).
+
+\item{$\bullet$} The current display mode; initially |F|, for |Full|.
+ The |T|, |B| and |F| commands allow you to toggle each of the
+ |Terse|, |Box| and |Full| display modes. All combinations of these
+ are permissible, but you be the judge of which combinations are useful,
+ and when.
+
+\item{$\bullet$} The current |Zoom| factor; initially |2.00|.
+ The |ZI|, |ZO|, |ZCI| and |ZCO| commands zoom in and out by the
+ current zoom factor.
+ |ZI| $z$ and |ZCI| $z$ zoom in, and |ZCI| $z$ and |ZCO| $z$ zoom
+ out, by the factor $z$, which then becomes the current zoom factor.
+
+\noindent
+The second status line shows:
+
+\item{$\bullet$} The current location and size of the window.
+ $h$ and $v$ are horizontal and vertical coordinates that define
+ the current paper position of the top left corner of the window region.
+ The following section has details on the coordinate scheme used
+ by {\dvgt}\null. The |W| command allows you to move the window to an
+ absolute position; the |U|, |D|, |L| and |R| commands allow relative
+ positioning.
+ $wwd$ and $wht$ represent the current width and height of the window region;
+ their values are changed by the |H| and |V| commands (and by |ZI|,
+ |ZO|, |ZCI| and |ZCO|).
+ The initial window size depends on the |-r| value and the size and
+ resolution of your VDU screen.
+
+\item{$\bullet$} The location and size of the ``page rectangle''.
+ $minh$, $minv$, $maxh$ and $maxv$ define the smallest rectangle containing
+ all the rules and characters in the current page.
+ $(minh{,}minv)$ is the top left corner of this rectangle; it is
+ $pwd$ units wide and $pht$ units high.
+
+\item{$\bullet$} The current units; initially inches.
+ All numbers shown in this line are dimensions in terms of these units.
+ The two letters shown at the end of the line are the unit names.
+ These are: inches (|IN|), centimetres (|CM|), millimetres (|MM|),
+ points (|PT|), picas (|PC|), big (or PostScript, or standard) points
+ (|BP|), scaled points (|SP|), and paper pixels (|PX|).
+ Pixel values are shown as integral numbers and represent exact dimensions;
+ all other values are shown as real numbers rounded to two decimal places.
+ To change the current units, use the |C| command, then the unit name.
+ For example, either |CMM| or |C MM| will change to millimetres.
+
+\noindent
+The third line initially shows the current version number.
+{\dvgt} displays messages of various
+kinds in this line. Some of these messages appear only briefly but may convey
+helpful information.
+Others are more important and indicate some sort of problem, such as
+an invalid command or a page that won't fit on the paper;
+in these cases, hit the |RETURN| key before continuing.
+
+The last line in the dialog region is for entering commands. The first
+thing you normally want to do is choose a particular page for display.
+For example, typing `|1|' will select the first page in the DVI file.
+Many commands can be entered in the one command line. Hit |RETURN| to
+execute the command(s).
+
+\medskip
+\bigskip
+\leftline{WINDOW REGION.}
+\bigskip
+
+The number of paper pixels per inch is given by the |-r| option.
+A pixel can be either black (corresponding to a tiny blob of ink) or white
+(no ink). However, on a screen with black background, inked pixels are
+commonly white, and uninked pixels are black. In the following, `black'
+means inked, and `white' means uninked.
+A typical DVI page contains characters from one or more fonts, and
+perhaps a few rules.
+A rule is simply a rectangular region of black pixels, usually in the shape of
+a thin horizontal or vertical line.
+A character is usually a more complicated pattern of black and white pixels.
+Every character and rule has a
+paper position---or ``reference point''---defined
+by a pair of pixel values $(h{,}v)$
+where $h$ is the horizontal coordinate and $v$ is the vertical coordinate.
+{\dvgt} uses a coordinate scheme in which the
+position $(0{,}0)$ is a pixel one inch in from the top and left edges of
+the paper. Vertical coordinates increase down the paper,
+horizontal coordinates increase to the right.
+Confused? The illustration on page~14 may help clear things up. % XREF
+
+The window region is used to view the current DVI page.
+{\dvgt} treats this region of the VDU screen as a two-dimensional array
+of dots called ``screen pixels'' (to distinguish them
+from the paper pixels described above).
+A screen pixel is the smallest possible area on a VDU screen that
+can be drawn or erased; the greater the number of screen pixels in a given area,
+the higher the resolution of the VDU.
+
+The initial size of the window region depends on the VDU; the width and height
+are set so that each paper pixel corresponds to exactly one screen pixel.
+The most accurate representation of a page will occur at these values since
+neither horizontal nor vertical scaling is necessary:
+\begindisplay
+VDU& initial window size (width by height in pixels)\cr
+\noalign{\smallskip}
+|aed512|& \enskip 512 by 471\cr
+|ncsatel|& 1024 by 780\cr % - gt - Is ncsatel correct?
+|regis|& \enskip 768 by 400\cr
+|vis240|& \enskip 800 by 500\cr
+|vis500|, |vis550|& 1024 by 688\cr
+|vis603|& 1024 by 620\cr
+|vis630|& 1024 by 698\cr
+|vt100|& \quad 80 by \enskip20\cr
+|vt100132|& \enskip 132 by \enskip20\cr
+|vt220|& \enskip 132 by 100\cr
+|vt640|& 1024 by 650\cr
+\enddisplay
+Use the |H| command to change the width (the Horizontal size), and the
+and |V| command to change the height (the Vertical size).
+Try to avoid weird aspect ratios: `|H0.1 V100|' is a perfectly legal
+command string, but produces a very distorted display!
+If you want to zoom in or out, the |ZI|, |ZO|, |ZCI| and |ZCO| commands
+are safer because they tend to maintain the current aspect ratio.
+The higher the resolution of the VDU,
+the greater the accuracy of such scaled displays.
+The command string `|HV|' will restore the window size to the above unscaled
+dimensions.
+
+Note the very low resolution of the |vt100| and |vt100132| VDUs.
+Since the individual dots making up their screens cannot be turned on and off,
+{\dvgt} has to define a screen pixel to be an entire character position.
+A |vt100| screen typically consists of 24 lines of 80 characters,
+therefore the initial window region is 80 pixels wide and 20 pixels high
+(the top 4 lines are used for the dialog region).
+These VDUs can still show bitmap character shapes, if you zoom in
+closely enough!
+At more useful window sizes the resulting displays will be extremely crude.
+Nevertheless, a variety of formatting errors can still be detected on such
+terminals---just don't try proofreading your document!
+
+If automatic window calculation is enabled (|Auto=+|),
+then the size and location of
+the window region are automatically set every time a page is selected.
+{\dvgt} tries to show as much of the
+paper (and presumably the page) as possible, and at a readable scale,
+but without too much distortion.
+After comparing the shape of the paper with the shape of your
+VDU's {\it initial\/} window region, and depending on the location of the
+page, {\dvgt} may show the entire paper,
+or the top or bottom half, or the left or right half.
+If any part of the page is off the paper, then the entire paper
+{\it and\/} the entire page will initially be shown.
+Since most paper sizes have portrait dimensions (width $<$ height), and most
+VDU screens have landscape dimensions (width $>$ height), {\dvgt} will
+normally show the top half of a sheet of paper containing the selected page.
+
+\vfil\eject
+
+\subhead{The Commands.}
+
+In response to the `|Command: |' prompt, you can enter one or more of the
+following commands in upper or lower case. Multiple commands are
+processed in the order given, but the window region is only updated,
+if necessary, at the end of a line of commands. For example,
+if you type `|NFD|' then {\dvgt} will get the Next page, toggle
+Full display mode, move the window Down, and only then display the page.
+If an illegal command is detected, any further commands are ignored.
+Most commands consist of only one or two characters; some can be followed by
+parameters. Spaces before and after commands and parameters are optional.
+
+\parskip=0pt % TURN OFF FROM HERE ON.
+
+\medskip
+\bigskip
+\leftline{MISCELLANEOUS.}
+\bigskip
+
+\item{} \hskip -\the\parindent \hbox to \parindent{|?|\hfil}\null
+Display brief help on the available commands.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|^C|\hfil}\null
+|^C| will return you to the `|Command: |' level of {\dvgt}.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|^L|\hfil}\null
+Refresh the window. (This is not immediate, because all interactive
+commands are read before any is parsed and executed.) Useful if
+the screen gets messed up, as may happen with some network software
+on some VDUs.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|^Q|\hfil}\null
+|^Q| is ignored.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|^S|\hfil}\null
+|^S| is ignored.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|^Z|\hfil}\null
+|^Z| will suspend {\dvgt}.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|A|\hfil}\null
+Toggle Automatic window calculation after page selection.
+When |Auto| is enabled, \dvgt\ will usually show the top half
+of the imaginary sheet of paper. When |Auto| is disabled,
+\dvgt\ will use the current window size and location to display the
+new page.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|Q|\hfil}\null
+Quit from {\dvgt}\null.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|S|\hfil}\null
+Show the option values being used, as well as statistics about the number of
+fonts, characters and rules used on the current page.
+The file specs of each font used (on any page) will be listed.
+You'll also be warned about any fonts that don't exist.
+
+\medskip
+\bigskip
+\leftline{SELECTING A PAGE.}
+\bigskip
+
+\item{} \hskip -\the\parindent \hbox to \parindent{$i$\hfil}\null
+Select the $i$th DVI page. $i$ must be a positive integer from
+1 to $n$ where $n$ is the total number of pages in the DVI file.
+
+\bigskip
+\noindent |[|$i_0$|.|$i_1$|.| $\scriptstyle\cdots$ |.|$i_9$|]|
+\item{}
+Select the DVI page whose \TeX\ page counters match the given specification.
+$i_0$ to $i_9$ are integers separated by periods. Any number of these
+integers may be absent and trailing periods may be omitted.
+An absent integer will match any value in the corresponding counter.
+If more than one DVI page matches, the lowest will be chosen.
+E.g., |[]| is equivalent to |[.........]| and will select the first DVI page,
+even though the request matches every possible page.
+\medskip
+\item{}
+\TeX\ stores the values of |\count0,\count1,...,\count9| in each DVI page.
+Plain \TeX\ only uses |\count0| to control page numbering; the remaining
+counters are set to zero.
+Some macro packages may use the other counters for section or chapter
+numbering; e.g., |[2.5]| might mean ``select page~2 from chapter~5''.
+When showing the current \TeX\ page in the top status line, {\dvgt}
+always shows the value of |\count0|, but trailing counters with zero values are
+not shown.
+Note that plain \TeX\ uses negative values in |\count0| to indicate page
+numbers in roman numerals (such as in a preface).
+In most documents, the $i$th DVI page will be the same as \TeX\ page |[|$i$|]|.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|N|\hfil}\null
+Select the Next DVI page.
+Before any page has been requested, |N| will select the first DVI page.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|P|\hfil}\null
+Select the Previous DVI page.
+Before any page has been requested, |P| will select the last DVI page.
+
+\medskip
+\bigskip
+\leftline{CHANGING HOW A PAGE IS DISPLAYED.}
+\bigskip
+
+\noindent
+The |B|, |F| and |T| commands toggle each of three different ways
+of displaying a page. They may be combined.
+The choice of display mode depends on the capabilities of your VDU
+and the level of detail you wish to see.
+Whatever the display mode, the window region
+is always updated in the following manner:
+Visible paper edges are drawn first, followed by visible rules.
+Visible characters are then shown on a font by font basis; those fonts
+with the least number of characters on the page are drawn first.
+\medskip
+\noindent
+While the window region is being updated,
+but not during the drawing of a rule or character,
+{\dvgt} will check to see if you've typed something at the keyboard.
+You can hit the |RETURN| key to abort the display,
+or you can change the display mode by hitting the |T|, |B| or |F| keys
+in any combination (without hitting |RETURN|). There might be a
+delay between the time you hit a key and the time something actually
+happens, especially if a (visually) large rule or character is being
+drawn. Over slow remote connections, this may take a while!
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|B|\hfil}\null
+Toggle the display of Box outlines of the smallest rectangles containing all
+black pixels in characters.
+The reference point of a \TeX\ character is usually located near
+the bottom left corner of one of these boxes.
+Box mode is intermediate in speed between Terse and Full modes;
+it is a quick and accurate way of checking
+the alignment of entries in a table, for example --- assuming that
+accurate TFM metrics are being used.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|F|\hfil}\null
+Toggle the display of a Full representation of all pixels in characters.
+Full display is the most accurate but may take some time;
+hit |RETURN| or switch to Terse or Box mode if you get bored.
+The fact that the display mode can be changed {\it while the window is
+being updated\/} can be very useful.
+A good compromise between speed and accuracy is
+to start off in Full mode so that math symbols and any other special
+characters are displayed correctly, then to switch to Terse mode
+(by hitting |T|) when the bulk of the text begins.
+Note that characters from a font that lacks a PK file, but has a TFM metric,
+such as PostScript or other scalable fonts, are shown as outline rectangles
+of roughly the right size.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|T|\hfil}\null
+Toggle the display of a Terse representation of characters.
+On high resolution VDUs the \TeX\ text fonts should be quite readable;
+characters will be in
+approximately the right position and may even be about the right size.
+The display on low resolution VDUs can be a bit confusing; characters get
+overwritten if they are too close together. Don't worry too much
+if you suddenly see many more spelling mistakes than usual!
+Note that the text fonts will all look alike in Terse mode.
+The only way to distinguish between different fonts is to note the
+order in which characters are displayed (the less used fonts are drawn first).
+Most of {\dvgt}'s VDU drivers assume all characters come from a
+\TeX\ text font, such as cmr10, and then attempt to map them into
+similar-looking ASCII characters.
+Characters from non-text fonts, such as math symbols, will usually appear
+incorrect.
+
+\medskip
+\bigskip
+\leftline{CHANGING UNITS.}
+\bigskip
+
+\noindent
+All the numbers in the second line of the dialog region are dimensions in
+terms of the units shown at the end of the line.
+The parameters following some commands are also dimensions, in the
+current units:
+unlike the dimensions in \TeX, you don't explicitly type the units when you
+need to specify a dimension after a \dvgt\ interactive command---simply
+enter an integer or real value.
+This value is rounded up internally to the nearest paper pixel, based on the
+current units and the conversion factors shown below.
+To change the units, use the |C| command, followed by the unit name.
+For example, `|CCM H5 V3.4|' will change the units to centimetres and set the
+window size to be 5\;cm wide and 3.4\;cm high.
+The available units are as follows.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|BP|\hfil}\null
+Dimensions are in terms of big points
+(72\;bp $=$ 1\;in).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|CM|\hfil}\null
+Dimensions are in terms of centimetres
+(2.54\;cm $=$ 1\;in).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|IN|\hfil}\null
+Dimensions are in terms of inches.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|MM|\hfil}\null
+Dimensions are in terms of millimetres
+(10\;mm $=$ 1\;cm).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|PC|\hfil}\null
+Dimensions are in terms of picas
+(1\;pc $=$ 12\;pt).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|PT|\hfil}\null
+Dimensions are in terms of points
+(72.27\;pt $=$ 1\;in).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|PX|\hfil}\null
+Dimensions are in terms of paper pixels.
+(The |-r| command line option sets the numbers of horizontal and
+vertical paper pixels per inch).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|SP|\hfil}\null
+Dimensions are in terms of scaled points
+(65536\;sp $=$ 1\;pt).
+
+\medskip
+\bigskip
+\leftline{MOVING THE WINDOW.}
+\bigskip
+
+\noindent
+The window region can be moved to any position over the current page.
+You will be told if the window moves entirely outside the page rectangle
+defined by $minh$, $minv$, $maxh$ and $maxv$. If this does happen, movement
+is restricted to {\it just outside\/} the edges to make it easier to get back
+over the page using only the |U|, |D|, |L| and |R| commands.
+If |Auto=+| then the location of the window is automatically set every time a
+page is selected. This position will normally be
+the top left corner of the paper; i.e., $(-1,-1)$ in inches.
+The parameters $h$ and $v$ are dimensions ranging from $-480$ inches to
+$+480$ inches (for those of you \TeX ing billboards).
+
+\bigskip
+\noindent |W| $h$|,|$v$
+\item{}
+Move the Window region's top left corner to the given paper position.
+$h$ is the horizontal coordinate, $v$ is the vertical coordinate.
+If $h$ and $v$ are absent then the window is moved to $(minh{,}minv)$,
+the top left corner of the page rectangle.
+
+\bigskip
+\noindent |U| $v$
+\item{}
+Move the window Up $v$ units.
+If $v$ is absent then move up an amount equal to half the window's
+current height.
+
+\bigskip
+\noindent |D| $v$
+\item{}
+Move the window Down $v$ units.
+If $v$ is absent then move down an amount equal to half the window's
+current height.
+
+\bigskip
+\noindent |L| $h$
+\item{}
+Move the window Left $h$ units.
+If $h$ is absent then move left an amount equal to half the window's
+current width.
+
+\bigskip
+\noindent |R| $h$
+\item{}
+Move the window Right $h$ units.
+If $h$ is absent then move right an amount equal to half the window's
+current width.
+
+The default behavior of |U|, |D|, |L| and |R| was changed in {\dvgt}
+version 3.5 to move by half the window dimension instead of by the
+full window size. The newer behavior retains some visible context
+when moving the window.
+
+\medskip
+\bigskip
+\leftline{CHANGING WINDOW SIZE.}
+\bigskip
+
+\noindent
+The |H| and |V| commands are used to change the
+width and height of the window region.
+It is up to you to maintain a sensible aspect ratio.
+
+The |ZI|, |ZO|, |ZCI| and |ZCO| zoom commands change both dimensions
+by the same factor and so maintain the current aspect ratio.
+|ZI| and |ZO| keep the top left of the window fixed;
+|ZCI| and |ZCO| hold the centre of the window fixed.
+If zooming causes the page to become invisible, the location of the
+window may change;
+otherwise, |ZCI| and |ZCO| are equivalent to |DRZI<z>UL| and
+|DRZO<z>UL|, respectively,
+where |<z>| represents the specified zoom factor (if any).
+
+If |Auto=+| then the width and height of the window are automatically set every
+time a page is selected; the values chosen will depend on the paper dimensions.
+The parameters $wd$ and $ht$ are dimensions ranging from 1 pixel to 480 inches.
+
+\bigskip
+\noindent |H| $wd$
+\item{}
+Set the Horizontal size of the window to the given width.
+If $wd$ is absent then set window width to its initial, unscaled value
+(one screen pixel's width equals one paper pixel's width).
+
+\bigskip
+\noindent |V| $ht$
+\item{}
+Set the Vertical size of the window to the given height.
+If $ht$ is absent then set window height to its initial, unscaled value
+(one screen pixel's height equals one paper pixel's height).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|ZI| $z$\hfil}\null
+Zoom In (holding the top left of the window) by dividing the current
+window height and width both by $z$.
+This also sets the current zoom factor to $z$.
+If $z$ is absent, then Zoom In by the current zoom factor.
+Initially, the current zoom factor is 2 (two).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|ZO| $z$\hfil}\null
+Zoom Out (holding the top left of the window) by multiplying the
+current window height and width both by $z$.
+This also sets the current zoom factor to $z$.
+If $z$ is absent, then Zoom Out by the current zoom factor.
+Initially, the current zoom factor is 2 (two).
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|ZCI| $z$\hss}\null
+Zoom Center In --- as for |ZI|, except holding the window's centre.
+
+\bigskip
+\item{} \hskip -\the\parindent \hbox to \parindent{|ZCO| $z$\hss}\null
+Zoom Center Out --- as for |ZO|, except holding the window's centre.
+
+\vfil\eject
+
+\subhead{The Coordinate Scheme.}
+
+% MACROS FOR DIAGRAM.
+% \plot is based on \point macro described on page 389 of _The TeXbook_.
+
+\newdimen\unit
+\unit=1truein
+
+\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}}}
+
+\newdimen\pix
+\pix=.003truein % SYSDEP: .003" is approx 1 pixel for a 300dpi device
+
+\def\bigdot{\hbox to 0pt{\hss\kern3\pix$\scriptstyle\bullet$\hss}}
+\def\dot{\chlap{$\cdot$}}
+
+\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\vleaders{\leaders\vbox to .1\unit
+ {\vss\hrule width1sp height.05\unit\vss}\vfil}
+\def\hleaders{\leaders\hbox to .1\unit
+ {\hss\vrule height1sp width.05\unit\hss}\hfil}
+
+\def\cornervrule{\hbox{\vrule width1sp height.075\unit}}
+\def\cornerhrule{\vrule width.075\unit height1sp}
+
+\newdimen\paperwd \paperwd =\hsize
+\newdimen\paperht \paperht =8.0\unit
+\newdimen\pagewd \pagewd =3.0\unit
+\newdimen\pageht \pageht =4.0\unit
+\newdimen\windowwd \windowwd =2.5\unit
+\newdimen\windowht \windowht =2.6\unit
+
+\def\draworiginbox
+ {\plot 0 0
+ \cvlap{\bigdot}
+ \ulap{\vbox to 1\unit
+ {\kern.25truemm
+ \leaders\vbox to 1truemm{\vss\moveright1\pix\dot\vss}\vfil
+ \kern.75truemm
+ }
+ }
+ \cvlap{\kern2\pix % shift dots down slightly
+ \llap{\hbox to 1\unit
+ {\kern.25truemm
+ \leaders\hbox to 1truemm{\hss\dot\hss}\hfil
+ \kern.75truemm
+ }}
+ }
+ \ulap{\vbox to 1\unit
+ {\vfil
+ \rlap{~~\rlap{$1''$}~~~~~~The numbers of horizontal and
+ vertical pixels per inch
+ are set by |-r| option.}
+ \vfil
+ }
+ }
+ \ulap{\llap{$(0{,}0)$~~}
+ \medskip
+ }
+ \cvlap{\rlap{~~\rlap{$\rightarrow$}~~~~~~increasing $h$ coordinates}}
+ \dlap{\kern 1ex
+ \llap{\strut \hbox to 1\unit{\hfil$1''$\hfil}}
+ }
+ \dlap{\kern 1ex
+ \chlap{\strut $\downarrow$}
+ \chlap{\strut increasing}
+ \chlap{\strut $v$ coordinates}
+ }
+ \endplot
+ }
+
+\def\drawpaperbox
+ {\plot -1 -1 % top left corner of paper box
+ \vbox
+ {\hsize=\paperwd % width of paper box
+ \ulap
+ {\line{\rlap{$(-1,-1)$ in inches}\hss
+ Paper edges will be displayed if visible.\hss}
+ \medskip
+ }
+ \cvlap{\bigdot}
+ \hrule height 1sp
+ \hbox to \hsize
+ {\vrule height \paperht width 1sp % height of paper box
+ \vbox to \paperht
+ {\vfil
+ \rlap{ \strut Paper height is set}
+ \rlap{ \strut by |-y| option.}
+ \vfil
+ }\hfil
+ \vrule height \paperht width 1sp
+ }
+ \hrule height 1sp
+ \medskip
+ \centerline{Paper width is set by |-x| option.}
+ }
+ \vss
+ \endplot
+ }
+
+\def\drawpagebox
+ {\plot 2.2 0.6 % top left corner of page box
+ \vbox
+ {\hsize=\pagewd % width of page box
+ \cvlap{\llap{Page at $(minh{,}minv)$~~}}
+ \cvlap{\bigdot}
+ \cvlap{\rlap{\hbox to \pagewd
+ {\cornerhrule\hleaders\cornerhrule}}}
+ \dlap{\vbox to \pageht
+ {\centerline{\title Chapter 56}
+ \vskip1.175\unit
+ {\advance\hsize by 6\pix % get N touching maxh
+ \line{\title How\hfil to\hfil LOGIN}
+ }
+ \vfil
+ \setbox0=\hbox{\bigbf g}
+ \setbox1=\copy0
+ \dp0=0sp
+ \centerline
+ {\bigbf HAL\thinspace9000 Be\copy0inner's Guide}
+ \kern\dp1 % get g touching maxv
+ }
+ }
+ \hbox to \hsize
+ {\vbox to \pageht % height of page box
+ {\cornervrule\vleaders\cornervrule}%
+ \vbox to \pageht
+ {\vfil
+ \llap{Page height. }
+ \vfil
+ }%
+ \hfil
+ \vbox to \pageht
+ {\cornervrule\vleaders\cornervrule}%
+ }
+ \cvlap{\rlap{\hbox to \pagewd
+ {\cornerhrule\hleaders\cornerhrule}}}
+ \cvlap{\rightline{\bigdot}}
+ \cvlap{\rightline{\rlap{~~$(maxh{,}maxv)$}}}
+ \medskip
+ \centerline{Page width.}
+ }
+ \vss
+ \endplot
+ }
+
+\def\drawwindowbox
+ {\plot 1.2 1.6 % top left corner of window box
+ \vbox
+ {\hsize=\windowwd % width of window box
+ \ulap
+ {\centerline{Window width is set by |H| command.}
+ \medskip
+ }
+ \cvlap{\llap{Window at $(h{,}v)$~~}}
+ \cvlap{\bigdot}
+ \cvlap{\rlap{\hbox to \windowwd
+ {\cornerhrule\hleaders\cornerhrule}}}
+ \dlap{\medskip
+ \centerline{\strut Use |U|, |D|, |L|, |R| and |W| commands}
+ \centerline{\strut to move the window.}
+ }
+ \dlap{\kern1\unit
+ \vbox to 1.6\unit
+ {\hsize=2\unit
+ \vfil
+ \centerline{\strut Only this portion of the}
+ \centerline{\strut page is currently visible.}
+ \vfil
+ }
+ }
+ \hbox to \hsize
+ {\vbox to \windowht % height of window box
+ {\cornervrule\vleaders\cornervrule}%
+ \hfil
+ \vbox to \windowht
+ {\cornervrule\vleaders\cornervrule}%
+ \vbox to \windowht
+ {\vfil
+ \rlap{ \strut Window height is}
+ \rlap{ \strut set by |V| command.}
+ \vfil
+ }\relax
+ }
+ \cvlap{\rlap{\hbox to \windowwd
+ {\cornerhrule\hleaders\cornerhrule}}}
+ }
+ \vss
+ \endplot
+ }
+
+% SWITCH TO SMALLER FONT, MOVE TO 0,0 AND START PLOTTING.
+
+\smallrm
+
+\vskip 1.5\unit
+\hbox
+ {\kern 1\unit % 0,0 is 1\unit in from left margin
+ \draworiginbox
+ \drawpaperbox
+ \drawpagebox
+ \drawwindowbox
+ }
+
+\rm % back to normal text
+
+\vfil\eject
+
+\subhead{Some Examples.}
+
+\medskip
+\noindent
+For clarity, commands are separated by spaces and typed
+in upper case; neither condition is mandatory.
+
+\bigskip\noindent
+|P P P|
+\item{}
+If these commands are given before a page has been requested, they will select
+the 3rd last page for display (assuming there are at least 3 pages).
+The first |P| selects the last page;
+the remaining |P|s go back another 2 pages.
+Note that only the 3rd last page will be displayed. The intervening pages are
+still processed, though, and you'll be warned about any problems with them
+(such as a page off the paper).
+
+\bigskip\noindent
+% |1 F W H V| % - gt - in the days before dvgt 3.5,
+% % when Full was not a toggle, and
+% % Terse mode was the default.
+|1 W H V|
+\item{}
+This command sequence is very useful for looking carefully at the results of
+a small \TeX\ experiment. You might, for instance, want to look closely
+at the appearance of two characters separated by a small |\kern|.
+Suppose that Full display only is on (as is easily arranged). Then:
+|1|~selects the first DVI page (usually the only page in such experiments);
+% |F|~sets the display mode to full; % - gt - since dvgt 3.5, |F| toggles,
+% % and Full mode is the default.
+|W|~moves the window to the top left corner of the page;
+|H|~sets the horizontal size of the window to its unscaled value, and
+|V|~sets the vertical size of the window to its unscaled value.
+Remember that this unscaled window size produces the most accurate display,
+since each screen pixel corresponds to exactly one paper pixel, both
+horizontally and vertically.
+
+\bigskip\noindent
+|R9999 L D9999 U|
+\item{}
+Sometimes you want to move quickly to the right edge of the page to have a
+look at line breaks, or you might want to go to the bottom and look at where
+the page was broken.
+This particular command sequence will move the window's {\it bottom right\/}
+corner to the bottom right corner of the current page; i.e., $(maxh{,}maxv)$.
+In most current units (except scaled points, |SP|, which are minute),
+|R9999|~suffices to move the entire window to the right of the page,
+but only just;
+|L|~then moves the window left by its current width so that the {\it right\/}
+edges of the window and the page coincide;
+|D9999|~moves the entire window below the page, but only just;
+|U|~then moves the window up by its current height so that the {\it bottom\/}
+edges of the window and page also coincide.
+
+\bigskip\noindent
+|1 ZO2 FB|
+\item{}
+It is often useful to get an overview of the positioning of printed matter
+within the sheet of paper.
+These commands will do just that on all the VDUs currently
+implemented, assuming that automatic window calculation is enabled
+and that the display mode is already set to Full only.
+|1|~selects the first page, moves the window to the top left corner of
+the paper, sets the window height to half the paper height and the
+window width to the paper width
+(resulting in a sensible aspect ratio on a typical VDU screen);
+|ZO2|~doubles the window height and width, keeping the top left
+corner of the window coincident with the top left corner of the paper,
+so that the entire sheet of paper is visible and maintains the right
+proportions;
+|FB|~changes the Full only display mode to Box outlines only,
+since the characters are now likely to be too small to read.
+
+\bigskip\noindent
+% |[.56] W IN H2.5 V2.6 R1 U1 F| % - gt - before dvgt 3.5. Now:
+|[.56] W IN H2.5 V2.6 R1 U1|
+\item{}
+This is the likely command sequence that led to the window display shown in the
+illustration on the previous page. % XREF
+The [original] author [Andrew Trevorrow] has been clever enough to define
+a |\chapter| macro that sets |\count1| to the given chapter number.
+|[.56]|~will thus select the appropriate DVI page (|\count0| is ignored);
+|W|~moves the window to the top left corner of the page;
+|IN|~sets the current units to inches;
+|H2.5|~and |V2.6|~set the window dimensions;
+|R1|~moves the window right 1 inch;
+|U1|~moves the window up 1 inch;
+% |F|~sets the display mode to full. % - gt - before dvgt 3.5.
+
+\finishline
+\bye
diff --git a/dviware/dvgtk/dvgt.c b/dviware/dvgtk/dvgt.c
new file mode 100644
index 0000000000..2c5b6dd3d9
--- /dev/null
+++ b/dviware/dvgtk/dvgt.c
@@ -0,0 +1,3595 @@
+/* dvgtk.c - main dvgtk functions
+ $Id: dvgt.c,v 0.2 1997/03/28 03:15:36 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+
+#include <kpathsea/c-ctype.h>
+#include <kpathsea/proginit.h>
+#include <kpathsea/tex-file.h>
+
+#include "defaults.h"
+#include "screenio.h"
+#include "options.h"
+#include "unixio.h"
+#include "vdu.h"
+#include "dvireader.h"
+#include "fontreader.h"
+
+/* Variables Exported, via vdu.h */
+
+int DVIstatusl, windowstatusl, messagel, commandl, bottoml;
+int windowh, windowv, windowwd, windowht;
+
+
+static void DisplayPage ();
+static void NextCommandLine ();
+static boolean ShowCmdHelp ();
+
+
+/*----------------------------------------------------------------------
+ DECLARATIONS FOR PROCESSING USER COMMANDS
+
+ Most commands consist of one or two characters and can be entered in
+ upper or lowercase. Multiple commands are processed in the order
+ given but we only update the window, if necessary, at the end. If a
+ bad command is encountered, any further commands are ignored. Some
+ commands can have parameters; they are all dimensions in terms of the
+ current units. Spaces before and after commands and parameters are
+ ignored.
+*/
+
+/* Possible commands are: */
+/* i a positive integer; display ith DVI page */
+
+#define TeXpage "["
+ /* start of a TeX page specification: [i0. ... .i9] */
+#define NextPage "N"
+ /* display next DVI page, depending on direction */
+#define Window "W"
+ /* move window's top left corner to given position */
+#define Up "U"
+ /* move window up a given amount */
+#define Down "D"
+ /* move window down a given amount */
+#define Left "L"
+ /* move window left a given amount */
+#define Right "R"
+ /* move window right a given amount */
+#define Hsize "H"
+ /* set scaledwd: window's horizontal size */
+#define Vsize "V"
+ /* set scaledht: window's vertical size */
+#define AutoView "A"
+ /* enable/disable automatic view after page selection */
+#define ZoomInOut "Z"
+ /* halve/double window dimensions */
+#define Terse "T"
+ /* display quick and nasty chars at reference points */
+#define Box "B"
+ /* display box outlines of glyphs */
+#define Full "F"
+ /* display all pixels in glyphs */
+#define Ic "I"
+ /* get/show dimensions in inches */
+#define Cm "C"
+ /* get/show dimensions in centimetres */
+#define Mm "M"
+ /* get/show dimensions in millimetres */
+#define PcPtPx "P"
+ /* get/show dimensions in picas/points/pixels */
+#define Help "?"
+ /* display help on available commands */
+#define Show "S"
+ /* display useful statistics */
+#define Quit "Q"
+ /* have a guess */
+
+#define commprompt "Command: "
+
+
+static String commstring; /* holds user responses */
+static int commpos; /* current position in commstring */
+static int commlen; /* length of commstring */
+static char command; /* starting character of command */
+static int maxpix;
+/* maximum absolute pixel value; depends on resolution */
+/* These flags are used to handle multiple commands: */
+static boolean screenjustcleared;
+ /* has screen just been cleared? */
+static boolean paintDVIStatus; /* does DVI status line need updating? */
+static boolean paintWindowStatus;
+ /* does window status line need updating? */
+static boolean paintwindow; /* does window region need updating? */
+static boolean pageoffpaper; /* is page off paper? */
+static boolean badcommand; /* was there a bad command? */
+
+
+/*----------------------------------------------------------------------
+ DECLARATIONS FOR DISPLAYING A PAGE
+
+ The reference points of characters and rules on a page are stored as
+ pairs of horizontal and vertical paper pixel coordinates.
+ The paper coordinate scheme is described in detail in DVIReader.
+ The screen coordinate scheme is described in detail in VDU.
+ To update the window region, DVItoVDU maps visible paper pixels
+ to screen pixels using windowh and windowv to help with translation,
+ and windowwd and windowht to help with scaling.
+ What the user sees depends on the current displaymode, the current size
+ of the window region (scaledwd by scaledht are in paper pixels and determine
+ the horizontal and vertical scaling factors), and the current paper position
+ of the window region's top left corner; i.e., (windowleft,windowtop).
+
+ A NOTE ON THE SCALING METHOD USED BY DVItoVDU:
+ We desire the following conditions when scaling paper pixels to
+ screen pixels:
+ 1. Rules/glyphs having the same top/bottom/left/right paper coordinates also
+ have the same screen coordinates (e.g., to ensure baselines line up).
+ This condition is incompatible with a rule/glyph staying the same
+ width and height as the window position changes! Too bad.
+ 2. After being scaled, visible pixel positions must not exceed the
+ window region's edges. In our case, only the bottom and right edges are
+ a problem because scaling starts at the top left corner of the window.
+ We use two different scaling calculations depending on
+ whether the h/vscalefactors are < 1.0 or not.
+ 3. Scaled heights and widths must be > 0 even when h/vscalefactors
+ approach 0. If h/vscalefactors are > 1.0 then the width/height of
+ paper pixels increase accordingly.
+*/
+
+/* terse - show quick and nasty chars at ref pts */
+/* box - show box outlines of glyphs */
+/* full - show all pixels in glyphs */
+
+#define tersemode 1
+#define boxmode 2
+#define fullmode 4
+int displaymode;
+
+/* we get/show dimensions in currentunits */
+units currentunits;
+
+static int papertop, paperleft, paperbottom, paperright;
+ /* these define the edges of the paper */
+
+static int windowtop, windowleft, windowbottom, windowright;
+ /* these define the current window edges */
+
+static boolean allpagevisible; /* is all of page visible in window? */
+static boolean outsidepage; /* is entire window outside page? */
+static int scaledht; /* current window height in paper pixels */
+static int scaledwd; /* current window width in paper pixels */
+static double zoomfactor; /* current zoom factor - default is 2 */
+static double vscalefactor; /* windowht / scaledht */
+static double hscalefactor; /* windowwd / scaledwd */
+static ruleinfo *thisruleinfo; /* current rule info in rulelist */
+static fontinfo *unusedfont; /* first unused font in sorted fontlist */
+static fontinfo *thisfontinfo; /* current font info in sorted fontlist */
+static charinfo *thischarinfo; /* current char info in charlist */
+static int thischar; /* current index into current chartable */
+static boolean fontopen; /* is thisfontinfo->fontspec open? */
+static boolean useraborted; /* did user abort page display? */
+static boolean autoviewing; /* automatic window view enabled? */
+
+static char *immed_help_strings[] =
+{
+ DVGT_VERSION,
+ "dvgt interactively views TeX-generated DVI files on some common VDUs.",
+ "This is the precompiled help shown if no arguments are given.",
+ "The options help file, `options.txt', gives more information.",
+ "USAGE:",
+ " dvgt filename[.dvi]",
+ " [-H x_offset] [-V y_offset] [-d dummy_pk] [-e dummy_tfm]",
+ " [-i] [-k kpathsea_debug_mode] [-l]",
+ " [-m magnification] [-r xres[,yres]]",
+ " [-t tfm_directory] [-x paperwd] [-y paperht]",
+ "",
+ "-H horizontal_offset (default = 0.0 in)",
+ "-V vertical_offset (default = 0.0 in)",
+ "-l (set landscape mode, instead of the default portrait mode)",
+ "-m magnification (default = DVI file's intrinsic magnification)",
+ "",
+ "The other parameters' default values are system dependent.",
+ NULL
+};
+
+static char *cmd_help_strings[] =
+{
+ "MISCELLANEOUS CHANGING PAGE DISPLAY (TOGGLES)",
+ "? Display this command help info T Terse - fast but inaccurate",
+ "S Show options, fonts and page info B Bounding Box of glyphs",
+ "A Toggle Auto window F Full - accurate but slow",
+ "^L Refresh screen",
+ "Q Quit from dvgt CHANGING UNITS OF DIMENSIONS",
+ " C u Where u is one of the units",
+ "SELECTING A PAGE BP, CM, IN, MM, PC, PT, PX, or SP",
+ "[i0. ... .i9] Select TeX page (big point, cm, inch, mm, pica,",
+"i Select the ith DVI page point, paper pixel, or scaled point)",
+ "N Next DVI page",
+ "P Previous DVI page MOVING THE WINDOW",
+ " W h,v Move Window to given posn",
+"CHANGING THE SIZE OF THE WINDOW or to (minh,minv) if no h,v ",
+ "H x Set Horiz. window size to x U v Move window Up by v",
+" or to unscaled width if no x or by half current ht if no v",
+ "V y Set Vertical window size to y D v Move window Down by v",
+ " or to unscaled height if no y or by half cur. ht if no v",
+ "ZI z Zoom In by factor z L h Move window Left by h",
+" or by current factor if no z or by half cur. width if no h",
+ "ZO z Zoom Out, as for ZI R h Move window Right by h",
+"ZCI z, ZCO z Zoom wrt window center or by half cur. width if no h",
+ NULL
+};
+
+/*--------------------------------------------------------------------*/
+
+static void
+ClearMessageLine ()
+{
+ /* Clear message line and move cursor to start of line.
+ We don't show any message here; that will usually be done
+ immediately after calling this routine.
+ */
+ ClearTextLine (messagel);
+ MoveToTextLine (messagel);
+}
+/* ClearMessageLine */
+/*--------------------------------------------------------------------*/
+static void
+WaitForReturn ()
+{
+ /* DVItoVDU has just displayed an important message.
+ To ensure message is seen we wait for user to hit Return.
+ */
+
+ char ch;
+
+ MesgFlush ();
+ do
+ {
+ ReadChar (&ch);
+ }
+ while (ch != CR);
+}
+/* WaitForReturn */
+/*--------------------------------------------------------------------*/
+static boolean
+PrintText (char **text)
+{
+ int retval = false;
+
+ if (text == (char **) NULL)
+ {
+ retval = false; /* No text to print. */
+ }
+ else
+ {
+ /* Print each text string */
+ for (; *text != (char *) NULL; text++)
+ {
+ printf ("%s", *text);
+ /* If there's no newline in *text, print one. */
+ if (strchr (*text, '\n') == (char *) NULL)
+ printf ("\n");
+ }
+ retval = true;
+ }
+ return retval;
+}
+/* PrintText */
+/*--------------------------------------------------------------------*/
+static boolean
+ShowText (char **text)
+{
+ /* Show text of consecutive lines, in a way something like UNIX more. */
+ int lines;
+ char answer;
+
+ if (text == (char **) NULL)
+ {
+ ClearMessageLine ();
+ MesgString ("NULL text!");
+ return false;
+ }
+ ClearScreen ();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ rawoutoff ();
+
+ for (lines = 0; true; lines++)
+ {
+ if (text[lines] == (char *) NULL)
+ { /* end of text */
+ ClearTextLine (bottoml);
+ MoveToTextLine (bottoml);
+ MesgString ("End of text,");
+ MesgString (" hit RETURN key to resume page display: ");
+ MesgFlush ();
+ do
+ {
+ ReadChar (&answer);
+ }
+ while (answer != CR);
+ break; /* EXIT point 1 of 2 from enclosing (for) loop */
+ }
+ if (lines >= bottoml - 2)
+ {
+ /* blank line before prompt */
+ ClearTextLine (bottoml);
+ MoveToTextLine (bottoml);
+
+ /* prompt */
+ MesgString ("Hit RETURN key to resume page display,");
+ MesgString (" or any other key for more text: ");
+ MesgFlush ();
+
+ ReadChar (&answer);
+ if (answer == CR)
+ break; /* EXIT point 2 of 2 from enclosing (for) loop */
+
+ ClearScreen ();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ lines = 0; /* reset line count */
+ }
+ MesgString (text[lines]);
+ MesgLine ();
+ }
+
+ rawouton ();
+ ClearScreen ();
+ screenjustcleared = true;
+ paintDVIStatus = true;
+ paintWindowStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+
+ return true;
+}
+/* ShowText */
+
+/*--------------------------------------------------------------------*/
+static boolean
+ShowCmdHelp ()
+{
+ /* Help information is displayed in lines 1 to bottoml-2.
+ We assume that bottoml is at least 3 and that VDU screen is at least
+ maxline characters wide.
+ */
+ return ShowText (cmd_help_strings);
+}
+/* ShowCmdHelp */
+/*--------------------------------------------------------------------*/
+void
+PadMesg ()
+{
+ /* Pad current text line with spaces. */
+ String padding;
+ int i;
+ for (i = 0; i < maxstring; i++)
+ padding[i] = ' ';
+ padding[maxstring] = '\0';
+ MesgString (padding);
+}
+/* Pad Mesg */
+/*--------------------------------------------------------------------*/
+static void
+InitWinVars ()
+{
+ /* TeX will not generate dimensions > than about 38 feet, so we
+ choose an absolute limit on our dimensions to be 40 feet.
+ */
+
+ int ymaxpix = yres * (40 * 12); /* 40 ft = 40 * 12 in */
+ maxpix = xres * (40 * 12);
+ if (ymaxpix < maxpix)
+ maxpix = ymaxpix;
+
+ /* top left corner of paper is fixed at (-1",-1") */
+ papertop = -yres;
+ paperleft = -xres;
+
+ paperbottom = papertop + paperht - 1;
+ paperright = paperleft + paperwd - 1;
+
+ /* User sees the following status values before requesting the first page. */
+
+ /*
+ FIRST STATUS LINE: # pages, DVI page, TeX page, Auto, Displaymode, Zoom.
+ Note that DVIReader has already counted the number of pages,
+ and initialized currDVIpage and currTeXpage.
+ */
+
+ autoviewing = true; /* start off enabled */
+ displaymode = fullmode; /* Full mode, neither Box nor Terse mode */
+ zoomfactor = 2.0; /* default factor for zooming is 2 */
+
+ /*
+ SECOND STATUS LINE: Window loc. & dims, Page loc. & dims, Unit.
+ */
+
+ windowleft = 0; /* window location */
+ windowtop = 0;
+ scaledwd = windowwd; /* window size is initially unscaled */
+ scaledht = windowht;
+
+ minhp = 0;
+ minvp = 0; /* page location */
+ maxhp = 0;
+ maxvp = 0;
+ hscalefactor = 1.0; /* page size is initially unscaled, too */
+ vscalefactor = 1.0;
+
+ currentunits = ic; /* inch */
+
+ /* WINDOW: Chars & Rules. */
+
+ pageempty = true; /* no page read yet, so no chars and no rules! */
+}
+/* InitWinVars */
+
+/*--------------------------------------------------------------------*/
+static void
+UpdateDVIStatusLine ()
+{
+ /* Show totalpages, currDVIpage, currTeXpage, direction and displaymode. */
+
+ int i, lastnonzero;
+
+ ClearTextLine (DVIstatusl);
+ MoveToTextLine (DVIstatusl);
+
+ MesgInt (totalpages);
+ MesgString (" pages");
+
+ MesgString (" DVI page=");
+ MesgInt (currDVIpage);
+
+ MesgString (" TeX page=");
+
+ MesgChar ('[');
+
+ lastnonzero = 9;
+ while (lastnonzero > 0 && currTeXpage[lastnonzero] == 0)
+ {
+ lastnonzero--; /* find last counter with non-zero value */
+ }
+ /* always show \count0 but don't show trailing 0 counters */
+ for (i = 0; i <= lastnonzero; i++)
+ {
+ MesgInt (currTeXpage[i]);
+
+ if (i != lastnonzero)
+ MesgChar ('.');
+ }
+ MesgChar (']');
+
+ MesgString (" Auto=");
+ if (autoviewing)
+ MesgChar ('+');
+ else
+ MesgChar ('-');
+
+ MesgString (" ");
+ if (displaymode & tersemode)
+ MesgString ("T");
+ else
+ MesgString (" ");
+
+ if (displaymode & boxmode)
+ MesgString ("B");
+ else
+ MesgString (" ");
+
+ if (displaymode & fullmode)
+ MesgString ("F");
+ else
+ MesgString (" ");
+
+ {
+ String msgstring;
+ /* gt - this is surely safe from overflow of msgstring - yes? */
+ sprintf (msgstring, " Zoom=%.2f", zoomfactor);
+ MesgString (msgstring);
+ }
+
+ MesgLine ();
+}
+/* UpdateDVIStatusLine */
+
+
+/*--------------------------------------------------------------------*/
+static void
+WriteDimension (double precision, double res, int pixels)
+{
+ /* Show the given pixel dimension in terms of currentunits. */
+
+ double realdim = 0.0;
+ int fracpart;
+
+ if (currentunits == px)
+ MesgInt (pixels);
+ else
+ {
+ switch (currentunits)
+ {
+ case ic:
+ realdim = (double) pixels / res;
+ break;
+ case cm:
+ realdim = (double) pixels / res * 2.54;
+ break;
+ case mm:
+ realdim = (double) pixels / res * 25.4;
+ break;
+ case bp:
+ realdim = (double) pixels / res * 72.0;
+ break;
+ case pc:
+ realdim = (double) pixels / res * 72.27 / 12.0;
+ break;
+ case pt:
+ realdim = (double) pixels / res * 72.27;
+ break;
+ case sp:
+ realdim = (double) pixels / res * 72.27 * 65536.0;
+ break;
+ case px:
+ return; /* can't happen */
+ } /* currentunits */
+ /* gt - This seems immensely complicated, for what it's doing! */
+ /* show realdim to the specified precision */
+ if (fabs (realdim) < 0.5 * precision)
+ MesgString ("0.0");
+ else
+ {
+ if (realdim < 0.0)
+ {
+ MesgChar ('-');
+ realdim = fabs (realdim);
+ }
+ realdim += 0.5 * precision; /* round up to specified precision */
+ MesgInt ((int) realdim); /* whole part */
+ MesgChar ('.');
+ fracpart = (int) ((realdim - (int) realdim) / precision);
+ MesgInt (fracpart);
+ } /* if */
+ } /* if */
+}
+
+/* WriteDimension */
+
+/*--------------------------------------------------------------------*/
+static void
+WriteXDim (double precision, int pixels)
+{
+ WriteDimension (precision, xres, pixels);
+}
+/* Write XDim */
+/*--------------------------------------------------------------------*/
+static void
+WriteYDim (double precision, int pixels)
+{
+ WriteDimension (precision, yres, pixels);
+}
+/* Write YDim */
+/*--------------------------------------------------------------------*/
+static void
+UpdateWindowStatusLine ()
+{
+ /* Show current window location and size, page location and size, and units. */
+
+ double precision = 0.1; /* precision for status line */
+
+ ClearTextLine (windowstatusl);
+ MoveToTextLine (windowstatusl);
+
+ MesgString ("Window at (");
+ WriteXDim (precision, windowleft);
+ MesgChar (',');
+ WriteYDim (precision, windowtop);
+ MesgString (") ");
+ WriteXDim (precision, scaledwd);
+ MesgString (" by ");
+ WriteYDim (precision, scaledht);
+
+ MesgString (" Page at (");
+ WriteXDim (precision, minhp);
+ MesgChar (',');
+ WriteYDim (precision, minvp);
+ MesgString (") ");
+ WriteXDim (precision, maxhp - minhp + 1);
+ MesgString (" by ");
+ WriteYDim (precision, maxvp - minvp + 1);
+ MesgString (" ");
+
+ switch (currentunits)
+ {
+ case ic:
+ MesgString ("IN");
+ break;
+ case cm:
+ MesgString ("CM");
+ break;
+ case mm:
+ MesgString ("MM");
+ break;
+ case bp:
+ MesgString ("BP");
+ break;
+ case pc:
+ MesgString ("PC");
+ break;
+ case pt:
+ MesgString ("PT");
+ break;
+ case sp:
+ MesgString ("SP");
+ break;
+ case px:
+ MesgString ("PX");
+ break;
+ } /* currentunits */
+ MesgLine ();
+}
+/* UpdateWindowStatusLine */
+/*--------------------------------------------------------------------*/
+#define limit 2147483647
+/* TeX's limit = 2^31 - 1.
+ Should also be >= maxpix.
+ Note that this also defines the range of
+ page numbers the user can ask for! */
+#define threshold (limit / 10) /* nearing overflow */
+
+
+static boolean
+GetInteger (char *str_in, int slen, int *pos, int *n)
+{
+ /* Extract an integer from given str_in starting at given pos.
+ pos is also used to return the position after the integer.
+ If no integer is found, then set n to 0 and return FALSE
+ (in that case, pos will only change if leading spaces were skipped).
+ If ABS(n) > limit then set n to sign * limit.
+ Valid syntax is +{digit} or -{digit} or digit{digit}.
+ Note that a + or - by itself is valid and sets n to 0.
+ */
+
+ String str;
+
+ int absval, last, sign;
+ boolean inttoobig;
+ boolean intfound = false;
+
+ memcpy (str, str_in, sizeof (String));
+
+ while (*pos < slen && str[*pos] == ' ')
+ { /* skip any leading spaces */
+ (*pos)++;
+ }
+
+ absval = 0;
+ sign = 1;
+ last = *pos;
+ inttoobig = false;
+
+ if (*pos < slen)
+ {
+ if (str[*pos] == '-')
+ {
+ sign = -1;
+ last++;
+ }
+ else
+ {
+ if (str[*pos] == '+')
+ last++;
+ }
+
+ while (last < slen && (str[last] >= '0' && str[last] <= '9'))
+ {
+ if (absval > threshold || (absval == threshold && str[last] > '7'))
+ inttoobig = true;
+ else
+ absval = absval * 10 + str[last] - '0';
+ last++;
+ }
+ }
+ if (*pos == last)
+ {
+ *n = 0;
+ intfound = false;
+ }
+ else
+ {
+ *pos = last;
+ if (inttoobig)
+ absval = limit;
+ *n = sign * absval;
+ intfound = true;
+ }
+
+ return intfound;
+} /* GetInteger */
+
+#undef limit
+#undef threshold
+/*--------------------------------------------------------------------*/
+static boolean
+GetReal (char *str_in, int slen, int *pos, double *r)
+{
+ /* Extract a real number r from given str_in starting at given pos.
+ pos is also used to return the position after the real number.
+ If no number is found, then set r to 0.0 and return FALSE
+ (in that case pos will only change if leading spaces were skipped).
+ Valid syntax of a real number is integer[.{digit}] or .{digit}
+ where an integer is defined by GetInteger.
+ Real numbers are truncated to 4 decimal places.
+ Note that a sign or decimal point by itself is valid and sets r to 0.0.
+ */
+
+ String str;
+ int sign, intpart, fracpart, divisor;
+ double absreal;
+
+ memcpy (str, str_in, strlen (str_in) + 1);
+
+ /* GetInteger does not remember a sign by itself, so we need to check
+ for -ve dimensions like -.5 first.
+ */
+
+ while (*pos < slen && str[*pos] == ' ')
+ { /* skip any spaces */
+ (*pos)++;
+ }
+
+ sign = 1;
+ if (*pos < slen)
+ {
+ if (str[*pos] == '-')
+ sign = -1;
+ }
+ if (!GetInteger (str, slen, pos, &intpart))
+ {
+ if (*pos == slen || str[*pos] != '.')
+ {
+ *r = 0.0;
+ return false;
+ }
+ }
+ /* real number is valid;
+ if no integer part, then intpart will be 0;
+ sign = +|-1
+ */
+ if (*pos == slen || str[*pos] != '.')
+ {
+ /* no fractional part */
+ absreal = (double) abs (intpart);
+ }
+ else
+ {
+ /* extract fractional part */
+ (*pos)++; /* skip over decimal point */
+ divisor = 1;
+ fracpart = 0;
+ while (*pos < slen && (str[*pos] >= '0' && str[*pos] <= '9'))
+ {
+ /* only consider up to 4 decimal places */
+ if (divisor < 10000)
+ {
+ divisor *= 10;
+ fracpart = fracpart * 10 + str[*pos] - '0';
+ }
+ (*pos)++;
+ }
+ absreal = (double) abs (intpart) + (double) fracpart / divisor;
+ }
+
+ *r = sign * absreal;
+
+ return true;
+} /* GetReal */
+
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+GetDimension (double res, char *str_in, int slen, int *pos, int *n)
+{
+ /* Extract a dimension from given str_ starting at given pos.
+ n returns the corresponding number of pixels in the dimension
+ (which is an integer or real value in terms of currentunits);
+ pos is also used to return the position after the dimension.
+ If no dimension is found then set n to 0 and return FALSE (pos will only
+ change if leading spaces were skipped).
+ If ABS(n) > maxpix then set n to sign * maxpix.
+ Valid syntax of a dimension is integer[.{digit}] or .{digit} where
+ an integer is defined by GetInteger.
+ Real dimensions are truncated to 4 decimal places.
+ Note that a sign or decimal point by itself is valid and sets n to 0.
+ */
+
+ String str;
+ int sign, intdim, fracpart, divisor;
+ double absrealdim;
+ boolean intpresent, dimtoobig;
+
+ memcpy (str, str_in, sizeof (String));
+
+ /* GetInteger does not remember a sign by itself, so we need to check
+ for -ve dimensions like -.5 first.
+ */
+
+ while (*pos < slen && str[*pos] == ' ')
+ { /* skip any leading spaces */
+ (*pos)++;
+ }
+
+ sign = 1;
+ if (*pos < slen)
+ {
+ if (str[*pos] == '-')
+ sign = -1;
+ }
+ intpresent = GetInteger (str, slen, pos, &intdim);
+ if (!intpresent)
+ {
+ if (*pos == slen || str[*pos] != '.')
+ {
+ *n = 0;
+ return false;
+ }
+ } /* if */
+ /* dimension is valid; if no integer part then intdim will be 0; sign = +|-1 */
+ if (*pos == slen || str[*pos] != '.')
+ {
+ /* no fractional part */
+ absrealdim = abs (intdim);
+ }
+ else
+ {
+ /* extract fractional part */
+ (*pos)++; /* skip over decimal point */
+ divisor = 1;
+ fracpart = 0;
+ while (*pos < slen && (str[*pos] >= '0' && str[*pos] <= '9'))
+ {
+ /* only consider up to 4 decimal places */
+ if (divisor < 10000)
+ {
+ divisor *= 10;
+ fracpart = fracpart * 10 + str[*pos] - '0';
+ }
+ (*pos)++;
+ } /* while */
+ absrealdim = abs (intdim) + (double) fracpart / divisor;
+ } /* if */
+
+ /* calculate n based on absrealdim, sign and currentunits */
+ dimtoobig = false;
+ switch (currentunits)
+ {
+ case ic:
+ if (absrealdim > (double) maxpix / res)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim * res + 0.5);
+ break;
+ case cm:
+ if (absrealdim > (double) maxpix / res * 2.54)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / 2.54 * res + 0.5);
+ break;
+ case mm:
+ if (absrealdim > (double) maxpix / res * 25.4)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / 25.4 * res + 0.5);
+ break;
+ case bp:
+ if (absrealdim > (double) maxpix / res * 72.0)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / 72.0 * res + 0.5);
+ break;
+ case pc:
+ if (absrealdim > (double) maxpix / res * (72.27 / 12.0))
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / 72.27 * 12.0 * res + 0.5);
+ break;
+ case pt:
+ if (absrealdim > (double) maxpix / res * 72.27)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / 72.27 * res + 0.5);
+ break;
+ case sp:
+ if (absrealdim > (double) maxpix / res * 72.27 * 65536.0)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim / (72.27 * 65536.0) * res + 0.5);
+ break;
+ case px:
+ if (absrealdim > maxpix)
+ dimtoobig = true;
+ else
+ *n = sign * (int) (absrealdim + 0.5);
+ break;
+ } /* currentunits */
+
+ if (dimtoobig)
+ *n = sign * maxpix;
+
+ return true;
+}
+/* GetDimension */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+GetXDim (char *str_in, int slen, int *pos, int *n)
+{
+ return GetDimension (xres, str_in, slen, pos, n);
+}
+/* GetXDim */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+GetYDim (char *str_in, int slen, int *pos, int *n)
+{
+ return GetDimension (yres, str_in, slen, pos, n);
+}
+/* GetYDim */
+
+/*--------------------------------------------------------------------*/
+
+static void
+BadCommandMessage ()
+{
+ /* A bad command has just been detected and some sort of message displayed.
+ Note that commpos is pointing to just after the problem character.
+ If there are further commands then we show user what will be ignored.
+ */
+
+ int i;
+
+ badcommand = true;
+
+ ClearTextLine (commandl);
+ MoveToTextLine (commandl);
+
+ MesgString (commprompt);
+ for (i = 0; i < commpos; i++)
+ MesgChar (commstring[i]);
+ MesgChar ('!'); /* put ! after the problem character */
+ if (commpos < commlen)
+ {
+ MesgString (" Ignoring: ");
+ for (i = commpos; i < commlen; i++)
+ MesgChar (commstring[i]);
+ }
+ NextCommandLine ();
+}
+/* BadCommandMessage */
+
+/*--------------------------------------------------------------------*/
+
+static void
+NewLocation (int newhp, int newvp)
+{
+ /* Change window location to given position and update window edges.
+ If entire window moves outside non-empty page rectangle then outsidepage
+ becomes TRUE and we restrict movement to just beyond the edge(s) so that
+ user can easily move window (via Up,Down,Left,Right) to positions
+ in which one or more window and page edges coincide.
+ Note that allpagevisible is also updated.
+ */
+
+ outsidepage = false;
+ if (currDVIpage != 0 && !pageempty)
+ {
+ /* check if new position puts window entirely outside edges;
+ if so then minimize the movement needed to keep this true */
+
+ if (newvp > maxvp)
+ {
+ outsidepage = true;
+ newvp = maxvp + 1;
+ }
+ else if (newvp <= minvp - scaledht)
+ {
+ outsidepage = true;
+ newvp = minvp - scaledht;
+ }
+ if (newhp > maxhp)
+ {
+ outsidepage = true;
+ newhp = maxhp + 1;
+ }
+ else if (newhp <= minhp - scaledwd)
+ {
+ outsidepage = true;
+ newhp = minhp - scaledwd;
+ }
+ }
+ windowtop = newvp;
+ windowleft = newhp;
+ windowbottom = windowtop + scaledht - 1;
+ windowright = windowleft + scaledwd - 1;
+ allpagevisible = (currDVIpage != 0 && !pageempty
+ && (minvp >= windowtop && maxvp <= windowbottom)
+ && (minhp >= windowleft && maxhp <= windowright));
+
+ /* even if pageempty or window hasn't moved we must still call DisplayPage */
+
+ if (currDVIpage != 0)
+ paintwindow = true;
+}
+/* NewLocation */
+
+/*--------------------------------------------------------------------*/
+
+static void
+WindowMove ()
+{
+ /* Syntax of Window command is W hpos,vpos where hpos and vpos are
+ dimensions with leading and/or trailing spaces. If hpos,vpos absent
+ then we move to minhp,minvp (top left corner of page rectangle).
+ */
+
+ int hpos, vpos; /* move window to this new position */
+
+ /* commpos is positioned after W */
+
+ /* seek hpos */
+ if (!GetXDim (commstring, commlen, &commpos, &hpos))
+ {
+ /* hpos,vpos absent - move to top left of page */
+ NewLocation (minhp, minvp);
+ return;
+ }
+ /* skip any spaces before comma */
+ while (commpos < commlen && commstring[commpos] == ' ')
+ commpos++;
+
+ /* seek comma */
+ if (commpos == commlen || commstring[commpos] != ',')
+ {
+ /* comma , (which ought to precede vpos) is missing */
+ ClearMessageLine ();
+ MesgString ("Comma expected!");
+ if (commpos < commlen)
+ commpos++;
+ BadCommandMessage ();
+ return;
+ }
+ commpos++; /* skip over comma */
+
+ /* seek vpos */
+ if (GetYDim (commstring, commlen, &commpos, &vpos))
+ {
+ NewLocation (hpos, vpos);
+ }
+ else
+ {
+ /* vpos is missing or wrongly typed */
+ ClearMessageLine ();
+ MesgString ("Vertical coordinate expected!");
+ if (commpos < commlen)
+ commpos++;
+ BadCommandMessage ();
+ }
+}
+/* WindowMove */
+
+/*--------------------------------------------------------------------*/
+
+static void
+WindowUpDown ()
+{
+ int amount; /* move window up/down this many pixels */
+ char STR[2];
+
+ /* commpos is positioned after U or D */
+ if (!GetYDim (commstring, commlen, &commpos, &amount))
+ /* if amount absent, move by _half_ window height */
+ amount = scaledht / 2; /* for odd scaleht, this is half a pixel less */
+
+ sprintf (STR, "%c", command);
+ if (!strcmp (STR, Up)) /* move Up. (Down is positive.) */
+ amount = -amount;
+
+ NewLocation (windowleft, windowtop + amount);
+}
+/* WindowUpDown */
+
+/*--------------------------------------------------------------------*/
+
+static void
+WindowLeftRight ()
+{
+ int amount; /* move window left/right this many pixels */
+ char STR[2];
+
+ /* commpos is positioned after L or R */
+ if (!GetXDim (commstring, commlen, &commpos, &amount))
+ /* if amount absent, move by _half_ window width */
+ amount = scaledwd / 2; /* for odd scaledwd, this is half a pixel less */
+
+ sprintf (STR, "%c", command);
+ if (!strcmp (STR, Left)) /* move Left. (Right is positive.) */
+ amount = -amount;
+
+ NewLocation (windowleft + amount, windowtop);
+}
+/* WindowLeftRight */
+
+/*--------------------------------------------------------------------*/
+
+static void
+NewWindowWidth (int wd)
+{
+ /* Set window width to given value (> 0 and <= max dimension). */
+
+ scaledwd = wd;
+ hscalefactor = (double) windowwd / scaledwd;
+}
+
+/* NewWindowWidth */
+
+/*--------------------------------------------------------------------*/
+
+static void
+SetWindowWidth ()
+{
+ /* Set horizontal size of window region to given dimension;
+ if <= 0, then set horizontal size to 1 pixel.
+ If no parameter, then use the unscaled width represented by windowwd.
+ */
+
+ int wd;
+
+ /* commpos is positioned after H */
+ if (!GetXDim (commstring, commlen, &commpos, &wd))
+ { /* parameter absent */
+ NewWindowWidth (windowwd);
+ return;
+ }
+ /* note that maximum value of wd is restricted to maxpix */
+ if (wd <= 0)
+ wd = 1;
+ NewWindowWidth (wd);
+}
+/* SetWindowWidth */
+
+/*--------------------------------------------------------------------*/
+
+static void
+NewWindowHeight (int ht)
+{
+ /* Set window height to given value (> 0 and <= max dimension). */
+
+ scaledht = ht;
+ vscalefactor = (double) windowht / scaledht;
+}
+
+/* NewWindowHeight */
+
+/*--------------------------------------------------------------------*/
+
+static void
+SetWindowHeight ()
+{
+ /* Set vertical size of window region to given dimension;
+ if <= 0, then set vertical size to 1 pixel.
+ If no parameter, then use the unscaled height represented by windowht.
+ */
+
+ int ht;
+
+ /* commpos is positioned after V */
+ if (!GetYDim (commstring, commlen, &commpos, &ht))
+ { /* parameter absent */
+ NewWindowHeight (windowht);
+ return;
+ }
+ /* note that maximum value of ht is restricted to maxpix */
+ if (ht <= 0)
+ ht = 1;
+ NewWindowHeight (ht);
+}
+/* SetWindowHeight */
+
+/*--------------------------------------------------------------------*/
+
+static int
+ScaleHpos (int h)
+{
+ /* Return a scaled value for the given horizontal window coordinate. */
+
+ if (hscalefactor > 1.0)
+ return ((int) (h * hscalefactor + 0.5));
+ else /* hscalefactor <= 1.0 */
+ return ((int) ((h + 0.5) * hscalefactor));
+}
+
+/* ScaleHpos */
+
+/*--------------------------------------------------------------------*/
+
+static int
+ScaleVpos (int v)
+{
+ /* Return a scaled value for the given vertical window coordinate. */
+
+ if (vscalefactor > 1.0)
+ return ((int) (v * vscalefactor + 0.5));
+ else /* vscalefactor <= 1.0 */
+ return ((int) ((v + 0.5) * vscalefactor));
+}
+
+/* ScaleVpos */
+
+/*--------------------------------------------------------------------*/
+
+static void
+SetAutoView ()
+{
+ /* Toggle AutoView. */
+
+ autoviewing = (autoviewing == false ? true : false);
+}
+
+/* SetAutoView */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ZITL ()
+{
+ /* Zoom In, fixing Top Left of window. */
+
+ /* scaledwd and scaledht are > 0 */
+ NewWindowWidth ((int) ceil (scaledwd / zoomfactor));
+ NewWindowHeight ((int) ceil (scaledht / zoomfactor));
+}
+
+/* ZITL */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ZOTL ()
+{
+ /* Zoom out, fixing Top Left of window. */
+
+ /* avoid overflow *//* GT asks: what overflow? */
+
+ if (maxpix / zoomfactor > scaledwd)
+ NewWindowWidth ((int) (scaledwd * zoomfactor));
+ else
+ NewWindowWidth (maxpix);
+
+ if (maxpix / zoomfactor > scaledht)
+ NewWindowHeight ((int) (scaledht * zoomfactor));
+ else
+ NewWindowHeight (maxpix);
+}
+/* ZOTL */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ZoomWindow ()
+{
+ /* Zoom In, or Zoom Out. */
+ /* For ZI, ZO, zoom relative to top left of window. */
+ /* For ZCI, ZCO, zoom relative to centre of window. */
+
+ /* Just read a 'Z'. */
+ /* Parse the rest of a ZoomInOut command and do it.
+ commpos is pointing to next position in commandstr
+ (and should be I or O).
+ */
+
+ String zs; /* Zoom command string */
+ char zch2 = '\0', zch3 = '\0'; /* Zoom command characters 2 and 3 */
+ double zoomf; /* Zoom Factor */
+ boolean zin = true; /* flag for Zoom direction; default = Zoom in */
+ boolean zc = false; /* flag for Zoom location; default = top left */
+ boolean zok = true; /* flag for valid Zoom; default = valid */
+
+ zs[0] = 'Z'; /* Zoom commands begin with 'Z' */
+ zs[1] = '\0'; /* properly terminate zs */
+
+ /* read second command character, which should be 'I' or 'O'. */
+ if (commpos < commlen)
+ {
+ zch2 = TOUPPER (commstring[commpos]);
+ commpos++;
+ zs[1] = zch2;
+ zs[2] = '\0';
+ }
+ switch (zch2)
+ {
+ case 'I':
+ zc = false;
+ zin = true;
+ break;
+ case 'O':
+ zc = false;
+ zin = false;
+ break;
+ case 'C':
+ if (commpos < commlen)
+ {
+ zch3 = TOUPPER (commstring[commpos]);
+ commpos++;
+ zs[2] = zch3;
+ zs[3] = '\0';
+ }
+ switch (zch3)
+ {
+ case 'I':
+ zc = true;
+ zin = true;
+ break;
+ case 'O':
+ zc = true;
+ zin = false;
+ break;
+ default:
+ zok = false;
+ break;
+ }
+ break;
+ default:
+ zok = false;
+ break;
+ }
+
+ if (!zok)
+ { /* invalid Z* command */
+ String got;
+ ClearMessageLine ();
+ sprintf (got, "Read `%s', ", zs);
+ MesgString (got);
+ MesgString ("ZI, ZO, ZCI or ZCO expected!");
+ BadCommandMessage ();
+ }
+ else
+ { /* valid Zoom command */
+ int pos = 0;
+ boolean realfound = false;
+
+ /* skip any spaces after Zoom command */
+ while (commpos < commlen && commstring[commpos] == ' ')
+ commpos++;
+
+ /* scan rest of command line for a number */
+ /* this is unambiguous, b/c "zoom, goto new page" is silly on a line */
+ /* fortunately, commstring is well terminated, with a NUL char */
+
+/* GT - this is the line I once spoilt: I wasn't advancing by characters! */
+/* GT - use the real number reading code from GetDimension? */
+/* static boolean GetReal (char * str_in, int slen, int * pos, double *r) */
+
+/* if (sscanf (commstring+commpos, "%lf", &zoomf) == 1) */
+
+ pos = 0; /* pos == new commpos - old commpos */
+ realfound = GetReal (commstring + commpos, commlen - commpos, &pos, &zoomf);
+ commpos += pos;
+
+ /* Set Zoom Factor, if any. */
+ if (realfound)
+ {
+ if (zoomf > 1.0)
+ /* change Zoom Factor */
+ zoomfactor = zoomf;
+ else
+ {
+ /* Zooms of unity or less are rejected */
+ /* this covers zero, and avoids ZI/ZO confusion for user */
+ String msgstring;
+
+ /* !! GT - dangerous, as msgstring may overflow - unlikely, though */
+ sprintf (msgstring,
+ "zoom factor must > 1, so keeping old factor of %.2f\n",
+ zoomfactor);
+
+ ClearMessageLine ();
+ MesgString (msgstring);
+
+ BadCommandMessage ();
+ }
+ /* gt - signal to update status line b/c of new Zoom Factor */
+ paintDVIStatus = true;
+ }
+
+ /* Zoom! */
+ if (zc)
+ { /* Zoom wrt Centre */
+ if (zin)
+ {
+ /* ZCI = Zoom In to Centre. Algorithm: */
+ /* Down and Right to centre of window, */
+ /* Zoom in to top left of new window, */
+ /* Up and Left to top left of that window. */
+
+ NewLocation (windowleft + scaledwd / 2, windowtop + scaledht / 2);
+ ZITL ();
+ NewLocation (windowleft - scaledwd / 2, windowtop - scaledht / 2);
+ }
+ else
+ {
+ /* ZCO = Zoom Out from Centre. Algorithm: */
+ /* Down and Right to centre of window, */
+ /* Zoom out from top left of new window, */
+ /* Up and Left to top left of that window. */
+ /* DEFECT: can be altered by Zoom Out restrictions. */
+
+ NewLocation (windowleft + scaledwd / 2, windowtop + scaledht / 2);
+ ZOTL ();
+ NewLocation (windowleft - scaledwd / 2, windowtop - scaledht / 2);
+ }
+ }
+ else
+ { /* Zoom wrt Top Left */
+ /* DEFECT: Zoom Out is restricted; see ZOTL and NewLocation code. */
+ if (zin)
+ ZITL (); /* ZI = Zoom In to Top Left */
+ else
+ ZOTL (); /* ZO = Zoom out from Top Left */
+ }
+ }
+}
+/* ZoomWindow */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+NextPageFound (boolean ascending)
+{
+ /* User has selected next page in DVI file; what they get will depend on
+ the current DVI page and whether we are ascending or not.
+ Return TRUE iff we can move to next page.
+ */
+
+ boolean found = false;
+
+ if (currDVIpage == 1 && !ascending)
+ {
+ ClearMessageLine ();
+ MesgString ("You are looking at first DVI page!");
+ BadCommandMessage ();
+ found = false;
+ }
+ else if (currDVIpage == totalpages && ascending)
+ {
+ ClearMessageLine ();
+ MesgString ("You are looking at last DVI page!");
+ BadCommandMessage ();
+ found = false;
+ }
+ else
+ {
+ MoveToNextPage (ascending); /* position to next DVI page */
+ found = true;
+ }
+ return found;
+}
+/* NextPageFound */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+DVIPageFound (int n)
+{
+ /* User has selected a particular DVI page number.
+ Move to page n and return TRUE iff n is in 1..totalpages.
+ */
+
+ boolean found = false;
+
+ if (n < 1 || n > totalpages)
+ {
+ ClearMessageLine ();
+ if (totalpages > 1)
+ {
+ MesgString ("You can only request DVI pages 1 to ");
+ MesgInt (totalpages);
+ MesgChar ('!');
+ }
+ else
+ {
+ MesgString ("You can only request DVI page 1!");
+ }
+ BadCommandMessage ();
+ found = false;
+ }
+ else
+ {
+ MoveToDVIPage (n); /* position to given DVI page */
+ found = true;
+ }
+ return found;
+}
+/* DVIPageFound */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+ParseTeXpage (TeXpageinfo * newTeXpage)
+{
+ /* Return TRUE iff TeX page specification in commstring is valid. If so then
+ newTeXpage will contain the appropriate information for MoveToTeXPage.
+ The syntax of a TeX page specification is [n{.n}] where n is any integer as
+ defined by GetInteger. Up to 10 integers may be given and are separated by
+ periods, even if absent. Trailing periods may be omitted. Spaces before
+ and after integers and periods are skipped. The 10 positions correspond to
+ the \count0, \count1, ... ,\count9 values that TeX stores with every page.
+ commpos is initially pointing at [.
+ */
+
+ newTeXpage->lastvalue = 0;
+ while (true)
+ {
+ commpos++;
+
+ newTeXpage->present[(int) newTeXpage->lastvalue] =
+ GetInteger (commstring, commlen, &commpos,
+ &newTeXpage->value[(int) newTeXpage->lastvalue]);
+
+ /* commpos now at commlen, space, period, non-digit or ']' */
+
+ while (commpos < commlen && commstring[commpos] == ' ')
+ {
+ commpos++; /* skip any spaces */
+ }
+ if (commpos == commlen)
+ { /* check this first! */
+ ClearMessageLine ();
+ MesgString ("] expected!");
+ BadCommandMessage (); /* commpos at commlen */
+ return false;
+ }
+ if (commstring[commpos] == ']')
+ { /* end of TeX page spec */
+ commpos++;
+ break; /* escape from enclosing "infinite" while loop */
+ }
+ if (newTeXpage->lastvalue >= 9)
+ {
+ ClearMessageLine ();
+ MesgString ("] expected after 10 integers!");
+ commpos++;
+ BadCommandMessage ();
+ return false;
+ }
+ newTeXpage->lastvalue++;
+ if (commstring[commpos] == '.')
+ continue;
+ ClearMessageLine ();
+ MesgString ("Period, integer or ] expected!");
+ commpos++;
+ BadCommandMessage ();
+ return false;
+ } /* while */
+
+ while (newTeXpage->lastvalue > 0
+ && !newTeXpage->present[(int) newTeXpage->lastvalue])
+ {
+ newTeXpage->lastvalue--;
+ }
+ return true;
+}
+/* ParseTeXpage */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+TeXPageFound ()
+{
+ /* Return TRUE iff TeX page specification is valid and exists.
+ If so then position to lowest matching page.
+ */
+
+ boolean found = false;
+ TeXpageinfo newTeXpage;
+
+ if (ParseTeXpage (&newTeXpage))
+ { /* invalid TeX page specification */
+ if (MoveToTeXPage (&newTeXpage))
+ found = true; /* we found lowest matching page */
+ else
+ {
+ ClearMessageLine ();
+ MesgString ("No TeX page matches your request!");
+ BadCommandMessage ();
+ found = false;
+ }
+ }
+ else
+ found = false;
+ return found;
+}
+/* TeXPageFound */
+
+/*--------------------------------------------------------------------*/
+
+static int
+Min (int a, int b)
+{
+ /* Return the minimum value of a and b. */
+
+ if (a < b)
+ return a;
+ else
+ return b;
+}
+/* Min */
+
+/*--------------------------------------------------------------------*/
+
+static int
+Max (int a, int b)
+{
+ /* Return the maximum value of a and b. */
+
+ if (a > b)
+ return a;
+ else
+ return b;
+}
+/* Max */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ProcessPage ()
+{
+ /* We are ready to interpret the current DVI page and fill in the various data
+ structures imported from DVIReader. This routine will also:
+ set the window size and location to useful values (if autoviewing),
+ update pageoffpaper (after checking to see if it was TRUE for the previous
+ page processed as part of a multiple command string),
+ set screenjustcleared, paintwindow and paintWindowStatus to TRUE,
+ set paintDVIStatus to FALSE.
+ */
+
+ int halfht, halfwd;
+
+ /* We check pageoffpaper here so user can type "NNNNNNNNNNNNN..." and
+ note ALL the pages that are off the paper, not just the last one
+ processed.
+ */
+ if (pageoffpaper)
+ {
+ ClearMessageLine ();
+ MesgString ("Page off paper!");
+ WaitForReturn ();
+ /* the previous page */
+ }
+ ClearScreen ();
+ screenjustcleared = true;
+ UpdateDVIStatusLine ();
+ /* a MoveTo... routine has updated currDVI/TeXpage */
+ paintDVIStatus = false;
+ InterpretPage (); /* fill in DVIReader's page data structures */
+ SortFonts (&unusedfont);
+ /* sort fonts in order of least chars and return
+ pointer to first unused font */
+ ClearMessageLine (); /* clear any message */
+ if (pageempty)
+ {
+ minhp = 0;
+ maxhp = 0;
+ minvp = 0;
+ maxvp = 0; /* for window status */
+ }
+ if (autoviewing)
+ { /* view as much of paper as possible, but without too much distortion */
+ if ((paperwd < paperht && windowwd >= windowht)
+ || (paperwd == paperht && windowwd > windowht))
+ {
+ halfht = paperht / 2;
+ if (paperht & 1) /* ensure bottom visible */
+ halfht++;
+ NewWindowHeight (halfht); /* try top half of paper */
+ NewWindowWidth (paperwd);
+ NewLocation (paperleft, papertop); /* top left corner of paper */
+ if (!pageempty && outsidepage) /* try moving down */
+ NewLocation (paperleft, papertop + halfht);
+ }
+ else if ((paperwd > paperht && windowwd <= windowht)
+ || (paperwd == paperht && windowwd < windowht))
+ {
+ halfwd = paperwd / 2;
+ if (paperwd & 1) /* ensure right visible */
+ halfwd++;
+ NewWindowHeight (paperht);
+ NewWindowWidth (halfwd); /* try left half of paper */
+ NewLocation (paperleft, papertop); /* top left corner of paper */
+ if (!pageempty && outsidepage) /* try moving right */
+ NewLocation (paperleft + halfwd, papertop);
+ }
+ else
+ {
+ /* paper shape matches unscaled window shape */
+ NewWindowHeight (paperht); /* try all of paper */
+ NewWindowWidth (paperwd);
+ NewLocation (paperleft, papertop); /* top left corner of paper */
+ }
+ }
+ else
+ {
+ /* not autoviewing, so use current window location and size */
+ NewWindowHeight (scaledht);
+ NewWindowWidth (scaledwd);
+ NewLocation (windowleft, windowtop);
+ }
+
+ /* check if part/all of page is off paper;
+ if so, and autoviewing is enabled, then we set window size and location
+ so user can just see ALL of paper AND ALL of page.
+ */
+ pageoffpaper = (!pageempty && ((minhp < paperleft || minvp < papertop)
+ || (maxhp > paperright || maxvp > paperbottom)));
+ if (pageoffpaper && autoviewing)
+ {
+ NewWindowHeight (Max (maxvp, paperbottom) - Min (minvp, papertop) + 1);
+ NewWindowWidth (Max (maxhp, paperright) - Min (minhp, paperleft) + 1);
+ NewLocation (Min (minhp, paperleft), Min (minvp, papertop));
+ }
+ paintWindowStatus = true;
+ paintwindow = true;
+}
+/* ProcessPage */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ChangeUnits ()
+{
+ /* Parse a C command.
+ commpos is pointing to next position in commstring.
+ Hope that is the start of IN, CM, MM, BP, PC, PT, SP, or PX.
+ */
+
+ char nextch1, nextch2;
+ String cstr;
+
+ /* skip any spaces between 'C' command and following unit */
+
+ while (commpos < commlen && commstring[commpos] == ' ')
+ commpos++;
+
+ /* read next two characters */
+ /* these should comprise a known unit of distance */
+
+ if (commpos < commlen)
+ {
+ nextch1 = TOUPPER (commstring[commpos]);
+ commpos++;
+ }
+ else
+ nextch1 = ' ';
+
+ if (commpos < commlen)
+ {
+ nextch2 = TOUPPER (commstring[commpos]);
+ commpos++;
+ }
+ else
+ nextch2 = ' ';
+
+ sprintf (cstr, "%c%c", nextch1, nextch2);
+
+ if (!strcmp (cstr, "IN"))
+ currentunits = ic;
+ else if (!strcmp (cstr, "CM"))
+ currentunits = cm;
+ else if (!strcmp (cstr, "MM"))
+ currentunits = mm;
+ else if (!strcmp (cstr, "BP"))
+ currentunits = bp;
+ else if (!strcmp (cstr, "PC"))
+ currentunits = pc;
+ else if (!strcmp (cstr, "PT"))
+ currentunits = pt;
+ else if (!strcmp (cstr, "SP"))
+ currentunits = sp;
+ else if (!strcmp (cstr, "PX"))
+ currentunits = px;
+ else
+ {
+ ClearMessageLine ();
+ MesgString ("Unknown units: `");
+ MesgString (cstr);
+ MesgString ("'. ");
+ switch (nextch1)
+ {
+ case 'I':
+ MesgString ("IN");
+ break;
+
+ case 'C':
+ MesgString ("CM");
+ break;
+
+ case 'M':
+ MesgString ("MM");
+ break;
+
+ case 'B':
+ MesgString ("BP");
+ break;
+
+ case 'P':
+ MesgString ("PC, PT or PX");
+ break;
+
+ case 'S':
+ MesgString ("SP");
+ break;
+
+ default:
+ MesgString ("IN, CM, MM, BP, PC, PT, SP or PX");
+ break;
+ } /* command */
+
+ MesgString (" expected.");
+ BadCommandMessage ();
+
+ } /* strcmp (cstr, UNITNAME) */
+}
+/* ChangeUnits */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+UserHitsReturn (int *linecount)
+{
+ /* Do a MesgLine and return TRUE iff linecount = bottoml-2 AND user hits CR.
+ If linecount < bottoml-2 then return FALSE; if not, and user hits
+ something other than CR, then prepare a new screen before returning FALSE.
+ */
+
+ char ch;
+
+ MesgLine ();
+ /* test for approaching end of screen */
+ if (*linecount == bottoml - 2)
+ {
+ /* prompt for next screen */
+ MoveToTextLine (bottoml);
+ MesgString ("Hit RETURN key to resume page display,");
+ MesgString (" or any other key for more: ");
+ MesgFlush ();
+
+ /* read first character typed by user in response to prompt */
+ ReadChar (&ch);
+ if (ch == CR)
+ {
+ return true;
+ }
+ ClearScreen ();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ *linecount = 1;
+ }
+ else
+ {
+ (*linecount)++;
+ }
+ return false;
+}
+/* UserHitsReturn */
+
+/*--------------------------------------------------------------------*/
+
+static void
+WriteUnits ()
+{
+ switch (currentunits)
+ {
+ case ic:
+ MesgString ("in");
+ break;
+ case cm:
+ MesgString ("cm");
+ break;
+ case mm:
+ MesgString ("mm");
+ break;
+ case bp:
+ MesgString ("bp");
+ break;
+ case pc:
+ MesgString ("pc");
+ break;
+ case pt:
+ MesgString ("pt");
+ break;
+ case sp:
+ MesgString ("sp");
+ break;
+ case px:
+ MesgString ("px");
+ break;
+ } /* currentunits */
+}
+/* WriteUnits */
+
+/*--------------------------------------------------------------------*/
+
+static int
+WritePtSize (int scaledsize)
+{
+ /* Show given font size (in DVI units), in (possibly magnified) pts.
+ Return length of displayed message.
+ */
+
+ double realdim;
+ int fracpart;
+ double precision = 0.1;
+ int len = 0;
+
+ realdim = scaledsize / 65536.0 * (mag / 1000.0);
+ /* show realdim to the precision given above */
+ if (fabs (realdim) < 0.5 * precision)
+ {
+ MesgChar ('0');
+ ++len;
+ }
+ else
+ {
+ if (realdim < 0.0)
+ {
+ MesgChar ('-');
+ ++len;
+ realdim = fabs (realdim);
+ }
+ realdim += 0.5 * precision; /* round up to specified precision */
+ len += MesgInt ((int) realdim); /* whole part */
+ fracpart = (int) ((realdim - (int) realdim) / precision);
+ if (fracpart > 0)
+ {
+ MesgChar ('.');
+ ++len;
+ len += MesgInt (fracpart);
+ }
+ }
+ MesgString ("pt");
+ len += 2;
+ return (len);
+}
+/* WritePtSize */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ShowStatistics ()
+{
+ /* Show option values and font/character/rule/special statistics.
+ UserHitsReturn controls pagination and takes the place of MesgLine.
+ */
+
+ specialinfo *temp;
+ int linecount, fontcount;
+ char ch;
+ static char LeftStr[] = "";
+ static char RightStr[] = "";
+ double precision = 1.0e-3; /* precision of quantities */
+
+ ClearScreen ();
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ linecount = 1;
+
+ MesgString ("DVI file = ");
+ MesgString (LeftStr);
+ MesgString (DVIname);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("VDU = ");
+ MesgString (LeftStr);
+ MesgString (vdu);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ { /* beginblock */
+ String realstring;
+
+ MesgString ("X Resolution (dpi) = ");
+ /* xres is unlikely to overflow realstring */
+ sprintf (realstring, "%f", xres);
+ MesgString (realstring);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Y Resolution (dpi) = ");
+ /* yres is unlikely to overflow realstring */
+ sprintf (realstring, "%f", yres);
+ MesgString (realstring);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ } /* endblock */
+
+ MesgString ("Magnification = ");
+ MesgInt (mag);
+ if (mag == DVImag)
+ {
+ MesgString (" (DVI mag)");
+ }
+ else
+ {
+ MesgString (" (DVI mag of ");
+ MesgInt (DVImag);
+ MesgString (" was overridden)");
+ }
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Dummy PK font = ");
+ MesgString (LeftStr);
+ MesgString (dummy_pk);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Dummy TFM metric = ");
+ MesgString (LeftStr);
+ MesgString (dummy_tfm);
+ MesgString (RightStr);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Horizontal offset = ");
+ WriteXDim (precision, hoffset);
+ WriteUnits ();
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Vertical offset = ");
+ WriteYDim (precision, voffset);
+ WriteUnits ();
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Paper wd by ht = ");
+ WriteXDim (precision, paperwd);
+ WriteUnits ();
+ MesgString (" by ");
+ WriteYDim (precision, paperht);
+ WriteUnits ();
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Total fonts on ALL pages = ");
+ MesgInt (totalfonts);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Fonts, at pt size: (if on current page, give (total chars))");
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString
+ ("H: Honest, S: Substitute; K: PK, T: TFM, D: DVI.");
+ if (UserHitsReturn (&linecount))
+ return;
+
+ fontcount = 0;
+ for (thisfontinfo = fontlist;
+ thisfontinfo != (fontinfo *) NULL;
+ thisfontinfo = thisfontinfo->nextfont)
+ {
+ String msgstr; /* output string for messages */
+ int len; /* length of a displayed message */
+ int maxptroom = 7; /* room for point size message */
+ int i;
+
+ if (thisfontinfo->fontspeclen == 0)
+ { /* need to build fontspec */
+ BuildFontSpec (thisfontinfo);
+ /* fontexists may have become TRUE */
+ }
+ /* most font names have at most 8 characters, for ms-dos! */
+ sprintf (msgstr, "%-8s", thisfontinfo->fontname);
+ MesgString (msgstr);
+
+ MesgString (" ");
+ len = WritePtSize (thisfontinfo->scaledsize);
+ for (i = len; i < maxptroom; i++)
+ MesgChar (' ');
+
+ MesgString ("->");
+
+ if (thisfontinfo->fontexists)
+ {
+ if (thisfontinfo->honest)
+ MesgChar ('H');
+ else /* substitute */
+ MesgChar ('S');
+
+ if (thisfontinfo->pkfont)
+ MesgChar ('K');
+ else /* non-PostScript TFM */
+ MesgChar ('T');
+
+ MesgString (" ");
+ i = thisfontinfo->fontspeclen - 50; /* try to show last 70 chars */
+ if (i < 0)
+ i = 0;
+ MesgString (thisfontinfo->fontspec + i);
+ }
+ else
+ {
+ MesgChar ('S');
+ MesgChar ('D');
+
+ MesgString (" ");
+ MesgString ("Terse display");
+ }
+
+ if (thisfontinfo->fontused)
+ {
+ fontcount++;
+ MesgString (" (");
+ MesgInt (thisfontinfo->totalchars);
+ MesgString (")");
+ }
+ if (UserHitsReturn (&linecount))
+ return;
+ }
+ /* end (for) loop */
+
+ if (currDVIpage == 0)
+ MesgString ("You haven't selected a page yet.");
+ else
+ {
+ MesgString ("Total fonts on current page = ");
+ MesgInt (fontcount);
+ }
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("Total rules on current page = ");
+ MesgInt (totalrules);
+
+ if (speciallist != (specialinfo *) NULL)
+ {
+ if (UserHitsReturn (&linecount))
+ return;
+
+ MesgString ("\\special commands on current page: ");
+ if (UserHitsReturn (&linecount))
+ return;
+
+ temp = speciallist;
+ while (temp != (specialinfo *) NULL)
+ {
+ MesgString ("At (");
+ WriteXDim (precision, temp->hp);
+ MesgChar (',');
+ WriteYDim (precision, temp->vp);
+ MesgString ("): ");
+ MesgString (temp->special);
+ if (UserHitsReturn (&linecount))
+ return;
+
+ temp = temp->nextspecial;
+ } /* while */
+ } /* if */
+ MesgLine ();
+ MesgLine ();
+ MoveToTextLine (bottoml);
+ MesgString ("Hit RETURN key to resume page display: ");
+ MesgFlush ();
+
+ do
+ {
+ ReadChar (&ch);
+ }
+ while (ch != CR);
+
+}
+/* ShowStatistics */
+
+/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+
+#define edgepixel '.'
+ /* black pixel for outlines on non-graphic VDUs;
+ note that VDU TeXtoASCII['.'] = '.' */
+
+static void
+DisplayPaperEdges ()
+{
+ /* Display visible outlines of the imaginary sheet of paper.
+ Thickness of outlines = 1 screen pixel,
+ no matter what the h and v scaling.
+ */
+
+ int top, bot, left, right; /* visible edges of paper in paper pixels */
+ int scaledtop, scaledleft; /* scaled visible edges in screen pixels */
+ int scaledbot, scaledright, scaledheight;
+ /* scaled width and height */
+ int scaledwidth;
+
+ /* first check if any part of paper is visible */
+
+ if (papertop > windowbottom)
+ return;
+
+ if (paperbottom < windowtop)
+ return;
+
+ if (paperleft > windowright)
+ return;
+
+ if (paperright < windowleft)
+ return;
+
+ /* part or all of paper is visible, so return visible region */
+ top = Max (papertop, windowtop);
+ bot = Min (paperbottom, windowbottom);
+ left = Max (paperleft, windowleft);
+ right = Min (paperright, windowright);
+ scaledtop = ScaleVpos (top - windowtop) + windowv;
+ scaledleft = ScaleHpos (left - windowleft) + windowh;
+ if (vscalefactor > 1.0)
+ scaledbot = ScaleVpos (bot - windowtop + 1) + windowv - 1;
+ else
+ scaledbot = ScaleVpos (bot - windowtop) + windowv;
+ if (hscalefactor > 1.0)
+ scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1;
+ else
+ scaledright = ScaleHpos (right - windowleft) + windowh;
+ scaledheight = scaledbot - scaledtop + 1;
+ scaledwidth = scaledright - scaledleft + 1;
+ /* only show visible edges if they are also paper outlines */
+ if (left == paperleft)
+ ShowRectangle (scaledleft, scaledtop, 1, scaledheight, edgepixel);
+ if (bot == paperbottom)
+ ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, edgepixel);
+ if (top == papertop)
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, edgepixel);
+ if (right == paperright)
+ ShowRectangle (scaledright, scaledtop, 1, scaledheight, edgepixel);
+}
+/* DisplayPaperEdges */
+
+#undef edgepixel
+
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+RectangleVisible (int intop, int inbot, int inleft, int inright,
+ int *outtop, int *outbot, int *outleft, int *outright)
+{
+ /* Return TRUE iff part or all of given rectangle would be visible
+ in the current window. Iff so, then we also return the visible
+ region; the input and possible output rectangles are defined by their
+ top, bottom, left and right edges in paper pixel coordinates.
+ */
+
+ if (allpagevisible)
+ { /* all of rectangle must be visible */
+ *outtop = intop;
+ *outbot = inbot;
+ *outleft = inleft;
+ *outright = inright;
+ return true;
+ }
+ else if (intop > windowbottom)
+ return false;
+ else if (inbot < windowtop)
+ return false;
+ else if (inleft > windowright)
+ return false;
+ else if (inright < windowleft)
+ return false;
+ else
+ {
+ /* part or all of rectangle is visible, so return visible region */
+ *outtop = Max (intop, windowtop);
+ *outbot = Min (inbot, windowbottom);
+ *outleft = Max (inleft, windowleft);
+ *outright = Min (inright, windowright);
+ return true;
+ }
+}
+/* RectangleVisible */
+
+/*--------------------------------------------------------------------*/
+
+#define RULEPIXEL '*'
+ /* black pixel for rules on non-graphic VDUs;
+ note that VDU sets TeXtoASCII['*'] := '*' */
+
+
+static void
+DisplayRules ()
+{
+ /* Display all pixels in rules, regardless of current displaymode.
+ Rules will be displayed in the same order as in the DVI page (essentially
+ top-down and left-right) because of the way DVIReader builds a rulelist.
+ */
+
+ int top, bottom, left, right; /* visible edges of rule */
+ int scaledtop, scaledleft; /* scaled visible edges */
+ int scaledbot, scaledright, scaledwidth, scaledheight;
+ /* scaled width and height */
+ int thisrule;
+ char keyhit; /* returned by BusyRead if TRUE */
+ _REC_ruletable *ruletab = (_REC_ruletable *) NULL;
+
+ thisruleinfo = rulelist;
+ while (thisruleinfo != (ruleinfo *) NULL)
+ {
+ thisrule = 0;
+ while (thisrule < thisruleinfo->rulecount)
+ {
+ ruletab = &thisruleinfo->ruletable[thisrule];
+ /* check if any part of rule is visible */
+ /* vp,hp is bottom left corner of rule on page */
+ if (RectangleVisible (ruletab->vp - ruletab->ht + 1,
+ ruletab->vp, ruletab->hp,
+ ruletab->hp + ruletab->wd - 1,
+ &top, &bottom, &left, &right))
+ { /* rule edges */
+ /* show all pixels in this rectangle */
+ scaledtop = ScaleVpos (top - windowtop) + windowv;
+ scaledleft = ScaleHpos (left - windowleft) + windowh;
+
+ if (vscalefactor > 1.0)
+ scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1;
+ else
+ scaledbot = ScaleVpos (bottom - windowtop) + windowv;
+
+ if (hscalefactor > 1.0)
+ scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1;
+ else
+ scaledright = ScaleHpos (right - windowleft) + windowh;
+
+ /* v coord of top left cnr */
+ scaledheight = scaledbot - scaledtop + 1;
+
+ /* h coord of top left cnr */
+ scaledwidth = scaledright - scaledleft + 1;
+
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, scaledheight,
+ RULEPIXEL);
+
+ /* check keyboard after every visible rule */
+ if (BusyRead (&keyhit))
+ {
+ char STR1[2];
+ keyhit = TOUPPER (keyhit);
+ sprintf (STR1, "%c", keyhit);
+ if (!strcmp (STR1, Terse))
+ {
+ displaymode ^= tersemode; /* toggle terse mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else
+ {
+ char STR2[2];
+ sprintf (STR2, "%c", keyhit);
+ if (!strcmp (STR2, Box))
+ {
+ displaymode ^= boxmode; /* toggle box mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else
+ {
+ char STR3[2];
+ sprintf (STR3, "%c", keyhit);
+ if (!strcmp (STR3, Full))
+ {
+ displaymode ^= fullmode; /* toggle full mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else if (keyhit == CR)
+ {
+ useraborted = true; /* checked in DisplayPage */
+ return;
+
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ /* visible rectangle */
+ thisrule++;
+ } /* while */
+ thisruleinfo = thisruleinfo->nextrule;
+ } /* while */
+}
+/* DisplayRules */
+
+
+
+
+/*--------------------------------------------------------------------*/
+/* Adapted from xdvi-20.0 by Paul Vojta */
+/* Keys for epsf specials */
+
+static char *keytab[] =
+{
+ "clip",
+ "llx",
+ "lly",
+ "urx",
+ "ury",
+ "rwi",
+ "rhi",
+
+ "hsize",
+ "vsize",
+ "hoffset",
+ "voffset",
+ "hscale",
+ "vscale",
+ "angle"
+};
+
+#define KEY_LLX keyval[0]
+#define KEY_LLY keyval[1]
+#define KEY_URX keyval[2]
+#define KEY_URY keyval[3]
+#define KEY_RWI keyval[4]
+#define KEY_RHI keyval[5]
+
+#define KEY_HSIZE keyval[6]
+#define KEY_VSIZE keyval[7]
+#define KEY_HOFFSET keyval[8]
+#define KEY_VOFFSET keyval[9]
+#define KEY_HSCALE keyval[10]
+#define KEY_VSCALE keyval[11]
+#define KEY_ANGLE keyval[12]
+
+#define NKEYS (sizeof(keytab)/sizeof(*keytab))
+#define N_ARGLESS_KEYS 1
+
+static int
+epsf_special (char *cp, int *wd, int *ht)
+{
+ char *filename;
+ int filenamelen = 0;
+ int flags = 0;
+ double keyval[NKEYS - N_ARGLESS_KEYS];
+
+ /* skip to the file name */
+ while (isspace (*cp))
+ ++cp;
+ if (*cp != '=')
+ return 0;
+ do
+ ++cp;
+ while (isspace (*cp));
+
+ filename = cp;
+ if (*cp == '\'' || *cp == '"')
+ {
+ do
+ ++cp;
+ while (*cp != '\0' && *cp != *filename); /* up to closing ['"] */
+ ++filename;
+ }
+ else
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+ ++cp;
+ filenamelen = cp - filename;
+ while (*cp == ' ' || *cp == '\t')
+ ++cp;
+ while (*cp != '\0')
+ {
+ char *p1 = cp;
+ int keyno;
+
+ while (*p1 != '=' && !isspace (*p1) && *p1 != '\0')
+ ++p1;
+ for (keyno = 0;; ++keyno)
+ {
+ if (keyno >= NKEYS)
+ {
+#if 0
+ Fprintf (stderr,
+ "%s: unknown keyword (%*s) in \\special will be ignored\n",
+ prog, (int) (p1 - cp), cp);
+#endif
+
+ break;
+ }
+ if (strncmp (cp, keytab[keyno], p1 - cp) == 0)
+ {
+ if (keyno >= N_ARGLESS_KEYS)
+ {
+ while (isspace (*p1))
+ ++p1;
+ if (*p1 == '=')
+ {
+ ++p1;
+ while (isspace (*p1))
+ ++p1;
+ }
+ {
+ int keyno_tmp = keyno - N_ARGLESS_KEYS;
+ keyval[keyno_tmp] = atof (p1);
+ flags |= (1 << keyno_tmp);
+ }
+ }
+ break;
+ }
+ }
+ cp = p1;
+ while (!isspace (*cp) && *cp != '\0')
+ ++cp;
+ while (isspace (*cp))
+ ++cp;
+ }
+
+ if ((flags & 0x30) == 0x30 || ((flags & 0x30) && (flags & 0xf) == 0xf))
+ {
+ /* convert from pt to sp and next to pixels */
+ *wd = XPixelRound (65536 * 0.1 * ((flags & 0x10) ? KEY_RWI
+ : KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY - KEY_LLY)));
+ *ht = YPixelRound (65536 * 0.1 * ((flags & 0x20) ? KEY_RHI
+ : KEY_RWI * (KEY_URY - KEY_LLY) / (KEY_URX - KEY_LLX)));
+ return 1;
+ }
+ else if ((flags & 0xc0) == 0xc0)
+ {
+ *wd = XPixelRound (65536 * ((flags & 0x400) ? KEY_HSCALE : 1.0) * KEY_HSIZE);
+ *ht = YPixelRound (65536 * ((flags & 0x800) ? KEY_VSCALE : 1.0) * KEY_VSIZE);
+ return 1;
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------*/
+static void
+DisplaySpecials ()
+{
+ /* Display dvips eps specials as boxes */
+
+ int top, bottom, left, right; /* visible edges of special */
+ int scaledtop, scaledleft; /* scaled visible edges */
+ int scaledbot, scaledright, scaledwidth, scaledheight;
+ /* scaled width and height */
+ specialinfo *thisspecial;
+ char keyhit; /* returned by BusyRead if TRUE */
+
+ thisspecial = speciallist;
+ while (thisspecial != (specialinfo *) NULL)
+ {
+ int wd, ht;
+ /* Using undeclared strncasecmp just as xdvik/hypertex.c does. */
+ if (strncasecmp (thisspecial->special, "psfile", 6) == 0 &&
+ epsf_special (thisspecial->special + 6, &wd, &ht))
+ {
+ /* check if any part of special is visible */
+ /* vp,hp is bottom left corner of special on page */
+ if (RectangleVisible (thisspecial->vp - ht + 1,
+ thisspecial->vp,
+ thisspecial->hp,
+ thisspecial->hp + wd - 1,
+ &top, &bottom, &left, &right))
+ { /* special edges */
+ /* show all pixels in this rectangle */
+ scaledtop = ScaleVpos (top - windowtop) + windowv;
+ scaledleft = ScaleHpos (left - windowleft) + windowh;
+
+ if (vscalefactor > 1.0)
+ scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1;
+ else
+ scaledbot = ScaleVpos (bottom - windowtop) + windowv;
+
+ if (hscalefactor > 1.0)
+ scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1;
+ else
+ scaledright = ScaleHpos (right - windowleft) + windowh;
+ /* coord of top left cnr */
+ scaledheight = scaledbot - scaledtop + 1;
+ scaledwidth = scaledright - scaledleft + 1;
+
+ if (left == thisspecial->hp)
+ ShowRectangle (scaledleft, scaledtop, 1, scaledheight, RULEPIXEL);
+ if (bottom == thisspecial->vp)
+ ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, RULEPIXEL);
+ if (top == thisspecial->vp - ht + 1)
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, RULEPIXEL);
+ if (right == thisspecial->hp + wd - 1)
+ ShowRectangle (scaledright, scaledtop, 1, scaledheight, RULEPIXEL);
+
+ /* check keyboard after every visible special */
+ if (BusyRead (&keyhit))
+ {
+ char STR1[2];
+ keyhit = TOUPPER (keyhit);
+ sprintf (STR1, "%c", keyhit);
+ if (!strcmp (STR1, Terse))
+ {
+ displaymode ^= tersemode; /* toggle terse mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else
+ {
+ char STR2[2];
+ sprintf (STR2, "%c", keyhit);
+ if (!strcmp (STR2, Box))
+ {
+ displaymode ^= boxmode; /* toggle box mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else
+ {
+ char STR3[2];
+ sprintf (STR3, "%c", keyhit);
+ if (!strcmp (STR3, Full))
+ {
+ displaymode ^= fullmode; /* toggle full mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else if (keyhit == CR)
+ {
+ useraborted = true; /* checked in DisplayPage */
+ return;
+
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+ }
+ thisspecial = thisspecial->nextspecial;
+ } /* while */
+}
+/* DisplaySpecials */
+
+#undef RULEPIXEL
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+PixelVisible (int hpos, int vpos)
+{
+ /* Return TRUE iff given paper pixel would be visible in current window. */
+
+ if (allpagevisible)
+ return true;
+ else if (vpos < windowtop)
+ return false;
+ else if (vpos > windowbottom)
+ return false;
+ else if (hpos < windowleft)
+ return false;
+ else if (hpos > windowright)
+ return false;
+ else
+ return true;
+}
+/* PixelVisible */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+TerseChar ()
+{
+ /* Display a quick and nasty representation of character,
+ only if ref pt visible.
+ Just how good the representation is,
+ depends on the capabilities of the VDU.
+ We don't bother checking
+ whether glyph is actually blank or non-existent.
+ */
+
+ _REC_chartable *chartab = &thischarinfo->chartable[thischar];
+
+ if (chartab == (_REC_chartable *) NULL)
+ return false;
+
+ if (PixelVisible (chartab->hp, chartab->vp)) /* ref pt of char is visible */
+ ShowChar (ScaleHpos (chartab->hp - windowleft) + windowh,
+ ScaleVpos (chartab->vp - windowtop) + windowv,
+ chartab->code);
+
+ return true;
+}
+/* TerseChar */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+BoxChar ()
+{
+ /* Display visible box outlines of glyph.
+ Thickness of outlines = 1 screen pixel,
+ no matter what the h and v scaling.
+ */
+
+ int vpmyo, hpmxo; /* vp-yo, hp-xo: glyph's top and left edges */
+ int top, bottom, left, right; /* visible edges of glyph */
+ int scaledtop, scaledleft; /* scaled visible edges */
+ int scaledbot, scaledright, scaledheight;
+ /* scaled width and height */
+ int scaledwidth;
+ char ch;
+
+ _REC_chartable *chartab = &thischarinfo->chartable[thischar];
+ _REC_pixeltable *pixtab = (_REC_pixeltable *) NULL;
+
+ if (chartab == (_REC_chartable *) NULL)
+ return false;
+
+ pixtab = &thisfontinfo->pixelptr[chartab->code];
+ if (pixtab == (_REC_pixeltable *) NULL)
+ return false;
+
+ if (pixtab->mapadr != 0)
+ { /* glyph present and non-blank */
+ /* check if any part of glyph is visible */
+
+ vpmyo = chartab->vp - pixtab->yo;
+ hpmxo = chartab->hp - pixtab->xo;
+
+ if (RectangleVisible (vpmyo, vpmyo + pixtab->ht - 1,
+ hpmxo, hpmxo + pixtab->wd - 1,
+ &top, &bottom, &left, &right))
+ { /* glyph edges */
+
+ scaledtop = ScaleVpos (top - windowtop) + windowv;
+ scaledleft = ScaleHpos (left - windowleft) + windowh;
+
+ if (vscalefactor > 1.0)
+ scaledbot = ScaleVpos (bottom - windowtop + 1) + windowv - 1;
+ else
+ scaledbot = ScaleVpos (bottom - windowtop) + windowv;
+
+ if (hscalefactor > 1.0)
+ scaledright = ScaleHpos (right - windowleft + 1) + windowh - 1;
+ else
+ scaledright = ScaleHpos (right - windowleft) + windowh;
+
+ scaledheight = scaledbot - scaledtop + 1;
+ scaledwidth = scaledright - scaledleft + 1;
+
+ /* Only show edges that are also glyph outlines!
+ Following method reduces the number of ShowRectangle calls needed for
+ very small boxes.
+ */
+ ch = chartab->code;
+ if ((scaledheight < 3
+ && (top == vpmyo && bottom == vpmyo + pixtab->ht - 1))
+ || (scaledwidth < 3
+ && (left == hpmxo && right == hpmxo + pixtab->wd - 1)))
+ {
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, scaledheight, ch);
+ }
+ else
+ {
+ if (left == hpmxo)
+ ShowRectangle (scaledleft, scaledtop, 1, scaledheight, ch);
+ if (bottom == vpmyo + pixtab->ht - 1)
+ ShowRectangle (scaledleft, scaledbot, scaledwidth, 1, ch);
+ if (top == vpmyo)
+ ShowRectangle (scaledleft, scaledtop, scaledwidth, 1, ch);
+ if (right == hpmxo + pixtab->wd - 1)
+ ShowRectangle (scaledright, scaledtop, 1, scaledheight, ch);
+ }
+ }
+ /* visible part */
+ }
+ return true;
+}
+/* BoxChar */
+
+/*--------------------------------------------------------------------*/
+
+static void
+NotFound (char *fspec)
+{
+ StartText ();
+ ResetVDU (); /* do before message since it might erase screen! */
+ FATAL1 ("Couldn't open font %s.", fspec);
+}
+
+/* NotFound */
+
+/*--------------------------------------------------------------------*/
+
+#define MAXVISWORDS 100
+#define WORDSIZE 32
+
+/* MAXVISWORDS * WORDSIZE = 100 * 32 = 3200 bits = maximum pixel width
+ of glyph!
+ If any fonts have glyphs wider than this, then increase MAXVISWORDS.
+ */
+
+/* SYSDEP: BITSET is 32 bit word with elements 31,30,29,...,0 */
+typedef Word glyphrow[MAXVISWORDS];
+
+
+static boolean
+FullChar ()
+{
+ /* Display all pixels in a glyph using bitmap from font file.
+ The algorithm avoids overlapping rows when vscalefactor < 1.0.
+ When hscalefactor < 1.0, it is not worth the extra code to avoid
+ overlapping runs of 1 bits because the majority of character glyphs
+ have only one or two runs per row.
+ */
+
+ int vpmyo, hpmxo; /* vp-yo, hp-xo: glyph's top and left edges */
+ int top, bottom, left, right; /* visible edges of glyph */
+ int scaledv, scalednextv; /* scaled vertical positions for rows */
+ int scaledh = 0; /* scaled horizontal positions within row */
+ int scaledwidth, scaledheight; /* scaled width and height of row */
+ int thisrow, thisbit; /* in paper coordinates */
+ int wordsperrow; /* rows of bitmap are word aligned */
+ int firstbit, lastbit; /* somewhere in 0 .. wordsperrow*WORDSIZE-1 */
+ int firstword, lastword; /* somewhere in 0 .. wordsperrow-1 */
+ int endword; /* = visible words in row, - 1 */
+ int wordpos; /* 0 .. endword */
+ int bitpos; /* (WORDSIZE-1) .. 0 */
+ int i;
+
+ glyphrow row; /* holds VISIBLE bits in one row of glyph;
+ possibly > one row if vscalefactor < 1.0 */
+
+ int_or_bptr ptr; /* pointer into bitmap - actually a "struct" */
+ boolean inrun = false; /* are we in a run of black pixels in row? */
+
+ _REC_chartable *chartab = &thischarinfo->chartable[thischar];
+ _REC_pixeltable *pixtab = &thisfontinfo->pixelptr[chartab->code];
+
+ if (pixtab->mapadr != 0)
+ { /* glyph present and non-blank */
+ /* check if any part of glyph is visible */
+
+ vpmyo = chartab->vp - pixtab->yo;
+ hpmxo = chartab->hp - pixtab->xo;
+ if (RectangleVisible (vpmyo, vpmyo + pixtab->ht - 1, hpmxo,
+ hpmxo + pixtab->wd - 1, &top, &bottom, &left, &right))
+ { /* glyph edges */
+ if (pixtab->bitmap.UU.mptr == (Word *) NULL)
+ {
+ if (!fontopen)
+ { /* dimensions of bitmap */
+ if (thisfontinfo->fontexists)
+ {
+ if (!OpenFontFile (thisfontinfo->fontspec))
+ NotFound (thisfontinfo->fontspec);
+ }
+ else
+ {
+ NotFound (dummy_pk); /* !!! */
+ }
+ fontopen = true; /* only open font once */
+ }
+ /* bitmap info in font file */
+ /* &pixtab->bitmap receives the starting address of bitmap */
+ if (!GetBitmap (pixtab->ht, pixtab->wd, pixtab->mapadr, &pixtab->bitmap))
+ return false;
+ }
+ /* Words in 1 row of bitmap */
+ wordsperrow = (pixtab->wd + (WORDSIZE - 1)) / WORDSIZE;
+
+ firstbit = left - hpmxo; /* first visible bit */
+ lastbit = right - hpmxo; /* last visible bit */
+ firstword = firstbit / WORDSIZE; /* first visible word */
+ lastword = lastbit / WORDSIZE; /* last visible word */
+ endword = lastword - firstword;
+
+ /* set the visible words in row to 0 */
+ for (i = 0; i <= endword; i++)
+ row[i] = 0;
+ /* calculate scaled v coord of first visible row */
+ scaledv = ScaleVpos (top - windowtop) + windowv;
+
+ /* only consider visible rows; thisrow := top to bottom */
+ thisrow = top;
+ while (true)
+ {
+ /* move to first byte of first visible word in this row */
+ ptr.UU.int_ = pixtab->bitmap.UU.int_ +
+ ((thisrow - vpmyo) * wordsperrow + firstword) * 4;
+ /* get row of visible words from bitmap and OR with row array */
+ wordpos = 0;
+ while (true)
+ {
+ row[wordpos] |= *ptr.UU.bptr; /* set union */
+ if (wordpos == endword)
+ break; /* escape from inner "infinite" loop */
+ wordpos++;
+ ptr.UU.int_ += 4; /* next word */
+ }
+ /* calculate scaled v coord of next row */
+ scalednextv = ScaleVpos (thisrow - windowtop + 1) + windowv;
+ scaledheight = scalednextv - scaledv;
+ if (scaledheight > 0 || thisrow == bottom)
+ {
+ /* display black pixels in row, doing any h/v expansion */
+ if (scaledheight < 1) /* avoid 0 */
+ scaledheight = 1;
+ inrun = false;
+ /* bitpos ranges over (WORDSIZE-1)..0 */
+ bitpos = (WORDSIZE - 1) - (firstbit & (WORDSIZE - 1));
+ wordpos = 0;
+
+ /* only consider visible bits; thisbit := left to right */
+ thisbit = left;
+ while (true)
+ { /* bit loop */
+ if ((unsigned) bitpos < WORDSIZE
+ && ((1 << bitpos) & row[wordpos]) != 0)
+ { /* start/continue run */
+ if (!inrun)
+ { /* remember start of run */
+ inrun = true;
+ scaledh = ScaleHpos (thisbit - windowleft) + windowh;
+ }
+ }
+ else if (inrun)
+ {
+ inrun = false;
+ scaledwidth = ScaleHpos (thisbit - windowleft) + windowh - scaledh;
+ if (scaledwidth < 1) /* avoid 0 */
+ scaledwidth = 1;
+ ShowRectangle (scaledh, scaledv, scaledwidth, scaledheight,
+ chartab->code);
+ }
+ if (thisbit == right) /* EXIT bit loop */
+ break;
+ if (bitpos == 0)
+ {
+ wordpos++;
+ bitpos = (WORDSIZE - 1);
+ }
+ else
+ { /* look at next bit in word */
+ bitpos--;
+ }
+ thisbit++;
+ } /* bit loop */
+
+ if (inrun)
+ { /* show run at end of row */
+ scaledwidth = ScaleHpos (thisbit - windowleft + 1) + windowh - scaledh;
+ if (scaledwidth < 1) /* avoid 0 */
+ scaledwidth = 1;
+ ShowRectangle (scaledh, scaledv, scaledwidth, scaledheight,
+ chartab->code);
+ }
+ if (thisrow == bottom) /* EXIT row loop */
+ break;
+ /* else reset the visible words in row to 0 */
+ for (i = 0; i <= endword; i++)
+ row[i] = 0;
+ } /* if */
+ scaledv = scalednextv;
+ thisrow++;
+ } /* row loop */
+
+ } /* if */
+ /* visible part */
+ }
+ /* 0 bit has ended run */
+ return true;
+}
+/* FullChar */
+
+
+#undef WORDSIZE
+#undef MAXVISWORDS
+/*--------------------------------------------------------------------*/
+static void
+DisplayChars ()
+{
+ /* Display all characters on a font by font basis. How characters will be
+ represented depends on the current displaymode (which the user can change,
+ while the window is being updated, by typing the Terse/Box/Full commands).
+ Fonts will be displayed in order of ascending totalchars (due to SortFonts).
+ Characters in a font will be displayed in a top-down, left-right manner
+ because of the way DVIReader builds a charlist.
+ */
+
+ char keyhit; /* check for abort or mode change */
+
+ for (thisfontinfo = fontlist;
+ thisfontinfo != unusedfont;
+ thisfontinfo = thisfontinfo->nextfont)
+ {
+ /* SortFont makes sure we only consider used fonts */
+
+ fontopen = false; /* might be set in FullChar */
+
+ /* Some VDUs may be able to simulate the given font.
+ To help the VDU select appropriately sized characters, we need to
+ pass the scaledsize of the font (converted to unscaled paper pixels),
+ the overall mag, and the current h/vscalefactors.
+ */
+
+ LoadFont (thisfontinfo->fontspec,
+ XPixelRound (thisfontinfo->scaledsize),
+ mag / 1000.0,
+ hscalefactor,
+ vscalefactor);
+
+ /* display chars in chartable */
+
+ for (thischarinfo = thisfontinfo->charlist;
+ thischarinfo != (charinfo *) NULL;
+ thischarinfo = thischarinfo->nextchar)
+ {
+ for (thischar = 0; thischar < thischarinfo->charcount; thischar++)
+ {
+ if (thisfontinfo->fontexists)
+ {
+ if (displaymode & fullmode)
+ {
+ if (thisfontinfo->pkfont)
+ FullChar ();
+ else
+ BoxChar ();
+ }
+ if (displaymode & tersemode)
+ {
+ TerseChar ();
+ }
+ if (displaymode & boxmode)
+ {
+ BoxChar ();
+ }
+ }
+ else
+ { /* font is missing! */
+ if (displaymode & (fullmode | tersemode))
+ {
+ TerseChar ();
+ }
+ if (displaymode & boxmode)
+ {
+ BoxChar ();
+ }
+ }
+
+ /* check for abort or mode change */
+ if (BusyRead (&keyhit))
+ {
+ char STR1[2];
+ keyhit = TOUPPER (keyhit);
+ sprintf (STR1, "%c", keyhit);
+
+ if (!strcmp (STR1, Terse))
+ {
+ displaymode ^= tersemode; /* toggle terse mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else if (!strcmp (STR1, Box))
+ {
+ displaymode ^= boxmode; /* toggle box mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else if (!strcmp (STR1, Full))
+ {
+ displaymode ^= fullmode; /* toggle full mode */
+ StartText ();
+ UpdateDVIStatusLine ();
+ StartGraphics ();
+ }
+ else if (keyhit == CR)
+ {
+ if (fontopen)
+ CloseFontFile ();
+ /* no need to set useraborted; DisplayRules done first */
+ return;
+
+ } /* if */
+ } /* if */
+ } /* inner (for) loop */
+ } /* middle (for) loop */
+ if (fontopen)
+ CloseFontFile ();
+ } /* outer (for) loop */
+}
+/* DisplayChars */
+
+/*--------------------------------------------------------------------*/
+static void
+PaperMessage (double precision)
+{
+ /* Called by CheckPageEdges to remind user of the paper size. */
+
+ WriteUnits ();
+ MesgString ("! (Paper ");
+ WriteXDim (precision, paperwd);
+ MesgString (" x ");
+ WriteYDim (precision, paperht);
+ MesgChar (')');
+ ClearMessageLine ();
+ WaitForReturn ();
+}
+
+/* PaperMessage */
+
+/*--------------------------------------------------------------------*/
+
+static void
+CheckPageEdges ()
+{
+ /* One or more page edges do not fall within the paper edges.
+ This routine is called after the page & paper have been displayed so
+ user can see how bad the problem is.
+ */
+
+ double precision = 1.0e-2;
+
+ if (minhp < paperleft)
+ {
+ ClearMessageLine ();
+ MesgString ("Page past paper's left edge by ");
+ WriteXDim (precision, paperleft - minhp);
+ PaperMessage (precision);
+ }
+ if (maxhp > paperright)
+ {
+ ClearMessageLine ();
+ MesgString ("Page past paper's right edge by ");
+ WriteXDim (precision, maxhp - paperright);
+ PaperMessage (precision);
+ }
+ if (minvp < papertop)
+ {
+ ClearMessageLine ();
+ MesgString ("Page past paper's top edge by ");
+ WriteYDim (precision, papertop - minvp);
+ PaperMessage (precision);
+ }
+ if (maxvp > paperbottom)
+ {
+ ClearMessageLine ();
+ MesgString ("Page past paper's bottom edge by ");
+ WriteYDim (precision, maxvp - paperbottom);
+ PaperMessage (precision);
+ }
+}
+/* CheckPageEdges */
+/*--------------------------------------------------------------------*/
+static void
+DisplayPage ()
+{
+ /* Display page in window region based on window location and size,
+ and displaymode. This routine is only called if paintwindow is TRUE
+ after all commands have been processed.
+ */
+
+ if (screenjustcleared)
+ {
+ /* avoid doing it again */
+
+ if (paintDVIStatus)
+ UpdateDVIStatusLine ();
+
+ if (paintWindowStatus)
+ UpdateWindowStatusLine ();
+ }
+ else
+ {
+ ClearScreen ();
+ screenjustcleared = true;
+ UpdateDVIStatusLine ();
+ UpdateWindowStatusLine ();
+ }
+
+ StartGraphics ();
+ DisplayPaperEdges ();
+ StartText ();
+
+ if (pageempty)
+ {
+ ClearMessageLine ();
+ MesgString ("Page is empty.");
+ }
+ else if (outsidepage)
+ {
+ if (pageoffpaper)
+ CheckPageEdges ();
+
+ ClearMessageLine ();
+ MesgString ("Window is ");
+
+ if (windowtop > maxvp)
+ {
+ MesgString ("below ");
+ if (windowleft > maxhp || windowleft <= minhp - scaledwd)
+ MesgString ("and ");
+ }
+ else if (windowtop <= minvp - scaledht)
+ {
+ MesgString ("above ");
+ if (windowleft > maxhp || windowleft <= minhp - scaledwd)
+ MesgString ("and ");
+ }
+ if (windowleft > maxhp)
+ MesgString ("to the right of ");
+ else if (windowleft <= minhp - scaledwd)
+ MesgString ("to the left of ");
+
+ MesgString ("page.");
+ }
+ else
+ {
+ /* Page is not empty and part or all of it is visible. */
+ StartGraphics ();
+
+ useraborted = false;
+ DisplayRules ();
+ if (!useraborted)
+ DisplaySpecials ();
+ if (!useraborted)
+ DisplayChars ();
+
+ StartText ();
+
+ if (pageoffpaper)
+ CheckPageEdges (); /* May write messages */
+
+ if (allpagevisible)
+ {
+ ClearMessageLine ();
+ MesgString ("Entire page is visible. ");
+ PadMesg ();
+ }
+ }
+
+ MesgFlush ();
+}
+/* DisplayPage */
+/*--------------------------------------------------------------------*/
+void
+ProcessCommandLine (String commstring)
+{
+ /* Parse commstring, and call the appropriate command handler
+ for each command in commstring.
+ */
+ int n; /* returned by GetInteger call */
+
+ ClearMessageLine (); /* erase message line at this stage */
+ commlen = strlen (commstring);
+ /* ignore any trailing spaces */
+ while (commlen > 0 && commstring[commlen - 1] == ' ')
+ commlen--;
+ /* terminate commstring properly */
+ commstring[commlen] = '\0';
+
+ /* initialize flags for multiple command processing */
+ badcommand = false;
+ paintWindowStatus = false;
+ paintDVIStatus = false;
+ paintwindow = false;
+ screenjustcleared = false;
+ pageoffpaper = false;
+
+ commpos = 0;
+ while (commpos < commlen && !badcommand)
+ {
+ /* next command is defined by the next non-space character in commstring */
+ while (commstring[commpos] == ' ')
+ commpos++; /* ignore any leading spaces */
+
+ command = TOUPPER (commstring[commpos]);
+ switch (command)
+ {
+ case 'W': /* Window move */
+ commpos++;
+ WindowMove ();
+ if (!badcommand)
+ paintWindowStatus = true;
+ break;
+
+ case 'U': /* move Up */
+ case 'D': /* move Down */
+ commpos++;
+ WindowUpDown ();
+ paintWindowStatus = true;
+ break;
+
+ case 'L': /* move Left */
+ case 'R': /* move Right */
+ commpos++;
+ WindowLeftRight ();
+ paintWindowStatus = true;
+ break;
+
+ case 'H': /* Horizontal dimension */
+ commpos++;
+ SetWindowWidth ();
+ NewLocation (windowleft, windowtop);
+ paintWindowStatus = true;
+ break;
+
+ case 'V': /* Vertical dimension */
+ commpos++;
+ SetWindowHeight ();
+ NewLocation (windowleft, windowtop);
+ paintWindowStatus = true;
+ break;
+
+ case 'A': /* toggle Autoview on or off */
+ commpos++;
+ SetAutoView ();
+ if (!badcommand)
+ paintDVIStatus = true;
+ break;
+
+ case 'Z': /* Zoom in or out */
+ commpos++;
+ ZoomWindow ();
+ if (!badcommand)
+ NewLocation (windowleft, windowtop);
+ if (!badcommand)
+ paintWindowStatus = true;
+ break;
+
+ case 'N': /* Next page */
+ commpos++;
+ if (NextPageFound (true)) /* ascending */
+ ProcessPage ();
+ break;
+
+ case 'P': /* Previous page */
+ commpos++;
+ if (NextPageFound (false)) /* descending */
+ ProcessPage ();
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* go to page with this number, if number is valid */
+
+ if (GetInteger (commstring, commlen, &commpos, &n))
+ {
+ /* must be true, and commpos now after last digit */
+ if (DVIPageFound (n))
+ ProcessPage ();
+ }
+ else
+ { /* safety net */
+ ClearMessageLine ();
+ MesgString ("Expected an Integer! Type ? for help.");
+ BadCommandMessage ();
+ }
+ break;
+
+ case '[': /* go to page described by count0...count9 */
+ if (TeXPageFound ())
+ /* commpos incremented in ParseTeXpage */
+ ProcessPage ();
+ break;
+
+ case 'T': /* Terse display */
+ commpos++;
+ displaymode ^= tersemode; /* toggle terse mode */
+ paintDVIStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+ break;
+
+ case 'B': /* Box display */
+ commpos++;
+ displaymode ^= boxmode; /* toggle box mode */
+ paintDVIStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+ break;
+
+ case 'F': /* Full display */
+ commpos++;
+ displaymode ^= fullmode; /* toggle full mode */
+ paintDVIStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+ break;
+
+ case 'C': /* Change units */
+ commpos++;
+ ChangeUnits ();
+ if (!badcommand)
+ paintWindowStatus = true;
+ break;
+
+ case '?': /* command help */
+ commpos++;
+ ShowCmdHelp ();
+ break;
+
+ case 'S': /* file-and-page Statistics */
+ commpos++;
+ ShowStatistics ();
+ ClearScreen ();
+ screenjustcleared = true;
+ paintDVIStatus = true;
+ paintWindowStatus = true;
+ if (currDVIpage != 0)
+ paintwindow = true;
+ break;
+
+ case '\014': /* ctrl-L : refresh screen */
+ commpos++;
+ DisplayPage (); /* unconditionally, and immediately on interpretation */
+ break;
+
+ case '\021': /* ctrl-Q : ignore flow-control continue */
+ case '\023': /* ctrl-S : ignore flow-control suspend */
+ /* do nothing, except advance character pointer */
+ commpos++;
+ break;
+
+ case 'Q': /* Quit */
+ return;
+
+ break;
+
+ default: /* unknown command */
+ commpos++;
+ ClearMessageLine ();
+ MesgString ("Unknown command! Type ? for help.");
+ BadCommandMessage ();
+ break;
+ } /* command */
+ } /* while */
+
+ if (paintwindow) /* only update window after processing all commands */
+ DisplayPage ();
+ else if (!vdu_clears_lines && (paintDVIStatus || paintWindowStatus))
+ DisplayPage ();
+ else
+ {
+ if (paintDVIStatus)
+ UpdateDVIStatusLine ();
+ if (paintWindowStatus)
+ UpdateWindowStatusLine ();
+ }
+}
+/* ProcessCommandLine */
+
+/*--------------------------------------------------------------------*/
+
+static void
+NextCommandLine ()
+{
+ /* Prompt user for next command line, and process response */
+
+ ClearTextLine (commandl);
+ MoveToTextLine (commandl);
+
+ MesgString (commprompt);
+ MesgFlush ();
+
+ ReadString (commstring); /* read new command line */
+
+ ProcessCommandLine (commstring);
+}
+
+/* NextCommandLine */
+
+/*--------------------------------------------------------------------*/
+static void
+Finish ()
+{
+ /* close DVI file, reset VDU and restore terminal */
+
+ CloseDVIFile ();
+
+ /*!!! ClearScreen(); */
+ screenjustcleared = true;
+ MoveToTextLine (1);
+ MesgLine ();
+ /*!!! ResetVDU(); */
+}
+
+/* Finish */
+
+/*--------------------------------------------------------------------*/
+void *
+Malloc (size_t n)
+{
+ void *MallocTemp;
+ MallocTemp = malloc (n);
+ if (MallocTemp)
+ {
+ return MallocTemp;
+ }
+ else
+ {
+ StartText ();
+ ResetVDU (); /* do before message since it might erase screen! */
+ FATAL ("Out of memory.");
+ return NULL;
+ }
+}
+/*--------------------------------------------------------------------*/
+
+int
+main (int argc, char **argv)
+{
+ char STR1[2];
+
+ kpse_set_progname (argv[0]);
+ kpse_init_prog ("DVGT", DEF_XRES, DEF_MFMODE, DEF_DUMMY);
+ kpse_set_program_enabled (kpse_pk_format, true, kpse_src_compile);
+
+ save_init_tty (); /* save initial terminal settings, early */
+ textlinewidth = 80; /* for the initial screen type */
+ if (!InitOptions (argc, argv))
+ { /* initialize DVIname and command options */
+ /* Print the precompiled information */
+ PrintText (immed_help_strings);
+ return 1;
+ }
+ InitScreenIO (); /* SYSDEP: sets cbreak on & echo off */
+
+ InitDVIReader ();
+ InitFontReader ();
+ OpenDVIFile (DVIname); /* and read DVImag etc. */
+ if (mag == 0) /* use DVImag */
+ mag = DVImag;
+ SetConversionFactors (xres, yres, mag / 1000.0); /* for DVIReader */
+ InitVDU (); /* init windowwd/ht etc. */
+ InitWinVars ();
+ StartText ();
+ ClearScreen ();
+ screenjustcleared = true;
+ UpdateDVIStatusLine ();
+ UpdateWindowStatusLine ();
+ MoveToTextLine (messagel);
+ MesgString (DVGT_VERSION);
+ MesgLine ();
+ do
+ {
+ NextCommandLine (); /* parse and execute command(s) */
+ }
+ while (strcmp ((sprintf (STR1, "%c", command), STR1), Quit));
+ Finish ();
+ return 0; /* OK */
+}
+/* main() program of DVItoVDU */
+
+/* end dvitovdu.c */
diff --git a/dviware/dvgtk/dvgt.h b/dviware/dvgtk/dvgt.h
new file mode 100644
index 0000000000..283ea7620d
--- /dev/null
+++ b/dviware/dvgtk/dvgt.h
@@ -0,0 +1,110 @@
+/* dvgt.h - common header file for dvgtk
+ $Id: dvgt.h,v 0.2 1997/03/28 03:16:09 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __DVGT_H__
+#define __DVGT_H__
+
+#include "c-auto.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <kpathsea/debug.h> /* debug */
+#include <kpathsea/progname.h> /* program_invocation_name */
+#include <kpathsea/c-pathch.h> /* DIR_SEP_STRING */
+#include <kpathsea/types.h> /* boolean */
+#include <kpathsea/lib.h> /* FATAL */
+
+#define DVGT_VERSION "This is dvgtk 0.2."
+
+/* Support for no prototypes */
+#ifndef PARAMS
+# if PROTOTYPES
+# define PARAMS(Args) Args
+# else
+# define PARAMS(Args) ()
+# endif
+#endif
+
+/* Word must be 32 bits. Word is used in the PK bitmap operations.
+ For an architecture with 32-bit ints, Word can be int.
+ */
+
+typedef int Word; /* SYSDEP: ASSUMES exactly 32 bits in int. */
+typedef void (*VFP) ();
+typedef void *Anyptr;
+
+/* Memory allocation */
+void *Malloc PARAMS ((size_t));
+#define Free(p, T) (free((Anyptr) (p)), (p) = (T *) NULL)
+
+/* Global declarations */
+#define maxstring 1024
+typedef char String[maxstring + 1]; /* Allow space for null terminator */
+
+/* SYSDEP: cmd_help should have <= maxline chars/line */
+#define maxline 80
+
+/* The following variant records are needed because Pyramid Pascal
+ does not provide type coercion.
+ Note that we couldn't overlay INTEGER and BITSET because
+ of the crazy storage scheme used to represent a set of 0..31
+ where the bit order within a word is 7..0 15..8 23..16 31..24!
+ */
+typedef union byte_order
+ {
+ int int_;
+ struct
+ {
+#ifdef WORDS_BIGENDIAN
+ char _byte3, _byte2, _byte1, _byte0;
+#else /* not WORDS_BIGENDIAN */
+ char _byte0, _byte1, _byte2, _byte3;
+#endif /* WORDS_BIGENDIAN */
+ }
+ _bytes;
+ }
+byte_order;
+
+#define byte0(lvalue) ((byte_order *)(&lvalue))->_bytes._byte0
+#define byte1(lvalue) ((byte_order *)(&lvalue))->_bytes._byte1
+#define byte2(lvalue) ((byte_order *)(&lvalue))->_bytes._byte2
+#define byte3(lvalue) ((byte_order *)(&lvalue))->_bytes._byte3
+
+typedef struct int_or_bptr
+ {
+ boolean b;
+ union
+ {
+ int int_;
+ int *bptr;
+ }
+ UU;
+ }
+int_or_bptr;
+
+typedef struct int_or_mptr
+ {
+ boolean b;
+ union
+ {
+ int int_;
+ Word *mptr; /* bitmap */
+ }
+ UU;
+ }
+int_or_mptr;
+
+#define bufflen 1024 /* size of buffer for holding DVI/PK bytes */
+typedef unsigned char buffer[bufflen];
+
+#endif /* __DVGT_H__ */
diff --git a/dviware/dvgtk/dvgt.man b/dviware/dvgtk/dvgt.man
new file mode 100644
index 0000000000..8971200406
--- /dev/null
+++ b/dviware/dvgtk/dvgt.man
@@ -0,0 +1,82 @@
+.TH DVGT 1
+.\" $Id:$
+.\" Tomasz J. Cholewo <t.cholewo@ieee.org>
+.SH DVGT
+dvgt \- DVI file previewer for Tektronix 4010 emulators
+.SH SYNOPSIS
+dvgt [options] filename.[dvi]
+.SH "DESCRIPTION"
+dvgt interactively views TeX-generated DVI files on Tektronix 4010 emulators.
+.SH OPTIONS
+.TP 5
+.BI "\-H " horizontal_offset
+(default = 0.0 in)
+.TP 5
+.BI "\-V " vertical_offset
+(default = 0.0 in)
+.TP 5
+.BI "\-d " dummy_pk
+.TP 5
+.BI "\-e " dummy_tfm
+.TP 5
+.BI "\-k " kpathsea_debug_mode
+.TP 5
+.B \-l
+set landscape mode, instead of the default portrait mode
+.TP 5
+.BI "\-m " magnification
+default = DVI file's intrinsic magnification
+.TP 5
+.BI "\-r " xres[,yres]]
+resolution in dpi
+.TP 5
+.BI "\-x " paper_width
+.TP 5
+.BI "\-y " paper_height
+
+.SH EXAMPLES
+Start dvgt on file.dvi with A4 paper settings:
+
+ dvgt -x210mm -y297mm file.dvi
+
+\" .SH ENVIRONMENT
+\" envariables this program might care about
+\" .SH FILES
+\" all files used by the program. typical usage is like this:
+\" .br
+\" .nf
+\" .\" set tabstop to longest possible filename, plus a wee bit
+\" .ta \w'/usr/lib/perl/getopts.pl 'u
+\" \fI/usr/man\fR default man tree
+\" \fI/usr/man/man*/*.*\fR unformatted (nroff source) man pages
+.SH "SEE ALSO"
+dvips(1), xdvi(1), dvilj(1)
+\" .SH NOTES
+\" miscellaneous commentary
+.SH CAVEATS
+This is a beta version.
+\" .SH DIAGNOSTICS
+\" all the possible error messages the program can print out, and
+\" what they mean.
+\" .SH BUGS
+\" things that are broken or just don't work quite right.
+\" .SH RESTRICTIONS
+\" bugs you don't plan to fix :-)
+.SH AUTHORS
+Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo and
+many more.
+.SH HISTORY
+Andrew Trevorrow wrote the original DVItoVDU in Modula-2.
+
+The initial C code for this version of DVItoVDU was copied from Ian
+Dall's site, ftp://augean.oz.au/pub/misc/dv.tar.Z. Ian had, as his
+source code seems to indicate, automatically translated it from Modula.
+
+Geoffrey Tobin added a lot of new functionality: font searching and
+substitution, option handling, bitmap allocation, help files, and much
+more.
+
+Tomasz J. Cholewo modified dvgt to use kpathsea library.
+
+A thorough history of the various versions of "dvitovdu", "dvi2vdu",
+and "dv" in the world is much more complex.
diff --git a/dviware/dvgtk/dvireader.c b/dviware/dvgtk/dvireader.c
new file mode 100644
index 0000000000..8e59cb79a8
--- /dev/null
+++ b/dviware/dvgtk/dvireader.c
@@ -0,0 +1,1885 @@
+/* dvireader.c - functions for reading DVI files
+ $Id: dvireader.c,v 0.2 1997/03/28 03:16:30 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "dvireader.h"
+#include "screenio.h"
+#include "fontreader.h"
+#include "options.h"
+
+/* Variables Exported, via "dvireader.h". */
+int DVImag;
+int totalpages, totalfonts, totalrules;
+int currDVIpage;
+TeXcounters currTeXpage;
+ruleinfo *rulelist, *ruletail;
+fontinfo *fontlist, *currfont;
+specialinfo *speciallist;
+boolean pageempty;
+int minhp, minvp, maxhp, maxvp;
+
+time_t dvi_time; /* last mod. time for dvi file */
+/*----------------------------------------------------------------------
+ DECLARATIONS FOR INTERPRETING A DVI PAGE
+
+ The commands between the bop and eop bytes for a particular page need to be
+ translated (based on the method used by DVITYPE) before we can determine the
+ the position and shape of all rules on that page, as well as the position
+ of all characters and which fonts they belong to.
+*/
+
+/* Use symbolic names for the opcodes of DVI commands: */
+
+#define setchar0 0
+ /* setchar1..setchar127 = 1..127 */
+#define set1 128
+ /* set2,set3,set4 = 129,130,131 */
+#define setrule 132
+#define put1 133
+ /* put2,put3,put4 = 134,135,136 */
+#define putrule 137
+#define nop 138
+#define bop 139
+#define eop 140
+#define push 141
+#define pop 142
+#define right1 143
+#define w0 147
+#define x0 152
+#define down1 157
+#define y0_ 161
+#define z0 166
+#define right2 144
+#define w1 148
+#define x1 153
+#define down2 158
+#define y1_ 162
+#define z1 167
+#define right3 145
+#define w2 149
+#define x2 154
+#define down3 159
+#define y2 163
+#define z2 168
+#define right4 146
+#define w3 150
+#define x3 155
+#define down4 160
+#define y3 164
+#define z3 169
+#define w4 151
+#define x4 156
+#define y4 165
+#define z4 170
+#define fntnum0 171
+ /* fntnum1..fntnum63 = 172..234 */
+#define fnt1 235
+ /* fnt2,fnt3,fnt4 = 236,237,238 */
+#define xxx1 239
+ /* xxx2,xxx3,xxx4 = 240,241,242 */
+#define fntdef1 243
+ /* fntdef2,fntdef3,fntdef4 = 244,245,246 */
+#define pre 247
+#define post 248
+#define postpost 249
+/* undefined commands = 250..255 */
+
+#define maxstacksize 100 /* maximum stack size for state values */
+
+/* According to the DVI Driver Standard, Level 0, version 0.5,
+ section 2.6.2, max_drift should depend on the output device:
+
+ 2 if a "device unit" <= 0.005 in (0.127 mm),
+ 1 if a "device unit" > 0.005 in (0.127 mm)
+ but <= 0.01 in (0.254 mm),
+ 0 if a "device unit" > 0.01 in (0.254 mm).
+
+ So, the value given here for max_drift implies a device with
+ a resolution of at least 200 dpi.
+
+ Note: max_drift is a number of pixels.
+ */
+
+#define max_drift 2 /* prevent hh & vv from drifting too far */
+
+
+/*----------------------------------------------------------------------
+ DECLARATIONS FOR ACCESSING BYTES IN A DVI FILE
+
+ A DVI file is a stream of 8-bit bytes. Once opened, we can access any byte
+ by setting DVIoffset to the required position and then calling
+GetDVIByte.
+*/
+
+static int DVIfile; /* DVI file descriptor */
+static int DVIoffset; /* current byte offset in DVIfile */
+static int currDVIbuff; /* starting byte offset in buffer */
+static buffer DVIbuffer; /* input buffer */
+static int postpostid; /* offset of postpost's id byte */
+
+/*----------------------------------------------------------------------
+ DECLARATIONS FOR GETTING TO A DVI PAGE
+
+ The user can select a particular page by specifying a DVI page
+ number (from 1 to totalpages), or a TeX page number (based on the
+ values of \count0,\count1,...,\count9), or simply requesting the next page
+ in the DVI file (which depends on whether we are ascending or not).
+ We will often need to follow the DVI backpointers to locate the bop byte
+ of a selected page.
+*/
+
+static int curreop; /* position of eop byte of current page */
+static int currbop; /* position of bop byte of current page */
+static int lastbop; /* position of last bop byte */
+static int prevbop; /* position of bop byte of previous page;
+ note that prevbop of first page = -1 */
+
+static unsigned char DVIcommand; /* holds next DVI command */
+
+static int maxstack; /* max pushes over pops in DVI file */
+static int num = 0; /* DVI numerator */
+static int den = 0; /* DVI denominator */
+static double xconv = 0.0; /* converts DVI units to X pixels */
+static double yconv = 0.0; /* converts DVI units to Y pixels */
+static int h, v; /* current pos on page in DVI units */
+static int w, x; /* horizontal increments in DVI units */
+static int y, z; /* vertical increments in DVI units */
+static int hh, vv; /* h and v in pixels (approx) */
+static int hhh, vvv; /* h and v rounded to nearest pixel */
+static int hstack[maxstacksize], vstack[maxstacksize];
+ /* push down stacks for state values */
+static int wstack[maxstacksize], xstack[maxstacksize], ystack[maxstacksize],
+ zstack[maxstacksize], hhstack[maxstacksize], vvstack[maxstacksize];
+static int stackpos;
+/* stacks empty when stackpos = 0, i.e., top of stacks = stackpos - 1 */
+static int fontspace; /* used in DoRight and DoDown */
+
+
+/*--------------------------------------------------------------------*/
+
+/* Here are the functions used to get byte/s from DVIfile.
+ They are essentially the same as those used in DVITYPE.
+ */
+
+static int
+GetDVIByte ()
+{
+ /* Returns the value (unsigned) of the byte at DVIoffset and
+ advances DVIoffset for the next GetDVIByte.
+ */
+
+ int Result, buffstart, result;
+
+ /* bufflen is a #define-d constant in "dvgt.h" */
+
+ buffstart = DVIoffset / bufflen * bufflen; /* 0, bufflen, 2*bufflen... */
+ if (buffstart != currDVIbuff)
+ {
+ currDVIbuff = buffstart;
+ result = lseek (DVIfile, buffstart, SEEK_SET);
+
+ if (result != buffstart)
+ {
+ FATAL ("lseek failed in GetDVIByte!");
+ }
+ result = read (DVIfile, DVIbuffer, bufflen);
+
+ if (result == -1)
+ {
+ FATAL ("read failed in GetDVIByte!");
+ }
+ }
+ Result = DVIbuffer[DVIoffset - buffstart];
+ DVIoffset++;
+ return Result;
+}
+/* GetDVIByte */
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedDVIByte ()
+{
+ /* the next byte, signed */
+ int b;
+
+ b = GetDVIByte ();
+ if (b < 128)
+ return b;
+ else
+ return (b - 256);
+}
+/* SignedDVIByte */
+
+/*--------------------------------------------------------------------*/
+
+static int
+GetTwoDVIBytes ()
+{
+ /* the next 2 bytes, unsigned */
+ int a, b;
+
+ a = GetDVIByte ();
+ b = GetDVIByte ();
+ return (a * 256 + b);
+}
+/* GetTwoDVIBytes */
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedDVIPair ()
+{
+ /* the next 2 bytes, signed */
+ int a, b;
+
+ a = GetDVIByte ();
+ b = GetDVIByte ();
+ if (a < 128)
+ return (a * 256 + b);
+ else
+ return ((a - 256) * 256 + b);
+}
+/* SignedDVIPair */
+
+/*--------------------------------------------------------------------*/
+
+static int
+GetThreeDVIBytes ()
+{
+ /* the next 3 bytes, unsigned */
+ int a, b, c;
+
+ a = GetDVIByte ();
+ b = GetDVIByte ();
+ c = GetDVIByte ();
+ return ((a * 256 + b) * 256 + c);
+}
+/* GetThreeDVIBytes */
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedDVITrio ()
+{
+ /* the next 3 bytes, signed */
+ int a, b, c;
+
+ a = GetDVIByte ();
+ b = GetDVIByte ();
+ c = GetDVIByte ();
+ if (a < 128)
+ return ((a * 256 + b) * 256 + c);
+ else
+ return (((a - 256) * 256 + b) * 256 + c);
+}
+/* SignedDVIOqTrio */
+
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedDVIQuad ()
+{
+ /* the next 4 bytes, signed */
+ int w;
+ byte3 (w) = GetDVIByte ();
+ byte2 (w) = GetDVIByte ();
+ byte1 (w) = GetDVIByte ();
+ byte0 (w) = GetDVIByte ();
+ return (w);
+}
+/* SignedDVIQuad */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ProcessPostamble ()
+{
+ /* Having successfully opened the DVI file, we find the postamble
+ and initialize these global variables:
+ lastbop, num, den, DVImag, maxstack, totalpages.
+ The font definitions are read by ProcessFontDefs.
+ */
+
+ int postamblepos, postamble, pagehtplusdp, pagewidth;
+
+ DVIoffset = postpostid - 4;
+ postamblepos = SignedDVIQuad (); /* get post_post's postamble ptr */
+ DVIoffset = postamblepos;
+ postamble = GetDVIByte ();
+ lastbop = SignedDVIQuad ();
+ num = SignedDVIQuad ();
+ den = SignedDVIQuad ();
+ DVImag = SignedDVIQuad ();
+ pagehtplusdp = SignedDVIQuad ();
+ pagewidth = SignedDVIQuad ();
+ maxstack = SignedDVIPair ();
+ totalpages = SignedDVIPair ();
+ if (maxstack <= maxstacksize)
+ return;
+
+ FATAL ("Stack capacity exceeded!");
+ /* now we don't need to test for stack overflow in DoPush */
+}
+/* ProcessPostamble */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ProcessFontDefs ()
+{
+ /* Read the fntdef commands in the postamble (fntdef commands in the DVI
+ pages will be skipped) and store the information in the font list.
+ (Note that complete fontspecs are NOT built here because DVIReader does not
+ want to know about the format or naming conventions of font files.)
+ Since ProcessPostamble ended by reading the totalpages parameter, the
+ next GetDVIByte should return nop or first fntdef.
+ */
+
+ int f = 0, c, s, d, a, l; /* hold fntdef parameters */
+ int i;
+ char ch; /* for getting farea and fname */
+ String farea, fname; /* a and l bytes long respectively */
+
+ totalfonts = 0; /* number of nodes in font list */
+ fontlist = (fontinfo *) NULL;
+ do
+ {
+ DVIcommand = GetDVIByte ();
+ if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3)
+ {
+ switch (DVIcommand - fntdef1)
+ {
+ case 0:
+ f = GetDVIByte ();
+ break;
+
+ case 1:
+ f = GetTwoDVIBytes ();
+ break;
+
+ case 2:
+ f = GetThreeDVIBytes ();
+ break;
+
+ case 3:
+ f = SignedDVIQuad ();
+ break;
+ }
+ c = SignedDVIQuad (); /* checksum; ignore it */
+ s = SignedDVIQuad (); /* scaled size */
+ d = SignedDVIQuad (); /* design size */
+ a = GetDVIByte (); /* length of font area */
+ l = GetDVIByte (); /* length of font name */
+
+ /* read and store font area */
+ for (i = 0; i < a; i++)
+ {
+ ch = GetDVIByte ();
+ if (i < maxfontspec)
+ farea[i] = ch;
+ }
+ farea[i <= maxfontspec ? i : maxfontspec] = '\0';
+
+ /* read and store font name */
+ for (i = 0; i < l; i++)
+ {
+ ch = GetDVIByte ();
+ if (i < maxfontspec)
+ fname[i] = ch;
+ }
+
+ fname[i <= maxfontspec ? i : maxfontspec] = '\0';
+
+ currfont = (fontinfo *) Malloc (sizeof (fontinfo));
+ currfont->fontused = false;
+ currfont->fontnum = f;
+ currfont->scaledsize = s;
+ currfont->designsize = d;
+ strncpy (currfont->fontarea, farea, maxstring);
+ currfont->fontarea[maxstring] = '\0'; /* to be careful */
+ currfont->fontarealen = a;
+ strncpy (currfont->fontname, fname, maxstring);
+ currfont->fontname[maxstring] = '\0'; /* to be careful */
+ currfont->fontnamelen = l;
+ currfont->fontspec[0] = '\0';
+ currfont->fontspeclen = 0; /* fontspec is built in FontReader */
+ currfont->fontexists = false; /* becomes TRUE if fontspec can be opened */
+ currfont->totalchars = 0;
+
+ /* first node allocated in DoFont */
+ currfont->charlist = (charinfo *) NULL;
+
+ /* nodes are added to tail of char list */
+ currfont->chartail = (charinfo *) NULL;
+
+ /* allocated once per font; see DoFont */
+ currfont->pixelptr = (_REC_pixeltable *) NULL;
+
+ currfont->nextfont = fontlist;
+ fontlist = currfont; /* add new font to head of list */
+ totalfonts++;
+ }
+ else if (DVIcommand != nop)
+ {
+ if (DVIcommand != postpost)
+ FATAL1 ("Unexpected DVI command in postamble = %d", DVIcommand);
+ /* we have reached end of postamble */
+ }
+ }
+ while (DVIcommand != postpost);
+
+ /* nop commands can occur between DVI commands */
+}
+/* ProcessFontDefs */
+
+/*--------------------------------------------------------------------*/
+
+void
+OpenDVIFile (char *name)
+{
+ /* If the given file can be opened and is a valid TeX82 DVI file then
+ the following global variables are initialized:
+
+ DVImag := magnification value stored in DVI file (TeX's \mag)
+ totalpages := total number of pages in DVI file
+ currDVIpage := 0 (and remains so until a page is selected)
+ currTeXpage := ten 0s (ditto)
+ totalfonts := total number of fonts in DVI file (= nodes in font list)
+ fontlist-> (nodes are added to head of list)
+ fontused := FALSE
+ fontnum := internal DVI font number
+ scaledsize := scaled size of font (in DVI units)
+ designsize := design size of font (in DVI units)
+ fontarea := a string of min (fontarealen, maxfontspec) characters
+ fontname := a string of min (fontnamelen, maxfontspec) characters
+ fontspec := a null string (fontspeclen := 0)
+ fontexists := FALSE
+ totalchars := 0
+ charlist := NIL
+ chartail := NIL
+ pixelptr := NIL
+ nextfont := next node in font list (if not NIL)
+ */
+
+#if 0
+ struct stat fstatbuf;
+#endif
+
+ currDVIbuff = -1; /* impossible value for first GetDVIByte */
+ DVIfile = open (name, O_RDONLY, 0);
+ if (DVIfile >= 0)
+ {
+ int i;
+#if 0
+ fstat (DVIfile, &fstatbuf);
+ if (S_ISDIR(fstatbuf.st_mode))
+ FATAL1 ("`%s' is a directory\n", name);
+ dvi_time = fstatbuf.st_mtime;
+#endif
+
+ /* get offset of last DVI byte */
+ DVIoffset = lseek (DVIfile, 0, SEEK_END);
+ if (DVIoffset == -1)
+ FATAL ("Failed to find end of file!");
+ if (DVIoffset == 0)
+ FATAL ("DVI file is empty!");
+ DVIoffset--;
+
+ /* In the following, DVIoffset == 1 signifies the start of the file. */
+
+ /* skip any NULs */
+ while (GetDVIByte () == 0 && DVIoffset != 1)
+ {
+ DVIoffset -= 2; /* GetDVIByte increments */
+ }
+ DVIoffset--;
+
+ /* skip 223s */
+ while (GetDVIByte () == 223 && DVIoffset != 1)
+ {
+ DVIoffset -= 2; /* GetDVIByte increments */
+ }
+
+ DVIoffset--;
+ postpostid = DVIoffset; /* remember offset of id byte */
+ if (GetDVIByte () != 2)
+ {
+ FATAL ("Not a valid DVI file!");
+ /*NOTREACHED */
+ return;
+ }
+ ProcessPostamble (); /* get DVImag, totalpages, etc */
+ ProcessFontDefs (); /* build and initialize font list */
+ currDVIpage = 0; /* we haven't processed a page yet */
+ for (i = 0; i <= 9; i++)
+ currTeXpage[i] = 0;
+
+ return;
+ }
+ else
+ FATAL1 ("Couldn't open DVI file: `%s'\n", name);
+}
+/* OpenDVIFile */
+/*--------------------------------------------------------------------*/
+#if 0
+boolean
+check_dvi_file (char *DVIname)
+{
+ struct stat statbuf;
+ if (DVIname == NULL || stat (DVIname, &statbuf) != 0 || statbuf.st_mtime != dvi_time) {
+ if (DVIname) {
+ Fclose(DVIname);
+ DVIname = NULL;
+ if (list_fonts) Putchar('\n');
+
+ }
+ }
+}
+#endif
+/*--------------------------------------------------------------------*/
+static void
+SkipFntdef (int which)
+{
+ /* Read past a fntdef command without interpreting it. */
+
+ int dummy, a, l, i;
+
+ switch (which)
+ { /* which = DVIcommand - fntdef1 */
+ case 0:
+ dummy = GetDVIByte ();
+ break;
+ case 1:
+ dummy = GetTwoDVIBytes ();
+ break;
+ case 2:
+ dummy = GetThreeDVIBytes ();
+ break;
+ case 3:
+ dummy = SignedDVIQuad ();
+ break;
+ }
+ dummy = SignedDVIQuad ();
+ dummy = SignedDVIQuad ();
+ dummy = SignedDVIQuad ();
+
+ a = GetDVIByte (); /* length of directory */
+ l = GetDVIByte (); /* length of font name */
+ for (i = 1; i <= l + a; i++)
+ dummy = GetDVIByte ();
+}
+/* SkipFntdef */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadFirstBop ()
+{
+
+ /* Read first bop by skipping past preamble; update currbop and currDVIpage. */
+ int k, i, dummy;
+
+ DVIoffset = 14; /* position of preamble's k parameter */
+ k = GetDVIByte (); /* length of x parameter */
+ for (i = 1; i <= k; i++) /* skip preamble comment */
+ dummy = GetDVIByte ();
+ do
+ { /* skip any nops and fntdefs */
+ DVIcommand = GetDVIByte ();
+ if (DVIcommand != nop && DVIcommand != bop)
+ {
+ if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3)
+ SkipFntdef (DVIcommand - fntdef1);
+ else
+ FATAL1 ("Unexpected DVI command before first bop = %d.",
+ DVIcommand);
+ }
+ /* do nothing */
+ }
+ while (DVIcommand != bop);
+ currbop = DVIoffset - 1; /* position in DVI file of first bop */
+ currDVIpage = 1;
+}
+/* ReadFirstBop */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadNextBop ()
+{
+ /* We are currently positioned after an eop byte which we know is not the
+ last. This routine positions us after the next bop byte and updates
+ currbop and currDVIpage.
+ */
+
+ /* skip any nops and fntdefs */
+ do
+ {
+ DVIcommand = GetDVIByte ();
+ if (DVIcommand != nop && DVIcommand != bop)
+ {
+ if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3)
+ SkipFntdef (DVIcommand - fntdef1);
+ else
+ FATAL1 ("Unexpected DVI command between eop and bop = %d.",
+ DVIcommand);
+ }
+ /* do nothing */
+ }
+ while (DVIcommand != bop);
+ currbop = DVIoffset - 1; /* position in DVI file of this bop */
+ currDVIpage++;
+}
+/* ReadNextBop */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadBopParameters ()
+{
+
+ /* We should now be positioned after the bop of desired page, so read
+ the 10 TeX counters and update currTeXpage and prevbop.
+ At the end of this routine we will be at the byte after currbop's parameters
+ and ready to InterpretPage.
+ */
+ int i;
+
+ for (i = 0; i <= 9; i++)
+ currTeXpage[i] = SignedDVIQuad ();
+ prevbop = SignedDVIQuad (); /* position of previous bop in DVI file */
+}
+/* ReadBopParameters */
+
+/*--------------------------------------------------------------------*/
+
+void
+MoveToNextPage (boolean ascending)
+{
+ /* MoveToNextPage will select the next page, depending on the current page
+ and the specified direction. If the value of currDVIpage is 0 (set in
+ OpenDVIFile), then MoveToNextPage will select the first page if ascending is
+ TRUE and the last page if ascending is FALSE. If currDVIpage is > 0 then
+ MoveToNextPage will select currDVIpage+1 if ascending (unless currDVIpage =
+ totalpages, in which case it does nothing), or currDVIpage-1 if descending
+ (unless currDVIpage = 0).
+
+ Before calling InterpretPage, DVItoVDU must position DVIReader to the
+ desired page by calling one of the MoveTo... routines.
+ The global variables updated if a page is located by any MoveTo... call are:
+ currDVIpage := the current DVI page (1..totalpages)
+ currTeXpage := the ten TeX counter values stored with this page
+ Note that currDVIpage is initially 0 until one of these routines succeeds.
+ */
+
+ /* keep within limits of document */
+ if ((currDVIpage != 1 && !ascending)
+ || (currDVIpage != totalpages && ascending))
+ {
+ if (currDVIpage == 0)
+ { /* special value */
+ /* we haven't processed a page yet */
+ if (ascending) /* get first page */
+ ReadFirstBop ();
+ else
+ { /* get last page */
+ currbop = lastbop;
+ DVIoffset = currbop + 1;
+ currDVIpage = totalpages;
+ }
+ }
+ else
+ {
+ if (ascending)
+ {
+ /* currently positioned after eop of currDVIpage, so get next bop */
+ ReadNextBop ();
+ }
+ else
+ {
+ /* move to bop pointed to by currbop's backpointer */
+ currbop = prevbop;
+ DVIoffset = currbop + 1; /* move to byte after previous bop */
+ currDVIpage--;
+ }
+ }
+ ReadBopParameters (); /* update currTeXpage and prevbop */
+ }
+}
+/* MoveToNextPage */
+
+/*--------------------------------------------------------------------*/
+
+void
+MoveToDVIPage (int n)
+{
+ /* Move to nth DVI page; n should be in 1..totalpages. */
+
+ if (n < 1 || n > totalpages) /* do nothing */
+ goto _L999;
+
+ if (n == 1)
+ {
+ /* Note that this test must come before next test so that we avoid any
+ problems when currDVIpage initially = 0. */
+ ReadFirstBop ();
+ }
+ else if (n == currDVIpage + 1)
+ {
+ ReadNextBop ();
+ }
+ else
+ {
+ if (n < currDVIpage)
+ {
+ currbop = prevbop; /* start searching backwards from previous page */
+ currDVIpage--;
+ }
+ else if (n > currDVIpage)
+ {
+ currbop = lastbop; /* start searching backwards from last page */
+ currDVIpage = totalpages;
+ }
+ /* if n = currDVIpage we'll just move back to currbop */
+ /* n is now <= currDVIpage so search by following backpointers */
+ while (true)
+ {
+ if (n == currDVIpage)
+ {
+ DVIoffset = currbop + 1; /* move to byte after currbop */
+ break; /* escape from "infinite" loop */
+ }
+ DVIoffset = currbop + 41; /* move to location of backpointer */
+ currbop = SignedDVIQuad (); /* get location of previous page */
+ currDVIpage--;
+ } /* while */
+ } /* if */
+ ReadBopParameters (); /* update currTeXpage and prevbop */
+_L999:;
+}
+/* MoveToDVIPage */
+
+/*--------------------------------------------------------------------*/
+
+static boolean
+CurrMatchesNew (TeXpageinfo * newTeXpage)
+{
+ /* Return TRUE iff currTeXpage matches newTeXpage. */
+
+ boolean Result;
+ int i, FORLIM;
+
+ Result = true;
+ FORLIM = newTeXpage->lastvalue;
+ for (i = 0; i <= FORLIM; i++)
+ {
+ if (newTeXpage->present[i])
+ {
+ if (newTeXpage->value[i] != currTeXpage[i])
+ Result = false;
+ }
+ }
+ return Result;
+}
+/* CurrMatchesNew */
+
+/*--------------------------------------------------------------------*/
+
+boolean
+MoveToTeXPage (TeXpageinfo * newTeXpage)
+{
+ /* MoveToTeXPage will search for the lowest DVI page matching the given
+ TeX page specification.
+
+ (TeX stores the values of \count0,\count1, ..., \count9 with every DVI
+ page. Plain TeX uses \count0 to control page numbering.)
+
+ newTeXpage is a VAR parameter only for efficiency; it won't be changed.
+ The value array stores the requested counter values, the present array
+ indicates which counters are relevant and lastvalue indicates
+ the position (0..9) of the last relevant counter.
+
+ DVItoVDU converts a more friendly representation
+ of a TeX page request into the TeXpageinfo format. For example,
+ [2..5] would be converted to: and [] would be converted to:
+ value = [2,?,5,?,?,?,?,?,?,?] value = [?,?,?,?,?,?,?,?,?,?]
+ present = [T,F,T,?,?,?,?,?,?,?] present = [F,?,?,?,?,?,?,?,?,?]
+ lastvalue = 2 lastvalue = 0
+ MoveToTeXPage returns TRUE iff the requested TeX page is located.
+ */
+
+ boolean Result;
+
+ int savecurrbop = 0, savecurrDVIpage, nextbop, i;
+ boolean atleastone;
+
+ /* save away current page and DVI position */
+ savecurrDVIpage = currDVIpage;
+ if (currDVIpage != 0) /* only if we've processed a page */
+ savecurrbop = currbop;
+ /* note that curreop is saved in last InterpretPage */
+ /* search backwards through all DVI pages for lowest matching page */
+ atleastone = false;
+ nextbop = lastbop;
+ for (i = totalpages; i >= 1; i--)
+ {
+ DVIoffset = nextbop + 1;
+ ReadBopParameters (); /* update currTeXpage and prevbop */
+ if (CurrMatchesNew (newTeXpage))
+ {
+ currbop = nextbop;
+ currDVIpage = i;
+ atleastone = true;
+ }
+ nextbop = prevbop;
+ }
+ if (!atleastone)
+ { /* no match, so restore currDVIpage */
+ currDVIpage = savecurrDVIpage;
+ if (currDVIpage != 0)
+ { /* restore page and positioning info */
+ currbop = savecurrbop;
+ DVIoffset = currbop + 1;
+ ReadBopParameters (); /* restore currTeXpage and prevbop */
+ DVIoffset = curreop + 1;
+ /* we should now be after the eop byte of the original page */
+ }
+ Result = false;
+ goto _L999;
+ }
+ DVIoffset = currbop + 1;
+ ReadBopParameters (); /* update currTeXpage and prevbop */
+ Result = true;
+_L999:
+ return Result;
+
+ /* we found lowest matching page */
+}
+/* MoveToTeXPage */
+
+/*--------------------------------------------------------------------*/
+
+void
+SetConversionFactors (double xres, double yres, double magnification)
+{
+/* Arguments:
+ xres: horizontal resolution of output device in dots per inch.
+ yres: vertical resolution.
+ magnification: magnification of document; 1 means normal size.
+ */
+ /* This routine must be called before the first InterpretPage call.
+ DVIReader needs to know the resolution and magnification values
+ before it attempts to convert DVI units into pixel values.
+ */
+
+ /* GT - The "254000.0" corresponds to ten thousand units per mm. */
+ /* Refer to TUG's DVI Driver standard. */
+
+ xconv = (num / 254000.0 * xres / den * magnification);
+ yconv = (num / 254000.0 * yres / den * magnification);
+}
+
+/* SetConversionFactors */
+
+/*--------------------------------------------------------------------*/
+
+static int
+Sign (double d)
+{
+ return (d < 0.0 ? -1 : 1);
+}
+/* Sign */
+
+/*--------------------------------------------------------------------*/
+
+static void
+InitStateValues ()
+{
+ /* Initialize state values and stack. */
+
+ /* This is the only place in "dvireader.c" */
+ /* where hoffset, voffset appear. */
+ /* The offsets are set in "options.c". */
+ /* The other extern variables are static in "dvireader.c". */
+
+ double hox, voy; /* offsets divided by conversion factors */
+
+ hox = hoffset / xconv;
+ voy = voffset / yconv;
+
+ hh = hoffset; /* 0 if no horizontal shift specified */
+ vv = voffset; /* 0 if no vertical shift specified */
+ h = Sign (hox) * (int) ((hox >= 0.0 ? hox : -hox) + 0.5);
+ v = Sign (voy) * (int) ((voy >= 0.0 ? voy : -voy) + 0.5);
+ w = 0;
+ x = 0;
+ y = 0;
+ z = 0;
+ stackpos = 0;
+ fontspace = 0; /* for DoRight and DoDown before a DoFont call */
+}
+
+/* InitStateValues */
+
+/*--------------------------------------------------------------------*/
+
+static void
+InitPage ()
+{
+ /* Initialize page so that there are no fonts, chars, rules, specials. */
+
+ pageempty = true; /* gt - assumed until a char or rule is found */
+
+ /* page edges will change if there is at least one char or rule on page */
+
+ /* gt - these shouldn't be necessary, but to be on the safe side ... */
+ minhp = 0;
+ minvp = 0;
+ maxhp = 0;
+ maxvp = 0;
+
+ currfont = fontlist;
+ while (currfont != (fontinfo *) NULL)
+ {
+ if (currfont->fontused)
+ { /* only reset those fonts used in last page */
+ currfont->fontused = false;
+
+ /* deallocate char list completely; DoFont will allocate first node */
+ currfont->totalchars = 0;
+ while (currfont->charlist != (charinfo *) NULL)
+ {
+ charinfo *thischar; /* temporary pointer to node in charlist */
+ thischar = currfont->charlist;
+ currfont->charlist = thischar->nextchar;
+ Free (thischar, charinfo);
+ }
+ currfont->chartail = (charinfo *) NULL;
+ /* pixel table remains allocated */
+ }
+ currfont = currfont->nextfont;
+ }
+ currfont = (fontinfo *) NULL; /* current font's undefined at start of page */
+
+ /* deallocate rule information except for one node (for DoSet/PutRule) */
+ totalrules = 0;
+ while (rulelist != ruletail)
+ {
+ ruleinfo *thisrule; /* temporary pointer to node in rulelist */
+ thisrule = rulelist;
+ rulelist = thisrule->nextrule;
+ Free (thisrule, ruleinfo);
+ }
+ rulelist->rulecount = 0; /* no rules in this node */
+ rulelist->nextrule = (ruleinfo *) NULL;
+
+ /* deallocate \special information */
+ while (speciallist != (specialinfo *) NULL)
+ {
+ specialinfo *thisspecial; /* temporary ptr to node in speciallist */
+ thisspecial = speciallist;
+ speciallist = speciallist->nextspecial;
+ Free (thisspecial, specialinfo);
+ }
+}
+/* InitPage */
+
+/*--------------------------------------------------------------------*/
+
+int
+XPixelRound (int DVIunits)
+{
+ /* Return the nearest number of X pixels in the given DVI X dimension. */
+
+ /* According to the DVI Driver Standard, Level 0, draft 0.05, */
+ /* section 2.6.2, "Changes in position due to characters and */
+ /* rules", */
+ /* pixel_round (n) = sign (Kn) * floor (abs (Kn) + 0.5), */
+ /* where sign (i) = -1 if i < 0 and = 1 if i >= 0, */
+ /* and K is xconv for horizontal and yconv for vertical */
+ /* dimensions. */
+
+ double Kn = xconv * (double) DVIunits;
+ return (Sign (Kn) * (int) ((Kn >= 0.0 ? Kn : -Kn) + 0.5));
+}
+
+/* XPixelRound */
+
+/*--------------------------------------------------------------------*/
+
+int
+YPixelRound (int DVIunits)
+{
+ /* Return the nearest number of Y pixels in the given DVI Y dimension. */
+
+ /* According to the DVI Driver Standard, Level 0, draft 0.05, */
+ /* section 2.6.2, "Changes in position due to characters and */
+ /* rules", */
+ /* pixel_round (n) = sign (Kn) * floor (abs (Kn) + 0.5), */
+ /* where sign (i) = -1 if i < 0 and = 1 if i >= 0, */
+ /* and K is xconv for horizontal and yconv for vertical */
+ /* dimensions. */
+
+ double Kn = yconv * (double) DVIunits;
+ return (Sign (Kn) * (int) ((Kn >= 0.0 ? Kn : -Kn) + 0.5));
+}
+
+/* YPixelRound */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoSetPutChar (int ch, boolean set)
+{
+ /* Add char info to current chartable, update our horizontal
+ position on the page and check the page edges.
+ */
+ /* putchar: Exactly the same as setchar, but we DON'T update the horizontal
+ position on the page. (We still have to check page edges.)
+ */
+
+ if (ch > maxTeXchar)
+ { /* ignore ch */
+ String codestr;
+ sprintf (codestr, "%d", ch);
+ MesgString ("Unknown character (code ");
+ MesgString (codestr);
+ MesgString (") from ");
+ MesgString (currfont->fontspec);
+ }
+ else
+ { /* ch is valid */
+ charinfo *char_info = currfont->chartail; /* may be new chartable */
+ _REC_chartable *char_tab = (_REC_chartable *) NULL;
+ _REC_pixeltable *pix_tab = (_REC_pixeltable *) NULL;
+
+ if (char_info->charcount == chartablesize)
+ {
+ char_info->nextchar = (charinfo *) Malloc (sizeof (charinfo));
+ /* add new node to end of char list */
+ char_info->nextchar->charcount = 0; /* reset charcount */
+ char_info->nextchar->nextchar = (charinfo *) NULL;
+ currfont->chartail = char_info->nextchar;
+ }
+ /* allocate a new chartable */
+
+ char_info = currfont->chartail;
+ char_tab = &char_info->chartable[char_info->charcount];
+ char_tab->hp = hh;
+ char_tab->vp = vv;
+ char_tab->code = ch;
+
+ pix_tab = &currfont->pixelptr[ch];
+
+ /* do page edges increase? */
+
+ if (pageempty || hh - pix_tab->xo < minhp)
+ minhp = hh - pix_tab->xo;
+ if (pageempty || vv - pix_tab->yo < minvp)
+ minvp = vv - pix_tab->yo;
+ if (pageempty || hh + pix_tab->wd - pix_tab->xo - 1 > maxhp)
+ maxhp = hh + pix_tab->wd - pix_tab->xo - 1;
+ if (pageempty || vv + pix_tab->ht - pix_tab->yo - 1 > maxvp)
+ maxvp = vv + pix_tab->ht - pix_tab->yo - 1;
+
+ /* the above checks ensure that page edges include all black
+ pixels in glyph, but we also want to include reference point */
+
+ if (pageempty || hh < minhp)
+ minhp = hh;
+ if (pageempty || vv < minvp)
+ minvp = vv;
+ if (pageempty || hh > maxhp)
+ maxhp = hh;
+ if (pageempty || vv > maxvp)
+ maxvp = vv;
+
+ if (set)
+ {
+ /* add DVI width calculated in PixelTableRoutine */
+ h += pix_tab->dwidth;
+
+ /* add pixel width calculated in PixelTableRoutine */
+ hh += pix_tab->pwidth;
+
+ /* use hhh and max_drift to prevent hh drifting too far from h */
+
+ hhh = XPixelRound (h);
+
+ if (abs (hhh - hh) > max_drift)
+ {
+ /* Adjust hh to be just within the allowed tolerance from h. */
+ hh = hhh + (hhh > hh ? -max_drift : max_drift);
+ }
+ }
+ currfont->totalchars++;
+ char_info->charcount++;
+ pageempty = false;
+ }
+}
+/* DoSetChar */
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoPush ()
+{
+ /* Push state values onto stack.
+ No need to test for stack overflow since we compare maxstack and
+ maxstacksize in ProcessPostamble.
+ */
+
+ hstack[stackpos] = h;
+ vstack[stackpos] = v;
+ wstack[stackpos] = w;
+ xstack[stackpos] = x;
+ ystack[stackpos] = y;
+ zstack[stackpos] = z;
+ hhstack[stackpos] = hh;
+ vvstack[stackpos] = vv;
+ stackpos++;
+}
+
+/* DoPush */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoPop ()
+{
+ /* Pop state values from top of stack. */
+
+ if (stackpos == 0)
+ {
+ FATAL ("Stack empty!");
+ }
+ stackpos--;
+ h = hstack[stackpos];
+ v = vstack[stackpos];
+ w = wstack[stackpos];
+ x = xstack[stackpos];
+ y = ystack[stackpos];
+ z = zstack[stackpos];
+ hh = hhstack[stackpos];
+ vv = vvstack[stackpos];
+}
+/* DoPop */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoRight (int amount)
+{
+ /* Move the reference point horizontally by given amount (usually +ve).
+ When the amount is small, like a kern, hh changes by rounding
+ the amount; but when the amount is large, hh changes by rounding
+ the true position h so that accumulated rounding errors disappear.
+ */
+
+ h += amount;
+
+ /* GT - Wrong? DVI Driver Standard specifies:
+ "if (processor uses TFM)
+ word_space = space - space_shrink;
+ else
+ quad = magnification * (design size of font);
+ word_space = 0.2 * quad;
+ fi;
+
+ back_space = 0.9 * quad;
+
+ if (amount < word_space && amount > -back_space)".
+
+ So, TFM -> space, space_shrink;
+ else -> design size.
+
+ Now, how do we learn those quantities?
+ */
+
+ if (amount < fontspace && amount > -fontspace * 4)
+ {
+ hh += XPixelRound (amount);
+
+ /* use hhh and max_drift to prevent hh drifting too far from h */
+
+ hhh = XPixelRound (h);
+ if (abs (hhh - hh) > max_drift)
+ {
+ /* Adjust hh to be just within the allowed tolerance from h. */
+ hh = hhh + (hhh > hh ? -max_drift : max_drift);
+ }
+ }
+ else
+ {
+ hh = XPixelRound (h);
+ }
+}
+/* DoRight */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoDown (int amount)
+{
+ /* Move the reference point vertically by given amount (usually +ve).
+ Rounding is done similarly to DoRight but with the threshold between
+ small and large amounts increased by a factor of 5.
+ */
+
+ v += amount;
+
+ /* GT - Wrong? DVI Driver Standard specifies:
+ "if (abs (y) < 0.8 * quad)".
+ */
+
+ if (abs (amount) < fontspace * 5)
+ {
+ vv += YPixelRound (amount);
+
+ /* use vvv and max_drift to prevent vv drifting too far from v */
+
+ vvv = YPixelRound (v);
+ if (abs (vvv - vv) > max_drift)
+ {
+ /* Adjust vv to be just within the allowed tolerance from v. */
+ vv = vvv + (vvv > vv ? -max_drift : max_drift);
+ }
+ }
+ else
+ {
+ vv = YPixelRound (v);
+ }
+}
+/* DoDown */
+
+/*--------------------------------------------------------------------*/
+
+static int
+RulePixels (double conv, int DVIunits)
+{
+ /* Return the number of pixels in the given height or width of a rule
+ using the method recommended in DVITYPE.
+ */
+
+ int n = (int) (conv * DVIunits);
+ if (n < conv * DVIunits)
+ return (n + 1);
+ else
+ return n;
+}
+/* RulePixels */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoPutSetRule (int height, int width, unsigned char DVIcommand)
+{
+ /* Exactly the same as DoSetRule, but we DON'T update the horizontal
+ position on the page. (We still have to check page edges.)
+ */
+ _REC_ruletable *ruletab;
+
+ if (height > 0 && width > 0)
+ {
+
+ /* may be new ruletable */
+ if (ruletail->rulecount == ruletablesize)
+ {
+ ruletail->nextrule = (ruleinfo *) Malloc (sizeof (ruleinfo));
+ /* add new node to end of rule list */
+ ruletail->nextrule->rulecount = 0; /* reset rulecount */
+ ruletail->nextrule->nextrule = (ruleinfo *) NULL;
+ ruletail = ruletail->nextrule;
+ }
+ /* allocate a new ruletable */
+ ruletab = &ruletail->ruletable[ruletail->rulecount];
+ ruletab->hp = hh;
+ ruletab->vp = vv;
+ ruletab->wd = RulePixels (xconv, width);
+ ruletab->ht = RulePixels (yconv, height);
+
+ /* do page edges increase? */
+
+ /* ref pt of rule is bottom left black pixel */
+
+ if (pageempty || hh < minhp)
+ minhp = hh;
+ if (pageempty || vv > maxvp)
+ maxvp = vv;
+
+ if (pageempty || hh + ruletab->wd - 1 > maxhp)
+ maxhp = hh + ruletab->wd - 1;
+ if (pageempty || vv - ruletab->ht + 1 < minvp)
+ minvp = vv - ruletab->ht + 1;
+
+ totalrules++;
+ ruletail->rulecount++;
+ pageempty = false;
+ }
+
+ if (DVIcommand == setrule)
+ {
+ hh += RulePixels (xconv, width);
+ h += width;
+
+ /* use hhh and max_drift to prevent hh drifting too far from h */
+
+ hhh = XPixelRound (h);
+
+ if (abs (hhh - hh) > max_drift)
+ {
+ /* Adjust hh to be just within the allowed tolerance from h. */
+ hh = hhh + (hhh > hh ? -max_drift : max_drift);
+ }
+ }
+} /* DoPutSetRule */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoFont (int externf)
+{
+ /* Search font list for externf, setting currfont and fontspace.
+ If this is the first time we've seen this font (on current page) then
+ we need to allocate the first chartable.
+ If this is the first time we've seen this font used at all then we
+ allocate a pixeltable and call routine to fill it in.
+ */
+
+ charinfo *char_info = (charinfo *) NULL;
+
+ currfont = fontlist;
+ while (currfont != (fontinfo *) NULL && currfont->fontnum != externf)
+ {
+ currfont = currfont->nextfont;
+ }
+
+ if (currfont == NULL)
+ FATAL1 ("Failed to find font #%d.", externf);
+ if (!currfont->fontused)
+ {
+ currfont->fontused = true;
+ currfont->charlist = (charinfo *) Malloc (sizeof (charinfo));
+ /* allocate first chartable */
+ char_info = currfont->charlist;
+ char_info->charcount = 0; /* for DoSet/PutChar */
+ char_info->nextchar = (charinfo *) NULL; /* this node is also last */
+ currfont->chartail = currfont->charlist;
+ if (currfont->pixelptr == (_REC_pixeltable *) NULL)
+ { /* first time we've seen this font */
+ currfont->pixelptr = (_REC_pixeltable *) Malloc (sizeof (pixeltable));
+ PixelTableRoutine (currfont);
+ }
+ }
+ /* do nothing since we've already used this font on this page */
+
+ fontspace = currfont->scaledsize / 6;
+
+ /* See DVITYPE; a 3-unit thin space.
+ Note that a thin space is 1/6 of a quad, where a quad is
+ 1 em in the current font and usually equals the design size.
+ */
+
+}
+/* DoFont */
+
+/*--------------------------------------------------------------------*/
+
+static void
+DoSpecial (int hpos, int vpos, int totalbytes)
+{
+ /* in */
+
+ /* DVIReader has seen a \special command while interpreting the current page.
+ It will pass the current page position and number of bytes in the command.
+ We save the info away in speciallist for later use by the main program.
+ */
+ int i;
+ specialinfo *temp;
+
+ temp = (specialinfo *) Malloc (sizeof (specialinfo));
+ for (i = 0; i < totalbytes; i++)
+ {
+ int temp1;
+ temp1 = GetDVIByte ();
+ if (i < maxspeciallen)
+ temp->special[i] = temp1;
+ }
+ temp->special[i <= maxspeciallen ? i : maxspeciallen] = '\0';
+
+ temp->hp = hpos;
+ temp->vp = vpos;
+ temp->nextspecial = speciallist;
+ speciallist = temp; /* add new info to head of list */
+}
+/* DoSpecial */
+
+/*--------------------------------------------------------------------*/
+
+void
+InterpretPage ()
+{
+ /* When this routine is called we are positioned after the bytes of a bop
+ command (i.e., at currbop + 45). At the end of this routine we will be
+ positioned after the eop byte for the current page. In between we carry
+ out the important task of translating the DVI description of this page
+ and filling in the following global data structures:
+
+ totalrules := number of rules on page
+ rulelist-> (nodes are added to tail of rule list)
+ rulecount := number of rules in this ruletable
+ ruletable[0..rulecount-1].
+ hp, vp := reference point of a rule
+ wd, ht := pixel dimensions of a rule (both > 0)
+ nextrule := next node in rule list (if not NIL)
+ ruletail := pointer to last node in rule list
+
+ speciallist-> (nodes are added to head of this list)
+ hp, vp := reference point on page
+ special := \special bytes
+ nextspecial := next node in list (if not NIL)
+
+ fontlist->
+ (the following fontinfo is relevant only if fontused is TRUE)
+ totalchars := number of chars on page from this font
+ charlist-> (nodes are added to tail of char list)
+ charcount := number of chars in this chartable
+ chartable[0..charcount-1].
+ hp, vp := reference point of a character
+ code := TeX character code (and index into pixel table)
+ nextchar := next node in char list (if not NIL)
+ chartail := pointer to last node in char list
+ pixelptr^[0..maxTeXchar].
+ (filled in by FontReader's PixelTableRoutine)
+ wd, ht := glyph width and height in pixels
+ xo, yo := offsets from the character's reference point
+ dwidth := advance width in DVI units
+ pwidth := advance width in pixels
+ mapadr := offset in fontspec of the glyph's bitmap info
+ bitmap := NIL
+ nextfont := next node in font list (if not NIL)
+
+ pageempty := TRUE iff the page has no rules and no characters
+ minhp, minvp, maxhp, maxvp
+ := the edges of the page (undefined if pageempty is TRUE)
+ They define the smallest rectangle containing all black
+ pixels on the page;(minhp,minvp) is the top left corner.
+
+ Reference points for rules and characters are stored as a pair of
+ horizontal and vertical pixel coordinates. The point (0,0) is assumed
+ to be the pixel 1 inch in from the top and left edges of an imaginary sheet
+ of paper. Horizontal coordinates increase to the right and vertical
+ coordinates increase down the paper.
+ The numbers of pixels per inch in the X and Y directions are defined by
+ the xres and yres resolution parameters given to SetConversionFactors.
+ */
+
+ int param = 0, ht, wd;
+
+ InitStateValues ();
+ InitPage ();
+ do
+ {
+ DVIcommand = GetDVIByte ();
+ /* For efficiency reasons the most frequent commands should be tested 1st.
+ The following order is the result of frequency testing on typical
+ DVI files. Note that the most frequent commands in the DVI file
+ generated by TeX 1.3 for the Dec. 1983 LaTeX manual were:
+ <set1, w0, right3, push/pop, x0, w3, y0, fntnum25, right2, fntnum31,
+ down3, x2, right4, w2, x3, down4, z0, fntnum8, setrule, y3, etc.
+ */
+ if (DVIcommand < set1) /* 0..127 */
+ DoSetPutChar (DVIcommand, true);
+ else if (DVIcommand == w0)
+ DoRight (w);
+ else if (DVIcommand == right3)
+ DoRight (SignedDVITrio ());
+ else if (DVIcommand == push)
+ DoPush ();
+ else if (DVIcommand == pop)
+ DoPop ();
+ else if (DVIcommand == x0)
+ DoRight (x);
+ else if (DVIcommand == w3)
+ {
+ w = SignedDVITrio ();
+ DoRight (w);
+ }
+ else if (DVIcommand == y0_)
+ DoDown (y);
+ else if (DVIcommand > z4 && DVIcommand < fnt1)
+ {
+ /* catch all the remaining movement commands */
+ DoFont (DVIcommand - fntnum0);
+ }
+ else if (DVIcommand > pop && DVIcommand < fntnum0)
+ {
+ if (DVIcommand == right2)
+ DoRight (SignedDVIPair ());
+ else if (DVIcommand == right4)
+ DoRight (SignedDVIQuad ());
+ else if (DVIcommand == x2)
+ {
+ x = SignedDVIPair ();
+ DoRight (x);
+ }
+ else if (DVIcommand == x3)
+ {
+ x = SignedDVITrio ();
+ DoRight (x);
+ }
+ else if (DVIcommand == down3)
+ DoDown (SignedDVITrio ());
+ else if (DVIcommand == down4)
+ DoDown (SignedDVIQuad ());
+ else if (DVIcommand == w2)
+ {
+ w = SignedDVIPair ();
+ DoRight (w);
+ }
+ else if (DVIcommand == z0)
+ DoDown (z);
+ else if (DVIcommand == y3)
+ {
+ y = SignedDVITrio ();
+ DoDown (y);
+ }
+ else if (DVIcommand == z3)
+ {
+ z = SignedDVITrio ();
+ DoDown (z);
+ }
+ else if (DVIcommand == down2)
+ {
+ /* the next DVI commands are used very rarely (by TeX 1.3 at least) */
+ DoDown (SignedDVIPair ());
+ }
+ else if (DVIcommand == w1)
+ {
+ w = SignedDVIByte ();
+ DoRight (w);
+ }
+ else if (DVIcommand == w4)
+ {
+ w = SignedDVIQuad ();
+ DoRight (w);
+ }
+ else if (DVIcommand == x1)
+ {
+ x = SignedDVIByte ();
+ DoRight (x);
+ }
+ else if (DVIcommand == x4)
+ {
+ x = SignedDVIQuad ();
+ DoRight (x);
+ }
+ else if (DVIcommand == y1_)
+ {
+ y = SignedDVIByte ();
+ DoDown (y);
+ }
+ else if (DVIcommand == y2)
+ {
+ y = SignedDVIPair ();
+ DoDown (y);
+ }
+ else if (DVIcommand == y4)
+ {
+ y = SignedDVIQuad ();
+ DoDown (y);
+ }
+ else if (DVIcommand == z1)
+ {
+ z = SignedDVIByte ();
+ DoDown (z);
+ }
+ else if (DVIcommand == z2)
+ {
+ z = SignedDVIPair ();
+ DoDown (z);
+ }
+ else if (DVIcommand == z4)
+ {
+ z = SignedDVIQuad ();
+ DoDown (z);
+ }
+ else if (DVIcommand == right1)
+ DoRight (SignedDVIByte ());
+ else if (DVIcommand == down1)
+ DoDown (SignedDVIByte ());
+ else
+ FATAL ("Bug in InterpretPage!");
+ }
+ else if (DVIcommand == setrule || DVIcommand == putrule)
+ {
+ ht = SignedDVIQuad ();
+ wd = SignedDVIQuad ();
+ DoPutSetRule (ht, wd, DVIcommand);
+ }
+ else if (DVIcommand >= put1 && DVIcommand <= put1 + 3)
+ {
+ switch (DVIcommand - put1)
+ {
+ case 0:
+ DoSetPutChar (GetDVIByte (), false);
+ break;
+ case 1:
+ DoSetPutChar (GetTwoDVIBytes (), false);
+ break;
+ case 2:
+ DoSetPutChar (GetThreeDVIBytes (), false);
+ break;
+ case 3:
+ DoSetPutChar (SignedDVIQuad (), false);
+ break;
+ }
+
+ }
+ else if (DVIcommand >= set1 && DVIcommand <= set1 + 3)
+ {
+ switch (DVIcommand - set1)
+ {
+ case 0:
+ DoSetPutChar (GetDVIByte (), true);
+ break;
+ case 1:
+ DoSetPutChar (GetTwoDVIBytes (), true);
+ break;
+ case 2:
+ DoSetPutChar (GetThreeDVIBytes (), true);
+ break;
+ case 3:
+ DoSetPutChar (SignedDVIQuad (), true);
+ break;
+ }
+
+ }
+ else if (DVIcommand >= fnt1 && DVIcommand <= fnt1 + 3)
+ {
+ switch (DVIcommand - fnt1)
+ {
+ case 0:
+ DoFont (GetDVIByte ());
+ break;
+ case 1:
+ DoFont (GetTwoDVIBytes ());
+ break;
+ case 2:
+ DoFont (GetThreeDVIBytes ());
+ break;
+ case 3:
+ DoFont (SignedDVIQuad ());
+ break;
+ }
+
+ }
+ else if (DVIcommand >= xxx1 && DVIcommand <= xxx1 + 3)
+ {
+ switch (DVIcommand - xxx1)
+ {
+ case 0:
+ param = GetDVIByte ();
+ break;
+ case 1:
+ param = GetTwoDVIBytes ();
+ break;
+ case 2:
+ param = GetThreeDVIBytes ();
+ break;
+ case 3:
+ param = SignedDVIQuad ();
+ break;
+ }
+ /* pass current pixel position and number of bytes */
+ DoSpecial (hh, vv, param);
+ }
+ else if (DVIcommand >= fntdef1 && DVIcommand <= fntdef1 + 3)
+ SkipFntdef (DVIcommand - fntdef1);
+ else if (DVIcommand != nop)
+ {
+ if (DVIcommand != eop) /* do nothing */
+ FATAL1 ("Unexpected DVI command while interpreting page = %d.",
+ DVIcommand);
+ }
+ }
+ while (DVIcommand != eop);
+
+ /* save position of eop byte for use in MoveToTeXPage */
+ curreop = DVIoffset - 1;
+
+ if (stackpos != 0)
+ FATAL ("Stack not empty at eop!");
+ /* InitPage values */
+
+
+ /* fntnum0..fntnum63 */
+
+
+ /* skip fntdef command since we've got this info from postamble */
+
+ /* do nothing */
+}
+/* InterpretPage */
+
+/*--------------------------------------------------------------------*/
+
+void
+SortFonts (fontinfo ** unusedlist)
+{
+ /* out */
+
+ /* Sort fontlist in order of ascending totalchars.
+ Fonts with least characters can then be accessed first.
+ Since the number of fonts used on a typical page is quite small, a simple
+ sorting algorithm should be good enough. Note that unused fonts are moved
+ to the end of the list and unusedlist points to the first such node.
+ DVItoVDU need only process fonts up to (but excluding) unusedlist
+ and does not have to worry about checking the fontused flag.
+ If unusedlist is NIL then either 1) all fonts are used on the current page
+ or 2) fontlist is also NIL (totalfonts = 0).
+ */
+ fontinfo *newfontlist, *prevfont, *largest, *prevlargest;
+ int mostchars;
+
+ newfontlist = (fontinfo *) NULL;
+ /* go thru fontlist once and move all unused fonts to head of newfontlist */
+ prevfont = (fontinfo *) NULL;
+ currfont = fontlist;
+ while (currfont != (fontinfo *) NULL)
+ {
+ if (currfont->fontused)
+ {
+ prevfont = currfont; /* remember previous node */
+ currfont = currfont->nextfont;
+ continue;
+ }
+ /* move node from fontlist to head of newfontlist
+ and don't change prevfont
+ */
+ if (prevfont == (fontinfo *) NULL)
+ {
+ fontlist = currfont->nextfont; /* remove first node in fontlist */
+ currfont->nextfont = newfontlist;
+ newfontlist = currfont;
+ currfont = fontlist;
+ }
+ else
+ {
+ prevfont->nextfont = currfont->nextfont;
+ currfont->nextfont = newfontlist;
+ newfontlist = currfont;
+ currfont = prevfont->nextfont;
+ }
+ }
+
+ /* unusedlist will be last unused font moved to newfontlist. It will be NIL
+ if either fontlist is NIL or all fonts are used.
+ */
+
+ *unusedlist = newfontlist;
+
+ /* Now go thru fontlist repeatedly moving node with max totalchars to
+ head of newfontlist until fontlist is exhausted.
+ */
+
+ while (fontlist != (fontinfo *) NULL)
+ {
+ prevfont = (fontinfo *) NULL;
+ currfont = fontlist;
+ prevlargest = (fontinfo *) NULL;
+ largest = fontlist;
+ mostchars = 0;
+
+ /* search for largest totalchars */
+ while (currfont != (fontinfo *) NULL)
+ {
+ if (currfont->totalchars > mostchars)
+ {
+ prevlargest = prevfont;
+ largest = currfont;
+ mostchars = currfont->totalchars;
+ }
+ prevfont = currfont;
+ currfont = currfont->nextfont;
+ }
+ /* move largest node from fontlist to head of newfontlist */
+ if (prevlargest == (fontinfo *) NULL)
+ fontlist = largest->nextfont; /* remove first node in fontlist */
+ else
+ prevlargest->nextfont = largest->nextfont;
+ largest->nextfont = newfontlist;
+ newfontlist = largest;
+ }
+ fontlist = newfontlist;
+ /* used fonts now sorted and unused fonts at end */
+}
+/* SortFonts */
+
+/*--------------------------------------------------------------------*/
+
+void
+CloseDVIFile ()
+{
+ /* Close the currently open DVI file,
+ and deallocate dynamic data structures. */
+
+ int result;
+
+ result = close (DVIfile);
+ while (fontlist != (fontinfo *) NULL)
+ {
+ currfont = fontlist;
+ while (currfont->charlist != (charinfo *) NULL)
+ {
+ charinfo *thischar; /* temporary pointer to node in charlist */
+ thischar = currfont->charlist;
+ currfont->charlist = thischar->nextchar;
+ Free (thischar, charinfo); /* deallocate char list */
+ }
+ if (currfont->pixelptr != (_REC_pixeltable *) NULL)
+ Free (currfont->pixelptr, _REC_pixeltable); /* deallocate pixel table */
+ fontlist = currfont->nextfont;
+ Free (currfont, fontinfo); /* deallocate font information */
+ }
+ /* Deallocate rule information except for one node
+ (in case DVItoVDU ever opens another DVI file).
+ */
+ while (rulelist != ruletail)
+ {
+ ruleinfo *thisrule; /* temporary pointer to node in rulelist */
+ thisrule = rulelist;
+ rulelist = thisrule->nextrule;
+ Free (thisrule, ruleinfo);
+ }
+ while (speciallist != (specialinfo *) NULL)
+ {
+ specialinfo *thisspecial; /* temporary ptr to node in speciallist */
+ thisspecial = speciallist;
+ speciallist = speciallist->nextspecial;
+ Free (thisspecial, specialinfo);
+ }
+}
+/* CloseDVIFile */
+
+/*--------------------------------------------------------------------*/
+
+void
+InitDVIReader ()
+{
+ totalrules = 0;
+ rulelist = (ruleinfo *) Malloc (sizeof (ruleinfo)); /* for first InitPage */
+ ruletail = rulelist; /* ditto */
+ speciallist = (specialinfo *) NULL; /* ditto */
+ fontlist = (fontinfo *) NULL; /* safer for CloseDVIFile */
+}
+/* InitDVIReader */
+
+/*--------------------------------------------------------------------*/
+
+/* end dvireader.c */
diff --git a/dviware/dvgtk/dvireader.h b/dviware/dvgtk/dvireader.h
new file mode 100644
index 0000000000..15780dd17a
--- /dev/null
+++ b/dviware/dvgtk/dvireader.h
@@ -0,0 +1,171 @@
+/* dvireader.h - functions for reading DVI files
+ $Id: dvireader.h,v 0.2 1997/03/28 03:16:45 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __DVIREADER_H__
+#define __DVIREADER_H__
+
+#include "dvgt.h"
+
+#define ruletablesize 300 /* maximum number of rules in a ruletable */
+#define chartablesize 3000 /* maximum number of chars in a chartable */
+#define maxfontspec maxstring
+ /* max length of a font file specification */
+#define maxspeciallen maxstring
+ /* maximum length of \special string */
+#define maxTeXchar 255 /* ignore character codes > 255 */
+
+typedef struct _REC_ruletable
+ {
+ int hp, vp; /* pixel coords of rule's ref point */
+ int wd, ht; /* dimensions of rule in pixels */
+ }
+_REC_ruletable;
+
+typedef struct _REC_chartable
+ {
+ int hp, vp; /* pixel coords of char's ref point */
+ unsigned char code; /* char's code and pixeltable index */
+ }
+_REC_chartable;
+
+typedef struct _REC_pixeltable
+ {
+ int wd, ht;
+ /* glyph width and height in pixels; they
+ define the size of the smallest box
+ containing all the black pixels */
+ int xo, yo;
+ /* x and y offsets from top left corner
+ of glyph to character's reference point */
+ int dwidth;
+ /* advance width in DVI units computed from
+ fix width stored in font file */
+ int pwidth;
+ /* advance width in pixels computed from
+ fix width stored in font file */
+ int mapadr; /* byte offset of bitmap info in font file */
+ int_or_mptr bitmap; /* SYSDEP: starting address of bitmap */
+ }
+_REC_pixeltable;
+
+/* Information about the rules and characters appearing on a page is stored
+ in dynamic one-way lists to avoid imposing any limit on their numbers.
+ To reduce pointer overheads, the nodes in these lists contain large
+ tables (the values of ruletablesize and chartablesize have been chosen
+ so that the vast majority of DVI pages will only require one-node lists).
+ When interpreting a DVI page, DVIReader adds a new rule or character node
+ to the TAIL of the relevant list. This is done so that when DVItoVDU
+ accesses such lists (starting at the head), rules and characters will be
+ processed in somewhat the same sequence as seen in the DVI file; i.e.,
+ top-to-bottom and left-to-right across the page.
+ Since a character list is part of the information stored for a font,
+ the precise sequence in which DVI characters are seen is not remembered.
+ Font information is also linked together in a one-way list, but the
+ ordering is more or less random (see, however, the SortFonts routine).
+ */
+
+typedef struct ruleinfo
+ {
+ int rulecount; /* number of rules in ruletable */
+ _REC_ruletable ruletable[ruletablesize];
+ struct ruleinfo *nextrule; /* next node in rule list */
+ }
+ruleinfo; /* a node in a list of ruletables */
+
+typedef struct charinfo
+ {
+ int charcount; /* number of chars in chartable */
+ _REC_chartable chartable[chartablesize];
+ struct charinfo *nextchar; /* next node in char list */
+ }
+charinfo; /* a node in list of chartables */
+
+/* DVIReader uses wd, ht, xo and yo to calculate minhp, minvp, maxhp and
+ maxvp. dwidth and pwidth are used to advance horizontally.
+ The mapadr and bitmap fields are not used by DVIReader; they are used
+ by FontReader and the main program to load character bitmaps.
+ */
+typedef _REC_pixeltable pixeltable[maxTeXchar + 1];
+
+typedef struct fontinfo
+ {
+ boolean pkfont; /* is this a PK bitmap font? */
+ boolean fontused; /* is font used on current page? */
+ int fontnum; /* DVI font number: -2^31 .. 2^30 - 1 */
+ int scaledsize; /* scaled font size in DVI units */
+ int designsize; /* design size in DVI units */
+ String fontarea; /* explicit font directory */
+ int fontarealen; /* length of fontarea */
+ String fontname; /* font name; e.g., "cmr10" */
+ int fontnamelen; /* length of font name */
+ String fontspec; /* complete font file pathname */
+ int fontspeclen; /* length of fontspec */
+ boolean fontexists; /* can fontspec be opened? */
+ boolean honest; /* true (and not substitute) font */
+ int totalchars; /* number of chars from font on page */
+ charinfo *charlist; /* head of char information list */
+ charinfo *chartail; /* tail of char information list */
+ _REC_pixeltable *pixelptr; /* allocated once: 1st time font used */
+ struct fontinfo *nextfont; /* next node in font list */
+ }
+fontinfo; /* a node in list of fonts */
+
+/* For the parameter in MoveToTeXPage: */
+typedef int TeXcounters[10];
+
+typedef struct TeXpageinfo
+ {
+ TeXcounters value; /* \count0..\count9 values */
+ boolean present[10]; /* is counter relevant? */
+ char lastvalue; /* last relevant counter */
+ }
+TeXpageinfo;
+
+/* DVIReader also builds a list of \special info: */
+
+typedef struct specialinfo
+ {
+ String special;
+ int hp, vp;
+ struct specialinfo *nextspecial;
+ }
+specialinfo;
+
+
+/* Most of these should be treated as read-only parameters: */
+extern int DVImag; /* magnification stored in DVI file */
+extern int totalpages; /* number of pages in DVI file */
+extern int totalfonts; /* number of fonts in DVI file */
+extern int currDVIpage; /* updated by MoveTo... calls */
+extern TeXcounters currTeXpage;
+ /* ditto */
+extern int totalrules; /* number of rules on current page */
+extern ruleinfo *rulelist; /* head of rule information list */
+extern ruleinfo *ruletail; /* tail of rule information list */
+extern specialinfo *speciallist;
+ /* head of \special information list */
+extern fontinfo *fontlist; /* head of font information list */
+extern fontinfo *currfont; /* InterpretPage's current font info */
+extern boolean pageempty; /* is page empty of rules and chars? */
+extern int minhp; /* minimum horizontal pixel coordinate */
+extern int minvp; /* minimum vertical pixel coordinate */
+extern int maxhp; /* maximum horizontal pixel coordinate */
+extern int maxvp; /* maximum vertical pixel coordinate */
+
+extern void InitDVIReader ();
+extern void OpenDVIFile PARAMS ((char *name));
+extern void SetConversionFactors PARAMS ((double xres, double yres, double magnification));
+extern void MoveToDVIPage PARAMS ((int n));
+extern void MoveToNextPage PARAMS ((boolean ascending));
+extern boolean MoveToTeXPage PARAMS ((TeXpageinfo * newTeXpage));
+extern int XPixelRound PARAMS ((int DVIunits));
+extern int YPixelRound PARAMS ((int DVIunits));
+extern void InterpretPage ();
+extern void SortFonts PARAMS ((fontinfo ** unusedlist));
+extern void CloseDVIFile ();
+
+#endif /* __DVIREADER_H__ */
+
+/* end dvireader.h */
diff --git a/dviware/dvgtk/etc/dv-env b/dviware/dvgtk/etc/dv-env
new file mode 100644
index 0000000000..2daced5ddb
--- /dev/null
+++ b/dviware/dvgtk/etc/dv-env
@@ -0,0 +1,25 @@
+# dv-env - 20:31 GMT +10:00 Sun 30 May 1993 - Geoffrey Tobin.
+# A sample C shell script for setting environment variables for the
+# dvgt 3.5 TeX previewer.
+
+# 1. Environment variables peculiar to dvitovdu.
+
+# PK font of last resort; assumed in usual font directory:
+setenv DV_DUMMY_PK cmr10.300pk
+# TFM metric of last resort; assumed in usual tfm directory:
+setenv DV_DUMMY_TFM cmr10.tfm
+# PS font prefix; Karl Berry's convention:
+setenv DV_PS_PREFIX p
+# Locations of help texts.
+setenv DV_HELP /usr/local/lib/tex/dv/help
+setenv DV_IMMED_HELP /usr/local/lib/tex/dv/immed.hlp
+# Video driver.
+setenv DV_TERM ncsatel
+
+# 2. Modify PKFONTS and TEXFONTS with care,
+# because other TeX programs use them!
+
+# PKFONTS lists directories where PK bitmap fonts live.
+setenv PKFONTS .:/usr/local/lib/tex/fonts/qume/
+# TEXFONTS lists directories where TFM metric files live.
+setenv TEXFONTS .:/usr/local/lib/tex/fonts/
diff --git a/dviware/dvgtk/etc/sane b/dviware/dvgtk/etc/sane
new file mode 100644
index 0000000000..fd766d1796
--- /dev/null
+++ b/dviware/dvgtk/etc/sane
@@ -0,0 +1,9 @@
+#!/bin/sh
+# sane
+# Complete, sane stty settings, for NCSA Telnet connection.
+
+stty sane
+stty 38400 # the baud rate is important: modify to suit
+stty -parenb cs8 -istrip tab3
+
+# end sane
diff --git a/dviware/dvgtk/fontreader.c b/dviware/dvgtk/fontreader.c
new file mode 100644
index 0000000000..3976e00281
--- /dev/null
+++ b/dviware/dvgtk/fontreader.c
@@ -0,0 +1,1079 @@
+/* fontreader.c - functions for reading PK fonts
+ $Id: fontreader.c,v 0.2 1997/03/28 03:16:59 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include <kpathsea/tex-file.h>
+#include <kpathsea/tex-glyph.h>
+
+#include "screenio.h"
+#include "vdu.h"
+#include "options.h"
+#include "dvireader.h"
+#include "fontreader.h"
+
+typedef struct _REC_TFMinfo
+ {
+ int wdindex, htindex, dpindex;
+ }
+_REC_TFMinfo;
+
+typedef struct _REC_charmetrics
+ {
+ int width[4], height[4], depth[4];
+ }
+_REC_charmetrics;
+
+
+static int PTfile; /* PK/TFM file descriptor */
+static int PToffset; /* current byte offset in PTfile */
+static int currPTbuff; /* starting byte offset in buffer */
+static buffer PTbuffer; /* input buffer */
+static int gpower[33]; /* 0,1,11,111,1111,... */
+static boolean turnon; /* is current run black? */
+static int dynf; /* dynamic packing variable */
+static int repeatcount; /* times to repeat the next row */
+static int bitweight; /* for bits or nybbles from inputbyte */
+static int inputbyte; /* the current input byte */
+static int lf, lh, bc, ec, nw, nh; /* TFM file data; lf unused */
+static _REC_TFMinfo TFMinfo[maxTeXchar + 1];
+static _REC_charmetrics charmetrics[maxTeXchar + 1];
+
+/*--------------------------------------------------------------------*/
+boolean
+CheckFontPtr (fontinfo * fontptr)
+{
+ boolean check = false;
+ if (fontptr == (fontinfo *) NULL)
+ {
+ MesgString ("NULL font info passed to CheckFontPtr!");
+ MesgLine ();
+ check = false;
+ }
+ else if (fontptr->fontnamelen == 0)
+ {
+ MesgString ("Zero length font name in font info passed to CheckFontPtr!");
+ MesgLine ();
+ check = false;
+ }
+ else if (!strcmp (fontptr->fontname, ""))
+ {
+ MesgString ("Empty font name in font info passed to CheckFontPtr!");
+ MesgLine ();
+ check = false;
+ }
+ else
+ {
+ check = true;
+ }
+ return check;
+}
+/* CheckFontPtr */
+
+/*--------------------------------------------------------------------*/
+
+boolean
+BuildFontSpec (fontinfo * fontptr)
+{
+ /* Build a complete PK or TFM font file specification in fontptr->fontspec.
+ (May end up with a dummy PK font's or TFM metric's file spec.
+ ShowStatistics() in "dvitovdu.c" will show any font substitutions.)
+ This will be done at most once per font.
+ Test for valid fontptr->fontname.
+ ASSUMPTIONS:
+ fontptr->fontname contains the basename of the font.
+ SIDE EFFECTS on success:
+ fontptr->fontspec will be set.
+ fontptr->fontspeclen will no longer be 0.
+ fontptr->fontexists becomes TRUE if the real or dummy PK or TFM
+ file can be opened, FALSE, otherwise.
+ fontptr->pkfont becomes TRUE if the real or dummy PK file
+ can be opened, FALSE, otherwise.
+ fontptr->honest becomes TRUE if the true font is used, FALSE otherwise.
+ SIDE EFFECTS on failure:
+ EITHER:
+ fontptr is NULL.
+ OR:
+ fontptr->fontspec will be unset (holds empty string "").
+ fontptr->fontspeclen will be 0.
+ fontptr->fontexists becomes FALSE.
+ fontptr->pkfont becomes FALSE.
+ fontptr->honest becomes FALSE.
+ */
+
+ kpse_glyph_file_type font_ret;
+ string name;
+ unsigned dpi;
+
+ if (!CheckFontPtr (fontptr))
+ return false;
+
+ /* Initialise correctly */
+ strncpy (fontptr->fontspec, "", maxfontspec);
+ fontptr->fontspeclen = 0;
+ fontptr->fontexists = false;
+ fontptr->pkfont = false;
+ fontptr->honest = false;
+
+#if 0
+ dpi = kpse_magstep_fix ((unsigned) (mag / 5.0 + .5),
+ xres, NULL);
+ tfontptr->font_mag = dpi * 5; /* save correct dpi */
+#endif
+ dpi = (int) (mag / 1000.0 *
+ (double) fontptr->scaledsize / fontptr->designsize * xres + 0.5);
+
+ if (dpi == 0) /* allow for subtracting 1 */
+ ++dpi;
+
+ name = kpse_find_pk (fontptr->fontname, dpi, &font_ret);
+ if (name)
+ {
+ if (!STREQ (fontptr->fontname, font_ret.name))
+ {
+#if 0
+ WARNING3 ("dvgt: Font %s not found, using %s at %d instead.\n",
+ fontptr->fontname, font_ret.name, font_ret.dpi);
+#endif
+ }
+ else if (!kpse_bitmap_tolerance ((double) font_ret.dpi, (double) dpi))
+ {
+#if 0
+ WARNING3 ("dvilj: Font %s at %d not found, using %d instead.\n",
+ fontptr->fontname, dpi, font_ret.dpi);
+#endif
+ }
+ else
+ fontptr->honest = true;
+
+ fontptr->fontspeclen = strlen (name);
+ strcpy (fontptr->fontspec, name);
+ free (name);
+ fontptr->fontexists = true; /* specified PK file exists */
+ fontptr->pkfont = true;
+
+ return true;
+ }
+ else
+ {
+ /* PK font file doesn't exist. */
+ name = kpse_find_tfm (fontptr->fontname);
+ if (name)
+ {
+ fontptr->fontspeclen = strlen (name);
+ strcpy (fontptr->fontspec, name);
+ free (name);
+
+ fontptr->fontexists = true;
+ fontptr->honest = true;
+ }
+ else
+ {
+ name = kpse_find_tfm (dummy_tfm);
+ if (name)
+ {
+ fontptr->fontspeclen = strlen (name);
+ strcpy (fontptr->fontspec, name);
+ free (name);
+ fontptr->fontexists = true;
+ }
+ }
+ }
+
+ return true;
+}
+/* BuildFontSpec */
+
+/*--------------------------------------------------------------------*/
+
+boolean
+OpenFontFile (char *name)
+{
+ /* Return TRUE if given file can be (unix-specifically) open-ed.
+ Only one font file will be open at any given time.
+ */
+
+ extern int currPTbuff;
+ extern int PTfile;
+
+ currPTbuff = -1; /* impossible value for first GetPTByte */
+ PTfile = open (name, O_RDONLY, 0); /* unix "open" returns -1 if fails */
+ return (PTfile >= 0);
+}
+/* OpenFontFile */
+
+/*--------------------------------------------------------------------*/
+
+void
+CloseFontFile ()
+{
+ /* If there is a currently open font file, then close it. */
+
+ if (PTfile >= 0)
+ {
+ close (PTfile);
+ /* Be cautious: ensure PTfile is negative, after this function. */
+ if (PTfile >= 0)
+ PTfile = -1;
+ }
+}
+/* CloseFontFile */
+
+/*--------------------------------------------------------------------*/
+
+static int
+GetPTByte ()
+{
+ /* Returns the value (unsigned) of the byte at PToffset and
+ advances PToffset for the next GetPTByte.
+ */
+
+ int Result, buffstart, result;
+
+ buffstart = PToffset / bufflen * bufflen; /* 0, bufflen, 2*bufflen... */
+ if (buffstart != currPTbuff)
+ {
+ currPTbuff = buffstart;
+
+ if (PTfile < 0)
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL ("PTfile not open in GetPTByte!");
+ }
+ result = lseek (PTfile, buffstart, 0);
+ if (result != buffstart)
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL ("lseek failed in GetPTByte!");
+ }
+ result = read (PTfile, PTbuffer, bufflen);
+ if (result == -1)
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL ("Read failed in GetPTByte!");
+ }
+ }
+ Result = PTbuffer[PToffset - buffstart];
+ PToffset++;
+ return Result;
+}
+/* GetPTByte */
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedPTByte ()
+{
+ /* the next byte, signed */
+ int b;
+
+ b = GetPTByte ();
+ if (b < 128)
+ return b;
+ else
+ return (b - 256);
+}
+/* SignedPTByte */
+
+/*--------------------------------------------------------------------*/
+
+static int
+GetTwoPTBytes ()
+{
+ /* the next 2 bytes, unsigned */
+ int a, b;
+
+ a = GetPTByte ();
+ b = GetPTByte ();
+ return (a * 256 + b);
+}
+/* GetTwoPTBytes */
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedPTPair ()
+{
+ /* the next 2 bytes, signed */
+ int a, b;
+
+ a = GetPTByte ();
+ b = GetPTByte ();
+ if (a < 128)
+ return (a * 256 + b);
+ else
+ return ((a - 256) * 256 + b);
+}
+/* SignedPTPair */
+
+/*--------------------------------------------------------------------*/
+
+/* UNUSED: */
+#ifdef GET_THREE_PT_BYTES
+static int
+GetThreePTBytes ()
+{
+ /* the next 3 bytes, unsigned */
+ int a, b, c;
+
+ a = GetPTByte ();
+ b = GetPTByte ();
+ c = GetPTByte ();
+ return ((a * 256 + b) * 256 + c);
+}
+/* GetThreePTBytes */
+#endif /* GET_THREE_PT_BYTES */
+
+/*--------------------------------------------------------------------*/
+
+typedef struct int_or_bytes
+{
+ boolean b;
+ union
+ {
+ int int_;
+ char byt[4];
+ }
+ UU;
+}
+int_or_bytes;
+
+/*--------------------------------------------------------------------*/
+
+static int
+SignedPTQuad ()
+{
+ /* the next 4 bytes, signed */
+ int w;
+
+ byte3 (w) = GetPTByte ();
+ byte2 (w) = GetPTByte ();
+ byte1 (w) = GetPTByte ();
+ byte0 (w) = GetPTByte ();
+ return (w);
+}
+/* SignedPTQuad */
+
+/*--------------------------------------------------------------------*/
+
+static int
+GetNyb ()
+{
+ /* Return next nybble in PK file. */
+
+ if (bitweight == 0)
+ {
+ inputbyte = GetPTByte ();
+ bitweight = 16; /* for next call of GetNyb */
+ return (inputbyte / 16); /* high nybble */
+ }
+ else
+ {
+ bitweight = 0; /* for next call of GetNyb */
+ return (inputbyte & 15); /* low nybble */
+ }
+}
+/* GetNyb */
+
+/*--------------------------------------------------------------------*/
+
+static int
+PackedNum ()
+{
+ /* Return next run count using algorithm given in section 23 of PKtype.
+ A possible side-effect is to set the global repeatcount value used
+ to duplicate the current row.
+ */
+
+ int i, j;
+
+ i = GetNyb ();
+ if (i == 0)
+ {
+ do
+ {
+ j = GetNyb ();
+ i++;
+ }
+ while (j == 0);
+ while (i > 0)
+ {
+ j = j * 16 + GetNyb ();
+ i--;
+ }
+ return (j + (13 - dynf) * 16 + dynf - 15);
+ }
+ else if (i <= dynf)
+ return i;
+ else if (i < 14)
+ return ((i - dynf - 1) * 16 + GetNyb () + dynf + 1);
+ else
+ {
+ if (i == 14) /* nybble = 15 */
+ repeatcount = PackedNum (); /* recursive */
+ else
+ repeatcount = 1;
+ return (PackedNum ()); /* recursive */
+ }
+}
+/* PackedNum */
+
+/*--------------------------------------------------------------------*/
+
+boolean
+GetBitmap (int ht, int wd, int mapadr, int_or_mptr * bitmap)
+{
+ /* Allocate space for bitmap and fill it in using information from
+ character definition starting at mapadr in currently open PK
+ file. Note that the memory used by a loaded bitmap is never
+ deallocated. Each bitmap row uses an integral number of words
+ (each 32 bits). Byte-aligned rows would use about 35% less
+ memory but would increase the processing time needed to display
+ each bitmap. It was felt that speed is more important than
+ memory. Return true if the bitmap is obtained, false if function
+ fails.
+ */
+
+ extern int bitweight; /* local to "fontreader.c" */
+
+ int_or_bptr wordptr, rowptr;
+ int i, j, flagbyte, wordwidth, wordweight, rowsleft, hbit, count, bitmapwords;
+ int word;
+ Word *bitmapptr = (Word *) NULL;
+
+ wordwidth = (wd + 31) / 32; /* words in one row of bitmap */
+ bitmapwords = ht * wordwidth; /* memory required by bitmap */
+
+ bitmapptr = (Word *) calloc (bitmapwords, sizeof (Word));
+ if (bitmapptr == (Word *) NULL)
+ {
+ StartText ();
+ ResetVDU (); /* do before message since it might erase screen! */
+ FATAL1 ("Out of memory. Character too big! size = %d", bitmapwords);
+ return false; /* Not Reached */
+ }
+ bitmap->UU.mptr = bitmapptr; /* return start of bitmap */
+ wordptr.UU.int_ = bitmap->UU.int_;
+ PToffset = mapadr; /* mapadr = flagbyte offset in PK file */
+
+ flagbyte = GetPTByte (); /* assume < 240 */
+ dynf = flagbyte / 16; /* dynamic packing variable */
+ turnon = ((flagbyte & 15) >= 8); /* is 1st pixel black? */
+ flagbyte &= 7; /* value of bottom 3 bits */
+ if (flagbyte < 4) /* skip short char preamble */
+ PToffset += 10;
+ else if (flagbyte < 7)
+ PToffset += 16;
+ else
+ PToffset += 36;
+
+ bitweight = 0; /* to get 1st inputbyte */
+ if (dynf == 14)
+ {
+ /* raster info is a string of bits in the next (wd * ht + 7) DIV 8 bytes */
+
+ for (i = 1; i <= ht; i++)
+ {
+ word = 0; /* set all bits to 0 */
+ wordweight = 31; /* leftmost bit */
+ for (j = 1; j <= wd; j++)
+ {
+ if (bitweight == 0)
+ {
+ inputbyte = GetPTByte ();
+ bitweight = 8;
+ }
+ bitweight--; /* 7..0 */
+ if ((unsigned) bitweight < 32 && ((1 << bitweight) & inputbyte))
+ /* set bit */
+ word |= 1 << wordweight;
+ if (wordweight > 0)
+ wordweight--;
+ else
+ {
+ *wordptr.UU.bptr = word;
+ wordptr.UU.int_ += 4;
+ word = 0;
+ wordweight = 31;
+ }
+ }
+ if (wordweight < 31)
+ {
+ *wordptr.UU.bptr = word;
+ wordptr.UU.int_ += 4; /* start of next word */
+ }
+ }
+ }
+ else
+ {
+ /* raster info is encoded as run and repeat counts */
+
+ rowsleft = ht;
+ hbit = wd;
+ repeatcount = 0;
+ wordweight = 32;
+ word = 0;
+ rowptr = wordptr; /* remember start of row */
+ while (rowsleft > 0)
+ {
+ count = PackedNum ();
+ while (count > 0)
+ {
+ if (count < wordweight && count < hbit)
+ {
+ if (turnon)
+ word = (word | gpower[wordweight]) & (~gpower[wordweight - count]);
+ hbit -= count;
+ wordweight -= count;
+ count = 0;
+ continue;
+ }
+ if (count >= hbit && hbit <= wordweight)
+ {
+ if (turnon)
+ word = (word | gpower[wordweight]) & (~gpower[wordweight - hbit]);
+ *wordptr.UU.bptr = word;
+ /* end of current row, so duplicate repeatcount times */
+ for (i = 1; i <= repeatcount; i++)
+ {
+ for (j = 1; j <= wordwidth; j++)
+ {
+ wordptr.UU.int_ += 4;
+ *wordptr.UU.bptr = *rowptr.UU.bptr;
+ rowptr.UU.int_ += 4;
+ }
+ }
+ rowsleft += -repeatcount - 1;
+ repeatcount = 0;
+ word = 0;
+ wordptr.UU.int_ += 4;
+ rowptr = wordptr; /* remember start of next row */
+ wordweight = 32;
+ count -= hbit;
+ hbit = wd;
+ }
+ else
+ {
+ if (turnon)
+ word |= gpower[wordweight];
+ *wordptr.UU.bptr = word;
+ wordptr.UU.int_ += 4;
+ word = 0;
+ count -= wordweight;
+ hbit -= wordweight;
+ wordweight = 32;
+ }
+ }
+ turnon = !turnon;
+ }
+ }
+ return true;
+}
+/* GetBitmap */
+
+/*--------------------------------------------------------------------*/
+
+static int
+FixToDVI (int scale, int b0, int b1, int b2, int b3)
+/* scale = currfont->scaledsize; */
+/* fix width: 4 bytes */
+{
+ /* Convert the given fix width (made up of 4 bytes) into DVI units
+ using the method recommended in DVITYPE.
+ Added local scale to avoid changing scaledsize; thanks to Niel Kempson
+ for reporting this bug.
+ */
+
+ int dviwidth = 0;
+ int alpha, beta, temp;
+
+ alpha = scale * 16;
+ beta = 16;
+ while (scale >= 0x800000)
+ { /* 2^23sp = 128pt */
+ scale /= 2;
+ beta /= 2;
+ }
+ temp = ((b3 * scale / 0x100 + b2 * scale) / 0x100 + b1 * scale) / beta;
+
+ if (b0 <= 0)
+ dviwidth = temp;
+ else if (b0 == 255)
+ dviwidth = (temp - alpha);
+ else
+ {
+ dviwidth = 0; /* keep compiler happy, if necessary */
+
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL1 ("Bad TFM width! 1st byte = %d.", b0);
+ }
+
+ return dviwidth;
+}
+/* FixToDVI */
+
+/*--------------------------------------------------------------------*/
+
+#define pkid 89
+#define pkpost 245
+#define pknoop 246
+#define pkpre 247
+
+static void
+PKFillPixelTable (fontinfo * currfont)
+{
+ /* Fill the pixeltable for currfont^ using the font directory info
+ in the currently open PK file.
+ */
+
+ int i, j, flagbyte, flagpos;
+ int chcode; /* char. code, assumed to be <= maxTeXchar */
+ int packetlen, endofpacket, b0, b1, b2, b3; /* 4 bytes in TFM width */
+ _REC_pixeltable *pix_tab;
+
+ PToffset = 0; /* move to first byte */
+
+ if (GetPTByte () != pkpre)
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL1 ("Bad PK pre command in `%s'.", currfont->fontspec);
+ }
+ if (GetPTByte () != pkid)
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL1 ("Bad PK id byte in `%s'.", currfont->fontspec);
+ }
+ j = GetPTByte (); /* length of comment */
+ PToffset += j + 16; /* skip rest of preamble */
+
+ for (i = 0; i <= maxTeXchar; i++)
+ {
+ pix_tab = &currfont->pixelptr[i];
+ pix_tab->mapadr = 0; /* all chars absent initially */
+ pix_tab->bitmap.UU.mptr = (Word *) NULL;
+ }
+
+ while (true)
+ {
+ flagpos = PToffset; /* remember position of flagbyte */
+ flagbyte = GetPTByte ();
+ if (flagbyte < 240)
+ { /* read character definition */
+
+ int scale = currfont->scaledsize; /* For FixToDVI */
+
+ flagbyte &= 7; /* value of bottom 3 bits */
+ if (flagbyte < 4)
+ { /* short char preamble */
+ packetlen = flagbyte * 256 + GetPTByte ();
+ chcode = GetPTByte ();
+ endofpacket = packetlen + PToffset;
+ pix_tab = &currfont->pixelptr[chcode];
+ b1 = GetPTByte ();
+ b2 = GetPTByte ();
+ b3 = GetPTByte ();
+ pix_tab->dwidth = FixToDVI (scale, 0, b1, b2, b3); /* b0 = 0 */
+ pix_tab->pwidth = GetPTByte ();
+ pix_tab->wd = GetPTByte ();
+ pix_tab->ht = GetPTByte ();
+ pix_tab->xo = SignedPTByte ();
+ pix_tab->yo = SignedPTByte ();
+ }
+ else if (flagbyte < 7)
+ {
+ packetlen = (flagbyte - 4) * 65536 + GetTwoPTBytes ();
+ chcode = GetPTByte ();
+ endofpacket = packetlen + PToffset;
+ pix_tab = &currfont->pixelptr[chcode];
+ b1 = GetPTByte ();
+ b2 = GetPTByte ();
+ b3 = GetPTByte ();
+ pix_tab->dwidth = FixToDVI (scale, 0, b1, b2, b3); /* b0 = 0 */
+ pix_tab->pwidth = GetTwoPTBytes ();
+ pix_tab->wd = GetTwoPTBytes ();
+ pix_tab->ht = GetTwoPTBytes ();
+ pix_tab->xo = SignedPTPair ();
+ pix_tab->yo = SignedPTPair ();
+ }
+ else
+ {
+ packetlen = SignedPTQuad ();
+ chcode = SignedPTQuad ();
+ endofpacket = packetlen + PToffset;
+ pix_tab = &currfont->pixelptr[chcode];
+ b0 = GetPTByte ();
+ b1 = GetPTByte ();
+ b2 = GetPTByte ();
+ b3 = GetPTByte ();
+ pix_tab->dwidth = FixToDVI (scale, b0, b1, b2, b3);
+ pix_tab->pwidth = SignedPTQuad () / 65536; /* dx in pixels */
+ PToffset += 4; /* skip dy */
+ pix_tab->wd = SignedPTQuad ();
+ pix_tab->ht = SignedPTQuad ();
+ pix_tab->xo = SignedPTQuad ();
+ pix_tab->yo = SignedPTQuad ();
+ }
+ pix_tab = &currfont->pixelptr[chcode]; /* position of flagbyte */
+ if (pix_tab->wd == 0 || pix_tab->ht == 0)
+ pix_tab->mapadr = 0; /* no bitmap */
+ else
+ pix_tab->mapadr = flagpos;
+ PToffset = endofpacket; /* skip raster info */
+ continue;
+ }
+ switch (flagbyte)
+ {
+ case 240:
+ case 241:
+ case 242:
+ case 243:
+ i = 0;
+ for (j = 240; j <= flagbyte; j++)
+ i = i * 256 + GetPTByte ();
+ PToffset += i; /* skip special parameter */
+ break;
+ case 244: /* skip numspecial param */
+ PToffset += 4;
+ break;
+ case pknoop: /* do nothing */
+ break;
+ case pkpost: /* no more char defs */
+ goto _L888;
+ break;
+
+ default:
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL1 ("Bad PK flag byte in `%s'.", currfont->fontspec);
+ }
+ } /* of LOOP; flagbyte = pkpost */
+_L888:;
+
+ /* extended short char preamble */
+ /* long char preamble */
+}
+/* PKFillPixelTable */
+
+#undef pkid
+#undef pkpost
+#undef pknoop
+#undef pkpre
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadTFMIntegers ()
+{
+ /* Read the first 6 (six) 16-bit integers in the TFM file. */
+ /* These give the dimensions of the arrays that constitute the rest */
+ /* of the TFM file. */
+ /* See TFtoPL section 8. */
+
+ PToffset = 0; /* start reading at 1st byte in TFM file */
+ lf = GetTwoPTBytes (); /* length of TFM file, in words: 0 <= lf < 2^15. */
+ lh = GetTwoPTBytes (); /* length of header, in words: 2 <= lh. */
+ bc = GetTwoPTBytes (); /* smallest character code in font */
+ ec = GetTwoPTBytes (); /* largest character code in font */
+ nw = GetTwoPTBytes (); /* number of words in width table */
+ nh = GetTwoPTBytes (); /* number of words in height table */
+
+ /* sanity check of lf */
+ if (!(0 <= lf && lf < 1 << 15))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL2 ("TFM file length given as: lf = %d words. Should have 0 <= lf < %d words.", lf, 1 << 15);
+ }
+ /* sanity check of lh */
+ if (!(2 <= lh))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL1 ("TFM's Header length given as: lh = %d words. Should have lh >= 2 (two) words.", lh);
+ }
+ /* sanity check of bc and ec */
+ if (!(0 <= bc && bc - 1 <= ec && ec <= maxTeXchar))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL2 ("First & last char codes = (bc, ec) = (%d, %d). Should have 0 <= bc <= ec <= maxTeXchar = 255.", bc, ec);
+ }
+ /* sanity check of nw */
+ if (!(0 <= nw && nw < 1 << 15))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL2 ("Number of Width Table words given as: nw = %d. Should have 0 <= nw < %d words.", nw, 1 << 15);
+ }
+ /* sanity check of nh */
+ if (!(0 <= nh && nh < 1 << 15))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL2 ("Number of Height Table words given as: nh = %d. Should have 0 <= nh < %d.", nh, 1 << 15);
+ }
+}
+/* ReadTFMIntegers */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadTFMCharInfo ()
+{
+ /* Read the TFMinfo array. See TFtoPL section 11. */
+
+ int c, i;
+ _REC_TFMinfo *tfm_inf;
+
+ PToffset = (6 + lh) * 4; /* offset of TFMinfo array (in bytes) */
+ /* 6 words of dimension info, plus header */
+ for (c = bc; c <= ec; c++)
+ {
+ tfm_inf = &TFMinfo[c];
+ tfm_inf->wdindex = GetPTByte () * 4; /* offset from start of width array */
+ i = GetPTByte (); /* 2nd byte contains htindex and dpindex */
+ tfm_inf->htindex = i / 16 * 4; /* offset from start of height array */
+ tfm_inf->dpindex = (i & 15) * 4; /* offset from start of depth array */
+ PToffset += 2; /* skip itindex and remainder bytes */
+ }
+}
+/* ReadTFMCharInfo */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ReadTFMCharMetrics ()
+{
+ /* Read the charmetrics array using the indices in TFMinfo. */
+
+ int wdbase = lh * 4 + (ec - bc + 1) * 4 + 24; /* offset of width array */
+ int htbase = wdbase + nw * 4; /* offset of height array */
+ int dpbase = htbase + nh * 4; /* offset of depth array */
+ int c;
+
+ for (c = bc; c <= ec; c++)
+ {
+ _REC_TFMinfo *tfm_inf = &TFMinfo[c];
+ _REC_charmetrics *char_met = &charmetrics[c];
+ int b;
+
+ PToffset = wdbase + tfm_inf->wdindex;
+ for (b = 0; b <= 3; b++)
+ char_met->width[b] = GetPTByte ();
+ PToffset = htbase + tfm_inf->htindex;
+ for (b = 0; b <= 3; b++)
+ char_met->height[b] = GetPTByte ();
+ PToffset = dpbase + tfm_inf->dpindex;
+ for (b = 0; b <= 3; b++)
+ char_met->depth[b] = GetPTByte ();
+ }
+}
+/* ReadTFMCharMetrics */
+
+/*--------------------------------------------------------------------*/
+
+static void
+TFMFillPixelTable (fontinfo * currfont)
+{
+ /* Fill the pixeltable for * currfont
+ (a PostScript or other font for which the PK file is missing),
+ using information in the currently open TFM file.
+ */
+
+ int c;
+
+ ReadTFMIntegers (); /* read lf..nh */
+ ReadTFMCharInfo (); /* fill TFMinfo array */
+ ReadTFMCharMetrics (); /* fill charmetrics array */
+
+ for (c = 0; c < bc; c++) /* chars < bc don't exist */
+ currfont->pixelptr[c].mapadr = 0;
+
+ for (c = ec + 1; c <= maxTeXchar; c++) /* chars > ec don't exist */
+ currfont->pixelptr[c].mapadr = 0;
+
+ for (c = bc; c <= ec; c++)
+ {
+ _REC_pixeltable *pix_tab = &currfont->pixelptr[c];
+ _REC_charmetrics *char_met = &charmetrics[c];
+ int scale = currfont->scaledsize; /* For FixToDVI */
+ int dheight, pheight, ddepth, pdepth;
+
+ pix_tab->dwidth = FixToDVI (scale,
+ char_met->width[0], char_met->width[1],
+ char_met->width[2], char_met->width[3]);
+
+ dheight = FixToDVI (scale,
+ char_met->height[0], char_met->height[1],
+ char_met->height[2], char_met->height[3]);
+
+ ddepth = FixToDVI (scale,
+ char_met->depth[0], char_met->depth[1],
+ char_met->depth[2], char_met->depth[3]);
+
+ /* convert DVI units to pixels */
+
+ pix_tab->pwidth = XPixelRound (pix_tab->dwidth);
+ pheight = YPixelRound (dheight);
+ pdepth = YPixelRound (ddepth);
+
+ /* Since we don't have access to PK bitmap info,
+ we will have to use the TFM width/height/depth info
+ to approximate wd, ht, xo, yo.
+ */
+
+ pix_tab->wd = pix_tab->pwidth;
+ pix_tab->wd -= pix_tab->wd / 8; /* better approximation */
+ pix_tab->ht = pheight + pdepth;
+ pix_tab->xo = 0;
+ pix_tab->yo = pheight - 1;
+ if (pix_tab->wd == 0 || pix_tab->ht == 0) /* anything but 0 */
+ pix_tab->mapadr = 0; /* char blank or not in font */
+ else
+ pix_tab->mapadr = 1;
+ pix_tab->bitmap.UU.mptr = (Word *) NULL;
+ }
+}
+/* TFMFillPixelTable */
+
+/*--------------------------------------------------------------------*/
+
+
+static void
+AbsentFillPixelTable (fontinfo * currfont)
+{
+ /* Fill the pixeltable for *currfont
+ * (a PostScript or other font that is missing and cannot be replaced),
+ * using information in the DVI file, since we have nothing else.
+ *
+ * Updated (Wed 9 June 1993) to use cmr10 info., as that is the most
+ * common font in most present-day documents.
+ */
+
+ int c;
+
+ for (c = 0; c <= maxTeXchar; c++)
+ {
+ _REC_pixeltable *pix_tab = &currfont->pixelptr[c];
+
+ /* scaled size of font in DVI units */
+ int scale = currfont->scaledsize; /* For character size estimate */
+ int dheight, ddepth; /* estimated height and depth, in DVI units */
+ int pheight, pdepth; /* same, in pixels */
+
+ /* Let character be a square, scaledsize high and wide, zero depth. */
+ /* For "example.tex", this width and height are not too bad. */
+ pix_tab->dwidth = scale / 2; /* wild, hazardous guess */
+ dheight = scale;
+ ddepth = 0;
+
+ /* convert DVI units to pixels */
+ pix_tab->pwidth = XPixelRound (pix_tab->dwidth);
+ pheight = YPixelRound (dheight);
+ pdepth = YPixelRound (ddepth);
+
+ /* Since we don't have access to PK bitmap or to TFM metric info,
+ we will have to use the guessed (DVI) width/height/depth info
+ to approximate wd, ht, xo, yo.
+ */
+
+ pix_tab->wd = pix_tab->pwidth;
+ pix_tab->wd -= pix_tab->wd / 8; /* better approximation */
+ pix_tab->ht = pheight + pdepth;
+ pix_tab->xo = 0;
+ pix_tab->yo = pheight - 1;
+ if (pix_tab->wd == 0 || pix_tab->ht == 0) /* anything but 0 */
+ pix_tab->mapadr = 0; /* char blank or not in font */
+ else
+ pix_tab->mapadr = 1;
+ pix_tab->bitmap.UU.mptr = (Word *) NULL;
+ }
+}
+/* AbsentFillPixelTable */
+
+/*--------------------------------------------------------------------*/
+
+void
+PixelTableRoutine (fontinfo * currfont)
+{
+ /* DVIReader has just allocated a new pixeltable for currfont, and
+ calls this routine from InterpretPage only ONCE per font
+ (the first time the font is used).
+ If this is the first time we've seen the font,
+ then we build fontspec first.
+ (Note that ShowStatistics, in the main program, may call BuildFontSpec
+ first.)
+ If we can't open the font file, we return dummy_pk or dummy_tfm values,
+ but using the current font's scaledsize.
+ */
+
+ if (!CheckFontPtr (currfont))
+ return;
+
+ /* Try to find and fopen (& fclose) PK file; if that fails, try TFM file. */
+ if (currfont->fontspeclen == 0)
+ BuildFontSpec (currfont);
+
+ if (currfont->fontexists && !OpenFontFile (currfont->fontspec))
+ {
+ StartText ();
+ ResetVDU (); /* let message stay */
+
+ FATAL2 ("fopen-ed but couldn't open file `%s' for font `%s'",
+ currfont->fontspec, currfont->fontname);
+ }
+ /* gt - is this right when a dummy font is used? */
+
+ if (currfont->fontexists)
+ {
+ if (currfont->pkfont)
+ PKFillPixelTable (currfont);
+ else
+ TFMFillPixelTable (currfont);
+
+ CloseFontFile ();
+ }
+ else
+ {
+ AbsentFillPixelTable (currfont);
+ }
+}
+/* PixelTableRoutine */
+
+/*--------------------------------------------------------------------*/
+
+void
+InitFontReader ()
+{
+ /* This routine initializes some global variables. */
+
+ int i;
+
+ gpower[0] = 0;
+ for (i = 1; i <= 32; i++) /* used in GetBitmap */
+ gpower[i] = gpower[i - 1] | (1 << (i - 1));
+}
+/* InitFontReader */
+
+/*--------------------------------------------------------------------*/
+
+/* end fontreader.c */
diff --git a/dviware/dvgtk/fontreader.h b/dviware/dvgtk/fontreader.h
new file mode 100644
index 0000000000..39ed6f9e7b
--- /dev/null
+++ b/dviware/dvgtk/fontreader.h
@@ -0,0 +1,21 @@
+/* fontreader.h - functions for reading PK fonts
+ $Id: fontreader.h,v 0.2 1997/03/28 03:17:08 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __FONTREADER_H__
+#define __FONTREADER_H__
+
+#include "dvgt.h"
+
+extern void InitFontReader ();
+extern void PixelTableRoutine PARAMS ((fontinfo * currfont));
+extern boolean GetBitmap PARAMS ((int ht, int wd, int mapadr, int_or_mptr * bitmap));
+extern boolean BuildFileSpec PARAMS ((const char *areas, const char *name, String spec));
+extern boolean BuildFontSpec PARAMS ((fontinfo * fontptr));
+extern boolean OpenFontFile PARAMS ((char *name));
+extern void CloseFontFile ();
+
+#endif /* __FONTREADER_H__ */
+
+/* end fontreader.h */
diff --git a/dviware/dvgtk/options.c b/dviware/dvgtk/options.c
new file mode 100644
index 0000000000..3d660c73af
--- /dev/null
+++ b/dviware/dvgtk/options.c
@@ -0,0 +1,534 @@
+/* options.c - command line arguments processing
+ $Id: options.c,v 0.2 1997/03/28 03:17:12 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "screenio.h"
+#include "options.h"
+#include "defaults.h"
+
+/* Variables Exported, via "options.h" */
+
+/* X and Y resolutions, in dpi */
+double xres, yres;
+
+/* Magnification */
+int mag;
+
+/* The next four are in paper pixels, and calculated. */
+int hoffset, voffset;
+int paperwd, paperht;
+
+String dummy_pk, dummy_tfm;
+String vdu;
+
+/* DVI file's name */
+string DVIname;
+
+
+typedef struct
+ {
+ units unit;
+ char *name;
+ double per_inch;
+ }
+Dan; /* `Dimension and name' */
+
+static
+Dan dans[] = /* `dimensions and names series' */
+{
+ {ic, "in", 1.0},
+ {cm, "cm", 2.54},
+ {mm, "mm", 25.4},
+ {bp, "bp", 72.0},
+ {pc, "pc", 72.27 / 12},
+ {pt, "pt", 72.27},
+ {sp, "sp", 72.27 * 65536},
+ {px, "px", 300.0} /* "px"'s per_inch value is not used, */
+}; /* but Qume, Laserwriter, etc, are 300 dpi */
+
+static
+size_t ldans = sizeof (dans) / sizeof (Dan); /* length of dans[] */
+
+static int Inint PARAMS ((double f));
+
+/*--------------------------------------------------------------------*/
+/* Auxiliary routines */
+/*--------------------------------------------------------------------*/
+
+/* Copy at most n characters from ct to s; set s[n] = NUL character. */
+/* This ASSUMES that s has memory >= n+1 characters. */
+
+char *
+strMcpy (char *s, const char *ct, size_t n)
+{
+ strncpy (s, ct, n);
+ s[n] = '\0';
+ return s;
+}
+/* strMcpy */
+
+/*--------------------------------------------------------------------*/
+
+/* Copy at most maxstring characters from ct to s; */
+/* set s[maxstring] = NUL character. */
+
+char *
+stringcopy (String s, const char *ct)
+{
+ strncpy (s, ct, maxstring);
+ s[maxstring] = '\0';
+ return (char *) &s;
+}
+/* stringcopy */
+/*--------------------------------------------------------------------*/
+static int
+Inint (double f)
+{
+ return ((int) (f + 0.5));
+}
+/* Inint */
+/*--------------------------------------------------------------------*/
+static void
+ToCardinal (const char *option, const char *value, int *n)
+{
+ /* If value represents a positive integer, then return via n. */
+
+ int check;
+ double r;
+
+ check = sscanf (value, "%lf", &r);
+ *n = Inint (r); /* round value to nearest integer */
+
+ /* check can be 1 or EOF if ok! */
+ if ((check == 1 || check == EOF) && *n > 0)
+ return;
+
+ FATAL2 ("Bad `%s' value: %s. Specify a positive integer.", option, value);
+}
+/* ToCardinal */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ToRes (const char *option, const char *value, double *xr, double *yr)
+{
+ /* X and Y resolutions, specified in dots per inch. */
+
+ int check;
+
+ check = sscanf (value, "%lf,%lf", xr, yr);
+ if (check == 2 && *xr > 0 && *yr > 0)
+ {
+ return;
+ }
+ else
+ {
+ check = sscanf (value, "%lf", xr);
+ if (check == 1 && *xr > 0)
+ {
+ *yr = *xr;
+ return;
+ }
+ }
+
+ FATAL2 ("Bad `%s' value(s): %s.\n"
+ "Resolutions must be positive reals,\n"
+ "specified as `-r xres' or `-r xres,yres'\n"
+ "in dots per inch.", option, value);
+}
+/* ToRes */
+
+/*--------------------------------------------------------------------*/
+
+static units
+Name2Unit (const char *uname)
+{
+ units unit = ic;
+ char Luname[3]; /* Lower case unit name */
+ int j;
+
+#define ToLower(x) (isupper(x) ? tolower(x) : (x))
+
+ Luname[0] = ToLower (uname[0]);
+ Luname[1] = ToLower (uname[1]);
+ Luname[2] = '\0';
+
+ for (j = 0; j < ldans && strcmp (Luname, dans[j].name); j++); /* Search for the name of the unit. */
+
+ if (j < ldans)
+ unit = dans[j].unit;
+ else
+ {
+ MesgString ("Bad unit name `");
+ MesgString (uname);
+ MesgString ("'");
+ MesgLine ();
+
+ MesgString ("Last two letters should be one of ");
+ for (j = 0; j < ldans; j++)
+ {
+ MesgString (" `");
+ MesgString (dans[j].name);
+ MesgString ("'");
+ }
+ MesgChar ('.');
+ MesgLine ();
+
+ MesgString ("Using inch.");
+ MesgLine ();
+ unit = ic;
+ }
+ return unit;
+}
+/* Name2Unit */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ToDimen (const char *option, const char *value, double *r, units *un)
+{
+ /* A valid dimension consists of an integer or real number followed
+ by a two-letter unit: see dans[] above.
+ If value represents a valid dimension,
+ return number part in r, and units part in un.
+ */
+
+ int check;
+ String nun; /* name of unit - ample space in a string for it */
+
+ check = sscanf (value, "%lf%2s", r, nun);
+ if (check == 2)
+ {
+ /* extract unit's code from its name */
+ *un = Name2Unit (nun);
+ }
+ else if (check == 1)
+ {
+ MesgString ("No dimension given, using inch.");
+ MesgLine ();
+ *un = ic;
+ }
+ else
+ { /* check < 1 */
+ FATAL2 ("Bad `%s' value: %s.\nSpecify a dimensioned quantity.",
+ option, value);
+ }
+}
+/* ToDimen */
+
+/*--------------------------------------------------------------------*/
+
+static void
+ToPosDimen (const char *option, const char *value, double *r, units *un)
+{
+ /* A valid +ve dimension consists of a positive integer or real number
+ followed by a two-letter unit: see dans[] above.
+ If value represents a valid dimension,
+ return numeric part in r, and units part in un.
+ */
+
+ ToDimen (option, value, r, un);
+
+ if (*r <= 0)
+ {
+ FATAL2 ("Bad `%s' value: %s.\nSpecify a positive dimension.",
+ option, value);
+ }
+}
+/* ToPosDimen */
+
+/*--------------------------------------------------------------------*/
+
+static int
+DimenPixels (double r, units u, double res)
+{
+ /* Return given dimension as nearest whole number of pixels, */
+ /* given the appropriate (eg, X or Y direction's) resolution in dpi. */
+
+ int Result;
+
+ int i;
+
+ if (u == px)
+ Result = Inint (r);
+ else
+ {
+ for (i = 0; i < ldans && u != dans[i].unit; i++); /* search for unit */
+
+ if (i < ldans)
+ Result = Inint (r / dans[i].per_inch * res);
+ else
+ {
+ MesgString ("Unimplemented unit, treating as inch.");
+ MesgLine ();
+ Result = Inint (r * res);
+ }
+ }
+ return Result;
+}
+/* DimenPixels */
+/*--------------------------------------------------------------------*/
+void
+WriteCardinal (char *name, int value)
+{
+ String outstring;
+
+ sprintf (outstring, "%s= %d", name, value);
+ MesgString (outstring);
+ MesgLine ();
+}
+/* WriteCardinal */
+/*--------------------------------------------------------------------*/
+
+void
+WriteReal (char *name, double value)
+{
+ String outstring;
+
+ sprintf (outstring, "%s= %f", name, value);
+ MesgString (outstring);
+ MesgLine ();
+}
+
+/* WriteReal */
+
+/*--------------------------------------------------------------------*/
+
+/* GT - TO BE FINISHED - Write... FUNCTIONS BELOW, TOO! */
+/* Might be better to use a pair of arrays, or array of pairs */
+/* That is, data-driven may be more flexible. */
+
+void
+NameUnit (units un, String nun)
+/* Interface: un (I), *nun (O). */
+{
+ int i;
+
+ for (i = 0; i < ldans && un != dans[i].unit; i++); /* Search for unit un. */
+
+ if (i < ldans)
+ stringcopy (nun, dans[i].name);
+ else
+ {
+ MesgString ("Unknown unit! Assuming inch.");
+ MesgLine ();
+
+ stringcopy (nun, "in");
+ }
+}
+/* NameUnit */
+
+/*--------------------------------------------------------------------*/
+
+void
+WriteDimen (char *varname, double r, units un)
+{
+ String outstring, nun;
+
+ NameUnit (un, nun);
+ /* !! gt - this line is unsafe, as outstring may overflow! */
+ sprintf (outstring, "%s= %f %s", varname, r, nun);
+ MesgString (outstring);
+ MesgLine ();
+}
+
+/* WriteDimen */
+
+/*--------------------------------------------------------------------*/
+
+void
+WriteName (char *varname, char *svalue)
+{
+ String outstring;
+
+ sprintf (outstring, "%s= %s", varname, svalue);
+ MesgString (outstring);
+ MesgLine ();
+}
+
+/* WriteName */
+
+/*--------------------------------------------------------------------*/
+
+double
+Unit2Value (units unit)
+{
+ double per_inch = 1.0; /* 1 unit per inch */
+ int j;
+
+ for (j = 0; (j < ldans) && (unit != dans[j].unit); j++); /* Search for the unit. */
+
+ if (j < ldans)
+ per_inch = dans[j].per_inch;
+ else
+ {
+ FATAL1 ("Bad unit, enumeration value = %d", unit);
+ }
+ return per_inch;
+}
+/* Unit2Value */
+
+/*--------------------------------------------------------------------*/
+
+int
+InitOptions (int argc, char **argv)
+{
+ /* Get DVI file, and any options, from the command line.
+ If an option appears more than once, then we return the last value.
+
+ Actually, proceed in three steps, in increasing priority:
+ (1) Initialise to default values, as set in "defaults.h".
+ (2) If the appropriate environment variable is set, use that.
+ (3) If the appropriate command line option is set, use that.
+ */
+
+ char *env; /* environment variable */
+ units def_unit = ic; /* default unit is inch */
+ units hoffu, voffu, xu, yu;
+ double hoffr, voffr, xr, yr;
+ boolean landscape;
+ int c;
+
+
+ /*
+ (1) DEFAULTS.
+ initialize option values with defaults; note that the dv script can
+ set up different defaults [- quoth Andrew Trevorrow, I presume]
+ - gt observes - no "dv" script provided with DVItoVDU version 3.0!
+ */
+
+ /* "dpi" means "dots per inch" */
+ /* printer's X and Y resolutions in dpi */
+ xres = (double) DEF_XRES;
+ yres = (double) DEF_YRES;
+
+ /* Page Offsets from Paper edges */
+ hoffu = def_unit;
+ voffu = def_unit;
+ hoffr = 0.0; /* no margin shifting, so 1" left and top margins */
+ voffr = 0.0;
+
+ mag = 0; /* use DVI file's intrinsic magnification */
+
+ /*
+ (2) ENVIRONMENT VARIABLES.
+ */
+
+ /* Resolution, in dots per inch */
+ /* If DV_RES is set in the environment, then try to use that. */
+ /* If two real values are in DV_RES, copy them to xres and yres. */
+ /* If only one is in DV_RES, copy it to both xres and yres. */
+ /* If none is, then ignore DV_RES. */
+
+ if ((env = getenv ("DV_RES")) != (char *) NULL)
+ ToRes (" -r", env, &xres, &yres);
+
+#if 0
+ if (!(env = getenv ("DV_TERM")))
+ env = getenv ("TERM");
+ stringcopy (vdu, !env ? "" : env);
+#else
+ stringcopy (vdu, "tek4010");
+#endif
+
+ /* Paper Width */
+ ToPosDimen ("", !(env = getenv ("DV_PAPERWD")) ? DEF_PAPERWD : env,
+ &xr, &xu);
+
+ /* Paper Height */
+ ToPosDimen ("", !(env = getenv ("DV_PAPERHT")) ? DEF_PAPERHT : env,
+ &yr, &yu);
+
+ /* fall-back PK font */
+ stringcopy (dummy_pk, !(env = getenv ("DV_DUMMY_PK")) ? DEF_DUMMY_PK : env);
+ /* fall-back TFM metric */
+ stringcopy (dummy_tfm, !(env = getenv ("DV_DUMMY_TFM")) ? DEF_DUMMY_TFM : env);
+ /* portrait or landscape page dimensions? */
+ landscape = false; /* portrait: don't swap -x and -y values */
+
+ /*
+ (3) COMMAND LINE OPTIONS.
+ */
+
+ while ((c = getopt (argc, argv, "H:V:d:e:k:lm:r:t:x:y:")) != -1)
+ {
+ switch (c)
+ {
+ case 0: /* flags already processed */
+ break;
+
+ case 'H':
+ ToDimen (" -H", optarg, &hoffr, &hoffu);
+ break;
+ case 'V':
+ ToDimen (" -V", optarg, &voffr, &voffu);
+ break;
+ case 'd':
+ stringcopy (dummy_pk, optarg);
+ break;
+ case 'e': /* gt - not very mnemonic, I know */
+ stringcopy (dummy_tfm, optarg);
+ break;
+ case 'k':
+ kpathsea_debug |= atoi (optarg);
+ break;
+ case 'l':
+ landscape = true;
+ break;
+ case 'm':
+ ToCardinal (" -m", optarg, &mag);
+ case 'r':
+ /* gt - resolutions should allow non-integer dpi */
+ /* - this is because there are such output devices */
+ /* - for example, metric printers. */
+ /* Get resolutions, specified in dots per inch */
+ ToRes (" -r", optarg, &xres, &yres);
+ break;
+ case 'v':
+ stringcopy (vdu, optarg);
+ break;
+ case 'x':
+ ToPosDimen (" -x", optarg, &xr, &xu);
+ break;
+ case 'y':
+ ToPosDimen (" -y", optarg, &yr, &yu);
+ break;
+ case '?': /* error message in getopt */
+ FATAL ("Exiting");
+ default:
+ FATAL ("Fatal error in getopt");
+ } /* switch */
+ }
+
+ argv += optind - 1;
+ argc -= optind - 1;
+
+ if (argc < 2)
+ {
+ return 0;
+ }
+
+ /* bad DVIname will be detected upon open in main module */
+ DVIname = extend_filename (argv[1], "dvi");
+
+ /* set h/voffset and paperwd/ht only after resolutions have been decided */
+ hoffset = DimenPixels (hoffr, hoffu, xres);
+ voffset = DimenPixels (voffr, voffu, yres);
+
+ paperwd = DimenPixels (xr, xu, xres);
+ paperht = DimenPixels (yr, yu, yres);
+
+ if (landscape)
+ { /* swap paperwd and paperht */
+ int temp = paperwd;
+ paperwd = paperht;
+ paperht = temp;
+ }
+ return 1;
+}
+
+/* InitOptions */
+
+/* end options.c */
diff --git a/dviware/dvgtk/options.h b/dviware/dvgtk/options.h
new file mode 100644
index 0000000000..5a8302c05f
--- /dev/null
+++ b/dviware/dvgtk/options.h
@@ -0,0 +1,45 @@
+/* options.h - command line arguments processing
+ $Id: options.h,v 0.2 1997/03/28 03:17:18 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __OPTIONS_H__
+#define __OPTIONS_H__
+
+#include "dvgt.h"
+
+/*
+ Units of measure:
+ inch, centimetre, millimetre, big point, pica, TeX point,
+ scaled point, paper pixel.
+ */
+
+typedef enum
+ {
+ ic, cm, mm, bp, pc, pt, sp, px
+ }
+units;
+
+extern double xres; /* X resolution in pixels per inch */
+extern double yres; /* Y resolution in pixels per inch */
+extern int mag; /* override DVI mag; 0 = use DVI mag */
+extern int hoffset; /* horizontal margin shift in pixels */
+extern int voffset; /* vertical margin shift in pixels */
+extern int paperwd; /* paper width in pixels */
+extern int paperht; /* paper height in pixels */
+extern String vdu; /* type of terminal */
+extern String dummy_tfm; /* dummy TFM file */
+extern String dummy_pk; /* dummy PK file */
+
+extern string DVIname; /* DVI file name */
+
+
+extern int InitOptions PARAMS ((int argc, char **argv));
+extern int Len PARAMS ((char *str));
+extern char *stringcopy PARAMS ((String s, const char *ct));
+extern char *strMcpy PARAMS ((char *s, const char *ct, size_t maxlen));
+extern void WriteReal PARAMS ((char *name, double value));
+
+#endif /* __OPTIONS_H__ */
+
+/* end options.h */
diff --git a/dviware/dvgtk/screenio.c b/dviware/dvgtk/screenio.c
new file mode 100644
index 0000000000..9a93a36f82
--- /dev/null
+++ b/dviware/dvgtk/screenio.c
@@ -0,0 +1,483 @@
+/* screenio.c - display functions
+ $Id: screenio.c,v 0.2 1997/03/28 03:17:23 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "screenio.h"
+#include "unixio.h"
+#include "vdu.h"
+
+/* Variables Exported, via "screenio.h" */
+
+char TeXtoASCII[XXX];
+
+
+/* IMPORT InitVDU, ClearScreen, StartText, ClearScreen, ResetVDU.
+ To handle ^Z suspension properly, ScreenIO needs to use some VDU routines.
+ */
+
+/* SYSDEP: We need to use the Unix write routine.
+ In particular, using Pascal's write/writeln has some nasty side-effect
+ that prevents BusyRead from working!
+ */
+
+int textlinewidth; /* text characters (columns) per line */
+int textcolumn = 0; /* column number in current text line */
+
+/*--------------------------------------------------------------------*/
+
+int
+MesgChar (int ch)
+{
+ int status;
+ /* maxcol <= both size of a string, and width of a line */
+ int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth);
+
+ /* Keep messages within maxcol columns */
+ if (textcolumn >= maxcol)
+ status = EOF;
+ else
+ {
+ status = putchar (ch);
+ ++textcolumn;
+ }
+ return status;
+}
+/* MesgChar */
+
+/*--------------------------------------------------------------------*/
+
+int
+MesgString (const char *s)
+{
+ int status;
+ String message;
+ /* maxcol <= both size of a string, and width of a line */
+ int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth);
+
+ /* Keep messages within maxcol columns */
+ if (textcolumn < 0 || textcolumn >= maxcol)
+ {
+ strcpy (message, "");
+ }
+ else
+ {
+ strncpy (message, s, maxcol - textcolumn);
+ message[maxcol - textcolumn] = '\0';
+ }
+
+ status = fputs (message, stdout);
+ textcolumn += strlen (message);
+ return status;
+}
+/* MesgString */
+
+/*--------------------------------------------------------------------*/
+
+int
+MesgFlush ()
+{
+ int status = fflush (stdout);
+ textcolumn = 0;
+ return status;
+}
+/* MesgFlush */
+
+/*--------------------------------------------------------------------*/
+
+void
+MesgLine ()
+{
+ save_temp_tty ();
+ rawoutoff (); /* Enable NL to CR+LF mapping */
+ /*!!! putchar (CR); *//* SYSDEP: Really an NL */
+ putchar ('\r'); /* SYSDEP: Really an NL */
+ putchar ('\n'); /* SYSDEP: Really an NL */
+ MesgFlush (); /* MesgLine also updates terminal */
+ restore_temp_tty ();
+}
+/* MesgLine */
+
+/*--------------------------------------------------------------------*/
+
+static int
+MesgCard (int c)
+{
+ /* Since the vast majority of given values will be small numbers, we avoid
+ recursion until c >= 100.
+ */
+
+ int len = 0;
+ if (c < 10)
+ {
+ MesgChar (c + '0');
+ ++len;
+ }
+ else if (c < 100)
+ {
+ MesgChar (c / 10 + '0');
+ MesgChar (c % 10 + '0');
+ len += 2;
+ }
+ else
+ { /* c >= 100 */
+ len += MesgCard (c / 100); /* recursive if c >= 100 */
+ c %= 100;
+ MesgChar (c / 10 + '0');
+ MesgChar (c % 10 + '0');
+ len += 2;
+ }
+ return (len);
+}
+/* MesgCard */
+
+/*--------------------------------------------------------------------*/
+
+int
+MesgInt (int i)
+{
+ int len = 0;
+ if (i < 0)
+ {
+ MesgChar ('-');
+ ++len;
+ i = abs (i);
+ }
+ len += MesgCard (i);
+ return (len);
+}
+/* MesgInt */
+
+/*--------------------------------------------------------------------*/
+
+void
+WriteLine ()
+{
+ WriteChar (CR);
+ WriteFlush (); /* WriteLine also updates terminal */
+}
+/* WriteLine */
+
+/*--------------------------------------------------------------------*/
+
+static void
+WriteCard (int c)
+{
+ /* Since the vast majority of given values will be small numbers, we avoid
+ recursion until c >= 100.
+ */
+
+ if (c < 10)
+ {
+ WriteChar (c + '0');
+ return;
+ }
+ if (c < 100)
+ {
+ WriteChar (c / 10 + '0');
+ WriteChar (c % 10 + '0');
+ return;
+ }
+ else
+ {
+ WriteCard (c / 100); /* recursive if c >= 100 */
+ c %= 100;
+ WriteChar (c / 10 + '0');
+ WriteChar (c % 10 + '0');
+ }
+}
+/* WriteCard */
+
+/*--------------------------------------------------------------------*/
+
+void
+WriteInt (int i)
+{
+ if (i < 0)
+ {
+ WriteChar ('-');
+ i = abs (i);
+ }
+ WriteCard (i);
+}
+/* WriteInt */
+
+/*--------------------------------------------------------------------*/
+
+static void
+Restore_Temp_Terminal ()
+{
+ /* Restore_Temp_Terminal is for screenio.c only. */
+
+ MesgFlush (); /* make sure terminal is up-to-date */
+ restore_temp_tty (); /* restore terminal characteristics saved below */
+}
+
+/* Restore_Temp_Terminal */
+
+/*--------------------------------------------------------------------*/
+
+void
+RestoreTerminal ()
+{
+ /* RestoreTerminal restores the initial terminal setting. */
+ /* It should be called before any client module terminates. */
+ MesgFlush (); /* make sure terminal is up-to-date */
+ restore_init_tty (); /* restore terminal characteristics saved below */
+}
+
+/* RestoreTerminal */
+
+/*--------------------------------------------------------------------*/
+
+void
+ReadChar (char *ch)
+{
+ /* gt - if cbreak's off, turn it on */
+ singlecharon ();
+ /* gt - if echo's on, turn it off */
+ echooff ();
+
+ /* gt - at this point, we need singlechar (cbreak) on and echo off. */
+ /* gt - BUT WHY? */
+
+ /* check for CTRL-C or CTRL-Z */
+
+ /* Interrupted by user? (CTRL-C) */
+ if (sig_flags.intr)
+ { /* echo ch since echooff has been called */
+ /* interrupt */
+ sig_flags.intr = 0; /* reset intr flag */
+ *ch = CR; /* return to "Command: " prompt level */
+ }
+ else if (sig_flags.tstop)
+ { /* Suspended by user? (CTRL-Z) */
+ /* suspend */
+ sig_flags.tstop = 0; /* reset tstop flag */
+
+ StartText ();
+ ClearScreen ();
+ MesgLine ();
+ ResetVDU ();
+ Restore_Temp_Terminal ();
+
+ suspend ();
+ save_temp_tty ();
+
+ singlecharon ();
+ rawouton ();
+ echooff ();
+
+ InitVDU ();
+ StartText ();
+ ClearScreen ();
+
+ *ch = CR; /* return to Command: level */
+ }
+ else
+ {
+ putchar (*ch = getchar ());
+ }
+}
+/* ReadChar */
+
+/*--------------------------------------------------------------------*/
+
+void
+ReadString (char *s)
+{
+ /* Read a string of characters.
+ The routine is terminated upon carriage return.
+ */
+
+ char ch;
+ int i;
+
+ singlecharoff (); /* read string in cooked mode */
+ rawoutoff ();
+ echoon (); /* echo characters */
+
+ for (i = 0; true; i++)
+ {
+ if (sig_flags.intr)
+ {
+ /* interrupt */
+ sig_flags.intr = 0; /* reset intr flag */
+ s[0] = '\0';
+ break;
+ }
+ if (sig_flags.tstop)
+ {
+ /* suspend */
+ sig_flags.tstop = 0; /* reset tstop flag */
+
+ StartText ();
+ ClearScreen ();
+ MesgLine ();
+ ResetVDU ();
+ Restore_Temp_Terminal ();
+
+ suspend ();
+ save_temp_tty ();
+ /* singlecharon and echooff are called below */
+
+ InitVDU ();
+ StartText ();
+ ClearScreen ();
+
+ s[0] = '\0';
+ break;
+ }
+ ch = getchar ();
+ if (ch == CR)
+ {
+ s[i] = '\0';
+ break;
+ }
+ s[i] = ch;
+ if (i == maxstring)
+ {
+ s[i] = '\0';
+ break;
+ }
+ }
+ singlecharon (); /* return to cbreak mode */
+ rawouton ();
+ echooff (); /* and no echo */
+}
+/* ReadString */
+
+/*--------------------------------------------------------------------*/
+
+boolean
+BusyRead (char *ch)
+{
+ /* Return TRUE if ch is waiting in input buffer or if a ^C or ^Z has been
+ typed. Set ch to CR or the character read (no echo).
+ If nothing in input buffer, then ch is undefined and we return FALSE.
+ */
+
+ if (sig_flags.intr)
+ {
+ /* interrupt */
+ sig_flags.intr = 0;
+ *ch = CR; /* main module will return to Command: level */
+ return true;
+ }
+ if (sig_flags.tstop)
+ {
+ /* suspend */
+ sig_flags.tstop = 0;
+
+ StartText ();
+ ClearScreen ();
+ MesgLine ();
+ ResetVDU ();
+ Restore_Temp_Terminal ();
+
+ suspend ();
+ save_temp_tty ();
+ /* singlecharon and echooff are called below */
+
+ InitVDU ();
+ StartText ();
+ ClearScreen ();
+
+ *ch = CR; /* after suspend, return to Command: level */
+ return true;
+ }
+ /* SYSDEP: buffercount assumes singlecharon and echooff have been called */
+
+ /* gt - check whether singlecharon and echooff have been called */
+
+ if (cmode_flags.cbreak == 0)
+ singlecharon ();
+
+ if (cmode_flags.echo == 1)
+ echooff ();
+
+ if (buffercount () == 0)
+ return false;
+ else
+ {
+ *ch = getchar ();
+ return true;
+ }
+}
+/* BusyRead */
+
+/*--------------------------------------------------------------------*/
+
+static void
+InitTeXtoASCII ()
+{
+ /* Initialize TeXtoASCII array used in specific ShowChar/Rectangle routines
+ to map a given TeX char into a similar, displayable ASCII char.
+ */
+
+ int i;
+
+ for (i = 0; i <= 0xa; i++) /* Greek letters */
+ TeXtoASCII[i] = '?';
+ for (i = 0xb; i <= 0xf; i++) /* ligatures */
+ TeXtoASCII[i] = '?';
+ TeXtoASCII[0x10] = 'i'; /* dotless i */
+ TeXtoASCII[0x11] = 'j'; /* dotless j */
+ TeXtoASCII[0x12] = '`'; /* grave accent */
+ TeXtoASCII[0x13] = '\''; /* acute accent */
+ for (i = 0x14; i <= 0x17; i++) /* high accents */
+ TeXtoASCII[i] = '~';
+ TeXtoASCII[0x18] = ','; /* cedilla */
+ for (i = 0x19; i <= 0x20; i++) /* foreigns */
+ TeXtoASCII[i] = '?';
+ for (i = 0x21; i <= 0x5b; i++) /* same */
+ TeXtoASCII[i] = i;
+ TeXtoASCII[0x5c] = '"'; /* open dble quote */
+ TeXtoASCII[0x5d] = ']'; /* same */
+ for (i = 0x5e; i <= 0x5f; i++) /* more accents */
+ TeXtoASCII[i] = '^';
+ for (i = 0x60; i <= 0x7a; i++) /* same */
+ TeXtoASCII[i] = i;
+ for (i = 0x7b; i <= 0x7c; i++) /* en & em dash */
+ TeXtoASCII[i] = '-';
+ for (i = 0x7d; i <= 0x7f; i++) /* more accents */
+ TeXtoASCII[i] = '~';
+ for (i = 0x80; i <= 0xff; i++) /* non-ASCII, but 8-bit: 128 to 255 */
+ TeXtoASCII[i] = '?';
+}
+/* InitTeXtoASCII */
+
+/*--------------------------------------------------------------------*/
+
+void
+InitScreenIO ()
+{
+ InitTeXtoASCII ();
+ /* We first save the current terminal characteristics.
+ save_init_tty also calls save_temp_tty, which
+ sets up ^C/^Z interrupt handlers; see unixio.c.
+ */
+ save_init_tty ();
+ atexit (RestoreTerminal);
+
+ singlecharon (); /* cbreak mode for ReadChar and BusyRead */
+ echooff (); /* no echo for BusyRead */
+ rawouton ();
+ /* was _IOFBF */
+#ifdef SETVBUF_REVERSED
+ if (setvbuf (stdout, _IONBF, NULL, BUFSIZ / 4) != 0)
+ {
+#else
+ if (setvbuf (stdout, NULL, _IONBF, BUFSIZ / 4) != 0)
+ {
+#endif
+ MesgString ("screenio.c: InitScreenIO: setvbuf failed!");
+ MesgLine ();
+ }
+}
+/* InitScreenIO */
+
+/*--------------------------------------------------------------------*/
+
+/* end screenio.c */
diff --git a/dviware/dvgtk/screenio.h b/dviware/dvgtk/screenio.h
new file mode 100644
index 0000000000..4a4b643e77
--- /dev/null
+++ b/dviware/dvgtk/screenio.h
@@ -0,0 +1,73 @@
+/* screenio.h - display functions
+ $Id: screenio.h,v 0.2 1997/03/28 03:17:29 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef __SCREENIO_H__
+#define __SCREENIO_H__
+
+#include "dvgt.h"
+
+/* 0 = success, 1 = error */
+/* These terminal i/o routines are highly system-dependent and have been
+ designed for DVItoVDU and its auxiliary modules.
+
+ Notes:
+ - InitScreenIO saves the current tty characteristics,
+ then sets the mode to cbreak with no echo.
+ Clients should therefore call RestoreTerminal before terminating.
+ - WriteFlush or WriteLine must be called to explicitly update the terminal
+ (e.g., just before a read) or to synchronize output with writes
+ from other modules that don't use ScreenIO.
+ - WriteString assumes the end of a string is the first blank (if not full),
+ so clients need to replace calls like WriteString('xxx = ') with
+ WriteString('xxx ='); WriteChar(' ').
+ */
+
+#define CR '\n' /* SYSDEP: char read upon hitting Return key */
+#define CTRLC '\0' /* SYSDEP: interrupt, see unixio */
+#define CTRLZ '\001' /* SYSDEP: suspend, see unixio */
+/* SYSDEP: unixio puts CTRLC and CTRLZ into input buffer (along with CR)
+ upon getting a ^C or ^Z interrupt.
+ (It can't put chr(3) and chr(26) into buffer
+ because tty will detect another interrupt and we'll loop forever!)
+ */
+#define NUL '\0'
+#define FF '\f'
+#define CAN '\030'
+#define ESC '\033'
+#define FS '\034'
+#define GS '\035'
+#define US '\037'
+#define XXX 256
+
+
+extern int textlinewidth; /* text characters (columns) per line */
+extern int textcolumn; /* column in current text line */
+
+extern char TeXtoASCII[XXX]; /* TeX char to ASCII char */
+
+
+extern void InitScreenIO ();
+extern void ReadChar PARAMS ((char *ch));
+extern void ReadString PARAMS ((char *s));
+extern boolean BusyRead PARAMS ((char *ch));
+extern void WriteInt PARAMS ((int i));
+extern void WriteLine ();
+
+#define WriteChar(X) putchar(X)
+#define WriteString(X) fputs(X, stdout)
+#define WriteFlush() fflush(stdout)
+
+extern int MesgInt PARAMS ((int i));
+extern void MesgLine ();
+
+extern int MesgChar PARAMS ((int ch));
+extern int MesgString PARAMS ((const char *s));
+extern int MesgFlush ();
+
+extern void RestoreTerminal ();
+
+#endif /* __SCREENIO_H__ */
+
+/* end screenio.h */
diff --git a/dviware/dvgtk/stamp-auto b/dviware/dvgtk/stamp-auto
new file mode 100644
index 0000000000..21ec1ed1b4
--- /dev/null
+++ b/dviware/dvgtk/stamp-auto
@@ -0,0 +1 @@
+Thu Mar 27 22:21:43 EST 1997
diff --git a/dviware/dvgtk/stamp-auto.in b/dviware/dvgtk/stamp-auto.in
new file mode 100644
index 0000000000..15e135c4d9
--- /dev/null
+++ b/dviware/dvgtk/stamp-auto.in
@@ -0,0 +1 @@
+Thu Mar 27 22:21:42 EST 1997
diff --git a/dviware/dvgtk/unixio.c b/dviware/dvgtk/unixio.c
new file mode 100644
index 0000000000..3c54a8a8f9
--- /dev/null
+++ b/dviware/dvgtk/unixio.c
@@ -0,0 +1,357 @@
+/* unixio.c - Unix terminal and signal handling
+ $Id: unixio.c,v 0.2 1997/03/28 03:17:33 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "unixio.h"
+#include "screenio.h" /* for MesgString, MesgLine */
+
+/* Set DV_FD (ioctl file descriptor) to 0 or 1 ? */
+#define DV_FD STDIN_FILENO
+
+sig_flags_t sig_flags;
+cmode_flags_t cmode_flags;
+
+/* Alex Dickinson
+ Procedures for setting and resetting UNIX tty characteristics.
+ Interesting functions are:
+ save_init_tty;
+ restore_init_tty;
+ save_temp_tty;
+ restore_temp_tty;
+ echoon;
+ echooff;
+ singlecharon;
+ singlecharoff;
+ buffercount;
+ suspend;
+ A side effect of calling save_temp_tty is to set up signal handling
+ to reset the terminal characteristics appropriately for the various
+ interrupt signals.
+ */
+
+/*****************************************************************
+* terminal handling
+*/
+
+#if defined(HAVE_TERMIO_H)
+#include <fcntl.h>
+#include <termio.h>
+#define TERMIO
+#ifdef NCC
+#define MAXCC NCC
+#else
+#define MAXCC 256
+#endif
+#define DV_GTTY TCGETA
+#define DV_STTY TCSETAW
+typedef struct termio dv_tty;
+unsigned char saved_cc[NCC];
+#else
+#include <sgtty.h>
+#define DV_GTTY TIOCGETP
+#define DV_STTY TIOCSETN
+typedef struct sgttyb dv_tty;
+#endif /* TERMIOS || TERMIO */
+
+#include <signal.h>
+#include <errno.h>
+
+static dv_tty init_tty_state; /* store initial terminal characteristics */
+static dv_tty temp_tty_state; /* current terminal characteristics */
+
+/* locally defined and used functions and data */
+
+static void setsignals ();
+static void reportio PARAMS ((int iostat));
+static int iostatus; /* return status of ioctl system function */
+
+static void
+reportio (int iostat)
+{
+ if (iostat < 0)
+ { /* an ioctl error */
+ char *str = "";
+ String cstr;
+ switch (errno)
+ {
+ /* generic errors */
+#ifdef EBADF
+ case EBADF:
+ str = "Not a valid, open, file descriptor!";
+ break;
+#endif
+#ifdef EINTR
+ case EINTR:
+ str = "Signal caught.";
+ break;
+#endif
+#ifdef ENOTTY
+ case ENOTTY:
+ str = "No device driver, or doesn't accept control functions!";
+ break;
+#endif
+ /* specialised errors */
+#ifdef EFAULT
+ case EFAULT:
+ str = "Illegal data transfer address!";
+ break;
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ str = "Driver ignorant of this request or arg!";
+ break;
+#endif
+#ifdef EIO
+ case EIO:
+ str = "Physical I/O error!";
+ break;
+#endif
+#ifdef ENOLINK
+ case ENOLINK:
+ str = "Remote machine link no longer active!";
+ break;
+#endif
+#ifdef ENXIO
+ case ENXIO:
+ str = "Subdevice cannot perform requested service!";
+ break;
+#endif
+ /* gt - should be ample space in cstr. */
+ default:
+ sprintf (cstr, "Unknown error %d !", errno);
+ str = cstr;
+ break;
+ }
+ MesgString ("ioctl: ");
+ MesgString (str);
+ MesgLine ();
+ }
+} /* reportio */
+
+void
+save_init_tty ()
+{
+ /* Save the original tty characteristics and set up the signalling. */
+ save_temp_tty ();
+ init_tty_state = temp_tty_state;
+} /* save_init_tty */
+
+void
+restore_init_tty ()
+{
+ /* Restore the original tty characteristics. */
+ temp_tty_state = init_tty_state;
+ restore_temp_tty ();
+} /* restore_init_tty */
+
+void
+save_temp_tty ()
+{
+ /* Save the current tty characteristics and set up the signalling. */
+ iostatus = ioctl (DV_FD, DV_GTTY, &temp_tty_state);
+ reportio (iostatus);
+ setsignals ();
+} /* save_temp_tty */
+
+void
+restore_temp_tty ()
+{
+ /* Restore the recent tty characteristics. */
+ iostatus = ioctl (DV_FD, DV_STTY, &temp_tty_state);
+ reportio (iostatus);
+} /* restore_temp_tty */
+
+void
+singlecharon ()
+{
+ /* Set driver to read characters as they are typed without waiting for a
+ terminator. Echo remains unchanged. */
+ dv_tty s;
+
+ if (cmode_flags.cbreak != 1)
+ {
+ reportio (ioctl (DV_FD, DV_GTTY, &s));
+#ifndef TERMIO
+ s.sg_flags |= CBREAK;
+#else /* TERMIO */
+ saved_cc[VEOL] = s.c_cc[VEOL];
+ saved_cc[VEOF] = s.c_cc[VEOF];
+ s.c_lflag &= ~ICANON; /* Disable erase/kill processing */
+ s.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
+ s.c_cc[VTIME] = 0; /* no matter how long that takes. */
+#endif /* TERMIO */
+ reportio (ioctl (DV_FD, DV_STTY, &s));
+#ifdef FLUSH_STDIN
+ fflush (stdin);
+#endif /* FLUSH_STDIN */
+
+ cmode_flags.cbreak = 1;
+ }
+} /* singlecharon */
+
+void
+singlecharoff ()
+{
+ /* Turn off single character read mode. */
+ dv_tty s;
+
+ if (cmode_flags.cbreak != 0)
+ {
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef TERMIO
+ s.sg_flags &= ~CBREAK;
+#else /* TERMIO */
+ s.c_lflag |= ICANON; /* Enable erase/kill processing */
+ s.c_cc[VEOL] = saved_cc[VEOL];
+ s.c_cc[VEOF] = saved_cc[VEOF];
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.cbreak = 0;
+ }
+} /* singlecharoff */
+
+void
+echoon ()
+{
+ /* Turn character echoing on. */
+ dv_tty s;
+
+ reportio (ioctl (DV_FD, DV_GTTY, &s));
+#ifndef TERMIO
+ s.sg_flags |= ECHO;
+#else /* TERMIO */
+ s.c_lflag |= ECHO;
+#endif /* TERMIO */
+ reportio (ioctl (DV_FD, DV_STTY, &s));
+ cmode_flags.echo = 1;
+} /* echoon */
+
+void
+echooff ()
+{
+ /* Turn character echoing off. */
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifndef TERMIO
+ s.sg_flags &= ~ECHO;
+#else /* TERMIO */
+ s.c_lflag &= ~ECHO;
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+ cmode_flags.echo = 0;
+} /* echooff */
+
+void
+rawouton ()
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef TERMIO
+ s.c_oflag &= ~OPOST; /* Disables tab interpretation etc. */
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 1;
+} /* rawouton */
+
+void
+rawoutoff ()
+{
+ dv_tty s;
+
+ iostatus = ioctl (DV_FD, DV_GTTY, &s);
+ reportio (iostatus);
+#ifdef TERMIO /* TERMIO */
+ s.c_oflag |= OPOST;
+#endif /* TERMIO */
+ iostatus = ioctl (DV_FD, DV_STTY, &s);
+ reportio (iostatus);
+
+ cmode_flags.raw = 0;
+} /* rawoutoff */
+
+int
+buffercount ()
+{
+ /* Return true if there are any characters currently in the input buffer. */
+#ifndef TERMIO
+ long count;
+ iostatus = ioctl (DV_FD, FIONREAD, &count);
+ reportio (iostatus);
+ return (count > 0);
+#else /* TERMIO */
+ int c, flags, ret;
+
+ /* Save the current fcntl flags and make reads return without waiting */
+ flags = fcntl (0, F_GETFL, 0);
+ fcntl (0, F_SETFL, flags | O_NDELAY); /* This might be SysV specific */
+ if ((c = getchar ()) != EOF)
+ {
+ ungetc (c, stdin);
+ ret = 1;
+ }
+ else
+ {
+ ret = 0;
+ }
+ fcntl (0, F_SETFL, flags); /* This might be SysV specific */
+ return ret;
+#endif /* TERMIO */
+} /* buffercount */
+
+RETSIGTYPE
+handleint (int sig)
+{
+ /* Catch signals from tty.
+ If sig is an interrupt, set the intr flag,
+ Otherwise it was a suspend, so set the tstop flag. */
+ fflush (stdin);
+ if (sig == SIGINT)
+ {
+ sig_flags.intr = 1;
+ }
+ else
+ {
+ sig_flags.tstop = 1;
+ }
+#ifdef TERMIO /* TERMIO */
+ setsignals (); /* Because SysV forgets its handlers */
+#endif /* TERMIO */
+} /* handleint */
+
+static void
+setsignals ()
+{
+ /* Signal initialization. */
+ signal (SIGINT, handleint);
+#ifndef TERMIO
+ signal (SIGTSTP, handleint);
+#endif /* TERMIO */
+} /* setsignals */
+
+void
+suspend ()
+{
+ /* Suspend the process */
+#ifndef TERMIO
+ signal (SIGTSTP, SIG_DFL);
+ kill (0, SIGTSTP);
+ /* resumed again, goody! */
+ setsignals ();
+#else
+ /* don't know what to do */
+#endif /* TERMIO */
+} /* suspend */
+
+#undef IN_UNIXIO_C
diff --git a/dviware/dvgtk/unixio.h b/dviware/dvgtk/unixio.h
new file mode 100644
index 0000000000..8d379765f6
--- /dev/null
+++ b/dviware/dvgtk/unixio.h
@@ -0,0 +1,44 @@
+/* unixio.h - Unix terminal and signal handling
+ $Id: unixio.h,v 0.2 1997/03/28 03:17:40 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef UNIXIO_H
+#define UNIXIO_H
+
+#include "dvgt.h"
+
+typedef struct
+ {
+ unsigned int intr, tstop:1;
+ }
+sig_flags_t;
+typedef struct
+ {
+ unsigned int cbreak, raw, echo:1;
+ }
+cmode_flags_t;
+
+extern sig_flags_t sig_flags;
+extern cmode_flags_t cmode_flags;
+
+/* Alex Dickinson */
+/* Definitions for some unix ioctl calls. These external procedures */
+/* refer to the C functions contained in unixio.c. */
+
+extern void save_init_tty ();
+extern void restore_init_tty ();
+extern void save_temp_tty ();
+extern void restore_temp_tty ();
+extern void singlecharon ();
+extern void singlecharoff ();
+extern void echoon ();
+extern void echooff ();
+extern void rawouton ();
+extern void rawoutoff ();
+extern int buffercount ();
+extern void suspend ();
+
+#endif /* UNIXIO_H */
+
+/* end unixio.h */
diff --git a/dviware/dvgtk/vdu.c b/dviware/dvgtk/vdu.c
new file mode 100644
index 0000000000..c338ca7249
--- /dev/null
+++ b/dviware/dvgtk/vdu.c
@@ -0,0 +1,547 @@
+/* vdu.c - VDU driver interface
+ $Id: vdu.c,v 0.2 1997/03/28 03:17:44 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#include "dvgt.h"
+#include "vdu.h"
+#include "options.h"
+#include "screenio.h"
+
+/* Exported via "vdu.h" */
+
+boolean vdu_clears_lines; /* Can current VDU clear a single line? */
+
+int maxy, lineht, dragdown;
+boolean havesentxy;
+
+static int oldhiy; /* for remembering old address in SendXY */
+static int oldhix, oldloy, charwidth;
+ /* set by LoadFont and used in ShowChar */
+
+static int loadedsize;
+/* remember alpha size set by last TEK4010LoadFont;
+ VT640, VIS500/550 VDUs don't actually need to worry about this,
+ since they use non-TEK4010 fonts to draw in dialogue region.
+ VIS240, however, uses alpha mode font. */
+
+static int charsize; /* used to select alpha character size */
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+Graphic ()
+{
+ WriteChar (GS); /* switch to graphics mode */
+}
+
+/* Graphic */
+
+/*--------------------------------------------------------------------*/
+
+static void
+Alpha ()
+{
+ WriteChar (US); /* switch to alphanumeric mode */
+}
+
+/* Alpha */
+
+/*--------------------------------------------------------------------*/
+
+void
+SendXY (int x, int y)
+{
+ /* Translates the given screen address into 4 bytes.
+ havesentxy is used to minimize the number of bytes sent: after the first
+ 4 bytes have been sent, subsequent bytes that don't change need not be sent
+ (except for the low x byte which is always sent).
+ If the high x byte changes then the low y byte must also be sent.
+ */
+
+ int hiy, loy, hix, lox;
+ boolean sendhix;
+
+ /* we assume y is in [0..maxy] and x is in [0..1023] */
+ hiy = y / 32 + ' ';
+ hix = x / 32 + ' ';
+ loy = (y & 31) + '`';
+ lox = (x & 31) + '@';
+ if (havesentxy)
+ {
+ if (hiy != oldhiy)
+ {
+ WriteChar (hiy);
+ oldhiy = hiy;
+ }
+ sendhix = (hix != oldhix);
+ if (loy != oldloy || sendhix)
+ {
+ WriteChar (loy);
+ oldloy = loy;
+ }
+ if (sendhix)
+ {
+ WriteChar (hix);
+ oldhix = hix;
+ }
+ WriteChar (lox);
+ }
+ else
+ {
+ /*
+ SYSDEP: We _assume_ XON/XOFF flow control is _enabled_,
+ to avoid data loss.
+ */
+ WriteChar (hiy);
+ oldhiy = hiy;
+ WriteChar (loy);
+ oldloy = loy;
+ WriteChar (hix);
+ oldhix = hix;
+ WriteChar (lox);
+ havesentxy = true;
+ /* send first 4 bytes */
+ }
+}
+/* SendXY */
+
+/*--------------------------------------------------------------------*/
+void
+ClearTextLine (int line)
+{
+ /* Do nothing as NCSA Telnet (version 2.3.0.3) can only clear
+ the entire screen in tek4010 and NOT just a line.
+ Live with the overwriting. In any case,
+ the next DisplayPage will clear and rewrite the status lines.
+ */
+}
+/* ClearTextLine */
+
+/*--------------------------------------------------------------------*/
+
+void
+ResetVDU ()
+{
+ WriteChar (CAN);
+ WriteChar (CAN);
+}
+/* ResetVDU */
+/*--------------------------------------------------------------------*/
+
+void
+StartText ()
+{
+ Alpha ();
+}
+/* StartText */
+
+/*--------------------------------------------------------------------*/
+
+void
+MoveToTextLine (int line)
+{
+ /* Move cursor to start of given line using lineht.
+ At the end of this routine we must be in alpha mode,
+ and ready to display characters in the default charsize.
+ */
+
+ Graphic ();
+
+ SendXY (0, maxy - line * lineht + 1);
+ textcolumn = 0;
+
+ WriteChar (ESC); /* reset alpha character size */
+ WriteChar ('0');
+ charsize = 0;
+ charwidth = 13;
+
+ Alpha (); /* back to alpha mode */
+}
+
+/* MoveToTextLine */
+
+/*--------------------------------------------------------------------*/
+
+void
+ClearScreen ()
+{
+#ifdef NCSA_TELNET
+ WriteChar (ESC);
+ WriteChar (FF); /* erase graphics and put in alpha mode */
+#endif
+
+ Graphic ();
+
+ WriteChar (ESC); /* erase graphics and put in alpha mode */
+ WriteChar (FF);
+
+ havesentxy = false; /* ESC FF will home cursor */
+ charsize = 0; /* ESC FF resets character size */
+ charwidth = 13;
+}
+
+/* ClearScreen */
+
+/*--------------------------------------------------------------------*/
+
+void
+StartGraphics ()
+{
+ if (charsize != loadedsize)
+ { /* graphics mode was interrupted */
+ charsize = loadedsize;
+ dragdown = (charsize + 1) * 5; /* used by VIS500/550 ShowChar */
+
+ Graphic ();
+
+ WriteChar (ESC);
+ WriteChar (charsize + '0'); /* recall last LoadFont character size */
+ }
+ Graphic ();
+
+ havesentxy = false; /* safer to send all bytes anew */
+}
+/* StartGraphics */
+
+
+/*--------------------------------------------------------------------*/
+
+void
+LoadFont (char *fontname, int fontsize, double mag,
+ double hscale, double vscale)
+{
+ /* Use the given fontsize to select an appropriate character size
+ (based on horizontal scaling only!) for future TEK4010ShowChar calls.
+ */
+
+ int newsize;
+
+ /* convert fontsize into scaled screen pixels using mag and hscale */
+ fontsize = (int) (fontsize * mag * hscale + 0.5);
+ /* Choose one of the 4 alpha mode character sizes based on fontsize:
+ charsize max chars/line relative size fontsize range
+ 0 80 x1 0..40
+ 1 40 x2 41..80
+ 2 26 x3 81..120
+ 3 20 x4 121...
+ The fontsize ranges were chosen by trial and error.
+ */
+ if (fontsize < 41)
+ {
+ newsize = 0;
+ charwidth = 13; /* 1024/80 = 12.8 */
+ }
+ else if (fontsize < 81)
+ {
+ newsize = 1;
+ charwidth = 26; /* 1024/40 = 25.6 */
+ }
+ else if (fontsize < 121)
+ {
+ newsize = 2;
+ charwidth = 40; /* 1024/26 = 39.4 */
+ }
+ else
+ {
+ newsize = 3;
+ charwidth = 52; /* 1024/20 = 51.2 */
+ }
+ loadedsize = newsize; /* remember in case graphics mode is interrupted */
+ if (charsize != newsize)
+ { /* change character size */
+ charsize = newsize;
+ WriteChar (ESC);
+ WriteChar (charsize + '0');
+ }
+ /* Alpha character reference pts on some emulating VDUs (VIS500/550)
+ are below baselines to allow for descenders.
+ Such VDUs can use dragdown to drag baselines down to TeX reference pts
+ when calling TEK4010ShowChar.
+ */
+ dragdown = (charsize + 1) * 5; /* used by VIS500/550 TEK4010ShowChar */
+
+ Graphic (); /* must return from LoadFont in graphics mode */
+}
+/* LoadFont */
+
+/*--------------------------------------------------------------------*/
+
+void
+ShowChar (int screenh, int screenv, char ch)
+{
+ /* Show the given Terse character (mapped to ASCII) at the given ref pt.
+ We use the charwidth set by last TEK4010LoadFont call.
+ */
+
+ char newch; /* = TeXtoASCII[ch] */
+
+ /* shift character left if it will overlap right edge of screen */
+
+ if (screenh + charwidth > 1023)
+ screenh = 1023 - charwidth;
+
+ /* We no longer _assume_ TEK4010StartGraphics, TEK4010LoadFont,
+ or last TEK4010ShowChar has just sent GS */
+
+ Graphic ();
+ SendXY (screenh, maxy - screenv); /* move cursor to ref pt */
+ Alpha (); /* enter alpha mode */
+
+ /* We use TeXtoASCII to map ch into a comparable ASCII character, apart
+ from most of the ? characters which we attempt to simulate.
+ */
+
+ newch = TeXtoASCII[ch - NUL];
+ if (newch != '?')
+ {
+ /* newch is similar to TeX ch */
+ WriteChar (newch);
+ }
+ else
+ {
+ /* attempt to display something other than ? */
+ switch (ch)
+ {
+ case 0xb: /* ff, fi, fl, ffi, ffl */
+ case 0xc:
+ case 0xd:
+ case 0xe:
+ case 0xf:
+ WriteChar ('f');
+ /* only simulate rest of ligature if room at right edge */
+ if (screenh + charwidth * 2 <= 1023)
+ {
+ Graphic ();
+ SendXY (screenh + charwidth, maxy - screenv);
+ Alpha ();
+
+ switch (ch)
+ {
+ case 0xb: /* ff */
+ WriteChar ('f');
+ break;
+
+ case 0xc: /* fi */
+ WriteChar ('i');
+ break;
+
+ case 0xd: /* fl */
+ WriteChar ('l');
+ break;
+
+ case 0xe:
+ case 0xf:
+ WriteChar ('f');
+ /* only simulate rest of ligature if room at right edge */
+ if (screenh + charwidth * 3 <= 1023)
+ {
+ Graphic ();
+ SendXY (screenh + charwidth * 2, maxy - screenv);
+ Alpha ();
+
+ if (ch == 0xe) /* ffi */
+ WriteChar ('i');
+ else /* if (ch == 0xf) */
+ /* ffl */
+ WriteChar ('l');
+ } /* fi */
+ break;
+ } /* switch */
+ } /* fi */
+ break;
+ case 0x19: /* German sharp S */
+ WriteChar ('B');
+ break;
+ case 0x1a: /* diphthongs: ae, oe, AE, OE */
+ case 0x1b:
+ case 0x1d:
+ case 0x1e:
+ switch (ch)
+ {
+ case 0x1a: /* ae */
+ WriteChar ('a');
+ break;
+ case 0x1b: /* oe */
+ WriteChar ('o');
+ break;
+ case 0x1d: /* AE */
+ WriteChar ('A');
+ break;
+ case 0x1e: /* OE */
+ WriteChar ('O');
+ break;
+ }
+ if (screenh + charwidth * 2 <= 1023)
+ {
+ Graphic ();
+ SendXY (screenh + charwidth, maxy - screenv);
+ Alpha ();
+
+ switch (ch)
+ {
+ case 0x1a: /* ae */
+ case 0x1b: /* oe */
+ WriteChar ('e');
+ break;
+
+ case 0x1d: /* AE */
+ case 0x1e: /* OE */
+ WriteChar ('E');
+ break;
+ }
+ }
+ break;
+ case 0x1c: /* Scandinavian slashed o and O */
+ case 0x1f:
+ switch (ch)
+ {
+ case 0x1c: /* o/ */
+ WriteChar ('o');
+ break;
+
+ case 0x1f: /* O/ */
+ WriteChar ('O');
+ break;
+ }
+
+ Graphic ();
+ SendXY (screenh, maxy - screenv); /* overwrite */
+ Alpha ();
+
+ WriteChar ('/');
+ break;
+ case 0x20: /* Polish suppressed l and L */
+ WriteChar ('\'');
+ break;
+ case '?': /* question mark */
+ WriteChar ('?');
+
+ default:
+ /* WriteChar ('?'); */
+ /* show hexadecimal character code, instead of question mark: */
+ WriteChar ('\\');
+ /* only simulate rest of ligature if room at right edge */
+ if (screenh + charwidth * 3 <= 1023)
+ {
+ String outstr; /* ample size */
+
+ Graphic ();
+ SendXY (screenh + charwidth * 2, maxy - screenv);
+ Alpha ();
+
+ sprintf (outstr, "%.2x", ch);
+ WriteChar (outstr[0]);
+ WriteChar (outstr[1]);
+ }
+ break;
+ } /* switch */
+ } /* fi */
+
+ Graphic (); /* must return from ShowChar in graphics mode */
+}
+/* ShowChar */
+
+/*--------------------------------------------------------------------*/
+
+void
+ShowRectangle (int screenh, int screenv, int width, int height,
+ char ch)
+{
+ /* Display the given rectangle
+ (_without_ using the given black pixel character).
+ DVItoVDU ensures that the top left position is visible,
+ and that the given dimensions do not go beyond the window edges.
+ */
+
+ int i, endpt;
+
+ /* DVItoVDU ensures width and height > 0 */
+ if (height < width)
+ {
+ /* show row vectors */
+ endpt = screenh + width - 1;
+ for (i = 0; i < height; i++)
+ {
+ Graphic ();
+
+ SendXY (screenh, maxy - screenv - i); /* move cursor to start of row */
+ SendXY (endpt, maxy - screenv - i); /* draw vector to end of row */
+ }
+ }
+ else
+ {
+ /* show column vectors */
+ endpt = maxy - screenv - height + 1;
+ for (i = 0; i < width; i++)
+ {
+ Graphic ();
+
+ SendXY (screenh + i, maxy - screenv);
+ /* move cursor to start of column */
+ SendXY (screenh + i, endpt); /* draw vector to end of column */
+ }
+ }
+}
+/* ShowRectangle */
+
+/*--------------------------------------------------------------------*/
+
+void
+InitVDU ()
+{
+ vdu_clears_lines = false;
+ havesentxy = false; /* for first SendXY call */
+ charsize = 0; /* the default character size */
+ loadedsize = charsize; /* for first TEK4010StartGraphics call */
+ charwidth = 13; /* 1024 / 80 = 12.8 */
+ maxy = 779; /* some VDUs may want to change this */
+ lineht = 26; /* 30 text lines; 26 * 30 = 780 */
+ textlinewidth = 80; /* text characters per line */
+ /* The dialog region will be the top 4 text lines in Tek mode:
+ Line 1 = DVI status line,
+ Line 2 = window status line,
+ Line 3 = message line,
+ Line 4 = command line.
+ The window region will be text lines 5 to 33 in TEK mode.
+ gt - in NCSA Telnet in TEK mode on my monitor (Viewsonic 5E VGA),
+ only 30 lines fit. If we use line 33, it wraps around!
+ */
+
+ /* The following line numbers assume NCSA Telnet is in VT100 mode. */
+ DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */
+ windowstatusl = 2;
+ messagel = 3;
+ commandl = 4;
+#ifdef VIJAY_BOTTOML
+ bottoml = 33; /* also number of text lines on screen */
+#else /* according to gt's experience */
+ bottoml = 30; /* also number of text lines on screen */
+#endif
+
+ /* The following values assume NCSA Telnet is emulating
+ a Tektronix 4010.
+ Note that windowv must be given a value using DVItoVDU's
+ coordinate scheme, where top left pixel is (0,0).
+ */
+
+ /*
+ Approx. height, in TEK4010 pixels, of 4 text lines, viz. 92
+ (i.e. ~ 4 * 780/34), does not work in the case of NCSA Telnet's
+ Tek mode. Value 115 arrived at by pure trial and error.
+ */
+ windowv = 115;
+ windowh = 0;
+ windowht = 780 - windowv;
+ windowwd = 1024;
+
+ textlinewidth = 72; /* text characters per line - a guess */
+
+ WriteChar (GS);
+}
+/* InitTEK4010emu */
+
+/*--------------------------------------------------------------------*/
+
+/* end vdu.c */
diff --git a/dviware/dvgtk/vdu.h b/dviware/dvgtk/vdu.h
new file mode 100644
index 0000000000..431f7c8da0
--- /dev/null
+++ b/dviware/dvgtk/vdu.h
@@ -0,0 +1,87 @@
+/* vdu.h - VDU driver interface
+ $Id: vdu.h,v 0.2 1997/03/28 03:14:10 tjchol01 Exp $
+ Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo
+ */
+
+#ifndef VDU_H
+#define VDU_H
+
+#include "dvgt.h"
+
+/* VDU implements the screen-driving routines used by DVItoVDU.
+ InitVDU initializes the parameters for the VDU screen.
+ After starting up, DVItoVDU breaks the screen into 2 parts:
+
+ 1. The DIALOGUE REGION will consist of the top 4 text lines on the screen.
+ This region is used to display DVI and window status information,
+ various kinds of messages and the command prompt. DVItoVDU assumes
+ text lines on the screen start at 1 and increase downwards. The bottom
+ text line on the screen is given by the parameter bottoml (also the total
+ number of text lines).
+
+ 2. The WINDOW REGION is typically the remaining area of the screen and
+ is used to display some sort of representation of the current DVI page.
+ The user can move the window over any part of the current page,
+ or even completely outside the page edges (but only just).
+ The user can scale the page display by changing the width and height of
+ the window region; windowwd and windowht are the initial, unscaled
+ dimensions where one paper pixel equals one screen pixel.
+ When addressing screen pixels, DVItoVDU assumes the top left pixel
+ in the screen is 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) in this coordinate scheme.
+
+ The following diagram illustrates the screen coordinate system used by
+ DVItoVDU and shows what the VDU parameters refer to.
+
+ --> h increases to the right
+ h,v=(0,0) *------------------------------------------------
+ | DVIstatusl | top text line = 1
+ | | DIALOGUE REGION windowstatusl | (lines increase
+ V | messagel | downwards)
+ | commandl |
+ v * (windowh,windowv) ----------------------------| ---
+ increases | | |
+ down | | |
+ | | |
+ | | |
+ | WINDOW REGION | windowht
+ | contains windowwd * windowht pixels | |
+ | | |
+ | | |
+ | bottoml | |
+ ------------------------------------------------- ---
+
+ |------------------ windowwd -------------------|
+
+*/
+
+extern int DVIstatusl; /* DVI status line */
+extern int windowstatusl; /* window status line */
+extern int messagel; /* message line */
+extern int commandl; /* command line */
+extern int bottoml; /* bottom line; also num. of text lines in screen */
+
+extern int windowh; /* horizontal coord for window's top left screen pixel */
+extern int windowv; /* vertical coord for window's top left screen pixel */
+extern int windowwd; /* width of window in screen pixels */
+extern int windowht; /* height of window in screen pixels */
+
+extern boolean vdu_clears_lines; /* Can current VDU clear a single line? */
+
+extern void InitVDU ();
+extern void ClearScreen ();
+
+extern void StartText ();
+extern void MoveToTextLine PARAMS ((int line));
+extern void ClearTextLine PARAMS ((int line));
+extern void ClearScreen ();
+extern void StartGraphics ();
+extern void LoadFont PARAMS ((char *fontname, int fontsize, double mag, double hscale, double vscale));
+extern void ShowChar PARAMS ((int screenh, int screenv, char ch));
+extern void ShowRectangle PARAMS ((int screenh, int screenv, int width, int height, char ch));
+extern void ResetVDU ();
+
+#endif /* VDU_H */
+
+/* end vdu.h */
diff --git a/dviware/dvgtk/web2c-dvgtk.patch b/dviware/dvgtk/web2c-dvgtk.patch
new file mode 100644
index 0000000000..a30ba0eeaa
--- /dev/null
+++ b/dviware/dvgtk/web2c-dvgtk.patch
@@ -0,0 +1,55 @@
+*** ../texk-7.0-orig/configure Mon Feb 3 14:22:07 1997
+--- configure Fri Mar 21 19:29:56 1997
+***************
+*** 2111,2117 ****
+
+
+
+! subdirs="kpathsea dviljk dvipsk web2c xdvik"
+
+
+ trap '' 1 2 15
+--- 2111,2117 ----
+
+
+
+! subdirs="kpathsea dviljk dvipsk web2c xdvik dvgtk"
+
+
+ trap '' 1 2 15
+***************
+*** 2434,2440 ****
+ esac
+ done
+
+! for ac_config_dir in kpathsea dviljk dvipsk web2c xdvik; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+--- 2434,2440 ----
+ esac
+ done
+
+! for ac_config_dir in kpathsea dviljk dvipsk web2c xdvik dvgtk; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+*** ../texk-7.0-orig/Makefile.in Fri Feb 7 13:39:38 1997
+--- Makefile.in Fri Mar 21 19:54:31 1997
+***************
+*** 1,7 ****
+ # Top-level Makefile for kpathsea-using programs.
+
+ # Package subdirectories, the library, and all subdirectories.
+! programs = dviljk dvipsk web2c xdvik
+ kpathsea_dir = kpathsea
+ all_dirs = $(programs) $(kpathsea_dir)
+
+--- 1,7 ----
+ # Top-level Makefile for kpathsea-using programs.
+
+ # Package subdirectories, the library, and all subdirectories.
+! programs = dviljk dvipsk web2c xdvik dvgtk
+ kpathsea_dir = kpathsea
+ all_dirs = $(programs) $(kpathsea_dir)
+