v04i069: xpic -- pic previewer for X11, Part04/15

Dan Heller argv at island.uu.net
Fri Jul 21 05:16:38 AEST 1989


Submitted-by: Mark Moraes <moraes at ai.toronto.edu>
Posting-number: Volume 4, Issue 69
Archive-name: xpic/part04



#! /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 4 (of 15)."
# Contents:  xpic/Imakefile xpic/arc.c xpic/defs.h xpic/hash.c
#   xpic/make.out xpic/obj_circ.c xpic/obj_ell.c xpic/test/rayan.ps
#   xpic/test/testtext.ps
# Wrapped by moraes at neat.ai on Thu Jul 13 22:36:07 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xpic/Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/Imakefile'\"
else
echo shar: Extracting \"'xpic/Imakefile'\" \(5800 characters\)
sed "s/^X//" >'xpic/Imakefile' <<'END_OF_FILE'
X/* Using inlining with gcc means you must not use the -traditional flag */
XCC=gcc
X
X/*
X * We use a few math library functions - cos, sin, sqrt, atan2. On Suns with
X * SunOS3.5 or greater, and with gcc, it is possible to inline these calls for
X * considerable speed improvement, and reduction in binary size.
X */
X
X# For SunOS3.5, Sun3 with f68881 installed
X#INLINELIBM=/usr/lib/f68881.il
X
X# For SunOS4.0, Sun3 with f68881 installed
X#INLINELIBM=/usr/lib/f68881/libm.il
X
X#ifdef CSRIToronto
X# For a machine with a 68881 using gcc - ../fastmath is where we keep
X# our inline math library for gcc. Collect that by anonymous ftp from
X# ai.toronto.edu:pub/moraes/fastmath.tar.Z
XINLINELIBM=-I../fastmath
X#endif /* CSRIToronto */
X
X# Where are the HP widgets - this is used with a -I option. If you have them
X# installed.
XXWSRC=$(CONTRIBSRC)/widgets/Xhp
XXWINC=-I$(XWSRC)
X
X# Note - You need the HP widgets (Xw) for the X11 Toolkit
X# These should be defined in an Imake.tmpl - except that the 
X# normal Imake.tmpl insists on these being compiled in the 
X# X directory tree.
X#XWLIB=$(XWSRC)/Xw/libXw.a
XXWLIB=$(USRLIBDIR)/libXw.a
X
X# The documents go in $(DOCDIR)/xpic - see the install target. 
X# At CSRI, we use a logical link to the source, so we don't 
X# install this. You must still keep this accurate, because 
X# it's put into the man page. Change the install target appropriately.
XDOCDIR=/local/doc/X11
X# the directory in which xpic saves the current buffer 
X# in case it dies on a signal
XDUMPDIR=/tmp
X
X# -DXWINDOWS is used by the filename completion code is ask.c and util.c
X# to include the Xos.h header file if compiled in an X program for
X# greater portability.
X# -DMAGIC will include code that puts a '#! $(BINDIR)/xpic'
X# header on the saved xpic files, and make them executable, so
X# you can just execute the saved xpic file and it starts up
X# xpic.
X# -DFASTARCS means your X server can draw arcs fast. Do *NOT* define this
X# for the MIT R3 sample server running on anything less than a 
X# MIPS-based workstation.
X# -DDEBUG turns on debugging output - do you really want that?!
X# -DDRAWBBOX is also for debugging - it draws the bounding box
X# of all gels.
X# -DGRAB should be defined if XtAddGrab and XtRemoveGrab can be 
X# made to work in Minibuf.c and input.c - I can't seem to get them
X# to work.
X# -DTYPEOUT includes the typeout code
XDEFINES = -DXWINDOWS -DMAGIC -DTYPEOUT # -DDEBUG
X
X# Define USLEEP if your system lacks a usleep (eg) Ultrix.
XUSLEEP=usleep.o
X
X########################################################################
X# You should not have to modify the rest of this file
X
XCDEBUGFLAGS = -O
XINCLUDES =  $(XWINC) -I$(TOP) -Ibitmaps $(INLINELIBM)
XXPICLIBDIR=$(LIBDIR)/xpic
X
X# Sigh - we use sin(), cos(), atan2() for arrow, and for ellipses
X# If inlining is chosen (see INLINELIBM), then the mathlib on won't be
X# used, saving a whopping 55K on Suns.
XMATHLIB=-lm
X
X# /usr/lib/debug/malloc.o is Sun's debugging malloc() - it
X# provides the malloc_debug() and malloc_verify() calls.
X# malloc.o is a first-fit malloc with debugging ASSERTs. Finds
X# heap corruption fast. Not defining this will use libc.
X#MALLOC = /usr/lib/debug/malloc.o
X#MALLOC = malloc.o
XMALLOC = 
X
XOBJS1 = main.o windows.o xpic.o handlers.o input.o  \
X	event.o grid.o error.o spline.o arrow.o newfonts.o \
X	util.o gels.o null.o obj_line.o obj_spline.o obj_text.o \
X	obj_box.o obj_circ.o obj_ell.o obj_block.o obj_elem.o \
X	updown.o text.o isqrt.o ask.o xtypeout.o Minibuf.o Window.o \
X	arc.o box.o focus.o line.o $(USLEEP)
X
XSRCS1 = main.c windows.c xpic.c handlers.c input.c  \
X	event.c grid.c error.c spline.c arrow.c newfonts.c \
X	util.c gels.c null.c obj_line.c obj_spline.c obj_text.c \
X	obj_box.c obj_circ.c obj_ell.c obj_block.c obj_elem.c \
X	updown.c text.c isqrt.c ask.c xtypeout.c Minibuf.c Window.c \
X	arc.c box.c focus.c line.c
X
XOBJS2 = x2pic.o hash.o
XSRCS2 = x2pic.c hash.c
X
XOBJS3 = x2ps.o hash.o
XSRCS3 = x2ps.c hash.c
X
XOBJS4 = x2tpic.o xtp.o hash.o
XSRCS4 = x2tpic.c xtp.c hash.c
X
XPROGRAMS = xpic x2ps x2pic x2tpic
X
X.SUFFIXES: .manX .man
X
X.manX.man:
X	sed -e 's?DOCDIR?$(DOCDIR)/xpic?g'\
X	    -e 's?XPICLIBDIR?$(XPICLIBDIR)?g' $*.manX > $*.man
X
XComplexProgramTarget_1(xpic,$(MYXTSTUFF) $(MALLOC) $(XWLIB) $(XTOOLLIB) $(XLIB),$(MATHLIB))
X/* Imake rules allow for only 3 SRCS */
XSRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4)
X
XSingleProgramTarget(x2pic,$(OBJS2),,)
XInstallProgram(x2pic, $(BINDIR))
XInstallManPage(x2pic, $(MANDIR))
X
XSingleProgramTarget(x2ps,$(OBJS3),,$(MATHLIB))
XInstallProgram(x2ps, $(BINDIR))
XInstallManPage(x2ps, $(MANDIR))
X
XSingleProgramTarget(x2tpic,$(OBJS4),,)
XInstallProgram(x2tpic, $(BINDIR))
XInstallManPage(x2tpic, $(MANDIR))
X
XInstallScript(x2tex, $(BINDIR))
XInstallManPage(x2tex, $(MANDIR))
X
Xlint:
X	(lint -abz $(SRCS1) -lXw -lXt -lX11 -lm $(LINTFLAGS); \
X	lint -abz $(SRCS2) $(LINTFLAGS); \
X	lint -abz $(SRCS3) -lm $(LINTFLAGS); \
X	lint -abz $(SRCS4) $(LINTFLAGS)) | \
X	./xlint
X
Xclean::
X	$(RM) tune.h.new xpic.man x2ps.man x2pic.man x2tpic.man x2tex.man
X
Xid: tags
X	mkid *.[ch]
X
Xinstall::
X	-mkdir $(XPICLIBDIR)
X	$(INSTALL) -c $(INSTAPPFLAGS) x2ps.pro $(XPICLIBDIR)
X	$(INSTALL) -c $(INSTAPPFLAGS) x2ps.tra $(XPICLIBDIR)
X	-mkdir $(XPICLIBDIR)/fontdesc
X	$(INSTALL) -c $(INSTAPPFLAGS) fontdesc/xpic $(XPICLIBDIR)/fontdesc
X	$(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2pic $(XPICLIBDIR)/fontdesc
X	$(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2tpic $(XPICLIBDIR)/fontdesc
X	$(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2ps $(XPICLIBDIR)/fontdesc
X
Xinstall::
X	-rm -r $(DOCDIR)/xpic
X	-cp -r doc $(DOCDIR)/xpic
X	
Xtar:
X	cd ..; tar cvfX - xpic/ExcludeFiles xpic | compress > xpic.tar.Z
X
Xtune.h: Makefile
X	echo \#define LIBDIR \"$(XPICLIBDIR)\" > tune.h.new
X	echo \#define PROGRAMNAME \"$(BINDIR)/xpic\" >> tune.h.new
X	echo \#define DUMPDIR \"$(DUMPDIR)\" >> tune.h.new
X	-cmp -s tune.h.new tune.h || cp tune.h.new tune.h
END_OF_FILE
if test 5800 -ne `wc -c <'xpic/Imakefile'`; then
    echo shar: \"'xpic/Imakefile'\" unpacked with wrong size!
fi
# end of 'xpic/Imakefile'
fi
if test -f 'xpic/arc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/arc.c'\"
else
echo shar: Extracting \"'xpic/arc.c'\" \(4811 characters\)
sed "s/^X//" >'xpic/arc.c' <<'END_OF_FILE'
X#ifndef FASTARCS
X
X#include <X11/Xlib.h>
X#include <math.h>
X
X/*
X * The R3 miarc.c code, which is used to draw arcs in the X server is very
X * slow, on Suns and uVaxen at least. (It uses iterative solution of
X * transcendentals to try to be faithful to the protocol) Instead, we use a
X * fast approximation that computes upto MAXPOINTS points on an arc and draws
X * a lines between them. Two calls each to sin(), cos(), and some floating
X * point math (could probably be done in fixed point or integer if you don't
X * have a math chip). These arcs don't follow the X protocol precisely, but
X * look reasonable.
X */
X/* Author: D. A. Cahlander, <dac at earth.cray.com> 89/02/21 */
X/*
X *  Last Modified: Mark Moraes, <moraes at csri.toronto.edu> 89/03/23 to
X *  generalize for elliptical arc drawing as a plug compatible
X *  substitute for Xlib XDrawArc()/XFillArc()/XDrawArcs()/XFillArcs()
X */
X
X/* Basic idea: By representing a ellipse as:
X
X        x = a * cos(t)
X        y = b * sin(t)
X
X   t can be divided into a small number of lines and represent the arc to
X   "display precision" with 15-20 lines.  (More than 20 if it was a large
X   arc.)
X
X        let dt be the delta angle
X        dc = cos(dt)
X        ds = sin(dt)
X
X        x1     dc  -ds    x0
X            =          x
X        y1     ds   dc    y0
X
X   or
X        x(i+1) = dc*x(i) - ds*y(i)
X        y(i+1) = ds*x(i) + dc*y(i)
X
X   with the actual (x,y) being:
X
X        x = xc + x(i)
X        y = yc + y(i)
X */
X
X
X#define MAXPOINTS 99
X
Xstatic drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, fill)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
Xint fill;
X{
X	XPoint	points[MAXPOINTS + 2];
X	int	npoints;
X	int	i;
X	double	xc, yc;
X	double	ang;
X#ifdef ELLIPSE_WITHIN_BBOX
X	double	delta;
X#endif /* ELLIPSE_WITHIN_BBOX */
X	double	t, xt, yt, dc, ds;
X	double	xr, yr;
X
X#define DEG_180  (180*64)
X#define DEG_360  (360*64)
X#define DEG_720  (720*64)
X
X	if (angle2 > DEG_360)
X		angle2 = DEG_360;
X
X	/*
X	 * compute number of points needed for "good" display precision 
X	 */
X	npoints = M_PI * sqrt((double) (width + height) / 2.0);
X	npoints = npoints < 8 ? 8 : npoints;
X	npoints = (npoints * ((angle2 < 0) ? -angle2 : angle2) + DEG_720 - 1)
X	 / DEG_360;
X	npoints = npoints > MAXPOINTS ? MAXPOINTS : npoints;
X	/* angle between polygon points */
X	ang = angle2 * M_PI / (DEG_180 * (npoints - 1));
X	dc = cos(ang);
X	ds = - sin(ang);
X	
X	if (angle1 == 0) {
X		xt = 1.0;
X		yt = 0.0;
X	} else {
X		ang = angle1 * M_PI / DEG_180;	/* start angle vector */
X		xt = cos(ang);
X		yt = - sin(ang);
X	}
X
X#ifdef ELLIPSE_WITHIN_BBOX
X	/*
X	 * Warning - possibly non-portable code. Uses internal details of GC
X	 * struct
X	 */
X	delta = gc->values.line_width / 2.0;
X#endif /* ELLIPSE_WITHIN_BBOX */
X	
X	/* radius of arc */
X	xr = width / 2.0;
X	yr = height / 2.0;
X
X	/* center of arc */
X	xc = x1 + xr;
X	yc = y1 + yr;
X
X#ifdef ELLIPSE_WITHIN_BBOX
X	xr = (xr > delta) ? xr - delta : delta;
X	yr = (yr > delta) ? yr - delta : delta;
X#endif /* ELLIPSE_WITHIN_BBOX */
X
X	i = 0;
X	
X	/*
X	 * Warning - possibly non-portable code. Uses internal details of GC
X	 * struct
X	 */
X	if (fill && angle2 != DEG_360 && gc->values.arc_mode == ArcPieSlice) {
X		points[i].x = xc;
X		points[i].y = yc;
X		i++;
X	}
X	
X	for (; i < npoints; i ++) {	/* compute polygon points */
X		points[i].x = xc + xr * xt + (xt >= 0. ? .5 : -.5);
X		points[i].y = yc + yr * yt + (yt >= 0. ? .5 : -.5);
X		t = dc * xt - ds * yt;		/* rotate vector */
X		yt = ds * xt + dc * yt;
X		xt = t;
X	}
X	
X	if (fill)
X		XFillPolygon(dpy, d, gc, points, npoints, Convex,
X		 CoordModeOrigin);
X	else
X		XDrawLines(dpy, d, gc, points, npoints, CoordModeOrigin);
X#undef DEG_180
X#undef DEG_360
X#undef DEG_720
X}
X
XXDrawArc(dpy, d, gc, x1, y1, width, height, angle1, angle2)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
X{
X	drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, 0);
X}
X
XXDrawArcs(dpy, d, gc, arcs, n_arcs)
XDisplay *dpy;
XDrawable d;
XGC gc;
XXArc *arcs;
Xint n_arcs;
X{
X	register XArc *arcp;
X
X	for(arcp = arcs; n_arcs > 0; n_arcs--)
X		drawarc(dpy, d, gc, (int) (arcp->x), (int) (arcp->y),
X		 (unsigned int) (arcp->width), (unsigned int) (arcp->height),
X		 (int) (arcp->angle1), (int) (arcp->angle2), 0);
X}
X
XXFillArc(dpy, d, gc, x1, y1, width, height, angle1, angle2)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
X{
X	drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, 1);
X}
X
XXFillArcs(dpy, d, gc, arcs, n_arcs)
XDisplay *dpy;
XDrawable d;
XGC gc;
XXArc *arcs;
Xint n_arcs;
X{
X	register XArc *arcp;
X
X	for(arcp = arcs; n_arcs > 0; n_arcs--)
X		drawarc(dpy, d, gc, (int) (arcp->x), (int) (arcp->y),
X		 (unsigned int) (arcp->width), (unsigned int) (arcp->height),
X		 (int) (arcp->angle1), (int) (arcp->angle2), 1);
X}
X#endif /* FASTARCS */
END_OF_FILE
if test 4811 -ne `wc -c <'xpic/arc.c'`; then
    echo shar: \"'xpic/arc.c'\" unpacked with wrong size!
fi
# end of 'xpic/arc.c'
fi
if test -f 'xpic/defs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/defs.h'\"
else
echo shar: Extracting \"'xpic/defs.h'\" \(5138 characters\)
sed "s/^X//" >'xpic/defs.h' <<'END_OF_FILE'
X#ifndef __XPIC_DEFS_H__
X#define __XPIC_DEFS_H__
X/*
X *  Some basic functions
X */
X#ifndef MAX
X#define MAX(x,y)	(((x) > (y)) ? (x) : (y))
X#endif
X#ifndef MIN
X#define MIN(x,y)	(((x) < (y)) ? (x) : (y))
X#endif
X#ifndef ABS
X#define ABS(x)		(((x) >= 0) ? (x) : -(x))
X#endif
X#ifndef SGN
X#define SGN(x)		(((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
X#endif
X/*
X *  Modulo function giving non-negative result
X */
X#ifndef IMOD
X#define IMOD(x,y)	(((x) % (y)) >= 0 ? ((x) % (y)) : ((x) % (y)) + (y))
X#endif
X
X/*
X *  Range checking - between lo & hi, inclusive
X */
X#define IN_RANGE(x, lo, hi)	((lo) <= (x) && (x) <= (hi))
X
X/*
X *  Two different strings are often different on the first char.
X */
X#define STREQ(s1, s2)	((*s1)==(*s2) && strcmp(s1, s2) == 0)
X#define STRLT(s1, s2)	(strcmp(s1, s2) < 0)
X#define STRGT(s1, s2)	(strcmp(s1, s2) > 0)
X
X#define BOOL		int
X
X#define YES		1
X#define NO		0
X#define ABORT	-1		/* Returned by the get_input routine */
X
X#ifndef TRUE
X#define TRUE	1
X#endif
X#ifndef FALSE
X#define FALSE	0
X#endif
X
X#define MAXSTR			64
X
X/* 'snap' rounds x to the nearest number divisible by dx */
X#define snap(x, dx)	(((int) (((x) + (dx / 2)) / dx)) * dx)
X
X/*
X *  The basic unit of scale is the separation of the grid points on the
X *  screen. Crosses are spaced every five grid points. I'm assuming the
X *  crosses to be 0.5 inches apart, and determine sizes from that by
X *  calculation. This simplifies drawing and re-scaling, I hope. It also
X *  allows pictures displayed on a high-resolution screen to be displayed
X *  on a screen of different resolution without changing the "snap". The
X *  use of that bizarre unit - the inch - is purely because that's how
X *  most of us still think of paper sizes.
X */
X
X#define DEFAULTSPACING		8		/*
X									 * For high resolution displays, it is
X									 * better to use 10, for low res, try 6
X									 */
X#define MINSPACING			2
X
X/* Letter size LaserWriter(tm) imaging area size, actually */
X#define DEFAULTPAGEHEIGHT	105		/* inches * 10 :-) */
X#define DEFAULTPAGEWIDTH	80
X#define MINPAGEHEIGHT		60		/* Paper can't get smaller than 6x6" */
X#define MINPAGEWIDTH		60
X
X/* 
X *  Defaults almost fill the screen of a Sun-3/50 Gives a nice round scale
X *  factor, with 8 pixel spacing of grid points, 40 pixel spacing of the
X *  crosses. Note that fonts are scaled for this grid spacing.
X */
X
X#define DEFAULTPICHEIGHT	DEFAULTPAGEHEIGHT * DEFAULTSPACING;
X#define DEFAULTPICWIDTH		DEFAULTPAGEWIDTH * DEFAULTSPACING;
X
X
X/*
X *  This font MUST be available, or else xpic won't start up. Doesn't
X *  really matter what it is though
X */
X
X#define DEFAULT_FONT		"fixed"
X
X#define INC_VERTS	128	/* The blocks in which the verts buffer is increased */
X
X/* Increment in which a Buf increments itself */
X#define BUF_CHUNK 128
X
X/* Various types of gels */
X#define CELL	0
X#define LINE	1
X#define SPLINE	2
X#define BOX		3
X#define CIRCLE	4
X#define ELLIPSE	5
X#define TEXT	6
X/* Pseudo-objects - we use them during edit operations */
X#define BLOCK	7
X#define ELEMENT	8
X
X/* Using one nybble per attribute should leave enough room for expansion */
X#define getlinestyle(x)		(x & 0x000f)
X#define SOLID	0x0000
X#define DOTTED	0x0001
X#define SDASH	0x0002
X#define LDASH	0x0003
X#define DDASH	0x0004
X#define NSTYLES	5
X
X#define getlinearrow(x)		((x & 0x00f0) >> 4)
X#define NO_ARROW	0x0000
X#define ST_ARROW	0x0010
X#define EN_ARROW	0x0020
X
X/* !!
X *  Implementing this implies taking care of object ordering - what gets
X *  drawn on top of what. Not yet done.
X */
X#define getfillstyle(x)		((x & 0x0f00) >> 8)
X#define EMPTY	0x0000
X#define GRAY0	0x0000
X#define GRAY1	0x0100
X#define GRAY2	0x0200
X#define GRAY3	0x0300
X#define GRAY4	0x0400
X#define GRAY5	0x0500
X#define GRAY6	0x0600
X#define GRAY7	0x0700
X#define GRAY8	0x0800
X#define GRAY9	0x0900
X#define NFILLSTYLES	10
X
X/* Text alignment is in two  bits */
X#define HALIGN	0x3000
X#define gettext_halign(x)	((x & HALIGN) >> 12)
X#define CENTRE	0x0000
X#define LJUST	0x1000
X#define RJUST	0x2000
X
X#define VALIGN	0xc000
X#define gettext_valign(x)	((x & VALIGN) >> 14)
X#define MIDLINE	0x0000
X#define TOPLINE	0x4000
X#define BOTLINE	0x8000
X
X/* Marks the elements in a gel list which have been selected and discarded */
X#define SELECTED 0x0001
X/* Marks a hilited gel - makes unhilite safer! */
X#define HILITED	 0x0002
X
X/* Cell.saved flags */
X#define SAVED		0x00
X#define MODIFIED	0x01
X#define NEWFILE		0x10
X
X/* These are or'ed with the event codes to give the event type */
X#define START_MODE	0x100
X#define END_MODE	0x200
X#define DRAG_MODE	0x300
X#define ASK_MODE	0x400
X
X/* Event codes */
X#define REDRAW		0x01
X#define MOTION		0x02
X#define LEFT		0x03
X#define RIGHT		0x04
X#define MIDDLE		0x05
X
X/* Various editing functions - either BLOCK or ELEMENT */
X#define COPY		1
X#define MOVE		2
X#define DELETE		3
X#define	PASTE		4
X#define GET			5
X#define PUT			6
X#define ADJUST		7
X#define ROTATE		8
X#define SCALE		9
X#define CHANGE_ATTRIBUTE	10
X
X/* DrawGel can draw a Gel in one of these modes */
X#define DRAW		1
X#define ERASE		2
X#define INVERT		3
X#define HILITE		4
X
X#define MAKEPATTERN(style, dashlist) \
X	((style).pattern = (dashlist), (style).len = strlen(dashlist))
X
X#endif /* __XPIC_DEFS_H__ */ /* Do not add anything after this line */
END_OF_FILE
if test 5138 -ne `wc -c <'xpic/defs.h'`; then
    echo shar: \"'xpic/defs.h'\" unpacked with wrong size!
fi
# end of 'xpic/defs.h'
fi
if test -f 'xpic/hash.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/hash.c'\"
else
echo shar: Extracting \"'xpic/hash.c'\" \(5105 characters\)
sed "s/^X//" >'xpic/hash.c' <<'END_OF_FILE'
X/* 
X *  A simple insertion-only hash routine for managing a single hash
X *  table. Heavily modified and tuned from a piece of code by Ron Unrau
X *  (ron at godzilla.ele.toronto.edu). Thanks Ron! It could be easily
X *  generalized to do multiple hashtables simply by having InitHash
X *  return a pointer to HashTable rather than maintain state in static
X *  variables, and have the Insert and Search routines take that
X *  pointer. Ron's hash function is pretty good for strings - it seems
X *  to stand up well to small dense tables. 
X */
X/*
X	Compile with -DTEST to make it a standalone test program.
X	Compile with -DPRINTHASH for information on the hash function
X	Compile with -DHSTATS for information on collisions
X */
X#ifndef lint
Xstatic char *rcsid = "$Header: hash.c,v 1.2 88/08/31 23:42:21 moraes Exp $";
X#endif
X
X#include <stdio.h>
X#ifdef XPIC
X#include <X11/Xos.h>
X#endif
X
X#define STREQ(s1, s2)	((*s1)==(*s2) && strcmp(s1, s2) == 0)
X/* A hash table smaller than this is pretty worthless */
X#define MINSIZE 17
X#define MAXSTR 128
X
Xextern char *malloc();
Xextern char *realloc();
Xextern char *calloc();
X
X/*
X *  The calling routines must malloc space for the key and datum - the
X *  hash table just stores pointers
X */
Xtypedef struct {
X	char *key;
X	char *datum;
X} HashRec;
X
Xtypedef struct {
X	HashRec *hashtable;
X	int hashsize;
X	int hashprobe;
X} HashTable;
X
Xstatic HashRec *hashtable = NULL; 
Xstatic int hashsize;
Xstatic int hashprobe;
Xextern char *calloc();
Xextern char *malloc();
X
Xstatic hashindex (s)
Xregister char *s;
X{
X	register int shift = 0;
X	register int index = 0;
X
X#ifdef PRINTHASH
X	(void) fprintf(stderr, "\"%s\" hashes to ", s);
X#endif
X	while (*s != '\0') {
X		index ^= *(s++) << shift;
X		shift = (shift == 0) ? 8 : 0;
X	}
X
X#ifdef PRINTHASH
X	(void) fprintf(stderr, "%d    ", index);
X#endif
X	return index;
X}
X
X
X/* size should be a prime number */
XHashInit(size)
X{
X	hashsize = (size < MINSIZE) ? MINSIZE : size;
X	hashprobe = hashsize / 3;
X	if (hashprobe * 3 == hashsize)
X		hashprobe--;
X	if (hashprobe % 2 == 0)
X		hashprobe--;
X#ifdef HSTATS
X	(void) fprintf(stderr, "size = %d      probe = %d\n", hashsize, hashprobe);
X#endif
X	if (hashtable)
X		hashtable = (HashRec *) realloc((char *) hashtable, 
X		 (unsigned) (hashsize * sizeof(HashRec)));
X	else 
X		hashtable = (HashRec *) calloc((unsigned) size, sizeof(HashRec));
X	if (hashtable)
X		return;
X	else {
X		(void) fprintf(stderr, "Couldn't allocate %d bytes for hash table\n",
X		 size * sizeof(HashRec));
X		exit(-1);
X	}
X}
X
X/*
X *  Will insert datum keyed by key in the table if key isn't already in
X *  the table - otherwise, it will replace teh datum already in the
X *  table for key with the new datum. It doesn't bother to free the old
X *  datum, so this is a search of garbage, if the stuff was malloced.
X *  Maybe we should return the old datum, so the caller can free it?
X */
XHashInsert (key, datum)
Xchar *key;
Xchar *datum;
X{
X	register int hashval;
X	register int index;
X	register HashRec *hashptr = hashtable;
X	register int countdown = hashsize;
X
X	hashval = hashindex (key);
X	index = hashval % hashsize;
X	hashptr += index;
X	while (hashptr->key && !STREQ(hashptr->key, key) && --countdown) {
X		index = (index + hashprobe) % hashsize;
X		hashptr = hashtable + index;
X	}
X	if (!hashptr->key) {
X		hashptr->key = key;
X		hashptr->datum = datum;
X#ifdef HSTATS
X		(void) fprintf(stderr, "%d probes\n", hashsize - countdown);
X#endif
X	} else if (countdown) {
X		/* replace current value with new one */
X		hashptr->datum = datum;
X#ifdef HSTATS
X		(void) fprintf(stderr, "%d probes - replacing\n", hashsize-countdown);
X#endif
X	} else {
X		(void) fprintf(stderr, "Can't insert in hash table - help\n");
X		exit(1);
X	}
X}
X
Xchar *HashSearch (key)
Xchar *key;
X{
X	register int hashval;
X 	register int index;
X	register HashRec *hashptr = hashtable;
X	register int countdown = hashsize;
X
X	hashval = hashindex (key);
X	index = hashval % hashsize;
X
X	hashptr += index;
X	while (hashptr->key && !STREQ (hashptr->key, key) && --countdown) {
X		index = (index + hashprobe) % hashsize;
X		hashptr = hashtable + index;
X	}
X#ifdef HSTATS
X	(void) fprintf(stderr, "%d probes - %s\n", hashsize - countdown, 
X	 (hashptr->key && countdown) ? "found" : "not found");
X#endif
X	if (hashptr->key && countdown)
X		return (hashptr->datum);
X	else
X		return((char *) 0);
X}
X
Xchar *strsave(s)
Xchar *s;
X{
X	char *s1 = malloc((unsigned) (strlen(s) + 1));
X
X	if (s1)
X		(void) strcpy(s1, s);
X	return(s1);
X}
X
X
X#ifdef TEST
X#define prompt() if(prompt_p) printf(":"); else ;
Xmain()
X{
X 	char s1[8], s2[MAXSTR], s3[MAXSTR];
X	char *result;
X	int prompt_p;
X
X	HashInit(128);
X	prompt_p = isatty(fileno(stdin));
X	prompt();
X	while(scanf(" %s %s", s1, s2) == 2) {
X		switch (*s1) {
X		case 'a':
X			scanf(" %s", s3);
X			HashInsert(strsave(s2), strsave(s3));
X			break;
X		case 's':
X			if (result = HashSearch(s2))
X				printf("found %s\n", result);
X			else
X				printf("no match\n");
X			break;
X		case 'i':
X			HashInit(atoi(s2));
X			break;
X		default:
X			printf("'a string1 string2' inserts datum (string2) keyed by string1\n");
X			printf("'s string1' prints the datum associated with string1 if any\n");
X			break;
X		}
X		prompt();
X	}
X}
X#endif
END_OF_FILE
if test 5105 -ne `wc -c <'xpic/hash.c'`; then
    echo shar: \"'xpic/hash.c'\" unpacked with wrong size!
fi
# end of 'xpic/hash.c'
fi
if test -f 'xpic/make.out' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/make.out'\"
else
echo shar: Extracting \"'xpic/make.out'\" \(4879 characters\)
sed "s/^X//" >'xpic/make.out' <<'END_OF_FILE'
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c main.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c windows.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c xpic.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c handlers.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c input.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c event.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c grid.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c error.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c spline.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c newfonts.c
Xnewfonts.c: In function addfont:
Xnewfonts.c:186: warning: `addfont' was declared `extern' and later `static'
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c util.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c null.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_line.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_spline.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_text.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_box.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_circ.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_ell.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_block.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c obj_elem.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c updown.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c text.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c ask.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c xtypeout.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c Minibuf.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c arc.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c box.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c focus.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c line.c
Xrm -f xpic
Xgcc -o xpic main.o windows.o xpic.o handlers.o input.o   event.o grid.o error.o spline.o arrow.o newfonts.o  util.o gels.o null.o obj_line.o obj_spline.o obj_text.o  obj_box.o obj_circ.o obj_ell.o obj_block.o obj_elem.o  updown.o text.o isqrt.o ask.o xtypeout.o Minibuf.o Window.o  arc.o box.o focus.o line.o usleep.o   /local/lib/X11/libXw.a /local/lib/X11/libXt.a /local/lib/X11/libX11.a -O   -lm 
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c x2ps.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c hash.c
Xrm -f x2ps
Xgcc -o x2ps x2ps.o hash.o  -O   -lm 
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c x2pic.c
Xrm -f x2pic
Xgcc -o x2pic x2pic.o hash.o  -O    
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c x2tpic.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath  -DXPIC -DMAGIC -DTYPEOUT  -c xtp.c
Xrm -f x2tpic
Xgcc -o x2tpic x2tpic.o xtp.o hash.o  -O    
END_OF_FILE
if test 4879 -ne `wc -c <'xpic/make.out'`; then
    echo shar: \"'xpic/make.out'\" unpacked with wrong size!
fi
# end of 'xpic/make.out'
fi
if test -f 'xpic/obj_circ.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/obj_circ.c'\"
else
echo shar: Extracting \"'xpic/obj_circ.c'\" \(4942 characters\)
sed "s/^X//" >'xpic/obj_circ.c' <<'END_OF_FILE'
X/* $Header: obj_circ.c,v 1.4 89/02/23 02:47:56 xwindows Exp $ */
X/*
X *  The circle object routines
X */
X#include <math.h>
X
X#include "xpic.h"
X#include "windows.h"
X#include "spline.h"
X#include "gels.h"
X#include "draw.h"
X#include "input.h"
X#include "newfonts.h"
X#include "assert.h"
X
Xstatic int xmin, xmax, ymin, ymax;	/* Bounding box */
Xstatic int xc, yc, xr, yr;			/* centre, radius of circles, ellipse */
Xstatic int rad;						/* radius of circle */
X
Xcircle_event(evtype, mx, my)
X{
X	switch(evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case MIDDLE | START_MODE:
X	case REDRAW | START_MODE:
X	case RIGHT  | END_MODE:
X		break;
X	case MOTION | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		xr = mx - xc;
X		yr = my - yc;
X		rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X		if (rad == 0)
X			rad = mouseResolution;
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		break;
X	case LEFT | START_MODE:
X		xc = mx;
X		yc = my;
X		rad = mouseResolution;
X		drawingMode = END_MODE;
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		break;
X	case LEFT | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		xr = mx - xc;
X		yr = my - yc;
X		rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X		if (rad == 0)
X			rad = mouseResolution;
X		xmin = xc - rad;
X		xmax = xc + rad;
X		ymin = yc - rad;
X		ymax = yc + rad;
X		ellipse(picWin, xc, yc, rad, rad, gcNormal);
X		AddConicGel(&(CurrentCell->gelList), CIRCLE, xc, yc, rad, rad, 
X		 line_type | fill_type, xmin, ymin, xmax, ymax, lineThickness);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, gcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown CIRCLE mode %d", drawingMode);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "circle_event");
X}
X
X
Xcircle_abort()
X{
X	circle_event((MIDDLE | drawingMode), 0, 0);
X}
X	
X
Xcircle_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X	static Gel *circgel;
X	/*
X	 *  Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X	 *  REDRAW|START_MODE - these are taken care of in
X	 *  the adj_element routine.
X	 */
X	switch(evtype) {
X	case MOTION | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		xr = mx - xc;
X		yr = my - yc;
X		rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X		if (rad == 0)
X			rad = mouseResolution;
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		break;
X	case LEFT | START_MODE:
X		xc = ((Conic *)gel->data)->centre.x;
X		yc = ((Conic *)gel->data)->centre.y;
X		rad = ((Conic *)gel->data)->xrad;
X		circgel = gel;
X		drawingMode = END_MODE;
X		setwidth(tmpGcNormal, circgel->linewidth);
X		setwidth(tmpGcInvert, circgel->linewidth);
X		SETDASHES(tmpGcNormal, getlinestyle(circgel->attributes))
X		SETDASHES(tmpGcInvert, getlinestyle(circgel->attributes))
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		break;
X	case LEFT | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		xr = mx - xc;
X		yr = my - yc;
X		rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X		if (rad == 0)
X			rad = mouseResolution;
X		xmin = xc - rad;
X		xmax = xc + rad;
X		ymin = yc - rad;
X		ymax = yc + rad;
X		ellipse(picWin, xc, yc, rad, rad, tmpGcNormal);
X		AddConicGel(&(CurrentCell->gelList), CIRCLE, xc, yc, rad, rad, 
X		 circgel->attributes, xmin, ymin, xmax, ymax, circgel->linewidth);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = circgel;
X		circgel = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		GelDraw(circgel, DRAW);
X		(void) PushUnderUndo(&(CurrentCell->gelList), circgel,
X		 CurrentCell->undo);
X		circgel = NULL;
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | START_MODE:
X		ClearGelFlags(CurrentCell->gelList);
X		break;
X	case REDRAW | END_MODE:
X		ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown mode %d in circle_adj", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "circle_adj");
X}
X
X/*
X * Finds distance of point from an circle. This is the distance to the
X * intersection of the line from the point to the centre of the circle.
X */
Xint
Xcircle_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X	int dist;
X	Conic *conic = (Conic *) gel->data;
X	double r = conic->xrad;
X	int dy = (yp - conic->centre.y);
X	int dx = (xp - conic->centre.x);
X
X	if (dx == 0) {
X		dist = ABS(dy) - conic->yrad;
X	} else if (dy == 0) {
X		dist = ABS(dx) - conic->xrad;
X	} else {
X		dist = sqrt((double) (dx * dx + dy * dy)) - r;
X	}
X	dist = ABS(dist);
X	return(dist);
X}
END_OF_FILE
if test 4942 -ne `wc -c <'xpic/obj_circ.c'`; then
    echo shar: \"'xpic/obj_circ.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_circ.c'
fi
if test -f 'xpic/obj_ell.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/obj_ell.c'\"
else
echo shar: Extracting \"'xpic/obj_ell.c'\" \(5859 characters\)
sed "s/^X//" >'xpic/obj_ell.c' <<'END_OF_FILE'
X/* $Header: obj_ell.c,v 1.3 89/02/23 02:48:02 xwindows Exp $ */
X/*
X *  The ellipse object routines
X */
X#include <math.h>
X
X#include "xpic.h"
X#include "windows.h"
X#include "gels.h"
X#include "draw.h"
X#include "assert.h"
X
Xstatic int x_1, y_1, x_2, y_2;			/* Corners of box, ellipse, ends of line */
Xstatic int xmin, xmax, ymin, ymax;	/* Bounding box */
Xstatic int xc, yc, xr, yr;			/* centre, radius of circles, ellipse */
X
Xellipse_event(evtype, mx, my)
X{
X	switch(evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case MIDDLE | START_MODE:
X	case REDRAW | START_MODE:
X	case RIGHT  | END_MODE:
X		break;
X	case MOTION | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xc = (x_2 + x_1) / 2;
X		yc = (y_2 + y_1) / 2;
X		xr = ABS(x_2 - xc);
X		yr = ABS(y_2 - yc);
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		break;
X	case LEFT | START_MODE:
X		x_1 = x_2 = xc = mx;
X		y_1 = y_2 = yc = my;
X		xr = yr = 0;
X		drawingMode = END_MODE;
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		break;
X	case LEFT | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xc = (x_2 + x_1) / 2;
X		yc = (y_2 + y_1) / 2;
X		xr = ABS(x_2 - xc);
X		yr = ABS(y_2 - yc);
X		xmin = MIN(x_1, mx);
X		xmax = MAX(x_1, mx);
X		ymin = MIN(y_1, my);
X		ymax = MAX(y_1, my);
X		ellipse(picWin, xc, yc, xr, yr, gcNormal);
X		AddConicGel(&(CurrentCell->gelList), ELLIPSE, xc, yc, xr, yr,
X		 line_type | fill_type, xmin, ymin, xmax, ymax, lineThickness);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, gcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Unknown ELLIPSE mode %d", drawingMode);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "ellipse_event");
X}
X
X
Xellipse_abort()
X{
X	ellipse_event((MIDDLE | drawingMode), 0, 0);
X}
X	
X
Xellipse_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X	static Gel *ellgel;
X	/*
X	 *  Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X	 *  REDRAW|START_MODE - these are taken care of in
X	 *  the adj_element routine.
X	 */
X	switch(evtype) {
X	case MOTION | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xc = (x_2 + x_1) / 2;
X		yc = (y_2 + y_1) / 2;
X		xr = ABS(x_2 - xc);
X		yr = ABS(y_2 - yc);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		break;
X	case LEFT | START_MODE:
X		GetBoxCorners(&x_1, &y_1, &x_2, &y_2, &gel->b_box, mx, my);
X		xc = (x_1 + x_2) / 2;
X		yc = (y_1 + y_2) / 2;
X		xr = ABS(x_2 - xc);
X		yr = ABS(y_2 - yc);
X		ellgel = gel;
X		drawingMode = END_MODE;
X		setwidth(tmpGcNormal, ellgel->linewidth);
X		setwidth(tmpGcInvert, ellgel->linewidth);
X		SETDASHES(tmpGcNormal, getlinestyle(ellgel->attributes))
X		SETDASHES(tmpGcInvert, getlinestyle(ellgel->attributes))
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		break;
X	case LEFT | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xc = (x_2 + x_1) / 2;
X		yc = (y_2 + y_1) / 2;
X		xr = ABS(x_2 - xc);
X		yr = ABS(y_2 - yc);
X		xmin = MIN(x_1, mx);
X		xmax = MAX(x_1, mx);
X		ymin = MIN(y_1, my);
X		ymax = MAX(y_1, my);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcNormal);
X		AddConicGel(&(CurrentCell->gelList), ELLIPSE, xc, yc, xr, yr, 
X		 ellgel->attributes, xmin, ymin, xmax, ymax, ellgel->linewidth);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = ellgel;
X		ellgel = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		GelDraw(ellgel, DRAW);
X		(void) PushUnderUndo(&(CurrentCell->gelList), ellgel,
X		 CurrentCell->undo);
X		ellgel = NULL;
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | START_MODE:
X		ClearGelFlags(CurrentCell->gelList);
X		break;
X	case REDRAW | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X		ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Unknown mode %d in ellipse_adj", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "ellipse_adj");
X}
X
X/*
X * Finds distance of point from an ellipse. This is taken as distance to the
X * intersection of the line from the point to the centre of the ellipse. It's
X * a fudge, because I don't know of a closed form solution to the problem of
X * finding the perpendicular distance of a point from an ellipse, and I really
X * don't want to iterate.
X */
Xint
Xellipse_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X	int dist;
X	Conic *conic = (Conic *) gel->data;
X	double a = conic->xrad;
X	double b = conic->yrad;
X	double slope;
X	int dy = (yp - conic->centre.y);
X	int dx = (xp - conic->centre.x);
X	double xm, ym;
X
X	if (dx == 0) {
X		dist = ABS(dy) - conic->yrad;
X		dist = ABS(dist);
X	} else if (dy == 0) {
X		dist = ABS(dx) - conic->xrad;
X		dist = ABS(dist);
X	} else {
X		slope = dy;
X		slope /= dx;
X		xm = 1.0 / sqrt(1.0 / (a * a) + (slope * slope) / (b * b));
X		if (dx < 0)
X			xm = -xm;
X		ym = slope * xm + conic->centre.y;
X		xm += conic->centre.x;
X		dist = sqrt((xp - xm) * (xp - xm) + (yp - ym) * (yp - ym));
X	}
X	return(dist);
X}
END_OF_FILE
if test 5859 -ne `wc -c <'xpic/obj_ell.c'`; then
    echo shar: \"'xpic/obj_ell.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_ell.c'
fi
if test -f 'xpic/test/rayan.ps' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/test/rayan.ps'\"
else
echo shar: Extracting \"'xpic/test/rayan.ps'\" \(5235 characters\)
sed "s/^X//" >'xpic/test/rayan.ps' <<'END_OF_FILE'
X%!
X%%Creator: root at bay.csri (Operator)
X%%Title: rayan.xpic (xpic)
X%%CreationDate: Wed May  4 23:51:39 1988
X%%Pages: 1
X%%DocumentFonts: (atend)
X%%BoundingBox: 28.8 28.8 561.6 669.6
X%	(in inches) at 0.4 0.4, width 7.4, height 8.9
X%%EndComments
X% Prolog for xpic to PostScript converter
X% Author: Mark Moraes
X% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp 
X%	%d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
X%	%d F - change font ROMAN, BOLD, ITALIC, SPECIAL
X%	%d S - change size (font size in points)
X%	(%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
X%	(%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
X%	(%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
X%	%d %d l - lineto
X%	%d %d m - moveto
X%	%d %d s - spline segment
X%	x - flush line, spline
X%	<wid> <ht> <x> <y> b - box
X%	<wid> <ht> <x> <y> e - ellipse
X%	%d ss - setscale
X%	%d W - change linewidth
Xsave 50 dict begin /xpic exch def
X/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
X% Set defaults
X/fontname /Times-Roman def
X/ptsize 12 def
X% xpic has 4 fonts R, B, I, S
X/nfonts 4 def
X/fonts /Times-Roman /Times-Bold /Times-Italic /Symbol nfonts array astore def
X% halign has the values for MIDLINE, TOPLINE, BOTLINE
X/halign 3 array def
X/s {rcurveto} def
X/x {stroke} def
X/l {lineto} def
X/m {moveto} def
X/b {
X	/ury exch def /urx exch def /lly exch def /llx exch def 
X	llx lly moveto urx lly lineto urx ury lineto 
X	llx ury lineto llx lly lineto stroke
X} def
X/mtrx matrix def
X/e {
X	/yc exch def /xc exch def /yrad exch def /xrad exch def
X	xc xrad add yc moveto
X	/savematrix mtrx currentmatrix def
X	xc yc translate
X	xrad yrad scale
X	0 0 1 0 360 arc
X	savematrix setmatrix stroke
X} def
X% The next three take the text string, and moveto the right horiz. position
X% leaving the string on the stack.
X/lj {} def
X/rj {dup stringwidth pop neg 0 rmoveto} def
X/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
X% And this is invoked after one of the three above, and 
X% computes the vert. pos, and then displays the string.
X/t {halign exch get 0 exch rmoveto show newpath} def
X% Store an array of patterns in /styles - a pattern is an array consisting 
X% of an array and an offset. Corresp to xpic patterns
X% solid, dotted, short-dashed, long-dashed, dot-dashed
X/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
X	5 array astore def
X% change style to arg.
X/D {stroke styles exch get aload pop setdash newpath} def
X/W {stroke setlinewidth newpath} def
X% fontbox takes a fontname of the stack, and returns an array
X% containing the values of the bottom line of the bounding box, the
X% mid line of the bounding box, and the top line of the bounding box
X% of that font, taken from the baseline, scaled to a font of size 1
X/fontbox {
X	findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
X	/ytop exch def pop /ybot exch def pop
X	/ymid ytop ybot sub 2 div def
X	0 ybot fm dtransform exch pop % botline
X	dup neg exch % midline - this works better than (ytop-ybot)/2!
X	0 ytop fm dtransform exch pop exch %topline
X	% now in the order midline, topline, botline.
X	3 array astore
X} def
X% fontboxes stores the fontbox of each of the fontnames in the 'fonts'
X% array
X/fontboxes nfonts array def
X0 1 nfonts 1 sub {
X	fontboxes exch dup fonts exch get fontbox put
X} for
X% select font
X/F {
X	dup fonts exch get /fontname exch def fontboxes exch get
X	/thisfontbox exch def SF 
X} def
X% set point size
X/S {/ptsize exch def SF} def
X% actually set font
X/SF {
X	fontname findfont ptsize curscale div scalefont setfont
X	thisfontbox aload pop
X	1 1 3 {
X		pop ptsize mul curscale div neg 3 1 roll
X	} for
X	halign astore pop
X} def
X% sets the scale to 72 / n, where n is on the stack, and stores the value
X% in curscale for font scaling
X/curscale 1 def
X/ss {/curscale exch 72 exch div dup dup scale def} def
X/land {8.5 72 mul curscale div 0 translate 90 rotate} def
XStartXpic
X%%EndProlog
X1 1 scale
X80 ss
X0 D
X215 352 m
X0 D
X224 349 m
X215 352 l
X224 356 l
X0 D
X215 352 m
X447 352 l
X0 D
X439 356 m
X447 352 l
X439 349 l
X0 D
X447 352 m
Xx
X2 D
X47 224 m
X279 80 l
X0 D
X275 88 m
X279 80 l
X270 81 l
X2 D
X279 80 m
Xx
X1 D
X79 120 m
X0 D
X82 130 m
X79 120 l
X74 128 l
X1 D
X79 120 m
X47 320 l
Xx
X575 640 m
X511 520 l
X599 592 l
Xx
X3 D
X599 696 m
X607 424 l
X535 528 l
X631 568 l
X583 512 l
X583 568 l
X639 512 l
Xx
X0 D
X88 88 439 656 e
X287 624 m
X383 488 l
X447 504 l
Xx
X279 584 m
X375 448 l
X439 464 l
Xx
X311 680 m
X407 544 l
X471 560 l
Xx
X239 528 m
X335 392 l
X399 408 l
Xx
X135 576 m
X351 576 l
X479 392 l
Xx
X223 664 m
X0 0 17 -2 52 -8 s
X34 -5 61 -24 80 -56 s
X18 -32 -8 -70 -80 -116 s
X-72 -45 -114 -33 -128 36 s
X-13 69 -2 116 32 140 s
X34 24 52 21 52 -8 s
X0 -29 17 -30 52 -4 s
X34 26 78 21 132 -16 s
X53 -37 58 -76 16 -116 s
X-42 -40 -30 -58 36 -56 s
X66 2 84 -25 52 -84 s
X-32 -58 -102 -94 -212 -108 s
X-109 -13 -164 8 -164 64 s
X0 56 -9 86 -28 92 s
X-18 5 -32 -20 -40 -76 s
X-8 -56 68 -116 228 -180 s
Xx
X2 F
X20 S
X423 496 m
X(This is more text) ce 0 t
X295 296 527 144 b
X12 S
X327 312 m
X(This is a box) ce 0 t
X0 F
X319 72 m
X(This is an ellipsis) ce 0 t
X164 44 331 76 e
X215 392 447 240 b
X%%Trailer
Xshowpage
X% Trailer for xpic to PostScript converter
X% $Header: x2ps.tra,v 1.1 87/11/21 20:33:03 moraes Exp $
Xxpic end restore
X%%DocumentFonts: Times-Roman Times-Italic Times-Bold Special
END_OF_FILE
if test 5235 -ne `wc -c <'xpic/test/rayan.ps'`; then
    echo shar: \"'xpic/test/rayan.ps'\" unpacked with wrong size!
fi
# end of 'xpic/test/rayan.ps'
fi
if test -f 'xpic/test/testtext.ps' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/test/testtext.ps'\"
else
echo shar: Extracting \"'xpic/test/testtext.ps'\" \(4867 characters\)
sed "s/^X//" >'xpic/test/testtext.ps' <<'END_OF_FILE'
X%!
X%%Creator: root at bay.csri (Operator)
X%%Title: testtext.xpic (xpic)
X%%CreationDate: Wed May  4 23:51:57 1988
X%%Pages: 1
X%%DocumentFonts: (atend)
X%%BoundingBox: 9 23.4 450 120.6
X%	(in inches) at 0.125 0.325, width 6.125, height 1.35
X%%EndComments
X% Prolog for xpic to PostScript converter
X% Author: Mark Moraes
X% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp 
X%	%d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
X%	%d F - change font ROMAN, BOLD, ITALIC, SPECIAL
X%	%d S - change size (font size in points)
X%	(%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
X%	(%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
X%	(%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
X%	%d %d l - lineto
X%	%d %d m - moveto
X%	%d %d s - spline segment
X%	x - flush line, spline
X%	<wid> <ht> <x> <y> b - box
X%	<wid> <ht> <x> <y> e - ellipse
X%	%d ss - setscale
X%	%d W - change linewidth
Xsave 50 dict begin /xpic exch def
X/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
X% Set defaults
X/fontname /Times-Roman def
X/ptsize 12 def
X% xpic has 4 fonts R, B, I, S
X/nfonts 4 def
X/fonts /Times-Roman /Times-Bold /Times-Italic /Symbol nfonts array astore def
X% halign has the values for MIDLINE, TOPLINE, BOTLINE
X/halign 3 array def
X/s {rcurveto} def
X/x {stroke} def
X/l {lineto} def
X/m {moveto} def
X/b {
X	/ury exch def /urx exch def /lly exch def /llx exch def 
X	llx lly moveto urx lly lineto urx ury lineto 
X	llx ury lineto llx lly lineto stroke
X} def
X/mtrx matrix def
X/e {
X	/yc exch def /xc exch def /yrad exch def /xrad exch def
X	xc xrad add yc moveto
X	/savematrix mtrx currentmatrix def
X	xc yc translate
X	xrad yrad scale
X	0 0 1 0 360 arc
X	savematrix setmatrix stroke
X} def
X% The next three take the text string, and moveto the right horiz. position
X% leaving the string on the stack.
X/lj {} def
X/rj {dup stringwidth pop neg 0 rmoveto} def
X/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
X% And this is invoked after one of the three above, and 
X% computes the vert. pos, and then displays the string.
X/t {halign exch get 0 exch rmoveto show newpath} def
X% Store an array of patterns in /styles - a pattern is an array consisting 
X% of an array and an offset. Corresp to xpic patterns
X% solid, dotted, short-dashed, long-dashed, dot-dashed
X/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
X	5 array astore def
X% change style to arg.
X/D {stroke styles exch get aload pop setdash newpath} def
X/W {stroke setlinewidth newpath} def
X% fontbox takes a fontname of the stack, and returns an array
X% containing the values of the bottom line of the bounding box, the
X% mid line of the bounding box, and the top line of the bounding box
X% of that font, taken from the baseline, scaled to a font of size 1
X/fontbox {
X	findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
X	/ytop exch def pop /ybot exch def pop
X	/ymid ytop ybot sub 2 div def
X	0 ybot fm dtransform exch pop % botline
X	dup neg exch % midline - this works better than (ytop-ybot)/2!
X	0 ytop fm dtransform exch pop exch %topline
X	% now in the order midline, topline, botline.
X	3 array astore
X} def
X% fontboxes stores the fontbox of each of the fontnames in the 'fonts'
X% array
X/fontboxes nfonts array def
X0 1 nfonts 1 sub {
X	fontboxes exch dup fonts exch get fontbox put
X} for
X% select font
X/F {
X	dup fonts exch get /fontname exch def fontboxes exch get
X	/thisfontbox exch def SF 
X} def
X% set point size
X/S {/ptsize exch def SF} def
X% actually set font
X/SF {
X	fontname findfont ptsize curscale div scalefont setfont
X	thisfontbox aload pop
X	1 1 3 {
X		pop ptsize mul curscale div neg 3 1 roll
X	} for
X	halign astore pop
X} def
X% sets the scale to 72 / n, where n is on the stack, and stores the value
X% in curscale for font scaling
X/curscale 1 def
X/ss {/curscale exch 72 exch div dup dup scale def} def
X/land {8.5 72 mul curscale div 0 translate 90 rotate} def
XStartXpic
X%%EndProlog
X1 1 scale
X80 ss
X0 F
X12 S
X295 40 m
X(hello world) rj 2 t
X215 40 m
X(hello world) rj 1 t
X135 40 m
X(hello world) rj 0 t
X0 D
X287 40 m
X303 40 l
X295 40 l
X295 48 l
X295 32 l
Xx
X207 40 m
X223 40 l
X215 40 l
X215 48 l
X215 32 l
Xx
X127 40 m
X143 40 l
X135 40 l
X135 48 l
X135 32 l
Xx
X455 120 m
X(hello world) lj 2 t
X375 120 m
X(hello world) lj 1 t
X367 120 m
X383 120 l
X375 120 l
X375 128 l
X375 112 l
Xx
X295 120 m
X(hello world) lj 0 t
X215 120 m
X(hello world) ce 2 t
X135 120 m
X(hello world) ce 1 t
X55 120 m
X(hello world) ce 0 t
X447 120 m
X463 120 l
X455 120 l
X455 128 l
X455 112 l
Xx
X287 120 m
X303 120 l
X295 120 l
X295 128 l
X295 112 l
Xx
X207 120 m
X223 120 l
X215 120 l
X215 128 l
X215 112 l
Xx
X127 120 m
X143 120 l
X135 120 l
X135 128 l
X135 112 l
Xx
X47 120 m
X63 120 l
X55 120 l
X55 128 l
X55 112 l
Xx
X%%Trailer
Xshowpage
X% Trailer for xpic to PostScript converter
X% $Header: x2ps.tra,v 1.1 87/11/21 20:33:03 moraes Exp $
Xxpic end restore
X%%DocumentFonts: Times-Roman Times-Italic Times-Bold Special
END_OF_FILE
if test 4867 -ne `wc -c <'xpic/test/testtext.ps'`; then
    echo shar: \"'xpic/test/testtext.ps'\" unpacked with wrong size!
fi
# end of 'xpic/test/testtext.ps'
fi
echo shar: End of archive 4 \(of 15\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 15 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.sources.x mailing list