[comp.sources.x] v01i005: xfig: a MacDraw style line editor

mikew@wyse.wyse.com (Mike Wexler) (08/17/88)

Submitted-by: ken@cs.rochester.edu (Ken Yap)
Posting-number: Volume 1, Issue 5
Archive-name: xfig/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 11)."
# Contents:  addpt.c canvas.c drag.c global.c intspline.c msgsw.c
#   save.c
# Wrapped by mikew@wyse on Tue Aug 16 13:14:37 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f addpt.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"addpt.c\"
else
echo shar: Extracting \"addpt.c\" \(6894 characters\)
sed "s/^X//" >addpt.c <<'END_OF_addpt.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : August 1985.
X *	2nd revision : March 1988.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "alloc.h"
X#include "func.h"
X#include "object.h"
X#include "paintop.h"
X
X#define			TOLERANCE	3
X
Xextern F_line		*line_search();
Xextern F_spline		*spline_search();
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
Xextern			null_proc();
Xextern			set_popupmenu();
X
Xextern int		cur_x, cur_y;
Xextern int		pointmarker_shown;
Xextern F_line		*line;
Xextern F_spline		*spline;
X
Xextern F_point		*added_point;
Xextern F_point		*left_point, *right_point;
X
X			init_point_adding();
X			move_addedpoint();
X			fix_linepoint_adding();
X			fix_splinepoint_adding();
X
Xstatic F_line		*cur_line;
Xstatic F_spline		*cur_spline;
X
Xpoint_adding_selected()
X{
X	canvas_kbd_proc = null_proc;
X	canvas_locmove_proc = null_proc;
X	canvas_leftbut_proc = init_point_adding;
X	canvas_middlebut_proc = null_proc;
X	canvas_rightbut_proc = set_popupmenu;
X	set_cursor(&pick9_cursor);
X	}
X
Xinit_point_adding(x, y)
Xint	x, y;
X{
X	int	px, py;
X
X	if ((cur_line = line_search(x, y, TOLERANCE, &px, &py)) != NULL) {
X	    if (cur_line->type == T_BOX) {
X		put_msg("Adding points to a box is not allowed");
X		return;
X		}
X	    init_linepointadding(px, py);
X	    }
X	else if ((cur_spline = spline_search(x,y,TOLERANCE,&px,&py)) != NULL){
X	    init_splinepointadding(px, py);
X	    }
X	else {
X	    return;
X	    }
X	canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
X	erase_pointmarker();
X	}
X
Xwrapup_pointadding()
X{
X	show_pointmarker();
X	point_adding_selected();
X	}
X
X/**************************  spline  *******************************/
X
Xinit_splinepointadding(px, py)
Xint		px, py;
X{
X	find_endpoints(cur_spline->points, px, py, &left_point, &right_point);
X	set_temp_cursor(&null_cursor);
X	win_setmouseposition(canvas_swfd, px, py);
X	cur_x = px; cur_y = py;
X	if (left_point == NULL && closed_spline(cur_spline)) {
X	    /* The added_point is between the 1st and 2nd point. */
X	    left_point = right_point;
X	    right_point = right_point->next;
X	    }
X	draw_addedlink(INV_PAINT);
X	canvas_locmove_proc = move_addedpoint;
X	canvas_middlebut_proc = fix_splinepoint_adding;
X	}
X
Xfix_splinepoint_adding(x, y)
Xint	x, y;
X{
X	F_point		*p;
X
X	if (NULL == (Point_malloc(p))) {
X	    put_msg(Err_mem);
X	    wrapup_pointadding();
X	    return;
X	    }
X	clean_up();
X	added_point = p;
X	added_point->x = x;
X	added_point->y = y;
X	draw_addedlink(INV_PAINT);
X	if (-1 == splinepoint_adding(cur_spline, added_point))
X	    wrapup_pointadding();
X	set_action_object(F_ADD_POINT, O_SPLINE);
X	set_latestspline(cur_spline);
X	wrapup_pointadding();
X	}
X
X/*
XWarning: Do not change the value of the pointers left_point and
Xright_point.  Added_point is always inserted between left_point
Xand right_point, except in two cases. 
X	(1) left_point is NULL, the added_point will be prepended
X		to the list of points. This case will never
X		occur if the spline is closed (periodic).
X	(2) right_point is NULL, the added_point will be appended
X		to the end of the list.
X*/
X
Xsplinepoint_adding(spline, added_point)
XF_spline	*spline;
XF_point		*added_point;
X{
X	F_control	*c;
X
X	set_temp_cursor(&wait_cursor);
X	if (int_spline(spline)) {	/* Interpolated spline */
X	    if (NULL == (Control_malloc(c))) {
X		put_msg(Err_mem);
X		return(-1);
X		}
X	    }
X	pw_batch_on(canvas_pixwin);
X	if (pointmarker_shown) toggle_splinepointmarker(spline);  
X	draw_spline(spline, ERASE); /* erase old spline */
X	if (left_point == NULL) {
X	    added_point->next = spline->points;
X	    spline->points = added_point;
X	    }
X	else {
X	    added_point->next = right_point;
X	    left_point->next = added_point;
X	    }
X
X	if (int_spline(spline)) {	/* Interpolated spline */
X	    c->next = spline->controls;
X	    spline->controls = c;
X	    remake_control_points(spline);
X	    }
X
X	draw_spline(spline, PAINT); /* draw the modified spline */
X	if (pointmarker_shown) toggle_splinepointmarker(spline);  
X	pw_batch_off(canvas_pixwin);
X	reset_cursor();
X	set_modifiedflag();
X	return(1);
X	}
X
X/***************************  line  ********************************/
X
Xinit_linepointadding(px, py)
Xint	px, py;
X{
X	find_endpoints(cur_line->points,px,py,&left_point,&right_point);
X	set_temp_cursor(&null_cursor);
X	win_setmouseposition(canvas_swfd, px, py);
X	cur_x = px; cur_y = py;
X	if (left_point == NULL && cur_line->type == T_POLYGON) {
X	    left_point = right_point;
X	    right_point = right_point->next;
X	    }
X	if (left_point != NULL && right_point != NULL)
X	    draw_line_segment(cur_line->style, cur_line->style_val,
X		left_point->x, left_point->y,
X		right_point->x, right_point->y, INV_PAINT);
X	draw_addedlink(INV_PAINT);
X	canvas_locmove_proc = move_addedpoint;
X	canvas_middlebut_proc = fix_linepoint_adding;
X	}
X
Xfix_linepoint_adding(x, y)
Xint	x, y;
X{
X	F_point		*p;
X
X	if (NULL == (Point_malloc(p))) {
X	    put_msg(Err_mem);
X	    wrapup_pointadding();
X	    return;
X	    }
X	clean_up();
X	added_point = p;
X	added_point->x = x;
X	added_point->y = y;
X	draw_addedlink(INV_PAINT);
X	linepoint_adding(cur_line, added_point);
X	set_action_object(F_ADD_POINT, O_POLYLINE);
X	set_latestline(cur_line);
X	wrapup_pointadding();
X	}
X
Xlinepoint_adding(line, added_point)
XF_line	*line;
XF_point	*added_point;
X{
X	if (pointmarker_shown) toggle_linepointmarker(line);
X	draw_line(line, ERASE);
X	if (left_point == NULL) {
X	    added_point->next = line->points;
X	    line->points = added_point;
X	    }
X	else {
X	    added_point->next = left_point->next;
X	    left_point->next = added_point;
X	    }
X	draw_line(line, PAINT);
X	if (pointmarker_shown) toggle_linepointmarker(line);  
X	set_modifiedflag();
X	}
X
X/*******************************************************************/
X
X/*
XIf (x,y) is close to a point, q, fp points to q and sp points to q->next
X(right).  However if q is the first point, fp contains NULL and sp points to q.
X*/
X
Xfind_endpoints(p, x, y, fp, sp)
XF_point	*p, **fp, **sp;
Xint	x, y;
X{
X	int	d;
X	F_point	*a = NULL, *b = p;
X
X	if (x == b->x && y == b->y) {
X	    *fp = a;
X	    *sp = b;
X	    return;
X	    }
X
X	for (a = p, b = p->next; b != NULL; a = b, b = b->next){
X	    if (x == b->x && y == b->y) {
X		*fp = b;
X		*sp = b->next;
X		return;
X		}
X	    if (close_to_vector(a->x, a->y, b->x, b->y, x, y, 1, 1.0, &d, &d)) {
X		*fp = a;
X		*sp = b;
X		return;
X		}
X	    }
X	*fp = a;
X	*sp = b;
X	}
X
Xdraw_addedlink(op)
Xint	op;
X{
X	if (left_point != NULL) {
X	    pw_vector(canvas_pixwin, left_point->x, left_point->y,
X			cur_x, cur_y, op, 1);
X	   }
X	if (right_point != NULL) {
X	    pw_vector(canvas_pixwin, right_point->x, 
X			right_point->y, cur_x, cur_y, op, 1);
X	    }
X	}
X
Xmove_addedpoint(x, y)
Xint	x, y;
X{
X	draw_addedlink(INV_PAINT);
X	cur_x = x;
X	cur_y = y;
X	draw_addedlink(INV_PAINT);
X	}
END_OF_addpt.c
if test 6894 -ne `wc -c <addpt.c`; then
    echo shar: \"addpt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f canvas.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"canvas.c\"
else
echo shar: Extracting \"canvas.c\" \(6379 characters\)
sed "s/^X//" >canvas.c <<'END_OF_canvas.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "const.h"
X#include "paintop.h"
X
X/***************** import global variables and routines *******************/
X
Xextern int		cur_command;
Xextern int		errno;
Xextern int		action_on;     /* tracker.c */
Xextern int		magnet_mode;
X
Xextern int		receiving_msg;
Xextern int		borderwid, stripeht, windowspacing;
Xextern int		CANVAS_WIDTH, CANVAS_HEIGHT;
Xextern			null_proc();
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
Xextern			null_proc();
Xextern			set_popupmenu();
X
X
X/*********************** local variables and routines ************************/
X
Xstatic			canvas_selected();
Xstatic			canvas_sighandler();
X
X#ifndef	X11
Xint
Xinit_canvas(tool)
XTOOL	tool;
X{
X	INPUTMASK	 mask;
X
X	canvas_sw = tool_createsubwindow(tool, "", CANVAS_WIDTH, CANVAS_HEIGHT);
X	if (canvas_sw == (TOOLSW)0) return(0);
X	canvas_swfd = canvas_sw->ts_windowfd;
X
X	canvas_pixwin = pw_open(canvas_swfd);
X	canvas_pixwin->pw_prretained = mem_create(CANVAS_WIDTH, 
X						CANVAS_HEIGHT, 1);
X	canvas_sw->ts_io.tio_selected = canvas_selected;
X	canvas_sw->ts_io.tio_handlesigwinch = canvas_sighandler;
X	canvas_sw->ts_destroy = null_proc;
X
X	input_imnull(&mask);
X	win_setinputcodebit(&mask, MS_LEFT);
X	win_setinputcodebit(&mask, MS_MIDDLE);
X	win_setinputcodebit(&mask, MS_RIGHT);
X	win_setinputcodebit(&mask, LOC_MOVE);
X	mask.im_flags |= IM_ASCII | IM_INTRANSIT;
X	win_setinputmask(canvas_swfd, &mask, NULL, WIN_NULLLINK);
X	set_temp_cursor(cur_cursor);
X	(void)fcntl(canvas_swfd, F_SETFL, fcntl(canvas_swfd, F_GETFL, 0) | O_NDELAY);
X	init_grid();
X	canvas_leftbut_proc = null_proc;
X	canvas_middlebut_proc = null_proc;
X	canvas_rightbut_proc = null_proc;
X	canvas_kbd_proc = canvas_locmove_proc = null_proc;
X	return(1);
X	}
X
Xstatic
Xcanvas_selected(nullsw, ibits, obits, ebits, timer)
Xcaddr_t		*nullsw;
Xint		*ibits, *obits, *ebits;
Xstruct timeval	*timer;
X{
X	static INPUTEVENT		ie;
X	static int			x, y, t;
X
X	*ibits = *obits = *ebits = 0;
X	if (input_readevent(canvas_swfd, &ie) == -1) {
X	    printf ("error %d in canvas_selected", errno);
X	    return;
X	    }
X
X	x = ie.ie_locx;
X	y = ie.ie_locy;
X	while (ie.ie_code == LOC_MOVE) {
X	    if (input_readevent(canvas_swfd, &ie) == -1) {
X		if (magnet_mode) {
X		    x = ((t = x % 5) < 3) ? x - t - 1 : x + 5 - t - 1;
X		    y = ((t = y % 5) < 3) ? y - t - 1 : y + 5 - t - 1;
X/*
X		    win_setmouseposition(canvas_swfd, x, y);
X*/
X		    }
X		set_rulermark(x, y);
X		(*canvas_locmove_proc)(x, y);
X		return;
X		}
X	    x = ie.ie_locx;
X	    y = ie.ie_locy;
X	    }
X	if (magnet_mode) {
X	    x = ((t = x % 5) < 3) ? x - t - 1 : x + 5 - t - 1;
X	    y = ((t = y % 5) < 3) ? y - t - 1 : y + 5 - t - 1;
X/*
X	    win_setmouseposition(canvas_swfd, x, y);
X*/
X	    }
X	if (ie.ie_code == MS_LEFT) {
X	    canvas_leftbut_proc(x, y);
X	    }
X	else if (ie.ie_code == MS_RIGHT) {
X	    canvas_rightbut_proc(&ie);
X	    }
X	else if (ie.ie_code == MS_MIDDLE) {
X	    canvas_middlebut_proc(x, y);
X	    }
X	else if (ie.ie_code <= ASCII_LAST) {
X	    canvas_kbd_proc(ie.ie_code);
X	    }
X	}
X
Xstatic
Xcanvas_sighandler()
X{
X	pw_damaged(canvas_pixwin);
X	pw_repairretained(canvas_pixwin);
X	pw_donedamaged(canvas_pixwin);
X	}
X
Xclear_canvas()
X{
X	pw_writebackground(canvas_pixwin, 0, 0, 2048, 2048, PAINT);
X	}
X#else
Xstatic Arg      canvas_args[] =
X{
X	{ XtNx, (XtArgVal)0 },
X	{ XtNy, (XtArgVal)0 },
X	{ XtNlabel, (XtArgVal)"" },
X	{ XtNwidth, (XtArgVal)0 },
X	{ XtNheight, (XtArgVal)0 },
X	{ XtNfromHoriz, (XtArgVal)NULL },
X	{ XtNhorizDistance, (XtArgVal)0 },
X	{ XtNfromVert, (XtArgVal)NULL },
X	{ XtNvertDistance, (XtArgVal)0 },
X};
X
Xstatic void canvas_exposed(tool, event, params, nparams)
X	TOOL		tool;
X	INPUTEVENT	*event;
X	String		*params;
X	Cardinal	*nparams;
X{
X	if (((XExposeEvent *)event)->count > 0)
X		return;
X	redisplay_canvas();
X}
X
Xstatic void set_pos(tool, event, params, nparams)
X	TOOL		tool;
X	XEvent		*event;
X	String		*params;
X	Cardinal	*nparams;
X{
X	Position	x, y;
X	Window		w;
X	extern TOOL	menu;
X	
X	XTranslateCoordinates(tool_d, canvas_swfd, XDefaultRootWindow(tool_d),
X			      event->xbutton.x, event->xbutton.y, &x, &y, &w);
X	XtMoveWidget(menu, x-10, y-10);
X}
X
XXtActionsRec canvas_actions[] =
X{
X	{ "Event", (XtActionProc)canvas_selected },
X	{ "Expose", (XtActionProc)canvas_exposed },
X	{ "set_pos", (XtActionProc)set_pos },
X};
X
Xstatic String canvas_translations =
X	"<Motion>:Event()\n\
X	<Btn1Down>:Event()\n\
X	<Btn2Down>:Event()\n\
X	<Btn3Down>:set_pos(popup_menu)MenuPopup(popup_menu)\n\
X	<Key>:Event()\n\
X	<Expose>:Expose()\n";
X
Xint init_canvas(tool)
X	TOOL		tool;
X{
X	canvas_args[3].value = CANVAS_WIDTH;
X	canvas_args[4].value = CANVAS_HEIGHT;
X	canvas_args[5].value = (XtArgVal)panel_sw;
X	canvas_args[7].value = (XtArgVal)topruler_sw;
X	canvas_sw = XtCreateWidget("canvas", labelWidgetClass, tool,
X		canvas_args, XtNumber(canvas_args));
X	canvas_leftbut_proc = null_proc;
X	canvas_middlebut_proc = null_proc;
X	canvas_rightbut_proc = null_proc;
X	canvas_kbd_proc = canvas_locmove_proc = null_proc;
X	XtAddActions(canvas_actions, XtNumber(canvas_actions));
X	XtOverrideTranslations(canvas_sw,
X		XtParseTranslationTable(canvas_translations));
X	return (1);
X}
X
Xsetup_canvas()
X{
X	canvas_rightbut_proc = set_popupmenu;
X	canvas_pixwin = canvas_swfd = XtWindow(canvas_sw);
X	init_grid();
X}
X
Xstatic canvas_selected(tool, event, params, nparams)
X	TOOL		tool;
X	INPUTEVENT	*event;
X	String		*params;
X	Cardinal	*nparams;
X{
X	register int	x, y, t;
X	char		buf[1];
X	XButtonPressedEvent	*be = (XButtonPressedEvent *)event;
X	XKeyPressedEvent	*ke = (XKeyPressedEvent *)event;
X
X	x = event->x;
X	y = event->y;
X	if (magnet_mode)
X	{
X		x = ((t = x % 5) < 3) ? x - t - 1 : x + 5 - t - 1;
X		y = ((t = y % 5) < 3) ? y - t - 1 : y + 5 - t - 1;
X	}
X	switch (event->type)
X	{
X	case MotionNotify:
X		set_rulermark(x, y);
X		(*canvas_locmove_proc)(x, y);
X		break;
X	case ButtonPress:
X		if (be->button & Button1)
X			(*canvas_leftbut_proc)(x, y);
X		else if (be->button & Button3)
X			(*canvas_middlebut_proc)(x, y);
X		break;
X	case KeyPress:
X		if (XLookupString(ke, buf, sizeof(buf), NULL, NULL) > 0)
X			(*canvas_kbd_proc)(buf[0]);
X		break;
X	}
X}
X
Xclear_canvas()
X{
X	XClearArea(tool_d, canvas_pixwin, 0, 0, 0, 0, False);
X}
X#endif	X11
END_OF_canvas.c
if test 6379 -ne `wc -c <canvas.c`; then
    echo shar: \"canvas.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f drag.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"drag.c\"
else
echo shar: Extracting \"drag.c\" \(6945 characters\)
sed "s/^X//" >drag.c <<'END_OF_drag.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "font.h"
X#include "object.h"
X#include "paintop.h"
X
Xextern F_pos		last_position, new_position;  /* undo.c   */
Xextern int		foreground_color, background_color;
Xextern int		fix_x, fix_y, cur_x, cur_y;
X
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
Xextern			null_proc();
Xextern			set_popupmenu();
X
Xstatic			draw_movingbox();
Xstatic int		x1off, y1off, x2off, y2off;
X
X			(*return_proc)();
X			 move_line(), place_line();
X			 move_arc(), place_arc();
X			 move_spline(), place_spline();
X			 move_movingbox();
X			 place_ellipse();
X			 move_text(), place_text();
X			 place_compound();
X
Xstatic F_arc		*arc;
Xstatic F_compound	*compound;
Xstatic F_ellipse	*ellipse;
Xstatic F_line		*line;
Xstatic F_spline		*spline;
Xstatic F_text		*text;
X
Xstatic
Xdraw_movingbox(op)
Xint	op;
X{
X	register int	x1, y1, x2, y2;
X
X	x1 = cur_x + x1off;
X	x2 = cur_x + x2off;
X	y1 = cur_y + y1off;
X	y2 = cur_y + y2off;
X	pw_vector(canvas_pixwin, x1, y1, x1, y2, op, 1);
X	pw_vector(canvas_pixwin, x1, y2, x2, y2, op, 1);
X	pw_vector(canvas_pixwin, x2, y2, x2, y1, op, 1);
X	pw_vector(canvas_pixwin, x2, y1, x1, y1, op, 1);
X	}
X
Xmove_movingbox(x, y)
Xint	x, y;
X{
X	draw_movingbox(INV_PAINT);
X	cur_x = x;
X	cur_y = y;
X	draw_movingbox(INV_PAINT);
X	}
X
X/***************************** ellipse section ************************/
X
Xinit_ellipsedragging(e, x, y)
XF_ellipse	*e;
Xint		x, y;
X{
X	ellipse = e;
X	last_position.x = cur_x = x; 
X	last_position.y = cur_y = y;
X	x1off = (e->center.x - e->radiuses.x) - cur_x; 
X	x2off = (e->center.x + e->radiuses.x) - cur_x; 
X	y1off = (e->center.y - e->radiuses.y) - cur_y;
X	y2off = (e->center.y + e->radiuses.y) - cur_y;
X	canvas_locmove_proc = move_movingbox;
X	canvas_middlebut_proc = place_ellipse;
X	set_action_on();
X	draw_movingbox(INV_PAINT);
X	}
X
Xplace_ellipse(x, y)
Xint	x, y;
X{
X	draw_movingbox(INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	translate_ellipse(ellipse, x - last_position.x, y - last_position.y);
X	pw_batch_on(canvas_pixwin);
X	draw_ellipse(ellipse, foreground_color);
X	pw_batch_off(canvas_pixwin);
X	show_pointmarker();
X	set_modifiedflag();
X	(*return_proc)();
X	}
X
X/*****************************  arc  section  *******************/
X
Xinit_arcdragging(a, x, y)
XF_arc	*a;
Xint	x, y;
X{
X	arc = a;
X	fix_x = last_position.x = cur_x = x;
X	fix_y = last_position.y = cur_y = y;
X	canvas_locmove_proc = move_arc;
X	canvas_middlebut_proc = place_arc;
X	set_action_on();
X	draw_movingarc(arc, INV_PAINT);
X	}
X
Xmove_arc(x, y)
Xint	x, y;
X{
X	draw_movingarc(arc, INV_PAINT);
X	cur_x = x;  
X	cur_y = y;
X	draw_movingarc(arc, INV_PAINT);
X	}
X
Xplace_arc(x, y)
Xint	x, y;
X{
X	draw_movingarc(arc, INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	translate_arc(arc, x - fix_x, y - fix_y);
X	pw_batch_on(canvas_pixwin);
X	draw_arc(arc, foreground_color);
X	pw_batch_off(canvas_pixwin);
X	show_pointmarker();
X	set_modifiedflag();
X	(*return_proc)();
X	}
X
Xdraw_movingarc(a, op)
XF_arc	*a;
Xint	op;
X{
X	int	dx, dy;
X
X	dx = cur_x - fix_x;
X	dy = cur_y - fix_y;
X	pw_vector(canvas_pixwin, a->point[0].x+dx, a->point[0].y+dy,
X		a->point[1].x+dx, a->point[1].y+dy, op, 1);
X	pw_vector(canvas_pixwin, a->point[1].x+dx, a->point[1].y+dy,
X		a->point[2].x+dx, a->point[2].y+dy, op, 1);
X	}
X
X/*************************  line  section  **********************/
X
Xinit_linedragging(l, x, y)
XF_line	*l;
Xint	x, y;
X{
X	line = l;
X	last_position.x = cur_x = fix_x = x;
X	last_position.y = cur_y = fix_y = y;
X	canvas_locmove_proc = move_line;
X	canvas_middlebut_proc = place_line;
X	set_action_on();
X	draw_movingpoint(line->points, INV_PAINT);
X	}
X
Xmove_line(x, y)
Xint	x, y;
X{
X	draw_movingpoint(line->points, INV_PAINT);
X	cur_x = x;  
X	cur_y = y;
X	draw_movingpoint(line->points, INV_PAINT);
X	}
X
Xplace_line(x, y)
Xint	x, y;
X{
X	draw_movingpoint(line->points, INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	translate_line(line, x - fix_x, y - fix_y);
X	draw_line(line, PAINT);
X	show_pointmarker();
X	set_modifiedflag();
X	(*return_proc)();
X	}
X
Xdraw_movingpoint(ps, op)
XF_point	*ps;
Xint	op;
X{
X	F_point	*p;
X	int	dx, dy, x, y, xx, yy;
X
X	dx = cur_x - fix_x;
X	dy = cur_y - fix_y;
X	p = ps;
X	x = p->x + dx;
X	y = p->y + dy;
X	for (p = p->next; p != NULL; x = xx, y = yy, p = p->next) {
X	    xx = p->x + dx;  yy = p->y +dy;
X	    pw_vector(canvas_pixwin, x, y, xx, yy, op, 1);
X	    }
X	}
X
X/************************  text section  **************************/
X
Xinit_textdragging(t, x, y)
XF_text	*t;
Xint	x, y;
X{
X	text = t;
X	fix_x = cur_x = x; 
X	fix_y = cur_y = y;
X	x1off = t->base_x - x;
X	y1off = t->base_y - y;
X	canvas_locmove_proc = move_text;
X	canvas_middlebut_proc = place_text;
X	draw_movingtext();
X	set_action_on();
X	}
X
Xmove_text(x, y)
Xint	x, y;
X{
X	draw_movingtext();
X	cur_x = x;
X	cur_y = y;
X	draw_movingtext();
X	}
X
Xplace_text(x, y)
Xint	x, y;
X{
X	draw_movingtext();
X	new_position.x = x;
X	new_position.y = y;
X	last_position.x = fix_x; 
X	last_position.y = fix_y;
X	translate_text(text, x - fix_x, y - fix_y);
X	draw_text(text, PAINT);
X	set_modifiedflag();
X	(*return_proc)();
X	}
X
Xdraw_movingtext()
X{
X	pw_text(canvas_pixwin, cur_x+x1off, cur_y + y1off, INV_PAINT,
X		canvas_font, text->cstring);
X	}
X
X/*************************  spline  section  **********************/
X
Xinit_splinedragging(s, x, y)
XF_spline	*s;
Xint		x, y;
X{
X	spline = s;
X	last_position.x = cur_x = fix_x = x;
X	last_position.y = cur_y = fix_y = y;
X	canvas_locmove_proc = move_spline;
X	canvas_middlebut_proc = place_spline;
X	set_action_on();
X	draw_movingpoint(spline->points, INV_PAINT);
X	}
X
Xmove_spline(x, y)
Xint	x, y;
X{
X	draw_movingpoint(spline->points, INV_PAINT);
X	cur_x = x;  
X	cur_y = y;
X	draw_movingpoint(spline->points, INV_PAINT);
X	}
X
Xplace_spline(x, y)
Xint	x, y;
X{
X	draw_movingpoint(spline->points, INV_PAINT);
X	translate_spline(spline, x - fix_x, y - fix_y);
X	new_position.x = x;
X	new_position.y = y;
X	pw_batch_on(canvas_pixwin);
X	draw_spline(spline, PAINT);
X	pw_batch_off(canvas_pixwin);
X	show_pointmarker();
X	set_modifiedflag();
X	(*return_proc)();
X	}
X
X/*****************************  Compound section  *******************/
X
Xinit_compounddragging(c, x, y)
XF_compound	*c;
Xint		x, y;
X{
X	compound = c;
X	last_position.x = cur_x = x; 
X	last_position.y = cur_y = y;
X	x1off = c->nwcorner.x - x;
X	x2off = c->secorner.x - x;
X	y1off = c->nwcorner.y - y;
X	y2off = c->secorner.y - y;
X	canvas_locmove_proc = move_movingbox;
X	canvas_middlebut_proc = place_compound;
X	set_action_on();
X	draw_movingbox(INV_PAINT);
X	}
X
Xplace_compound(x, y)
Xint	x, y;
X{
X	draw_movingbox(INV_PAINT);
X	new_position.x = x;
X	new_position.y = y;
X	translate_compound(compound, x - last_position.x, y - last_position.y);
X	draw_compound(compound);
X	draw_compoundbox(compound, INV_PAINT);
X	set_modifiedflag();
X	(*return_proc)();
X	}
END_OF_drag.c
if test 6945 -ne `wc -c <drag.c`; then
    echo shar: \"drag.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f global.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"global.c\"
else
echo shar: Extracting \"global.c\" \(7305 characters\)
sed "s/^X//" >global.c <<'END_OF_global.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#define	GLOBAL
X#include "resources.h"
X#include "font.h"
X#undef	GLOBAL
X#include "const.h"
X#include "func.h"
X#include "object.h"
X#include "paintop.h"
X
X/**********************  canvas variables  ************************/
X
Xint			(*canvas_kbd_proc)();
X			(*canvas_locmove_proc)();
X			(*canvas_leftbut_proc)();
X			(*canvas_middlebut_proc)();
X			(*canvas_rightbut_proc)();
Xint			fix_x, fix_y;
Xint			cur_x, cur_y;
X
Xint			receiving_msg = 0;
Xint			action_on = 0;
Xint			pointmarker_shown = 0;
Xint			compoundbox_shown = 0;
X
Xint			ICON_COLUMN;
Xint			CANVAS_HEIGHT, CANVAS_WIDTH;
Xint			CANVAS_LEFT, CANVAS_TOP;
Xint			PANEL_LEFT, PANEL_TOP, PANEL_HEIGHT, PANEL_WID;
Xint			MSG_LEFT, MSG_TOP, MSG_WIDTH;
Xint			SIDERULER_LEFT, SIDERULER_TOP;
Xint			SIDERULER_WIDTH, SIDERULER_HEIGHT;
Xint			SIDERULER_START;
Xint			TOPRULER_LEFT, TOPRULER_TOP;
Xint			TOPRULER_WIDTH, TOPRULER_HEIGHT;
Xint			borderwid, windowspacing, toolstripeht;
X
Xint			num_point;
XF_point			*first_point, *cur_point;
X
X/************************  Objects  **********************/
X
X/*
XObject_tails (not always) point to the last objects in each linked list
Xin objects.  It is used to speed up an undo-read action.  When a file
Xis read, the lists of the objects read are stored in saved_objects
Xand the pointers to tails of the lists in objects would kept in object_tails
Xthe "next" members of the tail objects point to the lists in saved_objects.
XTo undo, one would only set all the "next" of tail object to NULL;
X
XObject_tails is also used for speeding up the undo of compound breaking
Xaction in similar fashion.
X*/
XF_compound		object_tails = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
XF_compound		objects = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
XF_compound		saved_objects = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
XF_compound		*saved_compound = NULL;	/* Saved the broken compound */
X
X/*************************  Undo  variables  **********************/
X
Xint			last_action = F_NULL;
Xint			last_object;
Xint			last_axis;
Xint			last_rotateangle;
Xstruct {int x, y;}	last_position, new_position;
XF_point			*moved_point;
XF_point			*deleted_point;
XF_point			*added_point;
XF_point			*left_point;
XF_point			*right_point;
Xint			movedpoint_num;
X
X/***************************  Modes  ****************************/
X
Xint			manhattan_mode		= 0;
Xint			mountain_mode		= 0;
Xint			autoforwardarrow_mode	= 0;
Xint			autobackwardarrow_mode	= 0;
Xint			latexline_mode		= 0;
Xint			latexarrow_mode		= 0;
Xint			magnet_mode		= 0;
Xint			line_thickness		= 1;
Xint			pen_size		= 0;
Xint			pen_type		= 0;
Xint			flip_axis		= -1;
Xint			rotate_angle		= 0;
Xint			cur_line_style		= -1;
Xfloat			cur_dashlength		= .05*PIX_PER_INCH;
Xfloat			cur_dotgap		= .04*PIX_PER_INCH;
Xfloat			cur_styleval		= 0.0;
Xfloat			cur_angle		= 0.0;
Xint			cur_color		= BLACK;
Xint			cur_textstyle		= PLAIN;
X
Xshort			dot_image[16] = {
X				0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
X				0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
X				0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
X				0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
X				};
Xmpr_static(dot, 16, 16, 1, dot_image);
X
X/*************************  Flags  *******************************/
X
Xint			cur_command = -1;
Xint			DEBUG = 0;
Xint			RHS_PANEL = 0;
Xint			INVERSE = 0;
X
X/************************  Status  ****************************/
X
Xchar			directory[128] = "";
Xchar			current_file[32] = "";
Xint			figure_modified = 0;
X
X/************************  Error messages  ****************************/
X
Xchar		Err_incomp[] = "Incomplete %s object at line %d.";
Xchar		Err_mem[] = "Running out of memory.";
X
X/************************  Routines  ****************************/
X
Xnull_proc()
X{
X	}
X
Xset_modifiedflag()
X{
X	figure_modified = 1;
X	}
X
Xset_action_on()
X{
X	action_on = 1;
X	}
X
Xreset_action_on()
X{
X	action_on = 0;
X	}
X
Xreset_cursor()
X{
X#ifndef	X11
X	win_setcursor(canvas_swfd, cur_cursor);
X#else
X	XDefineCursor(tool_d, canvas_swfd, (Cursor)cur_cursor->bitmap);
X#endif	X11
X	}
X
Xset_temp_cursor(cursor)
XCURSOR	cursor;
X{
X#ifndef	X11
X	win_setcursor(canvas_swfd, cursor);
X#else
X	XDefineCursor(tool_d, canvas_swfd, (Cursor)cursor->bitmap);
X#endif	X11
X	}
X
Xset_cursor(cursor)
XCURSOR	cursor;
X{
X	cur_cursor = cursor;
X#ifndef	X11
X	win_setcursor(canvas_swfd, cursor);
X#else
X	XDefineCursor(tool_d, canvas_swfd, (Cursor)cursor->bitmap);
X#endif	X11
X	}
X
Xset_lastaxis(a)
Xint	a;
X{
X	last_axis = a;
X	}
X
Xset_lastangle(a)
Xint	a;
X{
X	last_rotateangle = a;
X	}
X
Xset_lastposition(x, y)
Xint	x, y;
X{
X	last_position.x = x;
X	last_position.y = y;
X	}
X
Xset_action(action)
Xint	 action;
X{
X	last_action = action;
X	}
X
Xset_action_object(action, object)
Xint	 action, object;
X{
X	last_action = action;
X	last_object = object;
X	}
X
X/*
XClean_up should be called before committing a user's request.
XClean_up will attempt to free all the allocated memories which
Xresulted from delete/remove action.  It will set the last_action
Xto F_NULL.  Thus this routine should be before set_action_object().
Xif they are to be called in the same routine.
X*/
Xclean_up()
X{
X	if (last_action == F_REMOVE) {
X	    switch (last_object) {
X		case O_ARC :
X		    free_arc(&saved_objects.arcs);
X		    break;
X		case O_COMPOUND :
X		    free_compound(&saved_objects.compounds);
X		    break;
X		case O_ELLIPSE :
X		    free_ellipse(&saved_objects.ellipses);
X		    break;
X		case O_POLYLINE :
X		    free_line(&saved_objects.lines);
X		    break;
X		case O_SPLINE :
X		    free_spline(&saved_objects.splines);
X		    break;
X		case O_TEXT :
X		    free_text(&saved_objects.texts);
X		    break;
X		case O_ALL_OBJECT :
X		    free_arc(&saved_objects.arcs);
X		    free_compound(&saved_objects.compounds);
X		    free_ellipse(&saved_objects.ellipses);
X		    free_line(&saved_objects.lines);
X		    free_spline(&saved_objects.splines);
X		    free_text(&saved_objects.texts);
X		    break;
X		}
X	    }
X	else if (last_action == F_DELETE_POINT) {
X	    free((char*)deleted_point);
X	    }
X	else if (last_action == F_REMOVE_ALL || last_action == F_EDIT) {
X	    free_arc(&saved_objects.arcs);
X	    free_compound(&saved_objects.compounds);
X	    free_ellipse(&saved_objects.ellipses);
X	    free_line(&saved_objects.lines);
X	    free_spline(&saved_objects.splines);
X	    free_text(&saved_objects.texts);
X	    }
X	else if (last_action == F_BREAK) {
X	    free_compound(&saved_compound);
X	    }
X	else if (last_action == F_CREATE) {
X	    saved_objects.arcs = NULL;
X	    saved_objects.compounds = NULL;
X	    saved_objects.ellipses = NULL;
X	    saved_objects.lines = NULL;
X	    saved_objects.splines = NULL;
X	    saved_objects.texts = NULL;
X	    }
X	else if (last_action == F_TURN) {
X	    if (last_object == O_POLYLINE) {
X		free_line(&saved_objects.lines);
X		}
X	    else {	/* last_object == O_SPLINE */
X		free_spline(&saved_objects.splines);
X		}
X	    }
X	last_action = F_NULL;
X	}
X
Xset_latestarc(arc)
XF_arc	*arc;
X{
X	saved_objects.arcs = arc;
X	}
X
Xset_latestcompound(compound)
XF_compound	*compound;
X{
X	saved_objects.compounds = compound;
X	}
X
Xset_latestellipse(ellipse)
XF_ellipse	*ellipse;
X{
X	saved_objects.ellipses = ellipse;
X	}
X
Xset_latestline(line)
XF_line	*line;
X{
X	saved_objects.lines = line;
X	}
X
Xset_latestspline(spline)
XF_spline	*spline;
X{
X	saved_objects.splines = spline;
X	}
X
Xset_latesttext(text)
XF_text	*text;
X{
X	saved_objects.texts = text;
X	}
END_OF_global.c
if test 7305 -ne `wc -c <global.c`; then
    echo shar: \"global.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f intspline.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"intspline.c\"
else
echo shar: Extracting \"intspline.c\" \(7649 characters\)
sed "s/^X//" >intspline.c <<'END_OF_intspline.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "alloc.h"
X#include "func.h"
X#include "object.h"
X#include "paintop.h"
X
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
Xextern			null_proc();
Xextern			set_popupmenu();
X
Xextern int		cur_line_style, line_thickness;
Xextern float		cur_styleval;
Xextern int		cur_color;
Xextern int		fix_x, fix_y, cur_x, cur_y;
Xextern int		cur_command;
Xextern int		manhattan_mode, mountain_mode;
Xextern int		autoforwardarrow_mode;
Xextern int		autobackwardarrow_mode;
Xextern F_compound	objects;
Xextern int		num_point;
Xextern int		DEBUG;
Xextern F_point		*first_point, *cur_point;
X
Xint			create_intsplineobject();
X			init_intspline_drawing();
X
Xdraw_intspline_selected()
X{
X	canvas_kbd_proc = null_proc;
X	canvas_locmove_proc = null_proc;
X	canvas_leftbut_proc = init_intspline_drawing;
X	canvas_middlebut_proc = null_proc;
X	canvas_rightbut_proc = set_popupmenu;
X	set_cursor(&arrow_cursor);
X	reset_action_on();
X	}
X
Xinit_intspline_drawing(x, y)
Xint	x, y;
X{
X	init_line_drawing(x, y);
X	canvas_middlebut_proc = create_intsplineobject;
X	canvas_rightbut_proc = null_proc;
X	}
X
Xcreate_intsplineobject(x, y)
Xint	x, y;
X{
X	extern F_arrow	*forward_arrow(), *backward_arrow();
X	F_spline	*spline;
X
X	if (x != fix_x || y != fix_y) get_intermediatepoint(x, y);
X	draw_elasticline();
X	if (num_point <= 2) {
X	    pw_vector(canvas_pixwin, first_point->x, first_point->y,
X			cur_point->x, cur_point->y, PAINT, 0);
X	    if (num_point == 1) free((char*)cur_point);
X	    free((char*)first_point);
X	    draw_intspline_selected();
X	    return;
X	    }
X	if (NULL == (Spline_malloc(spline))) {
X	    if (num_point == 1) free((char*)cur_point);
X	    free((char*)first_point);
X	    put_msg(Err_mem);
X	    return;
X	    }
X	spline->style = cur_line_style;
X	spline->thickness = line_thickness;
X	spline->style_val = cur_styleval;
X	spline->color = cur_color;
X	spline->depth = 0;
X	spline->area_fill = NULL;
X	spline->pen = NULL;
X	spline->points = first_point;
X	spline->controls = NULL; 
X	spline->next = NULL; 
X	cur_x = cur_y = fix_x = fix_y = 0; /* used in draw_movingpoint */
X	draw_movingpoint(spline->points, INV_PAINT); /* erase control vector */
X	spline->for_arrow = NULL;
X	spline->back_arrow  = NULL;
X	if (cur_command == F_CLOSED_INTSPLINE) {
X	    spline->type = T_CLOSED_INTERPOLATED;
X	    num_point++;
X	    append_point(first_point->x, first_point->y, &cur_point);
X	    }
X	else {
X	    spline->type = T_OPEN_INTERPOLATED;
X	    if (autoforwardarrow_mode) spline->for_arrow = forward_arrow();
X	    if (autobackwardarrow_mode) spline->back_arrow = backward_arrow();
X	    }
X	make_control_points(spline);
X	pw_batch_on(canvas_pixwin);
X	draw_intspline(spline, PAINT);
X	if (DEBUG) {
X	    int	xmin, ymin, xmax, ymax;
X	    spline_bound(spline, &xmin, &ymin, &xmax, &ymax);
X	    draw_rectbox(xmin, ymin, xmax, ymax, PAINT);
X	    }
X	pw_batch_off(canvas_pixwin);
X	clean_up();
X	set_action_object(F_CREATE, O_SPLINE);
X	insert_spline(&objects.splines, spline);
X	set_latestspline(spline);
X	set_modifiedflag();
X	draw_intspline_selected();
X	}
X
X/* Tension : 0 (min) -> 1 (max)	*/
X
X#define		round(x)	((int) (x + .5))
X
Xcreate_control_list(s)
XF_spline	*s;
X{
X	F_point		*p;
X	F_control	*cp;
X
X	if (NULL == (Control_malloc(cp))) {
X	    put_msg(Err_mem);
X	    return(-1);
X	    }
X	s->controls = cp;
X	for (p = s->points->next; p != NULL; p = p->next) {
X	    if (NULL == (Control_malloc(cp->next))) {
X		put_msg(Err_mem);
X		return(-1);
X		}
X	    cp = cp->next;
X	    }
X	cp->next = NULL;
X	return(1);
X	}
X
Xmake_control_points(s)
XF_spline	*s;
X{
X	if (-1 == create_control_list(s)) return;
X
X	remake_control_points(s);
X	}
X
Xremake_control_points(s)
XF_spline	*s;
X{
X	if (s->type == T_CLOSED_INTERPOLATED)
X	    compute_cp(s->points, s->controls, CLOSED_PATH);
X	else
X	    compute_cp(s->points, s->controls, OPEN_PATH);
X	}
X
Xdraw_intspline(s, op)
XF_spline	*s;
Xint		op;
X{
X	F_point		*p1, *p2;
X	F_control	*cp1, *cp2;
X
X	p1 = s->points;
X	cp1 = s->controls;
X	if (s->for_arrow)
X	    draw_arrow(round(cp1->rx), round(cp1->ry), p1->x,
X			p1->y, s->for_arrow, op);
X	for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
X		p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
X	    bezier_spline((float)p1->x, (float)p1->y, cp1->rx, cp1->ry,
X			cp2->lx, cp2->ly, (float)p2->x, (float)p2->y, op);
X	    }
X	if (s->back_arrow)
X	    draw_arrow(round(cp1->lx), round(cp1->ly), p1->x,
X			p1->y, s->back_arrow, op);
X	}
X
X#define		T		0.45
X#define		_2xPI		6.2832
X#define		_1dSQR2		0.7071
X#define		_SQR2		1.4142
X
Xcompute_cp(points, controls, path)
XF_point		*points;
XF_control	*controls;
Xint		path;
X{
X	F_control	*cp, *cpn;
X	F_point		*p, *p2, *pk;	/* Pk is the next-to-last point. */
X	float		dx, dy;
X	float		x1, y1, x2, y2, x3, y3;
X	float		l1, l2, theta1, theta2;
X
X	x1 = points->x;  y1 = points->y;
X	pk = p2 = points->next;
X	x2 = p2->x;  y2 = p2->y;
X	p = p2->next;
X	x3 = p->x;  y3 = p->y;
X
X	dx = x1 - x2;
X	dy = y2 - y1;
X	l1 = sqrt((double)(dx*dx + dy*dy));
X	theta1 = atan2((double)dy, (double)dx);
X	dx = x3 - x2;
X	dy = y2 - y3;
X	l2 = sqrt((double)(dx*dx + dy*dy));
X	theta2 = atan2((double)dy, (double)dx);
X	/* -PI <= theat1, theta2 <= PI */
X	if (theta1 < 0) theta1 += _2xPI;
X	if (theta2 < 0) theta2 += _2xPI;
X	/* 0 <= theat1, theta2 < 2PI */
X
X	cp = controls->next;
X	control_points(x2, y2, l1, l2, theta1, theta2, T, cp);
X	/* control points for (x2, y2) */
X	if (path == OPEN_PATH) {
X	    controls->lx = 0.0; controls->ly = 0.0;
X	    controls->rx = (x1 + 3*cp->lx)/4; controls->ry = (y1 + 3*cp->ly)/4;
X	    cp->lx = (3*cp->lx + x2)/4; cp->ly = (3*cp->ly + y2)/4;
X	    }
X
X	while (1) {
X	    x2 = x3; y2 = y3;
X	    l1 = l2;
X	    if (theta2 >= M_PI)
X		theta1 = theta2 - M_PI;
X	    else
X		theta1 = theta2 + M_PI;
X	    if ((p = p->next) == NULL) break;
X	    pk = pk->next;
X	    x3 = p->x; y3 = p->y;
X	    dx = x3 - x2;
X	    dy = y2 - y3;
X	    l2 = sqrt((double)(dx*dx + dy*dy));
X	    theta2 = atan2((double)dy, (double)dx);
X	    if (theta2 < 0) theta2 += _2xPI;
X	    cp = cp->next;
X	    control_points(x2, y2, l1, l2, theta1, theta2, T, cp);
X	    };
X
X	if (path == CLOSED_PATH) {
X	    dx = p2->x - x2;
X	    dy = y2 - p2->y;
X	    l2 = sqrt((double)(dx*dx + dy*dy));
X	    theta2 = atan2((double)dy, (double)dx);
X	    if (theta2 < 0) theta2 += _2xPI;
X	    cp = cp->next;
X	    control_points(x2, y2, l1, l2, theta1, theta2, T, cp);
X	    controls->lx = cp->lx; controls->ly = cp->ly;
X	    controls->rx = cp->rx; controls->ry = cp->ry;
X	    }
X	else {
X	    cpn = cp->next;
X	    cpn->lx = (3*cp->rx + x2) / 4; cpn->ly = (3*cp->ry + y2) / 4;
X	    cpn->rx = 0.0; cpn->ry = 0.0;
X	    cp->rx = (pk->x + 3*cp->rx) / 4; cp->ry = (pk->y + 3*cp->ry) / 4;
X	    }
X	}
X
X/*
XThe parameter t is the tension.  It must range in [0, 1].
XThe bigger the value of t, the higher the tension.
X*/
X
Xcontrol_points(x, y, l1, l2, theta1, theta2, t, cp)
Xfloat	x, y, l1, l2, theta1, theta2, t;
XF_control	*cp;
X{
X	float	s, theta, r = 1 - t;
X
X	/* 0 <= theat1, theta2 < 2PI */
X
X	theta = (theta1 + theta2) / 2;
X
X	if (theta1 > theta2) {
X	    s = sin((double)(theta-theta2));
X	    theta1 = theta + M_PI_2;
X	    theta2 = theta - M_PI_2;
X	    }
X	else {
X	    s = sin((double)(theta2-theta));
X	    theta1 = theta - M_PI_2;
X	    theta2 = theta + M_PI_2;
X	    }
X	if (s > _1dSQR2) s = _SQR2 - s;
X	s *= r;
X	l1 *= s; l2 *= s;
X	cp->lx = x + l1 * cos((double)theta1);
X	cp->ly = y - l1 * sin((double)theta1);
X	cp->rx = x + l2 * cos((double)theta2);
X	cp->ry = y - l2 * sin((double)theta2);
X	}
END_OF_intspline.c
if test 7649 -ne `wc -c <intspline.c`; then
    echo shar: \"intspline.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f msgsw.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"msgsw.c\"
else
echo shar: Extracting \"msgsw.c\" \(7513 characters\)
sed "s/^X//" >msgsw.c <<'END_OF_msgsw.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : Aug 1985.
X *	2nd revision : Feb 1988.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "const.h"
X#include "font.h"
X#include "paintop.h"
X
Xextern int		errno;
Xextern int		receiving_msg;
Xextern int		action_on;
Xextern			null_proc();
X
Xextern int		CANVAS_WIDTH;
Xextern char		prefix[], suffix[];
Xextern int		leng_prefix, leng_suffix;
Xextern int		cur_x, cur_y;
X
Xextern			(*canvas_kbd_proc)();
Xextern			(*canvas_locmove_proc)();
Xextern			(*canvas_leftbut_proc)();
Xextern			(*canvas_middlebut_proc)();
Xextern			(*canvas_rightbut_proc)();
X
X/*****************  exported  variables and procedures   *****************/
X
X			put_msg();
X			init_msgreceiving();
X
X/************************  local variables and routines ******************/
X
X#define			BUF_SIZE		80
X
Xstatic			(*msgsw_kbd_proc)();
Xstatic			(*msgsw_leftbut_proc)();
Xstatic			(*msgsw_rightbut_proc)();
Xstatic			(*recipient)();
X
Xstatic char		msg_received[BUF_SIZE];
Xstatic char		prompt[BUF_SIZE];
Xstatic int		len_prompt;
Xstatic int		base_x = 5, base_y = 18;
Xstatic int		input_base_x;
X
Xstatic			msg_selected();
Xstatic			msg_sighandler();
X
Xstatic			(*saved_canvas_kbd_proc)();
Xstatic			(*saved_canvas_locmove_proc)();
Xstatic			(*saved_canvas_leftbut_proc)();
Xstatic			(*saved_canvas_middlebut_proc)();
Xstatic			(*saved_canvas_rightbut_proc)();
X
X#ifndef	X11
Xint
Xinit_msg(tool)
XTOOL		tool;
X{
X	INPUTMASK		mask;
X
X	msg_sw = tool_createsubwindow(tool, "", -1, -1);
X	if (msg_sw == (TOOLSW)0) return(0);
X	msgswfd = msg_sw->ts_windowfd;
X	(void)fcntl(msgswfd, F_SETFL, fcntl(msgswfd, F_GETFL, 0) | O_NDELAY);
X
X	msg_pixwin = pw_open(msgswfd);
X	msg_sw->ts_io.tio_selected = msg_selected;
X	msg_sw->ts_io.tio_handlesigwinch = msg_sighandler;
X	msg_sw->ts_destroy = null_proc;
X
X	input_imnull(&mask);
X	win_setinputcodebit(&mask, MS_LEFT);
X	win_setinputcodebit(&mask, MS_RIGHT);
X	mask.im_flags |= IM_ASCII | IM_INTRANSIT;
X	win_setinputmask(msgswfd, &mask, NULL, WIN_NULLLINK);
X	win_setcursor(msgswfd, &pencil_cursor);
X	msgsw_kbd_proc = msgsw_leftbut_proc = msgsw_rightbut_proc = null_proc;
X	return(1);
X	}
X#else
Xstatic Arg      msg_args[] =
X{
X	{ XtNx, (XtArgVal)0 },
X	{ XtNy, (XtArgVal)0 },
X	{ XtNwidth, (XtArgVal)0 },
X	{ XtNheight, (XtArgVal)MSG_HEIGHT },
X	{ XtNlabel, (XtArgVal)"" },
X	{ XtNfromHoriz, (XtArgVal)NULL },
X	{ XtNhorizDistance, (XtArgVal)0 },
X	{ XtNfromVert, (XtArgVal)NULL },
X	{ XtNvertDistance, (XtArgVal)0 },
X};
X
Xint init_msg(tool)
X	TOOL		tool;
X{
X	msg_args[2].value = CANVAS_WIDTH;
X	msg_args[5].value = (XtArgVal)panel_sw;
X	msg_args[7].value = (XtArgVal)canvas_sw;
X	msg_sw = XtCreateManagedWidget("message", commandWidgetClass, tool,
X		msg_args, XtNumber(msg_args));
X	return (1);
X}
X
X/*
X**	We have to do this after realizing the widget otherwise
X**	the width is computed wrong and you get a tiny text box.
X*/
Xsetup_msg()
X{
X	static Arg      addn_args[] =
X	{
X		{ XtNfont, (XtArgVal)NULL },
X	};
X
X	if (bold_font != NULL)
X	{
X		addn_args[0].value = (XtArgVal)bold_font;
X		XtSetValues(msg_sw, addn_args, XtNumber(addn_args));
X	}
X	msgswfd = XtWindow(msg_sw);
X	XDefineCursor(tool_d, msgswfd, (Cursor)pencil_cursor.bitmap);
X}
X#endif	X11
X
X#ifndef	X11
Xstatic
Xmsg_selected(nullsw, ibits, obits, ebits, timer)
Xcaddr_t		*nullsw;
Xint		*ibits, *obits, *ebits;
Xstruct timeval	*timer;
X{
X	INPUTEVENT	   ie;
X
X	*ibits = *obits = *ebits = 0;
X	if (action_on) return;
X	if (input_readevent(msgswfd, &ie) == -1) {
X	    printf("error %d while read input event in msg window\n", errno);
X	    return;
X	    }
X	if (win_inputnegevent(&ie)) return;
X	if (! receiving_msg) return;
X
X	if (ie.ie_code <= ASCII_LAST) {
X	    msgsw_kbd_proc(ie.ie_code);
X	    }
X	else if (ie.ie_code == MS_LEFT) {
X	    msgsw_leftbut_proc(ie.ie_locx, ie.ie_locy);
X	    }
X	else if (ie.ie_code == MS_RIGHT) {
X	    msgsw_rightbut_proc(ie.ie_locx, ie.ie_locy);
X	    }
X	}
X
Xstatic
Xmsg_sighandler()
X{
X	pw_damaged(msg_pixwin);
X	pw_writebackground(msg_pixwin, 0, 0, 2048, 2048, PAINT);
X	pw_text(msg_pixwin, base_x, base_y, PAINT, bold_font, prompt);
X	pw_donedamaged(msg_pixwin);
X	}
X
X/*VARARGS1*/
Xput_msg(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
Xchar   *format, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8;
X{
X	clear_message();
X	sprintf(prompt, format, arg1, arg2, arg3, arg4, arg5, 
X		arg6, arg7, arg8);
X	pw_text(msg_pixwin, base_x, base_y, PAINT, bold_font, prompt);
X	}
X
Xclear_message()
X{
X	pw_writebackground(msg_pixwin, 0, 0, 2048, 2048, PAINT);
X	}
X#else
X/*VARARGS1*/
Xput_msg(format, arg1, arg2, arg3, arg4, arg5)
X	char	*format;
X	int	arg1, arg2, arg3, arg4, arg5;
X{
X	sprintf(prompt, format, arg1, arg2, arg3, arg4, arg5);
X	msg_args[4].value = (XtArgVal)prompt;
X	XtSetValues(msg_sw, &msg_args[4], 1);
X}
X
Xclear_message()
X{
X	msg_args[4].value = (XtArgVal)"";
X	XtSetValues(msg_sw, &msg_args[4], 1);
X}
X#endif	X11
X
Xstatic
Xend_char_input()
X{
X	receiving_msg = 0;  /*  msg input has been received  */
X	terminate_char_handler();
X	strcpy(&prefix[leng_prefix], suffix);
X	strcpy(msg_received, prefix);
X	strcpy(&prompt[len_prompt], prefix);
X	if (recipient != NULL) (* recipient) (msg_received);
X	restore_event_proc();
X	return;
X	}
X
Xstatic
Xreposition_cursor(x, y)
Xint	x, y;
X{
X	int		leng;
X	PR_SIZE		s;
X
X	strcpy(&prefix[leng_prefix], suffix);
X	leng = leng_prefix + leng_suffix; 
X	s = pf_textwidth(leng, bold_font, prefix);
X	if ( ! (input_base_x <= x && x <= input_base_x+s.x
X		&& base_y-s.y <= y && y <= base_y)) {
X	    prefix[leng_prefix] = '\0';
X	    return;
X	    }
X
X	leng_suffix = 0;
X	erase_char_string();
X	leng_prefix = prefix_length(bold_font, prefix, x-input_base_x);
X	strcpy(suffix, &prefix[leng_prefix]);
X	prefix[leng_prefix] = '\0';
X	leng_suffix = leng - leng_prefix;
X	s = pf_textwidth(leng_prefix, bold_font, prefix);
X	cur_x = input_base_x + s.x;
X	draw_char_string();
X	}
X
X#ifndef	X11
Xinit_msg_receiving(msg_recipient, p)
Xint	(*msg_recipient)();
Xchar	*p;			/* prompt */
X{
X	extern		char_handler();
X	PR_SIZE		prompt_size;
X
X	saved_canvas_kbd_proc = canvas_kbd_proc;
X	saved_canvas_locmove_proc = canvas_locmove_proc;
X	saved_canvas_leftbut_proc = canvas_leftbut_proc;
X	saved_canvas_middlebut_proc = canvas_middlebut_proc;
X	saved_canvas_rightbut_proc = canvas_rightbut_proc;
X
X	receiving_msg = 1;
X	msgsw_kbd_proc = char_handler;
X	msgsw_leftbut_proc = reposition_cursor;
X	canvas_kbd_proc = char_handler;
X	canvas_locmove_proc = null_proc;
X	canvas_leftbut_proc = null_proc;
X	canvas_rightbut_proc = null_proc;
X	recipient = msg_recipient;
X	blink_msg();
X	clear_message();
X	strcpy(prompt, p);
X	pw_text(msg_pixwin, base_x, base_y, PAINT, bold_font, prompt);
X
X	len_prompt = strlen(prompt);
X	prompt_size = pf_textwidth(len_prompt, bold_font, prompt);
X	cur_x = input_base_x = base_x + prompt_size.x;
X	cur_y = base_y;
X	leng_prefix = leng_suffix = 0;
X	*prefix = *suffix = '\0';
X	initialize_char_handler(msg_pixwin, bold_font, end_char_input, cur_x, base_y);
X	}
X#else
Xinit_msg_receiving(msg_recipient, p)
X	int		(*msg_recipient)();
X	char		*p;
X{
X	char		reply[100];
X
X	prompt_string(p, reply);
X	(*msg_recipient)(reply);
X}
X#endif	X11
X
Xrestore_event_proc()
X{
X	canvas_kbd_proc = saved_canvas_kbd_proc;
X	canvas_locmove_proc = saved_canvas_locmove_proc;
X	canvas_leftbut_proc = saved_canvas_leftbut_proc;
X	canvas_middlebut_proc = saved_canvas_middlebut_proc;
X	canvas_rightbut_proc = saved_canvas_rightbut_proc;
X	}
X
Xblink_msg()
X{
X	int	i;
X
X#ifndef	X11
X	pw_writebackground(msg_pixwin, 0, 0, 2048, 2048, ERASE);
X#else
X#endif	X11
X	for (i = 0; i < 2000; i++);
X	clear_message();
X	}
END_OF_msgsw.c
if test 7513 -ne `wc -c <msgsw.c`; then
    echo shar: \"msgsw.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f save.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"save.c\"
else
echo shar: Extracting \"save.c\" \(6448 characters\)
sed "s/^X//" >save.c <<'END_OF_save.c'
X/* 
X *	FIG : Facility for Interactive Generation of figures
X *
X *	Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
X *	January 1985.
X *	1st revision : August 1985.
X *	2nd revision : March 1988.
X *
X *	%W%	%G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "func.h"
X#include "object.h"
X#include "const.h"
X
Xextern F_compound	objects;
X
Xextern int		figure_modified;
Xextern int		errno;
X
Xextern 			null_proc();
X
Xextern char		*sys_errlist[];
Xextern int		sys_nerr, errno;
Xextern int		num_object;
X
Xwrite_file(file_name, prompt)
Xchar	*file_name;
Xint	prompt;
X{
X	FILE		*fp;
X	struct stat	file_status;
X	char		string[180];
X
X	if (*file_name == 0) {
X	    put_msg("No file.  Abort save operation.");
X	    return(-1);
X	    }
X	if (stat(file_name, &file_status) == 0) { /* file exists */
X	    if (file_status.st_mode & S_IFDIR) {
X		put_msg("\"%s\" is a directory", file_name);
X		return(-1);
X		}
X	    if (file_status.st_mode & S_IWRITE) { /* writing is permitted */
X		if (file_status.st_uid != geteuid()) {
X		    put_msg("\"%s\" permission is denied", file_name);
X		    return(-1);
X		    }
X		else if (prompt) {
X		    sprintf(string, "\"%s\" File exists. Please click the LEFT button to COMFIRM overwrite. To cancel, click the MIDDLE or RIGHT button.", file_name);
X		    if (wmgr_confirm(canvas_swfd, string) != -1) {
X			put_msg("Cancel save");
X			return(-1);
X			}
X		    }
X		}
X	    else {
X		put_msg("\"%s\" File is read only", file_name);
X		return(-1);
X		}
X	    }
X	else if (errno != ENOENT)
X	    return(-1);  /* file does exist but stat fails */
X
X	if ((fp = fopen(file_name, "w")) == NULL) {
X	    blink_msg();
X	    put_msg("Couldn't open file %s, %s", file_name, sys_errlist[errno]);
X	    return(-1);
X	    }
X	else {
X	    figure_modified = 0;
X	    num_object = 0;
X	    write_objects(fp);
X	    put_msg("%d objects saved in \"%s\"", num_object, file_name);
X	    return(0);
X	    }
X	}
X
Xwrite_objects(fp)
XFILE	*fp;
X{
X	extern char	file_header[];
X	F_arc		*a;
X	F_compound	*c;
X	F_ellipse	*e;
X	F_line		*l;
X	F_spline	*s;
X	F_text		*t;
X
X	/*  Number 2 means that the origin (0,0) is at the upper
X	left corner of the screen (2nd quadrant)	*/
X
X	put_msg("Writing . . .");
X	fprintf(fp, "%s\n", file_header);
X	fprintf(fp, "%d %d\n", PIX_PER_INCH, 2);
X	for (a = objects.arcs; a != NULL; a = a-> next) {
X	    num_object++;
X	    write_arc(fp, a);
X	    }
X	for (c = objects.compounds; c != NULL; c = c-> next) {
X	    num_object++;
X	    write_compound(fp, c);
X	    }
X	for (e = objects.ellipses; e != NULL; e = e-> next) {
X	    num_object++;
X	    write_ellipse(fp, e);
X	    }
X	for (l = objects.lines; l != NULL; l = l-> next) {
X	    num_object++;
X	    write_line(fp, l);
X	    }
X	for (s = objects.splines; s != NULL; s = s-> next) {
X	    num_object++;
X	    write_spline(fp, s);
X	    }
X	for (t = objects.texts; t != NULL; t = t-> next) {
X	    num_object++;
X	    write_text(fp, t);
X	    }
X	fclose(fp);
X	}
X
Xwrite_arc(fp, a)
XFILE	*fp;
XF_arc	*a;
X{
X	F_arrow	*f, *b;
X
X	fprintf(fp, "%d %d %d %d %d %d %d %d %.3f %d %d %d %.3f %.3f %d %d %d %d %d %d\n",
X		O_ARC, a->type, a->style, a->thickness, 
X		a->color, a->depth, a->pen, a->area_fill,
X		a->style_val, a->direction,
X		((f = a->for_arrow) ? 1 : 0), ((b = a->back_arrow) ? 1 : 0),
X		a->center.x, a->center.y, 
X		a->point[0].x, a->point[0].y, 
X		a->point[1].x, a->point[1].y, 
X		a->point[2].x, a->point[2].y);
X	if (f)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", f->type, f->style,
X			f->thickness, f->wid, f->ht);
X	if (b)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", b->type, b->style,
X			b->thickness, b->wid, b->ht);
X	}
X
Xwrite_compound(fp, com)
XFILE		*fp;
XF_compound	*com;
X{
X	F_arc		*a;
X	F_compound	*c;
X	F_ellipse	*e;
X	F_line		*l;
X	F_spline	*s;
X	F_text		*t;
X
X	fprintf(fp, "%d %d %d %d %d\n", O_COMPOUND, com->nwcorner.x,
X		com->nwcorner.y, com->secorner.x, com->secorner.y);
X	for (a = com->arcs; a != NULL; a = a-> next) write_arc(fp, a);
X	for (c = com->compounds; c != NULL; c = c-> next) write_compound(fp, c);
X	for (e = com->ellipses; e != NULL; e = e-> next) write_ellipse(fp, e);
X	for (l = com->lines; l != NULL; l = l-> next) write_line(fp, l);
X	for (s = com->splines; s != NULL; s = s-> next) write_spline(fp, s);
X	for (t = com->texts; t != NULL; t = t-> next) write_text(fp, t);
X	fprintf(fp, "%d\n", O_END_COMPOUND);
X	}
X
Xwrite_ellipse(fp, e)
XFILE		*fp;
XF_ellipse	*e;
X{
X	fprintf(fp, "%d %d %d %d %d %d %d %d %.3f %d %.3f %d %d %d %d %d %d %d %d\n",
X		O_ELLIPSE, e->type, e->style, e->thickness, 
X		e->color, e->depth, e->pen, e->area_fill,
X		e->style_val, e->direction, e->angle,
X		e->center.x, e->center.y, 
X		e->radiuses.x, e->radiuses.y, 
X		e->start.x, e->start.y, 
X		e->end.x, e->end.y);
X	}
X
Xwrite_line(fp, l)
XFILE	*fp;
XF_line	*l;
X{
X	F_point	*p;
X	F_arrow	*f, *b;
X
X	fprintf(fp, "%d %d %d %d %d %d %d %d %.3f %d %d\n",
X		O_POLYLINE, l->type, l->style, l->thickness,
X		l->color, l->depth, l->pen, l->area_fill, l->style_val, 
X		((f = l->for_arrow) ? 1 : 0), ((b = l->back_arrow) ? 1 : 0));
X	if (f)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", f->type, f->style,
X			f->thickness, f->wid, f->ht);
X	if (b)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", b->type, b->style,
X			b->thickness, b->wid, b->ht);
X	fprintf(fp, "\t");
X	for (p = l->points; p!= NULL; p = p->next) {
X	    fprintf(fp, " %d %d", p->x, p->y);
X	    };
X	fprintf(fp, " 9999 9999\n");
X	}
X
Xwrite_spline(fp, s)
XFILE		*fp;
XF_spline	*s;
X{
X	F_control	*cp;
X	F_point		*p;
X	F_arrow		*f, *b;
X
X	fprintf(fp, "%d %d %d %d %d %d %d %d %.3f %d %d\n",
X		O_SPLINE, s->type, s->style, s->thickness,
X		s->color, s->depth, s->pen, s->area_fill, s->style_val,
X		((f = s->for_arrow) ? 1 : 0), ((b = s->back_arrow) ? 1 : 0));
X	if (f)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", f->type, f->style,
X			f->thickness, f->wid, f->ht);
X	if (b)
X	    fprintf(fp, "\t%d %d %.3f %.3f %.3f\n", b->type, b->style,
X			b->thickness, b->wid, b->ht);
X	fprintf(fp, "\t");
X	for (p = s->points; p != NULL; p = p->next) {
X	    fprintf(fp, " %d %d", p->x, p->y);
X	    };
X	fprintf(fp, " 9999 9999\n");  /* terminating code  */
X
X	if (s->controls == NULL) return;
X	fprintf(fp, "\t");
X	for (cp = s->controls; cp != NULL; cp = cp->next) {
X	    fprintf(fp, " %.3f %.3f %.3f %.3f",
X			cp->lx, cp->ly, cp->rx, cp->ry);
X	    };
X	fprintf(fp, "\n");
X	}
X
Xwrite_text(fp, t)
XFILE	*fp;
XF_text	*t;
X{
X	fprintf(fp, "%d %d %d %d %d %d %d %.3f %d %d %d %d %d %s\1\n", 
X		O_TEXT, t->type, t->font, t->size, t->pen,
X		t->color, t->depth, t->angle,
X		t->style, t->height, t->length, 
X		t->base_x, t->base_y, t->cstring);
X	}
END_OF_save.c
if test 6448 -ne `wc -c <save.c`; then
    echo shar: \"save.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 11\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 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
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330