summaryrefslogtreecommitdiff
path: root/systems/msdos/dviware/xdvi-dos/src/xdvi.c
diff options
context:
space:
mode:
Diffstat (limited to 'systems/msdos/dviware/xdvi-dos/src/xdvi.c')
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/xdvi.c3175
1 files changed, 3175 insertions, 0 deletions
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 */
+}