v03i037: dvi previewer, Part01/03
Mike Wexler
mikew at wyse.wyse.com
Wed Mar 8 04:44:32 AEST 1989
Submitted-by: vojta at bosco.berkeley.edu
Posting-number: Volume 3, Issue 37
Archive-name: xdvi/part01
[I got this to compile under X11 Release 3. I modified it slightly
to follow the comp.sources.x guidelines. -mcw]
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 3)."
# Contents: README patchlevel.h xdvi.c xdvi.icon xdvi_curs.h
# Wrapped by mikew at wyse on Tue Mar 7 10:42:18 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(5416 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XLatest comments are at the end of the file. Add changes there.
X===$Header: README,v 1.2 88/07/22 21:00:33 eichin Exp $===
X================================================================
XThis directory contains a version of xdvi capable of reading GF, PXL
Xand PK font files. This version of xdvi is based on the source that
X"came with" X v10r3. Xdvi was modified by Paal Kvamme at the Norwegian
XInstitute of Technology, based on the modifications I had made to
Xdviimp (a dvi to ImPress converter). This code was again more or less
Xdirectly translated from the web source of PKtoPX.
X
XIf you discover (and fix) any bugs in this code, please notify me, so
XI can make the corresponding changes myself.
X
XMakefile was modified slightly to suit local conventions (CONFDIR and
XINCLUDES).
X
X[I threw in an Imakefile, but it's only a guess, as they don't have imake
Xat our site]--PV
X
X---------
XH}vard Eidnes (TeXish: H\aa vard Eidnes)
XDivision of Computer Science
XNorwegian Institute of Technology
X
XE-Mail: h_eidnes%vax.runit.unit.uninett at nta-vax.arpa
X================================================================
XAlso has path search added by Mark Eichin, looks in XTEXFONTS then TEXFONTS
X================================================================
X
XCompilation notes:
X To compile for X10 (non athena, assumes NORMAL X10 system)
X make -f Makefile_10
X To compile for X11 (athena environment)
X make
X _Mark Eichin
X <eichin at athena.mit.edu>
X The X10 flag only affects xdvi.c (and the flags MSBITFIRST, BMSHORT,
X and BMLONG, see below)
X
X You can also change the `make' variables FONTFORMATS_C and FONTFORMATS_O
X to reflect which font formats are actually used at your site.
X
XOther compilation flags are:
X FONT_PATH (xdvi.c) Name of the environment variable to use when
X searching for the font path
X DEFAULT_FONT_PATH (xdvi.c) Name of the default font path to use when
X the above environment variable is not set.
X MSBITFIRST (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
X bitmaps internally with the most significant bit at
X the left. For performance reasons, it would be best
X to set this to coincide with what your server uses.
X Use the keystroke '^P' to find information in this
X regard.
X BMSHORT (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
X bitmaps in short integers instead of bytes. See
X MSBITFIRST for other relevant comments. To check
X performance, you can use:
X time xdvi -d 8 file.dvi
X BMLONG (X11 only; xdvi.c dvi_draw.c gf.c pk.c pxl.c) Store
X bitmaps in long integers instead of bytes.
XAll flags should be set in the appropriate Makefile.
X================================================================
XAdditional notes:
X X11 version now works on the IBM PC/RT as well as VAX.
X [eichin:19880313.1330EST]
X================================================================
X*MORE* fixes (for athena release locker) [eichin:19880722.2058EST]
XFixes:
X narrow vertical and horizontal lines no longer disappear.
X bogus underlining (which usually occured on even sample sizes
Xof odd sized characters) no longer occurs.
X -S number (or typing number followed by S) will adjust the
Xsampling fraction; 0 is special cased to mean if anything in the
Xsampled zone is set, set the sample, else clear it. Interesting to
Xexperiment with, though not useful for reading (the default value of 3
Xis just right.)
X -display and -geometry arguments work (so do old style forms,
Xthough they were broken before)
X fixed one of the PK debugging messages to print the correct
Xfont name instead of printing the pointer as text.
X included Ken Raeburn <raeburn>'s changes to support multiple
Xscreens.
X================================================================
XMore changes:
X
X 1. Incorporated the bitmap under a viewport widget using the toolkit
X (X11 only);
X 2. Added an icon and icon geometry arguments (X11 only);
X 3. Supported window resizing;
X 4. Added a 'c' option to move whatever is currently under the cursor to
X the center of the window;
X 5. Added an 'R' option to reread the .dvi file, and added logic to make
X 'R' happen automatically whenever any part of the window is exposed
X and the dvi file changes (so that you can iconify xdvi, run tex,
X deiconify xdvi, and voila!);
X 6. Added a 'magnifying glass': when you push a button, a window pops
X up, showing the region of the page, unshrunk;
X 7. Added support for gf fonts;
X 8. Upgraded font searching (at our site we use /usr/custom/tex82/gf
X for gf fonts, /usr/custom/tex82/pk for pk fonts, etc.);
X 9. Made numerous internal changes (removed all the lint I could,
X made unshrunk bitmaps permanently resident, which speeds up size
X changing, made table.h necessary only for pxl.h, split up the source
X file into xdvi.c, dvi.c, gf.c, pxl.c, and pk.c, made shrinking occur
X relative to the character's hot point, etc.)
X-- Patchlevel 1: --
X 10. The program reads SIGIO signals and processes incoming events
X immediately, so that it can stop displaying things that would be
X erased anyway. If these interrupts are not coming through, then
X it also checks for incoming events every several dozen characters
X displayed.
X-- Patchlevel 2: --
X 11. Further split up dvi.c into dvi_init.c and dvi_draw.c; added
X compilation options for various internal bitmap representations.
X Fixed it so gcc won't give warnings, and so it works with R3 toolkit.
X
XPaul Vojta, vojta at math.berkeley.edu
END_OF_FILE
if test 5416 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 0
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'xdvi.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xdvi.c'\"
else
echo shar: Extracting \"'xdvi.c'\" \(43365 characters\)
sed "s/^X//" >'xdvi.c' <<'END_OF_FILE'
X/*
X * DVI previewer for X.
X *
X * Eric Cooper, CMU, September 1985.
X *
X * Code derived from dvi-imagen.c.
X *
X * Modification history:
X * 1/1986 Modified for X.10 by Bob Scheifler, MIT LCS.
X * 7/1988 Modified for X.11 by Mark Eichin, MIT
X * 12/1988 Added 'R' option, toolkit, magnifying glass
X * --Paul Vojta, UC Berkeley.
X * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
X *
X * Compilation options:
X * X10 compile for X10
X * MSBITFIRST store bitmaps internally in with significant bit first
X * BMSHORT store bitmaps in shorts instead of bytes
X * BMLONG store bitmaps in longs instead of bytes
X */
X#ifndef lint
X#include "patchlevel.h"
Xstatic struct {char a[36], b, c;}
X#ifndef X10
X dv_c = {"$Header: xdvi.c (X11), patchlevel = ", '0' + PATCHLEVEL, 0};
X#else X10
X dv_c = {"$Header: xdvi.c (X10), patchlevel = ", '0' + PATCHLEVEL, 0};
X#endif X10
X#endif lint
X
X#ifndef X10
X
X#undef Boolean
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Intrinsic.h>
X#ifdef OLD_X11_TOOLKIT
X#include <X11/Atoms.h>
X#else not OLD_X11_TOOLKIT
X#include <X11/Xatom.h>
X#include <X11/StringDefs.h>
X#endif not OLD_X11_TOOLKIT
X#include <X11/Shell.h> /* needed for def. of XtNiconX */
X#include <X11/Viewport.h>
X#include <X11/Simple.h>
X#include <X11/cursorfont.h>
X#include "xdvi.icon"
X
X#else X10
X
X#include <X/Xlib.h>
X
X#endif X10
X
X#include <stdio.h>
X#include <ctype.h>
X#include <fcntl.h>
X#include <signal.h>
X#include "xdvi.h"
X
X#ifndef X10
Xstatic Display *DISP;
X#define DPY DISP,
Xstatic Screen *SCRN;
Xstatic Cursor redraw_cursor, ready_cursor;
X#define SetCursor(x) XDefineCursor(DISP, mane.win, x)
X#define ClearPage() XClearWindow(DISP, mane.win);
X#define Flush() XFlush(DISP)
Xstatic Boolean unmapped = True;
X#ifndef X11HEIGHT
X#define X11HEIGHT 8 /* Height of server default font */
X#endif X11HEIGHT
X#else X10
X#define DPY
X#define GC int
X#define XtNumber(arr) (sizeof(arr)/sizeof(arr[0]))
X#define XtPending XPending
Xtypedef int Position;
Xtypedef int Dimension;
X#define SetCursor(x)
X#define ClearPage() XClear(mane.win);
X#define XBell(a,b) XFeep(b/10-1)
X#define Flush() XFlush()
X#define ConnectionNumber(DISP) (_XlibCurrentDisplay->fd)
X#ifndef X10FONT
X#define X10FONT "helv10b" /* Font for X10 error messages */
X#define X10HEIGHT 10
X#endif X10FONT
X#endif X10
X
X#define MAGBORD 1 /* border size for magnifier */
Xchar *font_path;
Xchar default_font_path[] = DEFAULT_FONT_PATH;
X
X/*
X * Command line flags.
X */
Xint debug = 0;
XBoolean list_fonts = False;
X
Xint density = 40;
Xint pixels_per_inch = 300;
Xstatic char *margins, *sidemargin, *topmargin;
Xstatic Boolean reverse;
Xstatic Dimension bwidth = 2;
Xstatic int bak_shrink;
Xstatic char *debug_arg;
Xstatic int mg_size[5] = {200, 350, 600, 900, 1200};
X
Xchar *dvi_name = NULL;
XFILE *dvi_file; /* user's file */
Xchar *prog;
Xchar *curr_page = NULL;
X
X#ifndef X10
Xstatic double specialConv;
X /* fg and bg colors */
Xstatic Arg fore_args = {XtNforeground, (XtArgVal) 0};
Xstatic Arg back_args = {XtNbackground, (XtArgVal) 0};
Xstatic XColor hl_Color, cr_Color;
X#endif X10
X
Xstatic char *fore_color;
Xstatic char *back_color;
Xstatic char *high_color;
Xstatic char *curs_color;
Xstatic GC foreGC, highGC;
X#ifndef X10
Xstatic GC ruleGC;
Xstatic GC foreGC2;
X#else X10
X#define ruleGC foreGC
X#endif X10
X
Xint page_w, page_h;
Xstatic int screen_w, screen_h;
Xstatic Dimension window_w, window_h;
Xstatic int home_x, home_y;
Xstatic int min_x, max_x, min_y, max_y;
X
Xstruct WindowRec mane = {NULL, 4, 0, 0, MAXINT, 0, MAXINT, 0};
Xstruct WindowRec alt = {NULL, 1, 0, 0, MAXINT, 0, MAXINT, 0};
X/* curr is temporary storage except for within redraw() */
Xstruct WindowRec curr = {NULL, 4, 0, 0, MAXINT, 0, MAXINT, 0};
X
X/*
X * Mechanism to keep track of the magnifier window. The problems are,
X * (a) if the button is released while the window is being drawn, this
X * could cause an X error if we continue drawing in it after it is
X * destroyed, and
X * (b) creating and destroying the window too quickly confuses the window
X * manager, which is avoided by waiting for an expose event before
X * destroying it.
X */
Xstatic short alt_stat; /* 1 = wait for expose, */
X /* -1 = destroy upon expose */
Xstatic Boolean alt_canit; /* stop drawing this window */
X
Xint pageno_correct = 1;
X
X/*
X * Data for buffered events.
X */
X
Xstatic Boolean canit = False,
X arg = False;
Xstatic short event_counter = 0,
X event_freq = 70;
Xstatic int number = 0,
X sign = 1;
Xstatic jmp_buf canit_env;
X
Xstatic void can_exposures(), read_events();
X
Xchar *malloc(), *index(), *rindex(), *sprintf(), *getenv(),
X *strcpy(), *strcat();
X
Xdouble atof();
X
X#ifndef X10
X/* Things we need from spec_draw, unfortunately */
X
X/* (ignored for now)
Xextern int pen_size, blacken, whiten, shade;
X*/
X
X#define toint(x) ((int) ((x) + 0.5))
X#define xconv(x) (toint(specialConv*(x))/shrink_factor + PXL_H)
X#define yconv(y) (toint(specialConv*(y))/shrink_factor + PXL_V)
X
X/*
X * Draw a line from (fx,fy) to (tx,ty).
X * Right now, we ignore pen_size.
X */
Xvoid
Xline_btw(fx, fy, tx, ty)
Xint fx, fy, tx, ty;
X{
X register int fcx = xconv(fx),
X tcx = xconv(tx),
X fcy = yconv(fy),
X tcy = yconv(ty);
X
X if ((fcx < max_x || tcx < max_x) && (fcx >= min_x || tcx >= min_x) &&
X (fcy < max_y || tcy < max_y) && (fcy >= min_y || tcy >= min_y))
X XDrawLine(DISP, curr.win, ruleGC,
X fcx - curr.base_x, fcy - curr.base_y,
X tcx - curr.base_x, tcy - curr.base_y);
X}
X
X/*
X * Draw a dot at (x,y)
X */
Xvoid
Xdot_at(x, y)
X{
X register int cx = xconv(x),
X cy = yconv(y);
X
X if (cx < max_x && cx >= min_x && cy < max_y && cy >= min_y)
X XDrawPoint(DISP, curr.win, ruleGC,
X cx - curr.base_x, cy - curr.base_y);
X}
X
X/*
X * Apply the requested attributes to the last path (box) drawn.
X * Attributes are reset.
X * (Not currently implemented.)
X */
X /* ARGSUSED */
Xvoid
Xdo_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y)
Xint last_min_x, last_max_x, last_min_y, last_max_y;
X{
X}
X#else X10
X/*
X * Specials are not implemented in X10.
X */
X
Xvoid
XapplicationDoSpecial(cmd)
Xchar *cmd;
X{
X if (spec_warn) Fprintf(stderr, "special ``%s'' not implemented\n", cmd);
X}
X#endif X10
X
X#ifndef X10
Xstatic Widget top_level, vport_widget, draw_widget, clip_widget;
Xstatic XImage *image;
X
Xstatic Arg vport_args[] = {
X {XtNallowHoriz, (XtArgVal) True},
X {XtNallowVert, (XtArgVal) True},
X};
X
X/* Note: Argument order in the following is important! */
X
Xstatic Arg draw_args[] = {
X {XtNwidth, (XtArgVal) 0},
X {XtNheight, (XtArgVal) 0},
X {XtNx, (XtArgVal) 0},
X {XtNy, (XtArgVal) 0},
X {XtNlabel, (XtArgVal) ""},
X};
X
Xstatic void set_draw_args();
X#else X10
Xstatic int GXfunc;
Xstatic int backpix, backmap, bdrmap;
X/*
X * Cursor and mask for valid cursor
X */
X#include "xdvi_curs.h"
X#include "xdvi_mask.h"
X#endif X10
X
X#ifdef lint
X#ifndef X10
XWidgetClass viewportWidgetClass, simpleWidgetClass;
Xchar xdvi_bits[288];
X#else X10
Xshort xdvi_bits[15], xdvi_mask_bits[15];
XDisplay *_XlibCurrentDisplay;
X#endif X10
X#endif lint
X
X/**
X ** Put a rectangle on the screen. hl determines the GC.
X **/
X
Xput_rectangle(x, y, w, h, hl)
X int x, y, w, h;
X Boolean hl;
X{
X if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y) {
X if (--event_counter == 0) read_events(False);
X#ifndef X10
X XFillRectangle(DISP, curr.win, hl ? highGC : ruleGC,
X x - curr.base_x, y - curr.base_y, w?w:1, h?h:1);
X#else X10
X XPixSet(curr.win, x - curr.base_x, y - curr.base_y,
X w?w:1, h?h:1, hl ? highGC : ruleGC);
X#endif X10
X }
X}
X
Xput_bitmap(bitmap, x, y)
X register struct bitmap *bitmap;
X register int x, y;
X{
X
X if (debug & DBG_BITMAP)
X Printf("X(%d,%d)\n", x-curr.base_x, y-curr.base_y);
X if (x < max_x && x + bitmap->w >= min_x &&
X y < max_y && y + bitmap->h >= min_y) {
X if (--event_counter == 0) read_events(False);
X#ifndef X10
X image->width = bitmap->w;
X image->height = bitmap->h;
X image->data = (char *)bitmap->bits;
X image->bytes_per_line = bitmap->bytes_wide;
X XPutImage(DISP, curr.win, foreGC, image,
X 0, 0,
X x - curr.base_x, y - curr.base_y,
X bitmap->w, bitmap->h);
X if (foreGC2)
X XPutImage(DISP, curr.win, foreGC2, image,
X 0, 0,
X x - curr.base_x, y - curr.base_y,
X bitmap->w, bitmap->h);
X#else X10
X XBitmapBitsPut(curr.win, x - curr.base_x, y - curr.base_y,
X bitmap->w, bitmap->h, (char *) bitmap->bits,
X foreGC, backpix, NULL, GXfunc, AllPlanes);
X#endif X10
X }
X}
X
Xput_border(x, y, w, h, t)
X int x, y, w, h, t;
X{
X put_rectangle(x, y, w, t, True);
X put_rectangle(x, y, t, h, True);
X put_rectangle(x, y + h - t, w, t, True);
X put_rectangle(x + w - t, y, t, h, True);
X}
X
X#ifndef X10
X/*
X * routines for X11 toolkit
X */
X
Xstatic Arg arg_wh[] = {
X {XtNwidth, (XtArgVal) &window_w},
X {XtNheight, (XtArgVal) &window_h},
X};
X
X#define get_wh(widget) XtGetValues(widget, arg_wh, 2)
X
Xstatic Position window_x, window_y;
Xstatic Arg arg_xy[] = {
X {XtNx, (XtArgVal) &window_x},
X {XtNy, (XtArgVal) &window_y},
X};
X
X#define get_xy() XtGetValues(draw_widget, arg_xy, 2)
X
X#define mane_base_x 0
X#define mane_base_y 0
X
Xstatic Boolean
Xscroll(horizontal, percent)
X Boolean horizontal;
X float percent;
X{
X register Widget widget;
X
X widget = XtNameToWidget(vport_widget,
X horizontal ? "horizontal" : "vertical");
X if (!widget) return False;
X XtGetValues(clip_widget, horizontal ? &arg_wh[0] : &arg_wh[1], 1);
X XtCallCallbacks(widget, XtNscrollProc,
X (int) (percent*(horizontal ? window_w : window_h)));
X return True;
X}
X
X/*
X * We unmap the window so that it does not generate expose events when
X * moving things around. I have found that compress_exposure does not do
X * this.
X */
X
Xstatic
Xunmap()
X{
X if (unmapped) return;
X XUnmapWindow(DISP, mane.win);
X unmapped = True;
X}
X
Xstatic
Xhome()
X{
X register Widget widget;
X register int coord;
X
X unmap();
X get_xy();
X get_wh(clip_widget);
X widget = XtNameToWidget(vport_widget, "horizontal");
X if (widget) {
X coord = 0;
X if (page_w > window_w) {
X coord = (page_w - window_w) / 2;
X if (coord > home_x / mane.shrinkfactor)
X coord = home_x / mane.shrinkfactor;
X }
X XtCallCallbacks(widget, XtNscrollProc, window_x + coord);
X }
X widget = XtNameToWidget(vport_widget, "vertical");
X if (widget) {
X coord = 0;
X if (page_h > window_h) {
X coord = (page_h - window_h) / 2;
X if (coord > home_y / mane.shrinkfactor)
X coord = home_y / mane.shrinkfactor;
X }
X XtCallCallbacks(widget, XtNscrollProc, window_y + coord);
X }
X}
X
Xstatic void
Xcenter(x, y)
X int x, y;
X{
X register Widget widget;
X
X/* We use the clip widget here because it gives a more exact value. */
X get_wh(clip_widget);
X x -= window_w/2;
X y -= window_h/2;
X widget = XtNameToWidget(vport_widget, "horizontal");
X if (widget) XtCallCallbacks(widget, XtNscrollProc, x);
X widget = XtNameToWidget(vport_widget, "vertical");
X if (widget) XtCallCallbacks(widget, XtNscrollProc, y);
X XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y);
X}
X
X/*
X * callback routines
X */
X
X/* The following callback routine should never be called. */
X /*ARGSUSED*/
Xstatic void
Xhandle_key(widget, junk, event)
X Widget widget;
X caddr_t junk;
X XEvent *event;
X{
X XBell(DISP, 20);
X}
X#else X10
Xstatic
Xhome()
X{
X mane.base_x = 0;
X if (page_w > window_w) {
X mane.base_x = (page_w - window_w) / 2;
X if (mane.base_x > home_x / mane.shrinkfactor)
X mane.base_x = home_x / mane.shrinkfactor;
X }
X mane.base_y = 0;
X if (page_h > window_h) {
X mane.base_y = (page_h - window_h) / 2;
X if (mane.base_y > home_y / mane.shrinkfactor)
X mane.base_y = home_y / mane.shrinkfactor;
X }
X}
X
X#define unmap()
X#define get_wh(widget)
X#define get_xy()
X#define window_x 0
X#define window_y 0
X#define mane_base_x mane.base_x
X#define mane_base_y mane.base_y
X#endif X10
X
X#ifndef X10
X /*ARGSUSED*/
Xstatic void
Xhandle_button(widget, junk, event)
X Widget widget;
X caddr_t junk;
X XButtonEvent *event;
X#else X10
Xstatic void
Xhandle_button(event, mag_size)
X XButtonPressedEvent *event;
X int mag_size;
X#endif X10
X{
X int x, y;
X#ifndef X10
X int mag_size = mg_size[event->button - 1];
X XSetWindowAttributes attr;
X#endif X10
X
X if (alt.win != NULL || mane.shrinkfactor == 1 || mag_size <= 0)
X XBell(DISP, 20);
X else {
X#ifndef X10
X x = event->x_root - mag_size/2;
X if (x > WidthOfScreen(SCRN) - mag_size - 2*MAGBORD)
X x = WidthOfScreen(SCRN) - mag_size - 2*MAGBORD;
X if (x < 0) x = 0;
X y = event->y_root - mag_size/2;
X if (y > HeightOfScreen(SCRN) - mag_size - 2*MAGBORD)
X y = HeightOfScreen(SCRN) - mag_size - 2*MAGBORD;
X if (y < 0) y = 0;
X#else X10
X x = event->x - mag_size/2;
X if (x > window_w - mag_size - 2*MAGBORD)
X x = window_w - mag_size - 2*MAGBORD;
X if (x < 0) x = 0;
X y = event->y - mag_size/2;
X if (y > window_h - mag_size - 2*MAGBORD)
X y = window_h - mag_size - 2*MAGBORD;
X if (y < 0) y = 0;
X#endif X10
X alt.base_x = (event->x + mane_base_x) * mane.shrinkfactor -
X mag_size/2;
X alt.base_y = (event->y + mane_base_y) * mane.shrinkfactor -
X mag_size/2;
X#ifndef X10
X attr.save_under = True;
X attr.border_pixel = fore_args.value;
X attr.background_pixel = back_args.value;
X alt.win = XCreateWindow(DISP, RootWindowOfScreen(SCRN),
X x, y, mag_size, mag_size, MAGBORD,
X 0, /* depth from parent */
X InputOutput, CopyFromParent,
X CWSaveUnder|CWBorderPixel|CWBackPixel, &attr);
X XSetTransientForHint(DISP, alt.win, XtWindow(top_level));
X XSelectInput(DISP, alt.win, ExposureMask);
X#else X10
X alt.win = XCreateWindow(mane.win,
X x, y, mag_size, mag_size, MAGBORD,
X bdrmap, backmap);
X XSelectInput(alt.win, ExposeRegion);
X#endif X10
X XMapWindow(DPY alt.win);
X alt_stat = 1; /* waiting for exposure */
X }
X}
X
X#ifndef X10
X /*ARGSUSED*/
Xstatic void
Xhandle_release(widget, junk, event)
X Widget widget;
X caddr_t junk;
X XButtonEvent *event;
X#else X10
Xstatic void
Xhandle_release()
X#endif X10
X{
X if (alt.win)
X if (alt_stat) alt_stat = -1; /* destroy upon expose */
X else {
X XDestroyWindow(DPY alt.win);
X if (curr.win == alt.win) alt_canit = True;
X alt.win = NULL;
X can_exposures(&alt);
X }
X}
X
X#ifndef X10
X /*ARGSUSED*/
Xstatic void
Xhandle_exp(widget, windowrec, event)
X Widget widget;
X struct WindowRec *windowrec;
X register XExposeEvent *event;
X{
X if (windowrec == &alt)
X if (alt_stat < 0) { /* destroy upon exposure */
X alt_stat = 0;
X handle_release(widget, (caddr_t) NULL, (XButtonEvent *) event);
X return;
X }
X else
X alt_stat = 0;
X if (windowrec->min_x > event->x) windowrec->min_x = event->x;
X if (windowrec->max_x < event->x + event->width)
X windowrec->max_x = event->x + event->width;
X if (windowrec->min_y > event->y) windowrec->min_y = event->y;
X if (windowrec->max_y < event->y + event->height)
X windowrec->max_y = event->y + event->height;
X}
X#endif X10
X
X#ifndef X10
X#define TRSIZE 100
X#endif X10
Xstatic void
Xread_events(wait)
X Boolean wait;
X{
X char ch;
X Boolean arg0;
X int number0;
X XEvent event;
X#ifndef X10
X char trbuf[TRSIZE];
X#endif X10
X char *string;
X int nbytes;
X int next_page;
X
X alt_canit = False;
X for (;;) {
X ch = '\0';
X event_counter = event_freq;
X /*
X * If we get a hit at this point, then we'll just end up making
X * an extra call.
X * Also, watch out, if we destroy the magnifying glass while
X * writing it.
X */
X if (!XtPending() && (!wait || canit || mane.min_x < MAXINT ||
X alt.min_x < MAXINT))
X if (alt_canit) longjmp(canit_env, 1);
X else return;
X#ifndef X10
X XtNextEvent(&event);
X if (event.xany.window == alt.win &&
X event.type == Expose) {
X handle_exp((Widget) NULL, &alt, &event.xexpose);
X continue;
X }
X if (event.type != KeyPress) {
X XtDispatchEvent(&event);
X continue;
X }
X string = trbuf;
X nbytes = XLookupString(&event, string, TRSIZE, NULL, NULL);
X if (nbytes > 1) goto bad;
X if (nbytes != 0) ch = *string;
X#else X10
X XNextEvent(&event);
X switch (event.type) {
X case ExposeWindow:
X if (event.window == mane.win) {
X window_h = ((XExposeEvent *)(&event))->height;
X window_w = ((XExposeEvent *)(&event))->width;
X home();
X ch = '\f';
X break;
X }
X /* otherwise control passes through */
X
X case ExposeRegion:
X /* check in case we already destroyed the window */
X if (event.window == mane.win || alt.win != NULL) {
X struct WindowRec *wr =
X (event.window == mane.win ? &mane : &alt);
X if (wr == &alt)
X if (alt_stat < 0) { /* destroy upon exposure */
X alt_stat = 0;
X handle_release();
X break;
X }
X else
X alt_stat = 0;
X#define ev ((XExposeEvent *)(&event))
X if (wr->min_x > ev->x) wr->min_x = ev->x;
X if (wr->max_x < ev->x + ev->width)
X wr->max_x = ev->x + ev->width;
X if (wr->min_y > ev->y) wr->min_y = ev->y;
X if (wr->max_y < ev->y + ev->height)
X wr->max_y = ev->y + ev->height;
X#undef ev
X }
X break;
X
X case ButtonPressed: {
X int n = 0;
X switch (((XButtonPressedEvent *) (&event))->detail &
X ValueMask) {
X case LeftButton: n=0; break;
X case MiddleButton: n=1; break;
X case RightButton: n=2; break;
X }
X handle_button((XButtonPressedEvent *) (&event), mg_size[n]);
X }
X break;
X case ButtonReleased:
X handle_release();
X break;
X case KeyPressed:
X string = XLookupMapping (&event, &nbytes);
X if (nbytes > 1) goto bad;
X if (nbytes != 0) ch = *string;
X break;
X }
X#endif X10
X if (ch == '\0') continue;
X if (ch >= '0' && ch <= '9') {
X arg = True;
X number = number * 10 + sign * (ch - '0');
X continue;
X }
X else if (ch == '-') {
X arg = True;
X sign = -1;
X number = 0;
X continue;
X }
X arg0 = arg;
X arg = False;
X number0 = number;
X number = 0;
X sign = 1;
X next_page = current_page;
X
X switch (ch) {
X case 'q':
X case '\003': /* control-C */
X case '\004': /* control-D */
X exit(0);
X case 'n':
X case 'f':
X case ' ':
X case '\r':
X case '\n':
X /* scroll forward; i.e. go to relative page */
X next_page = current_page + (arg0 ? number0 : 1);
X break;
X case 'p':
X case 'b':
X case '\b':
X case '\177': /* Del */
X /* scroll backward */
X next_page = current_page - 1;
X break;
X case 'g':
X /* go to absolute page */
X next_page = (arg0 ? number0 - pageno_correct :
X total_pages - 1);
X break;
X case 'P': /* declare current page */
X pageno_correct = arg0 * number0 - current_page;
X continue;
X case '\f':
X /* redisplay current page */
X break;
X case '^':
X home();
X break;
X#ifndef X10
X case 'u':
X if (!scroll(False, -0.67)) goto bad;
X continue;
X case 'd':
X if (!scroll(False, 0.67)) goto bad;
X continue;
X case 'l':
X if (!scroll(True, -0.67)) goto bad;
X continue;
X case 'r':
X if (!scroll(True, 0.67)) goto bad;
X continue;
X case 'c':
X center(event.xkey.x, event.xkey.y);
X continue;
X case 'M':
X XTranslateCoordinates(DISP, event.xkey.window, mane.win,
X event.xkey.x, event.xkey.y, &home_x, &home_y,
X &number0); /* throw away last argument */
X home_x *= mane.shrinkfactor;
X home_y *= mane.shrinkfactor;
X continue;
X case '\020': /* Control P */
X Printf("Unit = %d, bitord = %d, byteord = %d\n",
X BitmapUnit(DISP), BitmapBitOrder(DISP),
X ImageByteOrder(DISP));
X continue;
X#else X10
X case 'u':
X if (mane.base_y == 0) goto bad;
X mane.base_y -= window_h;
X if (mane.base_y < 0)
X mane.base_y = 0;
X break;
X case 'd':
X if (mane.base_y >= page_h - window_h) goto bad;
X mane.base_y += window_h;
X if (mane.base_y > page_h - window_h)
X mane.base_y = page_h - window_h;
X break;
X case 'l':
X if (mane.base_x == 0) goto bad;
X mane.base_x -= window_w;
X if (mane.base_x < 0)
X mane.base_x = 0;
X break;
X case 'r':
X if (mane.base_x >= page_w - window_w) goto bad;
X mane.base_x += window_w;
X if (mane.base_x > page_w - window_w)
X mane.base_x = page_w - window_w;
X break;
X case 'c':
X#define ev ((XKeyPressedEvent *) (&event))
X mane.base_x += ev->x - window_w/2;
X mane.base_y += ev->y - window_h/2;
X XWarpMouse(mane.win, window_w/2, window_h/2, 3);
X break;
X case 'M':
X home_x = (ev->x + mane.base_x) * mane.shrinkfactor;
X home_y = (ev->y + mane.base_y) * mane.shrinkfactor;
X continue;
X#undef ev
X#endif X10
X case 's':
X if (!arg0) {
X long fac1, fac2;
X shrink_factor = 1;
X get_wh(vport_widget);
X fac1 = ROUNDUP(PAPER_WIDTH, window_w);
X fac2 = ROUNDUP(PAPER_HEIGHT, window_h);
X if (fac1 < fac2)
X number0 = fac2;
X else
X number0 = fac1;
X }
X if (number0 <= 0) goto bad;
X if (number0 == mane.shrinkfactor) continue;
X shrink_factor = mane.shrinkfactor = number0;
X unmap();
X init_page();
X if (number0 != 1 && number0 != bak_shrink) {
X bak_shrink = number0;
X reset_fonts();
X }
X#ifndef X10
X set_draw_args();
X XtSetValues(draw_widget, draw_args, 2);
X#endif X10
X home();
X break;
X case 'S':
X if (!arg0) goto bad;
X if (number0 < 0) goto bad;
X if (number0 == density) continue;
X density = number0;
X reset_fonts();
X if (mane.shrinkfactor == 1) continue;
X unmap();
X break;
X case 'R':
X /* reread DVI file */
X --dvi_time; /* then it will notice a change */
X break;
X default:
X goto bad;
X }
X if (0 <= next_page && next_page < total_pages) {
X if (current_page != next_page) {
X current_page = next_page;
X spec_warn = True;
X home();
X }
X canit = True;
X Flush();
X longjmp(canit_env, 1);
X }
X bad: XBell(DISP, 10);
X }
X}
X
Xstatic
Xredraw(windowrec)
X struct WindowRec *windowrec;
X{
X char *errtext;
X#ifdef X10
X static FontInfo *font = 0;
X#endif X10
X
X curr = *windowrec;
X min_x = curr.min_x + curr.base_x;
X min_y = curr.min_y + curr.base_y;
X max_x = curr.max_x + curr.base_x;
X max_y = curr.max_y + curr.base_y;
X can_exposures(windowrec);
X
X if (debug & DBG_EVENT)
X Printf("Redraw %d x %d at (%d, %d) (base=%d,%d)\n", max_x - min_x,
X max_y - min_y, min_x, min_y, curr.base_x, curr.base_y);
X SetCursor(redraw_cursor);
X if (errtext = (char *) setjmp(dvi_env)) {
X ClearPage();
X#ifndef X10
X get_xy();
X XDrawString(DISP, mane.win, foreGC,
X 5 - window_x, 5 + X11HEIGHT - window_y,
X errtext, strlen(errtext));
X#else X10
X if (!font) font = XOpenFont(X10FONT);
X XTextMask(mane.win, 5, 5 + X10HEIGHT, errtext, strlen(errtext),
X font->id, foreGC);
X#endif X10
X if (dvi_file) {
X Fclose(dvi_file);
X dvi_file = NULL;
X }
X }
X else {
X draw_page();
X spec_warn = False;
X }
X}
X
Xredraw_page()
X{
X if (debug & DBG_EVENT) fputs("Redraw page: ", stdout);
X get_wh(clip_widget);
X get_xy();
X ClearPage();
X mane.min_x = -window_x;
X mane.max_x = -window_x + window_w;
X mane.min_y = -window_y;
X mane.max_y = -window_y + window_h;
X redraw(&mane);
X}
X
X/*
X * Interrupt system for receiving events. The program sets a flag
X * whenever an event comes in, so that at the proper time (i.e., when
X * reading a new dvi item), we can check incoming events to see if we
X * still want to go on printing this page. This way, one can stop
X * displaying a page if it is about to be erased anyway. We try to read
X * as many events as possible before doing anything and base the next
X * action on all events read.
X * Note that the Xlib and Xt routines are not reentrant, so the most we
X * can do is set a flag in the interrupt routine and check it later.
X * Also, sometimes the interrupts are not generated (some systems only
X * guarantee that SIGIO is generated for terminal files, and on the system
X * I use, the interrupts are not generated if I use "(xdvi foo &)" instead
X * of "xdvi foo"). Therefore, there is also a mechanism to check the
X * event queue every 70 drawing operations or so. This mechanism is
X * disabled if it turns out that the interrupts do work.
X * For a fuller discussion of some of the above, see xlife in
X * comp.sources.x.
X */
X
Xstatic void
Xcan_exposures(windowrec)
X struct WindowRec *windowrec;
X{
X windowrec->min_x = windowrec->min_y = MAXINT;
X windowrec->max_x = windowrec->max_y = 0;
X}
X
Xstatic int
Xhandle_intr() {
X event_counter = 1;
X event_freq = -1; /* forget Plan B */
X}
X
Xstatic void
Xenable_intr() {
X int socket = ConnectionNumber(DISP);
X if (!isatty(0)) {
X puts("trying...");
X if (dup2(socket, 0) == -1) perror(prog);
X socket = 0;
X }
X (void) signal(SIGIO, handle_intr);
X (void) fcntl(socket, F_SETOWN, getpid());
X (void) fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | FASYNC);
X}
X
Xstatic
Xdo_pages()
X{
X if (debug & DBG_BATCH) {
X while (mane.min_x == MAXINT) read_events(True);
X for (current_page = 0; current_page < total_pages; ++current_page)
X redraw_page();
X exit(0);
X }
X else {
X enable_intr();
X (void) setjmp(canit_env);
X for (;;) {
X SetCursor(ready_cursor);
X read_events(True);
X if (canit) {
X canit = False;
X can_exposures(&mane);
X can_exposures(&alt);
X#ifndef X10
X if (unmapped) {
X /* this creates a redraw event */
X XMapWindow(DISP, mane.win);
X unmapped = False;
X }
X else
X#endif
X redraw_page();
X }
X else if (alt.min_x < MAXINT) redraw(&alt);
X else if (mane.min_x < MAXINT) redraw(&mane);
X Flush();
X }
X }
X}
X
Xstatic
Xusage() {
X#ifndef X10
X fputs("\
XUsage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
X [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
X[-cr <color>]\n\
X [-margins <inches>] [-sidemargin <inches>] [-topmargin <inches>]\n\
X [-mgs[n] <size>] [-geometry <geometry>] [#<geometry>]\n\
X [-display <host:display>] dvi_file\n", stderr);
X#else X10
X fputs("\
XUsage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
X [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
X[-cr <color>]\n\
X [-margins <inches>] [-sidemargin <inches>] [-topmargin <inches>]\n\
X [-mgs[n] <size>] [-geometry <geometry> | =<geometry>]\n\
X [-display <host:display> | host:display] dvi_file\n", stderr);
X#endif X10
X exit(1);
X}
X
X/**
X ** Main programs start here.
X **/
X
X#ifndef X10
Xstatic char *icon_geometry;
Xstatic Boolean thorough;
X
Xstatic XrmOptionDescRec options[] = {
X{"-d", ".debugLevel", XrmoptionSepArg, (caddr_t) NULL},
X{"+", ".gotoPage", XrmoptionStickyArg, (caddr_t) NULL},
X{"-s", ".shrinkFactor", XrmoptionSepArg, (caddr_t) NULL},
X{"-S", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL},
X{"-p", ".pixelsPerInch", XrmoptionSepArg, (caddr_t) NULL},
X{"-margins", ".margins", XrmoptionSepArg, (caddr_t) NULL},
X{"-sidemargin", ".sideMargin", XrmoptionSepArg, (caddr_t) NULL},
X{"-topmargin", ".topMargin", XrmoptionSepArg, (caddr_t) NULL},
X{"-l", ".listFonts", XrmoptionNoArg, (caddr_t) "on"},
X{"+l", ".listFonts", XrmoptionNoArg, (caddr_t) "off"},
X{"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
X{"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
X{"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL},
X{"-background", ".background", XrmoptionSepArg, (caddr_t) NULL},
X{"-hl", ".highlight", XrmoptionSepArg, (caddr_t) NULL},
X{"-cr", ".cursorColor", XrmoptionSepArg, (caddr_t) NULL},
X{"#", ".iconGeometry",XrmoptionStickyArg, (caddr_t) NULL},
X{"-thorough", ".thorough", XrmoptionNoArg, (caddr_t) "on"},
X{"+thorough", ".thorough", XrmoptionNoArg, (caddr_t) "off"},
X{"-mgs", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
X{"-mgs1", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL},
X{"-mgs2", ".magnifierSize2",XrmoptionSepArg, (caddr_t) NULL},
X{"-mgs3", ".magnifierSize3",XrmoptionSepArg, (caddr_t) NULL},
X{"-mgs4", ".magnifierSize4",XrmoptionSepArg, (caddr_t) NULL},
X{"-mgs5", ".magnifierSize5",XrmoptionSepArg, (caddr_t) NULL},
X};
X
Xstatic XtResource resources[] = {
X{"debugLevel", "DebugLevel", XtRString, sizeof(char *),
X (Cardinal) &debug_arg, XtRString, NULL},
X{"gotoPage", "GotoPage", XtRString, sizeof(char *),
X (Cardinal) &curr_page, XtRString, NULL},
X{"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int),
X (Cardinal) &shrink_factor, XtRInt, (caddr_t) &shrink_factor},
X{"densityPercent", "DensityPercent", XtRInt, sizeof(int),
X (Cardinal) &density, XtRInt, (caddr_t) &density},
X{"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int),
X (Cardinal) &pixels_per_inch, XtRInt, (caddr_t) &pixels_per_inch},
X{"margins", "Margin", XtRString, sizeof(char *),
X (Cardinal) &margins, XtRString, NULL},
X{"sideMargin", "Margin", XtRString, sizeof(char *),
X (Cardinal) &sidemargin, XtRString, NULL},
X{"topMargin", "Margin", XtRString, sizeof(char *),
X (Cardinal) &topmargin, XtRString, NULL},
X{"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean),
X (Cardinal) &list_fonts, XtRBoolean, (caddr_t) &list_fonts},
X{"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
X (Cardinal) &reverse, XtRBoolean, (caddr_t) &reverse},
X{"foreground", "Foreground", XtRPixel, sizeof(Pixel),
X (Cardinal)&fore_args.value, XtRPixel, (caddr_t) &fore_args.value},
X{"foreground", "Foreground", XtRString, sizeof(char *),
X (Cardinal)&fore_color, XtRString, NULL},
X{"background", "Background", XtRPixel, sizeof(Pixel),
X (Cardinal)&back_args.value, XtRPixel, (caddr_t) &back_args.value},
X{"background", "Background", XtRString, sizeof(char *),
X (Cardinal)&back_color, XtRString, NULL},
X{"highlight", "Highlight", XtRColor, sizeof(XColor),
X (Cardinal)&hl_Color, XtRColor, (caddr_t) &hl_Color},
X{"highlight", "Highlight", XtRString, sizeof(char *),
X (Cardinal)&high_color, XtRString, NULL},
X{"cursorColor", "CursorColor", XtRColor, sizeof(XColor),
X (Cardinal)&cr_Color, XtRColor, (caddr_t) &cr_Color},
X{"cursorColor", "CursorColor", XtRString, sizeof(char *),
X (Cardinal)&curs_color, XtRString, NULL},
X{"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
X (Cardinal)&icon_geometry, XtRString, (caddr_t) NULL},
X{"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
X (Cardinal)&thorough, XtRBoolean, (caddr_t) &thorough},
X{"magnifierSize1", "MagnifierSize", XtRInt, sizeof(int),
X (Cardinal) &mg_size[0], XtRInt, (caddr_t) &mg_size[0]},
X{"magnifierSize2", "MagnifierSize", XtRInt, sizeof(int),
X (Cardinal) &mg_size[1], XtRInt, (caddr_t) &mg_size[1]},
X{"magnifierSize3", "MagnifierSize", XtRInt, sizeof(int),
X (Cardinal) &mg_size[2], XtRInt, (caddr_t) &mg_size[2]},
X{"magnifierSize4", "MagnifierSize", XtRInt, sizeof(int),
X (Cardinal) &mg_size[3], XtRInt, (caddr_t) &mg_size[3]},
X{"magnifierSize5", "MagnifierSize", XtRInt, sizeof(int),
X (Cardinal) &mg_size[4], XtRInt, (caddr_t) &mg_size[4]},
X};
X
Xstatic void
Xset_draw_args() {
X draw_args[0].value = (XtArgVal) page_w;
X draw_args[1].value = (XtArgVal) page_h;
X}
X
Xstatic Arg temp_args1[] = {
X {XtNiconX, (XtArgVal) 0},
X {XtNiconY, (XtArgVal) 0},
X};
X
Xstatic Arg temp_args2 = {XtNborderWidth, (XtArgVal) &bwidth};
X
Xstatic Arg temp_args3[] = {
X {XtNwidth, (XtArgVal) 0},
X {XtNheight, (XtArgVal) 0},
X {XtNiconPixmap, (XtArgVal) 0},
X};
X
X/*
X * X11 main program
X */
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X prog = *argv;
X if (*prog == '/') prog = rindex(prog, '/') + 1;
X
X top_level = XtInitialize(prog, "XDvi", options, XtNumber(options),
X &argc, argv);
X if (argc != 2) usage();
X dvi_name = argv[1];
X
X XtGetApplicationResources(top_level, (caddr_t) NULL, resources,
X XtNumber(resources), NULL, 0);
X if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0) usage();
X if (shrink_factor != 1) bak_shrink = shrink_factor;
X mane.shrinkfactor = shrink_factor;
X specialConv = pixels_per_inch / 1000.0;
X if (debug_arg != NULL)
X debug = isdigit(*debug_arg) ? atoi(debug_arg) : DBG_ALL;
X if (margins) home_x = home_y = atof(margins) * pixels_per_inch;
X if (sidemargin) home_x = atof(sidemargin) * pixels_per_inch;
X if (topmargin) home_y = atof(topmargin) * pixels_per_inch;
X /* The following code is lifted from Xterm */
X DISP = XtDisplay(top_level);
X SCRN = XtScreen(top_level);
X if (icon_geometry != NULL) {
X int scr, junk;
X
X for(scr = 0; /* yyuucchh */
X SCRN != ScreenOfDisplay(DISP, scr);
X scr++);
X
X temp_args1[0].name = XtNiconX;
X temp_args1[1].name = XtNiconY;
X XGeometry(DISP, scr, icon_geometry, "", 0, 0, 0, 0, 0,
X &temp_args1[0].value, &temp_args1[1].value, &junk, &junk);
X XtSetValues(top_level, temp_args1, 2);
X }
X
X if ((font_path = getenv(FONT_PATH)) == NULL)
X font_path = default_font_path;
X else if (*font_path == ':')
X /*concatenate default_font_path before font_path */
X font_path = strcat(strcpy(malloc((unsigned)
X strlen(default_font_path) + strlen(font_path) + 1),
X default_font_path), font_path);
X
X open_dvi_file();
X if (curr_page) {
X current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
X if (current_page < 0 || current_page >= total_pages) usage();
X }
X
X /* Set default window size and icon */
X XtGetValues(top_level, &temp_args2, 1); /* get border width */
X screen_w = WidthOfScreen(SCRN) - 2*bwidth;
X screen_h = HeightOfScreen(SCRN) - 2*bwidth;
X temp_args3[0].value = (XtArgVal) (page_w<screen_w ? page_w : screen_w);
X temp_args3[1].value = (XtArgVal) (page_h<screen_h ? page_h : screen_h);
X temp_args3[2].value = (XtArgVal) (XCreateBitmapFromData(DISP,
X RootWindowOfScreen(SCRN),
X xdvi_bits, xdvi_width, xdvi_height));
X XtSetValues(top_level, temp_args3, 3);
X
X vport_widget = XtCreateManagedWidget("vport", viewportWidgetClass,
X top_level, vport_args, XtNumber(vport_args));
X clip_widget = XtNameToWidget(vport_widget, "clip");
X set_draw_args();
X draw_widget = XtCreateManagedWidget("drawing", simpleWidgetClass,
X vport_widget, draw_args, XtNumber(draw_args));
X XtAddEventHandler(vport_widget, KeyPressMask, 0, handle_key,
X (caddr_t) NULL);
X XtAddEventHandler(draw_widget, ExposureMask, GraphicsExpose, handle_exp,
X (caddr_t) &mane);
X XtAddEventHandler(draw_widget, ButtonPressMask, 0, handle_button,
X (caddr_t) NULL);
X XtAddEventHandler(draw_widget, ButtonReleaseMask, 0, handle_release,
X (caddr_t) NULL);
X XtRealizeWidget(top_level);
X curr.win = mane.win = XtWindow(draw_widget);
X /* unmapped = True; (it was initialized this way) */
X home(); /* no need to unmap at this stage */
X unmapped = False;
X
X if (reverse) {
X if (!fore_color) fore_args.value = WhitePixelOfScreen(SCRN);
X if (!back_color) back_args.value = BlackPixelOfScreen(SCRN);
X fore_color = back_color = (char *)1; /* nonzero */
X } else {
X if (!fore_color) fore_args.value = BlackPixelOfScreen(SCRN);
X if (!back_color) back_args.value = WhitePixelOfScreen(SCRN);
X }
X if (fore_color) XtSetValues(draw_widget, &fore_args, 1);
X if (back_color) {
X XtSetValues(draw_widget, &back_args, 1);
X XtSetValues(clip_widget, &back_args, 1);
X }
X {
X XGCValues values;
X Pixel set_bits = (Pixel) (fore_args.value & ~back_args.value);
X Pixel clr_bits = (Pixel) (back_args.value & ~fore_args.value);
X#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\
X values.background=bg,\
X XCreateGC(DISP, RootWindowOfScreen(SCRN),\
X GCFunction|GCForeground|GCBackground, &values))
X
X if (set_bits && clr_bits)
X ruleGC = MakeGC(GXcopy, fore_args.value, back_args.value);
X if (!thorough && ruleGC) {
X foreGC = ruleGC;
X puts("Note: overstrike characters may be incorrect.");
X }
X else {
X if (set_bits) foreGC = MakeGC(GXor, set_bits, 0);
X if (clr_bits)
X *(foreGC ? &foreGC2 : &foreGC) =
X MakeGC(GXandInverted, clr_bits, 0);
X if (!ruleGC) ruleGC = foreGC;
X }
X highGC = ruleGC;
X if (high_color)
X highGC = MakeGC(GXcopy, hl_Color.pixel, back_args.value);
X }
X
X ready_cursor = XCreateFontCursor(DISP, XC_cross);
X redraw_cursor = XCreateFontCursor(DISP, XC_watch);
X if (!curs_color)
X if (high_color) cr_Color = hl_Color;
X else {
X cr_Color.pixel = fore_args.value;
X XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &cr_Color);
X }
X {
X XColor bg_Color;
X bg_Color.pixel = back_args.value;
X XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bg_Color);
X XRecolorCursor(DISP, ready_cursor, &cr_Color, &bg_Color);
X XRecolorCursor(DISP, redraw_cursor, &cr_Color, &bg_Color);
X }
X
X image = XCreateImage(DISP, DefaultVisualOfScreen(SCRN), 1, XYBitmap, 0,
X (char *)NULL, 0, 0, BITS_PER_BMUNIT, 0);
X image->bitmap_unit = BITS_PER_BMUNIT;
X#ifndef MSBITFIRST
X image->bitmap_bit_order = LSBFirst;
X#else MSBITFIRST
X image->bitmap_bit_order = MSBFirst;
X#endif MSBITFIRST
X {
X short endian = (MSBFirst << 8) + LSBFirst;
X image->byte_order = *((char *) &endian);
X }
X
X do_pages();
X}
X
X#else X10
Xstatic char *display;
Xstatic char *brdr_color;
Xstatic char *geometry;
X
Xstatic struct option {
X char *name;
X char *resource;
X enum {FalseArg, TrueArg, StickyArg, SepArg} argclass;
X enum {BooleanArg, StringArg, NumberArg} argtype;
X caddr_t address;
X} options[] = {
X /* the display option MUST be first */
X{"-display", NULL, SepArg, StringArg, (caddr_t) &display},
X{"-d", "debugLevel", SepArg, StringArg, (caddr_t) &debug_arg},
X{"+", NULL, StickyArg, StringArg, (caddr_t) &curr_page},
X{"-s", "shrinkFactor", SepArg, NumberArg, (caddr_t) &shrink_factor},
X{"-S", "densityPercent", SepArg, NumberArg, (caddr_t) &density},
X{"-p", "pixelsPerInch", SepArg, NumberArg, (caddr_t) &pixels_per_inch},
X{"-margins", "margins", SepArg, StringArg, (caddr_t) &margins},
X{"-sidemargin", "sideMargin", SepArg, StringArg, (caddr_t) &sidemargin},
X{"-topmargin", "topMargin", SepArg, StringArg, (caddr_t) &topmargin},
X{"-l", "listFonts", TrueArg, BooleanArg, (caddr_t) &list_fonts},
X{"+l", NULL, FalseArg, BooleanArg, (caddr_t) &list_fonts},
X{"-rv", "reverseVideo", TrueArg, BooleanArg, (caddr_t) &reverse},
X{"+rv", NULL, FalseArg, BooleanArg, (caddr_t) &reverse},
X{"-bw", "borderWidth", SepArg, NumberArg, (caddr_t) &bwidth},
X{"-borderwidth", NULL, SepArg, NumberArg, (caddr_t) &bwidth},
X{"-fg", "foreground", SepArg, StringArg, (caddr_t) &fore_color},
X{"-foreground", NULL, SepArg, StringArg, (caddr_t) &fore_color},
X{"-bg", "background", SepArg, StringArg, (caddr_t) &back_color},
X{"-background", NULL, SepArg, StringArg, (caddr_t) &back_color},
X{"-hl", "highlight", SepArg, StringArg, (caddr_t) &high_color},
X{"-bd", "borderColor", SepArg, StringArg, (caddr_t) &brdr_color},
X{"-cr", "cursorColor", SepArg, StringArg, (caddr_t) &curs_color},
X{"-geometry", "geometry", SepArg, StringArg, (caddr_t) &geometry},
X{"=", NULL, StickyArg, StringArg, (caddr_t) &geometry},
X{"-mgs", NULL, SepArg, NumberArg, (caddr_t) &mg_size[0]},
X{"-mgs1", "magnifierSize1",SepArg, NumberArg, (caddr_t) &mg_size[0]},
X{"-mgs2", "magnifierSize2",SepArg, NumberArg, (caddr_t) &mg_size[1]},
X{"-mgs3", "magnifierSize3",SepArg, NumberArg, (caddr_t) &mg_size[2]},
X};
X
X/*
X * X10 main program
X */
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X char **arg;
X char **argvend = argv + argc;
X char *optstring;
X caddr_t addr;
X struct option *opt, *candidate;
X int len1, len2, matchlen;
X OpaqueFrame frame;
X char def[32];
X int mouspix;
X Color cdef;
X
X prog = *argv;
X if (*prog == '/') prog = rindex(prog, '/') + 1;
X/*
X * Process the option table. This is not guaranteed for all possible
X * option tables, but at least it works for this one.
X */
X for (arg = argv + 1; arg < argvend; ++arg) {
X len1 = strlen(*arg);
X candidate = NULL;
X matchlen = 0;
X for (opt = options; opt < options + XtNumber(options); ++opt) {
X len2 = strlen(opt->name);
X if (opt->argclass == StickyArg) {
X if (matchlen <= len2 && !strncmp(*arg, opt->name, len2)) {
X candidate = opt;
X matchlen = len2;
X }
X }
X else if (len1 <= len2 && matchlen <= len1 &&
X !strncmp(*arg, opt->name, len1)) {
X if (len1 == len2) {
X candidate = opt;
X break;
X }
X if (matchlen < len1) candidate = opt;
X else if (candidate && candidate->argclass != StickyArg)
X candidate = NULL;
X matchlen = len1;
X }
X }
X if (candidate == NULL) {
X if (**arg == '-') usage();
X if (index(*arg, ':') != NULL) { /* display */
X --arg;
X candidate = options;
X }
X else if (dvi_name) usage();
X else {
X dvi_name = *arg;
X continue;
X }
X }
X addr = candidate->address;
X for (opt = options; opt < options + XtNumber(options); ++opt)
X if (opt->address == addr) opt->resource = NULL;
X switch (candidate->argclass) {
X case FalseArg: *((Boolean *) addr) = False; break;
X case TrueArg: *((Boolean *) addr) = True; break;
X case StickyArg: optstring = *arg + strlen(candidate->name);
X break;
X case SepArg:
X ++arg;
X if (arg >= argvend) usage();
X optstring = *arg;
X break;
X }
X switch (candidate->argtype) {
X case StringArg: *((char **) addr) = optstring; break;
X case NumberArg: *((int *) addr) = atoi(optstring); break;
X }
X }
X
X if (XOpenDisplay(display) == NULL)
X oops("Can't open display\n");
X for (opt = options; opt < options + XtNumber(options); ++opt)
X if (opt->resource && (optstring = XGetDefault(prog, opt->resource)))
X switch (opt->argtype) {
X case StringArg:
X *((char **) opt->address) = optstring;
X break;
X case NumberArg:
X *((int *) opt->address) = atoi(optstring);
X break;
X case BooleanArg:
X *((Boolean *) opt->address) =
X (strcmp(optstring, "on") == 0);
X }
X
X if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 ||
X dvi_name == NULL) usage();
X if (shrink_factor != 1) bak_shrink = shrink_factor;
X mane.shrinkfactor = shrink_factor;
X if (debug_arg != NULL)
X debug = isdigit(*debug_arg) ? atoi(debug_arg) : DBG_ALL;
X if (margins) home_x = home_y = atof(margins) * pixels_per_inch;
X if (sidemargin) home_x = atof(sidemargin) * pixels_per_inch;
X if (topmargin) home_y = atof(topmargin) * pixels_per_inch;
X
X if ((font_path = getenv(FONT_PATH)) == NULL)
X font_path = default_font_path;
X else if (*font_path == ':')
X /*concatenate default_font_path before font_path */
X font_path = strcat(strcpy(malloc((unsigned)
X strlen(default_font_path) + strlen(font_path) + 1),
X default_font_path), font_path);
X
X open_dvi_file();
X if (curr_page) {
X current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
X if (current_page < 0 || current_page >= total_pages) usage();
X }
X
X if (reverse) {
X foreGC = WhitePixel;
X highGC = WhitePixel;
X backpix = BlackPixel;
X backmap = BlackPixmap;
X bdrmap = WhitePixmap;
X mouspix = WhitePixel;
X GXfunc = GXor;
X } else {
X foreGC = BlackPixel;
X highGC = BlackPixel;
X backpix = WhitePixel;
X backmap = WhitePixmap;
X bdrmap = BlackPixmap;
X mouspix = BlackPixel;
X GXfunc = GXand;
X }
X if (DisplayCells() > 2) {
X if (fore_color && XParseColor(fore_color, &cdef) &&
X XGetHardwareColor(&cdef))
X foreGC = cdef.pixel;
X if (back_color && XParseColor(back_color, &cdef) &&
X XGetHardwareColor(&cdef)) {
X backpix = cdef.pixel;
X backmap = XMakeTile(backpix);
X }
X if (high_color && XParseColor(high_color, &cdef) &&
X XGetHardwareColor(&cdef))
X highGC = cdef.pixel;
X if (brdr_color && XParseColor(brdr_color, &cdef) &&
X XGetHardwareColor(&cdef))
X bdrmap = XMakeTile(cdef.pixel);
X if (curs_color && XParseColor(curs_color, &cdef) &&
X XGetHardwareColor(&cdef))
X mouspix = cdef.pixel;
X }
X
X frame.bdrwidth = bwidth;
X screen_w = DisplayWidth() - 2*bwidth;
X screen_h = DisplayHeight() - 2*bwidth;
X frame.width = (page_w < screen_w ? page_w : screen_w);
X frame.height = (page_h < screen_h ? page_h : screen_h);
X frame.border = bdrmap;
X frame.background = backmap;
X frame.x = 0;
X frame.y = 0;
X Sprintf(def, "=%dx%d+0+0", frame.width, frame.height);
X mane.win = XCreate("DVI Previewer", prog, geometry, def,
X &frame, 50, 50);
X window_w = frame.width;
X window_h = frame.height;
X XSelectInput(mane.win,
X KeyPressed|ButtonPressed|ButtonReleased|
X ExposeWindow|ExposeRegion);
X XMapWindow(mane.win);
X XDefineCursor(mane.win,
X XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_mask_bits,
X xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy));
X do_pages();
X}
X#endif X10
END_OF_FILE
if test 43365 -ne `wc -c <'xdvi.c'`; then
echo shar: \"'xdvi.c'\" unpacked with wrong size!
fi
# end of 'xdvi.c'
fi
if test -f 'xdvi.icon' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xdvi.icon'\"
else
echo shar: Extracting \"'xdvi.icon'\" \(1874 characters\)
sed "s/^X//" >'xdvi.icon' <<'END_OF_FILE'
X#define xdvi_width 48
X#define xdvi_height 48
Xstatic char xdvi_bits[] = {
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x22, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa2, 0xe0, 0x44, 0x38, 0x95, 0x13,
X 0x9e, 0x17, 0x45, 0x45, 0x55, 0xf4, 0x82, 0xf0, 0x28, 0x3d, 0xd5, 0x13,
X 0x82, 0x10, 0x28, 0x05, 0x55, 0x10, 0x82, 0xe0, 0x10, 0x39, 0x8a, 0x13,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x1f, 0x00,
X 0x79, 0x18, 0x18, 0x13, 0x16, 0x00, 0x69, 0x10, 0x18, 0x0e, 0x16, 0x00,
X 0xcf, 0x20, 0x1c, 0x0e, 0xd6, 0x00, 0xe9, 0xc3, 0x7b, 0x84, 0x3f, 0x01,
X 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x70, 0xcc,
X 0x08, 0x00, 0x00, 0x00, 0x30, 0x52, 0x0a, 0x00, 0x00, 0x00, 0x30, 0x52,
X 0x0a, 0xc0, 0xff, 0x03, 0x30, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
X 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0xc0, 0xff, 0x03, 0x10, 0x00,
X 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
X 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x17,
X 0x0b, 0x0c, 0x3c, 0xc0, 0x93, 0x20, 0x0c, 0x0e, 0x43, 0x20, 0x96, 0x40,
X 0x0c, 0x8e, 0x81, 0x10, 0x96, 0xbe, 0x0a, 0x8d, 0x81, 0x19, 0x90, 0x82,
X 0x8a, 0x8c, 0x81, 0x0d, 0x90, 0x42, 0x48, 0x8c, 0x81, 0xed, 0x91, 0x3e,
X 0x6a, 0x0c, 0xc3, 0x1d, 0x96, 0x12, 0x38, 0x0c, 0xbc, 0x0d, 0x1c, 0x02,
X 0xf8, 0x3f, 0x80, 0x0d, 0x1c, 0x3e, 0x0b, 0x0c, 0x80, 0x0c, 0x1c, 0x00,
X 0x0b, 0x0c, 0xc3, 0x18, 0x1c, 0x00, 0x0a, 0x0c, 0x63, 0x10, 0x16, 0x00,
X 0x89, 0x3f, 0x1e, 0xe0, 0x11, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00,
X 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00,
X 0xff, 0xff, 0xff, 0xff, 0x1f, 0xae, 0x0f, 0x00, 0x80, 0x84, 0x0a, 0xae,
X 0x87, 0x64, 0x86, 0x84, 0x08, 0x42, 0x42, 0x45, 0xe2, 0x1c, 0x07, 0x42};
END_OF_FILE
if test 1874 -ne `wc -c <'xdvi.icon'`; then
echo shar: \"'xdvi.icon'\" unpacked with wrong size!
fi
# end of 'xdvi.icon'
fi
if test -f 'xdvi_curs.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xdvi_curs.h'\"
else
echo shar: Extracting \"'xdvi_curs.h'\" \(249 characters\)
sed "s/^X//" >'xdvi_curs.h' <<'END_OF_FILE'
X#define xdvi_width 15
X#define xdvi_height 15
X#define xdvi_x_hot 7
X#define xdvi_y_hot 7
Xstatic short xdvi_bits[] = {
X 0x0080, 0x01c0, 0x03e0, 0x06b0,
X 0x0c98, 0x188c, 0x3086, 0x7fff,
X 0x3086, 0x188c, 0x0c98, 0x06b0,
X 0x03e0, 0x01c0, 0x0080};
END_OF_FILE
if test 249 -ne `wc -c <'xdvi_curs.h'`; then
echo shar: \"'xdvi_curs.h'\" unpacked with wrong size!
fi
# end of 'xdvi_curs.h'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330
Moderator of comp.sources.x
More information about the Comp.sources.x
mailing list