[comp.windows.x] Tgif-1.10

william@oahu.cs.ucla.edu (William Cheng) (07/20/90)

I've just put tgif-1.10 in the following places for anonymous ftp:

	expo.lcs.mit.edu	contrib/tgif-1.10.tar.Z
	rye.cs.ucla.edu		pub/tgif-1.10.tar.Z

Here's a short list of added features/bug fixes.

1) Fix bugs reported by Michael Webb regarding reading very long polygline.
2) Disallow stretching of zero width or zero height objects.
3) Add feature:  Add points and delete points to poly and splines.
4) In case of emergency, save working file in EmergencySave.obj or
   EmergencySave.sym.  (Thanks to Stephen Doyle and Christos Zoulas.)
5) Add XDefault "Tgif*Synchronize" call XSynchronize ().
6) Add -p command line option to prtgif to print encapsulated PostScript
   file.  (Thanks to Stephen Doyle.)

The following patch file takes tgif from version 1.9 to 1.10.
---------------------------------> cut here <---------------------------------
*** attr.c.orig	Thu Jul 19 11:03:00 1990
--- attr.c	Thu Jul 19 11:03:01 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.4 90/06/26 00:03:55 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.5 90/07/18 14:46:27 william Exp $";
  #endif
  
***************
*** 484,488 ****
  static
  char * ReadAttrString (Str)
!    char *	Str;
  {
     register char	* s = Str;
--- 484,488 ----
  static
  char * ReadAttrString (Str)
!    char	* Str;
  {
     register char	* s = Str;
***************
*** 496,500 ****
  }
  
! int  ReadAttr (FP, AttrPtr)
     FILE			* FP;
     struct AttrRec	* * AttrPtr;
--- 496,500 ----
  }
  
! int ReadAttr (FP, AttrPtr)
     FILE			* FP;
     struct AttrRec	* * AttrPtr;
***************
*** 505,509 ****
     int			len, shown, nameshown, inherited;
   
!    fgets (inbuf, 255, FP); 
  
     if (inbuf[0] == ']')  return (FALSE);
--- 505,509 ----
     int			len, shown, nameshown, inherited;
   
!    fgets (inbuf, MAXSTRING, FP); 
  
     if (inbuf[0] == ']')  return (FALSE);
***************
*** 1015,1019 ****
     int			* fore_colors, * pixel_ptr, * valid, * flag_ptr;
     int			len1, len2;
!    char			* * attrStrs, * s, buf[256], msg[80];
     unsigned int		button;
  
--- 1015,1019 ----
     int			* fore_colors, * pixel_ptr, * valid, * flag_ptr;
     int			len1, len2;
!    char			* * attrStrs, * s, buf[MAXSTRING], msg[80];
     unsigned int		button;
  
*** box.c.orig	Thu Jul 19 11:03:08 1990
--- box.c	Thu Jul 19 11:03:09 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/box.c,v 1.4 90/06/26 00:04:27 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/box.c,v 1.5 90/07/16 10:29:15 william Exp $";
  #endif
  
***************
*** 19,24 ****
  #include "grid.e"
  #include "obj.e"
- #include "poly.e"
  #include "pattern.e"
  #include "raster.e"
  #include "ruler.e"
--- 19,24 ----
  #include "grid.e"
  #include "obj.e"
  #include "pattern.e"
+ #include "poly.e"
  #include "raster.e"
  #include "ruler.e"
*** color.c.orig	Thu Jul 19 11:03:14 1990
--- color.c	Thu Jul 19 11:03:17 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/color.c,v 1.9 90/06/26 00:04:37 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/color.c,v 1.10 90/07/15 17:47:00 william Exp $";
  #endif
  
***************
*** 368,370 ****
--- 368,384 ----
     if (index != INVALID) ChangeAllSelColor (index);
     cfree (pixmap);
+ }
+ 
+ void CleanUpColors ()
+ {
+    register int	i;
+ 
+    cfree (colorPixels);
+    cfree (xorColorPixels);
+    for (i = 0; i < maxColors; i++) cfree (colorMenuItems[i]);
+    cfree (colorMenuItems);
+ 
+    maxColors = MAXCOLORS;
+    defaultColorIndex = 4;
+    colorIndex = 0;
  }
*** cursor.c.orig	Thu Jul 19 11:03:22 1990
--- cursor.c	Thu Jul 19 11:03:23 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/cursor.c,v 1.2 90/05/22 14:08:44 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/cursor.c,v 1.5 90/07/16 10:31:01 william Exp $";
  #endif
  
***************
*** 11,16 ****
  #include <X11/Xlib.h>
  #include <X11/cursorfont.h>
- #include "types.h"
  #include "const.h"
  
  #include "choice.e"
--- 11,16 ----
  #include <X11/Xlib.h>
  #include <X11/cursorfont.h>
  #include "const.h"
+ #include "types.h"
  
  #include "choice.e"
*** dialog.c.orig	Thu Jul 19 11:03:26 1990
--- dialog.c	Thu Jul 19 11:03:27 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dialog.c,v 1.4 90/05/25 13:36:58 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dialog.c,v 1.5 90/07/12 09:01:47 william Exp $";
  #endif
  
***************
*** 117,121 ****
           key_code = key_ev->keycode;
           XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
!          if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
                 (buf[0]=='\n' && (key_sym & 0xff)=='\n') ||
                 (buf[0]=='\b' && (key_sym & 0xff)=='\b') ||
--- 117,122 ----
           key_code = key_ev->keycode;
           XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
!          if ((buf[0]=='\033' && (key_sym & 0xff)=='\033') ||
!                (buf[0]=='\r' && (key_sym & 0xff)=='\r') ||
                 (buf[0]=='\n' && (key_sym & 0xff)=='\n') ||
                 (buf[0]=='\b' && (key_sym & 0xff)=='\b') ||
***************
*** 127,130 ****
--- 128,135 ----
              switch (buf[0])
              {
+                case '\033':
+                   ReturnStr[0] = '\0';
+                   dialoging = FALSE;
+                   break;
                 case '\r':
                 case '\n':
*** drawing.c.orig	Thu Jul 19 11:03:33 1990
--- drawing.c	Thu Jul 19 11:03:34 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.3 90/05/22 14:10:35 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.7 90/07/16 10:41:06 william Exp $";
  #endif
  
***************
*** 30,35 ****
  #include "menu.e"
  #include "msg.e"
- #include "oval.e"
  #include "obj.e"
  #include "pattern.e"
  #include "poly.e"
--- 30,35 ----
  #include "menu.e"
  #include "msg.e"
  #include "obj.e"
+ #include "oval.e"
  #include "pattern.e"
  #include "poly.e"
***************
*** 530,537 ****
           switch (buf[0])
           {
!             case '\001': /*^#A*/ break;
              case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break;
              case '\003': /*^#C*/ ChangeFontJust (JUST_C); break;
!             case '\004': /*^#D*/ break;
              case '\005': /*^#E*/ break;
              case '\006': /*^#F*/ break;
--- 530,537 ----
           switch (buf[0])
           {
!             case '\001': /*^#A*/ AddPoint (); break;
              case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break;
              case '\003': /*^#C*/ ChangeFontJust (JUST_C); break;
!             case '\004': /*^#D*/ DeletePoint (); break;
              case '\005': /*^#E*/ break;
              case '\006': /*^#F*/ break;
***************
*** 552,556 ****
              case '\025': /*^#U*/ break;
              case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break;
!             case '\027': /*^#W*/ break;
              case '\030': /*^#X*/ break;
              case '\031': /*^#Y*/ break;
--- 552,556 ----
              case '\025': /*^#U*/ break;
              case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break;
!             case '\027': /*^#W*/ ToggleAllSelLineType (); break;
              case '\030': /*^#X*/ break;
              case '\031': /*^#Y*/ break;
*** dup.c.orig	Thu Jul 19 11:03:41 1990
--- dup.c	Thu Jul 19 11:03:42 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.2 90/06/26 00:04:49 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.3 90/07/08 00:29:43 william Exp $";
  #endif
  
***************
*** 306,308 ****
--- 306,342 ----
     HighLightForward ();
     SetFileModified (TRUE);
+ }
+ 
+ void JustDupSelObj (NewTopSel, NewBotSel)
+    struct SelRec	* * NewTopSel, * * NewBotSel;
+ {
+    struct SelRec	* sel_ptr, * new_sel_ptr;
+    struct ObjRec	* obj_ptr, * top_obj, * bot_obj;
+ 
+    *NewTopSel = *NewBotSel = NULL;
+    if (topSel == NULL) return;
+ 
+    top_obj = bot_obj = NULL;
+    for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
+    {
+       obj_ptr = DupObj (sel_ptr->obj);
+       obj_ptr->next = top_obj;
+       new_sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec));
+       new_sel_ptr->next = *NewTopSel;
+       new_sel_ptr->obj = obj_ptr;
+       if (top_obj == NULL)
+       {
+          bot_obj = obj_ptr;
+          *NewBotSel = new_sel_ptr;
+       }
+       else
+       {
+          top_obj->prev = obj_ptr;
+          (*NewTopSel)->prev = new_sel_ptr;
+       }
+       top_obj = obj_ptr;
+       *NewTopSel = new_sel_ptr;
+    }
+    top_obj->prev = NULL;
+    (*NewTopSel)->prev = NULL;
  }
*** edit.c.orig	Thu Jul 19 11:03:48 1990
--- edit.c	Thu Jul 19 11:03:49 1990
***************
*** 6,13 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.2 90/06/26 00:04:59 william Exp $";
  #endif
  
  #include <stdio.h>
  #include <X11/Xlib.h>
  #include "const.h"
--- 6,14 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.6 90/07/13 12:51:58 william Exp $";
  #endif
  
  #include <stdio.h>
+ #include <math.h>
  #include <X11/Xlib.h>
  #include "const.h"
***************
*** 16,29 ****
--- 17,41 ----
  #include "align.e"
  #include "color.e"
+ #include "cursor.e"
  #include "drawing.e"
  #include "dup.e"
+ #include "font.e"
  #include "group.e"
  #include "mark.e"
  #include "obj.e"
+ #include "poly.e"
  #include "raster.e"
  #include "select.e"
  #include "setup.e"
+ #include "spline.e"
  #include "stretch.e"
  
+ #define OFFSET_X(x) (((x) - drawOrigX) >> zoomScale)
+ #define OFFSET_Y(y) (((y) - drawOrigY) >> zoomScale)
+ #define MARK(X,Y) \
+       XFillRectangle(mainDisplay,drawWindow,revDefaultGC,(X)-2,(Y)-2,5,5)
+ #define MyDashedLine(W,GC,V,N) XDrawLines (mainDisplay, W, GC, V, N, \
+       CoordModeOrigin)
+ 
  #define EDIT_REDRAW 0
  #define EDIT_DUP 1
***************
*** 31,44 ****
  #define EDIT_SELALL 3
  #define EDIT_UNDODEL 4
! #define MAXEDITMENUS 5
  
  static char * editMenuStr[] =
!       { "Redraw     ^R",
!         "Duplicate  ^D",
!         "Delete     ^X",
!         "SelectAll  ^A",
!         "UndoDelete #U"
        };
  
  void EditMenu (X, Y)
     int	X, Y;
--- 43,664 ----
  #define EDIT_SELALL 3
  #define EDIT_UNDODEL 4
! #define EDIT_DEL_POINT 5
! #define EDIT_ADD_POINT 6
  
+ #define MAXEDITMENUS 7
+ 
  static char * editMenuStr[] =
!       { "Redraw       ^R",
!         "Duplicate    ^D",
!         "Delete       ^X",
!         "SelectAll    ^A",
!         "UndoDelete   #U",
!         "DeletePoint ^#D",
!         "AddPoint    ^#A"
        };
  
+ void DeletePoint ()
+ {
+    register int			i;
+    register struct ObjRec	* obj_ptr;
+    struct PolyRec		* poly_ptr;
+    struct PolygonRec		* polygon_ptr;
+    int				index, n, point_deleted, deleting = TRUE;
+    int				root_x, root_y, old_x, old_y;
+    unsigned int			status;
+    Window			root_win, child_win;
+    XEvent			input;
+ 
+    if (!(topSel != NULL && topSel == botSel &&
+          (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
+    {
+       Msg ("Please select only one POLY or POLYGON object.");
+       return;
+    }
+ 
+    obj_ptr = topSel->obj;
+    switch (obj_ptr->type)
+    {
+       case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
+       case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
+    }
+    TwoLineMsg ("Click left mouse button to DELETE points.",
+          "Click other buttons to quit.");
+ 
+    XGrabPointer (mainDisplay, drawWindow, False,
+          PointerMotionMask | ButtonPressMask,
+          GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
+    XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
+          &root_x, &root_y, &old_x, &old_y, &status);
+    XDrawString (mainDisplay, drawWindow, revDefaultGC,
+          old_x+4, old_y+defaultFontAsc, "DEL", 3);
+    MarkRulers (old_x, old_y);
+ 
+    while (deleting)
+    {
+       XNextEvent (mainDisplay, &input);
+       if (input.type == ButtonPress)
+       {
+          if (input.xbutton.button == Button1)
+          {
+             point_deleted = FALSE;
+             if (obj_ptr->type == OBJ_POLY &&
+                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
+                   poly_ptr->n, poly_ptr->vlist, &index) ||
+                   obj_ptr->type == OBJ_POLYGON &&
+                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
+                   polygon_ptr->n-1, polygon_ptr->vlist, &index))
+             {
+                point_deleted = TRUE;
+                HighLightReverse ();
+                if (obj_ptr->type == OBJ_POLY && poly_ptr->n == 2 ||
+                      obj_ptr->type == OBJ_POLYGON && polygon_ptr->n == 4)
+                {
+                   CopySelToCut ();
+                   DelObj (obj_ptr);
+                   deleting = FALSE;
+                   obj_ptr = NULL;
+                   cfree (topSel);
+                   topSel = botSel = NULL;
+                }
+                else
+                {
+                   switch (obj_ptr->type)
+                   {
+                      case OBJ_POLY:
+                         n = poly_ptr->n;
+                         for (i = index+1; i < n; i++)
+                            poly_ptr->vlist[i-1] = poly_ptr->vlist[i];
+                         poly_ptr->n--;
+                         if (poly_ptr->curved)
+                         {
+                            cfree (poly_ptr->svlist);
+                            poly_ptr->svlist = MakeSplinePolyVertex (
+                                  &(poly_ptr->sn), drawOrigX, drawOrigY,
+                                  poly_ptr->n, poly_ptr->vlist);
+                         }
+                         UpdPolyBBox (obj_ptr, poly_ptr->n, poly_ptr->vlist);
+                         break;
+                      case OBJ_POLYGON:
+                         n = polygon_ptr->n;
+                         for (i = index+1; i < n; i++)
+                            polygon_ptr->vlist[i-1] = polygon_ptr->vlist[i];
+                         polygon_ptr->n--;
+                         n--;
+                         if (index == 0)
+                            polygon_ptr->vlist[n-1] = polygon_ptr->vlist[0];
+                         if (polygon_ptr->curved)
+                         {
+                            cfree (polygon_ptr->svlist);
+                            polygon_ptr->svlist = MakeSplinePolygonVertex (
+                                  &(polygon_ptr->sn), drawOrigX, drawOrigY,
+                                  polygon_ptr->n, polygon_ptr->vlist);
+                         }
+                         UpdPolyBBox (obj_ptr, polygon_ptr->n,
+                               polygon_ptr->vlist);
+                         break;
+                   }
+                   AdjObjBBox (obj_ptr);
+                }
+             }
+             if (point_deleted)
+             {
+                XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
+                      old_y+defaultFontAsc, "DEL", 3);
+                old_x = input.xbutton.x;
+                old_y = input.xbutton.y;
+                RedrawAnArea (botObj,
+                      selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
+                      selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
+                HighLightForward ();
+                if (obj_ptr != NULL)
+                   XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
+                         old_y+defaultFontAsc, "DEL", 3);
+                UpdSelBBox ();
+                SetFileModified (TRUE);
+             }
+          }
+          else
+          {
+             deleting = FALSE;
+             XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                   old_x+4, old_y+defaultFontAsc, "DEL", 3);
+          }
+       }
+       else if (input.type == MotionNotify)
+       {
+          XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                old_x+4, old_y+defaultFontAsc, "DEL", 3);
+          old_x = input.xmotion.x;
+          old_y = input.xmotion.y;
+          XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                old_x+4, old_y+defaultFontAsc, "DEL", 3);
+          MarkRulers (old_x, old_y);
+       }
+    }
+    XUngrabPointer (mainDisplay, CurrentTime);
+    Msg ("");
+ }
+ 
+ static
+ void ContinueAddPolyPoint (ObjPtr, MouseX, MouseY, Index, PolyPtr,
+       LastMouseX, LastMouseY)
+    struct ObjRec	* ObjPtr;
+    int			MouseX, MouseY, Index;
+    struct PolyRec	* PolyPtr;
+    int			* LastMouseX, * LastMouseY;
+    /* (MouseX,MouseY) is the mouse's origin in screen offsets */
+ {
+    int		n = PolyPtr->n, already_moved=FALSE, done=FALSE, before;
+    XPoint	* vs = PolyPtr->vlist, v[3];
+    int		prev_x, prev_y, x, y, next_x, next_y, new_x, new_y, dx, dy;
+    int		orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
+ /* int		prev_dist, next_dist, new_prev_dist, new_next_dist; */
+    int		sel_ltx, sel_lty, sel_rbx, sel_rby, num, i;
+    double	prev_angle, next_angle, new_angle, theta_1, theta_2;
+    XEvent	input;
+ 
+    MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
+ 
+    sel_ltx =  selLtX; sel_lty = selLtY;
+    sel_rbx =  selRbX; sel_rby = selRbY;
+ 
+    x = vs[Index].x;
+    y = vs[Index].y;
+ 
+    if (Index == 0)
+    {
+       next_x = vs[1].x;    next_y = vs[1].y;
+       prev_x = 2*x-next_x; prev_y = 2*y-next_y;
+ /*    prev_dist = next_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
+    }
+    else if (Index == n-1)
+    {
+       prev_x = vs[n-2].x;  prev_y = vs[n-2].y;
+       next_x = 2*x-prev_x; next_y = 2*y-prev_y;
+ /*    prev_dist = next_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
+    }
+    else
+    {
+       prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
+       next_x = vs[Index+1].x; next_y = vs[Index+1].y;
+ /*    prev_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
+ /*    next_dist = (x-next_x)*(x-next_x) + (y-next_y)*(y-next_y); */
+    }
+    prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
+    next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
+ 
+    GridXY (MouseX, MouseY, &orig_x, &orig_y);
+    new_mouse_x = MouseX; new_mouse_y = MouseY;
+    XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+          new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+    while (!done)
+    {
+       XNextEvent (mainDisplay, &input);
+       if (input.type == MotionNotify)
+       {
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+          new_mouse_x = input.xmotion.x;
+          new_mouse_y = input.xmotion.y;
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+          GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
+          new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
+          new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
+          if (!already_moved)
+          {
+             already_moved = TRUE;
+ 
+             new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
+             theta_1 = fabs (prev_angle - new_angle);
+             theta_2 = fabs (next_angle - new_angle);
+             if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
+             if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
+             before = (theta_1 <= theta_2);
+ 
+ /*          new_prev_dist = (new_x-prev_x)*(new_x-prev_x) + */
+ /*                (new_y-prev_y)*(new_y-prev_y); */
+ /*          new_next_dist = (new_x-next_x)*(new_x-next_x) + */
+ /*                (new_y-next_y)*(new_y-next_y); */
+ 
+ /*          if ((new_prev_dist-prev_dist)*(new_next_dist-next_dist) < 0) */
+ /*             before = (new_prev_dist < prev_dist); */
+ /*          else */
+ /*             before = (abs (new_prev_dist-prev_dist) < */
+ /*                   abs (new_next_dist-next_dist)); */
+ 
+             if (before)
+             {  /* Add a point between the current and the previous point */
+                if (Index == 0)
+                {
+                   num = 2;
+                   v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
+                   v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
+                }
+                else
+                {
+                   num = 3;
+                   v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
+                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
+                   v[2].x = OFFSET_X(x);      v[2].y = OFFSET_Y(y);
+                }
+             }
+             else
+             {  /* Add a point between the current and the next point */
+                if (Index == n-1)
+                {
+                   num = 2;
+                   v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
+                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
+                }
+                else
+                {
+                   num = 3;
+                   v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
+                   v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
+                   v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
+                }
+             }
+             MyDashedLine (drawWindow, revDefaultGC, v, num);
+          }
+          else
+          {
+             MyDashedLine (drawWindow, revDefaultGC, v, num);
+             v[1].x = OFFSET_X(x) + grid_x - orig_x;
+             v[1].y = OFFSET_Y(y) + grid_y - orig_y;
+             MyDashedLine (drawWindow, revDefaultGC, v, num);
+             MarkRulers (grid_x, grid_y);
+          }
+       }
+       else if (input.type == ButtonRelease)
+       {
+          done = TRUE;
+          *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
+          MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+          if (!already_moved)
+             continue;
+          else
+          {
+             MyDashedLine (drawWindow, revDefaultGC, v, num);
+             if (grid_x == orig_x && grid_y == orig_y)
+                continue;
+          }
+ 
+          HighLightReverse ();
+          vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
+          if (vs == NULL)
+          {
+             printf ("Can not realloc () in ContinueAddPolyPoint ().\n");
+             exit (-1);
+          }
+          PolyPtr->vlist = vs;
+          if (before)
+          {
+             for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
+             vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
+             vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
+          }
+          else
+          {
+             for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
+             vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
+             vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
+          }
+          PolyPtr->n++;
+          n++;
+          if (PolyPtr->curved)
+          {
+             cfree (PolyPtr->svlist);
+             PolyPtr->svlist = MakeSplinePolyVertex (&(PolyPtr->sn),
+                   drawOrigX, drawOrigY, PolyPtr->n, PolyPtr->vlist);
+          }
+          UpdPolyBBox (ObjPtr, PolyPtr->n, PolyPtr->vlist);
+          AdjObjBBox (ObjPtr);
+ 
+          UpdSelBBox ();
+          RedrawAreas (botObj,
+                sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
+                sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
+                selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
+                selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
+          HighLightForward ();
+          SetFileModified (TRUE);
+       }
+    }
+ }
+ 
+ static
+ void ContinueAddPolygonPoint (ObjPtr, MouseX, MouseY, Index, PolygonPtr,
+       LastMouseX, LastMouseY)
+    struct ObjRec	* ObjPtr;
+    int			MouseX, MouseY, Index;
+    struct PolygonRec	* PolygonPtr;
+    int			* LastMouseX, * LastMouseY;
+    /* (MouseX,MouseY) is the mouse's origin in screen offsets */
+ {
+    int		n = PolygonPtr->n, already_moved=FALSE, done=FALSE, before;
+    XPoint	* vs = PolygonPtr->vlist, v[3];
+    int		prev_x, prev_y, x, y, next_x, next_y, new_x, new_y, dx, dy;
+    int		orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
+ /* int		prev_dist, next_dist, new_prev_dist, new_next_dist; */
+    int		sel_ltx, sel_lty, sel_rbx, sel_rby, i;
+    double	prev_angle, next_angle, new_angle, theta_1, theta_2;
+    XEvent	input;
+ 
+    MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
+ 
+    sel_ltx =  selLtX; sel_lty = selLtY;
+    sel_rbx =  selRbX; sel_rby = selRbY;
+ 
+    x = vs[Index].x;
+    y = vs[Index].y;
+ 
+    if (Index == 0 || Index == n-1)
+    {
+       next_x = vs[1].x;   next_y = vs[1].y;
+       prev_x = vs[n-2].x; prev_y = vs[n-2].y;
+    }
+    else
+    {
+       prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
+       next_x = vs[Index+1].x; next_y = vs[Index+1].y;
+    }
+    prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
+    next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
+ 
+ /* prev_dist = (x-prev_x)*(x-prev_x) + (y-prev_y)*(y-prev_y); */
+ /* next_dist = (x-next_x)*(x-next_x) + (y-next_y)*(y-next_y); */
+ 
+    GridXY (MouseX, MouseY, &orig_x, &orig_y);
+    new_mouse_x = MouseX; new_mouse_y = MouseY;
+    XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+          new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+    while (!done)
+    {
+       XNextEvent (mainDisplay, &input);
+       if (input.type == MotionNotify)
+       {
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+          new_mouse_x = input.xmotion.x;
+          new_mouse_y = input.xmotion.y;
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+          GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
+          new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
+          new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
+          if (!already_moved)
+          {
+             already_moved = TRUE;
+ 
+             new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
+             theta_1 = fabs (prev_angle - new_angle);
+             theta_2 = fabs (next_angle - new_angle);
+             if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
+             if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
+             before = (theta_1 <= theta_2);
+ 
+ /*          new_prev_dist = (new_x-prev_x)*(new_x-prev_x) + */
+ /*                (new_y-prev_y)*(new_y-prev_y); */
+ /*          new_next_dist = (new_x-next_x)*(new_x-next_x) + */
+ /*                (new_y-next_y)*(new_y-next_y); */
+ 
+ /*          if ((new_prev_dist-prev_dist)*(new_next_dist-next_dist) < 0) */
+ /*             before = (new_prev_dist < prev_dist); */
+ /*          else */
+ /*             before = (abs (new_prev_dist-prev_dist) < */
+ /*                   abs (new_next_dist-next_dist)); */
+ 
+             if (before)
+             {  /* Add a point between the current and the previous point */
+                v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
+                v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
+                v[2].x = OFFSET_X(x);      v[2].y = OFFSET_Y(y);
+             }
+             else
+             {  /* Add a point between the current and the next point */
+                v[0].x = OFFSET_X(x);      v[0].y = OFFSET_Y(y);
+                v[1].x = OFFSET_X(x);      v[1].y = OFFSET_Y(y);
+                v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
+             }
+             MyDashedLine (drawWindow, revDefaultGC, v, 3);
+          }
+          else
+          {
+             MyDashedLine (drawWindow, revDefaultGC, v, 3);
+             v[1].x = OFFSET_X(x) + grid_x - orig_x;
+             v[1].y = OFFSET_Y(y) + grid_y - orig_y;
+             MyDashedLine (drawWindow, revDefaultGC, v, 3);
+             MarkRulers (grid_x, grid_y);
+          }
+       }
+       else if (input.type == ButtonRelease)
+       {
+          done = TRUE;
+          *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
+          MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
+          XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
+                new_mouse_y+defaultFontAsc, "ADD", 3);
+ 
+          if (!already_moved)
+             continue;
+          else
+          {
+             MyDashedLine (drawWindow, revDefaultGC, v, 3);
+             if (grid_x == orig_x && grid_y == orig_y)
+                continue;
+          }
+ 
+          HighLightReverse ();
+          vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
+          if (vs == NULL)
+          {
+             printf ("Can not realloc () in ContinueAddPolygonPoint ().\n");
+             exit (-1);
+          }
+          PolygonPtr->vlist = vs;
+          if (Index == 0 || Index == n-1)
+          {
+             if (before)
+             {
+                vs[n].x = vs[n-1].x;
+                vs[n].y = vs[n-1].y;
+                vs[n-1].x = x + ((grid_x-orig_x)<<zoomScale);
+                vs[n-1].y = y + ((grid_y-orig_y)<<zoomScale);
+             }
+             else
+             {
+                for (i = n-1; i > 0; i--) vs[i+1] = vs[i];
+                vs[1].x = x + ((grid_x-orig_x)<<zoomScale);
+                vs[1].y = y + ((grid_y-orig_y)<<zoomScale);
+             }
+          }
+          else
+          {
+             if (before)
+             {
+                for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
+                vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
+                vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
+             }
+             else
+             {
+                for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
+                vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
+                vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
+             }
+          }
+          PolygonPtr->n++;
+          n++;
+          if (PolygonPtr->curved)
+          {
+             cfree (PolygonPtr->svlist);
+             PolygonPtr->svlist = MakeSplinePolygonVertex (&(PolygonPtr->sn),
+                   drawOrigX, drawOrigY, PolygonPtr->n, PolygonPtr->vlist);
+          }
+          UpdPolyBBox (ObjPtr, PolygonPtr->n, PolygonPtr->vlist);
+          AdjObjBBox (ObjPtr);
+ 
+          UpdSelBBox ();
+          RedrawAreas (botObj,
+                sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
+                sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
+                selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
+                selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
+          HighLightForward ();
+          SetFileModified (TRUE);
+       }
+    }
+ }
+ 
+ void AddPoint ()
+ {
+    register int			i;
+    register struct ObjRec	* obj_ptr;
+    struct PolyRec		* poly_ptr;
+    struct PolygonRec		* polygon_ptr;
+    int				index, n, point_deleted, adding = TRUE;
+    int				root_x, root_y, old_x, old_y;
+    unsigned int			status;
+    Window			root_win, child_win;
+    XEvent			input;
+ 
+    if (!(topSel != NULL && topSel == botSel &&
+          (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
+    {
+       Msg ("Please select only one POLY or POLYGON object.");
+       return;
+    }
+ 
+    obj_ptr = topSel->obj;
+    switch (obj_ptr->type)
+    {
+       case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
+       case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
+    }
+    TwoLineMsg ("Drag left mouse button to ADD points.",
+          "Click other buttons to quit.");
+ 
+    XGrabPointer (mainDisplay, drawWindow, False,
+          PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+          GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
+    XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
+          &root_x, &root_y, &old_x, &old_y, &status);
+    XDrawString (mainDisplay, drawWindow, revDefaultGC,
+          old_x+4, old_y+defaultFontAsc, "ADD", 3);
+    MarkRulers (old_x, old_y);
+ 
+    while (adding)
+    {
+       XNextEvent (mainDisplay, &input);
+       if (input.type == ButtonPress)
+       {
+          if (input.xbutton.button == Button1)
+          {
+             XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
+             if (obj_ptr->type == OBJ_POLY &&
+                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
+                   poly_ptr->n, poly_ptr->vlist, &index))
+                ContinueAddPolyPoint (obj_ptr, input.xbutton.x, input.xbutton.y,
+                      index, poly_ptr, &old_x, &old_y);
+             else if (obj_ptr->type == OBJ_POLYGON &&
+                   PtInPolyMark (input.xbutton.x, input.xbutton.y,
+                   polygon_ptr->n-1, polygon_ptr->vlist, &index))
+                ContinueAddPolygonPoint (obj_ptr, input.xbutton.x,
+                      input.xbutton.y, index, polygon_ptr, &old_x, &old_y);
+             XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
+          }
+          else
+          {
+             adding = FALSE;
+             XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                   old_x+4, old_y+defaultFontAsc, "ADD", 3);
+          }
+       }
+       else if (input.type == MotionNotify)
+       {
+          XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                old_x+4, old_y+defaultFontAsc, "ADD", 3);
+          old_x = input.xmotion.x;
+          old_y = input.xmotion.y;
+          XDrawString (mainDisplay, drawWindow, revDefaultGC,
+                old_x+4, old_y+defaultFontAsc, "ADD", 3);
+          MarkRulers (old_x, old_y);
+       }
+    }
+    XUngrabPointer (mainDisplay, CurrentTime);
+    Msg ("");
+ }
+ 
  void EditMenu (X, Y)
     int	X, Y;
***************
*** 57,60 ****
--- 677,682 ----
        case EDIT_SELALL: SelAllObj (); break;
        case EDIT_UNDODEL: UndoDelete (); break;
+       case EDIT_DEL_POINT: DeletePoint (); break;
+       case EDIT_ADD_POINT: AddPoint (); break;
     }
  }
*** file.c.orig	Thu Jul 19 11:04:01 1990
--- file.c	Thu Jul 19 11:04:03 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/file.c,v 1.15 90/06/26 13:03:47 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/file.c,v 1.25 90/07/18 16:46:33 william Exp $";
  #endif
  
***************
*** 12,15 ****
--- 12,16 ----
  #include <sys/file.h>
  #include <stdio.h>
+ #include <signal.h>
  #include <X11/Xlib.h>
  #include "const.h"
***************
*** 27,30 ****
--- 28,32 ----
  #include "grid.e"
  #include "group.e"
+ #include "mainloop.e"
  #include "menu.e"
  #include "msg.e"
***************
*** 134,138 ****
  
  static
! int SaveTmpFile ()
     /* return TRUE if file successfully saved */
  {
--- 136,141 ----
  
  static
! int SaveTmpFile (NewFileName)
!    char	* NewFileName;
     /* return TRUE if file successfully saved */
  {
***************
*** 142,146 ****
     struct ObjRec	* obj_ptr;
  
!    strcpy (new_file_name, "tmpmodel");
  
     for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
--- 145,149 ----
     struct ObjRec	* obj_ptr;
  
!    strcpy (new_file_name, NewFileName);
  
     for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
***************
*** 425,433 ****
     char			inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
     char			* line = NULL, * c_ptr, * s, * s1;
!    int			len, id, old_len, cur_size, done = FALSE;
!    int			allocated = FALSE;
!    struct ObjRec	* tmp_obj_ptr;
!    struct ObjRec	* tmp_top_obj = NULL, * tmp_bot_obj = NULL;
!    struct AttrRec       * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  
     while (fgets (inbuf, MAXSTRING, FP) != NULL)
--- 428,433 ----
     char			inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
     char			* line = NULL, * c_ptr, * s, * s1;
!    int			len, id, cur_size, done = FALSE, allocated = FALSE;
!    struct AttrRec	* top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  
     while (fgets (inbuf, MAXSTRING, FP) != NULL)
***************
*** 444,448 ****
           strcpy (line, inbuf);
           c_ptr = &(line[MAXSTRING-1]);
!          while (fgets (inbuf, MAXSTRING, FP) != NULL && !done)
           {
              len = strlen(inbuf);
--- 444,448 ----
           strcpy (line, inbuf);
           c_ptr = &(line[MAXSTRING-1]);
!          while (!done && fgets (inbuf, MAXSTRING, FP) != NULL)
           {
              len = strlen(inbuf);
***************
*** 935,941 ****
--- 935,948 ----
        case PRINTER:
           if ((c_ptr = XGetDefault (mainDisplay,"Tgif","PrintCommand")) != NULL)
+          {
              sprintf (cmd, "%s %s 2>&1", c_ptr, tmp_file);
+             sprintf (message, "Printing with '%s' command.", c_ptr);
+          }
           else
+          {
              sprintf (cmd, "lpr %s 2>&1", tmp_file);
+             sprintf (message, "Printing with 'lpr' command.");
+          }
+          Msg (message);
  
           if ((fp = popen (cmd, "r")) == NULL)
***************
*** 1082,1086 ****
  int SolveProc ()
  {
!    switch (SaveTmpFile ())
     {
        case OBJ_FILE_SAVED: return (FILE_SOLVE);
--- 1089,1093 ----
  int SolveProc ()
  {
!    switch (SaveTmpFile ("tmpmodel"))
     {
        case OBJ_FILE_SAVED: return (FILE_SOLVE);
***************
*** 1092,1096 ****
  int SimulateProc ()
  {
!    switch (SaveTmpFile ())
     {
        case OBJ_FILE_SAVED: return (FILE_SIMULATE);
--- 1099,1103 ----
  int SimulateProc ()
  {
!    switch (SaveTmpFile ("tmpmodel"))
     {
        case OBJ_FILE_SAVED: return (FILE_SIMULATE);
***************
*** 1102,1106 ****
  int ProbeProc ()
  {
!    switch (SaveTmpFile ())
     {
        case OBJ_FILE_SAVED: return (FILE_PROBE);
--- 1109,1113 ----
  int ProbeProc ()
  {
!    switch (SaveTmpFile ("tmpmodel"))
     {
        case OBJ_FILE_SAVED: return (FILE_PROBE);
***************
*** 1112,1116 ****
  int AnimateProc ()
  {
!    switch (SaveTmpFile ())
     {
        case OBJ_FILE_SAVED: return (FILE_ANIMATE);
--- 1119,1123 ----
  int AnimateProc ()
  {
!    switch (SaveTmpFile ("tmpmodel"))
     {
        case OBJ_FILE_SAVED: return (FILE_ANIMATE);
***************
*** 1151,1153 ****
--- 1158,1186 ----
     }
     return (INVALID);
+ }
+ 
+ void CleanUpFiles ()
+ {
+    ClearFileInfo ();
+    fileModified = FALSE;
+ }
+ 
+ void EmergencySave ()
+ {
+    if (exitNormally) return;
+ 
+    switch (SaveTmpFile ("EmergencySave"))
+    {
+       case OBJ_FILE_SAVED:
+          fprintf (stderr, "Saved to EmergencySave.obj.\n");
+          break;
+       case SYM_FILE_SAVED:
+          fprintf (stderr, "Saved to EmergencySave.sym.\n");
+          break;
+       case INVALID:
+          fprintf (stderr, "Unable to save working file.\n");
+          break;
+    }
+    exitNormally = TRUE;
+    exit (0);
  }
*** font.c.orig	Thu Jul 19 11:04:10 1990
--- font.c	Thu Jul 19 11:04:11 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/font.c,v 1.2 90/06/26 00:05:27 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/font.c,v 1.4 90/07/16 09:04:29 william Exp $";
  #endif
  
***************
*** 631,635 ****
  }
  
! ChangeFont (FontIndex)
     int	FontIndex;
  {
--- 631,635 ----
  }
  
! void ChangeFont (FontIndex)
     int	FontIndex;
  {
*** grid.c.orig	Thu Jul 19 11:04:19 1990
--- grid.c	Thu Jul 19 11:04:20 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/grid.c,v 1.4 90/06/26 00:05:37 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/grid.c,v 1.6 90/07/16 10:18:38 william Exp $";
  #endif
  
***************
*** 30,34 ****
  int	gridOn = TRUE;
  int	xyGrid = DEFAULT_GRID;
- int	curScale = 1;
  int	pageStyle = PORTRAIT;
  int	whereToPrint = PRINTER;
--- 30,33 ----
***************
*** 586,588 ****
--- 585,591 ----
        *GridY = Y;
     }
+ }
+ 
+ void CleanUpGrids ()
+ {
  }
*** mainloop.c.orig	Thu Jul 19 11:04:26 1990
--- mainloop.c	Thu Jul 19 11:04:27 1990
***************
*** 6,13 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/mainloop.c,v 1.4 90/06/26 00:10:31 william Exp $";
  #endif
  
  #include <stdio.h>
  #include <X11/Xlib.h>
  #include "const.h"
--- 6,14 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/mainloop.c,v 1.11 90/07/18 16:20:39 william Exp $";
  #endif
  
  #include <stdio.h>
+ #include <signal.h>
  #include <X11/Xlib.h>
  #include "const.h"
***************
*** 22,25 ****
--- 23,27 ----
  #include "file.e"
  #include "font.e"
+ #include "grid.e"
  #include "menu.e"
  #include "msg.e"
***************
*** 29,36 ****
--- 31,41 ----
  #include "ruler.e"
  #include "scroll.e"
+ #include "select.e"
  #include "setup.e"
+ #include "stk.e"
  #include "text.e"
  
  int	geometrySpecified = FALSE;
+ int	exitNormally = FALSE;
  char	geometrySpec[80];
  char	initMsg1[80], initMsg2[80];
***************
*** 111,114 ****
--- 116,120 ----
  {
     CleanUpDrawingWindow ();
+    CleanUpStk ();
     CleanUpChoices ();
  
***************
*** 122,126 ****
--- 128,137 ----
     CleanUpNames ();
     CleanUpText ();
+    CleanUpColors ();
+    CleanUpFiles ();
+    CleanUpGrids ();
  
+    DelAllCutSel ();
+ 
     XDestroyWindow (mainDisplay, mainWindow);
     if (iconWindowCreated)
***************
*** 146,149 ****
--- 157,161 ----
     if (strcmp (Op, "init") == 0)
     {
+       exitNormally = FALSE;
        if ((mainDisplay = XOpenDisplay (NULL)) == 0)
        {
***************
*** 157,160 ****
--- 169,177 ----
  
  /*    XSetErrorHandler (MyErrorHandler); */
+       XSetIOErrorHandler (EmergencySave);
+       signal (SIGHUP, EmergencySave);
+       signal (SIGFPE, EmergencySave);
+       signal (SIGBUS, EmergencySave);
+       signal (SIGSEGV, EmergencySave);
  
        Setup ();
***************
*** 202,205 ****
--- 219,223 ----
        quitDraw = TRUE;
        XSync (mainDisplay, TRUE);
+       exitNormally = TRUE;
        AllocStrings (FuncStr, Str1, Menu1, Str2, Menu2, Str3, Menu3);
        strcpy (*FuncStr, "Quit");
*** move.c.orig	Thu Jul 19 11:04:34 1990
--- move.c	Thu Jul 19 11:04:35 1990
***************
*** 7,11 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/move.c,v 1.5 90/06/26 00:11:08 william Exp $";
  #endif
  #include <stdio.h>
--- 7,11 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/move.c,v 1.6 90/07/07 23:57:07 william Exp $";
  #endif
  #include <stdio.h>
***************
*** 64,69 ****
        for (i = 0; i < ObjPtr->detail.g->sn; i++)
        {
!          ObjPtr->detail.g->svlist[i].x += Dx;
!          ObjPtr->detail.g->svlist[i].y += Dy;
        }
  }
--- 64,69 ----
        for (i = 0; i < ObjPtr->detail.g->sn; i++)
        {
!          ObjPtr->detail.g->svlist[i].x += (Dx>>zoomScale);
!          ObjPtr->detail.g->svlist[i].y += (Dy>>zoomScale);
        }
  }
*** names.c.orig	Thu Jul 19 11:04:40 1990
--- names.c	Thu Jul 19 11:04:41 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/names.c,v 1.4 90/05/22 15:49:54 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/names.c,v 1.5 90/07/16 08:58:26 william Exp $";
  #endif
  
*** pattern.c.orig	Thu Jul 19 11:04:47 1990
--- pattern.c	Thu Jul 19 11:04:48 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/pattern.c,v 1.2 90/06/26 00:11:14 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/pattern.c,v 1.3 90/07/11 21:30:41 william Exp $";
  #endif
  
***************
*** 661,663 ****
--- 661,770 ----
  
     if (index != INVALID) ChangeAllSelPen (index);
+ }
+ 
+ static
+ int ToggleObjLineType (ObjPtr)
+    struct ObjRec	* ObjPtr;
+ {
+    register struct ObjRec       * obj_ptr;
+    register int			changed = FALSE;
+ 
+    for (obj_ptr = ObjPtr; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
+       switch (obj_ptr->type)
+       {
+          case OBJ_POLY:
+             obj_ptr->detail.p->curved = !obj_ptr->detail.p->curved;
+             if (obj_ptr->detail.p->curved == LT_SPLINE)
+                obj_ptr->detail.p->svlist = MakeSplinePolyVertex (
+                      &(obj_ptr->detail.p->sn), drawOrigX, drawOrigY,
+                      obj_ptr->detail.p->n, obj_ptr->detail.p->vlist);
+             else
+                cfree (obj_ptr->detail.p->svlist);
+             changed = TRUE;
+             AdjObjBBox (obj_ptr);
+             break;
+          case OBJ_POLYGON:
+             obj_ptr->detail.g->curved = !obj_ptr->detail.g->curved;
+             if (obj_ptr->detail.g->curved == LT_SPLINE)
+                obj_ptr->detail.g->svlist = MakeSplinePolygonVertex (
+                      &(obj_ptr->detail.g->sn), drawOrigX, drawOrigY,
+                      obj_ptr->detail.g->n, obj_ptr->detail.g->vlist);
+             else
+                cfree (obj_ptr->detail.g->svlist);
+             changed = TRUE;
+             AdjObjBBox (obj_ptr);
+             break;
+ 
+          case OBJ_GROUP:
+          case OBJ_SYM:
+             if (ToggleObjLineType (obj_ptr->detail.r->last))
+             {
+                changed = TRUE;
+                AdjObjBBox (obj_ptr);
+             }
+             break;
+       }
+    return (changed);
+ }
+ 
+ void ToggleAllSelLineType ()
+ {
+    register struct SelRec	* sel_ptr;
+    register struct ObjRec	* obj_ptr;
+    register int			changed = FALSE;
+ 
+    if (topSel == NULL)
+    {
+       curSpline = !curSpline;
+       ShowLineType ();
+       return;
+    }
+ 
+    for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
+    {
+       obj_ptr = sel_ptr->obj;
+       switch (obj_ptr->type)
+       {
+          case OBJ_POLY:
+             obj_ptr->detail.p->curved = !(obj_ptr->detail.p->curved);
+             if (obj_ptr->detail.p->curved == LT_SPLINE)
+             obj_ptr->detail.p->svlist = MakeSplinePolyVertex (
+                      &(obj_ptr->detail.p->sn), drawOrigX, drawOrigY,
+                      obj_ptr->detail.p->n, obj_ptr->detail.p->vlist);
+             else
+                cfree (obj_ptr->detail.p->svlist);
+             changed = TRUE;
+             AdjObjBBox (obj_ptr);
+             break;
+          case OBJ_POLYGON:
+             obj_ptr->detail.g->curved = !(obj_ptr->detail.g->curved);
+             if (obj_ptr->detail.g->curved == LT_SPLINE)
+                obj_ptr->detail.g->svlist = MakeSplinePolygonVertex (
+                      &(obj_ptr->detail.g->sn), drawOrigX, drawOrigY,
+                      obj_ptr->detail.g->n, obj_ptr->detail.g->vlist);
+             else
+                cfree (obj_ptr->detail.g->svlist);
+             changed = TRUE;
+             AdjObjBBox (obj_ptr);
+             break;
+ 
+          case OBJ_GROUP:
+          case OBJ_SYM:
+             if (ToggleObjLineType (obj_ptr->detail.r->last))
+             {
+                changed = TRUE;
+                AdjObjBBox (obj_ptr);
+             }
+             break;
+       }
+    }
+ 
+    if (changed)
+    {
+       SetFileModified (TRUE);
+       HighLightReverse ();
+       RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
+             selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
+       HighLightForward ();
+    }
  }
*** prtgif.c.orig	Thu Jul 19 11:04:57 1990
--- prtgif.c	Thu Jul 19 11:04:58 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/prtgif.c,v 1.9 90/06/05 10:09:52 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/prtgif.c,v 1.11 90/07/18 15:36:26 william Exp $";
  #endif
  
***************
*** 32,35 ****
--- 32,37 ----
  extern int	PDrawReadObj ();
  
+ static int	lastFile = TRUE;
+ 
  static char	drawPath[MAXSTRING];
  static short	pDrawCursorH[] =
***************
*** 170,179 ****
     }
  
     switch (penPat)
     {
!       case SOLIDPAT: fprintf (FP, "   0 setgray\n"); break;
!       case BACKPAT: fprintf (FP, "   1 setgray\n"); break;
        default:
!          fprintf (FP, "   pat%1d 8 1 0 72 300 32 div div setpattern\n", penPat);
           break;
     }
--- 172,183 ----
     }
  
+    fprintf (FP, "   gsave\n");
     switch (penPat)
     {
!       case SOLIDPAT: fprintf (FP, "      0 setgray\n"); break;
!       case BACKPAT: fprintf (FP, "      1 setgray\n"); break;
        default:
!          fprintf (FP, "      pat%1d 8 1 0 72 300 32 div div setpattern\n",
!                penPat);
           break;
     }
***************
*** 192,205 ****
        {
           case ROTATE0:
!             fprintf (FP, "   %1d %1d moveto (", x, y-canvasFontDes);
              break;
           case ROTATE90:
!             fprintf (FP, "   %1d %1d moveto 90 rotate (", x+canvasFontDes, y);
              break;
           case ROTATE180:
!             fprintf (FP, "   %1d %1d moveto 180 rotate (", x, y+canvasFontDes);
              break;
           case ROTATE270:
!             fprintf (FP, "   %1d %1d moveto 270 rotate (", x-canvasFontDes, y);
              break;
        }
--- 196,209 ----
        {
           case ROTATE0:
!             fprintf (FP, "      %1d %1d moveto (", x, y-canvasFontDes);
              break;
           case ROTATE90:
!             fprintf (FP, "      %1d %1d moveto 90 rotate (", x+canvasFontDes, y);
              break;
           case ROTATE180:
!             fprintf (FP, "      %1d %1d moveto 180 rotate (", x, y+canvasFontDes);
              break;
           case ROTATE270:
!             fprintf (FP, "      %1d %1d moveto 270 rotate (", x-canvasFontDes, y);
              break;
        }
***************
*** 222,226 ****
     }
     fprintf (FP, "\n");
!    fprintf (FP, "   0 setgray\n");
  }
  
--- 226,230 ----
     }
     fprintf (FP, "\n");
!    fprintf (FP, "   grestore\n");
  }
  
***************
*** 426,429 ****
--- 430,447 ----
  
  static
+ char * PDrawReadAttrString (Str)
+    char	* Str;
+ {
+    register char	* s = Str;
+ 
+    for (s = Str; *s != '\0' && *s != '"'; s++)
+       if (*s == '\\')
+          s++;
+ 
+    if (*s == '"') s++;
+    return (s);
+ }
+ 
+ static
  int  PDrawReadAttr (FP, AttrPtr)
     FILE			* FP;
***************
*** 445,452 ****
  
     strcpy(name, FindChar ('"', inbuf));
!    s = FindChar ('"', inbuf);
     s = FindChar (',', s);
     strcpy(value, FindChar ('"', s));
!    s = FindChar ('"', value);
     s = FindChar (',', s);
     sscanf (s, "%d, %d, %d", &shown, &nameshown, &inherited);
--- 463,470 ----
  
     strcpy(name, FindChar ('"', inbuf));
!    s = PDrawReadAttrString (inbuf);
     s = FindChar (',', s);
     strcpy(value, FindChar ('"', s));
!    s = PDrawReadAttrString (value);
     s = FindChar (',', s);
     sscanf (s, "%d, %d, %d", &shown, &nameshown, &inherited);
***************
*** 475,480 ****
  {
     char			inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
!    char			* s, * s1;
!    int			len, id;
     struct AttrRec       * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  
--- 493,498 ----
  {
     char			inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1];
!    char			* line = NULL, * c_ptr, * s, * s1;
!    int			len, id, cur_size, done = FALSE, allocated = FALSE;
     struct AttrRec       * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  
***************
*** 483,492 ****
        if (inbuf[0] == ']') return (FALSE);
  
!       len = strlen(inbuf)-1;
!       inbuf[len] = '\0';
!       ParseStr (inbuf, '(', obj_name);
        if (strcmp (obj_name, "poly") == 0)
        {
!          ReadPolyObj (inbuf, ObjPtr);
           if (fileVersion != INVALID)
              while (PDrawReadAttr (FP, &attr_ptr))
--- 501,546 ----
        if (inbuf[0] == ']') return (FALSE);
  
!       len = strlen(inbuf);
!       if (inbuf[len-1] != '\r' && inbuf[len-1] != '\n')
!       {  /* line longer than MAXSTRING characters */
!          /* inbuf[MAXSTRING-1] == '\0' and len == MAXSTRING-1 now */
!          cur_size = 2*(MAXSTRING-1);
!          allocated = TRUE;
!          line = (char *) calloc (cur_size, sizeof(char));
!          strcpy (line, inbuf);
!          c_ptr = &(line[MAXSTRING-1]);
!          while (!done && fgets (inbuf, MAXSTRING, FP) != NULL)
!          {
!             len = strlen(inbuf);
!             if (inbuf[len-1] == '\r' || inbuf[len-1] == '\n')
!             {
!                done = TRUE;
!                inbuf[len-1] = '\0';
!                strcpy (c_ptr, inbuf);
!             }
!             else
!             {
!                cur_size += MAXSTRING-1;
!                line = (char *) realloc (line, cur_size);
!                strcpy (c_ptr, inbuf);
!                c_ptr += MAXSTRING-1;
!             }
!          }
!          if (!done)
!          {
!             if (allocated) cfree (line);
!             return (FALSE);
!          }
!       }
!       else
!       {
!          line = inbuf;
!          line[len-1] = '\0';
!       }
! 
!       ParseStr (line, '(', obj_name);
        if (strcmp (obj_name, "poly") == 0)
        {
!          ReadPolyObj (line, ObjPtr);
           if (fileVersion != INVALID)
              while (PDrawReadAttr (FP, &attr_ptr))
***************
*** 505,508 ****
--- 559,563 ----
           (*ObjPtr)->detail.p->lattr = bot_attr;
           AdjObjBBox (*ObjPtr);
+          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 509,513 ****
        else if (strcmp (obj_name, "box") == 0)
        {
!          ReadBoxObj (inbuf, ObjPtr);
           return (TRUE);
        }
--- 564,569 ----
        else if (strcmp (obj_name, "box") == 0)
        {
!          ReadBoxObj (line, ObjPtr);
!          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 514,518 ****
        else if (strcmp (obj_name, "oval") == 0)
        {
!          ReadOvalObj (inbuf, ObjPtr);
           return (TRUE);
        }
--- 570,575 ----
        else if (strcmp (obj_name, "oval") == 0)
        {
!          ReadOvalObj (line, ObjPtr);
!          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 519,523 ****
        else if (strcmp (obj_name, "text") == 0)
        {
!          PDrawReadTextObj (FP, inbuf, ObjPtr);
           return (TRUE);
        }
--- 576,581 ----
        else if (strcmp (obj_name, "text") == 0)
        {
!          PDrawReadTextObj (FP, line, ObjPtr);
!          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 524,528 ****
        else if (strcmp (obj_name, "polygon") == 0)
        {
!          ReadPolygonObj (inbuf, ObjPtr);
           return (TRUE);
        }
--- 582,587 ----
        else if (strcmp (obj_name, "polygon") == 0)
        {
!          ReadPolygonObj (line, ObjPtr);
!          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 546,549 ****
--- 605,609 ----
           (*ObjPtr)->detail.r->lattr = bot_attr;
           AdjObjBBox (*ObjPtr);
+          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 568,571 ****
--- 628,632 ----
           (*ObjPtr)->detail.r->lattr = bot_attr;
           AdjObjBBox (*ObjPtr);
+          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 574,580 ****
           PDrawReadGroupObj (FP, ObjPtr);
           (*ObjPtr)->type = OBJ_ICON;
!          if (fgets (inbuf, MAXSTRING, FP) == NULL) return (FALSE);
  
!          strcpy(tmp_str, FindChar ('"', inbuf));
           s = FindChar ('"', tmp_str);
           if (fileVersion != INVALID)
--- 635,645 ----
           PDrawReadGroupObj (FP, ObjPtr);
           (*ObjPtr)->type = OBJ_ICON;
!          if (fgets (line, MAXSTRING, FP) == NULL)
!          {
!             if (allocated) cfree (line);
!             return (FALSE);
!          }
  
!          strcpy(tmp_str, FindChar ('"', line));
           s = FindChar ('"', tmp_str);
           if (fileVersion != INVALID)
***************
*** 604,607 ****
--- 669,673 ----
           (*ObjPtr)->detail.r->lattr = bot_attr;
           AdjObjBBox (*ObjPtr);
+          if (allocated) cfree (line);
           return (TRUE);
        }
***************
*** 608,616 ****
        else if (strcmp (obj_name, "state") == 0)
        {
!          PDrawReadState (inbuf);
           *ObjPtr = NULL;
           return (TRUE);
        }
     }
     return (FALSE);
  }
--- 674,684 ----
        else if (strcmp (obj_name, "state") == 0)
        {
!          PDrawReadState (line);
           *ObjPtr = NULL;
+          if (allocated) cfree (line);
           return (TRUE);
        }
     }
+    if (allocated) cfree (line);
     return (FALSE);
  }
***************
*** 617,621 ****
  
  static
! void PDrawLoad (FileName)
     char	* FileName;
  {
--- 685,689 ----
  
  static
! int PDrawLoad (FileName)
     char	* FileName;
  {
***************
*** 630,634 ****
     {
        printf ("Can not open '%s'.", full_name);
!       return;
     }
  
--- 698,702 ----
     {
        printf ("Can not open '%s'.", full_name);
!       return (FALSE);
     }
  
***************
*** 640,647 ****
  
     fclose (fp);
  }
  
  static
! void PDrawDump ()
  {
     register struct ObjRec	* obj_ptr;
--- 708,717 ----
  
     fclose (fp);
+    return (TRUE);
  }
  
  static
! void PDrawDump (FileName)
!    char	* FileName;
  {
     register struct ObjRec	* obj_ptr;
***************
*** 696,712 ****
     fclose (fp);
  
!    sprintf (cmd, "lpr %s 2>&1", tmp_file);
!    if ((fp = popen (cmd, "r")) == NULL)
     {
!       printf ("Can not execute '%s', print aborted.\n", cmd);
!       unlink (tmp_file);
!       return;
!    }
!    while (fgets (tmp_str, 256, fp) != NULL) sleep (5);
  
     pclose (fp);
     unlink (tmp_file);
- 
-    printf ("%s printed.\n\n", tmp_file);
  }
  
--- 766,811 ----
     fclose (fp);
  
!    switch (whereToPrint)
     {
!       case PRINTER:
!          if (lastFile)
!             sprintf (cmd, "lpr %s 2>&1", tmp_file);
!          else
!             sprintf (cmd, "lpr -h %s 2>&1", tmp_file);
  
+          if ((fp = popen (cmd, "r")) == NULL)
+          {
+             printf ("Can not execute '%s', print aborted.\n", cmd);
+             unlink (tmp_file);
+             return;
+          }
+          while (fgets (tmp_str, 256, fp) != NULL)
+          {
+             printf ("%s", tmp_str);
+             sleep (5);
+          }
+          printf ("%s printed.\n\n", tmp_file);
+          break;
+       case LATEX_FIG:
+          sprintf (ps_file, "%s.ps", FileName);
+          sprintf (cmd, "tgif2ps < %s 1> %s 2>&1; chmod %s %s", tmp_file,
+                ps_file, PSFILE_MOD, ps_file);
+ 
+          if ((fp = popen (cmd, "r")) == NULL)
+          {
+             printf ("Can not execute '%s', print aborted.\n", cmd);
+             unlink (tmp_file);
+             return;
+          }
+          while (fgets (tmp_str, 256, fp) != NULL)
+          {
+             printf ("%s", tmp_str);
+             sleep (5);
+          }
+          printf ("LaTeX figure printed into '%s'.\n\n", ps_file);
+          break;
+    }
     pclose (fp);
     unlink (tmp_file);
  }
  
***************
*** 717,720 ****
--- 816,820 ----
     char	inbuf[MAXSTRING+1];
     char	* c_ptr;
+    int	len;
  
  /* malloc_debug (1); */
***************
*** 729,732 ****
--- 829,839 ----
           strcpy (drawPath, c_ptr);
  
+    if ((argc > 1) && (strcmp (argv[1], "-p") == 0))
+    {
+       whereToPrint = LATEX_FIG;
+       argv++;
+       argc--;
+    }
+ 
     switch (argc)
     {
***************
*** 735,740 ****
           while (fgets (inbuf, MAXSTRING, stdin) != NULL)
           {
!             PDrawLoad (inbuf);
!             PDrawDump ();
              printf ("\nDraw File Name to Print> ");
           }
--- 842,855 ----
           while (fgets (inbuf, MAXSTRING, stdin) != NULL)
           {
!             len = strlen (inbuf);
!             if (len > 0)
!             {
!                if (inbuf[--len] == '\n') inbuf[len] = '\0';
!                if (PDrawLoad (inbuf))
!                {
!                   PDrawDump (inbuf);
!                   DelAllObj ();
!                }
!             }
              printf ("\nDraw File Name to Print> ");
           }
***************
*** 743,749 ****
           for (argc--, argv++; argc > 0; argc--, argv++)
           {
!             PDrawLoad (*argv);
!             PDrawDump ();
!             DelAllObj ();
           }
     }
--- 858,867 ----
           for (argc--, argv++; argc > 0; argc--, argv++)
           {
!             lastFile = (argc == 1);
!             if (PDrawLoad (*argv))
!             {
!                PDrawDump (*argv);
!                DelAllObj ();
!             }
           }
     }
*** raster.c.orig	Thu Jul 19 11:05:04 1990
--- raster.c	Thu Jul 19 11:05:05 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/raster.c,v 1.3 90/05/22 14:16:44 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/raster.c,v 1.5 90/07/16 10:51:23 william Exp $";
  #endif
  
***************
*** 13,18 ****
  #include "types.h"
  
- #include "color.e"
  #include "choice.e"
  #include "font.e"
  #include "pattern.e"
--- 13,18 ----
  #include "types.h"
  
  #include "choice.e"
+ #include "color.e"
  #include "font.e"
  #include "pattern.e"
***************
*** 106,111 ****
  GC	revDefaultGC;
  
- Pixmap	colorPxMp[MAXCOLORS];
- 
  Pixmap	choicePixmap[MAXCHOICES];
  Pixmap	lineWidthPixmap[MAXLINEWIDTHS];
--- 106,109 ----
***************
*** 323,327 ****
--- 321,332 ----
     register int	i;
  
+    for (i = 0; i < MAXCHOICES; i++) XFreePixmap (mainDisplay, choicePixmap[i]);
     for (i = 0; i < MAXPATTERNS+1; i++) XFreePixmap (mainDisplay, patPixmap[i]);
+    for (i = 0; i < MAXLINEWIDTHS; i++)
+       XFreePixmap (mainDisplay, lineWidthPixmap[i]);
+    for (i = 0; i < MAXLINEWIDTHS+MAXLINETYPES+MAXLINESTYLES; i++)
+       XFreePixmap (mainDisplay, lineStylePixmap[i]);
+    for (i = 0; i < MAXLINETYPES; i++)
+       XFreePixmap (mainDisplay, lineTypePixmap[i]);
     for (i = 0; i < MAXJUSTS; i++) XFreePixmap (mainDisplay, justPixmap[i]);
     XFreePixmap (mainDisplay, alignHoriPixmap[0]);
***************
*** 330,340 ****
     for (i = 1; i < MAXALIGNS; i++)
        XFreePixmap (mainDisplay, alignVertPixmap[i]);
-    for (i = 0; i < MAXLINEWIDTHS+MAXLINETYPES+MAXLINESTYLES; i++)
-       XFreePixmap (mainDisplay, lineStylePixmap[i]);
-    for (i = 0; i < MAXLINETYPES; i++)
-       XFreePixmap (mainDisplay, lineTypePixmap[i]);
     for (i = 0; i < MAXLINEWIDTHS; i++)
-       XFreePixmap (mainDisplay, lineWidthPixmap[i]);
-    for (i = 0; i < MAXLINEWIDTHS; i++)
        XFreePixmap (mainDisplay, shortLineWidthPixmap[i]);
     for (i = 0; i < 2; i++)
--- 335,339 ----
***************
*** 344,348 ****
     for (i = 0; i < MAXLINESTYLES; i++)
        XFreePixmap (mainDisplay, shortLineStylePixmap[i]);
-    for (i = 0; i < MAXCHOICES; i++) XFreePixmap (mainDisplay, choicePixmap[i]);
  
     XFreeGC (mainDisplay, rasterGC);
--- 343,346 ----
*** select.c.orig	Thu Jul 19 11:05:12 1990
--- select.c	Thu Jul 19 11:05:14 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/select.c,v 1.4 90/06/26 00:11:25 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/select.c,v 1.6 90/07/16 10:55:20 william Exp $";
  #endif
  
***************
*** 26,31 ****
  #include "rect.e"
  #include "ruler.e"
- #include "stretch.e"
  #include "setup.e"
  
  #define FORWARD 0
--- 26,31 ----
  #include "rect.e"
  #include "ruler.e"
  #include "setup.e"
+ #include "stretch.e"
  
  #define FORWARD 0
***************
*** 573,589 ****
  }
  
! static
! void DelCutSel ()
  {
     register struct SelRec	* sel_ptr;
  
!    if ((sel_ptr = topCutSel) == NULL) return;
! 
!    for ( ; sel_ptr != NULL; sel_ptr = sel_ptr->next)
     {
!       DelObj (sel_ptr->obj);
!       cfree (sel_ptr);
     }
-    topCutSel = botCutSel = NULL;
  }
  
--- 573,590 ----
  }
  
! void DelAllCutSel ()
  {
     register struct SelRec	* sel_ptr;
  
!    while (topCutSel != NULL)
     {
!       for (sel_ptr = topCutSel->next; sel_ptr != NULL; sel_ptr = sel_ptr->next)
!       {
!          DelObj (sel_ptr->obj);
!          cfree (sel_ptr);
!       }
!       topCutSel = topCutSel->prev; /* prev is used as the stack chaser */
!       botCutSel = botCutSel->prev; /* prev is used as the stack chaser */
     }
  }
  
***************
*** 590,594 ****
  void UndoDelete ()
  {
!    if (topCutSel == NULL) return;
  
     HighLightReverse ();
--- 591,599 ----
  void UndoDelete ()
  {
!    if (topCutSel == NULL)
!    {
!       Msg ("Un-delete buffer empty!");
!       return;
!    }
  
     HighLightReverse ();
***************
*** 595,600 ****
     RemoveAllSel ();
  
!    topSel = topCutSel;
!    botSel = botCutSel;
  
     botSel->obj->next = topObj;
--- 600,605 ----
     RemoveAllSel ();
  
!    topSel = topCutSel->next;
!    botSel = botCutSel->next;
  
     botSel->obj->next = topObj;
***************
*** 605,609 ****
     topObj = topSel->obj;
  
!    topCutSel = botCutSel = NULL;
  
     UpdSelBBox ();
--- 610,617 ----
     topObj = topSel->obj;
  
!    cfree (topCutSel);
!    cfree (botCutSel);
!    topCutSel = topCutSel->prev; /* prev is used as the stack chaser */
!    botCutSel = botCutSel->prev; /* prev is used as the stack chaser */
  
     UpdSelBBox ();
***************
*** 616,622 ****
  }
  
  void DelAllSelObj ()
  {
!    register struct SelRec	* sel_ptr;
  
     if (topSel == NULL) return;
--- 624,646 ----
  }
  
+ void CopySelToCut ()
+ {
+    register struct SelRec	* sel_ptr, * top_cut_ptr, * bot_cut_ptr;
+    struct SelRec		* top_sel_ptr, * bot_sel_ptr;
+ 
+    if (topSel == NULL) return;
+ 
+    JustDupSelObj (&top_sel_ptr, &bot_sel_ptr);
+ 
+    top_cut_ptr = (struct SelRec *) calloc (2, sizeof (struct SelRec));
+    bot_cut_ptr = &top_cut_ptr[1];
+    top_cut_ptr->next = top_sel_ptr; bot_cut_ptr->next = bot_sel_ptr;
+    top_cut_ptr->prev = topCutSel; bot_cut_ptr->prev = botCutSel;
+    topCutSel = top_cut_ptr; botCutSel = bot_cut_ptr;
+ }
+ 
  void DelAllSelObj ()
  {
!    register struct SelRec	* sel_ptr, * top_cut_ptr, * bot_cut_ptr;
  
     if (topSel == NULL) return;
***************
*** 625,630 ****
     tmpTopObj = tmpBotObj = NULL;
     BreakSel ();
!    topCutSel = topSel;
!    botCutSel = botSel;
  
     topSel = botSel = NULL;
--- 649,658 ----
     tmpTopObj = tmpBotObj = NULL;
     BreakSel ();
! 
!    top_cut_ptr = (struct SelRec *) calloc (2, sizeof (struct SelRec));
!    bot_cut_ptr = &top_cut_ptr[1];
!    top_cut_ptr->next = topSel; bot_cut_ptr->next = botSel;
!    top_cut_ptr->prev = topCutSel; bot_cut_ptr->prev = botCutSel;
!    topCutSel = top_cut_ptr; botCutSel = bot_cut_ptr;
  
     topSel = botSel = NULL;
*** setup.c.orig	Thu Jul 19 11:05:19 1990
--- setup.c	Thu Jul 19 11:05:20 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/setup.c,v 1.8 90/06/26 00:13:09 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/setup.c,v 1.10 90/07/17 16:46:52 william Exp $";
  #endif
  
***************
*** 14,19 ****
  #include "types.h"
  
- #include "color.e"
  #include "choice.e"
  #include "cursor.e"
  #include "drawing.e"
--- 14,19 ----
  #include "types.h"
  
  #include "choice.e"
+ #include "color.e"
  #include "cursor.e"
  #include "drawing.e"
***************
*** 216,219 ****
--- 216,223 ----
     XSizeHints	sizehints;
     XColor	color;
+ 
+    if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "Synchronize")) != NULL)
+       if ((strcmp (c_ptr, "on") == 0) || (strcmp (c_ptr, "On") == 0))
+          XSynchronize (mainDisplay, True);
  
     colorDisplay = (DisplayPlanes (mainDisplay, mainScreen) == 1) ? FALSE : TRUE;
*** spline.c.orig	Thu Jul 19 11:05:24 1990
--- spline.c	Thu Jul 19 11:05:26 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/spline.c,v 1.2 90/05/22 14:38:02 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/spline.c,v 1.3 90/07/16 10:58:15 william Exp $";
  #endif
  
*** stk.c.orig	Thu Jul 19 11:05:31 1990
--- stk.c	Thu Jul 19 11:05:32 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stk.c,v 1.3 90/06/26 00:11:30 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stk.c,v 1.4 90/07/16 09:30:47 william Exp $";
  #endif
  
***************
*** 210,212 ****
--- 210,223 ----
     XSync (mainDisplay, TRUE);
     justDupped = FALSE;
+ }
+ 
+ void CleanUpStk ()
+ {
+    for ( ; topStk != NULL; topStk = topStk->next)
+    {
+       topObj = topStk->first;
+       botObj = topStk->last;
+       DelAllObj ();
+       cfree (topStk);
+    }
  }
*** stretch.c.orig	Thu Jul 19 11:05:37 1990
--- stretch.c	Thu Jul 19 11:05:38 1990
***************
*** 6,10 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stretch.c,v 1.4 90/06/26 00:11:32 william Exp $";
  #endif
  
--- 6,10 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stretch.c,v 1.6 90/07/08 22:22:08 william Exp $";
  #endif
  
***************
*** 105,109 ****
  }
  
- static
  int PtInPolyMark (XOff, YOff, NumPts, V, Index)
     int		XOff, YOff, NumPts, * Index;
--- 105,108 ----
***************
*** 531,534 ****
--- 530,542 ----
     SelBox (drawWindow, revDefaultGC, stretched_ltx, stretched_lty,
           stretched_rbx, stretched_rby);
+ 
+    if (moveX == pivotX)
+    {
+       Msg ("Can not stretch!  Object has ZERO width!"); return;
+    }
+    else if (moveY == pivotY)
+    {
+       Msg ("Can not stretch!  Object has ZERO height!"); return;
+    }
  
     obj_w = (double)(moveX - pivotX);
*** version.c.orig	Thu Jul 19 11:05:44 1990
--- version.c	Thu Jul 19 11:05:45 1990
***************
*** 6,11 ****
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/version.c,v 1.12 90/06/26 08:47:59 william Exp $";
  #endif
  
! char	* version_string = "1.9";
--- 6,11 ----
  #ifndef lint
  static char RCSid[] =
!       "@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/version.c,v 1.13 90/07/12 09:02:19 william Exp $";
  #endif
  
! char	* version_string = "1.10";
*** color.e.orig	Thu Jul 19 11:05:51 1990
--- color.e	Thu Jul 19 11:05:52 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/color.e,v 1.4 90/05/07 15:24:58 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/color.e,v 1.6 90/07/15 17:42:49 william Exp $
   */
  
***************
*** 19,20 ****
--- 19,21 ----
  extern void	ChangeAllSelColor ();
  extern void	ColorMenu ();
+ extern void	CleanUpColors ();
*** cursor.e.orig	Thu Jul 19 11:05:56 1990
--- cursor.e	Thu Jul 19 11:05:56 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/cursor.e,v 1.1 90/04/01 22:16:57 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/cursor.e,v 1.3 90/07/08 00:33:40 william Exp $
   */
  
*** dup.e.orig	Thu Jul 19 11:06:00 1990
--- dup.e	Thu Jul 19 11:06:01 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dup.e,v 1.1 90/04/01 22:17:00 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/dup.e,v 1.2 90/07/06 18:00:44 william Exp $
   */
  
***************
*** 14,15 ****
--- 14,16 ----
  extern void	DupTextObj ();
  extern void	DupSelObj ();
+ extern void	JustDupSelObj ();
*** edit.e.orig	Thu Jul 19 11:06:05 1990
--- edit.e	Thu Jul 19 11:06:05 1990
***************
*** 4,10 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/edit.e,v 1.1 90/04/01 22:17:02 william Exp $
   */
  
  extern void	EditMenu ();
  extern void	FrontProc ();
--- 4,12 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/edit.e,v 1.2 90/07/04 21:07:20 william Exp $
   */
  
+ extern void	DeletePoint ();
+ extern void	AddPoint ();
  extern void	EditMenu ();
  extern void	FrontProc ();
*** file.e.orig	Thu Jul 19 11:06:10 1990
--- file.e	Thu Jul 19 11:06:11 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/file.e,v 1.6 90/05/24 10:35:30 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/file.e,v 1.10 90/07/18 16:21:33 william Exp $
   */
  
***************
*** 48,49 ****
--- 48,51 ----
  extern int	EscapeProc ();
  extern int	FileMenu ();
+ extern void	CleanUpFiles ();
+ extern void	EmergencySave ();
*** grid.e.orig	Thu Jul 19 11:06:14 1990
--- grid.e	Thu Jul 19 11:06:16 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/grid.e,v 1.1 90/04/01 22:17:05 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/grid.e,v 1.3 90/07/16 10:18:50 william Exp $
   */
  
***************
*** 9,13 ****
  extern int	gridOn;
  extern int	xyGrid;
- extern int	curScale;
  extern int	pageStyle;
  extern int	whereToPrint;
--- 9,12 ----
***************
*** 26,27 ****
--- 25,27 ----
  extern void	LayoutMenu ();
  extern void	GridXY ();
+ extern void	CleanUpGrids ();
*** mainloop.e.orig	Thu Jul 19 11:06:19 1990
--- mainloop.e	Thu Jul 19 11:06:20 1990
***************
*** 4,11 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/mainloop.e,v 1.1 90/04/29 22:38:38 william Exp $
   */
  
  extern int	geometrySpecified;
  extern char	geometrySpec[];
  extern char	initMsg1[];
--- 4,12 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/mainloop.e,v 1.2 90/07/17 18:04:57 william Exp $
   */
  
  extern int	geometrySpecified;
+ extern int	exitNormally;
  extern char	geometrySpec[];
  extern char	initMsg1[];
*** pattern.e.orig	Thu Jul 19 11:06:23 1990
--- pattern.e	Thu Jul 19 11:06:24 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/pattern.e,v 1.1 90/04/01 22:17:14 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/pattern.e,v 1.3 90/07/11 21:25:59 william Exp $
   */
  
***************
*** 18,21 ****
--- 18,22 ----
  extern void	ChangeAllSelLineWidth ();
  extern void	ChangeAllSelPen ();
+ extern void	ToggleAllSelLineType ();
  extern void	ModeMenu ();
  extern void	FillMenu ();
*** raster.e.orig	Thu Jul 19 11:06:30 1990
--- raster.e	Thu Jul 19 11:06:31 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/raster.e,v 1.1 90/04/01 22:17:17 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/raster.e,v 1.2 90/07/16 09:10:17 william Exp $
   */
  
***************
*** 15,20 ****
  extern GC	defaultGC;
  extern GC	revDefaultGC;
- 
- extern Pixmap	colorPxMp[];
  
  extern Pixmap	choicePixmap[];
--- 15,18 ----
*** select.e.orig	Thu Jul 19 11:06:35 1990
--- select.e	Thu Jul 19 11:06:36 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/select.e,v 1.1 90/04/01 22:17:20 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/select.e,v 1.2 90/07/06 18:02:44 william Exp $
   */
  
***************
*** 21,25 ****
--- 21,27 ----
  extern void	MoveSelToTop ();
  extern void	MoveSelToBot ();
+ extern void	DelAllCutSel ();
  extern void	UndoDelete ();
+ extern void	CopySelToCut ();
  extern void	DelAllSelObj ();
  extern void	GroupSelObj ();
*** stk.e.orig	Thu Jul 19 11:06:39 1990
--- stk.e	Thu Jul 19 11:06:40 1990
***************
*** 4,8 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stk.e,v 1.1 90/04/01 22:17:24 william Exp $
   */
  
--- 4,8 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stk.e,v 1.2 90/07/16 09:30:53 william Exp $
   */
  
***************
*** 10,11 ****
--- 10,12 ----
  extern void	PushIcon ();
  extern void	PopIcon ();
+ extern void	CleanUpStk ();
*** stretch.e.orig	Thu Jul 19 11:06:43 1990
--- stretch.e	Thu Jul 19 11:06:44 1990
***************
*** 4,10 ****
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stretch.e,v 1.1 90/04/01 22:17:25 william Exp $
   */
  
  extern struct SelRec	* PtInSelMark ();
  extern void	StretchSel ();
--- 4,11 ----
   * Copyright (C) 1989, William Cheng.
   *
!  * @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/stretch.e,v 1.2 90/07/07 01:48:10 william Exp $
   */
  
+ extern int	* PtInPolyMark ();
  extern struct SelRec	* PtInSelMark ();
  extern void	StretchSel ();
*** Makefile.noimake.orig	Thu Jul 19 11:06:52 1990
--- Makefile.noimake	Thu Jul 19 11:06:53 1990
***************
*** 4,8 ****
  # Copyright (C) 1990, William Cheng.
  #
! # @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/Makefile.noimake,v 1.10 90/06/13 14:32:34 william Exp $
  #
  
--- 4,8 ----
  # Copyright (C) 1990, William Cheng.
  #
! # @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/Makefile.noimake,v 1.16 90/07/17 18:06:05 william Exp $
  #
  
***************
*** 19,23 ****
  OBJ1 =	align.o animate.o attr.o \
  	box.o button.o \
! 	color.o choice.o cursor.o \
  	dialog.o drawing.o dup.o \
  	edit.o \
--- 19,23 ----
  OBJ1 =	align.o animate.o attr.o \
  	box.o button.o \
! 	choice.o color.o cursor.o \
  	dialog.o drawing.o dup.o \
  	edit.o \
***************
*** 53,56 ****
--- 53,58 ----
  	bitmaps/poly.bm bitmaps/polygon.bm bitmaps/printer.bm bitmaps/text.bm
  
+ NAMES_BM = bitmaps/uparrow.bm bitmaps/downarrow.bm
+ 
  SCROLL_BM = bitmaps/uparrow.bm bitmaps/downarrow.bm bitmaps/rightarrow.bm \
  	bitmaps/leftarrow.bm
***************
*** 87,92 ****
  button.o:	const.h types.h \
  		box.e cursor.e font.e mainloop.e raster.e rect.e setup.e
- color.o:	const.h types.h \
- 		choice.e mark.e menu.e obj.e raster.e select.e setup.e text.e
  choice.o:	const.h types.h \
  		align.e box.e color.e cursor.e font.e grid.e mark.e msg.e \
--- 89,92 ----
***************
*** 93,99 ****
  		oval.e pattern.e poly.e polygon.e raster.e select.e setup.e \
  		text.e
  cursor.o:	const.h types.h $(CURSOR_BM) choice.e setup.e
! tgif.o:		const.h types.h mainloop.e setup.e version.e
! dialog.o:	const.h cursor.e box.e font.e mainloop.e raster.e setup.e
  drawing.o:	const.h types.h \
  		align.e animate.e attr.e box.e choice.e cursor.e dialog.e \
--- 93,100 ----
  		oval.e pattern.e poly.e polygon.e raster.e select.e setup.e \
  		text.e
+ color.o:	const.h types.h \
+ 		choice.e mark.e menu.e obj.e raster.e select.e setup.e text.e
  cursor.o:	const.h types.h $(CURSOR_BM) choice.e setup.e
! dialog.o:	const.h box.e cursor.e font.e mainloop.e raster.e setup.e
  drawing.o:	const.h types.h \
  		align.e animate.e attr.e box.e choice.e cursor.e dialog.e \
***************
*** 105,114 ****
  		attr.e drawing.e grid.e obj.e select.e setup.e
  edit.o:		const.h types.h \
! 		align.e color.e drawing.e dup.e group.e mark.e obj.e \
! 		raster.e select.e setup.e stretch.e
  file.o:		const.h types.h \
  		align.e attr.e box.e button.e choice.e color.e dialog.e \
! 		drawing.e file.e font.e grid.e group.e menu.e msg.e \
! 		poly.e polygon.e obj.e oval.e pattern.e rect.e ruler.e \
  		scroll.e select.e setup.e stk.e text.e
  font.o:		const.h types.h \
--- 106,115 ----
  		attr.e drawing.e grid.e obj.e select.e setup.e
  edit.o:		const.h types.h \
! 		align.e color.e cursor.e drawing.e dup.e font.e group.e mark.e \
! 		obj.e poly.e raster.e select.e setup.e spline.e stretch.e
  file.o:		const.h types.h \
  		align.e attr.e box.e button.e choice.e color.e dialog.e \
! 		drawing.e font.e grid.e group.e mainloop.e menu.e msg.e \
! 		names.e poly.e polygon.e obj.e oval.e pattern.e rect.e ruler.e \
  		scroll.e select.e setup.e stk.e text.e
  font.o:		const.h types.h \
***************
*** 122,127 ****
  mainloop.o:	const.h types.h \
  		animate.e choice.e color.e cursor.e dialog.e drawing.e \
! 		file.e font.e menu.e msg.e names.e obj.e raster.e \
! 		ruler.e scroll.e setup.e
  mark.o:		const.h types.h \
  		raster.e setup.e select.e
--- 123,128 ----
  mainloop.o:	const.h types.h \
  		animate.e choice.e color.e cursor.e dialog.e drawing.e \
! 		file.e font.e grid.e menu.e msg.e names.e obj.e raster.e \
! 		ruler.e scroll.e select.e setup.e stk.e text.e
  mark.o:		const.h types.h \
  		raster.e setup.e select.e
***************
*** 134,138 ****
  		raster.e ruler.e select.e setup.e
  msg.o:		const.h types.h font.e raster.e setup.e
! names.o:	const.h types.h $(SCROLL_BM) \
  		box.e button.e cursor.e font.e mainloop.e raster.e scroll.e \
  		setup.e
--- 135,139 ----
  		raster.e ruler.e select.e setup.e
  msg.o:		const.h types.h font.e raster.e setup.e
! names.o:	const.h types.h $(NAMES_BM) \
  		box.e button.e cursor.e font.e mainloop.e raster.e scroll.e \
  		setup.e
***************
*** 143,149 ****
  		color.e cursor.e file.e grid.e menu.e obj.e pattern.e \
  		poly.e raster.e ruler.e select.e setup.e
! prtgif.o:	const.h types.h \
! 		attr.e box.e file.e font.e grid.e group.e obj.e oval.e \
! 		pattern.e poly.e polygon.e setup.e text.e
  poly.o:		const.h types.h \
  		attr.e color.e cursor.e drawing.e file.e grid.e obj.e \
--- 144,150 ----
  		color.e cursor.e file.e grid.e menu.e obj.e pattern.e \
  		poly.e raster.e ruler.e select.e setup.e
! pattern.o:	const.h types.h \
! 		choice.e drawing.e mark.e menu.e obj.e poly.e raster.e \
! 		select.e setup.e spline.e
  poly.o:		const.h types.h \
  		attr.e color.e cursor.e drawing.e file.e grid.e obj.e \
***************
*** 152,158 ****
  		color.e cursor.e dialog.e grid.e file.e obj.e \
  		pattern.e poly.e raster.e ruler.e select.e setup.e spline.e
! pattern.o:	const.h types.h \
! 		choice.e drawing.e mark.e menu.e obj.e poly.e raster.e \
! 		select.e setup.e spline.e
  raster.o:	const.h types.h $(RASTER_BM) \
  		choice.e color.e font.e pattern.e setup.e
--- 153,159 ----
  		color.e cursor.e dialog.e grid.e file.e obj.e \
  		pattern.e poly.e raster.e ruler.e select.e setup.e spline.e
! prtgif.o:	const.h types.h \
! 		attr.e box.e file.e font.e grid.e group.e obj.e oval.e \
! 		pattern.e poly.e polygon.e setup.e text.e
  raster.o:	const.h types.h $(RASTER_BM) \
  		choice.e color.e font.e pattern.e setup.e
***************
*** 166,173 ****
  		move.e obj.e raster.e rect.e ruler.e setup.e stretch.e
  setup.o:	const.h types.h \
! 		choice.e color.e cursor.e drawing.e font.e mainloop.e names.e \
! 		raster.e ruler.e scroll.e
  spline.o:	const.h types.h \
! 		poly.e rect.e raster.e setup.e
  special.o:	const.h types.h \
  		animate.e attr.e choice.e color.e cursor.e dialog.e drawing.e \
--- 167,174 ----
  		move.e obj.e raster.e rect.e ruler.e setup.e stretch.e
  setup.o:	const.h types.h \
! 		choice.e color.e cursor.e drawing.e font.e mainloop.e menu.e \
! 		names.e raster.e ruler.e scroll.e
  spline.o:	const.h types.h \
! 		poly.e raster.e rect.e setup.e
  special.o:	const.h types.h \
  		animate.e attr.e choice.e color.e cursor.e dialog.e drawing.e \
***************
*** 184,187 ****
--- 185,189 ----
  		attr.e choice.e color.e cursor.e dup.e file.e font.e \
  		grid.e obj.e pattern.e poly.e raster.e ruler.e setup.e
+ tgif.o:		const.h types.h mainloop.e setup.e version.e
  version.o:
  
*** Imakefile.orig	Thu Jul 19 11:06:58 1990
--- Imakefile	Thu Jul 19 11:06:58 1990
***************
*** 4,11 ****
  /**/# Copyright (C) 1990, William Cheng.
  /**/#
! /**/# @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/Imakefile,v 1.16 90/06/26 08:48:16 william Exp $
  /**/#
  
! TGIFVERSION	= 1.9
  PROGRAMS	= tgif prtgif tgif2ps frontend11.o
  CDEBUGFLAGS	= -g
--- 4,11 ----
  /**/# Copyright (C) 1990, William Cheng.
  /**/#
! /**/# @(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/Imakefile,v 1.18 90/07/17 16:54:34 william Exp $
  /**/#
  
! TGIFVERSION	= 1.10
  PROGRAMS	= tgif prtgif tgif2ps frontend11.o
  CDEBUGFLAGS	= -g
*** prtgif.man.orig	Thu Jul 19 11:07:02 1990
--- prtgif.man	Thu Jul 19 11:07:03 1990
***************
*** 1,4 ****
! .\"@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/prtgif.man,v 1.1 90/05/10 09:27:25 william Exp $
! .TH PRTGIF 1 "Version 1.0" "PrTgif"
  .SH NAME
  \fIprtgif\fR \- Prints a \fItgif\fR object file without opening windows
--- 1,4 ----
! .\"@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/prtgif.man,v 1.2 90/07/17 17:01:52 william Exp $
! .TH PRTGIF 1 "Version 1.10 or above" "PrTgif"
  .SH NAME
  \fIprtgif\fR \- Prints a \fItgif\fR object file without opening windows
***************
*** 6,17 ****
  .SH SYNOPSIS
  .B prtgif
! \fIfile\fR
  .SH DESCRIPTION
! \fIprtgif\fR prints \fIfile.obj\fR into a PostScript(TM) page description file,
! /tmp/DRAW.PS, and pipes it to \fIlpr\fR.
! .SH FILES
! /tmp/DRAW.PS
  .SH SEE ALSO
! \fBlpr\fR(1), \fBtgif\fR(1)
  .SH COPYRIGHT
  Please see the ``Copyright'' file for details on the copyrights.
--- 6,18 ----
  .SH SYNOPSIS
  .B prtgif
! [\fB\-p\fR]
! [\fIfile\fR]
  .SH DESCRIPTION
! \fIprtgif\fR prints \fIfile.obj\fR into a PostScript(TM) page description file
! and pipes it to \fIlpr\fR if the \fB\-p\fR option is not specified.  Otherwise,
! it generates an encapsulated PostScript file in \fIfile.ps\fR.  (Note that
! prtgif calls \fItgif2ps\fR, which should be found in the path.)
  .SH SEE ALSO
! \fBlpr\fR(1), \fBtgif\fR(1), \fBtgif2ps\fR(1), \fBlatex\fR(1L)
  .SH COPYRIGHT
  Please see the ``Copyright'' file for details on the copyrights.
*** tgif.man.orig	Thu Jul 19 11:07:11 1990
--- tgif.man	Thu Jul 19 11:07:13 1990
***************
*** 1,4 ****
! .\"@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/tgif.man,v 1.6 90/06/05 12:19:24 william Exp $
! .TH TGIF 1 "Version 1.6" "Tgif"
  .SH NAME
  \fItgif\fR \- Xlib based 2-D drawing facility under X11.  Also supports
--- 1,4 ----
! .\"@(#)$Header: /n/kona/tangram/u/william/X11/TGIF/RCS/tgif.man,v 1.9 90/07/19 11:08:00 william Exp $
! .TH TGIF 1 "Version 1.10 and Above" "Tgif"
  .SH NAME
  \fItgif\fR \- Xlib based 2-D drawing facility under X11.  Also supports
***************
*** 14,18 ****
  specifies a file of objects to be initially edited by tgif.
  Tgif is purely based on \fIXlib\fR.
! It is tested under X11-R3 and X11-R4, and
  it requires a 3 button mouse.
  .PP
--- 14,18 ----
  specifies a file of objects to be initially edited by tgif.
  Tgif is purely based on \fIXlib\fR.
! It is tested under X11-R4, and
  it requires a 3 button mouse.
  .PP
***************
*** 214,219 ****
--- 214,221 ----
    #.	scroll down\br
  \br
+  ^#A	add points to the selected poly or spline\br
   ^#B	change the text style to bold\br
   ^#C	change the text justification to center justified\br
+  ^#D	delete points from the selected poly or spline\br
   ^#G	toggle snapping to the grid points\br
   ^#I	make the selected complex object iconic\br
***************
*** 229,232 ****
--- 231,235 ----
   ^#T	change the text style to italic\br
   ^#V	change the drawing mode to oval\br
+  ^#W	toggle between poly and spline\br
  .DE
  .br
***************
*** 370,373 ****
--- 373,380 ----
  This specified the print command used for printing the PostScript file.
  Default is lpr (without any quotes).
+ .TP
+ .I Tgif*Synchronize: [on,off]
+ XSynchronize is called if this default is set to \fIon\fR.  Default is
+ \fIoff\fR.
  .SH ENVIRONMENT
  .TP
---------------------------------> cut here <---------------------------------
--

-- Bill Cheng // UCLA Computer Science Department // (213) 206-7135
   3277 Boelter Hall // Los Angeles, California 90024 // USA
   william@CS.UCLA.EDU      ...!{uunet|ucbvax}!cs.ucla.edu!william