[comp.sources.unix] v11i097: Graphcs editor for Suns, Part01/06

rsalz@uunet.UU.NET (Rich Salz) (10/07/87)

Submitted-by: steinmetz!sbcs!nyfca1!chan (Douglas Chan)
Posting-number: Volume 11, Issue 97
Archive-name: graphedit/part01

  This is the first release of a graphic editor implemented for Suns
running Sun 3.2 or latter.  Some minor changes are necessary to run it on
Sun 3.0 (mostly on the device dependent part, eg. anything related
to cg4dd()) and I did not do it because there is no Sun running 3.0 here.

Features of the current program include:
  1) display and edit of diagram with SunCore
  2) select operations and options on control pad in SunView
  3) save/load of diagram in PostScript
  4) output of diagram in rasterfile(5), plot(5) and pic(1) format
  5) draw lines, polygon, circle, ellipse, arc, rectangle, text
     and freehand
  6) operations on 'segments' include create, edit, save, load, copy,
     move, rotate, scale, join, break, delete and undelete
  7) can specify line width, linestyle, font, character size, and greylevel
  8) grid and alignment
  9) options to specify how to place diagram on 8.5 x 11 paper (PostScript only)
 10) global scale of diagram

  More information is in README and graphedit.l (manual page).

  Have fun!!!

Douglas Chan.

Address: Computer Science Department
         State University of New York at Stony Brook
         Stony Brook, NY 11794

csnet address: chan@sbcs.csnet
uucp address: {allegra,philabs,pyramid}!sbcs!chan

---------Cut Here--------Cut Here--------Cut Here--------Cut Here--------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Contents:  README Makefile display.h panel.c savepanel.c
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'

  @(#)README	1.1 6/8/87 Copyright 1987 SBCS-chan

******************************************************************************

          (c) Copyright 1987 

          Lap-Tak Chan
          Computer Science Department
          State University of New York at Stony Brook
          Stony Brook, NY 11794

    This software and its documentation may be used, copied, and
  distributed, provided that this legend appear in all copies and
  that it is not copied or distributed for a profit.

  No representations is made about the suitability of this software
  for any purpose.  It is provided "as is" with no support and no
  express or implied warranty.

******************************************************************************

  graphedit is a general purpose graphic editor for Sun workstations.
It was implemented on Sun-3s running Sun release 3.2 with SunView
and SunCore.  Some changes on core.c are necessary to run it on
Sun 3.0.

  Features of the current version of graphedit include:

  1) display and edit of diagram with SunCore
  2) select operations and options on control pad in SunView
  3) save/load of diagram in PostScript
  4) output of diagram in rasterfile(5), plot(5) and pic(1) format
  5) draw lines, polygon, circle, ellipse, arc, rectangle, text
     and freehand
  6) operations on 'segments' include create, edit, save, load, copy,
     move, rotate, scale, join, break, delete and undelete
  7) can specify line width, linestyle, font, character size, and greylevel
  8) grid and alignment
  9) options to specify how to place diagram on 8.5 x 11 paper (PostScript only)
 10) global scale of diagram
 11) usage and message panel to display messages and "how-to"s
 12) many other options

  Files in this directory include:
README                you are reading it
display.h             include file used by all c files
draw.c                editing routines
core.c                SunCore interface
display.c             maintain display list for storage of diagram
panel.c               create control pad
savepanel.c           create options window
misc.c                some math routines
optmize.c             internal optimizer
ps.c                  save/load diagram/segment in PostScript
pic.c                 output diagram for pic(1)
plot.c                output diagram in plot(5)
optm.c                driver for internal optimizer
ps2pic.c              driver to convert saved diagram to pic(1)
ps2plot.c             driver to convert saved diagram to plot(1)
images                directory for icon and images created by iconedit(1)
Makefile              makefile for graphedit
ps.head               header file for saved diagram (in PostScript)
graphedit.l           manual page

  To install it, set the parameters at the beginning of Makefile and do
    make install
More information on the installation is available in Makefile.

  You may modify the source to fix bugs and port it for any new Sun
hardware (e.g. cgfive0).  Please send any fixes to me at chan@sbcs.csnet
or {allegra,philabs,pyramid}!sbcs!chan so I can add them to future
releases.

  There is ongoing effort to add more advance editing functions
and primitives to graphedit, and to improve the existing
functions.  Please do not modify the source for any enhancement
to avoid duplicate efforts and any difficulty on combining
the enhancement to future releases.  You are welcome to send
suggestions to me at the email addresses above.
@//E*O*F README//
chmod u=r,g=r,o=r README
 
echo x - Makefile
sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
#
# @(#)Makefile	1.2 6/8/87 Copyright 1987 SBCS-chan
# 
#******************************************************************************
#
#          (c) Copyright 1987 
#
#          Lap-Tak Chan
#          Computer Science Department
#          State University of New York at Stony Brook
#          Stony Brook, NY 11794
#
#    This software and its documentation may be used, copied, and
#  distributed, provided that this legend appear in all copies and
#  that it is not copied or distributed for a profit.
#
#  No representations is made about the suitability of this software
#  for any purpose.  It is provided "as is" with no support and no
#  express or implied warranty.
#
#******************************************************************************

#
#  To install graphedit, set the proper value of the following parameters
#  and do 'make install':
#    LIB - existing directory where the header file will be installed
#    BIN - existing directory to install the binaries
#    BINARIES - what binaries to make
#    CFLAGS - C compiler options
#    LFLAGS - libraries, 'core' may be changed to 'corefpa' or 'core68881'
#             for different floating point options
#
#  ps2pic, optm, ps2plot are optional filters which take a saved PostScript
#  diagram from standard input and produce pic output, optimized PostScript,
#  and plot output on stardard output respectively.
#
#  graphedit.l should be installed manually because of differnet ways to
#  handle local manual pages at different sites.
#
LIB=/usr/local/lib

BIN=/usr/local/bin

BINARIES=graphedit ps2pic optm ps2plot

CFLAGS=-DGE_DEFAULTLIB=\"$(LIB)\" -O -fswitch -s

LFLAGS=-lcore -lsuntool -lsunwindow -lpixrect -lplot -lm

OBJ=draw.o panel.o core.o display.o ps.o savepanel.o pic.o plot.o optmize.o misc.o

OPTMOBJ=optm.o ps.o display.o optmize.o

PS2PLOTOBJ=ps2plot.o plot.o ps.o display.o misc.o

PS2PICOBJ=ps2pic.o pic.o ps.o display.o misc.o

BACKUP=/u7/sr/chan/backup/newdraw

FILES=README Makefile display.h draw.c panel.c core.c display.c ps.c savepanel.c pic.c plot.c optmize.c misc.c ps2pic.c ps2plot.c optm.c images images/* ps.head graphedit.l

make: $(BINARIES)

graphedit: ${OBJ}
	cc ${CFLAGS} -o graphedit ${OBJ} ${LFLAGS}

ps2pic: ${PS2PICOBJ}
	cc ${CFLAGS} -o ps2pic ${PS2PICOBJ} -lm

optm: ${OPTMOBJ}
	cc ${CFLAGS} -o optm ${OPTMOBJ}

ps2plot: ${PS2PLOTOBJ}
	cc ${CFLAGS} -o ps2plot ${PS2PLOTOBJ} -lplot -lm

all: graphedit ps2pic optm ps2plot

install: ${BINARIES}
	/bin/cp -p ${BINARIES} ${BIN}
	/bin/cp -p ps.head ${LIB}

backup:
	tar cf ${BACKUP} ${FILES} SCCS

shar:
	./makeshar

clean:
	/bin/rm -f ${OBJ} ${OPTMOBJ} ${PS2PICOBJ} ${PS2PLOTOBJ} ${BINARIES}
@//E*O*F Makefile//
chmod u=rw,g=r,o=r Makefile
 
echo x - display.h
sed 's/^@//' > "display.h" <<'@//E*O*F display.h//'

/* @(#)display.h	1.2	6/8/87 Copyright 1987 SBCS-chan */

/*****************************************************************************

          (c) Copyright 1987 

          Lap-Tak Chan
          Computer Science Department
          State University of New York at Stony Brook
          Stony Brook, NY 11794

    This software and its documentation may be used, copied, and
  distributed, provided that this legend appear in all copies and
  that it is not copied or distributed for a profit.

  No representations is made about the suitability of this software
  for any purpose.  It is provided "as is" with no support and no
  express or implied warranty.

*****************************************************************************/

/*****************************************************************************

                             display.h

   This file defines the constants and structures for graphedit.

*****************************************************************************/

#define GE_VERSION "1.1" /* current version of graphedit */

/* display instructions */
#define GE_MOVE	1	/* move */
#define GE_LINE 2	/* line */
#define GE_PLOT 3	/* move and intensify at end of stroke */
#define GE_POLYLINE 4	/* polyline */
#define GE_POLYGON 5	/* polygon */
#define GE_TEXT 6	/* text */
#define GE_ARC 7	/* arc */
#define GE_CIRCLE 8	/* circle */
#define GE_ELLIPSE 9	/* ellipse */
#define GE_CONT 10	/* continue of point list of last polygon/polyline */
#define GE_ARCEXT 11	/* extension for arc */
#define GE_SETCOLOR 20	/* change color attribute */
#define GE_SETTYPELINE 21	/* change line style */
#define GE_SETLINEWIDTH 22	/* change line width */
#define GE_SETFONT 23	/* change font */
#define GE_TRANSLATE 24
#define GE_ROTATE 25
#define GE_SCALE 26
#define GE_SETCHARSIZE 27 /* change character size */
#define GE_FILL 28	/* border/fill */
#define GE_NEW 31	/* beginning of new segment */
#define GE_DELETE 32	/* delete old segment */
#define GE_CLOSE 33	/* close a segment */

/* parameters for border/fill */
#define GE_BORDERONLY 0
#define GE_FILLONLY 1
#define GE_FILLBORDER 2

#define MAXUNDELETE 10 /* maximum number of segments which can be undeleted */

#define GE_OPENMAX 512	/* maximum number of opened segemnts at any time */

/* sample segments */
#define GE_COLOR_SAMPLE 1	/* show different color */
#define GE_LINE_SAMPLE 2	/* show different linewidth and linestyle */
#define GE_CHAR_SAMPLE 3	/* show different character size and font */
#define GE_GRID 4	/* grid */
#define GE_CIRCLE_SAMPLE 5	/* used to draw ellipse/circle */
#define GE_CROSSHAIR 6	/* echo at location read */
#define GE_ARC_SAMPLE 7	/* used to draw arc */
#define GE_MIN_SEG 10	/* lowest segment number available to user */

/* define size of window in world coordinate */
#define GE_WIN_X 511.
#define GE_WIN_Y 383.

#define GE_DEFAULT_GRID 10.
#define GE_MIN_GRID 5.
#define GE_DEFAULT_CHARSIZE 8
#define GE_DEFAULT_RADIUS 10.
#define PI 3.1415927

/* define how picture will be positioned on 8.5 x 11 paper */
struct saveattr {
  int fix;	/* 0 - Scale, 1 - Fix Width, 2 - Fix Height */
  int rotate;	/* whether picture is rotated 90 degree */
  int width;	/* width of picture, independent to rotate */
  int height;	/* height of picture, independent to rotate */
  int center;	/* whether picture is centered on paper */
  int offa;	/* horizontal offset */
  int offb;	/* vertical offset */
};

/* define attributes of a segment */
struct attr {
  float tx, ty;	/* translation in world coordinate */
  float ang;	/* angle of rotation in radian */
  float sx, sy;	/* scaling factor */
  int color;	/* color in 0-11 from light to dark*/
  int linestyle;/* line style, 0 - solid, 1 - dotted, 2 - dashed, 3 - dotdash */
  int linewidth;/* line width */
  int font;	/* font, 0 - Courier, 1 - Roman, 2- Greek, 3 - BoldItalic,
                   4 - Bold */
  int charsize;	/* character size */
  int drawn;	/* whether segment was drawn by ge_draw */
  int deleted;	/* whether segment was marked as deleted */
};

/* a display item */
struct list_item {
  int instr;  /* display instruction (move, plot, line, etc) */
  float x,y;  /* display coordinate (or other parameters) */
  struct list_item *next; /* point to next display item */
};

/* display list of a segment */
struct list {
  int segno; /* segment number */
  struct list_item *d_list; /* list of display items */
  int next; /* point to next segment */
  struct attr attr; /* attributes of segment */
};
@//E*O*F display.h//
chmod u=r,g=r,o=r display.h
 
echo x - panel.c
sed 's/^@//' > "panel.c" <<'@//E*O*F panel.c//'

static char SccsId[] = "@(#)panel.c	1.2 6/8/87 Copyright 1987 SBCS-chan";

/*****************************************************************************

          (c) Copyright 1987 

          Lap-Tak Chan
          Computer Science Department
          State University of New York at Stony Brook
          Stony Brook, NY 11794

    This software and its documentation may be used, copied, and
  distributed, provided that this legend appear in all copies and
  that it is not copied or distributed for a profit.

  No representations is made about the suitability of this software
  for any purpose.  It is provided "as is" with no support and no
  express or implied warranty.

*****************************************************************************/

/*****************************************************************************

                          Control Pad
                          ===========

    This file contains routines for making and maintaining the control
  pad of graphedit.

*****************************************************************************/

#include <suntool/sunview.h>
#include <suntool/panel.h>
#include "display.h"

/* external notify procedures for panel items in the control pad */
extern void do_new_seg(), do_del_seg(),
              do_align(), do_grid(),
              do_polyline(),do_circle(),do_rect(),
              do_polygon(), do_text(), do_pos(),
              do_rot(), do_size(), do_attributes(), do_save_seg(),
              do_restore_seg(), do_exit(), do_save_pic(), do_restore_pic(),
              do_change_color(), do_change_linewidth(), do_change_linestyle(),
              do_chg_xformchar(), do_change_font(), ge_refresh(), do_undelete(),
              do_confirm_exit(), do_copy_segment(), do_break(), do_arc(),
              do_change_grid(), do_edit_seg(), do_change_charsize(),
              do_join(), do_clear(), do_trace(), do_ellipse(), do_output(),
              do_global_scale();

void do_show_save();

/* exported panel items for draw.c */
Panel_item text_filen, text_textstr, mesg_display, mesg_usage;
Panel_item slider_linewidth, menu_linestyle, menu_font, slider_color,
           cycle_grid, cycle_align, cycle_fill,
           slider_gridx, slider_gridy, slider_charsize, cycle_save;

/* define pixrect images for the panel items */
  static short polyline_pr_image[]={
#include "images/polyline.pr"
  };

  static short polygon_pr_image[]={
#include "images/polygon.pr"
  };

  static short circle_pr_image[]={
#include "images/circle.pr"
  };

  static short rect_pr_image[]={
#include "images/rect.pr"
  };

  static short trace_pr_image[]={
#include "images/trace.pr"
  };

  static short ellipse_pr_image[]={
#include "images/ellipse.pr"
  };

  static short arc_pr_image[]={
#include "images/arc.pr"
  };

  static short text_pr_image[]={
#include "images/text.pr"
  };

  static short border_pr_image[]={
#include "images/border.pr"
  };

  static short fill_pr_image[]={
#include "images/fill.pr"
  };

  static short borderfill_pr_image[]={
#include "images/borderfill.pr"
  };

  static short solid_pr_image[]={
#include "images/solid.pr"
  };

  static short dot_pr_image[]={
#include "images/dot.pr"
  };

  static short dash_pr_image[]={
#include "images/dash.pr"
  };

  static short dotdash_pr_image[]={
#include "images/dotdash.pr"
  };

  mpr_static(polyline_pr, 16, 16, 1, polyline_pr_image);
  mpr_static(polygon_pr, 16, 16, 1, polygon_pr_image);
  mpr_static(circle_pr, 16, 16, 1, circle_pr_image);
  mpr_static(rect_pr, 16, 16, 1, rect_pr_image);
  mpr_static(trace_pr, 16, 16, 1, trace_pr_image);
  mpr_static(ellipse_pr, 16, 16, 1, ellipse_pr_image);
  mpr_static(arc_pr, 16, 16, 1, arc_pr_image);
  mpr_static(text_pr, 16, 16, 1, text_pr_image);
  mpr_static(border_pr, 64, 14, 1, border_pr_image);
  mpr_static(fill_pr, 64, 14, 1, fill_pr_image);
  mpr_static(borderfill_pr, 64, 14, 1, borderfill_pr_image);
  mpr_static(solid_pr, 64, 14, 1, solid_pr_image);
  mpr_static(dot_pr, 64, 14, 1, dot_pr_image);
  mpr_static(dash_pr, 64, 14, 1, dash_pr_image);
  mpr_static(dotdash_pr, 64, 14, 1, dotdash_pr_image);

/*****************************************************************************

    make_control_panel will create the message panel, main panel, segment
  panel, primitive panel and attribute panel in frame.  Each panel will
  have a number of panel items in it.

  Input
    frame - the frame to create the panels in

*****************************************************************************/

make_control_panel(frame)
Frame frame;
{
  Panel panels[5];
#define mesg_panel panels[0]
#define main_panel panels[1]
#define seg_panel  panels[2]
#define draw_panel panels[3]
#define attr_panel panels[4]

  /* panel items known internally */
  Panel_item but_new_seg, but_del_seg, but_clear,
             but_polyline, but_polygon, but_circle, but_rect,
             but_text, but_pos, but_rot, but_size, but_join, but_undelete,
             but_attributes, but_save_seg, but_restore_seg, but_edit_seg,
             but_exit, but_save_pic, but_restore_pic, but_redisplay,
             but_copy_seg, cycle_grid, cycle_align, but_break, but_trace,
             but_ellipse, but_output, but_arc, but_glbscale;

  /* create the message panel */
  mesg_panel=window_create(frame, PANEL, 0);

  /* item for the message */
  mesg_display=panel_create_item(mesg_panel, PANEL_MESSAGE,
               PANEL_LABEL_STRING, " ",
               PANEL_LABEL_BOLD, TRUE,               
               PANEL_ITEM_Y, ATTR_ROW(0),
               0);

  /* item for the usage */
  mesg_usage=panel_create_item(mesg_panel, PANEL_MESSAGE,
               PANEL_LABEL_STRING, " ",
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(1),
               0);

  window_fit(mesg_panel);

  /* create the main panel */
  main_panel=window_create(frame, PANEL,
               WIN_BELOW, mesg_panel,
               WIN_X, ATTR_COLS(0),
               0);

  /* save button */
  but_save_pic=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Save",
               4,0),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_save_pic,
               0);

  /* load button */
  but_restore_pic=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Load",
               4,0),
               PANEL_ITEM_X, ATTR_COL(6),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_restore_pic,
               0);

  /* redisplay button */
  but_redisplay=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
	       "Redisplay",
               9,0),
               PANEL_ITEM_X, ATTR_COL(12),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, ge_refresh,
               0);

  /* quit button */
  but_exit=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Quit",
               4,0),
               PANEL_ITEM_X, ATTR_COL(23),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_confirm_exit,
               0);

  /* clear button */
  but_clear=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Clear",
               5,0),
               PANEL_ITEM_X, ATTR_COL(29),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_clear,
               0);

  /* scale button */
  but_glbscale=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Scale",
               5,0),
               PANEL_ITEM_X, ATTR_COL(36),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_global_scale,
               0);

  /* output button */
  but_output=panel_create_item(main_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(main_panel,
               "Output",
               6,0),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_output,
               0);

  /* file name field */
  text_filen=panel_create_item(main_panel, PANEL_TEXT,
               PANEL_LABEL_STRING, "File:",
               PANEL_VALUE_DISPLAY_LENGTH, 30,
               PANEL_ITEM_X, ATTR_COL(8),
               PANEL_ITEM_Y, ATTR_ROW(1),
               0);

  window_fit(main_panel);

  /* create the segment panel */
  seg_panel=window_create(frame, PANEL,
               WIN_BELOW, main_panel,
               WIN_X, ATTR_COLS(0),
               0);

  /* create button */
  but_new_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Create",
               6,0),
               PANEL_NOTIFY_PROC, do_new_seg,
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0),
               0);

  /* edit button */
  but_edit_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Edit",
               4,0),
               PANEL_ITEM_X, ATTR_COL(8),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_edit_seg,
               0);

  /* delete button */
  but_del_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Delete",
               6,0),
               PANEL_ITEM_X, ATTR_COL(14),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_del_seg,
               0);

  /* save button */
  but_save_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Save",
               4,0),
               PANEL_ITEM_X, ATTR_COL(22),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_save_seg,
               0);

  /* load button */
  but_restore_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Load",
               4,0),
               PANEL_ITEM_X, ATTR_COL(28),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_restore_seg,
               0);

  /* copy button */
  but_copy_seg=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
	       "Copy",
               4,0),
               PANEL_ITEM_X, ATTR_COL(34),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_copy_segment,
               0);

  /* move button */
  but_pos=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Move",
               4,0),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_pos,
               0);

  /* rotate button */
  but_rot=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Rotate",
               6,0),
               PANEL_ITEM_X, ATTR_COL(6),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_rot,
               0);

  /* scale button */
  but_size=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Scale",
               5,0),
               PANEL_ITEM_X, ATTR_COL(14),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_size,
               0);

  /* join button */
  but_join=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Join",
               4,0),
               PANEL_ITEM_X, ATTR_COL(21),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_join,
               0);

  /* break button */
  but_break=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Break",
               5,0),
               PANEL_ITEM_X, ATTR_COL(27),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_break,
               0);

  /* undelete button */
  but_undelete=panel_create_item(seg_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, panel_button_image(seg_panel,
               "Undelete",
               4,0),
               PANEL_ITEM_X, ATTR_COL(34),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_undelete,
               0);

  window_fit(seg_panel);

  /* create the primitive panel */
  draw_panel=window_create(frame, PANEL,
               WIN_BELOW, seg_panel,
               WIN_X, ATTR_COLS(0),
               0);

  /* polyline button */
  but_polyline=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &polyline_pr,
               PANEL_NOTIFY_PROC, do_polyline,
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0),
               0);

  /* polygon button */
  but_polygon=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &polygon_pr,
               PANEL_ITEM_X, ATTR_COL(4),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_polygon,
               0);

  /* circle button */
  but_circle=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &circle_pr,
               PANEL_ITEM_X, ATTR_COL(8),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_circle,
               0);

  /* rectangle button */
  but_rect=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &rect_pr,
               PANEL_ITEM_X, ATTR_COL(12),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_rect,
               0);

  /* trace button */
  but_trace=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &trace_pr,
               PANEL_ITEM_X, ATTR_COL(16),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_trace,
               0);

  /* ellipse button */
  but_ellipse=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &ellipse_pr,
               PANEL_NOTIFY_PROC, do_ellipse,
               PANEL_ITEM_X, ATTR_COL(20),
               PANEL_ITEM_Y, ATTR_ROW(0),
               0);

  /* arc button */
  but_arc=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &arc_pr,
               PANEL_NOTIFY_PROC, do_arc,
               PANEL_ITEM_X, ATTR_COL(24),
               PANEL_ITEM_Y, ATTR_ROW(0),
               0);

  /* text button */
  but_text=panel_create_item(draw_panel, PANEL_BUTTON,
               PANEL_LABEL_IMAGE, &text_pr,
               PANEL_NOTIFY_PROC, do_text,
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0)+20,
               0);

  /* text field */
  text_textstr=panel_create_item(draw_panel, PANEL_TEXT,
                 PANEL_LABEL_STRING, ":",
                 PANEL_VALUE_DISPLAY_LENGTH, 30,
                 PANEL_ITEM_Y, ATTR_ROW(0)+20,
                 PANEL_ITEM_X, ATTR_COL(3),
                 0);

  window_fit(draw_panel);

  /* create the attribute panel */
  attr_panel=window_create(frame, PANEL,
               WIN_BELOW, draw_panel,
               WIN_X, ATTR_COLS(0),
               0);

  /* line width slider */
  slider_linewidth=panel_create_item(attr_panel, PANEL_SLIDER,
               PANEL_LABEL_STRING, "Line width:",
               PANEL_VALUE, 0,
               PANEL_MIN_VALUE, 0,
               PANEL_MAX_VALUE, 99,
               PANEL_SHOW_VALUE, TRUE,
               PANEL_SLIDER_WIDTH, ATTR_COLS(15),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_NOTIFY_PROC, do_change_linewidth,
               0);

  /* slider for grid interval along x axis */
  slider_gridx=panel_create_item(attr_panel, PANEL_SLIDER,
               PANEL_LABEL_STRING, "Grid interval: x",
               PANEL_VALUE, (int) GE_DEFAULT_GRID,
               PANEL_MIN_VALUE, (int) GE_MIN_GRID,
               PANEL_MAX_VALUE, (int) (GE_WIN_X/10),
               PANEL_SLIDER_WIDTH, ATTR_COLS(15),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(1),
               PANEL_NOTIFY_PROC, do_change_grid,
               0);

  /* slider for grid interval along y axis */
  slider_gridy=panel_create_item(attr_panel, PANEL_SLIDER,
               PANEL_LABEL_STRING, "               y",
               PANEL_VALUE, (int) GE_DEFAULT_GRID,
               PANEL_MIN_VALUE, (int) GE_MIN_GRID,
               PANEL_MAX_VALUE, (int) (GE_WIN_Y/10),
               PANEL_SLIDER_WIDTH, ATTR_COLS(15),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(2),
               PANEL_NOTIFY_PROC, do_change_grid,
               0);

  /* color slider */
  slider_color=panel_create_item(attr_panel, PANEL_SLIDER,
               PANEL_LABEL_STRING, "Color:",
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(3),
               PANEL_VALUE, 0,
               PANEL_MIN_VALUE, 0,
               PANEL_MAX_VALUE, 11,
               PANEL_SLIDER_WIDTH, ATTR_COLS(15),
               PANEL_NOTIFY_PROC, do_change_color,
               0);

  /* character size slider */
  slider_charsize=panel_create_item(attr_panel, PANEL_SLIDER,
               PANEL_LABEL_STRING, "Font size:",
               PANEL_VALUE, (int) GE_DEFAULT_CHARSIZE,
               PANEL_MIN_VALUE, 1,
               PANEL_MAX_VALUE, (int) 20,
               PANEL_SLIDER_WIDTH, ATTR_COLS(15),
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(4),
               PANEL_NOTIFY_PROC, do_change_charsize,
               0);

  /* line style menu */
  menu_linestyle=panel_create_item(attr_panel, PANEL_CHOICE,
                   PANEL_LABEL_STRING, "Line Style :",
                   PANEL_FEEDBACK, PANEL_MARKED,
                   PANEL_ITEM_X, ATTR_COL(0),
                   PANEL_ITEM_Y, ATTR_ROW(5),
                   PANEL_CHOICE_IMAGES, &solid_pr, &dot_pr,
                                        &dash_pr, &dotdash_pr, 0,
                   PANEL_CHOICE_XS,
                     ATTR_COL(4),ATTR_COL(4),ATTR_COL(4),ATTR_COL(4),0,
                   PANEL_CHOICE_YS,
                     ATTR_ROW(7),ATTR_ROW(8),ATTR_ROW(9),ATTR_ROW(10),0,
                   PANEL_MARK_XS,
                     ATTR_COL(0),ATTR_COL(0),ATTR_COL(0),ATTR_COL(0),0,
                   PANEL_MARK_YS,
                     ATTR_ROW(7),ATTR_ROW(8),ATTR_ROW(9),ATTR_ROW(10),0,
                   PANEL_NOTIFY_PROC, do_change_linestyle,
                   0);

  /* font menu */
  menu_font=panel_create_item(attr_panel, PANEL_CHOICE,
                   PANEL_LABEL_STRING, "Font :",
                   PANEL_FEEDBACK, PANEL_MARKED,
                   PANEL_ITEM_X, ATTR_COL(16),
                   PANEL_ITEM_Y, ATTR_ROW(5),
                   PANEL_CHOICE_STRINGS, "Courier", "Roman", "Greek",
                                         "BoldItalic", "Bold",0,
                   PANEL_CHOICE_XS,
                     ATTR_COL(20),ATTR_COL(20),ATTR_COL(20),
                     ATTR_COL(20),ATTR_COL(20),0,
                   PANEL_CHOICE_YS,
                     ATTR_ROW(7),ATTR_ROW(8),ATTR_ROW(9),
                     ATTR_ROW(10),ATTR_ROW(11),0,
                   PANEL_MARK_XS,
                     ATTR_COL(16),ATTR_COL(16),ATTR_COL(16),
                     ATTR_COL(16),ATTR_COL(16),0,
                   PANEL_MARK_YS,
                     ATTR_ROW(7),ATTR_ROW(8),ATTR_ROW(9),
                     ATTR_ROW(10),ATTR_ROW(11),0,
                   PANEL_NOTIFY_PROC, do_change_font,
                   0);

  /* grid on/off option */
  cycle_grid=panel_create_item(attr_panel, PANEL_CYCLE,
               PANEL_LABEL_STRING, "Grid ",
               PANEL_ITEM_X, ATTR_COL(30),
               PANEL_ITEM_Y, ATTR_ROW(5),
               PANEL_CHOICE_STRINGS, "Off", "On", 0,
               PANEL_NOTIFY_PROC, do_grid,
               0);

  /* align on/off option */
  cycle_align=panel_create_item(attr_panel, PANEL_CYCLE,
               PANEL_LABEL_STRING, "Align",
               PANEL_ITEM_X, ATTR_COL(30),
               PANEL_ITEM_Y, ATTR_ROW(6),
               PANEL_CHOICE_STRINGS, "Off", "On", 0,
               PANEL_NOTIFY_PROC, do_align,
               0);

  /* show options/options done button */
  cycle_save=panel_create_item(attr_panel, PANEL_CYCLE,
               PANEL_ITEM_X, ATTR_COL(30),
               PANEL_ITEM_Y, ATTR_ROW(8),
               PANEL_CHOICE_IMAGES,
                 panel_button_image(seg_panel, "Show Options", 12,0),
                 panel_button_image(seg_panel, "Options Done", 12,0),
                 0,
               PANEL_FEEDBACK, PANEL_NONE,
               PANEL_SHOW_MENU, 0,
               PANEL_NOTIFY_PROC, do_show_save,
               0);

  /* fill option */
  cycle_fill=panel_create_item(attr_panel, PANEL_CYCLE,
               PANEL_ITEM_X, ATTR_COL(30),
               PANEL_ITEM_Y, ATTR_ROW(9),
               PANEL_CHOICE_IMAGES, &border_pr, &fill_pr, &borderfill_pr, 0,
               0);

  window_fit(attr_panel);

  /* fit panels in frame */
  window_fit(frame);

  /* adjust the width of the panels to the maximum among them */
  {
    int i, width, maxwidth;

    /* determine the maximum width */
    width=0;
    maxwidth=0;
    for ( i=0; i<5; i++ ) {
      width = (int) window_get(panels[i], WIN_WIDTH);
      if ( width > maxwidth ) maxwidth = width;
    } /* for */

    /* set all of them to the maximum width */
    for ( i=0; i<5; i++ ) {
      (void) window_set(panels[i], WIN_WIDTH, maxwidth, 0);
    } /* for */
  }

} /* make control panel */

/*****************************************************************************

    do_message displays a message on the message panel.

  Input
    mesg - message to display

*****************************************************************************/

do_message(mesg)
char *mesg;
{
  panel_set(mesg_display,
    PANEL_LABEL_STRING, mesg,
    0);

} /* do_message */

/*****************************************************************************

    do_usage display the usage of the three mouse buttons on the message
  panel.

  Input
    mesg1 - message for left button
    mesg2 - message for middle button
    mesg3 - message for right button

*****************************************************************************/

do_usage(mesg1, mesg2, mesg3)
char *mesg1, *mesg2, *mesg3;
{
  static char usage[80];

  sprintf(usage, "L: %-11s M: %-11s R: %-11s", mesg1, mesg2, mesg3);
  panel_set(mesg_usage,
    PANEL_LABEL_STRING, usage,
    0);

} /* do_usage */

/*****************************************************************************

    do_show_save is the notify procedure for the show options/options done
  option.  It creates the options window if it does not exist and
  show/close the window according to the value.

  Input
    value - value of show options/options done option

*****************************************************************************/

static Frame save_frame=0;
void do_show_save(item, value, event)
Panel_item item;
int value;
Event *event;
{
  extern Frame base_frame;

  if ( ! save_frame ) {
    /* create the options window */
    save_frame = (Frame)make_save_panel(base_frame);
  }
  else {
    /* show/close options window according to value */
    window_set(save_frame,
      WIN_SHOW, value,
      0);
  } /* else */

} /* do_show_save */

/*****************************************************************************

    do_reset_save is the quit notify procedure for the options window.  It is
  called when the Done option is chosen from the frame menu of the window.
  It will reset the value of the show options/options done option and
  actually close the window.

*****************************************************************************/

void do_reset_save()
{
  panel_set(cycle_save,
    PANEL_VALUE, 0,
    0);

  /* close the window */
  window_set(save_frame,
    WIN_SHOW, 0,
    0);

} /* do_reset_save */
@//E*O*F panel.c//
chmod u=r,g=r,o=r panel.c
 
echo x - savepanel.c
sed 's/^@//' > "savepanel.c" <<'@//E*O*F savepanel.c//'

static char SccsId[] = "@(#)savepanel.c	1.1 6/8/87 Copyright 1987 SBCS-chan";

/*****************************************************************************

          (c) Copyright 1987 

          Lap-Tak Chan
          Computer Science Department
          State University of New York at Stony Brook
          Stony Brook, NY 11794

    This software and its documentation may be used, copied, and
  distributed, provided that this legend appear in all copies and
  that it is not copied or distributed for a profit.

  No representations is made about the suitability of this software
  for any purpose.  It is provided "as is" with no support and no
  express or implied warranty.

*****************************************************************************/

/*****************************************************************************

                         Options Window
                         ==============

    This file contains routines for the options window.

*****************************************************************************/

#include <suntool/sunview.h>
#include <suntool/panel.h>
#include "display.h"

/* define how the diagram is placed on 8.5 x 11 paper */
extern struct saveattr save_attr;

static Panel_item cycle_fix, cycle_rotate, cycle_center, 
       slider_width, slider_height, slider_offa, slider_offb;

/* externally accessible panel items */
Panel_item cycle_scale, cycle_blink, cycle_optm, cycle_output, cycle_newseg,
           cycle_cont, cycle_raster;

extern void do_change_save(), do_reset_save(), do_set_timer();

/* raster images */
static short norotate_pr_image[]={
#include "images/norotate.pr"
};

static short rotate_pr_image[]={
#include "images/rotate.pr"
};

mpr_static(norotate_pr, 64, 64, 1, norotate_pr_image);
mpr_static(rotate_pr, 64, 64, 1, rotate_pr_image);

/*****************************************************************************

    make_save_panel will create a new frame for the option window and create
  a save panel and an option panel.

  Input
    frame - parent frame

  Output
    Return frame created.

*****************************************************************************/

Frame
make_save_panel(frame)
Frame frame;
{

  Frame newframe;
  Panel panels[2];
#define save_panel	panels[0]
#define option_panel	panels[1]

  /* create a new frame under parent frame */
  newframe=window_create(frame, FRAME,
                         WIN_SHOW,TRUE,
                         FRAME_DONE_PROC, do_reset_save,
                         0);

  /* create save panel */
  save_panel=window_create(newframe, PANEL,
               0);

  /* slider for w */
  slider_width=panel_create_item(save_panel, PANEL_SLIDER,
             PANEL_LABEL_STRING, "w",
             PANEL_VALUE, save_attr.width,
             PANEL_MIN_VALUE, 10,
             PANEL_MAX_VALUE, 75,
             PANEL_SLIDER_WIDTH, ATTR_COLS(15),
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(0),
             PANEL_NOTIFY_PROC, do_change_save,
             0);

  /* slider for h */
  slider_height=panel_create_item(save_panel, PANEL_SLIDER,
             PANEL_LABEL_STRING, "h",
             PANEL_VALUE, save_attr.height,
             PANEL_MIN_VALUE, 10,
             PANEL_MAX_VALUE, 100,
             PANEL_SLIDER_WIDTH, ATTR_COLS(15),
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(1),
             PANEL_NOTIFY_PROC, do_change_save,
             0);

  /* slider for a */
  slider_offa=panel_create_item(save_panel, PANEL_SLIDER,
             PANEL_LABEL_STRING, "a",
             PANEL_VALUE, save_attr.offa,
             PANEL_MIN_VALUE, 5,
             PANEL_MAX_VALUE, 85-save_attr.width,
             PANEL_SLIDER_WIDTH, ATTR_COLS(15),
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(2),
             PANEL_NOTIFY_PROC, do_change_save,
             PANEL_SHOW_ITEM, ! save_attr.center,
             0);

  /* slider for b */
  slider_offb=panel_create_item(save_panel, PANEL_SLIDER,
             PANEL_LABEL_STRING, "b",
             PANEL_VALUE, save_attr.offb,
             PANEL_MIN_VALUE, 5,
             PANEL_MAX_VALUE, 110-save_attr.height,
             PANEL_SLIDER_WIDTH, ATTR_COLS(15),
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(3),
             PANEL_NOTIFY_PROC, do_change_save,
             PANEL_SHOW_ITEM, ! save_attr.center,
             0);

  /* just a message on the panel */
  (void)panel_create_item(save_panel, PANEL_MESSAGE,
             PANEL_LABEL_STRING, "Lengths in 1/10\"",
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(4),
             0);

  /* scale/fix width/fix height option */
  cycle_fix=panel_create_item(save_panel, PANEL_CYCLE,
             PANEL_VALUE, save_attr.fix,
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(6),
             PANEL_CHOICE_STRINGS, "Scale", "Fix Width", "Fix Height", 0,
             PANEL_NOTIFY_PROC, do_change_save,
             0);

  /* center/offset option */
  cycle_center=panel_create_item(save_panel, PANEL_CYCLE,
             PANEL_VALUE, save_attr.center,
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(7),
             PANEL_CHOICE_STRINGS, "Offset a,b", "Center", 0,
             PANEL_NOTIFY_PROC, do_change_save,
             0);

  /* rotate option */
  cycle_rotate=panel_create_item(save_panel, PANEL_CYCLE,
             PANEL_VALUE, save_attr.rotate,
             PANEL_ITEM_X, ATTR_COL(16),
             PANEL_ITEM_Y, ATTR_ROW(4),
             PANEL_CHOICE_IMAGES, &norotate_pr, &rotate_pr, 0,
             PANEL_NOTIFY_PROC, do_change_save,
             0);

  window_fit(save_panel);

  /* create option panel */
  option_panel=window_create(newframe, PANEL,
               WIN_BELOW, save_panel,
               WIN_X, ATTR_COLS(0),
               0);

  /* auto create option */
  cycle_newseg=panel_create_item(option_panel, PANEL_CYCLE,
               PANEL_LABEL_STRING, "Auto Create           ",
               PANEL_ITEM_X, ATTR_COL(0),
               PANEL_ITEM_Y, ATTR_ROW(0),
               PANEL_CHOICE_STRINGS, "Off", "On", 0,
               0);

  /* continous option */
  cycle_cont=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Continous             ",
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(1),
             PANEL_CHOICE_STRINGS, "No", "Yes", 0,
             0);

  /* proportional scale option */
  cycle_scale=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Proportional Scale    ",
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(2),
             PANEL_CHOICE_STRINGS, "No", "Yes", 0,
             0);

  /* blink current segment option */
  cycle_blink=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Blink Current Segment ",
             PANEL_VALUE, 1,
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(3),
             PANEL_CHOICE_STRINGS, "No", "Yes", 0,
             PANEL_NOTIFY_PROC, do_set_timer,
             0);

  /* optimize option */
  cycle_optm=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Optimize before Save  ",
             PANEL_VALUE,1,
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(4),
             PANEL_CHOICE_STRINGS, "No", "Yes", 0,
             0);

  /* output format option */
  cycle_output=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Output Format         ",
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(5),
             PANEL_CHOICE_STRINGS, "Raster", "Pic", "Plot", 0,
             0);

  /* select raster area option */
  cycle_raster=panel_create_item(option_panel, PANEL_CYCLE,
             PANEL_LABEL_STRING, "Select Area for Raster",
             PANEL_ITEM_X, ATTR_COL(0),
             PANEL_ITEM_Y, ATTR_ROW(6),
             PANEL_CHOICE_STRINGS, "No", "Yes", 0,
             0);

  window_fit(option_panel);
  window_fit(newframe);

  /* adjust both panels to the width of the wider panel */
  {
    int i, width, maxwidth;

    /* determine the maximum width */
    width=0;
    maxwidth=0;
    for ( i=0; i<2; i++ ) {
      width = (int) window_get(panels[i], WIN_WIDTH);
      if ( width > maxwidth ) maxwidth = width;
    } /* for */

    /* set both panels to the maximum */
    for ( i=0; i<2; i++ ) {
      (void) window_set(panels[i], WIN_WIDTH, maxwidth, 0);
    } /* for */
  }

  return(newframe);

} /* make_save_panel */

/*****************************************************************************

    do_change_save is the notify procedure of all the options on the save
  panel.  It updates the corresponding value in save_attr and change
  the setting of other options accordingly.

  Input
    item - panel item changed
    value - new value of panel item

*****************************************************************************/

void
do_change_save(item, value, event)
Panel_item item;
int value;
Event *event;
{
  if ( item == cycle_fix ) {
    /* scale/fix width/fix height option */
    save_attr.fix = value;

    /* disable slider for h when fix width */
    panel_set(slider_width,
      PANEL_SHOW_ITEM, ( (value == 0) || (value == 1) ),
      0);

    /* disable slider for w when fix height */
    panel_set(slider_height,
      PANEL_SHOW_ITEM, ( (value == 0) || (value == 2) ),
      0);
  }

  if ( item == cycle_rotate )
    /* rotate option */
    save_attr.rotate = value;

  if ( item == cycle_center ) {
    /* center/offset option */
    save_attr.center = value;

    /* disable slider for a and b when center */
    panel_set(slider_offa,
      PANEL_SHOW_ITEM, ! value,
      0);
    panel_set(slider_offb,
      PANEL_SHOW_ITEM, ! value,
      0);
  }

  if ( item == slider_width ) {
    int maxoffa;

    save_attr.width = value;
    /* adjust maximum offset a */
    maxoffa=85-value;
    panel_set(slider_offa,
              PANEL_MAX_VALUE, maxoffa,
              0);

    /* reduce offset a if it is larger than maximum */
    if ( save_attr.offa > maxoffa ) {
      panel_set(slider_offa,
                PANEL_VALUE, maxoffa,
                0);
      save_attr.offa = maxoffa;
    }
  }

  if ( item == slider_height ) {
    int maxoffb;

    save_attr.height = value;

    /* adjust maximum offset b */
    maxoffb=110-value;
    panel_set(slider_offb,
              PANEL_MAX_VALUE, maxoffb,
              0);

    /* reduce offset b when larger than maximum */
    if ( save_attr.offb > maxoffb ) {
      panel_set(slider_offb,
                PANEL_VALUE, maxoffb,
                0);
      save_attr.offb = maxoffb;
    }
  }

  if ( item == slider_offa )
    save_attr.offa = value;

  if ( item == slider_offb )
    save_attr.offb = value;

} /* do_change_save */
@//E*O*F savepanel.c//
chmod u=r,g=r,o=r savepanel.c
 
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
      80     463    3462 README
      89     353    2663 Makefile
     126     695    4492 display.h
     745    1672   24557 panel.c
     364     955   10974 savepanel.c
    1404    4138   46148 total
!!!
wc  README Makefile display.h panel.c savepanel.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0