summaryrefslogtreecommitdiff
path: root/systems/msdos/dviware/xdvi-dos
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 /systems/msdos/dviware/xdvi-dos
Initial commit
Diffstat (limited to 'systems/msdos/dviware/xdvi-dos')
-rw-r--r--systems/msdos/dviware/xdvi-dos/copying249
-rw-r--r--systems/msdos/dviware/xdvi-dos/copying.dj63
-rw-r--r--systems/msdos/dviware/xdvi-dos/read_dvx.tex79
-rw-r--r--systems/msdos/dviware/xdvi-dos/read_dvx.txt76
-rw-r--r--systems/msdos/dviware/xdvi-dos/readme268
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi.h62
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi_draw.c1049
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/dvi_init.c639
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/font_ope.c887
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/fontfmts.c21
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/fontsub.c62
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/gf.c294
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/makefile36
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/makefile.bak36
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/maketexp141
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/patchlev.h1
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/pk.c324
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/pxl.c166
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/tpic.c434
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/util.c216
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/vf.c123
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.c3175
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.h509
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.ico27
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h9
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h7
-rw-r--r--systems/msdos/dviware/xdvi-dos/texfonts.sub74
-rw-r--r--systems/msdos/dviware/xdvi-dos/xdvi.man396
28 files changed, 9423 insertions, 0 deletions
diff --git a/systems/msdos/dviware/xdvi-dos/copying b/systems/msdos/dviware/xdvi-dos/copying
new file mode 100644
index 0000000000..e038c461ac
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/copying
@@ -0,0 +1,249 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must tell them their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License. The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+ 7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+ 8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/systems/msdos/dviware/xdvi-dos/copying.dj b/systems/msdos/dviware/xdvi-dos/copying.dj
new file mode 100644
index 0000000000..3d87ae3ce2
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/copying.dj
@@ -0,0 +1,63 @@
+This is the file "copying.dj".
+
+ Copyright Information for sources and executables that are marked
+ Copyright (C) DJ Delorie
+ 24 Kirsten Ave
+ Rochester NH 03867-2954
+
+This document is Copyright (C) DJ Delorie and may be distributed
+verbatim, but changing it is not allowed.
+
+Source code copyright DJ Delorie is distributed under the terms of the
+GNU General Public Licence, with the following exceptions:
+
+
+* Source code copyright DJ Delorie is distributed under the terms of the
+ GNU General Public Licence, with the following exceptions:
+ ("go32.exe" refers to go32.exe and debug32.exe)
+
+ * There are no conditions on distributing copies of stub.exe as
+ it is originally distributed in this software package, prepended
+ onto a binary or otherwise. This is the recommended distribution
+ mechanism for applications.
+
+ * Binaries of emu387 may be distributed with no restrictions.
+
+ * If a user creates an application, prepends a copy of go32.exe onto
+ the beginning of it, and distributes it free of charge, then the
+ user is under no obligations to distribute source or pay royalties.
+ Note that the copyright terms of the FSF and/or UCB must be
+ obeyed regardless of this.
+
+ * If a user creates an application, prepends a copy of go32.exe onto
+ the beginning of it, and charges a fee for the software, then a
+ royalty of $5 or 5% of the selling price per copy sold must be paid
+ to DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954. Note that
+ shareware programs are not considered "sold" until payment is rendered
+ for them.
+
+ * For all other cases, source code for go32.exe must be distributed
+ with any distributed copies of go32.exe.
+
+ * Software that requires go32.exe to run, but is not distributed with
+ a copy of go32.exe, incurs no obligations with regards to the
+ above sections.
+
+ * Contact me for special terms if none of the above are suitable.
+
+ * Donations are always appreciated.
+
+ The intent of this copyright is this: If you make money by using the
+ programs I wrote, I get some of it. If you use your sources to
+ teach others how to write programs, I'll support you.
+
+Changes to source code copyright BSD or FSF are copyright DJ Delorie, but
+fall under the terms of the original copyright.
+
+A copy of the file "COPYING" is included with this document. If you did not
+receive a copy of "COPYING", you may obtain one from whence this document
+was obtained, or by writing:
+ Free Software Foundation
+ 675 Mass Ave
+ Cambridge, MA 02139
+ USA
diff --git a/systems/msdos/dviware/xdvi-dos/read_dvx.tex b/systems/msdos/dviware/xdvi-dos/read_dvx.tex
new file mode 100644
index 0000000000..18cd070d15
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/read_dvx.tex
@@ -0,0 +1,79 @@
+% This is a LaTeX file
+%
+% This file contains details of the XDVI port to DJGPP
+\documentstyle{article}
+\begin{document}
+
+
+\title{{\bf XDVI} for {\bf PC} under {\bf DV/X}}
+\author {Eric Ho \\ 9041477@SSCVAX.CIS.MCMASTER.CA}
+\maketitle
+
+This program is re-compiled using {\bf DJGPP}. As a result, the program
+expects 386 CPU and up with FPU as well as {\bf GO32}.
+Original {\bf XDVI} source is obtained from
+{\bf export.lcs.mit.edu:/contrib}.
+
+\section{Modifications}
+
+There are not many modifications done to the original xdvi except that
+fonts not available can now be substituted by specifying them in a file.
+The environmental variable {\bf TEXFONTSUB} points to this file. For example,
+{\bf TEXFONTSUB}=c:/xdvi/texfonts.sub". The filename texfonts.sub is arbitrary.
+One can rename it to some other name as long as the environmental variable
+TEXFONTSUB points to it. Format of the font substitute file (ASCII) is
+as follows:
+
+\vspace {10 pt}
+
+{\bf amr10} -$>$ {\bf cmr10}
+
+{\bf src2} -$>$ {\bf dest2}
+
+etc.
+\vspace {10 pt}
+
+where src2 is the unavailable font and dest2 is the font we intended to
+substitute. It is exactly as the font substitution machcanism found in
+{\bf DVIVGA}.
+
+For those interested in the image processing features provided by XDVI,
+please browse through the source and see if I did anything wrong
+in choosing suitable image quality since I do not know anything about
+image processing.
+
+Default \TeX font directory is "c:/tex/fonts." However, this can be overridden
+by specifying another directory through some environmental variable. Please
+look at the file {\it readme} for details.
+
+Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file. To
+use the other version one must re-compile the source. To obtain the other
+versions one must re-compile XDVI with appropiate switches set.
+
+\section{Optimizing XDVI}
+
+Opening and searching text file using DJGPP will add significant overhead
+to the execution due to mode switching. Also, I found most of substitutions
+are converting AM font to CM font (I only have cm font at home). Therefore,
+I also modified the program to convert amxxxx to cmxxxx internally to speed
+up execution. To choose this option one should recompile the source without
+defining {\bf FONTSUB} (i.e., take out -D{\bf FONTSUB} in the makefile). Finally,
+the makefile enclosed is compatible with both {\bf NDMAKE45}
+and Borlan?'s {\bf MAKE} utility.
+
+\section{Bugs}
+
+I have not yet found any bugs after I have performed some testings.
+However, I conducted the test without mouse attaching to my system (because I
+don't have one). Accordingly, I have no idea how XDVI will behave with mouse
+connected to the system. Finally, I tested only the {\bf pk} font version
+of XDVI, therefore the performance of using {\bf gf} and {\bf pxl} is unknown.
+
+\section{Acknowledgment}
+
+I wish to thank {\bf DJ, et. al.} for their excellent compiler. Also thank all
+authors of the original XDVI for their contribution.
+
+\end{document}
diff --git a/systems/msdos/dviware/xdvi-dos/read_dvx.txt b/systems/msdos/dviware/xdvi-dos/read_dvx.txt
new file mode 100644
index 0000000000..a0e076fd54
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/read_dvx.txt
@@ -0,0 +1,76 @@
+ XDVI for PC under DV/X
+ ----------------------
+
+
+This program is re-compiled using DJGPP. As a result, it expects 386 and
+up CPU with FPU as well as GO32. Original XDVI source is obtained from
+export.lcs.mit.edu:/contrib.
+==============================================================================
+
+Modifications
+-------------
+
+There are not many modifications done to the original xdvi except that
+fonts not available can now be substituted by specifying them in a file.
+The environmental variable "TEXFONTSUB" points to this file. For example,
+"TEXFONTSUB=c:\xdvi\texfonts.sub". The filename texfonts.sub is arbitrary.
+One can rename it to some other name as long as the environmental variable
+TEXFONTSUB points to it.
+
+
+Format of the font substitute (ASCII) file:
+
+amr10 -> cmr10
+src2 -> dest2
+ :
+ :
+
+where src2 is the unavailable font and dest2 is the font we intended to
+substitute. It is exactly as the font substitution machcanism found in
+DVIVGA.
+
+For those interested in the image processing features provided by XDVI,
+please browse through the source and see if I did anything wrong
+in choosing suitable image quality since I do not know anything about
+image processing.
+
+Default TeX font directory is "c:\tex\fonts." However, this can be overridden
+by specifying another directory through some environmental variable. Please
+look at the file "readme" for details.
+
+Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file.
+To obtain the other two versions one must re-compile XDVI with appropiate
+switches set.
+===============================================================================
+
+Optimizing the program
+----------------------
+
+Opening and searching text file using DJGPP will add significant overhead
+to the execution due to mode switching. Also, I found most of substitutions
+are converting AM font to CM font (I only have cm font at home). Therefore,
+I also modified the program to convert amxxxx to cmxxxx internally to speed
+up execution. To choose this option one should recompile the source without
+defining FONTSUB (i.e., take out -DFONTSUB in the makefile). Finally,
+the makefile enclosed is compatible with both NDMAKE45 and Borland's MAKE
+utility.
+===============================================================================
+
+Bugs
+----
+
+I have not yet found any bugs afte I have performed some testings. However,
+I conducted the test without mouse attaching to my system (because I do not
+ have one). Accordingly, I have no idea how XDVI will behave with mouse
+connected. Finally, I have tested only the "pk" font version of XDVI,
+therefore the performance of using "gf" and "pxl" is unknown. These two
+versions of XDVI are however also modified to look up font substitute file.
+===============================================================================
+
+Acknowledgment
+--------------
+
+I wish to thank DJ, et. al. for their excellent compiler. Also thank all
+authors of the original XDVI for their contribution.
diff --git a/systems/msdos/dviware/xdvi-dos/readme b/systems/msdos/dviware/xdvi-dos/readme
new file mode 100644
index 0000000000..8f07ff7d51
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/readme
@@ -0,0 +1,268 @@
+INSTALLATION INSTRUCTIONS
+
+To install, do the following:
+ 1. Read the ENVIRONMENT section of xdvi_man.sed to determine the correct
+ default values for the XDVIFONTS and XDVISIZES environment variables.
+ Edit the Imakefile or Makefile and change the values of the make
+ variables DEFAULT_FONT_PATH and DEFAULT_FONT_SIZES to these values.
+ If your site uses virtual fonts, do the same thing with the
+ DEFAULT_VF_PATH variable. Note that support of virtual fonts in xdvi
+ does not include support of built-in Postscript<tm> fonts.
+
+ (Note: for X10 compilation, use Makefile_10 instead of Makefile.)
+
+ You may also wish to change other compilation options; they are
+ described later in this file.
+
+ 2. make xdvi and try it out. If the settings in step one are incorrect,
+ you can use the corresponding environment variables to quickly try out
+ different values. If the values set in step 1 were incorrect,
+ rm font_open.o and go back to step 1.
+
+ If you get the error that the #include file <stdlib.h> does not exist,
+ then you should include -DX_NOT_STDC_ENV in the DEFS variable in the
+ Makefile or Imakefile. In X11R5 or later this problem should not
+ come up.
+
+ 3. make xdvi.man.
+
+ 4. Install xdvi and xdvi.man.
+
+
+ The X10 flag only affects xdvi.c (and the flags MSBITFIRST, BMSHORT,
+ and BMLONG, see below).
+
+ Note in particular the compilation flags USE_PK, USE_GF, and USE_PXL,
+ which can be set to reflect which font formats are actually used at
+ your site.
+
+Other compilation flags are:
+ SYSV (dvi_init.c font_open.c xdvi.c) Set for System V
+ compilation.
+ VMS Set for VMS compilation.
+ MSBITFIRST (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps internally with the most significant bit at
+ the left. For performance reasons, it would be best
+ to set this to coincide with what your server uses.
+ Use the keystroke '^P' to find information in this
+ regard. Generally, you should use MSBITFIRST if and
+ only if '^P' reports bitord = 1, and BMSHORT/BMLONG
+ (below) should be set to match whatever '^P' reports
+ under "Unit =". But, if bitord = byteord, then the
+ latter setting should not matter much.
+ BMSHORT (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps in short integers instead of bytes. See
+ MSBITFIRST for other relevant comments. To check
+ performance, you can use:
+ time xdvi -d 8 file.dvi
+ BMLONG (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
+ bitmaps in long integers instead of bytes.
+ ALTFONT (xdvi.c) Default font to use if the font named in the
+ dvi file cannot be found. Can be set to NULL. By
+ default, it is "cmr10".
+ SEARCH_SUBDIRECTORIES (font_open.c) Enable recursive searching of
+ subdirectories for font files (* and ** specifiers).
+ This also enables the TEXFONTS_SUBDIR environment
+ variable and the DEFAULT_SUBDIR_PATH makefile variable.
+ XDVIFONTS_ONLY (font_open.c) Never check the TEXFONTS environment
+ variable. Normally xdvi checks TEXFONTS if the
+ XDVIFONTS variable is not set. This option is
+ recommended if the version of TeX in use requires
+ that the TEXFONTS variable be set. See the relevant
+ paragraph in xdvi_man.sed for more details. This
+ option turns off that paragraph.
+ NOTOOL (X11 only; xdvi.c) Compile using raw X calls.
+ BUTTONS (xdvi.c) Put radio buttons on the right side of the
+ window for commonly used commands.
+ A4 (xdvi.c) Use European size paper by default.
+ NOQUERY (xdvi.c) Set this if you have trouble compiling the
+ definition of drawingWidgetClass.
+ TEXXET (everything) Enables op-codes 250 and 251 (used for
+ right-to-left languages).
+ BDPI (xdvi.c) Default number of pixels per inch to use.
+ GREY (everything) Use greyscale anti-aliasing for
+ displaying shrunken bitmaps.
+ MAKEPK (font_open.c) If a font is not found, then try to
+ call Metafont to create the font. When using this
+ option, remember to set the paths in MakeTeXPK
+ correctly for your site, and be sure that the
+ destination directory for MakeTeXPK appears in your
+ DEFAULT_FONT_PATH variable.
+ MAKEPKCMD=\"/usr/local/tex/bin/MakeTeXPK\" (font_open.c) Same as the
+ above, but this variant explicitly declares which
+ command to use to create the font.
+
+All flags should be set in the appropriate Makefile via the variable ``DEFS''.
+
+================================================================
+
+ This program is the combined work of many people, including but not
+restricted to:
+ Eric Cooper, CMU
+ Bob Scheifler, MIT LCS
+ Paal Kvamme, Norwegian Institute of Technology
+ H\aa vard Eidnes, Norwegian Institute of Technology
+ Mark Eichin, MIT SIPB
+ Paul Vojta, UC Berkeley
+ Jeffrey Lee, U of Toronto
+ Donald Richardson, Clarkson Univ.
+At the present time, the person to send bug reports to is Paul Vojta,
+ vojta@math.berkeley.edu.
+
+In addition to the various comp.sources.x archives, current versions of this
+program can also be obtained via anonymous ftp from the following location:
+ export.lcs.mit.edu [18.24.0.12] file contrib/xdvi.tar.Z
+To ease the load on export, you may also check other X archives, for example:
+ gatekeeper.dec.com [16.1.0.2] file pub/X11/contrib/xdvi.tar.Z
+
+Paul Vojta, 17 March 1992
+
+================================================================
+
+Note for IBM RS6000 users: some of the libraries are in non-obvious places:
+
+ libXmu /usr/lpp/X11/Xamples/lib/Xmu/libXmu.a
+ libXaw /usr/lpp/X11/Xamples/lib/Xaw/libXaw.a
+
+These should be moved to /usr/lib or some more reasonable place (or use
+symlinks), and ditto for the include files, which are initially placed
+in /usr/lpp/X11/Xamples/include.
+
+================================================================
+
+Notes of historical nature follow. Most recent changes are listed at the end
+of the file.
+
+================================================================
+
+This directory contains a version of xdvi capable of reading GF, PXL
+and PK font files. This version of xdvi is based on the source that
+"came with" X v10r3. Xdvi was modified by Paal Kvamme at the Norwegian
+Institute of Technology, based on the modifications I had made to
+dviimp (a dvi to ImPress converter). This code was again more or less
+directly translated from the web source of PKtoPX.
+
+If you discover (and fix) any bugs in this code, please notify me, so
+I can make the corresponding changes myself.
+
+---------
+H}vard Eidnes (TeXish: H\aa vard Eidnes)
+Division of Computer Science
+Norwegian Institute of Technology
+
+E-Mail: h_eidnes%vax.runit.unit.uninett@nta-vax.arpa
+================================================================
+Also has path search added by Mark Eichin, looks in TEXFONTS
+================================================================
+
+================================================================
+Additional notes:
+ X11 version now works on the IBM PC/RT as well as VAX.
+ [eichin:19880313.1330EST]
+================================================================
+*MORE* fixes (for athena release locker) [eichin:19880722.2058EST]
+Fixes:
+ narrow vertical and horizontal lines no longer disappear.
+ bogus underlining (which usually occured on even sample sizes
+of odd sized characters) no longer occurs.
+ -S number (or typing number followed by S) will adjust the
+sampling fraction; 0 is special cased to mean if anything in the
+sampled zone is set, set the sample, else clear it. Interesting to
+experiment with, though not useful for reading (the default value of 3
+is just right.)
+ -display and -geometry arguments work (so do old style forms,
+though they were broken before)
+ fixed one of the PK debugging messages to print the correct
+font name instead of printing the pointer as text.
+ included Ken Raeburn <raeburn>'s changes to support multiple
+screens.
+================================================================
+More changes:
+
+ 1. Incorporated the bitmap under a viewport widget using the toolkit
+ (X11 only);
+ 2. Added an icon and icon geometry arguments (X11 only);
+ 3. Supported window resizing;
+ 4. Added a 'c' option to move whatever is currently under the cursor to
+ the center of the window;
+ 5. Added an 'R' option to reread the .dvi file, and added logic to make
+ 'R' happen automatically whenever any part of the window is exposed
+ and the dvi file changes (so that you can iconify xdvi, run tex,
+ deiconify xdvi, and voila!);
+ 6. Added a 'magnifying glass': when you push a button, a window pops
+ up, showing the region of the page, unshrunk;
+ 7. Added support for gf fonts;
+ 8. Upgraded font searching (at our site we use /usr/custom/tex82/gf
+ for gf fonts, /usr/custom/tex82/pk for pk fonts, etc.);
+ 9. Made numerous internal changes (removed all the lint I could,
+ made unshrunk bitmaps permanently resident, which speeds up size
+ changing, made table.h necessary only for pxl.h, split up the source
+ file into xdvi.c, dvi.c, gf.c, pxl.c, and pk.c, made shrinking occur
+ relative to the character's hot point, etc.)
+ 10. The program reads SIGIO signals and processes incoming events
+ immediately, so that it can stop displaying things that would be
+ erased anyway. If these interrupts are not coming through, then
+ it also checks for incoming events every several dozen characters
+ displayed.
+ 11. Further split up dvi.c into dvi_init.c and dvi_draw.c; added
+ compilation options for various internal bitmap representations.
+ Fixed it so gcc won't give warnings, and so it works with R3 toolkit.
+-- Patchlevel 2: --
+ 12. Added MAXCHARS compilation option. Eliminated the nonsense with
+ generating table.h.
+-- Patchlevel 3: --
+ 13. Added -altfont command line option and SYSV compilation option.
+================================================================================
+
+4/1989 Modified for System V boxes. -DSYSV compiler option.
+
+Donald Richardson, donr@crystal.mie.clarkson.edu
+
+================================================================================
+-- Patchlevel 4: --
+ 14. Removed MAXCHARS compilation option. It's automatic now. Made X10
+ scrolling smoother. Implemented the moving magnifying glass.
+-- Patchlevel 5: --
+ 15. Implemented compilation without the toolkit, as well as scrollbars
+ and tpic support in X10. Also this version should work with color
+ VAXstations, although overstrike characters will come out incorrectly.
+ 16. Fixed a bug in gf reading routines: specials at the beginning of
+ a character def. were not being processed. Thanks to
+ kevin@amath.washington.edu for a bug report and fix.
+ 17. Added 'k' keystroke.
+-- Patchlevel 6: --
+ 18. Added buttons on the right side of the window.
+ 19. Added -pagewidth and -pageheight command line options and A4
+ compilation option.
+ 20. Added a yet more robust font finding algorithm.
+-- Patchlevel 7: --
+ 21. Replaced -pagewidth and -pageheight options with -paper.
+-- Patchlevel 8: --
+ 22. Added compatibility for X11R4 and VMS. Fixed up alignment of rules.
+-- Patchlevel 9: --
+ 23. Removed obsolete '#' and '=' options from the X11 version: they
+ interfere with emacs.
+-- Patchlevel 10: --
+ 24. Implemented arrow keys, expert mode, searching for the font's actual
+ size first, the -[xy]offset and -sw options, and numerous bug fixes.
+-- Patchlevel 11: --
+ 25. Implemented recursive searching for font files in subdirectories.
+ 26. Changed +sw to -hushspecials and implemented -hush.
+ 27. Modified mksedscript so that the man page comes out neater.
+ 28. Added a -keep option and resource to match the `k' keystroke.
+-- Patchlevel 12: --
+ 29. Implemented virtual fonts (this does not include built-in
+ Postscript<tm> fonts!!!).
+ 30. X11R5 support, and numerous bug fixes.
+-- Patchlevel 13: --
+ 31. Added support for TeXXeT.
+-- Patchlevel 14: --
+ 32. Added support for greyscale anti-aliasing.
+-- Patchlevel 15: --
+ 33. Added support for MakeTeXPK, as in dvips.
+-- Patchlevel 16: --
+ 34. In the code for greyscale anti-aliasing, try to allocate a colormap
+ so that GXor operations can be used for drawing. Also interpolate
+ between foreground and background colors.
+
+Paul Vojta, vojta@math.berkeley.edu
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi.h b/systems/msdos/dviware/xdvi-dos/src/dvi.h
new file mode 100644
index 0000000000..ca2b7bc78b
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi.h
@@ -0,0 +1,62 @@
+/*
+ * Mnemonics for bytes in dvi file.
+ */
+
+#define SETCHAR0 0
+#define SET1 128
+#define SETRULE 132
+#define PUT1 133
+#define PUTRULE 137
+#define NOP 138
+#define BOP 139
+#define EOP 140
+#define PUSH 141
+#define POP 142
+#define RIGHT1 143
+#define RIGHT2 144
+#define RIGHT3 145
+#define RIGHT4 146
+#define W0 147
+#define W1 148
+#define W2 149
+#define W3 150
+#define W4 151
+#define X0 152
+#define X1 153
+#define X2 154
+#define X3 155
+#define X4 156
+#define DOWN1 157
+#define DOWN2 158
+#define DOWN3 159
+#define DOWN4 160
+#define Y0 161
+#define Y1 162
+#define Y2 163
+#define Y3 164
+#define Y4 165
+#define Z0 166
+#define Z1 167
+#define Z2 168
+#define Z3 169
+#define Z4 170
+#define FNTNUM0 171
+#define FNT1 235
+#define FNT2 236
+#define FNT3 237
+#define FNT4 238
+#define XXX1 239
+#define XXX2 240
+#define XXX3 241
+#define XXX4 242
+#define FNTDEF1 243
+#define FNTDEF2 244
+#define FNTDEF3 245
+#define FNTDEF4 246
+#define PRE 247
+#define POST 248
+#define POSTPOST 249
+#define SREFL 250
+#define EREFL 251
+
+#define TRAILER 223 /* Trailing bytes at end of file */
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c b/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c
new file mode 100644
index 0000000000..4c8b0989a7
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi_draw.c
@@ -0,0 +1,1049 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+#include <ctype.h>
+#include "xdvi.h"
+#include "dvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+#if NeedVarargsPrototypes /* this is for tell_oops */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DOPRNT /* define this if vfprintf gives you trouble */
+#define vfprintf(stream, message, args) _doprnt(message, args, stream)
+#endif
+
+static struct frame frame0; /* dummy head of list */
+#ifdef TEXXET
+static struct frame *scan_frame; /* head frame for scanning */
+#endif
+
+#ifndef DVI_BUFFER_LEN
+#define DVI_BUFFER_LEN 512
+#endif
+
+static ubyte dvi_buffer[DVI_BUFFER_LEN];
+static struct frame *current_frame;
+
+#ifndef TEXXET
+#define DIR 1
+#else
+#define DIR currinf.dir
+#endif
+
+/*
+ * Explanation of the following constant:
+ * offset_[xy] << 16: margin (defaults to one inch)
+ * shrink_factor << 16: one pixel page border
+ * shrink_factor << 15: rounding for pixel_conv
+ */
+#define OFFSET_X (offset_x << 16) + (shrink_factor * 3 << 15)
+#define OFFSET_Y (offset_y << 16) + (shrink_factor * 3 << 15)
+
+#ifndef BMLONG
+#ifndef BMSHORT
+unsigned char bit_masks[9] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff
+};
+#else /* BMSHORT */
+unsigned short bit_masks[17] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff, 0x1ff, 0x3ff, 0x7ff,
+ 0xfff, 0x1fff, 0x3fff, 0x7fff,
+ 0xffff
+};
+#endif /* BMSHORT */
+#else /* BMLONG */
+unsigned long bit_masks[33] = {
+ 0x0, 0x1, 0x3, 0x7,
+ 0xf, 0x1f, 0x3f, 0x7f,
+ 0xff, 0x1ff, 0x3ff, 0x7ff,
+ 0xfff, 0x1fff, 0x3fff, 0x7fff,
+ 0xffff, 0x1ffff, 0x3ffff, 0x7ffff,
+ 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
+ 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff,
+ 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ 0xffffffff
+};
+#endif /* BMLONG */
+
+#ifdef VMS
+#define off_t int
+#endif
+extern off_t lseek();
+
+#ifndef SEEK_SET /* if <unistd.h> is not provided (or for <X11R5) */
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+static void draw_part();
+
+/*
+ * Byte reading routines for dvi file.
+ */
+
+#define xtell(pos) (lseek(fileno(dvi_file), 0L, SEEK_CUR) - \
+ (currinf.end - (pos)))
+
+static ubyte
+xxone()
+{
+ if (currinf.virtual) {
+ ++currinf.pos;
+ return EOP;
+ }
+ currinf.end = dvi_buffer +
+ read(fileno(dvi_file), (char *) (currinf.pos = dvi_buffer),
+ DVI_BUFFER_LEN);
+ return currinf.end > dvi_buffer ? *(currinf.pos)++ : EOF;
+}
+
+#define xone() (currinf.pos < currinf.end ? *(currinf.pos)++ : xxone())
+
+static unsigned long
+xnum(size)
+ register ubyte size;
+{
+ register long x = 0;
+
+ while (size--) x = (x << 8) | xone();
+ return x;
+}
+
+static long
+xsnum(size)
+ register ubyte size;
+{
+ register long x;
+
+#ifdef __STDC__
+ x = (signed char) xone();
+#else
+ x = xone();
+ if (x & 0x80) x -= 0x100;
+#endif
+ while (--size) x = (x << 8) | xone();
+ return x;
+}
+
+#define xsfour() xsnum(4)
+
+static void
+xskip(offset)
+ long offset;
+{
+ currinf.pos += offset;
+ if (!currinf.virtual && currinf.pos > currinf.end)
+ (void) lseek(fileno(dvi_file), (long) (currinf.pos - currinf.end),
+ SEEK_CUR);
+}
+
+#if NeedVarargsPrototypes
+static NORETURN void
+tell_oops(_Xconst char *message, ...)
+#else
+/* VARARGS */
+static NORETURN void
+tell_oops(va_alist)
+ va_dcl
+#endif
+{
+#if !NeedVarargsPrototypes
+ _Xconst char *message;
+#endif
+ va_list args;
+
+ Fprintf(stderr, "%s: ", prog);
+#if NeedVarargsPrototypes
+ va_start(args, message);
+#else
+ va_start(args);
+ message = va_arg(args, _Xconst char *);
+#endif
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ if (currinf.virtual)
+ Fprintf(stderr, " in virtual font %s\n", currinf.virtual->fontname);
+ else
+ Fprintf(stderr, ", offset %ld\n", xtell(currinf.pos - 1));
+ exit(1);
+}
+
+
+/*
+ * Code for debugging options.
+ */
+
+static void
+print_bitmap(bitmap)
+ register struct bitmap *bitmap;
+{
+ register BMUNIT *ptr = (BMUNIT *) bitmap->bits;
+ register int x, y, i;
+
+ if (ptr == NULL) oops("print_bitmap called with null pointer.");
+ Printf("w = %d, h = %d, bytes wide = %d\n",
+ bitmap->w, bitmap->h, bitmap->bytes_wide);
+ for (y = 0; y < bitmap->h; ++y) {
+ for (x = bitmap->bytes_wide; x > 0; x -= BYTES_PER_BMUNIT) {
+#ifndef MSBITFIRST
+ for (i = 0; i < BITS_PER_BMUNIT; ++i)
+#else
+ for (i = BITS_PER_BMUNIT - 1; i >= 0; --i)
+#endif
+ Putchar((*ptr & (1 << i)) ? '@' : ' ');
+ ++ptr;
+ }
+ Putchar('\n');
+ }
+}
+
+static void
+print_char(ch, g)
+ ubyte ch;
+ struct glyph *g;
+{
+ Printf("char %d", ch);
+ if (isprint(ch))
+ Printf(" (%c)", ch);
+ Putchar('\n');
+ Printf("x = %d, y = %d, dvi = %ld\n", g->x, g->y, g->dvi_adv);
+ print_bitmap(&g->bitmap);
+}
+
+static _Xconst char *dvi_table1[] = {
+ "SET1", NULL, NULL, NULL, "SETRULE", "PUT1", NULL, NULL,
+ NULL, "PUTRULE", "NOP", "BOP", "EOP", "PUSH", "POP", "RIGHT1",
+ "RIGHT2", "RIGHT3", "RIGHT4", "W0", "W1", "W2", "W3", "W4",
+ "X0", "X1", "X2", "X3", "X4", "DOWN1", "DOWN2", "DOWN3",
+ "DOWN4", "Y0", "Y1", "Y2", "Y3", "Y4", "Z0", "Z1",
+ "Z2", "Z3", "Z4"};
+
+static _Xconst char *dvi_table2[] = {
+ "FNT1", "FNT2", "FNT3", "FNT4", "XXX1", "XXX2", "XXX3", "XXX4",
+ "FNTDEF1", "FNTDEF2", "FNTDEF3", "FNTDEF4", "PRE", "POST", "POSTPOST",
+ "SREFL", "EREFL", NULL, NULL, NULL, NULL};
+
+static void
+print_dvi(ch)
+ ubyte ch;
+{
+ _Xconst char *s;
+
+ Printf("%4d %4d ", PXL_H, PXL_V);
+ if (ch <= SETCHAR0 + 127) {
+ Printf("SETCHAR%-3d", ch - SETCHAR0);
+ if (isprint(ch))
+ Printf(" (%c)", ch);
+ Putchar('\n');
+ return;
+ }
+ else if (ch < FNTNUM0) s = dvi_table1[ch - 128];
+ else if (ch <= FNTNUM0 + 63) {
+ Printf("FNTNUM%d\n", ch - FNTNUM0);
+ return;
+ }
+ else s = dvi_table2[ch - (FNTNUM0 + 64)];
+ if (s) Puts(s);
+ else
+ tell_oops("unknown op-code %d", ch);
+}
+
+
+/*
+ * Count the number of set bits in a given region of the bitmap
+ */
+
+char sample_count[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+static int
+sample(bits, bytes_wide, bit_skip, w, h)
+ BMUNIT *bits;
+ int bytes_wide, bit_skip, w, h;
+{
+ BMUNIT *ptr, *endp;
+ register BMUNIT *cp;
+ int bits_left;
+ register int n, bit_shift, wid;
+
+ ptr = bits + bit_skip / BITS_PER_BMUNIT;
+ endp = ADD(bits, h * bytes_wide);
+ bits_left = w;
+#ifndef MSBITFIRST
+ bit_shift = bit_skip % BITS_PER_BMUNIT;
+#else
+ bit_shift = BITS_PER_BMUNIT - bit_skip % BITS_PER_BMUNIT;
+#endif
+ n = 0;
+ while (bits_left) {
+#ifndef MSBITFIRST
+ wid = BITS_PER_BMUNIT - bit_shift;
+#else
+ wid = bit_shift;
+#endif
+ if (wid > bits_left) wid = bits_left;
+ if (wid > 4) wid = 4;
+#ifdef MSBITFIRST
+ bit_shift -= wid;
+#endif
+ for (cp = ptr; cp < endp; cp = ADD(cp, bytes_wide))
+ n += sample_count[(*cp >> bit_shift) & bit_masks[wid]];
+#ifndef MSBITFIRST
+ bit_shift += wid;
+ if (bit_shift == BITS_PER_BMUNIT) {
+ bit_shift = 0;
+ ++ptr;
+ }
+#else
+ if (bit_shift == 0) {
+ bit_shift = BITS_PER_BMUNIT;
+ ++ptr;
+ }
+#endif
+ bits_left -= wid;
+ }
+ return n;
+}
+
+#ifdef GREY
+static void
+shrink_glyph_grey(g)
+ register struct glyph *g;
+{
+ int rows_left, rows, init_cols, cols_left;
+ register int cols;
+ int x, y;
+ long thesample;
+ BMUNIT *old_ptr;
+
+ /* These machinations ensure that the character is shrunk according to
+ its hot point, rather than its upper left-hand corner. */
+ g->x2 = g->x / shrink_factor;
+ init_cols = g->x - g->x2 * shrink_factor;
+ if (init_cols <= 0) init_cols += shrink_factor;
+ else ++g->x2;
+ g->bitmap2.w = g->x2 + ROUNDUP(g->bitmap.w - g->x, shrink_factor);
+ /* include row zero with the positively numbered rows */
+ cols = g->y + 1; /* spare register variable */
+ g->y2 = cols / shrink_factor;
+ rows = cols - g->y2 * shrink_factor;
+ if (rows <= 0) {
+ rows += shrink_factor;
+ --g->y2;
+ }
+ g->bitmap2.h = g->y2 + ROUNDUP(g->bitmap.h - cols, shrink_factor) + 1;
+
+ g->image2 = XCreateImage(DISP, DefaultVisualOfScreen(SCRN),
+ DefaultDepthOfScreen(SCRN),
+ ZPixmap, 0, (char *) NULL,
+ g->bitmap2.w, g->bitmap2.h,
+ BITS_PER_BMUNIT, 0);
+ g->pixmap2 = g->image2->data = xmalloc((unsigned)
+ g->image2->bytes_per_line * g->bitmap2.h,
+ "character pixmap");
+
+ old_ptr = (BMUNIT *) g->bitmap.bits;
+ rows_left = g->bitmap.h;
+ y = 0;
+ while (rows_left) {
+ x = 0;
+ if (rows > rows_left) rows = rows_left;
+ cols_left = g->bitmap.w;
+ cols = init_cols;
+ while (cols_left) {
+ if (cols > cols_left) cols = cols_left;
+
+ thesample = sample(old_ptr, g->bitmap.bytes_wide,
+ g->bitmap.w - cols_left, cols, rows);
+ XPutPixel(g->image2, x, y, pixeltbl[thesample]);
+
+ cols_left -= cols;
+ cols = shrink_factor;
+ x++;
+ }
+ *((char **) &old_ptr) += rows * g->bitmap.bytes_wide;
+ rows_left -= rows;
+ rows = shrink_factor;
+ y++;
+ }
+
+ while (y < g->bitmap2.h) {
+ for (x = 0; x < g->bitmap2.w; x++)
+ XPutPixel(g->image2, x, y, *pixeltbl);
+ y++;
+ }
+
+ g->y2 = g->y / shrink_factor;
+}
+#endif /* GREY */
+
+static void
+shrink_glyph(g)
+ register struct glyph *g;
+{
+ int shrunk_bytes_wide, shrunk_height;
+ int rows_left, rows, init_cols, cols_left;
+ register int cols;
+ BMUNIT *old_ptr, *new_ptr;
+ register BMUNIT m, *cp;
+ int min_sample = shrink_factor * shrink_factor * density / 100;
+
+ /* These machinations ensure that the character is shrunk according to
+ its hot point, rather than its upper left-hand corner. */
+ g->x2 = g->x / shrink_factor;
+ init_cols = g->x - g->x2 * shrink_factor;
+ if (init_cols <= 0) init_cols += shrink_factor;
+ else ++g->x2;
+ g->bitmap2.w = g->x2 + ROUNDUP(g->bitmap.w - g->x, shrink_factor);
+ /* include row zero with the positively numbered rows */
+ cols = g->y + 1; /* spare register variable */
+ g->y2 = cols / shrink_factor;
+ rows = cols - g->y2 * shrink_factor;
+ if (rows <= 0) {
+ rows += shrink_factor;
+ --g->y2;
+ }
+ g->bitmap2.h = shrunk_height = g->y2 +
+ ROUNDUP(g->bitmap.h - cols, shrink_factor) + 1;
+ alloc_bitmap(&g->bitmap2);
+ old_ptr = (BMUNIT *) g->bitmap.bits;
+ new_ptr = (BMUNIT *) g->bitmap2.bits;
+ shrunk_bytes_wide = g->bitmap2.bytes_wide;
+ rows_left = g->bitmap.h;
+ bzero((char *) new_ptr, shrunk_bytes_wide * shrunk_height);
+ while (rows_left) {
+ if (rows > rows_left) rows = rows_left;
+ cols_left = g->bitmap.w;
+#ifndef MSBITFIRST
+ m = (1 << 0);
+#else
+ m = (1 << (BITS_PER_BMUNIT-1));
+#endif
+ cp = new_ptr;
+ cols = init_cols;
+ while (cols_left) {
+ if (cols > cols_left) cols = cols_left;
+ if (sample(old_ptr, g->bitmap.bytes_wide,
+ g->bitmap.w - cols_left, cols, rows) >= min_sample)
+ *cp |= m;
+#ifndef MSBITFIRST
+ if (m == (BMUNIT)(1 << (BITS_PER_BMUNIT-1))) {
+ m = (1 << 0);
+ ++cp;
+ }
+ else m <<= 1;
+#else
+ if (m == (1 << 0)) {
+ m = (1 << (BITS_PER_BMUNIT-1));
+ ++cp;
+ }
+ else m >>= 1;
+#endif
+ cols_left -= cols;
+ cols = shrink_factor;
+ }
+ *((char **) &new_ptr) += shrunk_bytes_wide;
+ *((char **) &old_ptr) += rows * g->bitmap.bytes_wide;
+ rows_left -= rows;
+ rows = shrink_factor;
+ }
+ g->y2 = g->y / shrink_factor;
+ if (debug & DBG_BITMAP)
+ print_bitmap(&g->bitmap2);
+}
+
+/*
+ * Find font #n.
+ */
+
+static void
+change_font(n)
+ unsigned long n;
+{
+ register struct tn *tnp;
+
+ currinf.fontp = NULL;
+ for (tnp = currinf.tn_head; tnp != NULL; tnp = tnp->next)
+ if (tnp->TeXnumber == n) {
+ currinf.fontp = tnp->fontp;
+ if (!(currinf.fontp->flags & FONT_LOADED))
+ load_font(currinf.fontp);
+ break;
+ }
+ if (currinf.fontp == NULL) tell_oops("non-existent font #%d", n);
+ maxchar = currinf.fontp->maxchar;
+ currinf.set_char_p = currinf.fontp->set_char_p;
+}
+
+
+/*
+ * Open a font file.
+ */
+
+static void
+open_font_file(fontp)
+ struct font *fontp;
+{
+ if (fontp->file == NULL) {
+ fontp->file = xfopen(fontp->filename);
+ if (fontp->file == NULL)
+ oops("Font file disappeared: %s", fontp->filename);
+ }
+}
+
+
+/*
+ * Routines to print characters.
+ */
+
+#ifndef TEXXET
+#define ERRVAL 0L
+#else
+#define ERRVAL
+#endif
+
+#ifndef TEXXET
+long
+set_char(ch)
+#else
+void
+set_char(cmd, ch)
+ WIDEARG(ubyte, int) cmd;
+#endif
+ WIDEARG(ubyte, int) ch;
+{
+ register struct glyph *g;
+#ifdef TEXXET
+ long dvi_h_sav;
+#endif
+
+ if (ch > maxchar) realloc_font(currinf.fontp, WIDEARG(,(int)) ch);
+ if ((g = &currinf.fontp->glyph[ch])->bitmap.bits == NULL) {
+ if (g->addr == 0) {
+ if (!hush_chars)
+ Fprintf(stderr, "Character %d not defined in font %s\n", ch,
+ currinf.fontp->fontname);
+ g->addr = -1;
+ return ERRVAL;
+ }
+ if (g->addr == -1)
+ return ERRVAL; /* previously flagged missing char */
+ open_font_file(currinf.fontp);
+ Fseek(currinf.fontp->file, g->addr, 0);
+ (*currinf.fontp->read_char)(currinf.fontp, ch);
+ if (debug & DBG_BITMAP) print_char((ubyte) ch, g);
+ currinf.fontp->timestamp = ++current_timestamp;
+ }
+
+#ifdef TEXXET
+ dvi_h_sav = DVI_H;
+ if (currinf.dir < 0) DVI_H -= g->dvi_adv;
+ if (scan_frame == NULL) {
+#endif
+ if (shrink_factor == 1)
+ put_bitmap(&g->bitmap, PXL_H - g->x, PXL_V - g->y);
+ else {
+#ifdef GREY
+ if (use_grey) {
+ if (g->pixmap2 == NULL) {
+ shrink_glyph_grey(g);
+ }
+ put_image(g->image2, PXL_H - g->x2, PXL_V - g->y2);
+ } else {
+ if (g->bitmap2.bits == NULL) {
+ shrink_glyph(g);
+ }
+ put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
+ }
+#else
+ if (g->bitmap2.bits == NULL) {
+ shrink_glyph(g);
+ }
+ put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
+#endif
+ }
+#ifndef TEXXET
+ return g->dvi_adv;
+#else
+ }
+ if (cmd == PUT1)
+ DVI_H = dvi_h_sav;
+ else
+ if (currinf.dir > 0) DVI_H += g->dvi_adv;
+#endif
+}
+
+
+#ifndef TEXXET
+long
+set_vf_char(ch)
+#else
+void
+set_vf_char(cmd, ch)
+ WIDEARG(ubyte, int) cmd;
+#endif
+ WIDEARG(ubyte, int) ch;
+{
+ register struct macro *m;
+ struct drawinf oldinfo;
+ ubyte oldmaxchar;
+ static ubyte c;
+#ifdef TEXXET
+ long dvi_h_sav;
+#endif
+
+ if (ch > maxchar) realloc_virtual_font(currinf.fontp, ch);
+ if ((m = &currinf.fontp->macro[ch])->pos == NULL) {
+ if (!hush_chars)
+ Fprintf(stderr, "Character %d not defined in font %s\n", ch,
+ currinf.fontp->fontname);
+ m->pos = m->end = &c;
+ return ERRVAL;
+ }
+#ifdef TEXXET
+ dvi_h_sav = DVI_H;
+ if (currinf.dir < 0) DVI_H -= m->dvi_adv;
+ if (scan_frame == NULL) {
+#endif
+ oldinfo = currinf;
+ oldmaxchar = maxchar;
+ WW = XX = YY = ZZ = 0;
+ currinf.tn_head = currinf.fontp->vf_chain;
+ currinf.pos = m->pos;
+ currinf.end = m->end;
+ currinf.virtual = currinf.fontp;
+ draw_part(current_frame, currinf.fontp->dimconv);
+ if (currinf.pos != currinf.end + 1)
+ tell_oops("virtual character macro does not end correctly");
+ currinf = oldinfo;
+ maxchar = oldmaxchar;
+#ifndef TEXXET
+ return m->dvi_adv;
+#else
+ }
+ if (cmd == PUT1)
+ DVI_H = dvi_h_sav;
+ else
+ if (currinf.dir > 0) DVI_H += m->dvi_adv;
+#endif
+}
+
+
+#ifndef TEXXET
+static long
+set_no_char(ch)
+#else
+static void
+set_no_char(cmd, ch)
+ ubyte cmd;
+#endif
+ ubyte ch;
+{
+ if (currinf.virtual) {
+ currinf.fontp = currinf.virtual->first_font;
+ if (currinf.fontp != NULL) {
+ if (!(currinf.fontp->flags & FONT_LOADED))
+ load_font(currinf.fontp);
+ maxchar = currinf.fontp->maxchar;
+ currinf.set_char_p = currinf.fontp->set_char_p;
+#ifndef TEXXET
+ return (*currinf.set_char_p)(ch);
+#else
+ (*currinf.set_char_p)(cmd, ch);
+ return;
+#endif
+ }
+ }
+ tell_oops("attempt to set character of unknown font");
+ /* NOTREACHED */
+}
+
+
+/*
+ * Set rule. Arguments are coordinates of lower left corner.
+ */
+
+static void
+set_rule(h, w)
+ int h, w;
+{
+#ifndef TEXXET
+ put_rectangle(PXL_H, PXL_V - h + 1, w, h, False);
+#else
+ put_rectangle(PXL_H - (currinf.dir < 0 ? w - 1 : 0), PXL_V - h + 1,
+ w, h, False);
+#endif
+}
+
+static void
+put_border(w, h)
+ int w, h;
+{
+ put_rectangle(0, 0, w, 1, True); /* top */
+ put_rectangle(w, 0, 1, h, True); /* right */
+ put_rectangle(1, h, w, 1, True); /* bottom */
+ put_rectangle(0, 1, 1, h, True); /* left */
+}
+
+static void
+special(nbytes)
+ long nbytes;
+{
+ static char *cmd = NULL;
+ static long cmdlen = -1;
+ char *p;
+
+ if (cmdlen < nbytes) {
+ if (cmd) free(cmd);
+ cmd = xmalloc((unsigned) nbytes + 1, "special");
+ cmdlen = nbytes;
+ }
+ p = cmd;
+ for (;;) {
+ int i = currinf.end - currinf.pos;
+
+ if (i > nbytes) i = nbytes;
+ bcopy((_Xconst char *) currinf.pos, p, i);
+ currinf.pos += i;
+ p += i;
+ nbytes -= i;
+ if (nbytes == 0) break;
+ (void) xxone();
+ --(currinf.pos);
+ }
+ *p = '\0';
+ applicationDoSpecial(cmd);
+}
+
+#define xspell_conv(n) spell_conv0(n, current_dimconv)
+
+static void
+draw_part(minframe, current_dimconv)
+ struct frame *minframe;
+ double current_dimconv;
+{
+ ubyte ch;
+#ifdef TEXXET
+ struct drawinf oldinfo;
+ ubyte oldmaxchar;
+ off_t file_pos;
+ int refl_count;
+#endif
+
+ currinf.fontp = NULL;
+ currinf.set_char_p = set_no_char;
+#ifdef TEXXET
+ currinf.dir = 1;
+ scan_frame = NULL; /* indicates we're not scanning */
+#endif
+ for (;;) {
+ ch = xone();
+ if (debug & DBG_DVI)
+ print_dvi(ch);
+ if (ch <= SETCHAR0 + 127)
+#ifndef TEXXET
+ DVI_H += (*currinf.set_char_p)(ch);
+#else
+ (*currinf.set_char_p)(ch, ch);
+#endif
+ else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63)
+ change_font((unsigned long) (ch - FNTNUM0));
+ else {
+ long a, b;
+
+ switch (ch) {
+ case SET1:
+ case PUT1:
+#ifndef TEXXET
+ a = (*currinf.set_char_p)(xone());
+ if (ch != PUT1) DVI_H += a;
+#else
+ (*currinf.set_char_p)(ch, xone());
+#endif
+ break;
+
+ case SETRULE:
+ /* Be careful, dvicopy outputs rules with
+ height = 0x80000000. We don't want any
+ SIGFPE here. */
+ a = xsfour();
+ b = xspell_conv(xsfour());
+#ifndef TEXXET
+ if (a > 0 && b > 0)
+#else
+ if (a > 0 && b > 0 && scan_frame == NULL)
+#endif
+ set_rule(pixel_round(xspell_conv(a)),
+ pixel_round(b));
+ DVI_H += DIR * b;
+ break;
+
+ case PUTRULE:
+ a = xspell_conv(xsfour());
+ b = xspell_conv(xsfour());
+#ifndef TEXXET
+ if (a > 0 && b > 0)
+#else
+ if (a > 0 && b > 0 && scan_frame == NULL)
+#endif
+ set_rule(pixel_round(a), pixel_round(b));
+ break;
+
+ case NOP:
+ break;
+
+ case BOP:
+ xskip((long) 11 * 4);
+ DVI_H = OFFSET_X;
+ DVI_V = OFFSET_Y;
+ PXL_V = pixel_conv(DVI_V);
+ WW = XX = YY = ZZ = 0;
+ break;
+
+ case EOP:
+ if (current_frame != minframe)
+ tell_oops("stack not empty at EOP");
+ return;
+
+ case PUSH:
+ if (current_frame->next == NULL) {
+ struct frame *newp = (struct frame *)
+ xmalloc(sizeof(struct frame), "stack frame");
+ current_frame->next = newp;
+ newp->prev = current_frame;
+ newp->next = NULL;
+ }
+ current_frame = current_frame->next;
+ current_frame->data = currinf.data;
+ break;
+
+ case POP:
+ if (current_frame == minframe)
+ tell_oops("more POPs than PUSHes");
+ currinf.data = current_frame->data;
+ current_frame = current_frame->prev;
+ break;
+
+#ifdef TEXXET
+ case SREFL:
+ if (scan_frame == NULL) {
+ /* we're not scanning: save some info. */
+ oldinfo = currinf;
+ oldmaxchar = maxchar;
+ if (!currinf.virtual)
+ file_pos = xtell(currinf.pos);
+ scan_frame = current_frame; /* now we're scanning */
+ refl_count = 0;
+ break;
+ }
+ /* we are scanning */
+ if (current_frame == scan_frame) ++refl_count;
+ break;
+
+ case EREFL:
+ if (scan_frame != NULL) { /* if we're scanning */
+ if (current_frame == scan_frame && --refl_count < 0)
+ {
+ /* we've hit the end of our scan */
+ scan_frame = NULL;
+ /* first: push */
+ if (current_frame->next == NULL) {
+ struct frame *newp = (struct frame *)
+ xmalloc(sizeof(struct frame),
+ "stack frame");
+ current_frame->next = newp;
+ newp->prev = current_frame;
+ newp->next = NULL;
+ }
+ current_frame = current_frame->next;
+ current_frame->data = currinf.data;
+ /* next: restore old file position, XX, etc. */
+ if (!currinf.virtual) {
+ off_t bgn_pos = xtell(dvi_buffer);
+
+ if (file_pos >= bgn_pos) {
+ oldinfo.pos = dvi_buffer
+ + (file_pos - bgn_pos);
+ oldinfo.end = currinf.end;
+ }
+ else {
+ (void) lseek(fileno(dvi_file), file_pos,
+ SEEK_SET);
+ oldinfo.pos = oldinfo.end;
+ }
+ }
+ currinf = oldinfo;
+ maxchar = oldmaxchar;
+ /* and then: recover position info. */
+ DVI_H = current_frame->data.dvi_h;
+ DVI_V = current_frame->data.dvi_v;
+ PXL_V = current_frame->data.pxl_v;
+ /* and finally, reverse direction */
+ currinf.dir = -currinf.dir;
+ }
+ break;
+ }
+ /* we're not scanning, */
+ /* so just reverse direction and then pop */
+ currinf.dir = -currinf.dir;
+ currinf.data = current_frame->data;
+ current_frame = current_frame->prev;
+ break;
+#endif /* TEXXET */
+
+ case RIGHT1:
+ case RIGHT2:
+ case RIGHT3:
+ case RIGHT4:
+ DVI_H += DIR * xspell_conv(xsnum(ch - RIGHT1 + 1));
+ break;
+
+ case W1:
+ case W2:
+ case W3:
+ case W4:
+ WW = xspell_conv(xsnum(ch - W0));
+ case W0:
+ DVI_H += DIR * WW;
+ break;
+
+ case X1:
+ case X2:
+ case X3:
+ case X4:
+ XX = xspell_conv(xsnum(ch - X0));
+ case X0:
+ DVI_H += DIR * XX;
+ break;
+
+ case DOWN1:
+ case DOWN2:
+ case DOWN3:
+ case DOWN4:
+ DVI_V += xspell_conv(xsnum(ch - DOWN1 + 1));
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case Y1:
+ case Y2:
+ case Y3:
+ case Y4:
+ YY = xspell_conv(xsnum(ch - Y0));
+ case Y0:
+ DVI_V += YY;
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case Z1:
+ case Z2:
+ case Z3:
+ case Z4:
+ ZZ = xspell_conv(xsnum(ch - Z0));
+ case Z0:
+ DVI_V += ZZ;
+ PXL_V = pixel_conv(DVI_V);
+ break;
+
+ case FNT1:
+ case FNT2:
+ case FNT3:
+ case FNT4:
+ change_font(xnum(ch - FNT1 + 1));
+ break;
+
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ a = xnum(ch - XXX1 + 1);
+ if (a > 0)
+ special(a);
+ break;
+
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ xskip((long) (12 + ch - FNTDEF1 + 1));
+ xskip((long) xone() + (long) xone());
+ break;
+
+#ifndef TEXXET
+ case SREFL:
+ case EREFL:
+#endif
+ case PRE:
+ case POST:
+ case POSTPOST:
+ tell_oops("shouldn't happen: %s encountered",
+ dvi_table2[ch - (FNTNUM0 + 64)]);
+ break;
+
+ default:
+ tell_oops("unknown op-code %d", ch);
+ } /* end switch*/
+ } /* end else (ch not a SETCHAR or FNTNUM) */
+ } /* end for */
+}
+
+#undef xspell_conv
+
+void
+draw_page()
+{
+ /* Check for changes in dvi file. */
+ if (!check_dvi_file()) return;
+
+ put_border(ROUNDUP(unshrunk_paper_w, shrink_factor) + 1,
+ ROUNDUP(unshrunk_paper_h, shrink_factor) + 1);
+
+ (void) lseek(fileno(dvi_file), page_offset[current_page], SEEK_SET);
+
+ bzero((char *) &currinf.data, sizeof(currinf.data));
+ currinf.tn_head = tn_head;
+ currinf.pos = currinf.end = dvi_buffer;
+ currinf.virtual = NULL;
+ draw_part(current_frame = &frame0, dimconv);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/dvi_init.c b/systems/msdos/dviware/xdvi-dos/src/dvi_init.c
new file mode 100644
index 0000000000..f257cd579f
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/dvi_init.c
@@ -0,0 +1,639 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+#include "xdvi.h"
+#include "dvi.h"
+#include <sys/stat.h>
+
+#ifdef sun
+extern char *sprintf();
+#endif
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+char *realloc();
+#endif
+#if defined(macII) && !defined(__STDC__) /* stdlib.h doesn't define these */
+char *realloc();
+#endif /* macII */
+
+#define PK_PRE 247
+#define PK_ID 89
+#define PK_MAGIC (PK_PRE << 8) + PK_ID
+#define GF_PRE 247
+#define GF_ID 131
+#define GF_MAGIC (GF_PRE << 8) + GF_ID
+#define VF_PRE 247
+#define VF_ID_BYTE 202
+#define VF_MAGIC (VF_PRE << 8) + VF_ID_BYTE
+#define PXL_MAGIC1 0
+#define PXL_MAGIC2 1001
+
+#define dvi_oops(str) longjmp(dvi_env, (int) str);
+
+static struct stat fstatbuf;
+
+static Boolean font_not_found;
+
+/*
+ * DVI preamble and postamble information.
+ */
+static char job_id[300];
+static long numerator, denominator, magnification;
+
+/*
+ * Offset in DVI file of last page, set in read_postamble().
+ */
+static long last_page_offset;
+
+
+/*
+ * free_vf_chain frees the vf_chain structure.
+ */
+
+static void
+free_vf_chain(tnp)
+ struct tn *tnp;
+{
+ while (tnp != NULL) {
+ register struct tn *tnp1 = tnp->next;
+ free((char *) tnp);
+ tnp = tnp1;
+ }
+}
+
+
+/*
+ * Release all shrunken bitmaps for all fonts.
+ */
+
+void
+reset_fonts()
+{
+ register struct font *f;
+ register struct glyph *g;
+
+ for (f = font_head; f != NULL; f = f->next)
+ if ((f->flags & FONT_LOADED) && !(f->flags & FONT_VIRTUAL))
+ for (g = f->glyph; g <= f->glyph + f->maxchar; ++g) {
+ if (g->bitmap2.bits) {
+ free(g->bitmap2.bits);
+ g->bitmap2.bits = NULL;
+ }
+#ifdef GREY
+ if (g->pixmap2) {
+ XDestroyImage(g->image2);
+ g->pixmap2 = NULL;
+ }
+#endif
+ }
+}
+
+/*
+ * realloc_font allocates the font structure to contain (newsize + 1)
+ * characters.
+ */
+
+void
+realloc_font(fontp, newsize)
+ struct font *fontp;
+ WIDEARG(ubyte, int) newsize;
+{
+ struct glyph *glyph;
+
+ glyph = fontp->glyph = (struct glyph *) realloc((char *) fontp->glyph,
+ ((unsigned int) newsize + 1) * sizeof(struct glyph));
+ if (glyph == NULL) oops("! Cannot reallocate space for glyph array.");
+ if (newsize > fontp->maxchar)
+ bzero((char *) (glyph + fontp->maxchar + 1),
+ (int) (newsize - fontp->maxchar) * sizeof(struct glyph));
+ maxchar = fontp->maxchar = newsize;
+}
+
+
+/*
+ * realloc_virtual_font does the same thing for virtual fonts.
+ */
+
+void
+realloc_virtual_font(fontp, newsize)
+ struct font *fontp;
+ WIDEARG(ubyte, int) newsize;
+{
+ struct macro *macro;
+
+ macro = fontp->macro = (struct macro *) realloc((char *) fontp->macro,
+ ((unsigned int) newsize + 1) * sizeof(struct macro));
+ if (macro == NULL) oops("! Cannot reallocate space for macro array.");
+ if (newsize > fontp->maxchar)
+ bzero((char *) (macro + fontp->maxchar + 1),
+ (int) (newsize - fontp->maxchar) * sizeof(struct macro));
+ maxchar = fontp->maxchar = newsize;
+}
+
+
+/*
+ * load_font locates the raster file and reads the index of characters,
+ * plus whatever other preprocessing is done (depending on the format).
+ */
+
+void
+load_font(fontp)
+ struct font *fontp;
+{
+ float fsize = fontp->fsize;
+ int dpi = fsize + 0.5;
+ char *font_found;
+ int size_found;
+ int magic;
+
+ fontp->flags |= FONT_LOADED;
+ fontp->file = font_open(fontp->fontname, &font_found,
+ (WIDEARG(float, double)) fsize, &size_found, fontp->magstepval,
+ &fontp->filename);
+ if (fontp->file == NULL) {
+ Fprintf(stderr, "Can't find font %s.\n", fontp->fontname);
+ font_not_found = True;
+ return;
+ }
+ --n_files_left;
+ if (font_found != NULL) {
+ Fprintf(stderr,
+ "Can't find font %s; using %s instead at %d dpi\n",
+ fontp->fontname, font_found, dpi);
+ free(fontp->fontname);
+ fontp->fontname = font_found;
+ }
+ else if (size_found > (int) (5 * 1.002 * fsize + 0.5) ||
+ size_found < (int) (5 * 0.998 * fsize + 0.5))
+ Fprintf(stderr,
+ "Can't find font %s at %d dpi; using %d dpi instead.\n",
+ fontp->fontname, dpi, (size_found + 2) / 5);
+ fontp->fsize = (float) size_found / 5;
+ fontp->timestamp = ++current_timestamp;
+ fontp->maxchar = maxchar = 255;
+ fontp->set_char_p = set_char;
+ magic = two(fontp->file);
+#ifdef USE_PK
+ if (magic == PK_MAGIC) read_PK_index(fontp);
+ else
+#endif
+#ifdef USE_GF
+ if (magic == GF_MAGIC) read_GF_index(fontp);
+ else
+#endif
+ if (magic == VF_MAGIC) read_VF_index(fontp);
+ else
+#ifdef USE_PXL
+ if (magic == PXL_MAGIC1 && two(fontp->file) == PXL_MAGIC2)
+ read_PXL_index(fontp);
+ else
+#endif
+ oops("Cannot recognize format for font file %s", fontp->filename);
+
+ if (fontp->flags & FONT_VIRTUAL) {
+ while (maxchar > 0 && fontp->macro[maxchar].pos == NULL) --maxchar;
+ if (maxchar < 255)
+ realloc_virtual_font(fontp, WIDEARG(,(int)) maxchar);
+ }
+ else {
+ while (maxchar > 0 && fontp->glyph[maxchar].addr == 0) --maxchar;
+ if (maxchar < 255)
+ realloc_font(fontp, WIDEARG(,(int)) maxchar);
+ }
+}
+
+
+/*
+ * MAGSTEPVALUE - If the given magnification is close to a \magstep
+ * or a \magstephalf, then return twice the number of \magsteps.
+ * Otherwise return NOMAGSTP.
+ */
+
+#define NOMAGSTP (-29999)
+#define NOBUILD 29999
+
+static int
+magstepvalue(mag)
+ float *mag;
+{
+ int m = 0;
+ double fmag = *mag;
+ double xmag = pixels_per_inch;
+ float margin = fmag * 0.002;
+
+ if (fmag < pixels_per_inch)
+ for (;;) {
+ if (xmag - fmag < margin && -(xmag - fmag) < margin) {
+ *mag = xmag;
+ return m;
+ }
+ if (xmag < fmag) break;
+ xmag *= 0.9128709292;
+ --m;
+ }
+ else
+ for (;;) {
+ if (xmag - fmag < margin && -(xmag - fmag) < margin) {
+ *mag = xmag;
+ return m;
+ }
+ if (xmag > fmag) break;
+ xmag *= 1.095445115;
+ ++m;
+ }
+ return NOMAGSTP;
+}
+
+
+/*
+ * reuse_font recursively sets the flags for font structures being reused.
+ */
+
+static void
+reuse_font(fontp)
+ struct font *fontp;
+{
+ struct tn *tnp;
+
+ if (fontp->flags & FONT_IN_USE) return;
+
+ fontp->flags |= FONT_IN_USE;
+ if (list_fonts)
+ Printf("(reusing) %s at %d dpi\n", fontp->fontname,
+ (int) (fontp->fsize + 0.5));
+ if (fontp->flags & FONT_VIRTUAL)
+ for (tnp = fontp->vf_chain; tnp != NULL; tnp = tnp->next)
+ reuse_font(tnp->fontp);
+}
+
+
+/*
+ * define_font reads the rest of the fntdef command and then reads in
+ * the specified pixel file, adding it to the global linked-list holding
+ * all of the fonts used in the job.
+ */
+void
+define_font(file, cmnd, vfparent, tn_headpp)
+ FILE *file;
+ WIDEARG(ubyte, unsigned int) cmnd;
+ struct font *vfparent; /* vf parent of this font, or NULL */
+ struct tn **tn_headpp; /* addr of head of list of TeXnumbers */
+{
+ register struct tn *tnp;
+ struct font *fontp;
+ float fsize;
+ double scale_dimconv;
+ int scale;
+ int design;
+ int magstepval;
+ int len;
+ char *fontname;
+ int size;
+
+ tnp = (struct tn *) xmalloc((unsigned) sizeof(struct tn),
+ "TeXnumber structure");
+ tnp->next = *tn_headpp;
+ *tn_headpp = tnp;
+ tnp->TeXnumber = num(file, (int) cmnd - FNTDEF1 + 1);
+ (void) four(file); /* checksum */
+ scale = four(file);
+ design = four(file);
+ len = one(file) + one(file);
+ fontname = xmalloc((unsigned) len + 1, "font name");
+ Fread(fontname, sizeof(char), len, file);
+ fontname[len] = '\0';
+ if(debug & DBG_PK)
+ Printf("Define font \"%s\" scale=%d design=%d\n",
+ fontname, scale, design);
+ if (vfparent == NULL) {
+ fsize = 0.001 * scale / design * magnification * pixels_per_inch;
+ scale_dimconv = dimconv;
+ }
+ else {
+ /*
+ * The scaled size is given in units of vfparent->scale * 2 ** -20
+ * SPELL units, so we convert it into SPELL units by multiplying by
+ * vfparent->dimconv.
+ * The design size is given in units of 2 ** -20 pt, so we convert
+ * into SPELL units by multiplying by
+ * (pixels_per_inch * 2**16) / (72.27 * 2**20).
+ */
+ fsize = (72.27 * (1<<4)) * vfparent->dimconv * scale / design;
+ scale_dimconv = vfparent->dimconv;
+ }
+ magstepval = magstepvalue(&fsize);
+ size = 5 * fsize + 0.5;
+ /*
+ * reuse font if possible
+ */
+ for (fontp = font_head;; fontp = fontp->next) {
+ if (fontp == NULL) { /* if font doesn't exist yet */
+ if (list_fonts)
+ Printf("%s at %d dpi\n", fontname, (int) (fsize + 0.5));
+ fontp = (struct font *) xmalloc((unsigned) sizeof(struct font),
+ "font structure");
+ fontp->dimconv = scale * scale_dimconv / (1<<20);
+ fontp->fontname = fontname;
+ fontp->fsize = fsize;
+ fontp->magstepval = magstepval;
+ fontp->flags = FONT_IN_USE;
+ if (vfparent == NULL) load_font(fontp);
+ fontp->next = font_head;
+ font_head = fontp;
+ break;
+ }
+ if (strcmp(fontname, fontp->fontname) == 0
+ && size == (int) (5 * fontp->fsize + 0.5)) {
+ /* if font already in use */
+ reuse_font(fontp);
+ free(fontname);
+ break;
+ }
+ }
+ tnp->fontp = fontp;
+}
+
+
+/*
+ * process_preamble reads the information in the preamble and stores
+ * it into global variables for later use.
+ */
+static void
+process_preamble()
+{
+ ubyte k;
+
+ if (one(dvi_file) != PRE)
+ dvi_oops("DVI file doesn't start with preamble");
+ if (one(dvi_file) != 2)
+ dvi_oops("Wrong version of DVI output for this program");
+ numerator = four(dvi_file);
+ denominator = four(dvi_file);
+ magnification = four(dvi_file);
+ dimconv = (((double) numerator * magnification)
+ / ((double) denominator * 1000.));
+ dimconv = dimconv * (((long) pixels_per_inch)<<16) / 254000;
+ specialConv = pixels_per_inch * magnification / 1000000.0;
+ k = one(dvi_file);
+ Fread(job_id, sizeof(char), (int) k, dvi_file);
+ job_id[k] = '\0';
+}
+
+/*
+ * find_postamble locates the beginning of the postamble
+ * and leaves the file ready to start reading at that location.
+ */
+#define TMPSIZ 516 /* 4 trailer bytes + 512 junk bytes allowed */
+static void
+find_postamble()
+{
+ long pos;
+ ubyte temp[TMPSIZ];
+ ubyte *p;
+ ubyte *p1;
+ ubyte byte;
+
+ Fseek(dvi_file, (long) 0, 2);
+ pos = ftell(dvi_file) - TMPSIZ;
+ if (pos < 0) pos = 0;
+ Fseek(dvi_file, pos, 0);
+ p = temp + fread((char *) temp, sizeof(char), TMPSIZ, dvi_file);
+ for (;;) {
+ p1 = p;
+ while (p1 > temp && *(--p1) != TRAILER) ;
+ p = p1;
+ while (p > temp && *(--p) == TRAILER) ;
+ if (p <= p1 - 4) break; /* found 4 TRAILER bytes */
+ if (p <= temp) dvi_oops("DVI file corrupted");
+ }
+ pos += p - temp;
+ byte = *p;
+ while (byte == TRAILER) {
+ Fseek(dvi_file, --pos, 0);
+ byte = one(dvi_file);
+ }
+ if (byte != 2)
+ dvi_oops("Wrong version of DVI output for this program");
+ Fseek(dvi_file, pos - 4, 0);
+ Fseek(dvi_file, sfour(dvi_file), 0);
+}
+
+
+/*
+ * read_postamble reads the information in the postamble,
+ * storing it into global variables.
+ * It also takes care of reading in all of the pixel files for the fonts
+ * used in the job.
+ */
+static void
+read_postamble()
+{
+ ubyte cmnd;
+ struct font *fontp;
+ struct font **fontpp;
+
+ if (one(dvi_file) != POST)
+ dvi_oops("Postamble doesn't begin with POST");
+ last_page_offset = four(dvi_file);
+ if (numerator != four(dvi_file)
+ || denominator != four(dvi_file)
+ || magnification != four(dvi_file))
+ dvi_oops("Postamble doesn't match preamble");
+ /* read largest box height and width */
+ unshrunk_page_h = (spell_conv(sfour(dvi_file)) >> 16) + offset_y;
+ if (unshrunk_page_h < unshrunk_paper_h)
+ unshrunk_page_h = unshrunk_paper_h;
+ unshrunk_page_w = (spell_conv(sfour(dvi_file)) >> 16) + offset_x;
+ if (unshrunk_page_w < unshrunk_paper_w)
+ unshrunk_page_w = unshrunk_paper_w;
+ (void) two(dvi_file); /* max stack size */
+ total_pages = two(dvi_file);
+ font_not_found = False;
+ while ((cmnd = one(dvi_file)) >= FNTDEF1 && cmnd <= FNTDEF4)
+ define_font(dvi_file, cmnd, (struct font *) NULL, &tn_head);
+ if (cmnd != POSTPOST)
+ dvi_oops("Non-fntdef command found in postamble");
+ if (font_not_found)
+ dvi_oops("Not all pixel files were found");
+ /*
+ * free up fonts no longer in use
+ */
+ fontpp = &font_head;
+ while ((fontp = *fontpp) != NULL)
+ if (fontp->flags & FONT_IN_USE)
+ fontpp = &fontp->next;
+ else {
+ if (debug & DBG_PK)
+ Printf("Discarding font \"%s\" at %d dpi\n",
+ fontp->fontname, (int) (fontp->fsize + 0.5));
+ *fontpp = fontp->next; /* remove from list */
+ free(fontp->fontname);
+ if (fontp->flags & FONT_LOADED) {
+ if (fontp->file != NULL) {
+ Fclose(fontp->file);
+ ++n_files_left;
+ }
+ free(fontp->filename);
+ if (fontp->flags & FONT_VIRTUAL) {
+ register struct macro *m;
+
+ for (m = fontp->macro;
+ m <= fontp->macro + fontp->maxchar; ++m)
+ if (m->free_me) free((char *) m->pos);
+ free((char *) fontp->macro);
+ free_vf_chain(fontp->vf_chain);
+ }
+ else {
+ register struct glyph *g;
+
+ for (g = fontp->glyph;
+ g <= fontp->glyph + fontp->maxchar; ++g) {
+ if (g->bitmap.bits != NULL) free(g->bitmap.bits);
+ if (g->bitmap2.bits != NULL) free(g->bitmap2.bits);
+#ifdef GREY
+ if (g->pixmap2 != NULL) XDestroyImage(g->image2);
+#endif
+ }
+ free((char *) fontp->glyph);
+ }
+ free((char *) fontp);
+ }
+ }
+}
+
+static void
+prepare_pages()
+{
+ int i;
+
+ page_offset = (long *) xmalloc((unsigned) total_pages * sizeof(long),
+ "page directory");
+ i = total_pages;
+ page_offset[--i] = last_page_offset;
+ Fseek(dvi_file, last_page_offset, 0);
+ /*
+ * Follow back pointers through pages in the DVI file,
+ * storing the offsets in the page_offset table.
+ */
+ while (i > 0) {
+ Fseek(dvi_file, (long) (1+4+(9*4)), 1);
+ Fseek(dvi_file, page_offset[--i] = four(dvi_file), 0);
+ }
+}
+
+void
+init_page()
+{
+ page_w = ROUNDUP(unshrunk_page_w, mane.shrinkfactor) + 2;
+ page_h = ROUNDUP(unshrunk_page_h, mane.shrinkfactor) + 2;
+}
+
+/*
+ * init_dvi_file is the main subroutine for reading the startup information
+ * from the dvi file.
+ */
+
+static void
+init_dvi_file()
+{
+ (void) fstat(fileno(dvi_file), &fstatbuf);
+ dvi_time = fstatbuf.st_mtime;
+ process_preamble();
+ find_postamble();
+ read_postamble();
+ prepare_pages();
+ init_page();
+ if (current_page >= total_pages) current_page = total_pages - 1;
+ hush_spec_now = hush_spec;
+}
+
+/**
+ ** open_dvi_file opens the dvi file and calls init_dvi_file() to
+ ** initialize it.
+ **/
+
+void
+open_dvi_file()
+{
+ char *errmsg;
+
+ if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
+ int n = strlen(dvi_name);
+ char *file = dvi_name;
+
+ if (strcmp(dvi_name + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+ perror(dvi_name);
+ exit(1);
+ }
+ dvi_name = xmalloc((unsigned) n + sizeof(".dvi"), "dvi file name");
+ Sprintf(dvi_name, "%s.dvi", file);
+ if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) {
+ perror(dvi_name);
+ exit(1);
+ }
+ }
+
+ if (errmsg = (char *) setjmp(dvi_env)) oops(errmsg);
+ init_dvi_file();
+}
+
+/**
+ ** Check for changes in dvi file.
+ **/
+
+Boolean
+check_dvi_file()
+{
+ struct font *fontp;
+
+ if (dvi_file == NULL || fstat(fileno(dvi_file), &fstatbuf) != 0
+ || fstatbuf.st_mtime != dvi_time) {
+ if (dvi_file) Fclose(dvi_file);
+ free((char *) page_offset);
+ dvi_file = fopen(dvi_name, OPEN_MODE);
+ if (dvi_file == NULL)
+ dvi_oops("Cannot reopen dvi file.");
+ if (list_fonts) Putchar('\n');
+ free_vf_chain(tn_head);
+ tn_head = NULL;
+ for (fontp = font_head; fontp != NULL; fontp = fontp->next)
+ fontp->flags &= ~FONT_IN_USE;
+ init_dvi_file();
+ redraw_page();
+ return False;
+ }
+ return True;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/font_ope.c b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
new file mode 100644
index 0000000000..78d9b412a9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
@@ -0,0 +1,887 @@
+/*
+ * font_open.c(font, font_ret, mag, mag_ret, magstepval, name)
+ * Find and open gf, pk, or pxl files in the given path, having the given
+ * name and magnification. It tries gf files first, followed by pk and pxl
+ * files. The path variable should be of the form path1:path2:...:pathn,
+ * and each of the paths will be tried successively. Strings in pathi of
+ * the form %f, %p, and %d will be replaced by the font name, "gf" or "pk"
+ * or "pxl", and the magnification, respectively. If no %f appears in a
+ * path specifier, then the string "/%f.%d%p" is added on the end. This
+ * procedure is repeated for each of the possible magnifications allowed,
+ * and if it fails then the procedure will try changing the point size
+ * as well. If all of the above fails, then alt_font will be tried.
+ *
+ * If the variable SEARCH_SUBDIRECTORIES is set, then the environment
+ * variable TEXFONTS_SUBDIR and the #define variable DEFAULT_SUBDIR_PATH
+ * will be enabled, as well as ``*'' and ``**'' specifiers. The
+ * SUBDIR_PATH things will be appended to the end of the usual path, with
+ * a `*' at the end of each component. The `*' means that subdirectories
+ * will be searched up to one level; `**' means that subdirectories
+ * will be recursively searched to any level. Neither specifier may be
+ * preceded by a `%' specifier (after the most recent colon).
+ *
+ * If the file is found, then a file pointer is returned, and the following
+ * values are set:
+ * *font_ret a pointer to a string containing the font name (if
+ * different from the font requested).
+ * *mag_ret the actual magnification found.
+ * *name a pointer to a string containing the file name
+ *
+ * If the file is not found, then the return value is NULL.
+ *
+ * Often there are so many fonts that we need to manage the number of
+ * simultaneously open files. For that reason, these routines call
+ * xfopen() instead of fopen(), which should manage the number of open
+ * font files.
+ *
+ */
+
+/*--------------------------- Msdos ---------------------------------------*/
+/* ericho */
+#ifdef __MSDOS__
+
+#define DEFAULT_FONT_PATH "/tex/fonts"
+#define DEFAULT_VF_PATH "/tex/fonts/vf"
+#define DEFAULT_FONT_SIZES "300:328.6:360:432:518.4:622:746.4"
+
+#ifdef FONTSUB
+#include <stdio.h>
+extern FILE *fontsubfile;
+extern char *subfont (FILE *,char *);
+#endif
+
+#endif
+/*--------------------------- Msdos ---------------------------------------*/
+
+#include "xdvi.h"
+#include <errno.h>
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h> /* has getenv() */
+#include <math.h> /* has atof() */
+#else
+extern char *getenv();
+#ifndef atof
+double atof();
+#endif
+#endif
+
+/*
+ * If you think you have to change DEFAULT_TAIL, then you haven't read the
+ * documentation closely enough.
+ */
+#ifndef VMS
+#define PATH_SEP ':'
+
+#ifndef __MSDOS__ /* eric ho */
+#define DEFAULT_TAIL "/%f.%d%p"
+#else
+#define DEFAULT_TAIL "/%d/%f.%p"
+#endif
+
+#define DEFAULT_VF_TAIL "/%f.vf"
+#else /* VMS */
+#define PATH_SEP '/'
+#define DEFAULT_TAIL ":%f.%d%p"
+#define DEFAULT_VF_TAIL ":%f.vf"
+#endif /* VMS */
+
+static _Xconst char *font_path;
+static _Xconst char *default_font_path = DEFAULT_FONT_PATH;
+static _Xconst char *vf_path;
+static _Xconst char *default_vf_path = DEFAULT_VF_PATH;
+#ifdef SEARCH_SUBDIRECTORIES
+static char default_subdir_path[] = DEFAULT_SUBDIR_PATH;
+#endif
+static int *sizes, *sizend;
+static char default_size_list[] = DEFAULT_FONT_SIZES;
+
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#ifdef PATH_MAX
+#define FILENAMESIZE PATH_MAX
+#endif
+#endif
+
+#ifndef FILENAMESIZE
+#define FILENAMESIZE 512
+#endif
+
+#ifdef sun
+char *sprintf();
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+/* We will need some system include files to deal with directories. */
+/* <sys/types.h> was included by xdvi.h. */
+
+#include <sys/stat.h>
+
+static int is_dir ();
+
+#if defined(SYSV) || defined(_POSIX_SOURCE)
+#include <dirent.h>
+typedef struct dirent *directory_entry_type;
+#else
+#include <sys/dir.h>
+typedef struct direct *directory_entry_type;
+#endif
+
+/* Declare the routine to get the current working directory. */
+
+#ifdef HAVE_GETWD
+extern char *getwd ();
+#define GETCWD(b, len) ((b) ? getwd (b) : getwd (xmalloc (len, "getwd")))
+#else
+/* POSIX says getcwd result is undefined if the pointer is NULL; at least
+ on a Convex, the result is a coredump. Hence the GETCWD macro
+ below is defined, as it works regardless of what getcwd() does
+ with a NULL pointer */
+#define GETCWD(b, len) ((b) ? getcwd (b,len) \
+ : getcwd (xmalloc (len, "getcwd"),len))
+#ifdef _POSIX_SOURCE
+#include <unistd.h> /* getcwd prototype */
+#else
+#if NeedFunctionPrototypes
+extern char *getcwd (char *, int);
+#else
+extern char *getcwd ();
+#endif /* not NeedFunctionPrototypes */
+#endif /* not _POSIX_SOURCE */
+#endif /* not HAVE_GETWD */
+
+static char *cwd;
+
+/* The following is a data structure containing the precomputed names of
+ subdirectories to be recursively searched. */
+
+static struct subdir_entry {
+ char *name; /* partial string */
+ _Xconst char *index; /* reference point in {,default_}font_path */
+ struct subdir_entry *next; /* link in list */
+}
+ *subdir_head = NULL,
+ *next_subdir;
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
+#endif
+
+
+
+/* Return true if FN is a directory or a symlink to a directory,
+ false if not. */
+
+static int
+is_dir (fn)
+ char *fn;
+{
+ struct stat stats;
+
+ return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
+}
+
+/*
+ * Compute extra length of subdirectory entries, including a star for each.
+ */
+
+static int
+extra_len(str1, str2)
+ char *str1, *str2;
+{
+ int bias = 0;
+ char *p = str1;
+ char *q;
+
+ do {
+ q = index(p, PATH_SEP);
+ if (q == NULL) q = p + strlen(p);
+ if (q == p) {
+ if (str2 != NULL) {
+ bias += extra_len(str2, (char *) NULL);
+ str2 = NULL;
+ }
+ }
+ else ++bias; /* don't forget the star */
+ p = q + 1;
+ }
+ while (p[-1] != '\0');
+ return bias + p - str1;
+}
+
+/*
+ * Add the specifiers (and double stars) for the given strings (user
+ * string, plus default string) to the destination string.
+ */
+
+static void
+add_subdir_paths(dst, dst_first, src, src_default)
+ char *dst, *dst_first, *src, *src_default;
+{
+ char *q;
+
+ do {
+ q = index(src, PATH_SEP);
+ if (q == NULL) q = src + strlen(src);
+ if (q == src) {
+ if (src_default != NULL) {
+ add_subdir_paths(dst, dst_first, src_default, (char *)NULL);
+ dst += strlen(dst);
+ src_default = NULL;
+ }
+ }
+ else {
+ if (dst != dst_first) *dst++ = PATH_SEP;
+ bcopy(src, dst, q - src);
+ dst += q - src;
+ *dst++ = '*';
+ }
+ src = q + 1;
+ }
+ while (src[-1] != '\0');
+ *dst = '\0';
+}
+
+/*
+ * Make a subdirectory entry.
+ */
+
+static struct subdir_entry *
+make_subdir_entry(index, name)
+ _Xconst char *index;
+ char *name;
+{
+ struct subdir_entry *new_entry;
+ static struct subdir_entry **subdir_tail = &subdir_head;
+
+ *subdir_tail = new_entry = (struct subdir_entry *)
+ xmalloc(sizeof(struct subdir_entry), "subdirectory list entry");
+ subdir_tail = &(new_entry->next);
+ new_entry->name = strcpy(xmalloc(strlen(name) + 1,
+ "subdirectory entry string"), name);
+ new_entry->index = index;
+ new_entry->next = NULL;
+ return new_entry;
+}
+
+/*
+ * Create the subdirectory linked list for the given initial string
+ */
+
+static void
+add_subdirs(str, len, recurs)
+ _Xconst char *str;
+ int len;
+ Boolean recurs;
+{
+ int len1 = len;
+ char temp[FILENAMESIZE];
+ struct subdir_entry *next_subdir;
+ DIR *dir;
+ directory_entry_type e;
+
+ bcopy(str, temp, len);
+ if (len > 0 && temp[len - 1] != '/') temp[len1++] = '/';
+ temp[len1] = '\0';
+ next_subdir = make_subdir_entry(str, temp + len);
+ do {
+ /* By changing directories, we save a bunch of string
+ concatenations (and make the pathnames the kernel looks up
+ shorter). */
+ Strcpy(temp + len, next_subdir->name);
+ if (chdir (temp) != 0) continue;
+
+ dir = opendir (".");
+ if (dir == NULL) continue;
+
+ len1 = strlen(temp);
+ if (len1 == 0 || temp[len1 - 1] != '/') temp[len1++] = '/';
+ while ((e = readdir (dir)) != NULL) {
+ if (is_dir (e->d_name) && strcmp (e->d_name, ".") != 0
+ && strcmp (e->d_name, "..") != 0) {
+ Strcpy(temp + len1, e->d_name);
+ (void) make_subdir_entry(str, temp + len);
+ }
+ }
+ (void) closedir (dir);
+
+
+ /* Change back to the current directory, in case the path
+ contains relative directory names. */
+ if (chdir (cwd) != 0) {
+ perror (cwd);
+ exit (errno);
+ }
+ }
+ while (recurs && (next_subdir = next_subdir->next) != NULL);
+}
+
+/*
+ * Recursively figure out the subdirectory tree and precompute the
+ * list of subdirectories to search.
+ */
+
+static void
+compute_subdir_paths(fp, fp_default)
+ _Xconst char *fp;
+ _Xconst char *fp_default;
+{
+ _Xconst char *star_loc = NULL;
+ _Xconst char *endp;
+
+ do {
+ if (star_loc == NULL) {
+ star_loc = index(fp, '*');
+ if (star_loc == NULL) star_loc = fp + strlen(fp);
+ }
+ endp = index(fp, PATH_SEP);
+ if (endp == NULL) endp = fp + strlen(fp);
+ if (endp == fp) {
+ if (fp_default != NULL) {
+ compute_subdir_paths(fp_default, (char *) NULL);
+ fp_default = NULL;
+ }
+ }
+ else if (star_loc < endp) {
+ add_subdirs(fp, star_loc - fp, star_loc[1] == '*');
+ star_loc = NULL;
+ }
+ fp = endp + 1;
+ }
+ while (fp[-1] != '\0');
+}
+#endif /* SEARCH_SUBDIRECTORIES */
+
+static void
+get_sizes(size_list, spp)
+ char *size_list;
+ int **spp;
+{
+ if (*size_list == PATH_SEP) ++size_list;
+ for (;;) {
+ *(*spp)++ = atof(size_list) * 5 + 0.5;
+ size_list = index(size_list, PATH_SEP);
+ if (size_list == NULL) return;
+ ++size_list;
+ }
+}
+
+void
+init_font_open()
+{
+ char *size_list;
+ int *sp, *sp1, *sp2;
+ unsigned int n;
+ char *p;
+#ifdef SEARCH_SUBDIRECTORIES
+ char *q;
+#endif
+
+ if ((font_path = getenv("XDVIFONTS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (font_path = getenv("PKFONTS")) == NULL
+ && (font_path = getenv("TEXFONTS")) == NULL
+#endif
+ ) {
+ font_path = default_font_path;
+ default_font_path = NULL;
+ }
+
+#ifdef SEARCH_SUBDIRECTORIES
+ p = getenv ("TEXFONTS_SUBDIR");
+ if (p == NULL) p = "";
+ q = xmalloc((unsigned) strlen(font_path)
+ + extra_len(p, default_subdir_path) + 1,
+ "initializing font searching");
+ Strcpy(q, font_path);
+ add_subdir_paths(q + strlen(q), q, p, default_subdir_path);
+ font_path = q;
+
+ /* Unfortunately, we can't look in the environment for the current
+ directory, because if we are running under a program (let's say
+ Emacs), the PWD variable might have been set by Emacs' parent
+ to the current directory at the time Emacs was invoked. This
+ is not necessarily the same directory the user expects to be
+ in. So, we must always call getcwd(3) or getwd(3), even though
+ they are slow and prone to hang in networked installations. */
+ cwd = GETCWD ((char *) NULL, FILENAMESIZE + 2);
+ if (cwd == NULL) {
+ perror ("getcwd");
+ exit (errno);
+ }
+ compute_subdir_paths(font_path, default_font_path);
+#endif
+
+ if ((vf_path = getenv("XDVIVFS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (vf_path = getenv("VFFONTS")) == NULL
+#endif
+ ) {
+ vf_path = default_vf_path;
+ default_vf_path = NULL;
+ }
+
+ size_list = getenv("XDVISIZES");
+ n = 1; /* count number of sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ for (p = default_size_list; (p = index(p, PATH_SEP)) != NULL; ++p)
+ ++n;
+ if (size_list != NULL)
+ for (p = size_list; (p = index(p, PATH_SEP)) != NULL; ++p) ++n;
+ sizes = (int *) xmalloc(n * sizeof(int), "size list");
+ sizend = sizes + n;
+ sp = sizes; /* get the actual sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ get_sizes(default_size_list, &sp);
+ if (size_list != NULL) get_sizes(size_list, &sp);
+
+ /* bubble sort the sizes */
+ sp1 = sizend - 1; /* extent of this pass */
+ do {
+ sp2 = NULL;
+ for (sp = sizes; sp < sp1; ++sp)
+ if (*sp > sp[1]) {
+ int i = *sp;
+ *sp = sp[1];
+ sp[1] = i;
+ sp2 = sp;
+ }
+ }
+ while ((sp1 = sp2) != NULL);
+}
+
+/* eric */
+static FILE *
+formatted_open(path, font, gforpk, mag, name, first_try, tail)
+ _Xconst char *path;
+ _Xconst char *font;
+ _Xconst char *gforpk;
+ int mag;
+ char **name;
+ Boolean first_try;
+ _Xconst char *tail;
+{
+ _Xconst char *p = path;
+ char nm[FILENAMESIZE];
+ char *n = nm;
+ char c;
+ Boolean f_used = False;
+ Boolean p_used = False;
+ FILE *f;
+
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ int len = index(p, '*') - p;
+
+ bcopy(p, n, len);
+ p += len;
+ n += len;
+ Strcpy(n, next_subdir->name);
+ n += strlen(n);
+ ++p;
+ if (*p == '*') ++p;
+ if (*p != '/') *n++ = '/';
+ }
+#endif
+ for (;;) {
+ c = *p++;
+ if (c==PATH_SEP || c=='\0') {
+ if (f_used) break;
+ p = tail;
+ continue;
+ }
+ if (c=='%') {
+ c = *p++;
+ switch (c) {
+ case 'f':
+ f_used = True;
+ Strcpy(n, font);
+ break;
+ case 'p':
+ p_used = True;
+ Strcpy(n, gforpk);
+ break;
+ case 'd':
+ Sprintf(n, "%d", mag);
+ break;
+ default:
+ *n++ = c;
+ *n = '\0';
+ }
+ n += strlen(n);
+ }
+ else *n++ = c;
+ }
+ if (!p_used && !first_try) return NULL;
+ *n = '\0';
+ if (debug & DBG_OPEN) Printf("Trying font file %s\n", nm);
+
+
+ f = xfopen(nm);
+ if (f != NULL) {
+ *name = xmalloc((unsigned) (n - nm + 1), "font file name");
+ Strcpy(*name, nm);
+ }
+ return f;
+}
+
+/*
+ * Try a given size
+ */
+
+static FILE *
+try_size(font, pxlmag, name, x_font_path, x_default_font_path)
+ _Xconst char *font;
+ int pxlmag;
+ char **name;
+ _Xconst char *x_font_path;
+ _Xconst char *x_default_font_path;
+{
+ _Xconst char *p = x_font_path;
+ FILE *f;
+ int pkmag = (pxlmag + 2) / 5;
+
+#ifdef __MSDOS__
+ char *sfont, *dotptr;
+#endif
+
+ /*
+ * loop over paths
+ */
+#ifdef SEARCH_SUBDIRECTORIES
+ next_subdir = subdir_head;
+#endif
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_font_path != NULL &&
+ (f = try_size(font, pxlmag, name, x_default_font_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+
+
+
+#define FIRST_TRY True
+#ifdef USE_PK
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && !defined(FONTSUB)
+
+ /* I prefer this method because it'll execute a lot */
+ /* faster than looking up the font substitute file */
+
+ /* simply convert all the amXXXX font to cmXXXX */
+ dotptr = strchr (font,'a');
+ if (dotptr != (char *)NULL) {
+ *dotptr = 'c';
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+ if ((f = formatted_open(p, font, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && defined(FONTSUB)
+ /* look for the substitute font from file */
+ if (fontsubfile != (FILE *) NULL) {
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,(char *)font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, (_Xconst char *)sfont, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+
+
+#ifdef USE_GF
+ if ((f = formatted_open(p, font, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+#ifdef USE_PXL
+ if ((f = formatted_open(p, font, "pxl", pxlmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "pxl", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ next_subdir = next_subdir->next;
+ if (next_subdir != NULL && next_subdir->index == p)
+ continue;
+ }
+#endif
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+/*
+ * Try a virtual font
+ */
+
+static FILE *
+try_vf(font, name, x_vf_path, x_default_vf_path)
+ _Xconst char *font;
+ char **name;
+ _Xconst char *x_vf_path;
+ _Xconst char *x_default_vf_path;
+{
+ _Xconst char *p = x_vf_path;
+ FILE *f;
+
+ /*
+ * loop over paths
+ */
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_vf_path != NULL &&
+ (f = try_vf(font, name, x_default_vf_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+ if ((f = formatted_open(p, font, "vf", 0, name, True,
+ DEFAULT_VF_TAIL)) != NULL)
+ return f;
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+#ifdef MAKEPKCMD
+#undef MAKEPK
+#define MAKEPK
+#endif
+
+#ifdef MAKEPK
+#ifndef MAKEPKCMD
+#define MAKEPKCMD "MakeTeXPK"
+#endif
+
+#define NOBUILD 29999
+#endif
+
+/*
+ * Try a given font name
+ */
+
+#ifndef MAKEPK
+#define PRE_FONT_OPEN(font, fmag, mag_ret, name, ignore) \
+ pre_font_open(font, fmag, mag_ret, name)
+#else
+#define PRE_FONT_OPEN pre_font_open
+#endif
+
+static FILE *
+PRE_FONT_OPEN(font, fmag, mag_ret, name, magstepval)
+ _Xconst char *font;
+ float fmag;
+ int *mag_ret;
+ char **name;
+#ifdef MAKEPK
+ int magstepval;
+#endif
+{
+ FILE *f;
+ int *p1, *p2;
+ int mag = 5 * fmag + 0.5;
+ int tmag;
+#ifndef VMS
+ _Xconst char *path_to_use;
+ _Xconst char *vf_path_to_use;
+#endif
+#ifdef MAKEPK
+ char mkpk[80];
+#endif
+
+ /*
+ * Loop over sizes. Try actual size first, then closest sizes.
+ If the pathname is absolutely or explicitly relative, don't
+ use the usual paths to search for it; just look for it in the
+ directory specified.
+ */
+
+#ifndef VMS
+ path_to_use = (_Xconst char *) NULL;
+ if (*font == '/') path_to_use = "/";
+ else if (*font == '.' && (*(font + 1) == '/'
+ || (*(font + 1) == '.' && *(font + 2) == '/')))
+ path_to_use = ".";
+ vf_path_to_use = path_to_use;
+ if (path_to_use == NULL) {
+ path_to_use = font_path;
+ vf_path_to_use = vf_path;
+ }
+#else /* VMS */
+#define path_to_use font_path
+#define vf_path_to_use vf_path
+#endif /* VMS */
+
+ if ((f = try_size(font, *mag_ret = mag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+
+ /* Try at one away from the size we just tried, to account
+ for rounding error. */
+ tmag = mag + (mag < 5 * fmag ? 1 : -1);
+ if ((f = try_size(font, tmag, name, path_to_use, default_font_path))
+ != NULL) {
+ *mag_ret = tmag;
+ return f;
+ }
+
+ /* Try a virtual font. */
+ if ((f = try_vf(font, name, vf_path_to_use, default_vf_path)) != NULL)
+ return f;
+
+#ifdef MAKEPK
+ /* Try to create the font. */
+ if (magstepval != NOBUILD) {
+ char str[24];
+ int dpi = (mag + 2) / 5;
+
+ if (magstepval == NOMAGSTP)
+ Sprintf(str, "%d+%d/%d", dpi / pixels_per_inch,
+ dpi % pixels_per_inch, pixels_per_inch);
+ else if (magstepval < 0)
+ Sprintf(str, "magstep\\(-%d%s\\)", (-magstepval) / 2,
+ magstepval % 2 ? ".5" :"");
+ else
+ Sprintf(str, "magstep\\(%d%s\\)", magstepval / 2,
+ magstepval % 2 ? ".5" :"");
+
+ Sprintf(mkpk, "%s %s %d %d %s", MAKEPKCMD, font, dpi,
+ pixels_per_inch, str);
+ Printf("- %s\n", mkpk);
+ if (system(mkpk) == 0
+ && (f = try_size(font, mag, name, path_to_use,
+ default_font_path))
+ != NULL)
+ return f;
+ }
+#endif
+
+ /* Now try at all the sizes. */
+ for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break;
+ p1 = p2;
+ for (;;) {
+ /* find another magnification */
+ if (p1 <= sizes)
+ if (p2 >= sizend) return NULL;
+ else tmag = *p2++;
+ else if (p2 >= sizend || (long) mag * mag <= (long) p1[-1] * *p2)
+ tmag = *--p1;
+ else tmag = *p2++;
+ if ((f = try_size(font, *mag_ret = tmag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+ }
+}
+
+/* ARGSUSED */
+FILE *
+font_open(font, font_ret, mag, mag_ret, magstepval, name)
+ _Xconst char *font;
+ char **font_ret;
+ WIDEARG(float, double) mag;
+ int *mag_ret;
+ int magstepval;
+ char **name;
+{
+ FILE *f;
+ int actual_pt, low_pt, high_pt, trial_pt;
+ char fn[50], *fnend;
+
+ f = PRE_FONT_OPEN(font, mag, mag_ret, name, magstepval);
+ if (f != NULL) {
+ *font_ret = NULL;
+ return f;
+ }
+ Strcpy(fn, font);
+ fnend = fn + strlen(fn);
+ while (fnend > fn && fnend[-1] >= '0' && fnend[-1] <= '9') --fnend;
+ actual_pt = low_pt = high_pt = atoi(fnend);
+ if (actual_pt) {
+ low_pt = actual_pt - 1;
+ high_pt = actual_pt + 1;
+ for (;;) {
+ if (2 * low_pt >= actual_pt &&
+ (low_pt * high_pt > actual_pt * actual_pt ||
+ high_pt > actual_pt + 5))
+ trial_pt = low_pt--;
+ else if (high_pt > actual_pt + 5) break;
+ else trial_pt = high_pt++;
+ Sprintf(fnend, "%d", trial_pt);
+ f = PRE_FONT_OPEN(fn, mag * actual_pt / trial_pt, mag_ret,
+ name, NOBUILD);
+ if (f != NULL) {
+ *font_ret = strcpy(xmalloc((unsigned) strlen(fn) + 1,
+ "name of font used"), fn);
+ return f;
+ }
+ }
+ }
+ if (alt_font != NULL) {
+ f = PRE_FONT_OPEN(alt_font, mag, mag_ret, name, NOBUILD);
+ if (f != NULL)
+ *font_ret = strcpy(xmalloc((unsigned) strlen(alt_font) + 1,
+ "name of font used"), alt_font);
+ }
+ return f;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/fontfmts.c b/systems/msdos/dviware/xdvi-dos/src/fontfmts.c
new file mode 100644
index 0000000000..69a0963d09
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/fontfmts.c
@@ -0,0 +1,21 @@
+#include "xdvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+/***
+ *** Font reading routines are read into this file.
+ ***/
+
+#ifdef USE_PK
+#include "pk.c"
+#endif
+
+#ifdef USE_GF
+#include "gf.c"
+#endif
+
+#ifdef USE_PXL
+#include "pxl.c"
+#endif
diff --git a/systems/msdos/dviware/xdvi-dos/src/fontsub.c b/systems/msdos/dviware/xdvi-dos/src/fontsub.c
new file mode 100644
index 0000000000..0ad76638d6
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/fontsub.c
@@ -0,0 +1,62 @@
+/* ------------------------------ For MsDos -------------------------------*/
+
+/*
+
+ These routines are written for opening and searching the font
+ substitute file pointed to by the environmental variable "TEXFONTSUB"
+
+ 10/OCT/1992 Eric Ho 9041477@SSCVAX.MCMASTER.CA
+
+*/
+
+#ifdef FONTSUB
+
+#include <stdio.h>
+#include <stdlib.h>
+
+FILE *openfontsubfile (void);
+char *subfont (FILE *,char *);
+
+
+char *subfont (fptr,font)
+FILE *fptr;
+char *font;
+{
+ char ofont[30], /* original font */
+ sfont[30]; /* font to be substitute */
+
+ rewind (fptr);
+ while (!feof (fptr)) {
+ fscanf (fptr,"%s -> %s",ofont,sfont);
+ if (strcmp (ofont,font) == 0) {
+/* fprintf (stderr,"Replacing %s with %s\n",font,sfont); */
+ return (sfont);
+ }
+ }
+ return (NULL);
+}
+
+
+
+FILE *openfontsubfile (void)
+{
+ FILE *fptr;
+ char fontsfname[64],
+ *sptr; /* font substitue file name */
+
+ if ((sptr = (char *) getenv ("TEXFONTSUB")) != (char *) NULL) {
+ (void) strcpy (fontsfname,sptr);
+ if ((fptr = fopen (fontsfname,"r")) != (FILE *) NULL) {
+ return ((FILE *) fptr);
+ } else {
+ fprintf (stderr,"\n\nFont substitute file not found!\n");
+ fprintf (stderr,"Check environmental variable TEXFONTSUB!\n\n");
+ return ((FILE *) NULL);
+ }
+ } else {
+ fprintf (stderr,"\n\nCheck environmental variable TEXFONTSUB!\n\n");
+ return ((FILE *) NULL);
+ }
+}
+
+#endif
diff --git a/systems/msdos/dviware/xdvi-dos/src/gf.c b/systems/msdos/dviware/xdvi-dos/src/gf.c
new file mode 100644
index 0000000000..cc6b9423fe
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/gf.c
@@ -0,0 +1,294 @@
+/***
+ *** GF font reading routines.
+ *** Public routines are read_GF_index and read_GF_char.
+ ***/
+
+#define PAINT_0 0
+#define PAINT1 64
+#define PAINT2 65
+#define PAINT3 66
+#define BOC 67
+#define BOC1 68
+#define EOC 69
+#define SKIP0 70
+#define SKIP1 71
+#define SKIP2 72
+#define SKIP3 73
+#define NEW_ROW_0 74
+#define NEW_ROW_MAX 238
+#define XXX1 239
+#define XXX2 240
+#define XXX3 241
+#define XXX4 242
+#define YYY 243
+#define NO_OP 244
+#define CHAR_LOC 245
+#define CHAR_LOC0 246
+#define PRE 247
+#define POST 248
+#define POST_POST 249
+
+#define GF_ID_BYTE 131
+#define TRAILER 223 /* Trailing bytes at end of file */
+
+static FILE *GF_file;
+
+static void
+expect(ch)
+ ubyte ch;
+{
+ ubyte ch1 = one(GF_file);
+
+ if (ch1 != ch)
+ oops("Bad GF file: %d expected, %d received.", ch, ch1);
+}
+
+static void
+too_many_bits(ch)
+ ubyte ch;
+{
+ oops("Too many bits found when loading character %d", ch);
+}
+
+/*
+ * Public routines
+ */
+
+
+static void
+read_GF_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ register struct glyph *g;
+ ubyte cmnd;
+ int min_m, max_m, min_n, max_n;
+ BMUNIT *cp, *basep, *maxp;
+ int bytes_wide;
+ Boolean paint_switch;
+#define White False
+#define Black True
+ Boolean new_row;
+ int count;
+ int word_weight;
+
+ g = &fontp->glyph[ch];
+ GF_file = fontp->file;
+
+ if(debug & DBG_PK)
+ Printf("Loading gf char %d", ch);
+
+ for (;;) {
+ switch (cmnd = one(GF_file)) {
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ Fseek(GF_file, (long) num(GF_file,
+ WIDEARG(,(int)) cmnd - XXX1 + 1), 1);
+ continue;
+ case YYY:
+ (void) four(GF_file);
+ continue;
+ case BOC:
+ (void) four(GF_file); /* skip character code */
+ (void) four(GF_file); /* skip pointer to prev char */
+ min_m = sfour(GF_file);
+ max_m = sfour(GF_file);
+ g->x = -min_m;
+ min_n = sfour(GF_file);
+ g->y = max_n = sfour(GF_file);
+ g->bitmap.w = max_m - min_m + 1;
+ g->bitmap.h = max_n - min_n + 1;
+ break;
+ case BOC1:
+ (void) one(GF_file); /* skip character code */
+ g->bitmap.w = one(GF_file); /* max_m - min_m */
+ g->x = g->bitmap.w - one(GF_file); /* ditto - max_m */
+ ++g->bitmap.w;
+ g->bitmap.h = one(GF_file) + 1;
+ g->y = one(GF_file);
+ break;
+ default:
+ oops("Bad BOC code: %d", cmnd);
+ }
+ break;
+ }
+ paint_switch = White;
+
+ if (debug & DBG_PK)
+ Printf(", size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+
+ alloc_bitmap(&g->bitmap);
+ cp = basep = (BMUNIT *) g->bitmap.bits;
+/*
+ * Read character data into *basep
+ */
+ bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
+ maxp = ADD(basep, g->bitmap.h * bytes_wide);
+ bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
+ new_row = False;
+ word_weight = BITS_PER_BMUNIT;
+ for (;;) {
+ count = -1;
+ cmnd = one(GF_file);
+ if (cmnd < 64) count = cmnd;
+ else if (cmnd >= NEW_ROW_0 && cmnd <= NEW_ROW_MAX) {
+ count = cmnd - NEW_ROW_0;
+ paint_switch = White; /* it'll be complemented later */
+ new_row = True;
+ }
+ else switch (cmnd) {
+ case PAINT1:
+ case PAINT2:
+ case PAINT3:
+ count = num(GF_file, WIDEARG(,(int)) cmnd - PAINT1 + 1);
+ break;
+ case EOC:
+ if (cp >= ADD(basep, bytes_wide)) too_many_bits(ch);
+ return;
+ case SKIP1:
+ case SKIP2:
+ case SKIP3:
+ *((char **) &basep) +=
+ num(GF_file, WIDEARG(,(int)) cmnd - SKIP0) * bytes_wide;
+ case SKIP0:
+ new_row = True;
+ paint_switch = White;
+ break;
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ Fseek(GF_file, (long) num(GF_file,
+ WIDEARG(,(int)) cmnd - XXX1 + 1), 1);
+ break;
+ case YYY:
+ (void) four(GF_file);
+ break;
+ case NO_OP:
+ break;
+ default:
+ oops("Bad command in GF file: %d", cmnd);
+ } /* end switch */
+ if (new_row) {
+ *((char **) &basep) += bytes_wide;
+ if (basep >= maxp || cp >= basep) too_many_bits(ch);
+ cp = basep;
+ word_weight = BITS_PER_BMUNIT;
+ new_row = False;
+ }
+ if (count >= 0) {
+ while (count)
+ if (count <= word_weight) {
+#ifndef MSBITFIRST
+ if (paint_switch)
+ *cp |= bit_masks[count] <<
+ (BITS_PER_BMUNIT - word_weight);
+#endif
+ word_weight -= count;
+#ifdef MSBITFIRST
+ if (paint_switch)
+ *cp |= bit_masks[count] << word_weight;
+#endif
+ break;
+ }
+ else {
+ if (paint_switch)
+#ifndef MSBITFIRST
+ *cp |= bit_masks[word_weight] <<
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ *cp |= bit_masks[word_weight];
+#endif
+ cp++;
+ count -= word_weight;
+ word_weight = BITS_PER_BMUNIT;
+ }
+ paint_switch = 1 - paint_switch;
+ }
+ } /* end for */
+}
+
+
+void
+read_GF_index(fontp)
+ register struct font *fontp;
+{
+ int hppp, vppp;
+ ubyte ch, cmnd;
+ register struct glyph *g;
+
+ fontp->read_char = read_GF_char;
+ GF_file = fontp->file;
+ if (debug & DBG_PK)
+ Printf("Reading GF pixel file %s\n", fontp->filename);
+/*
+ * Find postamble.
+ */
+ Fseek(GF_file, (long) -4, 2);
+ while (four(GF_file) !=
+ ((long) TRAILER << 24 | TRAILER << 16 | TRAILER << 8 | TRAILER))
+ Fseek(GF_file, (long) -5, 1);
+ Fseek(GF_file, (long) -5, 1);
+ for (;;) {
+ ch = one(GF_file);
+ if (ch != TRAILER) break;
+ Fseek(GF_file, (long) -2, 1);
+ }
+ if (ch != GF_ID_BYTE) oops("Bad end of font file %s", fontp->fontname);
+ Fseek(GF_file, (long) -6, 1);
+ expect(POST_POST);
+ Fseek(GF_file, sfour(GF_file), 0); /* move to postamble */
+/*
+ * Read postamble.
+ */
+ expect(POST);
+ (void) four(GF_file); /* pointer to last eoc + 1 */
+ (void) four(GF_file); /* skip design size */
+ (void) four(GF_file); /* skip checksum */
+ hppp = sfour(GF_file);
+ vppp = sfour(GF_file);
+ if (hppp != vppp && (debug & DBG_PK))
+ Printf("Font has non-square aspect ratio %d:%d\n", vppp, hppp);
+ (void) four(GF_file); /* skip min_m */
+ (void) four(GF_file); /* skip max_m */
+ (void) four(GF_file); /* skip min_n */
+ (void) four(GF_file); /* skip max_n */
+/*
+ * Prepare glyph array.
+ */
+ fontp->glyph = (struct glyph *) xmalloc(256 * sizeof(struct glyph),
+ "glyph array");
+ bzero((char *) fontp->glyph, 256 * sizeof(struct glyph));
+/*
+ * Read glyph directory.
+ */
+ while ((cmnd = one(GF_file)) != POST_POST) {
+ int addr;
+
+ ch = one(GF_file); /* character code */
+ g = &fontp->glyph[ch];
+ switch (cmnd) {
+ case CHAR_LOC:
+ /* g->pxl_adv = sfour(GF_file); */
+ (void) four(GF_file);
+ (void) four(GF_file); /* skip dy */
+ break;
+ case CHAR_LOC0:
+ /* g->pxl_adv = one(GF_file) << 16; */
+ (void) one(GF_file);
+ break;
+ default:
+ oops("Non-char_loc command found in GF preamble: %d",
+ cmnd);
+ }
+ g->dvi_adv = fontp->dimconv * sfour(GF_file);
+ addr = four(GF_file);
+ if (addr != -1) g->addr = addr;
+ if (debug & DBG_PK)
+ Printf("Read GF glyph for character %d; dy = %d, addr = %d\n",
+ ch, g->dvi_adv, addr);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/makefile b/systems/msdos/dviware/xdvi-dos/src/makefile
new file mode 100644
index 0000000000..6c817e2869
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/makefile
@@ -0,0 +1,36 @@
+
+# Makefile for dvi previewer (MSDOS version under dv/x).
+# eric ho
+
+
+# -DFONTSUB for running using font substitute file
+#
+DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY -DFONTSUB
+
+#DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY
+
+
+CFLAGS=-O2 -finline-functions -m486 -fexpensive-optimizations -Wall $(DEFS)
+LIBS= -lxt -lxmu -lxext -lxaw -lx -lsys -lm
+SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c fontsub.c
+OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o fontsub.o
+CC=gcc
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+xdvi: $(OBJS)
+ $(CC) -o xdvi *.o $(LIBS)
+ strip +strip-all xdvi
+ aout2exe xdvi
+
+xdvi.o: xdvi.h patchlevel.h xdvi_curs.h xdvi_mask.h
+dvi_init.o: xdvi.h dvi.h
+dvi_draw.o: xdvi.h dvi.h
+tpic.o: xdvi.h
+fontfmts.o: xdvi.h pk.c gf.c pxl.c
+util.o: xdvi.h
+
+font_open.o: font_open.c xdvi.h
+ $(CC) -c $(CFLAGS) font_open.c
+
diff --git a/systems/msdos/dviware/xdvi-dos/src/makefile.bak b/systems/msdos/dviware/xdvi-dos/src/makefile.bak
new file mode 100644
index 0000000000..135ee67d22
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/makefile.bak
@@ -0,0 +1,36 @@
+
+# Makefile for dvi previewer (MSDOS version under dv/x).
+# eric ho
+
+
+# -DFONTSUB for running using font substitute file
+#
+#DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY -DFONTSUB
+
+DEFS= -DUSE_PK -DNOTOOL -DBMLONG -DGREY
+
+
+CFLAGS=-O2 -finline-functions -m486 -fexpensive-optimizations -Wall $(DEFS)
+LIBS= -lxt -lxmu -lxext -lxaw -lx -lsys -lm
+SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c fontsub.c
+OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o fontsub.o
+CC=gcc
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+xdvi: $(OBJS)
+ $(CC) -o xdvi *.o $(LIBS)
+ strip +strip-all xdvi
+ aout2exe xdvi
+
+xdvi.o: xdvi.h patchlevel.h xdvi_curs.h xdvi_mask.h
+dvi_init.o: xdvi.h dvi.h
+dvi_draw.o: xdvi.h dvi.h
+tpic.o: xdvi.h
+fontfmts.o: xdvi.h pk.c gf.c pxl.c
+util.o: xdvi.h
+
+font_open.o: font_open.c xdvi.h
+ $(CC) -c $(CFLAGS) font_open.c
+
diff --git a/systems/msdos/dviware/xdvi-dos/src/maketexp b/systems/msdos/dviware/xdvi-dos/src/maketexp
new file mode 100644
index 0000000000..5c63ed3fb9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/maketexp
@@ -0,0 +1,141 @@
+#!/bin/sh
+#
+# This script file makes a new TeX PK font, because one wasn't
+# found. Parameters are:
+#
+# name dpi bdpi magnification [mode [subdir]]
+#
+# `name' is the name of the font, such as `cmr10'. `dpi' is
+# the resolution the font is needed at. `bdpi' is the base
+# resolution, useful for figuring out the mode to make the font
+# in. `magnification' is a string to pass to MF as the
+# magnification. `mode', if supplied, is the mode to use.
+#
+# Note that this file must execute Metafont, and then gftopk,
+# and place the result in the correct location for the PostScript
+# driver to find it subsequently. If this doesn't work, it will
+# be evident because MF will be invoked over and over again.
+#
+# Of course, it needs to be set up for your site.
+#
+TEXDIR=/usr/lib/tex
+LOCALDIR=/LocalLibrary/Fonts/TeXFonts
+DESTDIR=$LOCALDIR/pk
+#
+# TEMPDIR needs to be unique for each process because of the possibility
+# of simultaneous processes running this script.
+#
+if test "$TMPDIR" = ""
+then
+ TEMPDIR=/tmp/mtpk.$$
+else
+ TEMPDIR=$TMPDIR/mtpk.$$
+fi
+NAME=$1
+DPI=$2
+BDPI=$3
+MAG=$4
+MODE=$5
+
+umask 0
+
+if test "$MODE" = ""
+then
+ if test $BDPI = 300
+ then
+ MODE=imagen
+ elif test $BDPI = 200
+ then
+ MODE=FAX
+ elif test $BDPI = 360
+ then
+ MODE=nextII
+ elif test $BDPI = 400
+ then
+ MODE=nexthi
+ elif test $BDPI = 100
+ then
+ MODE=nextscreen
+ elif test $BDPI = 635
+ then
+ MODE=linolo
+ elif test $BDPI = 1270
+ then
+ MODE=linohi
+ elif test $BDPI = 2540
+ then
+ MODE=linosuper
+ else
+ echo "I don't know the mode for $BDPI"
+ echo "Have your system admin update MakeTeXPK"
+ exit 1
+ fi
+fi
+
+# Something like the following is useful at some sites.
+# DESTDIR=/usr/local/lib/tex/fonts/pk.$MODE
+GFNAME=$NAME.$DPI'gf'
+PKNAME=$NAME.$DPI'pk'
+
+# Clean up on normal or abnormal exit
+trap "cd /; /bin/rm -rf $TEMPDIR $DESTDIR/pktmp.$$" 0 1 2 15
+
+
+if test ! -d $DESTDIR
+then
+ mkdir $DESTDIR
+fi
+
+if test "$6" != ""
+then
+ DESTDIR=$DESTDIR"$6"
+ if test ! -d $DESTDIR
+ then
+ mkdir $DESTDIR
+ fi
+fi
+
+mkdir $TEMPDIR
+cd $TEMPDIR
+
+if test -r $DESTDIR/$PKNAME
+then
+ echo "$DESTDIR/$PKNAME already exists!"
+ exit 0
+fi
+
+# check also in the standard place
+
+if test "$6" = ""
+then
+ if test -r $TEXDIR/fonts/pk/$PKNAME
+ then
+ echo $TEXDIR/fonts/pk/$PKNAME already exists!
+ exit 0
+ fi
+else
+ if test -r $TEXDIR/fonts/pk/$6"$PKNAME"
+ then
+ echo $TEXDIR/fonts/pk/$6"$PKNAME" already exists!
+ exit 0
+ fi
+fi
+
+echo "mf \"\\mode:=$MODE; mag:=$MAG; scrollmode; input $NAME\" < /dev/null"
+mf "\mode:=$MODE; mag:=$MAG; scrollmode; input $NAME" < /dev/null
+if test ! -r $GFNAME
+then
+ echo "Metafont failed for some reason on $GFNAME"
+ exit 1
+fi
+
+gftopk -v ./$GFNAME ./$PKNAME
+
+# Install the PK file carefully, since others may be doing the same
+# as us simultaneously.
+
+mv $PKNAME $DESTDIR/pktmp.$$
+cd $DESTDIR
+mv pktmp.$$ $PKNAME
+
+exit 0
diff --git a/systems/msdos/dviware/xdvi-dos/src/patchlev.h b/systems/msdos/dviware/xdvi-dos/src/patchlev.h
new file mode 100644
index 0000000000..0eee8898e5
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/patchlev.h
@@ -0,0 +1 @@
+#define PATCHLEVEL 16
diff --git a/systems/msdos/dviware/xdvi-dos/src/pk.c b/systems/msdos/dviware/xdvi-dos/src/pk.c
new file mode 100644
index 0000000000..969245fdd1
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/pk.c
@@ -0,0 +1,324 @@
+/***
+ *** PK font reading routines.
+ *** Public routines are read_PK_index and read_PK_char.
+ ***/
+
+#define PK_ID 89
+#define PK_CMD_START 240
+#define PK_X1 240
+#define PK_X2 241
+#define PK_X3 242
+#define PK_X4 243
+#define PK_Y 244
+#define PK_POST 245
+#define PK_NOOP 246
+#define PK_PRE 247
+
+static int PK_flag_byte;
+static unsigned PK_input_byte;
+static int PK_bitpos;
+static int PK_dyn_f;
+static int PK_repeat_count;
+
+static int
+PK_get_nyb(fp)
+ register FILE *fp;
+{
+ unsigned temp;
+ if (PK_bitpos < 0) {
+ PK_input_byte = one(fp);
+ PK_bitpos = 4;
+ }
+ temp = PK_input_byte >> PK_bitpos;
+ PK_bitpos -= 4;
+ return (temp & 0xf);
+}
+
+
+static int
+PK_packed_num(fp)
+ register FILE *fp;
+{
+ int i,j;
+
+ if ((i = PK_get_nyb(fp)) == 0) {
+ do {
+ j = PK_get_nyb(fp);
+ ++i;
+ }
+ while (j == 0);
+ while (i > 0) {
+ j = (j << 4) | PK_get_nyb(fp);
+ --i;
+ }
+ return (j - 15 + ((13 - PK_dyn_f) << 4) + PK_dyn_f);
+ }
+ else {
+ if (i <= PK_dyn_f) return i;
+ if (i < 14)
+ return (((i - PK_dyn_f - 1) << 4) + PK_get_nyb(fp)
+ + PK_dyn_f + 1);
+ if (i == 14) PK_repeat_count = PK_packed_num(fp);
+ else PK_repeat_count = 1;
+ return PK_packed_num(fp);
+ }
+}
+
+
+static void
+PK_skip_specials(fontp)
+ register struct font *fontp;
+{
+ int i,j;
+ register FILE *fp = fontp->file;
+
+ do {
+ PK_flag_byte = one(fp);
+ if (PK_flag_byte >= PK_CMD_START) {
+ switch (PK_flag_byte) {
+ case PK_X1 :
+ case PK_X2 :
+ case PK_X3 :
+ case PK_X4 :
+ i = 0;
+ for (j = PK_CMD_START; j <= PK_flag_byte; ++j)
+ i = (i << 8) | one(fp);
+ while (i--) (void) one(fp);
+ break;
+ case PK_Y :
+ (void) four(fp);
+ case PK_POST :
+ case PK_NOOP :
+ break;
+ default :
+ oops("Unexpected %d in PK file %s", PK_flag_byte,
+ fontp->filename);
+ break;
+ }
+ }
+ }
+ while (PK_flag_byte != PK_POST && PK_flag_byte >= PK_CMD_START);
+}
+
+/*
+ * Public routines
+ */
+
+static void
+read_PK_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ int i, j;
+ int n;
+ int row_bit_pos;
+ Boolean paint_switch;
+ BMUNIT *cp;
+ register struct glyph *g;
+ register FILE *fp = fontp->file;
+ long fpwidth;
+ BMUNIT word;
+ int word_weight, bytes_wide;
+ int rows_left, h_bit, count;
+
+ g = &fontp->glyph[ch];
+ PK_flag_byte = g->x2;
+ PK_dyn_f = PK_flag_byte >> 4;
+ paint_switch = ((PK_flag_byte & 8) != 0);
+ PK_flag_byte &= 0x7;
+ if (PK_flag_byte == 7) n = 4;
+ else if (PK_flag_byte > 3) n = 2;
+ else n = 1;
+
+ if (debug & DBG_PK) Printf("loading pk char %d, char type %d ", ch, n);
+
+ /*
+ * now read rest of character preamble
+ */
+ if (n != 4) fpwidth = num(fp, 3);
+ else {
+ fpwidth = sfour(fp);
+ (void) four(fp); /* horizontal escapement */
+ }
+ (void) num(fp, n); /* vertical escapement */
+ {
+ unsigned long w, h;
+
+ w = num(fp, n);
+ h = num(fp, n);
+ if (w > 0x7fff || h > 0x7fff)
+ oops("Character %d too large in file %s", ch, fontp->fontname);
+ g->bitmap.w = w;
+ g->bitmap.h = h;
+ }
+ g->x = snum(fp, n);
+ g->y = snum(fp, n);
+
+ g->dvi_adv = fontp->dimconv * fpwidth;
+
+ if (debug & DBG_PK) {
+ if (g->bitmap.w != 0)
+ Printf(", size=%dx%d, dvi_adv=%ld", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+ Putchar('\n');
+ }
+
+ alloc_bitmap(&g->bitmap);
+ cp = (BMUNIT *) g->bitmap.bits;
+
+ /*
+ * read character data into *cp
+ */
+ bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
+ PK_bitpos = -1;
+ if (PK_dyn_f == 14) { /* get raster by bits */
+ bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
+ for (i = 0; i < g->bitmap.h; i++) { /* get all rows */
+ cp = ADD(g->bitmap.bits, i * bytes_wide);
+#ifndef MSBITFIRST
+ row_bit_pos = -1;
+#else
+ row_bit_pos = BITS_PER_BMUNIT;
+#endif
+ for (j = 0; j < g->bitmap.w; j++) { /* get one row */
+ if (--PK_bitpos < 0) {
+ word = one(fp);
+ PK_bitpos = 7;
+ }
+#ifndef MSBITFIRST
+ if (++row_bit_pos >= BITS_PER_BMUNIT) {
+ cp++;
+ row_bit_pos = 0;
+ }
+#else
+ if (--row_bit_pos < 0) {
+ cp++;
+ row_bit_pos = BITS_PER_BMUNIT - 1;
+ }
+#endif
+ if (word & (1 << PK_bitpos)) *cp |= 1 << row_bit_pos;
+ }
+ }
+ }
+ else { /* get packed raster */
+ rows_left = g->bitmap.h;
+ h_bit = g->bitmap.w;
+ PK_repeat_count = 0;
+ word_weight = BITS_PER_BMUNIT;
+ word = 0;
+ while (rows_left > 0) {
+ count = PK_packed_num(fp);
+ while (count > 0) {
+ if (count < word_weight && count < h_bit) {
+#ifndef MSBITFIRST
+ if (paint_switch)
+ word |= bit_masks[count] <<
+ (BITS_PER_BMUNIT - word_weight);
+#endif
+ h_bit -= count;
+ word_weight -= count;
+#ifdef MSBITFIRST
+ if (paint_switch)
+ word |= bit_masks[count] << word_weight;
+#endif
+ count = 0;
+ }
+ else if (count >= h_bit && h_bit <= word_weight) {
+ if (paint_switch)
+ word |= bit_masks[h_bit] <<
+#ifndef MSBITFIRST
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ (word_weight - h_bit);
+#endif
+ *cp++ = word;
+ /* "output" row(s) */
+ for (i = PK_repeat_count * bytes_wide /
+ BYTES_PER_BMUNIT; i > 0; --i) {
+ *cp = *SUB(cp, bytes_wide);
+ ++cp;
+ }
+ rows_left -= PK_repeat_count + 1;
+ PK_repeat_count = 0;
+ word = 0;
+ word_weight = BITS_PER_BMUNIT;
+ count -= h_bit;
+ h_bit = g->bitmap.w;
+ }
+ else {
+ if (paint_switch)
+#ifndef MSBITFIRST
+ word |= bit_masks[word_weight] <<
+ (BITS_PER_BMUNIT - word_weight);
+#else
+ word |= bit_masks[word_weight];
+#endif
+ *cp++ = word;
+ word = 0;
+ count -= word_weight;
+ h_bit -= word_weight;
+ word_weight = BITS_PER_BMUNIT;
+ }
+ }
+ paint_switch = 1 - paint_switch;
+ }
+ if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h)))
+ oops("Wrong number of bits stored: char. %d, font %s", ch,
+ fontp->fontname);
+ if (rows_left != 0 || h_bit != g->bitmap.w)
+ oops("Bad pk file (%s), too many bits", fontp->fontname);
+ }
+}
+
+void
+read_PK_index(fontp)
+ register struct font *fontp;
+{
+ int hppp, vppp;
+
+ fontp->read_char = read_PK_char;
+ if (debug & DBG_PK)
+ Printf("Reading PK pixel file %s\n", fontp->filename);
+
+ Fseek(fontp->file, (long) one(fontp->file), 1); /* skip comment */
+
+ (void) four(fontp->file); /* skip design size */
+ (void) four(fontp->file); /* skip checksum */
+ hppp = sfour(fontp->file);
+ vppp = sfour(fontp->file);
+ if (hppp != vppp && (debug & DBG_PK))
+ Printf("Font has non-square aspect ratio %d:%d\n", vppp, hppp);
+ /*
+ * Prepare glyph array.
+ */
+ fontp->glyph = (struct glyph *) xmalloc(256 * sizeof(struct glyph),
+ "glyph array");
+ bzero((char *) fontp->glyph, 256 * sizeof(struct glyph));
+ /*
+ * Read glyph directory (really a whole pass over the file).
+ */
+ for (;;) {
+ int bytes_left, flag_low_bits;
+ unsigned int ch;
+
+ PK_skip_specials(fontp);
+ if (PK_flag_byte == PK_POST) break;
+ flag_low_bits = PK_flag_byte & 0x7;
+ if (flag_low_bits == 7) {
+ bytes_left = four(fontp->file);
+ ch = four(fontp->file);
+ } else if (flag_low_bits > 3) {
+ bytes_left = ((flag_low_bits - 4) << 16) + two(fontp->file);
+ ch = one(fontp->file);
+ } else {
+ bytes_left = (flag_low_bits << 8) + one(fontp->file);
+ ch = one(fontp->file);
+ }
+ fontp->glyph[ch].addr = ftell(fontp->file);
+ fontp->glyph[ch].x2 = PK_flag_byte;
+ Fseek(fontp->file, (long) bytes_left, 1);
+ if (debug & DBG_PK)
+ Printf("Scanning pk char %u, at %ld.\n", ch,
+ fontp->glyph[ch].addr);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/pxl.c b/systems/msdos/dviware/xdvi-dos/src/pxl.c
new file mode 100644
index 0000000000..1841aa614a
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/pxl.c
@@ -0,0 +1,166 @@
+/***
+ *** PXL font reading routines.
+ *** Public routines are read_PXL_index and read_PXL_char.
+ ***/
+
+#ifndef MSBITFIRST
+static unsigned char _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+#endif /* MSBITFIRST */
+
+static void
+read_PXL_char(fontp, ch)
+ register struct font *fontp;
+ ubyte ch;
+{
+ register struct bitmap *bitmap;
+ register BMUNIT *ptr;
+ register FILE *fp = fontp->file;
+ register int i, j;
+#ifndef BMLONG
+ register int padding_length;
+#endif
+
+ bitmap = &fontp->glyph[ch].bitmap;
+ /* in file, bitmap rows are multiples of 32 bits wide */
+ alloc_bitmap(bitmap);
+ ptr = (BMUNIT *) bitmap->bits;
+#ifndef BMLONG
+ padding_length = 3 - (bitmap->bytes_wide + 3) % 4;
+#endif
+ for (i = bitmap->h; i > 0; --i) {
+ for (j = bitmap->bytes_wide; j > 0; j -= BYTES_PER_BMUNIT) {
+#ifndef MSBITFIRST
+ *ptr = _reverse_byte[one(fp)];
+#if BYTES_PER_BMUNIT > 1
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 8;
+#endif
+#ifdef BMLONG
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 16;
+ *ptr |= (BMUNIT) _reverse_byte[one(fp)] << 24;
+#endif
+#else /* MSBITFIRST */
+ *ptr = 0;
+#ifdef BMLONG
+ *ptr |= (BMUNIT) one(fp) << 24;
+ *ptr |= (BMUNIT) one(fp) << 16;
+#endif
+#if BYTES_PER_BMUNIT > 1
+ *ptr |= (BMUNIT) one(fp) << 8;
+#endif
+ *ptr |= (BMUNIT) one(fp);
+#endif /* MSBITFIRST */
+ ++ptr;
+ }
+#ifndef BMLONG
+ for (j = padding_length; j > 0; --j) (void) one(fp);
+#endif
+ }
+}
+
+void
+read_PXL_index(fontp)
+ register struct font *fontp;
+{
+ register FILE *fp = fontp->file;
+ register struct glyph *g;
+ long font_dir_ptr;
+ long trailer_ptr;
+
+ if (debug & DBG_PK)
+ Printf("Reading PXL file %s\n", fontp->filename);
+ fontp->read_char = read_PXL_char;
+ /* seek to trailer info */
+ Fseek(fp, (long) -4, 2);
+ while (four(fp) != 1001)
+ Fseek(fp, (long) -5, 1);
+ Fseek(fp, (long) -5 * 4, 1);
+ trailer_ptr = ftell(fp);
+ (void) four(fp); /* checksum */
+ (void) four(fp); /* magnify */
+ (void) four(fp); /* design size */
+ font_dir_ptr = sfour(fp) * 4;
+ (void) four(fp); /* pxl id word */
+ /* seek to font directory */
+ Fseek(fp, font_dir_ptr, 0);
+ maxchar = (trailer_ptr - font_dir_ptr) / 16 - 1;
+ fontp->glyph = (struct glyph *)
+ xmalloc((maxchar + 1) * sizeof(struct glyph), "glyph array");
+ for (g = fontp->glyph; g <= fontp->glyph + maxchar; ++g) {
+ g->bitmap.bits = NULL;
+ g->bitmap2.bits = NULL;
+#ifdef GREY
+ g->pixmap2 = NULL;
+#endif
+ g->bitmap.w = two(fp);
+ g->bitmap.h = two(fp);
+ g->x = stwo(fp);
+ g->y = stwo(fp);
+ g->addr = four(fp) * 4;
+ /*
+ ** The TFM-width word is kind of funny in the units
+ ** it is expressed in. It works this way:
+ **
+ ** If a glyph has width 'w' in a font with design-size
+ ** 'd' (both in same units), the TFM-width word is
+ **
+ ** t = (w/d) * 2^20
+ **
+ ** Therefore, in order to find the glyph width in
+ ** DVI units (1 / 2^16 points), we take the design-size
+ ** 'd' (in DVI's), the magnification 'm' of the PXL file
+ ** and the TFM-width word 't' to the width (in DVI's)
+ ** as follows:
+ **
+ ** dmt
+ ** w = -----
+ ** 2^20
+ **
+ ** But the magnification of the PXL file is just the
+ ** scaled size 's' over the design size, so the final
+ ** expression for the width is
+ **
+ ** st
+ ** w = ----
+ ** 2^20
+ **
+ */
+
+ g->dvi_adv = fontp->dimconv * four(fp);
+ if (debug & DBG_PK)
+ Printf("size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
+ g->dvi_adv);
+ }
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/tpic.c b/systems/msdos/dviware/xdvi-dos/src/tpic.c
new file mode 100644
index 0000000000..f6eb82da8c
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/tpic.c
@@ -0,0 +1,434 @@
+/*
+ * Support drawing routines for TeXsun and TeX
+ *
+ * Copyright, (C) 1987, 1988 Tim Morgan, UC Irvine
+ *
+ * At the time these routines are called, the values of hh and vv should
+ * have been updated to the upper left corner of the graph (the position
+ * the \special appears at in the dvi file). Then the coordinates in the
+ * graphics commands are in terms of a virtual page with axes oriented the
+ * same as the Imagen and the SUN normally have:
+ *
+ * 0,0
+ * +-----------> +x
+ * |
+ * |
+ * |
+ * \ /
+ * +y
+ *
+ * Angles are measured in the conventional way, from +x towards +y.
+ * Unfortunately, that reverses the meaning of "counterclockwise"
+ * from what it's normally thought of.
+ *
+ * A lot of floating point arithmetic has been converted to integer
+ * arithmetic for speed. In some places, this is kind-of kludgy, but
+ * it's worth it.
+ */
+
+#include <math.h>
+#include <ctype.h>
+
+#include "xdvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+#define MAXPOINTS 300 /* Max points in a path */
+#define TWOPI (double) (3.14159265359*2.0)
+#define MAX_PEN_SIZE 7 /* Max pixels of pen width */
+
+
+static int xx[MAXPOINTS], yy[MAXPOINTS]; /* Path in milli-inches */
+static int path_len = 0; /* # points in current path */
+static int pen_size = 1; /* Pixel width of lines drawn */
+
+static Boolean whiten = False;
+static Boolean shade = False;
+static Boolean blacken = False;
+
+/* Unfortunately, these values also appear in dvisun.c */
+#define xRESOLUTION (pixels_per_inch/shrink_factor)
+#define yRESOLUTION (pixels_per_inch/shrink_factor)
+
+
+/*
+ * Issue warning messages
+ */
+static void
+Warning(fmt, msg)
+ char *fmt, *msg;
+{
+ Fprintf(stderr, fmt, msg);
+ (void) fputc('\n', stderr);
+}
+
+
+/*
+ * Set the size of the virtual pen used to draw in milli-inches
+ */
+/* ARGSUSED */
+static void
+set_pen_size(cp)
+ char *cp;
+{
+ int ps;
+
+ if (sscanf(cp, " %d ", &ps) != 1) {
+ Warning("illegal .ps command format: %s", cp);
+ return;
+ }
+ pen_size = (ps * (xRESOLUTION + yRESOLUTION) + 1000) / 2000;
+ if (pen_size < 1) pen_size = 1;
+ else if (pen_size > MAX_PEN_SIZE) pen_size = MAX_PEN_SIZE;
+}
+
+
+/*
+ * Print the line defined by previous path commands
+ */
+static void
+flush_path()
+{
+ register int i;
+ int last_min_x, last_max_x, last_min_y, last_max_y;
+
+ last_min_x = 30000;
+ last_min_y = 30000;
+ last_max_x = -30000;
+ last_max_y = -30000;
+ for (i = 1; i < path_len; i++) {
+ if (xx[i] > last_max_x) last_max_x = xx[i];
+ if (xx[i] < last_min_x) last_min_x = xx[i];
+ if (yy[i] > last_max_y) last_max_y = yy[i];
+ if (yy[i] < last_min_y) last_min_y = yy[i];
+ line_btw(xx[i], yy[i], xx[i+1], yy[i+1]);
+ }
+ if (xx[path_len] > last_max_x) last_max_x = xx[path_len];
+ if (xx[path_len] < last_min_x) last_min_x = xx[path_len];
+ if (yy[path_len] > last_max_y) last_max_y = yy[path_len];
+ if (yy[path_len] < last_min_y) last_min_y = yy[path_len];
+ path_len = 0;
+ do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y);
+}
+
+
+/*
+ * Print a dashed line along the previously defined path, with
+ * the dashes/inch defined.
+ */
+
+static void
+flush_dashed(cp, dotted)
+ char *cp;
+ int dotted;
+{
+ int i;
+ int numdots;
+ int lx0, ly0, lx1, ly1;
+ int cx0, cy0, cx1, cy1;
+ float inchesperdash;
+ double d, spacesize, a, b, dx, dy, milliperdash;
+
+ if (sscanf(cp, " %f ", &inchesperdash) != 1) {
+ Warning("illegal format for dotted/dashed line: %s", cp);
+ return;
+ }
+ if (path_len <= 1 || inchesperdash <= 0.0) {
+ Warning("illegal conditions for dotted/dashed line", "");
+ return;
+ }
+ milliperdash = inchesperdash * 1000.0;
+ lx0 = xx[1]; ly0 = yy[1];
+ lx1 = xx[2]; ly1 = yy[2];
+ dx = lx1 - lx0;
+ dy = ly1 - ly0;
+ if (dotted) {
+ numdots = sqrt(dx*dx + dy*dy) / milliperdash + 0.5;
+ if (numdots == 0) numdots = 1;
+ for (i = 0; i <= numdots; i++) {
+ a = (float) i / (float) numdots;
+ cx0 = lx0 + a * dx + 0.5;
+ cy0 = ly0 + a * dy + 0.5;
+ dot_at(cx0, cy0);
+ }
+ }
+ else {
+ d = sqrt(dx*dx + dy*dy);
+ numdots = d / (2.0 * milliperdash) + 1.0;
+ if (numdots <= 1)
+ line_btw(lx0, ly0, lx1, ly1);
+ else {
+ spacesize = (d - numdots * milliperdash) / (numdots - 1);
+ for (i = 0; i < numdots - 1; i++) {
+ a = i * (milliperdash + spacesize) / d;
+ b = a + milliperdash / d;
+ cx0 = lx0 + a * dx + 0.5;
+ cy0 = ly0 + a * dy + 0.5;
+ cx1 = lx0 + b * dx + 0.5;
+ cy1 = ly0 + b * dy + 0.5;
+ line_btw(cx0, cy0, cx1, cy1);
+ b += spacesize / d;
+ }
+ cx0 = lx0 + b * dx + 0.5;
+ cy0 = ly0 + b * dy + 0.5;
+ line_btw(cx0, cy0, lx1, ly1);
+ }
+ }
+ path_len = 0;
+}
+
+
+/*
+ * Add a point to the current path
+ */
+static void
+add_path(cp)
+ char *cp;
+{
+ int pathx, pathy;
+
+ if (++path_len >= MAXPOINTS) oops("Too many points");
+ if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2)
+ oops("Malformed path command");
+ xx[path_len] = pathx;
+ yy[path_len] = pathy;
+}
+
+
+/*
+ * Draw to a floating point position
+ */
+static void
+im_fdraw(x, y)
+ double x,y;
+{
+ if (++path_len >= MAXPOINTS) oops("Too many arc points");
+ xx[path_len] = x + 0.5;
+ yy[path_len] = y + 0.5;
+}
+
+
+/*
+ * Draw an ellipse with the indicated center and radices.
+ */
+static void
+draw_ellipse(xc, yc, xr, yr)
+ int xc, yc, xr, yr;
+{
+ double angle, theta;
+ int n;
+ int px0, py0, px1, py1;
+
+ angle = (xr + yr) / 2.0;
+ theta = sqrt(1.0 / angle);
+ n = TWOPI / theta + 0.5;
+ if (n < 12) n = 12;
+ else if (n > 80) n = 80;
+ n /= 2;
+ theta = TWOPI / n;
+
+ angle = 0.0;
+ px0 = xc + xr; /* cos(0) = 1 */
+ py0 = yc; /* sin(0) = 0 */
+ while ((angle += theta) <= TWOPI) {
+ px1 = xc + xr*cos(angle) + 0.5;
+ py1 = yc + yr*sin(angle) + 0.5;
+ line_btw(px0, py0, px1, py1);
+ px0 = px1;
+ py0 = py1;
+ }
+ line_btw(px0, py0, xc + xr, yc);
+}
+
+/*
+ * Draw an arc
+ */
+static void
+arc(cp, invis)
+ char *cp;
+ Boolean invis;
+{
+ int xc, yc, xrad, yrad, n;
+ float start_angle, end_angle, angle, theta, r;
+ double xradius, yradius, xcenter, ycenter;
+
+ if (sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad,
+ &start_angle, &end_angle) != 6) {
+ Warning("illegal arc specification: %s", cp);
+ return;
+ }
+
+ if (invis) return;
+
+ /* We have a specialized fast way to draw closed circles/ellipses */
+ if (start_angle <= 0.0 && end_angle >= 6.282) {
+ draw_ellipse(xc, yc, xrad, yrad);
+ return;
+ }
+ xcenter = xc;
+ ycenter = yc;
+ xradius = xrad;
+ yradius = yrad;
+ r = (xradius + yradius) / 2.0;
+ theta = sqrt(1.0 / r);
+ n = 0.3 * TWOPI / theta + 0.5;
+ if (n < 12) n = 12;
+ else if (n > 80) n = 80;
+ n /= 2;
+ theta = TWOPI / n;
+ flush_path();
+ im_fdraw(xcenter + xradius * cos(start_angle),
+ ycenter + yradius * sin(start_angle));
+ angle = start_angle + theta;
+ if (end_angle < angle) end_angle += TWOPI;
+ while (angle < end_angle) {
+ im_fdraw(xcenter + xradius * cos(angle),
+ ycenter + yradius * sin(angle));
+ angle += theta;
+ }
+ im_fdraw(xcenter + xradius * cos(end_angle),
+ ycenter + yradius * sin(end_angle));
+ flush_path();
+}
+
+
+/*
+ * APPROXIMATE integer distance between two points
+ */
+#define dist(x0, y0, x1, y1) (abs(x0-x1)+abs(y0-y1))
+
+
+/*
+ * Draw a spline along the previously defined path
+ */
+static void
+flush_spline()
+{
+ int xp, yp;
+ int N;
+ int lastx, lasty;
+ int t1, t2, t3;
+ int steps;
+ int j;
+ register int i, w;
+
+#ifdef lint
+ lastx = lasty = -1;
+#endif
+ N = path_len + 1;
+ xx[0] = xx[1];
+ yy[0] = yy[1];
+ xx[N] = xx[N-1];
+ yy[N] = yy[N-1];
+ for (i = 0; i < N - 1; i++) { /* interval */
+ steps = (dist(xx[i], yy[i], xx[i+1], yy[i+1]) +
+ dist(xx[i+1], yy[i+1], xx[i+2], yy[i+2])) / 80;
+ for (j = 0; j < steps; j++) { /* points within */
+ w = (j * 1000 + 500) / steps;
+ t1 = w * w / 20;
+ w -= 500;
+ t2 = (750000 - w * w) / 10;
+ w -= 500;
+ t3 = w * w / 20;
+ xp = (t1*xx[i+2] + t2*xx[i+1] + t3*xx[i] + 50000) / 100000;
+ yp = (t1*yy[i+2] + t2*yy[i+1] + t3*yy[i] + 50000) / 100000;
+ if (i != 0 || j != 0) line_btw(lastx, lasty, xp, yp);
+ lastx = xp;
+ lasty = yp;
+ }
+ }
+ path_len = 0;
+}
+
+
+/*
+ * Shade the last box, circle, or ellipse
+ */
+static void
+shade_last()
+{
+ blacken = whiten = False;
+ shade = True;
+}
+
+
+/*
+ * Make the last box, circle, or ellipse, white inside (shade with white)
+ */
+static void
+whiten_last()
+{
+ whiten = True;
+ blacken = shade = False;
+}
+
+
+/*
+ * Make last box, etc, black inside
+ */
+static void
+blacken_last()
+{
+ blacken = True;
+ whiten = shade = False;
+}
+
+
+/*
+ * The following copyright message applies to the rest of this file. --PV
+ */
+
+/*
+ * This program is Copyright (C) 1987 by the Board of Trustees of the
+ * University of Illinois, and by the author Dirk Grunwald.
+ *
+ * This program may be freely copied, as long as this copyright
+ * message remaines affixed. It may not be sold, although it may
+ * be distributed with other software which is sold. If the
+ * software is distributed, the source code must be made available.
+ *
+ * No warranty, expressed or implied, is given with this software.
+ * It is presented in the hope that it will prove useful.
+ *
+ * Hacked in ignorance and desperation by jonah@db.toronto.edu
+ */
+
+/*
+ * The code to handle the \specials generated by tpic was modified
+ * by Dirk Grunwald using the code Tim Morgan at Univ. of Calif, Irvine
+ * wrote for TeXsun.
+ */
+
+#define COMLEN 4
+
+void
+applicationDoSpecial(cp)
+ char *cp;
+{
+ char command[COMLEN], *orig_cp;
+ register int len;
+
+ orig_cp = cp;
+ while (isspace(*cp)) ++cp;
+ len = 0;
+ while (!isspace(*cp) && *cp && len < COMLEN-1) command[len++] = *cp++;
+ command[len] = '\0';
+ if (strcmp(command, "pn") == 0) set_pen_size(cp);
+ else if (strcmp(command, "fp") == 0) flush_path();
+ else if (strcmp(command, "da") == 0) flush_dashed(cp, 0);
+ else if (strcmp(command, "dt") == 0) flush_dashed(cp, 1);
+ else if (strcmp(command, "pa") == 0) add_path(cp);
+ else if (strcmp(command, "ar") == 0) arc(cp, False);
+ else if (strcmp(command, "ia") == 0) arc(cp, True);
+ else if (strcmp(command, "sp") == 0) flush_spline();
+ else if (strcmp(command, "sh") == 0) shade_last();
+ else if (strcmp(command, "wh") == 0) whiten_last();
+ else if (strcmp(command, "bk") == 0) blacken_last();
+ /* throw away the path -- jansteen */
+ else if (strcmp(command, "ip") == 0) path_len = 0;
+ else if (!hush_spec_now)
+ Fprintf(stderr, "%s: special \"%s\" not implemented\n", prog,
+ orig_cp);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/util.c b/systems/msdos/dviware/xdvi-dos/src/util.c
new file mode 100644
index 0000000000..f1013d4d97
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/util.c
@@ -0,0 +1,216 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ */
+
+#include "xdvi.h"
+#include <errno.h>
+int errno;
+
+#ifdef VMS
+#include <rmsdef.h>
+#endif /* VMS */
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+char *malloc();
+#endif
+#if defined(macII) && !defined(__STDC__) /* stdlib.h doesn't define these */
+char *malloc();
+#endif /* macII */
+
+#if NeedVarargsPrototypes /* this is for oops */
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DOPRNT /* define this if vfprintf gives you trouble */
+#define vfprintf(stream, message, args) _doprnt(message, args, stream)
+#endif
+
+/*
+ * General utility routines.
+ */
+
+/*
+ * Print error message and quit.
+ */
+
+#if NeedVarargsPrototypes
+NORETURN void
+oops(_Xconst char *message, ...)
+#else
+/* VARARGS */
+NORETURN void
+oops(va_alist)
+ va_dcl
+#endif
+{
+#if !NeedVarargsPrototypes
+ _Xconst char *message;
+#endif
+ va_list args;
+
+ Fprintf(stderr, "%s: ", prog);
+#if NeedVarargsPrototypes
+ va_start(args, message);
+#else
+ va_start(args);
+ message = va_arg(args, _Xconst char *);
+#endif
+ (void) vfprintf(stderr, message, args);
+ va_end(args);
+ Putc('\n', stderr);
+ exit(1);
+}
+
+/*
+ * Either allocate storage or fail with explanation.
+ */
+
+char *
+xmalloc(size, why)
+ unsigned size;
+ _Xconst char *why;
+{
+ char *mem = malloc(size);
+
+ if (mem == NULL)
+ oops("! Cannot allocate %u bytes for %s.\n", size, why);
+ return mem;
+}
+
+/*
+ * Allocate bitmap for given font and character
+ */
+
+void
+alloc_bitmap(bitmap)
+ register struct bitmap *bitmap;
+{
+ register unsigned int size;
+
+ /* width must be multiple of 16 bits for raster_op */
+ bitmap->bytes_wide = ROUNDUP(bitmap->w, BITS_PER_BMUNIT) *
+ BYTES_PER_BMUNIT;
+ size = bitmap->bytes_wide * bitmap->h;
+ bitmap->bits = xmalloc(size != 0 ? size : 1, "character bitmap");
+}
+
+
+/*
+ * Close the pixel file for the least recently used font.
+ */
+
+static void
+close_a_file()
+{
+ register struct font *fontp;
+ unsigned short oldest = ~0;
+ struct font *f = NULL;
+
+ for (fontp = font_head; fontp != NULL; fontp = fontp->next)
+ if (fontp->file != NULL && fontp->timestamp <= oldest) {
+ f = fontp;
+ oldest = fontp->timestamp;
+ }
+ if (f == NULL)
+ oops("Can't find an open pixel file to close");
+ Fclose(f->file);
+ f->file = NULL;
+ ++n_files_left;
+}
+
+/*
+ * Open a file in the given mode.
+ */
+
+FILE *
+xfopen(filename)
+ _Xconst char *filename;
+{
+ FILE *f;
+
+ if (n_files_left == 0) close_a_file();
+ f = fopen(filename, OPEN_MODE);
+
+#ifndef VMS
+/* ericho if (f == NULL && (errno == EMFILE || errno == ENFILE)) */
+ if (f == NULL && (errno == EMFILE))
+#else /* VMS */
+ if (f == NULL && errno == EVMSERR && vaxc$errno == RMS$_ACC)
+#endif /* VMS */
+
+ {
+ n_files_left = 0;
+ close_a_file();
+ f = fopen(filename, OPEN_MODE);
+ }
+ return f;
+}
+
+
+/*
+ *
+ * Read size bytes from the FILE fp, constructing them into a
+ * signed/unsigned integer.
+ *
+ */
+
+unsigned long
+num(fp, size)
+ register FILE *fp;
+ register int size;
+{
+ register long x = 0;
+
+ while (size--) x = (x << 8) | one(fp);
+ return x;
+}
+
+long
+snum(fp, size)
+ register FILE *fp;
+ register int size;
+{
+ register long x;
+
+#ifdef __STDC__
+ x = (signed char) getc(fp);
+#else
+ x = (unsigned char) getc(fp);
+ if (x & 0x80) x -= 0x100;
+#endif
+ while (--size) x = (x << 8) | one(fp);
+ return x;
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/vf.c b/systems/msdos/dviware/xdvi-dos/src/vf.c
new file mode 100644
index 0000000000..4560a5f966
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/vf.c
@@ -0,0 +1,123 @@
+#include "xdvi.h"
+#include "dvi.h"
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+/***
+ *** VF font reading routines.
+ *** Public routine is read_index---because virtual characters are presumed
+ *** to be short, we read the whole virtual font in at once, instead of
+ *** faulting in characters as needed.
+ ***/
+
+#define LONG_CHAR 242
+
+/*
+ * These are parameters which determine whether macros are combined for
+ * storage allocation purposes. Small macros ( <= VF_PARM_1 bytes) are
+ * combined into chunks of size VF_PARM_2.
+ */
+
+#ifndef VF_PARM_1
+#define VF_PARM_1 20
+#endif
+#ifndef VF_PARM_2
+#define VF_PARM_2 256
+#endif
+
+/*
+ * The main routine
+ */
+
+void
+read_VF_index(fontp)
+ register struct font *fontp;
+{
+ FILE *VF_file = fontp->file;
+ ubyte cmnd;
+ ubyte *avail, *availend; /* available space for macros */
+
+ fontp->read_char = NULL;
+ fontp->flags |= FONT_VIRTUAL;
+ fontp->set_char_p = set_vf_char;
+ if (debug & DBG_PK)
+ Printf("Reading VF pixel file %s\n", fontp->filename);
+/*
+ * Read preamble.
+ */
+ Fseek(VF_file, (long) one(VF_file), 1); /* skip comment */
+ (void) four(VF_file); /* skip checksum */
+ (void) four(VF_file); /* skip design size */
+/*
+ * Read the fonts.
+ */
+ fontp->vf_chain = NULL;
+ fontp->first_font = NULL;
+ while ((cmnd = one(VF_file)) >= FNTDEF1 && cmnd <= FNTDEF4) {
+ define_font(VF_file, cmnd, fontp, &fontp->vf_chain);
+ if (fontp->first_font == NULL)
+ fontp->first_font = fontp->vf_chain->fontp;
+ }
+/*
+ * Prepare macro array.
+ */
+ fontp->macro = (struct macro *) xmalloc(256 * sizeof(struct macro),
+ "macro array");
+ bzero((char *) fontp->macro, 256 * sizeof(struct macro));
+/*
+ * Read macros.
+ */
+ avail = availend = NULL;
+ for (; cmnd <= LONG_CHAR; cmnd = one(VF_file)) {
+ register struct macro *m;
+ int len;
+ unsigned long cc;
+ long width;
+
+ if (cmnd == LONG_CHAR) { /* long form packet */
+ len = four(VF_file);
+ cc = four(VF_file);
+ width = four(VF_file);
+ if (cc >= 256) {
+ Fprintf(stderr,
+ "Virtual character %lu in font %s ignored.\n",
+ cc, fontp->fontname);
+ Fseek(VF_file, (long) len, 1);
+ continue;
+ }
+ }
+ else { /* short form packet */
+ len = cmnd;
+ cc = one(VF_file);
+ width = num(VF_file, 3);
+ }
+ m = &fontp->macro[cc];
+ m->dvi_adv = width * fontp->dimconv;
+ if (len > 0) {
+ if (len <= availend - avail) {
+ m->pos = avail;
+ avail += len;
+ }
+ else {
+ m->free_me = True;
+ if (len <= VF_PARM_1) {
+ m->pos = avail = (ubyte *) xmalloc(VF_PARM_2,
+ "macro array");
+ availend = avail + VF_PARM_2;
+ avail += len;
+ }
+ else m->pos = (ubyte *) xmalloc((unsigned) len,
+ "macro array");
+ }
+ Fread((char *) m->pos, 1, len, VF_file);
+ m->end = m->pos + len;
+ }
+ if (debug & DBG_PK)
+ Printf("Read VF macro for character %lu; dy = %ld, length = %d\n",
+ cc, m->dvi_adv, len);
+ }
+ if (cmnd != POST)
+ oops("Wrong command byte found in VF macro list: %d", cmnd);
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.c b/systems/msdos/dviware/xdvi-dos/src/xdvi.c
new file mode 100644
index 0000000000..1aaa216ace
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.c
@@ -0,0 +1,3175 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modification history:
+ * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
+ * 7/1988 Modified for X.11 --Mark Eichin, MIT
+ * 12/1988 Added 'R' option, toolkit, magnifying glass
+ * --Paul Vojta, UC Berkeley.
+ * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
+ * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
+ * 3/1990 Added VMS support --Scott Allendorf, U of Iowa
+ * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
+ * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
+ * and Lee Hetherington, MIT
+ *
+ * Compilation options:
+ * SYSV compile for System V
+ * VMS compile for VMS
+ * X10 compile for X10
+ * NOTOOL compile without toolkit (X11 only)
+ * BUTTONS compile with buttons on the side of the window (needs toolkit)
+ * MSBITFIRST store bitmaps internally with most significant bit first
+ * BMSHORT store bitmaps in shorts instead of bytes
+ * BMLONG store bitmaps in longs instead of bytes
+ * ALTFONT default for -altfont option
+ * A4 use European size paper
+ * TEXXET support reflection dvi codes (right-to-left typesetting)
+ * GREY use grey levels to shrink fonts
+ */
+
+
+
+#ifndef ALTFONT
+#define ALTFONT "cmr10"
+#endif
+
+#ifndef A4
+#define DEFAULT_PAPER "us"
+#else
+#define DEFAULT_PAPER "a4"
+#endif
+
+#if !defined(X10) && !defined(NOTOOL)
+#define TOOLKIT
+#else
+#undef TOOLKIT
+#undef BUTTONS
+#endif
+
+#include <ctype.h>
+
+#define EXTERN
+#define INIT(x) =x
+#ifndef TOOLKIT
+#define NTINIT(x) =x
+#else
+#define NTINIT(x)
+#endif
+#include "xdvi.h"
+
+#include "patchlevel.h"
+static struct {_Xconst char a[33], b, c, d;}
+#ifndef X10
+ version = {"This is xdvi for X11, patchlevel ", '0' + PATCHLEVEL / 10,
+ '0' + PATCHLEVEL % 10, 0};
+#else
+ version = {"This is xdvi for X10, patchlevel ", '0' + PATCHLEVEL / 10,
+ '0' + PATCHLEVEL % 10, 0};
+#endif
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+
+
+/*------------------------------- MSDOS (Eric Ho) --------------------------*/
+#if defined(__MSDOS__) && defined (FONTSUB)
+
+extern FILE *openfontsubfile (void);
+FILE *fontsubfile; /* make this global to minize interference to */
+ /* the orginial source */
+#endif
+/*------------------------------- MSDOS (Eric Ho) --------------------------*/
+
+
+#ifndef X10
+/* Xlib and Xutil are already included */
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include "xdvi.icon"
+#endif /* X10 */
+
+#ifdef TOOLKIT
+#undef Boolean
+#include <X11/Intrinsic.h>
+#ifdef OLD_X11_TOOLKIT
+#include <X11/Atoms.h>
+#else /* not OLD_X11_TOOLKIT */
+#include <X11/Xatom.h>
+#include <X11/StringDefs.h>
+#endif /* not OLD_X11_TOOLKIT */
+#include <X11/Shell.h> /* needed for def. of XtNiconX */
+#ifndef XtSpecificationRelease
+#define XtSpecificationRelease 0
+#endif
+#if XtSpecificationRelease >= 4
+#include <X11/Xaw/Viewport.h>
+#ifdef BUTTONS
+#include <X11/Xaw/Command.h>
+#endif
+#else /* XtSpecificationRelease < 4 */
+#define XtPointer caddr_t
+#include <X11/Viewport.h>
+#ifdef BUTTONS
+#include <X11/Command.h>
+#endif
+#endif /* XtSpecificationRelease */
+#else /* !TOOLKIT */
+#define XtNumber(arr) (sizeof(arr)/sizeof(arr[0]))
+typedef int Position;
+typedef unsigned int Dimension;
+#ifndef X10
+typedef unsigned long Pixel;
+#define XtPending() XPending(DISP)
+#else
+#define XtPending XPending
+#define XMoveResizeWindow XConfigureWindow
+#endif
+#endif /* TOOLKIT */
+
+#ifdef HAS_SIGIO
+#include <fcntl.h>
+#include <signal.h>
+#endif
+
+#ifndef X10
+#ifndef GREY
+static Display *DISP;
+static Screen *SCRN;
+#endif
+#define DPY DISP,
+static Cursor redraw_cursor, ready_cursor;
+
+#ifdef VMS
+/*
+ * Magnifying glass cursor
+ *
+ * Developed by Tom Sawyer, April 1990
+ * Contibuted by Hunter Goatley, January 1991
+ *
+ */
+
+#define mag_glass_width 16
+#define mag_glass_height 16
+#define mag_glass_x_hot 6
+#define mag_glass_y_hot 6
+static char mag_glass_bits[] = {
+ 0xf8, 0x03, 0x0c, 0x06, 0xe2, 0x09, 0x13, 0x1a, 0x01, 0x14, 0x01, 0x14,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x03, 0x10, 0x02, 0x18, 0x0c, 0x34,
+ 0xf8, 0x6f, 0x00, 0xd8, 0x00, 0xb0, 0x00, 0xe0
+};
+#include <decw$cursor.h> /* Include the DECWindows cursor symbols */
+static int DECWCursorFont; /* Space for the DECWindows cursor font */
+static Pixmap MagnifyPixmap; /* Pixmap to hold our special mag-glass */
+#endif /* VMS */
+
+#define SetCursor(x) XDefineCursor(DISP, WINDOW(mane), x)
+#define ClearPage(wr) XClearWindow(DISP, WINDOW(wr));
+#define ClearArea(win, x, y, w, h) XClearArea(DISP, win, x, y, w, h, False)
+#define DarkenArea(win, x, y, w, h) \
+ XFillRectangle(DISP, win, ruleGC, x, y, w, h)
+#define CopyArea(win, x, y, w, h, x2, y2) \
+ XCopyArea(DISP, win, win, DefaultGCOfScreen(SCRN), \
+ x, y, w, h, x2, y2)
+#define Flush() XFlush(DISP)
+#ifndef X11HEIGHT
+#define X11HEIGHT 8 /* Height of server default font */
+#endif
+#else /* X10 */
+#define DPY
+#define GC int
+#define SetCursor(x)
+#define ClearPage(wr) XClear(WINDOW(wr));
+#define ClearArea(win, x, y, w, h) XPixSet(win, x, y, w, h, backpix)
+#define DarkenArea(win, x, y, w, h) XPixSet(win, x, y, w, h, foreGC)
+#define CopyArea(win, x, y, w, h, x2, y2) \
+ XMoveArea(win, x, y, x2, y2, w, h, GXcopy);
+#define XBell(a,b) XFeep(b/10-1)
+#define Flush() XFlush()
+#define ConnectionNumber(DISP) (_XlibCurrentDisplay->fd)
+#ifndef X10FONT
+#define X10FONT "helv10b" /* Font for X10 error messages */
+#define X10HEIGHT 10
+#endif
+#endif /* X10 */
+
+#define MAGBORD 1 /* border size for magnifier */
+
+/*
+ * Command line flags.
+ */
+
+static Dimension bwidth = 2;
+
+#ifdef TOOLKIT
+
+#define RESOURCE(x) resource.x
+
+static struct _resource {
+ char *debug_arg;
+ int _shrink_factor;
+ int density;
+#ifdef GREY
+ float gamma;
+#endif
+ int pixels_per_inch;
+ char *sidemargin;
+ char *topmargin;
+ char *xoffset;
+ char *yoffset;
+ _Xconst char *paper;
+ char *alt_font;
+ Boolean list_fonts;
+ Boolean reverse;
+ Boolean hush_spec;
+ Boolean hush_chars;
+ Pixel fore_Pixel;
+ char *fore_color;
+ Pixel back_Pixel;
+ char *back_color;
+ Pixel brdr_Pixel;
+ char *brdr_color;
+ Pixel hl_Pixel;
+ char *high_color;
+ Pixel cr_Pixel;
+ char *curs_color;
+ char *icon_geometry;
+ Boolean keep_flag;
+ char *copy_arg;
+ Boolean copy;
+ Boolean thorough;
+ Boolean version_flag;
+#ifdef BUTTONS
+ Boolean expert;
+#endif
+ int mg_size[5];
+#ifdef GREY
+ Boolean use_grey;
+#endif
+} resource;
+
+#else /* !TOOLKIT */
+
+#define RESOURCE(x) x
+static char *debug_arg;
+#ifdef GREY
+static float gamma = 1.0;
+#endif
+static char *sidemargin, *topmargin;
+static char *xoffset, *yoffset;
+static _Xconst char *paper = DEFAULT_PAPER;
+static Boolean reverse;
+static Boolean keep_flag = False;
+#ifndef X10
+static Pixel fore_Pixel, back_Pixel, brdr_Pixel, hl_Pixel, cr_Pixel;
+static char *icon_geometry;
+static Boolean copy = 2;
+static Boolean thorough;
+#endif /* X10 */
+static Boolean version_flag = False;
+static int mg_size[5] = {200, 350, 600, 900, 1200};
+
+#endif /* TOOLKIT */
+
+static char *curr_page;
+
+#ifndef TOOLKIT
+static char *fore_color;
+static char *back_color;
+static char *brdr_color;
+static char *high_color;
+static char *curs_color;
+#endif
+static GC foreGC, highGC;
+#ifndef X10
+static GC ruleGC;
+static GC foreGC2;
+#else /* X10 */
+#define ruleGC foreGC
+#endif /* X10 */
+
+static int pageno_correct = 1;
+static int bak_shrink;
+
+#define clip_w mane.width
+#define clip_h mane.height
+static Dimension window_w, window_h;
+#ifndef X10
+static Position main_x, main_y;
+static XImage *image;
+#else /* X10 */
+#define main_x 0
+#define main_y 0
+static int GXfunc;
+static int backpix, backmap, bdrmap;
+/*
+ * Cursor and mask for valid cursor
+ */
+#include "xdvi_curs.h"
+#include "xdvi_mask.h"
+#endif /* X10 */
+
+static Position mag_x, mag_y, new_mag_x, new_mag_y;
+static Boolean mag_moved = False;
+static int home_x, home_y;
+static int min_x, max_x, min_y, max_y;
+
+struct WindowRec mane = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+struct WindowRec alt = {(Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+/* currwin is temporary storage except for within redraw() */
+struct WindowRec currwin = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
+
+#ifdef TOOLKIT
+static Widget top_level, vport_widget, draw_widget, clip_widget;
+#ifdef BUTTONS
+static Widget form_widget, line_widget, right_widget;
+#endif
+static Widget x_bar, y_bar; /* horizontal and vertical scroll bars */
+
+static Arg vport_args[] = {
+#ifdef BUTTONS
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainLeft},
+ {XtNright, (XtArgVal) XtChainRight},
+#endif
+ {XtNallowHoriz, (XtArgVal) True},
+ {XtNallowVert, (XtArgVal) True},
+};
+
+/* Note: Argument order in the following is important! */
+
+static Arg draw_args[] = {
+ {XtNwidth, (XtArgVal) 0},
+ {XtNheight, (XtArgVal) 0},
+ {XtNx, (XtArgVal) 0},
+ {XtNy, (XtArgVal) 0},
+ {XtNlabel, (XtArgVal) ""},
+};
+
+#ifdef BUTTONS
+static Arg form_args[] = {
+ {XtNdefaultDistance, (XtArgVal) 0},
+};
+#define XTRA_WID 79
+
+static Arg line_args[] = {
+ {XtNbackground, (XtArgVal) 0},
+ {XtNwidth, (XtArgVal) 1},
+ {XtNheight, (XtArgVal) 0},
+ {XtNfromHoriz, (XtArgVal) NULL},
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainRight},
+ {XtNright, (XtArgVal) XtChainRight},
+};
+
+static Arg right_args[] = {
+ {XtNfromHoriz, (XtArgVal) NULL},
+ {XtNwidth, (XtArgVal) (XTRA_WID - 1)},
+ {XtNheight, (XtArgVal) 0},
+ {XtNborderWidth, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) XtChainTop},
+ {XtNbottom, (XtArgVal) XtChainBottom},
+ {XtNleft, (XtArgVal) XtChainRight},
+ {XtNright, (XtArgVal) XtChainRight},
+};
+
+static struct {
+ _Xconst char *label;
+ _Xconst char *name;
+ int closure;
+ int y_pos;
+ }
+ command_table[] = {
+ {"Quit", "quit", 'q', 50},
+ {"Shrink1", "sh1", 1 << 8 | 's', 150},
+ {"Shrink2", "sh2", 2 << 8 | 's', 200},
+ {"Shrink3", "sh3", 3 << 8 | 's', 250},
+ {"Shrink4", "sh4", 4 << 8 | 's', 300},
+ {"Page-10", "prev10", 10 << 8 | 'p', 400},
+ {"Page-5", "prev5", 5 << 8 | 'p', 450},
+ {"Prev", "prev", 'p', 500},
+ {"Next", "next", 'n', 600},
+ {"Page+5", "next5", 5 << 8 | 'n', 650},
+ {"Page+10", "next10", 10 << 8 | 'n', 700},
+};
+
+static void handle_command();
+
+static XtCallbackRec command_call[] = {
+ {handle_command, NULL},
+ {NULL, NULL},
+};
+
+static Arg command_args[] = {
+ {XtNlabel, (XtArgVal) NULL},
+ {XtNx, (XtArgVal) 6},
+ {XtNy, (XtArgVal) 0},
+ {XtNwidth, (XtArgVal) 64},
+ {XtNheight, (XtArgVal) 30},
+ {XtNcallback, (XtArgVal) command_call},
+};
+
+
+
+static void
+create_buttons(h)
+ XtArgVal h;
+{
+ int i;
+
+ line_args[2].value = h;
+ line_args[3].value = (XtArgVal) vport_widget;
+ line_widget = XtCreateManagedWidget("line", widgetClass, form_widget,
+ line_args, XtNumber(line_args));
+ right_args[0].value = (XtArgVal) line_widget;
+ right_args[2].value = h;
+ right_widget = XtCreateManagedWidget("right", compositeWidgetClass,
+ form_widget, right_args, XtNumber(right_args));
+
+ command_args[2].value = (XtArgVal) vport_widget;
+ for (i = 0; i < XtNumber(command_table); ++i) {
+ command_args[0].value = (XtArgVal) command_table[i].label;
+ command_args[2].value = (XtArgVal) command_table[i].y_pos;
+ command_call[0].closure = (caddr_t) command_table[i].closure;
+ (void) XtCreateManagedWidget(command_table[i].name,
+ commandWidgetClass, right_widget,
+ command_args, XtNumber(command_args));
+ }
+}
+#endif /* BUTTONS */
+
+#ifdef NOQUERY
+#define drawWidgetClass widgetClass
+#else
+
+/* ARGSUSED */
+static XtGeometryResult
+QueryGeometry(w, constraints, reply)
+ Widget w;
+ XtWidgetGeometry *constraints, *reply;
+{
+ reply->request_mode = CWWidth | CWHeight;
+ reply->width = page_w;
+ reply->height = page_h;
+ return XtGeometryAlmost;
+}
+
+#include <X11/IntrinsicP.h>
+#include <X11/CoreP.h>
+
+ /* if the following gives you trouble, just compile with -DNOQUERY */
+static WidgetClassRec drawingWidgetClass = {
+ {
+ /* superclass */ &widgetClassRec,
+ /* class_name */ "Draw",
+ /* widget_size */ sizeof(WidgetRec),
+ /* class_initialize */ NULL,
+ /* class_part_initialize*/ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ NULL,
+ /* num_resources */ 0,
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ XtInheritAcceptFocus,
+ /* version */ XtVersion,
+ /* callback_offsets */ NULL,
+ /* tm_table */ XtInheritTranslations,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ }
+};
+
+#define drawWidgetClass &drawingWidgetClass
+
+#endif /* NOQUERY */
+
+#else /* !TOOLKIT */
+#define BAR_WID 12 /* width of darkened area */
+#define BAR_THICK 15 /* gross amount removed */
+
+static Window top_level;
+static Window x_bar, y_bar;
+static int x_bgn, x_end, y_bgn, y_end; /* scrollbar positions */
+#endif /* TOOLKIT */
+
+/*
+ * Mechanism to keep track of the magnifier window. The problems are,
+ * (a) if the button is released while the window is being drawn, this
+ * could cause an X error if we continue drawing in it after it is
+ * destroyed, and
+ * (b) creating and destroying the window too quickly confuses the window
+ * manager, which is avoided by waiting for an expose event before
+ * destroying it.
+ */
+static short alt_stat; /* 1 = wait for expose, */
+ /* -1 = destroy upon expose */
+static Boolean alt_canit; /* stop drawing this window */
+
+/*
+ * Data for buffered events.
+ */
+
+static Boolean canit = False,
+ has_arg = False;
+static VOLATILE short event_counter = 0;
+static VOLATILE short event_freq = 70;
+static int number = 0,
+ sign = 1;
+static jmp_buf canit_env;
+
+static void can_exposures(), read_events(), keystroke();
+
+#ifdef lint
+#ifndef X10
+char xdvi_bits[288];
+#ifdef TOOLKIT
+WidgetClass viewportWidgetClass, widgetClass;
+WidgetClassRec widgetClassRec;
+#ifdef BUTTONS
+WidgetClass formWidgetClass, compositeWidgetClass, commandWidgetClass;
+#endif /* BUTTONS */
+#endif /* TOOLKIT */
+#else /* X10 */
+short xdvi_bits[15], xdvi_mask_bits[15];
+Display *_XlibCurrentDisplay;
+#endif /* X10 */
+#endif /* lint */
+
+#ifdef GREY
+static void
+init_pix(warn)
+ Boolean warn;
+{
+ static int shrink_allocated_for = 0;
+ static Boolean colors_allocated = False;
+ int i;
+
+ if (!colors_allocated)
+ {
+ Pixel plane_masks[4];
+ Pixel pixel;
+ XColor color, fc, bc;
+ XGCValues values;
+ int i;
+
+ if (RESOURCE(gamma) == 0.0) RESOURCE(gamma) = 1.0;
+
+ if (!RESOURCE(copy))
+ /* allocate 4 color planes for 16 colors (for GXor drawing) */
+ if (!XAllocColorCells(DISP, DefaultColormapOfScreen(SCRN),
+ False, plane_masks, 4, &pixel, 1))
+ RESOURCE(copy) = warn = True;
+
+ /* get foreground and background RGB values for interpolating */
+ fc.pixel = RESOURCE(fore_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &fc);
+ bc.pixel = RESOURCE(back_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bc);
+
+ for (i = 0; i < 16; ++i) {
+ double pow();
+ double frac = RESOURCE(gamma) > 0 ?
+ pow((double) i / 15, 1 / RESOURCE(gamma))
+ : 1 - pow((double) (15 - i) / 15, -RESOURCE(gamma));
+
+ color.red = frac * ((double) fc.red - bc.red) + bc.red;
+ color.green = frac * ((double) fc.green - bc.green) + bc.green;
+ color.blue = frac * ((double) fc.blue - bc.blue) + bc.blue;
+
+ color.pixel = pixel;
+ color.flags = DoRed | DoGreen | DoBlue;
+
+ if (!RESOURCE(copy)) {
+ if (i & 1) color.pixel |= plane_masks[0];
+ if (i & 2) color.pixel |= plane_masks[1];
+ if (i & 4) color.pixel |= plane_masks[2];
+ if (i & 8) color.pixel |= plane_masks[3];
+ XStoreColor(DISP, DefaultColormapOfScreen(SCRN), &color);
+ palette[i] = color.pixel;
+ }
+ else {
+ if (!XAllocColor(DISP, DefaultColormapOfScreen(SCRN),
+ &color))
+ palette[i] = (i * 100 >= density * 15)
+ ? RESOURCE(fore_Pixel) : RESOURCE(back_Pixel);
+ else
+ palette[i] = color.pixel;
+ }
+ }
+
+ /* Make sure fore_ and back_Pixel are a part of the palette */
+ RESOURCE(fore_Pixel) = palette[15];
+ RESOURCE(back_Pixel) = palette[0];
+
+#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\
+ values.background=bg,\
+ XCreateGC(DISP, RootWindowOfScreen(SCRN),\
+ GCFunction|GCForeground|GCBackground, &values))
+
+ foreGC = ruleGC = MakeGC(RESOURCE(copy) ? GXcopy : GXor,
+ RESOURCE(fore_Pixel), RESOURCE(back_Pixel));
+
+ colors_allocated = True;
+ if (RESOURCE(copy) && warn)
+ Puts("Note: overstrike characters may be incorrect.");
+ }
+#undef MakeGC
+
+ if (mane.shrinkfactor == 1) return;
+
+ if (shrink_allocated_for < mane.shrinkfactor) {
+ if (pixeltbl != NULL) free((char *) pixeltbl);
+ pixeltbl = (Pixel *) xmalloc((unsigned)
+ (mane.shrinkfactor * mane.shrinkfactor + 1) * sizeof(Pixel),
+ "pixel table");
+ shrink_allocated_for = mane.shrinkfactor;
+ }
+
+ for (i = 0; i <= mane.shrinkfactor * mane.shrinkfactor; ++i)
+ pixeltbl[i] =
+ palette[(i * 30 + mane.shrinkfactor * mane.shrinkfactor)
+ / (2 * mane.shrinkfactor * mane.shrinkfactor)];
+}
+#endif /* GREY */
+
+#ifdef sun
+extern char *sprintf();
+#endif
+
+#ifndef atof /* on the Next it's a macro */
+extern double atof();
+#endif
+
+/********************************
+ * tpic routines *
+ *******************************/
+
+/* Things we need from spec_draw, unfortunately */
+
+/* (ignored for now)
+extern int pen_size, blacken, whiten, shade;
+*/
+
+#define toint(x) ((int) ((x) + 0.5))
+#define xconv(x) (toint(specialConv*(x))/shrink_factor + PXL_H)
+#define yconv(y) (toint(specialConv*(y))/shrink_factor + PXL_V)
+
+/*
+ * Draw a line from (fx,fy) to (tx,ty).
+ * Right now, we ignore pen_size.
+ */
+void
+line_btw(fx, fy, tx, ty)
+int fx, fy, tx, ty;
+{
+ register int fcx = xconv(fx),
+ tcx = xconv(tx),
+ fcy = yconv(fy),
+ tcy = yconv(ty);
+
+ if ((fcx < max_x || tcx < max_x) && (fcx >= min_x || tcx >= min_x) &&
+ (fcy < max_y || tcy < max_y) && (fcy >= min_y || tcy >= min_y))
+#ifndef X10
+ XDrawLine(DISP, WINDOW(currwin), ruleGC,
+ fcx - currwin.base_x, fcy - currwin.base_y,
+ tcx - currwin.base_x, tcy - currwin.base_y);
+#else
+ XLine(WINDOW(currwin),
+ fcx - currwin.base_x, fcy - currwin.base_y,
+ tcx - currwin.base_x, tcy - currwin.base_y,
+ 1, 1, ruleGC, GXcopy, AllPlanes);
+#endif
+}
+
+/*
+ * Draw a dot at (x,y)
+ */
+void
+dot_at(x, y)
+ int x, y;
+{
+ register int cx = xconv(x),
+ cy = yconv(y);
+
+ if (cx < max_x && cx >= min_x && cy < max_y && cy >= min_y)
+#ifndef X10
+ XDrawPoint(DISP, WINDOW(currwin), ruleGC,
+ cx - currwin.base_x, cy - currwin.base_y);
+#else
+ XPixSet(WINDOW(currwin), cx - currwin.base_x, cy - currwin.base_y,
+ 1, 1, ruleGC);
+#endif
+}
+
+/*
+ * Apply the requested attributes to the last path (box) drawn.
+ * Attributes are reset.
+ * (Not currently implemented.)
+ */
+ /* ARGSUSED */
+void
+do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y)
+int last_min_x, last_max_x, last_min_y, last_max_y;
+{
+}
+
+/*
+ * Put a rectangle on the screen. hl determines the GC.
+ */
+
+void
+put_rectangle(x, y, w, h, hl)
+ int x, y, w, h;
+ WIDEARG(Boolean, int) hl;
+{
+ if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y) {
+ if (--event_counter == 0) read_events(False);
+#ifndef X10
+ XFillRectangle(DISP, WINDOW(currwin), hl ? highGC : ruleGC,
+ x - currwin.base_x, y - currwin.base_y,
+ w ? w : 1, h ? h : 1);
+#else
+ XPixSet(WINDOW(currwin), x - currwin.base_x, y - currwin.base_y,
+ w ? w : 1, h ? h : 1, hl ? highGC : ruleGC);
+#endif
+ }
+}
+
+void
+put_bitmap(bitmap, x, y)
+ register struct bitmap *bitmap;
+ register int x, y;
+{
+
+ if (debug & DBG_BITMAP)
+ Printf("X(%d,%d)\n", x - currwin.base_x, y - currwin.base_y);
+ if (x < max_x && x + bitmap->w >= min_x &&
+ y < max_y && y + bitmap->h >= min_y) {
+ if (--event_counter == 0) read_events(False);
+#ifndef X10
+ image->width = bitmap->w;
+ image->height = bitmap->h;
+ image->data = bitmap->bits;
+ image->bytes_per_line = bitmap->bytes_wide;
+ XPutImage(DISP, WINDOW(currwin), foreGC, image,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h);
+ if (foreGC2)
+ XPutImage(DISP, WINDOW(currwin), foreGC2, image,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h);
+#else
+ XBitmapBitsPut(WINDOW(currwin),
+ x - currwin.base_x, y - currwin.base_y,
+ bitmap->w, bitmap->h, bitmap->bits,
+ foreGC, backpix, NULL, GXfunc, AllPlanes);
+#endif
+ }
+}
+
+#ifdef GREY
+void
+put_image(img, x, y)
+ register XImage *img;
+ register int x, y;
+{
+ if (x < max_x && x + img->width >= min_x &&
+ y < max_y && y + img->height >= min_y) {
+
+ if (--event_counter == 0) read_events (False);
+
+ XPutImage(DISP, WINDOW(currwin), foreGC, img,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ img->width, img->height);
+
+ if (foreGC2)
+ XPutImage(DISP, WINDOW(currwin), foreGC2, img,
+ 0, 0,
+ x - currwin.base_x, y - currwin.base_y,
+ img->width, img->height);
+ }
+}
+#endif /* GREY */
+
+/*
+ * Event-handling routines
+ */
+
+static void
+expose(windowrec, x, y, w, h)
+ register struct WindowRec *windowrec;
+ int x, y, w, h;
+{
+ if (windowrec->min_x > x) windowrec->min_x = x;
+ if (windowrec->max_x < x + w)
+ windowrec->max_x = x + w;
+ if (windowrec->min_y > y) windowrec->min_y = y;
+ if (windowrec->max_y < y + h)
+ windowrec->max_y = y + h;
+}
+
+static void
+clearexpose(windowrec, x, y, w, h)
+ struct WindowRec *windowrec;
+ int x, y, w, h;
+{
+ ClearArea(WINDOW(*windowrec), x, y, w, h);
+ expose(windowrec, x, y, w, h);
+}
+
+static void
+scrollwindow(windowrec, x0, y0)
+ register struct WindowRec *windowrec;
+ int x0, y0;
+{
+ int x, y;
+ int x2 = 0, y2 = 0;
+ int ww, hh;
+
+ x = x0 - windowrec->base_x;
+ y = y0 - windowrec->base_y;
+ ww = windowrec->width - x;
+ hh = windowrec->height - y;
+ windowrec->base_x = x0;
+ windowrec->base_y = y0;
+ if (currwin.win == windowrec->win) {
+ currwin.base_x = x0;
+ currwin.base_y = y0;
+ }
+ windowrec->min_x -= x;
+ if (windowrec->min_x < 0) windowrec->min_x = 0;
+ windowrec->max_x -= x;
+ if (windowrec->max_x > windowrec->width)
+ windowrec->max_x = windowrec->width;
+ windowrec->min_y -= y;
+ if (windowrec->min_y < 0) windowrec->min_y = 0;
+ windowrec->max_y -= y;
+ if (windowrec->max_y > windowrec->height)
+ windowrec->max_y = windowrec->height;
+ if (x < 0) {
+ x2 = -x;
+ x = 0;
+ ww = windowrec->width - x2;
+ }
+ if (y < 0) {
+ y2 = -y;
+ y = 0;
+ hh = windowrec->height - y2;
+ }
+ if (ww <= 0 || hh <= 0) {
+ ClearPage(*windowrec);
+ windowrec->min_x = windowrec->min_y = 0;
+ windowrec->max_x = windowrec->width;
+ windowrec->max_y = windowrec->height;
+ }
+ else {
+ CopyArea(WINDOW(*windowrec), x, y, ww, hh, x2, y2);
+ if (x > 0) clearexpose(windowrec, ww, 0, x, windowrec->height);
+ if (x2 > 0) clearexpose(windowrec, 0, 0, x2, windowrec->height);
+ if (y > 0) clearexpose(windowrec, 0, hh, windowrec->width, y);
+ if (y2 > 0) clearexpose(windowrec, 0, 0, windowrec->width, y2);
+ }
+}
+
+#ifdef TOOLKIT
+/*
+ * routines for X11 toolkit
+ */
+
+static Arg arg_wh[] = {
+ {XtNwidth, (XtArgVal) &window_w},
+ {XtNheight, (XtArgVal) &window_h},
+};
+
+static Position window_x, window_y;
+static Arg arg_xy[] = {
+ {XtNx, (XtArgVal) &window_x},
+ {XtNy, (XtArgVal) &window_y},
+};
+
+#define get_xy() XtGetValues(draw_widget, arg_xy, XtNumber(arg_xy))
+
+#define mane_base_x 0
+#define mane_base_y 0
+
+static void
+home(scrl)
+ Boolean scrl;
+{
+ if (!scrl) XUnmapWindow(DISP, WINDOW(mane));
+ get_xy();
+ if (x_bar != NULL) {
+ register int coord = (page_w - clip_w) / 2;
+ if (coord > home_x / mane.shrinkfactor)
+ coord = home_x / mane.shrinkfactor;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (window_x + coord));
+ }
+ if (y_bar != NULL) {
+ register int coord = (page_h - clip_h) / 2;
+ if (coord > home_y / mane.shrinkfactor)
+ coord = home_y / mane.shrinkfactor;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (window_y + coord));
+ }
+ if (!scrl) {
+ XMapWindow(DISP, WINDOW(mane));
+ /* Wait for the server to catch up---this eliminates flicker. */
+ XSync(DISP, False);
+ }
+}
+
+static Boolean resized = False;
+
+static void
+get_geom()
+{
+ static Dimension new_clip_w, new_clip_h;
+ static Arg arg_wh_clip[] = {
+ {XtNwidth, (XtArgVal) &new_clip_w},
+ {XtNheight, (XtArgVal) &new_clip_h},
+ };
+ register int old_clip_w;
+
+ XtGetValues(vport_widget, arg_wh, XtNumber(arg_wh));
+ XtGetValues(clip_widget, arg_wh_clip, XtNumber(arg_wh_clip));
+ /* Note: widgets may be destroyed but not forgotten */
+ x_bar = page_w <= new_clip_w ? NULL
+ : XtNameToWidget(vport_widget, "horizontal");
+ y_bar = page_h <= new_clip_h ? NULL
+ : XtNameToWidget(vport_widget, "vertical");
+ old_clip_w = clip_w;
+ /* we need to do this because */
+ /* sizeof(Dimension) != sizeof(int) */
+ clip_w = new_clip_w;
+ clip_h = new_clip_h;
+ if (old_clip_w == 0) home(False);
+ resized = False;
+}
+
+static void
+center(x, y)
+ int x, y;
+{
+/* We use the clip widget here because it gives a more exact value. */
+ x -= clip_w/2;
+ y -= clip_h/2;
+ if (x_bar) XtCallCallbacks(x_bar, XtNscrollProc, (XtPointer) x);
+ if (y_bar) XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) y);
+ XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y);
+}
+
+/*
+ * callback routines
+ */
+
+/* The following callback routine should never be called. */
+ /*ARGSUSED*/
+static void
+handle_key(widget, junk, event, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *event;
+ Boolean *cont; /* unused */
+{
+ XBell(DISP, 20);
+}
+
+ /*ARGSUSED*/
+static void
+handle_resize(widget, junk, event, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *event;
+ Boolean *cont; /* unused */
+{
+ resized = True;
+}
+
+#ifdef BUTTONS
+ /*ARGSUSED*/
+static void
+handle_command(widget, client_data, call_data)
+ Widget widget;
+ XtPointer client_data;
+ XtPointer call_data;
+{
+ int int_client_data = (int) client_data; /* Apollo cc bug */
+
+ keystroke((int_client_data) & 0xff, (int_client_data) >> 8,
+ ((int_client_data) >> 8) != 0, (XEvent *) NULL);
+}
+#endif /* BUTTONS */
+
+#else /* !TOOLKIT */
+
+/*
+ * brute force scrollbar routines
+ */
+
+static void
+paint_x_bar()
+{
+ register int new_x_bgn = mane.base_x * clip_w / page_w;
+ register int new_x_end = (mane.base_x + clip_w) * clip_w / page_w;
+
+ if (new_x_bgn >= x_end || x_bgn >= new_x_end) { /* no overlap */
+ ClearArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID);
+ DarkenArea(x_bar, new_x_bgn, 1, new_x_end - new_x_bgn, BAR_WID);
+ }
+ else { /* this stuff avoids flicker */
+ if (x_bgn < new_x_bgn)
+ ClearArea(x_bar, x_bgn, 1, new_x_bgn - x_bgn, BAR_WID);
+ else
+ DarkenArea(x_bar, new_x_bgn, 1, x_bgn - new_x_bgn, BAR_WID);
+ if (new_x_end < x_end)
+ ClearArea(x_bar, new_x_end, 1, x_end - new_x_end, BAR_WID);
+ else
+ DarkenArea(x_bar, x_end, 1, new_x_end - x_end, BAR_WID);
+ }
+ x_bgn = new_x_bgn;
+ x_end = new_x_end;
+}
+
+static void
+paint_y_bar()
+{
+ register int new_y_bgn = mane.base_y * clip_h / page_h;
+ register int new_y_end = (mane.base_y + clip_h) * clip_h / page_h;
+
+ if (new_y_bgn >= y_end || y_bgn >= new_y_end) { /* no overlap */
+ ClearArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn);
+ DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, new_y_end - new_y_bgn);
+ }
+ else { /* this stuff avoids flicker */
+ if (y_bgn < new_y_bgn)
+ ClearArea(y_bar, 1, y_bgn, BAR_WID, new_y_bgn - y_bgn);
+ else
+ DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, y_bgn - new_y_bgn);
+ if (new_y_end < y_end)
+ ClearArea(y_bar, 1, new_y_end, BAR_WID, y_end - new_y_end);
+ else
+ DarkenArea(y_bar, 1, y_end, BAR_WID, new_y_end - y_end);
+ }
+ y_bgn = new_y_bgn;
+ y_end = new_y_end;
+}
+
+static void
+scrollmane(x, y)
+ int x, y;
+{
+ register int old_base_x = mane.base_x;
+ register int old_base_y = mane.base_y;
+ if (x > page_w - clip_w) x = page_w - clip_w;
+ if (x < 0) x = 0;
+ if (y > page_h - clip_h) y = page_h - clip_h;
+ if (y < 0) y = 0;
+ scrollwindow(&mane, x, y);
+ if (old_base_x != mane.base_x && x_bar) paint_x_bar();
+ if (old_base_y != mane.base_y && y_bar) paint_y_bar();
+}
+
+static void
+reconfig()
+{
+ int x_thick = 0;
+ int y_thick = 0;
+#ifdef X10
+ int old_clip_w = clip_w;
+ int old_clip_h = clip_h;
+ int old_x_thick = x_thick;
+ int old_y_thick = y_thick;
+#endif
+
+ /* determine existence of scrollbars */
+ if (window_w < page_w) x_thick = BAR_THICK;
+ if (window_h - x_thick < page_h) y_thick = BAR_THICK;
+ clip_w = window_w - y_thick;
+ if (clip_w < page_w) x_thick = BAR_THICK;
+ clip_h = window_h - x_thick;
+
+ /* process drawing (clip) window */
+ if (mane.win == NULL) { /* initial creation */
+#ifndef X10
+ mane.win = XCreateSimpleWindow(DISP, top_level, y_thick, x_thick,
+ (unsigned int) clip_w, (unsigned int) clip_h, 0,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DPY WINDOW(mane), ExposureMask |
+ ButtonPressMask | ButtonMotionMask | ButtonReleaseMask);
+#else
+ mane.win = XCreateWindow(top_level, y_thick, x_thick,
+ clip_w, clip_h, 0, bdrmap, backmap);
+ XSelectInput(WINDOW(mane), ExposeRegion | ExposeCopy |
+ ButtonPressed | ButtonReleased |
+ LeftDownMotion | MiddleDownMotion | RightDownMotion);
+#endif
+ XMapWindow(DPY WINDOW(mane));
+ }
+ else
+#ifdef X10
+ if (clip_w != old_clip_w || clip_h != old_clip_h ||
+ x_thick != old_x_thick || y_thick != old_y_thick) {
+#endif
+ XMoveResizeWindow(DPY WINDOW(mane),
+ y_thick, x_thick, clip_w, clip_h);
+#ifdef X10
+ XSync(False);
+ }
+#endif
+
+ /* process scroll bars */
+ if (x_thick) {
+ if (x_bar) {
+ XMoveResizeWindow(DPY x_bar,
+ y_thick - 1, -1, clip_w, BAR_THICK - 1);
+ paint_x_bar();
+ }
+ else {
+#ifndef X10
+ x_bar = XCreateSimpleWindow(DISP, top_level, y_thick - 1, -1,
+ (unsigned int) clip_w, BAR_THICK - 1, 1,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DISP, x_bar,
+ ExposureMask | ButtonPressMask | Button2MotionMask);
+#else
+ x_bar = XCreateWindow(top_level,
+ y_thick - 1, -1, clip_w, BAR_THICK - 1, 1,
+ bdrmap, backmap);
+ XSelectInput(x_bar,
+ ExposeRegion | ButtonPressed | MiddleDownMotion);
+#endif
+ XMapWindow(DPY x_bar);
+ }
+ x_bgn = mane.base_x * clip_w / page_w;
+ x_end = (mane.base_x + clip_w) * clip_w / page_w;
+ }
+ else
+ if (x_bar) {
+ XDestroyWindow(DPY x_bar);
+ x_bar = NULL;
+ }
+
+ if (y_thick) {
+ if (y_bar) {
+ XMoveResizeWindow(DPY y_bar,
+ -1, x_thick - 1, BAR_THICK - 1, clip_h);
+ paint_y_bar();
+ }
+ else {
+#ifndef X10
+ y_bar = XCreateSimpleWindow(DISP, top_level, -1, x_thick - 1,
+ BAR_THICK - 1, (unsigned int) clip_h, 1,
+ brdr_Pixel, back_Pixel);
+ XSelectInput(DISP, y_bar,
+ ExposureMask | ButtonPressMask | Button2MotionMask);
+#else
+ y_bar = XCreateWindow(top_level,
+ -1, x_thick - 1, BAR_THICK - 1, clip_h, 1,
+ bdrmap, backmap);
+ XSelectInput(y_bar,
+ ExposeRegion | ButtonPressed | MiddleDownMotion);
+#endif
+ XMapWindow(DPY y_bar);
+ }
+ y_bgn = mane.base_y * clip_h / page_h;
+ y_end = (mane.base_y + clip_h) * clip_h / page_h;
+ }
+ else
+ if (y_bar) {
+ XDestroyWindow(DPY y_bar);
+ y_bar = NULL;
+ }
+}
+
+static void
+home(scrl)
+ Boolean scrl;
+{
+ int x = 0, y = 0;
+
+ if (page_w > clip_w) {
+ x = (page_w - clip_w) / 2;
+ if (x > home_x / mane.shrinkfactor)
+ x = home_x / mane.shrinkfactor;
+ }
+ if (page_h > clip_h) {
+ y = (page_h - clip_h) / 2;
+ if (y > home_y / mane.shrinkfactor)
+ y = home_y / mane.shrinkfactor;
+ }
+ if (scrl)
+ scrollmane(x, y);
+ else {
+ mane.base_x = x;
+ mane.base_y = y;
+ if (currwin.win == mane.win) {
+ currwin.base_x = x;
+ currwin.base_y = y;
+ }
+ if (x_bar) paint_x_bar();
+ if (y_bar) paint_y_bar();
+ }
+}
+
+#define get_xy()
+#define window_x 0
+#define window_y 0
+#define mane_base_x mane.base_x
+#define mane_base_y mane.base_y
+#endif /* TOOLKIT */
+
+static void
+compute_mag_pos(xp, yp)
+ int *xp, *yp;
+{
+ register int t;
+
+ t = mag_x + main_x - alt.width/2;
+#ifndef X10
+ if (t > WidthOfScreen(SCRN) - alt.width - 2*MAGBORD)
+ t = WidthOfScreen(SCRN) - alt.width - 2*MAGBORD;
+#else
+ if (t > (int) window_w - alt.width - 2*MAGBORD)
+ t = window_w - alt.width - 2*MAGBORD;
+#endif
+ if (t < 0) t = 0;
+ *xp = t;
+ t = mag_y + main_y - alt.height/2;
+#ifndef X10
+ if (t > HeightOfScreen(SCRN) - alt.height - 2*MAGBORD)
+ t = HeightOfScreen(SCRN) - alt.height - 2*MAGBORD;
+#else
+ if (t > (int) window_h - alt.height - 2*MAGBORD)
+ t = window_h - alt.height - 2*MAGBORD;
+#endif
+ if (t < 0) t = 0;
+ *yp = t;
+}
+
+#ifdef TOOLKIT
+ /*ARGSUSED*/
+static void
+handle_button(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xbutton))
+ Boolean *cont; /* unused */
+#else /* !TOOLKIT */
+static void
+handle_button(event)
+ XButtonEvent *event;
+#endif /* TOOLKIT */
+{
+ int x, y;
+#ifndef X10
+ int w = RESOURCE(mg_size[event->button - 1]);
+ XSetWindowAttributes attr;
+#else
+ int w = RESOURCE(mg_size[2 - (event->detail & ValueMask)]);
+#endif
+
+ if (alt.win != (Window) 0 || mane.shrinkfactor == 1 || w <= 0)
+ XBell(DISP, 20);
+ else {
+ mag_x = event->x;
+ mag_y = event->y;
+ alt.width = alt.height = w;
+#ifndef X10
+ main_x = event->x_root - mag_x;
+ main_y = event->y_root - mag_y;
+#endif
+ compute_mag_pos(&x, &y);
+ alt.base_x = (event->x + mane_base_x) * mane.shrinkfactor -
+ alt.width/2;
+ alt.base_y = (event->y + mane_base_y) * mane.shrinkfactor -
+ alt.height/2;
+#ifndef X10
+ attr.save_under = True;
+ attr.border_pixel = RESOURCE(brdr_Pixel);
+ attr.background_pixel = RESOURCE(back_Pixel);
+ attr.override_redirect = True;
+ alt.win = XCreateWindow(DISP, RootWindowOfScreen(SCRN),
+ x, y, alt.width, alt.height, MAGBORD,
+ 0, /* depth from parent */
+ InputOutput, CopyFromParent,
+ CWSaveUnder | CWBorderPixel | CWBackPixel |
+ CWOverrideRedirect, &attr);
+ XSelectInput(DISP, WINDOW(alt), ExposureMask);
+#else
+ alt.win = XCreateWindow(WINDOW(mane),
+ x, y, alt.width, alt.height, MAGBORD,
+ bdrmap, backmap);
+ XSelectInput(WINDOW(alt), ExposeRegion);
+#endif
+ XMapWindow(DPY WINDOW(alt));
+ alt_stat = 1; /* waiting for exposure */
+ }
+}
+
+#ifdef TOOLKIT
+#undef event
+
+ /*ARGSUSED*/
+static void
+handle_motion(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xmotion))
+ Boolean *cont; /* unused */
+{
+ new_mag_x = event->x;
+ main_x = event->x_root - new_mag_x;
+ new_mag_y = event->y;
+ main_y = event->y_root - new_mag_y;
+ mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y);
+}
+
+#undef event
+#endif /* TOOLKIT */
+
+static void
+movemag(x, y)
+ int x, y;
+{
+ int xx, yy;
+
+ mag_x = x;
+ mag_y = y;
+ if (mag_x == new_mag_x && mag_y == new_mag_y) mag_moved = False;
+ compute_mag_pos(&xx, &yy);
+ XMoveWindow(DPY WINDOW(alt), xx, yy);
+ scrollwindow(&alt, (x + mane_base_x) * mane.shrinkfactor - alt.width/2,
+ (y + mane_base_y) * mane.shrinkfactor - alt.height/2);
+}
+
+#ifdef TOOLKIT
+ /*ARGSUSED*/
+static void
+handle_release(widget, junk, ev, cont)
+ Widget widget;
+ XtPointer junk;
+ XEvent *ev;
+#define event (&(ev->xbutton))
+ Boolean *cont; /* unused */
+#else /* !TOOLKIT */
+static void
+handle_release()
+#endif /* TOOLKIT */
+{
+ if (alt.win)
+ if (alt_stat) alt_stat = -1; /* destroy upon expose */
+ else {
+ XDestroyWindow(DPY WINDOW(alt));
+ if (currwin.win == alt.win) alt_canit = True;
+ alt.win = (Window) 0;
+ mag_moved = False;
+ can_exposures(&alt);
+ }
+}
+
+#ifdef TOOLKIT
+#undef event
+
+ /*ARGSUSED*/
+static void
+handle_exp(widget, closure, ev, cont)
+ Widget widget;
+ XtPointer closure;
+ register XEvent *ev;
+#define event (&(ev->xexpose))
+ Boolean *cont; /* unused */
+{
+ struct WindowRec *windowrec = (struct WindowRec *) closure;
+
+ if (windowrec == &alt)
+ if (alt_stat < 0) { /* destroy upon exposure */
+ alt_stat = 0;
+ handle_release(widget, (caddr_t) NULL, ev, (Boolean *) NULL);
+ return;
+ }
+ else
+ alt_stat = 0;
+ expose(windowrec, event->x, event->y, event->width, event->height);
+}
+
+#undef event
+#endif /* TOOLKIT */
+
+/* |||
+ * Currently the event handler does not coordinate XCopyArea requests
+ * with GraphicsExpose events. This can lead to problems if the window
+ * is partially obscured and one, for example, drags a scrollbar.
+ */
+
+#ifndef X10
+#define XKEY(ev) (ev).xkey
+#ifndef TOOLKIT
+#define XANY(ev) (ev).xany
+#define XCONFIG(ev) (ev).xconfigure
+#define XEXPOSE(ev) (ev).xexpose
+#define XMOTION(ev) (ev).xmotion
+#define XBUTTON(ev) (ev).xbutton
+#define ISEXPOSE(ev) ((ev).type == Expose)
+#endif /* TOOLKIT */
+#else /* X10 */
+#define XANY(ev) (ev)
+#define XCONFIG(ev) (*((XExposeEvent *) &(ev)))
+#define XEXPOSE(ev) (*((XExposeEvent *) &(ev)))
+#define XMOTION(ev) (*((XMouseMovedEvent *) &(ev)))
+#define XBUTTON(ev) (*((XButtonEvent *) &(ev)))
+#define XKEY(ev) (*((XKeyEvent *) &(ev)))
+#define ConfigureNotify ExposeWindow
+#define Expose ExposeRegion
+#define ISEXPOSE(ev) ((ev).type == ExposeWindow || (ev).type == ExposeRegion)
+#define MotionNotify MouseMoved
+#define ButtonPress ButtonPressed
+#define ButtonRelease ButtonReleased
+#define KeyPress KeyPressed
+#endif /* X10 */
+
+static void
+keystroke(ch, number0, arg0, eventp)
+ char ch;
+ int number0;
+ Boolean arg0;
+ XEvent *eventp;
+{
+ int next_page;
+#ifdef TOOLKIT
+ Window ww;
+#endif
+
+ next_page = current_page;
+ switch (ch) {
+ case 'q':
+ case '\003': /* control-C */
+ case '\004': /* control-D */
+#ifdef VMS
+ case '\032': /* control-Z */
+#endif
+ exit(0);
+ case 'n':
+ case 'f':
+ case ' ':
+ case '\r':
+ case '\n':
+ /* scroll forward; i.e. go to relative page */
+ next_page = current_page + (arg0 ? number0 : 1);
+ break;
+ case 'p':
+ case 'b':
+ case '\b':
+ case '\177': /* Del */
+ /* scroll backward */
+ next_page = current_page - (arg0 ? number0 : 1);
+ break;
+ case 'g':
+ /* go to absolute page */
+ next_page = (arg0 ? number0 - pageno_correct :
+ total_pages - 1);
+ break;
+ case 'P': /* declare current page */
+ pageno_correct = arg0 * number0 - current_page;
+ return;
+ case 'k': /* toggle keep-position flag */
+ RESOURCE(keep_flag) = (arg0 ? number0 : !RESOURCE(keep_flag));
+ return;
+ case '\f':
+ /* redisplay current page */
+ break;
+ case '^':
+ home(True);
+ return;
+#ifdef TOOLKIT
+ case 'l':
+ if (!x_bar) goto bad;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (-2 * (int) clip_w / 3));
+ return;
+ case 'r':
+ if (!x_bar) goto bad;
+ XtCallCallbacks(x_bar, XtNscrollProc,
+ (XtPointer) (2 * (int) clip_w / 3));
+ return;
+ case 'u':
+ if (!y_bar) goto bad;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (-2 * (int) clip_h / 3));
+ return;
+ case 'd':
+ if (!y_bar) goto bad;
+ XtCallCallbacks(y_bar, XtNscrollProc,
+ (XtPointer) (2 * (int) clip_h / 3));
+ return;
+ case 'c':
+ center(eventp->xkey.x, eventp->xkey.y);
+ return;
+ case 'M':
+ XTranslateCoordinates(DISP, eventp->xkey.window,
+ WINDOW(mane), eventp->xkey.x, eventp->xkey.y,
+ &home_x, &home_y, &ww); /* throw away last argument */
+ home_x *= mane.shrinkfactor;
+ home_y *= mane.shrinkfactor;
+ return;
+#ifdef BUTTONS
+ case 'x':
+ if (arg0 && resource.expert == (number0 != 0)) return;
+ if (resource.expert) { /* create buttons */
+ XtResizeWidget(vport_widget, window_w -= XTRA_WID, window_h,
+ 0);
+ create_buttons((XtArgVal) window_h);
+ resource.expert = False;
+ }
+ else { /* destroy buttons */
+ XtResizeWidget(vport_widget, window_w += XTRA_WID, window_h,
+ 0);
+ XtDestroyWidget(right_widget);
+ XtDestroyWidget(line_widget);
+ resource.expert = True;
+ }
+ return;
+#endif /* BUTTONS */
+#else /* !TOOLKIT */
+ case 'l':
+ if (mane.base_x <= 0) goto bad;
+ scrollmane(mane.base_x - 2 * clip_w / 3, mane.base_y);
+ return;
+ case 'r':
+ if (mane.base_x >= page_w - clip_w) goto bad;
+ scrollmane(mane.base_x + 2 * clip_w / 3, mane.base_y);
+ return;
+ case 'u':
+ if (mane.base_y <= 0) goto bad;
+ scrollmane(mane.base_x, mane.base_y - 2 * clip_h / 3);
+ return;
+ case 'd':
+ if (mane.base_y >= page_h - clip_h) goto bad;
+ scrollmane(mane.base_x, mane.base_y + 2 * clip_h / 3);
+ return;
+ case 'c': /* unchecked scrollmane() */
+ scrollwindow(&mane, mane.base_x + XKEY(*eventp).x - clip_w/2,
+ mane.base_y + XKEY(*eventp).y - clip_h/2);
+ if (x_bar) paint_x_bar();
+ if (y_bar) paint_y_bar();
+#ifndef X10
+ XWarpPointer(DISP, None, None, 0, 0, 0, 0,
+ clip_w/2 - XKEY(*eventp).x, clip_h/2 - XKEY(*eventp).y);
+#else
+ XWarpMouse(WINDOW(mane), clip_w/2, clip_h/2, GXcopy);
+#endif
+ return;
+ case 'M':
+ home_x = (XKEY(*eventp).x - (y_bar ? BAR_THICK : 0)
+ + mane.base_x) * mane.shrinkfactor;
+ home_y = (XKEY(*eventp).y - (x_bar ? BAR_THICK : 0)
+ + mane.base_y) * mane.shrinkfactor;
+ return;
+#endif /* TOOLKIT */
+
+#ifndef X10
+ case '\020': /* Control P */
+ Printf("Unit = %d, bitord = %d, byteord = %d\n",
+ BitmapUnit(DISP), BitmapBitOrder(DISP),
+ ImageByteOrder(DISP));
+ return;
+#endif
+ case 's':
+ if (!arg0) {
+ int temp;
+ number0 = ROUNDUP(unshrunk_page_w, window_w - 2);
+ temp = ROUNDUP(unshrunk_page_h, window_h - 2);
+ if (number0 < temp) number0 = temp;
+ }
+ if (number0 <= 0) goto bad;
+ if (number0 == mane.shrinkfactor) return;
+ mane.shrinkfactor = number0;
+ init_page();
+ if (number0 != 1 && number0 != bak_shrink) {
+ bak_shrink = number0;
+#ifdef GREY
+ if (use_grey) init_pix(False);
+#endif
+ reset_fonts();
+ }
+#ifdef TOOLKIT
+ draw_args[0].value = (XtArgVal) page_w;
+ draw_args[1].value = (XtArgVal) page_h;
+ XtSetValues(draw_widget, draw_args, (Cardinal) 2);
+ get_geom();
+ home(False);
+#else /* TOOLKIT */
+ reconfig();
+ home(False);
+#endif /* TOOLKIT */
+ break;
+ case 'S':
+ if (!arg0) goto bad;
+ if (number0 < 0) goto bad;
+ if (number0 == density) return;
+ density = number0;
+ reset_fonts();
+ if (mane.shrinkfactor == 1) return;
+ break;
+#ifdef GREY
+ case 'G':
+ use_grey = (arg0 ? number0 : !use_grey);
+ if (use_grey) init_pix(False);
+ reset_fonts();
+ break;
+#endif
+ case 'R':
+ /* reread DVI file */
+ --dvi_time; /* then it will notice a change */
+ break;
+ default:
+ goto bad;
+ }
+ if (0 <= next_page && next_page < total_pages) {
+ if (current_page != next_page) {
+ current_page = next_page;
+ hush_spec_now = hush_spec;
+ if (!RESOURCE(keep_flag)) home(False);
+ }
+ canit = True;
+ Flush();
+ return; /* don't use longjmp here: it might be called from
+ * within the toolkit, and we don't want to longjmp out
+ * of Xt routines. */
+ }
+ bad: XBell(DISP, 10);
+}
+
+
+#ifndef X10
+#define TRSIZE 100
+#endif /* X10 */
+
+static void
+read_events(wait)
+ Boolean wait;
+{
+ char ch;
+ Boolean arg0;
+ int number0;
+ XEvent event;
+#ifndef X10
+ char trbuf[TRSIZE];
+#endif
+ char *string;
+ int nbytes;
+
+ alt_canit = False;
+ for (;;) {
+ ch = '\0';
+ event_counter = event_freq;
+ /*
+ * The above line clears the flag indicating that an event is
+ * pending. So if an event comes in right now, the flag will be
+ * set again needlessly, but we just end up making an extra call.
+ * Also, watch out, if we destroy the magnifying glass while
+ * writing it.
+ */
+ if (!XtPending() && (!wait || canit || mane.min_x < MAXDIM ||
+ alt.min_x < MAXDIM || mag_moved))
+ if (!wait && (canit || alt_canit)) longjmp(canit_env, 1);
+ else return;
+#ifdef TOOLKIT
+ XtNextEvent(&event);
+ if (resized) get_geom();
+ if (event.xany.window == WINDOW(alt) &&
+ event.type == Expose) {
+ handle_exp((Widget) NULL, (XtPointer) &alt, &event,
+ (Boolean *) NULL);
+ continue;
+ }
+ if (event.type != KeyPress) {
+ XtDispatchEvent(&event);
+ continue;
+ }
+ string = trbuf;
+ nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL, NULL);
+ if (nbytes > 1) ch = '?';
+ if (nbytes != 0) ch = *string;
+#else /* !TOOLKIT */
+
+ XNextEvent(DPY &event);
+ if (XANY(event).window == WINDOW(mane) ||
+ XANY(event).window == WINDOW(alt)) {
+
+ struct WindowRec *wr = &mane;
+
+ if (XANY(event).window == WINDOW(alt)) {
+ wr = &alt;
+ /* check in case we already destroyed the window */
+ if (alt_stat < 0) { /* destroy upon exposure */
+ alt_stat = 0;
+ handle_release();
+ continue;
+ }
+ else
+ alt_stat = 0;
+ }
+ switch (event.type) {
+#ifndef X10
+ case GraphicsExpose:
+#else
+ case ExposeWindow:
+#endif
+ case Expose:
+#ifdef X10
+ if (XEXPOSE(event).detail & ExposeCopy)
+ ClearArea(event.window,
+ XEXPOSE(event).x, XEXPOSE(event).y,
+ XEXPOSE(event).width, XEXPOSE(event).height);
+#endif
+ expose(wr, XEXPOSE(event).x, XEXPOSE(event).y,
+ XEXPOSE(event).width, XEXPOSE(event).height);
+#ifdef X10
+ case ExposeCopy: /* throw away junk event */
+#endif
+ break;
+
+ case MotionNotify:
+#ifdef X10
+ case LeftDownMotion:
+ case MiddleDownMotion:
+ case RightDownMotion:
+#endif
+ new_mag_x = XMOTION(event).x;
+ new_mag_y = XMOTION(event).y;
+ mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y);
+ break;
+
+ case ButtonPress:
+ handle_button(&XBUTTON(event));
+ break;
+
+ case ButtonRelease:
+ handle_release();
+ break;
+ } /* end switch */
+ } /* end if window == {mane,alt}.win */
+
+ else if (XANY(event).window == x_bar) {
+ if (ISEXPOSE(event))
+ DarkenArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID);
+ else if (event.type == MotionNotify)
+ scrollmane(XMOTION(event).x * page_w / clip_w,
+ mane.base_y);
+#ifndef X10
+ else switch (XBUTTON(event).button)
+#else
+ else if (event.type == ButtonPress)
+ switch (3 - (XBUTTON(event).detail & ValueMask))
+#endif
+ {
+ case 1:
+ scrollmane(mane.base_x + XBUTTON(event).x, mane.base_y);
+ break;
+ case 2:
+ scrollmane(XBUTTON(event).x * page_w / clip_w,
+ mane.base_y);
+ break;
+ case 3:
+ scrollmane(mane.base_x - XBUTTON(event).x, mane.base_y);
+ }
+ }
+
+ else if (XANY(event).window == y_bar) {
+ if (ISEXPOSE(event))
+ DarkenArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn);
+ else if (event.type == MotionNotify)
+ scrollmane(mane.base_x,
+ XMOTION(event).y * page_h / clip_h);
+#ifndef X10
+ else switch (XBUTTON(event).button)
+#else
+ else if (event.type == ButtonPress)
+ switch (3 - (XBUTTON(event).detail & ValueMask))
+#endif
+ {
+ case 1:
+ scrollmane(mane.base_x, mane.base_y + XBUTTON(event).y);
+ break;
+ case 2:
+ scrollmane(mane.base_x,
+ XBUTTON(event).y * page_h / clip_h);
+ break;
+ case 3:
+ scrollmane(mane.base_x, mane.base_y - XBUTTON(event).y);
+ }
+ }
+
+ else if (XANY(event).window == top_level)
+ switch (event.type) {
+ case ConfigureNotify:
+ if (XANY(event).window == top_level &&
+ (XCONFIG(event).width != window_w ||
+ XCONFIG(event).height != window_h)) {
+ register Window old_mane_win = mane.win;
+
+ window_w = XCONFIG(event).width;
+ window_h = XCONFIG(event).height;
+ reconfig();
+ if (old_mane_win == NULL) home(False);
+ }
+ break;
+
+#ifndef X10
+ case MapNotify: /* if running w/o WM */
+ if (mane.win == NULL) {
+ reconfig();
+ home(False);
+ }
+ break;
+#endif
+
+ case KeyPress:
+#ifndef X10
+ string = trbuf;
+ nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL,
+ NULL);
+#else
+ string = XLookupMapping(&event, &nbytes);
+#endif
+ if (nbytes > 1) ch = '?';
+ if (nbytes != 0) ch = *string;
+ break;
+ }
+#endif /* TOOLKIT */
+ if (ch == '\0') continue;
+ if (ch >= '0' && ch <= '9') {
+ has_arg = True;
+ number = number * 10 + sign * (ch - '0');
+ continue;
+ }
+ else if (ch == '-') {
+ has_arg = True;
+ sign = -1;
+ number = 0;
+ continue;
+ }
+ number0 = number;
+ number = 0;
+ sign = 1;
+ arg0 = has_arg;
+ has_arg = False;
+ keystroke(ch, number0, arg0, &event);
+ }
+}
+
+static void
+redraw(windowrec)
+ struct WindowRec *windowrec;
+{
+ char *errtext;
+#ifdef X10
+ static FontInfo *font = 0;
+#endif
+
+ currwin = *windowrec;
+ min_x = currwin.min_x + currwin.base_x;
+ min_y = currwin.min_y + currwin.base_y;
+ max_x = currwin.max_x + currwin.base_x;
+ max_y = currwin.max_y + currwin.base_y;
+ can_exposures(windowrec);
+
+ if (debug & DBG_EVENT)
+ Printf("Redraw %d x %d at (%d, %d) (base=%d,%d)\n", max_x - min_x,
+ max_y - min_y, min_x, min_y, currwin.base_x, currwin.base_y);
+ SetCursor(redraw_cursor);
+ Flush();
+ if (errtext = (char *) setjmp(dvi_env)) {
+ ClearPage(mane);
+#ifndef X10
+ get_xy();
+ XDrawString(DISP, WINDOW(mane), foreGC,
+ 5 - window_x, 5 + X11HEIGHT - window_y,
+ errtext, strlen(errtext));
+#else
+ if (!font) font = XOpenFont(X10FONT);
+ XTextMask(WINDOW(mane), 5, 5 + X10HEIGHT, errtext, strlen(errtext),
+ font->id, foreGC);
+#endif
+ if (dvi_file) {
+ Fclose(dvi_file);
+ dvi_file = NULL;
+ }
+ }
+ else {
+ draw_page();
+ hush_spec_now = True;
+ }
+}
+
+void
+redraw_page()
+{
+ if (debug & DBG_EVENT) Fputs("Redraw page: ", stdout);
+ get_xy();
+ ClearPage(mane);
+ mane.min_x = -window_x;
+ mane.max_x = -window_x + clip_w;
+ mane.min_y = -window_y;
+ mane.max_y = -window_y + clip_h;
+ redraw(&mane);
+}
+
+/*
+ * Interrupt system for receiving events. The program sets a flag
+ * whenever an event comes in, so that at the proper time (i.e., when
+ * reading a new dvi item), we can check incoming events to see if we
+ * still want to go on printing this page. This way, one can stop
+ * displaying a page if it is about to be erased anyway. We try to read
+ * as many events as possible before doing anything and base the next
+ * action on all events read.
+ * Note that the Xlib and Xt routines are not reentrant, so the most we
+ * can do is set a flag in the interrupt routine and check it later.
+ * Also, sometimes the interrupts are not generated (some systems only
+ * guarantee that SIGIO is generated for terminal files, and on the system
+ * I use, the interrupts are not generated if I use "(xdvi foo &)" instead
+ * of "xdvi foo"). Therefore, there is also a mechanism to check the
+ * event queue every 70 drawing operations or so. This mechanism is
+ * disabled if it turns out that the interrupts do work.
+ * For a fuller discussion of some of the above, see xlife in
+ * comp.sources.x.
+ */
+
+static void
+can_exposures(windowrec)
+ struct WindowRec *windowrec;
+{
+ windowrec->min_x = windowrec->min_y = MAXDIM;
+ windowrec->max_x = windowrec->max_y = 0;
+}
+
+static void
+handle_intr() {
+ event_counter = 1;
+ event_freq = -1; /* forget Plan B */
+}
+
+#ifdef HAS_SIGIO
+static void
+enable_intr() {
+ int socket = ConnectionNumber(DISP);
+ if (!isatty(0)) {
+ Puts("trying...");
+ if (dup2(socket, 0) == -1) perror(prog);
+ socket = 0;
+ }
+ (void) signal(SIGIO, handle_intr);
+ (void) fcntl(socket, F_SETOWN, getpid());
+ (void) fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | FASYNC);
+}
+#endif /* HAS_SIGIO */
+
+static void
+do_pages()
+{
+ if (debug & DBG_BATCH) {
+#ifdef TOOLKIT
+ while (mane.min_x == MAXDIM) read_events(True);
+#else /* !TOOLKIT */
+ while (mane.min_x == MAXDIM)
+ if (setjmp(canit_env)) break;
+ else read_events(True);
+#endif /* TOOLKIT */
+ for (current_page = 0; current_page < total_pages; ++current_page)
+ redraw_page();
+ }
+ else { /* normal operation */
+#ifdef HAS_SIGIO
+ enable_intr();
+#endif
+#ifdef __convex__
+ /* convex C turns off optimization for the entire function
+ if setjmp return value is discarded.*/
+ if (setjmp(canit_env)) /*optimize me*/;
+#else
+ (void) setjmp(canit_env);
+#endif
+ for (;;) {
+ if (mane.win) SetCursor(ready_cursor);
+ read_events(True);
+ if (canit) {
+ canit = False;
+ can_exposures(&mane);
+ can_exposures(&alt);
+ redraw_page();
+ }
+ else if (mag_moved) {
+ if (alt.win == (Window) 0) mag_moved = False;
+ else if (abs(new_mag_x - mag_x) >
+ 2 * abs(new_mag_y - mag_y))
+ movemag(new_mag_x, mag_y);
+ else if (abs(new_mag_y - mag_y) >
+ 2 * abs(new_mag_x - mag_x))
+ movemag(mag_x, new_mag_y);
+ else movemag(new_mag_x, new_mag_y);
+ }
+ else if (alt.min_x < MAXDIM) redraw(&alt);
+ else if (mane.min_x < MAXDIM) redraw(&mane);
+ Flush();
+ }
+ }
+}
+
+static NORETURN void
+usage() {
+#ifndef X10
+#ifndef VMS
+#ifdef BUTTONS
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
+ [-expert] [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] \
+[-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host:display>] [-copy] [-thorough] dvi_file\n\n\n\
+ Adapted to DV/X using DJGPP by Eric Ho\n\
+ 9041477@SSCVAX.MCMASTER.CA\n\n",
+ stderr);
+#else /* !BUTTONS */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] [-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] [-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host:display>] [-copy] [-thorough] dvi_file\n\n\n\
+ Adapted to DV/X using DJGPP by Eric Ho\n\
+ 9041477@SSCVAX.MCMASTER.CA\n\n",
+ stderr);
+#endif /* BUTTONS */
+#else /* VMS */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-density <%>] [-p <pixels>] [-l] [-rv]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\
+\n", stderr);
+ Fputs("\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma <g>] \
+[-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
+ [-iconic] [-display <host::display>] [-copy] [-thorough] dvi_file\n",
+ stderr);
+#endif /* VMS */
+#else /* X10 */
+ Fputs("\
+Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l]\n\
+ [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
+ [-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
+ [-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
+ [-hushspecials] [-hushchars] [-hush] [-version]\n\
+ [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
+[-cr <color>]\n\
+ [-bw <width>] [-geometry <geometry> | =<geometry>]\n\
+ [-display <host:display> | <host:display>] dvi_file\n", stderr);
+#endif /* X10 */
+ exit(1);
+}
+
+static int
+atopix(arg)
+ _Xconst char *arg;
+{
+ int len = strlen(arg);
+
+ return (len > 2 && arg[len - 2] == 'c' && arg[len - 1] == 'm' ?
+ 1.0 / 2.54 : 1.0) * atof(arg) * pixels_per_inch + 0.5;
+}
+
+/**
+ ** Main programs start here.
+ **/
+
+#ifdef TOOLKIT
+
+static XrmOptionDescRec options[] = {
+{"-d", ".debugLevel", XrmoptionSepArg, (caddr_t) NULL},
+{"-s", ".shrinkFactor", XrmoptionSepArg, (caddr_t) NULL},
+#ifndef VMS
+{"-S", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL},
+#endif
+{"-density", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL},
+#ifdef GREY
+{"-gamma", ".gamma", XrmoptionSepArg, (caddr_t) NULL},
+#endif
+{"-p", ".pixelsPerInch", XrmoptionSepArg, (caddr_t) NULL},
+{"-margins", ".Margin", XrmoptionSepArg, (caddr_t) NULL},
+{"-sidemargin", ".sideMargin", XrmoptionSepArg, (caddr_t) NULL},
+{"-topmargin", ".topMargin", XrmoptionSepArg, (caddr_t) NULL},
+{"-offsets", ".Offset", XrmoptionSepArg, (caddr_t) NULL},
+{"-xoffset", ".xOffset", XrmoptionSepArg, (caddr_t) NULL},
+{"-yoffset", ".yOffset", XrmoptionSepArg, (caddr_t) NULL},
+{"-paper", ".paper", XrmoptionSepArg, (caddr_t) NULL},
+{"-altfont", ".altFont", XrmoptionSepArg, (caddr_t) NULL},
+{"-l", ".listFonts", XrmoptionNoArg, (caddr_t) "on"},
+{"+l", ".listFonts", XrmoptionNoArg, (caddr_t) "off"},
+{"-hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "on"},
+{"+hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "off"},
+{"-hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "on"},
+{"+hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "off"},
+{"-hush", ".Hush", XrmoptionNoArg, (caddr_t) "on"},
+{"+hush", ".Hush", XrmoptionNoArg, (caddr_t) "off"},
+{"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
+{"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
+{"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL},
+{"-background", ".background", XrmoptionSepArg, (caddr_t) NULL},
+{"-hl", ".highlight", XrmoptionSepArg, (caddr_t) NULL},
+{"-cr", ".cursorColor", XrmoptionSepArg, (caddr_t) NULL},
+{"-icongeometry",".iconGeometry",XrmoptionSepArg, (caddr_t) NULL},
+{"-keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "on"},
+{"+keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "off"},
+{"-copy", ".copy", XrmoptionNoArg, (caddr_t) "on"},
+{"+copy", ".copy", XrmoptionNoArg, (caddr_t) "off"},
+{"-thorough", ".thorough", XrmoptionNoArg, (caddr_t) "on"},
+{"+thorough", ".thorough", XrmoptionNoArg, (caddr_t) "off"},
+{"-version", ".version", XrmoptionNoArg, (caddr_t) "on"},
+{"+version", ".version", XrmoptionNoArg, (caddr_t) "off"},
+#ifdef BUTTONS
+{"-expert", ".expert", XrmoptionNoArg, (caddr_t) "on"},
+{"+expert", ".expert", XrmoptionNoArg, (caddr_t) "off"},
+#endif
+{"-mgs", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs1", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs2", ".magnifierSize2",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs3", ".magnifierSize3",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs4", ".magnifierSize4",XrmoptionSepArg, (caddr_t) NULL},
+{"-mgs5", ".magnifierSize5",XrmoptionSepArg, (caddr_t) NULL},
+#ifdef GREY
+{"-nogrey", ".grey", XrmoptionNoArg, (caddr_t) "off"},
+{"+nogrey", ".grey", XrmoptionNoArg, (caddr_t) "on"},
+#endif
+};
+
+#define offset(field) XtOffsetOf(struct _resource, field)
+
+static int basedpi = BDPI; /* default value for -p option */
+
+static XtResource application_resources[] = {
+{"debugLevel", "DebugLevel", XtRString, sizeof(char *),
+ offset(debug_arg), XtRString, (caddr_t) NULL},
+{"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int),
+ offset(_shrink_factor), XtRString, "3"},
+{"densityPercent", "DensityPercent", XtRInt, sizeof(int),
+ offset(density), XtRString, "40"},
+#ifdef GREY
+{"gamma", "Gamma", XtRFloat, sizeof(float),
+ offset(gamma), XtRString, "1"},
+#endif
+{"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int),
+ offset(pixels_per_inch), XtRInt, (caddr_t) &basedpi},
+{"sideMargin", "Margin", XtRString, sizeof(char *),
+ offset(sidemargin), XtRString, (caddr_t) NULL},
+{"topMargin", "Margin", XtRString, sizeof(char *),
+ offset(topmargin), XtRString, (caddr_t) NULL},
+{"xOffset", "Offset", XtRString, sizeof(char *),
+ offset(xoffset), XtRString, (caddr_t) NULL},
+{"yOffset", "Offset", XtRString, sizeof(char *),
+ offset(yoffset), XtRString, (caddr_t) NULL},
+{"paper", "Paper", XtRString, sizeof(char *),
+ offset(paper), XtRString, (caddr_t) DEFAULT_PAPER},
+{"altFont", "AltFont", XtRString, sizeof(char *),
+ offset(alt_font), XtRString, (caddr_t) ALTFONT},
+{"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean),
+ offset(list_fonts), XtRString, "false"},
+{"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
+ offset(reverse), XtRString, "false"},
+{"hushSpecials", "Hush", XtRBoolean, sizeof(Boolean),
+ offset(hush_spec), XtRString, "false"},
+{"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean),
+ offset(hush_chars), XtRString, "false"},
+{"foreground", "Foreground", XtRPixel, sizeof(Pixel),
+ offset(fore_Pixel), XtRPixel, (caddr_t) &resource.fore_Pixel},
+{"foreground", "Foreground", XtRString, sizeof(char *),
+ offset(fore_color), XtRString, (caddr_t) NULL},
+{"background", "Background", XtRPixel, sizeof(Pixel),
+ offset(back_Pixel), XtRPixel, (caddr_t) &resource.back_Pixel},
+{"background", "Background", XtRString, sizeof(char *),
+ offset(back_color), XtRString, (caddr_t) NULL},
+{"borderColor", "BorderColor", XtRPixel, sizeof(Pixel),
+ offset(brdr_Pixel), XtRPixel, (caddr_t) &resource.brdr_Pixel},
+{"borderColor", "BorderColor", XtRString, sizeof(char *),
+ offset(brdr_color), XtRString, (caddr_t) NULL},
+{"highlight", "Highlight", XtRPixel, sizeof(Pixel),
+ offset(hl_Pixel), XtRPixel, (caddr_t) &resource.hl_Pixel},
+{"highlight", "Highlight", XtRString, sizeof(char *),
+ offset(high_color), XtRString, (caddr_t) NULL},
+{"cursorColor", "CursorColor", XtRPixel, sizeof(Pixel),
+ offset(cr_Pixel), XtRPixel, (caddr_t) &resource.cr_Pixel},
+{"cursorColor", "CursorColor", XtRString, sizeof(char *),
+ offset(curs_color), XtRString, (caddr_t) NULL},
+{"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
+ offset(icon_geometry), XtRString, (caddr_t) NULL},
+{"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean),
+ offset(keep_flag), XtRString, "false"},
+{"copy", "Copy", XtRString, sizeof(char *),
+ offset(copy_arg), XtRString, (caddr_t) NULL},
+{"copy", "Copy", XtRBoolean, sizeof(Boolean),
+ offset(copy), XtRString, "false"},
+{"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
+ offset(thorough), XtRString, "false"},
+{"version", "Version", XtRBoolean, sizeof(Boolean),
+ offset(version_flag), XtRString, "false"},
+#ifdef BUTTONS
+{"expert", "Expert", XtRBoolean, sizeof(Boolean),
+ offset(expert), XtRString, "false"},
+#endif
+{"magnifierSize1", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[0]), XtRString, "200"},
+{"magnifierSize2", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[1]), XtRString, "350"},
+{"magnifierSize3", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[2]), XtRString, "600"},
+{"magnifierSize4", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[3]), XtRString, "900"},
+{"magnifierSize5", "MagnifierSize", XtRInt, sizeof(int),
+ offset(mg_size[4]), XtRString, "1200"},
+#ifdef GREY
+{"grey", "Grey", XtRBoolean, sizeof (Boolean),
+ offset(use_grey), XtRString, "true"},
+#endif
+};
+#undef offset
+
+static Arg temp_args1[] = {
+ {XtNiconX, (XtArgVal) 0},
+ {XtNiconY, (XtArgVal) 0},
+};
+
+static Arg temp_args2 = {XtNborderWidth, (XtArgVal) &bwidth};
+
+static Pixmap icon_pm;
+
+static Arg temp_args3[] = {
+ {XtNiconPixmap, (XtArgVal) &icon_pm},
+};
+
+static Arg temp_args4[] = {
+ {XtNtitle, (XtArgVal) 0},
+ {XtNinput, (XtArgVal) True},
+};
+
+static Arg set_wh_args[] = {
+ {XtNwidth, (XtArgVal) 0},
+ {XtNheight, (XtArgVal) 0},
+};
+#else /* !TOOLKIT */
+
+static char *display;
+static char *geometry;
+static char *margins;
+static char *offsets;
+static Boolean hush;
+
+#ifndef X10
+static Boolean iconic = False;
+
+static Pixel
+string_to_pixel(strp) /* adapted from the toolkit */
+ char **strp;
+{
+ char *str = *strp;
+ Status status;
+ XColor color, junk;
+
+ if (*str == '#') { /* an rgb definition */
+ status = XParseColor(DISP, DefaultColormapOfScreen(SCRN),
+ str, &color);
+ if (status != 0)
+ status = XAllocColor(DISP, DefaultColormapOfScreen(SCRN),
+ &color);
+ }
+ else /* a name */
+ status = XAllocNamedColor(DISP, DefaultColormapOfScreen(SCRN),
+ str, &color, &junk);
+ if (status == 0) {
+ Fprintf(stderr, "Cannot allocate colormap entry for \"%s\"\n", str);
+ *strp = NULL;
+ return (Pixel) 0;
+ }
+ return color.pixel;
+}
+#endif /* X10 */
+
+static struct option {
+ _Xconst char *name;
+ _Xconst char *resource;
+ enum {FalseArg, TrueArg, StickyArg, SepArg} argclass;
+ enum {BooleanArg, StringArg, NumberArg, FloatArg} argtype;
+ int classcount;
+ caddr_t address;
+} options[] = {
+ /* the display option MUST be first */
+{"-display", NULL, SepArg, StringArg, 1, (caddr_t) &display},
+{"-d", "debugLevel", SepArg, StringArg, 1, (caddr_t) &debug_arg},
+{"+", NULL, StickyArg, StringArg, 1,(caddr_t) &curr_page},
+{"-s", "shrinkFactor", SepArg, NumberArg, 1, (caddr_t) &shrink_factor},
+{"-S", NULL, SepArg, NumberArg, 2, (caddr_t) &density},
+{"-density", "densityPercent", SepArg, NumberArg, 1, (caddr_t) &density},
+#ifdef GREY
+{"-gamma", "gamma", SepArg, FloatArg, 1, (caddr_t) &gamma},
+#endif
+{"-p", "pixelsPerInch", SepArg, NumberArg, 1, (caddr_t) &pixels_per_inch},
+{"-margins", "Margin", SepArg, StringArg, 3, (caddr_t) &margins},
+{"-sidemargin", "sideMargin", SepArg, StringArg, 1, (caddr_t) &sidemargin},
+{"-topmargin", "topMargin", SepArg, StringArg, 1, (caddr_t) &topmargin},
+{"-offsets", "Offset", SepArg, StringArg, 3, (caddr_t) &offsets},
+{"-xoffset", "xOffset", SepArg, StringArg, 1, (caddr_t) &xoffset},
+{"-yoffset", "yOffset", SepArg, StringArg, 1, (caddr_t) &yoffset},
+{"-paper", "paper", SepArg, StringArg, 1, (caddr_t) &paper},
+{"-altfont", "altFont", SepArg, StringArg, 1, (caddr_t) &alt_font},
+{"-l", NULL, TrueArg, BooleanArg, 2, (caddr_t) &list_fonts},
+{"+l", "listFonts", FalseArg, BooleanArg, 1,(caddr_t) &list_fonts},
+{"-rv", NULL, TrueArg, BooleanArg, 2, (caddr_t) &reverse},
+{"+rv", "reverseVideo", FalseArg, BooleanArg, 1,(caddr_t) &reverse},
+{"-hush", NULL, TrueArg, BooleanArg, 6, (caddr_t) &hush},
+{"+hush", "Hush", FalseArg, BooleanArg, 5,(caddr_t) &hush},
+{"-hushspecials", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_spec},
+{"+hushspecials", "hushSpecials", FalseArg, BooleanArg, 1,(caddr_t) &hush_spec},
+{"-hushchars", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_chars},
+{"+hushchars", "hushLostChars", FalseArg, BooleanArg, 1,(caddr_t) &hush_chars},
+{"-bw", NULL, SepArg, NumberArg, 2, (caddr_t) &bwidth},
+{"-borderwidth", "borderWidth", SepArg, NumberArg, 1, (caddr_t) &bwidth},
+{"-fg", NULL, SepArg, StringArg, 2, (caddr_t) &fore_color},
+{"-foreground", "foreground", SepArg, StringArg, 1, (caddr_t) &fore_color},
+{"-bg", NULL, SepArg, StringArg, 2, (caddr_t) &back_color},
+{"-background", "background", SepArg, StringArg, 1, (caddr_t) &back_color},
+{"-bd", NULL, SepArg, StringArg, 2, (caddr_t) &brdr_color},
+{"-bordercolor","borderColor", SepArg, StringArg, 1, (caddr_t) &brdr_color},
+{"-hl", "highlight", SepArg, StringArg, 1, (caddr_t) &high_color},
+{"-cr", "cursorColor", SepArg, StringArg, 1, (caddr_t) &curs_color},
+#ifdef X10
+{"=", NULL, StickyArg, StringArg, 2,(caddr_t) &geometry},
+#endif
+{"-geometry", "geometry", SepArg, StringArg, 1, (caddr_t) &geometry},
+#ifndef X10
+{"-icongeometry","iconGeometry",StickyArg, StringArg, 1,(caddr_t) &icon_geometry},
+{"-iconic", NULL, TrueArg, BooleanArg, 2, (caddr_t) &iconic},
+{"+iconic", "iconic", FalseArg, BooleanArg, 1,(caddr_t) &iconic},
+{"-keep", NULL, TrueArg, BooleanArg, 2, (caddr_t) &keep_flag},
+{"+keep", "keepPosition", FalseArg, BooleanArg, 1,(caddr_t) &keep_flag},
+{"-copy", NULL, TrueArg, BooleanArg, 2, (caddr_t) &copy},
+{"+copy", "copy", FalseArg, BooleanArg, 1,(caddr_t) &copy},
+{"-thorough", NULL, TrueArg, BooleanArg, 2, (caddr_t) &thorough},
+{"+thorough", "thorough", FalseArg, BooleanArg, 1,(caddr_t) &thorough},
+{"-version", NULL, TrueArg, BooleanArg, 2, (caddr_t)&version_flag},
+{"+version", "version", FalseArg, BooleanArg, 1,(caddr_t)&version_flag},
+#endif /* X10 */
+{"-mgs", NULL, SepArg, NumberArg, 2, (caddr_t) &mg_size[0]},
+{"-mgs1", "magnifierSize1",SepArg, NumberArg, 1, (caddr_t) &mg_size[0]},
+{"-mgs2", "magnifierSize2",SepArg, NumberArg, 1, (caddr_t) &mg_size[1]},
+{"-mgs3", "magnifierSize3",SepArg, NumberArg, 1, (caddr_t) &mg_size[2]},
+#ifndef X10
+{"-mgs4", "magnifierSize4",SepArg, NumberArg, 1, (caddr_t) &mg_size[3]},
+{"-mgs5", "magnifierSize5",SepArg, NumberArg, 1, (caddr_t) &mg_size[4]},
+#endif
+#ifdef GREY
+{"-nogrey", NULL, FalseArg, BooleanArg, 2,(caddr_t) &use_grey},
+{"+nogrey", "grey", TrueArg, BooleanArg, 1, (caddr_t) &use_grey},
+#endif
+};
+
+/*
+ * Process the option table. This is not guaranteed for all possible
+ * option tables, but at least it works for this one.
+ */
+
+static void
+parse_options(argc, argv)
+ int argc;
+ char **argv;
+{
+ char **arg;
+ char **argvend = argv + argc;
+ char *optstring;
+ caddr_t addr;
+ struct option *opt, *lastopt, *candidate;
+ int len1, len2, matchlen;
+
+ /*
+ * Step 1. Process command line options.
+ */
+ for (arg = argv + 1; arg < argvend; ++arg) {
+ len1 = strlen(*arg);
+ candidate = NULL;
+ matchlen = 0;
+ for (opt = options; opt < options + XtNumber(options); ++opt) {
+ len2 = strlen(opt->name);
+ if (opt->argclass == StickyArg) {
+ if (matchlen <= len2 && !strncmp(*arg, opt->name, len2)) {
+ candidate = opt;
+ matchlen = len2;
+ }
+ }
+ else if (len1 <= len2 && matchlen <= len1 &&
+ !strncmp(*arg, opt->name, len1)) {
+ if (len1 == len2) {
+ candidate = opt;
+ break;
+ }
+ if (matchlen < len1) candidate = opt;
+ else if (candidate && candidate->argclass != StickyArg)
+ candidate = NULL;
+ matchlen = len1;
+ }
+ }
+ if (candidate == NULL) {
+#ifdef X10
+ if (**arg == '-') usage();
+ if (index(*arg, ':') != NULL) { /* display */
+ --arg;
+ candidate = options;
+ }
+ else if (dvi_name) usage();
+#else
+ if (**arg == '-' || dvi_name) usage();
+#endif
+ else {
+ dvi_name = *arg;
+ continue;
+ }
+ }
+ /* flag it for subsequent processing */
+ candidate->resource = (char *) candidate;
+ /* store the value */
+ addr = candidate->address;
+ switch (candidate->argclass) {
+ case FalseArg: *((Boolean *) addr) = False; continue;
+ case TrueArg: *((Boolean *) addr) = True; continue;
+ case StickyArg: optstring = *arg + strlen(candidate->name);
+ break;
+ case SepArg:
+ ++arg;
+ if (arg >= argvend) usage();
+ optstring = *arg;
+ break;
+ }
+ switch (candidate->argtype) {
+ case StringArg: *((char **) addr) = optstring; break;
+ case NumberArg: *((int *) addr) = atoi(optstring); break;
+ case FloatArg: *((float *) addr) = atof(optstring); break;
+ default: ;
+ }
+ }
+ /*
+ * Step 2. Propagate classes for command line arguments. Backwards.
+ */
+ for (opt = options + XtNumber(options) - 1; opt >= options; --opt)
+ if (opt->resource == (char *) opt) {
+ addr = opt->address;
+ lastopt = opt + opt->classcount;
+ for (candidate = opt; candidate < lastopt; ++candidate) {
+ if (candidate->resource != NULL) {
+ switch (opt->argtype) {
+ case BooleanArg:
+ *((Boolean *) candidate->address) =
+ *((Boolean *) addr);
+ break;
+ case StringArg:
+ *((char **) candidate->address) =
+ *((char **) addr);
+ break;
+ case NumberArg:
+ *((int *) candidate->address) = *((int *) addr);
+ break;
+ case FloatArg:
+ *((float *) candidate->address) =
+ *((float *) addr);
+ break;
+ }
+ candidate->resource = NULL;
+ }
+ }
+ }
+
+#ifndef X10
+ if ((DISP = XOpenDisplay(display)) == NULL)
+ oops("Can't open display");
+ SCRN = DefaultScreenOfDisplay(DISP);
+#else
+ if (XOpenDisplay(display) == NULL)
+ oops("Can't open display");
+#endif
+ /*
+ * Step 3. Handle resources (including classes).
+ */
+ for (opt = options; opt < options + XtNumber(options); ++opt)
+ if (opt->resource &&
+#ifndef X10
+ ((optstring = XGetDefault(DISP, prog, opt->resource)) ||
+ (optstring = XGetDefault(DISP, "XDvi", opt->resource))))
+#else
+ (optstring = XGetDefault(DPY prog, opt->resource)))
+#endif
+ {
+ lastopt = opt + opt->classcount;
+ for (candidate = opt; candidate < lastopt; ++candidate)
+ if (candidate->resource != NULL) switch (opt->argtype) {
+ case BooleanArg:
+ *((Boolean *) candidate->address) =
+ (strcmp(optstring, "on") == 0);
+ break;
+ case StringArg:
+ *((char **) candidate->address) = optstring;
+ break;
+ case NumberArg:
+ *((int *) candidate->address) = atoi(optstring);
+ break;
+ case FloatArg:
+ *((float *) candidate->address) =
+ atof(optstring);
+ }
+ }
+}
+
+#endif /* TOOLKIT */
+
+static _Xconst char *paper_types[] = {
+ "us", "8.5x11",
+ "usr", "11x8.5",
+ "legal", "8.5x14",
+ "foolscap", "13.5x17.0", /* ??? */
+
+ /* ISO `A' formats, Portrait */
+ "a1", "59.4x84.0cm",
+ "a2", "42.0x59.4cm",
+ "a3", "29.7x42.0cm",
+ "a4", "21.0x29.7cm",
+ "a5", "14.85x21.0cm",
+ "a6", "10.5x14.85cm",
+ "a7", "7.42x10.5cm",
+
+ /* ISO `A' formats, Landscape */
+ "a1r", "84.0x59.4cm",
+ "a2r", "59.4x42.0cm",
+ "a3r", "42.0x29.7cm",
+ "a4r", "29.7x21.0cm",
+ "a5r", "21.0x14.85cm",
+ "a6r", "14.85x10.5cm",
+ "a7r", "10.5x7.42cm",
+
+ /* ISO `B' formats, Portrait */
+ "b1", "70.6x100.0cm",
+ "b2", "50.0x70.6cm",
+ "b3", "35.3x50.0cm",
+ "b4", "25.0x35.3cm",
+ "b5", "17.6x25.0cm",
+ "b6", "13.5x17.6cm",
+ "b7", "8.8x13.5cm",
+
+ /* ISO `B' formats, Landscape */
+ "b1r", "100.0x70.6cm",
+ "b2r", "70.6x50.0cm",
+ "b3r", "50.0x35.3cm",
+ "b4r", "35.3x25.0cm",
+ "b5r", "25.0x17.6cm",
+ "b6r", "17.6x13.5cm",
+ "b7r", "13.5x8.8cm",
+
+ /* ISO `C' formats, Portrait */
+ "c1", "64.8x91.6cm",
+ "c2", "45.8x64.8cm",
+ "c3", "32.4x45.8cm",
+ "c4", "22.9x32.4cm",
+ "c5", "16.2x22.9cm",
+ "c6", "11.46x16.2cm",
+ "c7", "8.1x11.46cm",
+
+ /* ISO `C' formats, Landscape */
+ "c1r", "91.6x64.8cm",
+ "c2r", "64.8x45.8cm",
+ "c3r", "45.8x32.4cm",
+ "c4r", "32.4x22.9cm",
+ "c5r", "22.9x16.2cm",
+ "c6r", "16.2x11.46cm",
+ "c7r", "11.46x8.1cm",
+};
+
+static Boolean
+set_paper_type() {
+ _Xconst char *arg, *arg1;
+ char temp[21];
+ _Xconst char **p;
+ char *q;
+
+ if (strlen(RESOURCE(paper)) > sizeof(temp) - 1) return False;
+ arg = RESOURCE(paper);
+ q = temp;
+ for (;;) { /* convert to lower case */
+ char c = *arg++;
+ if (c >= 'A' && c <= 'Z') c ^= ('a' ^ 'A');
+ *q++ = c;
+ if (c == '\0') break;
+ }
+ arg = temp;
+ /* perform substitutions */
+ for (p = paper_types; p < paper_types + XtNumber(paper_types); p += 2)
+ if (strcmp(temp, *p) == 0) {
+ arg = p[1];
+ break;
+ }
+ arg1 = index(arg, 'x');
+ if (arg1 == NULL) return False;
+ unshrunk_paper_w = atopix(arg);
+ unshrunk_paper_h = atopix(arg1 + 1);
+ return (unshrunk_paper_w != 0 && unshrunk_paper_h != 0);
+}
+
+/*
+ * main program
+ */
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+
+
+#ifndef TOOLKIT
+#ifndef X10
+ XSizeHints size_hints;
+ XWMHints wmhints;
+#else
+ OpaqueFrame frame;
+ char def[32];
+ int mouspix;
+ Color cdef;
+ int x_thick, y_thick;
+#endif
+#endif /* TOOLKIT */
+ int screen_w, screen_h;
+
+#ifndef VMS
+ prog = rindex(*argv, '/');
+#else
+ prog = rindex(*argv, ']');
+#endif
+ if (prog != NULL) ++prog; else prog = *argv;
+
+#ifdef VMS
+ if (index(prog, '.') != NULL) *index(prog, '.') = '\0';
+#endif
+
+#ifdef TOOLKIT
+ top_level = XtInitialize(prog, "XDvi", options, XtNumber(options),
+ &argc, argv);
+ while (--argc > 0) {
+ if (*(*++argv) == '+')
+ if (curr_page != NULL) usage();
+ else curr_page = *argv + 1;
+ else if (dvi_name != NULL) usage();
+ else dvi_name = *argv;
+ }
+
+ XtGetApplicationResources(top_level, (XtPointer) &resource,
+ application_resources, XtNumber(application_resources), NULL, 0);
+ DISP = XtDisplay(top_level);
+ SCRN = XtScreen(top_level);
+ shrink_factor = resource._shrink_factor;
+ density = resource.density;
+ pixels_per_inch = resource.pixels_per_inch;
+ alt_font = resource.alt_font;
+ list_fonts = resource.list_fonts;
+ hush_spec = resource.hush_spec;
+ hush_chars = resource.hush_chars;
+#ifdef GREY
+ use_grey = resource.use_grey;
+#endif
+
+#else /* !TOOLKIT */
+
+ parse_options(argc, argv);
+#ifndef X10
+ if (fore_color) fore_Pixel = string_to_pixel(&fore_color);
+ if (back_color) back_Pixel = string_to_pixel(&back_color);
+ if (brdr_color) brdr_Pixel = string_to_pixel(&brdr_color);
+ if (high_color) hl_Pixel = string_to_pixel(&high_color);
+ if (curs_color) cr_Pixel = string_to_pixel(&curs_color);
+#endif
+
+#endif /* TOOLKIT */
+
+
+ if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 ||
+ dvi_name == NULL) usage();
+
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+#if defined(__MSDOS__) && defined(FONTSUB)
+
+ /* Open the font substitute file */
+ fontsubfile = openfontsubfile ();
+
+#endif
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+ if (shrink_factor != 1) bak_shrink = shrink_factor;
+ mane.shrinkfactor = shrink_factor;
+ if (RESOURCE(debug_arg) != NULL)
+ debug = isdigit(*RESOURCE(debug_arg)) ? atoi(RESOURCE(debug_arg))
+ : DBG_ALL;
+ if (RESOURCE(sidemargin)) home_x = atopix(RESOURCE(sidemargin));
+ if (RESOURCE(topmargin)) home_y = atopix(RESOURCE(topmargin));
+ offset_x = RESOURCE(xoffset) ? atopix(RESOURCE(xoffset))
+ : pixels_per_inch;
+ offset_y = RESOURCE(yoffset) ? atopix(RESOURCE(yoffset))
+ : pixels_per_inch;
+ if (!set_paper_type()) oops("Don't recognize paper type %s",
+ RESOURCE(paper));
+
+ init_font_open();
+ open_dvi_file();
+
+
+
+ if (curr_page) {
+ current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
+ if (current_page < 0 || current_page >= total_pages) usage();
+ }
+ if (RESOURCE(version_flag)) Puts((_Xconst char *) &version);
+
+#ifndef X10
+
+ /*
+ * X11 colors
+ */
+
+ if (RESOURCE(reverse)) {
+ if (!RESOURCE(fore_color))
+ RESOURCE(fore_Pixel) = WhitePixelOfScreen(SCRN);
+ if (!RESOURCE(back_color))
+ RESOURCE(back_Pixel) = BlackPixelOfScreen(SCRN);
+ /* Set them nonzero */
+ RESOURCE(fore_color) = RESOURCE(back_color) = (char *) &version;
+ } else {
+ if (!RESOURCE(fore_color))
+ RESOURCE(fore_Pixel) = BlackPixelOfScreen(SCRN);
+ if (!RESOURCE(back_color))
+ RESOURCE(back_Pixel) = WhitePixelOfScreen(SCRN);
+ }
+
+#ifdef GREY
+ if (DefaultDepthOfScreen(SCRN) == 1)
+ use_grey = False;
+#endif
+
+#ifdef TOOLKIT
+ if (resource.copy_arg)
+#else
+ if (copy == 2)
+#endif
+#ifdef GREY
+ RESOURCE(copy) = (!RESOURCE(thorough) && !use_grey
+ && DefaultDepthOfScreen(SCRN) > 1);
+#else
+ RESOURCE(copy) = (!RESOURCE(thorough)
+ && DefaultDepthOfScreen(SCRN) > 1);
+#endif
+
+#ifdef GREY
+ if (use_grey)
+ init_pix(True);
+ else
+#endif
+ {
+ XGCValues values;
+ Pixel set_bits = (Pixel)
+ (RESOURCE(fore_Pixel) & ~RESOURCE(back_Pixel));
+ Pixel clr_bits = (Pixel)
+ (RESOURCE(back_Pixel) & ~RESOURCE(fore_Pixel));
+
+#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\
+ values.background=bg,\
+ XCreateGC(DISP, RootWindowOfScreen(SCRN),\
+ GCFunction|GCForeground|GCBackground, &values))
+
+ if (RESOURCE(copy) || (set_bits && clr_bits))
+ ruleGC = MakeGC(GXcopy,
+ RESOURCE(fore_Pixel), RESOURCE(back_Pixel));
+ if (RESOURCE(copy)) foreGC = ruleGC;
+ else if (!RESOURCE(thorough) && ruleGC) {
+ foreGC = ruleGC;
+ Puts("Note: overstrike characters may be incorrect.");
+ }
+ else {
+ if (set_bits) foreGC = MakeGC(GXor, set_bits, 0);
+ if (clr_bits)
+ *(foreGC ? &foreGC2 : &foreGC) =
+ MakeGC(GXandInverted, clr_bits, 0);
+ if (!ruleGC) ruleGC = foreGC;
+ }
+ }
+
+ {
+ XGCValues values;
+
+ highGC = ruleGC;
+ if (RESOURCE(high_color))
+ highGC = MakeGC(GXcopy,
+ RESOURCE(hl_Pixel), RESOURCE(back_Pixel));
+ }
+
+ if (!RESOURCE(brdr_color)) RESOURCE(brdr_Pixel) = RESOURCE(fore_Pixel);
+
+#ifndef VMS
+ ready_cursor = XCreateFontCursor(DISP, XC_cross);
+ redraw_cursor = XCreateFontCursor(DISP, XC_watch);
+#else
+ DECWCursorFont = XLoadFont(DISP, "DECW$CURSOR");
+ XSetFont(DISP, foreGC, DECWCursorFont);
+ redraw_cursor = XCreateGlyphCursor(DISP, DECWCursorFont, DECWCursorFont,
+ decw$c_wait_cursor, decw$c_wait_cursor + 1,
+ &RESOURCE(fore_color), &RESOURCE(back_color));
+ MagnifyPixmap = XCreateBitmapFromData (DISP, RootWindowOfScreen(SCRN),
+ mag_glass_bits, mag_glass_width, mag_glass_height);
+ ready_cursor = XCreatePixmapCursor(DISP, MagnifyPixmap, MagnifyPixmap,
+ &RESOURCE(back_color), &RESOURCE(fore_color),
+ mag_glass_x_hot, mag_glass_y_hot);
+#endif /* VMS */
+
+ if (!RESOURCE(curs_color))
+ RESOURCE(cr_Pixel) = RESOURCE(high_color) ? RESOURCE(hl_Pixel)
+ : RESOURCE(fore_Pixel);
+ {
+ XColor bg_Color, cr_Color;
+
+ bg_Color.pixel = RESOURCE(back_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bg_Color);
+ cr_Color.pixel = RESOURCE(cr_Pixel);
+ XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &cr_Color);
+ XRecolorCursor(DISP, ready_cursor, &cr_Color, &bg_Color);
+ XRecolorCursor(DISP, redraw_cursor, &cr_Color, &bg_Color);
+ }
+
+#ifdef TOOLKIT
+
+ /*
+ * X11 windows (toolkit)
+ */
+
+ /* The following code is lifted from Xterm */
+ if (resource.icon_geometry != NULL) {
+ int scr, junk;
+
+ for(scr = 0; /* yyuucchh */
+ SCRN != ScreenOfDisplay(DISP, scr);
+ scr++);
+
+ XGeometry(DISP, scr, resource.icon_geometry, "", 0, 0, 0, 0, 0,
+ (int *) &temp_args1[0].value,
+ (int *) &temp_args1[1].value, &junk, &junk);
+ XtSetValues(top_level, temp_args1, XtNumber(temp_args1));
+ }
+ /* Set icon pixmap */
+ XtGetValues(top_level, temp_args3, XtNumber(temp_args3));
+ if (icon_pm == (Pixmap) 0) {
+ temp_args3[0].value = (XtArgVal) (XCreateBitmapFromData(DISP,
+ RootWindowOfScreen(SCRN),
+ xdvi_bits, xdvi_width, xdvi_height));
+ XtSetValues(top_level, temp_args3, XtNumber(temp_args3));
+ }
+ temp_args4[0].value = (XtArgVal) dvi_name;
+ XtSetValues(top_level, temp_args4, XtNumber(temp_args4));
+
+#ifdef BUTTONS
+ form_widget = XtCreateManagedWidget("form", formWidgetClass,
+ top_level, form_args, XtNumber(form_args));
+
+ line_args[0].value = (XtArgVal) resource.high_color
+ ? resource.hl_Pixel : resource.fore_Pixel;
+#else /* !BUTTONS */
+#define form_widget top_level /* for calls to XtAddEventHandler */
+#endif /* BUTTONS */
+ vport_widget = XtCreateManagedWidget("vport", viewportWidgetClass,
+ form_widget, vport_args, XtNumber(vport_args));
+ clip_widget = XtNameToWidget(vport_widget, "clip");
+ draw_args[0].value = (XtArgVal) page_w;
+ draw_args[1].value = (XtArgVal) page_h;
+ draw_widget = XtCreateManagedWidget("drawing", drawWidgetClass,
+ vport_widget, draw_args, XtNumber(draw_args));
+ { /* set default window size */
+#ifdef BUTTONS
+ int xtra_wid = resource.expert ? 0 : XTRA_WID;
+#else
+#define xtra_wid 0
+#endif
+ XtWidgetGeometry constraints;
+ XtWidgetGeometry reply;
+
+ XtGetValues(top_level, &temp_args2, 1); /* get border width */
+ screen_w = WidthOfScreen(SCRN) - 2 * bwidth - xtra_wid;
+ screen_h = HeightOfScreen(SCRN) - 2 * bwidth;
+ constraints.request_mode = reply.request_mode = 0;
+ constraints.width = page_w;
+ if (page_w > screen_w) {
+ constraints.request_mode = CWWidth;
+ constraints.width = screen_w;
+ }
+ constraints.height = page_h;
+ if (page_h > screen_h) {
+ constraints.request_mode = CWHeight;
+ constraints.height = screen_h;
+ }
+ if (constraints.request_mode != 0
+ && constraints.request_mode != (CWWidth | CWHeight))
+ (void) XtQueryGeometry(vport_widget, &constraints, &reply);
+ if (!(reply.request_mode & CWWidth))
+ reply.width = constraints.width;
+ set_wh_args[0].value = (XtArgVal) ((reply.width < screen_w
+ ? reply.width : screen_w) + xtra_wid);
+ if (!(reply.request_mode & CWHeight))
+ reply.height = constraints.height;
+ set_wh_args[1].value = (XtArgVal) (reply.height < screen_h
+ ? reply.height : screen_h);
+ XtSetValues(top_level, set_wh_args, XtNumber(set_wh_args));
+#ifdef BUTTONS
+ set_wh_args[0].value -= xtra_wid;
+ XtSetValues(vport_widget, set_wh_args, XtNumber(set_wh_args));
+ if (!resource.expert) create_buttons(set_wh_args[1].value);
+#endif /* BUTTONS */
+ }
+ if (resource.fore_color) {
+ static Arg fore_args = {XtNforeground, (XtArgVal) 0};
+
+ fore_args.value = resource.fore_Pixel;
+ XtSetValues(draw_widget, &fore_args, 1);
+ }
+ if (resource.back_color) {
+ static Arg back_args = {XtNbackground, (XtArgVal) 0};
+
+ back_args.value = resource.back_Pixel;
+ XtSetValues(draw_widget, &back_args, 1);
+ XtSetValues(clip_widget, &back_args, 1);
+ }
+ XtAddEventHandler(form_widget, KeyPressMask, False, handle_key,
+ (caddr_t) NULL);
+ XtAddEventHandler(vport_widget, StructureNotifyMask, False,
+ handle_resize, (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ExposureMask, False, handle_exp,
+ (caddr_t) &mane);
+ XtAddEventHandler(draw_widget, ButtonPressMask, False, handle_button,
+ (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ButtonMotionMask, False, handle_motion,
+ (caddr_t) NULL);
+ XtAddEventHandler(draw_widget, ButtonReleaseMask, False, handle_release,
+ (caddr_t) NULL);
+ XtRealizeWidget(top_level);
+
+ currwin.win = mane.win = XtWindow(draw_widget);
+
+#else /* !TOOLKIT */
+
+ /*
+ * X11 windows (non toolkit)
+ */
+
+ screen_w = WidthOfScreen(SCRN) - 2*bwidth;
+ screen_h = HeightOfScreen(SCRN) - 2*bwidth;
+ size_hints.flags = PMinSize;
+ size_hints.min_width = size_hints.min_height = 50;
+ size_hints.x = size_hints.y = 0;
+ if (geometry != NULL) {
+ int flag = XParseGeometry(geometry, &size_hints.x, &size_hints.y,
+ &window_w, &window_h);
+
+ if (flag & (XValue | YValue))
+ size_hints.flags |= USPosition;
+ if (flag & (WidthValue | HeightValue))
+ size_hints.flags |= USSize;
+ if (flag & XNegative) size_hints.x += screen_w - window_w;
+ if (flag & YNegative) size_hints.y += screen_h - window_h;
+ }
+ if (!(size_hints.flags & USSize)) {
+ int x_thick = 0;
+ int y_thick = 0;
+ if (screen_w < page_w) x_thick = BAR_THICK;
+ if (screen_h < page_h + x_thick) y_thick = BAR_THICK;
+ window_w = page_w + y_thick;
+ if (window_w > screen_w) {
+ x_thick = BAR_THICK;
+ window_w = screen_w;
+ }
+ window_h = page_h + x_thick;
+ if (window_h > screen_h) window_h = screen_h;
+ size_hints.flags |= PSize;
+ }
+ size_hints.width = window_w;
+ size_hints.height = window_h;
+ top_level = XCreateSimpleWindow(DISP, RootWindowOfScreen(SCRN),
+ size_hints.x, size_hints.y, window_w, window_h, bwidth,
+ brdr_Pixel, back_Pixel);
+ XSetStandardProperties(DISP, top_level, dvi_name, prog, NULL,
+ argv, argc, &size_hints);
+
+ wmhints.flags = InputHint | StateHint | IconPixmapHint;
+ wmhints.input = True; /* window manager must direct input */
+ wmhints.initial_state = iconic ? IconicState : NormalState;
+ wmhints.icon_pixmap = XCreateBitmapFromData(DISP,
+ RootWindowOfScreen(SCRN),
+ xdvi_bits, xdvi_width, xdvi_height);
+ if (icon_geometry != NULL) {
+ int junk;
+
+ wmhints.flags |= IconPositionHint;
+ XGeometry(DISP, DefaultScreen(DISP), icon_geometry, "",
+ 0, 0, 0, 0, 0, &wmhints.icon_x, &wmhints.icon_y, &junk, &junk);
+ }
+ XSetWMHints(DISP, top_level, &wmhints);
+
+ XSelectInput(DISP, top_level, KeyPressMask | StructureNotifyMask);
+ XMapWindow(DISP, top_level);
+ Flush();
+
+#endif /* TOOLKIT */
+
+ XRebindKeysym(DISP, XK_Home, NULL, 0, (_Xconst ubyte *) "^", 1);
+ XRebindKeysym(DISP, XK_Left, NULL, 0, (_Xconst ubyte *) "l", 1);
+ XRebindKeysym(DISP, XK_Up, NULL, 0, (_Xconst ubyte *) "u", 1);
+ XRebindKeysym(DISP, XK_Right, NULL, 0, (_Xconst ubyte *) "r", 1);
+ XRebindKeysym(DISP, XK_Down, NULL, 0, (_Xconst ubyte *) "d", 1);
+ XRebindKeysym(DISP, XK_Prior, NULL, 0, (_Xconst ubyte *) "b", 1);
+ XRebindKeysym(DISP, XK_Next, NULL, 0, (_Xconst ubyte *) "f", 1);
+
+ image = XCreateImage(DISP, DefaultVisualOfScreen(SCRN), 1, XYBitmap, 0,
+ (char *)NULL, 0, 0, BITS_PER_BMUNIT, 0);
+ image->bitmap_unit = BITS_PER_BMUNIT;
+#ifndef MSBITFIRST
+ image->bitmap_bit_order = LSBFirst;
+#else
+ image->bitmap_bit_order = MSBFirst;
+#endif
+ {
+ short endian = MSBFirst << 8 | LSBFirst;
+ image->byte_order = *((char *) &endian);
+ }
+
+#else /* X10 */
+
+ /*
+ * X10 colors
+ */
+
+ if (reverse) {
+ foreGC = WhitePixel;
+ highGC = WhitePixel;
+ backpix = BlackPixel;
+ backmap = BlackPixmap;
+ bdrmap = WhitePixmap;
+ mouspix = WhitePixel;
+ GXfunc = GXor;
+ } else {
+ foreGC = BlackPixel;
+ highGC = BlackPixel;
+ backpix = WhitePixel;
+ backmap = WhitePixmap;
+ bdrmap = BlackPixmap;
+ mouspix = BlackPixel;
+ GXfunc = GXand;
+ }
+ if (DisplayCells() > 2) {
+ if (fore_color && XParseColor(fore_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ foreGC = cdef.pixel;
+ if (back_color && XParseColor(back_color, &cdef) &&
+ XGetHardwareColor(&cdef)) {
+ backpix = cdef.pixel;
+ backmap = XMakeTile(backpix);
+ }
+ if (brdr_color && XParseColor(brdr_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ bdrmap = XMakeTile(cdef.pixel);
+ if (high_color && XParseColor(high_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ highGC = cdef.pixel;
+ if (curs_color && XParseColor(curs_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ mouspix = cdef.pixel;
+ }
+
+ /*
+ * X10 windows
+ */
+
+ frame.bdrwidth = bwidth;
+ screen_w = DisplayWidth() - 2*bwidth;
+ screen_h = DisplayHeight() - 2*bwidth;
+ x_thick = y_thick = 0;
+ if (screen_w < page_w) x_thick = BAR_THICK;
+ if (screen_h < page_h + x_thick) y_thick = BAR_THICK;
+ frame.width = page_w + y_thick;
+ if (frame.width > screen_w) {
+ x_thick = BAR_THICK;
+ frame.width = screen_w;
+ }
+ frame.height = page_h + x_thick;
+ if (frame.height > screen_h) frame.height = screen_h;
+ frame.border = bdrmap;
+ frame.background = backmap;
+ frame.x = 0;
+ frame.y = 0;
+ Sprintf(def, "=%dx%d+0+0", frame.width, frame.height);
+ top_level = XCreate("DVI Previewer", prog, geometry, def,
+ &frame, 50, 50);
+ XSelectInput(top_level, ExposeWindow | KeyPressed);
+ XMapWindow(top_level);
+ XDefineCursor(top_level,
+ XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_mask_bits,
+ xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy));
+#endif /* X10 */
+
+ do_pages();
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+#if defined(__MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* close the font substitute file */
+ fclose (fontsubfile);
+ }
+
+#endif
+/* ----------------------------- MSDOS (Eric Ho) ----------------------------*/
+ return 0; /* do_pages() returns if DBG_BATCH is specified */
+}
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.h b/systems/msdos/dviware/xdvi-dos/src/xdvi.h
new file mode 100644
index 0000000000..2c0da4def9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.h
@@ -0,0 +1,509 @@
+/*
+ * Written by Eric C. Cooper, CMU
+ */
+
+/********************************
+ * The C environment *
+ *******************************/
+
+#ifndef X10
+#include <X11/Xlib.h> /* include Xfuncs.h, if available */
+#include <X11/Xutil.h> /* needed for XDestroyImage */
+#include <X11/Xos.h> /* same as below */
+#else /* X10 */
+#include <X/Xlib.h> /* get type of Window */
+#include <sys/types.h> /* for sites without X11 */
+#ifdef SYSV
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#include <fcntl.h>
+#else /* SYSV */
+#include <strings.h>
+#endif /* SYSV */
+#include <sys/file.h>
+#endif /* X10 */
+
+#ifndef XlibSpecificationRelease
+#define XlibSpecificationRelease 0
+#endif
+
+#if XlibSpecificationRelease >= 5
+#include <X11/Xfuncs.h>
+#endif
+
+#ifdef VMS
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#define bzero(a, b) (void) memset ((void *) (a), 0, (size_t) (b))
+#define bcopy(a, b, c) (void) memmove ((void *) (b), (void *) (a), (size_t) (c))
+#endif
+
+#include <stdio.h>
+#include <setjmp.h>
+
+#ifndef OPEN_MODE
+#ifndef VMS
+#define OPEN_MODE "rb"
+#else /* VMS */
+#define OPEN_MODE "r", "ctx=stm"
+#endif /* VMS */
+#endif /* OPEN_MODE */
+
+#ifndef SYSV
+#ifndef VMS
+#define HAS_SIGIO /* has SIGIO on _sockets_ */
+#endif
+#endif
+
+#ifndef NeedFunctionPrototypes
+#ifdef __STDC__
+#define NeedFunctionPrototypes 1
+#else /* STDC */
+#define NeedFunctionPrototypes 0
+#endif /* STDC */
+#endif /* NeedFunctionPrototypes */
+
+#ifndef NeedWidePrototypes
+#define NeedWidePrototypes NeedFunctionPrototypes
+#endif
+
+#if NeedWidePrototypes
+#define WIDEARG(a, b) b
+#else
+#define WIDEARG(a, b) a
+#endif
+
+#ifndef NeedVarargsPrototypes
+#define NeedVarargsPrototypes NeedFunctionPrototypes
+#endif
+
+#ifndef _XFUNCPROTOBEGIN
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#endif
+
+#ifndef _Xconst
+#ifdef __STDC__
+#define _Xconst const
+#else /* STDC */
+#define _Xconst
+#endif /* STDC */
+#endif /* _Xconst */
+
+#ifndef VOLATILE
+#if defined(__STDC__) || (defined(__stdc__) && defined(__convex__))
+#define VOLATILE volatile
+#else
+#define VOLATILE /* nothing */
+#endif
+#endif
+
+#ifndef NORETURN
+#ifdef __GNUC__
+#define NORETURN volatile
+#else
+#define NORETURN /* nothing */
+#endif
+#endif
+
+#define Printf (void) printf
+#define Puts (void) puts
+#define Fprintf (void) fprintf
+#define Sprintf (void) sprintf
+#define Fseek (void) fseek
+#define Fread (void) fread
+#define Fputs (void) fputs
+#define Putc (void) putc
+#define Putchar (void) putchar
+#define Fclose (void) fclose
+#define Strcpy (void) strcpy
+
+/********************************
+ * Types and data *
+ *******************************/
+
+#ifndef EXTERN
+#define EXTERN extern
+#define INIT(x)
+#define NTINIT(x)
+#endif
+
+typedef unsigned char ubyte;
+#define Boolean char
+#define True 1
+#define False 0
+
+#define MAXDIM 32767
+
+/*
+ * pixel_conv is currently used only for converting absolute positions
+ * to pixel values; although normally it should be
+ * ((int) ((x) / shrink_factor + (1 << 15) >> 16)),
+ * the rounding is achieved instead by moving the constant 1 << 15 to
+ * PAGE_OFFSET in dvi_draw.c.
+ */
+#define pixel_conv(x) ((int) ((x) / shrink_factor >> 16))
+#define pixel_round(x) ((int) ROUNDUP(x, shrink_factor << 16))
+#define spell_conv0(n, f) ((long) (n * f))
+#define spell_conv(n) spell_conv0(n, dimconv)
+
+#ifdef X10
+#undef MSBITFIRST
+#undef BMLONG
+#define BMSHORT
+#endif
+
+#ifdef BMLONG
+#define BMUNIT unsigned long
+#define BITS_PER_BMUNIT 32
+#define BYTES_PER_BMUNIT 4
+#else /* BMLONG */
+#ifdef BMSHORT
+#define BMUNIT unsigned short
+#define BITS_PER_BMUNIT 16
+#define BYTES_PER_BMUNIT 2
+#else /* BMSHORT */
+#define BMUNIT unsigned char
+#define BITS_PER_BMUNIT 8
+#define BYTES_PER_BMUNIT 1
+#endif /* BMSHORT */
+#endif /* BMLONG */
+
+#define ADD(a, b) ((BMUNIT *) (((char *) a) + b))
+#define SUB(a, b) ((BMUNIT *) (((char *) a) - b))
+
+extern BMUNIT bit_masks[BITS_PER_BMUNIT + 1];
+
+struct frame {
+ struct framedata {
+ long dvi_h, dvi_v, w, x, y, z;
+ int pxl_v;
+ } data;
+ struct frame *next, *prev;
+};
+
+#if NeedFunctionPrototypes
+#ifndef TEXXET
+typedef long (*set_char_proc)(WIDEARG(ubyte, int));
+#else /* TEXXET */
+typedef void (*set_char_proc)(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+#endif /* TEXXET */
+#else /* NeedFunctionPrototypes */
+#ifndef TEXXET
+typedef long (*set_char_proc)();
+#else /* TEXXET */
+typedef void (*set_char_proc)();
+#endif /* TEXXET */
+#endif /* NeedFunctionPrototypes */
+
+struct drawinf { /* this information is saved when using virtual fonts */
+ struct framedata data;
+ struct font *fontp;
+ set_char_proc set_char_p;
+ struct tn *tn_head;
+ ubyte *pos, *end;
+ struct font *virtual;
+#ifdef TEXXET
+ int dir;
+#endif
+};
+
+EXTERN struct drawinf currinf;
+
+/* entries below with the characters 'dvi' in them are actually stored in
+ scaled pixel units */
+
+#define DVI_H currinf.data.dvi_h
+#define PXL_H pixel_conv(currinf.data.dvi_h)
+#define DVI_V currinf.data.dvi_v
+#define PXL_V currinf.data.pxl_v
+#define WW currinf.data.w
+#define XX currinf.data.x
+#define YY currinf.data.y
+#define ZZ currinf.data.z
+#define ROUNDUP(x,y) (((x)+(y)-1)/(y))
+
+EXTERN int current_page;
+EXTERN int total_pages;
+EXTERN double dimconv;
+EXTERN int n_files_left INIT(32767); /* for LRU closing of fonts */
+EXTERN time_t dvi_time; /* last mod. time for dvi file */
+EXTERN int page_w, page_h;
+
+/*
+ * Table of page offsets in DVI file, indexed by page number - 1.
+ * Initialized in prepare_pages().
+ */
+EXTERN long *page_offset;
+
+/*
+ * Mechanism for reducing repeated warning about specials, lost characters, etc.
+ */
+EXTERN Boolean hush_spec NTINIT(False);
+EXTERN Boolean hush_spec_now;
+EXTERN Boolean hush_chars NTINIT(False);
+
+
+/*
+ * Bitmap structure for raster ops.
+ */
+struct bitmap {
+ short w, h; /* width and height in pixels */
+ short bytes_wide; /* scan-line width in bytes */
+ char *bits; /* pointer to the bits */
+};
+
+/*
+ * Per-character information.
+ * There is one of these for each character in a font (raster fonts only).
+ * All fields are filled in at font definition time,
+ * except for the bitmap, which is "faulted in"
+ * when the character is first referenced.
+ */
+struct glyph {
+ long addr; /* address of bitmap in font file */
+ long dvi_adv; /* DVI units to move reference point */
+ short x, y; /* x and y offset in pixels */
+ struct bitmap bitmap; /* bitmap for character */
+ short x2, y2; /* x and y offset in pixels (shrunken bitmap) */
+#ifdef GREY
+ XImage *image2;
+ char *pixmap2;
+#endif
+ struct bitmap bitmap2; /* shrunken bitmap for character */
+};
+
+/*
+ * Per character information for virtual fonts
+ */
+struct macro {
+ ubyte *pos; /* address of first byte of macro */
+ ubyte *end; /* address of last+1 byte */
+ long dvi_adv; /* DVI units to move reference point */
+ Boolean free_me; /* if free(pos) should be called when */
+ /* freeing space */
+};
+
+/*
+ * The layout of a font information block.
+ * There is one of these for every loaded font or magnification thereof.
+ * Duplicates are eliminated: this is necessary because of possible recursion
+ * in virtual fonts.
+ *
+ * Also note the strange units. The design size is in 1/2^20 point
+ * units (also called micro-points), and the individual character widths
+ * are in the TFM file in 1/2^20 ems units, i.e., relative to the design size.
+ *
+ * We then change the sizes to SPELL units (unshrunk pixel / 2^16).
+ */
+
+#define NOMAGSTP (-29999)
+
+#if NeedFunctionPrototypes
+typedef void (*read_char_proc)(struct font *, WIDEARG(ubyte, int));
+#else
+typedef void (*read_char_proc)();
+#endif
+
+struct font {
+ struct font *next; /* link to next font info block */
+ char *fontname; /* name of font */
+ float fsize; /* size information (dots per inch) */
+ int magstepval; /* magstep number * two, or NOMAGSTP */
+ FILE *file; /* open font file or NULL */
+ char *filename; /* name of font file */
+ unsigned short timestamp; /* for LRU management of fonts */
+ ubyte flags; /* flags byte (see values below) */
+ ubyte maxchar; /* largest character code */
+ double dimconv; /* size conversion factor */
+ set_char_proc set_char_p; /* proc used to set char */
+ /* these fields are used by (loaded) raster fonts */
+ read_char_proc read_char; /* function to read bitmap */
+ struct glyph *glyph;
+ /* these fields are used by (loaded) virtual fonts */
+ struct tn *vf_chain; /* list of fonts used by this vf */
+ struct font *first_font; /* first font defined */
+ struct macro *macro;
+ /* I suppose the above could be put into a union, but we */
+ /* wouldn't save all that much space. */
+};
+
+#define FONT_IN_USE 1 /* used for housekeeping */
+#define FONT_LOADED 2 /* if font file has been read */
+#define FONT_VIRTUAL 4 /* if font is virtual */
+
+struct tn {
+ struct tn *next; /* link to next TeXnumber info block */
+ int TeXnumber; /* font number (in DVI file) */
+ struct font *fontp; /* pointer to the rest of the info */
+};
+
+EXTERN struct font *font_head INIT(NULL);
+EXTERN struct tn *tn_head INIT(NULL);
+EXTERN ubyte maxchar;
+EXTERN unsigned short current_timestamp INIT(0);
+
+/*
+ * Command line flags.
+ */
+
+EXTERN int debug INIT(0);
+
+#define DBG_BITMAP 0x1
+#define DBG_DVI 0x2
+#define DBG_PK 0x4
+#define DBG_BATCH 0x8
+#define DBG_EVENT 0x10
+#define DBG_OPEN 0x20
+#define DBG_ALL (DBG_BITMAP|DBG_DVI|DBG_PK|DBG_EVENT|DBG_OPEN)
+
+EXTERN Boolean list_fonts NTINIT(False);
+
+#ifndef BDPI
+#define BDPI 300
+#endif
+
+EXTERN int pixels_per_inch NTINIT(BDPI);
+EXTERN int offset_x, offset_y;
+EXTERN int unshrunk_paper_w, unshrunk_paper_h;
+EXTERN int unshrunk_page_w, unshrunk_page_h;
+EXTERN int density NTINIT(40);
+EXTERN double specialConv;
+
+EXTERN char *dvi_name INIT(NULL);
+EXTERN FILE *dvi_file; /* user's file */
+EXTERN _Xconst char *alt_font NTINIT(ALTFONT);
+EXTERN char *prog;
+
+struct WindowRec {
+ Window win;
+ int shrinkfactor;
+ int base_x, base_y;
+ int width, height;
+ int min_x, max_x, min_y, max_y; /* for pending expose events */
+};
+
+extern struct WindowRec mane, alt, currwin;
+
+#define WINDOW(wr) ((Window) (wr).win)
+#define shrink_factor currwin.shrinkfactor
+
+EXTERN jmp_buf dvi_env; /* mechanism to communicate dvi file errors */
+
+#ifdef GREY
+#ifndef X10
+EXTERN Display *DISP;
+EXTERN Screen *SCRN;
+EXTERN unsigned long palette[17];
+EXTERN unsigned long *pixeltbl;
+EXTERN Boolean use_grey NTINIT(True);
+#else /* Sorry - GREY works only with X11 */
+#undef GREY
+#endif /* X10 */
+#endif /* GREY */
+
+/********************************
+ * Procedures *
+ *******************************/
+
+_XFUNCPROTOBEGIN
+#if NeedFunctionPrototypes
+
+extern void line_btw(int, int, int, int);
+extern void dot_at(int, int);
+extern void do_attribute_path(int, int, int, int);
+extern void put_bitmap(struct bitmap *, int, int);
+#ifdef GREY
+extern void put_image(XImage *, int, int);
+#endif
+extern void put_rectangle(int, int, int, int, WIDEARG(Boolean, int));
+extern void redraw_page(void);
+#if NeedVarargsPrototypes
+extern NORETURN void oops(_Xconst char *, ...);
+#else
+extern NORETURN void oops();
+#endif
+extern char *xmalloc(unsigned, _Xconst char *);
+extern void alloc_bitmap(struct bitmap *);
+extern FILE *xfopen(_Xconst char *);
+extern unsigned long num(FILE *, int);
+extern long snum(FILE *, int);
+extern void reset_fonts(void);
+extern void realloc_font(struct font *, WIDEARG(ubyte, int));
+extern void realloc_virtual_font(struct font *, WIDEARG(ubyte, int));
+extern void load_font(struct font *);
+extern void define_font(FILE *, WIDEARG(ubyte, unsigned int), struct font *,
+ struct tn **);
+extern void init_page(void);
+extern void open_dvi_file(void);
+extern Boolean check_dvi_file(void);
+#ifndef TEXXET
+extern long set_char(WIDEARG(ubyte, int));
+extern long set_vf_char(WIDEARG(ubyte, int));
+#else
+extern void set_char(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+extern void set_vf_char(WIDEARG(ubyte, int), WIDEARG(ubyte, int));
+#endif
+extern void draw_page(void);
+extern void init_font_open(void);
+extern FILE *font_open(_Xconst char *, char **,
+ WIDEARG(float, double), int *, int, char **);
+extern void applicationDoSpecial(char *);
+extern void read_PK_index(struct font *);
+extern void read_GF_index(struct font *);
+extern void read_PXL_index(struct font *);
+extern void read_VF_index(struct font *);
+
+#else /* ! NeedFunctionPrototypes */
+
+extern void line_btw();
+extern void dot_at();
+extern void do_attribute_path();
+extern void put_bitmap();
+#ifdef GREY
+extern void put_image();
+#endif
+extern void put_rectangle();
+extern void redraw_page();
+extern NORETURN void oops();
+extern char *xmalloc();
+extern void alloc_bitmap();
+extern FILE *xfopen();
+extern unsigned long num();
+extern long snum();
+extern void reset_fonts();
+extern void realloc_font();
+extern void realloc_virtual_font();
+extern void load_font();
+extern void define_font();
+extern void init_page();
+extern void open_dvi_file();
+extern Boolean check_dvi_file();
+#ifndef TEXXET
+extern long set_char();
+extern long set_vf_char();
+#else
+extern void set_char();
+extern void set_vf_char();
+#endif
+extern void draw_page();
+extern void init_font_open();
+extern FILE *font_open();
+extern void applicationDoSpecial();
+extern void read_PK_index();
+extern void read_GF_index();
+extern void read_PXL_index();
+extern void read_VF_index();
+
+#endif /* NeedFunctionPrototypes */
+
+#define one(fp) ((unsigned char) getc(fp))
+#define sone(fp) ((long) one(fp))
+#define two(fp) num (fp, 2)
+#define stwo(fp) snum(fp, 2)
+#define four(fp) num (fp, 4)
+#define sfour(fp) snum(fp, 4)
+
+_XFUNCPROTOEND
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi.ico b/systems/msdos/dviware/xdvi-dos/src/xdvi.ico
new file mode 100644
index 0000000000..e98aeff206
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi.ico
@@ -0,0 +1,27 @@
+#define xdvi_width 48
+#define xdvi_height 48
+static char xdvi_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa2, 0xe0, 0x44, 0x38, 0x95, 0x13,
+ 0x9e, 0x17, 0x45, 0x45, 0x55, 0xf4, 0x82, 0xf0, 0x28, 0x3d, 0xd5, 0x13,
+ 0x82, 0x10, 0x28, 0x05, 0x55, 0x10, 0x82, 0xe0, 0x10, 0x39, 0x8a, 0x13,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x1f, 0x00,
+ 0x79, 0x18, 0x18, 0x13, 0x16, 0x00, 0x69, 0x10, 0x18, 0x0e, 0x16, 0x00,
+ 0xcf, 0x20, 0x1c, 0x0e, 0xd6, 0x00, 0xe9, 0xc3, 0x7b, 0x84, 0x3f, 0x01,
+ 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x70, 0xcc,
+ 0x08, 0x00, 0x00, 0x00, 0x30, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x30, 0x52,
+ 0x0a, 0xc0, 0xff, 0x03, 0x30, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0xc0, 0xff, 0x03, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x17,
+ 0x0b, 0x0c, 0x3c, 0xc0, 0x93, 0x20, 0x0c, 0x0e, 0x43, 0x20, 0x96, 0x40,
+ 0x0c, 0x8e, 0x81, 0x10, 0x96, 0xbe, 0x0a, 0x8d, 0x81, 0x19, 0x90, 0x82,
+ 0x8a, 0x8c, 0x81, 0x0d, 0x90, 0x42, 0x48, 0x8c, 0x81, 0xed, 0x91, 0x3e,
+ 0x6a, 0x0c, 0xc3, 0x1d, 0x96, 0x12, 0x38, 0x0c, 0xbc, 0x0d, 0x1c, 0x02,
+ 0xf8, 0x3f, 0x80, 0x0d, 0x1c, 0x3e, 0x0b, 0x0c, 0x80, 0x0c, 0x1c, 0x00,
+ 0x0b, 0x0c, 0xc3, 0x18, 0x1c, 0x00, 0x0a, 0x0c, 0x63, 0x10, 0x16, 0x00,
+ 0x89, 0x3f, 0x1e, 0xe0, 0x11, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x1f, 0xae, 0x0f, 0x00, 0x80, 0x84, 0x0a, 0xae,
+ 0x87, 0x64, 0x86, 0x84, 0x08, 0x42, 0x42, 0x45, 0xe2, 0x1c, 0x07, 0x42};
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h b/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h
new file mode 100644
index 0000000000..a4083669b9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi_cur.h
@@ -0,0 +1,9 @@
+#define xdvi_width 15
+#define xdvi_height 15
+#define xdvi_x_hot 7
+#define xdvi_y_hot 7
+static short xdvi_bits[] = {
+ 0x0080, 0x01c0, 0x03e0, 0x06b0,
+ 0x0c98, 0x188c, 0x3086, 0x7fff,
+ 0x3086, 0x188c, 0x0c98, 0x06b0,
+ 0x03e0, 0x01c0, 0x0080};
diff --git a/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h b/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h
new file mode 100644
index 0000000000..ab2f850b12
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/xdvi_mas.h
@@ -0,0 +1,7 @@
+#define xdvi_mask_width 15
+#define xdvi_mask_height 15
+static short xdvi_mask_bits[] = {
+ 0x01c0, 0x03e0, 0x07f0, 0x0ff8,
+ 0x1ffc, 0x3ffe, 0x7fff, 0x7fff,
+ 0x7fff, 0x3ffe, 0x1ffc, 0x0ff8,
+ 0x07f0, 0x03e0, 0x01c0};
diff --git a/systems/msdos/dviware/xdvi-dos/texfonts.sub b/systems/msdos/dviware/xdvi-dos/texfonts.sub
new file mode 100644
index 0000000000..6d1a09caed
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/texfonts.sub
@@ -0,0 +1,74 @@
+amb10 -> cmb10
+ambsy10 -> cmbsy10
+ambx10 -> cmbx10
+ambx12 -> cmbx12
+ambx5 -> cmbx5
+ambx6 -> cmbx6
+ambx7 -> cmbx7
+ambx8 -> cmbx8
+ambx9 -> cmbx9
+ambxsl10 -> cmbxsl10
+ambxti10 -> cmbxti10
+amcsc10 -> cmcsc10
+amdunh10 -> cmdunh10
+amex10 -> cmex10
+amff10 -> cmff10
+amfib8 -> cmfib8
+aminch -> cminch
+amitt10 -> cmitt10
+ammi10 -> cmmi10
+ammi12 -> cmmi12
+ammi5 -> cmmi5
+ammi6 -> cmmi6
+ammi7 -> cmmi7
+ammi8 -> cmmi8
+ammi9 -> cmmi9
+ammib10 -> cmmib10
+amr10 -> cmr10
+amr12 -> cmr12
+amr17 -> cmr17
+amr5 -> cmr5
+amr6 -> cmr6
+amr7 -> cmr7
+amr8 -> cmr8
+amr9 -> cmr9
+amsl10 -> cmsl10
+amsl12 -> cmsl12
+amsl8 -> cmsl8
+amsl9 -> cmsl9
+amsltt10 -> cmsltt10
+amss10 -> cmss10
+amss12 -> cmss12
+amss17 -> cmss17
+amss8 -> cmss8
+amss9 -> cmss9
+amssbx10 -> cmssbx10
+amssdc10 -> cmssdc10
+amssi10 -> cmssi10
+amssi12 -> cmssi12
+amssi17 -> cmssi17
+amssi8 -> cmssi8
+amssi9 -> cmssi9
+amssq8 -> cmssq8
+amssqi8 -> cmssqi8
+amsy10 -> cmsy10
+amsy5 -> cmsy5
+amsy6 -> cmsy6
+amsy7 -> cmsy7
+amsy8 -> cmsy8
+amsy9 -> cmsy9
+amtcsc10 -> cmtcsc10
+amtex10 -> cmtex10
+amtex8 -> cmtex8
+amtex9 -> cmtex9
+amti10 -> cmti10
+amti12 -> cmti12
+amti7 -> cmti7
+amti8 -> cmti8
+amti9 -> cmti9
+amtt10 -> cmtt10
+amtt12 -> cmtt12
+amtt8 -> cmtt8
+amtt9 -> cmtt9
+amu10 -> cmu10
+amvtt10 -> cmvtt10
diff --git a/systems/msdos/dviware/xdvi-dos/xdvi.man b/systems/msdos/dviware/xdvi-dos/xdvi.man
new file mode 100644
index 0000000000..a60ddbdc09
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/xdvi.man
@@ -0,0 +1,396 @@
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+NAME
+ xdvi - DVI Previewer for the X Window System
+
+SYNOPSIS
+ xdvi [+[page]] [-s shrink] [-S density] [-p pixels]
+ [-altfont font] [-l] [-rv] [-fg color] [-bg color] [-hl
+ color] [-bd color] [-cr color] [-thorough] [-margins inches]
+ [-sidemargin inches] [-topmargin inches] [-mgs[n] size]
+ [-geometry geometry | =geometry] [%geometry] [-display
+ display] file
+
+DESCRIPTION
+ Xdvi is a program which runs under the X window system. It
+ is used to preview DVI files, such as are produced by TeX.
+
+ This program has the capability of showing the file shrunken
+ by various (integer) factors, and also has a ``magnifying
+ glass'' which allows one to see a small part of the unshrunk
+ image momentarily.
+
+ Also, before displaying any page or part thereof, it checks
+ to see if the dvi file has changed since the last time it
+ was displayed. If this is the case, then xdvi will reini-
+ tialize itself for the new dvi file. For this reason, ex-
+ posing parts of the xdvi window while TeX is running should
+ be avoided. This feature allows you to preview many ver-
+ sions of the same file while running xdvi only once.
+
+OPTIONS
+ In addition to specifying the .dvi file (with or without the
+ .dvi), Xdvi supports the following command line options. If
+ the option begins with a `+' instead of a `-', the option is
+ restored to its default value. By default, these options
+ can be set via the resource names given in parentheses in
+ the description of each option.
+
+ +page
+ Specifies the first page to show. If + is given
+ without a number, the last page is assumed; the first
+ page is the default.
+
+ -s shrink
+ (.shrinkFactor) Defines the initial shrink factor. The
+ default value is 3.
+
+ -S density
+ (.densityPercent) Determines the density used when
+ shrinking bitmaps for fonts. A higher value produces a
+ lighter font. The default value is 40.
+
+ -p pixels
+ (.pixelsPerInch) Defines the size of the fonts to use,
+
+
+
+X Version 11 Last change: 8 May 1989 1
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ in pixels per inch. The default value is 300.
+
+ -altfont font
+ (.altFont) Declares a default font to use when the font
+ in the dvi file cannot be found. This is useful, for
+ example, with PostScript <tm> fonts.
+
+ -l (.listFonts) Causes the names of the fonts used to be
+ listed.
+
+ -rv (.reverseVideo) Causes the page to be displayed with
+ white characters on a black background, instead of vice
+ versa.
+
+ -bw width
+ (.borderWidth) Specifies the width of the border of the
+ window.
+
+ -borderwidth width
+ Same as -bw, above.
+
+ -fg color
+ (.foreground) Determines the color of the text (fore-
+ ground).
+
+ -foreground color
+ Same as -fg, above.
+
+ -bg color
+ (.background) Determines the color of the background.
+
+ -background color
+ Same as -bg, above.
+
+ -hl color
+ (.highlight) Determines the color of the page border.
+
+ -bd color
+ (.borderColor) Determines the color of the window bord-
+ er.
+
+ -cr color
+ (.cursorColor) Determines the color of the cursor. The
+ default is the foreground color.
+
+ -thorough
+ (.thorough) Xdvi will usually try to ensure that over-
+ strike characters (e.g. \notin) are printed correctly.
+ On monochrome displays, this is always possible with
+ one logical operation, either and or or. On color
+ displays, however, this may take two operations, one to
+ set the appropriate bits and one to clear other bits.
+
+
+
+X Version 11 Last change: 8 May 1989 2
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ If this is the case, then by default xdvi will instead
+ use the copy operation, which does not handle over-
+ striking correctly. The ``thorough'' option chooses
+ the slower but more correct choice.
+
+ -margins inches
+ (.margins) Specifies the size of both the top margin
+ and side margin. This can be a decimal number, e.g.,
+ 1.5. It determines the ``home'' position of the page
+ within the window as follows. If the entire page fits
+ in the window, then the margin settings are ignored.
+ If, even after removing the margins from the left,
+ right, top, and bottom, the page still cannot fit in
+ the window, then the page is put in the window such
+ that the top and left margins are hidden, and presum-
+ ably the upper left-hand corner of the text on the page
+ will be in the upper left-hand corner of the window.
+ Otherwise, the text is centered in the window. See
+ also `H' under the KEYSTROKES section.
+
+ -sidemargin inches
+ (.sideMargin) Specifies the side margin (see above).
+
+ -topmargin inches
+ (.topMargin) Specifies the top and bottom margins (see
+ above).
+
+ -mgs[n] size
+ (.magnifierSize[n]) Specifies the size of the window to
+ be used for the ``magnifying glass'' for Button n. See
+ the MOUSE ACTIONS section. Defaults are 200, 350, 600,
+ 900, and 1200.
+
+ -mgs size
+ Same as -mgs1, above.
+
+ =geometry
+ (*geometry) Specifies the initial geometry of the win-
+ dow.
+
+ -geometry geometry
+ Same as above.
+
+ #geometry
+ (.iconGeometry) Specifies the initial position for the
+ icon.
+
+ -display host:display
+ Specifies the host and screen to be used for displaying
+ the dvi file. This is normally obtained from the en-
+ vironment variable ``DISPLAY.''
+
+
+
+
+X Version 11 Last change: 8 May 1989 3
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+KEYSTROKES
+ Xdvi recognizes the following keystrokes when typed in its
+ window. Each may optionally be preceded by a (positive or
+ negative) number, whose interpretation will depend on the
+ particular keystroke.
+
+ q Quits the program. Control-C and control-D will do
+ this, too.
+
+ n Moves to the next page (or to the nth next page if a
+ number is given). Synonyms are `f', Space, Return, and
+ Line Feed.
+
+ p Moves to the previous page (or back n pages). Synonyms
+ are `b', control-H, and Delete.
+
+ g Moves to the page with the given number. Initially,
+ the first page is assumed to be page number 1, but this
+ can be changed with the `P' keystroke, below. If no
+ page number is given, then it goes to the last page.
+
+ P ``This is page number n.'' This can be used to make
+ the `g' keystroke refer to actual page numbers instead
+ of absolute page numbers.
+
+ Control-L
+ Redisplays the current page.
+
+ ^ Move to the ``home'' position of the page. This is
+ normally the upper left-hand corner of the page,
+ depending on the margins as described in the -margins
+ option, above.
+
+ u Moves up a window-full.
+
+ d Moves down a window-full.
+
+ l Moves left a window-full.
+
+ r Moves right a window-full.
+
+ c Moves the page so that the point currently beneath the
+ cursor is moved to the middle of the window. It also
+ (gasp!) warps the cursor to the same place.
+
+ M Sets the margins so that the point currently under the
+ cursor is the upper left-hand corner of the text in the
+ page.
+
+ s Changes the shrink factor to the given number. If no
+ number is given, the smallest factor that makes the en-
+ tire page fit in the window will be used. (Margins are
+
+
+
+X Version 11 Last change: 8 May 1989 4
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+ ignored in this computation.)
+
+ S Sets the density factor to be used when shrinking bit-
+ maps. This should be a number between 0 and 100;
+ higher numbers produce lighter characters.
+
+ R Forces the dvi file to be reread. This allows you to
+ preview many versions of the same file while running
+ xdvi only once.
+
+MOUSE ACTIONS
+ If the shrink factor is set to any number other than one,
+ then clicking any mouse button will pop up a ``magnifying
+ glass'' which shows the unshrunk image in the vicinity of
+ the mouse click. This subwindow disappears when the mouse
+ button is released. Different mouse buttons produce dif-
+ ferent sized windows, as indicated by the -mgs option,
+ above.
+
+ Also, the scrollbars (if present) behave in the standard
+ way: pushing Button 2 in a scrollbar moves the top or left
+ edge of the scrollbar to that point; pushing Button 1 moves
+ the image up or right by an amount equal to the distance
+ from the button press to the upper left-hand corner of the
+ window; pushing Button 3 moves the image down or left by the
+ same amount.
+
+ENVIRONMENT
+ Uses the environment variable ``DISPLAY'' to specify which
+ bit map display terminal to use.
+
+ The environment variable ``TEXPKS'' determines the path(s)
+ searched for fonts in the following manner. The string con-
+ sists of one or more strings separated by colons. In each
+ such string, the substring ``%f'' is changed to the font
+ name; ``%d'' is changed to the magnification; and ``%p'' is
+ changed to the font family (``gf'', ``pk'', or ``pxl''). If
+ no ``%f'' appears in the string, then the string
+ ``/%f.%d%p'' is added on the end. For example, if the
+ string is ``/usr/local/tex/fonts'' and the font is cmr10 at
+ 300dpi, then it searches for
+ /usr/local/tex/fonts/cmr10.300gf,
+ /usr/local/tex/fonts/cmr10.300pk, and
+ /usr/local/tex/fonts/cmr10.1500pxl, in that order. If the
+ first character of the ``TEXPKS'' variable is a colon, then
+ the system default paths are tried first.
+
+FILES
+ /usr/local/lib/tex/fonts/pk Font pixel files.
+
+SEE ALSO
+ X(1).
+
+
+
+X Version 11 Last change: 8 May 1989 5
+
+
+
+
+
+
+XDVI(SIPB) MISC. REFERENCE MANUAL PAGES XDVI(SIPB)
+
+
+
+AUTHORS
+ Eric Cooper, CMU, did a version for direct output to a QVSS.
+ Modified for X by Bob Scheifler, MIT Laboratory for Computer
+ Science. Modified for X11 by Mark Eichin, MIT SIPB. Addi-
+ tional enhancements by many others.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+X Version 11 Last change: 8 May 1989 6
+
+
+