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